static int printed;
/* clear pending exceptions; no traps in vfp3; all v7 ops are scalar */
- m->fpscr = Dn | Fz | FPRNR | (FPINVAL | FPZDIV | FPOVFL) & ~Alltraps;
+ m->fpscr = Dn | FPRNR | (FPINVAL | FPZDIV | FPOVFL) & ~Alltraps;
+ /* VFPv2 needs software support for underflows, so force them to zero */
+ if(m->havefp == VFPv2)
+ m->fpscr |= Fz;
fpwr(Fpscr, m->fpscr);
m->fpconfiged = 1;
{
if(p->fpstate == FPactive){
if(p->state == Moribund)
- fpclear();
+ fpoff();
else{
/*
* Fpsave() stores without handling pending
void
fpusysprocsetup(Proc *p)
{
+ int s;
+
+ s = splhi();
p->fpstate = FPinit;
fpoff();
+ splx(s);
}
static void
static void
mathemu(Ureg *)
{
- if(m->havefp == VFPv3 && !(fprd(Fpexc) & (Fpex|Fpdex)))
- iprint("mathemu: not an FP exception but an unknown FP opcode\n");
switch(up->fpstate){
case FPemu:
error("illegal instruction: VFP opcode in emulated mode");
{
int s, nfp, cop, op;
uintptr pc;
+ static int already;
if(waserror()){
postnote(up, 1, up->errstr, NDebug);
nfp = 0;
pc = ureg->pc;
validaddr(pc, 4, 0);
- if(!condok(ureg->psr, *(ulong*)pc >> 28))
- iprint("fpuemu: conditional instr shouldn't have got here\n");
op = (*(ulong *)pc >> 24) & MASK(4);
cop = (*(ulong *)pc >> 8) & MASK(4);
if(m->fpon)
fpstuck(pc); /* debugging; could move down 1 line */
if (ISFPAOP(cop, op)) { /* old arm 7500 fpa opcode? */
-// iprint("fpuemu: fpa instr %#8.8lux at %#p\n", *(ulong *)pc, pc);
-// error("illegal instruction: old arm 7500 fpa opcode");
s = spllo();
+ if(!already++)
+ pprint("warning: emulated arm7500 fpa instr %#8.8lux at %#p\n", *(ulong *)pc, pc);
if(waserror()){
splx(s);
nexterror();
m->fppc = m->fpcnt = 0;
splx(s);
poperror();
- } else if (ISVFPOP(cop, op)) { /* if vfp, fpu must be off */
+ } else if (ISVFPOP(cop, op)) { /* if vfp, fpu off or unsupported instruction */
mathemu(ureg); /* enable fpu & retry */
nfp = 1;
}