MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / emit_atomic_cmpxchg

Method emit_atomic_cmpxchg

winch/codegen/src/codegen/mod.rs:2353–2392  ·  view source on GitHub ↗
(
        &mut self,
        arg: &MemArg,
        size: OperandSize,
        extend: Option<Extend<Zero>>,
    )

Source from the content-addressed store, hash-verified

2351 }
2352
2353 pub(crate) fn emit_atomic_cmpxchg(
2354 &mut self,
2355 arg: &MemArg,
2356 size: OperandSize,
2357 extend: Option<Extend<Zero>>,
2358 ) -> Result<()> {
2359 // At this point in the stack we have:
2360 // [ address, expected, replacement ]
2361 //
2362 // Therefore, emission for this instruction is a bit
2363 // trickier. The address for the CAS is the 3rd from the top
2364 // of the stack, and we must emit instruction to compute the
2365 // actual address with
2366 // `emit_compute_heap_address_align_checked`, while we still
2367 // have access to self. However, some ISAs have requirements
2368 // with regard to the registers used for some arguments, so we
2369 // need to pass the context to the masm. To solve this issue,
2370 // we pop the two first arguments from the stack, compute the
2371 // address, push back the arguments, and hand over the control
2372 // to masm. The implementer of `atomic_cas` can expect to find
2373 // `expected` and `replacement` at the top the context's
2374 // stack.
2375
2376 let replacement = self.context.pop_to_reg(self.masm, None)?;
2377 let expected = self.context.pop_to_reg(self.masm, None)?;
2378
2379 let memory_index = MemoryIndex::from_u32(arg.memory);
2380 let heap = self.env.resolve_heap(memory_index);
2381 if let Some(addr) = self.emit_compute_heap_address_align_checked(&heap, arg, size)? {
2382 self.context.stack.push(expected.into());
2383 self.context.stack.push(replacement.into());
2384
2385 let src = self.masm.address_at_reg(addr, 0)?;
2386 self.masm
2387 .atomic_cas(&mut self.context, src, size, UNTRUSTED_FLAGS, extend)?;
2388
2389 self.context.free_reg(addr);
2390 }
2391 Ok(())
2392 }
2393
2394 /// Emit the sequence of instruction for a `memory.atomic.wait*`.
2395 pub fn emit_atomic_wait(&mut self, arg: &MemArg, kind: AtomicWaitKind) -> Result<()> {

Calls 8

OkFunction · 0.85
pop_to_regMethod · 0.80
resolve_heapMethod · 0.80
free_regMethod · 0.80
pushMethod · 0.45
address_at_regMethod · 0.45
atomic_casMethod · 0.45

Tested by

no test coverage detected