From f8f6fa9fc1bca1734c178c048b8fb629ccc81f1c Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 10 Sep 2018 00:21:16 +0200 Subject: [PATCH] Added some more incredibly untested helper functions. --- mach/mips/libem/bls4.s | 30 +++++++++++++++++++ mach/mips/libem/c_ud_i.s | 12 +++++--- mach/mips/libem/c_uf_i.s | 5 ++++ mach/mips/libem/c_ui_d.s | 26 ++++++++++++++++ mach/mips/libem/c_ui_f.s | 26 ++++++++++++++++ mach/mips/libem/fd_80000000.s | 10 ------- mach/mips/libem/fef8.s | 56 +++++++++++++++++++++++++++++++++++ mach/mips/libem/ff_80000000.s | 10 ------- 8 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 mach/mips/libem/bls4.s create mode 100644 mach/mips/libem/c_ui_d.s create mode 100644 mach/mips/libem/c_ui_f.s delete mode 100644 mach/mips/libem/fd_80000000.s create mode 100644 mach/mips/libem/fef8.s delete mode 100644 mach/mips/libem/ff_80000000.s diff --git a/mach/mips/libem/bls4.s b/mach/mips/libem/bls4.s new file mode 100644 index 000000000..559e23fe2 --- /dev/null +++ b/mach/mips/libem/bls4.s @@ -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 diff --git a/mach/mips/libem/c_ud_i.s b/mach/mips/libem/c_ud_i.s index cfb9668ea..ccd798e03 100644 --- a/mach/mips/libem/c_ud_i.s +++ b/mach/mips/libem/c_ud_i.s @@ -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 + diff --git a/mach/mips/libem/c_uf_i.s b/mach/mips/libem/c_uf_i.s index f8b7f5f22..8bd840b40 100644 --- a/mach/mips/libem/c_uf_i.s +++ b/mach/mips/libem/c_uf_i.s @@ -31,3 +31,8 @@ toobig: jr ra nop +/* 2147483648 as a float. */ +.sect .rom +.ff_80000000: + .data4 0x4f000000 + diff --git a/mach/mips/libem/c_ui_d.s b/mach/mips/libem/c_ui_d.s new file mode 100644 index 000000000..c46a2cf4a --- /dev/null +++ b/mach/mips/libem/c_ui_d.s @@ -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 diff --git a/mach/mips/libem/c_ui_f.s b/mach/mips/libem/c_ui_f.s new file mode 100644 index 000000000..46f9f0b62 --- /dev/null +++ b/mach/mips/libem/c_ui_f.s @@ -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 diff --git a/mach/mips/libem/fd_80000000.s b/mach/mips/libem/fd_80000000.s deleted file mode 100644 index 3618d0b44..000000000 --- a/mach/mips/libem/fd_80000000.s +++ /dev/null @@ -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 - diff --git a/mach/mips/libem/fef8.s b/mach/mips/libem/fef8.s new file mode 100644 index 000000000..4fa545676 --- /dev/null +++ b/mach/mips/libem/fef8.s @@ -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 diff --git a/mach/mips/libem/ff_80000000.s b/mach/mips/libem/ff_80000000.s deleted file mode 100644 index 95e4f9506..000000000 --- a/mach/mips/libem/ff_80000000.s +++ /dev/null @@ -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 - -- 2.34.1