summaryrefslogtreecommitdiff
path: root/os/mpc/fpipower.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/fpipower.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/fpipower.c')
-rw-r--r--os/mpc/fpipower.c970
1 files changed, 0 insertions, 970 deletions
diff --git a/os/mpc/fpipower.c b/os/mpc/fpipower.c
deleted file mode 100644
index ec4363b2..00000000
--- a/os/mpc/fpipower.c
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * this doesn't attempt to implement Power architecture floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-#include "ureg.h"
-
-#include "fpi.h"
-
-#define REG(x) (*(long*)(((char*)em->ur)+roff[(x)]))
-#define FR(x) (*(Internal*)em->fr[(x)&0x1F])
-#define REGSP 1 /* stack pointer */
-
-/* BUG: check fetch (not worthwhile in Inferno) */
-#define getulong(a) (*(ulong*)(a))
-
-enum {
- CRLT = 1<<31,
- CRGT = 1<<30,
- CREQ = 1<<29,
- CRSO = 1<<28,
- CRFU = CRSO,
-
- CRFX = 1<<27,
- CRFEX = 1<<26,
- CRVX = 1<<25,
- CROX = 1<<24,
-};
-
-#define getCR(x,w) (((w)>>(28-(x*4)))&0xF)
-#define mkCR(x,v) (((v)&0xF)<<(28-(x*4)))
-
-#define simm(xx, ii) xx = (short)(ii&0xFFFF);
-#define getairr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; simm(imm,i)
-#define getarrr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; rb = (i>>11)&0x1f;
-#define getop(i) ((i>>26)&0x3F)
-#define getxo(i) ((i>>1)&0x3FF)
-
-#define FPS_FX (1<<31) /* exception summary (sticky) */
-#define FPS_EX (1<<30) /* enabled exception summary */
-#define FPS_VX (1<<29) /* invalid operation exception summary */
-#define FPS_OX (1<<28) /* overflow exception OX (sticky) */
-#define FPS_UX (1<<27) /* underflow exception UX (sticky) */
-#define FPS_ZX (1<<26) /* zero divide exception ZX (sticky) */
-#define FPS_XX (1<<25) /* inexact exception XX (sticky) */
-#define FPS_VXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */
-#define FPS_VXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */
-#define FPS_VXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */
-#define FPS_VXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */
-#define FPS_VXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */
-#define FPS_VXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */
-#define FPS_FR (1<<18) /* fraction rounded */
-#define FPS_FI (1<<17) /* fraction inexact */
-#define FPS_FPRF (1<<16) /* floating point result class */
-#define FPS_FPCC (0xF<<12) /* <, >, =, unordered */
-#define FPS_VXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */
-#define FPS_VE (1<<7) /* invalid operation exception enable */
-#define FPS_OE (1<<6) /* enable overflow exceptions */
-#define FPS_UE (1<<5) /* enable underflow */
-#define FPS_ZE (1<<4) /* enable zero divide */
-#define FPS_XE (1<<3) /* enable inexact exceptions */
-#define FPS_RN (3<<0) /* rounding mode */
-
-typedef struct Emreg Emreg;
-
-struct Emreg {
- Ureg* ur;
- ulong (*fr)[3];
- FPenv* ufp;
- ulong ir;
- char* name;
-};
-
-int fpemudebug = 0;
-
-#undef OFR
-#define OFR(X) ((ulong)&((Ureg*)0)->X)
-
-static int roff[] = {
- OFR(r0), OFR(r1), OFR(r2), OFR(r3),
- OFR(r4), OFR(r5), OFR(r6), OFR(r7),
- OFR(r8), OFR(r9), OFR(r10), OFR(r11),
- OFR(r12), OFR(r13), OFR(r14), OFR(r15),
- OFR(r16), OFR(r17), OFR(r18), OFR(r19),
- OFR(r20), OFR(r21), OFR(r22), OFR(r23),
- OFR(r24), OFR(r25), OFR(r26), OFR(r27),
- OFR(r28), OFR(r29), OFR(r30), OFR(r31),
-};
-
-/*
- * initial FP register values assumed by qc's code
- */
-static Internal fpreginit[] = {
- /* s, e, l, h */
- {0, 0x400, 0x00000000, 0x08000000}, /* F31=2.0 */
- {0, 0x3FF, 0x00000000, 0x08000000}, /* F30=1.0 */
- {0, 0x3FE, 0x00000000, 0x08000000}, /* F29=0.5 */
- {0, 0x1, 0x00000000, 0x00000000}, /* F28=0.0 */
- {0, 0x433, 0x00000000, 0x08000040}, /* F27=FREGCVI */
-};
-
-static void
-fadd(Emreg *em, Internal *d, int ra, int rb)
-{
- Internal a, b;
-
- a = FR(ra);
- b = FR(rb);
- (a.s == b.s? fpiadd: fpisub)(&b, &a, d);
-}
-
-static void
-fsub(Emreg *em, Internal *d, int ra, int rb)
-{
- Internal a, b;
-
- a = FR(ra);
- b = FR(rb);
- b.s ^= 1;
- (b.s == a.s? fpiadd: fpisub)(&b, &a, d);
-}
-
-static void
-fmul(Emreg *em, Internal *d, int ra, int rb)
-{
- Internal a, b;
-
- a = FR(ra);
- b = FR(rb);
- fpimul(&b, &a, d);
-}
-
-static void
-fdiv(Emreg *em, Internal *d, int ra, int rb)
-{
- Internal a, b;
-
- a = FR(ra);
- b = FR(rb);
- fpidiv(&b, &a, d);
-}
-
-static void
-fmsub(Emreg *em, Internal *d, int ra, int rc, int rb)
-{
- Internal a, c, b, t;
-
- a = FR(ra);
- c = FR(rc);
- b = FR(rb);
- fpimul(&a, &c, &t);
- b.s ^= 1;
- (b.s == t.s? fpiadd: fpisub)(&b, &t, d);
-}
-
-static void
-fmadd(Emreg *em, Internal *d, int ra, int rc, int rb)
-{
- Internal a, c, b, t;
-
- a = FR(ra);
- c = FR(rc);
- b = FR(rb);
- fpimul(&a, &c, &t);
- (t.s == b.s? fpiadd: fpisub)(&b, &t, d);
-}
-
-static ulong setfpscr(Emreg*);
-static void setfpcc(Emreg*, int);
-
-static void
-unimp(Emreg *em, ulong op)
-{
- char buf[60];
-
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", em->ur->pc, op);
- if(fpemudebug)
- print("FPE: %s\n", buf);
- error(buf);
- /* no return */
-}
-
-/*
- * floating load/store
- */
-
-static void
-fpeairr(Emreg *em, ulong ir, void **eap, int *rdp)
-{
- ulong ea;
- long imm;
- int ra, rd, upd;
-
- getairr(ir);
- ea = imm;
- upd = (ir&(1L<<26))!=0;
- if(ra) {
- ea += REG(ra);
- if(upd){
- if(ra == REGSP)
- panic("fpemu: r1 update"); /* can't do it because we're running on the same stack */
- REG(ra) = ea;
- }
- } else {
- if(upd)
- unimp(em, ir);
- }
- *rdp = rd;
- *eap = (void*)ea;
- if(fpemudebug)
- print("%8.8lux %s\tf%d,%ld(r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, imm, ra, ea, upd);
-}
-
-static void
-fpearrr(Emreg *em, ulong ir, int upd, void **eap, int *rdp)
-{
- ulong ea;
- int ra, rb, rd;
-
- getarrr(ir);
- ea = REG(rb);
- if(ra){
- ea += REG(ra);
- if(upd){
- if(ra == REGSP)
- panic("fpemu: r1 update");
- REG(ra) = ea;
- }
- if(fpemudebug)
- print("%8.8lux %s\tf%d,(r%d+r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, ra, rb, ea, upd);
- } else {
- if(upd)
- unimp(em, ir);
- if(fpemudebug)
- print("%8.8lux %s\tf%d,(r%d) ea=%lux\n", em->ur->pc, em->name, rd, rb, ea);
- }
- *eap = (void*)ea;
- *rdp = rd;
-}
-
-static void
-lfs(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
-
- em->name = "lfs";
- fpeairr(em, ir, &ea, &rd);
- fpis2i(&FR(rd), (void*)ea);
-}
-
-static void
-lfsx(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
-
- em->name = "lfsx";
- fpearrr(em, ir, ((ir>>1)&0x3FF)==567, &ea, &rd);
- fpis2i(&FR(rd), (void*)ea);
-}
-
-static void
-lfd(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
-
- em->name = "lfd";
- fpeairr(em, ir, &ea, &rd);
- fpid2i(&FR(rd), (void*)ea);
-}
-
-static void
-lfdx(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
-
- em->name = "lfdx";
- fpearrr(em, ir, ((ir>>1)&0x3FF)==631, &ea, &rd);
- fpid2i(&FR(rd), (void*)ea);
-}
-
-static void
-stfs(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
- Internal tmp;
-
- em->name = "stfs";
- fpeairr(em, ir, &ea, &rd);
- tmp = FR(rd);
- fpii2s(ea, &tmp);
-}
-
-static void
-stfsx(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
- Internal tmp;
-
- em->name = "stfsx";
- fpearrr(em, ir, getxo(ir)==695, &ea, &rd);
- tmp = FR(rd);
- fpii2s(ea, &tmp);
-}
-
-static void
-stfd(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
- Internal tmp;
-
- em->name = "stfd";
- fpeairr(em, ir, &ea, &rd);
- tmp = FR(rd);
- fpii2d(ea, &tmp);
-}
-
-static void
-stfdx(Emreg *em, ulong ir)
-{
- void *ea;
- int rd;
- Internal tmp;
-
- em->name = "stfdx";
- fpearrr(em, ir, ((ir>>1)&0x3FF)==759, &ea, &rd);
- tmp = FR(rd);
- fpii2d(ea, &tmp);
-}
-
-static void
-mcrfs(Emreg *em, ulong ir)
-{
- int rd, ra, rb;
- static ulong fpscr0[] ={
- FPS_FX|FPS_OX,
- FPS_UX|FPS_ZX|FPS_XX|FPS_VXSNAN,
- FPS_VXISI|FPS_VXIDI|FPS_VXZDZ|FPS_VXIMZ,
- FPS_VXVC,
- 0,
- FPS_VXCVI,
- };
-
- getarrr(ir);
- if(rb || ra&3 || rd&3)
- unimp(em, ir);
- ra >>= 2;
- rd >>= 2;
- em->ur->cr = (em->ur->cr & ~mkCR(rd, 0xF)) | mkCR(rd, getCR(ra, em->ufp->fpscr));
- em->ufp->fpscr &= ~fpscr0[ra];
- if(fpemudebug)
- print("%8.8lux mcrfs\tcrf%d,crf%d\n", em->ur->pc, rd, ra);
-}
-
-static void
-mffs(Emreg *em, ulong ir)
-{
- int rd, ra, rb;
- Double dw;
-
- getarrr(ir);
- if(ra || rb)
- unimp(em, ir);
- dw.h = 0;
- dw.l = ((uvlong)0xFFF8000L<<16)|em->ufp->fpscr;
- fpid2i(&FR(rd), &dw);
- /* it's anyone's guess how CR1 should be set when ir&1 */
- em->ur->cr &= ~mkCR(1, 0xE); /* leave SO, reset others */
- if(fpemudebug)
- print("%8.8lux mffs%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd);
-}
-
-static void
-mtfsb1(Emreg *em, ulong ir)
-{
- int rd, ra, rb;
-
- getarrr(ir);
- if(ra || rb)
- unimp(em, ir);
- em->ufp->fpscr |= (1L << (31-rd));
- /* BUG: should set summary bits */
- if(ir & 1)
- em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */
- if(fpemudebug)
- print("%8.8lux mtfsb1%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd);
-}
-
-static void
-mtfsb0(Emreg *em, ulong ir)
-{
- int rd, ra, rb;
-
- getarrr(ir);
- if(ra || rb)
- unimp(em, ir);
- em->ufp->fpscr &= ~(1L << (31-rd));
- if(ir & 1)
- em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */
- if(fpemudebug)
- print("%8.8lux mtfsb0%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd);
-}
-
-static void
-mtfsf(Emreg *em, ulong ir)
-{
- int fm, rb, i;
- ulong v;
- Internal b;
- Double db;
-
- if(ir & ((1L << 25)|(1L << 16)))
- unimp(em, ir);
- rb = (ir >> 11) & 0x1F;
- fm = (ir >> 17) & 0xFF;
- b = FR(rb);
- fpii2d(&db, &b); /* reconstruct hi/lo format to recover low word */
- v = db.l;
- for(i=0; i<8; i++)
- if(fm & (1 << (7-i)))
- em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(i, 0xF)) | mkCR(i, getCR(i, v));
- /* BUG: should set FEX and VX `according to the usual rule' */
- if(ir & 1)
- em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */
- if(fpemudebug)
- print("%8.8lux mtfsf%s\t#%.2x,fr%d\n", em->ur->pc, ir&1?".":"", fm, rb);
-}
-
-static void
-mtfsfi(Emreg *em, ulong ir)
-{
- int imm, rd;
-
- if(ir & ((0x7F << 16)|(1L << 11)))
- unimp(em, ir);
- rd = (ir >> 23) & 0xF;
- imm = (ir >> 12) & 0xF;
- em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(rd, 0xF)) | mkCR(rd, imm);
- /* BUG: should set FEX and VX `according to the usual rule' */
- if(ir & 1)
- em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */
- if(fpemudebug)
- print("%8.8lux mtfsfi%s\tcrf%d,#%x\n", em->ur->pc, ir&1?".":"", rd, imm);
-}
-
-static void
-fcmp(Emreg *em, ulong ir)
-{
- int fc, rd, ra, rb, sig, i;
-
- getarrr(ir);
- if(rd & 3)
- unimp(em, ir);
- rd >>= 2;
- sig = 0;
- switch(getxo(ir)) {
- default:
- unimp(em, ir);
- case 32:
- if(fpemudebug)
- print("%8.8lux fcmpo\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb);
- sig = 1;
- break;
- case 0:
- if(fpemudebug)
- print("%8.8lux fcmpu\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb);
- break;
- }
- if(IsWeird(&FR(ra)) || IsWeird(&FR(rb))) {
- if(sig){
- ; /* BUG: should trap if not masked ... */
- }
- fc = CRFU;
- } else {
- i = fpicmp(&FR(ra), &FR(rb));
- if(i > 0)
- fc = CRGT;
- else if(i == 0)
- fc = CREQ;
- else
- fc = CRLT;
- }
- fc >>= 28;
- em->ur->cr = (em->ur->cr & ~mkCR(rd,~0)) | mkCR(rd, fc);
- em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (fc<<11);
- /* BUG: update FX, VXSNAN, VXVC */
-}
-
-static void
-fariths(Emreg *em, ulong ir)
-{
- int rd, ra, rb, rc, fmt;
- char *cc, *n;
- ulong fpscr;
- Internal *d;
-
- fmt = 0;
- rc = (ir>>6)&0x1F;
- getarrr(ir);
- d = &FR(rd);
- switch(getxo(ir)&0x1F) { /* partial XO decode */
- case 22: /* fsqrts */
- case 24: /* fres */
- default:
- unimp(em, ir);
- return;
- case 18:
- if(IsZero(&FR(rb))) {
- em->ufp->fpscr |= FPS_ZX | FPS_FX;
- error("sys: fp: zero divide");
- }
- fdiv(em, d, ra, rb);
- n = "fdivs";
- break;
- case 20:
- fsub(em, d, ra, rb);
- n = "fsubs";
- break;
- case 21:
- fadd(em, d, ra, rb);
- n = "fadds";
- break;
- case 25:
- fmul(em, d, ra, rc);
- rb = rc;
- n = "fmuls";
- break;
- case 28:
- fmsub(em, d, ra, rc, rb);
- fmt = 2;
- n = "fmsubs";
- break;
- case 29:
- fmadd(em, d, ra, rc, rb);
- fmt = 2;
- n = "fmadds";
- break;
- case 30:
- fmsub(em, d, ra, rc, rb);
- d->s ^= 1;
- fmt = 2;
- n = "fnmsubs";
- break;
- case 31:
- fmadd(em, d, ra, rc, rb);
- d->s ^= 1;
- fmt = 2;
- n = "fnmadds";
- break;
- }
- if(fmt==1 && ra)
- unimp(em, ir);
- fpscr = setfpscr(em);
- setfpcc(em, rd);
- cc = "";
- if(ir & 1) {
- cc = ".";
- em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28));
- }
- if(fpemudebug) {
- switch(fmt) {
- case 0:
- print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb);
- break;
- case 1:
- print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb);
- break;
- case 2:
- print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb);
- break;
- }
- }
-}
-
-static void
-farith(Emreg *em, ulong ir)
-{
- Word w;
- Double dv;
- int rd, ra, rb, rc, fmt;
- char *cc, *n;
- ulong fpscr;
- int nocc;
- Internal *d;
-
- fmt = 0;
- nocc = 0;
- rc = (ir>>6)&0x1F;
- getarrr(ir);
- d = &FR(rd);
- switch(getxo(ir)&0x1F) { /* partial XO decode */
- case 22: /* frsqrt */
- case 23: /* fsel */
- case 26: /* fsqrte */
- default:
- unimp(em, ir);
- return;
- case 12: /* frsp */
- *d = FR(rb); /* BUG: doesn't round to single precision */
- fmt = 1;
- n = "frsp";
- break;
- case 14: /* fctiw */ /* BUG: ignores rounding mode */
- case 15: /* fctiwz */
- fpii2w(&w, &FR(rb));
- dv.h = 0;
- dv.l = w;
- fpid2i(d, &dv);
- fmt = 1;
- nocc = 1;
- n = "fctiw";
- break;
- case 18:
- if(IsZero(&FR(rb))) {
- em->ufp->fpscr |= FPS_ZX | FPS_FX;
- error("sys: fp: zero divide");
- }
- fdiv(em, d, ra, rb);
- n = "fdiv";
- break;
- case 20:
- fsub(em, d, ra, rb);
- n = "fsub";
- break;
- case 21:
- fadd(em, d, ra, rb);
- n = "fadd";
- break;
- case 25:
- fmul(em, d, ra, rc);
- rb = rc;
- n = "fmul";
- break;
- case 28:
- fmsub(em, d, ra, rc, rb);
- fmt = 2;
- n = "fmsub";
- break;
- case 29:
- fmadd(em, d, ra, rc, rb);
- fmt = 2;
- n = "fmadd";
- break;
- case 30:
- fmsub(em, d, ra, rc, rb);
- d->s ^= 1;
- fmt = 2;
- n = "fnmsub";
- break;
- case 31:
- fmadd(em, d, ra, rc, rb);
- d->s ^= 1;
- fmt = 2;
- n = "fnmadd";
- break;
- }
- if(fmt==1 && ra)
- unimp(em, ir);
- fpscr = setfpscr(em);
- if(nocc == 0)
- setfpcc(em, rd);
- cc = "";
- if(ir & 1) {
- cc = ".";
- em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28));
- }
- if(fpemudebug) {
- switch(fmt) {
- case 0:
- print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb);
- break;
- case 1:
- print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb);
- break;
- case 2:
- print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb);
- break;
- }
- }
-}
-
-static void
-farith2(Emreg *em, ulong ir)
-{
- int rd, ra, rb;
- char *cc, *n;
- ulong fpscr;
- Internal *d, *b;
-
- getarrr(ir);
- if(ra)
- unimp(em, ir);
- d = &FR(rd);
- b = &FR(rb);
- switch(getxo(ir)) { /* full XO decode */
- default:
- unimp(em, ir);
- case 40:
- *d = *b;
- d->s ^= 1;
- n = "fneg";
- break;
- case 72:
- *d = *b;
- n = "fmr";
- break;
- case 136:
- *d = *b;
- d->s = 1;
- n = "fnabs";
- break;
- case 264:
- *d = *b;
- d->s = 0;
- n = "fabs";
- break;
- }
- fpscr = setfpscr(em);
- setfpcc(em, rd);
- cc = "";
- if(ir & 1) {
- cc = ".";
- em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28));
- }
- if(fpemudebug)
- print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb);
-}
-
-static ulong
-setfpscr(Emreg *em)
-{
- ulong fps, fpscr;
-
- fps = 0; /* BUG: getfsr() */
- fpscr = em->ufp->fpscr;
- if(fps & FPAOVFL)
- fpscr |= FPS_OX;
- if(fps & FPAINEX)
- fpscr |= FPS_XX;
- if(fps & FPAUNFL)
- fpscr |= FPS_UX;
- if(fps & FPAZDIV)
- fpscr |= FPS_ZX;
- if(fpscr != em->ufp->fpscr) {
- fpscr |= FPS_FX;
- em->ufp->fpscr = fpscr;
- }
- return fpscr;
-}
-
-static void
-setfpcc(Emreg *em, int r)
-{
- int c;
- Internal *d;
-
- d = &FR(r);
- c = 0;
- if(IsZero(d))
- c |= 2;
- else if(d->s == 1)
- c |= 4;
- else
- c |= 8;
- if(IsNaN(d))
- c |= 1;
- em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (0<<15) | (c<<11); /* unsure about class bit */
-}
-
-static uchar op63flag[32] = {
-[12] 1, [14] 1, [15] 1, [18] 1, [20] 1, [21] 1, [22] 1,
-[23] 1, [25] 1, [26] 1, [28] 1, [29] 1, [30] 1, [31] 1,
-};
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpipower(Ureg *ur)
-{
- ulong op;
- int xo;
- Emreg emreg, *em;
- FPenv *ufp;
- int n;
-
- ufp = &up->env->fpu; /* because all the state is in Osenv, it need not be saved/restored */
- em = &emreg;
- em->ur = ur;
- em->fr = ufp->emreg;
- em->ufp = ufp;
- em->name = nil;
- if(em->ufp->fpistate != FPACTIVE) {
- em->ufp->fpistate = FPACTIVE;
- em->ufp->fpscr = 0; /* TO DO */
- for(n = 0; n < nelem(fpreginit); n++)
- FR(31-n) = fpreginit[n];
- }
- for(n=0;;n++){
- op = getulong(ur->pc);
- em->ir = op;
- if(fpemudebug > 1)
- print("%8.8lux %8.8lux: ", ur->pc, op);
- switch(op>>26){
- default:
- return n;
- case 48: /* lfs */
- case 49: /* lfsu */
- lfs(em, op);
- break;
- case 50: /* lfd */
- case 51: /* lfdu */
- lfd(em, op);
- break;
- case 52: /* stfs */
- case 53: /* stfsu */
- stfs(em, op);
- break;
- case 54: /* stfd */
- case 55: /* stfdu */
- stfd(em, op);
- break;
- case 31: /* indexed load/store */
- xo = getxo(op);
- if((xo & 0x300) != 0x200)
- return n;
- switch(xo){
- default:
- return n;
- case 535: /* lfsx */
- case 567: /* lfsux */
- lfsx(em, op);
- break;
- case 599: /* lfdx */
- case 631: /* lfdux */
- lfdx(em, op);
- break;
- case 663: /* stfsx */
- case 695: /* stfsux */
- stfsx(em, op);
- break;
- case 727: /* stfdx */
- case 759: /* stfdux */
- stfdx(em, op);
- break;
- }
- break;
- case 63: /* double precision */
- xo = getxo(op);
- if(op63flag[xo & 0x1F]){
- farith(em, op);
- break;
- }
- switch(xo){
- default:
- return n;
- case 0: /* fcmpu */
- case 32: /* fcmpo */
- fcmp(em, op);
- break;
- case 40: /* fneg */
- case 72: /* fmr */
- case 136: /* fnabs */
- case 264: /* fabs */
- farith2(em, op);
- break;
- case 38:
- mtfsb1(em, op);
- break;
- case 64:
- mcrfs(em, op);
- break;
- case 70:
- mtfsb0(em, op);
- break;
- case 134:
- mtfsfi(em, op);
- break;
- case 583:
- mffs(em, op);
- break;
- case 711:
- mtfsf(em, op);
- break;
- }
- break;
- case 59: /* single precision */
- fariths(em, op);
- break;
- }
- ur->pc += 4;
- if(anyhigher())
- sched();
- }
- return n;
-}
-
-/*
-50: lfd frD,d(rA)
-51: lfdu frD,d(rA)
-31,631: lfdux frD,rA,rB
-31,599: lfdx frD,rA,rB
-48: lfs frD,d(rA)
-49: lfsu frD,d(rA)
-31,567: lfsux frD,rA,rB
-31,535: lfsx frD,rA,rB
-
-54: stfd frS,d(rA)
-55: stfdu frS,d(rA)
-31,759: stfdux frS,rA,rB
-31,727: stfdx frS,rA,rB
-52: stfs frS,d(rA)
-53: stfsu frS,d(rA)
-31,695: stfsux frS,rA,rB
-31,663: stfsx frS,rA,rB
-
-63,64: mcrfs crfD,crfS
-63,583: mffs[.] frD
-63,70: mtfsb0[.] crbD
-63,38: mtfsb1[.] crbD
-63,711: mtfsf[.] FM,frB
-63,134: mtfsfi[.] crfD,IMM
-*/
-
-/*
-float to int:
- FMOVD g+0(SB),F1
- FCTIWZ F1,F4
- FMOVD F4,.rathole+0(SB)
- MOVW .rathole+4(SB),R7
- MOVW R7,l+0(SB)
-*/
-
-/*
-int to float:
- MOVW $1127219200,R9
- MOVW l+0(SB),R7
- MOVW R9,.rathole+0(SB)
- XOR $-2147483648,R7,R6
- MOVW R6,.rathole+4(SB)
- FMOVD .rathole+0(SB),F0
- FSUB F27,F0
-
-unsigned to float:
- MOVW ul+0(SB),R5
- MOVW R9,.rathole+0(SB)
- XOR $-2147483648,R5,R4
- MOVW R4,.rathole+4(SB)
- FMOVD .rathole+0(SB),F3
- FSUB F27,F3
- FCMPU F3,F28
- BGE ,3(PC)
- FMOVD $4.29496729600000000e+09,F2
- FADD F2,F3
- FMOVD F3,g+0(SB)
-*/