Added some more very untested helper functions.
This commit is contained in:
parent
a1747ac916
commit
008737ed19
69
mach/mips/libem/fif8.s
Normal file
69
mach/mips/libem/fif8.s
Normal file
|
@ -0,0 +1,69 @@
|
|||
#
|
||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||
|
||||
/* Multiplies two double-precision floats, then splits the product into
|
||||
* fraction and integer, both as floats, like modf(3) in C,
|
||||
* http://en.cppreference.com/w/c/numeric/math/modf
|
||||
*
|
||||
* Stack: ( a b -- fraction integer )
|
||||
*/
|
||||
|
||||
.sect .text
|
||||
.define .fif8
|
||||
.fif8:
|
||||
ldc1 f0, 8(sp) ! f0 = a
|
||||
ldc1 f2, 0(sp) ! f2 = b
|
||||
mul.d f0, f0, f2 ! f0 = a * b
|
||||
abs.d f2, f0 ! f2 = abs(f0)
|
||||
|
||||
li at, ha16[max_power_of_two]
|
||||
ldc1 f4, lo16[max_power_of_two] (at) ! f4 = max power of two
|
||||
|
||||
mov.d f6, f2 ! we're going to assemble the integer part in f6
|
||||
c.lt.d 0, f4, f2 ! if absolute value too big, it must be integral
|
||||
bc1t 0, return
|
||||
nop
|
||||
|
||||
! Crudely strip off the fractional part.
|
||||
|
||||
add.d f6, f2, f4 ! f6 = absolute value + max power of two
|
||||
sub.d f6, f6, f4 ! f6 -= max_power_of_two
|
||||
|
||||
! The above might round, so correct that.
|
||||
|
||||
li at, ha16[one]
|
||||
ldc1 f8, lo16[one] (at) ! f8 = 1.0
|
||||
1:
|
||||
c.le.d 0, f6, f2 ! if result <= absolute value, stop
|
||||
bc1t 0, 2f
|
||||
nop
|
||||
|
||||
sub.d f6, f6, f8 ! result -= 1.0
|
||||
b 1b
|
||||
nop
|
||||
2:
|
||||
|
||||
! Correct the sign of the result.
|
||||
|
||||
mtc1 zero, f8
|
||||
mthc1 zero, f8 ! f8 = 0.0
|
||||
c.lt.d 0, f0, f8 ! if original value was negative
|
||||
bc1f 0, 1f
|
||||
nop
|
||||
neg.d f6, f6 ! negate the result
|
||||
1:
|
||||
|
||||
return:
|
||||
sdc1 f6, 0(sp) ! store integer part
|
||||
sub.d f6, f0, f6 ! calculate fractional part
|
||||
sdc1 f6, 8(sp) ! store fractional part
|
||||
jr ra
|
||||
nop
|
||||
|
||||
! doubles >= MAXPOWTWO are already integers
|
||||
.sect .rom
|
||||
max_power_of_two:
|
||||
.dataf8 4.503599627370496000E+15
|
||||
|
||||
one:
|
||||
.dataf8 1.0
|
24
mach/mips/libem/sar4.s
Normal file
24
mach/mips/libem/sar4.s
Normal file
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||
|
||||
/* Store to bounds-checked array.
|
||||
*
|
||||
* Stack: ( element array-adr index descriptor-adr -- )
|
||||
*/
|
||||
|
||||
.sect .text
|
||||
.define .sar4
|
||||
.sar4:
|
||||
mov r25, ra
|
||||
|
||||
jal .aar4
|
||||
nop
|
||||
|
||||
/* pass r2 = size from .aar4 to .sts4
|
||||
|
||||
jal .sts4
|
||||
nop
|
||||
|
||||
jr r25
|
||||
nop
|
||||
|
57
mach/mips/libem/sts4.s
Normal file
57
mach/mips/libem/sts4.s
Normal file
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||
|
||||
/* Stores a variable-sized block from the stack.
|
||||
*
|
||||
* On entry: r2 = size
|
||||
* Stack: ( block address -- )
|
||||
* Preserves r25 for .lar4 and .sar4
|
||||
*/
|
||||
|
||||
.sect .text
|
||||
.define .sts4
|
||||
.sts4:
|
||||
lw r4, 0(sp) ! r4 = address
|
||||
addiu sp, sp, 4 ! sp = pointer to block
|
||||
|
||||
! Sizes 1 and 2 are handled specially.
|
||||
|
||||
li at, 1
|
||||
beq r2, at, byte_sized
|
||||
nop
|
||||
|
||||
li at, 2
|
||||
beq r2, at, word_sized
|
||||
nop
|
||||
|
||||
! Else the size must be a multiple of 4.
|
||||
|
||||
srl r5, r2, 2 ! r5 = number of words
|
||||
|
||||
! Copy.
|
||||
|
||||
1:
|
||||
lw at, 0(sp)
|
||||
sw at, 0(r4)
|
||||
addiu sp, sp, 4
|
||||
addiu r4, r4, 4
|
||||
addiu r5, r5, -1
|
||||
bne r5, zero, 1b
|
||||
nop
|
||||
|
||||
jr ra
|
||||
nop
|
||||
|
||||
byte_sized:
|
||||
lw at, 0(sp)
|
||||
sb at, 0(r4)
|
||||
addiu sp, sp, 4
|
||||
jr ra
|
||||
nop
|
||||
|
||||
word_sized:
|
||||
lw at, 0(sp)
|
||||
sh at, 0(r4)
|
||||
addiu sp, sp, 4
|
||||
jr ra
|
||||
nop
|
Loading…
Reference in a new issue