diff options
| author | Mike Pall <mike> | 2025-11-27 17:45:17 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2025-11-27 17:45:17 +0100 |
| commit | f80b349d5490aa289b2925d297f3f3c618977570 (patch) | |
| tree | 8d8fb0d2beb3e863592139d603ada63e5aa6ce77 /src/vm_mips.dasc | |
| parent | 3215838aa744d148e79a8ea0bd7c014e984302cb (diff) | |
| download | luajit-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.dasc | 119 |
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 | | |
