aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-01-18 13:18:59 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-01-18 13:18:59 +0100
commit8c233687b4b0fdad725bf81b204dde7ccba45f56 (patch)
tree5974b7e548172ad118cf83fc703676aeb983aee7 /src
parentaaa641feba8866ac38f2d06a8db2a24fa134e2f5 (diff)
downloadzig-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.zig22
-rw-r--r--src/arch/x86_64/Emit.zig2
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);