+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.
} 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))); \
[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
}
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 */