]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
arm fixes
authorAleksey Demakov <ademakov@gmail.com>
Wed, 25 Mar 2009 17:33:48 +0000 (17:33 +0000)
committerAleksey Demakov <ademakov@gmail.com>
Wed, 25 Mar 2009 17:33:48 +0000 (17:33 +0000)
ChangeLog
jit/jit-gen-arm.h
jit/jit-rules-arm.ins

index 259ec645d9ebb1e574aff61e780b44688c24aa16..bdff4fd074aee084d7b969d9a926bfa8982ef48a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-25  Michele Tartara  <mikyt@users.sourceforge.net>
+
+       * jit/jit-gen-arm.h (arm_alu_cc_reg): fix a typo.
+       * jit/jit-rules-arm.ins (JIT_OP_IDIV): support negative dividends.
+
 2009-03-24  Aleksey Demakov  <ademakov@gmail.com>
 
        * jit/jit-rules.h (jit_reg_other_reg): add macro.
index 88bcfd32992ee157c131f15a48487a6793b65d39..754911b05b75f918d9a9fd04d6246a7a6f0d343c 100644 (file)
@@ -421,7 +421,7 @@ extern void _arm_alu_reg_imm
                        } while (0)
 #define arm_alu_cc_reg(inst,opc,dreg,sreg)     \
                        do { \
-                               arm_inst_add((inst), arm_execute_cc | \
+                               arm_inst_add((inst), arm_execute_cc | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                         ((unsigned int)(sreg))); \
index 145e83461d5cf33582adc39ec29175762a2ddb4d..b676352fcb67eae6772a025a5822c11d9f24e80c 100644 (file)
@@ -189,8 +189,16 @@ JIT_OP_IDIV:
        [reg, immu8, if("$2 == 1")] -> {
                /* Division by 1. Return the value itself */
        }
-       [reg, immu8, if("($2 % 2) == 0")] -> {
-               /* Handle special cases of small immediate divides */
+       [reg, immu8, if("($2 > 0) && (((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> {
+               /* Handle special cases of small immediate divides: divisions by positive powers of two */
+               /* NB: (n & (n-1)) == 0 if and only if n is a power of 2 */
+               
+               /* Move the dividend in the work register, setting the codes (in order to know if it's positive or negative) */
+               arm_alu_cc_reg(inst, ARM_MOV, ARM_WORK, $1);
+
+               /* If the dividend is negative, make it positive (0-x = -x)*/
+               arm_alu_reg_imm8_cond(inst, ARM_RSB, $1, ARM_WORK, 0, ARM_CC_MI);
+
                switch($2)
                {
                        //Integer divide by shifting
@@ -236,6 +244,10 @@ JIT_OP_IDIV:
                        }
                        break;
                }
+               
+               /* If the dividend was negative, make it negative again (0-x = -x)*/
+               arm_alu_reg_imm8_cond(inst, ARM_RSB, $1, $1, 0, ARM_CC_MI);
+               
        }
        [reg, imm, if("$2 == -1")] -> {
                /* Dividing by -1 simply negates */