mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
ARM: Add integer variant of modulo operator.
This commit is contained in:
parent
d636a3decd
commit
add553edd8
@ -1821,6 +1821,7 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|->vm_trunc:
|
||||
#endif
|
||||
|
|
||||
| // double lj_vm_mod(double dividend, double divisor);
|
||||
|->vm_mod:
|
||||
| push {r0, r1, r2, r3, r4, lr}
|
||||
| bl extern __aeabi_ddiv
|
||||
@ -1833,6 +1834,41 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| add sp, sp, #20
|
||||
| pop {pc}
|
||||
|
|
||||
| // int lj_vm_modi(int dividend, int divisor);
|
||||
|->vm_modi:
|
||||
| ands RB, CARG1, #0x80000000
|
||||
| rsbmi CARG1, CARG1, #0 // a = |dividend|
|
||||
| eor RB, RB, CARG2, asr #1 // Keep signdiff and sign(divisor).
|
||||
| cmp CARG2, #0
|
||||
| rsbmi CARG2, CARG2, #0 // b = |divisor|
|
||||
| subs CARG4, CARG2, #1
|
||||
| cmpne CARG1, CARG2
|
||||
| moveq CARG1, #0 // if (b == 1 || a == b) a = 0
|
||||
| tsthi CARG2, CARG4
|
||||
| andeq CARG1, CARG1, CARG4 // else if ((b & (b-1)) == 0) a &= b-1
|
||||
| bls >1
|
||||
| // Use repeated subtraction to get the remainder.
|
||||
| clz CARG3, CARG1
|
||||
| clz CARG4, CARG2
|
||||
| sub CARG4, CARG4, CARG3
|
||||
| rsbs CARG3, CARG4, #31 // entry = (31-(clz(b)-clz(a)))*8
|
||||
| addne pc, pc, CARG3, lsl #3 // Duff's device.
|
||||
| nop
|
||||
{
|
||||
int i;
|
||||
for (i = 31; i >= 0; i--) {
|
||||
| cmp CARG1, CARG2, lsl #i
|
||||
| subhs CARG1, CARG1, CARG2, lsl #i
|
||||
}
|
||||
}
|
||||
|1:
|
||||
| cmp CARG1, #0
|
||||
| cmpne RB, #0
|
||||
| submi CARG1, CARG1, CARG2 // if (y != 0 && signdiff) y = y - b
|
||||
| eors CARG2, CARG1, RB, lsl #1
|
||||
| rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
|
||||
| bx lr
|
||||
|
|
||||
|->vm_powi:
|
||||
#if LJ_HASJIT
|
||||
| NYI
|
||||
@ -2266,33 +2302,42 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
|
|
||||
|.macro ins_arithdn, intins, fpcall
|
||||
| ins_arithpre
|
||||
|.if "intins" ~= "vm_modi"
|
||||
| ins_next1
|
||||
|.endif
|
||||
| ins_arithcheck_int >5
|
||||
|.if "intins" == "smull"
|
||||
| smull CARG1, RC, CARG3, CARG1
|
||||
| cmp RC, CARG1, asr #31
|
||||
| ins_arithfallback bne
|
||||
|.elif "intins" == "vm_modi"
|
||||
| movs CARG2, CARG3
|
||||
| ins_arithfallback beq
|
||||
| bl ->vm_modi
|
||||
| mvn CARG2, #~LJ_TISNUM
|
||||
|.else
|
||||
| intins CARG1, CARG1, CARG3
|
||||
| ins_arithfallback bvs
|
||||
|.endif
|
||||
|4:
|
||||
|.if "intins" == "vm_modi"
|
||||
| ins_next1
|
||||
|.endif
|
||||
| ins_next2
|
||||
| strd CARG12, [BASE, RA]
|
||||
| ins_next3
|
||||
|5: // FP variant.
|
||||
| ins_arithfallback ins_arithcheck_num
|
||||
| bl fpcall
|
||||
|.if "intins" ~= "vm_modi"
|
||||
| ins_next1
|
||||
|.endif
|
||||
| b <4
|
||||
|.endmacro
|
||||
|
|
||||
|.macro ins_arithfp, fpcall
|
||||
| ins_arithpre
|
||||
| ins_arithfallback ins_arithcheck_num
|
||||
||if (op == BC_MODVN) {
|
||||
| ->BC_MODVN_Z:
|
||||
||}
|
||||
| bl fpcall
|
||||
| ins_next1
|
||||
| ins_next2
|
||||
@ -2312,15 +2357,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
|
||||
| ins_arithfp extern __aeabi_ddiv
|
||||
break;
|
||||
case BC_MODVN:
|
||||
| // NYI: integer arithmetic.
|
||||
| // Note: __aeabi_idivmod is unsuitable. It uses trunc, not floor.
|
||||
| ins_arithfp ->vm_mod
|
||||
break;
|
||||
case BC_MODNV: case BC_MODVV:
|
||||
| ins_arithpre
|
||||
| ins_arithfallback ins_arithcheck_num
|
||||
| b ->BC_MODVN_Z
|
||||
case BC_MODVN: case BC_MODNV: case BC_MODVV:
|
||||
| ins_arithdn vm_modi, ->vm_mod
|
||||
break;
|
||||
case BC_POW:
|
||||
| // NYI: (partial) integer arithmetic.
|
||||
|
Loading…
Reference in New Issue
Block a user