-_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
-{
- jit_word_t w;
- w = beqi(_jit->pc.w, r2, 0);
- MOV(r1, r0);
- patch_at(w, _jit->pc.w);
-}
-
-static void
-_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
-{
- jit_word_t w;
- w = bnei(_jit->pc.w, r2, 0);
- MOV(r1, r0);
- patch_at(w, _jit->pc.w);
+_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
+ jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
+{
+ jit_word_t jump0, jump1, again, done;
+ jit_int32_t iscasi, r1_reg;
+ if ((iscasi = (r1 == _NOREG))) {
+ r1_reg = jit_get_reg(jit_class_gpr);
+ r1 = rn(r1_reg);
+ movi(r1, i0);
+ }
+ again = _jit->pc.w; /* AGAIN */
+ LDQ_L(r0, r1, 0); /* Load r0 locked */
+ jump0 = bner(0, r0, r2); /* bne FAIL r0 r2 */
+ movr(r0, r3); /* Move to r0 to attempt to store */
+ STQ_C(r0, r1, 0); /* r0 is an in/out argument */
+ jump1 = _jit->pc.w;
+ BEQ(r0, 0); /* beqi AGAIN r0 0 */
+ patch_at(jump1, again);
+ jump1 = _jit->pc.w;
+ BR(_R31_REGNO, 0); /* r0 set to 1 if store succeeded */
+ patch_at(jump0, _jit->pc.w); /* FAIL: */
+ movi(r0, 0); /* Already locked */
+ patch_at(jump1, _jit->pc.w);
+ if (iscasi)
+ jit_unget_reg(r1_reg);