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 %.4lux sb %.4lux 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);
110 seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
112 case 1: /* plan9 boot data goes into text */
113 seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
116 seek(cout, HEADR+textsize+datsize, 0);
118 case 3: /* next boot */
119 seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0);
121 case 4: /* preprocess pilot */
122 seek(cout, HEADR+textsize+datsize, 0);
127 Bprint(&bso, "%5.2f sym\n", cputime());
133 Bprint(&bso, "%5.2f sp\n", cputime());
139 Bprint(&bso, "%5.2f pc\n", cputime());
145 Bprint(&bso, "%5.2f reloc\n", cputime());
151 Bprint(&bso, "%5.2f headr\n", cputime());
156 lput(0x160L<<16); /* magic and sections */
157 lput(0L); /* time and date */
158 lput(rnd(HEADR+textsize, 4096)+datsize);
159 lput(symsize); /* nsyms */
160 lput((0x38L<<16)|7L); /* size of optional hdr and flags */
161 lput((0413<<16)|0437L); /* magic and version */
162 lput(rnd(HEADR+textsize, 4096)); /* sizes */
165 lput(entryvalue()); /* va of entry */
166 lput(INITTEXT-HEADR); /* va of base of text */
167 lput(INITDAT); /* va of base of data */
168 lput(INITDAT+datsize); /* va of base of bss */
169 lput(~0L); /* gp reg mask */
174 lput(~0L); /* gp value ?? */
176 case 1: /* plan9 boot data goes into text */
177 lput(0407); /* magic */
178 lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */
181 lput(symsize); /* nsyms */
182 lput(entryvalue()); /* va of entry */
183 lput(spsize); /* sp offsets */
184 lput(lcsize); /* line offsets */
187 lput(0407); /* magic */
188 lput(textsize); /* sizes */
191 lput(symsize); /* nsyms */
192 lput(entryvalue()); /* va of entry */
193 lput(spsize); /* sp offsets */
194 lput(lcsize); /* line offsets */
196 case 3: /* next boot */
198 lput(0xfeedfaceL); /* magic */
200 lput(1); /* more 68040 */
201 lput(5); /* file type 'boot' */
202 lput(HEADTYPE); /* number commands */
203 lput(HEADR-7*4); /* sizeof commands */
204 lput(1); /* no undefineds */
206 lput(1); /* command = 'segment' */
207 lput(124); /* command size */
209 /* botch?? entryvalue() */
210 lput(INITTEXT); /* va of start */
211 lput(rnd(textsize, 8192)); /* va size */
212 lput(HEADR); /* file offset */
213 lput(rnd(textsize, 8192)); /* file size */
214 lput(7); /* max prot */
215 lput(7); /* init prot */
216 lput(1); /* number of sections */
221 /* botch?? entryvalue() */
222 lput(INITTEXT); /* va of start */
223 lput(textsize); /* va size */
224 lput(HEADR); /* file offset */
226 lput(0); /* reloff */
227 lput(0); /* nreloc */
229 lput(0); /* reserved1 */
230 lput(0); /* reserved2 */
232 lput(1); /* command = 'segment' */
233 lput(192); /* command size */
235 lput(INITDAT); /* va of start */
236 lput(rnd(datsize, 8192)); /* va size */
237 lput(HEADR+rnd(textsize, 8192)); /* file offset */
238 lput(rnd(datsize, 8192)); /* file size */
239 lput(7); /* max prot */
240 lput(7); /* init prot */
241 lput(2); /* number of sections */
246 lput(INITDAT); /* va of start */
247 lput(datsize); /* va size */
248 lput(HEADR+rnd(textsize, 8192)); /* file offset */
250 lput(0); /* reloff */
251 lput(0); /* nreloc */
253 lput(0); /* reserved1 */
254 lput(0); /* reserved2 */
258 lput(INITDAT+datsize); /* va of start */
259 lput(bsssize); /* va size */
260 lput(0); /* file offset */
262 lput(0); /* reloff */
263 lput(0); /* nreloc */
264 lput(1); /* flags = zero fill */
265 lput(0); /* reserved1 */
266 lput(0); /* reserved2 */
267 /* command 2 symbol */
268 lput(2); /* command = 'symbol' */
269 lput(24); /* command size */
270 lput(HEADR+rnd(textsize, INITRND)
271 +datsize); /* symoff */
272 lput(symsize); /* nsyms */
273 lput(spsize); /* sp offsets */
274 lput(lcsize); /* line offsets */
276 case 4: /* preprocess pilot */
277 lput(0407); /* magic */
278 lput(textsize); /* sizes */
281 lput(symsize); /* nsyms */
282 lput(entryvalue()); /* va of entry */
283 lput(spsize); /* sp offsets */
284 lput(lcsize); /* line offsets */
285 lput(relocsize); /* relocation */
299 if(special[p->from.type])
300 switch(p->from.type) {
305 a = asmea(p, &p->to);
306 if((a & 0170) == 010)
308 opa[0] = 0x42c0 | a; /* mov from ccr */
314 a = asmea(p, &p->to);
315 if((a & 0170) == 010)
317 opa[0] = 0x40c0 | a; /* mov from sr */
323 a = asmea(p, &p->to);
324 if((a & 0170) == 010) {
325 opa[0] = 0x4e68|(a&7); /* mov usp An */
394 opa[0] = 0x4e7a; /* mov spc Dn */
395 a = asmea(p, &p->to);
397 if(b == 0 || b == 010) {
418 a = asmea(p, &p->to);
419 opa[0] = optab[AFMOVEL].opcode0 | a;
423 if(special[p->to.type])
427 if(p->as != AMOVW) /* botch, needs and, eor etc. */
429 a = asmea(p, &p->from);
430 if((a & 0170) == 010)
432 opa[0] = 0x44c0 | a; /* mov to ccr */
436 if(p->as != AMOVW) /* botch, needs and, eor etc. */
438 a = asmea(p, &p->from);
439 if((a & 0170) == 010)
441 opa[0] = 0x46c0 | a; /* mov to sr */
447 a = asmea(p, &p->from);
448 if((a & 0170) == 010) {
449 opa[0] = 0x4e60|(a&7); /* mov An usp */
518 opa[0] = 0x4e7b; /* mov Dn spc */
519 a = asmea(p, &p->from);
521 if(b == 0 || b == 010) {
542 a = asmea(p, &p->from);
543 opa[0] = optab[AFMOVEL].opcode0 | a;
551 case 0: /* pseudo ops */
552 if(p->as != ATEXT && p->as != ANOP) {
555 diag("unimplemented instruction in %s", TNAME);
561 case 1: /* branches */
562 if(p->to.type != D_BRANCH)
564 a = asmea(p, &p->to);
571 a = asmea(p, &p->from);
572 b = asmea(p, &p->to);
573 if((a & 0170) == 0110) { /* src quick */
587 a = asmea(p, &p->from);
588 b = asmea(p, &p->to);
589 if((a & 0170) == 0110) { /* src quick */
595 if((b & 0170) == 0) { /* dst Dn */
600 if((b & 0170) == 010) { /* dst An */
608 if((a & 0170) == 0) { /* src Dn */
614 if((a & 0177) == 074) { /* src immed */
621 case 4: /* no operands */
625 t |= asmea(p, &p->to);
631 a = asmea(p, &p->from);
632 b = asmea(p, &p->to);
633 if((b & 0170) != 010)
640 b = asmea(p, &p->to);
641 a = asmea(p, &p->from);
642 if((a & 0170) == 010) { /* dst An */
644 if(t == 0) /* cmpb illegal */
651 if((b & 0177) == 074) { /* src immed */
656 if((a & 0170) == 0) { /* dst Dn */
661 if((b&0170) == 030 && (a&0170) == 030) { /* (A)+,(A)+ */
670 *op++ = optab[ARTS].opcode0;
674 a = asmea(p, &p->from);
675 b = asmea(p, &p->to);
676 if((a & 0170) == 010)
678 if((b & 0170) == 0) { /* dst Dn */
683 if((a & 0170) == 0) { /* src Dn */
689 if((a & 0177) == 074) { /* src immed */
697 a = asmea(p, &p->from);
698 b = asmea(p, &p->to);
699 if((a & 0170) == 010)
701 if((a & 0170) == 0) { /* src Dn */
706 if((a & 0177) == 074) { /* src immed */
714 b = asmea(p, &p->to);
715 if((b & 0170) == 0) { /* dst Dn */
722 a = asmea(p, &p->from);
723 b = asmea(p, &p->to);
724 if((b & 0170) == 0) { /* dst Dn */
725 if((a & 0177) == 0110) { /* src quick */
726 t |= (a & 01600) << 2;
730 if((a & 0170) == 0) { /* src Dn */
740 case 13: /* mul, div short */
741 a = asmea(p, &p->from);
742 b = asmea(p, &p->to);
743 if((b & 0170) == 0) { /* dst Dn */
744 if((a & 0170) == 010)
752 case 14: /* mul, div long */
754 a = asmea(p, &p->from);
755 b = asmea(p, &p->to);
756 if((b & 0170) == 0) { /* dst Dn */
757 if((a & 0170) == 010)
766 case 15: /* dec and branch */
767 if(p->to.type != D_BRANCH)
769 v = p->pcond->pc - p->pc - 2;
770 if(v < -32768L || v >= 32768L)
773 a = asmea(p, &p->from);
781 a = asmea(p, &p->from);
782 b = asmea(p, &p->to);
783 if((a & 0170) == 0100) { /* src Fn */
784 if((b & 0170) == 0100) { /* both Fn */
785 opa[1] |= (a&7) << 10;
786 opa[1] |= (b&7) << 7;
791 opa[1] |= (a&7) << 7;
794 if((b & 0170) != 0100) /* dst Fn */
798 opa[1] |= (b&7) << 7;
801 case 17: /* floating ea,Fn */
803 a = asmea(p, &p->from);
804 b = asmea(p, &p->to);
805 if((b & 0170) != 0100) /* dst Fn */
807 if((a & 0170) == 0100) { /* both Fn */
808 opa[1] |= (a&7) << 10;
809 opa[1] |= (b&7) << 7;
814 opa[1] |= (b&7) << 7;
817 case 18: /* floating branchs */
818 if(p->to.type != D_BRANCH)
820 v = p->pcond->pc - p->pc - 2;
821 if(v < -32768L || v >= 32768L)
826 case 19: /* floating dec and branch */
827 if(p->to.type != D_BRANCH)
830 v = p->pcond->pc - p->pc - 2;
831 if(v < -32768L || v >= 32768L)
834 a = asmea(p, &p->from);
840 case 20: /* ftst ea */
842 if(p->from.type != D_NONE)
844 a = asmea(p, &p->to);
845 if((a & 0170) == 0100) { /* Fn */
846 opa[1] |= (a&7) << 10;
855 if(p->from.type == D_NONE) {
856 b = asmea(p, &p->to);
859 a = asmea(p, &p->from);
860 b = asmea(p, &p->to);
862 if((b & 0170) != 0100) /* dst Fn */
864 if((a & 0170) == 0100) { /* both Fn */
865 opa[1] |= (a&7) << 10;
866 opa[1] |= (b&7) << 7;
871 opa[1] |= (b&7) << 7;
874 case 22: /* floating cmp Fn,ea */
876 a = asmea(p, &p->from);
877 b = asmea(p, &p->to);
878 if((a & 0170) != 0100) /* dst Fn */
880 if((b & 0170) == 0100) { /* both Fn */
881 opa[1] |= (b&7) << 10;
882 opa[1] |= (a&7) << 7;
887 opa[1] |= (a&7) << 7;
890 case 23: /* word, long */
892 a = asmea(p, &p->to);
895 if(a == ((7<<3)|1)) {
902 if(a == ((7<<3)|0)) {
911 case 24: /* bit field */
912 a = ((p->to.field&31)<<6) | (p->from.field&31);
913 if(p->as == ABFINS) {
914 b = asmea(p, &p->from);
919 a = asmea(p, &p->to);
921 if(p->to.type != D_NONE) {
922 b = asmea(p, &p->to);
928 a = asmea(p, &p->from);
932 if(a == 010 || a == 030 || a == 040 || a == 074)
937 if(p->from.type == D_CONST) { /* registers -> memory */
939 a = asmea(p, &p->to);
943 if(b == 000 || b == 010 || b == 030)
948 if(p->to.type == D_CONST) { /* memory -> registers */
951 a = asmea(p, &p->from);
955 if(b == 000 || b == 010 || b == 040)
963 a = asmea(p, &p->from);
966 b = asmea(p, &p->to);
974 a = asmea(p, &p->from);
980 b = asmea(p, &p->to);
981 if(b == 074 || (b&0170) == 010)
986 case 28: /* fmovem */
987 if(p->from.type == D_CONST) { /* registers -> memory */
988 b = p->from.offset & 0xff;
989 b |= 0xf000; /* control or postinc */
991 a = asmea(p, &p->to);
995 if(b == 000 || b == 010 || b == 030)
998 op[-1] &= ~0x1000; /* predec */
1002 if(p->to.type == D_CONST) { /* memory -> registers */
1003 b = p->to.offset & 0xff;
1004 b |= 0xd000; /* control or postinc */
1006 a = asmea(p, &p->from);
1010 if(b == 000 || b == 010 || b == 040)
1017 case 29: /* fmovemc */
1018 if(p->from.type == D_CONST) { /* registers -> memory */
1019 b = (p->from.offset & 0x7) << 10;
1022 a = asmea(p, &p->to);
1026 if(b == 000 || b == 010 || b == 030)
1031 if(p->to.type == D_CONST) { /* memory -> registers */
1032 b = (p->to.offset & 0x7) << 10;
1035 a = asmea(p, &p->from);
1039 if(b == 000 || b == 010 || b == 040)
1047 if(p->to.type == D_CONST) {
1048 t |= p->to.offset & 0xf;
1053 case 31: /* chk2, cmp2 */
1054 b = asmea(p, &p->to);
1056 if(a == 000 || a == 010) {
1057 *op++ = o->opcode1 | (b << 12);
1058 t |= asmea(p, &p->from);
1063 case 32: /* casew */
1064 /* jmp (0,pc,r0.w*1) */
1069 case 34: /* moves */
1071 a = asmea(p, &p->from);
1073 if(b == 0 || b == 010) {
1074 opa[1] = (a << 12) | 0x800;
1075 b = asmea(p, &p->to);
1077 if(a == 0 || a == 010)
1083 b = asmea(p, &p->to);
1085 if(a != 0 && a != 010)
1091 a = asmea(p, &p->to);
1092 if((a & 0170) == 0) {
1104 diag("bad combination of addressing in %s", TNAME);
1109 asmea(Prog *p, Adr *a)
1121 if((r & 070) != 020)
1123 if(v >= -32768L && v < 32768L) {
1125 return t-D_A0-I_INDIR+050; /* d(Ax) */
1137 return (3<<3) | 7; /* (A7)+ */
1140 return (4<<3) | 7; /* -(A7) */
1141 return (2<<3) | 7; /* (A7) */
1144 v = p->pcond->pc - p->pc - 2;
1145 if(v < -32768L || v >= 32768L) {
1146 if(p->as == ABSR || p->as == ABRA) {
1154 if(v < -128 || v >= 128 || p->mark == 4) {
1160 case I_ADDR|D_STATIC:
1161 case I_ADDR|D_EXTERN:
1163 if(t == 0 || t == SXREF) {
1164 diag("undefined external: %s in %s",
1165 a->sym->name, TNAME);
1166 a->sym->type = SDATA;
1168 v = a->sym->value + a->offset;
1171 if(strcmp(a->sym->name, "a6base"))
1175 switch(f? o->srcsp: o->dstsp) {
1184 diag("unknown srcsp asmea in %s", TNAME);
1189 r = f? o->srcsp: o->dstsp;
1191 ((char*)op)[i] = gnuxi(&a->ieee, i, r);
1196 v = a->offset & 0xff;
1197 return 0110 | (v<<7);
1203 return (2<<3) | 7; /* (A7) */
1204 if(v >= -32768L && v < 32768L) {
1206 return (5<<3) | 7; /* d(A7) */
1210 case I_INDIR|D_CONST:
1211 if(v >= -32768L && v < 32768L) {
1222 if(t == 0 || t == SXREF) {
1223 diag("undefined external: %s in %s",
1224 a->sym->name, TNAME);
1225 a->sym->type = SDATA;
1229 v = a->sym->value + a->offset - p->pc - 2;
1230 if(v >= -32768L && v < 32768L) {
1236 v = a->sym->value + a->offset;
1241 v = a->sym->value + a->offset - A6OFFSET;
1242 if(v < -32768L || v >= 32768L) {
1243 v += INITDAT + A6OFFSET;
1244 if(v >= -32768L && v < 32768L) {
1259 diag("unknown addressing mode: %d in %s", t, TNAME);
1265 diag("addressing mode >> 2^16: %d in %s", t, TNAME);
1285 strncpy(name, n, sizeof(name));
1286 for(i=0; i<sizeof(name); i++)
1295 n = sizeof(buf.cbuf) - cbc;
1297 write(cout, buf.cbuf, n);
1299 cbc = sizeof(buf.cbuf);
1303 datblk(long s, long n)
1310 memset(buf.dbuf, 0, n+100);
1311 for(p = datap; p != P; p = p->link) {
1313 l = p->from.sym->value + p->from.offset - s;
1314 c = p->from.displace;
1326 for(j=l+(c-i)-1; j>=l; j--)
1329 diag("multiple initialization");
1332 switch(p->to.type) {
1337 fl = ieeedtof(&p->to.ieee);
1339 if(debug['a'] && i == 0) {
1340 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1342 Bprint(&bso, "%.2ux", cast[fnuxi8[j+4]] & 0xff);
1346 buf.dbuf[l] = cast[fnuxi8[i+4]];
1351 cast = (char*)&p->to.ieee;
1352 if(debug['a'] && i == 0) {
1353 Bprint(&bso, "%lux:%P\n\t\t", l+s+INITDAT, curp);
1355 Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
1359 buf.dbuf[l] = cast[fnuxi8[i]];
1367 if(debug['a'] && i == 0) {
1368 Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp);
1370 Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
1374 buf.dbuf[l] = p->to.scon[i];
1381 if(p->to.sym->type == STEXT)
1382 fl += p->to.sym->value;
1383 if(p->to.sym->type == SDATA)
1384 fl += p->to.sym->value + INITDAT;
1385 if(p->to.sym->type == SBSS)
1386 fl += p->to.sym->value + INITDAT;
1392 diag("bad nuxi %d %d\n%P", c, i, curp);
1395 if(debug['a'] && i == 0) {
1396 Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp);
1398 Bprint(&bso, "%.2ux",cast[inuxi1[j]] & 0xff);
1402 buf.dbuf[l] = cast[inuxi1[i]];
1407 if(debug['a'] && i == 0) {
1408 Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp);
1410 Bprint(&bso, "%.2ux",cast[inuxi2[j]] & 0xff);
1414 buf.dbuf[l] = cast[inuxi2[i]];
1419 if(debug['a'] && i == 0) {
1420 Bprint(&bso, "%.4lux:%P\n\t\t", l+s+INITDAT, curp);
1422 Bprint(&bso, "%.2ux",cast[inuxi4[j]] & 0xff);
1426 buf.dbuf[l] = cast[inuxi4[i]];
1434 write(cout, buf.dbuf, n);
1447 for(p = datap; p != P; p = p->link) {
1453 c3 = p->from.displace;
1455 v = s2->value + INITDAT;
1458 diag("unknown reloc %d", s1->type);
1477 Bprint(&bso, "r %c%c%d %.8lux %s $%s\n",
1478 c1, c2, c3, v, s2->name, s1->name);
1484 gnuxi(Ieee *d, int i, int c)
1491 diag("bad nuxi %d %d\n%P", c, i, curp);