| ... | ... | @@ -2904,7 +2904,30 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: |
| 2904 | 2904 | |
| 2905 | 2905 | const offset = @intCast(u32, optional_ty.abiSize(self.target.*) - payload_ty.abiSize(self.target.*)); |
| 2906 | 2906 | switch (mcv) { |
| 2907 | | .register => return self.fail("TODO optionalPayload for registers", .{}), |
| 2907 | .register => |source_reg| { |
| 2908 | // TODO should we reuse the operand here? |
| 2909 | const raw_reg = try self.register_manager.allocReg(inst, gp); |
| 2910 | const dest_reg = raw_reg.toX(); |
| 2911 | |
| 2912 | const shift = @intCast(u6, offset * 8); |
| 2913 | if (shift == 0) { |
| 2914 | try self.genSetReg(payload_ty, dest_reg, mcv); |
| 2915 | } else { |
| 2916 | _ = try self.addInst(.{ |
| 2917 | .tag = if (payload_ty.isSignedInt()) |
| 2918 | Mir.Inst.Tag.asr_immediate |
| 2919 | else |
| 2920 | Mir.Inst.Tag.lsr_immediate, |
| 2921 | .data = .{ .rr_shift = .{ |
| 2922 | .rd = dest_reg, |
| 2923 | .rn = source_reg, |
| 2924 | .shift = shift, |
| 2925 | } }, |
| 2926 | }); |
| 2927 | } |
| 2928 | |
| 2929 | return MCValue{ .register = dest_reg }; |
| 2930 | }, |
| 2908 | 2931 | .stack_argument_offset => |off| { |
| 2909 | 2932 | return MCValue{ .stack_argument_offset = off + offset }; |
| 2910 | 2933 | }, |