diff --git a/tests/disas/winch/aarch64/call/multi.wat b/tests/disas/winch/aarch64/call/multi.wat index 6bc942e8b9bc..71ad407dd931 100644 --- a/tests/disas/winch/aarch64/call/multi.wat +++ b/tests/disas/winch/aarch64/call/multi.wat @@ -52,7 +52,7 @@ ;; mov sp, x28 ;; mov x1, x9 ;; mov x2, x9 -;; ldur x0, [x28, #0xc] +;; add x0, x28, #0xc ;; bl #0 ;; c0: add x28, x28, #0xc ;; mov sp, x28 diff --git a/winch/codegen/src/codegen/call.rs b/winch/codegen/src/codegen/call.rs index 8bb10be47435..4ff008b9232c 100644 --- a/winch/codegen/src/codegen/call.rs +++ b/winch/codegen/src/codegen/call.rs @@ -330,14 +330,14 @@ impl FnCall { match operand { &ABIOperand::Reg { ty, reg, .. } => { - masm.load_addr(addr, writable!(reg), ty.try_into()?)?; + masm.compute_addr(addr, writable!(reg), ty.try_into()?)?; } &ABIOperand::Stack { ty, offset, .. } => { let slot = masm.address_at_sp(SPOffset::from_u32(offset))?; // Don't rely on `ABI::scratch_for` as we always use // an int register as the return pointer. let scratch = scratch!(M); - masm.load_addr(addr, writable!(scratch), ty.try_into()?)?; + masm.compute_addr(addr, writable!(scratch), ty.try_into()?)?; masm.store(scratch.into(), slot, ty.try_into()?)?; } } diff --git a/winch/codegen/src/isa/aarch64/address.rs b/winch/codegen/src/isa/aarch64/address.rs index 9e888f9898e7..d3b3ed1a8cb4 100644 --- a/winch/codegen/src/isa/aarch64/address.rs +++ b/winch/codegen/src/isa/aarch64/address.rs @@ -83,6 +83,17 @@ impl Address { ); Self::Offset { base, offset } } + + /// Returns the register base and immediate offset of the given [`Address`]. + /// + /// # Panics + /// This function panics if the [`Address`] is not [`Address::Offset`]. + pub fn unwrap_offset(&self) -> (Reg, i64) { + match self { + Self::Offset { base, offset } => (*base, *offset), + _ => panic!("Expected register and offset addressing mode"), + } + } } // Conversions between `winch-codegen`'s addressing mode representation diff --git a/winch/codegen/src/isa/aarch64/masm.rs b/winch/codegen/src/isa/aarch64/masm.rs index ca22aed3661c..30cd8f509e69 100644 --- a/winch/codegen/src/isa/aarch64/masm.rs +++ b/winch/codegen/src/isa/aarch64/masm.rs @@ -315,8 +315,15 @@ impl Masm for MacroAssembler { }) } - fn load_addr(&mut self, src: Self::Address, dst: WritableReg, size: OperandSize) -> Result<()> { - self.asm.uload(src, dst, size, TRUSTED_FLAGS); + fn compute_addr( + &mut self, + src: Self::Address, + dst: WritableReg, + size: OperandSize, + ) -> Result<()> { + let (base, offset) = src.unwrap_offset(); + self.asm + .add_ir(u64::try_from(offset).unwrap(), base, dst, size); Ok(()) } diff --git a/winch/codegen/src/isa/x64/masm.rs b/winch/codegen/src/isa/x64/masm.rs index 0594aeed5ffe..0466e5bf3f45 100644 --- a/winch/codegen/src/isa/x64/masm.rs +++ b/winch/codegen/src/isa/x64/masm.rs @@ -328,7 +328,12 @@ impl Masm for MacroAssembler { self.load(src, dst, self.ptr_size) } - fn load_addr(&mut self, src: Self::Address, dst: WritableReg, size: OperandSize) -> Result<()> { + fn compute_addr( + &mut self, + src: Self::Address, + dst: WritableReg, + size: OperandSize, + ) -> Result<()> { self.asm.lea(&src, dst, size); Ok(()) } diff --git a/winch/codegen/src/masm.rs b/winch/codegen/src/masm.rs index f1a0d2a8a17f..d16429aa9567 100644 --- a/winch/codegen/src/masm.rs +++ b/winch/codegen/src/masm.rs @@ -1442,8 +1442,9 @@ pub(crate) trait MacroAssembler { /// to the pointer size of the target. fn load_ptr(&mut self, src: Self::Address, dst: WritableReg) -> Result<()>; - /// Loads the effective address into destination. - fn load_addr( + /// Computes the effective address and stores the result in the destination + /// register. + fn compute_addr( &mut self, _src: Self::Address, _dst: WritableReg,