aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-03-24 17:01:00 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-03-24 17:02:29 +0100
commit608025456b164aae69c7e794b1419e6b03a5cb79 (patch)
treef311619d456863565ca26b43442b465295b72b66 /src
parent9d2ff7ed161ff0880818002fb75391be336b44ac (diff)
downloadzig-608025456b164aae69c7e794b1419e6b03a5cb79.tar.gz
zig-608025456b164aae69c7e794b1419e6b03a5cb79.zip
x64: account for signed ints in struct_field_val when struct fits in a register
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/CodeGen.zig16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index fe59cd6c63..fa83884329 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -2899,6 +2899,22 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });
try self.genBinMathOpMir(.@"and", Type.usize, dst_mcv, .{ .register = tmp_reg });
+ const signedness: std.builtin.Signedness = blk: {
+ if (struct_field_ty.zigTypeTag() != .Int) break :blk .unsigned;
+ break :blk struct_field_ty.intInfo(self.target.*).signedness;
+ };
+ const field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
+ if (signedness == .signed and field_size < 8) {
+ _ = try self.addInst(.{
+ .tag = .mov_sign_extend,
+ .ops = (Mir.Ops{
+ .reg1 = dst_mcv.register,
+ .reg2 = registerAlias(dst_mcv.register, field_size),
+ }).encode(),
+ .data = undefined,
+ });
+ }
+
break :result dst_mcv;
},
else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}),