@@ -1384,6 +1384,39 @@ where
13841384
13851385 Ok ( ( ) )
13861386 }
1387+
1388+ pub ( crate ) fn emit_atomic_cmpxchg (
1389+ & mut self ,
1390+ arg : & MemArg ,
1391+ size : OperandSize ,
1392+ extend : Option < Extend < Zero > > ,
1393+ ) -> Result < ( ) > {
1394+ // Emission for this instruction is a bit trickier. The address for the CAS is the 3rd from
1395+ // the top of the stack, and we must emit instruction to compute the actual address with
1396+ // `emit_compute_heap_address_align_checked`, while we still have access to self. However,
1397+ // some ISAs have requirements with regard to the registers used for some arguments, so we
1398+ // need to pass the context to the masm. To solve this issue, we pop the two first
1399+ // arguments from the stack, compute the address, push back the arguments, and hand over
1400+ // the control to masm. The implementer of `atomic_cas` can expect to find `expected` and
1401+ // `replacement` at the top the context's stack.
1402+
1403+ // pop the args
1404+ let replacement = self . context . pop_to_reg ( self . masm , None ) ?;
1405+ let expected = self . context . pop_to_reg ( self . masm , None ) ?;
1406+
1407+ if let Some ( addr) = self . emit_compute_heap_address_align_checked ( arg, size) ? {
1408+ // push back the args
1409+ self . context . stack . push ( expected. into ( ) ) ;
1410+ self . context . stack . push ( replacement. into ( ) ) ;
1411+
1412+ let src = self . masm . address_at_reg ( addr, 0 ) ?;
1413+ self . masm
1414+ . atomic_cas ( & mut self . context , src, size, UNTRUSTED_FLAGS , extend) ?;
1415+
1416+ self . context . free_reg ( addr) ;
1417+ }
1418+ Ok ( ( ) )
1419+ }
13871420}
13881421
13891422/// Returns the index of the [`ControlStackFrame`] for the given
0 commit comments