diff options
| author | Mike Pall <mike> | 2011-04-16 23:29:57 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-04-16 23:29:57 +0200 |
| commit | add553edd89e8e8472439d17b14c06c1d983ba6b (patch) | |
| tree | 299eb6b6ee8587acd2486bbb5b3dbfe7c8819bc6 /src | |
| parent | d636a3decdf8dc503e707fad8b0e2745c0cabd21 (diff) | |
| download | luajit-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.dasc | 62 |
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. |
