default: emit_shifti(as, REX_64IR(ir, xs), dest, shift); break;
}
} else { /* Variable shifts implicitly use register cl (i.e. ecx). */
- RegSet allow = rset_exclude(RSET_GPR, RID_ECX);
- Reg right = irr->r;
- if (ra_noreg(right)) {
+ Reg right;
+ dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX));
+ if (dest == RID_ECX) {
+ dest = ra_scratch(as, rset_exclude(RSET_GPR, RID_ECX));
+ emit_rr(as, XO_MOV, RID_ECX, dest);
+ }
+ right = irr->r;
+ if (ra_noreg(right))
right = ra_allocref(as, rref, RID2RSET(RID_ECX));
- } else if (right != RID_ECX) {
- rset_clear(allow, right);
+ else if (right != RID_ECX)
ra_scratch(as, RID2RSET(RID_ECX));
- }
- dest = ra_dest(as, ir, allow);
emit_rr(as, XO_SHIFTcl, REX_64IR(ir, xs), dest);
if (right != RID_ECX) {
ra_noweak(as, right);