174a4d8c2SCharles.Forsyth #include "l.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth #define LPUT(c)\
474a4d8c2SCharles.Forsyth {\
574a4d8c2SCharles.Forsyth cbp[0] = (c)>>24;\
674a4d8c2SCharles.Forsyth cbp[1] = (c)>>16;\
774a4d8c2SCharles.Forsyth cbp[2] = (c)>>8;\
874a4d8c2SCharles.Forsyth cbp[3] = (c);\
974a4d8c2SCharles.Forsyth cbp += 4;\
1074a4d8c2SCharles.Forsyth cbc -= 4;\
1174a4d8c2SCharles.Forsyth if(cbc <= 0)\
1274a4d8c2SCharles.Forsyth cflush();\
1374a4d8c2SCharles.Forsyth }
1474a4d8c2SCharles.Forsyth
1574a4d8c2SCharles.Forsyth #define CPUT(c)\
1674a4d8c2SCharles.Forsyth {\
1774a4d8c2SCharles.Forsyth cbp[0] = (c);\
1874a4d8c2SCharles.Forsyth cbp++;\
1974a4d8c2SCharles.Forsyth cbc--;\
2074a4d8c2SCharles.Forsyth if(cbc <= 0)\
2174a4d8c2SCharles.Forsyth cflush();\
2274a4d8c2SCharles.Forsyth }
2374a4d8c2SCharles.Forsyth
2474a4d8c2SCharles.Forsyth long
entryvalue(void)2574a4d8c2SCharles.Forsyth entryvalue(void)
2674a4d8c2SCharles.Forsyth {
2774a4d8c2SCharles.Forsyth char *a;
2874a4d8c2SCharles.Forsyth Sym *s;
2974a4d8c2SCharles.Forsyth
3074a4d8c2SCharles.Forsyth a = INITENTRY;
3174a4d8c2SCharles.Forsyth if(*a >= '0' && *a <= '9')
3274a4d8c2SCharles.Forsyth return atolwhex(a);
3374a4d8c2SCharles.Forsyth s = lookup(a, 0);
3474a4d8c2SCharles.Forsyth if(s->type == 0)
3574a4d8c2SCharles.Forsyth return INITTEXT;
3674a4d8c2SCharles.Forsyth if(s->type != STEXT && s->type != SLEAF)
3774a4d8c2SCharles.Forsyth diag("entry not text: %s", s->name);
3874a4d8c2SCharles.Forsyth return s->value;
3974a4d8c2SCharles.Forsyth }
4074a4d8c2SCharles.Forsyth
4174a4d8c2SCharles.Forsyth void
asmb(void)4274a4d8c2SCharles.Forsyth asmb(void)
4374a4d8c2SCharles.Forsyth {
4474a4d8c2SCharles.Forsyth Prog *p;
4574a4d8c2SCharles.Forsyth long t;
4674a4d8c2SCharles.Forsyth Optab *o;
4774a4d8c2SCharles.Forsyth
4874a4d8c2SCharles.Forsyth if(debug['v'])
4974a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f asm\n", cputime());
5074a4d8c2SCharles.Forsyth Bflush(&bso);
5174a4d8c2SCharles.Forsyth seek(cout, HEADR, 0);
5274a4d8c2SCharles.Forsyth pc = INITTEXT;
5374a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
5474a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
5574a4d8c2SCharles.Forsyth curtext = p;
5674a4d8c2SCharles.Forsyth autosize = p->to.offset + 4;
5774a4d8c2SCharles.Forsyth }
5874a4d8c2SCharles.Forsyth if(p->pc != pc) {
5974a4d8c2SCharles.Forsyth diag("phase error %lux sb %lux",
6074a4d8c2SCharles.Forsyth p->pc, pc);
6174a4d8c2SCharles.Forsyth if(!debug['a'])
6274a4d8c2SCharles.Forsyth prasm(curp);
6374a4d8c2SCharles.Forsyth pc = p->pc;
6474a4d8c2SCharles.Forsyth }
6574a4d8c2SCharles.Forsyth curp = p;
6674a4d8c2SCharles.Forsyth o = oplook(p); /* could probably avoid this call */
6774a4d8c2SCharles.Forsyth if(asmout(p, o, 0)) {
6874a4d8c2SCharles.Forsyth p = p->link;
6974a4d8c2SCharles.Forsyth pc += 4;
7074a4d8c2SCharles.Forsyth }
7174a4d8c2SCharles.Forsyth pc += o->size;
7274a4d8c2SCharles.Forsyth }
7374a4d8c2SCharles.Forsyth if(debug['a'])
7474a4d8c2SCharles.Forsyth Bprint(&bso, "\n");
7574a4d8c2SCharles.Forsyth Bflush(&bso);
7674a4d8c2SCharles.Forsyth cflush();
7774a4d8c2SCharles.Forsyth
7874a4d8c2SCharles.Forsyth curtext = P;
7974a4d8c2SCharles.Forsyth switch(HEADTYPE) {
8074a4d8c2SCharles.Forsyth case 0:
8174a4d8c2SCharles.Forsyth case 3:
8274a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize, 0);
8374a4d8c2SCharles.Forsyth break;
8474a4d8c2SCharles.Forsyth case 1:
8574a4d8c2SCharles.Forsyth case 2:
8674a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize, 0);
8774a4d8c2SCharles.Forsyth break;
8874a4d8c2SCharles.Forsyth }
8974a4d8c2SCharles.Forsyth for(t = 0; t < datsize; t += sizeof(buf)-100) {
9074a4d8c2SCharles.Forsyth if(datsize-t > sizeof(buf)-100)
9174a4d8c2SCharles.Forsyth datblk(t, sizeof(buf)-100);
9274a4d8c2SCharles.Forsyth else
9374a4d8c2SCharles.Forsyth datblk(t, datsize-t);
9474a4d8c2SCharles.Forsyth }
9574a4d8c2SCharles.Forsyth
9674a4d8c2SCharles.Forsyth symsize = 0;
9774a4d8c2SCharles.Forsyth lcsize = 0;
9874a4d8c2SCharles.Forsyth if(!debug['s']) {
9974a4d8c2SCharles.Forsyth if(debug['v'])
10074a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f sym\n", cputime());
10174a4d8c2SCharles.Forsyth Bflush(&bso);
10274a4d8c2SCharles.Forsyth switch(HEADTYPE) {
10374a4d8c2SCharles.Forsyth case 0:
10474a4d8c2SCharles.Forsyth case 3:
10574a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize+datsize, 0);
10674a4d8c2SCharles.Forsyth break;
10774a4d8c2SCharles.Forsyth case 2:
10874a4d8c2SCharles.Forsyth case 1:
10974a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize+datsize, 0);
11074a4d8c2SCharles.Forsyth break;
11174a4d8c2SCharles.Forsyth }
11274a4d8c2SCharles.Forsyth if(!debug['s'])
11374a4d8c2SCharles.Forsyth asmsym();
11474a4d8c2SCharles.Forsyth if(debug['v'])
11574a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f sp\n", cputime());
11674a4d8c2SCharles.Forsyth Bflush(&bso);
11774a4d8c2SCharles.Forsyth if(!debug['s'])
11874a4d8c2SCharles.Forsyth asmlc();
11974a4d8c2SCharles.Forsyth /* round up file length for boot image */
12074a4d8c2SCharles.Forsyth if(HEADTYPE == 0 || HEADTYPE == 3)
12174a4d8c2SCharles.Forsyth if((symsize+lcsize) & 1)
12274a4d8c2SCharles.Forsyth CPUT(0);
12374a4d8c2SCharles.Forsyth cflush();
12474a4d8c2SCharles.Forsyth }
12574a4d8c2SCharles.Forsyth
12674a4d8c2SCharles.Forsyth seek(cout, 0L, 0);
12774a4d8c2SCharles.Forsyth switch(HEADTYPE) {
12874a4d8c2SCharles.Forsyth case 0:
12974a4d8c2SCharles.Forsyth lput(0x1030107); /* magic and sections */
13074a4d8c2SCharles.Forsyth lput(textsize); /* sizes */
13174a4d8c2SCharles.Forsyth lput(datsize);
13274a4d8c2SCharles.Forsyth lput(bsssize);
13374a4d8c2SCharles.Forsyth lput(symsize); /* nsyms */
13474a4d8c2SCharles.Forsyth lput(entryvalue()); /* va of entry */
13574a4d8c2SCharles.Forsyth lput(0L);
13674a4d8c2SCharles.Forsyth lput(lcsize);
13774a4d8c2SCharles.Forsyth break;
13874a4d8c2SCharles.Forsyth case 1:
13974a4d8c2SCharles.Forsyth break;
14074a4d8c2SCharles.Forsyth case 2:
14174a4d8c2SCharles.Forsyth lput(4*13*13+7); /* magic */
14274a4d8c2SCharles.Forsyth lput(textsize); /* sizes */
14374a4d8c2SCharles.Forsyth lput(datsize);
14474a4d8c2SCharles.Forsyth lput(bsssize);
14574a4d8c2SCharles.Forsyth lput(symsize); /* nsyms */
14674a4d8c2SCharles.Forsyth lput(entryvalue()); /* va of entry */
14774a4d8c2SCharles.Forsyth lput(0L);
14874a4d8c2SCharles.Forsyth lput(lcsize);
14974a4d8c2SCharles.Forsyth break;
15074a4d8c2SCharles.Forsyth case 3:
15174a4d8c2SCharles.Forsyth lput(0x1030107); /* magic and sections */
15274a4d8c2SCharles.Forsyth lput(0x90100000);
15374a4d8c2SCharles.Forsyth #define SPARC_NOOP 0x01000000
15474a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
15574a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
15674a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
15774a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
15874a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
15974a4d8c2SCharles.Forsyth lput(SPARC_NOOP);
16074a4d8c2SCharles.Forsyth break;
16174a4d8c2SCharles.Forsyth }
16274a4d8c2SCharles.Forsyth cflush();
16374a4d8c2SCharles.Forsyth }
16474a4d8c2SCharles.Forsyth
16574a4d8c2SCharles.Forsyth void
lput(long l)16674a4d8c2SCharles.Forsyth lput(long l)
16774a4d8c2SCharles.Forsyth {
16874a4d8c2SCharles.Forsyth
16974a4d8c2SCharles.Forsyth LPUT(l);
17074a4d8c2SCharles.Forsyth }
17174a4d8c2SCharles.Forsyth
17274a4d8c2SCharles.Forsyth void
cflush(void)17374a4d8c2SCharles.Forsyth cflush(void)
17474a4d8c2SCharles.Forsyth {
17574a4d8c2SCharles.Forsyth int n;
17674a4d8c2SCharles.Forsyth
17774a4d8c2SCharles.Forsyth n = sizeof(buf.cbuf) - cbc;
17874a4d8c2SCharles.Forsyth if(n)
17974a4d8c2SCharles.Forsyth write(cout, buf.cbuf, n);
18074a4d8c2SCharles.Forsyth cbp = buf.cbuf;
18174a4d8c2SCharles.Forsyth cbc = sizeof(buf.cbuf);
18274a4d8c2SCharles.Forsyth }
18374a4d8c2SCharles.Forsyth
18474a4d8c2SCharles.Forsyth void
asmsym(void)18574a4d8c2SCharles.Forsyth asmsym(void)
18674a4d8c2SCharles.Forsyth {
18774a4d8c2SCharles.Forsyth Prog *p;
18874a4d8c2SCharles.Forsyth Auto *a;
18974a4d8c2SCharles.Forsyth Sym *s;
19074a4d8c2SCharles.Forsyth int h;
19174a4d8c2SCharles.Forsyth
19274a4d8c2SCharles.Forsyth s = lookup("etext", 0);
19374a4d8c2SCharles.Forsyth if(s->type == STEXT)
19474a4d8c2SCharles.Forsyth putsymb(s->name, 'T', s->value, s->version);
19574a4d8c2SCharles.Forsyth
19674a4d8c2SCharles.Forsyth for(h=0; h<NHASH; h++)
19774a4d8c2SCharles.Forsyth for(s=hash[h]; s!=S; s=s->link)
19874a4d8c2SCharles.Forsyth switch(s->type) {
19974a4d8c2SCharles.Forsyth case SCONST:
20074a4d8c2SCharles.Forsyth putsymb(s->name, 'D', s->value, s->version);
20174a4d8c2SCharles.Forsyth continue;
20274a4d8c2SCharles.Forsyth
20374a4d8c2SCharles.Forsyth case SDATA:
20474a4d8c2SCharles.Forsyth putsymb(s->name, 'D', s->value+INITDAT, s->version);
20574a4d8c2SCharles.Forsyth continue;
20674a4d8c2SCharles.Forsyth
20774a4d8c2SCharles.Forsyth case SBSS:
20874a4d8c2SCharles.Forsyth putsymb(s->name, 'B', s->value+INITDAT, s->version);
20974a4d8c2SCharles.Forsyth continue;
21074a4d8c2SCharles.Forsyth
21174a4d8c2SCharles.Forsyth case SFILE:
21274a4d8c2SCharles.Forsyth putsymb(s->name, 'f', s->value, s->version);
21374a4d8c2SCharles.Forsyth continue;
21474a4d8c2SCharles.Forsyth }
21574a4d8c2SCharles.Forsyth
21674a4d8c2SCharles.Forsyth for(p=textp; p!=P; p=p->cond) {
21774a4d8c2SCharles.Forsyth s = p->from.sym;
21874a4d8c2SCharles.Forsyth if(s->type != STEXT && s->type != SLEAF)
21974a4d8c2SCharles.Forsyth continue;
22074a4d8c2SCharles.Forsyth
22174a4d8c2SCharles.Forsyth /* filenames first */
22274a4d8c2SCharles.Forsyth for(a=p->to.autom; a; a=a->link)
22374a4d8c2SCharles.Forsyth if(a->type == D_FILE)
22474a4d8c2SCharles.Forsyth putsymb(a->asym->name, 'z', a->aoffset, 0);
22574a4d8c2SCharles.Forsyth else
22674a4d8c2SCharles.Forsyth if(a->type == D_FILE1)
22774a4d8c2SCharles.Forsyth putsymb(a->asym->name, 'Z', a->aoffset, 0);
22874a4d8c2SCharles.Forsyth
22974a4d8c2SCharles.Forsyth if(s->type == STEXT)
23074a4d8c2SCharles.Forsyth putsymb(s->name, 'T', s->value, s->version);
23174a4d8c2SCharles.Forsyth else
23274a4d8c2SCharles.Forsyth putsymb(s->name, 'L', s->value, s->version);
23374a4d8c2SCharles.Forsyth
23474a4d8c2SCharles.Forsyth /* frame, auto and param after */
23574a4d8c2SCharles.Forsyth putsymb(".frame", 'm', p->to.offset+4, 0);
23674a4d8c2SCharles.Forsyth for(a=p->to.autom; a; a=a->link)
23774a4d8c2SCharles.Forsyth if(a->type == D_AUTO)
23874a4d8c2SCharles.Forsyth putsymb(a->asym->name, 'a', -a->aoffset, 0);
23974a4d8c2SCharles.Forsyth else
24074a4d8c2SCharles.Forsyth if(a->type == D_PARAM)
24174a4d8c2SCharles.Forsyth putsymb(a->asym->name, 'p', a->aoffset, 0);
24274a4d8c2SCharles.Forsyth }
24374a4d8c2SCharles.Forsyth if(debug['v'] || debug['n'])
24474a4d8c2SCharles.Forsyth Bprint(&bso, "symsize = %lud\n", symsize);
24574a4d8c2SCharles.Forsyth Bflush(&bso);
24674a4d8c2SCharles.Forsyth }
24774a4d8c2SCharles.Forsyth
24874a4d8c2SCharles.Forsyth void
putsymb(char * s,int t,long v,int ver)24974a4d8c2SCharles.Forsyth putsymb(char *s, int t, long v, int ver)
25074a4d8c2SCharles.Forsyth {
25174a4d8c2SCharles.Forsyth int i, f;
25274a4d8c2SCharles.Forsyth
25374a4d8c2SCharles.Forsyth if(t == 'f')
25474a4d8c2SCharles.Forsyth s++;
25574a4d8c2SCharles.Forsyth LPUT(v);
25674a4d8c2SCharles.Forsyth if(ver)
25774a4d8c2SCharles.Forsyth t += 'a' - 'A';
25874a4d8c2SCharles.Forsyth CPUT(t+0x80); /* 0x80 is variable length */
25974a4d8c2SCharles.Forsyth
26074a4d8c2SCharles.Forsyth if(t == 'Z' || t == 'z') {
26174a4d8c2SCharles.Forsyth CPUT(s[0]);
26274a4d8c2SCharles.Forsyth for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
26374a4d8c2SCharles.Forsyth CPUT(s[i]);
26474a4d8c2SCharles.Forsyth CPUT(s[i+1]);
26574a4d8c2SCharles.Forsyth }
26674a4d8c2SCharles.Forsyth CPUT(0);
26774a4d8c2SCharles.Forsyth CPUT(0);
26874a4d8c2SCharles.Forsyth i++;
26974a4d8c2SCharles.Forsyth }
27074a4d8c2SCharles.Forsyth else {
27174a4d8c2SCharles.Forsyth for(i=0; s[i]; i++)
27274a4d8c2SCharles.Forsyth CPUT(s[i]);
27374a4d8c2SCharles.Forsyth CPUT(0);
27474a4d8c2SCharles.Forsyth }
27574a4d8c2SCharles.Forsyth symsize += 4 + 1 + i + 1;
27674a4d8c2SCharles.Forsyth
27774a4d8c2SCharles.Forsyth if(debug['n']) {
27874a4d8c2SCharles.Forsyth if(t == 'z' || t == 'Z') {
27974a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux ", t, v);
28074a4d8c2SCharles.Forsyth for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
28174a4d8c2SCharles.Forsyth f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
28274a4d8c2SCharles.Forsyth Bprint(&bso, "/%x", f);
28374a4d8c2SCharles.Forsyth }
28474a4d8c2SCharles.Forsyth Bprint(&bso, "\n");
28574a4d8c2SCharles.Forsyth return;
28674a4d8c2SCharles.Forsyth }
28774a4d8c2SCharles.Forsyth if(ver)
28874a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
28974a4d8c2SCharles.Forsyth else
29074a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux %s\n", t, v, s);
29174a4d8c2SCharles.Forsyth }
29274a4d8c2SCharles.Forsyth }
29374a4d8c2SCharles.Forsyth
29474a4d8c2SCharles.Forsyth #define MINLC 4
29574a4d8c2SCharles.Forsyth void
asmlc(void)29674a4d8c2SCharles.Forsyth asmlc(void)
29774a4d8c2SCharles.Forsyth {
29874a4d8c2SCharles.Forsyth long oldpc, oldlc;
29974a4d8c2SCharles.Forsyth Prog *p;
30074a4d8c2SCharles.Forsyth long v, s;
30174a4d8c2SCharles.Forsyth
30274a4d8c2SCharles.Forsyth oldpc = INITTEXT;
30374a4d8c2SCharles.Forsyth oldlc = 0;
30474a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
30574a4d8c2SCharles.Forsyth if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
30674a4d8c2SCharles.Forsyth if(p->as == ATEXT)
30774a4d8c2SCharles.Forsyth curtext = p;
30874a4d8c2SCharles.Forsyth if(debug['L'])
30974a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
31074a4d8c2SCharles.Forsyth p->pc, p);
31174a4d8c2SCharles.Forsyth continue;
31274a4d8c2SCharles.Forsyth }
31374a4d8c2SCharles.Forsyth if(debug['L'])
31474a4d8c2SCharles.Forsyth Bprint(&bso, "\t\t%6ld", lcsize);
31574a4d8c2SCharles.Forsyth v = (p->pc - oldpc) / MINLC;
31674a4d8c2SCharles.Forsyth while(v) {
31774a4d8c2SCharles.Forsyth s = 127;
31874a4d8c2SCharles.Forsyth if(v < 127)
31974a4d8c2SCharles.Forsyth s = v;
32074a4d8c2SCharles.Forsyth CPUT(s+128); /* 129-255 +pc */
32174a4d8c2SCharles.Forsyth if(debug['L'])
32274a4d8c2SCharles.Forsyth Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
32374a4d8c2SCharles.Forsyth v -= s;
32474a4d8c2SCharles.Forsyth lcsize++;
32574a4d8c2SCharles.Forsyth }
32674a4d8c2SCharles.Forsyth s = p->line - oldlc;
32774a4d8c2SCharles.Forsyth oldlc = p->line;
32874a4d8c2SCharles.Forsyth oldpc = p->pc + MINLC;
32974a4d8c2SCharles.Forsyth if(s > 64 || s < -64) {
33074a4d8c2SCharles.Forsyth CPUT(0); /* 0 vv +lc */
33174a4d8c2SCharles.Forsyth CPUT(s>>24);
33274a4d8c2SCharles.Forsyth CPUT(s>>16);
33374a4d8c2SCharles.Forsyth CPUT(s>>8);
33474a4d8c2SCharles.Forsyth CPUT(s);
33574a4d8c2SCharles.Forsyth if(debug['L']) {
33674a4d8c2SCharles.Forsyth if(s > 0)
33774a4d8c2SCharles.Forsyth Bprint(&bso, " lc+%ld(%d,%ld)\n",
33874a4d8c2SCharles.Forsyth s, 0, s);
33974a4d8c2SCharles.Forsyth else
34074a4d8c2SCharles.Forsyth Bprint(&bso, " lc%ld(%d,%ld)\n",
34174a4d8c2SCharles.Forsyth s, 0, s);
34274a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
34374a4d8c2SCharles.Forsyth p->pc, p);
34474a4d8c2SCharles.Forsyth }
34574a4d8c2SCharles.Forsyth lcsize += 5;
34674a4d8c2SCharles.Forsyth continue;
34774a4d8c2SCharles.Forsyth }
34874a4d8c2SCharles.Forsyth if(s > 0) {
34974a4d8c2SCharles.Forsyth CPUT(0+s); /* 1-64 +lc */
35074a4d8c2SCharles.Forsyth if(debug['L']) {
35174a4d8c2SCharles.Forsyth Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
35274a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
35374a4d8c2SCharles.Forsyth p->pc, p);
35474a4d8c2SCharles.Forsyth }
35574a4d8c2SCharles.Forsyth } else {
35674a4d8c2SCharles.Forsyth CPUT(64-s); /* 65-128 -lc */
35774a4d8c2SCharles.Forsyth if(debug['L']) {
35874a4d8c2SCharles.Forsyth Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
35974a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
36074a4d8c2SCharles.Forsyth p->pc, p);
36174a4d8c2SCharles.Forsyth }
36274a4d8c2SCharles.Forsyth }
36374a4d8c2SCharles.Forsyth lcsize++;
36474a4d8c2SCharles.Forsyth }
36574a4d8c2SCharles.Forsyth while(lcsize & 1) {
36674a4d8c2SCharles.Forsyth s = 129;
36774a4d8c2SCharles.Forsyth CPUT(s);
36874a4d8c2SCharles.Forsyth lcsize++;
36974a4d8c2SCharles.Forsyth }
37074a4d8c2SCharles.Forsyth if(debug['v'] || debug['L'])
37174a4d8c2SCharles.Forsyth Bprint(&bso, "lcsize = %ld\n", lcsize);
37274a4d8c2SCharles.Forsyth Bflush(&bso);
37374a4d8c2SCharles.Forsyth }
37474a4d8c2SCharles.Forsyth
37574a4d8c2SCharles.Forsyth void
datblk(long s,long n)37674a4d8c2SCharles.Forsyth datblk(long s, long n)
37774a4d8c2SCharles.Forsyth {
37874a4d8c2SCharles.Forsyth Prog *p;
37974a4d8c2SCharles.Forsyth char *cast;
38074a4d8c2SCharles.Forsyth long l, fl, j, d;
38174a4d8c2SCharles.Forsyth int i, c;
38274a4d8c2SCharles.Forsyth
38374a4d8c2SCharles.Forsyth memset(buf.dbuf, 0, n+100);
38474a4d8c2SCharles.Forsyth for(p = datap; p != P; p = p->link) {
38574a4d8c2SCharles.Forsyth curp = p;
38674a4d8c2SCharles.Forsyth l = p->from.sym->value + p->from.offset - s;
38774a4d8c2SCharles.Forsyth c = p->reg;
38874a4d8c2SCharles.Forsyth i = 0;
38974a4d8c2SCharles.Forsyth if(l < 0) {
39074a4d8c2SCharles.Forsyth if(l+c <= 0)
39174a4d8c2SCharles.Forsyth continue;
39274a4d8c2SCharles.Forsyth while(l < 0) {
39374a4d8c2SCharles.Forsyth l++;
39474a4d8c2SCharles.Forsyth i++;
39574a4d8c2SCharles.Forsyth }
39674a4d8c2SCharles.Forsyth }
39774a4d8c2SCharles.Forsyth if(l >= n)
39874a4d8c2SCharles.Forsyth continue;
39974a4d8c2SCharles.Forsyth if(p->as != AINIT && p->as != ADYNT) {
40074a4d8c2SCharles.Forsyth for(j=l+(c-i)-1; j>=l; j--)
40174a4d8c2SCharles.Forsyth if(buf.dbuf[j]) {
40274a4d8c2SCharles.Forsyth print("%P\n", p);
40374a4d8c2SCharles.Forsyth diag("multiple initialization");
40474a4d8c2SCharles.Forsyth break;
40574a4d8c2SCharles.Forsyth }
40674a4d8c2SCharles.Forsyth }
40774a4d8c2SCharles.Forsyth switch(p->to.type) {
40874a4d8c2SCharles.Forsyth default:
40974a4d8c2SCharles.Forsyth diag("unknown mode in initialization\n%P", p);
41074a4d8c2SCharles.Forsyth break;
41174a4d8c2SCharles.Forsyth
41274a4d8c2SCharles.Forsyth case D_FCONST:
41374a4d8c2SCharles.Forsyth switch(c) {
41474a4d8c2SCharles.Forsyth default:
41574a4d8c2SCharles.Forsyth case 4:
41674a4d8c2SCharles.Forsyth fl = ieeedtof(&p->to.ieee);
41774a4d8c2SCharles.Forsyth cast = (char*)&fl;
41874a4d8c2SCharles.Forsyth for(; i<c; i++) {
41974a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[fnuxi8[i+4]];
42074a4d8c2SCharles.Forsyth l++;
42174a4d8c2SCharles.Forsyth }
42274a4d8c2SCharles.Forsyth break;
42374a4d8c2SCharles.Forsyth case 8:
42474a4d8c2SCharles.Forsyth cast = (char*)&p->to.ieee;
42574a4d8c2SCharles.Forsyth for(; i<c; i++) {
42674a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[fnuxi8[i]];
42774a4d8c2SCharles.Forsyth l++;
42874a4d8c2SCharles.Forsyth }
42974a4d8c2SCharles.Forsyth break;
43074a4d8c2SCharles.Forsyth }
43174a4d8c2SCharles.Forsyth break;
43274a4d8c2SCharles.Forsyth
43374a4d8c2SCharles.Forsyth case D_SCONST:
43474a4d8c2SCharles.Forsyth for(; i<c; i++) {
43574a4d8c2SCharles.Forsyth buf.dbuf[l] = p->to.sval[i];
43674a4d8c2SCharles.Forsyth l++;
43774a4d8c2SCharles.Forsyth }
43874a4d8c2SCharles.Forsyth break;
43974a4d8c2SCharles.Forsyth
44074a4d8c2SCharles.Forsyth case D_CONST:
44174a4d8c2SCharles.Forsyth d = p->to.offset;
44274a4d8c2SCharles.Forsyth if(p->to.sym) {
44374a4d8c2SCharles.Forsyth if(p->to.sym->type == STEXT ||
44474a4d8c2SCharles.Forsyth p->to.sym->type == SLEAF)
44574a4d8c2SCharles.Forsyth d += p->to.sym->value;
44674a4d8c2SCharles.Forsyth if(p->to.sym->type == SDATA)
44774a4d8c2SCharles.Forsyth d += p->to.sym->value + INITDAT;
44874a4d8c2SCharles.Forsyth if(p->to.sym->type == SBSS)
44974a4d8c2SCharles.Forsyth d += p->to.sym->value + INITDAT;
45074a4d8c2SCharles.Forsyth }
45174a4d8c2SCharles.Forsyth cast = (char*)&d;
45274a4d8c2SCharles.Forsyth switch(c) {
45374a4d8c2SCharles.Forsyth default:
45474a4d8c2SCharles.Forsyth diag("bad nuxi %d %d\n%P", c, i, curp);
45574a4d8c2SCharles.Forsyth break;
45674a4d8c2SCharles.Forsyth case 1:
45774a4d8c2SCharles.Forsyth for(; i<c; i++) {
45874a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi1[i]];
45974a4d8c2SCharles.Forsyth l++;
46074a4d8c2SCharles.Forsyth }
46174a4d8c2SCharles.Forsyth break;
46274a4d8c2SCharles.Forsyth case 2:
46374a4d8c2SCharles.Forsyth for(; i<c; i++) {
46474a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi2[i]];
46574a4d8c2SCharles.Forsyth l++;
46674a4d8c2SCharles.Forsyth }
46774a4d8c2SCharles.Forsyth break;
46874a4d8c2SCharles.Forsyth case 4:
46974a4d8c2SCharles.Forsyth for(; i<c; i++) {
47074a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi4[i]];
47174a4d8c2SCharles.Forsyth l++;
47274a4d8c2SCharles.Forsyth }
47374a4d8c2SCharles.Forsyth break;
47474a4d8c2SCharles.Forsyth }
47574a4d8c2SCharles.Forsyth break;
47674a4d8c2SCharles.Forsyth }
47774a4d8c2SCharles.Forsyth }
47874a4d8c2SCharles.Forsyth write(cout, buf.dbuf, n);
47974a4d8c2SCharles.Forsyth }
48074a4d8c2SCharles.Forsyth
48174a4d8c2SCharles.Forsyth #define OP2(x) (0x80000000|((x)<<19))
48274a4d8c2SCharles.Forsyth #define OP3(x) (0xc0000000|((x)<<19))
48374a4d8c2SCharles.Forsyth #define OPB(x) (0x00800000|((x)<<25))
48474a4d8c2SCharles.Forsyth #define OPT(x) (0x81d02000|((x)<<25))
48574a4d8c2SCharles.Forsyth #define OPF1(x) (0x81a00000|((x)<<5))
48674a4d8c2SCharles.Forsyth #define OPF2(x) (0x81a80000|((x)<<5))
48774a4d8c2SCharles.Forsyth #define OPFB(x) (0x01800000|((x)<<25))
48874a4d8c2SCharles.Forsyth
48974a4d8c2SCharles.Forsyth #define OP_RRR(op,r1,r2,r3)\
49074a4d8c2SCharles.Forsyth (0x00000000 | op |\
49174a4d8c2SCharles.Forsyth (((r1)&31L)<<0) |\
49274a4d8c2SCharles.Forsyth (((r2)&31L)<<14) |\
49374a4d8c2SCharles.Forsyth (((r3)&31L)<<25))
49474a4d8c2SCharles.Forsyth #define OP_IRR(op,i,r2,r3)\
49574a4d8c2SCharles.Forsyth (0x00002000L | (op) |\
49674a4d8c2SCharles.Forsyth (((i)&0x1fffL)<<0) |\
49774a4d8c2SCharles.Forsyth (((r2)&31L)<<14) |\
49874a4d8c2SCharles.Forsyth (((r3)&31L)<<25))
49974a4d8c2SCharles.Forsyth #define OP_BRA(op,pc)\
50074a4d8c2SCharles.Forsyth ((op) |\
50174a4d8c2SCharles.Forsyth (((pc)&0x3fffff)<<0))
50274a4d8c2SCharles.Forsyth
50374a4d8c2SCharles.Forsyth int
asmout(Prog * p,Optab * o,int aflag)50474a4d8c2SCharles.Forsyth asmout(Prog *p, Optab *o, int aflag)
50574a4d8c2SCharles.Forsyth {
50674a4d8c2SCharles.Forsyth long o1, o2, o3, o4, o5, v;
50774a4d8c2SCharles.Forsyth Prog *ct;
50874a4d8c2SCharles.Forsyth int r;
50974a4d8c2SCharles.Forsyth
51074a4d8c2SCharles.Forsyth o1 = 0;
51174a4d8c2SCharles.Forsyth o2 = 0;
51274a4d8c2SCharles.Forsyth o3 = 0;
51374a4d8c2SCharles.Forsyth o4 = 0;
51474a4d8c2SCharles.Forsyth o5 = 0;
51574a4d8c2SCharles.Forsyth
51674a4d8c2SCharles.Forsyth switch(o->type) {
51774a4d8c2SCharles.Forsyth default:
51874a4d8c2SCharles.Forsyth if(aflag)
51974a4d8c2SCharles.Forsyth return 0;
52074a4d8c2SCharles.Forsyth diag("unknown type %d", o->type);
52174a4d8c2SCharles.Forsyth if(!debug['a'])
52274a4d8c2SCharles.Forsyth prasm(p);
52374a4d8c2SCharles.Forsyth break;
52474a4d8c2SCharles.Forsyth
52574a4d8c2SCharles.Forsyth case 0: /* pseudo ops */
52674a4d8c2SCharles.Forsyth if(aflag) {
52774a4d8c2SCharles.Forsyth if(p->link) {
52874a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
52974a4d8c2SCharles.Forsyth ct = curtext;
53074a4d8c2SCharles.Forsyth o2 = autosize;
53174a4d8c2SCharles.Forsyth curtext = p;
53274a4d8c2SCharles.Forsyth autosize = p->to.offset + 4;
53374a4d8c2SCharles.Forsyth o1 = asmout(p->link, oplook(p->link), aflag);
53474a4d8c2SCharles.Forsyth curtext = ct;
53574a4d8c2SCharles.Forsyth autosize = o2;
53674a4d8c2SCharles.Forsyth } else
53774a4d8c2SCharles.Forsyth o1 = asmout(p->link, oplook(p->link), aflag);
53874a4d8c2SCharles.Forsyth }
53974a4d8c2SCharles.Forsyth return o1;
54074a4d8c2SCharles.Forsyth }
54174a4d8c2SCharles.Forsyth break;
54274a4d8c2SCharles.Forsyth
54374a4d8c2SCharles.Forsyth case 1: /* mov r1,r2 ==> OR r1,r0,r2 */
54474a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(AOR), p->from.reg, REGZERO, p->to.reg);
54574a4d8c2SCharles.Forsyth break;
54674a4d8c2SCharles.Forsyth
54774a4d8c2SCharles.Forsyth case 2: /* mov $c,r ==> add r1,r0,r2 */
54874a4d8c2SCharles.Forsyth r = p->from.reg;
54974a4d8c2SCharles.Forsyth if(r == NREG)
55074a4d8c2SCharles.Forsyth r = o->param;
55174a4d8c2SCharles.Forsyth v = regoff(&p->from);
55274a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(AADD), v, r, p->to.reg);
55374a4d8c2SCharles.Forsyth break;
55474a4d8c2SCharles.Forsyth
55574a4d8c2SCharles.Forsyth case 3: /* mov soreg, r */
55674a4d8c2SCharles.Forsyth r = p->from.reg;
55774a4d8c2SCharles.Forsyth if(r == NREG)
55874a4d8c2SCharles.Forsyth r = o->param;
55974a4d8c2SCharles.Forsyth v = regoff(&p->from);
56074a4d8c2SCharles.Forsyth if(v == 0 && p->reg != NREG)
56174a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as), p->reg, r, p->to.reg);
56274a4d8c2SCharles.Forsyth else
56374a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
56474a4d8c2SCharles.Forsyth break;
56574a4d8c2SCharles.Forsyth
56674a4d8c2SCharles.Forsyth case 4: /* mov r, soreg */
56774a4d8c2SCharles.Forsyth r = p->to.reg;
56874a4d8c2SCharles.Forsyth if(r == NREG)
56974a4d8c2SCharles.Forsyth r = o->param;
57074a4d8c2SCharles.Forsyth v = regoff(&p->to);
57174a4d8c2SCharles.Forsyth if(v == 0 && p->reg != NREG)
57274a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as+AEND), p->reg, r, p->from.reg);
57374a4d8c2SCharles.Forsyth else
57474a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(p->as+AEND), v, r, p->from.reg);
57574a4d8c2SCharles.Forsyth break;
57674a4d8c2SCharles.Forsyth
57774a4d8c2SCharles.Forsyth case 5: /* mov $lcon, reg => sethi, add */
57874a4d8c2SCharles.Forsyth v = regoff(&p->from);
57974a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
58074a4d8c2SCharles.Forsyth o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg);
58174a4d8c2SCharles.Forsyth break;
58274a4d8c2SCharles.Forsyth
58374a4d8c2SCharles.Forsyth case 6: /* mov asi, r[+r] */
58474a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as), p->reg, p->from.reg, p->to.reg);
58574a4d8c2SCharles.Forsyth o1 |= (1<<23) | ((p->from.offset&0xff)<<5);
58674a4d8c2SCharles.Forsyth break;
58774a4d8c2SCharles.Forsyth
58874a4d8c2SCharles.Forsyth case 7: /* mov [+r]r, asi */
58974a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as+AEND), p->reg, p->to.reg, p->from.reg);
59074a4d8c2SCharles.Forsyth o1 |= (1<<23) | ((p->to.offset&0xff)<<5);
59174a4d8c2SCharles.Forsyth break;
59274a4d8c2SCharles.Forsyth
59374a4d8c2SCharles.Forsyth case 8: /* mov r, preg and mov preg, r */
59474a4d8c2SCharles.Forsyth if(p->to.type == D_PREG) {
59574a4d8c2SCharles.Forsyth r = p->from.reg;
59674a4d8c2SCharles.Forsyth switch(p->to.reg)
59774a4d8c2SCharles.Forsyth {
59874a4d8c2SCharles.Forsyth default:
59974a4d8c2SCharles.Forsyth diag("unknown register P%d", p->to.reg);
60074a4d8c2SCharles.Forsyth case D_Y:
60174a4d8c2SCharles.Forsyth o1 = OP2(48); /* wry */
60274a4d8c2SCharles.Forsyth break;
60374a4d8c2SCharles.Forsyth case D_PSR:
60474a4d8c2SCharles.Forsyth o1 = OP2(49); /* wrpsr */
60574a4d8c2SCharles.Forsyth break;
60674a4d8c2SCharles.Forsyth case D_WIM:
60774a4d8c2SCharles.Forsyth o1 = OP2(50); /* wrwim */
60874a4d8c2SCharles.Forsyth break;
60974a4d8c2SCharles.Forsyth case D_TBR:
61074a4d8c2SCharles.Forsyth o1 = OP2(51); /* wrtbr */
61174a4d8c2SCharles.Forsyth break;
61274a4d8c2SCharles.Forsyth }
61374a4d8c2SCharles.Forsyth o1 = OP_IRR(o1, 0, r, 0);
61474a4d8c2SCharles.Forsyth break;
61574a4d8c2SCharles.Forsyth }
61674a4d8c2SCharles.Forsyth if(p->from.type == D_PREG) {
61774a4d8c2SCharles.Forsyth r = p->to.reg;
61874a4d8c2SCharles.Forsyth switch(p->from.reg)
61974a4d8c2SCharles.Forsyth {
62074a4d8c2SCharles.Forsyth default:
62174a4d8c2SCharles.Forsyth diag("unknown register P%d", p->to.reg);
62274a4d8c2SCharles.Forsyth case D_Y:
62374a4d8c2SCharles.Forsyth o1 = OP2(40); /* rdy */
62474a4d8c2SCharles.Forsyth break;
62574a4d8c2SCharles.Forsyth case D_PSR:
62674a4d8c2SCharles.Forsyth o1 = OP2(41); /* rdpsr */
62774a4d8c2SCharles.Forsyth break;
62874a4d8c2SCharles.Forsyth case D_WIM:
62974a4d8c2SCharles.Forsyth o1 = OP2(42); /* rdwim */
63074a4d8c2SCharles.Forsyth break;
63174a4d8c2SCharles.Forsyth case D_TBR:
63274a4d8c2SCharles.Forsyth o1 = OP2(43); /* rdtbr */
63374a4d8c2SCharles.Forsyth break;
63474a4d8c2SCharles.Forsyth }
63574a4d8c2SCharles.Forsyth o1 = OP_RRR(o1, 0, 0, r);
63674a4d8c2SCharles.Forsyth break;
63774a4d8c2SCharles.Forsyth }
63874a4d8c2SCharles.Forsyth break;
63974a4d8c2SCharles.Forsyth
64074a4d8c2SCharles.Forsyth case 9: /* movb r,r */
64174a4d8c2SCharles.Forsyth v = 24;
64274a4d8c2SCharles.Forsyth if(p->as == AMOVH || p->as == AMOVHU)
64374a4d8c2SCharles.Forsyth v = 16;
64474a4d8c2SCharles.Forsyth r = ASRA;
64574a4d8c2SCharles.Forsyth if(p->as == AMOVBU || p->as == AMOVHU)
64674a4d8c2SCharles.Forsyth r = ASRL;
64774a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(ASLL), v, p->from.reg, p->to.reg);
64874a4d8c2SCharles.Forsyth o2 = OP_IRR(opcode(r), v, p->to.reg, p->to.reg);
64974a4d8c2SCharles.Forsyth break;
65074a4d8c2SCharles.Forsyth
65174a4d8c2SCharles.Forsyth case 10: /* mov $loreg, reg */
65274a4d8c2SCharles.Forsyth r = p->from.reg;
65374a4d8c2SCharles.Forsyth if(r == NREG)
65474a4d8c2SCharles.Forsyth r = o->param;
65574a4d8c2SCharles.Forsyth v = regoff(&p->from);
65674a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
65774a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
65874a4d8c2SCharles.Forsyth o3 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg);
65974a4d8c2SCharles.Forsyth break;
66074a4d8c2SCharles.Forsyth
66174a4d8c2SCharles.Forsyth case 11: /* mov loreg, r */
66274a4d8c2SCharles.Forsyth r = p->from.reg;
66374a4d8c2SCharles.Forsyth if(r == NREG)
66474a4d8c2SCharles.Forsyth r = o->param;
66574a4d8c2SCharles.Forsyth v = regoff(&p->from);
66674a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
66774a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
66874a4d8c2SCharles.Forsyth o3 = OP_IRR(opcode(p->as), (v&0x3ff), REGTMP, p->to.reg);
66974a4d8c2SCharles.Forsyth break;
67074a4d8c2SCharles.Forsyth
67174a4d8c2SCharles.Forsyth case 12: /* mov r, loreg */
67274a4d8c2SCharles.Forsyth r = p->to.reg;
67374a4d8c2SCharles.Forsyth if(r == NREG)
67474a4d8c2SCharles.Forsyth r = o->param;
67574a4d8c2SCharles.Forsyth v = regoff(&p->to);
67674a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
67774a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
67874a4d8c2SCharles.Forsyth o3 = OP_IRR(opcode(p->as+AEND), (v&0x3ff), REGTMP, p->from.reg);
67974a4d8c2SCharles.Forsyth break;
68074a4d8c2SCharles.Forsyth
68174a4d8c2SCharles.Forsyth case 13: /* mov $ucon, r */
68274a4d8c2SCharles.Forsyth v = regoff(&p->from);
68374a4d8c2SCharles.Forsyth o1 = 0x1000000 | (p->to.reg<<25) | ((v>>10) & 0x3fffff); /* sethi */
68474a4d8c2SCharles.Forsyth break;
68574a4d8c2SCharles.Forsyth
68674a4d8c2SCharles.Forsyth case 20: /* op $scon,r */
68774a4d8c2SCharles.Forsyth v = regoff(&p->from);
68874a4d8c2SCharles.Forsyth r = p->reg;
68974a4d8c2SCharles.Forsyth if(r == NREG)
69074a4d8c2SCharles.Forsyth r = p->to.reg;
69174a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
69274a4d8c2SCharles.Forsyth break;
69374a4d8c2SCharles.Forsyth
69474a4d8c2SCharles.Forsyth case 21: /* op r1,r2 */
69574a4d8c2SCharles.Forsyth r = p->reg;
69674a4d8c2SCharles.Forsyth if(r == NREG)
69774a4d8c2SCharles.Forsyth r = p->to.reg;
69874a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
69974a4d8c2SCharles.Forsyth break;
70074a4d8c2SCharles.Forsyth
70174a4d8c2SCharles.Forsyth case 22: /* op $lcon,r */
70274a4d8c2SCharles.Forsyth v = regoff(&p->from);
70374a4d8c2SCharles.Forsyth r = p->reg;
70474a4d8c2SCharles.Forsyth if(r == NREG)
70574a4d8c2SCharles.Forsyth r = p->to.reg;
70674a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
70774a4d8c2SCharles.Forsyth o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, REGTMP);
70874a4d8c2SCharles.Forsyth o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
70974a4d8c2SCharles.Forsyth break;
71074a4d8c2SCharles.Forsyth
71174a4d8c2SCharles.Forsyth case 23: /* cmp r,r */
71274a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(ASUBCC), p->to.reg, p->from.reg, REGZERO);
71374a4d8c2SCharles.Forsyth break;
71474a4d8c2SCharles.Forsyth
71574a4d8c2SCharles.Forsyth case 24: /* cmp r,$c */
71674a4d8c2SCharles.Forsyth v = regoff(&p->to);
71774a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(ASUBCC), v, p->from.reg, REGZERO);
71874a4d8c2SCharles.Forsyth break;
71974a4d8c2SCharles.Forsyth
72074a4d8c2SCharles.Forsyth case 25: /* cmp $c,r BOTCH, fix compiler */
72174a4d8c2SCharles.Forsyth v = regoff(&p->from);
72274a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(AADD), v, NREG, REGTMP);
72374a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(ASUBCC), p->to.reg, REGTMP, REGZERO);
72474a4d8c2SCharles.Forsyth break;
72574a4d8c2SCharles.Forsyth
72674a4d8c2SCharles.Forsyth case 26: /* op $ucon,r */
72774a4d8c2SCharles.Forsyth v = regoff(&p->from);
72874a4d8c2SCharles.Forsyth r = p->reg;
72974a4d8c2SCharles.Forsyth if(r == NREG)
73074a4d8c2SCharles.Forsyth r = p->to.reg;
73174a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
73274a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
73374a4d8c2SCharles.Forsyth break;
73474a4d8c2SCharles.Forsyth
73574a4d8c2SCharles.Forsyth case 30: /* jmp/jmpl soreg */
73674a4d8c2SCharles.Forsyth if(aflag)
73774a4d8c2SCharles.Forsyth return 0;
73874a4d8c2SCharles.Forsyth v = regoff(&p->to);
73974a4d8c2SCharles.Forsyth r = p->reg;
74074a4d8c2SCharles.Forsyth if(r == NREG && p->as == AJMPL)
74174a4d8c2SCharles.Forsyth r = 15;
74274a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(AJMPL), v, p->to.reg, r);
74374a4d8c2SCharles.Forsyth break;
74474a4d8c2SCharles.Forsyth
74574a4d8c2SCharles.Forsyth case 31: /* ba jmp */
74674a4d8c2SCharles.Forsyth if(aflag)
74774a4d8c2SCharles.Forsyth return 0;
74874a4d8c2SCharles.Forsyth r = p->as;
74974a4d8c2SCharles.Forsyth if(r == AJMP)
75074a4d8c2SCharles.Forsyth r = ABA;
75174a4d8c2SCharles.Forsyth v = 0;
75274a4d8c2SCharles.Forsyth if(p->cond)
75374a4d8c2SCharles.Forsyth v = p->cond->pc - p->pc;
75474a4d8c2SCharles.Forsyth o1 = OP_BRA(opcode(r), v/4);
75574a4d8c2SCharles.Forsyth if(r == ABA && p->link && p->cond && isnop(p->link)) {
75674a4d8c2SCharles.Forsyth o2 = asmout(p->cond, oplook(p->cond), 1);
75774a4d8c2SCharles.Forsyth if(o2) {
75874a4d8c2SCharles.Forsyth o1 += 1;
75974a4d8c2SCharles.Forsyth if(debug['a'])
76074a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
76174a4d8c2SCharles.Forsyth LPUT(o1);
76274a4d8c2SCharles.Forsyth LPUT(o2);
76374a4d8c2SCharles.Forsyth return 1;
76474a4d8c2SCharles.Forsyth }
76574a4d8c2SCharles.Forsyth /* cant set annul here because pc has already been counted */
76674a4d8c2SCharles.Forsyth }
76774a4d8c2SCharles.Forsyth break;
76874a4d8c2SCharles.Forsyth
76974a4d8c2SCharles.Forsyth case 32: /* jmpl lbra */
77074a4d8c2SCharles.Forsyth if(aflag)
77174a4d8c2SCharles.Forsyth return 0;
77274a4d8c2SCharles.Forsyth v = 0;
77374a4d8c2SCharles.Forsyth if(p->cond)
77474a4d8c2SCharles.Forsyth v = p->cond->pc - p->pc;
77574a4d8c2SCharles.Forsyth r = p->reg;
77674a4d8c2SCharles.Forsyth if(r != NREG && r != 15)
77774a4d8c2SCharles.Forsyth diag("cant jmpl other than R15");
77874a4d8c2SCharles.Forsyth o1 = 0x40000000 | ((v/4) & 0x3fffffffL); /* call */
77974a4d8c2SCharles.Forsyth if(p->link && p->cond && isnop(p->link)) {
78074a4d8c2SCharles.Forsyth o2 = asmout(p->cond, oplook(p->cond), 1);
78174a4d8c2SCharles.Forsyth if(o2) {
78274a4d8c2SCharles.Forsyth o1 += 1;
78374a4d8c2SCharles.Forsyth if(debug['a'])
78474a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
78574a4d8c2SCharles.Forsyth LPUT(o1);
78674a4d8c2SCharles.Forsyth LPUT(o2);
78774a4d8c2SCharles.Forsyth return 1;
78874a4d8c2SCharles.Forsyth }
78974a4d8c2SCharles.Forsyth }
79074a4d8c2SCharles.Forsyth break;
79174a4d8c2SCharles.Forsyth
79274a4d8c2SCharles.Forsyth case 33: /* trap r */
79374a4d8c2SCharles.Forsyth if(aflag)
79474a4d8c2SCharles.Forsyth return 0;
79574a4d8c2SCharles.Forsyth o1 = opcode(p->as) | (p->from.reg<<14);
79674a4d8c2SCharles.Forsyth break;
79774a4d8c2SCharles.Forsyth
79874a4d8c2SCharles.Forsyth case 34: /* rett r1,r2 -> jmpl (r1); rett (r2) */
79974a4d8c2SCharles.Forsyth if(aflag)
80074a4d8c2SCharles.Forsyth return 0;
80174a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(AJMPL), 0, p->from.reg, REGZERO);
80274a4d8c2SCharles.Forsyth o2 = OP_IRR(opcode(ARETT), 0, p->to.reg, REGZERO);
80374a4d8c2SCharles.Forsyth break;
80474a4d8c2SCharles.Forsyth
80574a4d8c2SCharles.Forsyth case 40: /* ldfsr, stfsr, stdq */
80674a4d8c2SCharles.Forsyth if(p->to.type == D_PREG) {
80774a4d8c2SCharles.Forsyth r = p->from.reg;
80874a4d8c2SCharles.Forsyth if(r == NREG)
80974a4d8c2SCharles.Forsyth r = o->param;
81074a4d8c2SCharles.Forsyth v = regoff(&p->from);
81174a4d8c2SCharles.Forsyth if(p->to.reg == D_FSR) {
81274a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(33), v, r, 0);
81374a4d8c2SCharles.Forsyth break;
81474a4d8c2SCharles.Forsyth }
81574a4d8c2SCharles.Forsyth diag("unknown reg load %d", p->to.reg);
81674a4d8c2SCharles.Forsyth } else {
81774a4d8c2SCharles.Forsyth r = p->to.reg;
81874a4d8c2SCharles.Forsyth if(r == NREG)
81974a4d8c2SCharles.Forsyth r = o->param;
82074a4d8c2SCharles.Forsyth v = regoff(&p->to);
82174a4d8c2SCharles.Forsyth if(p->from.reg == D_FSR) {
82274a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(37), v, r, 0);
82374a4d8c2SCharles.Forsyth break;
82474a4d8c2SCharles.Forsyth }
82574a4d8c2SCharles.Forsyth if(p->as == AMOVD && p->from.reg == D_FPQ) {
82674a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(38), v, r, 0);
82774a4d8c2SCharles.Forsyth break;
82874a4d8c2SCharles.Forsyth }
82974a4d8c2SCharles.Forsyth diag("unknown reg store %d", p->from.reg);
83074a4d8c2SCharles.Forsyth }
83174a4d8c2SCharles.Forsyth break;
83274a4d8c2SCharles.Forsyth
83374a4d8c2SCharles.Forsyth case 41: /* ldf,ldd */
83474a4d8c2SCharles.Forsyth r = p->from.reg;
83574a4d8c2SCharles.Forsyth if(r == NREG)
83674a4d8c2SCharles.Forsyth r = o->param;
83774a4d8c2SCharles.Forsyth v = regoff(&p->from);
83874a4d8c2SCharles.Forsyth if(p->as == AFMOVF || p->as == AMOVW) {
83974a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(32), v, r, p->to.reg);
84074a4d8c2SCharles.Forsyth break;
84174a4d8c2SCharles.Forsyth }
84274a4d8c2SCharles.Forsyth if(p->as == AMOVD || p->as == AFMOVD) {
84374a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(35), v, r, p->to.reg);
84474a4d8c2SCharles.Forsyth break;
84574a4d8c2SCharles.Forsyth }
84674a4d8c2SCharles.Forsyth diag("only MOVD and MOVW to FREG");
84774a4d8c2SCharles.Forsyth break;
84874a4d8c2SCharles.Forsyth
84974a4d8c2SCharles.Forsyth case 42: /* ldd -> ldf,ldf */
85074a4d8c2SCharles.Forsyth /* note should be ldd with proper allignment */
85174a4d8c2SCharles.Forsyth r = p->from.reg;
85274a4d8c2SCharles.Forsyth if(r == NREG)
85374a4d8c2SCharles.Forsyth r = o->param;
85474a4d8c2SCharles.Forsyth v = regoff(&p->from);
85574a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(32), v, r, p->to.reg);
85674a4d8c2SCharles.Forsyth o2 = OP_IRR(OP3(32), v+4, r, p->to.reg+1);
85774a4d8c2SCharles.Forsyth break;
85874a4d8c2SCharles.Forsyth
85974a4d8c2SCharles.Forsyth case 43: /* stf */
86074a4d8c2SCharles.Forsyth r = p->to.reg;
86174a4d8c2SCharles.Forsyth if(r == NREG)
86274a4d8c2SCharles.Forsyth r = o->param;
86374a4d8c2SCharles.Forsyth v = regoff(&p->to);
86474a4d8c2SCharles.Forsyth if(p->as == AFMOVF || p->as == AMOVW) {
86574a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(36), v, r, p->from.reg);
86674a4d8c2SCharles.Forsyth break;
86774a4d8c2SCharles.Forsyth }
86874a4d8c2SCharles.Forsyth if(p->as == AMOVD || p->as == AFMOVD) {
86974a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(39), v, r, p->from.reg);
87074a4d8c2SCharles.Forsyth break;
87174a4d8c2SCharles.Forsyth }
87274a4d8c2SCharles.Forsyth diag("only MOVD and MOVW from FREG");
87374a4d8c2SCharles.Forsyth break;
87474a4d8c2SCharles.Forsyth
87574a4d8c2SCharles.Forsyth case 44: /* std -> stf,stf */
87674a4d8c2SCharles.Forsyth /* note should be std with proper allignment */
87774a4d8c2SCharles.Forsyth r = p->to.reg;
87874a4d8c2SCharles.Forsyth if(r == NREG)
87974a4d8c2SCharles.Forsyth r = o->param;
88074a4d8c2SCharles.Forsyth v = regoff(&p->to);
88174a4d8c2SCharles.Forsyth o1 = OP_IRR(OP3(36), v, r, p->from.reg);
88274a4d8c2SCharles.Forsyth o2 = OP_IRR(OP3(36), v+4, r, p->from.reg+1);
88374a4d8c2SCharles.Forsyth break;
88474a4d8c2SCharles.Forsyth
88574a4d8c2SCharles.Forsyth case 45: /* ldf lorg */
88674a4d8c2SCharles.Forsyth r = p->from.reg;
88774a4d8c2SCharles.Forsyth if(r == NREG)
88874a4d8c2SCharles.Forsyth r = o->param;
88974a4d8c2SCharles.Forsyth v = regoff(&p->from);
89074a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
89174a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
89274a4d8c2SCharles.Forsyth o3 = OP_IRR(OP3(32), v&0x3ff, REGTMP, p->to.reg);
89374a4d8c2SCharles.Forsyth break;
89474a4d8c2SCharles.Forsyth
89574a4d8c2SCharles.Forsyth case 46: /* ldd lorg -> ldf,ldf */
89674a4d8c2SCharles.Forsyth /* note should be ldd with proper allignment */
89774a4d8c2SCharles.Forsyth r = p->from.reg;
89874a4d8c2SCharles.Forsyth if(r == NREG)
89974a4d8c2SCharles.Forsyth r = o->param;
90074a4d8c2SCharles.Forsyth v = regoff(&p->from);
90174a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
90274a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
90374a4d8c2SCharles.Forsyth o3 = OP_IRR(OP3(32), (v&0x3ff), REGTMP, p->to.reg);
90474a4d8c2SCharles.Forsyth o4 = OP_IRR(OP3(32), (v&0x3ff)+4, REGTMP, p->to.reg+1);
90574a4d8c2SCharles.Forsyth break;
90674a4d8c2SCharles.Forsyth
90774a4d8c2SCharles.Forsyth case 47: /* stf lorg */
90874a4d8c2SCharles.Forsyth r = p->to.reg;
90974a4d8c2SCharles.Forsyth if(r == NREG)
91074a4d8c2SCharles.Forsyth r = o->param;
91174a4d8c2SCharles.Forsyth v = regoff(&p->to);
91274a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
91374a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
91474a4d8c2SCharles.Forsyth o3 = OP_IRR(OP3(36), v&0x3ff, REGTMP, p->from.reg);
91574a4d8c2SCharles.Forsyth break;
91674a4d8c2SCharles.Forsyth
91774a4d8c2SCharles.Forsyth case 48: /* std lorg -> stf,stf */
91874a4d8c2SCharles.Forsyth /* note should be std with proper allignment */
91974a4d8c2SCharles.Forsyth r = p->to.reg;
92074a4d8c2SCharles.Forsyth if(r == NREG)
92174a4d8c2SCharles.Forsyth r = o->param;
92274a4d8c2SCharles.Forsyth v = regoff(&p->to);
92374a4d8c2SCharles.Forsyth o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff); /* sethi */
92474a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);
92574a4d8c2SCharles.Forsyth o3 = OP_IRR(OP3(36), (v&0x3ff), REGTMP, p->from.reg);
92674a4d8c2SCharles.Forsyth o4 = OP_IRR(OP3(36), (v&0x3ff)+4, REGTMP, p->from.reg+1);
92774a4d8c2SCharles.Forsyth break;
92874a4d8c2SCharles.Forsyth
92974a4d8c2SCharles.Forsyth case 49: /* fmovd -> fmovf,fmovf */
93074a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(AFMOVF), p->from.reg, 0, p->to.reg);
93174a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(AFMOVF), p->from.reg+1, 0, p->to.reg+1);
93274a4d8c2SCharles.Forsyth break;
93374a4d8c2SCharles.Forsyth
93474a4d8c2SCharles.Forsyth case 50: /* fcmp */
93574a4d8c2SCharles.Forsyth o1 = OP_RRR(opcode(p->as), p->to.reg, p->from.reg, 0);
93674a4d8c2SCharles.Forsyth break;
93774a4d8c2SCharles.Forsyth
93874a4d8c2SCharles.Forsyth case 51: /* word */
93974a4d8c2SCharles.Forsyth if(aflag)
94074a4d8c2SCharles.Forsyth return 0;
94174a4d8c2SCharles.Forsyth o1 = regoff(&p->from);
94274a4d8c2SCharles.Forsyth break;
94374a4d8c2SCharles.Forsyth
94474a4d8c2SCharles.Forsyth case 52: /* div */
94574a4d8c2SCharles.Forsyth r = p->reg;
94674a4d8c2SCharles.Forsyth if(r == NREG)
94774a4d8c2SCharles.Forsyth r = p->to.reg;
94874a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);
94974a4d8c2SCharles.Forsyth o2 = OP_IRR(OP2(48), 0, REGTMP, 0);
95074a4d8c2SCharles.Forsyth o3 = OP_RRR(opcode(ADIV), p->from.reg, r, p->to.reg);
95174a4d8c2SCharles.Forsyth break;
95274a4d8c2SCharles.Forsyth
95374a4d8c2SCharles.Forsyth case 53: /* divl */
95474a4d8c2SCharles.Forsyth r = p->reg;
95574a4d8c2SCharles.Forsyth if(r == NREG)
95674a4d8c2SCharles.Forsyth r = p->to.reg;
95774a4d8c2SCharles.Forsyth o1 = OP_IRR(OP2(48), 0, REGZERO, 0);
95874a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, p->to.reg);
95974a4d8c2SCharles.Forsyth break;
96074a4d8c2SCharles.Forsyth
96174a4d8c2SCharles.Forsyth case 54: /* mod */
96274a4d8c2SCharles.Forsyth r = p->reg;
96374a4d8c2SCharles.Forsyth if(r == NREG)
96474a4d8c2SCharles.Forsyth r = p->to.reg;
96574a4d8c2SCharles.Forsyth o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);
96674a4d8c2SCharles.Forsyth o2 = OP_IRR(OP2(48), 0, REGTMP, 0);
96774a4d8c2SCharles.Forsyth o3 = OP_RRR(opcode(ADIV), p->from.reg, r, REGTMP);
96874a4d8c2SCharles.Forsyth o4 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);
96974a4d8c2SCharles.Forsyth o5 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);
97074a4d8c2SCharles.Forsyth break;
97174a4d8c2SCharles.Forsyth
97274a4d8c2SCharles.Forsyth case 55: /* modl */
97374a4d8c2SCharles.Forsyth r = p->reg;
97474a4d8c2SCharles.Forsyth if(r == NREG)
97574a4d8c2SCharles.Forsyth r = p->to.reg;
97674a4d8c2SCharles.Forsyth o1 = OP_IRR(OP2(48), 0, REGZERO, 0);
97774a4d8c2SCharles.Forsyth o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, REGTMP);
97874a4d8c2SCharles.Forsyth o3 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);
97974a4d8c2SCharles.Forsyth o4 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);
98074a4d8c2SCharles.Forsyth break;
98174a4d8c2SCharles.Forsyth
98274a4d8c2SCharles.Forsyth case 56: /* b(cc) -- annullable */
98374a4d8c2SCharles.Forsyth if(aflag)
98474a4d8c2SCharles.Forsyth return 0;
98574a4d8c2SCharles.Forsyth r = p->as;
98674a4d8c2SCharles.Forsyth v = 0;
98774a4d8c2SCharles.Forsyth if(p->cond)
98874a4d8c2SCharles.Forsyth v = p->cond->pc - p->pc;
98974a4d8c2SCharles.Forsyth o1 = OP_BRA(opcode(r), v/4);
99074a4d8c2SCharles.Forsyth if(p->link && p->cond && isnop(p->link))
99174a4d8c2SCharles.Forsyth if(!debug['A']) {
99274a4d8c2SCharles.Forsyth o2 = asmout(p->cond, oplook(p->cond), 2);
99374a4d8c2SCharles.Forsyth if(o2) {
99474a4d8c2SCharles.Forsyth o1 |= 1<<29; /* annul */
99574a4d8c2SCharles.Forsyth o1 += 1;
99674a4d8c2SCharles.Forsyth if(debug['a'])
99774a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);
99874a4d8c2SCharles.Forsyth LPUT(o1);
99974a4d8c2SCharles.Forsyth LPUT(o2);
100074a4d8c2SCharles.Forsyth return 1;
100174a4d8c2SCharles.Forsyth }
100274a4d8c2SCharles.Forsyth }
100374a4d8c2SCharles.Forsyth break;
1004*4d1cf526Sforsyth
1005*4d1cf526Sforsyth case 57: /* op r1,r2 with reserved rs1 */
1006*4d1cf526Sforsyth r = 0;
1007*4d1cf526Sforsyth o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
1008*4d1cf526Sforsyth break;
100974a4d8c2SCharles.Forsyth }
101074a4d8c2SCharles.Forsyth if(aflag)
101174a4d8c2SCharles.Forsyth return o1;
101274a4d8c2SCharles.Forsyth v = p->pc;
101374a4d8c2SCharles.Forsyth switch(o->size) {
101474a4d8c2SCharles.Forsyth default:
101574a4d8c2SCharles.Forsyth if(debug['a'])
101674a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
101774a4d8c2SCharles.Forsyth break;
101874a4d8c2SCharles.Forsyth case 4:
101974a4d8c2SCharles.Forsyth if(debug['a'])
102074a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
102174a4d8c2SCharles.Forsyth LPUT(o1);
102274a4d8c2SCharles.Forsyth break;
102374a4d8c2SCharles.Forsyth case 8:
102474a4d8c2SCharles.Forsyth if(debug['a'])
102574a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
102674a4d8c2SCharles.Forsyth LPUT(o1);
102774a4d8c2SCharles.Forsyth LPUT(o2);
102874a4d8c2SCharles.Forsyth break;
102974a4d8c2SCharles.Forsyth case 12:
103074a4d8c2SCharles.Forsyth if(debug['a'])
103174a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
103274a4d8c2SCharles.Forsyth LPUT(o1);
103374a4d8c2SCharles.Forsyth LPUT(o2);
103474a4d8c2SCharles.Forsyth LPUT(o3);
103574a4d8c2SCharles.Forsyth break;
103674a4d8c2SCharles.Forsyth case 16:
103774a4d8c2SCharles.Forsyth if(debug['a'])
103874a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
103974a4d8c2SCharles.Forsyth v, o1, o2, o3, o4, p);
104074a4d8c2SCharles.Forsyth LPUT(o1);
104174a4d8c2SCharles.Forsyth LPUT(o2);
104274a4d8c2SCharles.Forsyth LPUT(o3);
104374a4d8c2SCharles.Forsyth LPUT(o4);
104474a4d8c2SCharles.Forsyth break;
104574a4d8c2SCharles.Forsyth case 20:
104674a4d8c2SCharles.Forsyth if(debug['a'])
104774a4d8c2SCharles.Forsyth Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
104874a4d8c2SCharles.Forsyth v, o1, o2, o3, o4, o5, p);
104974a4d8c2SCharles.Forsyth LPUT(o1);
105074a4d8c2SCharles.Forsyth LPUT(o2);
105174a4d8c2SCharles.Forsyth LPUT(o3);
105274a4d8c2SCharles.Forsyth LPUT(o4);
105374a4d8c2SCharles.Forsyth LPUT(o5);
105474a4d8c2SCharles.Forsyth break;
105574a4d8c2SCharles.Forsyth }
105674a4d8c2SCharles.Forsyth return 0;
105774a4d8c2SCharles.Forsyth }
105874a4d8c2SCharles.Forsyth
105974a4d8c2SCharles.Forsyth int
isnop(Prog * p)106074a4d8c2SCharles.Forsyth isnop(Prog *p)
106174a4d8c2SCharles.Forsyth {
106274a4d8c2SCharles.Forsyth if(p->as != AORN)
106374a4d8c2SCharles.Forsyth return 0;
106474a4d8c2SCharles.Forsyth if(p->reg != REGZERO && p->reg != NREG)
106574a4d8c2SCharles.Forsyth return 0;
106674a4d8c2SCharles.Forsyth if(p->from.type != D_REG || p->from.reg != REGZERO)
106774a4d8c2SCharles.Forsyth return 0;
106874a4d8c2SCharles.Forsyth if(p->to.type != D_REG || p->to.reg != REGZERO)
106974a4d8c2SCharles.Forsyth return 0;
107074a4d8c2SCharles.Forsyth return 1;
107174a4d8c2SCharles.Forsyth }
107274a4d8c2SCharles.Forsyth
107374a4d8c2SCharles.Forsyth long
opcode(int a)107474a4d8c2SCharles.Forsyth opcode(int a)
107574a4d8c2SCharles.Forsyth {
107674a4d8c2SCharles.Forsyth switch(a) {
107774a4d8c2SCharles.Forsyth case AADD: return OP2(0);
107874a4d8c2SCharles.Forsyth case AADDCC: return OP2(16);
107974a4d8c2SCharles.Forsyth case AADDX: return OP2(8);
108074a4d8c2SCharles.Forsyth case AADDXCC: return OP2(24);
108174a4d8c2SCharles.Forsyth
108274a4d8c2SCharles.Forsyth case AMUL: return OP2(10);
108374a4d8c2SCharles.Forsyth case ADIV: return OP2(15);
108474a4d8c2SCharles.Forsyth case ADIVL: return OP2(14);
108574a4d8c2SCharles.Forsyth
108674a4d8c2SCharles.Forsyth case ATADDCC: return OP2(32);
108774a4d8c2SCharles.Forsyth case ATADDCCTV: return OP2(34);
108874a4d8c2SCharles.Forsyth
108974a4d8c2SCharles.Forsyth case ASUB: return OP2(4);
109074a4d8c2SCharles.Forsyth case ASUBCC: return OP2(20);
109174a4d8c2SCharles.Forsyth case ASUBX: return OP2(12);
109274a4d8c2SCharles.Forsyth case ASUBXCC: return OP2(28);
109374a4d8c2SCharles.Forsyth
109474a4d8c2SCharles.Forsyth case ATSUBCC: return OP2(33);
109574a4d8c2SCharles.Forsyth case ATSUBCCTV: return OP2(35);
109674a4d8c2SCharles.Forsyth
109774a4d8c2SCharles.Forsyth case AMULSCC: return OP2(36);
109874a4d8c2SCharles.Forsyth case ASAVE: return OP2(60);
109974a4d8c2SCharles.Forsyth case ARESTORE: return OP2(61);
110074a4d8c2SCharles.Forsyth
110174a4d8c2SCharles.Forsyth case AAND: return OP2(1);
110274a4d8c2SCharles.Forsyth case AANDCC: return OP2(17);
110374a4d8c2SCharles.Forsyth case AANDN: return OP2(5);
110474a4d8c2SCharles.Forsyth case AANDNCC: return OP2(21);
110574a4d8c2SCharles.Forsyth
110674a4d8c2SCharles.Forsyth case AOR: return OP2(2);
110774a4d8c2SCharles.Forsyth case AORCC: return OP2(18);
110874a4d8c2SCharles.Forsyth case AORN: return OP2(6);
110974a4d8c2SCharles.Forsyth case AORNCC: return OP2(22);
111074a4d8c2SCharles.Forsyth
111174a4d8c2SCharles.Forsyth case AXOR: return OP2(3);
111274a4d8c2SCharles.Forsyth case AXORCC: return OP2(19);
111374a4d8c2SCharles.Forsyth case AXNOR: return OP2(7);
111474a4d8c2SCharles.Forsyth case AXNORCC: return OP2(23);
111574a4d8c2SCharles.Forsyth
111674a4d8c2SCharles.Forsyth case ASLL: return OP2(37);
111774a4d8c2SCharles.Forsyth case ASRL: return OP2(38);
111874a4d8c2SCharles.Forsyth case ASRA: return OP2(39);
111974a4d8c2SCharles.Forsyth
112074a4d8c2SCharles.Forsyth case AJMPL:
112174a4d8c2SCharles.Forsyth case AJMP: return OP2(56);
112274a4d8c2SCharles.Forsyth case ARETT: return OP2(57);
112374a4d8c2SCharles.Forsyth
112474a4d8c2SCharles.Forsyth case AMOVBU: return OP3(1); /* ldub */
112574a4d8c2SCharles.Forsyth case AMOVB: return OP3(9); /* ldsb */
112674a4d8c2SCharles.Forsyth case AMOVHU: return OP3(2); /* lduh */
112774a4d8c2SCharles.Forsyth case AMOVH: return OP3(10); /* ldsh */
112874a4d8c2SCharles.Forsyth case AMOVW: return OP3(0); /* ld */
112974a4d8c2SCharles.Forsyth case AMOVD: return OP3(3); /* ldd */
113074a4d8c2SCharles.Forsyth
113174a4d8c2SCharles.Forsyth case AMOVBU+AEND:
113274a4d8c2SCharles.Forsyth case AMOVB+AEND:return OP3(5); /* stb */
113374a4d8c2SCharles.Forsyth
113474a4d8c2SCharles.Forsyth case AMOVHU+AEND:
113574a4d8c2SCharles.Forsyth case AMOVH+AEND:return OP3(6); /* sth */
113674a4d8c2SCharles.Forsyth
113774a4d8c2SCharles.Forsyth case AMOVW+AEND:return OP3(4); /* st */
113874a4d8c2SCharles.Forsyth
113974a4d8c2SCharles.Forsyth case AMOVD+AEND:return OP3(7); /* std */
114074a4d8c2SCharles.Forsyth
114174a4d8c2SCharles.Forsyth case ASWAP: /* swap is symmetric */
114274a4d8c2SCharles.Forsyth case ASWAP+AEND:return OP3(15);
114374a4d8c2SCharles.Forsyth
114474a4d8c2SCharles.Forsyth case ATAS: return OP3(13); /* tas is really ldstub */
114574a4d8c2SCharles.Forsyth
114674a4d8c2SCharles.Forsyth case ABN: return OPB(0);
114774a4d8c2SCharles.Forsyth case ABE: return OPB(1);
114874a4d8c2SCharles.Forsyth case ABLE: return OPB(2);
114974a4d8c2SCharles.Forsyth case ABL: return OPB(3);
115074a4d8c2SCharles.Forsyth case ABLEU: return OPB(4);
115174a4d8c2SCharles.Forsyth case ABCS: return OPB(5);
115274a4d8c2SCharles.Forsyth case ABNEG: return OPB(6);
115374a4d8c2SCharles.Forsyth case ABVS: return OPB(7);
115474a4d8c2SCharles.Forsyth case ABA: return OPB(8);
115574a4d8c2SCharles.Forsyth case ABNE: return OPB(9);
115674a4d8c2SCharles.Forsyth case ABG: return OPB(10);
115774a4d8c2SCharles.Forsyth case ABGE: return OPB(11);
115874a4d8c2SCharles.Forsyth case ABGU: return OPB(12);
115974a4d8c2SCharles.Forsyth case ABCC: return OPB(13);
116074a4d8c2SCharles.Forsyth case ABPOS: return OPB(14);
116174a4d8c2SCharles.Forsyth case ABVC: return OPB(15);
116274a4d8c2SCharles.Forsyth
116374a4d8c2SCharles.Forsyth case AFBA: return OPFB(8);
116474a4d8c2SCharles.Forsyth case AFBE: return OPFB(9);
116574a4d8c2SCharles.Forsyth case AFBG: return OPFB(6);
116674a4d8c2SCharles.Forsyth case AFBGE: return OPFB(11);
116774a4d8c2SCharles.Forsyth case AFBL: return OPFB(4);
116874a4d8c2SCharles.Forsyth case AFBLE: return OPFB(13);
116974a4d8c2SCharles.Forsyth case AFBLG: return OPFB(2);
117074a4d8c2SCharles.Forsyth case AFBN: return OPFB(0);
117174a4d8c2SCharles.Forsyth case AFBNE: return OPFB(1);
117274a4d8c2SCharles.Forsyth case AFBO: return OPFB(15);
117374a4d8c2SCharles.Forsyth case AFBU: return OPFB(7);
117474a4d8c2SCharles.Forsyth case AFBUE: return OPFB(10);
117574a4d8c2SCharles.Forsyth case AFBUG: return OPFB(5);
117674a4d8c2SCharles.Forsyth case AFBUGE: return OPFB(12);
117774a4d8c2SCharles.Forsyth case AFBUL: return OPFB(3);
117874a4d8c2SCharles.Forsyth case AFBULE: return OPFB(14);
117974a4d8c2SCharles.Forsyth
118074a4d8c2SCharles.Forsyth case ATN: return OPT(0);
118174a4d8c2SCharles.Forsyth case ATE: return OPT(1);
118274a4d8c2SCharles.Forsyth case ATLE: return OPT(2);
118374a4d8c2SCharles.Forsyth case ATL: return OPT(3);
118474a4d8c2SCharles.Forsyth case ATLEU: return OPT(4);
118574a4d8c2SCharles.Forsyth case ATCS: return OPT(5);
118674a4d8c2SCharles.Forsyth case ATNEG: return OPT(6);
118774a4d8c2SCharles.Forsyth case ATVS: return OPT(7);
118874a4d8c2SCharles.Forsyth case ATA: return OPT(8);
118974a4d8c2SCharles.Forsyth case ATNE: return OPT(9);
119074a4d8c2SCharles.Forsyth case ATG: return OPT(10);
119174a4d8c2SCharles.Forsyth case ATGE: return OPT(11);
119274a4d8c2SCharles.Forsyth case ATGU: return OPT(12);
119374a4d8c2SCharles.Forsyth case ATCC: return OPT(13);
119474a4d8c2SCharles.Forsyth case ATPOS: return OPT(14);
119574a4d8c2SCharles.Forsyth case ATVC: return OPT(15);
119674a4d8c2SCharles.Forsyth
119774a4d8c2SCharles.Forsyth case AFADDF: return OPF1(65);
119874a4d8c2SCharles.Forsyth case AFADDD: return OPF1(66);
119974a4d8c2SCharles.Forsyth case AFADDX: return OPF1(67);
120074a4d8c2SCharles.Forsyth case AFSUBF: return OPF1(69);
120174a4d8c2SCharles.Forsyth case AFSUBD: return OPF1(70);
120274a4d8c2SCharles.Forsyth case AFSUBX: return OPF1(71);
120374a4d8c2SCharles.Forsyth case AFMULF: return OPF1(73);
120474a4d8c2SCharles.Forsyth case AFMULD: return OPF1(74);
120574a4d8c2SCharles.Forsyth case AFMULX: return OPF1(75);
120674a4d8c2SCharles.Forsyth case AFDIVF: return OPF1(77);
120774a4d8c2SCharles.Forsyth case AFDIVD: return OPF1(78);
120874a4d8c2SCharles.Forsyth case AFDIVX: return OPF1(79);
120974a4d8c2SCharles.Forsyth
121074a4d8c2SCharles.Forsyth case AFMOVF: return OPF1(1);
121174a4d8c2SCharles.Forsyth case AFNEGF: return OPF1(5);
121274a4d8c2SCharles.Forsyth case AFABSF: return OPF1(9);
121374a4d8c2SCharles.Forsyth
121474a4d8c2SCharles.Forsyth case AFSQRTF: return OPF1(41);
121574a4d8c2SCharles.Forsyth case AFSQRTD: return OPF1(42);
121674a4d8c2SCharles.Forsyth case AFSQRTX: return OPF1(43);
121774a4d8c2SCharles.Forsyth
121874a4d8c2SCharles.Forsyth case AFMOVWF: return OPF1(196);
121974a4d8c2SCharles.Forsyth case AFMOVWD: return OPF1(200);
122074a4d8c2SCharles.Forsyth case AFMOVWX: return OPF1(204);
122174a4d8c2SCharles.Forsyth case AFMOVFW: return OPF1(209);
122274a4d8c2SCharles.Forsyth case AFMOVDW: return OPF1(210);
122374a4d8c2SCharles.Forsyth case AFMOVXW: return OPF1(211);
122474a4d8c2SCharles.Forsyth case AFMOVFD: return OPF1(201);
122574a4d8c2SCharles.Forsyth case AFMOVFX: return OPF1(205);
122674a4d8c2SCharles.Forsyth case AFMOVDF: return OPF1(198);
122774a4d8c2SCharles.Forsyth case AFMOVDX: return OPF1(206);
122874a4d8c2SCharles.Forsyth case AFMOVXF: return OPF1(199);
122974a4d8c2SCharles.Forsyth case AFMOVXD: return OPF1(203);
123074a4d8c2SCharles.Forsyth
123174a4d8c2SCharles.Forsyth case AFCMPF: return OPF2(81);
123274a4d8c2SCharles.Forsyth case AFCMPD: return OPF2(82);
123374a4d8c2SCharles.Forsyth case AFCMPX: return OPF2(83);
123474a4d8c2SCharles.Forsyth case AFCMPEF: return OPF2(85);
123574a4d8c2SCharles.Forsyth case AFCMPED: return OPF2(86);
123674a4d8c2SCharles.Forsyth case AFCMPEX: return OPF2(87);
123774a4d8c2SCharles.Forsyth
123874a4d8c2SCharles.Forsyth case AUNIMP: return 0;
123974a4d8c2SCharles.Forsyth }
124074a4d8c2SCharles.Forsyth diag("bad opcode %A", a);
124174a4d8c2SCharles.Forsyth return 0;
124274a4d8c2SCharles.Forsyth }
1243