aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_x86.h')
-rw-r--r--src/lj_asm_x86.h28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 512e0534..718cb12e 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -1956,7 +1956,7 @@ static void asm_bswap(ASMState *as, IRIns *ir)
1956#define asm_bor(as, ir) asm_intarith(as, ir, XOg_OR) 1956#define asm_bor(as, ir) asm_intarith(as, ir, XOg_OR)
1957#define asm_bxor(as, ir) asm_intarith(as, ir, XOg_XOR) 1957#define asm_bxor(as, ir) asm_intarith(as, ir, XOg_XOR)
1958 1958
1959static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs) 1959static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs, x86Op xv)
1960{ 1960{
1961 IRRef rref = ir->op2; 1961 IRRef rref = ir->op2;
1962 IRIns *irr = IR(rref); 1962 IRIns *irr = IR(rref);
@@ -1965,11 +1965,27 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs)
1965 int shift; 1965 int shift;
1966 dest = ra_dest(as, ir, RSET_GPR); 1966 dest = ra_dest(as, ir, RSET_GPR);
1967 shift = irr->i & (irt_is64(ir->t) ? 63 : 31); 1967 shift = irr->i & (irt_is64(ir->t) ? 63 : 31);
1968 if (!xv && shift && (as->flags & JIT_F_BMI2)) {
1969 Reg left = asm_fuseloadm(as, ir->op1, RSET_GPR, irt_is64(ir->t));
1970 if (left != dest) { /* BMI2 rotate right by constant. */
1971 emit_i8(as, xs == XOg_ROL ? -shift : shift);
1972 emit_mrm(as, VEX_64IR(ir, XV_RORX), dest, left);
1973 return;
1974 }
1975 }
1968 switch (shift) { 1976 switch (shift) {
1969 case 0: break; 1977 case 0: break;
1970 case 1: emit_rr(as, XO_SHIFT1, REX_64IR(ir, xs), dest); break; 1978 case 1: emit_rr(as, XO_SHIFT1, REX_64IR(ir, xs), dest); break;
1971 default: emit_shifti(as, REX_64IR(ir, xs), dest, shift); break; 1979 default: emit_shifti(as, REX_64IR(ir, xs), dest, shift); break;
1972 } 1980 }
1981 } else if ((as->flags & JIT_F_BMI2) && xv) { /* BMI2 variable shifts. */
1982 Reg left, right;
1983 dest = ra_dest(as, ir, RSET_GPR);
1984 right = ra_alloc1(as, rref, RSET_GPR);
1985 left = asm_fuseloadm(as, ir->op1, rset_exclude(RSET_GPR, right),
1986 irt_is64(ir->t));
1987 emit_mrm(as, VEX_64IR(ir, xv) ^ (right << 19), dest, left);
1988 return;
1973 } else { /* Variable shifts implicitly use register cl (i.e. ecx). */ 1989 } else { /* Variable shifts implicitly use register cl (i.e. ecx). */
1974 Reg right; 1990 Reg right;
1975 dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX)); 1991 dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX));
@@ -1995,11 +2011,11 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs)
1995 */ 2011 */
1996} 2012}
1997 2013
1998#define asm_bshl(as, ir) asm_bitshift(as, ir, XOg_SHL) 2014#define asm_bshl(as, ir) asm_bitshift(as, ir, XOg_SHL, XV_SHLX)
1999#define asm_bshr(as, ir) asm_bitshift(as, ir, XOg_SHR) 2015#define asm_bshr(as, ir) asm_bitshift(as, ir, XOg_SHR, XV_SHRX)
2000#define asm_bsar(as, ir) asm_bitshift(as, ir, XOg_SAR) 2016#define asm_bsar(as, ir) asm_bitshift(as, ir, XOg_SAR, XV_SARX)
2001#define asm_brol(as, ir) asm_bitshift(as, ir, XOg_ROL) 2017#define asm_brol(as, ir) asm_bitshift(as, ir, XOg_ROL, 0)
2002#define asm_bror(as, ir) asm_bitshift(as, ir, XOg_ROR) 2018#define asm_bror(as, ir) asm_bitshift(as, ir, XOg_ROR, 0)
2003 2019
2004/* -- Comparisons --------------------------------------------------------- */ 2020/* -- Comparisons --------------------------------------------------------- */
2005 2021