| ... | ... | @@ -1271,7 +1271,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1271 | 1271 | return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); |
| 1272 | 1272 | }, |
| 1273 | 1273 | .register => |reg| { |
| 1274 | | return self.fail(src, "TODO implement set stack variable from register", .{}); |
| 1274 | try self.code.ensureCapacity(self.code.items.len + 7); |
| 1275 | self.rex(.{ .w = reg.size() == 64, .b = reg.isExtended() }); |
| 1276 | const reg_id: u8 = @truncate(u3, reg.id()); |
| 1277 | if (stack_offset <= 128) { |
| 1278 | // example: 48 89 55 7f mov QWORD PTR [rbp+0x7f],rdx |
| 1279 | const RM = @as(u8, 0b01_101_000) | reg_id; |
| 1280 | const negative_offset = @intCast(i8, -@intCast(i32, stack_offset)); |
| 1281 | const twos_comp = @bitCast(u8, negative_offset); |
| 1282 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM, twos_comp }); |
| 1283 | } else if (stack_offset <= 2147483648) { |
| 1284 | // example: 48 89 95 80 00 00 00 mov QWORD PTR [rbp+0x80],rdx |
| 1285 | const RM = @as(u8, 0b10_101_000) | reg_id; |
| 1286 | const negative_offset = @intCast(i32, -@intCast(i33, stack_offset)); |
| 1287 | const twos_comp = @bitCast(u32, negative_offset); |
| 1288 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x89, RM }); |
| 1289 | mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp); |
| 1290 | } else { |
| 1291 | return self.fail(src, "stack offset too large", .{}); |
| 1292 | } |
| 1275 | 1293 | }, |
| 1276 | 1294 | .memory => |vaddr| { |
| 1277 | 1295 | return self.fail(src, "TODO implement set stack variable from memory vaddr", .{}); |
| ... | ... | @@ -1475,7 +1493,28 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1475 | 1493 | } |
| 1476 | 1494 | }, |
| 1477 | 1495 | .stack_offset => |off| { |
| 1478 | | return self.fail(src, "TODO implement genSetReg for stack variables", .{}); |
| 1496 | if (reg.size() != 64) { |
| 1497 | return self.fail(src, "TODO decide whether to implement non-64-bit loads", .{}); |
| 1498 | } |
| 1499 | try self.code.ensureCapacity(self.code.items.len + 7); |
| 1500 | self.rex(.{ .w = true, .r = reg.isExtended() }); |
| 1501 | const reg_id: u8 = @truncate(u3, reg.id()); |
| 1502 | if (off <= 128) { |
| 1503 | // Example: 48 8b 4d 7f mov rcx,QWORD PTR [rbp+0x7f] |
| 1504 | const RM = @as(u8, 0b01_000_101) | (reg_id << 3); |
| 1505 | const negative_offset = @intCast(i8, -@intCast(i32, off)); |
| 1506 | const twos_comp = @bitCast(u8, negative_offset); |
| 1507 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8b, RM, twos_comp }); |
| 1508 | } else if (off <= 2147483648) { |
| 1509 | // Example: 48 8b 8d 80 00 00 00 mov rcx,QWORD PTR [rbp+0x80] |
| 1510 | const RM = @as(u8, 0b10_000_101) | (reg_id << 3); |
| 1511 | const negative_offset = @intCast(i32, -@intCast(i33, off)); |
| 1512 | const twos_comp = @bitCast(u32, negative_offset); |
| 1513 | self.code.appendSliceAssumeCapacity(&[_]u8{ 0x8b, RM }); |
| 1514 | mem.writeIntLittle(u32, self.code.addManyAsArrayAssumeCapacity(4), twos_comp); |
| 1515 | } else { |
| 1516 | return self.fail(src, "stack offset too large", .{}); |
| 1517 | } |
| 1479 | 1518 | }, |
| 1480 | 1519 | }, |
| 1481 | 1520 | else => return self.fail(src, "TODO implement getSetReg for {}", .{self.target.cpu.arch}), |