xref: /plan9/sys/src/cmd/qi/iu.c (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
17d9195a7SDavid du Colombier #include <u.h>
27d9195a7SDavid du Colombier #include <libc.h>
37d9195a7SDavid du Colombier #include <bio.h>
47d9195a7SDavid du Colombier #include <mach.h>
57d9195a7SDavid du Colombier #define Extern extern
67d9195a7SDavid du Colombier #include "power.h"
77d9195a7SDavid du Colombier 
87d9195a7SDavid du Colombier void	add(ulong);
97d9195a7SDavid du Colombier void	addc(ulong);
107d9195a7SDavid du Colombier void	adde(ulong);
117d9195a7SDavid du Colombier void	addme(ulong);
127d9195a7SDavid du Colombier void	addze(ulong);
137d9195a7SDavid du Colombier void	and(ulong);
147d9195a7SDavid du Colombier void	andc(ulong);
157d9195a7SDavid du Colombier void	cmp(ulong);
167d9195a7SDavid du Colombier void	cmpl(ulong);
177d9195a7SDavid du Colombier void	cntlzw(ulong);
187d9195a7SDavid du Colombier void	dcbf(ulong);
197d9195a7SDavid du Colombier void	dcbi(ulong);
207d9195a7SDavid du Colombier void	dcbst(ulong);
217d9195a7SDavid du Colombier void	dcbt(ulong);
227d9195a7SDavid du Colombier void	dcbtst(ulong);
237d9195a7SDavid du Colombier void	dcbz(ulong);
247d9195a7SDavid du Colombier void	divw(ulong);
257d9195a7SDavid du Colombier void	divwu(ulong);
267d9195a7SDavid du Colombier void	eciwx(ulong);
277d9195a7SDavid du Colombier void	ecowx(ulong);
287d9195a7SDavid du Colombier void	eieio(ulong);
297d9195a7SDavid du Colombier void	eqv(ulong);
307d9195a7SDavid du Colombier void	extsb(ulong);
317d9195a7SDavid du Colombier void	extsh(ulong);
327d9195a7SDavid du Colombier void	icbi(ulong);
337d9195a7SDavid du Colombier void	lbzx(ulong);
347d9195a7SDavid du Colombier void	lfdx(ulong);
357d9195a7SDavid du Colombier void	lfsx(ulong);
367d9195a7SDavid du Colombier void	lhax(ulong);
377d9195a7SDavid du Colombier void	lhbrx(ulong);
387d9195a7SDavid du Colombier void	lhzx(ulong);
397d9195a7SDavid du Colombier void	lswi(ulong);
407d9195a7SDavid du Colombier void	lswx(ulong);
417d9195a7SDavid du Colombier void	lwarx(ulong);
427d9195a7SDavid du Colombier void	lwbrx(ulong);
437d9195a7SDavid du Colombier void	lwzx(ulong);
447d9195a7SDavid du Colombier void	mcrxr(ulong);
457d9195a7SDavid du Colombier void	mfcr(ulong);
467d9195a7SDavid du Colombier void	mfmsr(ulong);
477d9195a7SDavid du Colombier void	mfpmr(ulong);
487d9195a7SDavid du Colombier void	mfspr(ulong);
497d9195a7SDavid du Colombier void	mfsr(ulong);
507d9195a7SDavid du Colombier void	mfsrin(ulong);
517d9195a7SDavid du Colombier void	mftb(ulong);
527d9195a7SDavid du Colombier void	mftbu(ulong);
537d9195a7SDavid du Colombier void	mspr(ulong);
547d9195a7SDavid du Colombier void	mtcrf(ulong);
557d9195a7SDavid du Colombier void	mtmsr(ulong);
567d9195a7SDavid du Colombier void	mtpmr(ulong);
577d9195a7SDavid du Colombier void	mtspr(ulong);
587d9195a7SDavid du Colombier void	mtsr(ulong);
597d9195a7SDavid du Colombier void	mtsrin(ulong);
607d9195a7SDavid du Colombier void	mttb(ulong);
617d9195a7SDavid du Colombier void	mttbu(ulong);
627d9195a7SDavid du Colombier void	mulhw(ulong);
637d9195a7SDavid du Colombier void	mulhwu(ulong);
647d9195a7SDavid du Colombier void	mullw(ulong);
657d9195a7SDavid du Colombier void	nand(ulong);
667d9195a7SDavid du Colombier void	neg(ulong);
677d9195a7SDavid du Colombier void	nor(ulong);
687d9195a7SDavid du Colombier void	or(ulong);
697d9195a7SDavid du Colombier void	orc(ulong);
707d9195a7SDavid du Colombier void	slbia(ulong);
717d9195a7SDavid du Colombier void	slbia(ulong);
727d9195a7SDavid du Colombier void	slw(ulong);
737d9195a7SDavid du Colombier void	sraw(ulong);
747d9195a7SDavid du Colombier void	srawi(ulong);
757d9195a7SDavid du Colombier void	srw(ulong);
767d9195a7SDavid du Colombier void	stbx(ulong);
777d9195a7SDavid du Colombier void	stfdx(ulong);
787d9195a7SDavid du Colombier void	stfiwx(ulong);
797d9195a7SDavid du Colombier void	stfsx(ulong);
807d9195a7SDavid du Colombier void	sthbrx(ulong);
817d9195a7SDavid du Colombier void	sthx(ulong);
827d9195a7SDavid du Colombier void	stswi(ulong);
837d9195a7SDavid du Colombier void	stswx(ulong);
847d9195a7SDavid du Colombier void	stwbrx(ulong);
857d9195a7SDavid du Colombier void	stwcx(ulong);
867d9195a7SDavid du Colombier void	stwx(ulong);
877d9195a7SDavid du Colombier void	subf(ulong);
887d9195a7SDavid du Colombier void	subfc(ulong);
897d9195a7SDavid du Colombier void	subfe(ulong);
907d9195a7SDavid du Colombier void	subfme(ulong);
917d9195a7SDavid du Colombier void	subfze(ulong);
927d9195a7SDavid du Colombier void	sync(ulong);
937d9195a7SDavid du Colombier void	tlbie(ulong);
947d9195a7SDavid du Colombier void	tw(ulong);
957d9195a7SDavid du Colombier void	xor(ulong);
967d9195a7SDavid du Colombier 
977d9195a7SDavid du Colombier Inst	op31[] = {
987d9195a7SDavid du Colombier [0] {cmp, "cmp", Iarith},
997d9195a7SDavid du Colombier [4] {tw, "tw", Iarith},
1007d9195a7SDavid du Colombier [8] {subfc, "subfc", Iarith},
1017d9195a7SDavid du Colombier [10] {addc, "addc", Iarith},
1027d9195a7SDavid du Colombier [11] {mulhwu, "mulhwu", Iarith},
1037d9195a7SDavid du Colombier [19] {mfcr, "mfcr", Iarith},
1047d9195a7SDavid du Colombier [20] {lwarx, "lwarx", Iload},
1057d9195a7SDavid du Colombier [23] {lwzx, "lwzx", Iload},
1067d9195a7SDavid du Colombier [24] {slw, "slw", Ilog},
1077d9195a7SDavid du Colombier [26] {cntlzw, "cntlzw", Ilog},
1087d9195a7SDavid du Colombier [28] {and, "and", Ilog},
1097d9195a7SDavid du Colombier [32] {cmpl, "cmpl", Iarith},
1107d9195a7SDavid du Colombier [40] {subf, "subf", Iarith},
1117d9195a7SDavid du Colombier [54] {dcbst, "dcbst", Icontrol},
1127d9195a7SDavid du Colombier [55] {lwzx, "lwzux", Iload},
1137d9195a7SDavid du Colombier [60] {andc, "andc", Ilog},
1147d9195a7SDavid du Colombier [75] {mulhw, "mulhw", Iarith},
1157d9195a7SDavid du Colombier [83] {0, "mfmsr", Icontrol},
1167d9195a7SDavid du Colombier [86] {dcbf, "dcbf", Icontrol},
1177d9195a7SDavid du Colombier [87] {lbzx, "lbzx", Iload},
1187d9195a7SDavid du Colombier [104] {neg, "neg", Iarith},
1197d9195a7SDavid du Colombier [115] {0, "mfpmr", Iarith},
1207d9195a7SDavid du Colombier [119] {lbzx, "lbzux", Iload},
1217d9195a7SDavid du Colombier [124] {nor, "nor", Iarith},
1227d9195a7SDavid du Colombier [136] {subfe, "subfe", Iarith},
1237d9195a7SDavid du Colombier [138] {adde, "adde", Iarith},
1247d9195a7SDavid du Colombier [144] {mtcrf, "mtcrf", Ireg},
1257d9195a7SDavid du Colombier [146] {0, "mtmsr", Icontrol},
1267d9195a7SDavid du Colombier [150] {stwcx, "stwcx.", Istore},
1277d9195a7SDavid du Colombier [151] {stwx, "stwx", Istore},
1287d9195a7SDavid du Colombier [178] {0, "mtpmr", Icontrol},
1297d9195a7SDavid du Colombier [183] {stwx, "stwux", Istore},
1307d9195a7SDavid du Colombier [200] {subfze, "subfze", Iarith},
1317d9195a7SDavid du Colombier [202] {addze, "addze", Iarith},
1327d9195a7SDavid du Colombier [210] {0, "mtsr", Ireg},
1337d9195a7SDavid du Colombier [215] {stbx, "stbx", Istore},
1347d9195a7SDavid du Colombier [232] {subfme, "subfme", Iarith},
1357d9195a7SDavid du Colombier [234] {addme, "addme", Iarith},
1367d9195a7SDavid du Colombier [235] {mullw, "mullw", Iarith},
1377d9195a7SDavid du Colombier [242] {0, "mtsrin", Ireg},
1387d9195a7SDavid du Colombier [246] {dcbtst, "dcbtst", Icontrol},
1397d9195a7SDavid du Colombier [247] {stbx, "stbux", Istore},
1407d9195a7SDavid du Colombier [266] {add, "add", Iarith},
1417d9195a7SDavid du Colombier [275] {0, "mftb", Icontrol},
1427d9195a7SDavid du Colombier [278] {dcbt, "dcbt", Icontrol},
1437d9195a7SDavid du Colombier [279] {lhzx, "lhzx", Iload},
1447d9195a7SDavid du Colombier [284] {eqv, "eqv", Ilog},
1457d9195a7SDavid du Colombier [306] {0, "tlbie", Icontrol},
1467d9195a7SDavid du Colombier [307] {0, "mftbu", Icontrol},
1477d9195a7SDavid du Colombier [310] {0, "eciwx", Icontrol},
1487d9195a7SDavid du Colombier [311] {lhzx, "lhzux", Iload},
1497d9195a7SDavid du Colombier [316] {xor, "xor", Ilog},
1507d9195a7SDavid du Colombier [339] {mspr, "mfspr", Ireg},
1517d9195a7SDavid du Colombier [343] {lhax, "lhax", Iload},
1527d9195a7SDavid du Colombier [375] {lhax, "lhaux", Iload},
1537d9195a7SDavid du Colombier [403] {0, "mttb", Icontrol},
1547d9195a7SDavid du Colombier [407] {sthx, "sthx", Istore},
1557d9195a7SDavid du Colombier [412] {orc, "orc", Ilog},
1567d9195a7SDavid du Colombier [434] {0, "slbia", Iarith},
1577d9195a7SDavid du Colombier [435] {0, "mttbu", Icontrol},
1587d9195a7SDavid du Colombier [438] {0, "ecowx", Icontrol},
1597d9195a7SDavid du Colombier [439] {sthx, "sthux", Istore},
1607d9195a7SDavid du Colombier [444] {or, "or", Ilog},
1617d9195a7SDavid du Colombier [459] {divwu, "divwu", Iarith},
1627d9195a7SDavid du Colombier [467] {mspr, "mtspr", Ireg},
1637d9195a7SDavid du Colombier [470] {0, "dcbi", Icontrol},
1647d9195a7SDavid du Colombier [476] {nand, "nand", Ilog},
1657d9195a7SDavid du Colombier [491] {divw, "divw", Iarith},
1667d9195a7SDavid du Colombier [498] {0, "slbia", Icontrol},
1677d9195a7SDavid du Colombier [512] {mcrxr, "mcrxr", Ireg},
1687d9195a7SDavid du Colombier [533] {lswx, "lswx", Iload},
1697d9195a7SDavid du Colombier [534] {lwbrx, "lwbrx", Iload},
1707d9195a7SDavid du Colombier [535] {lfsx, "lfsx", Ifloat},
1717d9195a7SDavid du Colombier [536] {srw, "srw", Ilog},
1727d9195a7SDavid du Colombier [567] {lfsx, "lfsux", Ifloat},
1737d9195a7SDavid du Colombier [595] {0, "mfsr", Iarith},
1747d9195a7SDavid du Colombier [597] {lswi, "lswi", Iarith},
1757d9195a7SDavid du Colombier [598] {sync, "sync", Iarith},
1767d9195a7SDavid du Colombier [599] {lfdx, "lfdx", Ifloat},
1777d9195a7SDavid du Colombier [631] {lfdx, "lfdux", Ifloat},
1787d9195a7SDavid du Colombier [659] {0, "mfsrin", Ireg},
1797d9195a7SDavid du Colombier [661] {stswx, "stswx", Istore},
1807d9195a7SDavid du Colombier [662] {stwbrx, "stwbrx", Istore},
1817d9195a7SDavid du Colombier [663] {stfsx, "stfsx", Istore},
1827d9195a7SDavid du Colombier [695] {stfsx, "stfsux", Istore},
1837d9195a7SDavid du Colombier [725] {stswi, "stswi", Istore},
1847d9195a7SDavid du Colombier [727] {stfdx, "stfdx", Istore},
1857d9195a7SDavid du Colombier [759] {stfdx, "stfdux", Istore},
1867d9195a7SDavid du Colombier [790] {lhbrx, "lhbrx", Iload},
1877d9195a7SDavid du Colombier [792] {sraw, "sraw", Ilog},
1887d9195a7SDavid du Colombier [824] {srawi, "srawi", Ilog},
1897d9195a7SDavid du Colombier [854] {0, "eieio", Icontrol},
1907d9195a7SDavid du Colombier [918] {sthbrx, "sthbrx", Istore},
1917d9195a7SDavid du Colombier [922] {extsh, "extsh", Iarith},
1927d9195a7SDavid du Colombier [954] {extsb, "extsb", Iarith},
1937d9195a7SDavid du Colombier [982] {icbi, "icbi", Icontrol},
1947d9195a7SDavid du Colombier [983] {unimp, "stfiwx", Istore},
1957d9195a7SDavid du Colombier [1014] {dcbz, "dcbz", Icontrol},
1967d9195a7SDavid du Colombier };
1977d9195a7SDavid du Colombier 
1987d9195a7SDavid du Colombier Inset	ops31 = {op31, nelem(op31)};
1997d9195a7SDavid du Colombier 
2007d9195a7SDavid du Colombier void
mspr(ulong ir)2017d9195a7SDavid du Colombier mspr(ulong ir)
2027d9195a7SDavid du Colombier {
2037d9195a7SDavid du Colombier 	int rd, ra, rb;
2047d9195a7SDavid du Colombier 	ulong *d;
2057d9195a7SDavid du Colombier 	char *n;
2067d9195a7SDavid du Colombier 	char buf[20];
2077d9195a7SDavid du Colombier 
2087d9195a7SDavid du Colombier 	getarrr(ir);
2097d9195a7SDavid du Colombier 	switch((rb<<5) | ra) {
2107d9195a7SDavid du Colombier 	case 0:
2117d9195a7SDavid du Colombier 		undef(ir);	/* was mq */
2127d9195a7SDavid du Colombier 		return;
2137d9195a7SDavid du Colombier 	case 1:
2147d9195a7SDavid du Colombier 		d = &reg.xer; n = "xer";
2157d9195a7SDavid du Colombier 		break;
2167d9195a7SDavid du Colombier 	case 268:
2177d9195a7SDavid du Colombier 	case 284:
2187d9195a7SDavid du Colombier 		d = &reg.tbl; n = "tbl";
2197d9195a7SDavid du Colombier 		break;
2207d9195a7SDavid du Colombier 	case 269:
2217d9195a7SDavid du Colombier 	case 285:
2227d9195a7SDavid du Colombier 		d = &reg.tbu; n = "tbu";
2237d9195a7SDavid du Colombier 		break;
2247d9195a7SDavid du Colombier 	case 22:
2257d9195a7SDavid du Colombier 		d = &reg.dec; n = "dec";
2267d9195a7SDavid du Colombier 		break;
2277d9195a7SDavid du Colombier 	case 8:
2287d9195a7SDavid du Colombier 		d = &reg.lr; n = "lr";
2297d9195a7SDavid du Colombier 		break;
2307d9195a7SDavid du Colombier 	case 9:
2317d9195a7SDavid du Colombier 		d = &reg.ctr; n = "ctr";
2327d9195a7SDavid du Colombier 		break;
2337d9195a7SDavid du Colombier 	default:
2347d9195a7SDavid du Colombier 		d = 0; sprint(n = buf, "spr%d", rd);
2357d9195a7SDavid du Colombier 		break;
2367d9195a7SDavid du Colombier 	}
2377d9195a7SDavid du Colombier 	if(getxo(ir) == 339) {
2387d9195a7SDavid du Colombier 		if(trace)
2397d9195a7SDavid du Colombier 			itrace("%s\tr%d,%s", ci->name, rd, n);
240*6891d857SDavid du Colombier 		if(d != nil)
2417d9195a7SDavid du Colombier 			reg.r[rd] = *d;
2427d9195a7SDavid du Colombier 	} else {
2437d9195a7SDavid du Colombier 		if(trace)
2447d9195a7SDavid du Colombier 			itrace("%s\t%s,r%d", ci->name, n, rd);
245*6891d857SDavid du Colombier 		if(d != nil)
2467d9195a7SDavid du Colombier 			*d = reg.r[rd];
2477d9195a7SDavid du Colombier 	}
2487d9195a7SDavid du Colombier }
2497d9195a7SDavid du Colombier 
2507d9195a7SDavid du Colombier static void
setcr(int d,long r)2517d9195a7SDavid du Colombier setcr(int d, long r)
2527d9195a7SDavid du Colombier {
2537d9195a7SDavid du Colombier 	int c;
2547d9195a7SDavid du Colombier 
2557d9195a7SDavid du Colombier 	c = 0;
2567d9195a7SDavid du Colombier 	if(reg.xer & XER_SO)
2577d9195a7SDavid du Colombier 		c |= 1;
2587d9195a7SDavid du Colombier 	if(r == 0)
2597d9195a7SDavid du Colombier 		c |= 2;
2607d9195a7SDavid du Colombier 	else if(r > 0)
2617d9195a7SDavid du Colombier 		c |= 4;
2627d9195a7SDavid du Colombier 	else
2637d9195a7SDavid du Colombier 		c |= 8;
2647d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(d, 0xF)) | mkCR(d, c);
2657d9195a7SDavid du Colombier }
2667d9195a7SDavid du Colombier 
2677d9195a7SDavid du Colombier void
addi(ulong ir)2687d9195a7SDavid du Colombier addi(ulong ir)
2697d9195a7SDavid du Colombier {
2707d9195a7SDavid du Colombier 	int rd, ra;
2717d9195a7SDavid du Colombier 	long imm;
2727d9195a7SDavid du Colombier 
2737d9195a7SDavid du Colombier 	getairr(ir);
2747d9195a7SDavid du Colombier 	if(trace) {
2757d9195a7SDavid du Colombier 		if(ra)
2767d9195a7SDavid du Colombier 			itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
2777d9195a7SDavid du Colombier 		else
2787d9195a7SDavid du Colombier 			itrace("li\tr%d,$0x%lux", rd, imm);
2797d9195a7SDavid du Colombier 	}
2807d9195a7SDavid du Colombier 	if(ra)
2817d9195a7SDavid du Colombier 		imm += reg.r[ra];
2827d9195a7SDavid du Colombier 	reg.r[rd] = imm;
2837d9195a7SDavid du Colombier }
2847d9195a7SDavid du Colombier 
2857d9195a7SDavid du Colombier void
addis(ulong ir)2867d9195a7SDavid du Colombier addis(ulong ir)
2877d9195a7SDavid du Colombier {
2887d9195a7SDavid du Colombier 	int rd, ra;
2897d9195a7SDavid du Colombier 	long imm;
2907d9195a7SDavid du Colombier 
2917d9195a7SDavid du Colombier 	getairr(ir);
2927d9195a7SDavid du Colombier 	if(trace) {
2937d9195a7SDavid du Colombier 		if(ra)
2947d9195a7SDavid du Colombier 			itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
2957d9195a7SDavid du Colombier 		else
2967d9195a7SDavid du Colombier 			itrace("lis\tr%d,$0x%lux", rd, imm);
2977d9195a7SDavid du Colombier 	}
2987d9195a7SDavid du Colombier 	imm <<= 16;
2997d9195a7SDavid du Colombier 	if(ra)
3007d9195a7SDavid du Colombier 		imm += reg.r[ra];
3017d9195a7SDavid du Colombier 	reg.r[rd] = imm;
3027d9195a7SDavid du Colombier }
3037d9195a7SDavid du Colombier 
3047d9195a7SDavid du Colombier void
and(ulong ir)3057d9195a7SDavid du Colombier and(ulong ir)
3067d9195a7SDavid du Colombier {
3077d9195a7SDavid du Colombier 	int rs, ra, rb;
3087d9195a7SDavid du Colombier 
3097d9195a7SDavid du Colombier 	getlrrr(ir);
3107d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] & reg.r[rb];
3117d9195a7SDavid du Colombier 	if(trace)
3127d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
3137d9195a7SDavid du Colombier 	if(ir & 1)
3147d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
3157d9195a7SDavid du Colombier }
3167d9195a7SDavid du Colombier 
3177d9195a7SDavid du Colombier void
andc(ulong ir)3187d9195a7SDavid du Colombier andc(ulong ir)
3197d9195a7SDavid du Colombier {
3207d9195a7SDavid du Colombier 	int rs, ra, rb;
3217d9195a7SDavid du Colombier 
3227d9195a7SDavid du Colombier 	getlrrr(ir);
3237d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] & ~reg.r[rb];
3247d9195a7SDavid du Colombier 	if(trace)
3257d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
3267d9195a7SDavid du Colombier 	if(ir & 1)
3277d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
3287d9195a7SDavid du Colombier }
3297d9195a7SDavid du Colombier 
3307d9195a7SDavid du Colombier void
andicc(ulong ir)3317d9195a7SDavid du Colombier andicc(ulong ir)
3327d9195a7SDavid du Colombier {
3337d9195a7SDavid du Colombier 	int rs, ra;
3347d9195a7SDavid du Colombier 	ulong imm;
3357d9195a7SDavid du Colombier 
3367d9195a7SDavid du Colombier 	getlirr(ir);
3377d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] & imm;
3387d9195a7SDavid du Colombier 	if(trace)
3397d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
3407d9195a7SDavid du Colombier 	setcr(0, reg.r[ra]);
3417d9195a7SDavid du Colombier }
3427d9195a7SDavid du Colombier 
3437d9195a7SDavid du Colombier void
andiscc(ulong ir)3447d9195a7SDavid du Colombier andiscc(ulong ir)
3457d9195a7SDavid du Colombier {
3467d9195a7SDavid du Colombier 	int rs, ra;
3477d9195a7SDavid du Colombier 	ulong imm;
3487d9195a7SDavid du Colombier 
3497d9195a7SDavid du Colombier 	getlirr(ir);
3507d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] & (imm<<16);
3517d9195a7SDavid du Colombier 	if(trace)
3527d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
3537d9195a7SDavid du Colombier 	setcr(0, reg.r[ra]);
3547d9195a7SDavid du Colombier }
3557d9195a7SDavid du Colombier 
3567d9195a7SDavid du Colombier void
cmpli(ulong ir)3577d9195a7SDavid du Colombier cmpli(ulong ir)
3587d9195a7SDavid du Colombier {
3597d9195a7SDavid du Colombier 	int rd, ra;
3607d9195a7SDavid du Colombier 	ulong c;
3617d9195a7SDavid du Colombier 	ulong imm, v;
3627d9195a7SDavid du Colombier 
3637d9195a7SDavid du Colombier 	getairr(ir);
3647d9195a7SDavid du Colombier 	imm &= 0xFFFF;
3657d9195a7SDavid du Colombier 	if(rd & 3)
3667d9195a7SDavid du Colombier 		undef(ir);
3677d9195a7SDavid du Colombier 	rd >>= 2;
3687d9195a7SDavid du Colombier 	v = reg.r[ra];
3697d9195a7SDavid du Colombier 	c = 0;
3707d9195a7SDavid du Colombier 	if(reg.xer & XER_SO)
3717d9195a7SDavid du Colombier 		c |= CRSO;
3727d9195a7SDavid du Colombier 	if(v < imm)
3737d9195a7SDavid du Colombier 		c |= CRLT;
3747d9195a7SDavid du Colombier 	else if(v == imm)
3757d9195a7SDavid du Colombier 		c |= CREQ;
3767d9195a7SDavid du Colombier 	else
3777d9195a7SDavid du Colombier 		c |= CRGT;
3787d9195a7SDavid du Colombier 	c >>= 28;
3797d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
3807d9195a7SDavid du Colombier 	if(trace)
3817d9195a7SDavid du Colombier 		itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
3827d9195a7SDavid du Colombier }
3837d9195a7SDavid du Colombier 
3847d9195a7SDavid du Colombier void
cmp(ulong ir)3857d9195a7SDavid du Colombier cmp(ulong ir)
3867d9195a7SDavid du Colombier {
3877d9195a7SDavid du Colombier 	int rd, ra, rb;
3887d9195a7SDavid du Colombier 	ulong c;
3897d9195a7SDavid du Colombier 	long va, vb;
3907d9195a7SDavid du Colombier 
3917d9195a7SDavid du Colombier 	getarrr(ir);
3927d9195a7SDavid du Colombier 	if(rd & 3)
3937d9195a7SDavid du Colombier 		undef(ir);
3947d9195a7SDavid du Colombier 	rd >>= 2;
3957d9195a7SDavid du Colombier 	c = 0;
3967d9195a7SDavid du Colombier 	if(reg.xer & XER_SO)
3977d9195a7SDavid du Colombier 		c |= CRSO;
3987d9195a7SDavid du Colombier 	va = reg.r[ra];
3997d9195a7SDavid du Colombier 	vb = reg.r[rb];
4007d9195a7SDavid du Colombier 	if(va < vb)
4017d9195a7SDavid du Colombier 		c |= CRLT;
4027d9195a7SDavid du Colombier 	else if(va == vb)
4037d9195a7SDavid du Colombier 		c |= CREQ;
4047d9195a7SDavid du Colombier 	else
4057d9195a7SDavid du Colombier 		c |= CRGT;
4067d9195a7SDavid du Colombier 	c >>= 28;
4077d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
4087d9195a7SDavid du Colombier 	if(trace)
4097d9195a7SDavid du Colombier 		itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
4107d9195a7SDavid du Colombier }
4117d9195a7SDavid du Colombier 
4127d9195a7SDavid du Colombier void
cmpi(ulong ir)4137d9195a7SDavid du Colombier cmpi(ulong ir)
4147d9195a7SDavid du Colombier {
4157d9195a7SDavid du Colombier 	int rd, ra;
4167d9195a7SDavid du Colombier 	ulong c;
4177d9195a7SDavid du Colombier 	long imm, v;
4187d9195a7SDavid du Colombier 
4197d9195a7SDavid du Colombier 	getairr(ir);
4207d9195a7SDavid du Colombier 	if(rd & 3)
4217d9195a7SDavid du Colombier 		undef(ir);
4227d9195a7SDavid du Colombier 	rd >>= 2;
4237d9195a7SDavid du Colombier 	v = reg.r[ra];
4247d9195a7SDavid du Colombier 	c = 0;
4257d9195a7SDavid du Colombier 	if(reg.xer & XER_SO)
4267d9195a7SDavid du Colombier 		c |= CRSO;
4277d9195a7SDavid du Colombier 	if(v < imm)
4287d9195a7SDavid du Colombier 		c |= CRLT;
4297d9195a7SDavid du Colombier 	else if(v == imm)
4307d9195a7SDavid du Colombier 		c |= CREQ;
4317d9195a7SDavid du Colombier 	else
4327d9195a7SDavid du Colombier 		c |= CRGT;
4337d9195a7SDavid du Colombier 	c >>= 28;
4347d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
4357d9195a7SDavid du Colombier 	if(trace)
4367d9195a7SDavid du Colombier 		itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
4377d9195a7SDavid du Colombier }
4387d9195a7SDavid du Colombier 
4397d9195a7SDavid du Colombier void
cmpl(ulong ir)4407d9195a7SDavid du Colombier cmpl(ulong ir)
4417d9195a7SDavid du Colombier {
4427d9195a7SDavid du Colombier 	int rd, ra, rb;
4437d9195a7SDavid du Colombier 	ulong c;
4447d9195a7SDavid du Colombier 	ulong va, vb;
4457d9195a7SDavid du Colombier 
4467d9195a7SDavid du Colombier 	getarrr(ir);
4477d9195a7SDavid du Colombier 	if(rd & 3)
4487d9195a7SDavid du Colombier 		undef(ir);
4497d9195a7SDavid du Colombier 	rd >>= 2;
4507d9195a7SDavid du Colombier 	c = 0;
4517d9195a7SDavid du Colombier 	if(reg.xer & XER_SO)
4527d9195a7SDavid du Colombier 		c |= CRSO;
4537d9195a7SDavid du Colombier 	va = reg.r[ra];
4547d9195a7SDavid du Colombier 	vb = reg.r[rb];
4557d9195a7SDavid du Colombier 	if(va < vb)
4567d9195a7SDavid du Colombier 		c |= CRLT;
4577d9195a7SDavid du Colombier 	else if(va == vb)
4587d9195a7SDavid du Colombier 		c |= CREQ;
4597d9195a7SDavid du Colombier 	else
4607d9195a7SDavid du Colombier 		c |= CRGT;
4617d9195a7SDavid du Colombier 	c >>= 28;
4627d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
4637d9195a7SDavid du Colombier 	if(trace)
4647d9195a7SDavid du Colombier 		itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
4657d9195a7SDavid du Colombier }
4667d9195a7SDavid du Colombier 
4677d9195a7SDavid du Colombier void
cntlzw(ulong ir)4687d9195a7SDavid du Colombier cntlzw(ulong ir)
4697d9195a7SDavid du Colombier {
4707d9195a7SDavid du Colombier 	int rs, ra, rb, n;
4717d9195a7SDavid du Colombier 
4727d9195a7SDavid du Colombier 	getlrrr(ir);
4737d9195a7SDavid du Colombier 	if(rb)
4747d9195a7SDavid du Colombier 		undef(ir);
4757d9195a7SDavid du Colombier 	for(n=0; n<32 && (reg.r[rs] & (1L<<(31-n))) == 0; n++)
4767d9195a7SDavid du Colombier 		;
4777d9195a7SDavid du Colombier 	reg.r[ra] = n;
4787d9195a7SDavid du Colombier 	if(trace)
4797d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
4807d9195a7SDavid du Colombier 	if(ir & 1)
4817d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
4827d9195a7SDavid du Colombier }
4837d9195a7SDavid du Colombier 
4847d9195a7SDavid du Colombier void
eqv(ulong ir)4857d9195a7SDavid du Colombier eqv(ulong ir)
4867d9195a7SDavid du Colombier {
4877d9195a7SDavid du Colombier 	int rs, ra, rb;
4887d9195a7SDavid du Colombier 
4897d9195a7SDavid du Colombier 	getlrrr(ir);
4907d9195a7SDavid du Colombier 	reg.r[ra] = ~(reg.r[rs] ^ reg.r[rb]);
4917d9195a7SDavid du Colombier 	if(trace)
4927d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
4937d9195a7SDavid du Colombier 	if(ir & 1)
4947d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
4957d9195a7SDavid du Colombier }
4967d9195a7SDavid du Colombier 
4977d9195a7SDavid du Colombier void
extsb(ulong ir)4987d9195a7SDavid du Colombier extsb(ulong ir)
4997d9195a7SDavid du Colombier {
5007d9195a7SDavid du Colombier 	int rs, ra, rb;
5017d9195a7SDavid du Colombier 
5027d9195a7SDavid du Colombier 	getlrrr(ir);
5037d9195a7SDavid du Colombier 	if(rb)
5047d9195a7SDavid du Colombier 		undef(ir);
5057d9195a7SDavid du Colombier 	reg.r[ra] = (schar)reg.r[rs];
5067d9195a7SDavid du Colombier 	if(trace)
5077d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
5087d9195a7SDavid du Colombier 	if(ir & 1)
5097d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
5107d9195a7SDavid du Colombier }
5117d9195a7SDavid du Colombier 
5127d9195a7SDavid du Colombier void
extsh(ulong ir)5137d9195a7SDavid du Colombier extsh(ulong ir)
5147d9195a7SDavid du Colombier {
5157d9195a7SDavid du Colombier 	int rs, ra, rb;
5167d9195a7SDavid du Colombier 
5177d9195a7SDavid du Colombier 	getlrrr(ir);
5187d9195a7SDavid du Colombier 	if(rb)
5197d9195a7SDavid du Colombier 		undef(ir);
5207d9195a7SDavid du Colombier 	reg.r[ra] = (short)reg.r[rs];
5217d9195a7SDavid du Colombier 	if(trace)
5227d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
5237d9195a7SDavid du Colombier 	if(ir & 1)
5247d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
5257d9195a7SDavid du Colombier }
5267d9195a7SDavid du Colombier 
5277d9195a7SDavid du Colombier void
add(ulong ir)5287d9195a7SDavid du Colombier add(ulong ir)
5297d9195a7SDavid du Colombier {
5307d9195a7SDavid du Colombier 	int rd, ra, rb;
5317d9195a7SDavid du Colombier 	uvlong r;
5327d9195a7SDavid du Colombier 
5337d9195a7SDavid du Colombier 	getarrr(ir);
534*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)(ulong)reg.r[rb];
5357d9195a7SDavid du Colombier 	if(ir & OE) {
5367d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
5377d9195a7SDavid du Colombier 		if(r >> 16)
538*6891d857SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;	/* TO DO: rubbish */
5397d9195a7SDavid du Colombier 	}
5407d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
5417d9195a7SDavid du Colombier 	if(ir & Rc)
5427d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
5437d9195a7SDavid du Colombier 	if(trace)
5447d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
5457d9195a7SDavid du Colombier }
5467d9195a7SDavid du Colombier 
5477d9195a7SDavid du Colombier void
addc(ulong ir)5487d9195a7SDavid du Colombier addc(ulong ir)
5497d9195a7SDavid du Colombier {
5507d9195a7SDavid du Colombier 	int rd, ra, rb;
5517d9195a7SDavid du Colombier 	ulong v;
5527d9195a7SDavid du Colombier 	uvlong r;
5537d9195a7SDavid du Colombier 
5547d9195a7SDavid du Colombier 	getarrr(ir);
555*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)(ulong)reg.r[rb];
5567d9195a7SDavid du Colombier 	v = r>>32;
5577d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
5587d9195a7SDavid du Colombier 	if(v)
5597d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
5607d9195a7SDavid du Colombier 	if(ir & OE) {
5617d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
5627d9195a7SDavid du Colombier 		if(v>>1)
5637d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
5647d9195a7SDavid du Colombier 	}
5657d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
5667d9195a7SDavid du Colombier 	if(ir & Rc)
5677d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
5687d9195a7SDavid du Colombier 	if(trace)
5697d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
5707d9195a7SDavid du Colombier }
5717d9195a7SDavid du Colombier 
5727d9195a7SDavid du Colombier void
adde(ulong ir)5737d9195a7SDavid du Colombier adde(ulong ir)
5747d9195a7SDavid du Colombier {
5757d9195a7SDavid du Colombier 	int rd, ra, rb;
5767d9195a7SDavid du Colombier 	ulong v;
5777d9195a7SDavid du Colombier 	uvlong r;
5787d9195a7SDavid du Colombier 
5797d9195a7SDavid du Colombier 	getarrr(ir);
580*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)(ulong)reg.r[rb] + ((reg.xer&XER_CA)!=0);
5817d9195a7SDavid du Colombier 	v = r>>32;
5827d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
5837d9195a7SDavid du Colombier 	if(v)
5847d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
5857d9195a7SDavid du Colombier 	if(ir & OE) {
5867d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
5877d9195a7SDavid du Colombier 		if(v>>1)
5887d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
5897d9195a7SDavid du Colombier 	}
5907d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
5917d9195a7SDavid du Colombier 	if(ir & Rc)
5927d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
5937d9195a7SDavid du Colombier 	if(trace)
5947d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
5957d9195a7SDavid du Colombier }
5967d9195a7SDavid du Colombier 
5977d9195a7SDavid du Colombier void
addic(ulong ir)5987d9195a7SDavid du Colombier addic(ulong ir)
5997d9195a7SDavid du Colombier {
6007d9195a7SDavid du Colombier 	int rd, ra;
6017d9195a7SDavid du Colombier 	long imm;
6027d9195a7SDavid du Colombier 	ulong v;
6037d9195a7SDavid du Colombier 	uvlong r;
6047d9195a7SDavid du Colombier 
6057d9195a7SDavid du Colombier 	getairr(ir);
606*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)(ulong)imm;
6077d9195a7SDavid du Colombier 	v = r>>32;
6087d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
6097d9195a7SDavid du Colombier 	if(v)
6107d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
6117d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
6127d9195a7SDavid du Colombier 	if(trace)
6137d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
6147d9195a7SDavid du Colombier }
6157d9195a7SDavid du Colombier 
6167d9195a7SDavid du Colombier void
addiccc(ulong ir)6177d9195a7SDavid du Colombier addiccc(ulong ir)
6187d9195a7SDavid du Colombier {
6197d9195a7SDavid du Colombier 	int rd, ra;
6207d9195a7SDavid du Colombier 	long imm;
6217d9195a7SDavid du Colombier 	ulong v;
6227d9195a7SDavid du Colombier 	uvlong r;
6237d9195a7SDavid du Colombier 
6247d9195a7SDavid du Colombier 	getairr(ir);
625*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)(ulong)imm;
6267d9195a7SDavid du Colombier 	v = r>>32;
6277d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
6287d9195a7SDavid du Colombier 	if(v)
6297d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
6307d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
6317d9195a7SDavid du Colombier 	setcr(0, reg.r[rd]);
6327d9195a7SDavid du Colombier 	if(trace)
6337d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
6347d9195a7SDavid du Colombier }
6357d9195a7SDavid du Colombier 
6367d9195a7SDavid du Colombier void
addme(ulong ir)6377d9195a7SDavid du Colombier addme(ulong ir)
6387d9195a7SDavid du Colombier {
6397d9195a7SDavid du Colombier 	int rd, ra, rb;
6407d9195a7SDavid du Colombier 	ulong v;
6417d9195a7SDavid du Colombier 	uvlong r;
6427d9195a7SDavid du Colombier 
6437d9195a7SDavid du Colombier 	getarrr(ir);
6447d9195a7SDavid du Colombier 	if(rb)
6457d9195a7SDavid du Colombier 		undef(ir);
646*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + (uvlong)0xFFFFFFFFU + ((reg.xer&XER_CA)!=0);
6477d9195a7SDavid du Colombier 	v = r>>32;
6487d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
6497d9195a7SDavid du Colombier 	if(v)
6507d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
6517d9195a7SDavid du Colombier 	if(ir & OE) {
6527d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
6537d9195a7SDavid du Colombier 		if(v>>1)
6547d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
6557d9195a7SDavid du Colombier 	}
6567d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
6577d9195a7SDavid du Colombier 	if(ir & Rc)
6587d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
6597d9195a7SDavid du Colombier 	if(trace)
6607d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
6617d9195a7SDavid du Colombier }
6627d9195a7SDavid du Colombier 
6637d9195a7SDavid du Colombier void
addze(ulong ir)6647d9195a7SDavid du Colombier addze(ulong ir)
6657d9195a7SDavid du Colombier {
6667d9195a7SDavid du Colombier 	int rd, ra, rb;
6677d9195a7SDavid du Colombier 	ulong v;
6687d9195a7SDavid du Colombier 	uvlong r;
6697d9195a7SDavid du Colombier 
6707d9195a7SDavid du Colombier 	getarrr(ir);
6717d9195a7SDavid du Colombier 	if(rb)
6727d9195a7SDavid du Colombier 		undef(ir);
673*6891d857SDavid du Colombier 	r = (uvlong)(ulong)reg.r[ra] + ((reg.xer&XER_CA)!=0);
6747d9195a7SDavid du Colombier 	v = r>>32;
6757d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
6767d9195a7SDavid du Colombier 	if(v)
6777d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
6787d9195a7SDavid du Colombier 	if(ir & OE) {
6797d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
6807d9195a7SDavid du Colombier 		if(v>>1)
6817d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
6827d9195a7SDavid du Colombier 	}
6837d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
6847d9195a7SDavid du Colombier 	if(ir & Rc)
6857d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
6867d9195a7SDavid du Colombier 	if(trace)
6877d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
6887d9195a7SDavid du Colombier }
6897d9195a7SDavid du Colombier 
6907d9195a7SDavid du Colombier void
divw(ulong ir)6917d9195a7SDavid du Colombier divw(ulong ir)
6927d9195a7SDavid du Colombier {
6937d9195a7SDavid du Colombier 	int rd, ra, rb;
6947d9195a7SDavid du Colombier 
6957d9195a7SDavid du Colombier 	getarrr(ir);
6967d9195a7SDavid du Colombier 	if(reg.r[rb] != 0 && ((ulong)reg.r[ra] != 0x80000000 || reg.r[rb] != -1))
6977d9195a7SDavid du Colombier 		reg.r[rd] = reg.r[ra]/reg.r[rb];
6987d9195a7SDavid du Colombier 	else if(ir & OE)
6997d9195a7SDavid du Colombier 		reg.xer |= XER_SO | XER_OV;
7007d9195a7SDavid du Colombier 	if(ir & Rc)
7017d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
7027d9195a7SDavid du Colombier 	if(trace)
7037d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
7047d9195a7SDavid du Colombier }
7057d9195a7SDavid du Colombier 
7067d9195a7SDavid du Colombier void
divwu(ulong ir)7077d9195a7SDavid du Colombier divwu(ulong ir)
7087d9195a7SDavid du Colombier {
7097d9195a7SDavid du Colombier 	int rd, ra, rb;
7107d9195a7SDavid du Colombier 
7117d9195a7SDavid du Colombier 	getarrr(ir);
7127d9195a7SDavid du Colombier 	if(reg.r[rb] != 0)
7137d9195a7SDavid du Colombier 		reg.r[rd] = (ulong)reg.r[ra]/(ulong)reg.r[rb];
7147d9195a7SDavid du Colombier 	else if(ir & OE)
7157d9195a7SDavid du Colombier 		reg.xer |= XER_SO | XER_OV;
7167d9195a7SDavid du Colombier 	if(ir & Rc)
7177d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
7187d9195a7SDavid du Colombier 	if(trace)
7197d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
7207d9195a7SDavid du Colombier }
7217d9195a7SDavid du Colombier 
7227d9195a7SDavid du Colombier void
mcrxr(ulong ir)7237d9195a7SDavid du Colombier mcrxr(ulong ir)
7247d9195a7SDavid du Colombier {
7257d9195a7SDavid du Colombier 	int rd, ra, rb;
7267d9195a7SDavid du Colombier 
7277d9195a7SDavid du Colombier 	getarrr(ir);
7287d9195a7SDavid du Colombier 	if(rd & 3 || ra != 0 || rb != 0 || ir & Rc)
7297d9195a7SDavid du Colombier 		undef(ir);
7307d9195a7SDavid du Colombier 	rd >>= 2;
7317d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, reg.xer>>28);
7327d9195a7SDavid du Colombier 	reg.xer &= ~(0xF<<28);
7337d9195a7SDavid du Colombier }
7347d9195a7SDavid du Colombier 
7357d9195a7SDavid du Colombier void
mtcrf(ulong ir)7367d9195a7SDavid du Colombier mtcrf(ulong ir)
7377d9195a7SDavid du Colombier {
7387d9195a7SDavid du Colombier 	int rs, crm, i;
7397d9195a7SDavid du Colombier 	ulong m;
7407d9195a7SDavid du Colombier 
7417d9195a7SDavid du Colombier 	if(ir & ((1<<20)|(1<<11)|Rc))
7427d9195a7SDavid du Colombier 		undef(ir);
7437d9195a7SDavid du Colombier 	rs = (ir>>21)&0x1F;
7447d9195a7SDavid du Colombier 	crm = (ir>>12)&0xFF;
7457d9195a7SDavid du Colombier 	m = 0;
7467d9195a7SDavid du Colombier 	for(i = 0x80; i; i >>= 1) {
7477d9195a7SDavid du Colombier 		m <<= 4;
7487d9195a7SDavid du Colombier 		if(crm & i)
7497d9195a7SDavid du Colombier 			m |= 0xF;
7507d9195a7SDavid du Colombier 	}
7517d9195a7SDavid du Colombier 	reg.cr = (reg.cr & ~m) | (reg.r[rs] & m);
7527d9195a7SDavid du Colombier }
7537d9195a7SDavid du Colombier 
7547d9195a7SDavid du Colombier void
mfcr(ulong ir)7557d9195a7SDavid du Colombier mfcr(ulong ir)
7567d9195a7SDavid du Colombier {
7577d9195a7SDavid du Colombier 	int rd, ra, rb;
7587d9195a7SDavid du Colombier 
7597d9195a7SDavid du Colombier 	getarrr(ir);
7607d9195a7SDavid du Colombier 	if(ra != 0 || rb != 0 || ir & Rc)
7617d9195a7SDavid du Colombier 		undef(ir);
7627d9195a7SDavid du Colombier 	reg.r[rd] = reg.cr;
7637d9195a7SDavid du Colombier }
7647d9195a7SDavid du Colombier 
7657d9195a7SDavid du Colombier void
mulhw(ulong ir)7667d9195a7SDavid du Colombier mulhw(ulong ir)
7677d9195a7SDavid du Colombier {
7687d9195a7SDavid du Colombier 	int rd, ra, rb;
7697d9195a7SDavid du Colombier 
7707d9195a7SDavid du Colombier 	getarrr(ir);
7717d9195a7SDavid du Colombier 	reg.r[rd] = ((vlong)(long)reg.r[ra]*(long)reg.r[rb])>>32;
7727d9195a7SDavid du Colombier 	if(ir & Rc)
7737d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
7747d9195a7SDavid du Colombier 	if(trace)
7757d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
7767d9195a7SDavid du Colombier 	/* BUG: doesn't set OV */
7777d9195a7SDavid du Colombier }
7787d9195a7SDavid du Colombier 
7797d9195a7SDavid du Colombier void
mulhwu(ulong ir)7807d9195a7SDavid du Colombier mulhwu(ulong ir)
7817d9195a7SDavid du Colombier {
7827d9195a7SDavid du Colombier 	int rd, ra, rb;
7837d9195a7SDavid du Colombier 
7847d9195a7SDavid du Colombier 	getarrr(ir);
7857d9195a7SDavid du Colombier 	reg.r[rd] = ((uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb])>>32;
7867d9195a7SDavid du Colombier 	if(ir & Rc)
7877d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);	/* not sure whether CR setting is signed or unsigned */
7887d9195a7SDavid du Colombier 	if(trace)
7897d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
7907d9195a7SDavid du Colombier 	/* BUG: doesn't set OV */
7917d9195a7SDavid du Colombier }
7927d9195a7SDavid du Colombier 
7937d9195a7SDavid du Colombier void
mullw(ulong ir)7947d9195a7SDavid du Colombier mullw(ulong ir)
7957d9195a7SDavid du Colombier {
7967d9195a7SDavid du Colombier 	int rd, ra, rb;
7977d9195a7SDavid du Colombier 
7987d9195a7SDavid du Colombier 	getarrr(ir);
7997d9195a7SDavid du Colombier 	reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb];
8007d9195a7SDavid du Colombier 	if(ir & Rc)
8017d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
8027d9195a7SDavid du Colombier 	if(trace)
8037d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
8047d9195a7SDavid du Colombier 	/* BUG: doesn't set OV */
8057d9195a7SDavid du Colombier }
8067d9195a7SDavid du Colombier 
8077d9195a7SDavid du Colombier void
mulli(ulong ir)8087d9195a7SDavid du Colombier mulli(ulong ir)
8097d9195a7SDavid du Colombier {
8107d9195a7SDavid du Colombier 	int rd, ra;
8117d9195a7SDavid du Colombier 	long imm;
8127d9195a7SDavid du Colombier 
8137d9195a7SDavid du Colombier 	getairr(ir);
8147d9195a7SDavid du Colombier 	reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)imm;
8157d9195a7SDavid du Colombier 	if(trace)
8167d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
8177d9195a7SDavid du Colombier }
8187d9195a7SDavid du Colombier 
8197d9195a7SDavid du Colombier void
nand(ulong ir)8207d9195a7SDavid du Colombier nand(ulong ir)
8217d9195a7SDavid du Colombier {
8227d9195a7SDavid du Colombier 	int rs, ra, rb;
8237d9195a7SDavid du Colombier 
8247d9195a7SDavid du Colombier 	getlrrr(ir);
8257d9195a7SDavid du Colombier 	reg.r[ra] = ~(reg.r[rs] & reg.r[rb]);
8267d9195a7SDavid du Colombier 	if(ir & Rc)
8277d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
8287d9195a7SDavid du Colombier 	if(trace)
8297d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
8307d9195a7SDavid du Colombier }
8317d9195a7SDavid du Colombier 
8327d9195a7SDavid du Colombier void
neg(ulong ir)8337d9195a7SDavid du Colombier neg(ulong ir)
8347d9195a7SDavid du Colombier {
8357d9195a7SDavid du Colombier 	int rd, ra, rb;
8367d9195a7SDavid du Colombier 
8377d9195a7SDavid du Colombier 	getarrr(ir);
8387d9195a7SDavid du Colombier 	if(rb)
8397d9195a7SDavid du Colombier 		undef(ir);
8407d9195a7SDavid du Colombier 	if(ir & OE)
8417d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
8427d9195a7SDavid du Colombier 	if((ulong)reg.r[ra] == 0x80000000) {
8437d9195a7SDavid du Colombier 		if(ir & OE)
8447d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
8457d9195a7SDavid du Colombier 		reg.r[rd] = reg.r[ra];
8467d9195a7SDavid du Colombier 	} else
8477d9195a7SDavid du Colombier 		reg.r[rd] = -reg.r[ra];
8487d9195a7SDavid du Colombier 	if(ir & Rc)
8497d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
8507d9195a7SDavid du Colombier }
8517d9195a7SDavid du Colombier 
8527d9195a7SDavid du Colombier void
nor(ulong ir)8537d9195a7SDavid du Colombier nor(ulong ir)
8547d9195a7SDavid du Colombier {
8557d9195a7SDavid du Colombier 	int rs, ra, rb;
8567d9195a7SDavid du Colombier 
8577d9195a7SDavid du Colombier 	getlrrr(ir);
8587d9195a7SDavid du Colombier 	reg.r[ra] = ~(reg.r[rs] | reg.r[rb]);
8597d9195a7SDavid du Colombier 	if(ir & Rc)
8607d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
8617d9195a7SDavid du Colombier 	if(trace)
8627d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
8637d9195a7SDavid du Colombier }
8647d9195a7SDavid du Colombier 
8657d9195a7SDavid du Colombier void
or(ulong ir)8667d9195a7SDavid du Colombier or(ulong ir)
8677d9195a7SDavid du Colombier {
8687d9195a7SDavid du Colombier 	int rs, ra, rb;
8697d9195a7SDavid du Colombier 
8707d9195a7SDavid du Colombier 	getlrrr(ir);
8717d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] | reg.r[rb];
8727d9195a7SDavid du Colombier 	if(ir & Rc)
8737d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
8747d9195a7SDavid du Colombier 	if(trace) {
8757d9195a7SDavid du Colombier 		if(rs == rb)
8767d9195a7SDavid du Colombier 			itrace("mr%s\tr%d,r%d", ir&1?".":"", ra, rs);
8777d9195a7SDavid du Colombier 		else
8787d9195a7SDavid du Colombier 			itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
8797d9195a7SDavid du Colombier 	}
8807d9195a7SDavid du Colombier }
8817d9195a7SDavid du Colombier 
8827d9195a7SDavid du Colombier void
orc(ulong ir)8837d9195a7SDavid du Colombier orc(ulong ir)
8847d9195a7SDavid du Colombier {
8857d9195a7SDavid du Colombier 	int rs, ra, rb;
8867d9195a7SDavid du Colombier 
8877d9195a7SDavid du Colombier 	getlrrr(ir);
8887d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] | ~reg.r[rb];
8897d9195a7SDavid du Colombier 	if(ir & Rc)
8907d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
8917d9195a7SDavid du Colombier 	if(trace)
8927d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
8937d9195a7SDavid du Colombier }
8947d9195a7SDavid du Colombier 
8957d9195a7SDavid du Colombier void
ori(ulong ir)8967d9195a7SDavid du Colombier ori(ulong ir)
8977d9195a7SDavid du Colombier {
8987d9195a7SDavid du Colombier 	int rs, ra;
8997d9195a7SDavid du Colombier 	ulong imm;
9007d9195a7SDavid du Colombier 
9017d9195a7SDavid du Colombier 	getlirr(ir);
9027d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] | imm;
9037d9195a7SDavid du Colombier 	if(trace)
9047d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
9057d9195a7SDavid du Colombier }
9067d9195a7SDavid du Colombier 
9077d9195a7SDavid du Colombier void
oris(ulong ir)9087d9195a7SDavid du Colombier oris(ulong ir)
9097d9195a7SDavid du Colombier {
9107d9195a7SDavid du Colombier 	int rs, ra;
9117d9195a7SDavid du Colombier 	ulong imm;
9127d9195a7SDavid du Colombier 
9137d9195a7SDavid du Colombier 	getlirr(ir);
9147d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] | (imm<<16);
9157d9195a7SDavid du Colombier 	if(trace)
9167d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
9177d9195a7SDavid du Colombier }
9187d9195a7SDavid du Colombier 
9197d9195a7SDavid du Colombier static ulong
mkmask(int mb,int me)9207d9195a7SDavid du Colombier mkmask(int mb, int me)
9217d9195a7SDavid du Colombier {
9227d9195a7SDavid du Colombier 	int i;
9237d9195a7SDavid du Colombier 	ulong v;
9247d9195a7SDavid du Colombier 
9257d9195a7SDavid du Colombier 	if(mb > me)
9267d9195a7SDavid du Colombier 		return mkmask(0, me) | mkmask(mb, 31);
9277d9195a7SDavid du Colombier 	v = 0;
9287d9195a7SDavid du Colombier 	for(i=mb; i<=me; i++)
9297d9195a7SDavid du Colombier 		v |= 1L << (31-i);	/* don't need a loop, but i'm lazy */
9307d9195a7SDavid du Colombier 	return v;
9317d9195a7SDavid du Colombier }
9327d9195a7SDavid du Colombier 
9337d9195a7SDavid du Colombier static ulong
rotl(ulong v,int sh)9347d9195a7SDavid du Colombier rotl(ulong v, int sh)
9357d9195a7SDavid du Colombier {
9367d9195a7SDavid du Colombier 	if(sh == 0)
9377d9195a7SDavid du Colombier 		return v;
9387d9195a7SDavid du Colombier 	return (v<<sh) | (v>>(32-sh));
9397d9195a7SDavid du Colombier }
9407d9195a7SDavid du Colombier 
9417d9195a7SDavid du Colombier void
rlwimi(ulong ir)9427d9195a7SDavid du Colombier rlwimi(ulong ir)
9437d9195a7SDavid du Colombier {
9447d9195a7SDavid du Colombier 	int rs, ra, rb, sh;
9457d9195a7SDavid du Colombier 	ulong m;
9467d9195a7SDavid du Colombier 
9477d9195a7SDavid du Colombier 	getlrrr(ir);
9487d9195a7SDavid du Colombier 	sh = rb;
9497d9195a7SDavid du Colombier 	m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
9507d9195a7SDavid du Colombier 	reg.r[ra] = (reg.r[ra] & ~m) | (rotl(reg.r[rs], sh) & m);
9517d9195a7SDavid du Colombier 	if(trace)
9527d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,%d,#%lux", ci->name, ra, rs, sh, m);
9537d9195a7SDavid du Colombier 	if(ir & 1)
9547d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
9557d9195a7SDavid du Colombier }
9567d9195a7SDavid du Colombier 
9577d9195a7SDavid du Colombier void
rlwinm(ulong ir)9587d9195a7SDavid du Colombier rlwinm(ulong ir)
9597d9195a7SDavid du Colombier {
9607d9195a7SDavid du Colombier 	int rs, ra, rb, sh;
9617d9195a7SDavid du Colombier 	ulong m;
9627d9195a7SDavid du Colombier 
9637d9195a7SDavid du Colombier 	getlrrr(ir);
9647d9195a7SDavid du Colombier 	sh = rb;
9657d9195a7SDavid du Colombier 	m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
9667d9195a7SDavid du Colombier 	reg.r[ra] = rotl(reg.r[rs], sh) & m;
9677d9195a7SDavid du Colombier 	if(trace)
9687d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,%d,#%lux", ci->name, ir&Rc?".":"", ra, rs, sh, m);
9697d9195a7SDavid du Colombier 	if(ir & Rc)
9707d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
9717d9195a7SDavid du Colombier }
9727d9195a7SDavid du Colombier 
9737d9195a7SDavid du Colombier void
rlwnm(ulong ir)9747d9195a7SDavid du Colombier rlwnm(ulong ir)
9757d9195a7SDavid du Colombier {
9767d9195a7SDavid du Colombier 	int rs, ra, rb, sh;
9777d9195a7SDavid du Colombier 	ulong m;
9787d9195a7SDavid du Colombier 
9797d9195a7SDavid du Colombier 	getlrrr(ir);
9807d9195a7SDavid du Colombier 	sh = reg.r[rb] & 0x1F;
9817d9195a7SDavid du Colombier 	m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
9827d9195a7SDavid du Colombier 	reg.r[ra] = rotl(reg.r[rs], sh) & m;
9837d9195a7SDavid du Colombier 	if(trace)
9847d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,r%d,#%lux", ci->name, ra, rs, rb, m);
9857d9195a7SDavid du Colombier 	if(ir & 1)
9867d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
9877d9195a7SDavid du Colombier }
9887d9195a7SDavid du Colombier 
9897d9195a7SDavid du Colombier void
slw(ulong ir)9907d9195a7SDavid du Colombier slw(ulong ir)
9917d9195a7SDavid du Colombier {
9927d9195a7SDavid du Colombier 	int rs, ra, rb;
9937d9195a7SDavid du Colombier 	long v;
9947d9195a7SDavid du Colombier 
9957d9195a7SDavid du Colombier 	getlrrr(ir);
9967d9195a7SDavid du Colombier 	v = reg.r[rb];
9977d9195a7SDavid du Colombier 	if((v & 0x20) == 0) {
9987d9195a7SDavid du Colombier 		v &= 0x1F;
9997d9195a7SDavid du Colombier 		reg.r[ra] = (ulong)reg.r[rs] << v;
10007d9195a7SDavid du Colombier 	} else
10017d9195a7SDavid du Colombier 		reg.r[ra] = 0;
10027d9195a7SDavid du Colombier 	if(ir & Rc)
10037d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
10047d9195a7SDavid du Colombier 	if(trace)
10057d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
10067d9195a7SDavid du Colombier }
10077d9195a7SDavid du Colombier 
10087d9195a7SDavid du Colombier void
sraw(ulong ir)10097d9195a7SDavid du Colombier sraw(ulong ir)
10107d9195a7SDavid du Colombier {
10117d9195a7SDavid du Colombier 	int rs, ra, rb;
10127d9195a7SDavid du Colombier 	long v;
10137d9195a7SDavid du Colombier 
10147d9195a7SDavid du Colombier 	getlrrr(ir);
10157d9195a7SDavid du Colombier 	v = reg.r[rb];
10167d9195a7SDavid du Colombier 	if((v & 0x20) == 0) {
10177d9195a7SDavid du Colombier 		v &= 0x1F;
10187d9195a7SDavid du Colombier 		if(reg.r[rs]&SIGNBIT && v)
10197d9195a7SDavid du Colombier 			reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
10207d9195a7SDavid du Colombier 		else
10217d9195a7SDavid du Colombier 			reg.r[ra] = reg.r[rs]>>v;
10227d9195a7SDavid du Colombier 	} else
10237d9195a7SDavid du Colombier 		reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
10247d9195a7SDavid du Colombier 	if(ir & Rc)
10257d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
10267d9195a7SDavid du Colombier 	if(trace)
10277d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
10287d9195a7SDavid du Colombier }
10297d9195a7SDavid du Colombier 
10307d9195a7SDavid du Colombier void
srawi(ulong ir)10317d9195a7SDavid du Colombier srawi(ulong ir)
10327d9195a7SDavid du Colombier {
10337d9195a7SDavid du Colombier 	int rs, ra, rb;
10347d9195a7SDavid du Colombier 	long v;
10357d9195a7SDavid du Colombier 
10367d9195a7SDavid du Colombier 	getlrrr(ir);
10377d9195a7SDavid du Colombier 	v = rb;
10387d9195a7SDavid du Colombier 	if((v & 0x20) == 0) {
10397d9195a7SDavid du Colombier 		v &= 0x1F;
10407d9195a7SDavid du Colombier 		if(reg.r[rs]&SIGNBIT && v)
10417d9195a7SDavid du Colombier 			reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
10427d9195a7SDavid du Colombier 		else
10437d9195a7SDavid du Colombier 			reg.r[ra] = reg.r[rs]>>v;
10447d9195a7SDavid du Colombier 	} else
10457d9195a7SDavid du Colombier 		reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
10467d9195a7SDavid du Colombier 	if(ir & Rc)
10477d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
10487d9195a7SDavid du Colombier 	if(trace)
10497d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,$%d", ci->name, ir&1?".":"", ra, rs, v);
10507d9195a7SDavid du Colombier }
10517d9195a7SDavid du Colombier 
10527d9195a7SDavid du Colombier void
srw(ulong ir)10537d9195a7SDavid du Colombier srw(ulong ir)
10547d9195a7SDavid du Colombier {
10557d9195a7SDavid du Colombier 	int rs, ra, rb;
10567d9195a7SDavid du Colombier 	long v;
10577d9195a7SDavid du Colombier 
10587d9195a7SDavid du Colombier 	getlrrr(ir);
10597d9195a7SDavid du Colombier 	v = reg.r[rb];
10607d9195a7SDavid du Colombier 	if((v & 0x20) == 0)
10617d9195a7SDavid du Colombier 		reg.r[ra] = (ulong)reg.r[rs] >> (v&0x1F);
10627d9195a7SDavid du Colombier 	else
10637d9195a7SDavid du Colombier 		reg.r[ra] = 0;
10647d9195a7SDavid du Colombier 	if(ir & Rc)
10657d9195a7SDavid du Colombier 		setcr(0, reg.r[ra]);
10667d9195a7SDavid du Colombier 	if(trace)
10677d9195a7SDavid du Colombier 		itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
10687d9195a7SDavid du Colombier }
10697d9195a7SDavid du Colombier 
10707d9195a7SDavid du Colombier void
subf(ulong ir)10717d9195a7SDavid du Colombier subf(ulong ir)
10727d9195a7SDavid du Colombier {
10737d9195a7SDavid du Colombier 	int rd, ra, rb;
10747d9195a7SDavid du Colombier 	uvlong r;
10757d9195a7SDavid du Colombier 
10767d9195a7SDavid du Colombier 	getarrr(ir);
1077*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + (uvlong)(ulong)reg.r[rb] + 1;
10787d9195a7SDavid du Colombier 	if(ir & OE) {
10797d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
10807d9195a7SDavid du Colombier 		if(r >> 16)
10817d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
10827d9195a7SDavid du Colombier 	}
10837d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
10847d9195a7SDavid du Colombier 	if(ir & Rc)
10857d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
10867d9195a7SDavid du Colombier 	if(trace)
10877d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
10887d9195a7SDavid du Colombier }
10897d9195a7SDavid du Colombier 
10907d9195a7SDavid du Colombier void
subfc(ulong ir)10917d9195a7SDavid du Colombier subfc(ulong ir)
10927d9195a7SDavid du Colombier {
10937d9195a7SDavid du Colombier 	int rd, ra, rb;
10947d9195a7SDavid du Colombier 	ulong v;
10957d9195a7SDavid du Colombier 	uvlong r;
10967d9195a7SDavid du Colombier 
10977d9195a7SDavid du Colombier 	getarrr(ir);
1098*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + (uvlong)(ulong)reg.r[rb] + 1;
10997d9195a7SDavid du Colombier 	v = r>>32;
11007d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
11017d9195a7SDavid du Colombier 	if(v)
11027d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
11037d9195a7SDavid du Colombier 	if(ir & OE) {
11047d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
11057d9195a7SDavid du Colombier 		if(v>>1)
11067d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
11077d9195a7SDavid du Colombier 	}
11087d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
11097d9195a7SDavid du Colombier 	if(ir & Rc)
11107d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
11117d9195a7SDavid du Colombier 	if(trace)
11127d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
11137d9195a7SDavid du Colombier }
11147d9195a7SDavid du Colombier 
11157d9195a7SDavid du Colombier void
subfe(ulong ir)11167d9195a7SDavid du Colombier subfe(ulong ir)
11177d9195a7SDavid du Colombier {
11187d9195a7SDavid du Colombier 	int rd, ra, rb;
11197d9195a7SDavid du Colombier 	ulong v;
11207d9195a7SDavid du Colombier 	uvlong r;
11217d9195a7SDavid du Colombier 
11227d9195a7SDavid du Colombier 	getarrr(ir);
1123*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + (uvlong)(ulong)reg.r[rb] + ((reg.xer&XER_CA)!=0);
11247d9195a7SDavid du Colombier 	v = r>>32;
11257d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
11267d9195a7SDavid du Colombier 	if(v)
11277d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
11287d9195a7SDavid du Colombier 	if(ir & OE) {
11297d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
11307d9195a7SDavid du Colombier 		if(v>>1)
11317d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
11327d9195a7SDavid du Colombier 	}
11337d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
11347d9195a7SDavid du Colombier 	if(ir & Rc)
11357d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
11367d9195a7SDavid du Colombier 	if(trace)
11377d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
11387d9195a7SDavid du Colombier }
11397d9195a7SDavid du Colombier 
11407d9195a7SDavid du Colombier void
subfic(ulong ir)11417d9195a7SDavid du Colombier subfic(ulong ir)
11427d9195a7SDavid du Colombier {
11437d9195a7SDavid du Colombier 	int rd, ra;
11447d9195a7SDavid du Colombier 	long imm;
11457d9195a7SDavid du Colombier 	ulong v;
11467d9195a7SDavid du Colombier 	uvlong r;
11477d9195a7SDavid du Colombier 
11487d9195a7SDavid du Colombier 	getairr(ir);
1149*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + (uvlong)(ulong)imm + 1;
11507d9195a7SDavid du Colombier 	v = r>>32;
11517d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
11527d9195a7SDavid du Colombier 	if(v)
11537d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
11547d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
11557d9195a7SDavid du Colombier 	if(trace)
11567d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
11577d9195a7SDavid du Colombier }
11587d9195a7SDavid du Colombier 
11597d9195a7SDavid du Colombier void
subfme(ulong ir)11607d9195a7SDavid du Colombier subfme(ulong ir)
11617d9195a7SDavid du Colombier {
11627d9195a7SDavid du Colombier 	int rd, ra, rb;
11637d9195a7SDavid du Colombier 	ulong v;
11647d9195a7SDavid du Colombier 	uvlong r;
11657d9195a7SDavid du Colombier 
11667d9195a7SDavid du Colombier 	getarrr(ir);
11677d9195a7SDavid du Colombier 	if(rb)
11687d9195a7SDavid du Colombier 		undef(ir);
1169*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + (uvlong)0xFFFFFFFFU + ((reg.xer&XER_CA)!=0);
11707d9195a7SDavid du Colombier 	v = r>>32;
11717d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
11727d9195a7SDavid du Colombier 	if(v)
11737d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
11747d9195a7SDavid du Colombier 	if(ir & OE) {
11757d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
11767d9195a7SDavid du Colombier 		if(v>>1)
11777d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
11787d9195a7SDavid du Colombier 	}
11797d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
11807d9195a7SDavid du Colombier 	if(ir & Rc)
11817d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
11827d9195a7SDavid du Colombier 	if(trace)
11837d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
11847d9195a7SDavid du Colombier }
11857d9195a7SDavid du Colombier 
11867d9195a7SDavid du Colombier void
subfze(ulong ir)11877d9195a7SDavid du Colombier subfze(ulong ir)
11887d9195a7SDavid du Colombier {
11897d9195a7SDavid du Colombier 	int rd, ra, rb;
11907d9195a7SDavid du Colombier 	ulong v;
11917d9195a7SDavid du Colombier 	uvlong r;
11927d9195a7SDavid du Colombier 
11937d9195a7SDavid du Colombier 	getarrr(ir);
11947d9195a7SDavid du Colombier 	if(rb)
11957d9195a7SDavid du Colombier 		undef(ir);
1196*6891d857SDavid du Colombier 	r = (uvlong)((ulong)~reg.r[ra]) + ((reg.xer&XER_CA)!=0);
11977d9195a7SDavid du Colombier 	v = r>>32;
11987d9195a7SDavid du Colombier 	reg.xer &= ~XER_CA;
11997d9195a7SDavid du Colombier 	if(v)
12007d9195a7SDavid du Colombier 		reg.xer |= XER_CA;
12017d9195a7SDavid du Colombier 	if(ir & OE) {
12027d9195a7SDavid du Colombier 		reg.xer &= ~XER_OV;
12037d9195a7SDavid du Colombier 		if(v>>1)
12047d9195a7SDavid du Colombier 			reg.xer |= XER_SO | XER_OV;
12057d9195a7SDavid du Colombier 	}
12067d9195a7SDavid du Colombier 	reg.r[rd] = (ulong)r;
12077d9195a7SDavid du Colombier 	if(ir & Rc)
12087d9195a7SDavid du Colombier 		setcr(0, reg.r[rd]);
12097d9195a7SDavid du Colombier 	if(trace)
12107d9195a7SDavid du Colombier 		itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
12117d9195a7SDavid du Colombier }
12127d9195a7SDavid du Colombier 
12137d9195a7SDavid du Colombier void
xor(ulong ir)12147d9195a7SDavid du Colombier xor(ulong ir)
12157d9195a7SDavid du Colombier {
12167d9195a7SDavid du Colombier 	int rs, ra, rb;
12177d9195a7SDavid du Colombier 
12187d9195a7SDavid du Colombier 	getlrrr(ir);
12197d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] ^ reg.r[rb];
12207d9195a7SDavid du Colombier 	if(trace)
12217d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,r%d", ci->name, ra, rs, rb);
12227d9195a7SDavid du Colombier }
12237d9195a7SDavid du Colombier 
12247d9195a7SDavid du Colombier void
xori(ulong ir)12257d9195a7SDavid du Colombier xori(ulong ir)
12267d9195a7SDavid du Colombier {
12277d9195a7SDavid du Colombier 	int rs, ra;
12287d9195a7SDavid du Colombier 	ulong imm;
12297d9195a7SDavid du Colombier 
12307d9195a7SDavid du Colombier 	getlirr(ir);
12317d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] ^ imm;
12327d9195a7SDavid du Colombier 	if(trace)
12337d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
12347d9195a7SDavid du Colombier }
12357d9195a7SDavid du Colombier 
12367d9195a7SDavid du Colombier void
xoris(ulong ir)12377d9195a7SDavid du Colombier xoris(ulong ir)
12387d9195a7SDavid du Colombier {
12397d9195a7SDavid du Colombier 	int rs, ra;
12407d9195a7SDavid du Colombier 	ulong imm;
12417d9195a7SDavid du Colombier 
12427d9195a7SDavid du Colombier 	getlirr(ir);
12437d9195a7SDavid du Colombier 	reg.r[ra] = reg.r[rs] ^ (imm<<16);
12447d9195a7SDavid du Colombier 	if(trace)
12457d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
12467d9195a7SDavid du Colombier }
12477d9195a7SDavid du Colombier 
12487d9195a7SDavid du Colombier void
lwz(ulong ir)12497d9195a7SDavid du Colombier lwz(ulong ir)
12507d9195a7SDavid du Colombier {
12517d9195a7SDavid du Colombier 	ulong ea;
12527d9195a7SDavid du Colombier 	int ra, rd, upd;
12537d9195a7SDavid du Colombier 	long imm;
12547d9195a7SDavid du Colombier 
12557d9195a7SDavid du Colombier 	getairr(ir);
12567d9195a7SDavid du Colombier 	ea = imm;
12577d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
12587d9195a7SDavid du Colombier 	if(ra) {
12597d9195a7SDavid du Colombier 		ea += reg.r[ra];
12607d9195a7SDavid du Colombier 		if(upd)
12617d9195a7SDavid du Colombier 			reg.r[ra] = ea;
12627d9195a7SDavid du Colombier 	} else {
12637d9195a7SDavid du Colombier 		if(upd)
12647d9195a7SDavid du Colombier 			undef(ir);
12657d9195a7SDavid du Colombier 	}
12667d9195a7SDavid du Colombier 	if(trace)
12677d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
12687d9195a7SDavid du Colombier 
12697d9195a7SDavid du Colombier 	reg.r[rd] = getmem_w(ea);
12707d9195a7SDavid du Colombier }
12717d9195a7SDavid du Colombier 
12727d9195a7SDavid du Colombier void
lwzx(ulong ir)12737d9195a7SDavid du Colombier lwzx(ulong ir)
12747d9195a7SDavid du Colombier {
12757d9195a7SDavid du Colombier 	ulong ea;
12767d9195a7SDavid du Colombier 	int rb, ra, rd, upd;
12777d9195a7SDavid du Colombier 
12787d9195a7SDavid du Colombier 	getarrr(ir);
12797d9195a7SDavid du Colombier 	ea = reg.r[rb];
12807d9195a7SDavid du Colombier 	upd = getxo(ir)==55;
12817d9195a7SDavid du Colombier 	if(ra) {
12827d9195a7SDavid du Colombier 		ea += reg.r[ra];
12837d9195a7SDavid du Colombier 		if(upd)
12847d9195a7SDavid du Colombier 			reg.r[ra] = ea;
12857d9195a7SDavid du Colombier 		if(trace)
12867d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
12877d9195a7SDavid du Colombier 	} else {
12887d9195a7SDavid du Colombier 		if(upd)
12897d9195a7SDavid du Colombier 			undef(ir);
12907d9195a7SDavid du Colombier 		if(trace)
12917d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
12927d9195a7SDavid du Colombier 	}
12937d9195a7SDavid du Colombier 
12947d9195a7SDavid du Colombier 	reg.r[rd] = getmem_w(ea);
12957d9195a7SDavid du Colombier }
12967d9195a7SDavid du Colombier 
12977d9195a7SDavid du Colombier void
lwarx(ulong ir)12987d9195a7SDavid du Colombier lwarx(ulong ir)
12997d9195a7SDavid du Colombier {
13007d9195a7SDavid du Colombier 	lwzx(ir);
13017d9195a7SDavid du Colombier }
13027d9195a7SDavid du Colombier 
13037d9195a7SDavid du Colombier void
lbz(ulong ir)13047d9195a7SDavid du Colombier lbz(ulong ir)
13057d9195a7SDavid du Colombier {
13067d9195a7SDavid du Colombier 	ulong ea;
13077d9195a7SDavid du Colombier 	int ra, rd, upd;
13087d9195a7SDavid du Colombier 	long imm;
13097d9195a7SDavid du Colombier 
13107d9195a7SDavid du Colombier 	getairr(ir);
13117d9195a7SDavid du Colombier 	ea = imm;
13127d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
13137d9195a7SDavid du Colombier 	if(ra) {
13147d9195a7SDavid du Colombier 		ea += reg.r[ra];
13157d9195a7SDavid du Colombier 		if(upd)
13167d9195a7SDavid du Colombier 			reg.r[ra] = ea;
13177d9195a7SDavid du Colombier 	} else {
13187d9195a7SDavid du Colombier 		if(upd)
13197d9195a7SDavid du Colombier 			undef(ir);
13207d9195a7SDavid du Colombier 	}
13217d9195a7SDavid du Colombier 	if(trace)
13227d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
13237d9195a7SDavid du Colombier 
13247d9195a7SDavid du Colombier 	reg.r[rd] = getmem_b(ea);
13257d9195a7SDavid du Colombier }
13267d9195a7SDavid du Colombier 
13277d9195a7SDavid du Colombier void
lbzx(ulong ir)13287d9195a7SDavid du Colombier lbzx(ulong ir)
13297d9195a7SDavid du Colombier {
13307d9195a7SDavid du Colombier 	ulong ea;
13317d9195a7SDavid du Colombier 	int rb, ra, rd, upd;
13327d9195a7SDavid du Colombier 
13337d9195a7SDavid du Colombier 	getarrr(ir);
13347d9195a7SDavid du Colombier 	ea = reg.r[rb];
13357d9195a7SDavid du Colombier 	upd = getxo(ir)==119;
13367d9195a7SDavid du Colombier 	if(ra) {
13377d9195a7SDavid du Colombier 		ea += reg.r[ra];
13387d9195a7SDavid du Colombier 		if(upd)
13397d9195a7SDavid du Colombier 			reg.r[ra] = ea;
13407d9195a7SDavid du Colombier 		if(trace)
13417d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
13427d9195a7SDavid du Colombier 	} else {
13437d9195a7SDavid du Colombier 		if(upd)
13447d9195a7SDavid du Colombier 			undef(ir);
13457d9195a7SDavid du Colombier 		if(trace)
13467d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
13477d9195a7SDavid du Colombier 	}
13487d9195a7SDavid du Colombier 
13497d9195a7SDavid du Colombier 	reg.r[rd] = getmem_b(ea);
13507d9195a7SDavid du Colombier }
13517d9195a7SDavid du Colombier 
13527d9195a7SDavid du Colombier void
stw(ulong ir)13537d9195a7SDavid du Colombier stw(ulong ir)
13547d9195a7SDavid du Colombier {
13557d9195a7SDavid du Colombier 	ulong ea;
13567d9195a7SDavid du Colombier 	int ra, rd, upd;
13577d9195a7SDavid du Colombier 	long imm;
13587d9195a7SDavid du Colombier 
13597d9195a7SDavid du Colombier 	getairr(ir);
13607d9195a7SDavid du Colombier 	ea = imm;
13617d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
13627d9195a7SDavid du Colombier 	if(ra) {
13637d9195a7SDavid du Colombier 		ea += reg.r[ra];
13647d9195a7SDavid du Colombier 		if(upd)
13657d9195a7SDavid du Colombier 			reg.r[ra] = ea;
13667d9195a7SDavid du Colombier 	} else {
13677d9195a7SDavid du Colombier 		if(upd)
13687d9195a7SDavid du Colombier 			undef(ir);
13697d9195a7SDavid du Colombier 	}
13707d9195a7SDavid du Colombier 	if(trace)
13717d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
13727d9195a7SDavid du Colombier 					ci->name, rd, imm, ra, ea, reg.r[rd], reg.r[rd]);
13737d9195a7SDavid du Colombier 	putmem_w(ea, reg.r[rd]);
13747d9195a7SDavid du Colombier 
13757d9195a7SDavid du Colombier }
13767d9195a7SDavid du Colombier 
13777d9195a7SDavid du Colombier void
stwx(ulong ir)13787d9195a7SDavid du Colombier stwx(ulong ir)
13797d9195a7SDavid du Colombier {
13807d9195a7SDavid du Colombier 	ulong ea;
13817d9195a7SDavid du Colombier 	int ra, rd, upd, rb;
13827d9195a7SDavid du Colombier 
13837d9195a7SDavid du Colombier 	getarrr(ir);
13847d9195a7SDavid du Colombier 	ea = reg.r[rb];
13857d9195a7SDavid du Colombier 	upd = getxo(ir)==183;
13867d9195a7SDavid du Colombier 	if(ra) {
13877d9195a7SDavid du Colombier 		ea += reg.r[ra];
13887d9195a7SDavid du Colombier 		if(upd)
13897d9195a7SDavid du Colombier 			reg.r[ra] = ea;
13907d9195a7SDavid du Colombier 		if(trace)
13917d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
13927d9195a7SDavid du Colombier 					ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
13937d9195a7SDavid du Colombier 	} else {
13947d9195a7SDavid du Colombier 		if(upd)
13957d9195a7SDavid du Colombier 			undef(ir);
13967d9195a7SDavid du Colombier 		if(trace)
13977d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
13987d9195a7SDavid du Colombier 					ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
13997d9195a7SDavid du Colombier 	}
14007d9195a7SDavid du Colombier 	putmem_w(ea, reg.r[rd]);
14017d9195a7SDavid du Colombier 
14027d9195a7SDavid du Colombier }
14037d9195a7SDavid du Colombier 
14047d9195a7SDavid du Colombier void
stwcx(ulong ir)14057d9195a7SDavid du Colombier stwcx(ulong ir)
14067d9195a7SDavid du Colombier {
14077d9195a7SDavid du Colombier 	ulong ea;
14087d9195a7SDavid du Colombier 	int ra, rd, rb;
14097d9195a7SDavid du Colombier 
14107d9195a7SDavid du Colombier 	if((ir & Rc) == 0)
14117d9195a7SDavid du Colombier 		undef(ir);
14127d9195a7SDavid du Colombier 	getarrr(ir);
14137d9195a7SDavid du Colombier 	ea = reg.r[rb];
14147d9195a7SDavid du Colombier 	if(ra) {
14157d9195a7SDavid du Colombier 		ea += reg.r[ra];
14167d9195a7SDavid du Colombier 		if(trace)
14177d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
14187d9195a7SDavid du Colombier 					ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
14197d9195a7SDavid du Colombier 	} else {
14207d9195a7SDavid du Colombier 		if(trace)
14217d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
14227d9195a7SDavid du Colombier 					ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
14237d9195a7SDavid du Colombier 	}
14247d9195a7SDavid du Colombier 	putmem_w(ea, reg.r[rd]);	/* assume a reservation exists; store succeeded */
14257d9195a7SDavid du Colombier 	setcr(0, 0);
14267d9195a7SDavid du Colombier 
14277d9195a7SDavid du Colombier }
14287d9195a7SDavid du Colombier 
14297d9195a7SDavid du Colombier void
stb(ulong ir)14307d9195a7SDavid du Colombier stb(ulong ir)
14317d9195a7SDavid du Colombier {
14327d9195a7SDavid du Colombier 	ulong ea;
14337d9195a7SDavid du Colombier 	int ra, rd, upd, v;
14347d9195a7SDavid du Colombier 	long imm;
14357d9195a7SDavid du Colombier 
14367d9195a7SDavid du Colombier 	getairr(ir);
14377d9195a7SDavid du Colombier 	ea = imm;
14387d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
14397d9195a7SDavid du Colombier 	if(ra) {
14407d9195a7SDavid du Colombier 		ea += reg.r[ra];
14417d9195a7SDavid du Colombier 		if(upd)
14427d9195a7SDavid du Colombier 			reg.r[ra] = ea;
14437d9195a7SDavid du Colombier 	} else {
14447d9195a7SDavid du Colombier 		if(upd)
14457d9195a7SDavid du Colombier 			undef(ir);
14467d9195a7SDavid du Colombier 	}
14477d9195a7SDavid du Colombier 	v = reg.r[rd] & 0xFF;
14487d9195a7SDavid du Colombier 	if(trace)
14497d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
14507d9195a7SDavid du Colombier 					ci->name, rd, imm, ra, ea, v, v);
14517d9195a7SDavid du Colombier 	putmem_b(ea, v);
14527d9195a7SDavid du Colombier }
14537d9195a7SDavid du Colombier 
14547d9195a7SDavid du Colombier void
stbx(ulong ir)14557d9195a7SDavid du Colombier stbx(ulong ir)
14567d9195a7SDavid du Colombier {
14577d9195a7SDavid du Colombier 	ulong ea;
14587d9195a7SDavid du Colombier 	int ra, rd, upd, rb, v;
14597d9195a7SDavid du Colombier 
14607d9195a7SDavid du Colombier 	getarrr(ir);
14617d9195a7SDavid du Colombier 	ea = reg.r[rb];
14627d9195a7SDavid du Colombier 	upd = getxo(ir)==247;
14637d9195a7SDavid du Colombier 	v = reg.r[rd] & 0xFF;
14647d9195a7SDavid du Colombier 	if(ra) {
14657d9195a7SDavid du Colombier 		ea += reg.r[ra];
14667d9195a7SDavid du Colombier 		if(upd)
14677d9195a7SDavid du Colombier 			reg.r[ra] = ea;
14687d9195a7SDavid du Colombier 		if(trace)
14697d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
14707d9195a7SDavid du Colombier 					ci->name, rd, ra, rb, ea, v, v);
14717d9195a7SDavid du Colombier 	} else {
14727d9195a7SDavid du Colombier 		if(upd)
14737d9195a7SDavid du Colombier 			undef(ir);
14747d9195a7SDavid du Colombier 		if(trace)
14757d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
14767d9195a7SDavid du Colombier 					ci->name, rd, rb, ea, v, v);
14777d9195a7SDavid du Colombier 	}
14787d9195a7SDavid du Colombier 	putmem_b(ea, v);
14797d9195a7SDavid du Colombier 
14807d9195a7SDavid du Colombier }
14817d9195a7SDavid du Colombier 
14827d9195a7SDavid du Colombier void
lhz(ulong ir)14837d9195a7SDavid du Colombier lhz(ulong ir)
14847d9195a7SDavid du Colombier {
14857d9195a7SDavid du Colombier 	ulong ea;
14867d9195a7SDavid du Colombier 	int imm, ra, rd, upd;
14877d9195a7SDavid du Colombier 
14887d9195a7SDavid du Colombier 	getairr(ir);
14897d9195a7SDavid du Colombier 	ea = imm;
14907d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
14917d9195a7SDavid du Colombier 	if(ra) {
14927d9195a7SDavid du Colombier 		ea += reg.r[ra];
14937d9195a7SDavid du Colombier 		if(upd)
14947d9195a7SDavid du Colombier 			reg.r[ra] = ea;
14957d9195a7SDavid du Colombier 	} else {
14967d9195a7SDavid du Colombier 		if(upd)
14977d9195a7SDavid du Colombier 			undef(ir);
14987d9195a7SDavid du Colombier 	}
14997d9195a7SDavid du Colombier 	if(trace)
15007d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
15017d9195a7SDavid du Colombier 
15027d9195a7SDavid du Colombier 	reg.r[rd] = getmem_h(ea);
15037d9195a7SDavid du Colombier }
15047d9195a7SDavid du Colombier 
15057d9195a7SDavid du Colombier void
lhzx(ulong ir)15067d9195a7SDavid du Colombier lhzx(ulong ir)
15077d9195a7SDavid du Colombier {
15087d9195a7SDavid du Colombier 	ulong ea;
15097d9195a7SDavid du Colombier 	int rb, ra, rd, upd;
15107d9195a7SDavid du Colombier 
15117d9195a7SDavid du Colombier 	getarrr(ir);
15127d9195a7SDavid du Colombier 	ea = reg.r[rb];
15137d9195a7SDavid du Colombier 	upd = getxo(ir)==311;
15147d9195a7SDavid du Colombier 	if(ra) {
15157d9195a7SDavid du Colombier 		ea += reg.r[ra];
15167d9195a7SDavid du Colombier 		if(upd)
15177d9195a7SDavid du Colombier 			reg.r[ra] = ea;
15187d9195a7SDavid du Colombier 		if(trace)
15197d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
15207d9195a7SDavid du Colombier 	} else {
15217d9195a7SDavid du Colombier 		if(upd)
15227d9195a7SDavid du Colombier 			undef(ir);
15237d9195a7SDavid du Colombier 		if(trace)
15247d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
15257d9195a7SDavid du Colombier 	}
15267d9195a7SDavid du Colombier 
15277d9195a7SDavid du Colombier 	reg.r[rd] = getmem_h(ea);
15287d9195a7SDavid du Colombier }
15297d9195a7SDavid du Colombier 
15307d9195a7SDavid du Colombier void
lha(ulong ir)15317d9195a7SDavid du Colombier lha(ulong ir)
15327d9195a7SDavid du Colombier {
15337d9195a7SDavid du Colombier 	ulong ea;
15347d9195a7SDavid du Colombier 	int imm, ra, rd, upd;
15357d9195a7SDavid du Colombier 
15367d9195a7SDavid du Colombier 	getairr(ir);
15377d9195a7SDavid du Colombier 	ea = imm;
15387d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
15397d9195a7SDavid du Colombier 	if(ra) {
15407d9195a7SDavid du Colombier 		ea += reg.r[ra];
15417d9195a7SDavid du Colombier 		if(upd)
15427d9195a7SDavid du Colombier 			reg.r[ra] = ea;
15437d9195a7SDavid du Colombier 	} else {
15447d9195a7SDavid du Colombier 		if(upd)
15457d9195a7SDavid du Colombier 			undef(ir);
15467d9195a7SDavid du Colombier 	}
15477d9195a7SDavid du Colombier 	if(trace)
15487d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
15497d9195a7SDavid du Colombier 
15507d9195a7SDavid du Colombier 	reg.r[rd] = (short)getmem_h(ea);
15517d9195a7SDavid du Colombier }
15527d9195a7SDavid du Colombier 
15537d9195a7SDavid du Colombier void
lhax(ulong ir)15547d9195a7SDavid du Colombier lhax(ulong ir)
15557d9195a7SDavid du Colombier {
15567d9195a7SDavid du Colombier 	ulong ea;
15577d9195a7SDavid du Colombier 	int rb, ra, rd, upd;
15587d9195a7SDavid du Colombier 
15597d9195a7SDavid du Colombier 	getarrr(ir);
15607d9195a7SDavid du Colombier 	ea = reg.r[rb];
15617d9195a7SDavid du Colombier 	upd = getxo(ir)==311;
15627d9195a7SDavid du Colombier 	if(ra) {
15637d9195a7SDavid du Colombier 		ea += reg.r[ra];
15647d9195a7SDavid du Colombier 		if(upd)
15657d9195a7SDavid du Colombier 			reg.r[ra] = ea;
15667d9195a7SDavid du Colombier 		if(trace)
15677d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
15687d9195a7SDavid du Colombier 	} else {
15697d9195a7SDavid du Colombier 		if(upd)
15707d9195a7SDavid du Colombier 			undef(ir);
15717d9195a7SDavid du Colombier 		if(trace)
15727d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
15737d9195a7SDavid du Colombier 	}
15747d9195a7SDavid du Colombier 
15757d9195a7SDavid du Colombier 	reg.r[rd] = (short)getmem_h(ea);
15767d9195a7SDavid du Colombier }
15777d9195a7SDavid du Colombier 
15787d9195a7SDavid du Colombier void
lhbrx(ulong ir)15797d9195a7SDavid du Colombier lhbrx(ulong ir)
15807d9195a7SDavid du Colombier {
15817d9195a7SDavid du Colombier 	ulong ea;
15827d9195a7SDavid du Colombier 	int rb, ra, rd;
15837d9195a7SDavid du Colombier 	ulong v;
15847d9195a7SDavid du Colombier 
15857d9195a7SDavid du Colombier 	getarrr(ir);
15867d9195a7SDavid du Colombier 	ea = reg.r[rb];
15877d9195a7SDavid du Colombier 	if(ra) {
15887d9195a7SDavid du Colombier 		ea += reg.r[ra];
15897d9195a7SDavid du Colombier 		if(trace)
15907d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
15917d9195a7SDavid du Colombier 	} else {
15927d9195a7SDavid du Colombier 		if(trace)
15937d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
15947d9195a7SDavid du Colombier 	}
15957d9195a7SDavid du Colombier 	v = getmem_h(ea);
15967d9195a7SDavid du Colombier 
15977d9195a7SDavid du Colombier 	reg.r[rd] = ((v&0xFF)<<8)|(v&0xFF);
15987d9195a7SDavid du Colombier }
15997d9195a7SDavid du Colombier 
16007d9195a7SDavid du Colombier void
sth(ulong ir)16017d9195a7SDavid du Colombier sth(ulong ir)
16027d9195a7SDavid du Colombier {
16037d9195a7SDavid du Colombier 	ulong ea;
16047d9195a7SDavid du Colombier 	int imm, ra, rd, upd, v;
16057d9195a7SDavid du Colombier 
16067d9195a7SDavid du Colombier 	getairr(ir);
16077d9195a7SDavid du Colombier 	ea = imm;
16087d9195a7SDavid du Colombier 	upd = (ir&(1L<<26))!=0;
16097d9195a7SDavid du Colombier 	if(ra) {
16107d9195a7SDavid du Colombier 		ea += reg.r[ra];
16117d9195a7SDavid du Colombier 		if(upd)
16127d9195a7SDavid du Colombier 			reg.r[ra] = ea;
16137d9195a7SDavid du Colombier 	} else {
16147d9195a7SDavid du Colombier 		if(upd)
16157d9195a7SDavid du Colombier 			undef(ir);
16167d9195a7SDavid du Colombier 	}
16177d9195a7SDavid du Colombier 	v = reg.r[rd] & 0xFFFF;
16187d9195a7SDavid du Colombier 	if(trace)
16197d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
16207d9195a7SDavid du Colombier 					ci->name, rd, imm, ra, ea, v, v);
16217d9195a7SDavid du Colombier 	putmem_h(ea, v);
16227d9195a7SDavid du Colombier 
16237d9195a7SDavid du Colombier }
16247d9195a7SDavid du Colombier 
16257d9195a7SDavid du Colombier void
sthx(ulong ir)16267d9195a7SDavid du Colombier sthx(ulong ir)
16277d9195a7SDavid du Colombier {
16287d9195a7SDavid du Colombier 	ulong ea;
16297d9195a7SDavid du Colombier 	int ra, rd, upd, rb, v;
16307d9195a7SDavid du Colombier 
16317d9195a7SDavid du Colombier 	getarrr(ir);
16327d9195a7SDavid du Colombier 	ea = reg.r[rb];
16337d9195a7SDavid du Colombier 	upd = getxo(ir)==247;
16347d9195a7SDavid du Colombier 	v = reg.r[rd] & 0xFFFF;
16357d9195a7SDavid du Colombier 	if(ra) {
16367d9195a7SDavid du Colombier 		ea += reg.r[ra];
16377d9195a7SDavid du Colombier 		if(upd)
16387d9195a7SDavid du Colombier 			reg.r[ra] = ea;
16397d9195a7SDavid du Colombier 		if(trace)
16407d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
16417d9195a7SDavid du Colombier 					ci->name, rd, ra, rb, ea, v, v);
16427d9195a7SDavid du Colombier 	} else {
16437d9195a7SDavid du Colombier 		if(upd)
16447d9195a7SDavid du Colombier 			undef(ir);
16457d9195a7SDavid du Colombier 		if(trace)
16467d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
16477d9195a7SDavid du Colombier 					ci->name, rd, rb, ea, v, v);
16487d9195a7SDavid du Colombier 	}
16497d9195a7SDavid du Colombier 	putmem_h(ea, v);
16507d9195a7SDavid du Colombier }
16517d9195a7SDavid du Colombier 
16527d9195a7SDavid du Colombier void
sthbrx(ulong ir)16537d9195a7SDavid du Colombier sthbrx(ulong ir)
16547d9195a7SDavid du Colombier {
16557d9195a7SDavid du Colombier 	ulong ea;
16567d9195a7SDavid du Colombier 	int ra, rd, rb;
16577d9195a7SDavid du Colombier 	ulong v;
16587d9195a7SDavid du Colombier 
16597d9195a7SDavid du Colombier 	getarrr(ir);
16607d9195a7SDavid du Colombier 	ea = reg.r[rb];
16617d9195a7SDavid du Colombier 	v = reg.r[rd];
16627d9195a7SDavid du Colombier 	v = ((v&0xFF)<<8)|(v&0xFF);
16637d9195a7SDavid du Colombier 	if(ra) {
16647d9195a7SDavid du Colombier 		ea += reg.r[ra];
16657d9195a7SDavid du Colombier 		if(trace)
16667d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
16677d9195a7SDavid du Colombier 					ci->name, rd, ra, rb, ea, v, v);
16687d9195a7SDavid du Colombier 	} else {
16697d9195a7SDavid du Colombier 		if(trace)
16707d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
16717d9195a7SDavid du Colombier 					ci->name, rd, rb, ea, v, v);
16727d9195a7SDavid du Colombier 	}
16737d9195a7SDavid du Colombier 	putmem_h(ea, v);
16747d9195a7SDavid du Colombier }
16757d9195a7SDavid du Colombier 
16767d9195a7SDavid du Colombier void
lwbrx(ulong ir)16777d9195a7SDavid du Colombier lwbrx(ulong ir)
16787d9195a7SDavid du Colombier {
16797d9195a7SDavid du Colombier 	ulong ea;
16807d9195a7SDavid du Colombier 	int rb, ra, rd, i;
16817d9195a7SDavid du Colombier 	ulong v;
16827d9195a7SDavid du Colombier 
16837d9195a7SDavid du Colombier 	getarrr(ir);
16847d9195a7SDavid du Colombier 	if(ir & Rc)
16857d9195a7SDavid du Colombier 		undef(ir);
16867d9195a7SDavid du Colombier 	ea = reg.r[rb];
16877d9195a7SDavid du Colombier 	if(ra) {
16887d9195a7SDavid du Colombier 		ea += reg.r[ra];
16897d9195a7SDavid du Colombier 		if(trace)
16907d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
16917d9195a7SDavid du Colombier 	} else {
16927d9195a7SDavid du Colombier 		if(trace)
16937d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
16947d9195a7SDavid du Colombier 	}
16957d9195a7SDavid du Colombier 	v = 0;
16967d9195a7SDavid du Colombier 	for(i = 0; i < 4; i++)
16977d9195a7SDavid du Colombier 		v = v>>8 | getmem_b(ea++);	/* assume unaligned load is allowed */
16987d9195a7SDavid du Colombier 	reg.r[rd] = v;
16997d9195a7SDavid du Colombier }
17007d9195a7SDavid du Colombier 
17017d9195a7SDavid du Colombier void
stwbrx(ulong ir)17027d9195a7SDavid du Colombier stwbrx(ulong ir)
17037d9195a7SDavid du Colombier {
17047d9195a7SDavid du Colombier 	ulong ea;
17057d9195a7SDavid du Colombier 	int rb, ra, rd, i;
17067d9195a7SDavid du Colombier 	ulong v;
17077d9195a7SDavid du Colombier 
17087d9195a7SDavid du Colombier 	getarrr(ir);
17097d9195a7SDavid du Colombier 	if(ir & Rc)
17107d9195a7SDavid du Colombier 		undef(ir);
17117d9195a7SDavid du Colombier 	ea = reg.r[rb];
17127d9195a7SDavid du Colombier 	if(ra) {
17137d9195a7SDavid du Colombier 		ea += reg.r[ra];
17147d9195a7SDavid du Colombier 		if(trace)
17157d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
17167d9195a7SDavid du Colombier 	} else {
17177d9195a7SDavid du Colombier 		if(trace)
17187d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
17197d9195a7SDavid du Colombier 	}
17207d9195a7SDavid du Colombier 	v = 0;
17217d9195a7SDavid du Colombier 	for(i = 0; i < 4; i++) {
17227d9195a7SDavid du Colombier 		putmem_b(ea++, v & 0xFF);	/* assume unaligned store is allowed */
17237d9195a7SDavid du Colombier 		v >>= 8;
17247d9195a7SDavid du Colombier 	}
17257d9195a7SDavid du Colombier }
17267d9195a7SDavid du Colombier 
17277d9195a7SDavid du Colombier void
lswi(ulong ir)17287d9195a7SDavid du Colombier lswi(ulong ir)
17297d9195a7SDavid du Colombier {
17307d9195a7SDavid du Colombier 	ulong ea;
17317d9195a7SDavid du Colombier 	int rb, ra, rd, n, i, r, b;
17327d9195a7SDavid du Colombier 
17337d9195a7SDavid du Colombier 	getarrr(ir);
17347d9195a7SDavid du Colombier 	if(ir & Rc)
17357d9195a7SDavid du Colombier 		undef(ir);
17367d9195a7SDavid du Colombier 	n = rb;
17377d9195a7SDavid du Colombier 	if(n == 0)
17387d9195a7SDavid du Colombier 		n = 32;
17397d9195a7SDavid du Colombier 	ea = 0;
17407d9195a7SDavid du Colombier 	if(ra) {
17417d9195a7SDavid du Colombier 		ea += reg.r[ra];
17427d9195a7SDavid du Colombier 		if(trace)
17437d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
17447d9195a7SDavid du Colombier 	} else {
17457d9195a7SDavid du Colombier 		if(trace)
17467d9195a7SDavid du Colombier 			itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
17477d9195a7SDavid du Colombier 	}
17487d9195a7SDavid du Colombier 	i = -1;
17497d9195a7SDavid du Colombier 	r = rd-1;
17507d9195a7SDavid du Colombier 	while(--n >= 0) {
17517d9195a7SDavid du Colombier 		if(i < 0) {
17527d9195a7SDavid du Colombier 			r = (r+1)&0x1F;
17537d9195a7SDavid du Colombier 			if(ra == 0 || r != ra)
17547d9195a7SDavid du Colombier 				reg.r[r] = 0;
17557d9195a7SDavid du Colombier 			i = 24;
17567d9195a7SDavid du Colombier 		}
17577d9195a7SDavid du Colombier 		b = getmem_b(ea++);
17587d9195a7SDavid du Colombier 		if(ra == 0 || r != ra)
17597d9195a7SDavid du Colombier 			reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
17607d9195a7SDavid du Colombier 		i -= 8;
17617d9195a7SDavid du Colombier 	}
17627d9195a7SDavid du Colombier }
17637d9195a7SDavid du Colombier 
17647d9195a7SDavid du Colombier void
lswx(ulong ir)17657d9195a7SDavid du Colombier lswx(ulong ir)
17667d9195a7SDavid du Colombier {
17677d9195a7SDavid du Colombier 	ulong ea;
17687d9195a7SDavid du Colombier 	int rb, ra, rd, n, i, r, b;
17697d9195a7SDavid du Colombier 
17707d9195a7SDavid du Colombier 	getarrr(ir);
17717d9195a7SDavid du Colombier 	if(ir & Rc)
17727d9195a7SDavid du Colombier 		undef(ir);
17737d9195a7SDavid du Colombier 	n = reg.xer & 0x7F;
17747d9195a7SDavid du Colombier 	ea = reg.r[rb];
17757d9195a7SDavid du Colombier 	if(ra) {
17767d9195a7SDavid du Colombier 		ea += reg.r[ra];
17777d9195a7SDavid du Colombier 		if(trace)
17787d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
17797d9195a7SDavid du Colombier 	} else {
17807d9195a7SDavid du Colombier 		if(trace)
17817d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
17827d9195a7SDavid du Colombier 	}
17837d9195a7SDavid du Colombier 	i = -1;
17847d9195a7SDavid du Colombier 	r = rd-1;
17857d9195a7SDavid du Colombier 	while(--n >= 0) {
17867d9195a7SDavid du Colombier 		if(i < 0) {
17877d9195a7SDavid du Colombier 			r = (r+1)&0x1F;
17887d9195a7SDavid du Colombier 			if((ra == 0 || r != ra) && r != rb)
17897d9195a7SDavid du Colombier 				reg.r[r] = 0;
17907d9195a7SDavid du Colombier 			i = 24;
17917d9195a7SDavid du Colombier 		}
17927d9195a7SDavid du Colombier 		b = getmem_b(ea++);
17937d9195a7SDavid du Colombier 		if((ra == 0 || r != ra) && r != rb)
17947d9195a7SDavid du Colombier 			reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
17957d9195a7SDavid du Colombier 		i -= 8;
17967d9195a7SDavid du Colombier 	}
17977d9195a7SDavid du Colombier }
17987d9195a7SDavid du Colombier 
17997d9195a7SDavid du Colombier void
stswx(ulong ir)18007d9195a7SDavid du Colombier stswx(ulong ir)
18017d9195a7SDavid du Colombier {
18027d9195a7SDavid du Colombier 	ulong ea;
18037d9195a7SDavid du Colombier 	int rb, ra, rd, n, i, r;
18047d9195a7SDavid du Colombier 
18057d9195a7SDavid du Colombier 	getarrr(ir);
18067d9195a7SDavid du Colombier 	if(ir & Rc)
18077d9195a7SDavid du Colombier 		undef(ir);
18087d9195a7SDavid du Colombier 	n = reg.xer & 0x7F;
18097d9195a7SDavid du Colombier 	ea = reg.r[rb];
18107d9195a7SDavid du Colombier 	if(ra) {
18117d9195a7SDavid du Colombier 		ea += reg.r[ra];
18127d9195a7SDavid du Colombier 		if(trace)
18137d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
18147d9195a7SDavid du Colombier 	} else {
18157d9195a7SDavid du Colombier 		if(trace)
18167d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
18177d9195a7SDavid du Colombier 	}
18187d9195a7SDavid du Colombier 	i = -1;
18197d9195a7SDavid du Colombier 	r = rd-1;
18207d9195a7SDavid du Colombier 	while(--n >= 0) {
18217d9195a7SDavid du Colombier 		if(i < 0) {
18227d9195a7SDavid du Colombier 			r = (r+1)&0x1F;
18237d9195a7SDavid du Colombier 			i = 24;
18247d9195a7SDavid du Colombier 		}
18257d9195a7SDavid du Colombier 		putmem_b(ea++, (reg.r[r]>>i)&0xFF);
18267d9195a7SDavid du Colombier 		i -= 8;
18277d9195a7SDavid du Colombier 	}
18287d9195a7SDavid du Colombier }
18297d9195a7SDavid du Colombier 
18307d9195a7SDavid du Colombier void
stswi(ulong ir)18317d9195a7SDavid du Colombier stswi(ulong ir)
18327d9195a7SDavid du Colombier {
18337d9195a7SDavid du Colombier 	ulong ea;
18347d9195a7SDavid du Colombier 	int rb, ra, rd, n, i, r;
18357d9195a7SDavid du Colombier 
18367d9195a7SDavid du Colombier 	getarrr(ir);
18377d9195a7SDavid du Colombier 	if(ir & Rc)
18387d9195a7SDavid du Colombier 		undef(ir);
18397d9195a7SDavid du Colombier 	n = rb;
18407d9195a7SDavid du Colombier 	if(n == 0)
18417d9195a7SDavid du Colombier 		n = 32;
18427d9195a7SDavid du Colombier 	ea = 0;
18437d9195a7SDavid du Colombier 	if(ra) {
18447d9195a7SDavid du Colombier 		ea += reg.r[ra];
18457d9195a7SDavid du Colombier 		if(trace)
18467d9195a7SDavid du Colombier 			itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
18477d9195a7SDavid du Colombier 	} else {
18487d9195a7SDavid du Colombier 		if(trace)
18497d9195a7SDavid du Colombier 			itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
18507d9195a7SDavid du Colombier 	}
18517d9195a7SDavid du Colombier 	i = -1;
18527d9195a7SDavid du Colombier 	r = rd-1;
18537d9195a7SDavid du Colombier 	while(--n >= 0) {
18547d9195a7SDavid du Colombier 		if(i < 0) {
18557d9195a7SDavid du Colombier 			r = (r+1)&0x1F;
18567d9195a7SDavid du Colombier 			i = 24;
18577d9195a7SDavid du Colombier 		}
18587d9195a7SDavid du Colombier 		putmem_b(ea++, (reg.r[r]>>i)&0xFF);
18597d9195a7SDavid du Colombier 		i -= 8;
18607d9195a7SDavid du Colombier 	}
18617d9195a7SDavid du Colombier }
18627d9195a7SDavid du Colombier 
18637d9195a7SDavid du Colombier void
lmw(ulong ir)18647d9195a7SDavid du Colombier lmw(ulong ir)
18657d9195a7SDavid du Colombier {
18667d9195a7SDavid du Colombier 	ulong ea;
18677d9195a7SDavid du Colombier 	int ra, rd, r;
18687d9195a7SDavid du Colombier 	long imm;
18697d9195a7SDavid du Colombier 
18707d9195a7SDavid du Colombier 	getairr(ir);
18717d9195a7SDavid du Colombier 	ea = imm;
18727d9195a7SDavid du Colombier 	if(ra)
18737d9195a7SDavid du Colombier 		ea += reg.r[ra];
18747d9195a7SDavid du Colombier 	if(trace)
18757d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
18767d9195a7SDavid du Colombier 
18777d9195a7SDavid du Colombier 	for(r = rd; r <= 31; r++) {
18787d9195a7SDavid du Colombier 		if(r != 0 && r != rd)
18797d9195a7SDavid du Colombier 			reg.r[rd] = getmem_w(ea);
18807d9195a7SDavid du Colombier 		ea += 4;
18817d9195a7SDavid du Colombier 	}
18827d9195a7SDavid du Colombier }
18837d9195a7SDavid du Colombier 
18847d9195a7SDavid du Colombier void
stmw(ulong ir)18857d9195a7SDavid du Colombier stmw(ulong ir)
18867d9195a7SDavid du Colombier {
18877d9195a7SDavid du Colombier 	ulong ea;
18887d9195a7SDavid du Colombier 	int ra, rd, r;
18897d9195a7SDavid du Colombier 	long imm;
18907d9195a7SDavid du Colombier 
18917d9195a7SDavid du Colombier 	getairr(ir);
18927d9195a7SDavid du Colombier 	ea = imm;
18937d9195a7SDavid du Colombier 	if(ra)
18947d9195a7SDavid du Colombier 		ea += reg.r[ra];
18957d9195a7SDavid du Colombier 	if(trace)
18967d9195a7SDavid du Colombier 		itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
18977d9195a7SDavid du Colombier 
18987d9195a7SDavid du Colombier 	for(r = rd; r <= 31; r++) {
18997d9195a7SDavid du Colombier 		putmem_w(ea, reg.r[rd]);
19007d9195a7SDavid du Colombier 		ea += 4;
19017d9195a7SDavid du Colombier 	}
19027d9195a7SDavid du Colombier }
19037d9195a7SDavid du Colombier 
19047d9195a7SDavid du Colombier void
twi(ulong ir)19057d9195a7SDavid du Colombier twi(ulong ir)
19067d9195a7SDavid du Colombier {
19077d9195a7SDavid du Colombier 	int rd, ra;
19087d9195a7SDavid du Colombier 	long a, imm;
19097d9195a7SDavid du Colombier 
19107d9195a7SDavid du Colombier 	getairr(ir);
19117d9195a7SDavid du Colombier 	a = reg.r[ra];
19127d9195a7SDavid du Colombier 	if(trace)
19137d9195a7SDavid du Colombier 		itrace("twi\t#%.2x,r%d,$0x%lux (%ld)", rd, ra, imm, imm);
19147d9195a7SDavid du Colombier 	if(a < imm && rd&0x10 ||
19157d9195a7SDavid du Colombier 	   a > imm && rd&0x08 ||
19167d9195a7SDavid du Colombier 	   a == imm && rd&0x04 ||
19177d9195a7SDavid du Colombier 	   (ulong)a < imm && rd&0x02 ||
19187d9195a7SDavid du Colombier 	   (ulong)a > imm && rd&0x01) {
19197d9195a7SDavid du Colombier 		Bprint(bioout, "program_exception (trap type)\n");
19207d9195a7SDavid du Colombier 		longjmp(errjmp, 0);
19217d9195a7SDavid du Colombier 	}
19227d9195a7SDavid du Colombier }
19237d9195a7SDavid du Colombier 
19247d9195a7SDavid du Colombier void
tw(ulong ir)19257d9195a7SDavid du Colombier tw(ulong ir)
19267d9195a7SDavid du Colombier {
19277d9195a7SDavid du Colombier 	int rd, ra, rb;
19287d9195a7SDavid du Colombier 	long a, b;
19297d9195a7SDavid du Colombier 
19307d9195a7SDavid du Colombier 	getarrr(ir);
19317d9195a7SDavid du Colombier 	a = reg.r[ra];
19327d9195a7SDavid du Colombier 	b = reg.r[rb];
19337d9195a7SDavid du Colombier 	if(trace)
19347d9195a7SDavid du Colombier 		itrace("tw\t#%.2x,r%d,r%d", rd, ra, rb);
19357d9195a7SDavid du Colombier 	if(a < b && rd&0x10 ||
19367d9195a7SDavid du Colombier 	   a > b && rd&0x08 ||
19377d9195a7SDavid du Colombier 	   a == b && rd&0x04 ||
19387d9195a7SDavid du Colombier 	   (ulong)a < b && rd&0x02 ||
19397d9195a7SDavid du Colombier 	   (ulong)a > b && rd&0x01) {
19407d9195a7SDavid du Colombier 		Bprint(bioout, "program_exception (trap type)\n");
19417d9195a7SDavid du Colombier 		longjmp(errjmp, 0);
19427d9195a7SDavid du Colombier 	}
19437d9195a7SDavid du Colombier }
19447d9195a7SDavid du Colombier 
19457d9195a7SDavid du Colombier void
sync(ulong ir)19467d9195a7SDavid du Colombier sync(ulong ir)
19477d9195a7SDavid du Colombier {
19487d9195a7SDavid du Colombier 	USED(ir);
19497d9195a7SDavid du Colombier 	if(trace)
19507d9195a7SDavid du Colombier 		itrace("sync");
19517d9195a7SDavid du Colombier }
19527d9195a7SDavid du Colombier 
19537d9195a7SDavid du Colombier void
icbi(ulong ir)19547d9195a7SDavid du Colombier icbi(ulong ir)
19557d9195a7SDavid du Colombier {
19567d9195a7SDavid du Colombier 	int rd, ra, rb;
19577d9195a7SDavid du Colombier 
19587d9195a7SDavid du Colombier 	if(ir & Rc)
19597d9195a7SDavid du Colombier 		undef(ir);
19607d9195a7SDavid du Colombier 	getarrr(ir);
19617d9195a7SDavid du Colombier 	USED(rd);
19627d9195a7SDavid du Colombier 	if(trace)
19637d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
19647d9195a7SDavid du Colombier }
19657d9195a7SDavid du Colombier 
19667d9195a7SDavid du Colombier void
dcbf(ulong ir)19677d9195a7SDavid du Colombier dcbf(ulong ir)
19687d9195a7SDavid du Colombier {
19697d9195a7SDavid du Colombier 	int rd, ra, rb;
19707d9195a7SDavid du Colombier 
19717d9195a7SDavid du Colombier 	if(ir & Rc)
19727d9195a7SDavid du Colombier 		undef(ir);
19737d9195a7SDavid du Colombier 	getarrr(ir);
19747d9195a7SDavid du Colombier 	USED(rd);
19757d9195a7SDavid du Colombier 	if(trace)
19767d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
19777d9195a7SDavid du Colombier }
19787d9195a7SDavid du Colombier 
19797d9195a7SDavid du Colombier void
dcbst(ulong ir)19807d9195a7SDavid du Colombier dcbst(ulong ir)
19817d9195a7SDavid du Colombier {
19827d9195a7SDavid du Colombier 	int rd, ra, rb;
19837d9195a7SDavid du Colombier 
19847d9195a7SDavid du Colombier 	if(ir & Rc)
19857d9195a7SDavid du Colombier 		undef(ir);
19867d9195a7SDavid du Colombier 	getarrr(ir);
19877d9195a7SDavid du Colombier 	USED(rd);
19887d9195a7SDavid du Colombier 	if(trace)
19897d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
19907d9195a7SDavid du Colombier }
19917d9195a7SDavid du Colombier 
19927d9195a7SDavid du Colombier void
dcbt(ulong ir)19937d9195a7SDavid du Colombier dcbt(ulong ir)
19947d9195a7SDavid du Colombier {
19957d9195a7SDavid du Colombier 	int rd, ra, rb;
19967d9195a7SDavid du Colombier 
19977d9195a7SDavid du Colombier 	if(ir & Rc)
19987d9195a7SDavid du Colombier 		undef(ir);
19997d9195a7SDavid du Colombier 	getarrr(ir);
20007d9195a7SDavid du Colombier 	USED(rd);
20017d9195a7SDavid du Colombier 	if(trace)
20027d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
20037d9195a7SDavid du Colombier }
20047d9195a7SDavid du Colombier 
20057d9195a7SDavid du Colombier void
dcbtst(ulong ir)20067d9195a7SDavid du Colombier dcbtst(ulong ir)
20077d9195a7SDavid du Colombier {
20087d9195a7SDavid du Colombier 	int rd, ra, rb;
20097d9195a7SDavid du Colombier 
20107d9195a7SDavid du Colombier 	if(ir & Rc)
20117d9195a7SDavid du Colombier 		undef(ir);
20127d9195a7SDavid du Colombier 	getarrr(ir);
20137d9195a7SDavid du Colombier 	USED(rd);
20147d9195a7SDavid du Colombier 	if(trace)
20157d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
20167d9195a7SDavid du Colombier }
20177d9195a7SDavid du Colombier 
20187d9195a7SDavid du Colombier void
dcbz(ulong ir)20197d9195a7SDavid du Colombier dcbz(ulong ir)
20207d9195a7SDavid du Colombier {
20217d9195a7SDavid du Colombier 	int rd, ra, rb;
20227d9195a7SDavid du Colombier 
20237d9195a7SDavid du Colombier 	if(ir & Rc)
20247d9195a7SDavid du Colombier 		undef(ir);
20257d9195a7SDavid du Colombier 	getarrr(ir);
20267d9195a7SDavid du Colombier 	USED(rd);
20277d9195a7SDavid du Colombier 	if(trace)
20287d9195a7SDavid du Colombier 		itrace("%s\tr%d,r%d", ci->name, ra, rb);
20297d9195a7SDavid du Colombier }
2030