diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-01-18 13:18:59 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-01-18 13:18:59 +0100 |
| commit | 8c233687b4b0fdad725bf81b204dde7ccba45f56 (patch) | |
| tree | 5974b7e548172ad118cf83fc703676aeb983aee7 /src | |
| parent | aaa641feba8866ac38f2d06a8db2a24fa134e2f5 (diff) | |
| download | zig-8c233687b4b0fdad725bf81b204dde7ccba45f56.tar.gz zig-8c233687b4b0fdad725bf81b204dde7ccba45f56.zip | |
stage2: partially implement intcast on x86_64
* fix violating encoding invariant for memory encoding
* enable some cast tests for x86_64 and arm
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 22 | ||||
| -rw-r--r-- | src/arch/x86_64/Emit.zig | 2 |
2 files changed, 20 insertions, 4 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 213e460588..5ae5fee6b0 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -877,10 +877,26 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { if (info_a.signedness != info_b.signedness) return self.fail("TODO gen intcast sign safety in semantic analysis", .{}); - if (info_a.bits == info_b.bits) - return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none }); + const operand_abi_size = operand_ty.abiSize(self.target.*); + const dest_ty = self.air.typeOfIndex(inst); + const dest_abi_size = dest_ty.abiSize(self.target.*); + const dst_mcv: MCValue = blk: { + if (info_a.bits == info_b.bits) { + break :blk operand; + } + if (operand_abi_size > 8 or dest_abi_size > 8) { + return self.fail("TODO implement intCast for abi sizes larger than 8", .{}); + } + const reg = switch (operand) { + .register => |src_reg| try self.register_manager.allocReg(inst, &.{src_reg}), + else => try self.register_manager.allocReg(inst, &.{}), + }; + try self.genSetReg(dest_ty, reg, .{ .immediate = 0 }); + try self.genSetReg(dest_ty, reg, operand); + break :blk .{ .register = registerAlias(reg, @intCast(u32, dest_abi_size)) }; + }; - return self.fail("TODO implement intCast for {}", .{self.target.cpu.arch}); + return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); } fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 39d0c33975..4ec80dd1ba 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -1320,7 +1320,7 @@ const Memory = struct { encoder.disp32(@bitCast(i32, mem_op.disp)); } } else { - if (mem_op.disp == 0) { + if (mem_op.disp == 0 and dst != 5) { encoder.modRm_indirectDisp0(src, dst); } else if (immOpSize(mem_op.disp) == 8) { encoder.modRm_indirectDisp8(src, dst); |
