From b123eb4c70e5c11bad167025556589a4ed869d42 Mon Sep 17 00:00:00 2001 From: Klaus Treichel Date: Sat, 29 Mar 2008 18:45:24 +0000 Subject: [PATCH] Fix signed division of a negative value by a positive power of two on x86. --- ChangeLog | 5 +++++ jit/jit-rules-x86.ins | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) 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")] -> { -- 2.47.3