aboutsummaryrefslogtreecommitdiff
path: root/src/vm_mips.dasc
diff options
context:
space:
mode:
authorMike Pall <mike>2025-11-27 17:45:17 +0100
committerMike Pall <mike>2025-11-27 17:45:17 +0100
commitf80b349d5490aa289b2925d297f3f3c618977570 (patch)
tree8d8fb0d2beb3e863592139d603ada63e5aa6ce77 /src/vm_mips.dasc
parent3215838aa744d148e79a8ea0bd7c014e984302cb (diff)
downloadluajit-f80b349d5490aa289b2925d297f3f3c618977570.tar.gz
luajit-f80b349d5490aa289b2925d297f3f3c618977570.tar.bz2
luajit-f80b349d5490aa289b2925d297f3f3c618977570.zip
Unify Lua number to FFI integer conversions.
Phew. #1411
Diffstat (limited to 'src/vm_mips.dasc')
-rw-r--r--src/vm_mips.dasc119
1 files changed, 118 insertions, 1 deletions
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index 02e588ee..8a6b8270 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -85,6 +85,7 @@
85| 85|
86|.if FPU 86|.if FPU
87|.define FARG1, f12 87|.define FARG1, f12
88|.define FARG1HI, f13
88|.define FARG2, f14 89|.define FARG2, f14
89| 90|
90|.define FRET1, f0 91|.define FRET1, f0
@@ -2560,7 +2561,7 @@ static void build_subroutines(BuildCtx *ctx)
2560 | mtc1 r0, f4 2561 | mtc1 r0, f4
2561 | mtc1 TMP0, f5 2562 | mtc1 TMP0, f5
2562 | abs.d FRET2, FARG1 // |x| 2563 | abs.d FRET2, FARG1 // |x|
2563 | mfc1 AT, f13 2564 | mfc1 AT, FARG1HI
2564 | c.olt.d 0, FRET2, f4 2565 | c.olt.d 0, FRET2, f4
2565 | add.d FRET1, FRET2, f4 // (|x| + 2^52) - 2^52 2566 | add.d FRET1, FRET2, f4 // (|x| + 2^52) - 2^52
2566 | bc1f 0, >1 // Truncate only if |x| < 2^52. 2567 | bc1f 0, >1 // Truncate only if |x| < 2^52.
@@ -2822,6 +2823,122 @@ static void build_subroutines(BuildCtx *ctx)
2822 | sfmin_max max, vm_sfcmpogt 2823 | sfmin_max max, vm_sfcmpogt
2823 | 2824 |
2824 |//----------------------------------------------------------------------- 2825 |//-----------------------------------------------------------------------
2826 |//-- Number conversion functions ----------------------------------------
2827 |//-----------------------------------------------------------------------
2828 |
2829 |// int64_t lj_vm_num2int_check(double x)
2830 |->vm_num2int_check:
2831 |.if FPU
2832 | trunc.w.d FARG2, FARG1
2833 | mfc1 SFRETLO, FARG2
2834 | cvt.d.w FARG2, FARG2
2835 | c.eq.d FARG1, FARG2
2836 | bc1f 0, >2
2837 |. nop
2838 | jr ra
2839 |. move SFRETHI, r0
2840 |
2841 |.else
2842 |
2843 | sll SFRETLO, SFARG1HI, 1
2844 | or SFRETHI, SFRETLO, SFARG1LO
2845 | beqz SFRETHI, >1 // Return 0 for +-0.
2846 |. li TMP0, 1054
2847 | srl AT, SFRETLO, 21
2848 | subu TMP0, TMP0, AT
2849 | sltiu AT, TMP0, 32
2850 | beqz AT, >2 // Fail if |x| < 0x1p0 || |x| >= 0x1p32.
2851 |. sll SFRETLO, SFARG1HI, 11
2852 | srl SFRETHI, SFARG1LO, 21
2853 | negu TMP1, TMP0
2854 | or SFRETLO, SFRETLO, SFRETHI // Left-aligned mantissa.
2855 | sllv TMP2, SFRETLO, TMP1
2856 | lui AT, 0x8000
2857 | sll SFRETHI, SFARG1LO, 11
2858 | or SFRETLO, SFRETLO, AT // Merge leading 1.
2859 | or TMP2, TMP2, SFRETHI
2860 | srlv SFRETLO, SFRETLO, TMP0 // lo = right-aligned absolute value.
2861 | bnez TMP2, >2 // Fail if fractional part != 0.
2862 |. sra SFARG1HI, SFARG1HI, 31 // sign = 0 or -1.
2863 | addu SFRETLO, SFRETLO, SFARG1HI
2864 | bltz SFRETLO, >2 // Fail if lo+sign >= 0x80000000.
2865 |. xor SFRETLO, SFRETLO, SFARG1HI // lo = sign?-lo:lo = (lo+sign)^sign.
2866 |1:
2867 | jr ra
2868 |. move SFRETHI, r0
2869 |.endif
2870 |2: // Not an integer, return 0x8000000080000000LL.
2871 | lui SFRETHI, 0x8000
2872 | jr ra
2873 |. lui SFRETLO, 0x8000
2874 |
2875 |// int64_t lj_vm_num2i64(double x)
2876 |->vm_num2i64:
2877 |// fallthrough, same as lj_vm_num2u64.
2878 |
2879 |// uint64_t lj_vm_num2u64(double x)
2880 |->vm_num2u64:
2881 |.if FPU
2882 | mfc1 SFARG1HI, FARG1HI
2883 | mfc1 SFARG1LO, FARG1
2884 |.endif
2885 | srl TMP0, SFARG1HI, 20
2886 | andi TMP0, TMP0, 0x7ff
2887 | addiu SFRETLO, TMP0, -1023
2888 | sltiu SFRETLO, SFRETLO, 116
2889 | beqz SFRETLO, >3 // Exponent out of range.
2890 |. sll SFRETHI, SFARG1HI, 12
2891 | lui AT, 0x0010
2892 | srl SFRETHI, SFRETHI, 12
2893 | addiu TMP0, TMP0, -1075
2894 | sra SFARG1HI, SFARG1HI, 31 // sign = 0 or -1.
2895 | bgez TMP0, >2 // Shift mantissa left or right?
2896 |. or SFRETHI, SFRETHI, AT // Merge leading 1 into masked mantissa.
2897 | subu TMP1, r0, TMP0
2898 | sll AT, SFRETHI, 1
2899 | nor TMP0, r0, TMP1
2900 | srlv SFRETHI, SFRETHI, TMP1 // Shift hi mantissa right for low exp.
2901 | sllv AT, AT, TMP0 // Shifted-out hi mantissa.
2902 | srlv SFRETLO, SFARG1LO, TMP1 // Shift lo mantissa right for low exp.
2903 | andi TMP1, TMP1, 0x20 // Conditional right shift by 32.
2904 | or AT, AT, SFRETLO // Merge into lo mantissa.
2905 | movn AT, SFRETHI, TMP1
2906 | movn SFRETHI, r0, TMP1
2907 |1:
2908 | addu SFRETLO, AT, SFARG1HI // m = sign?-m:m = (m+sign)^sign.
2909 | addu SFRETHI, SFRETHI, SFARG1HI
2910 | sltu TMP0, SFRETLO, AT // Carry
2911 | addu SFRETHI, SFRETHI, TMP0
2912 | xor SFRETLO, SFRETLO, SFARG1HI
2913 | jr ra
2914 |. xor SFRETHI, SFRETHI, SFARG1HI
2915 |2:
2916 | srl TMP2, SFARG1LO, 1
2917 | nor AT, r0, TMP0
2918 | sllv SFRETHI, SFRETHI, TMP0 // Shift hi mantissa left for high exp.
2919 | srlv TMP2, TMP2, AT // Shifted-out lo mantissa.
2920 | sllv AT, SFARG1LO, TMP0 // Shift lo mantissa left for high exp.
2921 | andi TMP0, TMP0, 0x20 // Conditional left shift by 32.
2922 | or SFRETHI, SFRETHI, TMP2 // Merge into hi mantissa.
2923 | movn SFRETHI, AT, TMP0
2924 | b <1
2925 |. movn AT, r0, TMP0
2926 |3:
2927 | jr ra
2928 |. li SFRETHI, 0
2929 |
2930 |// int32_t lj_vm_tobit(double x)
2931 |.if FPU
2932 |->vm_tobit:
2933 | lui AT, 0x59c0 // 2^52 + 2^51 (float).
2934 | mtc1 AT, FARG2
2935 | cvt.d.s FARG2, FARG2
2936 | add.d FARG1, FARG1, FARG2
2937 | jr ra
2938 |. mfc1 CRET1, FARG1
2939 |.endif
2940 |
2941 |//-----------------------------------------------------------------------
2825 |//-- Miscellaneous functions -------------------------------------------- 2942 |//-- Miscellaneous functions --------------------------------------------
2826 |//----------------------------------------------------------------------- 2943 |//-----------------------------------------------------------------------
2827 | 2944 |