783 lines · 12.5 KB · C
RawDownload
#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 }}; voidunimp(ulong inst){	print("op %ld\n", inst&0x3f);	Bprint(bioout, "Unimplemented floating point Trap IR %.8lux\n", inst);	longjmp(errjmp, 0);} voidinval(ulong inst){	Bprint(bioout, "Invalid Operation Exception IR %.8lux\n", inst);	longjmp(errjmp, 0);} voidifmt(int r){	Bprint(bioout, "Invalid Floating Data Format f%d pc 0x%lux\n", r, reg.pc);	longjmp(errjmp, 0);} voidfloatop(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;} voiddoubop(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;} voidIswc1(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]);} voidIfsub(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);} voidIfmov(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);} voidIfabs(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);} voidIfneg(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);} voidIcvtd(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);} voidIcvts(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);} voidIcvtw(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);} voidIfadd(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);} voidIfmul(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);} voidIfdiv(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);} voidIlwc1(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;} 

Lines 1–500 of 783.