174a4d8c2SCharles.Forsyth #include "l.h"
274a4d8c2SCharles.Forsyth
3647adfbcSforsyth #define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
474a4d8c2SCharles.Forsyth
574a4d8c2SCharles.Forsyth #define LPUT(c)\
674a4d8c2SCharles.Forsyth {\
774a4d8c2SCharles.Forsyth cbp[0] = (c)>>24;\
874a4d8c2SCharles.Forsyth cbp[1] = (c)>>16;\
974a4d8c2SCharles.Forsyth cbp[2] = (c)>>8;\
1074a4d8c2SCharles.Forsyth cbp[3] = (c);\
1174a4d8c2SCharles.Forsyth cbp += 4;\
1274a4d8c2SCharles.Forsyth cbc -= 4;\
1374a4d8c2SCharles.Forsyth if(cbc <= 0)\
1474a4d8c2SCharles.Forsyth cflush();\
1574a4d8c2SCharles.Forsyth }
1674a4d8c2SCharles.Forsyth
1774a4d8c2SCharles.Forsyth #define CPUT(c)\
1874a4d8c2SCharles.Forsyth {\
1974a4d8c2SCharles.Forsyth cbp[0] = (c);\
2074a4d8c2SCharles.Forsyth cbp++;\
2174a4d8c2SCharles.Forsyth cbc--;\
2274a4d8c2SCharles.Forsyth if(cbc <= 0)\
2374a4d8c2SCharles.Forsyth cflush();\
2474a4d8c2SCharles.Forsyth }
2574a4d8c2SCharles.Forsyth
2674a4d8c2SCharles.Forsyth void strnput(char*, int);
2774a4d8c2SCharles.Forsyth
2874a4d8c2SCharles.Forsyth long
entryvalue(void)2974a4d8c2SCharles.Forsyth entryvalue(void)
3074a4d8c2SCharles.Forsyth {
3174a4d8c2SCharles.Forsyth char *a;
3274a4d8c2SCharles.Forsyth Sym *s;
3374a4d8c2SCharles.Forsyth
3474a4d8c2SCharles.Forsyth a = INITENTRY;
3574a4d8c2SCharles.Forsyth if(*a >= '0' && *a <= '9')
3674a4d8c2SCharles.Forsyth return atolwhex(a);
3774a4d8c2SCharles.Forsyth s = lookup(a, 0);
3874a4d8c2SCharles.Forsyth if(s->type == 0)
3974a4d8c2SCharles.Forsyth return INITTEXT;
4074a4d8c2SCharles.Forsyth if(dlm && s->type == SDATA)
4174a4d8c2SCharles.Forsyth return s->value+INITDAT;
4274a4d8c2SCharles.Forsyth if(s->type != STEXT && s->type != SLEAF)
4374a4d8c2SCharles.Forsyth diag("entry not text: %s", s->name);
4474a4d8c2SCharles.Forsyth return s->value;
4574a4d8c2SCharles.Forsyth }
4674a4d8c2SCharles.Forsyth
47*45a20ab7Sforsyth static void
elf32jmp(Putl putl)48*45a20ab7Sforsyth elf32jmp(Putl putl)
49*45a20ab7Sforsyth {
50*45a20ab7Sforsyth /* describe a tiny text section at end with jmp to start; see below */
51*45a20ab7Sforsyth elf32phdr(putl, PT_LOAD, HEADR+textsize-JMPSZ, 0xFFFFFFFC, 0xFFFFFFFC,
52*45a20ab7Sforsyth JMPSZ, JMPSZ, R|X, 0); /* text */
53*45a20ab7Sforsyth }
54*45a20ab7Sforsyth
5574a4d8c2SCharles.Forsyth void
asmb(void)5674a4d8c2SCharles.Forsyth asmb(void)
5774a4d8c2SCharles.Forsyth {
5874a4d8c2SCharles.Forsyth Prog *p;
5974a4d8c2SCharles.Forsyth long t;
6074a4d8c2SCharles.Forsyth Optab *o;
61647adfbcSforsyth long prevpc;
6274a4d8c2SCharles.Forsyth
6374a4d8c2SCharles.Forsyth if(debug['v'])
6474a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f asm\n", cputime());
6574a4d8c2SCharles.Forsyth Bflush(&bso);
66647adfbcSforsyth
67647adfbcSforsyth /* emit text segment */
6874a4d8c2SCharles.Forsyth seek(cout, HEADR, 0);
69647adfbcSforsyth prevpc = pc = INITTEXT;
7074a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
7174a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
7274a4d8c2SCharles.Forsyth curtext = p;
7374a4d8c2SCharles.Forsyth autosize = p->to.offset + 4;
7474a4d8c2SCharles.Forsyth if(p->from3.type == D_CONST) {
7574a4d8c2SCharles.Forsyth for(; pc < p->pc; pc++)
7674a4d8c2SCharles.Forsyth CPUT(0);
7774a4d8c2SCharles.Forsyth }
7874a4d8c2SCharles.Forsyth }
7974a4d8c2SCharles.Forsyth if(p->pc != pc) {
8074a4d8c2SCharles.Forsyth diag("phase error %lux sb %lux",
8174a4d8c2SCharles.Forsyth p->pc, pc);
8274a4d8c2SCharles.Forsyth if(!debug['a'])
8374a4d8c2SCharles.Forsyth prasm(curp);
8474a4d8c2SCharles.Forsyth pc = p->pc;
8574a4d8c2SCharles.Forsyth }
8674a4d8c2SCharles.Forsyth curp = p;
8774a4d8c2SCharles.Forsyth o = oplook(p); /* could probably avoid this call */
8874a4d8c2SCharles.Forsyth if(asmout(p, o, 0)) {
8974a4d8c2SCharles.Forsyth p = p->link;
9074a4d8c2SCharles.Forsyth pc += 4;
9174a4d8c2SCharles.Forsyth }
9274a4d8c2SCharles.Forsyth pc += o->size;
93647adfbcSforsyth if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
94647adfbcSforsyth char *tn;
95647adfbcSforsyth
96*45a20ab7Sforsyth tn = "??none??";
97647adfbcSforsyth if(curtext != P && curtext->from.sym != S)
98647adfbcSforsyth tn = curtext->from.sym->name;
99647adfbcSforsyth Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
10074a4d8c2SCharles.Forsyth }
101647adfbcSforsyth prevpc = pc;
102647adfbcSforsyth }
103647adfbcSforsyth
10474a4d8c2SCharles.Forsyth if(debug['a'])
10574a4d8c2SCharles.Forsyth Bprint(&bso, "\n");
10674a4d8c2SCharles.Forsyth Bflush(&bso);
10774a4d8c2SCharles.Forsyth cflush();
10874a4d8c2SCharles.Forsyth
109647adfbcSforsyth /* emit data segment */
11074a4d8c2SCharles.Forsyth curtext = P;
11174a4d8c2SCharles.Forsyth switch(HEADTYPE) {
112647adfbcSforsyth case 6:
113*45a20ab7Sforsyth /*
114*45a20ab7Sforsyth * but first, for virtex 4, inject a jmp instruction after
115*45a20ab7Sforsyth * other text: branch to absolute entry address (0xfffe2100).
116*45a20ab7Sforsyth */
117*45a20ab7Sforsyth lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
118647adfbcSforsyth textsize += JMPSZ;
119*45a20ab7Sforsyth cflush();
120647adfbcSforsyth /* fall through */
12174a4d8c2SCharles.Forsyth case 0:
12274a4d8c2SCharles.Forsyth case 1:
12374a4d8c2SCharles.Forsyth case 2:
12474a4d8c2SCharles.Forsyth case 5:
12574a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize, 0);
12674a4d8c2SCharles.Forsyth break;
12774a4d8c2SCharles.Forsyth case 3:
12874a4d8c2SCharles.Forsyth seek(cout, rnd(HEADR+textsize, 4), 0);
12974a4d8c2SCharles.Forsyth break;
13074a4d8c2SCharles.Forsyth case 4:
13174a4d8c2SCharles.Forsyth seek(cout, rnd(HEADR+textsize, 4096), 0);
13274a4d8c2SCharles.Forsyth break;
13374a4d8c2SCharles.Forsyth }
13474a4d8c2SCharles.Forsyth
13574a4d8c2SCharles.Forsyth if(dlm){
13674a4d8c2SCharles.Forsyth char buf[8];
13774a4d8c2SCharles.Forsyth
13874a4d8c2SCharles.Forsyth write(cout, buf, INITDAT-textsize);
13974a4d8c2SCharles.Forsyth textsize = INITDAT;
14074a4d8c2SCharles.Forsyth }
14174a4d8c2SCharles.Forsyth
14274a4d8c2SCharles.Forsyth for(t = 0; t < datsize; t += sizeof(buf)-100) {
14374a4d8c2SCharles.Forsyth if(datsize-t > sizeof(buf)-100)
14474a4d8c2SCharles.Forsyth datblk(t, sizeof(buf)-100);
14574a4d8c2SCharles.Forsyth else
14674a4d8c2SCharles.Forsyth datblk(t, datsize-t);
14774a4d8c2SCharles.Forsyth }
14874a4d8c2SCharles.Forsyth
14974a4d8c2SCharles.Forsyth symsize = 0;
15074a4d8c2SCharles.Forsyth lcsize = 0;
15174a4d8c2SCharles.Forsyth if(!debug['s']) {
15274a4d8c2SCharles.Forsyth if(debug['v'])
15374a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f sym\n", cputime());
15474a4d8c2SCharles.Forsyth Bflush(&bso);
15574a4d8c2SCharles.Forsyth switch(HEADTYPE) {
15674a4d8c2SCharles.Forsyth case 0:
15774a4d8c2SCharles.Forsyth case 1:
15874a4d8c2SCharles.Forsyth case 2:
15974a4d8c2SCharles.Forsyth case 5:
160647adfbcSforsyth case 6:
16174a4d8c2SCharles.Forsyth seek(cout, HEADR+textsize+datsize, 0);
16274a4d8c2SCharles.Forsyth break;
16374a4d8c2SCharles.Forsyth case 3:
16474a4d8c2SCharles.Forsyth seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
16574a4d8c2SCharles.Forsyth break;
16674a4d8c2SCharles.Forsyth case 4:
16774a4d8c2SCharles.Forsyth seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
16874a4d8c2SCharles.Forsyth break;
16974a4d8c2SCharles.Forsyth }
17074a4d8c2SCharles.Forsyth if(!debug['s'])
17174a4d8c2SCharles.Forsyth asmsym();
17274a4d8c2SCharles.Forsyth if(debug['v'])
17374a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f sp\n", cputime());
17474a4d8c2SCharles.Forsyth Bflush(&bso);
17574a4d8c2SCharles.Forsyth if(!debug['s'])
17674a4d8c2SCharles.Forsyth asmlc();
17774a4d8c2SCharles.Forsyth if(dlm)
17874a4d8c2SCharles.Forsyth asmdyn();
17974a4d8c2SCharles.Forsyth if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */
18074a4d8c2SCharles.Forsyth if((symsize+lcsize) & 1)
18174a4d8c2SCharles.Forsyth CPUT(0);
18274a4d8c2SCharles.Forsyth cflush();
18374a4d8c2SCharles.Forsyth }
18474a4d8c2SCharles.Forsyth else if(dlm){
18574a4d8c2SCharles.Forsyth asmdyn();
18674a4d8c2SCharles.Forsyth cflush();
18774a4d8c2SCharles.Forsyth }
18874a4d8c2SCharles.Forsyth
189647adfbcSforsyth /* back up and write the header */
19074a4d8c2SCharles.Forsyth seek(cout, 0L, 0);
19174a4d8c2SCharles.Forsyth switch(HEADTYPE) {
19274a4d8c2SCharles.Forsyth case 0:
19374a4d8c2SCharles.Forsyth lput(0x1030107); /* magic and sections */
19474a4d8c2SCharles.Forsyth lput(textsize); /* sizes */
19574a4d8c2SCharles.Forsyth lput(datsize);
19674a4d8c2SCharles.Forsyth lput(bsssize);
19774a4d8c2SCharles.Forsyth lput(symsize); /* nsyms */
19874a4d8c2SCharles.Forsyth lput(entryvalue()); /* va of entry */
19974a4d8c2SCharles.Forsyth lput(0L);
20074a4d8c2SCharles.Forsyth lput(lcsize);
20174a4d8c2SCharles.Forsyth break;
20274a4d8c2SCharles.Forsyth case 1:
20374a4d8c2SCharles.Forsyth lput(0x4a6f7921); /* Joy! */
20474a4d8c2SCharles.Forsyth lput(0x70656666); /* peff */
20574a4d8c2SCharles.Forsyth lput(0x70777063); /* pwpc */
20674a4d8c2SCharles.Forsyth lput(1);
20774a4d8c2SCharles.Forsyth lput(0);
20874a4d8c2SCharles.Forsyth lput(0);
20974a4d8c2SCharles.Forsyth lput(0);
21074a4d8c2SCharles.Forsyth lput(0);
21174a4d8c2SCharles.Forsyth lput(0x30002); /*YY*/
21274a4d8c2SCharles.Forsyth lput(0);
21374a4d8c2SCharles.Forsyth lput(~0);
21474a4d8c2SCharles.Forsyth lput(0);
21574a4d8c2SCharles.Forsyth lput(textsize+datsize);
21674a4d8c2SCharles.Forsyth lput(textsize+datsize);
21774a4d8c2SCharles.Forsyth lput(textsize+datsize);
21874a4d8c2SCharles.Forsyth lput(0xd0); /* header size */
21974a4d8c2SCharles.Forsyth lput(0x10400);
22074a4d8c2SCharles.Forsyth lput(~0);
22174a4d8c2SCharles.Forsyth lput(0);
22274a4d8c2SCharles.Forsyth lput(0xc);
22374a4d8c2SCharles.Forsyth lput(0xc);
22474a4d8c2SCharles.Forsyth lput(0xc);
22574a4d8c2SCharles.Forsyth lput(0xc0);
22674a4d8c2SCharles.Forsyth lput(0x01010400);
22774a4d8c2SCharles.Forsyth lput(~0);
22874a4d8c2SCharles.Forsyth lput(0);
22974a4d8c2SCharles.Forsyth lput(0x38);
23074a4d8c2SCharles.Forsyth lput(0x38);
23174a4d8c2SCharles.Forsyth lput(0x38);
23274a4d8c2SCharles.Forsyth lput(0x80);
23374a4d8c2SCharles.Forsyth lput(0x04040400);
23474a4d8c2SCharles.Forsyth lput(0);
23574a4d8c2SCharles.Forsyth lput(1);
23674a4d8c2SCharles.Forsyth lput(0);
23774a4d8c2SCharles.Forsyth lput(~0);
23874a4d8c2SCharles.Forsyth lput(0);
23974a4d8c2SCharles.Forsyth lput(~0);
24074a4d8c2SCharles.Forsyth lput(0);
24174a4d8c2SCharles.Forsyth lput(0);
24274a4d8c2SCharles.Forsyth lput(0);
24374a4d8c2SCharles.Forsyth lput(0);
24474a4d8c2SCharles.Forsyth lput(0);
24574a4d8c2SCharles.Forsyth lput(0);
24674a4d8c2SCharles.Forsyth lput(0);
24774a4d8c2SCharles.Forsyth lput(0);
24874a4d8c2SCharles.Forsyth lput(0);
24974a4d8c2SCharles.Forsyth lput(0);
25074a4d8c2SCharles.Forsyth lput(0);
25174a4d8c2SCharles.Forsyth lput(0x3100); /* load address */
25274a4d8c2SCharles.Forsyth lput(0);
25374a4d8c2SCharles.Forsyth lput(0);
25474a4d8c2SCharles.Forsyth lput(0); /* whew! */
25574a4d8c2SCharles.Forsyth break;
25674a4d8c2SCharles.Forsyth case 2:
25774a4d8c2SCharles.Forsyth if(dlm)
25874a4d8c2SCharles.Forsyth lput(0x80000000 | (4*21*21+7)); /* magic */
25974a4d8c2SCharles.Forsyth else
26074a4d8c2SCharles.Forsyth lput(4*21*21+7); /* magic */
26174a4d8c2SCharles.Forsyth lput(textsize); /* sizes */
26274a4d8c2SCharles.Forsyth lput(datsize);
26374a4d8c2SCharles.Forsyth lput(bsssize);
26474a4d8c2SCharles.Forsyth lput(symsize); /* nsyms */
26574a4d8c2SCharles.Forsyth lput(entryvalue()); /* va of entry */
26674a4d8c2SCharles.Forsyth lput(0L);
26774a4d8c2SCharles.Forsyth lput(lcsize);
26874a4d8c2SCharles.Forsyth break;
26974a4d8c2SCharles.Forsyth case 3:
27074a4d8c2SCharles.Forsyth break;
27174a4d8c2SCharles.Forsyth case 4:
27274a4d8c2SCharles.Forsyth lput((0x1DFL<<16)|3L); /* magic and sections */
27374a4d8c2SCharles.Forsyth lput(time(0)); /* time and date */
27474a4d8c2SCharles.Forsyth lput(rnd(HEADR+textsize, 4096)+datsize);
27574a4d8c2SCharles.Forsyth lput(symsize); /* nsyms */
27674a4d8c2SCharles.Forsyth lput((0x48L<<16)|15L); /* size of optional hdr and flags */
27774a4d8c2SCharles.Forsyth
27874a4d8c2SCharles.Forsyth lput((0413<<16)|01L); /* magic and version */
27974a4d8c2SCharles.Forsyth lput(textsize); /* sizes */
28074a4d8c2SCharles.Forsyth lput(datsize);
28174a4d8c2SCharles.Forsyth lput(bsssize);
28274a4d8c2SCharles.Forsyth lput(entryvalue()); /* va of entry */
28374a4d8c2SCharles.Forsyth lput(INITTEXT); /* va of base of text */
28474a4d8c2SCharles.Forsyth lput(INITDAT); /* va of base of data */
28574a4d8c2SCharles.Forsyth lput(INITDAT); /* address of TOC */
28674a4d8c2SCharles.Forsyth lput((1L<<16)|1); /* sn(entry) | sn(text) */
28774a4d8c2SCharles.Forsyth lput((2L<<16)|1); /* sn(data) | sn(toc) */
28874a4d8c2SCharles.Forsyth lput((0L<<16)|3); /* sn(loader) | sn(bss) */
28974a4d8c2SCharles.Forsyth lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */
29074a4d8c2SCharles.Forsyth lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */
29174a4d8c2SCharles.Forsyth lput(0); /* max stack allowed */
29274a4d8c2SCharles.Forsyth lput(0); /* max data allowed */
29374a4d8c2SCharles.Forsyth lput(0); lput(0); lput(0); /* reserved */
29474a4d8c2SCharles.Forsyth
29574a4d8c2SCharles.Forsyth strnput(".text", 8); /* text segment */
29674a4d8c2SCharles.Forsyth lput(INITTEXT); /* address */
29774a4d8c2SCharles.Forsyth lput(INITTEXT);
29874a4d8c2SCharles.Forsyth lput(textsize);
29974a4d8c2SCharles.Forsyth lput(HEADR);
30074a4d8c2SCharles.Forsyth lput(0L);
30174a4d8c2SCharles.Forsyth lput(HEADR+textsize+datsize+symsize);
30274a4d8c2SCharles.Forsyth lput(lcsize); /* line number size */
30374a4d8c2SCharles.Forsyth lput(0x20L); /* flags */
30474a4d8c2SCharles.Forsyth
30574a4d8c2SCharles.Forsyth strnput(".data", 8); /* data segment */
30674a4d8c2SCharles.Forsyth lput(INITDAT); /* address */
30774a4d8c2SCharles.Forsyth lput(INITDAT);
30874a4d8c2SCharles.Forsyth lput(datsize);
30974a4d8c2SCharles.Forsyth lput(rnd(HEADR+textsize, 4096));/* sizes */
31074a4d8c2SCharles.Forsyth lput(0L);
31174a4d8c2SCharles.Forsyth lput(0L);
31274a4d8c2SCharles.Forsyth lput(0L);
31374a4d8c2SCharles.Forsyth lput(0x40L); /* flags */
31474a4d8c2SCharles.Forsyth
31574a4d8c2SCharles.Forsyth strnput(".bss", 8); /* bss segment */
31674a4d8c2SCharles.Forsyth lput(INITDAT+datsize); /* address */
31774a4d8c2SCharles.Forsyth lput(INITDAT+datsize);
31874a4d8c2SCharles.Forsyth lput(bsssize);
31974a4d8c2SCharles.Forsyth lput(0L);
32074a4d8c2SCharles.Forsyth lput(0L);
32174a4d8c2SCharles.Forsyth lput(0L);
32274a4d8c2SCharles.Forsyth lput(0L);
32374a4d8c2SCharles.Forsyth lput(0x80L); /* flags */
32474a4d8c2SCharles.Forsyth break;
32574a4d8c2SCharles.Forsyth case 5:
326647adfbcSforsyth /*
327*45a20ab7Sforsyth * intended for blue/gene
328647adfbcSforsyth */
329*45a20ab7Sforsyth elf32(POWER, ELFDATA2MSB, 0, nil);
33074a4d8c2SCharles.Forsyth break;
331647adfbcSforsyth case 6:
332647adfbcSforsyth /*
333*45a20ab7Sforsyth * intended for virtex 4 boot
334647adfbcSforsyth */
335*45a20ab7Sforsyth debug['S'] = 1; /* symbol table */
336*45a20ab7Sforsyth elf32(POWER, ELFDATA2MSB, 1, elf32jmp);
337647adfbcSforsyth break;
33874a4d8c2SCharles.Forsyth }
33974a4d8c2SCharles.Forsyth cflush();
34074a4d8c2SCharles.Forsyth }
34174a4d8c2SCharles.Forsyth
34274a4d8c2SCharles.Forsyth void
strnput(char * s,int n)34374a4d8c2SCharles.Forsyth strnput(char *s, int n)
34474a4d8c2SCharles.Forsyth {
34574a4d8c2SCharles.Forsyth for(; *s; s++){
34674a4d8c2SCharles.Forsyth CPUT(*s);
34774a4d8c2SCharles.Forsyth n--;
34874a4d8c2SCharles.Forsyth }
34974a4d8c2SCharles.Forsyth for(; n > 0; n--)
35074a4d8c2SCharles.Forsyth CPUT(0);
35174a4d8c2SCharles.Forsyth }
35274a4d8c2SCharles.Forsyth
35374a4d8c2SCharles.Forsyth void
cput(long l)35474a4d8c2SCharles.Forsyth cput(long l)
35574a4d8c2SCharles.Forsyth {
35674a4d8c2SCharles.Forsyth CPUT(l);
35774a4d8c2SCharles.Forsyth }
35874a4d8c2SCharles.Forsyth
35974a4d8c2SCharles.Forsyth void
wput(long l)36074a4d8c2SCharles.Forsyth wput(long l)
36174a4d8c2SCharles.Forsyth {
36274a4d8c2SCharles.Forsyth cbp[0] = l>>8;
36374a4d8c2SCharles.Forsyth cbp[1] = l;
36474a4d8c2SCharles.Forsyth cbp += 2;
36574a4d8c2SCharles.Forsyth cbc -= 2;
36674a4d8c2SCharles.Forsyth if(cbc <= 0)
36774a4d8c2SCharles.Forsyth cflush();
36874a4d8c2SCharles.Forsyth }
36974a4d8c2SCharles.Forsyth
37074a4d8c2SCharles.Forsyth void
wputl(long l)371*45a20ab7Sforsyth wputl(long l)
372*45a20ab7Sforsyth {
373*45a20ab7Sforsyth cbp[0] = l;
374*45a20ab7Sforsyth cbp[1] = l>>8;
375*45a20ab7Sforsyth cbp += 2;
376*45a20ab7Sforsyth cbc -= 2;
377*45a20ab7Sforsyth if(cbc <= 0)
378*45a20ab7Sforsyth cflush();
379*45a20ab7Sforsyth }
380*45a20ab7Sforsyth
381*45a20ab7Sforsyth void
lput(long l)38274a4d8c2SCharles.Forsyth lput(long l)
38374a4d8c2SCharles.Forsyth {
38474a4d8c2SCharles.Forsyth LPUT(l);
38574a4d8c2SCharles.Forsyth }
38674a4d8c2SCharles.Forsyth
38774a4d8c2SCharles.Forsyth void
lputl(long c)388*45a20ab7Sforsyth lputl(long c)
389*45a20ab7Sforsyth {
390*45a20ab7Sforsyth cbp[0] = (c);
391*45a20ab7Sforsyth cbp[1] = (c)>>8;
392*45a20ab7Sforsyth cbp[2] = (c)>>16;
393*45a20ab7Sforsyth cbp[3] = (c)>>24;
394*45a20ab7Sforsyth cbp += 4;
395*45a20ab7Sforsyth cbc -= 4;
396*45a20ab7Sforsyth if(cbc <= 0)
397*45a20ab7Sforsyth cflush();
398*45a20ab7Sforsyth }
399*45a20ab7Sforsyth
400*45a20ab7Sforsyth void
llput(vlong v)401*45a20ab7Sforsyth llput(vlong v)
402*45a20ab7Sforsyth {
403*45a20ab7Sforsyth lput(v>>32);
404*45a20ab7Sforsyth lput(v);
405*45a20ab7Sforsyth }
406*45a20ab7Sforsyth
407*45a20ab7Sforsyth void
llputl(vlong v)408*45a20ab7Sforsyth llputl(vlong v)
409*45a20ab7Sforsyth {
410*45a20ab7Sforsyth lputl(v);
411*45a20ab7Sforsyth lputl(v>>32);
412*45a20ab7Sforsyth }
413*45a20ab7Sforsyth
414*45a20ab7Sforsyth void
cflush(void)41574a4d8c2SCharles.Forsyth cflush(void)
41674a4d8c2SCharles.Forsyth {
41774a4d8c2SCharles.Forsyth int n;
41874a4d8c2SCharles.Forsyth
41974a4d8c2SCharles.Forsyth n = sizeof(buf.cbuf) - cbc;
42074a4d8c2SCharles.Forsyth if(n)
42174a4d8c2SCharles.Forsyth write(cout, buf.cbuf, n);
42274a4d8c2SCharles.Forsyth cbp = buf.cbuf;
42374a4d8c2SCharles.Forsyth cbc = sizeof(buf.cbuf);
42474a4d8c2SCharles.Forsyth }
42574a4d8c2SCharles.Forsyth
42674a4d8c2SCharles.Forsyth void
asmsym(void)42774a4d8c2SCharles.Forsyth asmsym(void)
42874a4d8c2SCharles.Forsyth {
42974a4d8c2SCharles.Forsyth Prog *p;
43074a4d8c2SCharles.Forsyth Auto *a;
43174a4d8c2SCharles.Forsyth Sym *s;
43274a4d8c2SCharles.Forsyth int h;
43374a4d8c2SCharles.Forsyth
43474a4d8c2SCharles.Forsyth s = lookup("etext", 0);
43574a4d8c2SCharles.Forsyth if(s->type == STEXT)
43674a4d8c2SCharles.Forsyth putsymb(s->name, 'T', s->value, s->version);
43774a4d8c2SCharles.Forsyth
43874a4d8c2SCharles.Forsyth for(h=0; h<NHASH; h++)
43974a4d8c2SCharles.Forsyth for(s=hash[h]; s!=S; s=s->link)
44074a4d8c2SCharles.Forsyth switch(s->type) {
44174a4d8c2SCharles.Forsyth case SCONST:
44274a4d8c2SCharles.Forsyth putsymb(s->name, 'D', s->value, s->version);
44374a4d8c2SCharles.Forsyth continue;
44474a4d8c2SCharles.Forsyth
44574a4d8c2SCharles.Forsyth case SDATA:
44674a4d8c2SCharles.Forsyth putsymb(s->name, 'D', s->value+INITDAT, s->version);
44774a4d8c2SCharles.Forsyth continue;
44874a4d8c2SCharles.Forsyth
44974a4d8c2SCharles.Forsyth case SBSS:
45074a4d8c2SCharles.Forsyth putsymb(s->name, 'B', s->value+INITDAT, s->version);
45174a4d8c2SCharles.Forsyth continue;
45274a4d8c2SCharles.Forsyth
45374a4d8c2SCharles.Forsyth case SFILE:
45474a4d8c2SCharles.Forsyth putsymb(s->name, 'f', s->value, s->version);
45574a4d8c2SCharles.Forsyth continue;
45674a4d8c2SCharles.Forsyth }
45774a4d8c2SCharles.Forsyth
45874a4d8c2SCharles.Forsyth for(p=textp; p!=P; p=p->cond) {
45974a4d8c2SCharles.Forsyth s = p->from.sym;
46074a4d8c2SCharles.Forsyth if(s->type != STEXT && s->type != SLEAF)
46174a4d8c2SCharles.Forsyth continue;
46274a4d8c2SCharles.Forsyth
46374a4d8c2SCharles.Forsyth /* filenames first */
46474a4d8c2SCharles.Forsyth for(a=p->to.autom; a; a=a->link)
46574a4d8c2SCharles.Forsyth if(a->type == D_FILE)
46674a4d8c2SCharles.Forsyth putsymb(a->sym->name, 'z', a->aoffset, 0);
46774a4d8c2SCharles.Forsyth else
46874a4d8c2SCharles.Forsyth if(a->type == D_FILE1)
46974a4d8c2SCharles.Forsyth putsymb(a->sym->name, 'Z', a->aoffset, 0);
47074a4d8c2SCharles.Forsyth
47174a4d8c2SCharles.Forsyth if(s->type == STEXT)
47274a4d8c2SCharles.Forsyth putsymb(s->name, 'T', s->value, s->version);
47374a4d8c2SCharles.Forsyth else
47474a4d8c2SCharles.Forsyth putsymb(s->name, 'L', s->value, s->version);
47574a4d8c2SCharles.Forsyth
47674a4d8c2SCharles.Forsyth /* frame, auto and param after */
47774a4d8c2SCharles.Forsyth putsymb(".frame", 'm', p->to.offset+4, 0);
47874a4d8c2SCharles.Forsyth for(a=p->to.autom; a; a=a->link)
47974a4d8c2SCharles.Forsyth if(a->type == D_AUTO)
48074a4d8c2SCharles.Forsyth putsymb(a->sym->name, 'a', -a->aoffset, 0);
48174a4d8c2SCharles.Forsyth else
48274a4d8c2SCharles.Forsyth if(a->type == D_PARAM)
48374a4d8c2SCharles.Forsyth putsymb(a->sym->name, 'p', a->aoffset, 0);
48474a4d8c2SCharles.Forsyth }
48574a4d8c2SCharles.Forsyth if(debug['v'] || debug['n'])
48674a4d8c2SCharles.Forsyth Bprint(&bso, "symsize = %lud\n", symsize);
48774a4d8c2SCharles.Forsyth Bflush(&bso);
48874a4d8c2SCharles.Forsyth }
48974a4d8c2SCharles.Forsyth
49074a4d8c2SCharles.Forsyth void
putsymb(char * s,int t,long v,int ver)49174a4d8c2SCharles.Forsyth putsymb(char *s, int t, long v, int ver)
49274a4d8c2SCharles.Forsyth {
49374a4d8c2SCharles.Forsyth int i, f;
49474a4d8c2SCharles.Forsyth
49574a4d8c2SCharles.Forsyth if(t == 'f')
49674a4d8c2SCharles.Forsyth s++;
49774a4d8c2SCharles.Forsyth LPUT(v);
49874a4d8c2SCharles.Forsyth if(ver)
49974a4d8c2SCharles.Forsyth t += 'a' - 'A';
50074a4d8c2SCharles.Forsyth CPUT(t+0x80); /* 0x80 is variable length */
50174a4d8c2SCharles.Forsyth
50274a4d8c2SCharles.Forsyth if(t == 'Z' || t == 'z') {
50374a4d8c2SCharles.Forsyth CPUT(s[0]);
50474a4d8c2SCharles.Forsyth for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
50574a4d8c2SCharles.Forsyth CPUT(s[i]);
50674a4d8c2SCharles.Forsyth CPUT(s[i+1]);
50774a4d8c2SCharles.Forsyth }
50874a4d8c2SCharles.Forsyth CPUT(0);
50974a4d8c2SCharles.Forsyth CPUT(0);
51074a4d8c2SCharles.Forsyth i++;
51174a4d8c2SCharles.Forsyth }
51274a4d8c2SCharles.Forsyth else {
51374a4d8c2SCharles.Forsyth for(i=0; s[i]; i++)
51474a4d8c2SCharles.Forsyth CPUT(s[i]);
51574a4d8c2SCharles.Forsyth CPUT(0);
51674a4d8c2SCharles.Forsyth }
51774a4d8c2SCharles.Forsyth symsize += 4 + 1 + i + 1;
51874a4d8c2SCharles.Forsyth
51974a4d8c2SCharles.Forsyth if(debug['n']) {
52074a4d8c2SCharles.Forsyth if(t == 'z' || t == 'Z') {
52174a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux ", t, v);
52274a4d8c2SCharles.Forsyth for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
52374a4d8c2SCharles.Forsyth f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
52474a4d8c2SCharles.Forsyth Bprint(&bso, "/%x", f);
52574a4d8c2SCharles.Forsyth }
52674a4d8c2SCharles.Forsyth Bprint(&bso, "\n");
52774a4d8c2SCharles.Forsyth return;
52874a4d8c2SCharles.Forsyth }
52974a4d8c2SCharles.Forsyth if(ver)
53074a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
53174a4d8c2SCharles.Forsyth else
53274a4d8c2SCharles.Forsyth Bprint(&bso, "%c %.8lux %s\n", t, v, s);
53374a4d8c2SCharles.Forsyth }
53474a4d8c2SCharles.Forsyth }
53574a4d8c2SCharles.Forsyth
53674a4d8c2SCharles.Forsyth #define MINLC 4
53774a4d8c2SCharles.Forsyth void
asmlc(void)53874a4d8c2SCharles.Forsyth asmlc(void)
53974a4d8c2SCharles.Forsyth {
54074a4d8c2SCharles.Forsyth long oldpc, oldlc;
54174a4d8c2SCharles.Forsyth Prog *p;
54274a4d8c2SCharles.Forsyth long v, s;
54374a4d8c2SCharles.Forsyth
54474a4d8c2SCharles.Forsyth oldpc = INITTEXT;
54574a4d8c2SCharles.Forsyth oldlc = 0;
54674a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
54774a4d8c2SCharles.Forsyth if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
54874a4d8c2SCharles.Forsyth if(p->as == ATEXT)
54974a4d8c2SCharles.Forsyth curtext = p;
550*45a20ab7Sforsyth if(debug['V'])
55174a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
55274a4d8c2SCharles.Forsyth p->pc, p);
55374a4d8c2SCharles.Forsyth continue;
55474a4d8c2SCharles.Forsyth }
555*45a20ab7Sforsyth if(debug['V'])
55674a4d8c2SCharles.Forsyth Bprint(&bso, "\t\t%6ld", lcsize);
55774a4d8c2SCharles.Forsyth v = (p->pc - oldpc) / MINLC;
55874a4d8c2SCharles.Forsyth while(v) {
55974a4d8c2SCharles.Forsyth s = 127;
56074a4d8c2SCharles.Forsyth if(v < 127)
56174a4d8c2SCharles.Forsyth s = v;
56274a4d8c2SCharles.Forsyth CPUT(s+128); /* 129-255 +pc */
563*45a20ab7Sforsyth if(debug['V'])
56474a4d8c2SCharles.Forsyth Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
56574a4d8c2SCharles.Forsyth v -= s;
56674a4d8c2SCharles.Forsyth lcsize++;
56774a4d8c2SCharles.Forsyth }
56874a4d8c2SCharles.Forsyth s = p->line - oldlc;
56974a4d8c2SCharles.Forsyth oldlc = p->line;
57074a4d8c2SCharles.Forsyth oldpc = p->pc + MINLC;
57174a4d8c2SCharles.Forsyth if(s > 64 || s < -64) {
57274a4d8c2SCharles.Forsyth CPUT(0); /* 0 vv +lc */
57374a4d8c2SCharles.Forsyth CPUT(s>>24);
57474a4d8c2SCharles.Forsyth CPUT(s>>16);
57574a4d8c2SCharles.Forsyth CPUT(s>>8);
57674a4d8c2SCharles.Forsyth CPUT(s);
577*45a20ab7Sforsyth if(debug['V']) {
57874a4d8c2SCharles.Forsyth if(s > 0)
57974a4d8c2SCharles.Forsyth Bprint(&bso, " lc+%ld(%d,%ld)\n",
58074a4d8c2SCharles.Forsyth s, 0, s);
58174a4d8c2SCharles.Forsyth else
58274a4d8c2SCharles.Forsyth Bprint(&bso, " lc%ld(%d,%ld)\n",
58374a4d8c2SCharles.Forsyth s, 0, s);
58474a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
58574a4d8c2SCharles.Forsyth p->pc, p);
58674a4d8c2SCharles.Forsyth }
58774a4d8c2SCharles.Forsyth lcsize += 5;
58874a4d8c2SCharles.Forsyth continue;
58974a4d8c2SCharles.Forsyth }
59074a4d8c2SCharles.Forsyth if(s > 0) {
59174a4d8c2SCharles.Forsyth CPUT(0+s); /* 1-64 +lc */
592*45a20ab7Sforsyth if(debug['V']) {
59374a4d8c2SCharles.Forsyth Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
59474a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
59574a4d8c2SCharles.Forsyth p->pc, p);
59674a4d8c2SCharles.Forsyth }
59774a4d8c2SCharles.Forsyth } else {
59874a4d8c2SCharles.Forsyth CPUT(64-s); /* 65-128 -lc */
599*45a20ab7Sforsyth if(debug['V']) {
60074a4d8c2SCharles.Forsyth Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
60174a4d8c2SCharles.Forsyth Bprint(&bso, "%6lux %P\n",
60274a4d8c2SCharles.Forsyth p->pc, p);
60374a4d8c2SCharles.Forsyth }
60474a4d8c2SCharles.Forsyth }
60574a4d8c2SCharles.Forsyth lcsize++;
60674a4d8c2SCharles.Forsyth }
60774a4d8c2SCharles.Forsyth while(lcsize & 1) {
60874a4d8c2SCharles.Forsyth s = 129;
60974a4d8c2SCharles.Forsyth CPUT(s);
61074a4d8c2SCharles.Forsyth lcsize++;
61174a4d8c2SCharles.Forsyth }
612*45a20ab7Sforsyth if(debug['v'] || debug['V'])
61374a4d8c2SCharles.Forsyth Bprint(&bso, "lcsize = %ld\n", lcsize);
61474a4d8c2SCharles.Forsyth Bflush(&bso);
61574a4d8c2SCharles.Forsyth }
61674a4d8c2SCharles.Forsyth
61774a4d8c2SCharles.Forsyth void
datblk(long s,long n)61874a4d8c2SCharles.Forsyth datblk(long s, long n)
61974a4d8c2SCharles.Forsyth {
62074a4d8c2SCharles.Forsyth Prog *p;
62174a4d8c2SCharles.Forsyth char *cast;
62274a4d8c2SCharles.Forsyth long l, fl, j, d;
62374a4d8c2SCharles.Forsyth int i, c;
62474a4d8c2SCharles.Forsyth
62574a4d8c2SCharles.Forsyth memset(buf.dbuf, 0, n+100);
62674a4d8c2SCharles.Forsyth for(p = datap; p != P; p = p->link) {
62774a4d8c2SCharles.Forsyth curp = p;
62874a4d8c2SCharles.Forsyth l = p->from.sym->value + p->from.offset - s;
62974a4d8c2SCharles.Forsyth c = p->reg;
63074a4d8c2SCharles.Forsyth i = 0;
63174a4d8c2SCharles.Forsyth if(l < 0) {
63274a4d8c2SCharles.Forsyth if(l+c <= 0)
63374a4d8c2SCharles.Forsyth continue;
63474a4d8c2SCharles.Forsyth while(l < 0) {
63574a4d8c2SCharles.Forsyth l++;
63674a4d8c2SCharles.Forsyth i++;
63774a4d8c2SCharles.Forsyth }
63874a4d8c2SCharles.Forsyth }
63974a4d8c2SCharles.Forsyth if(l >= n)
64074a4d8c2SCharles.Forsyth continue;
64174a4d8c2SCharles.Forsyth if(p->as != AINIT && p->as != ADYNT) {
64274a4d8c2SCharles.Forsyth for(j=l+(c-i)-1; j>=l; j--)
64374a4d8c2SCharles.Forsyth if(buf.dbuf[j]) {
64474a4d8c2SCharles.Forsyth print("%P\n", p);
64574a4d8c2SCharles.Forsyth diag("multiple initialization");
64674a4d8c2SCharles.Forsyth break;
64774a4d8c2SCharles.Forsyth }
64874a4d8c2SCharles.Forsyth }
64974a4d8c2SCharles.Forsyth switch(p->to.type) {
65074a4d8c2SCharles.Forsyth default:
65174a4d8c2SCharles.Forsyth diag("unknown mode in initialization\n%P", p);
65274a4d8c2SCharles.Forsyth break;
65374a4d8c2SCharles.Forsyth
65474a4d8c2SCharles.Forsyth case D_FCONST:
65574a4d8c2SCharles.Forsyth switch(c) {
65674a4d8c2SCharles.Forsyth default:
65774a4d8c2SCharles.Forsyth case 4:
65874a4d8c2SCharles.Forsyth fl = ieeedtof(&p->to.ieee);
65974a4d8c2SCharles.Forsyth cast = (char*)&fl;
66074a4d8c2SCharles.Forsyth for(; i<c; i++) {
66174a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[fnuxi8[i+4]];
66274a4d8c2SCharles.Forsyth l++;
66374a4d8c2SCharles.Forsyth }
66474a4d8c2SCharles.Forsyth break;
66574a4d8c2SCharles.Forsyth case 8:
66674a4d8c2SCharles.Forsyth cast = (char*)&p->to.ieee;
66774a4d8c2SCharles.Forsyth for(; i<c; i++) {
66874a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[fnuxi8[i]];
66974a4d8c2SCharles.Forsyth l++;
67074a4d8c2SCharles.Forsyth }
67174a4d8c2SCharles.Forsyth break;
67274a4d8c2SCharles.Forsyth }
67374a4d8c2SCharles.Forsyth break;
67474a4d8c2SCharles.Forsyth
67574a4d8c2SCharles.Forsyth case D_SCONST:
67674a4d8c2SCharles.Forsyth for(; i<c; i++) {
67774a4d8c2SCharles.Forsyth buf.dbuf[l] = p->to.sval[i];
67874a4d8c2SCharles.Forsyth l++;
67974a4d8c2SCharles.Forsyth }
68074a4d8c2SCharles.Forsyth break;
68174a4d8c2SCharles.Forsyth
68274a4d8c2SCharles.Forsyth case D_CONST:
68374a4d8c2SCharles.Forsyth d = p->to.offset;
68474a4d8c2SCharles.Forsyth if(p->to.sym) {
68574a4d8c2SCharles.Forsyth if(p->to.sym->type == SUNDEF){
68674a4d8c2SCharles.Forsyth ckoff(p->to.sym, d);
68774a4d8c2SCharles.Forsyth d += p->to.sym->value;
68874a4d8c2SCharles.Forsyth }
68974a4d8c2SCharles.Forsyth if(p->to.sym->type == STEXT ||
69074a4d8c2SCharles.Forsyth p->to.sym->type == SLEAF)
69174a4d8c2SCharles.Forsyth d += p->to.sym->value;
69274a4d8c2SCharles.Forsyth if(p->to.sym->type == SDATA)
69374a4d8c2SCharles.Forsyth d += p->to.sym->value + INITDAT;
69474a4d8c2SCharles.Forsyth if(p->to.sym->type == SBSS)
69574a4d8c2SCharles.Forsyth d += p->to.sym->value + INITDAT;
69674a4d8c2SCharles.Forsyth if(dlm)
69774a4d8c2SCharles.Forsyth dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
69874a4d8c2SCharles.Forsyth }
69974a4d8c2SCharles.Forsyth cast = (char*)&d;
70074a4d8c2SCharles.Forsyth switch(c) {
70174a4d8c2SCharles.Forsyth default:
70274a4d8c2SCharles.Forsyth diag("bad nuxi %d %d\n%P", c, i, curp);
70374a4d8c2SCharles.Forsyth break;
70474a4d8c2SCharles.Forsyth case 1:
70574a4d8c2SCharles.Forsyth for(; i<c; i++) {
70674a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi1[i]];
70774a4d8c2SCharles.Forsyth l++;
70874a4d8c2SCharles.Forsyth }
70974a4d8c2SCharles.Forsyth break;
71074a4d8c2SCharles.Forsyth case 2:
71174a4d8c2SCharles.Forsyth for(; i<c; i++) {
71274a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi2[i]];
71374a4d8c2SCharles.Forsyth l++;
71474a4d8c2SCharles.Forsyth }
71574a4d8c2SCharles.Forsyth break;
71674a4d8c2SCharles.Forsyth case 4:
71774a4d8c2SCharles.Forsyth for(; i<c; i++) {
71874a4d8c2SCharles.Forsyth buf.dbuf[l] = cast[inuxi4[i]];
71974a4d8c2SCharles.Forsyth l++;
72074a4d8c2SCharles.Forsyth }
72174a4d8c2SCharles.Forsyth break;
72274a4d8c2SCharles.Forsyth }
72374a4d8c2SCharles.Forsyth break;
72474a4d8c2SCharles.Forsyth }
72574a4d8c2SCharles.Forsyth }
72674a4d8c2SCharles.Forsyth write(cout, buf.dbuf, n);
72774a4d8c2SCharles.Forsyth }
728