From: Klaus Treichel Date: Sat, 29 Mar 2008 18:45:24 +0000 (+0000) Subject: Fix signed division of a negative value by a positive power of two on x86. X-Git-Tag: before.move.to.git~95 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=b123eb4c70e5c11bad167025556589a4ed869d42;p=francis%2Flibjit.git Fix signed division of a negative value by a positive power of two on x86. --- diff --git a/ChangeLog b/ChangeLog index 8d49d03..d082236 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-03-29 Klaus treichel + + * jit/jit-rules-x86.ins: Fix signed division of negative values by a + constant positive power of two. + 2008-03-29 Klaus Treichel * jit/jit-apply.c, tools/gen-apply.c: changes to apply needed for diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index 358155a..57fa4a0 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -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")] -> {