|
|
@ -584,13 +584,26 @@ JIT_OP_IDIV: more_space |
|
|
|
x86_patch(patch, inst); |
|
|
|
x86_neg_reg(inst, $1); |
|
|
|
} |
|
|
|
[reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> { |
|
|
|
[reg, imm, scratch reg, if("$2 == 2")] -> { |
|
|
|
x86_mov_reg_reg(inst, $3, $1, 4); |
|
|
|
x86_shift_reg_imm(inst, X86_SHR, $3, 0x1f); |
|
|
|
x86_alu_reg_reg(inst, X86_ADD, $1, $3); |
|
|
|
x86_shift_reg_imm(inst, X86_SAR, $1, 1); |
|
|
|
} |
|
|
|
[reg, imm, scratch reg, if("($2 > 0) && (((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> { |
|
|
|
/* x & (x - 1) is equal to zero if x is a power of 2 */ |
|
|
|
jit_nuint shift, value = $2 >> 1; |
|
|
|
/* This code is generated by gcc for pentium. */ |
|
|
|
/* We use this code because cmov is not available on all i386 cpus */ |
|
|
|
jit_nuint shift, temp, value = $2 >> 1; |
|
|
|
for(shift = 0; value; value >>= 1) |
|
|
|
{ |
|
|
|
++shift; |
|
|
|
} |
|
|
|
temp = 32 - shift; |
|
|
|
x86_mov_reg_reg(inst, $3, $1, 4); |
|
|
|
x86_shift_reg_imm(inst, X86_SAR, $3, 0x1f); |
|
|
|
x86_shift_reg_imm(inst, X86_SHR, $3, temp); |
|
|
|
x86_alu_reg_reg(inst, X86_ADD, $1, $3); |
|
|
|
x86_shift_reg_imm(inst, X86_SAR, $1, shift); |
|
|
|
} |
|
|
|
[reg("eax"), imm, scratch reg, scratch reg("edx")] -> { |
|
|
|