Преглед на файлове

fenv support for ppc, untested

based on code sent to the mailing list by nsz, with minor changes.
Rich Felker преди 12 години
родител
ревизия
75c450cff3
променени са 2 файла, в които са добавени 148 реда и са изтрити 7 реда
  1. 28 7
      arch/powerpc/bits/fenv.h
  2. 120 0
      src/fenv/powerpc/fenv.s

+ 28 - 7
arch/powerpc/bits/fenv.h

@@ -1,10 +1,31 @@
-#define FE_ALL_EXCEPT 0
-#define FE_TONEAREST  0
+#define FE_TONEAREST	0
+#define FE_TOWARDZERO	1
+#define FE_UPWARD	2
+#define FE_DOWNWARD	3
 
-typedef unsigned long fexcept_t;
+#define FE_INEXACT	0x02000000
+#define FE_DIVBYZERO	0x04000000
+#define FE_UNDERFLOW	0x08000000
+#define FE_OVERFLOW	0x10000000
+#define FE_INVALID	0x20000000
 
-typedef struct {
-	unsigned long __cw;
-} fenv_t;
+#define FE_ALL_EXCEPT	0x3e000000
 
-#define FE_DFL_ENV      ((const fenv_t *) -1)
+#ifdef _GNU_SOURCE
+#define FE_INVALID_SNAN		0x01000000
+#define FE_INVALID_ISI		0x00800000
+#define FE_INVALID_IDI		0x00400000
+#define FE_INVALID_ZDZ		0x00200000
+#define FE_INVALID_IMZ		0x00100000
+#define FE_INVALID_COMPARE	0x00080000
+#define FE_INVALID_SOFTWARE	0x00000400
+#define FE_INVALID_SQRT		0x00000200
+#define FE_INVALID_INTEGER_CONVERSION	0x00000100
+
+#define FE_ALL_INVALID		0x01f80700
+#endif
+
+typedef unsigned fexcept_t;
+typedef double fenv_t;
+
+#define FE_DFL_ENV ((fenv_t *)-1)

+ 120 - 0
src/fenv/powerpc/fenv.s

@@ -0,0 +1,120 @@
+.global feclearexcept
+.type feclearexcept,@function
+feclearexcept:
+	# if (r3 & FE_INVALID) r3 |= all_invalid_flags
+	andis. 0,3,0x2000
+	stwu 1,-16(1)
+	beq- 0,1f
+	oris 3,3,0x01f8
+	ori  3,3,0x0700
+1:
+	# note: fpscr contains various fpu status and control
+	# flags and we dont check if r3 may alter other flags
+	# than the exception related ones
+	# fpscr &= ~r3
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	andc 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	# return 0
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global feraiseexcept
+.type feraiseexcept,@function
+feraiseexcept:
+	# if (r3 & FE_INVALID) r3 |= software_invalid_flag
+	andis. 0,3,0x2000
+	stwu 1,-16(1)
+	beq- 0,1f
+	ori 3,3,0x0400
+1:
+	# fpscr |= r3
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	or 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	# return 0
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global fetestexcept
+.type fetestexcept,@function
+fetestexcept:
+	# return r3 & fpscr
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	addi 1,1,16
+	and 3,3,9
+	blr
+
+.global fegetround
+.type fegetround,@function
+fegetround:
+	# return fpscr & 3
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 3,12(1)
+	addi 1,1,16
+	clrlwi 3,3,30
+	blr
+
+.global fesetround
+.type fesetround,@function
+fesetround:
+	# note: invalid input is not checked, r3 < 4 must hold
+	# fpscr = (fpscr & -4U) | r3
+	stwu 1,-16(1)
+	mffs 0
+	stfd 0,8(1)
+	lwz 9,12(1)
+	clrrwi 9,9,2
+	or 9,9,3
+	stw 9,12(1)
+	lfd 0,8(1)
+	mtfsf 255,0
+
+	# return 0
+	li 3,0
+	addi 1,1,16
+	blr
+
+.global fegetenv
+.type fegetenv,@function
+fegetenv:
+	# *r3 = fpscr
+	mffs 0
+	stfd 0,0(3)
+	# return 0
+	li 3,0
+	blr
+
+.global fesetenv
+.type fesetenv,@function
+fesetenv:
+	cmpwi 3, -1
+	bne 1f
+	mflr 4
+	bl 2f
+	.zero 8
+2:	mflr 3
+	mtlr 4
+1:	# fpscr = *r3
+	lfd 0,0(3)
+	mtfsf 255,0
+	# return 0
+	li 3,0
+	blr