xref: /plan9/sys/src/cmd/ki/float.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier #define Extern extern
63e12c5d1SDavid du Colombier #include "sparc.h"
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier void
ldf(ulong ir)93e12c5d1SDavid du Colombier ldf(ulong ir)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier 	ulong ea;
123e12c5d1SDavid du Colombier 	int rd, rs1, rs2;
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier 	getrop23(ir);
153e12c5d1SDavid du Colombier 	if(ir&IMMBIT) {
163e12c5d1SDavid du Colombier 		ximm(ea, ir);
173e12c5d1SDavid du Colombier 		if(trace)
183e12c5d1SDavid du Colombier 			itrace("ldf\tf%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
193e12c5d1SDavid du Colombier 		ea += reg.r[rs1];
203e12c5d1SDavid du Colombier 	}
213e12c5d1SDavid du Colombier 	else {
223e12c5d1SDavid du Colombier 		ea = reg.r[rs1] + reg.r[rs2];
233e12c5d1SDavid du Colombier 		if(trace)
243e12c5d1SDavid du Colombier 			itrace("ldf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
253e12c5d1SDavid du Colombier 	}
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	reg.di[rd] = getmem_w(ea);
283e12c5d1SDavid du Colombier }
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier void
lddf(ulong ir)313e12c5d1SDavid du Colombier lddf(ulong ir)
323e12c5d1SDavid du Colombier {
333e12c5d1SDavid du Colombier 	ulong ea;
343e12c5d1SDavid du Colombier 	int rd, rs1, rs2;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	getrop23(ir);
373e12c5d1SDavid du Colombier 	if(ir&IMMBIT) {
383e12c5d1SDavid du Colombier 		ximm(ea, ir);
393e12c5d1SDavid du Colombier 		if(trace)
403e12c5d1SDavid du Colombier 			itrace("lddf\tf%d,0x%lux(r%d) ea=%lux",
413e12c5d1SDavid du Colombier 							rd, ea, rs1, ea+reg.r[rs1]);
423e12c5d1SDavid du Colombier 		ea += reg.r[rs1];
433e12c5d1SDavid du Colombier 	}
443e12c5d1SDavid du Colombier 	else {
453e12c5d1SDavid du Colombier 		ea = reg.r[rs1] + reg.r[rs2];
463e12c5d1SDavid du Colombier 		if(trace)
473e12c5d1SDavid du Colombier 			itrace("lddf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
483e12c5d1SDavid du Colombier 	}
493e12c5d1SDavid du Colombier 
503e12c5d1SDavid du Colombier 	if(ea&7) {
513e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", ea);
523e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
533e12c5d1SDavid du Colombier 	}
543e12c5d1SDavid du Colombier 	if(rd&1)
553e12c5d1SDavid du Colombier 		undef(ir);
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier 	reg.di[rd] = getmem_w(ea);
583e12c5d1SDavid du Colombier 	reg.di[rd+1] = getmem_w(ea+4);
593e12c5d1SDavid du Colombier }
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier void
stf(ulong ir)623e12c5d1SDavid du Colombier stf(ulong ir)
633e12c5d1SDavid du Colombier {
643e12c5d1SDavid du Colombier 	ulong ea;
653e12c5d1SDavid du Colombier 	int rd, rs1, rs2;
663e12c5d1SDavid du Colombier 
673e12c5d1SDavid du Colombier 	getrop23(ir);
683e12c5d1SDavid du Colombier 	if(ir&IMMBIT) {
693e12c5d1SDavid du Colombier 		ximm(ea, ir);
703e12c5d1SDavid du Colombier 		if(trace)
713e12c5d1SDavid du Colombier 			itrace("stf\tf%d,0x%lux(r%d) %lux=%g",
723e12c5d1SDavid du Colombier 					rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
733e12c5d1SDavid du Colombier 		ea += reg.r[rs1];
743e12c5d1SDavid du Colombier 	}
753e12c5d1SDavid du Colombier 	else {
763e12c5d1SDavid du Colombier 		ea = reg.r[rs1] + reg.r[rs2];
773e12c5d1SDavid du Colombier 		if(trace)
783e12c5d1SDavid du Colombier 			itrace("stf\tf%d,[r%d+r%d] %lux=%lux",
793e12c5d1SDavid du Colombier 					rd, rs1, rs2, ea, reg.r[rd]);
803e12c5d1SDavid du Colombier 	}
813e12c5d1SDavid du Colombier 
823e12c5d1SDavid du Colombier 	putmem_w(ea, reg.di[rd]);
833e12c5d1SDavid du Colombier }
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier void
stdf(ulong ir)863e12c5d1SDavid du Colombier stdf(ulong ir)
873e12c5d1SDavid du Colombier {
883e12c5d1SDavid du Colombier 	ulong ea;
893e12c5d1SDavid du Colombier 	int rd, rs1, rs2;
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 	getrop23(ir);
923e12c5d1SDavid du Colombier 	if(ir&IMMBIT) {
933e12c5d1SDavid du Colombier 		ximm(ea, ir);
943e12c5d1SDavid du Colombier 		if(trace)
953e12c5d1SDavid du Colombier 			itrace("stdf\tf%d,0x%lux(r%d) %lux=%g",
963e12c5d1SDavid du Colombier 					rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
973e12c5d1SDavid du Colombier 		ea += reg.r[rs1];
983e12c5d1SDavid du Colombier 	}
993e12c5d1SDavid du Colombier 	else {
1003e12c5d1SDavid du Colombier 		ea = reg.r[rs1] + reg.r[rs2];
1013e12c5d1SDavid du Colombier 		if(trace)
1023e12c5d1SDavid du Colombier 			itrace("stdf\tf%d,[r%d+r%d] %lux=%lux",
1033e12c5d1SDavid du Colombier 					rd, rs1, rs2, ea, reg.r[rd]);
1043e12c5d1SDavid du Colombier 	}
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	if(ea&7) {
1073e12c5d1SDavid du Colombier 		Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", ea);
1083e12c5d1SDavid du Colombier 		longjmp(errjmp, 0);
1093e12c5d1SDavid du Colombier 	}
1103e12c5d1SDavid du Colombier 	if(rd&1)
1113e12c5d1SDavid du Colombier 		undef(ir);
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier 	putmem_w(ea, reg.di[rd]);
1143e12c5d1SDavid du Colombier 	putmem_w(ea+4, reg.di[rd+1]);
1153e12c5d1SDavid du Colombier }
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier void
fcmp(ulong ir)1183e12c5d1SDavid du Colombier fcmp(ulong ir)
1193e12c5d1SDavid du Colombier {
1203e12c5d1SDavid du Colombier 	int fc, rd, rs1, rs2;
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier 	getrop23(ir);
1233e12c5d1SDavid du Colombier 	USED(rd);
1243e12c5d1SDavid du Colombier 	SET(fc);
1253e12c5d1SDavid du Colombier 	switch((ir>>5)&0x1FF) {
1263e12c5d1SDavid du Colombier 	default:
1273e12c5d1SDavid du Colombier 		undef(ir);
1283e12c5d1SDavid du Colombier 	case 0x51:		/* fcmps */
1293e12c5d1SDavid du Colombier 		if(trace)
1303e12c5d1SDavid du Colombier 			itrace("fcmps\tf%d,f%d", rs1, rs2);
1313e12c5d1SDavid du Colombier 		if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
1323e12c5d1SDavid du Colombier 			fc = 3;
1333e12c5d1SDavid du Colombier 			break;
1343e12c5d1SDavid du Colombier 		}
1353e12c5d1SDavid du Colombier 		if(reg.fl[rs1] == reg.fl[rs2]) {
1363e12c5d1SDavid du Colombier 			fc = 0;
1373e12c5d1SDavid du Colombier 			break;
1383e12c5d1SDavid du Colombier 		}
1393e12c5d1SDavid du Colombier 		if(reg.fl[rs1] < reg.fl[rs2]) {
1403e12c5d1SDavid du Colombier 			fc = 1;
1413e12c5d1SDavid du Colombier 			break;
1423e12c5d1SDavid du Colombier 		}
1433e12c5d1SDavid du Colombier 		if(reg.fl[rs1] > reg.fl[rs2]) {
1443e12c5d1SDavid du Colombier 			fc = 2;
1453e12c5d1SDavid du Colombier 			break;
1463e12c5d1SDavid du Colombier 		}
1473e12c5d1SDavid du Colombier 		print("ki: fcmp error\n");
1483e12c5d1SDavid du Colombier 		break;
1493e12c5d1SDavid du Colombier 	case 0x52:
1503e12c5d1SDavid du Colombier 		if(trace)
1513e12c5d1SDavid du Colombier 			itrace("fcmpd\tf%d,f%d", rs1, rs2);
1523e12c5d1SDavid du Colombier 		rs1 >>= 1;
1533e12c5d1SDavid du Colombier 		rs2 >>= 1;
1543e12c5d1SDavid du Colombier 		if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
1553e12c5d1SDavid du Colombier 			fc = 3;
1563e12c5d1SDavid du Colombier 			break;
1573e12c5d1SDavid du Colombier 		}
1583e12c5d1SDavid du Colombier 		if(reg.fd[rs1] == reg.fd[rs2]) {
1593e12c5d1SDavid du Colombier 			fc = 0;
1603e12c5d1SDavid du Colombier 			break;
1613e12c5d1SDavid du Colombier 		}
1623e12c5d1SDavid du Colombier 		if(reg.fd[rs1] < reg.fd[rs2]) {
1633e12c5d1SDavid du Colombier 			fc = 1;
1643e12c5d1SDavid du Colombier 			break;
1653e12c5d1SDavid du Colombier 		}
1663e12c5d1SDavid du Colombier 		if(reg.fd[rs1] > reg.fd[rs2]) {
1673e12c5d1SDavid du Colombier 			fc = 2;
1683e12c5d1SDavid du Colombier 			break;
1693e12c5d1SDavid du Colombier 		}
1703e12c5d1SDavid du Colombier 		print("ki: fcmp error\n");
1713e12c5d1SDavid du Colombier 		break;
1723e12c5d1SDavid du Colombier 	case 0x55:		/* fcmpes */
1733e12c5d1SDavid du Colombier 		if(trace)
1743e12c5d1SDavid du Colombier 			itrace("fcmpes\tf%d,f%d", rs1, rs2);
1753e12c5d1SDavid du Colombier 		rs1 >>= 1;
1763e12c5d1SDavid du Colombier 		rs2 >>= 2;
1773e12c5d1SDavid du Colombier 		if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
1783e12c5d1SDavid du Colombier 			Bprint(bioout, "invalid_fp_register\n");
1793e12c5d1SDavid du Colombier 			longjmp(errjmp, 0);
1803e12c5d1SDavid du Colombier 		}
1813e12c5d1SDavid du Colombier 		if(reg.fl[rs1] == reg.fl[rs2]) {
1823e12c5d1SDavid du Colombier 			fc = 0;
1833e12c5d1SDavid du Colombier 			break;
1843e12c5d1SDavid du Colombier 		}
1853e12c5d1SDavid du Colombier 		if(reg.fl[rs1] < reg.fl[rs2]) {
1863e12c5d1SDavid du Colombier 			fc = 1;
1873e12c5d1SDavid du Colombier 			break;
1883e12c5d1SDavid du Colombier 		}
1893e12c5d1SDavid du Colombier 		if(reg.fl[rs1] > reg.fl[rs2]) {
1903e12c5d1SDavid du Colombier 			fc = 2;
1913e12c5d1SDavid du Colombier 			break;
1923e12c5d1SDavid du Colombier 		}
1933e12c5d1SDavid du Colombier 		print("ki: fcmp error\n");
1943e12c5d1SDavid du Colombier 		break;
1953e12c5d1SDavid du Colombier 	case 0x56:
1963e12c5d1SDavid du Colombier 		if(trace)
1973e12c5d1SDavid du Colombier 			itrace("fcmped\tf%d,f%d", rs1, rs2);
1983e12c5d1SDavid du Colombier 		if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
1993e12c5d1SDavid du Colombier 			Bprint(bioout, "invalid_fp_register\n");
2003e12c5d1SDavid du Colombier 			longjmp(errjmp, 0);
2013e12c5d1SDavid du Colombier 		}
2023e12c5d1SDavid du Colombier 		if(reg.fd[rs1] == reg.fd[rs2]) {
2033e12c5d1SDavid du Colombier 			fc = 0;
2043e12c5d1SDavid du Colombier 			break;
2053e12c5d1SDavid du Colombier 		}
2063e12c5d1SDavid du Colombier 		if(reg.fd[rs1] < reg.fd[rs2]) {
2073e12c5d1SDavid du Colombier 			fc = 1;
2083e12c5d1SDavid du Colombier 			break;
2093e12c5d1SDavid du Colombier 		}
2103e12c5d1SDavid du Colombier 		if(reg.fd[rs1] > reg.fd[rs2]) {
2113e12c5d1SDavid du Colombier 			fc = 2;
2123e12c5d1SDavid du Colombier 			break;
2133e12c5d1SDavid du Colombier 		}
2143e12c5d1SDavid du Colombier 		print("ki: fcmp error\n");
2153e12c5d1SDavid du Colombier 		break;
2163e12c5d1SDavid du Colombier 
2173e12c5d1SDavid du Colombier 	}
2183e12c5d1SDavid du Colombier 	reg.fpsr = (reg.fpsr&~(0x3<<10)) | (fc<<10);
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier void
fbcc(ulong ir)2223e12c5d1SDavid du Colombier fbcc(ulong ir)
2233e12c5d1SDavid du Colombier {
2243e12c5d1SDavid du Colombier 	char *op;
2253e12c5d1SDavid du Colombier 	ulong npc;
2263e12c5d1SDavid du Colombier 	int takeit, fc, ba, anul;
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	fc = (reg.fpsr>>10)&3;
2293e12c5d1SDavid du Colombier 	ba = 0;
2303e12c5d1SDavid du Colombier 	SET(op, takeit);
2313e12c5d1SDavid du Colombier 	switch((ir>>25)&0x0F) {
2323e12c5d1SDavid du Colombier 	case 0:
2333e12c5d1SDavid du Colombier 		op = "fbn";
2343e12c5d1SDavid du Colombier 		takeit = 0;
2353e12c5d1SDavid du Colombier 		break;
2363e12c5d1SDavid du Colombier 	case 1:
2373e12c5d1SDavid du Colombier 		op = "fbne";
2383e12c5d1SDavid du Colombier 		takeit = fc == FP_L || fc == FP_G || fc == FP_U;
2393e12c5d1SDavid du Colombier 		break;
2403e12c5d1SDavid du Colombier 	case 2:
2413e12c5d1SDavid du Colombier 		op = "fblg";
2423e12c5d1SDavid du Colombier 		takeit = fc == FP_L || fc == FP_G;
2433e12c5d1SDavid du Colombier 		break;
2443e12c5d1SDavid du Colombier 	case 3:
2453e12c5d1SDavid du Colombier 		op = "fbul";
2463e12c5d1SDavid du Colombier 		takeit = fc == FP_L || fc == FP_U;
2473e12c5d1SDavid du Colombier 		break;
2483e12c5d1SDavid du Colombier 	case 4:
2493e12c5d1SDavid du Colombier 		op = "fbl";
2503e12c5d1SDavid du Colombier 		takeit = fc == FP_L;
2513e12c5d1SDavid du Colombier 		break;
2523e12c5d1SDavid du Colombier 	case 5:
2533e12c5d1SDavid du Colombier 		op = "fbug";
2543e12c5d1SDavid du Colombier 		takeit = fc == FP_U || fc == FP_G;
2553e12c5d1SDavid du Colombier 		break;
2563e12c5d1SDavid du Colombier 	case 6:
2573e12c5d1SDavid du Colombier 		op = "fbg";
2583e12c5d1SDavid du Colombier 		takeit = fc == FP_G;
2593e12c5d1SDavid du Colombier 		break;
2603e12c5d1SDavid du Colombier 	case 7:
2613e12c5d1SDavid du Colombier 		op = "fbu";
2623e12c5d1SDavid du Colombier 		takeit = fc == FP_U;
2633e12c5d1SDavid du Colombier 		break;
2643e12c5d1SDavid du Colombier 	case 8:
2653e12c5d1SDavid du Colombier 		op = "fba";
2663e12c5d1SDavid du Colombier 		ba = 1;
2673e12c5d1SDavid du Colombier 		takeit = 1;
2683e12c5d1SDavid du Colombier 		break;
2693e12c5d1SDavid du Colombier 	case 9:
2703e12c5d1SDavid du Colombier 		op = "fbe";
2713e12c5d1SDavid du Colombier 		takeit = fc == FP_E;
2723e12c5d1SDavid du Colombier 		break;
2733e12c5d1SDavid du Colombier 	case 10:
2743e12c5d1SDavid du Colombier 		op = "fbue";
2753e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_U;
2763e12c5d1SDavid du Colombier 		break;
2773e12c5d1SDavid du Colombier 	case 11:
2783e12c5d1SDavid du Colombier 		op = "fbge";
2793e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_G;
2803e12c5d1SDavid du Colombier 		break;
2813e12c5d1SDavid du Colombier 	case 12:
2823e12c5d1SDavid du Colombier 		op = "fbuge";
2833e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_G || fc == FP_U;
2843e12c5d1SDavid du Colombier 		break;
2853e12c5d1SDavid du Colombier 	case 13:
2863e12c5d1SDavid du Colombier 		op = "fble";
2873e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_L;
2883e12c5d1SDavid du Colombier 		break;
2893e12c5d1SDavid du Colombier 	case 14:
2903e12c5d1SDavid du Colombier 		op = "fbule";
2913e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_L || fc == FP_U;
2923e12c5d1SDavid du Colombier 		break;
2933e12c5d1SDavid du Colombier 	case 15:
2943e12c5d1SDavid du Colombier 		op = "fbo";
2953e12c5d1SDavid du Colombier 		takeit = fc == FP_E || fc == FP_L || fc == FP_G;
2963e12c5d1SDavid du Colombier 		break;
2973e12c5d1SDavid du Colombier 	}
2983e12c5d1SDavid du Colombier 
2993e12c5d1SDavid du Colombier 	npc = ir & 0x3FFFFF;
3003e12c5d1SDavid du Colombier 	if(npc & (1<<21))
3013e12c5d1SDavid du Colombier 		npc |= ~((1<<22)-1);
3023e12c5d1SDavid du Colombier 	npc = (npc<<2) + reg.pc;
3033e12c5d1SDavid du Colombier 
3043e12c5d1SDavid du Colombier 	anul = ir&ANUL;
3053e12c5d1SDavid du Colombier 	if(trace) {
3063e12c5d1SDavid du Colombier 		if(anul)
3073e12c5d1SDavid du Colombier 			itrace("%s,a\t%lux", op, npc);
3083e12c5d1SDavid du Colombier 		else
3093e12c5d1SDavid du Colombier 			itrace("%s\t%lux", op, npc);
3103e12c5d1SDavid du Colombier 	}
3113e12c5d1SDavid du Colombier 
3123e12c5d1SDavid du Colombier 	if(takeit == 0) {
3133e12c5d1SDavid du Colombier 		reg.pc += 4;
3143e12c5d1SDavid du Colombier 		if(anul == 0) {
3153e12c5d1SDavid du Colombier 			reg.ir = ifetch(reg.pc);
316bd389b36SDavid du Colombier 			delay(reg.pc+4);
3173e12c5d1SDavid du Colombier 		}
3183e12c5d1SDavid du Colombier 		else
3193e12c5d1SDavid du Colombier 			anulled++;
3203e12c5d1SDavid du Colombier 		return;
3213e12c5d1SDavid du Colombier 	}
3223e12c5d1SDavid du Colombier 
3233e12c5d1SDavid du Colombier 	ci->taken++;
3243e12c5d1SDavid du Colombier 	if(ba && anul) {
3253e12c5d1SDavid du Colombier 		reg.pc = npc-4;
3263e12c5d1SDavid du Colombier 		anulled++;
3273e12c5d1SDavid du Colombier 		return;
3283e12c5d1SDavid du Colombier 	}
3293e12c5d1SDavid du Colombier 	reg.ir = ifetch(reg.pc+4);
330bd389b36SDavid du Colombier 	delay(npc);
3313e12c5d1SDavid du Colombier 	reg.pc = npc-4;
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier void
farith(ulong ir)3353e12c5d1SDavid du Colombier farith(ulong ir)
3363e12c5d1SDavid du Colombier {
3373e12c5d1SDavid du Colombier 	char *op;
338*219b2ee8SDavid du Colombier 	long v;
3393e12c5d1SDavid du Colombier 	int rd, rs1, rs2, fmt;
3403e12c5d1SDavid du Colombier 
3413e12c5d1SDavid du Colombier 	fmt = 0;
3423e12c5d1SDavid du Colombier 	getrop23(ir);
3433e12c5d1SDavid du Colombier 	switch((ir>>5)&0x1FF) {
3443e12c5d1SDavid du Colombier 	default:
3453e12c5d1SDavid du Colombier 		undef(ir);
3463e12c5d1SDavid du Colombier 	case 0x41:
3473e12c5d1SDavid du Colombier 		reg.fl[rd] = reg.fl[rs1] + reg.fl[rs2];
3483e12c5d1SDavid du Colombier 		op = "fadds";
3493e12c5d1SDavid du Colombier 		break;
3503e12c5d1SDavid du Colombier 	case 0x42:
3513e12c5d1SDavid du Colombier 		reg.fd[rd>>1] = reg.fd[rs1>>1] + reg.fd[rs2>>1];
3523e12c5d1SDavid du Colombier 		op = "faddd";
3533e12c5d1SDavid du Colombier 		break;
3543e12c5d1SDavid du Colombier 	case 0x45:
3553e12c5d1SDavid du Colombier 		reg.fl[rd] = reg.fl[rs1] - reg.fl[rs2];
3563e12c5d1SDavid du Colombier 		op = "fsubs";
3573e12c5d1SDavid du Colombier 		break;
3583e12c5d1SDavid du Colombier 	case 0x46:
3593e12c5d1SDavid du Colombier 		reg.fd[rd>>1] = reg.fd[rs1>>1] - reg.fd[rs2>>1];
3603e12c5d1SDavid du Colombier 		op = "fsubd";
3613e12c5d1SDavid du Colombier 		break;
3623e12c5d1SDavid du Colombier 	case 0x4d:
3633e12c5d1SDavid du Colombier 		if(reg.fl[rs2] == 0.0) {
3643e12c5d1SDavid du Colombier 			Bprint(bioout, "fp_exception DZ\n");
3653e12c5d1SDavid du Colombier 			longjmp(errjmp, 0);
3663e12c5d1SDavid du Colombier 		}
3673e12c5d1SDavid du Colombier 		reg.fl[rd] = reg.fl[rs1] / reg.fl[rs2];
3683e12c5d1SDavid du Colombier 		op = "fdivs";
3693e12c5d1SDavid du Colombier 		break;
3703e12c5d1SDavid du Colombier 	case 0x4e:
3713e12c5d1SDavid du Colombier 		if(reg.fd[rs2>>1] == 0.0) {
3723e12c5d1SDavid du Colombier 			Bprint(bioout, "fp_exception DZ\n");
3733e12c5d1SDavid du Colombier 			longjmp(errjmp, 0);
3743e12c5d1SDavid du Colombier 		}
3753e12c5d1SDavid du Colombier 		reg.fd[rd>>1] = reg.fd[rs1>>1] / reg.fd[rs2>>1];
3763e12c5d1SDavid du Colombier 		op = "fdivd";
3773e12c5d1SDavid du Colombier 		break;
3783e12c5d1SDavid du Colombier 	case 0x49:
3793e12c5d1SDavid du Colombier 		reg.fl[rd] = reg.fl[rs1] * reg.fl[rs2];
3803e12c5d1SDavid du Colombier 		op = "fmuls";
3813e12c5d1SDavid du Colombier 		break;
3823e12c5d1SDavid du Colombier 	case 0x4a:
3833e12c5d1SDavid du Colombier 		reg.fd[rd>>1] = reg.fd[rs1>>1] * reg.fd[rs2>>1];
3843e12c5d1SDavid du Colombier 		op = "fmuld";
3853e12c5d1SDavid du Colombier 		break;
3863e12c5d1SDavid du Colombier 	case 0xc4:
387*219b2ee8SDavid du Colombier 		reg.fl[rd] = (long)reg.di[rs2];
3883e12c5d1SDavid du Colombier 		fmt = 1;
3893e12c5d1SDavid du Colombier 		op = "fitos";
3903e12c5d1SDavid du Colombier 		break;
3913e12c5d1SDavid du Colombier 	case 0xc8:
392*219b2ee8SDavid du Colombier 		reg.fd[rd>>1] = (long)reg.di[rs2];
3933e12c5d1SDavid du Colombier 		fmt = 1;
3943e12c5d1SDavid du Colombier 		op = "fitod";
3953e12c5d1SDavid du Colombier 		break;
3963e12c5d1SDavid du Colombier 	case 0xd1:
397*219b2ee8SDavid du Colombier 		v = reg.fl[rs2];
398*219b2ee8SDavid du Colombier 		reg.di[rd] = v;
3993e12c5d1SDavid du Colombier 		fmt = 1;
4003e12c5d1SDavid du Colombier 		op = "fstoi";
4013e12c5d1SDavid du Colombier 		break;
4023e12c5d1SDavid du Colombier 	case 0xd2:
403*219b2ee8SDavid du Colombier 		v = reg.fd[rs2>>1];
404*219b2ee8SDavid du Colombier 		reg.di[rd] = v;
4053e12c5d1SDavid du Colombier 		fmt = 1;
4063e12c5d1SDavid du Colombier 		op = "fdtoi";
4073e12c5d1SDavid du Colombier 		break;
4083e12c5d1SDavid du Colombier 	case 0x01:
4093e12c5d1SDavid du Colombier 		reg.di[rd] = reg.di[rs2];
4103e12c5d1SDavid du Colombier 		fmt = 1;
4113e12c5d1SDavid du Colombier 		op = "fmovs";
4123e12c5d1SDavid du Colombier 		break;
4133e12c5d1SDavid du Colombier 	case 0x05:
4143e12c5d1SDavid du Colombier 		reg.fl[rd] = -reg.fl[rs2];
4153e12c5d1SDavid du Colombier 		fmt = 1;
4163e12c5d1SDavid du Colombier 		op = "fnegs";
4173e12c5d1SDavid du Colombier 		break;
4183e12c5d1SDavid du Colombier 	case 0x09:
4193e12c5d1SDavid du Colombier 		reg.fl[rd] = fabs(reg.fl[rs2]);
4203e12c5d1SDavid du Colombier 		fmt = 1;
4213e12c5d1SDavid du Colombier 		op = "fabss";
4223e12c5d1SDavid du Colombier 		break;
4233e12c5d1SDavid du Colombier 	case 0xc9:
4243e12c5d1SDavid du Colombier 		reg.fd[rd>>1] = reg.fl[rs2];
4253e12c5d1SDavid du Colombier 		fmt = 1;
4263e12c5d1SDavid du Colombier 		op = "fstod";
4273e12c5d1SDavid du Colombier 		break;
4283e12c5d1SDavid du Colombier 	case 0xc6:
4293e12c5d1SDavid du Colombier 		reg.fl[rd] = reg.fd[rs2>>1];
4303e12c5d1SDavid du Colombier 		fmt = 1;
4313e12c5d1SDavid du Colombier 		op = "fdtos";
4323e12c5d1SDavid du Colombier 		break;
4333e12c5d1SDavid du Colombier 	}
4343e12c5d1SDavid du Colombier 
4353e12c5d1SDavid du Colombier 	if(trace) {
4363e12c5d1SDavid du Colombier 		switch(fmt) {
4373e12c5d1SDavid du Colombier 		case 0:
4383e12c5d1SDavid du Colombier 			itrace("%s\tf%d,f%d,f%d", op, rs1, rs2, rd);
4393e12c5d1SDavid du Colombier 			break;
4403e12c5d1SDavid du Colombier 		case 1:
4413e12c5d1SDavid du Colombier 			itrace("%s\tf%d,f%d", op, rs2, rd);
4423e12c5d1SDavid du Colombier 			break;
4433e12c5d1SDavid du Colombier 		}
4443e12c5d1SDavid du Colombier 	}
4453e12c5d1SDavid du Colombier }
446