xref: /plan9-contrib/sys/src/cmd/9l/asmout.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1*fbadb1c4SDavid du Colombier #include "l.h"
2*fbadb1c4SDavid du Colombier 
3*fbadb1c4SDavid du Colombier #define	OPVCC(o,xo,oe,rc) (((o)<<26)|((xo)<<1)|((oe)<<10)|((rc)&1))
4*fbadb1c4SDavid du Colombier #define	OPCC(o,xo,rc) OPVCC((o),(xo),0,(rc))
5*fbadb1c4SDavid du Colombier #define	OP(o,xo) OPVCC((o),(xo),0,0)
6*fbadb1c4SDavid du Colombier 
7*fbadb1c4SDavid du Colombier /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
8*fbadb1c4SDavid du Colombier #define	AOP_RRR(op,d,a,b) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
9*fbadb1c4SDavid du Colombier #define	AOP_IRR(op,d,a,simm) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|((simm)&0xFFFF))
10*fbadb1c4SDavid du Colombier #define	LOP_RRR(op,a,s,b) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
11*fbadb1c4SDavid du Colombier #define	LOP_IRR(op,a,s,uimm) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|((uimm)&0xFFFF))
12*fbadb1c4SDavid du Colombier #define	OP_BR(op,li,aa) ((op)|((li)&0x03FFFFFC)|((aa)<<1))
13*fbadb1c4SDavid du Colombier #define	OP_BC(op,bo,bi,bd,aa) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16)|((bd)&0xFFFC)|((aa)<<1))
14*fbadb1c4SDavid du Colombier #define	OP_BCR(op,bo,bi) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16))
15*fbadb1c4SDavid du Colombier #define	OP_RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\
16*fbadb1c4SDavid du Colombier 					(((mb)&31L)<<6)|(((me)&31L)<<1))
17*fbadb1c4SDavid du Colombier 
18*fbadb1c4SDavid du Colombier #define	OP_ADD	OPVCC(31,266,0,0)
19*fbadb1c4SDavid du Colombier #define	OP_ADDI	OPVCC(14,0,0,0)
20*fbadb1c4SDavid du Colombier #define	OP_ADDIS OPVCC(15,0,0,0)
21*fbadb1c4SDavid du Colombier #define	OP_ANDI	OPVCC(28,0,0,0)
22*fbadb1c4SDavid du Colombier #define	OP_EXTSB	OPVCC(31,954,0,0)
23*fbadb1c4SDavid du Colombier #define	OP_EXTSH OPVCC(31,922,0,0)
24*fbadb1c4SDavid du Colombier #define	OP_EXTSW OPVCC(31,986,0,0)
25*fbadb1c4SDavid du Colombier #define	OP_MCRF	OPVCC(19,0,0,0)
26*fbadb1c4SDavid du Colombier #define	OP_MCRFS OPVCC(63,64,0,0)
27*fbadb1c4SDavid du Colombier #define	OP_MCRXR OPVCC(31,512,0,0)
28*fbadb1c4SDavid du Colombier #define	OP_MFCR	OPVCC(31,19,0,0)
29*fbadb1c4SDavid du Colombier #define	OP_MFFS	OPVCC(63,583,0,0)
30*fbadb1c4SDavid du Colombier #define	OP_MFMSR OPVCC(31,83,0,0)
31*fbadb1c4SDavid du Colombier #define	OP_MFSPR OPVCC(31,339,0,0)
32*fbadb1c4SDavid du Colombier #define	OP_MFSR	OPVCC(31,595,0,0)
33*fbadb1c4SDavid du Colombier #define	OP_MFSRIN	OPVCC(31,659,0,0)
34*fbadb1c4SDavid du Colombier #define	OP_MTCRF OPVCC(31,144,0,0)
35*fbadb1c4SDavid du Colombier #define	OP_MTFSF OPVCC(63,711,0,0)
36*fbadb1c4SDavid du Colombier #define	OP_MTFSFI OPVCC(63,134,0,0)
37*fbadb1c4SDavid du Colombier #define	OP_MTMSR OPVCC(31,146,0,0)
38*fbadb1c4SDavid du Colombier #define	OP_MTMSRD OPVCC(31,178,0,0)
39*fbadb1c4SDavid du Colombier #define	OP_MTSPR OPVCC(31,467,0,0)
40*fbadb1c4SDavid du Colombier #define	OP_MTSR	OPVCC(31,210,0,0)
41*fbadb1c4SDavid du Colombier #define	OP_MTSRIN	OPVCC(31,242,0,0)
42*fbadb1c4SDavid du Colombier #define	OP_MULLW OPVCC(31,235,0,0)
43*fbadb1c4SDavid du Colombier #define	OP_MULLD OPVCC(31,233,0,0)
44*fbadb1c4SDavid du Colombier #define	OP_OR	OPVCC(31,444,0,0)
45*fbadb1c4SDavid du Colombier #define	OP_ORI	OPVCC(24,0,0,0)
46*fbadb1c4SDavid du Colombier #define	OP_ORIS	OPVCC(25,0,0,0)
47*fbadb1c4SDavid du Colombier #define	OP_RLWINM	OPVCC(21,0,0,0)
48*fbadb1c4SDavid du Colombier #define	OP_SUBF	OPVCC(31,40,0,0)
49*fbadb1c4SDavid du Colombier #define	OP_RLDIC	OPVCC(30,4,0,0)
50*fbadb1c4SDavid du Colombier #define	OP_RLDICR	OPVCC(30,2,0,0)
51*fbadb1c4SDavid du Colombier #define	OP_RLDICL	OPVCC(30,0,0,0)
52*fbadb1c4SDavid du Colombier 
53*fbadb1c4SDavid du Colombier #define	oclass(v)	((v).class-1)
54*fbadb1c4SDavid du Colombier 
55*fbadb1c4SDavid du Colombier long	oprrr(int), opirr(int), opload(int), opstore(int), oploadx(int), opstorex(int);
56*fbadb1c4SDavid du Colombier 
57*fbadb1c4SDavid du Colombier /*
58*fbadb1c4SDavid du Colombier  * 32-bit masks
59*fbadb1c4SDavid du Colombier  */
60*fbadb1c4SDavid du Colombier int
getmask(uchar * m,ulong v)61*fbadb1c4SDavid du Colombier getmask(uchar *m, ulong v)
62*fbadb1c4SDavid du Colombier {
63*fbadb1c4SDavid du Colombier 	int i;
64*fbadb1c4SDavid du Colombier 
65*fbadb1c4SDavid du Colombier 	m[0] = m[1] = 0;
66*fbadb1c4SDavid du Colombier 	if(v != ~0L && v & (1<<31) && v & 1){	/* MB > ME */
67*fbadb1c4SDavid du Colombier 		if(getmask(m, ~v)){
68*fbadb1c4SDavid du Colombier 			i = m[0]; m[0] = m[1]+1; m[1] = i-1;
69*fbadb1c4SDavid du Colombier 			return 1;
70*fbadb1c4SDavid du Colombier 		}
71*fbadb1c4SDavid du Colombier 		return 0;
72*fbadb1c4SDavid du Colombier 	}
73*fbadb1c4SDavid du Colombier 	for(i=0; i<32; i++)
74*fbadb1c4SDavid du Colombier 		if(v & (1<<(31-i))){
75*fbadb1c4SDavid du Colombier 			m[0] = i;
76*fbadb1c4SDavid du Colombier 			do {
77*fbadb1c4SDavid du Colombier 				m[1] = i;
78*fbadb1c4SDavid du Colombier 			} while(++i<32 && (v & (1<<(31-i))) != 0);
79*fbadb1c4SDavid du Colombier 			for(; i<32; i++)
80*fbadb1c4SDavid du Colombier 				if(v & (1<<(31-i)))
81*fbadb1c4SDavid du Colombier 					return 0;
82*fbadb1c4SDavid du Colombier 			return 1;
83*fbadb1c4SDavid du Colombier 		}
84*fbadb1c4SDavid du Colombier 	return 0;
85*fbadb1c4SDavid du Colombier }
86*fbadb1c4SDavid du Colombier 
87*fbadb1c4SDavid du Colombier void
maskgen(Prog * p,uchar * m,ulong v)88*fbadb1c4SDavid du Colombier maskgen(Prog *p, uchar *m, ulong v)
89*fbadb1c4SDavid du Colombier {
90*fbadb1c4SDavid du Colombier 	if(!getmask(m, v))
91*fbadb1c4SDavid du Colombier 		diag("cannot generate mask #%lux\n%P", v, p);
92*fbadb1c4SDavid du Colombier }
93*fbadb1c4SDavid du Colombier 
94*fbadb1c4SDavid du Colombier /*
95*fbadb1c4SDavid du Colombier  * 64-bit masks (rldic etc)
96*fbadb1c4SDavid du Colombier  */
97*fbadb1c4SDavid du Colombier int
getmask64(uchar * m,uvlong v)98*fbadb1c4SDavid du Colombier getmask64(uchar *m, uvlong v)
99*fbadb1c4SDavid du Colombier {
100*fbadb1c4SDavid du Colombier 	int i;
101*fbadb1c4SDavid du Colombier 
102*fbadb1c4SDavid du Colombier 	m[0] = m[1] = 0;
103*fbadb1c4SDavid du Colombier 	for(i=0; i<64; i++)
104*fbadb1c4SDavid du Colombier 		if(v & ((uvlong)1<<(63-i))){
105*fbadb1c4SDavid du Colombier 			m[0] = i;
106*fbadb1c4SDavid du Colombier 			do {
107*fbadb1c4SDavid du Colombier 				m[1] = i;
108*fbadb1c4SDavid du Colombier 			} while(++i<64 && (v & ((uvlong)1<<(63-i))) != 0);
109*fbadb1c4SDavid du Colombier 			for(; i<64; i++)
110*fbadb1c4SDavid du Colombier 				if(v & ((uvlong)1<<(63-i)))
111*fbadb1c4SDavid du Colombier 					return 0;
112*fbadb1c4SDavid du Colombier 			return 1;
113*fbadb1c4SDavid du Colombier 		}
114*fbadb1c4SDavid du Colombier 	return 0;
115*fbadb1c4SDavid du Colombier }
116*fbadb1c4SDavid du Colombier 
117*fbadb1c4SDavid du Colombier void
maskgen64(Prog * p,uchar * m,uvlong v)118*fbadb1c4SDavid du Colombier maskgen64(Prog *p, uchar *m, uvlong v)
119*fbadb1c4SDavid du Colombier {
120*fbadb1c4SDavid du Colombier 	if(!getmask64(m, v))
121*fbadb1c4SDavid du Colombier 		diag("cannot generate mask #%llux\n%P", v, p);
122*fbadb1c4SDavid du Colombier }
123*fbadb1c4SDavid du Colombier 
124*fbadb1c4SDavid du Colombier static void
reloc(Adr * a,long pc,int sext)125*fbadb1c4SDavid du Colombier reloc(Adr *a, long pc, int sext)
126*fbadb1c4SDavid du Colombier {
127*fbadb1c4SDavid du Colombier 	if(a->name == D_EXTERN || a->name == D_STATIC)
128*fbadb1c4SDavid du Colombier 		dynreloc(a->sym, pc, 1, 1, sext);
129*fbadb1c4SDavid du Colombier }
130*fbadb1c4SDavid du Colombier 
131*fbadb1c4SDavid du Colombier static ulong
loadu32(int r,vlong d)132*fbadb1c4SDavid du Colombier loadu32(int r, vlong d)
133*fbadb1c4SDavid du Colombier {
134*fbadb1c4SDavid du Colombier 	long v;
135*fbadb1c4SDavid du Colombier 
136*fbadb1c4SDavid du Colombier 	v = d>>16;
137*fbadb1c4SDavid du Colombier 	if(isuint32(d))
138*fbadb1c4SDavid du Colombier 		return LOP_IRR(OP_ORIS, r, REGZERO, v);
139*fbadb1c4SDavid du Colombier 	return AOP_IRR(OP_ADDIS, r, REGZERO, v);
140*fbadb1c4SDavid du Colombier }
141*fbadb1c4SDavid du Colombier 
142*fbadb1c4SDavid du Colombier int
asmout(Prog * p,Optab * o,int aflag)143*fbadb1c4SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
144*fbadb1c4SDavid du Colombier {
145*fbadb1c4SDavid du Colombier 	long o1, o2, o3, o4, o5, v, t;
146*fbadb1c4SDavid du Colombier 	vlong d;
147*fbadb1c4SDavid du Colombier 	Prog *ct;
148*fbadb1c4SDavid du Colombier 	int r, a;
149*fbadb1c4SDavid du Colombier 	uchar mask[2];
150*fbadb1c4SDavid du Colombier 
151*fbadb1c4SDavid du Colombier 	o1 = 0;
152*fbadb1c4SDavid du Colombier 	o2 = 0;
153*fbadb1c4SDavid du Colombier 	o3 = 0;
154*fbadb1c4SDavid du Colombier 	o4 = 0;
155*fbadb1c4SDavid du Colombier 	o5 = 0;
156*fbadb1c4SDavid du Colombier 	switch(o->type) {
157*fbadb1c4SDavid du Colombier 	default:
158*fbadb1c4SDavid du Colombier 		if(aflag)
159*fbadb1c4SDavid du Colombier 			return 0;
160*fbadb1c4SDavid du Colombier 		diag("unknown type %d", o->type);
161*fbadb1c4SDavid du Colombier 		if(!debug['a'])
162*fbadb1c4SDavid du Colombier 			prasm(p);
163*fbadb1c4SDavid du Colombier 		break;
164*fbadb1c4SDavid du Colombier 
165*fbadb1c4SDavid du Colombier 	case 0:		/* pseudo ops */
166*fbadb1c4SDavid du Colombier 		if(aflag) {
167*fbadb1c4SDavid du Colombier 			if(p->link) {
168*fbadb1c4SDavid du Colombier 				if(p->as == ATEXT) {
169*fbadb1c4SDavid du Colombier 					ct = curtext;
170*fbadb1c4SDavid du Colombier 					o2 = autosize;
171*fbadb1c4SDavid du Colombier 					curtext = p;
172*fbadb1c4SDavid du Colombier 					autosize = p->to.offset + 8;
173*fbadb1c4SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
174*fbadb1c4SDavid du Colombier 					curtext = ct;
175*fbadb1c4SDavid du Colombier 					autosize = o2;
176*fbadb1c4SDavid du Colombier 				} else
177*fbadb1c4SDavid du Colombier 					o1 = asmout(p->link, oplook(p->link), aflag);
178*fbadb1c4SDavid du Colombier 			}
179*fbadb1c4SDavid du Colombier 			return o1;
180*fbadb1c4SDavid du Colombier 		}
181*fbadb1c4SDavid du Colombier 		break;
182*fbadb1c4SDavid du Colombier 
183*fbadb1c4SDavid du Colombier 	case 1:		/* mov r1,r2 ==> OR Rs,Rs,Ra */
184*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGZERO && p->from.type == D_CONST) {
185*fbadb1c4SDavid du Colombier 			v = regoff(&p->from);
186*fbadb1c4SDavid du Colombier 			if(r0iszero && v != 0) {
187*fbadb1c4SDavid du Colombier 				nerrors--;
188*fbadb1c4SDavid du Colombier 				diag("literal operation on R0\n%P", p);
189*fbadb1c4SDavid du Colombier 			}
190*fbadb1c4SDavid du Colombier 			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
191*fbadb1c4SDavid du Colombier 			break;
192*fbadb1c4SDavid du Colombier 		}
193*fbadb1c4SDavid du Colombier 		o1 = LOP_RRR(OP_OR, p->to.reg, p->from.reg, p->from.reg);
194*fbadb1c4SDavid du Colombier 		break;
195*fbadb1c4SDavid du Colombier 
196*fbadb1c4SDavid du Colombier 	case 2:		/* int/cr/fp op Rb,[Ra],Rd */
197*fbadb1c4SDavid du Colombier 		r = p->reg;
198*fbadb1c4SDavid du Colombier 		if(r == NREG)
199*fbadb1c4SDavid du Colombier 			r = p->to.reg;
200*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
201*fbadb1c4SDavid du Colombier 		break;
202*fbadb1c4SDavid du Colombier 
203*fbadb1c4SDavid du Colombier 	case 3:		/* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
204*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from);
205*fbadb1c4SDavid du Colombier 		v = d;
206*fbadb1c4SDavid du Colombier 		r = p->from.reg;
207*fbadb1c4SDavid du Colombier 		if(r == NREG)
208*fbadb1c4SDavid du Colombier 			r = o->param;
209*fbadb1c4SDavid du Colombier 		if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
210*fbadb1c4SDavid du Colombier 			diag("literal operation on R0\n%P", p);
211*fbadb1c4SDavid du Colombier 		a = OP_ADDI;
212*fbadb1c4SDavid du Colombier 		if(o->a1 == C_UCON) {
213*fbadb1c4SDavid du Colombier 			v >>= 16;
214*fbadb1c4SDavid du Colombier 			if(r == REGZERO && isuint32(d)){
215*fbadb1c4SDavid du Colombier 				o1 = LOP_IRR(OP_ORIS, p->to.reg, REGZERO, v);
216*fbadb1c4SDavid du Colombier 				break;
217*fbadb1c4SDavid du Colombier 			}
218*fbadb1c4SDavid du Colombier 			a = OP_ADDIS;
219*fbadb1c4SDavid du Colombier 		}
220*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(a, p->to.reg, r, v);
221*fbadb1c4SDavid du Colombier 		break;
222*fbadb1c4SDavid du Colombier 
223*fbadb1c4SDavid du Colombier 	case 4:		/* add/mul $scon,[r1],r2 */
224*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
225*fbadb1c4SDavid du Colombier 		r = p->reg;
226*fbadb1c4SDavid du Colombier 		if(r == NREG)
227*fbadb1c4SDavid du Colombier 			r = p->to.reg;
228*fbadb1c4SDavid du Colombier 		if(r0iszero && p->to.reg == 0)
229*fbadb1c4SDavid du Colombier 			diag("literal operation on R0\n%P", p);
230*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
231*fbadb1c4SDavid du Colombier 		break;
232*fbadb1c4SDavid du Colombier 
233*fbadb1c4SDavid du Colombier 	case 5:		/* syscall */
234*fbadb1c4SDavid du Colombier 		if(aflag)
235*fbadb1c4SDavid du Colombier 			return 0;
236*fbadb1c4SDavid du Colombier 		o1 = oprrr(p->as);
237*fbadb1c4SDavid du Colombier 		break;
238*fbadb1c4SDavid du Colombier 
239*fbadb1c4SDavid du Colombier 	case 6:		/* logical op Rb,[Rs,]Ra; no literal */
240*fbadb1c4SDavid du Colombier 		r = p->reg;
241*fbadb1c4SDavid du Colombier 		if(r == NREG)
242*fbadb1c4SDavid du Colombier 			r = p->to.reg;
243*fbadb1c4SDavid du Colombier 		o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
244*fbadb1c4SDavid du Colombier 		break;
245*fbadb1c4SDavid du Colombier 
246*fbadb1c4SDavid du Colombier 	case 7:		/* mov r, soreg ==> stw o(r) */
247*fbadb1c4SDavid du Colombier 		r = p->to.reg;
248*fbadb1c4SDavid du Colombier 		if(r == NREG)
249*fbadb1c4SDavid du Colombier 			r = o->param;
250*fbadb1c4SDavid du Colombier 		v = regoff(&p->to);
251*fbadb1c4SDavid du Colombier 		if(p->to.type == D_OREG && p->reg != NREG) {
252*fbadb1c4SDavid du Colombier 			if(v)
253*fbadb1c4SDavid du Colombier 				diag("illegal indexed instruction\n%P", p);
254*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(opstorex(p->as), p->from.reg, p->reg, r);
255*fbadb1c4SDavid du Colombier 		} else
256*fbadb1c4SDavid du Colombier 			o1 = AOP_IRR(opstore(p->as), p->from.reg, r, v);
257*fbadb1c4SDavid du Colombier 		break;
258*fbadb1c4SDavid du Colombier 
259*fbadb1c4SDavid du Colombier 	case 8:		/* mov soreg, r ==> lbz/lhz/lwz o(r) */
260*fbadb1c4SDavid du Colombier 		r = p->from.reg;
261*fbadb1c4SDavid du Colombier 		if(r == NREG)
262*fbadb1c4SDavid du Colombier 			r = o->param;
263*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
264*fbadb1c4SDavid du Colombier 		if(p->from.type == D_OREG && p->reg != NREG) {
265*fbadb1c4SDavid du Colombier 			if(v)
266*fbadb1c4SDavid du Colombier 				diag("illegal indexed instruction\n%P", p);
267*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
268*fbadb1c4SDavid du Colombier 		} else
269*fbadb1c4SDavid du Colombier 			o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
270*fbadb1c4SDavid du Colombier 		break;
271*fbadb1c4SDavid du Colombier 
272*fbadb1c4SDavid du Colombier 	case 9:		/* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
273*fbadb1c4SDavid du Colombier 		r = p->from.reg;
274*fbadb1c4SDavid du Colombier 		if(r == NREG)
275*fbadb1c4SDavid du Colombier 			r = o->param;
276*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
277*fbadb1c4SDavid du Colombier 		if(p->from.type == D_OREG && p->reg != NREG) {
278*fbadb1c4SDavid du Colombier 			if(v)
279*fbadb1c4SDavid du Colombier 				diag("illegal indexed instruction\n%P", p);
280*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
281*fbadb1c4SDavid du Colombier 		} else
282*fbadb1c4SDavid du Colombier 			o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
283*fbadb1c4SDavid du Colombier 		o2 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
284*fbadb1c4SDavid du Colombier 		break;
285*fbadb1c4SDavid du Colombier 
286*fbadb1c4SDavid du Colombier 	case 10:		/* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
287*fbadb1c4SDavid du Colombier 		r = p->reg;
288*fbadb1c4SDavid du Colombier 		if(r == NREG)
289*fbadb1c4SDavid du Colombier 			r = p->to.reg;
290*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, r);
291*fbadb1c4SDavid du Colombier 		break;
292*fbadb1c4SDavid du Colombier 
293*fbadb1c4SDavid du Colombier 	case 11:	/* br/bl lbra */
294*fbadb1c4SDavid du Colombier 		if(aflag)
295*fbadb1c4SDavid du Colombier 			return 0;
296*fbadb1c4SDavid du Colombier 		v = 0;
297*fbadb1c4SDavid du Colombier 		if(p->cond == UP){
298*fbadb1c4SDavid du Colombier 			if(p->to.sym->type != SUNDEF)
299*fbadb1c4SDavid du Colombier 				diag("bad branch sym type");
300*fbadb1c4SDavid du Colombier 			v = (ulong)p->to.sym->value >> (Roffset-2);
301*fbadb1c4SDavid du Colombier 			dynreloc(p->to.sym, p->pc, 0, 0, 0);
302*fbadb1c4SDavid du Colombier 		}
303*fbadb1c4SDavid du Colombier 		else if(p->cond)
304*fbadb1c4SDavid du Colombier 			v = p->cond->pc - p->pc;
305*fbadb1c4SDavid du Colombier 		if(v & 03) {
306*fbadb1c4SDavid du Colombier 			diag("odd branch target address\n%P", p);
307*fbadb1c4SDavid du Colombier 			v &= ~03;
308*fbadb1c4SDavid du Colombier 		}
309*fbadb1c4SDavid du Colombier 		if(v < -(1L<<25) || v >= (1L<<24))
310*fbadb1c4SDavid du Colombier 			diag("branch too far\n%P", p);
311*fbadb1c4SDavid du Colombier 		o1 = OP_BR(opirr(p->as), v, 0);
312*fbadb1c4SDavid du Colombier 		break;
313*fbadb1c4SDavid du Colombier 
314*fbadb1c4SDavid du Colombier 	case 12:	/* movb r,r (extsb); movw r,r (extsw) */
315*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGZERO && p->from.type == D_CONST) {
316*fbadb1c4SDavid du Colombier 			v = regoff(&p->from);
317*fbadb1c4SDavid du Colombier 			if(r0iszero && v != 0) {
318*fbadb1c4SDavid du Colombier 				nerrors--;
319*fbadb1c4SDavid du Colombier 				diag("literal operation on R0\n%P", p);
320*fbadb1c4SDavid du Colombier 			}
321*fbadb1c4SDavid du Colombier 			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
322*fbadb1c4SDavid du Colombier 			break;
323*fbadb1c4SDavid du Colombier 		}
324*fbadb1c4SDavid du Colombier 		if(p->as == AMOVW)
325*fbadb1c4SDavid du Colombier 			o1 = LOP_RRR(OP_EXTSW, p->to.reg, p->from.reg, 0);
326*fbadb1c4SDavid du Colombier 		else
327*fbadb1c4SDavid du Colombier 			o1 = LOP_RRR(OP_EXTSB, p->to.reg, p->from.reg, 0);
328*fbadb1c4SDavid du Colombier 		break;
329*fbadb1c4SDavid du Colombier 
330*fbadb1c4SDavid du Colombier 	case 13:	/* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
331*fbadb1c4SDavid du Colombier 		if(p->as == AMOVBZ)
332*fbadb1c4SDavid du Colombier 			o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 24, 31);
333*fbadb1c4SDavid du Colombier 		else if(p->as == AMOVH)
334*fbadb1c4SDavid du Colombier 			o1 = LOP_RRR(OP_EXTSH, p->to.reg, p->from.reg, 0);
335*fbadb1c4SDavid du Colombier 		else if(p->as == AMOVHZ)
336*fbadb1c4SDavid du Colombier 			o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 16, 31);
337*fbadb1c4SDavid du Colombier 		else if(p->as == AMOVWZ)
338*fbadb1c4SDavid du Colombier 			o1 = OP_RLW(OP_RLDIC, p->to.reg, p->from.reg, 0, 0, 0) | (1<<5);	/* MB=32 */
339*fbadb1c4SDavid du Colombier 		else
340*fbadb1c4SDavid du Colombier 			diag("internal: bad mov[bhw]z\n%P", p);
341*fbadb1c4SDavid du Colombier 		break;
342*fbadb1c4SDavid du Colombier 
343*fbadb1c4SDavid du Colombier 	case 14:	/* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
344*fbadb1c4SDavid du Colombier 		r = p->reg;
345*fbadb1c4SDavid du Colombier 		if(r == NREG)
346*fbadb1c4SDavid du Colombier 			r = p->to.reg;
347*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from3);
348*fbadb1c4SDavid du Colombier 		maskgen64(p, mask, d);
349*fbadb1c4SDavid du Colombier 		switch(p->as){
350*fbadb1c4SDavid du Colombier 		case ARLDCL: case ARLDCLCC:
351*fbadb1c4SDavid du Colombier 			a = mask[0];	/* MB */
352*fbadb1c4SDavid du Colombier 			if(mask[1] != 63)
353*fbadb1c4SDavid du Colombier 				diag("invalid mask for rotate: %llux (end != bit 63)\n%P", d, p);
354*fbadb1c4SDavid du Colombier 			break;
355*fbadb1c4SDavid du Colombier 		case ARLDCR: case ARLDCRCC:
356*fbadb1c4SDavid du Colombier 			a = mask[1];	/* ME */
357*fbadb1c4SDavid du Colombier 			if(mask[0] != 0)
358*fbadb1c4SDavid du Colombier 				diag("invalid mask for rotate: %llux (start != 0)\n%P", d, p);
359*fbadb1c4SDavid du Colombier 			break;
360*fbadb1c4SDavid du Colombier 		default:
361*fbadb1c4SDavid du Colombier 			diag("unexpected op in rldc case\n%P", p);
362*fbadb1c4SDavid du Colombier 			a = 0;
363*fbadb1c4SDavid du Colombier 		}
364*fbadb1c4SDavid du Colombier 		o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
365*fbadb1c4SDavid du Colombier 		o1 |= (a&31L)<<6;
366*fbadb1c4SDavid du Colombier 		if(a & 0x20)
367*fbadb1c4SDavid du Colombier 			o1 |= 1<<5;	/* mb[5] is top bit */
368*fbadb1c4SDavid du Colombier 		break;
369*fbadb1c4SDavid du Colombier 
370*fbadb1c4SDavid du Colombier 	case 17:	/* bc bo,bi,lbra (same for now) */
371*fbadb1c4SDavid du Colombier 	case 16:	/* bc bo,bi,sbra */
372*fbadb1c4SDavid du Colombier 		if(aflag)
373*fbadb1c4SDavid du Colombier 			return 0;
374*fbadb1c4SDavid du Colombier 		a = 0;
375*fbadb1c4SDavid du Colombier 		if(p->from.type == D_CONST)
376*fbadb1c4SDavid du Colombier 			a = regoff(&p->from);
377*fbadb1c4SDavid du Colombier 		r = p->reg;
378*fbadb1c4SDavid du Colombier 		if(r == NREG)
379*fbadb1c4SDavid du Colombier 			r = 0;
380*fbadb1c4SDavid du Colombier 		v = 0;
381*fbadb1c4SDavid du Colombier 		if(p->cond)
382*fbadb1c4SDavid du Colombier 			v = p->cond->pc - p->pc;
383*fbadb1c4SDavid du Colombier 		if(v & 03) {
384*fbadb1c4SDavid du Colombier 			diag("odd branch target address\n%P", p);
385*fbadb1c4SDavid du Colombier 			v &= ~03;
386*fbadb1c4SDavid du Colombier 		}
387*fbadb1c4SDavid du Colombier 		if(v < -(1L<<16) || v >= (1L<<15))
388*fbadb1c4SDavid du Colombier 			diag("branch too far\n%P", p);
389*fbadb1c4SDavid du Colombier 		o1 = OP_BC(opirr(p->as), a, r, v, 0);
390*fbadb1c4SDavid du Colombier 		break;
391*fbadb1c4SDavid du Colombier 
392*fbadb1c4SDavid du Colombier 	case 15:	/* br/bl (r) => mov r,lr; br/bl (lr) */
393*fbadb1c4SDavid du Colombier 		if(aflag)
394*fbadb1c4SDavid du Colombier 			return 0;
395*fbadb1c4SDavid du Colombier 		if(p->as == ABC || p->as == ABCL)
396*fbadb1c4SDavid du Colombier 			v = regoff(&p->to)&31L;
397*fbadb1c4SDavid du Colombier 		else
398*fbadb1c4SDavid du Colombier 			v = 20;	/* unconditional */
399*fbadb1c4SDavid du Colombier 		r = p->reg;
400*fbadb1c4SDavid du Colombier 		if(r == NREG)
401*fbadb1c4SDavid du Colombier 			r = 0;
402*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((D_LR&0x1f)<<16) | (((D_LR>>5)&0x1f)<<11);
403*fbadb1c4SDavid du Colombier 		o2 = OPVCC(19, 16, 0, 0);
404*fbadb1c4SDavid du Colombier 		if(p->as == ABL || p->as == ABCL)
405*fbadb1c4SDavid du Colombier 			o2 |= 1;
406*fbadb1c4SDavid du Colombier 		o2 = OP_BCR(o2, v, r);
407*fbadb1c4SDavid du Colombier 		break;
408*fbadb1c4SDavid du Colombier 
409*fbadb1c4SDavid du Colombier 	case 18:	/* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
410*fbadb1c4SDavid du Colombier 		if(aflag)
411*fbadb1c4SDavid du Colombier 			return 0;
412*fbadb1c4SDavid du Colombier 		if(p->as == ABC || p->as == ABCL)
413*fbadb1c4SDavid du Colombier 			v = regoff(&p->from)&31L;
414*fbadb1c4SDavid du Colombier 		else
415*fbadb1c4SDavid du Colombier 			v = 20;	/* unconditional */
416*fbadb1c4SDavid du Colombier 		r = p->reg;
417*fbadb1c4SDavid du Colombier 		if(r == NREG)
418*fbadb1c4SDavid du Colombier 			r = 0;
419*fbadb1c4SDavid du Colombier 		switch(oclass(p->to)) {
420*fbadb1c4SDavid du Colombier 		case C_CTR:
421*fbadb1c4SDavid du Colombier 			o1 = OPVCC(19, 528, 0, 0);
422*fbadb1c4SDavid du Colombier 			break;
423*fbadb1c4SDavid du Colombier 		case C_LR:
424*fbadb1c4SDavid du Colombier 			o1 = OPVCC(19, 16, 0, 0);
425*fbadb1c4SDavid du Colombier 			break;
426*fbadb1c4SDavid du Colombier 		default:
427*fbadb1c4SDavid du Colombier 			diag("bad optab entry (18): %d\n%P", p->to.class, p);
428*fbadb1c4SDavid du Colombier 			v = 0;
429*fbadb1c4SDavid du Colombier 		}
430*fbadb1c4SDavid du Colombier 		if(p->as == ABL || p->as == ABCL)
431*fbadb1c4SDavid du Colombier 			o1 |= 1;
432*fbadb1c4SDavid du Colombier 		o1 = OP_BCR(o1, v, r);
433*fbadb1c4SDavid du Colombier 		break;
434*fbadb1c4SDavid du Colombier 
435*fbadb1c4SDavid du Colombier 	case 19:	/* mov $lcon,r ==> cau+or */
436*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from);
437*fbadb1c4SDavid du Colombier 		o1 = loadu32(p->to.reg, d);
438*fbadb1c4SDavid du Colombier 		o2 = LOP_IRR(OP_ORI, p->to.reg, p->to.reg, (long)d);
439*fbadb1c4SDavid du Colombier 		if(dlm)
440*fbadb1c4SDavid du Colombier 			reloc(&p->from, p->pc, 0);
441*fbadb1c4SDavid du Colombier 		break;
442*fbadb1c4SDavid du Colombier 
443*fbadb1c4SDavid du Colombier 	case 20:	/* add $ucon,,r */
444*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
445*fbadb1c4SDavid du Colombier 		r = p->reg;
446*fbadb1c4SDavid du Colombier 		if(r == NREG)
447*fbadb1c4SDavid du Colombier 			r = p->to.reg;
448*fbadb1c4SDavid du Colombier 		if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
449*fbadb1c4SDavid du Colombier 			diag("literal operation on R0\n%P", p);
450*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16);
451*fbadb1c4SDavid du Colombier 		break;
452*fbadb1c4SDavid du Colombier 
453*fbadb1c4SDavid du Colombier 	case 22:	/* add $lcon,r1,r2 ==> cau+or+add */	/* could do add/sub more efficiently */
454*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGTMP || p->reg == REGTMP)
455*fbadb1c4SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
456*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from);
457*fbadb1c4SDavid du Colombier 		o1 = loadu32(REGTMP, d);
458*fbadb1c4SDavid du Colombier 		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (long)d);
459*fbadb1c4SDavid du Colombier 		r = p->reg;
460*fbadb1c4SDavid du Colombier 		if(r == NREG)
461*fbadb1c4SDavid du Colombier 			r = p->to.reg;
462*fbadb1c4SDavid du Colombier 		o3 = AOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
463*fbadb1c4SDavid du Colombier 		if(dlm)
464*fbadb1c4SDavid du Colombier 			reloc(&p->from, p->pc, 0);
465*fbadb1c4SDavid du Colombier 		break;
466*fbadb1c4SDavid du Colombier 
467*fbadb1c4SDavid du Colombier 	case 23:	/* and $lcon,r1,r2 ==> cau+or+and */	/* masks could be done using rlnm etc. */
468*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGTMP || p->reg == REGTMP)
469*fbadb1c4SDavid du Colombier 			diag("cant synthesize large constant\n%P", p);
470*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from);
471*fbadb1c4SDavid du Colombier 		o1 = loadu32(REGTMP, d);
472*fbadb1c4SDavid du Colombier 		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (long)d);
473*fbadb1c4SDavid du Colombier 		r = p->reg;
474*fbadb1c4SDavid du Colombier 		if(r == NREG)
475*fbadb1c4SDavid du Colombier 			r = p->to.reg;
476*fbadb1c4SDavid du Colombier 		o3 = LOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
477*fbadb1c4SDavid du Colombier 		if(dlm)
478*fbadb1c4SDavid du Colombier 			reloc(&p->from, p->pc, 0);
479*fbadb1c4SDavid du Colombier 		break;
480*fbadb1c4SDavid du Colombier /*24*/
481*fbadb1c4SDavid du Colombier 
482*fbadb1c4SDavid du Colombier 	case 25:	/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
483*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
484*fbadb1c4SDavid du Colombier 		if(v < 0)
485*fbadb1c4SDavid du Colombier 			v = 0;
486*fbadb1c4SDavid du Colombier 		else if(v > 63)
487*fbadb1c4SDavid du Colombier 			v = 63;
488*fbadb1c4SDavid du Colombier 		r = p->reg;
489*fbadb1c4SDavid du Colombier 		if(r == NREG)
490*fbadb1c4SDavid du Colombier 			r = p->to.reg;
491*fbadb1c4SDavid du Colombier 		switch(p->as){
492*fbadb1c4SDavid du Colombier 		case ASLD: case ASLDCC:
493*fbadb1c4SDavid du Colombier 			a = 63-v;
494*fbadb1c4SDavid du Colombier 			o1 = OP_RLDICR;
495*fbadb1c4SDavid du Colombier 			break;
496*fbadb1c4SDavid du Colombier 		case ASRD: case ASRDCC:
497*fbadb1c4SDavid du Colombier 			a = v;
498*fbadb1c4SDavid du Colombier 			v = 64-v;
499*fbadb1c4SDavid du Colombier 			o1 = OP_RLDICL;
500*fbadb1c4SDavid du Colombier 			break;
501*fbadb1c4SDavid du Colombier 		default:
502*fbadb1c4SDavid du Colombier 			diag("unexpected op in sldi case\n%P", p);
503*fbadb1c4SDavid du Colombier 			a = 0;
504*fbadb1c4SDavid du Colombier 			o1 = 0;
505*fbadb1c4SDavid du Colombier 		}
506*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(o1, r, p->to.reg, (v&0x1F));
507*fbadb1c4SDavid du Colombier 		o1 |= (a&31L)<<6;
508*fbadb1c4SDavid du Colombier 		if(v & 0x20)
509*fbadb1c4SDavid du Colombier 			o1 |= 1<<1;
510*fbadb1c4SDavid du Colombier 		if(a & 0x20)
511*fbadb1c4SDavid du Colombier 			o1 |= 1<<5;	/* mb[5] is top bit */
512*fbadb1c4SDavid du Colombier 		if(p->as == ASLDCC || p->as == ASRDCC)
513*fbadb1c4SDavid du Colombier 			o1 |= 1;	/* Rc */
514*fbadb1c4SDavid du Colombier 		break;
515*fbadb1c4SDavid du Colombier 
516*fbadb1c4SDavid du Colombier 	case 26:	/* mov $lsext/auto/oreg,,r2 ==> addis+addi */
517*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGTMP)
518*fbadb1c4SDavid du Colombier 			diag("can't synthesize large constant\n%P", p);
519*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
520*fbadb1c4SDavid du Colombier 		if(v & 0x8000L)
521*fbadb1c4SDavid du Colombier 			v += 0x10000L;
522*fbadb1c4SDavid du Colombier 		r = p->from.reg;
523*fbadb1c4SDavid du Colombier 		if(r == NREG)
524*fbadb1c4SDavid du Colombier 			r = o->param;
525*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
526*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
527*fbadb1c4SDavid du Colombier 		break;
528*fbadb1c4SDavid du Colombier 
529*fbadb1c4SDavid du Colombier 	case 27:		/* subc ra,$simm,rd => subfic rd,ra,$simm */
530*fbadb1c4SDavid du Colombier 		v = regoff(&p->from3);
531*fbadb1c4SDavid du Colombier 		r = p->from.reg;
532*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
533*fbadb1c4SDavid du Colombier 		break;
534*fbadb1c4SDavid du Colombier 
535*fbadb1c4SDavid du Colombier 	case 28:	/* subc r1,$lcon,r2 ==> cau+or+subfc */
536*fbadb1c4SDavid du Colombier 		if(p->to.reg == REGTMP || p->from.reg == REGTMP)
537*fbadb1c4SDavid du Colombier 			diag("can't synthesize large constant\n%P", p);
538*fbadb1c4SDavid du Colombier 		v = regoff(&p->from3);
539*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
540*fbadb1c4SDavid du Colombier 		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
541*fbadb1c4SDavid du Colombier 		o3 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, REGTMP);
542*fbadb1c4SDavid du Colombier 		if(dlm)
543*fbadb1c4SDavid du Colombier 			reloc(&p->from3, p->pc, 0);
544*fbadb1c4SDavid du Colombier 		break;
545*fbadb1c4SDavid du Colombier 
546*fbadb1c4SDavid du Colombier 	case 29:	/* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
547*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
548*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from3);
549*fbadb1c4SDavid du Colombier 		maskgen64(p, mask, d);
550*fbadb1c4SDavid du Colombier 		switch(p->as){
551*fbadb1c4SDavid du Colombier 		case ARLDC: case ARLDCCC:
552*fbadb1c4SDavid du Colombier 			a = mask[0];	/* MB */
553*fbadb1c4SDavid du Colombier 			if(mask[1] != (63-v))
554*fbadb1c4SDavid du Colombier 				diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
555*fbadb1c4SDavid du Colombier 			break;
556*fbadb1c4SDavid du Colombier 		case ARLDCL: case ARLDCLCC:
557*fbadb1c4SDavid du Colombier 			a = mask[0];	/* MB */
558*fbadb1c4SDavid du Colombier 			if(mask[1] != 63)
559*fbadb1c4SDavid du Colombier 				diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
560*fbadb1c4SDavid du Colombier 			break;
561*fbadb1c4SDavid du Colombier 		case ARLDCR: case ARLDCRCC:
562*fbadb1c4SDavid du Colombier 			a = mask[1];	/* ME */
563*fbadb1c4SDavid du Colombier 			if(mask[0] != 0)
564*fbadb1c4SDavid du Colombier 				diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
565*fbadb1c4SDavid du Colombier 			break;
566*fbadb1c4SDavid du Colombier 		default:
567*fbadb1c4SDavid du Colombier 			diag("unexpected op in rldic case\n%P", p);
568*fbadb1c4SDavid du Colombier 			a = 0;
569*fbadb1c4SDavid du Colombier 		}
570*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, (v&0x1F));
571*fbadb1c4SDavid du Colombier 		o1 |= (a&31L)<<6;
572*fbadb1c4SDavid du Colombier 		if(v & 0x20)
573*fbadb1c4SDavid du Colombier 			o1 |= 1<<1;
574*fbadb1c4SDavid du Colombier 		if(a & 0x20)
575*fbadb1c4SDavid du Colombier 			o1 |= 1<<5;	/* mb[5] is top bit */
576*fbadb1c4SDavid du Colombier 		break;
577*fbadb1c4SDavid du Colombier 
578*fbadb1c4SDavid du Colombier 	case 30:	/* rldimi $sh,s,$mask,a */
579*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
580*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from3);
581*fbadb1c4SDavid du Colombier 		maskgen64(p, mask, d);
582*fbadb1c4SDavid du Colombier 		if(mask[1] != (63-v))
583*fbadb1c4SDavid du Colombier 			diag("invalid mask for shift: %llux (shift %ld)\n%P", d, v, p);
584*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, (v&0x1F));
585*fbadb1c4SDavid du Colombier 		o1 |= (mask[0]&31L)<<6;
586*fbadb1c4SDavid du Colombier 		if(v & 0x20)
587*fbadb1c4SDavid du Colombier 			o1 |= 1<<1;
588*fbadb1c4SDavid du Colombier 		if(mask[0] & 0x20)
589*fbadb1c4SDavid du Colombier 			o1 |= 1<<5;	/* mb[5] is top bit */
590*fbadb1c4SDavid du Colombier 		break;
591*fbadb1c4SDavid du Colombier 
592*fbadb1c4SDavid du Colombier 	case 31:	/* dword */
593*fbadb1c4SDavid du Colombier 		if(aflag)
594*fbadb1c4SDavid du Colombier 			return 0;
595*fbadb1c4SDavid du Colombier 		d = vregoff(&p->from);
596*fbadb1c4SDavid du Colombier 		o1 = d>>32;
597*fbadb1c4SDavid du Colombier 		o2 = d;
598*fbadb1c4SDavid du Colombier 		break;
599*fbadb1c4SDavid du Colombier 
600*fbadb1c4SDavid du Colombier 	case 32:	/* fmul frc,fra,frd */
601*fbadb1c4SDavid du Colombier 		r = p->reg;
602*fbadb1c4SDavid du Colombier 		if(r == NREG)
603*fbadb1c4SDavid du Colombier 			r = p->to.reg;
604*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
605*fbadb1c4SDavid du Colombier 		break;
606*fbadb1c4SDavid du Colombier 
607*fbadb1c4SDavid du Colombier 	case 33:	/* fabs [frb,]frd; fmr. frb,frd */
608*fbadb1c4SDavid du Colombier 		r = p->from.reg;
609*fbadb1c4SDavid du Colombier 		if(oclass(p->from) == C_NONE)
610*fbadb1c4SDavid du Colombier 			r = p->to.reg;
611*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, 0, r);
612*fbadb1c4SDavid du Colombier 		break;
613*fbadb1c4SDavid du Colombier 
614*fbadb1c4SDavid du Colombier 	case 34:	/* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
615*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6);
616*fbadb1c4SDavid du Colombier 		break;
617*fbadb1c4SDavid du Colombier 
618*fbadb1c4SDavid du Colombier 	case 35:	/* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
619*fbadb1c4SDavid du Colombier 		v = regoff(&p->to);
620*fbadb1c4SDavid du Colombier 		if(v & 0x8000L)
621*fbadb1c4SDavid du Colombier 			v += 0x10000L;
622*fbadb1c4SDavid du Colombier 		r = p->to.reg;
623*fbadb1c4SDavid du Colombier 		if(r == NREG)
624*fbadb1c4SDavid du Colombier 			r = o->param;
625*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
626*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
627*fbadb1c4SDavid du Colombier 		break;
628*fbadb1c4SDavid du Colombier 
629*fbadb1c4SDavid du Colombier 	case 36:	/* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
630*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
631*fbadb1c4SDavid du Colombier 		if(v & 0x8000L)
632*fbadb1c4SDavid du Colombier 			v += 0x10000L;
633*fbadb1c4SDavid du Colombier 		r = p->from.reg;
634*fbadb1c4SDavid du Colombier 		if(r == NREG)
635*fbadb1c4SDavid du Colombier 			r = o->param;
636*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
637*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
638*fbadb1c4SDavid du Colombier 		break;
639*fbadb1c4SDavid du Colombier 
640*fbadb1c4SDavid du Colombier 	case 37:	/* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
641*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
642*fbadb1c4SDavid du Colombier 		if(v & 0x8000L)
643*fbadb1c4SDavid du Colombier 			v += 0x10000L;
644*fbadb1c4SDavid du Colombier 		r = p->from.reg;
645*fbadb1c4SDavid du Colombier 		if(r == NREG)
646*fbadb1c4SDavid du Colombier 			r = o->param;
647*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
648*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
649*fbadb1c4SDavid du Colombier 		o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
650*fbadb1c4SDavid du Colombier 		break;
651*fbadb1c4SDavid du Colombier 
652*fbadb1c4SDavid du Colombier 	case 40:	/* word */
653*fbadb1c4SDavid du Colombier 		if(aflag)
654*fbadb1c4SDavid du Colombier 			return 0;
655*fbadb1c4SDavid du Colombier 		o1 = regoff(&p->from);
656*fbadb1c4SDavid du Colombier 		break;
657*fbadb1c4SDavid du Colombier 
658*fbadb1c4SDavid du Colombier 	case 41:	/* stswi */
659*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->from.reg, p->to.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
660*fbadb1c4SDavid du Colombier 		break;
661*fbadb1c4SDavid du Colombier 
662*fbadb1c4SDavid du Colombier 	case 42:	/* lswi */
663*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->to.reg, p->from.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
664*fbadb1c4SDavid du Colombier 		break;
665*fbadb1c4SDavid du Colombier 
666*fbadb1c4SDavid du Colombier 	case 43:	/* unary indexed source: dcbf (b); dcbf (a+b) */
667*fbadb1c4SDavid du Colombier 		r = p->reg;
668*fbadb1c4SDavid du Colombier 		if(r == NREG)
669*fbadb1c4SDavid du Colombier 			r = 0;
670*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), 0, r, p->from.reg);
671*fbadb1c4SDavid du Colombier 		break;
672*fbadb1c4SDavid du Colombier 
673*fbadb1c4SDavid du Colombier 	case 44:	/* indexed store */
674*fbadb1c4SDavid du Colombier 		r = p->reg;
675*fbadb1c4SDavid du Colombier 		if(r == NREG)
676*fbadb1c4SDavid du Colombier 			r = 0;
677*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opstorex(p->as), p->from.reg, r, p->to.reg);
678*fbadb1c4SDavid du Colombier 		break;
679*fbadb1c4SDavid du Colombier 	case 45:	/* indexed load */
680*fbadb1c4SDavid du Colombier 		r = p->reg;
681*fbadb1c4SDavid du Colombier 		if(r == NREG)
682*fbadb1c4SDavid du Colombier 			r = 0;
683*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oploadx(p->as), p->to.reg, r, p->from.reg);
684*fbadb1c4SDavid du Colombier 		break;
685*fbadb1c4SDavid du Colombier 
686*fbadb1c4SDavid du Colombier 	case 46:	/* plain op */
687*fbadb1c4SDavid du Colombier 		o1 = oprrr(p->as);
688*fbadb1c4SDavid du Colombier 		break;
689*fbadb1c4SDavid du Colombier 
690*fbadb1c4SDavid du Colombier 	case 47:	/* op Ra, Rd; also op [Ra,] Rd */
691*fbadb1c4SDavid du Colombier 		r = p->from.reg;
692*fbadb1c4SDavid du Colombier 		if(r == NREG)
693*fbadb1c4SDavid du Colombier 			r = p->to.reg;
694*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0);
695*fbadb1c4SDavid du Colombier 		break;
696*fbadb1c4SDavid du Colombier 
697*fbadb1c4SDavid du Colombier 	case 48:	/* op Rs, Ra */
698*fbadb1c4SDavid du Colombier 		r = p->from.reg;
699*fbadb1c4SDavid du Colombier 		if(r == NREG)
700*fbadb1c4SDavid du Colombier 			r = p->to.reg;
701*fbadb1c4SDavid du Colombier 		o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, 0);
702*fbadb1c4SDavid du Colombier 		break;
703*fbadb1c4SDavid du Colombier 
704*fbadb1c4SDavid du Colombier 	case 49:	/* op Rb; op $n, Rb */
705*fbadb1c4SDavid du Colombier 		if(p->from.type != D_REG){	/* tlbie $L, rB */
706*fbadb1c4SDavid du Colombier 			v = regoff(&p->from) & 1;
707*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(oprrr(p->as), 0, 0, p->to.reg) | (v<<21);
708*fbadb1c4SDavid du Colombier 		}else
709*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(oprrr(p->as), 0, 0, p->from.reg);
710*fbadb1c4SDavid du Colombier 		break;
711*fbadb1c4SDavid du Colombier 
712*fbadb1c4SDavid du Colombier 	case 50:	/* rem[u] r1[,r2],r3 */
713*fbadb1c4SDavid du Colombier 		r = p->reg;
714*fbadb1c4SDavid du Colombier 		if(r == NREG)
715*fbadb1c4SDavid du Colombier 			r = p->to.reg;
716*fbadb1c4SDavid du Colombier 		v = oprrr(p->as);
717*fbadb1c4SDavid du Colombier 		t = v & ((1<<10)|1);	/* OE|Rc */
718*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
719*fbadb1c4SDavid du Colombier 		o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
720*fbadb1c4SDavid du Colombier 		o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
721*fbadb1c4SDavid du Colombier 		break;
722*fbadb1c4SDavid du Colombier 
723*fbadb1c4SDavid du Colombier 	case 51:	/* remd[u] r1[,r2],r3 */
724*fbadb1c4SDavid du Colombier 		r = p->reg;
725*fbadb1c4SDavid du Colombier 		if(r == NREG)
726*fbadb1c4SDavid du Colombier 			r = p->to.reg;
727*fbadb1c4SDavid du Colombier 		v = oprrr(p->as);
728*fbadb1c4SDavid du Colombier 		t = v & ((1<<10)|1);	/* OE|Rc */
729*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
730*fbadb1c4SDavid du Colombier 		o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, p->from.reg);
731*fbadb1c4SDavid du Colombier 		o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
732*fbadb1c4SDavid du Colombier 		break;
733*fbadb1c4SDavid du Colombier 
734*fbadb1c4SDavid du Colombier 	case 52:	/* mtfsbNx cr(n) */
735*fbadb1c4SDavid du Colombier 		v = regoff(&p->from)&31L;
736*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), v, 0, 0);
737*fbadb1c4SDavid du Colombier 		break;
738*fbadb1c4SDavid du Colombier 
739*fbadb1c4SDavid du Colombier 	case 53:	/* mffsX ,fr1 */
740*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0);
741*fbadb1c4SDavid du Colombier 		break;
742*fbadb1c4SDavid du Colombier 
743*fbadb1c4SDavid du Colombier 	case 54:	/* mov msr,r1; mov r1, msr*/
744*fbadb1c4SDavid du Colombier 		if(oclass(p->from) == C_REG){
745*fbadb1c4SDavid du Colombier 			if(p->as == AMOVD)
746*fbadb1c4SDavid du Colombier 				o1 = AOP_RRR(OP_MTMSRD, p->from.reg, 0, 0);
747*fbadb1c4SDavid du Colombier 			else
748*fbadb1c4SDavid du Colombier 				o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0);
749*fbadb1c4SDavid du Colombier 		}else
750*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0);
751*fbadb1c4SDavid du Colombier 		break;
752*fbadb1c4SDavid du Colombier 
753*fbadb1c4SDavid du Colombier 	case 55:	/* op Rb, Rd */
754*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->to.reg, 0, p->from.reg);
755*fbadb1c4SDavid du Colombier 		break;
756*fbadb1c4SDavid du Colombier 
757*fbadb1c4SDavid du Colombier 	case 56:	/* sra $sh,[s,]a; srd $sh,[s,]a */
758*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
759*fbadb1c4SDavid du Colombier 		r = p->reg;
760*fbadb1c4SDavid du Colombier 		if(r == NREG)
761*fbadb1c4SDavid du Colombier 			r = p->to.reg;
762*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), r, p->to.reg, v&31L);
763*fbadb1c4SDavid du Colombier 		if(p->as == ASRAD && (v&0x20))
764*fbadb1c4SDavid du Colombier 			o1 |= 1<<1;	/* mb[5] */
765*fbadb1c4SDavid du Colombier 		break;
766*fbadb1c4SDavid du Colombier 
767*fbadb1c4SDavid du Colombier 	case 57:	/* slw $sh,[s,]a -> rlwinm ... */
768*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
769*fbadb1c4SDavid du Colombier 		r = p->reg;
770*fbadb1c4SDavid du Colombier 		if(r == NREG)
771*fbadb1c4SDavid du Colombier 			r = p->to.reg;
772*fbadb1c4SDavid du Colombier 		/*
773*fbadb1c4SDavid du Colombier 		 * Let user (gs) shoot himself in the foot.
774*fbadb1c4SDavid du Colombier 		 * qc has already complained.
775*fbadb1c4SDavid du Colombier 		 *
776*fbadb1c4SDavid du Colombier 		if(v < 0 || v > 31)
777*fbadb1c4SDavid du Colombier 			diag("illegal shift %ld\n%P", v, p);
778*fbadb1c4SDavid du Colombier 		 */
779*fbadb1c4SDavid du Colombier 		if(v < 0)
780*fbadb1c4SDavid du Colombier 			v = 0;
781*fbadb1c4SDavid du Colombier 		else if(v > 32)
782*fbadb1c4SDavid du Colombier 			v = 32;
783*fbadb1c4SDavid du Colombier 		if(p->as == ASRW || p->as == ASRWCC) {	/* shift right */
784*fbadb1c4SDavid du Colombier 			mask[0] = v;
785*fbadb1c4SDavid du Colombier 			mask[1] = 31;
786*fbadb1c4SDavid du Colombier 			v = 32-v;
787*fbadb1c4SDavid du Colombier 		} else {
788*fbadb1c4SDavid du Colombier 			mask[0] = 0;
789*fbadb1c4SDavid du Colombier 			mask[1] = 31-v;
790*fbadb1c4SDavid du Colombier 		}
791*fbadb1c4SDavid du Colombier 		o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]);
792*fbadb1c4SDavid du Colombier 		if(p->as == ASLWCC || p->as == ASRWCC)
793*fbadb1c4SDavid du Colombier 			o1 |= 1;	/* Rc */
794*fbadb1c4SDavid du Colombier 		break;
795*fbadb1c4SDavid du Colombier 
796*fbadb1c4SDavid du Colombier 	case 58:		/* logical $andcon,[s],a */
797*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
798*fbadb1c4SDavid du Colombier 		r = p->reg;
799*fbadb1c4SDavid du Colombier 		if(r == NREG)
800*fbadb1c4SDavid du Colombier 			r = p->to.reg;
801*fbadb1c4SDavid du Colombier 		o1 = LOP_IRR(opirr(p->as), p->to.reg, r, v);
802*fbadb1c4SDavid du Colombier 		break;
803*fbadb1c4SDavid du Colombier 
804*fbadb1c4SDavid du Colombier 	case 59:	/* or/and $ucon,,r */
805*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
806*fbadb1c4SDavid du Colombier 		r = p->reg;
807*fbadb1c4SDavid du Colombier 		if(r == NREG)
808*fbadb1c4SDavid du Colombier 			r = p->to.reg;
809*fbadb1c4SDavid du Colombier 		o1 = LOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16);	/* oris, xoris, andis */
810*fbadb1c4SDavid du Colombier 		break;
811*fbadb1c4SDavid du Colombier 
812*fbadb1c4SDavid du Colombier 	case 60:	/* tw to,a,b */
813*fbadb1c4SDavid du Colombier 		r = regoff(&p->from)&31L;
814*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), r, p->reg, p->to.reg);
815*fbadb1c4SDavid du Colombier 		break;
816*fbadb1c4SDavid du Colombier 
817*fbadb1c4SDavid du Colombier 	case 61:	/* tw to,a,$simm */
818*fbadb1c4SDavid du Colombier 		r = regoff(&p->from)&31L;
819*fbadb1c4SDavid du Colombier 		v = regoff(&p->to);
820*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(opirr(p->as), r, p->reg, v);
821*fbadb1c4SDavid du Colombier 		break;
822*fbadb1c4SDavid du Colombier 
823*fbadb1c4SDavid du Colombier 	case 62:	/* rlwmi $sh,s,$mask,a */
824*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
825*fbadb1c4SDavid du Colombier 		maskgen(p, mask, regoff(&p->from3));
826*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, v);
827*fbadb1c4SDavid du Colombier 		o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
828*fbadb1c4SDavid du Colombier 		break;
829*fbadb1c4SDavid du Colombier 
830*fbadb1c4SDavid du Colombier 	case 63:	/* rlwmi b,s,$mask,a */
831*fbadb1c4SDavid du Colombier 		maskgen(p, mask, regoff(&p->from3));
832*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, p->from.reg);
833*fbadb1c4SDavid du Colombier 		o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
834*fbadb1c4SDavid du Colombier 		break;
835*fbadb1c4SDavid du Colombier 
836*fbadb1c4SDavid du Colombier 	case 64:	/* mtfsf fr[, $m] {,fpcsr} */
837*fbadb1c4SDavid du Colombier 		if(p->from3.type != D_NONE)
838*fbadb1c4SDavid du Colombier 			v = regoff(&p->from3)&255L;
839*fbadb1c4SDavid du Colombier 		else
840*fbadb1c4SDavid du Colombier 			v = 255;
841*fbadb1c4SDavid du Colombier 		o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11);
842*fbadb1c4SDavid du Colombier 		break;
843*fbadb1c4SDavid du Colombier 
844*fbadb1c4SDavid du Colombier 	case 65:	/* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
845*fbadb1c4SDavid du Colombier 		if(p->to.reg == NREG)
846*fbadb1c4SDavid du Colombier 			diag("must specify FPSCR(n)\n%P", p);
847*fbadb1c4SDavid du Colombier 		o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(&p->from)&31L)<<12);
848*fbadb1c4SDavid du Colombier 		break;
849*fbadb1c4SDavid du Colombier 
850*fbadb1c4SDavid du Colombier 	case 66:	/* mov spr,r1; mov r1,spr, also dcr */
851*fbadb1c4SDavid du Colombier 		if(p->from.type == D_REG) {
852*fbadb1c4SDavid du Colombier 			r = p->from.reg;
853*fbadb1c4SDavid du Colombier 			v = p->to.offset;
854*fbadb1c4SDavid du Colombier 			if(p->to.type == D_DCR)
855*fbadb1c4SDavid du Colombier 				o1 = OPVCC(31,451,0,0);	/* mtdcr */
856*fbadb1c4SDavid du Colombier 			else
857*fbadb1c4SDavid du Colombier 				o1 = OPVCC(31,467,0,0); /* mtspr */
858*fbadb1c4SDavid du Colombier 		} else {
859*fbadb1c4SDavid du Colombier 			r = p->to.reg;
860*fbadb1c4SDavid du Colombier 			v = p->from.offset;
861*fbadb1c4SDavid du Colombier 			if(p->from.type == D_DCR)
862*fbadb1c4SDavid du Colombier 				o1 = OPVCC(31,323,0,0);	/* mfdcr */
863*fbadb1c4SDavid du Colombier 			else
864*fbadb1c4SDavid du Colombier 				o1 = OPVCC(31,339,0,0);	/* mfspr */
865*fbadb1c4SDavid du Colombier 		}
866*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
867*fbadb1c4SDavid du Colombier 		break;
868*fbadb1c4SDavid du Colombier 
869*fbadb1c4SDavid du Colombier 	case 67:	/* mcrf crfD,crfS */
870*fbadb1c4SDavid du Colombier 		if(p->from.type != D_CREG || p->from.reg == NREG ||
871*fbadb1c4SDavid du Colombier 		   p->to.type != D_CREG || p->to.reg == NREG)
872*fbadb1c4SDavid du Colombier 			diag("illegal CR field number\n%P", p);
873*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
874*fbadb1c4SDavid du Colombier 		break;
875*fbadb1c4SDavid du Colombier 
876*fbadb1c4SDavid du Colombier 	case 68:	/* mfcr rD; mfocrf CRM,rD */
877*fbadb1c4SDavid du Colombier 		if(p->from.type == D_CREG && p->from.reg != NREG){
878*fbadb1c4SDavid du Colombier 			v = 1<<(7-(p->to.reg&7));	/* CR(n) */
879*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0) | (1<<20) | (v<<12);	/* new form, mfocrf */
880*fbadb1c4SDavid du Colombier 		}else
881*fbadb1c4SDavid du Colombier 			o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0);	/* old form, whole register */
882*fbadb1c4SDavid du Colombier 		break;
883*fbadb1c4SDavid du Colombier 
884*fbadb1c4SDavid du Colombier 	case 69:	/* mtcrf CRM,rS */
885*fbadb1c4SDavid du Colombier 		if(p->from3.type != D_NONE) {
886*fbadb1c4SDavid du Colombier 			if(p->to.reg != NREG)
887*fbadb1c4SDavid du Colombier 				diag("can't use both mask and CR(n)\n%P", p);
888*fbadb1c4SDavid du Colombier 			v = regoff(&p->from3) & 0xff;
889*fbadb1c4SDavid du Colombier 		} else {
890*fbadb1c4SDavid du Colombier 			if(p->to.reg == NREG)
891*fbadb1c4SDavid du Colombier 				v = 0xff;	/* CR */
892*fbadb1c4SDavid du Colombier 			else
893*fbadb1c4SDavid du Colombier 				v = 1<<(7-(p->to.reg&7));	/* CR(n) */
894*fbadb1c4SDavid du Colombier 		}
895*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
896*fbadb1c4SDavid du Colombier 		break;
897*fbadb1c4SDavid du Colombier 
898*fbadb1c4SDavid du Colombier 	case 70:	/* [f]cmp r,r,cr*/
899*fbadb1c4SDavid du Colombier 		if(p->reg == NREG)
900*fbadb1c4SDavid du Colombier 			r = 0;
901*fbadb1c4SDavid du Colombier 		else
902*fbadb1c4SDavid du Colombier 			r = (p->reg&7)<<2;
903*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
904*fbadb1c4SDavid du Colombier 		break;
905*fbadb1c4SDavid du Colombier 
906*fbadb1c4SDavid du Colombier 	case 71:	/* cmp[l] r,i,cr*/
907*fbadb1c4SDavid du Colombier 		if(p->reg == NREG)
908*fbadb1c4SDavid du Colombier 			r = 0;
909*fbadb1c4SDavid du Colombier 		else
910*fbadb1c4SDavid du Colombier 			r = (p->reg&7)<<2;
911*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(opirr(p->as), r, p->from.reg, 0) | (regoff(&p->to)&0xffff);
912*fbadb1c4SDavid du Colombier 		break;
913*fbadb1c4SDavid du Colombier 
914*fbadb1c4SDavid du Colombier 	case 72:	/* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
915*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(oprrr(p->as), p->from.reg, 0, p->to.reg);
916*fbadb1c4SDavid du Colombier 		break;
917*fbadb1c4SDavid du Colombier 
918*fbadb1c4SDavid du Colombier 	case 73:	/* mcrfs crfD,crfS */
919*fbadb1c4SDavid du Colombier 		if(p->from.type != D_FPSCR || p->from.reg == NREG ||
920*fbadb1c4SDavid du Colombier 		   p->to.type != D_CREG || p->to.reg == NREG)
921*fbadb1c4SDavid du Colombier 			diag("illegal FPSCR/CR field number\n%P", p);
922*fbadb1c4SDavid du Colombier 		o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
923*fbadb1c4SDavid du Colombier 		break;
924*fbadb1c4SDavid du Colombier 
925*fbadb1c4SDavid du Colombier 	/* relocation operations */
926*fbadb1c4SDavid du Colombier 
927*fbadb1c4SDavid du Colombier 	case 74:
928*fbadb1c4SDavid du Colombier 		v = regoff(&p->to);
929*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
930*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
931*fbadb1c4SDavid du Colombier 		if(dlm)
932*fbadb1c4SDavid du Colombier 			reloc(&p->to, p->pc, 1);
933*fbadb1c4SDavid du Colombier 		break;
934*fbadb1c4SDavid du Colombier 
935*fbadb1c4SDavid du Colombier 	case 75:
936*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
937*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
938*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
939*fbadb1c4SDavid du Colombier 		if(dlm)
940*fbadb1c4SDavid du Colombier 			reloc(&p->from, p->pc, 1);
941*fbadb1c4SDavid du Colombier 		break;
942*fbadb1c4SDavid du Colombier 
943*fbadb1c4SDavid du Colombier 	case 76:
944*fbadb1c4SDavid du Colombier 		v = regoff(&p->from);
945*fbadb1c4SDavid du Colombier 		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
946*fbadb1c4SDavid du Colombier 		o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
947*fbadb1c4SDavid du Colombier 		o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
948*fbadb1c4SDavid du Colombier 		if(dlm)
949*fbadb1c4SDavid du Colombier 			reloc(&p->from, p->pc, 1);
950*fbadb1c4SDavid du Colombier 		break;
951*fbadb1c4SDavid du Colombier 
952*fbadb1c4SDavid du Colombier 	}
953*fbadb1c4SDavid du Colombier 	if(aflag)
954*fbadb1c4SDavid du Colombier 		return o1;
955*fbadb1c4SDavid du Colombier 	v = p->pc;
956*fbadb1c4SDavid du Colombier 	switch(o->size) {
957*fbadb1c4SDavid du Colombier 	default:
958*fbadb1c4SDavid du Colombier 		if(debug['a'])
959*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
960*fbadb1c4SDavid du Colombier 		break;
961*fbadb1c4SDavid du Colombier 	case 4:
962*fbadb1c4SDavid du Colombier 		if(debug['a'])
963*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
964*fbadb1c4SDavid du Colombier 		lput(o1);
965*fbadb1c4SDavid du Colombier 		break;
966*fbadb1c4SDavid du Colombier 	case 8:
967*fbadb1c4SDavid du Colombier 		if(debug['a'])
968*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
969*fbadb1c4SDavid du Colombier 		lput(o1);
970*fbadb1c4SDavid du Colombier 		lput(o2);
971*fbadb1c4SDavid du Colombier 		break;
972*fbadb1c4SDavid du Colombier 	case 12:
973*fbadb1c4SDavid du Colombier 		if(debug['a'])
974*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
975*fbadb1c4SDavid du Colombier 		lput(o1);
976*fbadb1c4SDavid du Colombier 		lput(o2);
977*fbadb1c4SDavid du Colombier 		lput(o3);
978*fbadb1c4SDavid du Colombier 		break;
979*fbadb1c4SDavid du Colombier 	case 16:
980*fbadb1c4SDavid du Colombier 		if(debug['a'])
981*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
982*fbadb1c4SDavid du Colombier 				v, o1, o2, o3, o4, p);
983*fbadb1c4SDavid du Colombier 		lput(o1);
984*fbadb1c4SDavid du Colombier 		lput(o2);
985*fbadb1c4SDavid du Colombier 		lput(o3);
986*fbadb1c4SDavid du Colombier 		lput(o4);
987*fbadb1c4SDavid du Colombier 		break;
988*fbadb1c4SDavid du Colombier 	case 20:
989*fbadb1c4SDavid du Colombier 		if(debug['a'])
990*fbadb1c4SDavid du Colombier 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
991*fbadb1c4SDavid du Colombier 				v, o1, o2, o3, o4, o5, p);
992*fbadb1c4SDavid du Colombier 		lput(o1);
993*fbadb1c4SDavid du Colombier 		lput(o2);
994*fbadb1c4SDavid du Colombier 		lput(o3);
995*fbadb1c4SDavid du Colombier 		lput(o4);
996*fbadb1c4SDavid du Colombier 		lput(o5);
997*fbadb1c4SDavid du Colombier 		break;
998*fbadb1c4SDavid du Colombier 	}
999*fbadb1c4SDavid du Colombier 	return 0;
1000*fbadb1c4SDavid du Colombier }
1001*fbadb1c4SDavid du Colombier 
1002*fbadb1c4SDavid du Colombier long
oprrr(int a)1003*fbadb1c4SDavid du Colombier oprrr(int a)
1004*fbadb1c4SDavid du Colombier {
1005*fbadb1c4SDavid du Colombier 	switch(a) {
1006*fbadb1c4SDavid du Colombier 	case AADD:	return OPVCC(31,266,0,0);
1007*fbadb1c4SDavid du Colombier 	case AADDCC:	return OPVCC(31,266,0,1);
1008*fbadb1c4SDavid du Colombier 	case AADDV:	return OPVCC(31,266,1,0);
1009*fbadb1c4SDavid du Colombier 	case AADDVCC:	return OPVCC(31,266,1,1);
1010*fbadb1c4SDavid du Colombier 	case AADDC:	return OPVCC(31,10,0,0);
1011*fbadb1c4SDavid du Colombier 	case AADDCCC:	return OPVCC(31,10,0,1);
1012*fbadb1c4SDavid du Colombier 	case AADDCV:	return OPVCC(31,10,1,0);
1013*fbadb1c4SDavid du Colombier 	case AADDCVCC:	return OPVCC(31,10,1,1);
1014*fbadb1c4SDavid du Colombier 	case AADDE:	return OPVCC(31,138,0,0);
1015*fbadb1c4SDavid du Colombier 	case AADDECC:	return OPVCC(31,138,0,1);
1016*fbadb1c4SDavid du Colombier 	case AADDEV:	return OPVCC(31,138,1,0);
1017*fbadb1c4SDavid du Colombier 	case AADDEVCC:	return OPVCC(31,138,1,1);
1018*fbadb1c4SDavid du Colombier 	case AADDME:	return OPVCC(31,234,0,0);
1019*fbadb1c4SDavid du Colombier 	case AADDMECC:	return OPVCC(31,234,0,1);
1020*fbadb1c4SDavid du Colombier 	case AADDMEV:	return OPVCC(31,234,1,0);
1021*fbadb1c4SDavid du Colombier 	case AADDMEVCC:	return OPVCC(31,234,1,1);
1022*fbadb1c4SDavid du Colombier 	case AADDZE:	return OPVCC(31,202,0,0);
1023*fbadb1c4SDavid du Colombier 	case AADDZECC:	return OPVCC(31,202,0,1);
1024*fbadb1c4SDavid du Colombier 	case AADDZEV:	return OPVCC(31,202,1,0);
1025*fbadb1c4SDavid du Colombier 	case AADDZEVCC:	return OPVCC(31,202,1,1);
1026*fbadb1c4SDavid du Colombier 
1027*fbadb1c4SDavid du Colombier 	case AAND:	return OPVCC(31,28,0,0);
1028*fbadb1c4SDavid du Colombier 	case AANDCC:	return OPVCC(31,28,0,1);
1029*fbadb1c4SDavid du Colombier 	case AANDN:	return OPVCC(31,60,0,0);
1030*fbadb1c4SDavid du Colombier 	case AANDNCC:	return OPVCC(31,60,0,1);
1031*fbadb1c4SDavid du Colombier 
1032*fbadb1c4SDavid du Colombier 	case ACMP:	return OPVCC(31,0,0,0)|(1<<21);	/* L=1 */
1033*fbadb1c4SDavid du Colombier 	case ACMPU:	return OPVCC(31,32,0,0)|(1<<21);
1034*fbadb1c4SDavid du Colombier 	case ACMPW:	return OPVCC(31,0,0,0);	/* L=0 */
1035*fbadb1c4SDavid du Colombier 	case ACMPWU:	return OPVCC(31,32,0,0);
1036*fbadb1c4SDavid du Colombier 
1037*fbadb1c4SDavid du Colombier 	case ACNTLZW:	return OPVCC(31,26,0,0);
1038*fbadb1c4SDavid du Colombier 	case ACNTLZWCC:	return OPVCC(31,26,0,1);
1039*fbadb1c4SDavid du Colombier 	case ACNTLZD:		return OPVCC(31,58,0,0);
1040*fbadb1c4SDavid du Colombier 	case ACNTLZDCC:	return OPVCC(31,58,0,1);
1041*fbadb1c4SDavid du Colombier 
1042*fbadb1c4SDavid du Colombier 	case ACRAND:	return OPVCC(19,257,0,0);
1043*fbadb1c4SDavid du Colombier 	case ACRANDN:	return OPVCC(19,129,0,0);
1044*fbadb1c4SDavid du Colombier 	case ACREQV:	return OPVCC(19,289,0,0);
1045*fbadb1c4SDavid du Colombier 	case ACRNAND:	return OPVCC(19,225,0,0);
1046*fbadb1c4SDavid du Colombier 	case ACRNOR:	return OPVCC(19,33,0,0);
1047*fbadb1c4SDavid du Colombier 	case ACROR:	return OPVCC(19,449,0,0);
1048*fbadb1c4SDavid du Colombier 	case ACRORN:	return OPVCC(19,417,0,0);
1049*fbadb1c4SDavid du Colombier 	case ACRXOR:	return OPVCC(19,193,0,0);
1050*fbadb1c4SDavid du Colombier 
1051*fbadb1c4SDavid du Colombier 	case ADCBF:	return OPVCC(31,86,0,0);
1052*fbadb1c4SDavid du Colombier 	case ADCBI:	return OPVCC(31,470,0,0);
1053*fbadb1c4SDavid du Colombier 	case ADCBST:	return OPVCC(31,54,0,0);
1054*fbadb1c4SDavid du Colombier 	case ADCBT:	return OPVCC(31,278,0,0);
1055*fbadb1c4SDavid du Colombier 	case ADCBTST:	return OPVCC(31,246,0,0);
1056*fbadb1c4SDavid du Colombier 	case ADCBZ:	return OPVCC(31,1014,0,0);
1057*fbadb1c4SDavid du Colombier 
1058*fbadb1c4SDavid du Colombier 	case AREM:
1059*fbadb1c4SDavid du Colombier 	case ADIVW:	return OPVCC(31,491,0,0);
1060*fbadb1c4SDavid du Colombier 	case AREMCC:
1061*fbadb1c4SDavid du Colombier 	case ADIVWCC:	return OPVCC(31,491,0,1);
1062*fbadb1c4SDavid du Colombier 	case AREMV:
1063*fbadb1c4SDavid du Colombier 	case ADIVWV:	return OPVCC(31,491,1,0);
1064*fbadb1c4SDavid du Colombier 	case AREMVCC:
1065*fbadb1c4SDavid du Colombier 	case ADIVWVCC:	return OPVCC(31,491,1,1);
1066*fbadb1c4SDavid du Colombier 	case AREMU:
1067*fbadb1c4SDavid du Colombier 	case ADIVWU:	return OPVCC(31,459,0,0);
1068*fbadb1c4SDavid du Colombier 	case AREMUCC:
1069*fbadb1c4SDavid du Colombier 	case ADIVWUCC:	return OPVCC(31,459,0,1);
1070*fbadb1c4SDavid du Colombier 	case AREMUV:
1071*fbadb1c4SDavid du Colombier 	case ADIVWUV:	return OPVCC(31,459,1,0);
1072*fbadb1c4SDavid du Colombier 	case AREMUVCC:
1073*fbadb1c4SDavid du Colombier 	case ADIVWUVCC:	return OPVCC(31,459,1,1);
1074*fbadb1c4SDavid du Colombier 
1075*fbadb1c4SDavid du Colombier 	case AREMD:
1076*fbadb1c4SDavid du Colombier 	case ADIVD:	return OPVCC(31,489,0,0);
1077*fbadb1c4SDavid du Colombier 	case AREMDCC:
1078*fbadb1c4SDavid du Colombier 	case ADIVDCC:	return OPVCC(31,489,0,1);
1079*fbadb1c4SDavid du Colombier 	case AREMDV:
1080*fbadb1c4SDavid du Colombier 	case ADIVDV:	return OPVCC(31,489,1,0);
1081*fbadb1c4SDavid du Colombier 	case AREMDVCC:
1082*fbadb1c4SDavid du Colombier 	case ADIVDVCC:	return OPVCC(31,489,1,1);
1083*fbadb1c4SDavid du Colombier 	case AREMDU:
1084*fbadb1c4SDavid du Colombier 	case ADIVDU:	return OPVCC(31,457,0,0);
1085*fbadb1c4SDavid du Colombier 	case AREMDUCC:
1086*fbadb1c4SDavid du Colombier 	case ADIVDUCC:	return OPVCC(31,457,0,1);
1087*fbadb1c4SDavid du Colombier 	case AREMDUV:
1088*fbadb1c4SDavid du Colombier 	case ADIVDUV:	return OPVCC(31,457,1,0);
1089*fbadb1c4SDavid du Colombier 	case AREMDUVCC:
1090*fbadb1c4SDavid du Colombier 	case ADIVDUVCC:	return OPVCC(31,457,1,1);
1091*fbadb1c4SDavid du Colombier 
1092*fbadb1c4SDavid du Colombier 	case AEIEIO:	return OPVCC(31,854,0,0);
1093*fbadb1c4SDavid du Colombier 
1094*fbadb1c4SDavid du Colombier 	case AEQV:	return OPVCC(31,284,0,0);
1095*fbadb1c4SDavid du Colombier 	case AEQVCC:	return OPVCC(31,284,0,1);
1096*fbadb1c4SDavid du Colombier 
1097*fbadb1c4SDavid du Colombier 	case AEXTSB:	return OPVCC(31,954,0,0);
1098*fbadb1c4SDavid du Colombier 	case AEXTSBCC:	return OPVCC(31,954,0,1);
1099*fbadb1c4SDavid du Colombier 	case AEXTSH:	return OPVCC(31,922,0,0);
1100*fbadb1c4SDavid du Colombier 	case AEXTSHCC:	return OPVCC(31,922,0,1);
1101*fbadb1c4SDavid du Colombier 	case AEXTSW:	return OPVCC(31,986,0,0);
1102*fbadb1c4SDavid du Colombier 	case AEXTSWCC:	return OPVCC(31,986,0,1);
1103*fbadb1c4SDavid du Colombier 
1104*fbadb1c4SDavid du Colombier 	case AFABS:	return OPVCC(63,264,0,0);
1105*fbadb1c4SDavid du Colombier 	case AFABSCC:	return OPVCC(63,264,0,1);
1106*fbadb1c4SDavid du Colombier 	case AFADD:	return OPVCC(63,21,0,0);
1107*fbadb1c4SDavid du Colombier 	case AFADDCC:	return OPVCC(63,21,0,1);
1108*fbadb1c4SDavid du Colombier 	case AFADDS:	return OPVCC(59,21,0,0);
1109*fbadb1c4SDavid du Colombier 	case AFADDSCC:	return OPVCC(59,21,0,1);
1110*fbadb1c4SDavid du Colombier 	case AFCMPO:	return OPVCC(63,32,0,0);
1111*fbadb1c4SDavid du Colombier 	case AFCMPU:	return OPVCC(63,0,0,0);
1112*fbadb1c4SDavid du Colombier 	case AFCFID:	return OPVCC(63,846,0,0);
1113*fbadb1c4SDavid du Colombier 	case AFCFIDCC:	return OPVCC(63,846,0,1);
1114*fbadb1c4SDavid du Colombier 	case AFCTIW:	return OPVCC(63,14,0,0);
1115*fbadb1c4SDavid du Colombier 	case AFCTIWCC:	return OPVCC(63,14,0,1);
1116*fbadb1c4SDavid du Colombier 	case AFCTIWZ:	return OPVCC(63,15,0,0);
1117*fbadb1c4SDavid du Colombier 	case AFCTIWZCC:	return OPVCC(63,15,0,1);
1118*fbadb1c4SDavid du Colombier 	case AFCTID:	return OPVCC(63,814,0,0);
1119*fbadb1c4SDavid du Colombier 	case AFCTIDCC:	return OPVCC(63,814,0,1);
1120*fbadb1c4SDavid du Colombier 	case AFCTIDZ:	return OPVCC(63,815,0,0);
1121*fbadb1c4SDavid du Colombier 	case AFCTIDZCC:	return OPVCC(63,815,0,1);
1122*fbadb1c4SDavid du Colombier 	case AFDIV:	return OPVCC(63,18,0,0);
1123*fbadb1c4SDavid du Colombier 	case AFDIVCC:	return OPVCC(63,18,0,1);
1124*fbadb1c4SDavid du Colombier 	case AFDIVS:	return OPVCC(59,18,0,0);
1125*fbadb1c4SDavid du Colombier 	case AFDIVSCC:	return OPVCC(59,18,0,1);
1126*fbadb1c4SDavid du Colombier 	case AFMADD:	return OPVCC(63,29,0,0);
1127*fbadb1c4SDavid du Colombier 	case AFMADDCC:	return OPVCC(63,29,0,1);
1128*fbadb1c4SDavid du Colombier 	case AFMADDS:	return OPVCC(59,29,0,0);
1129*fbadb1c4SDavid du Colombier 	case AFMADDSCC:	return OPVCC(59,29,0,1);
1130*fbadb1c4SDavid du Colombier 	case AFMOVS:
1131*fbadb1c4SDavid du Colombier 	case AFMOVD:	return OPVCC(63,72,0,0);	/* load */
1132*fbadb1c4SDavid du Colombier 	case AFMOVDCC:	return OPVCC(63,72,0,1);
1133*fbadb1c4SDavid du Colombier 	case AFMSUB:	return OPVCC(63,28,0,0);
1134*fbadb1c4SDavid du Colombier 	case AFMSUBCC:	return OPVCC(63,28,0,1);
1135*fbadb1c4SDavid du Colombier 	case AFMSUBS:	return OPVCC(59,28,0,0);
1136*fbadb1c4SDavid du Colombier 	case AFMSUBSCC:	return OPVCC(59,28,0,1);
1137*fbadb1c4SDavid du Colombier 	case AFMUL:	return OPVCC(63,25,0,0);
1138*fbadb1c4SDavid du Colombier 	case AFMULCC:	return OPVCC(63,25,0,1);
1139*fbadb1c4SDavid du Colombier 	case AFMULS:	return OPVCC(59,25,0,0);
1140*fbadb1c4SDavid du Colombier 	case AFMULSCC:	return OPVCC(59,25,0,1);
1141*fbadb1c4SDavid du Colombier 	case AFNABS:	return OPVCC(63,136,0,0);
1142*fbadb1c4SDavid du Colombier 	case AFNABSCC:	return OPVCC(63,136,0,1);
1143*fbadb1c4SDavid du Colombier 	case AFNEG:	return OPVCC(63,40,0,0);
1144*fbadb1c4SDavid du Colombier 	case AFNEGCC:	return OPVCC(63,40,0,1);
1145*fbadb1c4SDavid du Colombier 	case AFNMADD:	return OPVCC(63,31,0,0);
1146*fbadb1c4SDavid du Colombier 	case AFNMADDCC:	return OPVCC(63,31,0,1);
1147*fbadb1c4SDavid du Colombier 	case AFNMADDS:	return OPVCC(59,31,0,0);
1148*fbadb1c4SDavid du Colombier 	case AFNMADDSCC:	return OPVCC(59,31,0,1);
1149*fbadb1c4SDavid du Colombier 	case AFNMSUB:	return OPVCC(63,30,0,0);
1150*fbadb1c4SDavid du Colombier 	case AFNMSUBCC:	return OPVCC(63,30,0,1);
1151*fbadb1c4SDavid du Colombier 	case AFNMSUBS:	return OPVCC(59,30,0,0);
1152*fbadb1c4SDavid du Colombier 	case AFNMSUBSCC:	return OPVCC(59,30,0,1);
1153*fbadb1c4SDavid du Colombier 	case AFRES:	return OPVCC(59,24,0,0);
1154*fbadb1c4SDavid du Colombier 	case AFRESCC:	return OPVCC(59,24,0,1);
1155*fbadb1c4SDavid du Colombier 	case AFRSP:	return OPVCC(63,12,0,0);
1156*fbadb1c4SDavid du Colombier 	case AFRSPCC:	return OPVCC(63,12,0,1);
1157*fbadb1c4SDavid du Colombier 	case AFRSQRTE:	return OPVCC(63,26,0,0);
1158*fbadb1c4SDavid du Colombier 	case AFRSQRTECC:	return OPVCC(63,26,0,1);
1159*fbadb1c4SDavid du Colombier 	case AFSEL:	return OPVCC(63,23,0,0);
1160*fbadb1c4SDavid du Colombier 	case AFSELCC:	return OPVCC(63,23,0,1);
1161*fbadb1c4SDavid du Colombier 	case AFSQRT:	return OPVCC(63,22,0,0);
1162*fbadb1c4SDavid du Colombier 	case AFSQRTCC:	return OPVCC(63,22,0,1);
1163*fbadb1c4SDavid du Colombier 	case AFSQRTS:	return OPVCC(59,22,0,0);
1164*fbadb1c4SDavid du Colombier 	case AFSQRTSCC:	return OPVCC(59,22,0,1);
1165*fbadb1c4SDavid du Colombier 	case AFSUB:	return OPVCC(63,20,0,0);
1166*fbadb1c4SDavid du Colombier 	case AFSUBCC:	return OPVCC(63,20,0,1);
1167*fbadb1c4SDavid du Colombier 	case AFSUBS:	return OPVCC(59,20,0,0);
1168*fbadb1c4SDavid du Colombier 	case AFSUBSCC:	return OPVCC(59,20,0,1);
1169*fbadb1c4SDavid du Colombier 
1170*fbadb1c4SDavid du Colombier 	case AICBI:	return OPVCC(31,982,0,0);
1171*fbadb1c4SDavid du Colombier 	case AISYNC:	return OPVCC(19,150,0,0);
1172*fbadb1c4SDavid du Colombier 
1173*fbadb1c4SDavid du Colombier 	case AMTFSB0:	return OPVCC(63,70,0,0);
1174*fbadb1c4SDavid du Colombier 	case AMTFSB0CC:	return OPVCC(63,70,0,1);
1175*fbadb1c4SDavid du Colombier 	case AMTFSB1:	return OPVCC(63,38,0,0);
1176*fbadb1c4SDavid du Colombier 	case AMTFSB1CC:	return OPVCC(63,38,0,1);
1177*fbadb1c4SDavid du Colombier 
1178*fbadb1c4SDavid du Colombier 	case AMULHW:	return OPVCC(31,75,0,0);
1179*fbadb1c4SDavid du Colombier 	case AMULHWCC:	return OPVCC(31,75,0,1);
1180*fbadb1c4SDavid du Colombier 	case AMULHWU:	return OPVCC(31,11,0,0);
1181*fbadb1c4SDavid du Colombier 	case AMULHWUCC:	return OPVCC(31,11,0,1);
1182*fbadb1c4SDavid du Colombier 	case AMULLW:	return OPVCC(31,235,0,0);
1183*fbadb1c4SDavid du Colombier 	case AMULLWCC:	return OPVCC(31,235,0,1);
1184*fbadb1c4SDavid du Colombier 	case AMULLWV:	return OPVCC(31,235,1,0);
1185*fbadb1c4SDavid du Colombier 	case AMULLWVCC:	return OPVCC(31,235,1,1);
1186*fbadb1c4SDavid du Colombier 
1187*fbadb1c4SDavid du Colombier 	case AMULHD:	return OPVCC(31,73,0,0);
1188*fbadb1c4SDavid du Colombier 	case AMULHDCC:	return OPVCC(31,73,0,1);
1189*fbadb1c4SDavid du Colombier 	case AMULHDU:	return OPVCC(31,9,0,0);
1190*fbadb1c4SDavid du Colombier 	case AMULHDUCC:	return OPVCC(31,9,0,1);
1191*fbadb1c4SDavid du Colombier 	case AMULLD:	return OPVCC(31,233,0,0);
1192*fbadb1c4SDavid du Colombier 	case AMULLDCC:	return OPVCC(31,233,0,1);
1193*fbadb1c4SDavid du Colombier 	case AMULLDV:	return OPVCC(31,233,1,0);
1194*fbadb1c4SDavid du Colombier 	case AMULLDVCC:	return OPVCC(31,233,1,1);
1195*fbadb1c4SDavid du Colombier 
1196*fbadb1c4SDavid du Colombier 	case ANAND:	return OPVCC(31,476,0,0);
1197*fbadb1c4SDavid du Colombier 	case ANANDCC:	return OPVCC(31,476,0,1);
1198*fbadb1c4SDavid du Colombier 	case ANEG:	return OPVCC(31,104,0,0);
1199*fbadb1c4SDavid du Colombier 	case ANEGCC:	return OPVCC(31,104,0,1);
1200*fbadb1c4SDavid du Colombier 	case ANEGV:	return OPVCC(31,104,1,0);
1201*fbadb1c4SDavid du Colombier 	case ANEGVCC:	return OPVCC(31,104,1,1);
1202*fbadb1c4SDavid du Colombier 	case ANOR:	return OPVCC(31,124,0,0);
1203*fbadb1c4SDavid du Colombier 	case ANORCC:	return OPVCC(31,124,0,1);
1204*fbadb1c4SDavid du Colombier 	case AOR:	return OPVCC(31,444,0,0);
1205*fbadb1c4SDavid du Colombier 	case AORCC:	return OPVCC(31,444,0,1);
1206*fbadb1c4SDavid du Colombier 	case AORN:	return OPVCC(31,412,0,0);
1207*fbadb1c4SDavid du Colombier 	case AORNCC:	return OPVCC(31,412,0,1);
1208*fbadb1c4SDavid du Colombier 
1209*fbadb1c4SDavid du Colombier 	case ARFI:	return OPVCC(19,50,0,0);
1210*fbadb1c4SDavid du Colombier 	case ARFCI:	return OPVCC(19,51,0,0);
1211*fbadb1c4SDavid du Colombier 	case ARFID:	return OPVCC(19,18,0,0);
1212*fbadb1c4SDavid du Colombier 	case AHRFID: return OPVCC(19,274,0,0);
1213*fbadb1c4SDavid du Colombier 
1214*fbadb1c4SDavid du Colombier 	case ARLWMI:	return OPVCC(20,0,0,0);
1215*fbadb1c4SDavid du Colombier 	case ARLWMICC: return OPVCC(20,0,0,1);
1216*fbadb1c4SDavid du Colombier 	case ARLWNM:	return OPVCC(23,0,0,0);
1217*fbadb1c4SDavid du Colombier 	case ARLWNMCC:	return OPVCC(23,0,0,1);
1218*fbadb1c4SDavid du Colombier 
1219*fbadb1c4SDavid du Colombier 	case ARLDCL:	return OPVCC(30,8,0,0);
1220*fbadb1c4SDavid du Colombier 	case ARLDCR:	return OPVCC(30,9,0,0);
1221*fbadb1c4SDavid du Colombier 
1222*fbadb1c4SDavid du Colombier 	case ASYSCALL:	return OPVCC(17,1,0,0);
1223*fbadb1c4SDavid du Colombier 
1224*fbadb1c4SDavid du Colombier 	case ASLW:	return OPVCC(31,24,0,0);
1225*fbadb1c4SDavid du Colombier 	case ASLWCC:	return OPVCC(31,24,0,1);
1226*fbadb1c4SDavid du Colombier 	case ASLD:	return OPVCC(31,27,0,0);
1227*fbadb1c4SDavid du Colombier 	case ASLDCC:	return OPVCC(31,27,0,1);
1228*fbadb1c4SDavid du Colombier 
1229*fbadb1c4SDavid du Colombier 	case ASRAW:	return OPVCC(31,792,0,0);
1230*fbadb1c4SDavid du Colombier 	case ASRAWCC:	return OPVCC(31,792,0,1);
1231*fbadb1c4SDavid du Colombier 	case ASRAD:	return OPVCC(31,794,0,0);
1232*fbadb1c4SDavid du Colombier 	case ASRADCC:	return OPVCC(31,794,0,1);
1233*fbadb1c4SDavid du Colombier 
1234*fbadb1c4SDavid du Colombier 	case ASRW:	return OPVCC(31,536,0,0);
1235*fbadb1c4SDavid du Colombier 	case ASRWCC:	return OPVCC(31,536,0,1);
1236*fbadb1c4SDavid du Colombier 	case ASRD:	return OPVCC(31,539,0,0);
1237*fbadb1c4SDavid du Colombier 	case ASRDCC:	return OPVCC(31,539,0,1);
1238*fbadb1c4SDavid du Colombier 
1239*fbadb1c4SDavid du Colombier 	case ASUB:	return OPVCC(31,40,0,0);
1240*fbadb1c4SDavid du Colombier 	case ASUBCC:	return OPVCC(31,40,0,1);
1241*fbadb1c4SDavid du Colombier 	case ASUBV:	return OPVCC(31,40,1,0);
1242*fbadb1c4SDavid du Colombier 	case ASUBVCC:	return OPVCC(31,40,1,1);
1243*fbadb1c4SDavid du Colombier 	case ASUBC:	return OPVCC(31,8,0,0);
1244*fbadb1c4SDavid du Colombier 	case ASUBCCC:	return OPVCC(31,8,0,1);
1245*fbadb1c4SDavid du Colombier 	case ASUBCV:	return OPVCC(31,8,1,0);
1246*fbadb1c4SDavid du Colombier 	case ASUBCVCC:	return OPVCC(31,8,1,1);
1247*fbadb1c4SDavid du Colombier 	case ASUBE:	return OPVCC(31,136,0,0);
1248*fbadb1c4SDavid du Colombier 	case ASUBECC:	return OPVCC(31,136,0,1);
1249*fbadb1c4SDavid du Colombier 	case ASUBEV:	return OPVCC(31,136,1,0);
1250*fbadb1c4SDavid du Colombier 	case ASUBEVCC:	return OPVCC(31,136,1,1);
1251*fbadb1c4SDavid du Colombier 	case ASUBME:	return OPVCC(31,232,0,0);
1252*fbadb1c4SDavid du Colombier 	case ASUBMECC:	return OPVCC(31,232,0,1);
1253*fbadb1c4SDavid du Colombier 	case ASUBMEV:	return OPVCC(31,232,1,0);
1254*fbadb1c4SDavid du Colombier 	case ASUBMEVCC:	return OPVCC(31,232,1,1);
1255*fbadb1c4SDavid du Colombier 	case ASUBZE:	return OPVCC(31,200,0,0);
1256*fbadb1c4SDavid du Colombier 	case ASUBZECC:	return OPVCC(31,200,0,1);
1257*fbadb1c4SDavid du Colombier 	case ASUBZEV:	return OPVCC(31,200,1,0);
1258*fbadb1c4SDavid du Colombier 	case ASUBZEVCC:	return OPVCC(31,200,1,1);
1259*fbadb1c4SDavid du Colombier 
1260*fbadb1c4SDavid du Colombier 	case ASYNC:	return OPVCC(31,598,0,0);
1261*fbadb1c4SDavid du Colombier 	case APTESYNC:	return OPVCC(31,598,0,0) | (2<<21);
1262*fbadb1c4SDavid du Colombier 
1263*fbadb1c4SDavid du Colombier 	case ATLBIE:	return OPVCC(31,306,0,0);
1264*fbadb1c4SDavid du Colombier 	case ATLBIEL:	return OPVCC(31,274,0,0);
1265*fbadb1c4SDavid du Colombier 	case ATLBSYNC:	return OPVCC(31,566,0,0);
1266*fbadb1c4SDavid du Colombier 	case ASLBIA:	return OPVCC(31,498,0,0);
1267*fbadb1c4SDavid du Colombier 	case ASLBIE:	return OPVCC(31,434,0,0);
1268*fbadb1c4SDavid du Colombier 	case ASLBMFEE:	return OPVCC(31,915,0,0);
1269*fbadb1c4SDavid du Colombier 	case ASLBMFEV:	return OPVCC(31,851,0,0);
1270*fbadb1c4SDavid du Colombier 	case ASLBMTE:		return OPVCC(31,402,0,0);
1271*fbadb1c4SDavid du Colombier 
1272*fbadb1c4SDavid du Colombier 	case ATW:	return OPVCC(31,4,0,0);
1273*fbadb1c4SDavid du Colombier 	case ATD:	return OPVCC(31,68,0,0);
1274*fbadb1c4SDavid du Colombier 
1275*fbadb1c4SDavid du Colombier 	case AXOR:	return OPVCC(31,316,0,0);
1276*fbadb1c4SDavid du Colombier 	case AXORCC:	return OPVCC(31,316,0,1);
1277*fbadb1c4SDavid du Colombier 	}
1278*fbadb1c4SDavid du Colombier 	diag("bad r/r opcode %A", a);
1279*fbadb1c4SDavid du Colombier 	return 0;
1280*fbadb1c4SDavid du Colombier }
1281*fbadb1c4SDavid du Colombier 
1282*fbadb1c4SDavid du Colombier long
opirr(int a)1283*fbadb1c4SDavid du Colombier opirr(int a)
1284*fbadb1c4SDavid du Colombier {
1285*fbadb1c4SDavid du Colombier 	switch(a) {
1286*fbadb1c4SDavid du Colombier 	case AADD:	return OPVCC(14,0,0,0);
1287*fbadb1c4SDavid du Colombier 	case AADDC:	return OPVCC(12,0,0,0);
1288*fbadb1c4SDavid du Colombier 	case AADDCCC:	return OPVCC(13,0,0,0);
1289*fbadb1c4SDavid du Colombier 	case AADD+AEND:	return OPVCC(15,0,0,0);		/* ADDIS/CAU */
1290*fbadb1c4SDavid du Colombier 
1291*fbadb1c4SDavid du Colombier 	case AANDCC:	return OPVCC(28,0,0,0);
1292*fbadb1c4SDavid du Colombier 	case AANDCC+AEND:	return OPVCC(29,0,0,0);		/* ANDIS./ANDIU. */
1293*fbadb1c4SDavid du Colombier 
1294*fbadb1c4SDavid du Colombier 	case ABR:	return OPVCC(18,0,0,0);
1295*fbadb1c4SDavid du Colombier 	case ABL:	return OPVCC(18,0,0,0) | 1;
1296*fbadb1c4SDavid du Colombier 	case ABC:	return OPVCC(16,0,0,0);
1297*fbadb1c4SDavid du Colombier 	case ABCL:	return OPVCC(16,0,0,0) | 1;
1298*fbadb1c4SDavid du Colombier 
1299*fbadb1c4SDavid du Colombier 	case ABEQ:	return AOP_RRR(16<<26,12,2,0);
1300*fbadb1c4SDavid du Colombier 	case ABGE:	return AOP_RRR(16<<26,4,0,0);
1301*fbadb1c4SDavid du Colombier 	case ABGT:	return AOP_RRR(16<<26,12,1,0);
1302*fbadb1c4SDavid du Colombier 	case ABLE:	return AOP_RRR(16<<26,4,1,0);
1303*fbadb1c4SDavid du Colombier 	case ABLT:	return AOP_RRR(16<<26,12,0,0);
1304*fbadb1c4SDavid du Colombier 	case ABNE:	return AOP_RRR(16<<26,4,2,0);
1305*fbadb1c4SDavid du Colombier 	case ABVC:	return AOP_RRR(16<<26,4,3,0);
1306*fbadb1c4SDavid du Colombier 	case ABVS:	return AOP_RRR(16<<26,12,3,0);
1307*fbadb1c4SDavid du Colombier 
1308*fbadb1c4SDavid du Colombier 	case ACMP:	return OPVCC(11,0,0,0)|(1<<21);	/* L=1 */
1309*fbadb1c4SDavid du Colombier 	case ACMPU:	return OPVCC(10,0,0,0)|(1<<21);
1310*fbadb1c4SDavid du Colombier 	case ACMPW:	return OPVCC(11,0,0,0);	/* L=0 */
1311*fbadb1c4SDavid du Colombier 	case ACMPWU:	return OPVCC(10,0,0,0);
1312*fbadb1c4SDavid du Colombier 	case ALSW:	return OPVCC(31,597,0,0);
1313*fbadb1c4SDavid du Colombier 
1314*fbadb1c4SDavid du Colombier 	case AMULLW:	return OPVCC(7,0,0,0);
1315*fbadb1c4SDavid du Colombier 
1316*fbadb1c4SDavid du Colombier 	case AOR:	return OPVCC(24,0,0,0);
1317*fbadb1c4SDavid du Colombier 	case AOR+AEND:	return OPVCC(25,0,0,0);		/* ORIS/ORIU */
1318*fbadb1c4SDavid du Colombier 
1319*fbadb1c4SDavid du Colombier 	case ARLWMI:	return OPVCC(20,0,0,0);		/* rlwimi */
1320*fbadb1c4SDavid du Colombier 	case ARLWMICC:	return OPVCC(20,0,0,1);
1321*fbadb1c4SDavid du Colombier 	case ARLDMI:	return OPVCC(30,0,0,0) | (3<<2);	/* rldimi */
1322*fbadb1c4SDavid du Colombier 	case ARLDMICC:	return OPVCC(30,0,0,1) | (3<<2);
1323*fbadb1c4SDavid du Colombier 
1324*fbadb1c4SDavid du Colombier 	case ARLWNM:	return OPVCC(21,0,0,0);		/* rlwinm */
1325*fbadb1c4SDavid du Colombier 	case ARLWNMCC:	return OPVCC(21,0,0,1);
1326*fbadb1c4SDavid du Colombier 
1327*fbadb1c4SDavid du Colombier 	case ARLDCL:	return OPVCC(30,0,0,0);		/* rldicl */
1328*fbadb1c4SDavid du Colombier 	case ARLDCLCC:	return OPVCC(30,0,0,1);
1329*fbadb1c4SDavid du Colombier 	case ARLDCR:	return OPVCC(30,1,0,0);		/* rldicr */
1330*fbadb1c4SDavid du Colombier 	case ARLDCRCC:	return OPVCC(30,1,0,1);
1331*fbadb1c4SDavid du Colombier 	case ARLDC:	return OPVCC(30,0,0,0) | (2<<2);
1332*fbadb1c4SDavid du Colombier 	case ARLDCCC:	return OPVCC(30,0,0,1) | (2<<2);
1333*fbadb1c4SDavid du Colombier 
1334*fbadb1c4SDavid du Colombier 	case ASRAW:	return OPVCC(31,824,0,0);
1335*fbadb1c4SDavid du Colombier 	case ASRAWCC:	return OPVCC(31,824,0,1);
1336*fbadb1c4SDavid du Colombier 	case ASRAD:	return OPVCC(31,(413<<1),0,0);
1337*fbadb1c4SDavid du Colombier 	case ASRADCC:	return OPVCC(31,(413<<1),0,1);
1338*fbadb1c4SDavid du Colombier 
1339*fbadb1c4SDavid du Colombier 	case ASTSW:	return OPVCC(31,725,0,0);
1340*fbadb1c4SDavid du Colombier 
1341*fbadb1c4SDavid du Colombier 	case ASUBC:	return OPVCC(8,0,0,0);
1342*fbadb1c4SDavid du Colombier 
1343*fbadb1c4SDavid du Colombier 	case ATW:	return OPVCC(3,0,0,0);
1344*fbadb1c4SDavid du Colombier 	case ATD:	return OPVCC(2,0,0,0);
1345*fbadb1c4SDavid du Colombier 
1346*fbadb1c4SDavid du Colombier 	case AXOR:	return OPVCC(26,0,0,0);		/* XORIL */
1347*fbadb1c4SDavid du Colombier 	case AXOR+AEND:	return OPVCC(27,0,0,0);		/* XORIU */
1348*fbadb1c4SDavid du Colombier 	}
1349*fbadb1c4SDavid du Colombier 	diag("bad opcode i/r %A", a);
1350*fbadb1c4SDavid du Colombier 	return 0;
1351*fbadb1c4SDavid du Colombier }
1352*fbadb1c4SDavid du Colombier 
1353*fbadb1c4SDavid du Colombier /*
1354*fbadb1c4SDavid du Colombier  * load o(a),d
1355*fbadb1c4SDavid du Colombier  */
1356*fbadb1c4SDavid du Colombier long
opload(int a)1357*fbadb1c4SDavid du Colombier opload(int a)
1358*fbadb1c4SDavid du Colombier {
1359*fbadb1c4SDavid du Colombier 	switch(a) {
1360*fbadb1c4SDavid du Colombier 	case AMOVD:	return OPVCC(58,0,0,0);	/* ld */
1361*fbadb1c4SDavid du Colombier 	case AMOVDU:	return OPVCC(58,0,0,1);	/* ldu */
1362*fbadb1c4SDavid du Colombier 	case AMOVWZ:	return OPVCC(32,0,0,0);		/* lwz */
1363*fbadb1c4SDavid du Colombier 	case AMOVWZU:	return OPVCC(33,0,0,0);		/* lwzu */
1364*fbadb1c4SDavid du Colombier 	case AMOVW:		return OPVCC(58,0,0,0)|(1<<1);	/* lwa */
1365*fbadb1c4SDavid du Colombier 	/* no AMOVWU */
1366*fbadb1c4SDavid du Colombier 	case AMOVB:
1367*fbadb1c4SDavid du Colombier 	case AMOVBZ:	return OPVCC(34,0,0,0);		/* load */
1368*fbadb1c4SDavid du Colombier 	case AMOVBU:
1369*fbadb1c4SDavid du Colombier 	case AMOVBZU:	return OPVCC(35,0,0,0);
1370*fbadb1c4SDavid du Colombier 	case AFMOVD:	return OPVCC(50,0,0,0);
1371*fbadb1c4SDavid du Colombier 	case AFMOVDU:	return OPVCC(51,0,0,0);
1372*fbadb1c4SDavid du Colombier 	case AFMOVS:	return OPVCC(48,0,0,0);
1373*fbadb1c4SDavid du Colombier 	case AFMOVSU:	return OPVCC(49,0,0,0);
1374*fbadb1c4SDavid du Colombier 	case AMOVH:	return OPVCC(42,0,0,0);
1375*fbadb1c4SDavid du Colombier 	case AMOVHU:	return OPVCC(43,0,0,0);
1376*fbadb1c4SDavid du Colombier 	case AMOVHZ:	return OPVCC(40,0,0,0);
1377*fbadb1c4SDavid du Colombier 	case AMOVHZU:	return OPVCC(41,0,0,0);
1378*fbadb1c4SDavid du Colombier 	case AMOVMW:	return OPVCC(46,0,0,0);	/* lmw */
1379*fbadb1c4SDavid du Colombier 	}
1380*fbadb1c4SDavid du Colombier 	diag("bad load opcode %A", a);
1381*fbadb1c4SDavid du Colombier 	return 0;
1382*fbadb1c4SDavid du Colombier }
1383*fbadb1c4SDavid du Colombier 
1384*fbadb1c4SDavid du Colombier /*
1385*fbadb1c4SDavid du Colombier  * indexed load a(b),d
1386*fbadb1c4SDavid du Colombier  */
1387*fbadb1c4SDavid du Colombier long
oploadx(int a)1388*fbadb1c4SDavid du Colombier oploadx(int a)
1389*fbadb1c4SDavid du Colombier {
1390*fbadb1c4SDavid du Colombier 	switch(a) {
1391*fbadb1c4SDavid du Colombier 	case AMOVWZ: return OPVCC(31,23,0,0);	/* lwzx */
1392*fbadb1c4SDavid du Colombier 	case AMOVWZU:	return OPVCC(31,55,0,0); /* lwzux */
1393*fbadb1c4SDavid du Colombier 	case AMOVW:	return OPVCC(31,341,0,0);	/* lwax */
1394*fbadb1c4SDavid du Colombier 	case AMOVWU:	return OPVCC(31,373,0,0);	/* lwaux */
1395*fbadb1c4SDavid du Colombier 	case AMOVB:
1396*fbadb1c4SDavid du Colombier 	case AMOVBZ: return OPVCC(31,87,0,0);	/* lbzx */
1397*fbadb1c4SDavid du Colombier 	case AMOVBU:
1398*fbadb1c4SDavid du Colombier 	case AMOVBZU: return OPVCC(31,119,0,0);	/* lbzux */
1399*fbadb1c4SDavid du Colombier 	case AFMOVD:	return OPVCC(31,599,0,0);	/* lfdx */
1400*fbadb1c4SDavid du Colombier 	case AFMOVDU:	return OPVCC(31,631,0,0);	/*  lfdux */
1401*fbadb1c4SDavid du Colombier 	case AFMOVS:	return OPVCC(31,535,0,0);	/* lfsx */
1402*fbadb1c4SDavid du Colombier 	case AFMOVSU:	return OPVCC(31,567,0,0);	/* lfsux */
1403*fbadb1c4SDavid du Colombier 	case AMOVH:	return OPVCC(31,343,0,0);	/* lhax */
1404*fbadb1c4SDavid du Colombier 	case AMOVHU:	return OPVCC(31,375,0,0);	/* lhaux */
1405*fbadb1c4SDavid du Colombier 	case AMOVHBR:	return OPVCC(31,790,0,0);	/* lhbrx */
1406*fbadb1c4SDavid du Colombier 	case AMOVWBR:	return OPVCC(31,534,0,0);	/* lwbrx */
1407*fbadb1c4SDavid du Colombier 	case AMOVHZ:	return OPVCC(31,279,0,0);	/* lhzx */
1408*fbadb1c4SDavid du Colombier 	case AMOVHZU:	return OPVCC(31,311,0,0);	/* lhzux */
1409*fbadb1c4SDavid du Colombier 	case AECIWX:	return OPVCC(31,310,0,0);	/* eciwx */
1410*fbadb1c4SDavid du Colombier 	case ALWAR:	return OPVCC(31,20,0,0);	/* lwarx */
1411*fbadb1c4SDavid du Colombier 	case ALSW:	return OPVCC(31,533,0,0);	/* lswx */
1412*fbadb1c4SDavid du Colombier 	case AMOVD:	return OPVCC(31,21,0,0);	/* ldx */
1413*fbadb1c4SDavid du Colombier 	case AMOVDU:	return OPVCC(31,53,0,0);	/* ldux */
1414*fbadb1c4SDavid du Colombier 	}
1415*fbadb1c4SDavid du Colombier 	diag("bad loadx opcode %A", a);
1416*fbadb1c4SDavid du Colombier 	return 0;
1417*fbadb1c4SDavid du Colombier }
1418*fbadb1c4SDavid du Colombier 
1419*fbadb1c4SDavid du Colombier /*
1420*fbadb1c4SDavid du Colombier  * store s,o(d)
1421*fbadb1c4SDavid du Colombier  */
1422*fbadb1c4SDavid du Colombier long
opstore(int a)1423*fbadb1c4SDavid du Colombier opstore(int a)
1424*fbadb1c4SDavid du Colombier {
1425*fbadb1c4SDavid du Colombier 	switch(a) {
1426*fbadb1c4SDavid du Colombier 	case AMOVB:
1427*fbadb1c4SDavid du Colombier 	case AMOVBZ:	return OPVCC(38,0,0,0);	/* stb */
1428*fbadb1c4SDavid du Colombier 	case AMOVBU:
1429*fbadb1c4SDavid du Colombier 	case AMOVBZU:	return OPVCC(39,0,0,0);	/* stbu */
1430*fbadb1c4SDavid du Colombier 	case AFMOVD:	return OPVCC(54,0,0,0);	/* stfd */
1431*fbadb1c4SDavid du Colombier 	case AFMOVDU:	return OPVCC(55,0,0,0);	/* stfdu */
1432*fbadb1c4SDavid du Colombier 	case AFMOVS:	return OPVCC(52,0,0,0);	/* stfs */
1433*fbadb1c4SDavid du Colombier 	case AFMOVSU:	return OPVCC(53,0,0,0);	/* stfsu */
1434*fbadb1c4SDavid du Colombier 	case AMOVHZ:
1435*fbadb1c4SDavid du Colombier 	case AMOVH:	return OPVCC(44,0,0,0);	/* sth */
1436*fbadb1c4SDavid du Colombier 	case AMOVHZU:
1437*fbadb1c4SDavid du Colombier 	case AMOVHU:	return OPVCC(45,0,0,0);	/* sthu */
1438*fbadb1c4SDavid du Colombier 	case AMOVMW:	return OPVCC(47,0,0,0);	/* stmw */
1439*fbadb1c4SDavid du Colombier 	case ASTSW:	return OPVCC(31,725,0,0);	/* stswi */
1440*fbadb1c4SDavid du Colombier 	case AMOVWZ:
1441*fbadb1c4SDavid du Colombier 	case AMOVW:	return OPVCC(36,0,0,0);	/* stw */
1442*fbadb1c4SDavid du Colombier 	case AMOVWZU:
1443*fbadb1c4SDavid du Colombier 	case AMOVWU:	return OPVCC(37,0,0,0);	/* stwu */
1444*fbadb1c4SDavid du Colombier 	case AMOVD:	return OPVCC(62,0,0,0);	/* std */
1445*fbadb1c4SDavid du Colombier 	case AMOVDU:	return OPVCC(62,0,0,1);	/* stdu */
1446*fbadb1c4SDavid du Colombier 	}
1447*fbadb1c4SDavid du Colombier 	diag("unknown store opcode %A", a);
1448*fbadb1c4SDavid du Colombier 	return 0;
1449*fbadb1c4SDavid du Colombier }
1450*fbadb1c4SDavid du Colombier 
1451*fbadb1c4SDavid du Colombier /*
1452*fbadb1c4SDavid du Colombier  * indexed store s,a(b)
1453*fbadb1c4SDavid du Colombier  */
1454*fbadb1c4SDavid du Colombier long
opstorex(int a)1455*fbadb1c4SDavid du Colombier opstorex(int a)
1456*fbadb1c4SDavid du Colombier {
1457*fbadb1c4SDavid du Colombier 	switch(a) {
1458*fbadb1c4SDavid du Colombier 	case AMOVB:
1459*fbadb1c4SDavid du Colombier 	case AMOVBZ:	return OPVCC(31,215,0,0);	/* stbx */
1460*fbadb1c4SDavid du Colombier 	case AMOVBU:
1461*fbadb1c4SDavid du Colombier 	case AMOVBZU:	return OPVCC(31,247,0,0);	/* stbux */
1462*fbadb1c4SDavid du Colombier 	case AFMOVD:	return OPVCC(31,727,0,0);	/* stfdx */
1463*fbadb1c4SDavid du Colombier 	case AFMOVDU:	return OPVCC(31,759,0,0);	/* stfdux */
1464*fbadb1c4SDavid du Colombier 	case AFMOVS:	return OPVCC(31,663,0,0);	/* stfsx */
1465*fbadb1c4SDavid du Colombier 	case AFMOVSU:	return OPVCC(31,695,0,0);	/* stfsux */
1466*fbadb1c4SDavid du Colombier 	case AMOVHZ:
1467*fbadb1c4SDavid du Colombier 	case AMOVH:	return OPVCC(31,407,0,0);	/* sthx */
1468*fbadb1c4SDavid du Colombier 	case AMOVHBR:	return OPVCC(31,918,0,0);	/* sthbrx */
1469*fbadb1c4SDavid du Colombier 	case AMOVHZU:
1470*fbadb1c4SDavid du Colombier 	case AMOVHU:	return OPVCC(31,439,0,0);	/* sthux */
1471*fbadb1c4SDavid du Colombier 	case AMOVWZ:
1472*fbadb1c4SDavid du Colombier 	case AMOVW:	return OPVCC(31,151,0,0);	/* stwx */
1473*fbadb1c4SDavid du Colombier 	case AMOVWZU:
1474*fbadb1c4SDavid du Colombier 	case AMOVWU:	return OPVCC(31,183,0,0);	/* stwux */
1475*fbadb1c4SDavid du Colombier 	case ASTSW:	return OPVCC(31,661,0,0);	/* stswx */
1476*fbadb1c4SDavid du Colombier 	case AMOVWBR:	return OPVCC(31,662,0,0);	/* stwbrx */
1477*fbadb1c4SDavid du Colombier 	case ASTWCCC:	return OPVCC(31,150,0,1);	/* stwcx. */
1478*fbadb1c4SDavid du Colombier 	case ASTDCCC:	return OPVCC(31,214,0,1);	/* stwdx. */
1479*fbadb1c4SDavid du Colombier 	case AECOWX:	return OPVCC(31,438,0,0);	/* ecowx */
1480*fbadb1c4SDavid du Colombier 	case AMOVD:	return OPVCC(31,149,0,0);	/* stdx */
1481*fbadb1c4SDavid du Colombier 	case AMOVDU:	return OPVCC(31,181,0,0);	/* stdux */
1482*fbadb1c4SDavid du Colombier 	}
1483*fbadb1c4SDavid du Colombier 	diag("unknown storex opcode %A", a);
1484*fbadb1c4SDavid du Colombier 	return 0;
1485*fbadb1c4SDavid du Colombier }
1486