Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}