784 lines
12 KiB
C
784 lines
12 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <bio.h>
|
|
#include <mach.h>
|
|
#define Extern extern
|
|
#include "mips.h"
|
|
|
|
void unimp(ulong);
|
|
void Ifcmp(ulong);
|
|
void Ifdiv(ulong);
|
|
void Ifmul(ulong);
|
|
void Ifadd(ulong);
|
|
void Ifsub(ulong);
|
|
void Ifmov(ulong);
|
|
void Icvtd(ulong);
|
|
void Icvtw(ulong);
|
|
void Icvts(ulong);
|
|
void Ifabs(ulong);
|
|
void Ifneg(ulong);
|
|
|
|
Inst cop1[] = {
|
|
{ Ifadd, "add.f", Ifloat },
|
|
{ Ifsub, "sub.f", Ifloat },
|
|
{ Ifmul, "mul.f", Ifloat },
|
|
{ Ifdiv, "div.f", Ifloat },
|
|
{ unimp, "", },
|
|
{ Ifabs, "abs.f", Ifloat },
|
|
{ Ifmov, "mov.f", Ifloat },
|
|
{ Ifneg, "neg.f", Ifloat },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ Icvts, "cvt.s", Ifloat },
|
|
{ Icvtd, "cvt.d", Ifloat },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ Icvtw, "cvt.w", Ifloat },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ unimp, "", },
|
|
{ Ifcmp, "c.f", Ifloat },
|
|
{ Ifcmp, "c.un", Ifloat },
|
|
{ Ifcmp, "c.eq", Ifloat },
|
|
{ Ifcmp, "c.ueq", Ifloat },
|
|
{ Ifcmp, "c.olt", Ifloat },
|
|
{ Ifcmp, "c.ult", Ifloat },
|
|
{ Ifcmp, "c.ole", Ifloat },
|
|
{ Ifcmp, "c.ule", Ifloat },
|
|
{ Ifcmp, "c,sf", Ifloat },
|
|
{ Ifcmp, "c.ngle",Ifloat },
|
|
{ Ifcmp, "c.seq", Ifloat },
|
|
{ Ifcmp, "c.ngl", Ifloat },
|
|
{ Ifcmp, "c.lt", Ifloat },
|
|
{ Ifcmp, "c.nge", Ifloat },
|
|
{ Ifcmp, "c.le", Ifloat },
|
|
{ Ifcmp, "c.ngt", Ifloat },
|
|
{ 0 }
|
|
};
|
|
|
|
void
|
|
unimp(ulong inst)
|
|
{
|
|
print("op %ld\n", inst&0x3f);
|
|
Bprint(bioout, "Unimplemented floating point Trap IR %.8lux\n", inst);
|
|
longjmp(errjmp, 0);
|
|
}
|
|
|
|
void
|
|
inval(ulong inst)
|
|
{
|
|
Bprint(bioout, "Invalid Operation Exception IR %.8lux\n", inst);
|
|
longjmp(errjmp, 0);
|
|
}
|
|
|
|
void
|
|
ifmt(int r)
|
|
{
|
|
Bprint(bioout, "Invalid Floating Data Format f%d pc 0x%lux\n", r, reg.pc);
|
|
longjmp(errjmp, 0);
|
|
}
|
|
|
|
void
|
|
floatop(int dst, int s1, int s2)
|
|
{
|
|
if(reg.ft[s1] == FPd && s1 != 24)
|
|
ifmt(s1);
|
|
if(reg.ft[s2] == FPd && s2 != 24)
|
|
ifmt(s2);
|
|
reg.ft[dst] = FPs;
|
|
}
|
|
|
|
void
|
|
doubop(int dst, int s1, int s2)
|
|
{
|
|
ulong l;
|
|
|
|
if(reg.ft[s1] != FPd) {
|
|
if(reg.ft[s1] == FPs && s1 != 24)
|
|
ifmt(s1);
|
|
l = reg.di[s1];
|
|
reg.di[s1] = reg.di[s1+1];
|
|
reg.di[s1+1] = l;
|
|
reg.ft[s1] = FPd;
|
|
}
|
|
if(reg.ft[s2] != FPd) {
|
|
if(reg.ft[s2] == FPs && s2 != 24)
|
|
ifmt(s2);
|
|
l = reg.di[s2];
|
|
reg.di[s2] = reg.di[s2+1];
|
|
reg.di[s2+1] = l;
|
|
reg.ft[s2] = FPd;
|
|
}
|
|
reg.ft[dst] = FPd;
|
|
}
|
|
|
|
void
|
|
Iswc1(ulong inst)
|
|
{
|
|
int off;
|
|
ulong l;
|
|
int rt, rb, ert;
|
|
|
|
Getrbrt(rb, rt, inst);
|
|
off = (short)(inst&0xffff);
|
|
|
|
if(trace)
|
|
itrace("swc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
|
|
|
|
ert = rt&~1;
|
|
if(reg.ft[ert] == FPd) {
|
|
l = reg.di[ert];
|
|
reg.di[ert] = reg.di[ert+1];
|
|
reg.di[ert+1] = l;
|
|
reg.ft[ert] = FPmemory;
|
|
}
|
|
putmem_w(reg.r[rb]+off, reg.di[rt]);
|
|
}
|
|
|
|
void
|
|
Ifsub(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, ft, fd;
|
|
|
|
Getf3(fs, ft, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, ft);
|
|
reg.fl[fd] = reg.fl[fs] - reg.fl[ft];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, ft);
|
|
reg.fd[fd>>1] = reg.fd[fs>>1] - reg.fd[ft>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = reg.di[fs] - reg.di[ft];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("sub.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
|
|
}
|
|
|
|
void
|
|
Ifmov(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
reg.fl[fd] = reg.fl[fs];
|
|
reg.ft[fd] = reg.ft[fs];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
reg.fd[fd>>1] = reg.fd[fs>>1];
|
|
reg.ft[fd] = reg.ft[fs];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = reg.di[fs];
|
|
reg.ft[fd] = reg.ft[fs];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("mov.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Ifabs(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, fs);
|
|
if(reg.fl[fs] < 0.0)
|
|
reg.fl[fd] = -reg.fl[fs];
|
|
else
|
|
reg.fl[fd] = reg.fl[fs];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, fs);
|
|
if(reg.fd[fs>>1] < 0.0)
|
|
reg.fd[fd>>1] = -reg.fd[fs>>1];
|
|
else
|
|
reg.fd[fd>>1] = reg.fd[fs>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
if((long)reg.di[fs] < 0)
|
|
reg.di[fd] = -reg.di[fs];
|
|
else
|
|
reg.di[fd] = reg.di[fs];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("abs.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Ifneg(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, fs);
|
|
reg.fl[fd] = -reg.fl[fs];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, fs);
|
|
reg.fd[fd>>1] = -reg.fd[fs>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = -reg.di[fs];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("neg.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Icvtd(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fs, fs, fs);
|
|
reg.fd[fd>>1] = reg.fl[fs];
|
|
reg.ft[fd] = FPd;
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, fs);
|
|
reg.fd[fd>>1] = reg.fd[fs>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.fd[fd>>1] = (long)reg.di[fs];
|
|
reg.ft[fd] = FPd;
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("cvt.d.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Icvts(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, fs);
|
|
reg.fl[fd] = reg.fl[fs];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fs, fs, fs);
|
|
reg.fl[fd] = reg.fd[fs>>1];
|
|
reg.ft[fd] = FPs;
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.fl[fd] = (long)reg.di[fs];
|
|
reg.ft[fd] = FPs;
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("cvt.s.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Icvtw(ulong ir)
|
|
{
|
|
long v;
|
|
char fmt;
|
|
int fs, fd;
|
|
|
|
Getf2(fs, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fs, fs, fs);
|
|
v = reg.fl[fs];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fs, fs, fs);
|
|
v = reg.fd[fs>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
v = reg.di[fs];
|
|
break;
|
|
}
|
|
reg.di[fd] = v;
|
|
reg.ft[fd] = FPmemory;
|
|
if(trace)
|
|
itrace("cvt.w.%c\tf%d,f%d", fmt, fd, fs);
|
|
}
|
|
|
|
void
|
|
Ifadd(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, ft, fd;
|
|
|
|
Getf3(fs, ft, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, ft);
|
|
reg.fl[fd] = reg.fl[fs] + reg.fl[ft];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, ft);
|
|
reg.fd[fd>>1] = reg.fd[fs>>1] + reg.fd[ft>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = reg.di[fs] + reg.di[ft];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("add.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
|
|
}
|
|
|
|
void
|
|
Ifmul(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, ft, fd;
|
|
|
|
Getf3(fs, ft, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, ft);
|
|
reg.fl[fd] = reg.fl[fs] * reg.fl[ft];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, ft);
|
|
reg.fd[fd>>1] = reg.fd[fs>>1] * reg.fd[ft>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = reg.di[fs] * reg.di[ft];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("mul.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
|
|
}
|
|
|
|
void
|
|
Ifdiv(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fs, ft, fd;
|
|
|
|
Getf3(fs, ft, fd, ir);
|
|
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fd, fs, ft);
|
|
reg.fl[fd] = reg.fl[fs] / reg.fl[ft];
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fd, fs, ft);
|
|
reg.fd[fd>>1] = reg.fd[fs>>1] / reg.fd[ft>>1];
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
reg.di[fd] = reg.di[fs] / reg.di[ft];
|
|
break;
|
|
}
|
|
if(trace)
|
|
itrace("div.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
|
|
}
|
|
|
|
void
|
|
Ilwc1(ulong inst)
|
|
{
|
|
int rt, rb;
|
|
int off;
|
|
|
|
Getrbrt(rb, rt, inst);
|
|
off = (short)(inst&0xffff);
|
|
|
|
if(trace)
|
|
itrace("lwc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
|
|
|
|
reg.di[rt] = getmem_w(reg.r[rb]+off);
|
|
reg.ft[rt] = FPmemory;
|
|
}
|
|
|
|
void
|
|
Ibcfbct(ulong inst)
|
|
{
|
|
int takeit;
|
|
int off;
|
|
ulong npc;
|
|
|
|
off = (short)(inst&0xffff);
|
|
|
|
takeit = 0;
|
|
npc = reg.pc + (off<<2) + 4;
|
|
if(inst&(1<<16)) {
|
|
if(trace)
|
|
itrace("bc1t\t0x%lux", npc);
|
|
|
|
if(reg.fpsr&FP_CBIT)
|
|
takeit = 1;
|
|
}
|
|
else {
|
|
if(trace)
|
|
itrace("bc1f\t0x%lux", npc);
|
|
|
|
if((reg.fpsr&FP_CBIT) == 0)
|
|
takeit = 1;
|
|
}
|
|
|
|
if(takeit) {
|
|
/* Do the delay slot */
|
|
reg.ir = ifetch(reg.pc+4);
|
|
Statbra();
|
|
Iexec(reg.ir);
|
|
reg.pc = npc-4;
|
|
}
|
|
}
|
|
|
|
void
|
|
Imtct(ulong ir)
|
|
{
|
|
int rt, fs;
|
|
|
|
SpecialGetrtrd(rt, fs, ir);
|
|
if(ir&(1<<22)) { /* CT */
|
|
if(trace)
|
|
itrace("ctc1\tr%d,f%d", rt, fs);
|
|
}
|
|
else { /* MT */
|
|
if(trace)
|
|
itrace("mtc1\tr%d,f%d", rt, fs);
|
|
|
|
reg.di[fs] = reg.r[rt];
|
|
reg.ft[fs] = FPmemory;
|
|
}
|
|
}
|
|
|
|
void
|
|
Imfcf(ulong ir)
|
|
{
|
|
int rt, fs;
|
|
|
|
SpecialGetrtrd(rt, fs, ir);
|
|
if(ir&(1<<22)) { /* CF */
|
|
if(trace)
|
|
itrace("cfc1\tr%d,f%d", rt, fs);
|
|
}
|
|
else { /* MF */
|
|
if(trace)
|
|
itrace("mfc1\tr%d,f%d", rt, fs);
|
|
|
|
reg.r[rt] = reg.di[fs];
|
|
}
|
|
}
|
|
|
|
void
|
|
Icop1(ulong ir)
|
|
{
|
|
Inst *i;
|
|
|
|
switch((ir>>23)&7) {
|
|
case 0:
|
|
Imfcf(ir);
|
|
break;
|
|
case 1:
|
|
Imtct(ir);
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
Ibcfbct(ir);
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
i = &cop1[ir&0x3f];
|
|
i->count++;
|
|
(*i->func)(ir);
|
|
}
|
|
}
|
|
|
|
void
|
|
Ifcmp(ulong ir)
|
|
{
|
|
char fmt;
|
|
int fc;
|
|
int ft, fs;
|
|
|
|
SpecialGetrtrd(ft, fs, ir);
|
|
|
|
SET(fc);
|
|
switch((ir>>21)&0xf) {
|
|
default:
|
|
unimp(ir);
|
|
case 0: /* single */
|
|
fmt = 's';
|
|
floatop(fs, fs, ft);
|
|
if(isNaN(reg.fl[fs]) || isNaN(reg.fl[ft])) {
|
|
fc = FP_U;
|
|
break;
|
|
}
|
|
if(reg.fl[fs] == reg.fl[ft]) {
|
|
fc = FP_E;
|
|
break;
|
|
}
|
|
if(reg.fl[fs] < reg.fl[ft]) {
|
|
fc = FP_L;
|
|
break;
|
|
}
|
|
if(reg.fl[fs] > reg.fl[ft]) {
|
|
fc = FP_G;
|
|
break;
|
|
}
|
|
print("vi: bad in fcmp");
|
|
break;
|
|
case 1: /* double */
|
|
fmt = 'd';
|
|
doubop(fs, fs, ft);
|
|
if(isNaN(reg.fd[fs>>1]) || isNaN(reg.fd[ft>>1])) {
|
|
fc = FP_U;
|
|
break;
|
|
}
|
|
if(reg.fd[fs>>1] == reg.fd[ft>>1]) {
|
|
fc = FP_E;
|
|
break;
|
|
}
|
|
if(reg.fd[fs>>1] < reg.fd[ft>>1]) {
|
|
fc = FP_L;
|
|
break;
|
|
}
|
|
if(reg.fd[fs>>1] > reg.fd[ft>>1]) {
|
|
fc = FP_G;
|
|
break;
|
|
}
|
|
print("vi: bad in fcmp");
|
|
break;
|
|
case 4:
|
|
fmt = 'w';
|
|
if(reg.di[fs] == reg.di[ft]) {
|
|
fc = FP_E;
|
|
break;
|
|
}
|
|
if(reg.di[fs] < reg.di[ft]) {
|
|
fc = FP_L;
|
|
break;
|
|
}
|
|
if(reg.di[fs] > reg.di[ft]) {
|
|
fc = FP_G;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
reg.fpsr &= ~FP_CBIT;
|
|
switch(ir&0xf) {
|
|
case 0:
|
|
if(trace)
|
|
itrace("c.f.%c\tf%d,f%d", fmt, fs, ft);
|
|
break;
|
|
case 1:
|
|
if(trace)
|
|
itrace("c.un.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 2:
|
|
if(trace)
|
|
itrace("c.eq.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 3:
|
|
if(trace)
|
|
itrace("c.ueq.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 4:
|
|
if(trace)
|
|
itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_L)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 5:
|
|
if(trace)
|
|
itrace("c.ult.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_L || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 6:
|
|
if(trace)
|
|
itrace("c.le.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_L)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 7:
|
|
if(trace)
|
|
itrace("c.ule.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_L || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
break;
|
|
case 8:
|
|
if(trace)
|
|
itrace("c.sf.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 9:
|
|
if(trace)
|
|
itrace("c.ngle.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_U) {
|
|
reg.fpsr |= FP_CBIT;
|
|
inval(ir);
|
|
}
|
|
break;
|
|
case 10:
|
|
if(trace)
|
|
itrace("c.seq.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 11:
|
|
if(trace)
|
|
itrace("c.ngl.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 12:
|
|
if(trace)
|
|
itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_L)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 13:
|
|
if(trace)
|
|
itrace("c.nge.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_L || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 14:
|
|
if(trace)
|
|
itrace("c.le.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_L)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
case 15:
|
|
if(trace)
|
|
itrace("c.ngt.%c\tf%d,f%d", fmt, fs, ft);
|
|
if(fc == FP_E || fc == FP_L || fc == FP_U)
|
|
reg.fpsr |= FP_CBIT;
|
|
if(fc == FP_U)
|
|
inval(ir);
|
|
break;
|
|
}
|
|
USED(fmt);
|
|
}
|