+static void
+_movznr(jit_state_t *_jit, int ct, jit_int32_t r0,
+ jit_int32_t r1, jit_int32_t r2)
+{
+ if (jit_thumb_p()) {
+ if (r2 < 7)
+ T1_CMPI(r2, 0);
+ else
+ T2_CMPI(r2, 0);
+ IT(ct);
+ T1_MOV(r0, r1);
+ } else {
+ CMPI(r2, 0);
+ CC_MOV(ct, r0, r1);
+ }
+}
+
+static void
+_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ _movznr(_jit, ARM_CC_NE, r0, r1, r2);
+}
+
+static void
+_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+ _movznr(_jit, ARM_CC_EQ, r0, r1, r2);
+}
+
+static void
+_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_int32_t r1_reg, iscasi;
+ jit_word_t retry, done, jump0, jump1;
+ if (!jit_armv7_p())
+ fallback_casx(r0, r1, r2, r3, i0);
+ else {
+ if ((iscasi = (r1 == _NOREG))) {
+ r1_reg = jit_get_reg(jit_class_gpr);
+ r1 = rn(r1_reg);
+ movi(r1, i0);
+ }
+ if (jit_thumb_p()) {
+ T2_DMB(DMB_ISH);
+ /* retry: */
+ retry = _jit->pc.w;
+ T2_LDREX(r0, r1, 0);
+ eqr(r0, r0, r2);
+ jump0 = beqi(_jit->pc.w, r0, 0); /* beqi done r0 0 */
+ T2_STREX(r0, r3, r1, 0);
+ jump1 = bnei(_jit->pc.w, r0, 0); /* bnei retry r0 0 */
+ /* r0 = 0 if memory updated, 1 otherwise */
+ xori(r0, r0, 1);
+ /* done: */
+ done = _jit->pc.w;
+ T2_DMB(DMB_ISH);
+ }
+ else {
+ DMB(DMB_ISH);
+ /* retry: */
+ retry = _jit->pc.w;
+ LDREX(r0, r1);
+ eqr(r0, r0, r2);
+ jump0 = beqi(_jit->pc.w, r0, 0); /* beqi done r0 0 */
+ STREX(r0, r3, r1);
+ jump1 = bnei(_jit->pc.w, r0, 0); /* bnei retry r0 0 */
+ /* r0 = 0 if memory updated, 1 otherwise */
+ xori(r0, r0, 1);
+ /* done: */
+ done = _jit->pc.w;
+ DMB(DMB_ISH);
+ }
+ patch_at(arm_patch_jump, jump0, done);
+ patch_at(arm_patch_jump, jump1, retry);
+ if (iscasi)
+ jit_unget_reg(r1_reg);
+ }
+}
+