aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-11-07 15:16:54 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-11-08 13:42:58 +0100
commita07449450f460dacd3ad4daa480e00c7bc9e9d7f (patch)
tree57a2c5ed921872ac5c88887bb21a8ab126a00d8b /src
parent35bd5363eed17270f1d3f96b8b1579126b12048a (diff)
downloadzig-a07449450f460dacd3ad4daa480e00c7bc9e9d7f.tar.gz
zig-a07449450f460dacd3ad4daa480e00c7bc9e9d7f.zip
aarch64: implement optionalPayload when mcv is register
Diffstat (limited to 'src')
-rw-r--r--src/arch/aarch64/CodeGen.zig25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig
index 0f34f4bbc6..29a01ae8b8 100644
--- a/src/arch/aarch64/CodeGen.zig
+++ b/src/arch/aarch64/CodeGen.zig
@@ -2904,7 +2904,30 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty:
const offset = @intCast(u32, optional_ty.abiSize(self.target.*) - payload_ty.abiSize(self.target.*));
switch (mcv) {
- .register => return self.fail("TODO optionalPayload for registers", .{}),
+ .register => |source_reg| {
+ // TODO should we reuse the operand here?
+ const raw_reg = try self.register_manager.allocReg(inst, gp);
+ const dest_reg = raw_reg.toX();
+
+ const shift = @intCast(u6, offset * 8);
+ if (shift == 0) {
+ try self.genSetReg(payload_ty, dest_reg, mcv);
+ } else {
+ _ = try self.addInst(.{
+ .tag = if (payload_ty.isSignedInt())
+ Mir.Inst.Tag.asr_immediate
+ else
+ Mir.Inst.Tag.lsr_immediate,
+ .data = .{ .rr_shift = .{
+ .rd = dest_reg,
+ .rn = source_reg,
+ .shift = shift,
+ } },
+ });
+ }
+
+ return MCValue{ .register = dest_reg };
+ },
.stack_argument_offset => |off| {
return MCValue{ .stack_argument_offset = off + offset };
},