Inline-Lua
view release on metacpan or search on metacpan
ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/vm_mips.dasc view on Meta::CPAN
|
|->vm_floor:
| vm_round floor
|->vm_ceil:
| vm_round ceil
|->vm_trunc:
|.if JIT
| vm_round trunc
|.endif
|
|// Soft-float integer to number conversion.
|.macro sfi2d, AHI, ALO
|.if not FPU
| beqz ALO, >9 // Handle zero first.
|. sra TMP0, ALO, 31
| xor TMP1, ALO, TMP0
| subu TMP1, TMP1, TMP0 // Absolute value in TMP1.
| clz AHI, TMP1
| andi TMP0, TMP0, 0x800 // Mask sign bit.
| li AT, 0x3ff+31-1
| sllv TMP1, TMP1, AHI // Align mantissa left with leading 1.
| subu AHI, AT, AHI // Exponent - 1 in AHI.
| sll ALO, TMP1, 21
| or AHI, AHI, TMP0 // Sign | Exponent.
| srl TMP1, TMP1, 11
| sll AHI, AHI, 20 // Align left.
| jr ra
|. addu AHI, AHI, TMP1 // Add mantissa, increment exponent.
|9:
| jr ra
|. li AHI, 0
|.endif
|.endmacro
|
|// Input SFARG1LO. Output: SFARG1*. Temporaries: AT, TMP0, TMP1.
|->vm_sfi2d_1:
| sfi2d SFARG1HI, SFARG1LO
|
|// Input SFARG2LO. Output: SFARG2*. Temporaries: AT, TMP0, TMP1.
|->vm_sfi2d_2:
| sfi2d SFARG2HI, SFARG2LO
|
|// Soft-float comparison. Equivalent to c.eq.d.
|// Input: SFARG*. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|->vm_sfcmpeq:
|.if not FPU
| sll AT, SFARG1HI, 1
| sll TMP0, SFARG2HI, 1
| or CRET1, SFARG1LO, SFARG2LO
| or TMP1, AT, TMP0
| or TMP1, TMP1, CRET1
| beqz TMP1, >8 // Both args +-0: return 1.
|. sltu CRET1, r0, SFARG1LO
| lui TMP1, 0xffe0
| addu AT, AT, CRET1
| sltu CRET1, r0, SFARG2LO
| sltu AT, TMP1, AT
| addu TMP0, TMP0, CRET1
| sltu TMP0, TMP1, TMP0
| or TMP1, AT, TMP0
| bnez TMP1, >9 // Either arg is NaN: return 0;
|. xor TMP0, SFARG1HI, SFARG2HI
| xor TMP1, SFARG1LO, SFARG2LO
| or AT, TMP0, TMP1
| jr ra
|. sltiu CRET1, AT, 1 // Same values: return 1.
|8:
| jr ra
|. li CRET1, 1
|9:
| jr ra
|. li CRET1, 0
|.endif
|
|// Soft-float comparison. Equivalent to c.ult.d and c.olt.d.
|// Input: SFARG*. Output: CRET1. Temporaries: AT, TMP0, TMP1, CRET2.
|->vm_sfcmpult:
|.if not FPU
| b >1
|. li CRET2, 1
|.endif
|
|->vm_sfcmpolt:
|.if not FPU
| li CRET2, 0
|1:
| sll AT, SFARG1HI, 1
| sll TMP0, SFARG2HI, 1
| or CRET1, SFARG1LO, SFARG2LO
| or TMP1, AT, TMP0
| or TMP1, TMP1, CRET1
| beqz TMP1, >8 // Both args +-0: return 0.
|. sltu CRET1, r0, SFARG1LO
| lui TMP1, 0xffe0
| addu AT, AT, CRET1
| sltu CRET1, r0, SFARG2LO
| sltu AT, TMP1, AT
| addu TMP0, TMP0, CRET1
| sltu TMP0, TMP1, TMP0
| or TMP1, AT, TMP0
| bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
|. and AT, SFARG1HI, SFARG2HI
| bltz AT, >5 // Both args negative?
|. nop
| beq SFARG1HI, SFARG2HI, >8
|. sltu CRET1, SFARG1LO, SFARG2LO
| jr ra
|. slt CRET1, SFARG1HI, SFARG2HI
|5: // Swap conditions if both operands are negative.
| beq SFARG1HI, SFARG2HI, >8
|. sltu CRET1, SFARG2LO, SFARG1LO
| jr ra
|. slt CRET1, SFARG2HI, SFARG1HI
|8:
| jr ra
|. nop
|9:
| jr ra
|. move CRET1, CRET2
|.endif
|
|->vm_sfcmpogt:
|.if not FPU
| sll AT, SFARG2HI, 1
| sll TMP0, SFARG1HI, 1
| or CRET1, SFARG2LO, SFARG1LO
| or TMP1, AT, TMP0
| or TMP1, TMP1, CRET1
| beqz TMP1, >8 // Both args +-0: return 0.
|. sltu CRET1, r0, SFARG2LO
| lui TMP1, 0xffe0
| addu AT, AT, CRET1
| sltu CRET1, r0, SFARG1LO
| sltu AT, TMP1, AT
| addu TMP0, TMP0, CRET1
| sltu TMP0, TMP1, TMP0
| or TMP1, AT, TMP0
| bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
|. and AT, SFARG2HI, SFARG1HI
| bltz AT, >5 // Both args negative?
|. nop
| beq SFARG2HI, SFARG1HI, >8
|. sltu CRET1, SFARG2LO, SFARG1LO
| jr ra
|. slt CRET1, SFARG2HI, SFARG1HI
|5: // Swap conditions if both operands are negative.
| beq SFARG2HI, SFARG1HI, >8
|. sltu CRET1, SFARG1LO, SFARG2LO
| jr ra
|. slt CRET1, SFARG1HI, SFARG2HI
|8:
| jr ra
|. nop
|9:
| jr ra
|. li CRET1, 0
|.endif
|
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
|// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|->vm_sfcmpolex:
|.if not FPU
| sll AT, SFARG1HI, 1
| sll TMP0, SFARG2HI, 1
| or CRET1, SFARG1LO, SFARG2LO
| or TMP1, AT, TMP0
| or TMP1, TMP1, CRET1
| beqz TMP1, >8 // Both args +-0: return 1.
|. sltu CRET1, r0, SFARG1LO
| lui TMP1, 0xffe0
| addu AT, AT, CRET1
| sltu CRET1, r0, SFARG2LO
| sltu AT, TMP1, AT
| addu TMP0, TMP0, CRET1
| sltu TMP0, TMP1, TMP0
| or TMP1, AT, TMP0
| bnez TMP1, >9 // Either arg is NaN: return 0;
|. and AT, SFARG1HI, SFARG2HI
| xor AT, AT, TMP3
| bltz AT, >5 // Both args negative?
|. nop
| beq SFARG1HI, SFARG2HI, >6
|. sltu CRET1, SFARG2LO, SFARG1LO
| jr ra
|. slt CRET1, SFARG2HI, SFARG1HI
|5: // Swap conditions if both operands are negative.
| beq SFARG1HI, SFARG2HI, >6
|. sltu CRET1, SFARG1LO, SFARG2LO
| slt CRET1, SFARG1HI, SFARG2HI
|6:
| jr ra
|. nop
|8:
| jr ra
|. li CRET1, 1
|9:
| jr ra
|. li CRET1, 0
|.endif
|
|.macro sfmin_max, name, fpcall
|->vm_sf .. name:
|.if JIT and not FPU
| move TMP2, ra
| bal ->fpcall
|. nop
| move TMP0, CRET1
| move SFRETHI, SFARG1HI
| move SFRETLO, SFARG1LO
| move ra, TMP2
| movz SFRETHI, SFARG2HI, TMP0
| jr ra
|. movz SFRETLO, SFARG2LO, TMP0
|.endif
|.endmacro
|
| sfmin_max min, vm_sfcmpolt
| sfmin_max max, vm_sfcmpogt
|
|//-----------------------------------------------------------------------
|//-- Miscellaneous functions --------------------------------------------
|//-----------------------------------------------------------------------
|
|.define NEXT_TAB, TAB:CARG1
|.define NEXT_IDX, CARG2
|.define NEXT_ASIZE, CARG3
|.define NEXT_NIL, CARG4
|.define NEXT_TMP0, r12
|.define NEXT_TMP1, r13
|.define NEXT_TMP2, r14
|.define NEXT_RES_VK, CRET1
|.define NEXT_RES_IDX, CRET2
|.define NEXT_RES_PTR, sp
|.define NEXT_RES_VAL_I, 0(sp)
|.define NEXT_RES_VAL_IT, 4(sp)
|.define NEXT_RES_KEY_I, 8(sp)
|.define NEXT_RES_KEY_IT, 12(sp)
( run in 0.986 second using v1.01-cache-2.11-cpan-39bf76dae61 )