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