summaryrefslogtreecommitdiff
path: root/src/fenv
diff options
context:
space:
mode:
Diffstat (limited to 'src/fenv')
-rw-r--r--src/fenv/loongarch64/fenv.S78
-rw-r--r--src/fenv/powerpc/fenv-sf.c2
-rw-r--r--src/fenv/powerpc/fenv.S2
-rw-r--r--src/fenv/riscv32/fenv-sf.c3
-rw-r--r--src/fenv/riscv32/fenv.S56
5 files changed, 139 insertions, 2 deletions
diff --git a/src/fenv/loongarch64/fenv.S b/src/fenv/loongarch64/fenv.S
new file mode 100644
index 00000000..9c38599e
--- /dev/null
+++ b/src/fenv/loongarch64/fenv.S
@@ -0,0 +1,78 @@
+#ifndef __loongarch_soft_float
+
+#ifdef BROKEN_LOONGARCH_FCSR_ASM
+#define FCSR $r0
+#else
+#define FCSR $fcsr0
+#endif
+
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ andn $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ or $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+ li.w $t0, 0x1f0000
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ and $a0, $t1, $a0
+ jr $ra
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+ movfcsr2gr $t0, FCSR
+ andi $a0, $t0, 0x300
+ jr $ra
+
+.global __fesetround
+.hidden __fesetround
+.type __fesetround,@function
+__fesetround:
+ li.w $t0, 0x300
+ and $a0, $a0, $t0
+ movfcsr2gr $t1, FCSR
+ andn $t1, $t1, $t0
+ or $t1, $t1, $a0
+ movgr2fcsr FCSR, $t1
+ li.w $a0, 0
+ jr $ra
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+ movfcsr2gr $t0, FCSR
+ st.w $t0, $a0, 0
+ li.w $a0, 0
+ jr $ra
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+ addi.d $t0, $a0, 1
+ beq $t0, $r0, 1f
+ ld.w $t0, $a0, 0
+1: movgr2fcsr FCSR, $t0
+ li.w $a0, 0
+ jr $ra
+
+#endif
diff --git a/src/fenv/powerpc/fenv-sf.c b/src/fenv/powerpc/fenv-sf.c
index 85bef40f..d4248f26 100644
--- a/src/fenv/powerpc/fenv-sf.c
+++ b/src/fenv/powerpc/fenv-sf.c
@@ -1,3 +1,3 @@
-#ifdef _SOFT_FLOAT
+#if defined(_SOFT_FLOAT) || defined(__NO_FPRS__)
#include "../fenv.c"
#endif
diff --git a/src/fenv/powerpc/fenv.S b/src/fenv/powerpc/fenv.S
index 22cea216..55055d0b 100644
--- a/src/fenv/powerpc/fenv.S
+++ b/src/fenv/powerpc/fenv.S
@@ -1,4 +1,4 @@
-#ifndef _SOFT_FLOAT
+#if !defined(_SOFT_FLOAT) && !defined(__NO_FPRS__)
.global feclearexcept
.type feclearexcept,@function
feclearexcept:
diff --git a/src/fenv/riscv32/fenv-sf.c b/src/fenv/riscv32/fenv-sf.c
new file mode 100644
index 00000000..ecd3cb5c
--- /dev/null
+++ b/src/fenv/riscv32/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifndef __riscv_flen
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/riscv32/fenv.S b/src/fenv/riscv32/fenv.S
new file mode 100644
index 00000000..0ea78bf9
--- /dev/null
+++ b/src/fenv/riscv32/fenv.S
@@ -0,0 +1,56 @@
+#ifdef __riscv_flen
+
+.global feclearexcept
+.type feclearexcept, %function
+feclearexcept:
+ csrc fflags, a0
+ li a0, 0
+ ret
+
+.global feraiseexcept
+.type feraiseexcept, %function
+feraiseexcept:
+ csrs fflags, a0
+ li a0, 0
+ ret
+
+.global fetestexcept
+.type fetestexcept, %function
+fetestexcept:
+ frflags t0
+ and a0, t0, a0
+ ret
+
+.global fegetround
+.type fegetround, %function
+fegetround:
+ frrm a0
+ ret
+
+.global __fesetround
+.type __fesetround, %function
+__fesetround:
+ fsrm t0, a0
+ li a0, 0
+ ret
+
+.global fegetenv
+.type fegetenv, %function
+fegetenv:
+ frcsr t0
+ sw t0, 0(a0)
+ li a0, 0
+ ret
+
+.global fesetenv
+.type fesetenv, %function
+fesetenv:
+ li t2, -1
+ li t1, 0
+ beq a0, t2, 1f
+ lw t1, 0(a0)
+1: fscsr t1
+ li a0, 0
+ ret
+
+#endif