Added some more incredibly untested helper functions.
authorDavid Given <dg@cowlark.com>
Sun, 9 Sep 2018 22:21:16 +0000 (00:21 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 9 Sep 2018 22:21:16 +0000 (00:21 +0200)
mach/mips/libem/bls4.s [new file with mode: 0644]
mach/mips/libem/c_ud_i.s
mach/mips/libem/c_uf_i.s
mach/mips/libem/c_ui_d.s [new file with mode: 0644]
mach/mips/libem/c_ui_f.s [new file with mode: 0644]
mach/mips/libem/fd_80000000.s [deleted file]
mach/mips/libem/fef8.s [new file with mode: 0644]
mach/mips/libem/ff_80000000.s [deleted file]

diff --git a/mach/mips/libem/bls4.s b/mach/mips/libem/bls4.s
new file mode 100644 (file)
index 0000000..559e23f
--- /dev/null
@@ -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
index cfb9668..ccd798e 100644 (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
+
index f8b7f5f..8bd840b 100644 (file)
@@ -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 (file)
index 0000000..c46a2cf
--- /dev/null
@@ -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 (file)
index 0000000..46f9f0b
--- /dev/null
@@ -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 (file)
index 3618d0b..0000000
+++ /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 (file)
index 0000000..4fa5456
--- /dev/null
@@ -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 (file)
index 95e4f95..0000000
+++ /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
-