changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/bcm64/fpu.c

revision 7199: ba62683c0e2d
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/9/bcm64/fpu.c
     1.4@@ -0,0 +1,92 @@
     1.5+#include "u.h"
     1.6+#include "../port/lib.h"
     1.7+#include "mem.h"
     1.8+#include "dat.h"
     1.9+#include "fns.h"
    1.10+
    1.11+#include "ureg.h"
    1.12+#include "sysreg.h"
    1.13+
    1.14+/* libc */
    1.15+extern ulong getfcr(void);
    1.16+extern void setfcr(ulong fcr);
    1.17+extern ulong getfsr(void);
    1.18+extern void setfsr(ulong fsr);
    1.19+
    1.20+void
    1.21+fpuinit(void)
    1.22+{
    1.23+	fpoff();
    1.24+}
    1.25+
    1.26+void
    1.27+fpon(void)
    1.28+{
    1.29+	syswr(CPACR_EL1, 3<<20);
    1.30+}
    1.31+
    1.32+void
    1.33+fpoff(void)
    1.34+{
    1.35+	syswr(CPACR_EL1, 0<<20);
    1.36+}
    1.37+
    1.38+void
    1.39+fpinit(void)
    1.40+{
    1.41+	fpon();
    1.42+	setfcr(0);
    1.43+	setfsr(0);
    1.44+}
    1.45+
    1.46+void
    1.47+fpclear(void)
    1.48+{
    1.49+	fpoff();
    1.50+}
    1.51+
    1.52+void
    1.53+fpsave(FPsave *p)
    1.54+{
    1.55+	p->control = getfcr();
    1.56+	p->status = getfsr();
    1.57+	fpsaveregs(p->regs);
    1.58+	fpoff();
    1.59+}
    1.60+
    1.61+void
    1.62+fprestore(FPsave *p)
    1.63+{
    1.64+	fpon();
    1.65+	setfcr(p->control);
    1.66+	setfsr(p->status);
    1.67+	fploadregs(p->regs);
    1.68+}
    1.69+
    1.70+void
    1.71+mathtrap(Ureg*)
    1.72+{
    1.73+	int s;
    1.74+
    1.75+	if((up->fpstate & FPillegal) != 0){
    1.76+		postnote(up, 1, "sys: floating point in note handler", NDebug);
    1.77+		return;
    1.78+	}
    1.79+	switch(up->fpstate){
    1.80+	case FPinit:
    1.81+		s = splhi();
    1.82+		fpinit();
    1.83+		up->fpstate = FPactive;
    1.84+		splx(s);
    1.85+		break;
    1.86+	case FPinactive:
    1.87+		s = splhi();
    1.88+		fprestore(up->fpsave);
    1.89+		up->fpstate = FPactive;
    1.90+		splx(s);
    1.91+		break;
    1.92+	case FPactive:
    1.93+		postnote(up, 1, "sys: floating point error", NDebug);
    1.94+		break;
    1.95+	}
    1.96+}