⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 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 }};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;}voidIbcfbct(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;	}}voidImtct(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;	}}voidImfcf(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];	}}voidIcop1(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);	}}voidIfcmp(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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -