+ if (c.r.rd == 31)
+ return;
+
+ if (c.r.rd == 30)
+ flags |= REG_EXT;
+
+ rt = lightrec_alloc_reg_in(reg_cache, _jit, c.r.rt, flags);
+
+ switch (c.r.rd) {
+ case 15:
+ tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
+ jit_ldxi_i(tmp, LIGHTREC_REG_STATE,
+ offsetof(struct lightrec_state, regs.cp2d[13]));
+
+ tmp2 = lightrec_alloc_reg_temp(reg_cache, _jit);
+ jit_ldxi_i(tmp2, LIGHTREC_REG_STATE,
+ offsetof(struct lightrec_state, regs.cp2d[14]));
+
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[12]),
+ LIGHTREC_REG_STATE, tmp);
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[13]),
+ LIGHTREC_REG_STATE, tmp2);
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[14]),
+ LIGHTREC_REG_STATE, rt);
+
+ lightrec_free_reg(reg_cache, tmp);
+ lightrec_free_reg(reg_cache, tmp2);
+ break;
+ case 28:
+ tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
+
+ jit_lshi(tmp, rt, 7);
+ jit_andi(tmp, tmp, 0xf80);
+ jit_stxi_s(offsetof(struct lightrec_state, regs.cp2d[9]),
+ LIGHTREC_REG_STATE, tmp);
+
+ jit_lshi(tmp, rt, 2);
+ jit_andi(tmp, tmp, 0xf80);
+ jit_stxi_s(offsetof(struct lightrec_state, regs.cp2d[10]),
+ LIGHTREC_REG_STATE, tmp);
+
+ jit_rshi(tmp, rt, 3);
+ jit_andi(tmp, tmp, 0xf80);
+ jit_stxi_s(offsetof(struct lightrec_state, regs.cp2d[11]),
+ LIGHTREC_REG_STATE, tmp);
+
+ lightrec_free_reg(reg_cache, tmp);
+ break;
+ case 30:
+ tmp = lightrec_alloc_reg_temp(reg_cache, _jit);
+ tmp2 = lightrec_alloc_reg_temp(reg_cache, _jit);
+
+ /* if (rt < 0) rt = ~rt; */
+ jit_rshi(tmp, rt, 31);
+ jit_xorr(tmp, rt, tmp);
+
+ /* We know the sign bit is 0. Left-shift by 1 to start the algorithm */
+ jit_lshi(tmp, tmp, 1);
+ jit_movi(tmp2, 33);
+
+ /* Decrement tmp2 and right-shift the value by 1 until it equals zero */
+ loop = jit_label();
+ jit_subi(tmp2, tmp2, 1);
+ jit_rshi_u(tmp, tmp, 1);
+ to_loop = jit_bnei(tmp, 0);
+
+ jit_patch_at(to_loop, loop);
+
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[31]),
+ LIGHTREC_REG_STATE, tmp2);
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[30]),
+ LIGHTREC_REG_STATE, rt);
+
+ lightrec_free_reg(reg_cache, tmp);
+ lightrec_free_reg(reg_cache, tmp2);
+ break;
+ default:
+ jit_stxi_i(offsetof(struct lightrec_state, regs.cp2d[c.r.rd]),
+ LIGHTREC_REG_STATE, rt);
+ break;
+ }