174a4d8c2SCharles.Forsyth #include "l.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth #define OPVCC(o,xo,oe,rc) (((o)<<26)|((xo)<<1)|((oe)<<10)|((rc)&1))
474a4d8c2SCharles.Forsyth #define OPCC(o,xo,rc) OPVCC((o),(xo),0,(rc))
574a4d8c2SCharles.Forsyth #define OP(o,xo) OPVCC((o),(xo),0,0)
674a4d8c2SCharles.Forsyth
774a4d8c2SCharles.Forsyth /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
874a4d8c2SCharles.Forsyth #define AOP_RRR(op,d,a,b) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
974a4d8c2SCharles.Forsyth #define AOP_IRR(op,d,a,simm) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|((simm)&0xFFFF))
1074a4d8c2SCharles.Forsyth #define LOP_RRR(op,a,s,b) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
1174a4d8c2SCharles.Forsyth #define LOP_IRR(op,a,s,uimm) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|((uimm)&0xFFFF))
1274a4d8c2SCharles.Forsyth #define OP_BR(op,li,aa) ((op)|((li)&0x03FFFFFC)|((aa)<<1))
1374a4d8c2SCharles.Forsyth #define OP_BC(op,bo,bi,bd,aa) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16)|((bd)&0xFFFC)|((aa)<<1))
1474a4d8c2SCharles.Forsyth #define OP_BCR(op,bo,bi) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16))
1574a4d8c2SCharles.Forsyth #define OP_RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\
1674a4d8c2SCharles.Forsyth (((mb)&31L)<<6)|(((me)&31L)<<1))
1774a4d8c2SCharles.Forsyth
1874a4d8c2SCharles.Forsyth #define OP_ADD OPVCC(31,266,0,0)
1974a4d8c2SCharles.Forsyth #define OP_ADDI OPVCC(14,0,0,0)
2074a4d8c2SCharles.Forsyth #define OP_ADDIS OPVCC(15,0,0,0)
2174a4d8c2SCharles.Forsyth #define OP_ANDI OPVCC(28,0,0,0)
2274a4d8c2SCharles.Forsyth #define OP_EXTSB OPVCC(31,954,0,0)
2374a4d8c2SCharles.Forsyth #define OP_EXTSH OPVCC(31,922,0,0)
2474a4d8c2SCharles.Forsyth #define OP_MCRF OPVCC(19,0,0,0)
2574a4d8c2SCharles.Forsyth #define OP_MCRFS OPVCC(63,64,0,0)
2674a4d8c2SCharles.Forsyth #define OP_MCRXR OPVCC(31,512,0,0)
2774a4d8c2SCharles.Forsyth #define OP_MFCR OPVCC(31,19,0,0)
2874a4d8c2SCharles.Forsyth #define OP_MFFS OPVCC(63,583,0,0)
2974a4d8c2SCharles.Forsyth #define OP_MFMSR OPVCC(31,83,0,0)
3074a4d8c2SCharles.Forsyth #define OP_MFSPR OPVCC(31,339,0,0)
3174a4d8c2SCharles.Forsyth #define OP_MFSR OPVCC(31,595,0,0)
3274a4d8c2SCharles.Forsyth #define OP_MFSRIN OPVCC(31,659,0,0)
3374a4d8c2SCharles.Forsyth #define OP_MTCRF OPVCC(31,144,0,0)
3474a4d8c2SCharles.Forsyth #define OP_MTFSF OPVCC(63,711,0,0)
3574a4d8c2SCharles.Forsyth #define OP_MTFSFI OPVCC(63,134,0,0)
3674a4d8c2SCharles.Forsyth #define OP_MTMSR OPVCC(31,146,0,0)
3774a4d8c2SCharles.Forsyth #define OP_MTSPR OPVCC(31,467,0,0)
3874a4d8c2SCharles.Forsyth #define OP_MTSR OPVCC(31,210,0,0)
3974a4d8c2SCharles.Forsyth #define OP_MTSRIN OPVCC(31,242,0,0)
4074a4d8c2SCharles.Forsyth #define OP_MULLW OPVCC(31,235,0,0)
4174a4d8c2SCharles.Forsyth #define OP_OR OPVCC(31,444,0,0)
4274a4d8c2SCharles.Forsyth #define OP_ORI OPVCC(24,0,0,0)
4374a4d8c2SCharles.Forsyth #define OP_RLWINM OPVCC(21,0,0,0)
4474a4d8c2SCharles.Forsyth #define OP_SUBF OPVCC(31,40,0,0)
4574a4d8c2SCharles.Forsyth
4674a4d8c2SCharles.Forsyth #define oclass(v) ((v).class-1)
4774a4d8c2SCharles.Forsyth
4874a4d8c2SCharles.Forsyth long oprrr(int), opirr(int), opload(int), opstore(int), oploadx(int), opstorex(int);
4974a4d8c2SCharles.Forsyth
5074a4d8c2SCharles.Forsyth int
getmask(uchar * m,ulong v)5174a4d8c2SCharles.Forsyth getmask(uchar *m, ulong v)
5274a4d8c2SCharles.Forsyth {
5374a4d8c2SCharles.Forsyth int i;
5474a4d8c2SCharles.Forsyth
5574a4d8c2SCharles.Forsyth m[0] = m[1] = 0;
5674a4d8c2SCharles.Forsyth if(v != ~0L && v & (1<<31) && v & 1){ /* MB > ME */
5774a4d8c2SCharles.Forsyth if(getmask(m, ~v)){
5874a4d8c2SCharles.Forsyth i = m[0]; m[0] = m[1]+1; m[1] = i-1;
5974a4d8c2SCharles.Forsyth return 1;
6074a4d8c2SCharles.Forsyth }
6174a4d8c2SCharles.Forsyth return 0;
6274a4d8c2SCharles.Forsyth }
6374a4d8c2SCharles.Forsyth for(i=0; i<32; i++)
6474a4d8c2SCharles.Forsyth if(v & (1<<(31-i))){
6574a4d8c2SCharles.Forsyth m[0] = i;
6674a4d8c2SCharles.Forsyth do {
6774a4d8c2SCharles.Forsyth m[1] = i;
6874a4d8c2SCharles.Forsyth } while(++i<32 && (v & (1<<(31-i))) != 0);
6974a4d8c2SCharles.Forsyth for(; i<32; i++)
7074a4d8c2SCharles.Forsyth if(v & (1<<(31-i)))
7174a4d8c2SCharles.Forsyth return 0;
7274a4d8c2SCharles.Forsyth return 1;
7374a4d8c2SCharles.Forsyth }
7474a4d8c2SCharles.Forsyth return 0;
7574a4d8c2SCharles.Forsyth }
7674a4d8c2SCharles.Forsyth
7774a4d8c2SCharles.Forsyth void
maskgen(Prog * p,uchar * m,ulong v)7874a4d8c2SCharles.Forsyth maskgen(Prog *p, uchar *m, ulong v)
7974a4d8c2SCharles.Forsyth {
8074a4d8c2SCharles.Forsyth if(!getmask(m, v))
8174a4d8c2SCharles.Forsyth diag("cannot generate mask #%lux\n%P", v, p);
8274a4d8c2SCharles.Forsyth }
8374a4d8c2SCharles.Forsyth
8474a4d8c2SCharles.Forsyth static void
reloc(Adr * a,long pc,int sext)8574a4d8c2SCharles.Forsyth reloc(Adr *a, long pc, int sext)
8674a4d8c2SCharles.Forsyth {
8774a4d8c2SCharles.Forsyth if(a->name == D_EXTERN || a->name == D_STATIC)
8874a4d8c2SCharles.Forsyth dynreloc(a->sym, pc, 1, 1, sext);
8974a4d8c2SCharles.Forsyth }
9074a4d8c2SCharles.Forsyth
9174a4d8c2SCharles.Forsyth int
asmout(Prog * p,Optab * o,int aflag)9274a4d8c2SCharles.Forsyth asmout(Prog *p, Optab *o, int aflag)
9374a4d8c2SCharles.Forsyth {
9474a4d8c2SCharles.Forsyth long o1, o2, o3, o4, o5, v, t;
9574a4d8c2SCharles.Forsyth Prog *ct;
9674a4d8c2SCharles.Forsyth int r, a;
9774a4d8c2SCharles.Forsyth uchar mask[2];
9874a4d8c2SCharles.Forsyth
9974a4d8c2SCharles.Forsyth o1 = 0;
10074a4d8c2SCharles.Forsyth o2 = 0;
10174a4d8c2SCharles.Forsyth o3 = 0;
10274a4d8c2SCharles.Forsyth o4 = 0;
10374a4d8c2SCharles.Forsyth o5 = 0;
10474a4d8c2SCharles.Forsyth switch(o->type) {
10574a4d8c2SCharles.Forsyth default:
10674a4d8c2SCharles.Forsyth if(aflag)
10774a4d8c2SCharles.Forsyth return 0;
10874a4d8c2SCharles.Forsyth diag("unknown type %d", o->type);
10974a4d8c2SCharles.Forsyth if(!debug['a'])
11074a4d8c2SCharles.Forsyth prasm(p);
11174a4d8c2SCharles.Forsyth break;
11274a4d8c2SCharles.Forsyth
11374a4d8c2SCharles.Forsyth case 0: /* pseudo ops */
11474a4d8c2SCharles.Forsyth if(aflag) {
11574a4d8c2SCharles.Forsyth if(p->link) {
11674a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
11774a4d8c2SCharles.Forsyth ct = curtext;
11874a4d8c2SCharles.Forsyth o2 = autosize;
11974a4d8c2SCharles.Forsyth curtext = p;
12074a4d8c2SCharles.Forsyth autosize = p->to.offset + 4;
12174a4d8c2SCharles.Forsyth o1 = asmout(p->link, oplook(p->link), aflag);
12274a4d8c2SCharles.Forsyth curtext = ct;
12374a4d8c2SCharles.Forsyth autosize = o2;
12474a4d8c2SCharles.Forsyth } else
12574a4d8c2SCharles.Forsyth o1 = asmout(p->link, oplook(p->link), aflag);
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth return o1;
12874a4d8c2SCharles.Forsyth }
12974a4d8c2SCharles.Forsyth break;
13074a4d8c2SCharles.Forsyth
13174a4d8c2SCharles.Forsyth case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
13274a4d8c2SCharles.Forsyth if(p->to.reg == REGZERO && p->from.type == D_CONST) {
13374a4d8c2SCharles.Forsyth v = regoff(&p->from);
13474a4d8c2SCharles.Forsyth if(r0iszero && v != 0) {
13574a4d8c2SCharles.Forsyth nerrors--;
13674a4d8c2SCharles.Forsyth diag("literal operation on R0\n%P", p);
13774a4d8c2SCharles.Forsyth }
13874a4d8c2SCharles.Forsyth o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
13974a4d8c2SCharles.Forsyth break;
14074a4d8c2SCharles.Forsyth }
14174a4d8c2SCharles.Forsyth o1 = LOP_RRR(OP_OR, p->to.reg, p->from.reg, p->from.reg);
14274a4d8c2SCharles.Forsyth break;
14374a4d8c2SCharles.Forsyth
14474a4d8c2SCharles.Forsyth case 2: /* int/cr/fp op Rb,[Ra],Rd */
14574a4d8c2SCharles.Forsyth r = p->reg;
14674a4d8c2SCharles.Forsyth if(r == NREG)
14774a4d8c2SCharles.Forsyth r = p->to.reg;
14874a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
14974a4d8c2SCharles.Forsyth break;
15074a4d8c2SCharles.Forsyth
15174a4d8c2SCharles.Forsyth case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
15274a4d8c2SCharles.Forsyth v = regoff(&p->from);
15374a4d8c2SCharles.Forsyth r = p->from.reg;
15474a4d8c2SCharles.Forsyth if(r == NREG)
15574a4d8c2SCharles.Forsyth r = o->param;
15674a4d8c2SCharles.Forsyth a = OP_ADDI;
15774a4d8c2SCharles.Forsyth if(o->a1 == C_UCON) {
15874a4d8c2SCharles.Forsyth a = OP_ADDIS;
15974a4d8c2SCharles.Forsyth v >>= 16;
16074a4d8c2SCharles.Forsyth }
16174a4d8c2SCharles.Forsyth if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
16274a4d8c2SCharles.Forsyth diag("literal operation on R0\n%P", p);
16374a4d8c2SCharles.Forsyth o1 = AOP_IRR(a, p->to.reg, r, v);
16474a4d8c2SCharles.Forsyth break;
16574a4d8c2SCharles.Forsyth
16674a4d8c2SCharles.Forsyth case 4: /* add/mul $scon,[r1],r2 */
16774a4d8c2SCharles.Forsyth v = regoff(&p->from);
16874a4d8c2SCharles.Forsyth r = p->reg;
16974a4d8c2SCharles.Forsyth if(r == NREG)
17074a4d8c2SCharles.Forsyth r = p->to.reg;
17174a4d8c2SCharles.Forsyth if(r0iszero && p->to.reg == 0)
17274a4d8c2SCharles.Forsyth diag("literal operation on R0\n%P", p);
17374a4d8c2SCharles.Forsyth o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
17474a4d8c2SCharles.Forsyth break;
17574a4d8c2SCharles.Forsyth
17674a4d8c2SCharles.Forsyth case 5: /* syscall */
17774a4d8c2SCharles.Forsyth if(aflag)
17874a4d8c2SCharles.Forsyth return 0;
17974a4d8c2SCharles.Forsyth o1 = oprrr(p->as);
18074a4d8c2SCharles.Forsyth break;
18174a4d8c2SCharles.Forsyth
18274a4d8c2SCharles.Forsyth case 6: /* logical op Rb,[Rs,]Ra; no literal */
18374a4d8c2SCharles.Forsyth r = p->reg;
18474a4d8c2SCharles.Forsyth if(r == NREG)
18574a4d8c2SCharles.Forsyth r = p->to.reg;
18674a4d8c2SCharles.Forsyth o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
18774a4d8c2SCharles.Forsyth break;
18874a4d8c2SCharles.Forsyth
18974a4d8c2SCharles.Forsyth case 7: /* mov r, soreg ==> stw o(r) */
19074a4d8c2SCharles.Forsyth r = p->to.reg;
19174a4d8c2SCharles.Forsyth if(r == NREG)
19274a4d8c2SCharles.Forsyth r = o->param;
19374a4d8c2SCharles.Forsyth v = regoff(&p->to);
19474a4d8c2SCharles.Forsyth if(p->to.type == D_OREG && p->reg != NREG) {
19574a4d8c2SCharles.Forsyth if(v)
19674a4d8c2SCharles.Forsyth diag("illegal indexed instruction\n%P", p);
19774a4d8c2SCharles.Forsyth o1 = AOP_RRR(opstorex(p->as), p->from.reg, p->reg, r);
19874a4d8c2SCharles.Forsyth } else
19974a4d8c2SCharles.Forsyth o1 = AOP_IRR(opstore(p->as), p->from.reg, r, v);
20074a4d8c2SCharles.Forsyth break;
20174a4d8c2SCharles.Forsyth
20274a4d8c2SCharles.Forsyth case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
20374a4d8c2SCharles.Forsyth r = p->from.reg;
20474a4d8c2SCharles.Forsyth if(r == NREG)
20574a4d8c2SCharles.Forsyth r = o->param;
20674a4d8c2SCharles.Forsyth v = regoff(&p->from);
20774a4d8c2SCharles.Forsyth if(p->from.type == D_OREG && p->reg != NREG) {
20874a4d8c2SCharles.Forsyth if(v)
20974a4d8c2SCharles.Forsyth diag("illegal indexed instruction\n%P", p);
21074a4d8c2SCharles.Forsyth o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
21174a4d8c2SCharles.Forsyth } else
21274a4d8c2SCharles.Forsyth o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
21374a4d8c2SCharles.Forsyth break;
21474a4d8c2SCharles.Forsyth
21574a4d8c2SCharles.Forsyth case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
21674a4d8c2SCharles.Forsyth r = p->from.reg;
21774a4d8c2SCharles.Forsyth if(r == NREG)
21874a4d8c2SCharles.Forsyth r = o->param;
21974a4d8c2SCharles.Forsyth v = regoff(&p->from);
22074a4d8c2SCharles.Forsyth if(p->from.type == D_OREG && p->reg != NREG) {
22174a4d8c2SCharles.Forsyth if(v)
22274a4d8c2SCharles.Forsyth diag("illegal indexed instruction\n%P", p);
22374a4d8c2SCharles.Forsyth o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
22474a4d8c2SCharles.Forsyth } else
22574a4d8c2SCharles.Forsyth o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
22674a4d8c2SCharles.Forsyth o2 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
22774a4d8c2SCharles.Forsyth break;
22874a4d8c2SCharles.Forsyth
22974a4d8c2SCharles.Forsyth case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
23074a4d8c2SCharles.Forsyth r = p->reg;
23174a4d8c2SCharles.Forsyth if(r == NREG)
23274a4d8c2SCharles.Forsyth r = p->to.reg;
23374a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, r);
23474a4d8c2SCharles.Forsyth break;
23574a4d8c2SCharles.Forsyth
23674a4d8c2SCharles.Forsyth case 11: /* br/bl lbra */
23774a4d8c2SCharles.Forsyth if(aflag)
23874a4d8c2SCharles.Forsyth return 0;
23974a4d8c2SCharles.Forsyth v = 0;
24074a4d8c2SCharles.Forsyth if(p->cond == UP){
24174a4d8c2SCharles.Forsyth if(p->to.sym->type != SUNDEF)
24274a4d8c2SCharles.Forsyth diag("bad branch sym type");
24374a4d8c2SCharles.Forsyth v = (ulong)p->to.sym->value >> (Roffset-2);
24474a4d8c2SCharles.Forsyth dynreloc(p->to.sym, p->pc, 0, 0, 0);
24574a4d8c2SCharles.Forsyth }
24674a4d8c2SCharles.Forsyth else if(p->cond)
24774a4d8c2SCharles.Forsyth v = p->cond->pc - p->pc;
24874a4d8c2SCharles.Forsyth if(v & 03) {
24974a4d8c2SCharles.Forsyth diag("odd branch target address\n%P", p);
25074a4d8c2SCharles.Forsyth v &= ~03;
25174a4d8c2SCharles.Forsyth }
25274a4d8c2SCharles.Forsyth if(v < -(1L<<25) || v >= (1L<<25))
25374a4d8c2SCharles.Forsyth diag("branch too far\n%P", p);
25474a4d8c2SCharles.Forsyth o1 = OP_BR(opirr(p->as), v, 0);
25574a4d8c2SCharles.Forsyth break;
25674a4d8c2SCharles.Forsyth
25774a4d8c2SCharles.Forsyth case 12: /* movb r,r (signed); extsb is on PowerPC but not POWER */
25874a4d8c2SCharles.Forsyth o1 = LOP_RRR(OP_EXTSB, p->to.reg, p->from.reg, 0);
25974a4d8c2SCharles.Forsyth break;
26074a4d8c2SCharles.Forsyth
26174a4d8c2SCharles.Forsyth case 13: /* mov[bh]z r,r; uses rlwinm not andi. to avoid changing CC */
26274a4d8c2SCharles.Forsyth if(p->as == AMOVBZ)
26374a4d8c2SCharles.Forsyth o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 24, 31);
26474a4d8c2SCharles.Forsyth else if(p->as == AMOVH)
26574a4d8c2SCharles.Forsyth o1 = LOP_RRR(OP_EXTSH, p->to.reg, p->from.reg, 0);
26674a4d8c2SCharles.Forsyth else if(p->as == AMOVHZ)
26774a4d8c2SCharles.Forsyth o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 16, 31);
26874a4d8c2SCharles.Forsyth else
26974a4d8c2SCharles.Forsyth diag("internal: bad mov[bh]z\n%P", p);
27074a4d8c2SCharles.Forsyth break;
27174a4d8c2SCharles.Forsyth
27274a4d8c2SCharles.Forsyth /*14 */
27374a4d8c2SCharles.Forsyth
27474a4d8c2SCharles.Forsyth case 17: /* bc bo,bi,lbra (same for now) */
27574a4d8c2SCharles.Forsyth case 16: /* bc bo,bi,sbra */
27674a4d8c2SCharles.Forsyth if(aflag)
27774a4d8c2SCharles.Forsyth return 0;
27874a4d8c2SCharles.Forsyth a = 0;
27974a4d8c2SCharles.Forsyth if(p->from.type == D_CONST)
28074a4d8c2SCharles.Forsyth a = regoff(&p->from);
28174a4d8c2SCharles.Forsyth r = p->reg;
28274a4d8c2SCharles.Forsyth if(r == NREG)
28374a4d8c2SCharles.Forsyth r = 0;
28474a4d8c2SCharles.Forsyth v = 0;
28574a4d8c2SCharles.Forsyth if(p->cond)
28674a4d8c2SCharles.Forsyth v = p->cond->pc - p->pc;
28774a4d8c2SCharles.Forsyth if(v & 03) {
28874a4d8c2SCharles.Forsyth diag("odd branch target address\n%P", p);
28974a4d8c2SCharles.Forsyth v &= ~03;
29074a4d8c2SCharles.Forsyth }
29174a4d8c2SCharles.Forsyth if(v < -(1L<<16) || v >= (1L<<16))
29274a4d8c2SCharles.Forsyth diag("branch too far\n%P", p);
29374a4d8c2SCharles.Forsyth o1 = OP_BC(opirr(p->as), a, r, v, 0);
29474a4d8c2SCharles.Forsyth break;
29574a4d8c2SCharles.Forsyth
29674a4d8c2SCharles.Forsyth case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
29774a4d8c2SCharles.Forsyth if(aflag)
29874a4d8c2SCharles.Forsyth return 0;
29974a4d8c2SCharles.Forsyth if(p->as == ABC || p->as == ABCL)
30074a4d8c2SCharles.Forsyth v = regoff(&p->to)&31L;
30174a4d8c2SCharles.Forsyth else
30274a4d8c2SCharles.Forsyth v = 20; /* unconditional */
30374a4d8c2SCharles.Forsyth r = p->reg;
30474a4d8c2SCharles.Forsyth if(r == NREG)
30574a4d8c2SCharles.Forsyth r = 0;
30674a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((D_LR&0x1f)<<16) | (((D_LR>>5)&0x1f)<<11);
30774a4d8c2SCharles.Forsyth o2 = OPVCC(19, 16, 0, 0);
30874a4d8c2SCharles.Forsyth if(p->as == ABL || p->as == ABCL)
30974a4d8c2SCharles.Forsyth o2 |= 1;
31074a4d8c2SCharles.Forsyth o2 = OP_BCR(o2, v, r);
31174a4d8c2SCharles.Forsyth break;
31274a4d8c2SCharles.Forsyth
31374a4d8c2SCharles.Forsyth case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
31474a4d8c2SCharles.Forsyth if(aflag)
31574a4d8c2SCharles.Forsyth return 0;
31674a4d8c2SCharles.Forsyth if(p->as == ABC || p->as == ABCL)
31774a4d8c2SCharles.Forsyth v = regoff(&p->from)&31L;
31874a4d8c2SCharles.Forsyth else
31974a4d8c2SCharles.Forsyth v = 20; /* unconditional */
32074a4d8c2SCharles.Forsyth r = p->reg;
32174a4d8c2SCharles.Forsyth if(r == NREG)
32274a4d8c2SCharles.Forsyth r = 0;
32374a4d8c2SCharles.Forsyth switch(oclass(p->to)) {
32474a4d8c2SCharles.Forsyth case C_CTR:
32574a4d8c2SCharles.Forsyth o1 = OPVCC(19, 528, 0, 0);
32674a4d8c2SCharles.Forsyth break;
32774a4d8c2SCharles.Forsyth case C_LR:
32874a4d8c2SCharles.Forsyth o1 = OPVCC(19, 16, 0, 0);
32974a4d8c2SCharles.Forsyth break;
33074a4d8c2SCharles.Forsyth default:
33174a4d8c2SCharles.Forsyth diag("bad optab entry (18): %d\n%P", p->to.class, p);
33274a4d8c2SCharles.Forsyth v = 0;
33374a4d8c2SCharles.Forsyth }
33474a4d8c2SCharles.Forsyth if(p->as == ABL || p->as == ABCL)
33574a4d8c2SCharles.Forsyth o1 |= 1;
33674a4d8c2SCharles.Forsyth o1 = OP_BCR(o1, v, r);
33774a4d8c2SCharles.Forsyth break;
33874a4d8c2SCharles.Forsyth
33974a4d8c2SCharles.Forsyth case 19: /* mov $lcon,r ==> cau+or */
34074a4d8c2SCharles.Forsyth v = regoff(&p->from);
34174a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, p->to.reg, REGZERO, v>>16);
34274a4d8c2SCharles.Forsyth o2 = LOP_IRR(OP_ORI, p->to.reg, p->to.reg, v);
34374a4d8c2SCharles.Forsyth if(dlm)
34474a4d8c2SCharles.Forsyth reloc(&p->from, p->pc, 0);
34574a4d8c2SCharles.Forsyth break;
34674a4d8c2SCharles.Forsyth
34774a4d8c2SCharles.Forsyth case 20: /* add $ucon,,r */
34874a4d8c2SCharles.Forsyth v = regoff(&p->from);
34974a4d8c2SCharles.Forsyth r = p->reg;
35074a4d8c2SCharles.Forsyth if(r == NREG)
35174a4d8c2SCharles.Forsyth r = p->to.reg;
35274a4d8c2SCharles.Forsyth if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
35374a4d8c2SCharles.Forsyth diag("literal operation on R0\n%P", p);
35474a4d8c2SCharles.Forsyth o1 = AOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16);
35574a4d8c2SCharles.Forsyth break;
35674a4d8c2SCharles.Forsyth
35774a4d8c2SCharles.Forsyth case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
35874a4d8c2SCharles.Forsyth v = regoff(&p->from);
35974a4d8c2SCharles.Forsyth if(p->to.reg == REGTMP || p->reg == REGTMP)
36074a4d8c2SCharles.Forsyth diag("cant synthesize large constant\n%P", p);
36174a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
36274a4d8c2SCharles.Forsyth o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
36374a4d8c2SCharles.Forsyth r = p->reg;
36474a4d8c2SCharles.Forsyth if(r == NREG)
36574a4d8c2SCharles.Forsyth r = p->to.reg;
36674a4d8c2SCharles.Forsyth o3 = AOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
36774a4d8c2SCharles.Forsyth if(dlm)
36874a4d8c2SCharles.Forsyth reloc(&p->from, p->pc, 0);
36974a4d8c2SCharles.Forsyth break;
37074a4d8c2SCharles.Forsyth
37174a4d8c2SCharles.Forsyth case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
37274a4d8c2SCharles.Forsyth v = regoff(&p->from);
37374a4d8c2SCharles.Forsyth if(p->to.reg == REGTMP || p->reg == REGTMP)
37474a4d8c2SCharles.Forsyth diag("cant synthesize large constant\n%P", p);
37574a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
37674a4d8c2SCharles.Forsyth o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
37774a4d8c2SCharles.Forsyth r = p->reg;
37874a4d8c2SCharles.Forsyth if(r == NREG)
37974a4d8c2SCharles.Forsyth r = p->to.reg;
38074a4d8c2SCharles.Forsyth o3 = LOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
38174a4d8c2SCharles.Forsyth if(dlm)
38274a4d8c2SCharles.Forsyth reloc(&p->from, p->pc, 0);
38374a4d8c2SCharles.Forsyth break;
38474a4d8c2SCharles.Forsyth /*24*/
38574a4d8c2SCharles.Forsyth
38674a4d8c2SCharles.Forsyth case 26: /* mov $lsext/auto/oreg,,r2 ==> cau+add */
38774a4d8c2SCharles.Forsyth v = regoff(&p->from);
38874a4d8c2SCharles.Forsyth if(v & 0x8000L)
38974a4d8c2SCharles.Forsyth v += 0x10000L;
39074a4d8c2SCharles.Forsyth if(p->to.reg == REGTMP)
39174a4d8c2SCharles.Forsyth diag("can't synthesize large constant\n%P", p);
39274a4d8c2SCharles.Forsyth r = p->from.reg;
39374a4d8c2SCharles.Forsyth if(r == NREG)
39474a4d8c2SCharles.Forsyth r = o->param;
39574a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
39674a4d8c2SCharles.Forsyth o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
39774a4d8c2SCharles.Forsyth break;
39874a4d8c2SCharles.Forsyth
39974a4d8c2SCharles.Forsyth case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
40074a4d8c2SCharles.Forsyth v = regoff(&p->from3);
40174a4d8c2SCharles.Forsyth r = p->from.reg;
40274a4d8c2SCharles.Forsyth o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
40374a4d8c2SCharles.Forsyth break;
40474a4d8c2SCharles.Forsyth
40574a4d8c2SCharles.Forsyth case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
40674a4d8c2SCharles.Forsyth v = regoff(&p->from3);
40774a4d8c2SCharles.Forsyth if(p->to.reg == REGTMP || p->from.reg == REGTMP)
40874a4d8c2SCharles.Forsyth diag("can't synthesize large constant\n%P", p);
40974a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
41074a4d8c2SCharles.Forsyth o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
41174a4d8c2SCharles.Forsyth o3 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, REGTMP);
41274a4d8c2SCharles.Forsyth if(dlm)
41374a4d8c2SCharles.Forsyth reloc(&p->from3, p->pc, 0);
41474a4d8c2SCharles.Forsyth break;
41574a4d8c2SCharles.Forsyth
41674a4d8c2SCharles.Forsyth /*29, 30, 31 */
41774a4d8c2SCharles.Forsyth
41874a4d8c2SCharles.Forsyth case 32: /* fmul frc,fra,frd */
41974a4d8c2SCharles.Forsyth r = p->reg;
42074a4d8c2SCharles.Forsyth if(r == NREG)
42174a4d8c2SCharles.Forsyth r = p->to.reg;
42274a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
42374a4d8c2SCharles.Forsyth break;
42474a4d8c2SCharles.Forsyth
42574a4d8c2SCharles.Forsyth case 33: /* fabs [frb,]frd; fmr. frb,frd */
42674a4d8c2SCharles.Forsyth r = p->from.reg;
42774a4d8c2SCharles.Forsyth if(oclass(p->from) == C_NONE)
42874a4d8c2SCharles.Forsyth r = p->to.reg;
42974a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, 0, r);
43074a4d8c2SCharles.Forsyth break;
43174a4d8c2SCharles.Forsyth
43274a4d8c2SCharles.Forsyth case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c) */
43374a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6);
43474a4d8c2SCharles.Forsyth break;
43574a4d8c2SCharles.Forsyth
43674a4d8c2SCharles.Forsyth case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
43774a4d8c2SCharles.Forsyth v = regoff(&p->to);
43874a4d8c2SCharles.Forsyth if(v & 0x8000L)
43974a4d8c2SCharles.Forsyth v += 0x10000L;
44074a4d8c2SCharles.Forsyth r = p->to.reg;
44174a4d8c2SCharles.Forsyth if(r == NREG)
44274a4d8c2SCharles.Forsyth r = o->param;
44374a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
44474a4d8c2SCharles.Forsyth o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
44574a4d8c2SCharles.Forsyth break;
44674a4d8c2SCharles.Forsyth
44774a4d8c2SCharles.Forsyth case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
44874a4d8c2SCharles.Forsyth v = regoff(&p->from);
44974a4d8c2SCharles.Forsyth if(v & 0x8000L)
45074a4d8c2SCharles.Forsyth v += 0x10000L;
45174a4d8c2SCharles.Forsyth r = p->from.reg;
45274a4d8c2SCharles.Forsyth if(r == NREG)
45374a4d8c2SCharles.Forsyth r = o->param;
45474a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
45574a4d8c2SCharles.Forsyth o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
45674a4d8c2SCharles.Forsyth break;
45774a4d8c2SCharles.Forsyth
45874a4d8c2SCharles.Forsyth case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
45974a4d8c2SCharles.Forsyth v = regoff(&p->from);
46074a4d8c2SCharles.Forsyth if(v & 0x8000L)
46174a4d8c2SCharles.Forsyth v += 0x10000L;
46274a4d8c2SCharles.Forsyth r = p->from.reg;
46374a4d8c2SCharles.Forsyth if(r == NREG)
46474a4d8c2SCharles.Forsyth r = o->param;
46574a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
46674a4d8c2SCharles.Forsyth o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
46774a4d8c2SCharles.Forsyth o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
46874a4d8c2SCharles.Forsyth break;
46974a4d8c2SCharles.Forsyth
47074a4d8c2SCharles.Forsyth case 40: /* word */
47174a4d8c2SCharles.Forsyth if(aflag)
47274a4d8c2SCharles.Forsyth return 0;
47374a4d8c2SCharles.Forsyth o1 = regoff(&p->from);
47474a4d8c2SCharles.Forsyth break;
47574a4d8c2SCharles.Forsyth
47674a4d8c2SCharles.Forsyth case 41: /* stswi */
47774a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), p->from.reg, p->to.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
47874a4d8c2SCharles.Forsyth break;
47974a4d8c2SCharles.Forsyth
48074a4d8c2SCharles.Forsyth case 42: /* lswi */
48174a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), p->to.reg, p->from.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
48274a4d8c2SCharles.Forsyth break;
48374a4d8c2SCharles.Forsyth
48474a4d8c2SCharles.Forsyth case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
48574a4d8c2SCharles.Forsyth r = p->reg;
48674a4d8c2SCharles.Forsyth if(r == NREG)
48774a4d8c2SCharles.Forsyth r = 0;
48874a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), 0, r, p->from.reg);
48974a4d8c2SCharles.Forsyth break;
49074a4d8c2SCharles.Forsyth
49174a4d8c2SCharles.Forsyth case 44: /* indexed store */
49274a4d8c2SCharles.Forsyth r = p->reg;
49374a4d8c2SCharles.Forsyth if(r == NREG)
49474a4d8c2SCharles.Forsyth r = 0;
49574a4d8c2SCharles.Forsyth o1 = AOP_RRR(opstorex(p->as), p->from.reg, r, p->to.reg);
49674a4d8c2SCharles.Forsyth break;
49774a4d8c2SCharles.Forsyth case 45: /* indexed load */
49874a4d8c2SCharles.Forsyth r = p->reg;
49974a4d8c2SCharles.Forsyth if(r == NREG)
50074a4d8c2SCharles.Forsyth r = 0;
50174a4d8c2SCharles.Forsyth o1 = AOP_RRR(oploadx(p->as), p->to.reg, r, p->from.reg);
50274a4d8c2SCharles.Forsyth break;
50374a4d8c2SCharles.Forsyth
50474a4d8c2SCharles.Forsyth case 46: /* plain op */
50574a4d8c2SCharles.Forsyth o1 = oprrr(p->as);
50674a4d8c2SCharles.Forsyth break;
50774a4d8c2SCharles.Forsyth
50874a4d8c2SCharles.Forsyth case 47: /* op Ra, Rd; also op [Ra,] Rd */
50974a4d8c2SCharles.Forsyth r = p->from.reg;
51074a4d8c2SCharles.Forsyth if(r == NREG)
51174a4d8c2SCharles.Forsyth r = p->to.reg;
51274a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0);
51374a4d8c2SCharles.Forsyth break;
51474a4d8c2SCharles.Forsyth
51574a4d8c2SCharles.Forsyth case 48: /* op Rs, Ra */
51674a4d8c2SCharles.Forsyth r = p->from.reg;
51774a4d8c2SCharles.Forsyth if(r == NREG)
51874a4d8c2SCharles.Forsyth r = p->to.reg;
51974a4d8c2SCharles.Forsyth o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, 0);
52074a4d8c2SCharles.Forsyth break;
52174a4d8c2SCharles.Forsyth
52274a4d8c2SCharles.Forsyth case 49: /* op Rb */
52374a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), 0, 0, p->from.reg);
52474a4d8c2SCharles.Forsyth break;
52574a4d8c2SCharles.Forsyth
52674a4d8c2SCharles.Forsyth /*50*/
52774a4d8c2SCharles.Forsyth
52874a4d8c2SCharles.Forsyth case 51: /* rem[u] r1[,r2],r3 */
52974a4d8c2SCharles.Forsyth r = p->reg;
53074a4d8c2SCharles.Forsyth if(r == NREG)
53174a4d8c2SCharles.Forsyth r = p->to.reg;
53274a4d8c2SCharles.Forsyth v = oprrr(p->as);
53374a4d8c2SCharles.Forsyth t = v & ((1<<10)|1); /* OE|Rc */
53474a4d8c2SCharles.Forsyth o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
53574a4d8c2SCharles.Forsyth o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
53674a4d8c2SCharles.Forsyth o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
53774a4d8c2SCharles.Forsyth break;
53874a4d8c2SCharles.Forsyth
53974a4d8c2SCharles.Forsyth case 52: /* mtfsbNx cr(n) */
54074a4d8c2SCharles.Forsyth v = regoff(&p->from)&31L;
54174a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), v, 0, 0);
54274a4d8c2SCharles.Forsyth break;
54374a4d8c2SCharles.Forsyth
54474a4d8c2SCharles.Forsyth case 53: /* mffsX ,fr1 */
54574a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0);
54674a4d8c2SCharles.Forsyth break;
54774a4d8c2SCharles.Forsyth
54874a4d8c2SCharles.Forsyth case 54: /* mov msr,r1; mov r1, msr*/
54974a4d8c2SCharles.Forsyth if(oclass(p->from) == C_REG)
55074a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0);
55174a4d8c2SCharles.Forsyth else
55274a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0);
55374a4d8c2SCharles.Forsyth break;
55474a4d8c2SCharles.Forsyth
55574a4d8c2SCharles.Forsyth case 55: /* mov sreg,r1; mov r1,sreg */
55674a4d8c2SCharles.Forsyth v = 0;
55774a4d8c2SCharles.Forsyth if(p->from.type == D_SREG) {
55874a4d8c2SCharles.Forsyth r = p->from.reg;
55974a4d8c2SCharles.Forsyth o1 = OP_MFSR;
56074a4d8c2SCharles.Forsyth if(r == NREG && p->reg != NREG) {
56174a4d8c2SCharles.Forsyth r = 0;
56274a4d8c2SCharles.Forsyth v = p->reg;
56374a4d8c2SCharles.Forsyth o1 = OP_MFSRIN;
56474a4d8c2SCharles.Forsyth }
56574a4d8c2SCharles.Forsyth o1 = AOP_RRR(o1, p->to.reg, r&15L, v);
56674a4d8c2SCharles.Forsyth } else {
56774a4d8c2SCharles.Forsyth r = p->to.reg;
56874a4d8c2SCharles.Forsyth o1 = OP_MTSR;
56974a4d8c2SCharles.Forsyth if(r == NREG && p->reg != NREG) {
57074a4d8c2SCharles.Forsyth r = 0;
57174a4d8c2SCharles.Forsyth v = p->reg;
57274a4d8c2SCharles.Forsyth o1 = OP_MTSRIN;
57374a4d8c2SCharles.Forsyth }
57474a4d8c2SCharles.Forsyth o1 = AOP_RRR(o1, p->from.reg, r&15L, v);
57574a4d8c2SCharles.Forsyth }
57674a4d8c2SCharles.Forsyth if(r == NREG)
57774a4d8c2SCharles.Forsyth diag("illegal move indirect to/from segment register\n%P", p);
57874a4d8c2SCharles.Forsyth break;
57974a4d8c2SCharles.Forsyth
58074a4d8c2SCharles.Forsyth case 56: /* sra $sh,[s,]a */
58174a4d8c2SCharles.Forsyth v = regoff(&p->from);
58274a4d8c2SCharles.Forsyth r = p->reg;
58374a4d8c2SCharles.Forsyth if(r == NREG)
58474a4d8c2SCharles.Forsyth r = p->to.reg;
58574a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), r, p->to.reg, v&31L);
58674a4d8c2SCharles.Forsyth break;
58774a4d8c2SCharles.Forsyth
58874a4d8c2SCharles.Forsyth case 57: /* slw $sh,[s,]a -> rlwinm ... */
58974a4d8c2SCharles.Forsyth v = regoff(&p->from);
59074a4d8c2SCharles.Forsyth r = p->reg;
59174a4d8c2SCharles.Forsyth if(r == NREG)
59274a4d8c2SCharles.Forsyth r = p->to.reg;
59374a4d8c2SCharles.Forsyth /*
59474a4d8c2SCharles.Forsyth * Let user (gs) shoot himself in the foot.
59574a4d8c2SCharles.Forsyth * qc has already complained.
59674a4d8c2SCharles.Forsyth *
59774a4d8c2SCharles.Forsyth if(v < 0 || v > 31)
59874a4d8c2SCharles.Forsyth diag("illegal shift %ld\n%P", v, p);
59974a4d8c2SCharles.Forsyth */
60074a4d8c2SCharles.Forsyth if(v < 0)
60174a4d8c2SCharles.Forsyth v = 0;
60274a4d8c2SCharles.Forsyth else if(v > 32)
60374a4d8c2SCharles.Forsyth v = 32;
60474a4d8c2SCharles.Forsyth if(p->as == ASRW || p->as == ASRWCC) { /* shift right */
60574a4d8c2SCharles.Forsyth mask[0] = v;
60674a4d8c2SCharles.Forsyth mask[1] = 31;
60774a4d8c2SCharles.Forsyth v = 32-v;
60874a4d8c2SCharles.Forsyth } else {
60974a4d8c2SCharles.Forsyth mask[0] = 0;
61074a4d8c2SCharles.Forsyth mask[1] = 31-v;
61174a4d8c2SCharles.Forsyth }
61274a4d8c2SCharles.Forsyth o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]);
61374a4d8c2SCharles.Forsyth if(p->as == ASLWCC || p->as == ASRWCC)
61474a4d8c2SCharles.Forsyth o1 |= 1; /* Rc */
61574a4d8c2SCharles.Forsyth break;
61674a4d8c2SCharles.Forsyth
61774a4d8c2SCharles.Forsyth case 58: /* logical $andcon,[s],a */
61874a4d8c2SCharles.Forsyth v = regoff(&p->from);
61974a4d8c2SCharles.Forsyth r = p->reg;
62074a4d8c2SCharles.Forsyth if(r == NREG)
62174a4d8c2SCharles.Forsyth r = p->to.reg;
62274a4d8c2SCharles.Forsyth o1 = LOP_IRR(opirr(p->as), p->to.reg, r, v);
62374a4d8c2SCharles.Forsyth break;
62474a4d8c2SCharles.Forsyth
62574a4d8c2SCharles.Forsyth case 59: /* or/and $ucon,,r */
62674a4d8c2SCharles.Forsyth v = regoff(&p->from);
62774a4d8c2SCharles.Forsyth r = p->reg;
62874a4d8c2SCharles.Forsyth if(r == NREG)
62974a4d8c2SCharles.Forsyth r = p->to.reg;
63074a4d8c2SCharles.Forsyth o1 = LOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16); /* oris, xoris, andis */
63174a4d8c2SCharles.Forsyth break;
63274a4d8c2SCharles.Forsyth
63374a4d8c2SCharles.Forsyth case 60: /* tw to,a,b */
63474a4d8c2SCharles.Forsyth r = regoff(&p->from)&31L;
63574a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), r, p->reg, p->to.reg);
63674a4d8c2SCharles.Forsyth break;
63774a4d8c2SCharles.Forsyth
63874a4d8c2SCharles.Forsyth case 61: /* tw to,a,$simm */
63974a4d8c2SCharles.Forsyth r = regoff(&p->from)&31L;
64074a4d8c2SCharles.Forsyth v = regoff(&p->to);
64174a4d8c2SCharles.Forsyth o1 = AOP_IRR(opirr(p->as), r, p->reg, v);
64274a4d8c2SCharles.Forsyth break;
64374a4d8c2SCharles.Forsyth
64474a4d8c2SCharles.Forsyth case 62: /* rlwmi $sh,s,$mask,a */
64574a4d8c2SCharles.Forsyth v = regoff(&p->from);
64674a4d8c2SCharles.Forsyth maskgen(p, mask, regoff(&p->from3));
64774a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, v);
64874a4d8c2SCharles.Forsyth o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
64974a4d8c2SCharles.Forsyth break;
65074a4d8c2SCharles.Forsyth
65174a4d8c2SCharles.Forsyth case 63: /* rlwmi b,s,$mask,a */
65274a4d8c2SCharles.Forsyth maskgen(p, mask, regoff(&p->from3));
65374a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, p->from.reg);
65474a4d8c2SCharles.Forsyth o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
65574a4d8c2SCharles.Forsyth break;
65674a4d8c2SCharles.Forsyth
65774a4d8c2SCharles.Forsyth case 64: /* mtfsf fr[, $m] {,fpcsr} */
65874a4d8c2SCharles.Forsyth if(p->from3.type != D_NONE)
65974a4d8c2SCharles.Forsyth v = regoff(&p->from3)&255L;
66074a4d8c2SCharles.Forsyth else
66174a4d8c2SCharles.Forsyth v = 255;
66274a4d8c2SCharles.Forsyth o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11);
66374a4d8c2SCharles.Forsyth break;
66474a4d8c2SCharles.Forsyth
66574a4d8c2SCharles.Forsyth case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
66674a4d8c2SCharles.Forsyth if(p->to.reg == NREG)
66774a4d8c2SCharles.Forsyth diag("must specify FPSCR(n)\n%P", p);
66874a4d8c2SCharles.Forsyth o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(&p->from)&31L)<<12);
66974a4d8c2SCharles.Forsyth break;
67074a4d8c2SCharles.Forsyth
67174a4d8c2SCharles.Forsyth case 66: /* mov spr,r1; mov r1,spr, also dcr */
67274a4d8c2SCharles.Forsyth if(p->from.type == D_REG) {
67374a4d8c2SCharles.Forsyth r = p->from.reg;
67474a4d8c2SCharles.Forsyth v = p->to.offset;
675*647adfbcSforsyth if(p->to.type == D_DCR) {
676*647adfbcSforsyth if(p->to.reg != NREG) {
677*647adfbcSforsyth o1 = OPVCC(31,387,0,0); /* mtdcrx */
678*647adfbcSforsyth v = p->to.reg;
679*647adfbcSforsyth }else
68074a4d8c2SCharles.Forsyth o1 = OPVCC(31,451,0,0); /* mtdcr */
681*647adfbcSforsyth }else
68274a4d8c2SCharles.Forsyth o1 = OPVCC(31,467,0,0); /* mtspr */
68374a4d8c2SCharles.Forsyth } else {
68474a4d8c2SCharles.Forsyth r = p->to.reg;
68574a4d8c2SCharles.Forsyth v = p->from.offset;
686*647adfbcSforsyth if(p->from.type == D_DCR) {
687*647adfbcSforsyth if(p->from.reg != NREG) {
688*647adfbcSforsyth o1 = OPVCC(31,259,0,0); /* mfdcrx */
689*647adfbcSforsyth v = p->from.reg;
690*647adfbcSforsyth }else
69174a4d8c2SCharles.Forsyth o1 = OPVCC(31,323,0,0); /* mfdcr */
692*647adfbcSforsyth }else
69374a4d8c2SCharles.Forsyth o1 = OPVCC(31,339,0,0); /* mfspr */
69474a4d8c2SCharles.Forsyth }
69574a4d8c2SCharles.Forsyth o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
69674a4d8c2SCharles.Forsyth break;
69774a4d8c2SCharles.Forsyth
69874a4d8c2SCharles.Forsyth case 67: /* mcrf crfD,crfS */
69974a4d8c2SCharles.Forsyth if(p->from.type != D_CREG || p->from.reg == NREG ||
70074a4d8c2SCharles.Forsyth p->to.type != D_CREG || p->to.reg == NREG)
70174a4d8c2SCharles.Forsyth diag("illegal CR field number\n%P", p);
70274a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
70374a4d8c2SCharles.Forsyth break;
70474a4d8c2SCharles.Forsyth
70574a4d8c2SCharles.Forsyth case 68: /* mfcr rD */
70674a4d8c2SCharles.Forsyth if(p->from.type == D_CREG && p->from.reg != NREG)
70774a4d8c2SCharles.Forsyth diag("must move whole CR to register\n%P", p);
70874a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0);
70974a4d8c2SCharles.Forsyth break;
71074a4d8c2SCharles.Forsyth
71174a4d8c2SCharles.Forsyth case 69: /* mtcrf CRM,rS */
71274a4d8c2SCharles.Forsyth if(p->from3.type != D_NONE) {
71374a4d8c2SCharles.Forsyth if(p->to.reg != NREG)
71474a4d8c2SCharles.Forsyth diag("can't use both mask and CR(n)\n%P", p);
71574a4d8c2SCharles.Forsyth v = regoff(&p->from3) & 0xff;
71674a4d8c2SCharles.Forsyth } else {
71774a4d8c2SCharles.Forsyth if(p->to.reg == NREG)
71874a4d8c2SCharles.Forsyth v = 0xff; /* CR */
71974a4d8c2SCharles.Forsyth else
72074a4d8c2SCharles.Forsyth v = 1<<(7-(p->to.reg&7)); /* CR(n) */
72174a4d8c2SCharles.Forsyth }
72274a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
72374a4d8c2SCharles.Forsyth break;
72474a4d8c2SCharles.Forsyth
72574a4d8c2SCharles.Forsyth case 70: /* [f]cmp r,r,cr*/
72674a4d8c2SCharles.Forsyth if(p->reg == NREG)
72774a4d8c2SCharles.Forsyth r = 0;
72874a4d8c2SCharles.Forsyth else
72974a4d8c2SCharles.Forsyth r = (p->reg&7)<<2;
73074a4d8c2SCharles.Forsyth o1 = AOP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
73174a4d8c2SCharles.Forsyth break;
73274a4d8c2SCharles.Forsyth
73374a4d8c2SCharles.Forsyth case 71: /* cmp[l] r,i,cr*/
73474a4d8c2SCharles.Forsyth if(p->reg == NREG)
73574a4d8c2SCharles.Forsyth r = 0;
73674a4d8c2SCharles.Forsyth else
73774a4d8c2SCharles.Forsyth r = (p->reg&7)<<2;
73874a4d8c2SCharles.Forsyth o1 = AOP_RRR(opirr(p->as), r, p->from.reg, 0) | (regoff(&p->to)&0xffff);
73974a4d8c2SCharles.Forsyth break;
74074a4d8c2SCharles.Forsyth
74174a4d8c2SCharles.Forsyth case 72: /* mcrxr crfD */
74274a4d8c2SCharles.Forsyth if(p->to.reg == NREG)
74374a4d8c2SCharles.Forsyth diag("must move XER to CR(n)\n%P", p);
74474a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MCRXR, ((p->to.reg&7L)<<2), 0, 0);
74574a4d8c2SCharles.Forsyth break;
74674a4d8c2SCharles.Forsyth
74774a4d8c2SCharles.Forsyth case 73: /* mcrfs crfD,crfS */
74874a4d8c2SCharles.Forsyth if(p->from.type != D_FPSCR || p->from.reg == NREG ||
74974a4d8c2SCharles.Forsyth p->to.type != D_CREG || p->to.reg == NREG)
75074a4d8c2SCharles.Forsyth diag("illegal FPSCR/CR field number\n%P", p);
75174a4d8c2SCharles.Forsyth o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
75274a4d8c2SCharles.Forsyth break;
75374a4d8c2SCharles.Forsyth
75474a4d8c2SCharles.Forsyth /* relocation operations */
75574a4d8c2SCharles.Forsyth
75674a4d8c2SCharles.Forsyth case 74:
75774a4d8c2SCharles.Forsyth v = regoff(&p->to);
75874a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
75974a4d8c2SCharles.Forsyth o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
76074a4d8c2SCharles.Forsyth if(dlm)
76174a4d8c2SCharles.Forsyth reloc(&p->to, p->pc, 1);
76274a4d8c2SCharles.Forsyth break;
76374a4d8c2SCharles.Forsyth
76474a4d8c2SCharles.Forsyth case 75:
76574a4d8c2SCharles.Forsyth v = regoff(&p->from);
76674a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
76774a4d8c2SCharles.Forsyth o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
76874a4d8c2SCharles.Forsyth if(dlm)
76974a4d8c2SCharles.Forsyth reloc(&p->from, p->pc, 1);
77074a4d8c2SCharles.Forsyth break;
77174a4d8c2SCharles.Forsyth
77274a4d8c2SCharles.Forsyth case 76:
77374a4d8c2SCharles.Forsyth v = regoff(&p->from);
77474a4d8c2SCharles.Forsyth o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
77574a4d8c2SCharles.Forsyth o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
77674a4d8c2SCharles.Forsyth o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
77774a4d8c2SCharles.Forsyth if(dlm)
77874a4d8c2SCharles.Forsyth reloc(&p->from, p->pc, 1);
77974a4d8c2SCharles.Forsyth break;
78074a4d8c2SCharles.Forsyth
78174a4d8c2SCharles.Forsyth }
78274a4d8c2SCharles.Forsyth if(aflag)
78374a4d8c2SCharles.Forsyth return o1;
78474a4d8c2SCharles.Forsyth v = p->pc;
78574a4d8c2SCharles.Forsyth switch(o->size) {
78674a4d8c2SCharles.Forsyth default:
78774a4d8c2SCharles.Forsyth if(debug['a'])
78874a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
78974a4d8c2SCharles.Forsyth break;
79074a4d8c2SCharles.Forsyth case 4:
79174a4d8c2SCharles.Forsyth if(debug['a'])
79274a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
79374a4d8c2SCharles.Forsyth lput(o1);
79474a4d8c2SCharles.Forsyth break;
79574a4d8c2SCharles.Forsyth case 8:
79674a4d8c2SCharles.Forsyth if(debug['a'])
79774a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
79874a4d8c2SCharles.Forsyth lput(o1);
79974a4d8c2SCharles.Forsyth lput(o2);
80074a4d8c2SCharles.Forsyth break;
80174a4d8c2SCharles.Forsyth case 12:
80274a4d8c2SCharles.Forsyth if(debug['a'])
80374a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
80474a4d8c2SCharles.Forsyth lput(o1);
80574a4d8c2SCharles.Forsyth lput(o2);
80674a4d8c2SCharles.Forsyth lput(o3);
80774a4d8c2SCharles.Forsyth break;
80874a4d8c2SCharles.Forsyth case 16:
80974a4d8c2SCharles.Forsyth if(debug['a'])
81074a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
81174a4d8c2SCharles.Forsyth v, o1, o2, o3, o4, p);
81274a4d8c2SCharles.Forsyth lput(o1);
81374a4d8c2SCharles.Forsyth lput(o2);
81474a4d8c2SCharles.Forsyth lput(o3);
81574a4d8c2SCharles.Forsyth lput(o4);
81674a4d8c2SCharles.Forsyth break;
81774a4d8c2SCharles.Forsyth case 20:
81874a4d8c2SCharles.Forsyth if(debug['a'])
81974a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
82074a4d8c2SCharles.Forsyth v, o1, o2, o3, o4, o5, p);
82174a4d8c2SCharles.Forsyth lput(o1);
82274a4d8c2SCharles.Forsyth lput(o2);
82374a4d8c2SCharles.Forsyth lput(o3);
82474a4d8c2SCharles.Forsyth lput(o4);
82574a4d8c2SCharles.Forsyth lput(o5);
82674a4d8c2SCharles.Forsyth break;
82774a4d8c2SCharles.Forsyth }
82874a4d8c2SCharles.Forsyth return 0;
82974a4d8c2SCharles.Forsyth }
83074a4d8c2SCharles.Forsyth
83174a4d8c2SCharles.Forsyth long
oprrr(int a)83274a4d8c2SCharles.Forsyth oprrr(int a)
83374a4d8c2SCharles.Forsyth {
83474a4d8c2SCharles.Forsyth switch(a) {
83574a4d8c2SCharles.Forsyth case AADD: return OPVCC(31,266,0,0);
83674a4d8c2SCharles.Forsyth case AADDCC: return OPVCC(31,266,0,1);
83774a4d8c2SCharles.Forsyth case AADDV: return OPVCC(31,266,1,0);
83874a4d8c2SCharles.Forsyth case AADDVCC: return OPVCC(31,266,1,1);
83974a4d8c2SCharles.Forsyth case AADDC: return OPVCC(31,10,0,0);
84074a4d8c2SCharles.Forsyth case AADDCCC: return OPVCC(31,10,0,1);
84174a4d8c2SCharles.Forsyth case AADDCV: return OPVCC(31,10,1,0);
84274a4d8c2SCharles.Forsyth case AADDCVCC: return OPVCC(31,10,1,1);
84374a4d8c2SCharles.Forsyth case AADDE: return OPVCC(31,138,0,0);
84474a4d8c2SCharles.Forsyth case AADDECC: return OPVCC(31,138,0,1);
84574a4d8c2SCharles.Forsyth case AADDEV: return OPVCC(31,138,1,0);
84674a4d8c2SCharles.Forsyth case AADDEVCC: return OPVCC(31,138,1,1);
84774a4d8c2SCharles.Forsyth case AADDME: return OPVCC(31,234,0,0);
84874a4d8c2SCharles.Forsyth case AADDMECC: return OPVCC(31,234,0,1);
84974a4d8c2SCharles.Forsyth case AADDMEV: return OPVCC(31,234,1,0);
85074a4d8c2SCharles.Forsyth case AADDMEVCC: return OPVCC(31,234,1,1);
85174a4d8c2SCharles.Forsyth case AADDZE: return OPVCC(31,202,0,0);
85274a4d8c2SCharles.Forsyth case AADDZECC: return OPVCC(31,202,0,1);
85374a4d8c2SCharles.Forsyth case AADDZEV: return OPVCC(31,202,1,0);
85474a4d8c2SCharles.Forsyth case AADDZEVCC: return OPVCC(31,202,1,1);
85574a4d8c2SCharles.Forsyth
85674a4d8c2SCharles.Forsyth case AAND: return OPVCC(31,28,0,0);
85774a4d8c2SCharles.Forsyth case AANDCC: return OPVCC(31,28,0,1);
85874a4d8c2SCharles.Forsyth case AANDN: return OPVCC(31,60,0,0);
85974a4d8c2SCharles.Forsyth case AANDNCC: return OPVCC(31,60,0,1);
86074a4d8c2SCharles.Forsyth
86174a4d8c2SCharles.Forsyth case ACMP: return OPVCC(31,0,0,0);
86274a4d8c2SCharles.Forsyth case ACMPU: return OPVCC(31,32,0,0);
86374a4d8c2SCharles.Forsyth
86474a4d8c2SCharles.Forsyth case ACNTLZW: return OPVCC(31,26,0,0);
86574a4d8c2SCharles.Forsyth case ACNTLZWCC: return OPVCC(31,26,0,1);
86674a4d8c2SCharles.Forsyth
86774a4d8c2SCharles.Forsyth case ACRAND: return OPVCC(19,257,0,0);
86874a4d8c2SCharles.Forsyth case ACRANDN: return OPVCC(19,129,0,0);
86974a4d8c2SCharles.Forsyth case ACREQV: return OPVCC(19,289,0,0);
87074a4d8c2SCharles.Forsyth case ACRNAND: return OPVCC(19,225,0,0);
87174a4d8c2SCharles.Forsyth case ACRNOR: return OPVCC(19,33,0,0);
87274a4d8c2SCharles.Forsyth case ACROR: return OPVCC(19,449,0,0);
87374a4d8c2SCharles.Forsyth case ACRORN: return OPVCC(19,417,0,0);
87474a4d8c2SCharles.Forsyth case ACRXOR: return OPVCC(19,193,0,0);
87574a4d8c2SCharles.Forsyth
87674a4d8c2SCharles.Forsyth case ADCBF: return OPVCC(31,86,0,0);
87774a4d8c2SCharles.Forsyth case ADCBI: return OPVCC(31,470,0,0);
87874a4d8c2SCharles.Forsyth case ADCBST: return OPVCC(31,54,0,0);
87974a4d8c2SCharles.Forsyth case ADCBT: return OPVCC(31,278,0,0);
88074a4d8c2SCharles.Forsyth case ADCBTST: return OPVCC(31,246,0,0);
88174a4d8c2SCharles.Forsyth case ADCBZ: return OPVCC(31,1014,0,0);
88274a4d8c2SCharles.Forsyth
88374a4d8c2SCharles.Forsyth case AREM:
88474a4d8c2SCharles.Forsyth case ADIVW: return OPVCC(31,491,0,0);
88574a4d8c2SCharles.Forsyth case AREMCC:
88674a4d8c2SCharles.Forsyth case ADIVWCC: return OPVCC(31,491,0,1);
88774a4d8c2SCharles.Forsyth case AREMV:
88874a4d8c2SCharles.Forsyth case ADIVWV: return OPVCC(31,491,1,0);
88974a4d8c2SCharles.Forsyth case AREMVCC:
89074a4d8c2SCharles.Forsyth case ADIVWVCC: return OPVCC(31,491,1,1);
89174a4d8c2SCharles.Forsyth case AREMU:
89274a4d8c2SCharles.Forsyth case ADIVWU: return OPVCC(31,459,0,0);
89374a4d8c2SCharles.Forsyth case AREMUCC:
89474a4d8c2SCharles.Forsyth case ADIVWUCC: return OPVCC(31,459,0,1);
89574a4d8c2SCharles.Forsyth case AREMUV:
89674a4d8c2SCharles.Forsyth case ADIVWUV: return OPVCC(31,459,1,0);
89774a4d8c2SCharles.Forsyth case AREMUVCC:
89874a4d8c2SCharles.Forsyth case ADIVWUVCC: return OPVCC(31,459,1,1);
89974a4d8c2SCharles.Forsyth
90074a4d8c2SCharles.Forsyth case AEIEIO: return OPVCC(31,854,0,0);
90174a4d8c2SCharles.Forsyth
90274a4d8c2SCharles.Forsyth case AEQV: return OPVCC(31,284,0,0);
90374a4d8c2SCharles.Forsyth case AEQVCC: return OPVCC(31,284,0,1);
90474a4d8c2SCharles.Forsyth
90574a4d8c2SCharles.Forsyth case AEXTSB: return OPVCC(31,954,0,0);
90674a4d8c2SCharles.Forsyth case AEXTSBCC: return OPVCC(31,954,0,1);
90774a4d8c2SCharles.Forsyth case AEXTSH: return OPVCC(31,922,0,0);
90874a4d8c2SCharles.Forsyth case AEXTSHCC: return OPVCC(31,922,0,1);
90974a4d8c2SCharles.Forsyth
91074a4d8c2SCharles.Forsyth case AFABS: return OPVCC(63,264,0,0);
91174a4d8c2SCharles.Forsyth case AFABSCC: return OPVCC(63,264,0,1);
91274a4d8c2SCharles.Forsyth case AFADD: return OPVCC(63,21,0,0);
91374a4d8c2SCharles.Forsyth case AFADDCC: return OPVCC(63,21,0,1);
91474a4d8c2SCharles.Forsyth case AFADDS: return OPVCC(59,21,0,0);
91574a4d8c2SCharles.Forsyth case AFADDSCC: return OPVCC(59,21,0,1);
91674a4d8c2SCharles.Forsyth case AFCMPO: return OPVCC(63,32,0,0);
91774a4d8c2SCharles.Forsyth case AFCMPU: return OPVCC(63,0,0,0);
91874a4d8c2SCharles.Forsyth case AFCTIW: return OPVCC(63,14,0,0);
91974a4d8c2SCharles.Forsyth case AFCTIWCC: return OPVCC(63,14,0,1);
92074a4d8c2SCharles.Forsyth case AFCTIWZ: return OPVCC(63,15,0,0);
92174a4d8c2SCharles.Forsyth case AFCTIWZCC: return OPVCC(63,15,0,1);
92274a4d8c2SCharles.Forsyth case AFDIV: return OPVCC(63,18,0,0);
92374a4d8c2SCharles.Forsyth case AFDIVCC: return OPVCC(63,18,0,1);
92474a4d8c2SCharles.Forsyth case AFDIVS: return OPVCC(59,18,0,0);
92574a4d8c2SCharles.Forsyth case AFDIVSCC: return OPVCC(59,18,0,1);
92674a4d8c2SCharles.Forsyth case AFMADD: return OPVCC(63,29,0,0);
92774a4d8c2SCharles.Forsyth case AFMADDCC: return OPVCC(63,29,0,1);
92874a4d8c2SCharles.Forsyth case AFMADDS: return OPVCC(59,29,0,0);
92974a4d8c2SCharles.Forsyth case AFMADDSCC: return OPVCC(59,29,0,1);
93074a4d8c2SCharles.Forsyth case AFMOVS:
93174a4d8c2SCharles.Forsyth case AFMOVD: return OPVCC(63,72,0,0); /* load */
93274a4d8c2SCharles.Forsyth case AFMOVDCC: return OPVCC(63,72,0,1);
93374a4d8c2SCharles.Forsyth case AFMSUB: return OPVCC(63,28,0,0);
93474a4d8c2SCharles.Forsyth case AFMSUBCC: return OPVCC(63,28,0,1);
93574a4d8c2SCharles.Forsyth case AFMSUBS: return OPVCC(59,28,0,0);
93674a4d8c2SCharles.Forsyth case AFMSUBSCC: return OPVCC(59,28,0,1);
93774a4d8c2SCharles.Forsyth case AFMUL: return OPVCC(63,25,0,0);
93874a4d8c2SCharles.Forsyth case AFMULCC: return OPVCC(63,25,0,1);
93974a4d8c2SCharles.Forsyth case AFMULS: return OPVCC(59,25,0,0);
94074a4d8c2SCharles.Forsyth case AFMULSCC: return OPVCC(59,25,0,1);
94174a4d8c2SCharles.Forsyth case AFNABS: return OPVCC(63,136,0,0);
94274a4d8c2SCharles.Forsyth case AFNABSCC: return OPVCC(63,136,0,1);
94374a4d8c2SCharles.Forsyth case AFNEG: return OPVCC(63,40,0,0);
94474a4d8c2SCharles.Forsyth case AFNEGCC: return OPVCC(63,40,0,1);
94574a4d8c2SCharles.Forsyth case AFNMADD: return OPVCC(63,31,0,0);
94674a4d8c2SCharles.Forsyth case AFNMADDCC: return OPVCC(63,31,0,1);
94774a4d8c2SCharles.Forsyth case AFNMADDS: return OPVCC(59,31,0,0);
94874a4d8c2SCharles.Forsyth case AFNMADDSCC: return OPVCC(59,31,0,1);
94974a4d8c2SCharles.Forsyth case AFNMSUB: return OPVCC(63,30,0,0);
95074a4d8c2SCharles.Forsyth case AFNMSUBCC: return OPVCC(63,30,0,1);
95174a4d8c2SCharles.Forsyth case AFNMSUBS: return OPVCC(59,30,0,0);
95274a4d8c2SCharles.Forsyth case AFNMSUBSCC: return OPVCC(59,30,0,1);
953d67b7dadSforsyth case AFRES: return OPVCC(59,24,0,0);
954d67b7dadSforsyth case AFRESCC: return OPVCC(59,24,0,1);
95574a4d8c2SCharles.Forsyth case AFRSP: return OPVCC(63,12,0,0);
95674a4d8c2SCharles.Forsyth case AFRSPCC: return OPVCC(63,12,0,1);
957d67b7dadSforsyth case AFRSQRTE: return OPVCC(63,26,0,0);
958d67b7dadSforsyth case AFRSQRTECC: return OPVCC(63,26,0,1);
959d67b7dadSforsyth case AFSEL: return OPVCC(63,23,0,0);
960d67b7dadSforsyth case AFSELCC: return OPVCC(63,23,0,1);
961d67b7dadSforsyth case AFSQRT: return OPVCC(63,22,0,0);
962d67b7dadSforsyth case AFSQRTCC: return OPVCC(63,22,0,1);
963d67b7dadSforsyth case AFSQRTS: return OPVCC(59,22,0,0);
964d67b7dadSforsyth case AFSQRTSCC: return OPVCC(59,22,0,1);
96574a4d8c2SCharles.Forsyth case AFSUB: return OPVCC(63,20,0,0);
96674a4d8c2SCharles.Forsyth case AFSUBCC: return OPVCC(63,20,0,1);
96774a4d8c2SCharles.Forsyth case AFSUBS: return OPVCC(59,20,0,0);
96874a4d8c2SCharles.Forsyth case AFSUBSCC: return OPVCC(59,20,0,1);
96974a4d8c2SCharles.Forsyth
970d67b7dadSforsyth /* fp2 */
971d67b7dadSforsyth case AFPMUL: return OPVCC(0,8,0,0);
972d67b7dadSforsyth case AFXMUL: return OPVCC(0,9,0,0);
973d67b7dadSforsyth case AFXPMUL: return OPVCC(0,10,0,0);
974d67b7dadSforsyth case AFXSMUL: return OPVCC(0,11,0,0);
975d67b7dadSforsyth case AFPADD: return OPVCC(0,12,0,0);
976d67b7dadSforsyth case AFPSUB: return OPVCC(0,13,0,0);
977d67b7dadSforsyth case AFPRE: return OPVCC(0,14,0,0);
978d67b7dadSforsyth case AFPRSQRTE: return OPVCC(0,15,0,0);
979d67b7dadSforsyth case AFPMADD: return OPVCC(0,16,0,0);
980d67b7dadSforsyth case AFXMADD: return OPVCC(0,17,0,0);
981d67b7dadSforsyth case AFXCPMADD: return OPVCC(0,18,0,0);
982d67b7dadSforsyth case AFXCSMADD: return OPVCC(0,19,0,0);
983d67b7dadSforsyth case AFPNMADD: return OPVCC(0,20,0,0);
984d67b7dadSforsyth case AFXNMADD: return OPVCC(0,21,0,0);
985d67b7dadSforsyth case AFXCPNMADD: return OPVCC(0,22,0,0);
986d67b7dadSforsyth case AFXCSNMADD: return OPVCC(0,23,0,0);
987d67b7dadSforsyth case AFPMSUB: return OPVCC(0,24,0,0);
988d67b7dadSforsyth case AFXMSUB: return OPVCC(0,25,0,0);
989d67b7dadSforsyth case AFXCPMSUB: return OPVCC(0,26,0,0);
990d67b7dadSforsyth case AFXCSMSUB: return OPVCC(0,27,0,0);
991d67b7dadSforsyth case AFPNMSUB: return OPVCC(0,28,0,0);
992d67b7dadSforsyth case AFXNMSUB: return OPVCC(0,29,0,0);
993d67b7dadSforsyth case AFXCPNMSUB: return OPVCC(0,30,0,0);
994d67b7dadSforsyth case AFXCSNMSUB: return OPVCC(0,31,0,0);
995d67b7dadSforsyth case AFPABS: return OPVCC(0,96,0,0);
996d67b7dadSforsyth case AFPNEG: return OPVCC(0,160,0,0);
997d67b7dadSforsyth case AFPRSP: return OPVCC(0,192,0,0);
998d67b7dadSforsyth case AFPNABS: return OPVCC(0,224,0,0);
999d67b7dadSforsyth case AFSCMP: return OPVCC(0,320,0,0)|(3<<21);
1000d67b7dadSforsyth case AFSABS: return OPVCC(0,352,0,0);
1001d67b7dadSforsyth case AFSNEG: return OPVCC(0,416,0,0);
1002d67b7dadSforsyth case AFSNABS: return OPVCC(0,480,0,0);
1003d67b7dadSforsyth case AFPCTIW: return OPVCC(0,576,0,0);
1004d67b7dadSforsyth case AFPCTIWZ: return OPVCC(0,704,0,0);
1005d67b7dadSforsyth
1006d67b7dadSforsyth case AFPMOVD: return OPVCC(0,32,0,0); /* fpmr */
1007d67b7dadSforsyth case AFSMOVD: return OPVCC(0,288,0,0); /* fsmr */
1008d67b7dadSforsyth case AFXMOVD: return OPVCC(0,544,0,0); /* fxmr */
1009*647adfbcSforsyth case AFMOVSPD: return OPVCC(0,800,0,0); /* fsmtp */
1010*647adfbcSforsyth case AFMOVPSD: return OPVCC(0,928,0,0); /* fsmfp */
1011d67b7dadSforsyth
1012d67b7dadSforsyth case AFXCPNPMA: return OPVCC(4,24,0,0);
1013d67b7dadSforsyth case AFXCSNPMA: return OPVCC(4,25,0,0);
1014d67b7dadSforsyth case AFXCPNSMA: return OPVCC(4,26,0,0);
1015d67b7dadSforsyth case AFXCSNSMA: return OPVCC(4,27,0,0);
1016d67b7dadSforsyth case AFXCXNPMA: return OPVCC(4,29,0,0);
1017d67b7dadSforsyth case AFXCXNSMA: return OPVCC(4,30,0,0);
1018d67b7dadSforsyth case AFXCXMA: return OPVCC(4,28,0,0);
1019d67b7dadSforsyth case AFXCXNMS: return OPVCC(4,31,0,0);
1020d67b7dadSforsyth
102174a4d8c2SCharles.Forsyth case AICBI: return OPVCC(31,982,0,0);
102274a4d8c2SCharles.Forsyth case AISYNC: return OPVCC(19,150,0,0);
102374a4d8c2SCharles.Forsyth
102474a4d8c2SCharles.Forsyth case AMTFSB0: return OPVCC(63,70,0,0);
102574a4d8c2SCharles.Forsyth case AMTFSB0CC: return OPVCC(63,70,0,1);
102674a4d8c2SCharles.Forsyth case AMTFSB1: return OPVCC(63,38,0,0);
102774a4d8c2SCharles.Forsyth case AMTFSB1CC: return OPVCC(63,38,0,1);
102874a4d8c2SCharles.Forsyth
102974a4d8c2SCharles.Forsyth case AMULHW: return OPVCC(31,75,0,0);
103074a4d8c2SCharles.Forsyth case AMULHWCC: return OPVCC(31,75,0,1);
103174a4d8c2SCharles.Forsyth case AMULHWU: return OPVCC(31,11,0,0);
103274a4d8c2SCharles.Forsyth case AMULHWUCC: return OPVCC(31,11,0,1);
103374a4d8c2SCharles.Forsyth case AMULLW: return OPVCC(31,235,0,0);
103474a4d8c2SCharles.Forsyth case AMULLWCC: return OPVCC(31,235,0,1);
103574a4d8c2SCharles.Forsyth case AMULLWV: return OPVCC(31,235,1,0);
103674a4d8c2SCharles.Forsyth case AMULLWVCC: return OPVCC(31,235,1,1);
103774a4d8c2SCharles.Forsyth
103874a4d8c2SCharles.Forsyth /* the following group is only available on IBM embedded powerpc */
103974a4d8c2SCharles.Forsyth case AMACCHW: return OPVCC(4,172,0,0);
104074a4d8c2SCharles.Forsyth case AMACCHWCC: return OPVCC(4,172,0,1);
104174a4d8c2SCharles.Forsyth case AMACCHWS: return OPVCC(4,236,0,0);
104274a4d8c2SCharles.Forsyth case AMACCHWSCC: return OPVCC(4,236,0,1);
104374a4d8c2SCharles.Forsyth case AMACCHWSU: return OPVCC(4,204,0,0);
104474a4d8c2SCharles.Forsyth case AMACCHWSUCC: return OPVCC(4,204,0,1);
104574a4d8c2SCharles.Forsyth case AMACCHWSUV: return OPVCC(4,204,1,0);
104674a4d8c2SCharles.Forsyth case AMACCHWSUVCC: return OPVCC(4,204,1,1);
104774a4d8c2SCharles.Forsyth case AMACCHWSV: return OPVCC(4,236,1,0);
104874a4d8c2SCharles.Forsyth case AMACCHWSVCC: return OPVCC(4,236,1,1);
104974a4d8c2SCharles.Forsyth case AMACCHWU: return OPVCC(4,140,0,0);
105074a4d8c2SCharles.Forsyth case AMACCHWUCC: return OPVCC(4,140,0,1);
105174a4d8c2SCharles.Forsyth case AMACCHWUV: return OPVCC(4,140,1,0);
105274a4d8c2SCharles.Forsyth case AMACCHWUVCC: return OPVCC(4,140,1,1);
105374a4d8c2SCharles.Forsyth case AMACCHWV: return OPVCC(4,172,1,0);
105474a4d8c2SCharles.Forsyth case AMACCHWVCC: return OPVCC(4,172,1,1);
105574a4d8c2SCharles.Forsyth case AMACHHW: return OPVCC(4,44,0,0);
105674a4d8c2SCharles.Forsyth case AMACHHWCC: return OPVCC(4,44,0,1);
105774a4d8c2SCharles.Forsyth case AMACHHWS: return OPVCC(4,108,0,0);
105874a4d8c2SCharles.Forsyth case AMACHHWSCC: return OPVCC(4,108,0,1);
105974a4d8c2SCharles.Forsyth case AMACHHWSU: return OPVCC(4,76,0,0);
106074a4d8c2SCharles.Forsyth case AMACHHWSUCC: return OPVCC(4,76,0,1);
106174a4d8c2SCharles.Forsyth case AMACHHWSUV: return OPVCC(4,76,1,0);
106274a4d8c2SCharles.Forsyth case AMACHHWSUVCC: return OPVCC(4,76,1,1);
106374a4d8c2SCharles.Forsyth case AMACHHWSV: return OPVCC(4,108,1,0);
106474a4d8c2SCharles.Forsyth case AMACHHWSVCC: return OPVCC(4,108,1,1);
106574a4d8c2SCharles.Forsyth case AMACHHWU: return OPVCC(4,12,0,0);
106674a4d8c2SCharles.Forsyth case AMACHHWUCC: return OPVCC(4,12,0,1);
106774a4d8c2SCharles.Forsyth case AMACHHWUV: return OPVCC(4,12,1,0);
106874a4d8c2SCharles.Forsyth case AMACHHWUVCC: return OPVCC(4,12,1,1);
106974a4d8c2SCharles.Forsyth case AMACHHWV: return OPVCC(4,44,1,0);
107074a4d8c2SCharles.Forsyth case AMACHHWVCC: return OPVCC(4,44,1,1);
107174a4d8c2SCharles.Forsyth case AMACLHW: return OPVCC(4,428,0,0);
107274a4d8c2SCharles.Forsyth case AMACLHWCC: return OPVCC(4,428,0,1);
107374a4d8c2SCharles.Forsyth case AMACLHWS: return OPVCC(4,492,0,0);
107474a4d8c2SCharles.Forsyth case AMACLHWSCC: return OPVCC(4,492,0,1);
107574a4d8c2SCharles.Forsyth case AMACLHWSU: return OPVCC(4,460,0,0);
107674a4d8c2SCharles.Forsyth case AMACLHWSUCC: return OPVCC(4,460,0,1);
107774a4d8c2SCharles.Forsyth case AMACLHWSUV: return OPVCC(4,460,1,0);
107874a4d8c2SCharles.Forsyth case AMACLHWSUVCC: return OPVCC(4,460,1,1);
107974a4d8c2SCharles.Forsyth case AMACLHWSV: return OPVCC(4,492,1,0);
108074a4d8c2SCharles.Forsyth case AMACLHWSVCC: return OPVCC(4,492,1,1);
108174a4d8c2SCharles.Forsyth case AMACLHWU: return OPVCC(4,396,0,0);
108274a4d8c2SCharles.Forsyth case AMACLHWUCC: return OPVCC(4,396,0,1);
108374a4d8c2SCharles.Forsyth case AMACLHWUV: return OPVCC(4,396,1,0);
108474a4d8c2SCharles.Forsyth case AMACLHWUVCC: return OPVCC(4,396,1,1);
108574a4d8c2SCharles.Forsyth case AMACLHWV: return OPVCC(4,428,1,0);
108674a4d8c2SCharles.Forsyth case AMACLHWVCC: return OPVCC(4,428,1,1);
108774a4d8c2SCharles.Forsyth case AMULCHW: return OPVCC(4,168,0,0);
108874a4d8c2SCharles.Forsyth case AMULCHWCC: return OPVCC(4,168,0,1);
108974a4d8c2SCharles.Forsyth case AMULCHWU: return OPVCC(4,136,0,0);
109074a4d8c2SCharles.Forsyth case AMULCHWUCC: return OPVCC(4,136,0,1);
109174a4d8c2SCharles.Forsyth case AMULHHW: return OPVCC(4,40,0,0);
109274a4d8c2SCharles.Forsyth case AMULHHWCC: return OPVCC(4,40,0,1);
109374a4d8c2SCharles.Forsyth case AMULHHWU: return OPVCC(4,8,0,0);
109474a4d8c2SCharles.Forsyth case AMULHHWUCC: return OPVCC(4,8,0,1);
109574a4d8c2SCharles.Forsyth case AMULLHW: return OPVCC(4,424,0,0);
109674a4d8c2SCharles.Forsyth case AMULLHWCC: return OPVCC(4,424,0,1);
109774a4d8c2SCharles.Forsyth case AMULLHWU: return OPVCC(4,392,0,0);
109874a4d8c2SCharles.Forsyth case AMULLHWUCC: return OPVCC(4,392,0,1);
109974a4d8c2SCharles.Forsyth case ANMACCHW: return OPVCC(4,174,0,0);
110074a4d8c2SCharles.Forsyth case ANMACCHWCC: return OPVCC(4,174,0,1);
110174a4d8c2SCharles.Forsyth case ANMACCHWS: return OPVCC(4,238,0,0);
110274a4d8c2SCharles.Forsyth case ANMACCHWSCC: return OPVCC(4,238,0,1);
110374a4d8c2SCharles.Forsyth case ANMACCHWSV: return OPVCC(4,238,1,0);
110474a4d8c2SCharles.Forsyth case ANMACCHWSVCC: return OPVCC(4,238,1,1);
110574a4d8c2SCharles.Forsyth case ANMACCHWV: return OPVCC(4,174,1,0);
110674a4d8c2SCharles.Forsyth case ANMACCHWVCC: return OPVCC(4,174,1,1);
110774a4d8c2SCharles.Forsyth case ANMACHHW: return OPVCC(4,46,0,0);
110874a4d8c2SCharles.Forsyth case ANMACHHWCC: return OPVCC(4,46,0,1);
110974a4d8c2SCharles.Forsyth case ANMACHHWS: return OPVCC(4,110,0,0);
111074a4d8c2SCharles.Forsyth case ANMACHHWSCC: return OPVCC(4,110,0,1);
111174a4d8c2SCharles.Forsyth case ANMACHHWSV: return OPVCC(4,110,1,0);
111274a4d8c2SCharles.Forsyth case ANMACHHWSVCC: return OPVCC(4,110,1,1);
111374a4d8c2SCharles.Forsyth case ANMACHHWV: return OPVCC(4,46,1,0);
111474a4d8c2SCharles.Forsyth case ANMACHHWVCC: return OPVCC(4,46,1,1);
111574a4d8c2SCharles.Forsyth case ANMACLHW: return OPVCC(4,430,0,0);
111674a4d8c2SCharles.Forsyth case ANMACLHWCC: return OPVCC(4,430,0,1);
111774a4d8c2SCharles.Forsyth case ANMACLHWS: return OPVCC(4,494,0,0);
111874a4d8c2SCharles.Forsyth case ANMACLHWSCC: return OPVCC(4,494,0,1);
111974a4d8c2SCharles.Forsyth case ANMACLHWSV: return OPVCC(4,494,1,0);
112074a4d8c2SCharles.Forsyth case ANMACLHWSVCC: return OPVCC(4,494,1,1);
112174a4d8c2SCharles.Forsyth case ANMACLHWV: return OPVCC(4,430,1,0);
112274a4d8c2SCharles.Forsyth case ANMACLHWVCC: return OPVCC(4,430,1,1);
112374a4d8c2SCharles.Forsyth
112474a4d8c2SCharles.Forsyth case ANAND: return OPVCC(31,476,0,0);
112574a4d8c2SCharles.Forsyth case ANANDCC: return OPVCC(31,476,0,1);
112674a4d8c2SCharles.Forsyth case ANEG: return OPVCC(31,104,0,0);
112774a4d8c2SCharles.Forsyth case ANEGCC: return OPVCC(31,104,0,1);
112874a4d8c2SCharles.Forsyth case ANEGV: return OPVCC(31,104,1,0);
112974a4d8c2SCharles.Forsyth case ANEGVCC: return OPVCC(31,104,1,1);
113074a4d8c2SCharles.Forsyth case ANOR: return OPVCC(31,124,0,0);
113174a4d8c2SCharles.Forsyth case ANORCC: return OPVCC(31,124,0,1);
113274a4d8c2SCharles.Forsyth case AOR: return OPVCC(31,444,0,0);
113374a4d8c2SCharles.Forsyth case AORCC: return OPVCC(31,444,0,1);
113474a4d8c2SCharles.Forsyth case AORN: return OPVCC(31,412,0,0);
113574a4d8c2SCharles.Forsyth case AORNCC: return OPVCC(31,412,0,1);
113674a4d8c2SCharles.Forsyth
113774a4d8c2SCharles.Forsyth case ARFI: return OPVCC(19,50,0,0);
113874a4d8c2SCharles.Forsyth case ARFCI: return OPVCC(19,51,0,0);
113974a4d8c2SCharles.Forsyth
114074a4d8c2SCharles.Forsyth case ARLWMI: return OPVCC(20,0,0,0);
114174a4d8c2SCharles.Forsyth case ARLWMICC: return OPVCC(20,0,0,1);
114274a4d8c2SCharles.Forsyth case ARLWNM: return OPVCC(23,0,0,0);
114374a4d8c2SCharles.Forsyth case ARLWNMCC: return OPVCC(23,0,0,1);
114474a4d8c2SCharles.Forsyth
114574a4d8c2SCharles.Forsyth case ASYSCALL: return OPVCC(17,1,0,0);
114674a4d8c2SCharles.Forsyth
114774a4d8c2SCharles.Forsyth case ASLW: return OPVCC(31,24,0,0);
114874a4d8c2SCharles.Forsyth case ASLWCC: return OPVCC(31,24,0,1);
114974a4d8c2SCharles.Forsyth
115074a4d8c2SCharles.Forsyth case ASRAW: return OPVCC(31,792,0,0);
115174a4d8c2SCharles.Forsyth case ASRAWCC: return OPVCC(31,792,0,1);
115274a4d8c2SCharles.Forsyth
115374a4d8c2SCharles.Forsyth case ASRW: return OPVCC(31,536,0,0);
115474a4d8c2SCharles.Forsyth case ASRWCC: return OPVCC(31,536,0,1);
115574a4d8c2SCharles.Forsyth
115674a4d8c2SCharles.Forsyth case ASUB: return OPVCC(31,40,0,0);
115774a4d8c2SCharles.Forsyth case ASUBCC: return OPVCC(31,40,0,1);
115874a4d8c2SCharles.Forsyth case ASUBV: return OPVCC(31,40,1,0);
115974a4d8c2SCharles.Forsyth case ASUBVCC: return OPVCC(31,40,1,1);
116074a4d8c2SCharles.Forsyth case ASUBC: return OPVCC(31,8,0,0);
116174a4d8c2SCharles.Forsyth case ASUBCCC: return OPVCC(31,8,0,1);
116274a4d8c2SCharles.Forsyth case ASUBCV: return OPVCC(31,8,1,0);
116374a4d8c2SCharles.Forsyth case ASUBCVCC: return OPVCC(31,8,1,1);
116474a4d8c2SCharles.Forsyth case ASUBE: return OPVCC(31,136,0,0);
116574a4d8c2SCharles.Forsyth case ASUBECC: return OPVCC(31,136,0,1);
116674a4d8c2SCharles.Forsyth case ASUBEV: return OPVCC(31,136,1,0);
116774a4d8c2SCharles.Forsyth case ASUBEVCC: return OPVCC(31,136,1,1);
116874a4d8c2SCharles.Forsyth case ASUBME: return OPVCC(31,232,0,0);
116974a4d8c2SCharles.Forsyth case ASUBMECC: return OPVCC(31,232,0,1);
117074a4d8c2SCharles.Forsyth case ASUBMEV: return OPVCC(31,232,1,0);
117174a4d8c2SCharles.Forsyth case ASUBMEVCC: return OPVCC(31,232,1,1);
117274a4d8c2SCharles.Forsyth case ASUBZE: return OPVCC(31,200,0,0);
117374a4d8c2SCharles.Forsyth case ASUBZECC: return OPVCC(31,200,0,1);
117474a4d8c2SCharles.Forsyth case ASUBZEV: return OPVCC(31,200,1,0);
117574a4d8c2SCharles.Forsyth case ASUBZEVCC: return OPVCC(31,200,1,1);
117674a4d8c2SCharles.Forsyth
117774a4d8c2SCharles.Forsyth case ASYNC: return OPVCC(31,598,0,0);
117874a4d8c2SCharles.Forsyth case ATLBIE: return OPVCC(31,306,0,0);
117974a4d8c2SCharles.Forsyth case ATW: return OPVCC(31,4,0,0);
118074a4d8c2SCharles.Forsyth
118174a4d8c2SCharles.Forsyth case AXOR: return OPVCC(31,316,0,0);
118274a4d8c2SCharles.Forsyth case AXORCC: return OPVCC(31,316,0,1);
118374a4d8c2SCharles.Forsyth }
118474a4d8c2SCharles.Forsyth diag("bad r/r opcode %A", a);
118574a4d8c2SCharles.Forsyth return 0;
118674a4d8c2SCharles.Forsyth }
118774a4d8c2SCharles.Forsyth
118874a4d8c2SCharles.Forsyth long
opirr(int a)118974a4d8c2SCharles.Forsyth opirr(int a)
119074a4d8c2SCharles.Forsyth {
119174a4d8c2SCharles.Forsyth switch(a) {
119274a4d8c2SCharles.Forsyth case AADD: return OPVCC(14,0,0,0);
119374a4d8c2SCharles.Forsyth case AADDC: return OPVCC(12,0,0,0);
119474a4d8c2SCharles.Forsyth case AADDCCC: return OPVCC(13,0,0,0);
119574a4d8c2SCharles.Forsyth case AADD+AEND: return OPVCC(15,0,0,0); /* ADDIS/CAU */
119674a4d8c2SCharles.Forsyth
119774a4d8c2SCharles.Forsyth case AANDCC: return OPVCC(28,0,0,0);
119874a4d8c2SCharles.Forsyth case AANDCC+AEND: return OPVCC(29,0,0,0); /* ANDIS./ANDIU. */
119974a4d8c2SCharles.Forsyth
120074a4d8c2SCharles.Forsyth case ABR: return OPVCC(18,0,0,0);
120174a4d8c2SCharles.Forsyth case ABL: return OPVCC(18,0,0,0) | 1;
120274a4d8c2SCharles.Forsyth case ABC: return OPVCC(16,0,0,0);
120374a4d8c2SCharles.Forsyth case ABCL: return OPVCC(16,0,0,0) | 1;
120474a4d8c2SCharles.Forsyth
120574a4d8c2SCharles.Forsyth case ABEQ: return AOP_RRR(16<<26,12,2,0);
120674a4d8c2SCharles.Forsyth case ABGE: return AOP_RRR(16<<26,4,0,0);
120774a4d8c2SCharles.Forsyth case ABGT: return AOP_RRR(16<<26,12,1,0);
120874a4d8c2SCharles.Forsyth case ABLE: return AOP_RRR(16<<26,4,1,0);
120974a4d8c2SCharles.Forsyth case ABLT: return AOP_RRR(16<<26,12,0,0);
121074a4d8c2SCharles.Forsyth case ABNE: return AOP_RRR(16<<26,4,2,0);
121174a4d8c2SCharles.Forsyth case ABVC: return AOP_RRR(16<<26,4,3,0);
121274a4d8c2SCharles.Forsyth case ABVS: return AOP_RRR(16<<26,12,3,0);
121374a4d8c2SCharles.Forsyth
121474a4d8c2SCharles.Forsyth case ACMP: return OPVCC(11,0,0,0);
121574a4d8c2SCharles.Forsyth case ACMPU: return OPVCC(10,0,0,0);
121674a4d8c2SCharles.Forsyth case ALSW: return OPVCC(31,597,0,0);
121774a4d8c2SCharles.Forsyth
121874a4d8c2SCharles.Forsyth case AMULLW: return OPVCC(7,0,0,0);
121974a4d8c2SCharles.Forsyth
122074a4d8c2SCharles.Forsyth case AOR: return OPVCC(24,0,0,0);
122174a4d8c2SCharles.Forsyth case AOR+AEND: return OPVCC(25,0,0,0); /* ORIS/ORIU */
122274a4d8c2SCharles.Forsyth
122374a4d8c2SCharles.Forsyth case ARLWMI: return OPVCC(20,0,0,0); /* rlwimi */
122474a4d8c2SCharles.Forsyth case ARLWMICC: return OPVCC(20,0,0,1);
122574a4d8c2SCharles.Forsyth
122674a4d8c2SCharles.Forsyth case ARLWNM: return OPVCC(21,0,0,0); /* rlwinm */
122774a4d8c2SCharles.Forsyth case ARLWNMCC: return OPVCC(21,0,0,1);
122874a4d8c2SCharles.Forsyth
122974a4d8c2SCharles.Forsyth case ASRAW: return OPVCC(31,824,0,0);
123074a4d8c2SCharles.Forsyth case ASRAWCC: return OPVCC(31,824,0,1);
123174a4d8c2SCharles.Forsyth
123274a4d8c2SCharles.Forsyth case ASTSW: return OPVCC(31,725,0,0);
123374a4d8c2SCharles.Forsyth
123474a4d8c2SCharles.Forsyth case ASUBC: return OPVCC(8,0,0,0);
123574a4d8c2SCharles.Forsyth
123674a4d8c2SCharles.Forsyth case ATW: return OPVCC(3,0,0,0);
123774a4d8c2SCharles.Forsyth
123874a4d8c2SCharles.Forsyth case AXOR: return OPVCC(26,0,0,0); /* XORIL */
123974a4d8c2SCharles.Forsyth case AXOR+AEND: return OPVCC(27,0,0,0); /* XORIU */
124074a4d8c2SCharles.Forsyth }
124174a4d8c2SCharles.Forsyth diag("bad opcode i/r %A", a);
124274a4d8c2SCharles.Forsyth return 0;
124374a4d8c2SCharles.Forsyth }
124474a4d8c2SCharles.Forsyth
124574a4d8c2SCharles.Forsyth /*
124674a4d8c2SCharles.Forsyth * load o(a),d
124774a4d8c2SCharles.Forsyth */
124874a4d8c2SCharles.Forsyth long
opload(int a)124974a4d8c2SCharles.Forsyth opload(int a)
125074a4d8c2SCharles.Forsyth {
125174a4d8c2SCharles.Forsyth switch(a) {
125274a4d8c2SCharles.Forsyth case AMOVW: return OPVCC(32,0,0,0); /* lwz */
125374a4d8c2SCharles.Forsyth case AMOVWU: return OPVCC(33,0,0,0); /* lwzu */
125474a4d8c2SCharles.Forsyth case AMOVB:
125574a4d8c2SCharles.Forsyth case AMOVBZ: return OPVCC(34,0,0,0); /* load */
125674a4d8c2SCharles.Forsyth case AMOVBU:
125774a4d8c2SCharles.Forsyth case AMOVBZU: return OPVCC(35,0,0,0);
125874a4d8c2SCharles.Forsyth case AFMOVD: return OPVCC(50,0,0,0);
125974a4d8c2SCharles.Forsyth case AFMOVDU: return OPVCC(51,0,0,0);
126074a4d8c2SCharles.Forsyth case AFMOVS: return OPVCC(48,0,0,0);
126174a4d8c2SCharles.Forsyth case AFMOVSU: return OPVCC(49,0,0,0);
126274a4d8c2SCharles.Forsyth case AMOVH: return OPVCC(42,0,0,0);
126374a4d8c2SCharles.Forsyth case AMOVHU: return OPVCC(43,0,0,0);
126474a4d8c2SCharles.Forsyth case AMOVHZ: return OPVCC(40,0,0,0);
126574a4d8c2SCharles.Forsyth case AMOVHZU: return OPVCC(41,0,0,0);
126674a4d8c2SCharles.Forsyth case AMOVMW: return OPVCC(46,0,0,0); /* lmw */
126774a4d8c2SCharles.Forsyth }
126874a4d8c2SCharles.Forsyth diag("bad load opcode %A", a);
126974a4d8c2SCharles.Forsyth return 0;
127074a4d8c2SCharles.Forsyth }
127174a4d8c2SCharles.Forsyth
127274a4d8c2SCharles.Forsyth /*
127374a4d8c2SCharles.Forsyth * indexed load a(b),d
127474a4d8c2SCharles.Forsyth */
127574a4d8c2SCharles.Forsyth long
oploadx(int a)127674a4d8c2SCharles.Forsyth oploadx(int a)
127774a4d8c2SCharles.Forsyth {
127874a4d8c2SCharles.Forsyth switch(a) {
127974a4d8c2SCharles.Forsyth case AMOVW: return OPVCC(31,23,0,0); /* lwzx */
128074a4d8c2SCharles.Forsyth case AMOVWU: return OPVCC(31,55,0,0); /* lwzux */
128174a4d8c2SCharles.Forsyth case AMOVB:
128274a4d8c2SCharles.Forsyth case AMOVBZ: return OPVCC(31,87,0,0); /* lbzx */
128374a4d8c2SCharles.Forsyth case AMOVBU:
128474a4d8c2SCharles.Forsyth case AMOVBZU: return OPVCC(31,119,0,0); /* lbzux */
128574a4d8c2SCharles.Forsyth case AFMOVD: return OPVCC(31,599,0,0); /* lfdx */
128674a4d8c2SCharles.Forsyth case AFMOVDU: return OPVCC(31,631,0,0); /* lfdux */
128774a4d8c2SCharles.Forsyth case AFMOVS: return OPVCC(31,535,0,0); /* lfsx */
128874a4d8c2SCharles.Forsyth case AFMOVSU: return OPVCC(31,567,0,0); /* lfsux */
128974a4d8c2SCharles.Forsyth case AMOVH: return OPVCC(31,343,0,0); /* lhax */
129074a4d8c2SCharles.Forsyth case AMOVHU: return OPVCC(31,375,0,0); /* lhaux */
129174a4d8c2SCharles.Forsyth case AMOVHBR: return OPVCC(31,790,0,0); /* lhbrx */
129274a4d8c2SCharles.Forsyth case AMOVWBR: return OPVCC(31,534,0,0); /* lwbrx */
129374a4d8c2SCharles.Forsyth case AMOVHZ: return OPVCC(31,279,0,0); /* lhzx */
129474a4d8c2SCharles.Forsyth case AMOVHZU: return OPVCC(31,311,0,0); /* lhzux */
129574a4d8c2SCharles.Forsyth case AECIWX: return OPVCC(31,310,0,0); /* eciwx */
129674a4d8c2SCharles.Forsyth case ALWAR: return OPVCC(31,20,0,0); /* lwarx */
129774a4d8c2SCharles.Forsyth case ALSW: return OPVCC(31,533,0,0); /* lswx */
1298*647adfbcSforsyth case AFSMOVS: return OPVCC(31,142,0,0); /* lfssx */
1299*647adfbcSforsyth case AFSMOVSU: return OPVCC(31,174,0,0); /* lfssux */
1300*647adfbcSforsyth case AFSMOVD: return OPVCC(31,206,0,0); /* lfsdx */
1301*647adfbcSforsyth case AFSMOVDU: return OPVCC(31,238,0,0); /* lfsdux */
1302*647adfbcSforsyth case AFXMOVS: return OPVCC(31,270,0,0); /* lfxsx */
1303*647adfbcSforsyth case AFXMOVSU: return OPVCC(31,302,0,0); /* lfxsux */
1304*647adfbcSforsyth case AFXMOVD: return OPVCC(31,334,0,0); /* lfxdx */
1305*647adfbcSforsyth case AFXMOVDU: return OPVCC(31,366,0,0); /* lfxdux */
1306*647adfbcSforsyth case AFPMOVS: return OPVCC(31,398,0,0); /* lfpsx */
1307*647adfbcSforsyth case AFPMOVSU: return OPVCC(31,430,0,0); /* lfpsux */
1308*647adfbcSforsyth case AFPMOVD: return OPVCC(31,462,0,0); /* lfpdx */
1309*647adfbcSforsyth case AFPMOVDU: return OPVCC(31,494,0,0); /* lfpdux */
131074a4d8c2SCharles.Forsyth }
131174a4d8c2SCharles.Forsyth diag("bad loadx opcode %A", a);
131274a4d8c2SCharles.Forsyth return 0;
131374a4d8c2SCharles.Forsyth }
131474a4d8c2SCharles.Forsyth
131574a4d8c2SCharles.Forsyth /*
131674a4d8c2SCharles.Forsyth * store s,o(d)
131774a4d8c2SCharles.Forsyth */
131874a4d8c2SCharles.Forsyth long
opstore(int a)131974a4d8c2SCharles.Forsyth opstore(int a)
132074a4d8c2SCharles.Forsyth {
132174a4d8c2SCharles.Forsyth switch(a) {
132274a4d8c2SCharles.Forsyth case AMOVB:
132374a4d8c2SCharles.Forsyth case AMOVBZ: return OPVCC(38,0,0,0); /* stb */
132474a4d8c2SCharles.Forsyth case AMOVBU:
132574a4d8c2SCharles.Forsyth case AMOVBZU: return OPVCC(39,0,0,0); /* stbu */
132674a4d8c2SCharles.Forsyth case AFMOVD: return OPVCC(54,0,0,0); /* stfd */
132774a4d8c2SCharles.Forsyth case AFMOVDU: return OPVCC(55,0,0,0); /* stfdu */
132874a4d8c2SCharles.Forsyth case AFMOVS: return OPVCC(52,0,0,0); /* stfs */
132974a4d8c2SCharles.Forsyth case AFMOVSU: return OPVCC(53,0,0,0); /* stfsu */
133074a4d8c2SCharles.Forsyth case AMOVHZ:
133174a4d8c2SCharles.Forsyth case AMOVH: return OPVCC(44,0,0,0); /* sth */
133274a4d8c2SCharles.Forsyth case AMOVHZU:
133374a4d8c2SCharles.Forsyth case AMOVHU: return OPVCC(45,0,0,0); /* sthu */
133474a4d8c2SCharles.Forsyth case AMOVMW: return OPVCC(47,0,0,0); /* stmw */
133574a4d8c2SCharles.Forsyth case ASTSW: return OPVCC(31,725,0,0); /* stswi */
133674a4d8c2SCharles.Forsyth case AMOVW: return OPVCC(36,0,0,0); /* stw */
133774a4d8c2SCharles.Forsyth case AMOVWU: return OPVCC(37,0,0,0); /* stwu */
133874a4d8c2SCharles.Forsyth }
133974a4d8c2SCharles.Forsyth diag("unknown store opcode %A", a);
134074a4d8c2SCharles.Forsyth return 0;
134174a4d8c2SCharles.Forsyth }
134274a4d8c2SCharles.Forsyth
134374a4d8c2SCharles.Forsyth /*
134474a4d8c2SCharles.Forsyth * indexed store s,a(b)
134574a4d8c2SCharles.Forsyth */
134674a4d8c2SCharles.Forsyth long
opstorex(int a)134774a4d8c2SCharles.Forsyth opstorex(int a)
134874a4d8c2SCharles.Forsyth {
134974a4d8c2SCharles.Forsyth switch(a) {
135074a4d8c2SCharles.Forsyth case AMOVB:
135174a4d8c2SCharles.Forsyth case AMOVBZ: return OPVCC(31,215,0,0); /* stbx */
135274a4d8c2SCharles.Forsyth case AMOVBU:
135374a4d8c2SCharles.Forsyth case AMOVBZU: return OPVCC(31,247,0,0); /* stbux */
135474a4d8c2SCharles.Forsyth case AFMOVD: return OPVCC(31,727,0,0); /* stfdx */
135574a4d8c2SCharles.Forsyth case AFMOVDU: return OPVCC(31,759,0,0); /* stfdux */
135674a4d8c2SCharles.Forsyth case AFMOVS: return OPVCC(31,663,0,0); /* stfsx */
135774a4d8c2SCharles.Forsyth case AFMOVSU: return OPVCC(31,695,0,0); /* stfsux */
135874a4d8c2SCharles.Forsyth case AMOVHZ:
135974a4d8c2SCharles.Forsyth case AMOVH: return OPVCC(31,407,0,0); /* sthx */
136074a4d8c2SCharles.Forsyth case AMOVHBR: return OPVCC(31,918,0,0); /* sthbrx */
136174a4d8c2SCharles.Forsyth case AMOVHZU:
136274a4d8c2SCharles.Forsyth case AMOVHU: return OPVCC(31,439,0,0); /* sthux */
136374a4d8c2SCharles.Forsyth case AMOVW: return OPVCC(31,151,0,0); /* stwx */
136474a4d8c2SCharles.Forsyth case AMOVWU: return OPVCC(31,183,0,0); /* stwux */
136574a4d8c2SCharles.Forsyth case ASTSW: return OPVCC(31,661,0,0); /* stswx */
136674a4d8c2SCharles.Forsyth case AMOVWBR: return OPVCC(31,662,0,0); /* stwbrx */
136774a4d8c2SCharles.Forsyth case ASTWCCC: return OPVCC(31,150,0,1); /* stwcx. */
136874a4d8c2SCharles.Forsyth case AECOWX: return OPVCC(31,438,0,0); /* ecowx */
1369*647adfbcSforsyth case AFSMOVS: return OPVCC(31,654,0,0); /* stfssx */
1370*647adfbcSforsyth /* case AFSMOVSU: return OPVCC(31,yy,0,0); */ /* stfssux not known */
1371*647adfbcSforsyth /* case AFSMOVD: return OPVCC(31,yy,0,0); */ /* stfsdx not known */
1372*647adfbcSforsyth case AFSMOVDU: return OPVCC(31,750,0,0); /* stfsdux */
1373*647adfbcSforsyth case AFXMOVS: return OPVCC(31,782,0,0); /* stfxsx */
1374*647adfbcSforsyth case AFXMOVSU: return OPVCC(31,814,0,0); /* stfxsux */
1375*647adfbcSforsyth case AFXMOVD: return OPVCC(31,846,0,0); /* stfxdx */
1376*647adfbcSforsyth case AFXMOVDU: return OPVCC(31,878,0,0); /* stfxdux */
1377*647adfbcSforsyth case AFPMOVS: return OPVCC(31,910,0,0); /* stfpsx */
1378*647adfbcSforsyth case AFPMOVSU: return OPVCC(31,942,0,0); /* stfpsux */
1379*647adfbcSforsyth case AFPMOVD: return OPVCC(31,974,0,0); /* stfpdx */
1380*647adfbcSforsyth case AFPMOVDU: return OPVCC(31,1006,0,0); /* stfpdux */
1381*647adfbcSforsyth case AFPMOVIW: return OPVCC(31,526,0,0); /* stfpiwx */
138274a4d8c2SCharles.Forsyth }
138374a4d8c2SCharles.Forsyth diag("unknown storex opcode %A", a);
138474a4d8c2SCharles.Forsyth return 0;
138574a4d8c2SCharles.Forsyth }
1386