aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-16 23:29:57 +0200
committerMike Pall <mike>2011-04-16 23:29:57 +0200
commitadd553edd89e8e8472439d17b14c06c1d983ba6b (patch)
tree299eb6b6ee8587acd2486bbb5b3dbfe7c8819bc6 /src
parentd636a3decdf8dc503e707fad8b0e2745c0cabd21 (diff)
downloadluajit-add553edd89e8e8472439d17b14c06c1d983ba6b.tar.gz
luajit-add553edd89e8e8472439d17b14c06c1d983ba6b.tar.bz2
luajit-add553edd89e8e8472439d17b14c06c1d983ba6b.zip
ARM: Add integer variant of modulo operator.
Diffstat (limited to 'src')
-rw-r--r--src/buildvm_arm.dasc62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc
index c12b4da8..b0338702 100644
--- a/src/buildvm_arm.dasc
+++ b/src/buildvm_arm.dasc
@@ -1821,6 +1821,7 @@ static void build_subroutines(BuildCtx *ctx)
1821 |->vm_trunc: 1821 |->vm_trunc:
1822#endif 1822#endif
1823 | 1823 |
1824 | // double lj_vm_mod(double dividend, double divisor);
1824 |->vm_mod: 1825 |->vm_mod:
1825 | push {r0, r1, r2, r3, r4, lr} 1826 | push {r0, r1, r2, r3, r4, lr}
1826 | bl extern __aeabi_ddiv 1827 | bl extern __aeabi_ddiv
@@ -1833,6 +1834,41 @@ static void build_subroutines(BuildCtx *ctx)
1833 | add sp, sp, #20 1834 | add sp, sp, #20
1834 | pop {pc} 1835 | pop {pc}
1835 | 1836 |
1837 | // int lj_vm_modi(int dividend, int divisor);
1838 |->vm_modi:
1839 | ands RB, CARG1, #0x80000000
1840 | rsbmi CARG1, CARG1, #0 // a = |dividend|
1841 | eor RB, RB, CARG2, asr #1 // Keep signdiff and sign(divisor).
1842 | cmp CARG2, #0
1843 | rsbmi CARG2, CARG2, #0 // b = |divisor|
1844 | subs CARG4, CARG2, #1
1845 | cmpne CARG1, CARG2
1846 | moveq CARG1, #0 // if (b == 1 || a == b) a = 0
1847 | tsthi CARG2, CARG4
1848 | andeq CARG1, CARG1, CARG4 // else if ((b & (b-1)) == 0) a &= b-1
1849 | bls >1
1850 | // Use repeated subtraction to get the remainder.
1851 | clz CARG3, CARG1
1852 | clz CARG4, CARG2
1853 | sub CARG4, CARG4, CARG3
1854 | rsbs CARG3, CARG4, #31 // entry = (31-(clz(b)-clz(a)))*8
1855 | addne pc, pc, CARG3, lsl #3 // Duff's device.
1856 | nop
1857 {
1858 int i;
1859 for (i = 31; i >= 0; i--) {
1860 | cmp CARG1, CARG2, lsl #i
1861 | subhs CARG1, CARG1, CARG2, lsl #i
1862 }
1863 }
1864 |1:
1865 | cmp CARG1, #0
1866 | cmpne RB, #0
1867 | submi CARG1, CARG1, CARG2 // if (y != 0 && signdiff) y = y - b
1868 | eors CARG2, CARG1, RB, lsl #1
1869 | rsbmi CARG1, CARG1, #0 // if (sign(divisor) != sign(y)) y = -y
1870 | bx lr
1871 |
1836 |->vm_powi: 1872 |->vm_powi:
1837#if LJ_HASJIT 1873#if LJ_HASJIT
1838 | NYI 1874 | NYI
@@ -2266,33 +2302,42 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2266 | 2302 |
2267 |.macro ins_arithdn, intins, fpcall 2303 |.macro ins_arithdn, intins, fpcall
2268 | ins_arithpre 2304 | ins_arithpre
2305 |.if "intins" ~= "vm_modi"
2269 | ins_next1 2306 | ins_next1
2307 |.endif
2270 | ins_arithcheck_int >5 2308 | ins_arithcheck_int >5
2271 |.if "intins" == "smull" 2309 |.if "intins" == "smull"
2272 | smull CARG1, RC, CARG3, CARG1 2310 | smull CARG1, RC, CARG3, CARG1
2273 | cmp RC, CARG1, asr #31 2311 | cmp RC, CARG1, asr #31
2274 | ins_arithfallback bne 2312 | ins_arithfallback bne
2313 |.elif "intins" == "vm_modi"
2314 | movs CARG2, CARG3
2315 | ins_arithfallback beq
2316 | bl ->vm_modi
2317 | mvn CARG2, #~LJ_TISNUM
2275 |.else 2318 |.else
2276 | intins CARG1, CARG1, CARG3 2319 | intins CARG1, CARG1, CARG3
2277 | ins_arithfallback bvs 2320 | ins_arithfallback bvs
2278 |.endif 2321 |.endif
2279 |4: 2322 |4:
2323 |.if "intins" == "vm_modi"
2324 | ins_next1
2325 |.endif
2280 | ins_next2 2326 | ins_next2
2281 | strd CARG12, [BASE, RA] 2327 | strd CARG12, [BASE, RA]
2282 | ins_next3 2328 | ins_next3
2283 |5: // FP variant. 2329 |5: // FP variant.
2284 | ins_arithfallback ins_arithcheck_num 2330 | ins_arithfallback ins_arithcheck_num
2285 | bl fpcall 2331 | bl fpcall
2332 |.if "intins" ~= "vm_modi"
2286 | ins_next1 2333 | ins_next1
2334 |.endif
2287 | b <4 2335 | b <4
2288 |.endmacro 2336 |.endmacro
2289 | 2337 |
2290 |.macro ins_arithfp, fpcall 2338 |.macro ins_arithfp, fpcall
2291 | ins_arithpre 2339 | ins_arithpre
2292 | ins_arithfallback ins_arithcheck_num 2340 | ins_arithfallback ins_arithcheck_num
2293 ||if (op == BC_MODVN) {
2294 | ->BC_MODVN_Z:
2295 ||}
2296 | bl fpcall 2341 | bl fpcall
2297 | ins_next1 2342 | ins_next1
2298 | ins_next2 2343 | ins_next2
@@ -2312,15 +2357,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2312 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: 2357 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
2313 | ins_arithfp extern __aeabi_ddiv 2358 | ins_arithfp extern __aeabi_ddiv
2314 break; 2359 break;
2315 case BC_MODVN: 2360 case BC_MODVN: case BC_MODNV: case BC_MODVV:
2316 | // NYI: integer arithmetic. 2361 | ins_arithdn vm_modi, ->vm_mod
2317 | // Note: __aeabi_idivmod is unsuitable. It uses trunc, not floor.
2318 | ins_arithfp ->vm_mod
2319 break;
2320 case BC_MODNV: case BC_MODVV:
2321 | ins_arithpre
2322 | ins_arithfallback ins_arithcheck_num
2323 | b ->BC_MODVN_Z
2324 break; 2362 break;
2325 case BC_POW: 2363 case BC_POW:
2326 | // NYI: (partial) integer arithmetic. 2364 | // NYI: (partial) integer arithmetic.