13 if(*a >= '0' && *a <= '9')
19 diag("entry not text: %s", s->name);
32 Bprint(&bso, "%5.2f asmb\n", cputime());
38 for(p = firstp; p != P; p = p->link) {
44 diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME);
49 Bprint(&bso, "%lux:%P\n", pc, curp);
53 for(op1 = opa; op1 < op; op1++) {
62 for(op1 = opa; op1 < op; op1++)
64 Bprint(&bso, "\t\t%4ux", *op1 & 0xffff);
66 Bprint(&bso, " %4ux", *op1 & 0xffff);
73 case 0: /* this is garbage */
74 seek(cout, rnd(HEADR+textsize, 8192), 0);
76 case 1: /* plan9 boot data goes into text */
77 seek(cout, rnd(HEADR+textsize, INITRND), 0);
80 seek(cout, HEADR+textsize, 0);
82 case 3: /* next boot */
83 seek(cout, HEADR+rnd(textsize, INITRND), 0);
85 case 4: /* preprocess pilot */
86 seek(cout, HEADR+textsize, 0);
91 Bprint(&bso, "%5.2f datblk\n", cputime());
94 for(v = 0; v < datsize; v += sizeof(buf)-100) {
95 if(datsize-v > sizeof(buf)-100)
96 datblk(v, sizeof(buf)-100);
109 seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
111 case 1: /* plan9 boot data goes into text */
112 seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
115 seek(cout, HEADR+textsize+datsize, 0);
117 case 3: /* next boot */
118 seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0);
123 Bprint(&bso, "%5.2f sym\n", cputime());
129 Bprint(&bso, "%5.2f sp\n", cputime());
135 Bprint(&bso, "%5.2f pc\n", cputime());
141 Bprint(&bso, "%5.2f headr\n", cputime());
146 lput(0x160L<<16); /* magic and sections */
147 lput(0L); /* time and date */
148 lput(rnd(HEADR+textsize, 4096)+datsize);
149 lput(symsize); /* nsyms */
150 lput((0x38L<<16)|7L); /* size of optional hdr and flags */
151 lput((0413<<16)|0437L); /* magic and version */
152 lput(rnd(HEADR+textsize, 4096)); /* sizes */
155 lput(entryvalue()); /* va of entry */
156 lput(INITTEXT-HEADR); /* va of base of text */
157 lput(INITDAT); /* va of base of data */
158 lput(INITDAT+datsize); /* va of base of bss */
159 lput(~0L); /* gp reg mask */
164 lput(~0L); /* gp value ?? */
166 case 1: /* plan9 boot data goes into text */
167 lput(0407); /* magic */
168 lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */
171 lput(symsize); /* nsyms */
172 lput(entryvalue()); /* va of entry */
173 lput(spsize); /* sp offsets */
174 lput(lcsize); /* line offsets */
177 lput(0407); /* magic */
178 lput(textsize); /* sizes */
181 lput(symsize); /* nsyms */
182 lput(entryvalue()); /* va of entry */
183 lput(spsize); /* sp offsets */
184 lput(lcsize); /* line offsets */
186 case 3: /* next boot */
188 lput(0xfeedfaceL); /* magic */
190 lput(1); /* more 68040 */
191 lput(5); /* file type 'boot' */
192 lput(HEADTYPE); /* number commands */
193 lput(HEADR-7*4); /* sizeof commands */
194 lput(1); /* no undefineds */
196 lput(1); /* command = 'segment' */
197 lput(124); /* command size */
199 /* botch?? entryvalue() */
200 lput(INITTEXT); /* va of start */
201 lput(rnd(textsize, 8192)); /* va size */
202 lput(HEADR); /* file offset */
203 lput(rnd(textsize, 8192)); /* file size */
204 lput(7); /* max prot */
205 lput(7); /* init prot */
206 lput(1); /* number of sections */
211 /* botch?? entryvalue() */
212 lput(INITTEXT); /* va of start */
213 lput(textsize); /* va size */
214 lput(HEADR); /* file offset */
216 lput(0); /* reloff */
217 lput(0); /* nreloc */
219 lput(0); /* reserved1 */
220 lput(0); /* reserved2 */
222 lput(1); /* command = 'segment' */
223 lput(192); /* command size */
225 lput(INITDAT); /* va of start */
226 lput(rnd(datsize, 8192)); /* va size */
227 lput(HEADR+rnd(textsize, 8192)); /* file offset */
228 lput(rnd(datsize, 8192)); /* file size */
229 lput(7); /* max prot */
230 lput(7); /* init prot */
231 lput(2); /* number of sections */
236 lput(INITDAT); /* va of start */
237 lput(datsize); /* va size */
238 lput(HEADR+rnd(textsize, 8192)); /* file offset */
240 lput(0); /* reloff */
241 lput(0); /* nreloc */
243 lput(0); /* reserved1 */
244 lput(0); /* reserved2 */
248 lput(INITDAT+datsize); /* va of start */
249 lput(bsssize); /* va size */
250 lput(0); /* file offset */
252 lput(0); /* reloff */
253 lput(0); /* nreloc */
254 lput(1); /* flags = zero fill */
255 lput(0); /* reserved1 */
256 lput(0); /* reserved2 */
257 /* command 2 symbol */
258 lput(2); /* command = 'symbol' */
259 lput(24); /* command size */
260 lput(HEADR+rnd(textsize, INITRND)
261 +datsize); /* symoff */
262 lput(symsize); /* nsyms */
263 lput(spsize); /* sp offsets */
264 lput(lcsize); /* line offsets */
279 if(special[p->from.type])
280 switch(p->from.type) {
285 a = asmea(p, &p->to);
286 if((a & 0170) == 010)
288 opa[0] = 0x42c0 | a; /* mov from ccr */
294 a = asmea(p, &p->to);
295 if((a & 0170) == 010)
297 opa[0] = 0x40c0 | a; /* mov from sr */
303 a = asmea(p, &p->to);
304 if((a & 0170) == 010) {
305 opa[0] = 0x4e68|(a&7); /* mov usp An */
374 opa[0] = 0x4e7a; /* mov spc Dn */
375 a = asmea(p, &p->to);
377 if(b == 0 || b == 010) {
398 a = asmea(p, &p->to);
399 opa[0] = optab[AFMOVEL].opcode0 | a;
403 if(special[p->to.type])
407 if(p->as != AMOVW) /* botch, needs and, eor etc. */
409 a = asmea(p, &p->from);
410 if((a & 0170) == 010)
412 opa[0] = 0x44c0 | a; /* mov to ccr */
416 if(p->as != AMOVW) /* botch, needs and, eor etc. */
418 a = asmea(p, &p->from);
419 if((a & 0170) == 010)
421 opa[0] = 0x46c0 | a; /* mov to sr */
427 a = asmea(p, &p->from);
428 if((a & 0170) == 010) {
429 opa[0] = 0x4e60|(a&7); /* mov An usp */
498 opa[0] = 0x4e7b; /* mov Dn spc */
499 a = asmea(p, &p->from);
501 if(b == 0 || b == 010) {
522 a = asmea(p, &p->from);
523 opa[0] = optab[AFMOVEL].opcode0 | a;
531 case 0: /* pseudo ops */
532 if(p->as != ATEXT && p->as != ANOP) {
535 diag("unimplemented instruction in %s", TNAME);
541 case 1: /* branches */
542 if(p->to.type != D_BRANCH)
544 a = asmea(p, &p->to);
545 /* hack to turn 3-word bsr into 2-word jsr */
546 if(a == 0xff && p->as == ABSR &&
547 p->pcond->pc < 32768L && p->pcond->pc >= 0) {
550 *op++ = p->pcond->pc;
557 a = asmea(p, &p->from);
558 b = asmea(p, &p->to);
559 if((a & 0170) == 0110) { /* src quick */
573 a = asmea(p, &p->from);
574 b = asmea(p, &p->to);
575 if((a & 0170) == 0110) { /* src quick */
581 if((b & 0170) == 0) { /* dst Dn */
586 if((b & 0170) == 010) { /* dst An */
594 if((a & 0170) == 0) { /* src Dn */
600 if((a & 0177) == 074) { /* src immed */
607 case 4: /* no operands */
611 t |= asmea(p, &p->to);
617 a = asmea(p, &p->from);
618 b = asmea(p, &p->to);
619 if((b & 0170) != 010)
626 b = asmea(p, &p->to);
627 a = asmea(p, &p->from);
628 if((a & 0170) == 010) { /* dst An */
630 if(t == 0) /* cmpb illegal */
637 if((b & 0177) == 074) { /* src immed */
642 if((a & 0170) == 0) { /* dst Dn */
647 if((b&0170) == 030 && (a&0170) == 030) { /* (A)+,(A)+ */
656 *op++ = optab[ARTS].opcode0;
660 a = asmea(p, &p->from);
661 b = asmea(p, &p->to);
662 if((a & 0170) == 010)
664 if((b & 0170) == 0) { /* dst Dn */
669 if((a & 0170) == 0) { /* src Dn */
675 if((a & 0177) == 074) { /* src immed */
683 a = asmea(p, &p->from);
684 b = asmea(p, &p->to);
685 if((a & 0170) == 010)
687 if((a & 0170) == 0) { /* src Dn */
692 if((a & 0177) == 074) { /* src immed */
700 b = asmea(p, &p->to);
701 if((b & 0170) == 0) { /* dst Dn */
708 a = asmea(p, &p->from);
709 b = asmea(p, &p->to);
710 if((b & 0170) == 0) { /* dst Dn */
711 if((a & 0177) == 0110) { /* src quick */
712 t |= (a & 01600) << 2;
716 if((a & 0170) == 0) { /* src Dn */
726 case 13: /* mul, div short */
727 a = asmea(p, &p->from);
728 b = asmea(p, &p->to);
729 if((b & 0170) == 0) { /* dst Dn */
730 if((a & 0170) == 010)
738 case 14: /* mul, div long */
740 a = asmea(p, &p->from);
741 b = asmea(p, &p->to);
742 if((b & 0170) == 0) { /* dst Dn */
743 if((a & 0170) == 010)
752 case 15: /* dec and branch */
753 if(p->to.type != D_BRANCH)
755 v = p->pcond->pc - p->pc - 2;
756 if(v < -32768L || v >= 32768L)
759 a = asmea(p, &p->from);
767 a = asmea(p, &p->from);
768 b = asmea(p, &p->to);
769 if((a & 0170) == 0100) { /* src Fn */
770 if((b & 0170) == 0100) { /* both Fn */
771 opa[1] |= (a&7) << 10;
772 opa[1] |= (b&7) << 7;
777 opa[1] |= (a&7) << 7;
780 if((b & 0170) != 0100) /* dst Fn */
784 opa[1] |= (b&7) << 7;
787 case 17: /* floating ea,Fn */
789 a = asmea(p, &p->from);
790 b = asmea(p, &p->to);
791 if((b & 0170) != 0100) /* dst Fn */
793 if((a & 0170) == 0100) { /* both Fn */
794 opa[1] |= (a&7) << 10;
795 opa[1] |= (b&7) << 7;
800 opa[1] |= (b&7) << 7;
803 case 18: /* floating branchs */
804 if(p->to.type != D_BRANCH)
806 v = p->pcond->pc - p->pc - 2;
807 if(v < -32768L || v >= 32768L)
812 case 19: /* floating dec and branch */
813 if(p->to.type != D_BRANCH)
816 v = p->pcond->pc - p->pc - 2;
817 if(v < -32768L || v >= 32768L)
820 a = asmea(p, &p->from);
826 case 20: /* ftst ea */
828 if(p->from.type != D_NONE)
830 a = asmea(p, &p->to);
831 if((a & 0170) == 0100) { /* Fn */
832 opa[1] |= (a&7) << 10;
841 if(p->from.type == D_NONE) {
842 b = asmea(p, &p->to);
845 a = asmea(p, &p->from);
846 b = asmea(p, &p->to);
848 if((b & 0170) != 0100) /* dst Fn */
850 if((a & 0170) == 0100) { /* both Fn */
851 opa[1] |= (a&7) << 10;
852 opa[1] |= (b&7) << 7;
857 opa[1] |= (b&7) << 7;
860 case 22: /* floating cmp Fn,ea */
862 a = asmea(p, &p->from);
863 b = asmea(p, &p->to);
864 if((a & 0170) != 0100) /* dst Fn */
866 if((b & 0170) == 0100) { /* both Fn */
867 opa[1] |= (b&7) << 10;
868 opa[1] |= (a&7) << 7;
873 opa[1] |= (a&7) << 7;
876 case 23: /* word, long */
878 a = asmea(p, &p->to);
881 if(a == ((7<<3)|1)) {
888 if(a == ((7<<3)|0)) {
897 case 24: /* bit field */
898 a = ((p->to.field&31)<<6) | (p->from.field&31);
899 if(p->as == ABFINS) {
900 b = asmea(p, &p->from);
905 a = asmea(p, &p->to);
907 if(p->to.type != D_NONE) {
908 b = asmea(p, &p->to);
914 a = asmea(p, &p->from);
918 if(a == 010 || a == 030 || a == 040 || a == 074)
923 if(p->from.type == D_CONST) { /* registers -> memory */
925 a = asmea(p, &p->to);
929 if(b == 000 || b == 010 || b == 030)
934 if(p->to.type == D_CONST) { /* memory -> registers */
937 a = asmea(p, &p->from);
941 if(b == 000 || b == 010 || b == 040)
949 a = asmea(p, &p->from);
952 b = asmea(p, &p->to);
960 a = asmea(p, &p->from);
966 b = asmea(p, &p->to);
967 if(b == 074 || (b&0170) == 010)
972 case 28: /* fmovem */
973 if(p->from.type == D_CONST) { /* registers -> memory */
974 b = p->from.offset & 0xff;
975 b |= 0xf000; /* control or postinc */
977 a = asmea(p, &p->to);
981 if(b == 000 || b == 010 || b == 030)
984 op[-1] &= ~0x1000; /* predec */
988 if(p->to.type == D_CONST) { /* memory -> registers */
989 b = p->to.offset & 0xff;
990 b |= 0xd000; /* control or postinc */
992 a = asmea(p, &p->from);
996 if(b == 000 || b == 010 || b == 040)
1003 case 29: /* fmovemc */
1004 if(p->from.type == D_CONST) { /* registers -> memory */
1005 b = (p->from.offset & 0x7) << 10;
1008 a = asmea(p, &p->to);
1012 if(b == 000 || b == 010 || b == 030)
1017 if(p->to.type == D_CONST) { /* memory -> registers */
1018 b = (p->to.offset & 0x7) << 10;
1021 a = asmea(p, &p->from);
1025 if(b == 000 || b == 010 || b == 040)
1033 if(p->to.type == D_CONST) {
1034 t |= p->to.offset & 0xf;
1039 case 31: /* chk2, cmp2 */
1040 b = asmea(p, &p->to);
1042 if(a == 000 || a == 010) {
1043 *op++ = o->opcode1 | (b << 12);
1044 t |= asmea(p, &p->from);
1049 case 32: /* casew */
1050 /* jmp (0,pc,r0.w*1) */
1055 case 33: /* bcase */
1058 q->to.type = D_CONST;
1059 q->to.offset = p->pcond->pc - casepc - 2;
1060 q->from.displace = 2;
1064 Bprint(&bso, "%P\n", q);
1068 case 34: /* moves */
1070 a = asmea(p, &p->from);
1072 if(b == 0 || b == 010) {
1073 opa[1] = (a << 12) | 0x800;
1074 b = asmea(p, &p->to);
1076 if(a == 0 || a == 010)
1082 b = asmea(p, &p->to);
1084 if(a != 0 && a != 010)
1090 a = asmea(p, &p->to);
1091 if((a & 0170) == 0) {
1103 diag("bad combination of addressing in %s", TNAME);
1108 asmea(Prog *p, Adr *a)
1115 if(a->index != D_NONE)
1123 if((r & 070) != 020)
1125 if(v >= -32768L && v < 32768L) {
1127 return t-D_A0-I_INDIR+050; /* d(Ax) */
1129 *op++ = 0x170; /* is, no indirect */
1132 return t-D_A0-I_INDIR+060; /* (d,Ax) */
1142 return (3<<3) | 7; /* (A7)+ */
1145 return (4<<3) | 7; /* -(A7) */
1146 return (2<<3) | 7; /* (A7) */
1149 v = p->pcond->pc - p->pc - 2;
1150 if(v < -32768L || v >= 32768L) {
1155 if(v < -128 || v >= 128 || p->mark == 4) {
1161 case I_ADDR|D_STATIC:
1162 case I_ADDR|D_EXTERN:
1164 if(t == 0 || t == SXREF) {
1165 diag("undefined external: %s in %s",
1166 a->sym->name, TNAME);
1167 a->sym->type = SDATA;
1169 v = a->sym->value + a->offset;
1174 switch(f? o->srcsp: o->dstsp) {
1183 diag("unknown srcsp asmea in %s", TNAME);
1188 r = f? o->srcsp: o->dstsp;
1190 ((char*)op)[i] = gnuxi(&a->ieee, i, r);
1195 v = a->offset & 0xff;
1196 return 0110 | (v<<7);
1202 return (2<<3) | 7; /* (A7) */
1203 if(v >= -32768L && v < 32768L) {
1205 return (5<<3) | 7; /* d(A7) */
1207 *op++ = 0x170; /* is, no indirect */
1210 return (6<<3) | 7; /* (d,A7) */
1212 case I_INDIR|D_CONST:
1218 if(t == 0 || t == SXREF) {
1219 diag("undefined external: %s in %s",
1220 a->sym->name, TNAME);
1221 a->sym->type = SDATA;
1224 v = a->sym->value + a->offset;
1229 v = a->sym->value + a->offset - A6OFFSET;
1231 v += INITDAT + A6OFFSET;
1236 if(v >= -32768L && v < 32768L) {
1240 v += INITDAT + A6OFFSET;
1243 if(v >= -32768L && v < 32768L) {
1253 diag("unknown addressing mode: %d in %s", t, TNAME);
1258 t = a->index & D_MASK;
1259 f = (a->scale & 7) << 9; /* w/l scale */
1260 f |= (t & 7) << 12; /* register */
1261 if(t < D_R0 || t >= D_R0+8) {
1262 if(t >= D_A0 && t < D_A0+8) {
1263 f |= 0x8000; /* d/a */
1274 if(t < (I_INDIR|D_A0) || t >= (I_INDIR|(D_A0+8)))
1279 case I_INDIR|D_NONE:
1293 if(t == 0 || t == SXREF) {
1294 diag("undefined external: %s in %s",
1295 a->sym->name, TNAME);
1296 a->sym->type = SDATA;
1299 v += a->sym->value - A6OFFSET;
1309 v += INITDAT + A6OFFSET;
1313 f |= 0x10; /* bd size = null */
1315 if(v >= -32768L && v < 32768L) {
1316 f |= 0x20; /* bd size = word */
1320 f |= 0x30; /* bd size = long */
1325 t = a->index & I_MASK;
1326 if(t != I_INDEX1) { /* non-memory index */
1328 f |= 5; /* post indexing */
1331 f |= 1; /* pre indexing */
1336 if(v >= -32768L && v < 32768L) {
1337 f++; /* is size = word */
1340 f += 2; /* is size = long */
1351 diag("bad operand in %s", TNAME);
1371 strncpy(name, n, sizeof(name));
1372 for(i=0; i<sizeof(name); i++)
1381 n = sizeof(buf.cbuf) - cbc;
1383 write(cout, buf.cbuf, n);
1385 cbc = sizeof(buf.cbuf);
1389 datblk(long s, long n)
1396 memset(buf.dbuf, 0, n+100);
1397 for(p = datap; p != P; p = p->link) {
1399 l = p->from.sym->value + p->from.offset - s;
1400 c = p->from.displace;
1412 for(j=l+(c-i)-1; j>=l; j--)
1415 diag("multiple initialization");
1418 switch(p->to.type) {
1423 fl = ieeedtof(&p->to.ieee);
1425 if(debug['a'] && i == 0) {
1426 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1428 Bprint(&bso, "%.2ux", cast[fnuxi8[j+4]] & 0xff);
1432 buf.dbuf[l] = cast[fnuxi8[i+4]];
1437 cast = (char*)&p->to.ieee;
1438 if(debug['a'] && i == 0) {
1439 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1441 Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
1445 buf.dbuf[l] = cast[fnuxi8[i]];
1453 if(debug['a'] && i == 0) {
1454 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1456 Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
1460 buf.dbuf[l] = p->to.scon[i];
1467 if(p->to.sym->type == STEXT)
1468 fl += p->to.sym->value;
1469 if(p->to.sym->type == SDATA)
1470 fl += p->to.sym->value + INITDAT;
1471 if(p->to.sym->type == SBSS)
1472 fl += p->to.sym->value + INITDAT;
1478 diag("bad nuxi %d %d\n%P", c, i, curp);
1481 if(debug['a'] && i == 0) {
1482 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1484 Bprint(&bso, "%.2ux",cast[inuxi1[j]] & 0xff);
1488 buf.dbuf[l] = cast[inuxi1[i]];
1493 if(debug['a'] && i == 0) {
1494 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1496 Bprint(&bso, "%.2ux",cast[inuxi2[j]] & 0xff);
1500 buf.dbuf[l] = cast[inuxi2[i]];
1505 if(debug['a'] && i == 0) {
1506 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1508 Bprint(&bso, "%.2ux",cast[inuxi4[j]] & 0xff);
1512 buf.dbuf[l] = cast[inuxi4[i]];
1520 write(cout, buf.dbuf, n);
1524 gnuxi(Ieee *d, int i, int c)
1531 diag("bad nuxi %d %d\n%P", c, i, curp);