diff options
Diffstat (limited to 'src/buildvm_arm.dasc')
-rw-r--r-- | src/buildvm_arm.dasc | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index 2e87acdd..4d3ba5b7 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
@@ -1308,10 +1308,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1308 | | movmi CARG1, #0x80000000 | 1308 | | movmi CARG1, #0x80000000 |
1309 | | bmi <1 | 1309 | | bmi <1 |
1310 | |4: | 1310 | |4: |
1311 | | // NYI: Use internal implementation. | 1311 | | bl ->vm_..func |
1312 | | IOS mov RA, BASE | ||
1313 | | bl extern func | ||
1314 | | IOS mov BASE, RA | ||
1315 | | b ->fff_restv | 1312 | | b ->fff_restv |
1316 | |.endmacro | 1313 | |.endmacro |
1317 | | | 1314 | | |
@@ -2010,23 +2007,76 @@ static void build_subroutines(BuildCtx *ctx) | |||
2010 | |// double lj_vm_floor/ceil/trunc(double x); | 2007 | |// double lj_vm_floor/ceil/trunc(double x); |
2011 | |.macro vm_round, func | 2008 | |.macro vm_round, func |
2012 | |->vm_ .. func: | 2009 | |->vm_ .. func: |
2013 | | // NYI: Use internal implementation. | 2010 | | lsl CARG3, CARG2, #1 |
2014 | | b extern func | 2011 | | adds RB, CARG3, #0x00200000 |
2012 | | bpl >2 // |x| < 1? | ||
2013 | | mvn CARG4, #0x3cc | ||
2014 | | subs RB, CARG4, RB, asr #21 // 2^0: RB = 51, 2^51: RB = 0. | ||
2015 | | bxlo lr // |x| >= 2^52: done. | ||
2016 | | mvn CARG4, #1 | ||
2017 | | bic CARG3, CARG1, CARG4, lsl RB // ztest = lo & ~lomask | ||
2018 | | and CARG1, CARG1, CARG4, lsl RB // lo &= lomask | ||
2019 | | subs RB, RB, #32 | ||
2020 | | bicpl CARG4, CARG2, CARG4, lsl RB // |x| <= 2^20: ztest |= hi & ~himask | ||
2021 | | orrpl CARG3, CARG3, CARG4 | ||
2022 | | mvnpl CARG4, #1 | ||
2023 | | andpl CARG2, CARG2, CARG4, lsl RB // |x| <= 2^20: hi &= himask | ||
2024 | |.if "func" == "floor" | ||
2025 | | tst CARG3, CARG2, asr #31 // iszero = ((ztest & signmask) == 0) | ||
2026 | |.else | ||
2027 | | bics CARG3, CARG3, CARG2, asr #31 // iszero = ((ztest & ~signmask) == 0) | ||
2028 | |.endif | ||
2029 | | bxeq lr // iszero: done. | ||
2030 | | mvn CARG4, #1 | ||
2031 | | cmp RB, #0 | ||
2032 | | lslpl CARG3, CARG4, RB | ||
2033 | | mvnmi CARG3, #0 | ||
2034 | | add RB, RB, #32 | ||
2035 | | subs CARG1, CARG1, CARG4, lsl RB // lo = lo-lomask | ||
2036 | | sbc CARG2, CARG2, CARG3 // hi = hi-himask+carry | ||
2037 | | bx lr | ||
2038 | | | ||
2039 | |2: // |x| < 1: | ||
2040 | | orr CARG3, CARG3, CARG1 // ztest = (2*hi) | lo | ||
2041 | |.if "func" == "floor" | ||
2042 | | tst CARG3, CARG2, asr #31 // iszero = ((ztest & signmask) == 0) | ||
2043 | |.else | ||
2044 | | bics CARG3, CARG3, CARG2, asr #31 // iszero = ((ztest & ~signmask) == 0) | ||
2045 | |.endif | ||
2046 | | mov CARG1, #0 // lo = 0 | ||
2047 | | and CARG2, CARG2, #0x80000000 | ||
2048 | | ldrne CARG4, <9 // hi = sign(x) | (iszero ? 0.0 : 1.0) | ||
2049 | | orrne CARG2, CARG2, CARG4 | ||
2050 | | bx lr | ||
2015 | |.endmacro | 2051 | |.endmacro |
2016 | | | 2052 | | |
2053 | |9: | ||
2054 | | .long 0x3ff00000 // hiword(1.0) | ||
2017 | | vm_round floor | 2055 | | vm_round floor |
2018 | | vm_round ceil | 2056 | | vm_round ceil |
2019 | #if LJ_HASJIT | 2057 | | |
2020 | | vm_round trunc | ||
2021 | #else | ||
2022 | |->vm_trunc: | 2058 | |->vm_trunc: |
2059 | #if LJ_HASJIT | ||
2060 | | lsl CARG3, CARG2, #1 | ||
2061 | | adds RB, CARG3, #0x00200000 | ||
2062 | | andpl CARG2, CARG2, #0x80000000 // |x| < 1? hi = sign(x), lo = 0. | ||
2063 | | movpl CARG1, #0 | ||
2064 | | bxpl lr | ||
2065 | | mvn CARG4, #0x3cc | ||
2066 | | subs RB, CARG4, RB, asr #21 // 2^0: RB = 51, 2^51: RB = 0. | ||
2067 | | bxlo lr // |x| >= 2^52: already done. | ||
2068 | | mvn CARG4, #1 | ||
2069 | | and CARG1, CARG1, CARG4, lsl RB // lo &= lomask | ||
2070 | | subs RB, RB, #32 | ||
2071 | | andpl CARG2, CARG2, CARG4, lsl RB // |x| <= 2^20: hi &= himask | ||
2072 | | bx lr | ||
2023 | #endif | 2073 | #endif |
2024 | | | 2074 | | |
2025 | | // double lj_vm_mod(double dividend, double divisor); | 2075 | | // double lj_vm_mod(double dividend, double divisor); |
2026 | |->vm_mod: | 2076 | |->vm_mod: |
2027 | | push {r0, r1, r2, r3, r4, lr} | 2077 | | push {r0, r1, r2, r3, r4, lr} |
2028 | | bl extern __aeabi_ddiv | 2078 | | bl extern __aeabi_ddiv |
2029 | | bl extern floor // NYI: Use internal implementation of floor. | 2079 | | bl ->vm_floor |
2030 | | ldrd CARG34, [sp, #8] | 2080 | | ldrd CARG34, [sp, #8] |
2031 | | bl extern __aeabi_dmul | 2081 | | bl extern __aeabi_dmul |
2032 | | ldrd CARG34, [sp] | 2082 | | ldrd CARG34, [sp] |
@@ -2586,9 +2636,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
2586 | |5: // FP variant. | 2636 | |5: // FP variant. |
2587 | | ins_arithfallback ins_arithcheck_num | 2637 | | ins_arithfallback ins_arithcheck_num |
2588 | |.if "intins" == "vm_modi" | 2638 | |.if "intins" == "vm_modi" |
2589 | | IOS mov RC, BASE | ||
2590 | | bl fpcall | 2639 | | bl fpcall |
2591 | | IOS mov BASE, RC // NYI: remove once we use internal impl. of floor. | ||
2592 | |.else | 2640 | |.else |
2593 | | bl fpcall | 2641 | | bl fpcall |
2594 | | ins_next1 | 2642 | | ins_next1 |
@@ -3966,7 +4014,6 @@ static void emit_asm_debug(BuildCtx *ctx) | |||
3966 | fprintf(ctx->fp, | 4014 | fprintf(ctx->fp, |
3967 | "\t.align 2\n" | 4015 | "\t.align 2\n" |
3968 | ".LEFDE0:\n\n"); | 4016 | ".LEFDE0:\n\n"); |
3969 | /* NYI: emit ARM.exidx. */ | ||
3970 | break; | 4017 | break; |
3971 | default: | 4018 | default: |
3972 | break; | 4019 | break; |