xref: /inferno-os/utils/ql/asmout.c (revision 2b69dba5038ffd0b59cf30a4c44bce549e5097f8)
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  				if(p->to.reg != NREG) {
677  					o1 = OPVCC(31,387,0,0);	/* mtdcrx */
678  					v = p->to.reg;
679  				}else
680  					o1 = OPVCC(31,451,0,0);	/* mtdcr */
681  			}else
682  				o1 = OPVCC(31,467,0,0); /* mtspr */
683  		} else {
684  			r = p->to.reg;
685  			v = p->from.offset;
686  			if(p->from.type == D_DCR) {
687  				if(p->from.reg != NREG) {
688  					o1 = OPVCC(31,259,0,0);	/* mfdcrx */
689  					v = p->from.reg;
690  				}else
691  					o1 = OPVCC(31,323,0,0);	/* mfdcr */
692  			}else
693  				o1 = OPVCC(31,339,0,0);	/* mfspr */
694  		}
695  		o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
696  		break;
697  
698  	case 67:	/* mcrf crfD,crfS */
699  		if(p->from.type != D_CREG || p->from.reg == NREG ||
700  		   p->to.type != D_CREG || p->to.reg == NREG)
701  			diag("illegal CR field number\n%P", p);
702  		o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
703  		break;
704  
705  	case 68:	/* mfcr rD */
706  		if(p->from.type == D_CREG && p->from.reg != NREG)
707  			diag("must move whole CR to register\n%P", p);
708  		o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0);
709  		break;
710  
711  	case 69:	/* mtcrf CRM,rS */
712  		if(p->from3.type != D_NONE) {
713  			if(p->to.reg != NREG)
714  				diag("can't use both mask and CR(n)\n%P", p);
715  			v = regoff(&p->from3) & 0xff;
716  		} else {
717  			if(p->to.reg == NREG)
718  				v = 0xff;	/* CR */
719  			else
720  				v = 1<<(7-(p->to.reg&7));	/* CR(n) */
721  		}
722  		o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
723  		break;
724  
725  	case 70:	/* [f]cmp r,r,cr*/
726  		if(p->reg == NREG)
727  			r = 0;
728  		else
729  			r = (p->reg&7)<<2;
730  		o1 = AOP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
731  		break;
732  
733  	case 71:	/* cmp[l] r,i,cr*/
734  		if(p->reg == NREG)
735  			r = 0;
736  		else
737  			r = (p->reg&7)<<2;
738  		o1 = AOP_RRR(opirr(p->as), r, p->from.reg, 0) | (regoff(&p->to)&0xffff);
739  		break;
740  
741  	case 72:	/* mcrxr crfD */
742  		if(p->to.reg == NREG)
743  			diag("must move XER to CR(n)\n%P", p);
744  		o1 = AOP_RRR(OP_MCRXR, ((p->to.reg&7L)<<2), 0, 0);
745  		break;
746  
747  	case 73:	/* mcrfs crfD,crfS */
748  		if(p->from.type != D_FPSCR || p->from.reg == NREG ||
749  		   p->to.type != D_CREG || p->to.reg == NREG)
750  			diag("illegal FPSCR/CR field number\n%P", p);
751  		o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
752  		break;
753  
754  	/* relocation operations */
755  
756  	case 74:
757  		v = regoff(&p->to);
758  		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
759  		o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
760  		if(dlm)
761  			reloc(&p->to, p->pc, 1);
762  		break;
763  
764  	case 75:
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  		if(dlm)
769  			reloc(&p->from, p->pc, 1);
770  		break;
771  
772  	case 76:
773  		v = regoff(&p->from);
774  		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
775  		o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
776  		o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
777  		if(dlm)
778  			reloc(&p->from, p->pc, 1);
779  		break;
780  
781  	}
782  	if(aflag)
783  		return o1;
784  	v = p->pc;
785  	switch(o->size) {
786  	default:
787  		if(debug['a'])
788  			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
789  		break;
790  	case 4:
791  		if(debug['a'])
792  			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
793  		lput(o1);
794  		break;
795  	case 8:
796  		if(debug['a'])
797  			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
798  		lput(o1);
799  		lput(o2);
800  		break;
801  	case 12:
802  		if(debug['a'])
803  			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
804  		lput(o1);
805  		lput(o2);
806  		lput(o3);
807  		break;
808  	case 16:
809  		if(debug['a'])
810  			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
811  				v, o1, o2, o3, o4, p);
812  		lput(o1);
813  		lput(o2);
814  		lput(o3);
815  		lput(o4);
816  		break;
817  	case 20:
818  		if(debug['a'])
819  			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
820  				v, o1, o2, o3, o4, o5, p);
821  		lput(o1);
822  		lput(o2);
823  		lput(o3);
824  		lput(o4);
825  		lput(o5);
826  		break;
827  	}
828  	return 0;
829  }
830  
831  long
832  oprrr(int a)
833  {
834  	switch(a) {
835  	case AADD:	return OPVCC(31,266,0,0);
836  	case AADDCC:	return OPVCC(31,266,0,1);
837  	case AADDV:	return OPVCC(31,266,1,0);
838  	case AADDVCC:	return OPVCC(31,266,1,1);
839  	case AADDC:	return OPVCC(31,10,0,0);
840  	case AADDCCC:	return OPVCC(31,10,0,1);
841  	case AADDCV:	return OPVCC(31,10,1,0);
842  	case AADDCVCC:	return OPVCC(31,10,1,1);
843  	case AADDE:	return OPVCC(31,138,0,0);
844  	case AADDECC:	return OPVCC(31,138,0,1);
845  	case AADDEV:	return OPVCC(31,138,1,0);
846  	case AADDEVCC:	return OPVCC(31,138,1,1);
847  	case AADDME:	return OPVCC(31,234,0,0);
848  	case AADDMECC:	return OPVCC(31,234,0,1);
849  	case AADDMEV:	return OPVCC(31,234,1,0);
850  	case AADDMEVCC:	return OPVCC(31,234,1,1);
851  	case AADDZE:	return OPVCC(31,202,0,0);
852  	case AADDZECC:	return OPVCC(31,202,0,1);
853  	case AADDZEV:	return OPVCC(31,202,1,0);
854  	case AADDZEVCC:	return OPVCC(31,202,1,1);
855  
856  	case AAND:	return OPVCC(31,28,0,0);
857  	case AANDCC:	return OPVCC(31,28,0,1);
858  	case AANDN:	return OPVCC(31,60,0,0);
859  	case AANDNCC:	return OPVCC(31,60,0,1);
860  
861  	case ACMP:	return OPVCC(31,0,0,0);
862  	case ACMPU:	return OPVCC(31,32,0,0);
863  
864  	case ACNTLZW:	return OPVCC(31,26,0,0);
865  	case ACNTLZWCC:	return OPVCC(31,26,0,1);
866  
867  	case ACRAND:	return OPVCC(19,257,0,0);
868  	case ACRANDN:	return OPVCC(19,129,0,0);
869  	case ACREQV:	return OPVCC(19,289,0,0);
870  	case ACRNAND:	return OPVCC(19,225,0,0);
871  	case ACRNOR:	return OPVCC(19,33,0,0);
872  	case ACROR:	return OPVCC(19,449,0,0);
873  	case ACRORN:	return OPVCC(19,417,0,0);
874  	case ACRXOR:	return OPVCC(19,193,0,0);
875  
876  	case ADCBF:	return OPVCC(31,86,0,0);
877  	case ADCBI:	return OPVCC(31,470,0,0);
878  	case ADCBST:	return OPVCC(31,54,0,0);
879  	case ADCBT:	return OPVCC(31,278,0,0);
880  	case ADCBTST:	return OPVCC(31,246,0,0);
881  	case ADCBZ:	return OPVCC(31,1014,0,0);
882  
883  	case AREM:
884  	case ADIVW:	return OPVCC(31,491,0,0);
885  	case AREMCC:
886  	case ADIVWCC:	return OPVCC(31,491,0,1);
887  	case AREMV:
888  	case ADIVWV:	return OPVCC(31,491,1,0);
889  	case AREMVCC:
890  	case ADIVWVCC:	return OPVCC(31,491,1,1);
891  	case AREMU:
892  	case ADIVWU:	return OPVCC(31,459,0,0);
893  	case AREMUCC:
894  	case ADIVWUCC:	return OPVCC(31,459,0,1);
895  	case AREMUV:
896  	case ADIVWUV:	return OPVCC(31,459,1,0);
897  	case AREMUVCC:
898  	case ADIVWUVCC:	return OPVCC(31,459,1,1);
899  
900  	case AEIEIO:	return OPVCC(31,854,0,0);
901  
902  	case AEQV:	return OPVCC(31,284,0,0);
903  	case AEQVCC:	return OPVCC(31,284,0,1);
904  
905  	case AEXTSB:	return OPVCC(31,954,0,0);
906  	case AEXTSBCC:	return OPVCC(31,954,0,1);
907  	case AEXTSH:	return OPVCC(31,922,0,0);
908  	case AEXTSHCC:	return OPVCC(31,922,0,1);
909  
910  	case AFABS:	return OPVCC(63,264,0,0);
911  	case AFABSCC:	return OPVCC(63,264,0,1);
912  	case AFADD:	return OPVCC(63,21,0,0);
913  	case AFADDCC:	return OPVCC(63,21,0,1);
914  	case AFADDS:	return OPVCC(59,21,0,0);
915  	case AFADDSCC:	return OPVCC(59,21,0,1);
916  	case AFCMPO:	return OPVCC(63,32,0,0);
917  	case AFCMPU:	return OPVCC(63,0,0,0);
918  	case AFCTIW:	return OPVCC(63,14,0,0);
919  	case AFCTIWCC:	return OPVCC(63,14,0,1);
920  	case AFCTIWZ:	return OPVCC(63,15,0,0);
921  	case AFCTIWZCC:	return OPVCC(63,15,0,1);
922  	case AFDIV:	return OPVCC(63,18,0,0);
923  	case AFDIVCC:	return OPVCC(63,18,0,1);
924  	case AFDIVS:	return OPVCC(59,18,0,0);
925  	case AFDIVSCC:	return OPVCC(59,18,0,1);
926  	case AFMADD:	return OPVCC(63,29,0,0);
927  	case AFMADDCC:	return OPVCC(63,29,0,1);
928  	case AFMADDS:	return OPVCC(59,29,0,0);
929  	case AFMADDSCC:	return OPVCC(59,29,0,1);
930  	case AFMOVS:
931  	case AFMOVD:	return OPVCC(63,72,0,0);	/* load */
932  	case AFMOVDCC:	return OPVCC(63,72,0,1);
933  	case AFMSUB:	return OPVCC(63,28,0,0);
934  	case AFMSUBCC:	return OPVCC(63,28,0,1);
935  	case AFMSUBS:	return OPVCC(59,28,0,0);
936  	case AFMSUBSCC:	return OPVCC(59,28,0,1);
937  	case AFMUL:	return OPVCC(63,25,0,0);
938  	case AFMULCC:	return OPVCC(63,25,0,1);
939  	case AFMULS:	return OPVCC(59,25,0,0);
940  	case AFMULSCC:	return OPVCC(59,25,0,1);
941  	case AFNABS:	return OPVCC(63,136,0,0);
942  	case AFNABSCC:	return OPVCC(63,136,0,1);
943  	case AFNEG:	return OPVCC(63,40,0,0);
944  	case AFNEGCC:	return OPVCC(63,40,0,1);
945  	case AFNMADD:	return OPVCC(63,31,0,0);
946  	case AFNMADDCC:	return OPVCC(63,31,0,1);
947  	case AFNMADDS:	return OPVCC(59,31,0,0);
948  	case AFNMADDSCC:	return OPVCC(59,31,0,1);
949  	case AFNMSUB:	return OPVCC(63,30,0,0);
950  	case AFNMSUBCC:	return OPVCC(63,30,0,1);
951  	case AFNMSUBS:	return OPVCC(59,30,0,0);
952  	case AFNMSUBSCC:	return OPVCC(59,30,0,1);
953  	case AFRES:	return OPVCC(59,24,0,0);
954  	case AFRESCC:	return OPVCC(59,24,0,1);
955  	case AFRSP:	return OPVCC(63,12,0,0);
956  	case AFRSPCC:	return OPVCC(63,12,0,1);
957  	case AFRSQRTE:	return OPVCC(63,26,0,0);
958  	case AFRSQRTECC:	return OPVCC(63,26,0,1);
959  	case AFSEL:	return OPVCC(63,23,0,0);
960  	case AFSELCC:	return OPVCC(63,23,0,1);
961  	case AFSQRT:	return OPVCC(63,22,0,0);
962  	case AFSQRTCC:	return OPVCC(63,22,0,1);
963  	case AFSQRTS:	return OPVCC(59,22,0,0);
964  	case AFSQRTSCC:	return OPVCC(59,22,0,1);
965  	case AFSUB:	return OPVCC(63,20,0,0);
966  	case AFSUBCC:	return OPVCC(63,20,0,1);
967  	case AFSUBS:	return OPVCC(59,20,0,0);
968  	case AFSUBSCC:	return OPVCC(59,20,0,1);
969  
970  	/* fp2 */
971  	case AFPMUL:	return OPVCC(0,8,0,0);
972  	case AFXMUL:	return OPVCC(0,9,0,0);
973  	case AFXPMUL:	return OPVCC(0,10,0,0);
974  	case AFXSMUL:	return OPVCC(0,11,0,0);
975  	case AFPADD:	return OPVCC(0,12,0,0);
976  	case AFPSUB:	return OPVCC(0,13,0,0);
977  	case AFPRE:	return OPVCC(0,14,0,0);
978  	case AFPRSQRTE:	return OPVCC(0,15,0,0);
979  	case AFPMADD:	return OPVCC(0,16,0,0);
980  	case AFXMADD:	return OPVCC(0,17,0,0);
981  	case AFXCPMADD:	return OPVCC(0,18,0,0);
982  	case AFXCSMADD:	return OPVCC(0,19,0,0);
983  	case AFPNMADD:	return OPVCC(0,20,0,0);
984  	case AFXNMADD:	return OPVCC(0,21,0,0);
985  	case AFXCPNMADD:	return OPVCC(0,22,0,0);
986  	case AFXCSNMADD:	return OPVCC(0,23,0,0);
987  	case AFPMSUB:	return OPVCC(0,24,0,0);
988  	case AFXMSUB:	return OPVCC(0,25,0,0);
989  	case AFXCPMSUB:	return OPVCC(0,26,0,0);
990  	case AFXCSMSUB:	return OPVCC(0,27,0,0);
991  	case AFPNMSUB:	return OPVCC(0,28,0,0);
992  	case AFXNMSUB:	return OPVCC(0,29,0,0);
993  	case AFXCPNMSUB:	return OPVCC(0,30,0,0);
994  	case AFXCSNMSUB:	return OPVCC(0,31,0,0);
995  	case AFPABS:	return OPVCC(0,96,0,0);
996  	case AFPNEG:	return OPVCC(0,160,0,0);
997  	case AFPRSP:	return OPVCC(0,192,0,0);
998  	case AFPNABS:	return OPVCC(0,224,0,0);
999  	case AFSCMP:	return OPVCC(0,320,0,0)|(3<<21);
1000  	case AFSABS:	return OPVCC(0,352,0,0);
1001  	case AFSNEG:	return OPVCC(0,416,0,0);
1002  	case AFSNABS:	return OPVCC(0,480,0,0);
1003  	case AFPCTIW:	return OPVCC(0,576,0,0);
1004  	case AFPCTIWZ:	return OPVCC(0,704,0,0);
1005  
1006  	case AFPMOVD:	return OPVCC(0,32,0,0);	/* fpmr */
1007  	case AFSMOVD:	return OPVCC(0,288,0,0);	/* fsmr */
1008  	case AFXMOVD:	return OPVCC(0,544,0,0);	/* fxmr */
1009  	case AFMOVSPD:		return OPVCC(0,800,0,0);	/* fsmtp */
1010  	case AFMOVPSD:		return OPVCC(0,928,0,0);	/* fsmfp */
1011  
1012  	case AFXCPNPMA:	return OPVCC(4,24,0,0);
1013  	case AFXCSNPMA:	return OPVCC(4,25,0,0);
1014  	case AFXCPNSMA:	return OPVCC(4,26,0,0);
1015  	case AFXCSNSMA:	return OPVCC(4,27,0,0);
1016  	case AFXCXNPMA:	return OPVCC(4,29,0,0);
1017  	case AFXCXNSMA:	return OPVCC(4,30,0,0);
1018  	case AFXCXMA:	return OPVCC(4,28,0,0);
1019  	case AFXCXNMS:	return OPVCC(4,31,0,0);
1020  
1021  	case AICBI:	return OPVCC(31,982,0,0);
1022  	case AISYNC:	return OPVCC(19,150,0,0);
1023  
1024  	case AMTFSB0:	return OPVCC(63,70,0,0);
1025  	case AMTFSB0CC:	return OPVCC(63,70,0,1);
1026  	case AMTFSB1:	return OPVCC(63,38,0,0);
1027  	case AMTFSB1CC:	return OPVCC(63,38,0,1);
1028  
1029  	case AMULHW:	return OPVCC(31,75,0,0);
1030  	case AMULHWCC:	return OPVCC(31,75,0,1);
1031  	case AMULHWU:	return OPVCC(31,11,0,0);
1032  	case AMULHWUCC:	return OPVCC(31,11,0,1);
1033  	case AMULLW:	return OPVCC(31,235,0,0);
1034  	case AMULLWCC:	return OPVCC(31,235,0,1);
1035  	case AMULLWV:	return OPVCC(31,235,1,0);
1036  	case AMULLWVCC:	return OPVCC(31,235,1,1);
1037  
1038  	/* the following group is only available on IBM embedded powerpc */
1039  	case AMACCHW:	return OPVCC(4,172,0,0);
1040  	case AMACCHWCC:	return OPVCC(4,172,0,1);
1041  	case AMACCHWS:	return OPVCC(4,236,0,0);
1042  	case AMACCHWSCC:	return OPVCC(4,236,0,1);
1043  	case AMACCHWSU:	return OPVCC(4,204,0,0);
1044  	case AMACCHWSUCC:	return OPVCC(4,204,0,1);
1045  	case AMACCHWSUV:	return OPVCC(4,204,1,0);
1046  	case AMACCHWSUVCC:	return OPVCC(4,204,1,1);
1047  	case AMACCHWSV:	return OPVCC(4,236,1,0);
1048  	case AMACCHWSVCC:	return OPVCC(4,236,1,1);
1049  	case AMACCHWU:	return OPVCC(4,140,0,0);
1050  	case AMACCHWUCC:	return OPVCC(4,140,0,1);
1051  	case AMACCHWUV:	return OPVCC(4,140,1,0);
1052  	case AMACCHWUVCC:	return OPVCC(4,140,1,1);
1053  	case AMACCHWV:	return OPVCC(4,172,1,0);
1054  	case AMACCHWVCC:	return OPVCC(4,172,1,1);
1055  	case AMACHHW:	return OPVCC(4,44,0,0);
1056  	case AMACHHWCC:	return OPVCC(4,44,0,1);
1057  	case AMACHHWS:	return OPVCC(4,108,0,0);
1058  	case AMACHHWSCC:	return OPVCC(4,108,0,1);
1059  	case AMACHHWSU:	return OPVCC(4,76,0,0);
1060  	case AMACHHWSUCC:	return OPVCC(4,76,0,1);
1061  	case AMACHHWSUV:	return OPVCC(4,76,1,0);
1062  	case AMACHHWSUVCC:	return OPVCC(4,76,1,1);
1063  	case AMACHHWSV:	return OPVCC(4,108,1,0);
1064  	case AMACHHWSVCC:	return OPVCC(4,108,1,1);
1065  	case AMACHHWU:	return OPVCC(4,12,0,0);
1066  	case AMACHHWUCC:	return OPVCC(4,12,0,1);
1067  	case AMACHHWUV:	return OPVCC(4,12,1,0);
1068  	case AMACHHWUVCC:	return OPVCC(4,12,1,1);
1069  	case AMACHHWV:	return OPVCC(4,44,1,0);
1070  	case AMACHHWVCC:	return OPVCC(4,44,1,1);
1071  	case AMACLHW:	return OPVCC(4,428,0,0);
1072  	case AMACLHWCC:	return OPVCC(4,428,0,1);
1073  	case AMACLHWS:	return OPVCC(4,492,0,0);
1074  	case AMACLHWSCC:	return OPVCC(4,492,0,1);
1075  	case AMACLHWSU:	return OPVCC(4,460,0,0);
1076  	case AMACLHWSUCC:	return OPVCC(4,460,0,1);
1077  	case AMACLHWSUV:	return OPVCC(4,460,1,0);
1078  	case AMACLHWSUVCC:	return OPVCC(4,460,1,1);
1079  	case AMACLHWSV:	return OPVCC(4,492,1,0);
1080  	case AMACLHWSVCC:	return OPVCC(4,492,1,1);
1081  	case AMACLHWU:	return OPVCC(4,396,0,0);
1082  	case AMACLHWUCC:	return OPVCC(4,396,0,1);
1083  	case AMACLHWUV:	return OPVCC(4,396,1,0);
1084  	case AMACLHWUVCC:	return OPVCC(4,396,1,1);
1085  	case AMACLHWV:	return OPVCC(4,428,1,0);
1086  	case AMACLHWVCC:	return OPVCC(4,428,1,1);
1087  	case AMULCHW:	return OPVCC(4,168,0,0);
1088  	case AMULCHWCC:	return OPVCC(4,168,0,1);
1089  	case AMULCHWU:	return OPVCC(4,136,0,0);
1090  	case AMULCHWUCC:	return OPVCC(4,136,0,1);
1091  	case AMULHHW:	return OPVCC(4,40,0,0);
1092  	case AMULHHWCC:	return OPVCC(4,40,0,1);
1093  	case AMULHHWU:	return OPVCC(4,8,0,0);
1094  	case AMULHHWUCC:	return OPVCC(4,8,0,1);
1095  	case AMULLHW:	return OPVCC(4,424,0,0);
1096  	case AMULLHWCC:	return OPVCC(4,424,0,1);
1097  	case AMULLHWU:	return OPVCC(4,392,0,0);
1098  	case AMULLHWUCC:	return OPVCC(4,392,0,1);
1099  	case ANMACCHW:	return OPVCC(4,174,0,0);
1100  	case ANMACCHWCC:	return OPVCC(4,174,0,1);
1101  	case ANMACCHWS:	return OPVCC(4,238,0,0);
1102  	case ANMACCHWSCC:	return OPVCC(4,238,0,1);
1103  	case ANMACCHWSV:	return OPVCC(4,238,1,0);
1104  	case ANMACCHWSVCC:	return OPVCC(4,238,1,1);
1105  	case ANMACCHWV:	return OPVCC(4,174,1,0);
1106  	case ANMACCHWVCC:	return OPVCC(4,174,1,1);
1107  	case ANMACHHW:	return OPVCC(4,46,0,0);
1108  	case ANMACHHWCC:	return OPVCC(4,46,0,1);
1109  	case ANMACHHWS:	return OPVCC(4,110,0,0);
1110  	case ANMACHHWSCC:	return OPVCC(4,110,0,1);
1111  	case ANMACHHWSV:	return OPVCC(4,110,1,0);
1112  	case ANMACHHWSVCC:	return OPVCC(4,110,1,1);
1113  	case ANMACHHWV:	return OPVCC(4,46,1,0);
1114  	case ANMACHHWVCC:	return OPVCC(4,46,1,1);
1115  	case ANMACLHW:	return OPVCC(4,430,0,0);
1116  	case ANMACLHWCC:	return OPVCC(4,430,0,1);
1117  	case ANMACLHWS:	return OPVCC(4,494,0,0);
1118  	case ANMACLHWSCC:	return OPVCC(4,494,0,1);
1119  	case ANMACLHWSV:	return OPVCC(4,494,1,0);
1120  	case ANMACLHWSVCC:	return OPVCC(4,494,1,1);
1121  	case ANMACLHWV:	return OPVCC(4,430,1,0);
1122  	case ANMACLHWVCC:	return OPVCC(4,430,1,1);
1123  
1124  	case ANAND:	return OPVCC(31,476,0,0);
1125  	case ANANDCC:	return OPVCC(31,476,0,1);
1126  	case ANEG:	return OPVCC(31,104,0,0);
1127  	case ANEGCC:	return OPVCC(31,104,0,1);
1128  	case ANEGV:	return OPVCC(31,104,1,0);
1129  	case ANEGVCC:	return OPVCC(31,104,1,1);
1130  	case ANOR:	return OPVCC(31,124,0,0);
1131  	case ANORCC:	return OPVCC(31,124,0,1);
1132  	case AOR:	return OPVCC(31,444,0,0);
1133  	case AORCC:	return OPVCC(31,444,0,1);
1134  	case AORN:	return OPVCC(31,412,0,0);
1135  	case AORNCC:	return OPVCC(31,412,0,1);
1136  
1137  	case ARFI:	return OPVCC(19,50,0,0);
1138  	case ARFCI:	return OPVCC(19,51,0,0);
1139  
1140  	case ARLWMI:	return OPVCC(20,0,0,0);
1141  	case ARLWMICC: return OPVCC(20,0,0,1);
1142  	case ARLWNM:	return OPVCC(23,0,0,0);
1143  	case ARLWNMCC:	return OPVCC(23,0,0,1);
1144  
1145  	case ASYSCALL:	return OPVCC(17,1,0,0);
1146  
1147  	case ASLW:	return OPVCC(31,24,0,0);
1148  	case ASLWCC:	return OPVCC(31,24,0,1);
1149  
1150  	case ASRAW:	return OPVCC(31,792,0,0);
1151  	case ASRAWCC:	return OPVCC(31,792,0,1);
1152  
1153  	case ASRW:	return OPVCC(31,536,0,0);
1154  	case ASRWCC:	return OPVCC(31,536,0,1);
1155  
1156  	case ASUB:	return OPVCC(31,40,0,0);
1157  	case ASUBCC:	return OPVCC(31,40,0,1);
1158  	case ASUBV:	return OPVCC(31,40,1,0);
1159  	case ASUBVCC:	return OPVCC(31,40,1,1);
1160  	case ASUBC:	return OPVCC(31,8,0,0);
1161  	case ASUBCCC:	return OPVCC(31,8,0,1);
1162  	case ASUBCV:	return OPVCC(31,8,1,0);
1163  	case ASUBCVCC:	return OPVCC(31,8,1,1);
1164  	case ASUBE:	return OPVCC(31,136,0,0);
1165  	case ASUBECC:	return OPVCC(31,136,0,1);
1166  	case ASUBEV:	return OPVCC(31,136,1,0);
1167  	case ASUBEVCC:	return OPVCC(31,136,1,1);
1168  	case ASUBME:	return OPVCC(31,232,0,0);
1169  	case ASUBMECC:	return OPVCC(31,232,0,1);
1170  	case ASUBMEV:	return OPVCC(31,232,1,0);
1171  	case ASUBMEVCC:	return OPVCC(31,232,1,1);
1172  	case ASUBZE:	return OPVCC(31,200,0,0);
1173  	case ASUBZECC:	return OPVCC(31,200,0,1);
1174  	case ASUBZEV:	return OPVCC(31,200,1,0);
1175  	case ASUBZEVCC:	return OPVCC(31,200,1,1);
1176  
1177  	case ASYNC:	return OPVCC(31,598,0,0);
1178  	case ATLBIE:	return OPVCC(31,306,0,0);
1179  	case ATW:	return OPVCC(31,4,0,0);
1180  
1181  	case AXOR:	return OPVCC(31,316,0,0);
1182  	case AXORCC:	return OPVCC(31,316,0,1);
1183  	}
1184  	diag("bad r/r opcode %A", a);
1185  	return 0;
1186  }
1187  
1188  long
1189  opirr(int a)
1190  {
1191  	switch(a) {
1192  	case AADD:	return OPVCC(14,0,0,0);
1193  	case AADDC:	return OPVCC(12,0,0,0);
1194  	case AADDCCC:	return OPVCC(13,0,0,0);
1195  	case AADD+AEND:	return OPVCC(15,0,0,0);		/* ADDIS/CAU */
1196  
1197  	case AANDCC:	return OPVCC(28,0,0,0);
1198  	case AANDCC+AEND:	return OPVCC(29,0,0,0);		/* ANDIS./ANDIU. */
1199  
1200  	case ABR:	return OPVCC(18,0,0,0);
1201  	case ABL:	return OPVCC(18,0,0,0) | 1;
1202  	case ABC:	return OPVCC(16,0,0,0);
1203  	case ABCL:	return OPVCC(16,0,0,0) | 1;
1204  
1205  	case ABEQ:	return AOP_RRR(16<<26,12,2,0);
1206  	case ABGE:	return AOP_RRR(16<<26,4,0,0);
1207  	case ABGT:	return AOP_RRR(16<<26,12,1,0);
1208  	case ABLE:	return AOP_RRR(16<<26,4,1,0);
1209  	case ABLT:	return AOP_RRR(16<<26,12,0,0);
1210  	case ABNE:	return AOP_RRR(16<<26,4,2,0);
1211  	case ABVC:	return AOP_RRR(16<<26,4,3,0);
1212  	case ABVS:	return AOP_RRR(16<<26,12,3,0);
1213  
1214  	case ACMP:	return OPVCC(11,0,0,0);
1215  	case ACMPU:	return OPVCC(10,0,0,0);
1216  	case ALSW:	return OPVCC(31,597,0,0);
1217  
1218  	case AMULLW:	return OPVCC(7,0,0,0);
1219  
1220  	case AOR:	return OPVCC(24,0,0,0);
1221  	case AOR+AEND:	return OPVCC(25,0,0,0);		/* ORIS/ORIU */
1222  
1223  	case ARLWMI:	return OPVCC(20,0,0,0);		/* rlwimi */
1224  	case ARLWMICC:	return OPVCC(20,0,0,1);
1225  
1226  	case ARLWNM:	return OPVCC(21,0,0,0);		/* rlwinm */
1227  	case ARLWNMCC:	return OPVCC(21,0,0,1);
1228  
1229  	case ASRAW:	return OPVCC(31,824,0,0);
1230  	case ASRAWCC:	return OPVCC(31,824,0,1);
1231  
1232  	case ASTSW:	return OPVCC(31,725,0,0);
1233  
1234  	case ASUBC:	return OPVCC(8,0,0,0);
1235  
1236  	case ATW:	return OPVCC(3,0,0,0);
1237  
1238  	case AXOR:	return OPVCC(26,0,0,0);		/* XORIL */
1239  	case AXOR+AEND:	return OPVCC(27,0,0,0);		/* XORIU */
1240  	}
1241  	diag("bad opcode i/r %A", a);
1242  	return 0;
1243  }
1244  
1245  /*
1246   * load o(a),d
1247   */
1248  long
1249  opload(int a)
1250  {
1251  	switch(a) {
1252  	case AMOVW:	return OPVCC(32,0,0,0);		/* lwz */
1253  	case AMOVWU:	return OPVCC(33,0,0,0);		/* lwzu */
1254  	case AMOVB:
1255  	case AMOVBZ:	return OPVCC(34,0,0,0);		/* load */
1256  	case AMOVBU:
1257  	case AMOVBZU:	return OPVCC(35,0,0,0);
1258  	case AFMOVD:	return OPVCC(50,0,0,0);
1259  	case AFMOVDU:	return OPVCC(51,0,0,0);
1260  	case AFMOVS:	return OPVCC(48,0,0,0);
1261  	case AFMOVSU:	return OPVCC(49,0,0,0);
1262  	case AMOVH:	return OPVCC(42,0,0,0);
1263  	case AMOVHU:	return OPVCC(43,0,0,0);
1264  	case AMOVHZ:	return OPVCC(40,0,0,0);
1265  	case AMOVHZU:	return OPVCC(41,0,0,0);
1266  	case AMOVMW:	return OPVCC(46,0,0,0);	/* lmw */
1267  	}
1268  	diag("bad load opcode %A", a);
1269  	return 0;
1270  }
1271  
1272  /*
1273   * indexed load a(b),d
1274   */
1275  long
1276  oploadx(int a)
1277  {
1278  	switch(a) {
1279  	case AMOVW: return OPVCC(31,23,0,0);	/* lwzx */
1280  	case AMOVWU:	return OPVCC(31,55,0,0); /* lwzux */
1281  	case AMOVB:
1282  	case AMOVBZ: return OPVCC(31,87,0,0);	/* lbzx */
1283  	case AMOVBU:
1284  	case AMOVBZU: return OPVCC(31,119,0,0);	/* lbzux */
1285  	case AFMOVD:	return OPVCC(31,599,0,0);	/* lfdx */
1286  	case AFMOVDU:	return OPVCC(31,631,0,0);	/*  lfdux */
1287  	case AFMOVS:	return OPVCC(31,535,0,0);	/* lfsx */
1288  	case AFMOVSU:	return OPVCC(31,567,0,0);	/* lfsux */
1289  	case AMOVH:	return OPVCC(31,343,0,0);	/* lhax */
1290  	case AMOVHU:	return OPVCC(31,375,0,0);	/* lhaux */
1291  	case AMOVHBR:	return OPVCC(31,790,0,0);	/* lhbrx */
1292  	case AMOVWBR:	return OPVCC(31,534,0,0);	/* lwbrx */
1293  	case AMOVHZ:	return OPVCC(31,279,0,0);	/* lhzx */
1294  	case AMOVHZU:	return OPVCC(31,311,0,0);	/* lhzux */
1295  	case AECIWX:	return OPVCC(31,310,0,0);	/* eciwx */
1296  	case ALWAR:	return OPVCC(31,20,0,0);	/* lwarx */
1297  	case ALSW:	return OPVCC(31,533,0,0);	/* lswx */
1298  	case AFSMOVS:	return OPVCC(31,142,0,0);	/* lfssx */
1299  	case AFSMOVSU:	return OPVCC(31,174,0,0);	/* lfssux */
1300  	case AFSMOVD:	return OPVCC(31,206,0,0);	/* lfsdx */
1301  	case AFSMOVDU:	return OPVCC(31,238,0,0);	/* lfsdux */
1302  	case AFXMOVS:	return OPVCC(31,270,0,0);	/* lfxsx */
1303  	case AFXMOVSU:	return OPVCC(31,302,0,0);	/* lfxsux */
1304  	case AFXMOVD:	return OPVCC(31,334,0,0);	/* lfxdx */
1305  	case AFXMOVDU:	return OPVCC(31,366,0,0);	/* lfxdux */
1306  	case AFPMOVS:	return OPVCC(31,398,0,0);	/* lfpsx */
1307  	case AFPMOVSU:	return OPVCC(31,430,0,0);	/* lfpsux */
1308  	case AFPMOVD:	return OPVCC(31,462,0,0);	/* lfpdx */
1309  	case AFPMOVDU:	return OPVCC(31,494,0,0);	/* lfpdux */
1310  	}
1311  	diag("bad loadx opcode %A", a);
1312  	return 0;
1313  }
1314  
1315  /*
1316   * store s,o(d)
1317   */
1318  long
1319  opstore(int a)
1320  {
1321  	switch(a) {
1322  	case AMOVB:
1323  	case AMOVBZ:	return OPVCC(38,0,0,0);	/* stb */
1324  	case AMOVBU:
1325  	case AMOVBZU:	return OPVCC(39,0,0,0);	/* stbu */
1326  	case AFMOVD:	return OPVCC(54,0,0,0);	/* stfd */
1327  	case AFMOVDU:	return OPVCC(55,0,0,0);	/* stfdu */
1328  	case AFMOVS:	return OPVCC(52,0,0,0);	/* stfs */
1329  	case AFMOVSU:	return OPVCC(53,0,0,0);	/* stfsu */
1330  	case AMOVHZ:
1331  	case AMOVH:	return OPVCC(44,0,0,0);	/* sth */
1332  	case AMOVHZU:
1333  	case AMOVHU:	return OPVCC(45,0,0,0);	/* sthu */
1334  	case AMOVMW:	return OPVCC(47,0,0,0);	/* stmw */
1335  	case ASTSW:	return OPVCC(31,725,0,0);	/* stswi */
1336  	case AMOVW:	return OPVCC(36,0,0,0);	/* stw */
1337  	case AMOVWU:	return OPVCC(37,0,0,0);	/* stwu */
1338  	}
1339  	diag("unknown store opcode %A", a);
1340  	return 0;
1341  }
1342  
1343  /*
1344   * indexed store s,a(b)
1345   */
1346  long
1347  opstorex(int a)
1348  {
1349  	switch(a) {
1350  	case AMOVB:
1351  	case AMOVBZ:	return OPVCC(31,215,0,0);	/* stbx */
1352  	case AMOVBU:
1353  	case AMOVBZU:	return OPVCC(31,247,0,0);	/* stbux */
1354  	case AFMOVD:	return OPVCC(31,727,0,0);	/* stfdx */
1355  	case AFMOVDU:	return OPVCC(31,759,0,0);	/* stfdux */
1356  	case AFMOVS:	return OPVCC(31,663,0,0);	/* stfsx */
1357  	case AFMOVSU:	return OPVCC(31,695,0,0);	/* stfsux */
1358  	case AMOVHZ:
1359  	case AMOVH:	return OPVCC(31,407,0,0);	/* sthx */
1360  	case AMOVHBR:	return OPVCC(31,918,0,0);	/* sthbrx */
1361  	case AMOVHZU:
1362  	case AMOVHU:	return OPVCC(31,439,0,0);	/* sthux */
1363  	case AMOVW:	return OPVCC(31,151,0,0);	/* stwx */
1364  	case AMOVWU:	return OPVCC(31,183,0,0);	/* stwux */
1365  	case ASTSW:	return OPVCC(31,661,0,0);	/* stswx */
1366  	case AMOVWBR:	return OPVCC(31,662,0,0);	/* stwbrx */
1367  	case ASTWCCC:	return OPVCC(31,150,0,1);	/* stwcx. */
1368  	case AECOWX:	return OPVCC(31,438,0,0);	/* ecowx */
1369  	case AFSMOVS:	return OPVCC(31,654,0,0);	/* stfssx */
1370  /*	case AFSMOVSU:	return OPVCC(31,yy,0,0); */	/* stfssux not known */
1371  /*	case AFSMOVD:	return OPVCC(31,yy,0,0); */ /* stfsdx not known */
1372  	case AFSMOVDU:	return OPVCC(31,750,0,0);	/* stfsdux */
1373  	case AFXMOVS:	return OPVCC(31,782,0,0);	/* stfxsx */
1374  	case AFXMOVSU:	return OPVCC(31,814,0,0);	/* stfxsux */
1375  	case AFXMOVD:	return OPVCC(31,846,0,0);	/* stfxdx */
1376  	case AFXMOVDU:	return OPVCC(31,878,0,0);	/* stfxdux */
1377  	case AFPMOVS:	return OPVCC(31,910,0,0);	/* stfpsx */
1378  	case AFPMOVSU:	return OPVCC(31,942,0,0);	/* stfpsux */
1379  	case AFPMOVD:	return OPVCC(31,974,0,0);	/* stfpdx */
1380  	case AFPMOVDU:	return OPVCC(31,1006,0,0);	/* stfpdux */
1381  	case AFPMOVIW:	return OPVCC(31,526,0,0);	/* stfpiwx */
1382  	}
1383  	diag("unknown storex opcode %A", a);
1384  	return 0;
1385  }
1386