浏览代码

x86/x64: Fix register allocation for variable shifts.

Mike Pall 14 年之前
父节点
当前提交
d4da9ff55e
共有 1 个文件被更改,包括 9 次插入7 次删除
  1. 9 7
      src/lj_asm_x86.h

+ 9 - 7
src/lj_asm_x86.h

@@ -1878,15 +1878,17 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs)
     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);