+ if (r0 != r1 && r0 != r2) {
+ rsbi(r0, r2, __WORDSIZE);
+ lrotr(r0, r1, r0);
+ }
+ else {
+ reg = jit_get_reg_but_zero(0);
+ rsbi(rn(reg), r2, __WORDSIZE);
+ lrotr(r0, r1, rn(reg));
+ jit_unget_reg(reg);
+ }
+}
+
+static void
+_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+#if CHECK_FLOGR
+ if (jit_cpu.flogr) {
+#endif
+ comr(r0, r1);
+ clzr(r0, r0);
+#if CHECK_FLOGR
+ }
+ else
+ fallback_clo(r0, r1);
+#endif
+}
+
+static void
+_clzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+#if CHECK_FLOGR
+ if (jit_cpu.flogr) {
+#endif
+#if __WORDSIZE == 32
+ jit_word_t w;
+#endif
+ jit_int32_t regno;
+ regno = jit_get_reg_pair();
+#if __WORDSIZE == 32
+ SLLG(rn(regno), r1, 32, 0);
+#else
+ movr(rn(regno), r1);
+#endif
+ FLOGR(rn(regno), rn(regno));
+ movr(r0, rn(regno));
+#if __WORDSIZE == 32
+ w = blei_p(_jit->pc.w, r0, 31);
+ rshi(r0, r0, 1); /* r0 is 64 */
+ patch_at(w, _jit->pc.w);
+#endif
+ jit_unget_reg_pair(regno);
+#if CHECK_FLOGR
+ }
+ else
+ fallback_clz(r0, r1);
+#endif
+}
+
+static void
+_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+#if CHECK_FLOGR
+ if (jit_cpu.flogr) {
+#endif
+ comr(r0, r1);
+ ctzr(r0, r0);
+#if CHECK_FLOGR
+ }
+ else
+ fallback_cto(r0, r1);
+#endif
+}
+
+static void
+_ctzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
+{
+ jit_int32_t t0, t1;
+#if CHECK_FLOGR
+ if (jit_cpu.flogr) {
+#endif
+ t0 = jit_get_reg_but_zero(0);
+ t1 = jit_get_reg_but_zero(0);
+ negr(rn(t0), r1);
+ andr(rn(t0), rn(t0), r1);
+ clzr(r0, rn(t0));
+ xori(rn(t1), r0, __WORDSIZE - 1);
+ movnr(r0, rn(t1), rn(t0));
+ jit_unget_reg(t0);
+ jit_unget_reg(t1);
+#if CHECK_FLOGR
+ }
+ else
+ fallback_ctz(r0, r1);
+#endif
+}
+
+static void
+_extr(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0, jit_word_t i1)
+{
+ assert(i0 >= 0 && i1 >= 1 && i0 + i1 <= __WORDSIZE);
+ /* Big Endian always */
+ i0 = __WORDSIZE - (i0 + i1);
+ if (i1 == __WORDSIZE)
+ movr(r0, r1);
+ else {
+ if (__WORDSIZE - (i0 + i1)) {
+ lshi(r0, r1, __WORDSIZE - (i0 + i1));
+ rshi(r0, r0, __WORDSIZE - i1);
+ }
+ else
+ rshi(r0, r1, __WORDSIZE - i1);
+ }
+}
+
+static void
+_extr_u(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0, jit_word_t i1)
+{
+ assert(i0 >= 0 && i1 >= 1 && i0 + i1 <= __WORDSIZE);
+ /* Big Endian always */
+ i0 = __WORDSIZE - (i0 + i1);
+ if (i1 == __WORDSIZE)
+ movr(r0, r1);
+ else {
+ if (i0)
+ rshi_u(r0, r1, i0);
+ andi(r0, r0, (1L << i1) - 1);
+ }
+}
+
+static void
+_depr(jit_state_t *_jit,
+ jit_int32_t r0, jit_int32_t r1, jit_word_t i0, jit_word_t i1)
+{
+ jit_int32_t t0;
+ jit_word_t mask;
+ /* Big Endian always */
+ i0 = __WORDSIZE - (i0 + i1);
+ if (i1 == __WORDSIZE)
+ movr(r0, r1);
+ else {
+ mask = (1L << i1) - 1;
+ t0 = jit_get_reg(jit_class_gpr);
+ andi(rn(t0), r1, mask);
+ if (i0) {
+ lshi(rn(t0), rn(t0), i0);
+ mask <<= i0;
+ }
+ andi(r0, r0, ~mask);
+ orr(r0, r0, rn(t0));
+ jit_unget_reg(t0);
+ }