Added some more incredibly untested helper functions.

This commit is contained in:
David Given 2018-09-10 00:21:16 +02:00
parent ee328a0572
commit f8f6fa9fc1
8 changed files with 151 additions and 24 deletions

30
mach/mips/libem/bls4.s Normal file
View file

@ -0,0 +1,30 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
/* Does a block move of words between non-overlapping buffers.
* Stack: ( src dst len -- )
*/
.sect .text
.define .bls4
.bls4:
lw r4, 0(sp) ! r4=len
lw r5, 4(sp) ! r5=dst
lw r6, 8(sp) ! r6=src
addiu sp, sp, 12
srl r4, r4, 2 ! convert len to words
1:
beq r4, zero, 2f
nop
lw at, 0(r6)
sw at, 0(r5)
addiu r6, r6, 4
addiu r5, r5, 4
addiu r4, r4, -1
b 1b
2:
jr ra
nop

View file

@ -1,8 +1,5 @@
#
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .c_ud_i
@ -30,3 +27,10 @@ toobig:
addiu r2, r2, 0x8000
jr ra
nop
/* 2147483648 as a double. */
.sect .rom
.define .fd_80000000
.fd_80000000:
.data4 0, 0x41e00000

View file

@ -31,3 +31,8 @@ toobig:
jr ra
nop
/* 2147483648 as a float. */
.sect .rom
.ff_80000000:
.data4 0x4f000000

26
mach/mips/libem/c_ui_d.s Normal file
View file

@ -0,0 +1,26 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .c_ui_d
.c_ui_d:
/* Input: r2
* Output: f0
* Only at and f30/f31 may be used.
*/
mtc1 r2, f0
cvt.d.w f0, f0
bgez r2, nonnegative
nop
ori at, zero, hi16[.fd_100000000]
ldc1 f30, lo16[.fd_100000000] (at)
add.d f0, f0, f30
nonnegative:
jr ra
nop
/* 4294967296 as a double. */
.sect .rom
.fd_100000000:
.data4 0, 0x41f00000

26
mach/mips/libem/c_ui_f.s Normal file
View file

@ -0,0 +1,26 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text
.define .c_ui_f
.c_ui_f:
/* Input: r2
* Output: f0
* Only at and f30/f31 may be used.
*/
mtc1 r2, f0
cvt.s.w f0, f0
bgez r2, nonnegative
nop
ori at, zero, hi16[.fs_100000000]
ldc1 f30, lo16[.fs_100000000] (at)
add.d f0, f0, f30
nonnegative:
jr ra
nop
/* 4294967296 as a float. */
.sect .rom
.fs_100000000:
.data4 0x4f800000

View file

@ -1,10 +0,0 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
/* 2147483648 as a double; used as a pivot for double->unsigned and unsigned->double. */
.sect .rom
.define .fd_80000000
.fd_80000000:
.data4 0x41e00000, 0

56
mach/mips/libem/fef8.s Normal file
View file

@ -0,0 +1,56 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
/* Split a double-precision float into fraction and exponent, like
* frexp(3) in C, http://en.cppreference.com/w/c/numeric/math/frexp
*
* Stack: ( double -- fraction exponent )
*/
#define DBL_EXPBITS 11
#define DBL_FRACHBITS 20
#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define DBL_EXP_INFNAN 2047
#define DBL_EXP_BIAS 1023
.sect .text
.define .fef8
.fef8:
lw r4, 0(sp) ! r4 = low word (bits 0..31)
lw r5, 4(sp) ! r5 = high word (bits 32..63)
! IEEE double = sign * 1.fraction * 2**(exponent - 1023)
! sign exponent fraction
! 31 30..19 18..0, 31..0
!
! IEEE exponent = 1022 in [0.5, 1) or (-1, -0.5].
ext r7, r5, DBL_FRACHBITS, DBL_EXPBITS ! r7 = IEEE exponent
beq r7, zero, zeroexp ! this number is zero or denormalised, treat specially
nop
li at, DBL_EXP_INFNAN
beq r7, at, return ! just return if infinity or NaN
nop
addiu r7, r7, -[DBL_EXP_BIAS-1] ! undo exponent bias
li at, DBL_EXP_BIAS-1
ins r5, at, DBL_FRACHBITS, DBL_EXPBITS ! replace exponent
return:
addiu sp, sp, -4 ! returning one more quad than we got
sw r5, 8(sp)
sw r6, 4(sp)
sw r7, 0(sp)
jr ra
nop
/* We received a denormalised number or zero. */
zeroexp:
/* TODO: we just assume that the number is zero here. */
mov r5, zero
mov r6, zero
mov r7, zero
b return
nop

View file

@ -1,10 +0,0 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
/* 2147483648 as a float; used as a pivot for double->float and unsigned->float. */
.sect .rom
.define .ff_80000000
.ff_80000000:
.data4 0x4f000000