@@ -2113,7 +2113,7 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| dinsu CRET2, AT, 21, 21
|
||||
| slt AT, CARG1, r0
|
||||
| dsrlv CRET1, CRET2, TMP0
|
||||
| dsubu CARG1, r0, CRET1
|
||||
| negu CARG1, CRET1
|
||||
|.if MIPSR6
|
||||
| seleqz CRET1, CRET1, AT
|
||||
| selnez CARG1, CARG1, AT
|
||||
@@ -2121,20 +2121,12 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|.else
|
||||
| movn CRET1, CARG1, AT
|
||||
|.endif
|
||||
| li CARG1, 64
|
||||
| subu TMP0, CARG1, TMP0
|
||||
| negu TMP0, TMP0
|
||||
| dsllv CRET2, CRET2, TMP0 // Integer check.
|
||||
| sextw AT, CRET1
|
||||
| xor AT, CRET1, AT // Range check.
|
||||
|.if MIPSR6
|
||||
| seleqz AT, AT, CRET2
|
||||
| selnez CRET2, CRET2, CRET2
|
||||
| jr ra
|
||||
|. or CRET2, AT, CRET2
|
||||
|.else
|
||||
| jr ra
|
||||
|. movz CRET2, AT, CRET2
|
||||
|.endif
|
||||
|1:
|
||||
| jr ra
|
||||
|. li CRET2, 1
|
||||
@@ -2929,6 +2921,136 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| sfmin_max max, vm_sfcmpogt
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- Number conversion functions ----------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
|
||||
|// int64_t lj_vm_num2int_check(double x)
|
||||
|->vm_num2int_check:
|
||||
|.if FPU
|
||||
| trunc.w.d FARG2, FARG1
|
||||
| mfc1 CRET1, FARG2
|
||||
| cvt.d.w FARG2, FARG2
|
||||
|.if MIPSR6
|
||||
| cmp.eq.d FARG2, FARG1, FARG2
|
||||
| bc1eqz FARG2, >2
|
||||
|.else
|
||||
| c.eq.d FARG1, FARG2
|
||||
| bc1f 0, >2
|
||||
|.endif
|
||||
|. nop
|
||||
| jr ra
|
||||
|. zextw CRET1, CRET1
|
||||
|
|
||||
|.else
|
||||
|
|
||||
| dsll CRET2, CARG1, 1
|
||||
| beqz CRET2, >1
|
||||
|. li TMP0, 1076
|
||||
| dsrl AT, CRET2, 53
|
||||
| dsubu TMP0, TMP0, AT
|
||||
| sltiu AT, TMP0, 54
|
||||
| beqz AT, >2
|
||||
|. dextm CRET2, CRET2, 0, 20
|
||||
| dinsu CRET2, AT, 21, 21
|
||||
| slt AT, CARG1, r0
|
||||
| dsrlv CRET1, CRET2, TMP0
|
||||
| negu CARG1, CRET1
|
||||
|.if MIPSR6
|
||||
| seleqz CRET1, CRET1, AT
|
||||
| selnez CARG1, CARG1, AT
|
||||
| or CRET1, CRET1, CARG1
|
||||
|.else
|
||||
| movn CRET1, CARG1, AT
|
||||
|.endif
|
||||
| negu TMP0, TMP0
|
||||
| dsllv CRET2, CRET2, TMP0 // Integer check.
|
||||
| sextw AT, CRET1
|
||||
| xor AT, CRET1, AT // Range check.
|
||||
| or AT, AT, CRET2
|
||||
| bnez AT, >2
|
||||
|. nop
|
||||
| jr ra
|
||||
|. zextw CRET1, CRET1
|
||||
|1:
|
||||
| jr ra
|
||||
|. move CRET1, r0
|
||||
|.endif
|
||||
|2:
|
||||
| lui CRET1, 0x8000
|
||||
| dsll CRET1, CRET1, 16
|
||||
| ori CRET1, CRET1, 0x8000
|
||||
| jr ra
|
||||
|. dsll CRET1, CRET1, 16
|
||||
|
|
||||
|// int64_t lj_vm_num2i64(double x)
|
||||
|->vm_num2i64:
|
||||
|.if FPU
|
||||
| trunc.l.d FARG1, FARG1
|
||||
| jr ra
|
||||
|. dmfc1 CRET1, FARG1
|
||||
|.else
|
||||
|// fallthrough, same as lj_vm_num2u64 for soft-float.
|
||||
|.endif
|
||||
|
|
||||
|// uint64_t lj_vm_num2u64(double x)
|
||||
|->vm_num2u64:
|
||||
|.if FPU
|
||||
| trunc.l.d FARG2, FARG1
|
||||
| dmfc1 CRET1, FARG2
|
||||
| li AT, -1
|
||||
| dsrl AT, AT, 1
|
||||
| beq CRET1, AT, >1
|
||||
|. lui AT, 0xdf80 // -2^64 (float).
|
||||
| jr ra
|
||||
|. nop
|
||||
|1:
|
||||
| mtc1 AT, FARG2
|
||||
| cvt.d.s FARG2, FARG2
|
||||
| add.d FARG1, FARG1, FARG2
|
||||
| trunc.l.d FARG2, FARG1
|
||||
| jr ra
|
||||
|. dmfc1 CRET1, FARG2
|
||||
|
|
||||
|.else
|
||||
|
|
||||
| dextu CARG2, CARG1, 20, 10
|
||||
| addiu AT, CARG2, -1023
|
||||
| sltiu AT, AT, 116
|
||||
| beqz AT, >2 // Exponent out of range.
|
||||
|. addiu CARG2, CARG2, -1075
|
||||
| dextm CRET1, CARG1, 0, 19
|
||||
| dsll AT, AT, 52
|
||||
| dsra CARG1, CARG1, 63 // sign = 0 or -1.
|
||||
| bgez CARG2, >1 // Shift mantissa left or right?
|
||||
|. or CRET1, CRET1, AT // Merge leading 1 into masked mantissa.
|
||||
| subu CARG2, r0, CARG2
|
||||
| dsrlv CRET1, CRET1, CARG2 // Shift mantissa right for low exp.
|
||||
| daddu CRET1, CRET1, CARG1
|
||||
| jr ra
|
||||
|. xor CRET1, CRET1, CARG1 // m = sign?-m:m = (m+sign)^sign.
|
||||
|1:
|
||||
| dsllv CRET1, CRET1, CARG2 // Shift mantissa left for high exp.
|
||||
| daddu CRET1, CRET1, CARG1
|
||||
| jr ra
|
||||
|. xor CRET1, CRET1, CARG1 // m = sign?-m:m = (m+sign)^sign.
|
||||
|2:
|
||||
| jr ra
|
||||
|. move CRET1, r0
|
||||
|.endif
|
||||
|
|
||||
|// int32_t lj_vm_tobit(double x)
|
||||
|.if FPU
|
||||
|->vm_tobit:
|
||||
| lui AT, 0x59c0 // 2^52 + 2^51 (float).
|
||||
| mtc1 AT, FARG2
|
||||
| cvt.d.s FARG2, FARG2
|
||||
| add.d FARG1, FARG1, FARG2
|
||||
| mfc1 CRET1, FARG1
|
||||
| jr ra
|
||||
|. sextw CRET1, CRET1
|
||||
|.endif
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- Miscellaneous functions --------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user