17dd7cddfSDavid du Colombier #include "l.h"
27dd7cddfSDavid du Colombier
36891d857SDavid du Colombier #define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
4dc5a79c1SDavid du Colombier
57dd7cddfSDavid du Colombier #define LPUT(c)\
67dd7cddfSDavid du Colombier {\
77dd7cddfSDavid du Colombier cbp[0] = (c)>>24;\
87dd7cddfSDavid du Colombier cbp[1] = (c)>>16;\
97dd7cddfSDavid du Colombier cbp[2] = (c)>>8;\
107dd7cddfSDavid du Colombier cbp[3] = (c);\
117dd7cddfSDavid du Colombier cbp += 4;\
127dd7cddfSDavid du Colombier cbc -= 4;\
137dd7cddfSDavid du Colombier if(cbc <= 0)\
147dd7cddfSDavid du Colombier cflush();\
157dd7cddfSDavid du Colombier }
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier #define CPUT(c)\
187dd7cddfSDavid du Colombier {\
197dd7cddfSDavid du Colombier cbp[0] = (c);\
207dd7cddfSDavid du Colombier cbp++;\
217dd7cddfSDavid du Colombier cbc--;\
227dd7cddfSDavid du Colombier if(cbc <= 0)\
237dd7cddfSDavid du Colombier cflush();\
247dd7cddfSDavid du Colombier }
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier void strnput(char*, int);
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier long
entryvalue(void)297dd7cddfSDavid du Colombier entryvalue(void)
307dd7cddfSDavid du Colombier {
317dd7cddfSDavid du Colombier char *a;
327dd7cddfSDavid du Colombier Sym *s;
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier a = INITENTRY;
357dd7cddfSDavid du Colombier if(*a >= '0' && *a <= '9')
367dd7cddfSDavid du Colombier return atolwhex(a);
377dd7cddfSDavid du Colombier s = lookup(a, 0);
387dd7cddfSDavid du Colombier if(s->type == 0)
397dd7cddfSDavid du Colombier return INITTEXT;
40375daca8SDavid du Colombier if(dlm && s->type == SDATA)
41375daca8SDavid du Colombier return s->value+INITDAT;
427dd7cddfSDavid du Colombier if(s->type != STEXT && s->type != SLEAF)
437dd7cddfSDavid du Colombier diag("entry not text: %s", s->name);
447dd7cddfSDavid du Colombier return s->value;
457dd7cddfSDavid du Colombier }
467dd7cddfSDavid du Colombier
47fff5665eSDavid du Colombier static void
elf32jmp(Putl putl)48*8153b942SDavid du Colombier elf32jmp(Putl putl)
49fff5665eSDavid du Colombier {
50*8153b942SDavid du Colombier /* describe a tiny text section at end with jmp to start; see below */
51*8153b942SDavid du Colombier elf32phdr(putl, PT_LOAD, HEADR+textsize-JMPSZ, 0xFFFFFFFC, 0xFFFFFFFC,
52*8153b942SDavid du Colombier JMPSZ, JMPSZ, R|X, 0); /* text */
53fff5665eSDavid du Colombier }
54fff5665eSDavid du Colombier
557dd7cddfSDavid du Colombier void
asmb(void)567dd7cddfSDavid du Colombier asmb(void)
577dd7cddfSDavid du Colombier {
587dd7cddfSDavid du Colombier Prog *p;
597dd7cddfSDavid du Colombier long t;
607dd7cddfSDavid du Colombier Optab *o;
616891d857SDavid du Colombier long prevpc;
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier if(debug['v'])
647dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f asm\n", cputime());
657dd7cddfSDavid du Colombier Bflush(&bso);
666891d857SDavid du Colombier
676891d857SDavid du Colombier /* emit text segment */
687dd7cddfSDavid du Colombier seek(cout, HEADR, 0);
696891d857SDavid du Colombier prevpc = pc = INITTEXT;
707dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
717dd7cddfSDavid du Colombier if(p->as == ATEXT) {
727dd7cddfSDavid du Colombier curtext = p;
737dd7cddfSDavid du Colombier autosize = p->to.offset + 4;
747dd7cddfSDavid du Colombier if(p->from3.type == D_CONST) {
757dd7cddfSDavid du Colombier for(; pc < p->pc; pc++)
767dd7cddfSDavid du Colombier CPUT(0);
777dd7cddfSDavid du Colombier }
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier if(p->pc != pc) {
806b6b9ac8SDavid du Colombier diag("phase error %lux sb %lux",
817dd7cddfSDavid du Colombier p->pc, pc);
827dd7cddfSDavid du Colombier if(!debug['a'])
837dd7cddfSDavid du Colombier prasm(curp);
847dd7cddfSDavid du Colombier pc = p->pc;
857dd7cddfSDavid du Colombier }
867dd7cddfSDavid du Colombier curp = p;
877dd7cddfSDavid du Colombier o = oplook(p); /* could probably avoid this call */
887dd7cddfSDavid du Colombier if(asmout(p, o, 0)) {
897dd7cddfSDavid du Colombier p = p->link;
907dd7cddfSDavid du Colombier pc += 4;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier pc += o->size;
936891d857SDavid du Colombier if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
946891d857SDavid du Colombier char *tn;
956891d857SDavid du Colombier
966891d857SDavid du Colombier tn = "??none??";
976891d857SDavid du Colombier if(curtext != P && curtext->from.sym != S)
986891d857SDavid du Colombier tn = curtext->from.sym->name;
996891d857SDavid du Colombier Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
1007dd7cddfSDavid du Colombier }
1016891d857SDavid du Colombier prevpc = pc;
1026891d857SDavid du Colombier }
1036891d857SDavid du Colombier
1047dd7cddfSDavid du Colombier if(debug['a'])
1057dd7cddfSDavid du Colombier Bprint(&bso, "\n");
1067dd7cddfSDavid du Colombier Bflush(&bso);
1077dd7cddfSDavid du Colombier cflush();
1087dd7cddfSDavid du Colombier
1096891d857SDavid du Colombier /* emit data segment */
1107dd7cddfSDavid du Colombier curtext = P;
1117dd7cddfSDavid du Colombier switch(HEADTYPE) {
1126891d857SDavid du Colombier case 6:
113*8153b942SDavid du Colombier /*
114*8153b942SDavid du Colombier * but first, for virtex 4, inject a jmp instruction after
115*8153b942SDavid du Colombier * other text: branch to absolute entry address (0xfffe2100).
116*8153b942SDavid du Colombier */
117*8153b942SDavid du Colombier lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
1186891d857SDavid du Colombier textsize += JMPSZ;
119*8153b942SDavid du Colombier cflush();
1206891d857SDavid du Colombier /* fall through */
1217dd7cddfSDavid du Colombier case 0:
1227dd7cddfSDavid du Colombier case 1:
1237dd7cddfSDavid du Colombier case 2:
124dc5a79c1SDavid du Colombier case 5:
1257dd7cddfSDavid du Colombier seek(cout, HEADR+textsize, 0);
1267dd7cddfSDavid du Colombier break;
1277dd7cddfSDavid du Colombier case 3:
1287dd7cddfSDavid du Colombier seek(cout, rnd(HEADR+textsize, 4), 0);
1297dd7cddfSDavid du Colombier break;
1307dd7cddfSDavid du Colombier case 4:
1317dd7cddfSDavid du Colombier seek(cout, rnd(HEADR+textsize, 4096), 0);
1327dd7cddfSDavid du Colombier break;
1337dd7cddfSDavid du Colombier }
134375daca8SDavid du Colombier
135375daca8SDavid du Colombier if(dlm){
136375daca8SDavid du Colombier char buf[8];
137375daca8SDavid du Colombier
138375daca8SDavid du Colombier write(cout, buf, INITDAT-textsize);
139375daca8SDavid du Colombier textsize = INITDAT;
140375daca8SDavid du Colombier }
141375daca8SDavid du Colombier
1427dd7cddfSDavid du Colombier for(t = 0; t < datsize; t += sizeof(buf)-100) {
1437dd7cddfSDavid du Colombier if(datsize-t > sizeof(buf)-100)
1447dd7cddfSDavid du Colombier datblk(t, sizeof(buf)-100);
1457dd7cddfSDavid du Colombier else
1467dd7cddfSDavid du Colombier datblk(t, datsize-t);
1477dd7cddfSDavid du Colombier }
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier symsize = 0;
1507dd7cddfSDavid du Colombier lcsize = 0;
1517dd7cddfSDavid du Colombier if(!debug['s']) {
1527dd7cddfSDavid du Colombier if(debug['v'])
1537dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f sym\n", cputime());
1547dd7cddfSDavid du Colombier Bflush(&bso);
1557dd7cddfSDavid du Colombier switch(HEADTYPE) {
1567dd7cddfSDavid du Colombier case 0:
157375daca8SDavid du Colombier case 1:
158375daca8SDavid du Colombier case 2:
159dc5a79c1SDavid du Colombier case 5:
1606891d857SDavid du Colombier case 6:
1617dd7cddfSDavid du Colombier seek(cout, HEADR+textsize+datsize, 0);
1627dd7cddfSDavid du Colombier break;
1637dd7cddfSDavid du Colombier case 3:
1647dd7cddfSDavid du Colombier seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
1657dd7cddfSDavid du Colombier break;
1667dd7cddfSDavid du Colombier case 4:
1677dd7cddfSDavid du Colombier seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
1687dd7cddfSDavid du Colombier break;
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier if(!debug['s'])
1717dd7cddfSDavid du Colombier asmsym();
1727dd7cddfSDavid du Colombier if(debug['v'])
1737dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f sp\n", cputime());
1747dd7cddfSDavid du Colombier Bflush(&bso);
1757dd7cddfSDavid du Colombier if(!debug['s'])
1767dd7cddfSDavid du Colombier asmlc();
177375daca8SDavid du Colombier if(dlm)
178375daca8SDavid du Colombier asmdyn();
1797dd7cddfSDavid du Colombier if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */
1807dd7cddfSDavid du Colombier if((symsize+lcsize) & 1)
1817dd7cddfSDavid du Colombier CPUT(0);
1827dd7cddfSDavid du Colombier cflush();
1837dd7cddfSDavid du Colombier }
184375daca8SDavid du Colombier else if(dlm){
185375daca8SDavid du Colombier asmdyn();
186375daca8SDavid du Colombier cflush();
187375daca8SDavid du Colombier }
1887dd7cddfSDavid du Colombier
1896891d857SDavid du Colombier /* back up and write the header */
1907dd7cddfSDavid du Colombier seek(cout, 0L, 0);
1917dd7cddfSDavid du Colombier switch(HEADTYPE) {
1927dd7cddfSDavid du Colombier case 0:
1937dd7cddfSDavid du Colombier lput(0x1030107); /* magic and sections */
1947dd7cddfSDavid du Colombier lput(textsize); /* sizes */
1957dd7cddfSDavid du Colombier lput(datsize);
1967dd7cddfSDavid du Colombier lput(bsssize);
1977dd7cddfSDavid du Colombier lput(symsize); /* nsyms */
1987dd7cddfSDavid du Colombier lput(entryvalue()); /* va of entry */
1997dd7cddfSDavid du Colombier lput(0L);
2007dd7cddfSDavid du Colombier lput(lcsize);
2017dd7cddfSDavid du Colombier break;
2027dd7cddfSDavid du Colombier case 1:
2037dd7cddfSDavid du Colombier lput(0x4a6f7921); /* Joy! */
2047dd7cddfSDavid du Colombier lput(0x70656666); /* peff */
2057dd7cddfSDavid du Colombier lput(0x70777063); /* pwpc */
2067dd7cddfSDavid du Colombier lput(1);
2077dd7cddfSDavid du Colombier lput(0);
2087dd7cddfSDavid du Colombier lput(0);
2097dd7cddfSDavid du Colombier lput(0);
2107dd7cddfSDavid du Colombier lput(0);
2117dd7cddfSDavid du Colombier lput(0x30002); /*YY*/
2127dd7cddfSDavid du Colombier lput(0);
2137dd7cddfSDavid du Colombier lput(~0);
2147dd7cddfSDavid du Colombier lput(0);
2157dd7cddfSDavid du Colombier lput(textsize+datsize);
2167dd7cddfSDavid du Colombier lput(textsize+datsize);
2177dd7cddfSDavid du Colombier lput(textsize+datsize);
2187dd7cddfSDavid du Colombier lput(0xd0); /* header size */
2197dd7cddfSDavid du Colombier lput(0x10400);
2207dd7cddfSDavid du Colombier lput(~0);
2217dd7cddfSDavid du Colombier lput(0);
2227dd7cddfSDavid du Colombier lput(0xc);
2237dd7cddfSDavid du Colombier lput(0xc);
2247dd7cddfSDavid du Colombier lput(0xc);
2257dd7cddfSDavid du Colombier lput(0xc0);
2267dd7cddfSDavid du Colombier lput(0x01010400);
2277dd7cddfSDavid du Colombier lput(~0);
2287dd7cddfSDavid du Colombier lput(0);
2297dd7cddfSDavid du Colombier lput(0x38);
2307dd7cddfSDavid du Colombier lput(0x38);
2317dd7cddfSDavid du Colombier lput(0x38);
2327dd7cddfSDavid du Colombier lput(0x80);
2337dd7cddfSDavid du Colombier lput(0x04040400);
2347dd7cddfSDavid du Colombier lput(0);
2357dd7cddfSDavid du Colombier lput(1);
2367dd7cddfSDavid du Colombier lput(0);
2377dd7cddfSDavid du Colombier lput(~0);
2387dd7cddfSDavid du Colombier lput(0);
2397dd7cddfSDavid du Colombier lput(~0);
2407dd7cddfSDavid du Colombier lput(0);
2417dd7cddfSDavid du Colombier lput(0);
2427dd7cddfSDavid du Colombier lput(0);
2437dd7cddfSDavid du Colombier lput(0);
2447dd7cddfSDavid du Colombier lput(0);
2457dd7cddfSDavid du Colombier lput(0);
2467dd7cddfSDavid du Colombier lput(0);
2477dd7cddfSDavid du Colombier lput(0);
2487dd7cddfSDavid du Colombier lput(0);
2497dd7cddfSDavid du Colombier lput(0);
2507dd7cddfSDavid du Colombier lput(0);
2517dd7cddfSDavid du Colombier lput(0x3100); /* load address */
2527dd7cddfSDavid du Colombier lput(0);
2537dd7cddfSDavid du Colombier lput(0);
2547dd7cddfSDavid du Colombier lput(0); /* whew! */
2557dd7cddfSDavid du Colombier break;
2567dd7cddfSDavid du Colombier case 2:
257375daca8SDavid du Colombier if(dlm)
258375daca8SDavid du Colombier lput(0x80000000 | (4*21*21+7)); /* magic */
259375daca8SDavid du Colombier else
2607dd7cddfSDavid du Colombier lput(4*21*21+7); /* magic */
2617dd7cddfSDavid du Colombier lput(textsize); /* sizes */
2627dd7cddfSDavid du Colombier lput(datsize);
2637dd7cddfSDavid du Colombier lput(bsssize);
2647dd7cddfSDavid du Colombier lput(symsize); /* nsyms */
2657dd7cddfSDavid du Colombier lput(entryvalue()); /* va of entry */
2667dd7cddfSDavid du Colombier lput(0L);
2677dd7cddfSDavid du Colombier lput(lcsize);
2687dd7cddfSDavid du Colombier break;
2697dd7cddfSDavid du Colombier case 3:
2707dd7cddfSDavid du Colombier break;
2717dd7cddfSDavid du Colombier case 4:
2727dd7cddfSDavid du Colombier lput((0x1DFL<<16)|3L); /* magic and sections */
2737dd7cddfSDavid du Colombier lput(time(0)); /* time and date */
2747dd7cddfSDavid du Colombier lput(rnd(HEADR+textsize, 4096)+datsize);
2757dd7cddfSDavid du Colombier lput(symsize); /* nsyms */
2767dd7cddfSDavid du Colombier lput((0x48L<<16)|15L); /* size of optional hdr and flags */
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier lput((0413<<16)|01L); /* magic and version */
2797dd7cddfSDavid du Colombier lput(textsize); /* sizes */
2807dd7cddfSDavid du Colombier lput(datsize);
2817dd7cddfSDavid du Colombier lput(bsssize);
2827dd7cddfSDavid du Colombier lput(entryvalue()); /* va of entry */
2837dd7cddfSDavid du Colombier lput(INITTEXT); /* va of base of text */
2847dd7cddfSDavid du Colombier lput(INITDAT); /* va of base of data */
2857dd7cddfSDavid du Colombier lput(INITDAT); /* address of TOC */
2867dd7cddfSDavid du Colombier lput((1L<<16)|1); /* sn(entry) | sn(text) */
2877dd7cddfSDavid du Colombier lput((2L<<16)|1); /* sn(data) | sn(toc) */
2887dd7cddfSDavid du Colombier lput((0L<<16)|3); /* sn(loader) | sn(bss) */
2897dd7cddfSDavid du Colombier lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */
2907dd7cddfSDavid du Colombier lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */
2917dd7cddfSDavid du Colombier lput(0); /* max stack allowed */
2927dd7cddfSDavid du Colombier lput(0); /* max data allowed */
2937dd7cddfSDavid du Colombier lput(0); lput(0); lput(0); /* reserved */
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier strnput(".text", 8); /* text segment */
2967dd7cddfSDavid du Colombier lput(INITTEXT); /* address */
2977dd7cddfSDavid du Colombier lput(INITTEXT);
2987dd7cddfSDavid du Colombier lput(textsize);
2997dd7cddfSDavid du Colombier lput(HEADR);
3007dd7cddfSDavid du Colombier lput(0L);
3017dd7cddfSDavid du Colombier lput(HEADR+textsize+datsize+symsize);
3027dd7cddfSDavid du Colombier lput(lcsize); /* line number size */
3037dd7cddfSDavid du Colombier lput(0x20L); /* flags */
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier strnput(".data", 8); /* data segment */
3067dd7cddfSDavid du Colombier lput(INITDAT); /* address */
3077dd7cddfSDavid du Colombier lput(INITDAT);
3087dd7cddfSDavid du Colombier lput(datsize);
3097dd7cddfSDavid du Colombier lput(rnd(HEADR+textsize, 4096));/* sizes */
3107dd7cddfSDavid du Colombier lput(0L);
3117dd7cddfSDavid du Colombier lput(0L);
3127dd7cddfSDavid du Colombier lput(0L);
3137dd7cddfSDavid du Colombier lput(0x40L); /* flags */
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier strnput(".bss", 8); /* bss segment */
3167dd7cddfSDavid du Colombier lput(INITDAT+datsize); /* address */
3177dd7cddfSDavid du Colombier lput(INITDAT+datsize);
3187dd7cddfSDavid du Colombier lput(bsssize);
3197dd7cddfSDavid du Colombier lput(0L);
3207dd7cddfSDavid du Colombier lput(0L);
3217dd7cddfSDavid du Colombier lput(0L);
3227dd7cddfSDavid du Colombier lput(0L);
3237dd7cddfSDavid du Colombier lput(0x80L); /* flags */
3247dd7cddfSDavid du Colombier break;
325dc5a79c1SDavid du Colombier case 5:
3266891d857SDavid du Colombier /*
327*8153b942SDavid du Colombier * intended for blue/gene
3286891d857SDavid du Colombier */
329*8153b942SDavid du Colombier elf32(POWER, ELFDATA2MSB, 0, nil);
330dc5a79c1SDavid du Colombier break;
3316891d857SDavid du Colombier case 6:
3326891d857SDavid du Colombier /*
333*8153b942SDavid du Colombier * intended for virtex 4 boot
3346891d857SDavid du Colombier */
335*8153b942SDavid du Colombier debug['S'] = 1; /* symbol table */
336*8153b942SDavid du Colombier elf32(POWER, ELFDATA2MSB, 1, elf32jmp);
3376891d857SDavid du Colombier break;
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier cflush();
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier void
strnput(char * s,int n)3437dd7cddfSDavid du Colombier strnput(char *s, int n)
3447dd7cddfSDavid du Colombier {
3457dd7cddfSDavid du Colombier for(; *s; s++){
3467dd7cddfSDavid du Colombier CPUT(*s);
3477dd7cddfSDavid du Colombier n--;
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier for(; n > 0; n--)
3507dd7cddfSDavid du Colombier CPUT(0);
3517dd7cddfSDavid du Colombier }
3527dd7cddfSDavid du Colombier
3537dd7cddfSDavid du Colombier void
cput(long l)354375daca8SDavid du Colombier cput(long l)
355375daca8SDavid du Colombier {
356375daca8SDavid du Colombier CPUT(l);
357375daca8SDavid du Colombier }
358375daca8SDavid du Colombier
359375daca8SDavid du Colombier void
wput(long l)360375daca8SDavid du Colombier wput(long l)
361375daca8SDavid du Colombier {
362375daca8SDavid du Colombier cbp[0] = l>>8;
363375daca8SDavid du Colombier cbp[1] = l;
364375daca8SDavid du Colombier cbp += 2;
365375daca8SDavid du Colombier cbc -= 2;
366375daca8SDavid du Colombier if(cbc <= 0)
367375daca8SDavid du Colombier cflush();
368375daca8SDavid du Colombier }
369375daca8SDavid du Colombier
370375daca8SDavid du Colombier void
wputl(long l)371*8153b942SDavid du Colombier wputl(long l)
372*8153b942SDavid du Colombier {
373*8153b942SDavid du Colombier cbp[0] = l;
374*8153b942SDavid du Colombier cbp[1] = l>>8;
375*8153b942SDavid du Colombier cbp += 2;
376*8153b942SDavid du Colombier cbc -= 2;
377*8153b942SDavid du Colombier if(cbc <= 0)
378*8153b942SDavid du Colombier cflush();
379*8153b942SDavid du Colombier }
380*8153b942SDavid du Colombier
381*8153b942SDavid du Colombier void
lput(long l)3827dd7cddfSDavid du Colombier lput(long l)
3837dd7cddfSDavid du Colombier {
3847dd7cddfSDavid du Colombier LPUT(l);
3857dd7cddfSDavid du Colombier }
3867dd7cddfSDavid du Colombier
3877dd7cddfSDavid du Colombier void
lputl(long c)388*8153b942SDavid du Colombier lputl(long c)
389*8153b942SDavid du Colombier {
390*8153b942SDavid du Colombier cbp[0] = (c);
391*8153b942SDavid du Colombier cbp[1] = (c)>>8;
392*8153b942SDavid du Colombier cbp[2] = (c)>>16;
393*8153b942SDavid du Colombier cbp[3] = (c)>>24;
394*8153b942SDavid du Colombier cbp += 4;
395*8153b942SDavid du Colombier cbc -= 4;
396*8153b942SDavid du Colombier if(cbc <= 0)
397*8153b942SDavid du Colombier cflush();
398*8153b942SDavid du Colombier }
399*8153b942SDavid du Colombier
400*8153b942SDavid du Colombier void
llput(vlong v)401*8153b942SDavid du Colombier llput(vlong v)
402*8153b942SDavid du Colombier {
403*8153b942SDavid du Colombier lput(v>>32);
404*8153b942SDavid du Colombier lput(v);
405*8153b942SDavid du Colombier }
406*8153b942SDavid du Colombier
407*8153b942SDavid du Colombier void
llputl(vlong v)408*8153b942SDavid du Colombier llputl(vlong v)
409*8153b942SDavid du Colombier {
410*8153b942SDavid du Colombier lputl(v);
411*8153b942SDavid du Colombier lputl(v>>32);
412*8153b942SDavid du Colombier }
413*8153b942SDavid du Colombier
414*8153b942SDavid du Colombier void
cflush(void)4157dd7cddfSDavid du Colombier cflush(void)
4167dd7cddfSDavid du Colombier {
4177dd7cddfSDavid du Colombier int n;
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier n = sizeof(buf.cbuf) - cbc;
4207dd7cddfSDavid du Colombier if(n)
4217dd7cddfSDavid du Colombier write(cout, buf.cbuf, n);
4227dd7cddfSDavid du Colombier cbp = buf.cbuf;
4237dd7cddfSDavid du Colombier cbc = sizeof(buf.cbuf);
4247dd7cddfSDavid du Colombier }
4257dd7cddfSDavid du Colombier
4267dd7cddfSDavid du Colombier void
asmsym(void)4277dd7cddfSDavid du Colombier asmsym(void)
4287dd7cddfSDavid du Colombier {
4297dd7cddfSDavid du Colombier Prog *p;
4307dd7cddfSDavid du Colombier Auto *a;
4317dd7cddfSDavid du Colombier Sym *s;
4327dd7cddfSDavid du Colombier int h;
4337dd7cddfSDavid du Colombier
4347dd7cddfSDavid du Colombier s = lookup("etext", 0);
4357dd7cddfSDavid du Colombier if(s->type == STEXT)
4367dd7cddfSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
4377dd7cddfSDavid du Colombier
4387dd7cddfSDavid du Colombier for(h=0; h<NHASH; h++)
4397dd7cddfSDavid du Colombier for(s=hash[h]; s!=S; s=s->link)
4407dd7cddfSDavid du Colombier switch(s->type) {
4417dd7cddfSDavid du Colombier case SCONST:
4427dd7cddfSDavid du Colombier putsymb(s->name, 'D', s->value, s->version);
4437dd7cddfSDavid du Colombier continue;
4447dd7cddfSDavid du Colombier
4457dd7cddfSDavid du Colombier case SDATA:
4467dd7cddfSDavid du Colombier putsymb(s->name, 'D', s->value+INITDAT, s->version);
4477dd7cddfSDavid du Colombier continue;
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier case SBSS:
4507dd7cddfSDavid du Colombier putsymb(s->name, 'B', s->value+INITDAT, s->version);
4517dd7cddfSDavid du Colombier continue;
4527dd7cddfSDavid du Colombier
4537dd7cddfSDavid du Colombier case SFILE:
4547dd7cddfSDavid du Colombier putsymb(s->name, 'f', s->value, s->version);
4557dd7cddfSDavid du Colombier continue;
4567dd7cddfSDavid du Colombier }
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier for(p=textp; p!=P; p=p->cond) {
4597dd7cddfSDavid du Colombier s = p->from.sym;
4607dd7cddfSDavid du Colombier if(s->type != STEXT && s->type != SLEAF)
4617dd7cddfSDavid du Colombier continue;
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier /* filenames first */
4647dd7cddfSDavid du Colombier for(a=p->to.autom; a; a=a->link)
4657dd7cddfSDavid du Colombier if(a->type == D_FILE)
466375daca8SDavid du Colombier putsymb(a->sym->name, 'z', a->aoffset, 0);
4677dd7cddfSDavid du Colombier else
4687dd7cddfSDavid du Colombier if(a->type == D_FILE1)
469375daca8SDavid du Colombier putsymb(a->sym->name, 'Z', a->aoffset, 0);
4707dd7cddfSDavid du Colombier
4717dd7cddfSDavid du Colombier if(s->type == STEXT)
4727dd7cddfSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
4737dd7cddfSDavid du Colombier else
4747dd7cddfSDavid du Colombier putsymb(s->name, 'L', s->value, s->version);
4757dd7cddfSDavid du Colombier
4767dd7cddfSDavid du Colombier /* frame, auto and param after */
4777dd7cddfSDavid du Colombier putsymb(".frame", 'm', p->to.offset+4, 0);
4787dd7cddfSDavid du Colombier for(a=p->to.autom; a; a=a->link)
4797dd7cddfSDavid du Colombier if(a->type == D_AUTO)
480375daca8SDavid du Colombier putsymb(a->sym->name, 'a', -a->aoffset, 0);
4817dd7cddfSDavid du Colombier else
4827dd7cddfSDavid du Colombier if(a->type == D_PARAM)
483375daca8SDavid du Colombier putsymb(a->sym->name, 'p', a->aoffset, 0);
4847dd7cddfSDavid du Colombier }
4857dd7cddfSDavid du Colombier if(debug['v'] || debug['n'])
4867dd7cddfSDavid du Colombier Bprint(&bso, "symsize = %lud\n", symsize);
4877dd7cddfSDavid du Colombier Bflush(&bso);
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier
4907dd7cddfSDavid du Colombier void
putsymb(char * s,int t,long v,int ver)4917dd7cddfSDavid du Colombier putsymb(char *s, int t, long v, int ver)
4927dd7cddfSDavid du Colombier {
4937dd7cddfSDavid du Colombier int i, f;
4947dd7cddfSDavid du Colombier
4957dd7cddfSDavid du Colombier if(t == 'f')
4967dd7cddfSDavid du Colombier s++;
4977dd7cddfSDavid du Colombier LPUT(v);
4987dd7cddfSDavid du Colombier if(ver)
4997dd7cddfSDavid du Colombier t += 'a' - 'A';
5007dd7cddfSDavid du Colombier CPUT(t+0x80); /* 0x80 is variable length */
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier if(t == 'Z' || t == 'z') {
5037dd7cddfSDavid du Colombier CPUT(s[0]);
5047dd7cddfSDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
5057dd7cddfSDavid du Colombier CPUT(s[i]);
5067dd7cddfSDavid du Colombier CPUT(s[i+1]);
5077dd7cddfSDavid du Colombier }
5087dd7cddfSDavid du Colombier CPUT(0);
5097dd7cddfSDavid du Colombier CPUT(0);
5107dd7cddfSDavid du Colombier i++;
5117dd7cddfSDavid du Colombier }
5127dd7cddfSDavid du Colombier else {
5137dd7cddfSDavid du Colombier for(i=0; s[i]; i++)
5147dd7cddfSDavid du Colombier CPUT(s[i]);
5157dd7cddfSDavid du Colombier CPUT(0);
5167dd7cddfSDavid du Colombier }
5177dd7cddfSDavid du Colombier symsize += 4 + 1 + i + 1;
5187dd7cddfSDavid du Colombier
5197dd7cddfSDavid du Colombier if(debug['n']) {
5207dd7cddfSDavid du Colombier if(t == 'z' || t == 'Z') {
5217dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux ", t, v);
5227dd7cddfSDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
5237dd7cddfSDavid du Colombier f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
5247dd7cddfSDavid du Colombier Bprint(&bso, "/%x", f);
5257dd7cddfSDavid du Colombier }
5267dd7cddfSDavid du Colombier Bprint(&bso, "\n");
5277dd7cddfSDavid du Colombier return;
5287dd7cddfSDavid du Colombier }
5297dd7cddfSDavid du Colombier if(ver)
5307dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
5317dd7cddfSDavid du Colombier else
5327dd7cddfSDavid du Colombier Bprint(&bso, "%c %.8lux %s\n", t, v, s);
5337dd7cddfSDavid du Colombier }
5347dd7cddfSDavid du Colombier }
5357dd7cddfSDavid du Colombier
5367dd7cddfSDavid du Colombier #define MINLC 4
5377dd7cddfSDavid du Colombier void
asmlc(void)5387dd7cddfSDavid du Colombier asmlc(void)
5397dd7cddfSDavid du Colombier {
5407dd7cddfSDavid du Colombier long oldpc, oldlc;
5417dd7cddfSDavid du Colombier Prog *p;
5427dd7cddfSDavid du Colombier long v, s;
5437dd7cddfSDavid du Colombier
5447dd7cddfSDavid du Colombier oldpc = INITTEXT;
5457dd7cddfSDavid du Colombier oldlc = 0;
5467dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) {
5477dd7cddfSDavid du Colombier if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
5487dd7cddfSDavid du Colombier if(p->as == ATEXT)
5497dd7cddfSDavid du Colombier curtext = p;
550b87cd620SDavid du Colombier if(debug['V'])
5517dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
5527dd7cddfSDavid du Colombier p->pc, p);
5537dd7cddfSDavid du Colombier continue;
5547dd7cddfSDavid du Colombier }
555b87cd620SDavid du Colombier if(debug['V'])
5567dd7cddfSDavid du Colombier Bprint(&bso, "\t\t%6ld", lcsize);
5577dd7cddfSDavid du Colombier v = (p->pc - oldpc) / MINLC;
5587dd7cddfSDavid du Colombier while(v) {
5597dd7cddfSDavid du Colombier s = 127;
5607dd7cddfSDavid du Colombier if(v < 127)
5617dd7cddfSDavid du Colombier s = v;
5627dd7cddfSDavid du Colombier CPUT(s+128); /* 129-255 +pc */
563b87cd620SDavid du Colombier if(debug['V'])
5647dd7cddfSDavid du Colombier Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
5657dd7cddfSDavid du Colombier v -= s;
5667dd7cddfSDavid du Colombier lcsize++;
5677dd7cddfSDavid du Colombier }
5687dd7cddfSDavid du Colombier s = p->line - oldlc;
5697dd7cddfSDavid du Colombier oldlc = p->line;
5707dd7cddfSDavid du Colombier oldpc = p->pc + MINLC;
5717dd7cddfSDavid du Colombier if(s > 64 || s < -64) {
5727dd7cddfSDavid du Colombier CPUT(0); /* 0 vv +lc */
5737dd7cddfSDavid du Colombier CPUT(s>>24);
5747dd7cddfSDavid du Colombier CPUT(s>>16);
5757dd7cddfSDavid du Colombier CPUT(s>>8);
5767dd7cddfSDavid du Colombier CPUT(s);
577b87cd620SDavid du Colombier if(debug['V']) {
5787dd7cddfSDavid du Colombier if(s > 0)
5797dd7cddfSDavid du Colombier Bprint(&bso, " lc+%ld(%d,%ld)\n",
5807dd7cddfSDavid du Colombier s, 0, s);
5817dd7cddfSDavid du Colombier else
5827dd7cddfSDavid du Colombier Bprint(&bso, " lc%ld(%d,%ld)\n",
5837dd7cddfSDavid du Colombier s, 0, s);
5847dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
5857dd7cddfSDavid du Colombier p->pc, p);
5867dd7cddfSDavid du Colombier }
5877dd7cddfSDavid du Colombier lcsize += 5;
5887dd7cddfSDavid du Colombier continue;
5897dd7cddfSDavid du Colombier }
5907dd7cddfSDavid du Colombier if(s > 0) {
5917dd7cddfSDavid du Colombier CPUT(0+s); /* 1-64 +lc */
592b87cd620SDavid du Colombier if(debug['V']) {
5937dd7cddfSDavid du Colombier Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
5947dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
5957dd7cddfSDavid du Colombier p->pc, p);
5967dd7cddfSDavid du Colombier }
5977dd7cddfSDavid du Colombier } else {
5987dd7cddfSDavid du Colombier CPUT(64-s); /* 65-128 -lc */
599b87cd620SDavid du Colombier if(debug['V']) {
6007dd7cddfSDavid du Colombier Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
6017dd7cddfSDavid du Colombier Bprint(&bso, "%6lux %P\n",
6027dd7cddfSDavid du Colombier p->pc, p);
6037dd7cddfSDavid du Colombier }
6047dd7cddfSDavid du Colombier }
6057dd7cddfSDavid du Colombier lcsize++;
6067dd7cddfSDavid du Colombier }
6077dd7cddfSDavid du Colombier while(lcsize & 1) {
6087dd7cddfSDavid du Colombier s = 129;
6097dd7cddfSDavid du Colombier CPUT(s);
6107dd7cddfSDavid du Colombier lcsize++;
6117dd7cddfSDavid du Colombier }
612b87cd620SDavid du Colombier if(debug['v'] || debug['V'])
6137dd7cddfSDavid du Colombier Bprint(&bso, "lcsize = %ld\n", lcsize);
6147dd7cddfSDavid du Colombier Bflush(&bso);
6157dd7cddfSDavid du Colombier }
6167dd7cddfSDavid du Colombier
6177dd7cddfSDavid du Colombier void
datblk(long s,long n)6187dd7cddfSDavid du Colombier datblk(long s, long n)
6197dd7cddfSDavid du Colombier {
6207dd7cddfSDavid du Colombier Prog *p;
6217dd7cddfSDavid du Colombier char *cast;
6227dd7cddfSDavid du Colombier long l, fl, j, d;
6237dd7cddfSDavid du Colombier int i, c;
6247dd7cddfSDavid du Colombier
6257dd7cddfSDavid du Colombier memset(buf.dbuf, 0, n+100);
6267dd7cddfSDavid du Colombier for(p = datap; p != P; p = p->link) {
6277dd7cddfSDavid du Colombier curp = p;
6287dd7cddfSDavid du Colombier l = p->from.sym->value + p->from.offset - s;
6297dd7cddfSDavid du Colombier c = p->reg;
6307dd7cddfSDavid du Colombier i = 0;
6317dd7cddfSDavid du Colombier if(l < 0) {
6327dd7cddfSDavid du Colombier if(l+c <= 0)
6337dd7cddfSDavid du Colombier continue;
6347dd7cddfSDavid du Colombier while(l < 0) {
6357dd7cddfSDavid du Colombier l++;
6367dd7cddfSDavid du Colombier i++;
6377dd7cddfSDavid du Colombier }
6387dd7cddfSDavid du Colombier }
6397dd7cddfSDavid du Colombier if(l >= n)
6407dd7cddfSDavid du Colombier continue;
6417dd7cddfSDavid du Colombier if(p->as != AINIT && p->as != ADYNT) {
6427dd7cddfSDavid du Colombier for(j=l+(c-i)-1; j>=l; j--)
6437dd7cddfSDavid du Colombier if(buf.dbuf[j]) {
6447dd7cddfSDavid du Colombier print("%P\n", p);
6456b6b9ac8SDavid du Colombier diag("multiple initialization");
6467dd7cddfSDavid du Colombier break;
6477dd7cddfSDavid du Colombier }
6487dd7cddfSDavid du Colombier }
6497dd7cddfSDavid du Colombier switch(p->to.type) {
6507dd7cddfSDavid du Colombier default:
6516b6b9ac8SDavid du Colombier diag("unknown mode in initialization\n%P", p);
6527dd7cddfSDavid du Colombier break;
6537dd7cddfSDavid du Colombier
6547dd7cddfSDavid du Colombier case D_FCONST:
6557dd7cddfSDavid du Colombier switch(c) {
6567dd7cddfSDavid du Colombier default:
6577dd7cddfSDavid du Colombier case 4:
6587dd7cddfSDavid du Colombier fl = ieeedtof(&p->to.ieee);
6597dd7cddfSDavid du Colombier cast = (char*)&fl;
6607dd7cddfSDavid du Colombier for(; i<c; i++) {
6617dd7cddfSDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i+4]];
6627dd7cddfSDavid du Colombier l++;
6637dd7cddfSDavid du Colombier }
6647dd7cddfSDavid du Colombier break;
6657dd7cddfSDavid du Colombier case 8:
6667dd7cddfSDavid du Colombier cast = (char*)&p->to.ieee;
6677dd7cddfSDavid du Colombier for(; i<c; i++) {
6687dd7cddfSDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i]];
6697dd7cddfSDavid du Colombier l++;
6707dd7cddfSDavid du Colombier }
6717dd7cddfSDavid du Colombier break;
6727dd7cddfSDavid du Colombier }
6737dd7cddfSDavid du Colombier break;
6747dd7cddfSDavid du Colombier
6757dd7cddfSDavid du Colombier case D_SCONST:
6767dd7cddfSDavid du Colombier for(; i<c; i++) {
6777dd7cddfSDavid du Colombier buf.dbuf[l] = p->to.sval[i];
6787dd7cddfSDavid du Colombier l++;
6797dd7cddfSDavid du Colombier }
6807dd7cddfSDavid du Colombier break;
6817dd7cddfSDavid du Colombier
6827dd7cddfSDavid du Colombier case D_CONST:
6837dd7cddfSDavid du Colombier d = p->to.offset;
6847dd7cddfSDavid du Colombier if(p->to.sym) {
685375daca8SDavid du Colombier if(p->to.sym->type == SUNDEF){
686375daca8SDavid du Colombier ckoff(p->to.sym, d);
687375daca8SDavid du Colombier d += p->to.sym->value;
688375daca8SDavid du Colombier }
6897dd7cddfSDavid du Colombier if(p->to.sym->type == STEXT ||
6907dd7cddfSDavid du Colombier p->to.sym->type == SLEAF)
6917dd7cddfSDavid du Colombier d += p->to.sym->value;
6927dd7cddfSDavid du Colombier if(p->to.sym->type == SDATA)
6937dd7cddfSDavid du Colombier d += p->to.sym->value + INITDAT;
6947dd7cddfSDavid du Colombier if(p->to.sym->type == SBSS)
6957dd7cddfSDavid du Colombier d += p->to.sym->value + INITDAT;
696375daca8SDavid du Colombier if(dlm)
697375daca8SDavid du Colombier dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
6987dd7cddfSDavid du Colombier }
6997dd7cddfSDavid du Colombier cast = (char*)&d;
7007dd7cddfSDavid du Colombier switch(c) {
7017dd7cddfSDavid du Colombier default:
7026b6b9ac8SDavid du Colombier diag("bad nuxi %d %d\n%P", c, i, curp);
7037dd7cddfSDavid du Colombier break;
7047dd7cddfSDavid du Colombier case 1:
7057dd7cddfSDavid du Colombier for(; i<c; i++) {
7067dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi1[i]];
7077dd7cddfSDavid du Colombier l++;
7087dd7cddfSDavid du Colombier }
7097dd7cddfSDavid du Colombier break;
7107dd7cddfSDavid du Colombier case 2:
7117dd7cddfSDavid du Colombier for(; i<c; i++) {
7127dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi2[i]];
7137dd7cddfSDavid du Colombier l++;
7147dd7cddfSDavid du Colombier }
7157dd7cddfSDavid du Colombier break;
7167dd7cddfSDavid du Colombier case 4:
7177dd7cddfSDavid du Colombier for(; i<c; i++) {
7187dd7cddfSDavid du Colombier buf.dbuf[l] = cast[inuxi4[i]];
7197dd7cddfSDavid du Colombier l++;
7207dd7cddfSDavid du Colombier }
7217dd7cddfSDavid du Colombier break;
7227dd7cddfSDavid du Colombier }
7237dd7cddfSDavid du Colombier break;
7247dd7cddfSDavid du Colombier }
7257dd7cddfSDavid du Colombier }
7267dd7cddfSDavid du Colombier write(cout, buf.dbuf, n);
7277dd7cddfSDavid du Colombier }
728