(
&mut self,
arg: &MemArg,
op: RmwOp,
size: OperandSize,
extend: Option<Extend<Zero>>,
)
| 2327 | } |
| 2328 | |
| 2329 | pub(crate) fn emit_atomic_rmw( |
| 2330 | &mut self, |
| 2331 | arg: &MemArg, |
| 2332 | op: RmwOp, |
| 2333 | size: OperandSize, |
| 2334 | extend: Option<Extend<Zero>>, |
| 2335 | ) -> Result<()> { |
| 2336 | let memory_index = MemoryIndex::from_u32(arg.memory); |
| 2337 | let heap = self.env.resolve_heap(memory_index); |
| 2338 | // We need to pop-push the operand to compute the address before passing control over to |
| 2339 | // masm, because some architectures may have specific requirements for the registers used |
| 2340 | // in some atomic operations. |
| 2341 | let operand = self.context.pop_to_reg(self.masm, None)?; |
| 2342 | if let Some(addr) = self.emit_compute_heap_address_align_checked(&heap, arg, size)? { |
| 2343 | let src = self.masm.address_at_reg(addr, 0)?; |
| 2344 | self.context.stack.push(operand.into()); |
| 2345 | self.masm |
| 2346 | .atomic_rmw(&mut self.context, src, size, op, UNTRUSTED_FLAGS, extend)?; |
| 2347 | self.context.free_reg(addr); |
| 2348 | } |
| 2349 | |
| 2350 | Ok(()) |
| 2351 | } |
| 2352 | |
| 2353 | pub(crate) fn emit_atomic_cmpxchg( |
| 2354 | &mut self, |
no test coverage detected