| ... | ... | @@ -1346,11 +1346,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1346 | 1346 | return self.fail(src, "TODO implement set stack variable with compare flags value (signed)", .{}); |
| 1347 | 1347 | }, |
| 1348 | 1348 | .immediate => |x_big| { |
| 1349 | | if (stack_offset > 128) { |
| 1349 | const abi_size = ty.abiSize(self.target.*); |
| 1350 | const adj_off = stack_offset + abi_size; |
| 1351 | if (adj_off > 128) { |
| 1350 | 1352 | return self.fail(src, "TODO implement set stack variable with large stack offset", .{}); |
| 1351 | 1353 | } |
| 1352 | 1354 | try self.code.ensureCapacity(self.code.items.len + 8); |
| 1353 | | switch (ty.abiSize(self.target.*)) { |
| 1355 | switch (abi_size) { |
| 1354 | 1356 | 1 => { |
| 1355 | 1357 | return self.fail(src, "TODO implement set abi_size=1 stack variable with immediate", .{}); |
| 1356 | 1358 | }, |
| ... | ... | @@ -1361,7 +1363,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1361 | 1363 | const x = @intCast(u32, x_big); |
| 1362 | 1364 | // We have a positive stack offset value but we want a twos complement negative |
| 1363 | 1365 | // offset from rbp, which is at the top of the stack frame. |
| 1364 | | const negative_offset = @intCast(i8, -@intCast(i32, stack_offset)); |
| 1366 | const negative_offset = @intCast(i8, -@intCast(i32, adj_off)); |
| 1365 | 1367 | const twos_comp = @bitCast(u8, negative_offset); |
| 1366 | 1368 | // mov DWORD PTR [rbp+offset], immediate |
| 1367 | 1369 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0xc7, 0x45, twos_comp }); |
| ... | ... | @@ -1382,19 +1384,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1382 | 1384 | return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); |
| 1383 | 1385 | }, |
| 1384 | 1386 | .register => |reg| { |
| 1387 | const abi_size = ty.abiSize(self.target.*); |
| 1388 | const adj_off = stack_offset + abi_size; |
| 1385 | 1389 | try self.code.ensureCapacity(self.code.items.len + 7); |
| 1386 | 1390 | self.rex(.{ .w = reg.size() == 64, .b = reg.isExtended() }); |
| 1387 | 1391 | const reg_id: u8 = @truncate(u3, reg.id()); |
| 1388 | | if (stack_offset <= 128) { |
| 1392 | if (adj_off <= 128) { |
| 1389 | 1393 | // example: 48 89 55 7f mov QWORD PTR [rbp+0x7f],rdx |
| 1390 | 1394 | const RM = @as(u8, 0b01_000_101) | (reg_id << 3); |
| 1391 | | const negative_offset = @intCast(i8, -@intCast(i32, stack_offset)); |
| 1395 | const negative_offset = @intCast(i8, -@intCast(i32, adj_off)); |
| 1392 | 1396 | const twos_comp = @bitCast(u8, negative_offset); |
| 1393 | 1397 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM, twos_comp }); |
| 1394 | | } else if (stack_offset <= 2147483648) { |
| 1398 | } else if (adj_off <= 2147483648) { |
| 1395 | 1399 | // example: 48 89 95 80 00 00 00 mov QWORD PTR [rbp+0x80],rdx |
| 1396 | 1400 | const RM = @as(u8, 0b10_000_101) | (reg_id << 3); |
| 1397 | | const negative_offset = @intCast(i32, -@intCast(i33, stack_offset)); |
| 1401 | const negative_offset = @intCast(i32, -@intCast(i33, adj_off)); |
| 1398 | 1402 | const twos_comp = @bitCast(u32, negative_offset); |
| 1399 | 1403 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM }); |
| 1400 | 1404 | mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp); |
| ... | ... | @@ -1605,8 +1609,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1605 | 1609 | } |
| 1606 | 1610 | } |
| 1607 | 1611 | }, |
| 1608 | | .stack_offset => |off| { |
| 1612 | .stack_offset => |unadjusted_off| { |
| 1609 | 1613 | try self.code.ensureCapacity(self.code.items.len + 7); |
| 1614 | const size_bytes = @divExact(reg.size(), 8); |
| 1615 | const off = unadjusted_off + size_bytes; |
| 1610 | 1616 | self.rex(.{ .w = reg.size() == 64, .r = reg.isExtended() }); |
| 1611 | 1617 | const reg_id: u8 = @truncate(u3, reg.id()); |
| 1612 | 1618 | if (off <= 128) { |