diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-07 15:16:54 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-08 13:42:58 +0100 |
| commit | a07449450f460dacd3ad4daa480e00c7bc9e9d7f (patch) | |
| tree | 57a2c5ed921872ac5c88887bb21a8ab126a00d8b /src | |
| parent | 35bd5363eed17270f1d3f96b8b1579126b12048a (diff) | |
| download | zig-a07449450f460dacd3ad4daa480e00c7bc9e9d7f.tar.gz zig-a07449450f460dacd3ad4daa480e00c7bc9e9d7f.zip | |
aarch64: implement optionalPayload when mcv is register
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/aarch64/CodeGen.zig | 25 |
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 }; }, |
