1*74a4d8c2SCharles.Forsyth #define EXTERN
2*74a4d8c2SCharles.Forsyth #include "l.h"
3*74a4d8c2SCharles.Forsyth #include <ar.h>
4*74a4d8c2SCharles.Forsyth
5*74a4d8c2SCharles.Forsyth #ifndef DEFAULT
6*74a4d8c2SCharles.Forsyth #define DEFAULT '9'
7*74a4d8c2SCharles.Forsyth #endif
8*74a4d8c2SCharles.Forsyth
9*74a4d8c2SCharles.Forsyth char *noname = "<none>";
10*74a4d8c2SCharles.Forsyth char symname[] = SYMDEF;
11*74a4d8c2SCharles.Forsyth char thechar = 'k';
12*74a4d8c2SCharles.Forsyth char *thestring = "sparc";
13*74a4d8c2SCharles.Forsyth
14*74a4d8c2SCharles.Forsyth /*
15*74a4d8c2SCharles.Forsyth * -H0 -T0x200000 -R0 is boot
16*74a4d8c2SCharles.Forsyth * -H2 -T4128 -R4096 is plan9 format
17*74a4d8c2SCharles.Forsyth * -H3 -T0xE0004000 -R4 is javastation boot format
18*74a4d8c2SCharles.Forsyth */
19*74a4d8c2SCharles.Forsyth
20*74a4d8c2SCharles.Forsyth void
main(int argc,char * argv[])21*74a4d8c2SCharles.Forsyth main(int argc, char *argv[])
22*74a4d8c2SCharles.Forsyth {
23*74a4d8c2SCharles.Forsyth int c;
24*74a4d8c2SCharles.Forsyth char *a;
25*74a4d8c2SCharles.Forsyth
26*74a4d8c2SCharles.Forsyth Binit(&bso, 1, OWRITE);
27*74a4d8c2SCharles.Forsyth cout = -1;
28*74a4d8c2SCharles.Forsyth listinit();
29*74a4d8c2SCharles.Forsyth outfile = 0;
30*74a4d8c2SCharles.Forsyth nerrors = 0;
31*74a4d8c2SCharles.Forsyth curtext = P;
32*74a4d8c2SCharles.Forsyth HEADTYPE = -1;
33*74a4d8c2SCharles.Forsyth INITTEXT = -1;
34*74a4d8c2SCharles.Forsyth INITDAT = -1;
35*74a4d8c2SCharles.Forsyth INITRND = -1;
36*74a4d8c2SCharles.Forsyth INITENTRY = 0;
37*74a4d8c2SCharles.Forsyth
38*74a4d8c2SCharles.Forsyth ARGBEGIN {
39*74a4d8c2SCharles.Forsyth default:
40*74a4d8c2SCharles.Forsyth c = ARGC();
41*74a4d8c2SCharles.Forsyth if(c >= 0 && c < sizeof(debug))
42*74a4d8c2SCharles.Forsyth debug[c]++;
43*74a4d8c2SCharles.Forsyth break;
44*74a4d8c2SCharles.Forsyth case 'o':
45*74a4d8c2SCharles.Forsyth outfile = ARGF();
46*74a4d8c2SCharles.Forsyth break;
47*74a4d8c2SCharles.Forsyth case 'E':
48*74a4d8c2SCharles.Forsyth a = ARGF();
49*74a4d8c2SCharles.Forsyth if(a)
50*74a4d8c2SCharles.Forsyth INITENTRY = a;
51*74a4d8c2SCharles.Forsyth break;
52*74a4d8c2SCharles.Forsyth case 'T':
53*74a4d8c2SCharles.Forsyth a = ARGF();
54*74a4d8c2SCharles.Forsyth if(a)
55*74a4d8c2SCharles.Forsyth INITTEXT = atolwhex(a);
56*74a4d8c2SCharles.Forsyth break;
57*74a4d8c2SCharles.Forsyth case 'D':
58*74a4d8c2SCharles.Forsyth a = ARGF();
59*74a4d8c2SCharles.Forsyth if(a)
60*74a4d8c2SCharles.Forsyth INITDAT = atolwhex(a);
61*74a4d8c2SCharles.Forsyth break;
62*74a4d8c2SCharles.Forsyth case 'R':
63*74a4d8c2SCharles.Forsyth a = ARGF();
64*74a4d8c2SCharles.Forsyth if(a)
65*74a4d8c2SCharles.Forsyth INITRND = atolwhex(a);
66*74a4d8c2SCharles.Forsyth break;
67*74a4d8c2SCharles.Forsyth case 'H':
68*74a4d8c2SCharles.Forsyth a = ARGF();
69*74a4d8c2SCharles.Forsyth if(a)
70*74a4d8c2SCharles.Forsyth HEADTYPE = atolwhex(a);
71*74a4d8c2SCharles.Forsyth break;
72*74a4d8c2SCharles.Forsyth } ARGEND
73*74a4d8c2SCharles.Forsyth USED(argc);
74*74a4d8c2SCharles.Forsyth if(*argv == 0) {
75*74a4d8c2SCharles.Forsyth diag("usage: vl [-options] objects");
76*74a4d8c2SCharles.Forsyth errorexit();
77*74a4d8c2SCharles.Forsyth }
78*74a4d8c2SCharles.Forsyth if(!debug['9'] && !debug['U'] && !debug['B'])
79*74a4d8c2SCharles.Forsyth debug[DEFAULT] = 1;
80*74a4d8c2SCharles.Forsyth if(HEADTYPE == -1) {
81*74a4d8c2SCharles.Forsyth if(debug['U'])
82*74a4d8c2SCharles.Forsyth HEADTYPE = 0;
83*74a4d8c2SCharles.Forsyth if(debug['B'])
84*74a4d8c2SCharles.Forsyth HEADTYPE = 1;
85*74a4d8c2SCharles.Forsyth if(debug['9'])
86*74a4d8c2SCharles.Forsyth HEADTYPE = 2;
87*74a4d8c2SCharles.Forsyth }
88*74a4d8c2SCharles.Forsyth switch(HEADTYPE) {
89*74a4d8c2SCharles.Forsyth default:
90*74a4d8c2SCharles.Forsyth diag("unknown -H option");
91*74a4d8c2SCharles.Forsyth errorexit();
92*74a4d8c2SCharles.Forsyth
93*74a4d8c2SCharles.Forsyth case 0: /* boot */
94*74a4d8c2SCharles.Forsyth HEADR = 32L;
95*74a4d8c2SCharles.Forsyth if(INITTEXT == -1)
96*74a4d8c2SCharles.Forsyth INITTEXT = 0x200000L;
97*74a4d8c2SCharles.Forsyth if(INITDAT == -1)
98*74a4d8c2SCharles.Forsyth INITDAT = 0;
99*74a4d8c2SCharles.Forsyth if(INITRND == -1)
100*74a4d8c2SCharles.Forsyth INITRND = 4096L;
101*74a4d8c2SCharles.Forsyth break;
102*74a4d8c2SCharles.Forsyth case 1: /* garbage */
103*74a4d8c2SCharles.Forsyth HEADR = 20L+60L;
104*74a4d8c2SCharles.Forsyth if(INITTEXT == -1)
105*74a4d8c2SCharles.Forsyth INITTEXT = 0x80020000L;
106*74a4d8c2SCharles.Forsyth if(INITDAT == -1)
107*74a4d8c2SCharles.Forsyth INITDAT = 0;
108*74a4d8c2SCharles.Forsyth if(INITRND == -1)
109*74a4d8c2SCharles.Forsyth INITRND = 4;
110*74a4d8c2SCharles.Forsyth break;
111*74a4d8c2SCharles.Forsyth case 2: /* plan 9 */
112*74a4d8c2SCharles.Forsyth HEADR = 32L;
113*74a4d8c2SCharles.Forsyth if(INITTEXT == -1)
114*74a4d8c2SCharles.Forsyth INITTEXT = 4128;
115*74a4d8c2SCharles.Forsyth if(INITDAT == -1)
116*74a4d8c2SCharles.Forsyth INITDAT = 0;
117*74a4d8c2SCharles.Forsyth if(INITRND == -1)
118*74a4d8c2SCharles.Forsyth INITRND = 4096;
119*74a4d8c2SCharles.Forsyth break;
120*74a4d8c2SCharles.Forsyth case 3: /* javastation boot */
121*74a4d8c2SCharles.Forsyth HEADR = 32L;
122*74a4d8c2SCharles.Forsyth if(INITTEXT == -1)
123*74a4d8c2SCharles.Forsyth INITTEXT = 0xE0004020L;
124*74a4d8c2SCharles.Forsyth if(INITDAT == -1)
125*74a4d8c2SCharles.Forsyth INITDAT = 0;
126*74a4d8c2SCharles.Forsyth if(INITRND == -1)
127*74a4d8c2SCharles.Forsyth INITRND = 4;
128*74a4d8c2SCharles.Forsyth break;
129*74a4d8c2SCharles.Forsyth }
130*74a4d8c2SCharles.Forsyth if(INITDAT != 0 && INITRND != 0)
131*74a4d8c2SCharles.Forsyth print("warning: -D0x%lux is ignored because of -R0x%lux\n",
132*74a4d8c2SCharles.Forsyth INITDAT, INITRND);
133*74a4d8c2SCharles.Forsyth if(debug['v'])
134*74a4d8c2SCharles.Forsyth Bprint(&bso, "HEADER = -H0x%d -T0x%lux -D0x%lux -R0x%lux\n",
135*74a4d8c2SCharles.Forsyth HEADTYPE, INITTEXT, INITDAT, INITRND);
136*74a4d8c2SCharles.Forsyth Bflush(&bso);
137*74a4d8c2SCharles.Forsyth zprg.as = AGOK;
138*74a4d8c2SCharles.Forsyth zprg.reg = NREG;
139*74a4d8c2SCharles.Forsyth zprg.from.name = D_NONE;
140*74a4d8c2SCharles.Forsyth zprg.from.type = D_NONE;
141*74a4d8c2SCharles.Forsyth zprg.from.reg = NREG;
142*74a4d8c2SCharles.Forsyth zprg.to = zprg.from;
143*74a4d8c2SCharles.Forsyth buildop();
144*74a4d8c2SCharles.Forsyth histgen = 0;
145*74a4d8c2SCharles.Forsyth textp = P;
146*74a4d8c2SCharles.Forsyth datap = P;
147*74a4d8c2SCharles.Forsyth pc = 0;
148*74a4d8c2SCharles.Forsyth dtype = 4;
149*74a4d8c2SCharles.Forsyth if(outfile == 0)
150*74a4d8c2SCharles.Forsyth outfile = "k.out";
151*74a4d8c2SCharles.Forsyth cout = create(outfile, 1, 0775);
152*74a4d8c2SCharles.Forsyth if(cout < 0) {
153*74a4d8c2SCharles.Forsyth diag("%s: cannot create", outfile);
154*74a4d8c2SCharles.Forsyth errorexit();
155*74a4d8c2SCharles.Forsyth }
156*74a4d8c2SCharles.Forsyth nuxiinit();
157*74a4d8c2SCharles.Forsyth version = 0;
158*74a4d8c2SCharles.Forsyth cbp = buf.cbuf;
159*74a4d8c2SCharles.Forsyth cbc = sizeof(buf.cbuf);
160*74a4d8c2SCharles.Forsyth firstp = prg();
161*74a4d8c2SCharles.Forsyth lastp = firstp;
162*74a4d8c2SCharles.Forsyth
163*74a4d8c2SCharles.Forsyth if(INITENTRY == 0) {
164*74a4d8c2SCharles.Forsyth INITENTRY = "_main";
165*74a4d8c2SCharles.Forsyth if(debug['p'])
166*74a4d8c2SCharles.Forsyth INITENTRY = "_mainp";
167*74a4d8c2SCharles.Forsyth if(!debug['l'])
168*74a4d8c2SCharles.Forsyth lookup(INITENTRY, 0)->type = SXREF;
169*74a4d8c2SCharles.Forsyth } else
170*74a4d8c2SCharles.Forsyth lookup(INITENTRY, 0)->type = SXREF;
171*74a4d8c2SCharles.Forsyth
172*74a4d8c2SCharles.Forsyth while(*argv)
173*74a4d8c2SCharles.Forsyth objfile(*argv++);
174*74a4d8c2SCharles.Forsyth if(!debug['l'])
175*74a4d8c2SCharles.Forsyth loadlib();
176*74a4d8c2SCharles.Forsyth firstp = firstp->link;
177*74a4d8c2SCharles.Forsyth if(firstp == P)
178*74a4d8c2SCharles.Forsyth goto out;
179*74a4d8c2SCharles.Forsyth patch();
180*74a4d8c2SCharles.Forsyth if(debug['p'])
181*74a4d8c2SCharles.Forsyth if(debug['1'])
182*74a4d8c2SCharles.Forsyth doprof1();
183*74a4d8c2SCharles.Forsyth else
184*74a4d8c2SCharles.Forsyth doprof2();
185*74a4d8c2SCharles.Forsyth dodata();
186*74a4d8c2SCharles.Forsyth follow();
187*74a4d8c2SCharles.Forsyth if(firstp == P)
188*74a4d8c2SCharles.Forsyth goto out;
189*74a4d8c2SCharles.Forsyth noops();
190*74a4d8c2SCharles.Forsyth span();
191*74a4d8c2SCharles.Forsyth asmb();
192*74a4d8c2SCharles.Forsyth undef();
193*74a4d8c2SCharles.Forsyth
194*74a4d8c2SCharles.Forsyth out:
195*74a4d8c2SCharles.Forsyth if(debug['v']) {
196*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f cpu time\n", cputime());
197*74a4d8c2SCharles.Forsyth Bprint(&bso, "%ld memory used\n", tothunk);
198*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
199*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
200*74a4d8c2SCharles.Forsyth }
201*74a4d8c2SCharles.Forsyth errorexit();
202*74a4d8c2SCharles.Forsyth }
203*74a4d8c2SCharles.Forsyth
204*74a4d8c2SCharles.Forsyth void
loadlib(void)205*74a4d8c2SCharles.Forsyth loadlib(void)
206*74a4d8c2SCharles.Forsyth {
207*74a4d8c2SCharles.Forsyth int i;
208*74a4d8c2SCharles.Forsyth long h;
209*74a4d8c2SCharles.Forsyth Sym *s;
210*74a4d8c2SCharles.Forsyth
211*74a4d8c2SCharles.Forsyth loop:
212*74a4d8c2SCharles.Forsyth xrefresolv = 0;
213*74a4d8c2SCharles.Forsyth for(i=0; i<libraryp; i++) {
214*74a4d8c2SCharles.Forsyth if(debug['v'])
215*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
216*74a4d8c2SCharles.Forsyth objfile(library[i]);
217*74a4d8c2SCharles.Forsyth }
218*74a4d8c2SCharles.Forsyth if(xrefresolv)
219*74a4d8c2SCharles.Forsyth for(h=0; h<nelem(hash); h++)
220*74a4d8c2SCharles.Forsyth for(s = hash[h]; s != S; s = s->link)
221*74a4d8c2SCharles.Forsyth if(s->type == SXREF)
222*74a4d8c2SCharles.Forsyth goto loop;
223*74a4d8c2SCharles.Forsyth }
224*74a4d8c2SCharles.Forsyth
225*74a4d8c2SCharles.Forsyth void
errorexit(void)226*74a4d8c2SCharles.Forsyth errorexit(void)
227*74a4d8c2SCharles.Forsyth {
228*74a4d8c2SCharles.Forsyth
229*74a4d8c2SCharles.Forsyth Bflush(&bso);
230*74a4d8c2SCharles.Forsyth if(nerrors) {
231*74a4d8c2SCharles.Forsyth if(cout >= 0)
232*74a4d8c2SCharles.Forsyth remove(outfile);
233*74a4d8c2SCharles.Forsyth exits("error");
234*74a4d8c2SCharles.Forsyth }
235*74a4d8c2SCharles.Forsyth exits(0);
236*74a4d8c2SCharles.Forsyth }
237*74a4d8c2SCharles.Forsyth
238*74a4d8c2SCharles.Forsyth void
objfile(char * file)239*74a4d8c2SCharles.Forsyth objfile(char *file)
240*74a4d8c2SCharles.Forsyth {
241*74a4d8c2SCharles.Forsyth long off, esym, cnt, l;
242*74a4d8c2SCharles.Forsyth int f, work;
243*74a4d8c2SCharles.Forsyth Sym *s;
244*74a4d8c2SCharles.Forsyth char magbuf[SARMAG];
245*74a4d8c2SCharles.Forsyth char name[100], pname[150];
246*74a4d8c2SCharles.Forsyth struct ar_hdr arhdr;
247*74a4d8c2SCharles.Forsyth char *e, *start, *stop;
248*74a4d8c2SCharles.Forsyth
249*74a4d8c2SCharles.Forsyth if(file[0] == '-' && file[1] == 'l') {
250*74a4d8c2SCharles.Forsyth if(debug['9'])
251*74a4d8c2SCharles.Forsyth sprint(name, "/%s/lib/lib", thestring);
252*74a4d8c2SCharles.Forsyth else
253*74a4d8c2SCharles.Forsyth sprint(name, "/usr/%clib/lib", thechar);
254*74a4d8c2SCharles.Forsyth strcat(name, file+2);
255*74a4d8c2SCharles.Forsyth strcat(name, ".a");
256*74a4d8c2SCharles.Forsyth file = name;
257*74a4d8c2SCharles.Forsyth }
258*74a4d8c2SCharles.Forsyth if(debug['v'])
259*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
260*74a4d8c2SCharles.Forsyth Bflush(&bso);
261*74a4d8c2SCharles.Forsyth f = open(file, 0);
262*74a4d8c2SCharles.Forsyth if(f < 0) {
263*74a4d8c2SCharles.Forsyth diag("cannot open file: %s", file);
264*74a4d8c2SCharles.Forsyth errorexit();
265*74a4d8c2SCharles.Forsyth }
266*74a4d8c2SCharles.Forsyth l = read(f, magbuf, SARMAG);
267*74a4d8c2SCharles.Forsyth if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
268*74a4d8c2SCharles.Forsyth /* load it as a regular file */
269*74a4d8c2SCharles.Forsyth l = seek(f, 0L, 2);
270*74a4d8c2SCharles.Forsyth seek(f, 0L, 0);
271*74a4d8c2SCharles.Forsyth ldobj(f, l, file);
272*74a4d8c2SCharles.Forsyth close(f);
273*74a4d8c2SCharles.Forsyth return;
274*74a4d8c2SCharles.Forsyth }
275*74a4d8c2SCharles.Forsyth
276*74a4d8c2SCharles.Forsyth l = read(f, &arhdr, SAR_HDR);
277*74a4d8c2SCharles.Forsyth if(l != SAR_HDR) {
278*74a4d8c2SCharles.Forsyth diag("%s: short read on archive file symbol header", file);
279*74a4d8c2SCharles.Forsyth goto out;
280*74a4d8c2SCharles.Forsyth }
281*74a4d8c2SCharles.Forsyth if(strncmp(arhdr.name, symname, strlen(symname))) {
282*74a4d8c2SCharles.Forsyth diag("%s: first entry not symbol header", file);
283*74a4d8c2SCharles.Forsyth goto out;
284*74a4d8c2SCharles.Forsyth }
285*74a4d8c2SCharles.Forsyth
286*74a4d8c2SCharles.Forsyth esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
287*74a4d8c2SCharles.Forsyth off = SARMAG + SAR_HDR;
288*74a4d8c2SCharles.Forsyth
289*74a4d8c2SCharles.Forsyth /*
290*74a4d8c2SCharles.Forsyth * just bang the whole symbol file into memory
291*74a4d8c2SCharles.Forsyth */
292*74a4d8c2SCharles.Forsyth seek(f, off, 0);
293*74a4d8c2SCharles.Forsyth cnt = esym - off;
294*74a4d8c2SCharles.Forsyth start = malloc(cnt + 10);
295*74a4d8c2SCharles.Forsyth cnt = read(f, start, cnt);
296*74a4d8c2SCharles.Forsyth if(cnt <= 0){
297*74a4d8c2SCharles.Forsyth close(f);
298*74a4d8c2SCharles.Forsyth return;
299*74a4d8c2SCharles.Forsyth }
300*74a4d8c2SCharles.Forsyth stop = &start[cnt];
301*74a4d8c2SCharles.Forsyth memset(stop, 0, 10);
302*74a4d8c2SCharles.Forsyth
303*74a4d8c2SCharles.Forsyth work = 1;
304*74a4d8c2SCharles.Forsyth while(work){
305*74a4d8c2SCharles.Forsyth if(debug['v'])
306*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);
307*74a4d8c2SCharles.Forsyth Bflush(&bso);
308*74a4d8c2SCharles.Forsyth work = 0;
309*74a4d8c2SCharles.Forsyth for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
310*74a4d8c2SCharles.Forsyth s = lookup(e+5, 0);
311*74a4d8c2SCharles.Forsyth if(s->type != SXREF)
312*74a4d8c2SCharles.Forsyth continue;
313*74a4d8c2SCharles.Forsyth sprint(pname, "%s(%s)", file, s->name);
314*74a4d8c2SCharles.Forsyth if(debug['v'])
315*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
316*74a4d8c2SCharles.Forsyth Bflush(&bso);
317*74a4d8c2SCharles.Forsyth l = e[1] & 0xff;
318*74a4d8c2SCharles.Forsyth l |= (e[2] & 0xff) << 8;
319*74a4d8c2SCharles.Forsyth l |= (e[3] & 0xff) << 16;
320*74a4d8c2SCharles.Forsyth l |= (e[4] & 0xff) << 24;
321*74a4d8c2SCharles.Forsyth seek(f, l, 0);
322*74a4d8c2SCharles.Forsyth l = read(f, &arhdr, SAR_HDR);
323*74a4d8c2SCharles.Forsyth if(l != SAR_HDR)
324*74a4d8c2SCharles.Forsyth goto bad;
325*74a4d8c2SCharles.Forsyth if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
326*74a4d8c2SCharles.Forsyth goto bad;
327*74a4d8c2SCharles.Forsyth l = atolwhex(arhdr.size);
328*74a4d8c2SCharles.Forsyth ldobj(f, l, pname);
329*74a4d8c2SCharles.Forsyth if(s->type == SXREF) {
330*74a4d8c2SCharles.Forsyth diag("%s: failed to load: %s", file, s->name);
331*74a4d8c2SCharles.Forsyth errorexit();
332*74a4d8c2SCharles.Forsyth }
333*74a4d8c2SCharles.Forsyth work = 1;
334*74a4d8c2SCharles.Forsyth xrefresolv = 1;
335*74a4d8c2SCharles.Forsyth }
336*74a4d8c2SCharles.Forsyth }
337*74a4d8c2SCharles.Forsyth return;
338*74a4d8c2SCharles.Forsyth
339*74a4d8c2SCharles.Forsyth bad:
340*74a4d8c2SCharles.Forsyth diag("%s: bad or out of date archive", file);
341*74a4d8c2SCharles.Forsyth out:
342*74a4d8c2SCharles.Forsyth close(f);
343*74a4d8c2SCharles.Forsyth }
344*74a4d8c2SCharles.Forsyth
345*74a4d8c2SCharles.Forsyth int
zaddr(uchar * p,Adr * a,Sym * h[])346*74a4d8c2SCharles.Forsyth zaddr(uchar *p, Adr *a, Sym *h[])
347*74a4d8c2SCharles.Forsyth {
348*74a4d8c2SCharles.Forsyth int i, c;
349*74a4d8c2SCharles.Forsyth long l;
350*74a4d8c2SCharles.Forsyth Sym *s;
351*74a4d8c2SCharles.Forsyth Auto *u;
352*74a4d8c2SCharles.Forsyth
353*74a4d8c2SCharles.Forsyth c = p[2];
354*74a4d8c2SCharles.Forsyth if(c < 0 || c > NSYM){
355*74a4d8c2SCharles.Forsyth print("sym out of range: %d\n", c);
356*74a4d8c2SCharles.Forsyth p[0] = AEND+1;
357*74a4d8c2SCharles.Forsyth return 0;
358*74a4d8c2SCharles.Forsyth }
359*74a4d8c2SCharles.Forsyth a->type = p[0];
360*74a4d8c2SCharles.Forsyth a->reg = p[1];
361*74a4d8c2SCharles.Forsyth a->sym = h[c];
362*74a4d8c2SCharles.Forsyth a->name = p[3];
363*74a4d8c2SCharles.Forsyth c = 4;
364*74a4d8c2SCharles.Forsyth
365*74a4d8c2SCharles.Forsyth if(a->reg < 0 || a->reg > NREG) {
366*74a4d8c2SCharles.Forsyth print("register out of range %d\n", a->reg);
367*74a4d8c2SCharles.Forsyth p[0] = AEND+1;
368*74a4d8c2SCharles.Forsyth return 0; /* force real diagnostic */
369*74a4d8c2SCharles.Forsyth }
370*74a4d8c2SCharles.Forsyth
371*74a4d8c2SCharles.Forsyth switch(a->type) {
372*74a4d8c2SCharles.Forsyth default:
373*74a4d8c2SCharles.Forsyth print("unknown type %d\n", a->type);
374*74a4d8c2SCharles.Forsyth p[0] = AEND+1;
375*74a4d8c2SCharles.Forsyth return 0; /* force real diagnostic */
376*74a4d8c2SCharles.Forsyth
377*74a4d8c2SCharles.Forsyth case D_NONE:
378*74a4d8c2SCharles.Forsyth case D_REG:
379*74a4d8c2SCharles.Forsyth case D_FREG:
380*74a4d8c2SCharles.Forsyth case D_CREG:
381*74a4d8c2SCharles.Forsyth case D_PREG:
382*74a4d8c2SCharles.Forsyth break;
383*74a4d8c2SCharles.Forsyth
384*74a4d8c2SCharles.Forsyth case D_BRANCH:
385*74a4d8c2SCharles.Forsyth case D_OREG:
386*74a4d8c2SCharles.Forsyth case D_ASI:
387*74a4d8c2SCharles.Forsyth case D_CONST:
388*74a4d8c2SCharles.Forsyth a->offset = p[4] | (p[5]<<8) |
389*74a4d8c2SCharles.Forsyth (p[6]<<16) | (p[7]<<24);
390*74a4d8c2SCharles.Forsyth c += 4;
391*74a4d8c2SCharles.Forsyth break;
392*74a4d8c2SCharles.Forsyth
393*74a4d8c2SCharles.Forsyth case D_SCONST:
394*74a4d8c2SCharles.Forsyth memmove(a->sval, p+4, NSNAME);
395*74a4d8c2SCharles.Forsyth c += NSNAME;
396*74a4d8c2SCharles.Forsyth break;
397*74a4d8c2SCharles.Forsyth
398*74a4d8c2SCharles.Forsyth case D_FCONST:
399*74a4d8c2SCharles.Forsyth a->ieee.l = p[4] | (p[5]<<8) |
400*74a4d8c2SCharles.Forsyth (p[6]<<16) | (p[7]<<24);
401*74a4d8c2SCharles.Forsyth a->ieee.h = p[8] | (p[9]<<8) |
402*74a4d8c2SCharles.Forsyth (p[10]<<16) | (p[11]<<24);
403*74a4d8c2SCharles.Forsyth c += 8;
404*74a4d8c2SCharles.Forsyth break;
405*74a4d8c2SCharles.Forsyth }
406*74a4d8c2SCharles.Forsyth s = a->sym;
407*74a4d8c2SCharles.Forsyth if(s == S)
408*74a4d8c2SCharles.Forsyth goto out;
409*74a4d8c2SCharles.Forsyth i = a->name;
410*74a4d8c2SCharles.Forsyth if(i != D_AUTO && i != D_PARAM)
411*74a4d8c2SCharles.Forsyth goto out;
412*74a4d8c2SCharles.Forsyth
413*74a4d8c2SCharles.Forsyth l = a->offset;
414*74a4d8c2SCharles.Forsyth for(u=curauto; u; u=u->link)
415*74a4d8c2SCharles.Forsyth if(u->asym == s)
416*74a4d8c2SCharles.Forsyth if(u->type == i) {
417*74a4d8c2SCharles.Forsyth if(u->aoffset > l)
418*74a4d8c2SCharles.Forsyth u->aoffset = l;
419*74a4d8c2SCharles.Forsyth goto out;
420*74a4d8c2SCharles.Forsyth }
421*74a4d8c2SCharles.Forsyth
422*74a4d8c2SCharles.Forsyth u = malloc(sizeof(Auto));
423*74a4d8c2SCharles.Forsyth
424*74a4d8c2SCharles.Forsyth u->link = curauto;
425*74a4d8c2SCharles.Forsyth curauto = u;
426*74a4d8c2SCharles.Forsyth u->asym = s;
427*74a4d8c2SCharles.Forsyth u->aoffset = l;
428*74a4d8c2SCharles.Forsyth u->type = i;
429*74a4d8c2SCharles.Forsyth out:
430*74a4d8c2SCharles.Forsyth return c;
431*74a4d8c2SCharles.Forsyth }
432*74a4d8c2SCharles.Forsyth
433*74a4d8c2SCharles.Forsyth void
addlib(char * obj)434*74a4d8c2SCharles.Forsyth addlib(char *obj)
435*74a4d8c2SCharles.Forsyth {
436*74a4d8c2SCharles.Forsyth char name[1024], comp[256], *p;
437*74a4d8c2SCharles.Forsyth int i;
438*74a4d8c2SCharles.Forsyth
439*74a4d8c2SCharles.Forsyth if(histfrogp <= 0)
440*74a4d8c2SCharles.Forsyth return;
441*74a4d8c2SCharles.Forsyth
442*74a4d8c2SCharles.Forsyth if(histfrog[0]->name[1] == '/') {
443*74a4d8c2SCharles.Forsyth sprint(name, "");
444*74a4d8c2SCharles.Forsyth i = 1;
445*74a4d8c2SCharles.Forsyth } else
446*74a4d8c2SCharles.Forsyth if(histfrog[0]->name[1] == '.') {
447*74a4d8c2SCharles.Forsyth sprint(name, ".");
448*74a4d8c2SCharles.Forsyth i = 0;
449*74a4d8c2SCharles.Forsyth } else {
450*74a4d8c2SCharles.Forsyth if(debug['9'])
451*74a4d8c2SCharles.Forsyth sprint(name, "/%s/lib", thestring);
452*74a4d8c2SCharles.Forsyth else
453*74a4d8c2SCharles.Forsyth sprint(name, "/usr/%clib", thechar);
454*74a4d8c2SCharles.Forsyth i = 0;
455*74a4d8c2SCharles.Forsyth }
456*74a4d8c2SCharles.Forsyth
457*74a4d8c2SCharles.Forsyth for(; i<histfrogp; i++) {
458*74a4d8c2SCharles.Forsyth snprint(comp, sizeof comp, histfrog[i]->name+1);
459*74a4d8c2SCharles.Forsyth for(;;) {
460*74a4d8c2SCharles.Forsyth p = strstr(comp, "$O");
461*74a4d8c2SCharles.Forsyth if(p == 0)
462*74a4d8c2SCharles.Forsyth break;
463*74a4d8c2SCharles.Forsyth memmove(p+1, p+2, strlen(p+2)+1);
464*74a4d8c2SCharles.Forsyth p[0] = thechar;
465*74a4d8c2SCharles.Forsyth }
466*74a4d8c2SCharles.Forsyth for(;;) {
467*74a4d8c2SCharles.Forsyth p = strstr(comp, "$M");
468*74a4d8c2SCharles.Forsyth if(p == 0)
469*74a4d8c2SCharles.Forsyth break;
470*74a4d8c2SCharles.Forsyth if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
471*74a4d8c2SCharles.Forsyth diag("library component too long");
472*74a4d8c2SCharles.Forsyth return;
473*74a4d8c2SCharles.Forsyth }
474*74a4d8c2SCharles.Forsyth memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
475*74a4d8c2SCharles.Forsyth memmove(p, thestring, strlen(thestring));
476*74a4d8c2SCharles.Forsyth }
477*74a4d8c2SCharles.Forsyth if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
478*74a4d8c2SCharles.Forsyth diag("library component too long");
479*74a4d8c2SCharles.Forsyth return;
480*74a4d8c2SCharles.Forsyth }
481*74a4d8c2SCharles.Forsyth strcat(name, "/");
482*74a4d8c2SCharles.Forsyth strcat(name, comp);
483*74a4d8c2SCharles.Forsyth }
484*74a4d8c2SCharles.Forsyth for(i=0; i<libraryp; i++)
485*74a4d8c2SCharles.Forsyth if(strcmp(name, library[i]) == 0)
486*74a4d8c2SCharles.Forsyth return;
487*74a4d8c2SCharles.Forsyth if(libraryp == nelem(library)){
488*74a4d8c2SCharles.Forsyth diag("too many autolibs; skipping %s", name);
489*74a4d8c2SCharles.Forsyth return;
490*74a4d8c2SCharles.Forsyth }
491*74a4d8c2SCharles.Forsyth
492*74a4d8c2SCharles.Forsyth p = malloc(strlen(name) + 1);
493*74a4d8c2SCharles.Forsyth strcpy(p, name);
494*74a4d8c2SCharles.Forsyth library[libraryp] = p;
495*74a4d8c2SCharles.Forsyth p = malloc(strlen(obj) + 1);
496*74a4d8c2SCharles.Forsyth strcpy(p, obj);
497*74a4d8c2SCharles.Forsyth libraryobj[libraryp] = p;
498*74a4d8c2SCharles.Forsyth libraryp++;
499*74a4d8c2SCharles.Forsyth }
500*74a4d8c2SCharles.Forsyth
501*74a4d8c2SCharles.Forsyth void
addhist(long line,int type)502*74a4d8c2SCharles.Forsyth addhist(long line, int type)
503*74a4d8c2SCharles.Forsyth {
504*74a4d8c2SCharles.Forsyth Auto *u;
505*74a4d8c2SCharles.Forsyth Sym *s;
506*74a4d8c2SCharles.Forsyth int i, j, k;
507*74a4d8c2SCharles.Forsyth
508*74a4d8c2SCharles.Forsyth u = malloc(sizeof(Auto));
509*74a4d8c2SCharles.Forsyth s = malloc(sizeof(Sym));
510*74a4d8c2SCharles.Forsyth s->name = malloc(2*(histfrogp+1) + 1);
511*74a4d8c2SCharles.Forsyth
512*74a4d8c2SCharles.Forsyth u->asym = s;
513*74a4d8c2SCharles.Forsyth u->type = type;
514*74a4d8c2SCharles.Forsyth u->aoffset = line;
515*74a4d8c2SCharles.Forsyth u->link = curhist;
516*74a4d8c2SCharles.Forsyth curhist = u;
517*74a4d8c2SCharles.Forsyth
518*74a4d8c2SCharles.Forsyth j = 1;
519*74a4d8c2SCharles.Forsyth for(i=0; i<histfrogp; i++) {
520*74a4d8c2SCharles.Forsyth k = histfrog[i]->value;
521*74a4d8c2SCharles.Forsyth s->name[j+0] = k>>8;
522*74a4d8c2SCharles.Forsyth s->name[j+1] = k;
523*74a4d8c2SCharles.Forsyth j += 2;
524*74a4d8c2SCharles.Forsyth }
525*74a4d8c2SCharles.Forsyth }
526*74a4d8c2SCharles.Forsyth
527*74a4d8c2SCharles.Forsyth void
histtoauto(void)528*74a4d8c2SCharles.Forsyth histtoauto(void)
529*74a4d8c2SCharles.Forsyth {
530*74a4d8c2SCharles.Forsyth Auto *l;
531*74a4d8c2SCharles.Forsyth
532*74a4d8c2SCharles.Forsyth while(l = curhist) {
533*74a4d8c2SCharles.Forsyth curhist = l->link;
534*74a4d8c2SCharles.Forsyth l->link = curauto;
535*74a4d8c2SCharles.Forsyth curauto = l;
536*74a4d8c2SCharles.Forsyth }
537*74a4d8c2SCharles.Forsyth }
538*74a4d8c2SCharles.Forsyth
539*74a4d8c2SCharles.Forsyth void
collapsefrog(Sym * s)540*74a4d8c2SCharles.Forsyth collapsefrog(Sym *s)
541*74a4d8c2SCharles.Forsyth {
542*74a4d8c2SCharles.Forsyth int i;
543*74a4d8c2SCharles.Forsyth
544*74a4d8c2SCharles.Forsyth /*
545*74a4d8c2SCharles.Forsyth * bad encoding of path components only allows
546*74a4d8c2SCharles.Forsyth * MAXHIST components. if there is an overflow,
547*74a4d8c2SCharles.Forsyth * first try to collapse xxx/..
548*74a4d8c2SCharles.Forsyth */
549*74a4d8c2SCharles.Forsyth for(i=1; i<histfrogp; i++)
550*74a4d8c2SCharles.Forsyth if(strcmp(histfrog[i]->name+1, "..") == 0) {
551*74a4d8c2SCharles.Forsyth memmove(histfrog+i-1, histfrog+i+1,
552*74a4d8c2SCharles.Forsyth (histfrogp-i-1)*sizeof(histfrog[0]));
553*74a4d8c2SCharles.Forsyth histfrogp--;
554*74a4d8c2SCharles.Forsyth goto out;
555*74a4d8c2SCharles.Forsyth }
556*74a4d8c2SCharles.Forsyth
557*74a4d8c2SCharles.Forsyth /*
558*74a4d8c2SCharles.Forsyth * next try to collapse .
559*74a4d8c2SCharles.Forsyth */
560*74a4d8c2SCharles.Forsyth for(i=0; i<histfrogp; i++)
561*74a4d8c2SCharles.Forsyth if(strcmp(histfrog[i]->name+1, ".") == 0) {
562*74a4d8c2SCharles.Forsyth memmove(histfrog+i, histfrog+i+1,
563*74a4d8c2SCharles.Forsyth (histfrogp-i-1)*sizeof(histfrog[0]));
564*74a4d8c2SCharles.Forsyth goto out;
565*74a4d8c2SCharles.Forsyth }
566*74a4d8c2SCharles.Forsyth
567*74a4d8c2SCharles.Forsyth /*
568*74a4d8c2SCharles.Forsyth * last chance, just truncate from front
569*74a4d8c2SCharles.Forsyth */
570*74a4d8c2SCharles.Forsyth memmove(histfrog+0, histfrog+1,
571*74a4d8c2SCharles.Forsyth (histfrogp-1)*sizeof(histfrog[0]));
572*74a4d8c2SCharles.Forsyth
573*74a4d8c2SCharles.Forsyth out:
574*74a4d8c2SCharles.Forsyth histfrog[histfrogp-1] = s;
575*74a4d8c2SCharles.Forsyth }
576*74a4d8c2SCharles.Forsyth
577*74a4d8c2SCharles.Forsyth void
nopout(Prog * p)578*74a4d8c2SCharles.Forsyth nopout(Prog *p)
579*74a4d8c2SCharles.Forsyth {
580*74a4d8c2SCharles.Forsyth p->as = ANOP;
581*74a4d8c2SCharles.Forsyth p->from.type = D_NONE;
582*74a4d8c2SCharles.Forsyth p->to.type = D_NONE;
583*74a4d8c2SCharles.Forsyth }
584*74a4d8c2SCharles.Forsyth
585*74a4d8c2SCharles.Forsyth uchar*
readsome(int f,uchar * buf,uchar * good,uchar * stop,int max)586*74a4d8c2SCharles.Forsyth readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
587*74a4d8c2SCharles.Forsyth {
588*74a4d8c2SCharles.Forsyth int n;
589*74a4d8c2SCharles.Forsyth
590*74a4d8c2SCharles.Forsyth n = stop - good;
591*74a4d8c2SCharles.Forsyth memmove(buf, good, stop - good);
592*74a4d8c2SCharles.Forsyth stop = buf + n;
593*74a4d8c2SCharles.Forsyth n = MAXIO - n;
594*74a4d8c2SCharles.Forsyth if(n > max)
595*74a4d8c2SCharles.Forsyth n = max;
596*74a4d8c2SCharles.Forsyth n = read(f, stop, n);
597*74a4d8c2SCharles.Forsyth if(n <= 0)
598*74a4d8c2SCharles.Forsyth return 0;
599*74a4d8c2SCharles.Forsyth return stop + n;
600*74a4d8c2SCharles.Forsyth }
601*74a4d8c2SCharles.Forsyth
602*74a4d8c2SCharles.Forsyth void
ldobj(int f,long c,char * pn)603*74a4d8c2SCharles.Forsyth ldobj(int f, long c, char *pn)
604*74a4d8c2SCharles.Forsyth {
605*74a4d8c2SCharles.Forsyth Prog *p, *t;
606*74a4d8c2SCharles.Forsyth Sym *h[NSYM], *s, *di;
607*74a4d8c2SCharles.Forsyth int v, o, r, skip;
608*74a4d8c2SCharles.Forsyth long ipc;
609*74a4d8c2SCharles.Forsyth uchar *bloc, *bsize, *stop;
610*74a4d8c2SCharles.Forsyth
611*74a4d8c2SCharles.Forsyth bsize = buf.xbuf;
612*74a4d8c2SCharles.Forsyth bloc = buf.xbuf;
613*74a4d8c2SCharles.Forsyth di = S;
614*74a4d8c2SCharles.Forsyth
615*74a4d8c2SCharles.Forsyth newloop:
616*74a4d8c2SCharles.Forsyth memset(h, 0, sizeof(h));
617*74a4d8c2SCharles.Forsyth histfrogp = 0;
618*74a4d8c2SCharles.Forsyth version++;
619*74a4d8c2SCharles.Forsyth ipc = pc;
620*74a4d8c2SCharles.Forsyth skip = 0;
621*74a4d8c2SCharles.Forsyth
622*74a4d8c2SCharles.Forsyth loop:
623*74a4d8c2SCharles.Forsyth if(c <= 0)
624*74a4d8c2SCharles.Forsyth goto eof;
625*74a4d8c2SCharles.Forsyth r = bsize - bloc;
626*74a4d8c2SCharles.Forsyth if(r < 100 && r < c) { /* enough for largest prog */
627*74a4d8c2SCharles.Forsyth bsize = readsome(f, buf.xbuf, bloc, bsize, c);
628*74a4d8c2SCharles.Forsyth if(bsize == 0)
629*74a4d8c2SCharles.Forsyth goto eof;
630*74a4d8c2SCharles.Forsyth bloc = buf.xbuf;
631*74a4d8c2SCharles.Forsyth goto loop;
632*74a4d8c2SCharles.Forsyth }
633*74a4d8c2SCharles.Forsyth o = bloc[0]; /* as */
634*74a4d8c2SCharles.Forsyth if(o <= 0 || o >= ALAST) {
635*74a4d8c2SCharles.Forsyth diag("%s: opcode out of range %d", pn, o);
636*74a4d8c2SCharles.Forsyth print(" probably not a .k file\n");
637*74a4d8c2SCharles.Forsyth errorexit();
638*74a4d8c2SCharles.Forsyth }
639*74a4d8c2SCharles.Forsyth if(o == ANAME || o == ASIGNAME) {
640*74a4d8c2SCharles.Forsyth if(o == ASIGNAME) {
641*74a4d8c2SCharles.Forsyth bloc += 4;
642*74a4d8c2SCharles.Forsyth c -= 4;
643*74a4d8c2SCharles.Forsyth }
644*74a4d8c2SCharles.Forsyth stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
645*74a4d8c2SCharles.Forsyth if(stop == 0){
646*74a4d8c2SCharles.Forsyth bsize = readsome(f, buf.xbuf, bloc, bsize, c);
647*74a4d8c2SCharles.Forsyth if(bsize == 0)
648*74a4d8c2SCharles.Forsyth goto eof;
649*74a4d8c2SCharles.Forsyth bloc = buf.xbuf;
650*74a4d8c2SCharles.Forsyth stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
651*74a4d8c2SCharles.Forsyth if(stop == 0){
652*74a4d8c2SCharles.Forsyth fprint(2, "%s: name too long\n", pn);
653*74a4d8c2SCharles.Forsyth errorexit();
654*74a4d8c2SCharles.Forsyth }
655*74a4d8c2SCharles.Forsyth }
656*74a4d8c2SCharles.Forsyth v = bloc[1]; /* type */
657*74a4d8c2SCharles.Forsyth o = bloc[2]; /* sym */
658*74a4d8c2SCharles.Forsyth bloc += 3;
659*74a4d8c2SCharles.Forsyth c -= 3;
660*74a4d8c2SCharles.Forsyth
661*74a4d8c2SCharles.Forsyth r = 0;
662*74a4d8c2SCharles.Forsyth if(v == D_STATIC)
663*74a4d8c2SCharles.Forsyth r = version;
664*74a4d8c2SCharles.Forsyth s = lookup((char*)bloc, r);
665*74a4d8c2SCharles.Forsyth c -= &stop[1] - bloc;
666*74a4d8c2SCharles.Forsyth bloc = stop + 1;
667*74a4d8c2SCharles.Forsyth
668*74a4d8c2SCharles.Forsyth if(debug['W'])
669*74a4d8c2SCharles.Forsyth print(" ANAME %s\n", s->name);
670*74a4d8c2SCharles.Forsyth h[o] = s;
671*74a4d8c2SCharles.Forsyth if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
672*74a4d8c2SCharles.Forsyth s->type = SXREF;
673*74a4d8c2SCharles.Forsyth if(v == D_FILE) {
674*74a4d8c2SCharles.Forsyth if(s->type != SFILE) {
675*74a4d8c2SCharles.Forsyth histgen++;
676*74a4d8c2SCharles.Forsyth s->type = SFILE;
677*74a4d8c2SCharles.Forsyth s->value = histgen;
678*74a4d8c2SCharles.Forsyth }
679*74a4d8c2SCharles.Forsyth if(histfrogp < MAXHIST) {
680*74a4d8c2SCharles.Forsyth histfrog[histfrogp] = s;
681*74a4d8c2SCharles.Forsyth histfrogp++;
682*74a4d8c2SCharles.Forsyth } else
683*74a4d8c2SCharles.Forsyth collapsefrog(s);
684*74a4d8c2SCharles.Forsyth }
685*74a4d8c2SCharles.Forsyth goto loop;
686*74a4d8c2SCharles.Forsyth }
687*74a4d8c2SCharles.Forsyth
688*74a4d8c2SCharles.Forsyth if(nhunk < sizeof(Prog))
689*74a4d8c2SCharles.Forsyth gethunk();
690*74a4d8c2SCharles.Forsyth p = (Prog*)hunk;
691*74a4d8c2SCharles.Forsyth nhunk -= sizeof(Prog);
692*74a4d8c2SCharles.Forsyth hunk += sizeof(Prog);
693*74a4d8c2SCharles.Forsyth
694*74a4d8c2SCharles.Forsyth p->as = o;
695*74a4d8c2SCharles.Forsyth p->reg = bloc[1] & 0x7f;
696*74a4d8c2SCharles.Forsyth if(bloc[1] & 0x80)
697*74a4d8c2SCharles.Forsyth p->mark = NOSCHED;
698*74a4d8c2SCharles.Forsyth p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
699*74a4d8c2SCharles.Forsyth r = zaddr(bloc+6, &p->from, h) + 6;
700*74a4d8c2SCharles.Forsyth r += zaddr(bloc+r, &p->to, h);
701*74a4d8c2SCharles.Forsyth bloc += r;
702*74a4d8c2SCharles.Forsyth c -= r;
703*74a4d8c2SCharles.Forsyth
704*74a4d8c2SCharles.Forsyth if(p->reg < 0 || p->reg > NREG)
705*74a4d8c2SCharles.Forsyth diag("register out of range %d", p->reg);
706*74a4d8c2SCharles.Forsyth
707*74a4d8c2SCharles.Forsyth p->link = P;
708*74a4d8c2SCharles.Forsyth p->cond = P;
709*74a4d8c2SCharles.Forsyth
710*74a4d8c2SCharles.Forsyth if(debug['W'])
711*74a4d8c2SCharles.Forsyth print("%P\n", p);
712*74a4d8c2SCharles.Forsyth
713*74a4d8c2SCharles.Forsyth switch(o) {
714*74a4d8c2SCharles.Forsyth case AHISTORY:
715*74a4d8c2SCharles.Forsyth if(p->to.offset == -1) {
716*74a4d8c2SCharles.Forsyth addlib(pn);
717*74a4d8c2SCharles.Forsyth histfrogp = 0;
718*74a4d8c2SCharles.Forsyth goto loop;
719*74a4d8c2SCharles.Forsyth }
720*74a4d8c2SCharles.Forsyth addhist(p->line, D_FILE); /* 'z' */
721*74a4d8c2SCharles.Forsyth if(p->to.offset)
722*74a4d8c2SCharles.Forsyth addhist(p->to.offset, D_FILE1); /* 'Z' */
723*74a4d8c2SCharles.Forsyth histfrogp = 0;
724*74a4d8c2SCharles.Forsyth goto loop;
725*74a4d8c2SCharles.Forsyth
726*74a4d8c2SCharles.Forsyth case AEND:
727*74a4d8c2SCharles.Forsyth histtoauto();
728*74a4d8c2SCharles.Forsyth if(curtext != P)
729*74a4d8c2SCharles.Forsyth curtext->to.autom = curauto;
730*74a4d8c2SCharles.Forsyth curauto = 0;
731*74a4d8c2SCharles.Forsyth curtext = P;
732*74a4d8c2SCharles.Forsyth if(c)
733*74a4d8c2SCharles.Forsyth goto newloop;
734*74a4d8c2SCharles.Forsyth return;
735*74a4d8c2SCharles.Forsyth
736*74a4d8c2SCharles.Forsyth case AGLOBL:
737*74a4d8c2SCharles.Forsyth s = p->from.sym;
738*74a4d8c2SCharles.Forsyth if(s == S) {
739*74a4d8c2SCharles.Forsyth diag("GLOBL must have a name\n%P", p);
740*74a4d8c2SCharles.Forsyth errorexit();
741*74a4d8c2SCharles.Forsyth }
742*74a4d8c2SCharles.Forsyth if(s->type == 0 || s->type == SXREF) {
743*74a4d8c2SCharles.Forsyth s->type = SBSS;
744*74a4d8c2SCharles.Forsyth s->value = 0;
745*74a4d8c2SCharles.Forsyth }
746*74a4d8c2SCharles.Forsyth if(s->type != SBSS) {
747*74a4d8c2SCharles.Forsyth diag("redefinition: %s\n%P", s->name, p);
748*74a4d8c2SCharles.Forsyth s->type = SBSS;
749*74a4d8c2SCharles.Forsyth s->value = 0;
750*74a4d8c2SCharles.Forsyth }
751*74a4d8c2SCharles.Forsyth if(p->to.offset > s->value)
752*74a4d8c2SCharles.Forsyth s->value = p->to.offset;
753*74a4d8c2SCharles.Forsyth break;
754*74a4d8c2SCharles.Forsyth
755*74a4d8c2SCharles.Forsyth case ADYNT:
756*74a4d8c2SCharles.Forsyth if(p->to.sym == S) {
757*74a4d8c2SCharles.Forsyth diag("DYNT without a sym\n%P", p);
758*74a4d8c2SCharles.Forsyth break;
759*74a4d8c2SCharles.Forsyth }
760*74a4d8c2SCharles.Forsyth di = p->to.sym;
761*74a4d8c2SCharles.Forsyth p->reg = 4;
762*74a4d8c2SCharles.Forsyth if(di->type == SXREF) {
763*74a4d8c2SCharles.Forsyth if(debug['z'])
764*74a4d8c2SCharles.Forsyth Bprint(&bso, "%P set to %d\n", p, dtype);
765*74a4d8c2SCharles.Forsyth di->type = SCONST;
766*74a4d8c2SCharles.Forsyth di->value = dtype;
767*74a4d8c2SCharles.Forsyth dtype += 4;
768*74a4d8c2SCharles.Forsyth }
769*74a4d8c2SCharles.Forsyth if(p->from.sym == S)
770*74a4d8c2SCharles.Forsyth break;
771*74a4d8c2SCharles.Forsyth
772*74a4d8c2SCharles.Forsyth p->from.offset = di->value;
773*74a4d8c2SCharles.Forsyth p->from.sym->type = SDATA;
774*74a4d8c2SCharles.Forsyth if(curtext == P) {
775*74a4d8c2SCharles.Forsyth diag("DYNT not in text: %P", p);
776*74a4d8c2SCharles.Forsyth break;
777*74a4d8c2SCharles.Forsyth }
778*74a4d8c2SCharles.Forsyth p->to.sym = curtext->from.sym;
779*74a4d8c2SCharles.Forsyth p->to.type = D_CONST;
780*74a4d8c2SCharles.Forsyth p->link = datap;
781*74a4d8c2SCharles.Forsyth datap = p;
782*74a4d8c2SCharles.Forsyth break;
783*74a4d8c2SCharles.Forsyth
784*74a4d8c2SCharles.Forsyth case AINIT:
785*74a4d8c2SCharles.Forsyth if(p->from.sym == S) {
786*74a4d8c2SCharles.Forsyth diag("INIT without a sym\n%P", p);
787*74a4d8c2SCharles.Forsyth break;
788*74a4d8c2SCharles.Forsyth }
789*74a4d8c2SCharles.Forsyth if(di == S) {
790*74a4d8c2SCharles.Forsyth diag("INIT without previous DYNT\n%P", p);
791*74a4d8c2SCharles.Forsyth break;
792*74a4d8c2SCharles.Forsyth }
793*74a4d8c2SCharles.Forsyth p->from.offset = di->value;
794*74a4d8c2SCharles.Forsyth p->from.sym->type = SDATA;
795*74a4d8c2SCharles.Forsyth p->link = datap;
796*74a4d8c2SCharles.Forsyth datap = p;
797*74a4d8c2SCharles.Forsyth break;
798*74a4d8c2SCharles.Forsyth
799*74a4d8c2SCharles.Forsyth case ADATA:
800*74a4d8c2SCharles.Forsyth p->link = datap;
801*74a4d8c2SCharles.Forsyth datap = p;
802*74a4d8c2SCharles.Forsyth break;
803*74a4d8c2SCharles.Forsyth
804*74a4d8c2SCharles.Forsyth case AGOK:
805*74a4d8c2SCharles.Forsyth diag("unknown opcode\n%P", p);
806*74a4d8c2SCharles.Forsyth p->pc = pc;
807*74a4d8c2SCharles.Forsyth pc++;
808*74a4d8c2SCharles.Forsyth break;
809*74a4d8c2SCharles.Forsyth
810*74a4d8c2SCharles.Forsyth case ATEXT:
811*74a4d8c2SCharles.Forsyth if(curtext != P) {
812*74a4d8c2SCharles.Forsyth histtoauto();
813*74a4d8c2SCharles.Forsyth curtext->to.autom = curauto;
814*74a4d8c2SCharles.Forsyth curauto = 0;
815*74a4d8c2SCharles.Forsyth }
816*74a4d8c2SCharles.Forsyth curtext = p;
817*74a4d8c2SCharles.Forsyth autosize = (p->to.offset+3L) & ~3L;
818*74a4d8c2SCharles.Forsyth p->to.offset = autosize;
819*74a4d8c2SCharles.Forsyth autosize += 4;
820*74a4d8c2SCharles.Forsyth s = p->from.sym;
821*74a4d8c2SCharles.Forsyth if(s == S) {
822*74a4d8c2SCharles.Forsyth diag("TEXT must have a name\n%P", p);
823*74a4d8c2SCharles.Forsyth errorexit();
824*74a4d8c2SCharles.Forsyth }
825*74a4d8c2SCharles.Forsyth if(s->type != 0 && s->type != SXREF) {
826*74a4d8c2SCharles.Forsyth if(p->reg & DUPOK) {
827*74a4d8c2SCharles.Forsyth skip = 1;
828*74a4d8c2SCharles.Forsyth goto casedef;
829*74a4d8c2SCharles.Forsyth }
830*74a4d8c2SCharles.Forsyth diag("redefinition: %s\n%P", s->name, p);
831*74a4d8c2SCharles.Forsyth }
832*74a4d8c2SCharles.Forsyth s->type = STEXT;
833*74a4d8c2SCharles.Forsyth s->value = pc;
834*74a4d8c2SCharles.Forsyth if(textp != P) {
835*74a4d8c2SCharles.Forsyth for(t = textp; t->cond != P; t = t->cond)
836*74a4d8c2SCharles.Forsyth ;
837*74a4d8c2SCharles.Forsyth t->cond = p;
838*74a4d8c2SCharles.Forsyth } else
839*74a4d8c2SCharles.Forsyth textp = p;
840*74a4d8c2SCharles.Forsyth lastp->link = p;
841*74a4d8c2SCharles.Forsyth lastp = p;
842*74a4d8c2SCharles.Forsyth p->pc = pc;
843*74a4d8c2SCharles.Forsyth pc++;
844*74a4d8c2SCharles.Forsyth break;
845*74a4d8c2SCharles.Forsyth
846*74a4d8c2SCharles.Forsyth case AFMOVF:
847*74a4d8c2SCharles.Forsyth if(skip)
848*74a4d8c2SCharles.Forsyth goto casedef;
849*74a4d8c2SCharles.Forsyth
850*74a4d8c2SCharles.Forsyth if(p->from.type == D_FCONST) {
851*74a4d8c2SCharles.Forsyth /* size sb 9 max */
852*74a4d8c2SCharles.Forsyth sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
853*74a4d8c2SCharles.Forsyth s = lookup(literal, 0);
854*74a4d8c2SCharles.Forsyth if(s->type == 0) {
855*74a4d8c2SCharles.Forsyth s->type = SBSS;
856*74a4d8c2SCharles.Forsyth s->value = 4;
857*74a4d8c2SCharles.Forsyth t = prg();
858*74a4d8c2SCharles.Forsyth t->as = ADATA;
859*74a4d8c2SCharles.Forsyth t->line = p->line;
860*74a4d8c2SCharles.Forsyth t->from.type = D_OREG;
861*74a4d8c2SCharles.Forsyth t->from.sym = s;
862*74a4d8c2SCharles.Forsyth t->from.name = D_EXTERN;
863*74a4d8c2SCharles.Forsyth t->reg = 4;
864*74a4d8c2SCharles.Forsyth t->to = p->from;
865*74a4d8c2SCharles.Forsyth t->link = datap;
866*74a4d8c2SCharles.Forsyth datap = t;
867*74a4d8c2SCharles.Forsyth }
868*74a4d8c2SCharles.Forsyth p->from.type = D_OREG;
869*74a4d8c2SCharles.Forsyth p->from.sym = s;
870*74a4d8c2SCharles.Forsyth p->from.name = D_EXTERN;
871*74a4d8c2SCharles.Forsyth p->from.offset = 0;
872*74a4d8c2SCharles.Forsyth }
873*74a4d8c2SCharles.Forsyth goto casedef;
874*74a4d8c2SCharles.Forsyth
875*74a4d8c2SCharles.Forsyth case AFMOVD:
876*74a4d8c2SCharles.Forsyth if(skip)
877*74a4d8c2SCharles.Forsyth goto casedef;
878*74a4d8c2SCharles.Forsyth if(p->from.type == D_FCONST) {
879*74a4d8c2SCharles.Forsyth /* size sb 18 max */
880*74a4d8c2SCharles.Forsyth sprint(literal, "$%lux.%lux",
881*74a4d8c2SCharles.Forsyth p->from.ieee.l, p->from.ieee.h);
882*74a4d8c2SCharles.Forsyth s = lookup(literal, 0);
883*74a4d8c2SCharles.Forsyth if(s->type == 0) {
884*74a4d8c2SCharles.Forsyth s->type = SBSS;
885*74a4d8c2SCharles.Forsyth s->value = 8;
886*74a4d8c2SCharles.Forsyth t = prg();
887*74a4d8c2SCharles.Forsyth t->as = ADATA;
888*74a4d8c2SCharles.Forsyth t->line = p->line;
889*74a4d8c2SCharles.Forsyth t->from.type = D_OREG;
890*74a4d8c2SCharles.Forsyth t->from.sym = s;
891*74a4d8c2SCharles.Forsyth t->from.name = D_EXTERN;
892*74a4d8c2SCharles.Forsyth t->reg = 8;
893*74a4d8c2SCharles.Forsyth t->to = p->from;
894*74a4d8c2SCharles.Forsyth t->link = datap;
895*74a4d8c2SCharles.Forsyth datap = t;
896*74a4d8c2SCharles.Forsyth }
897*74a4d8c2SCharles.Forsyth p->from.type = D_OREG;
898*74a4d8c2SCharles.Forsyth p->from.sym = s;
899*74a4d8c2SCharles.Forsyth p->from.name = D_EXTERN;
900*74a4d8c2SCharles.Forsyth p->from.offset = 0;
901*74a4d8c2SCharles.Forsyth }
902*74a4d8c2SCharles.Forsyth goto casedef;
903*74a4d8c2SCharles.Forsyth
904*74a4d8c2SCharles.Forsyth default:
905*74a4d8c2SCharles.Forsyth casedef:
906*74a4d8c2SCharles.Forsyth if(skip)
907*74a4d8c2SCharles.Forsyth nopout(p);
908*74a4d8c2SCharles.Forsyth
909*74a4d8c2SCharles.Forsyth if(p->to.type == D_BRANCH)
910*74a4d8c2SCharles.Forsyth p->to.offset += ipc;
911*74a4d8c2SCharles.Forsyth lastp->link = p;
912*74a4d8c2SCharles.Forsyth lastp = p;
913*74a4d8c2SCharles.Forsyth p->pc = pc;
914*74a4d8c2SCharles.Forsyth pc++;
915*74a4d8c2SCharles.Forsyth break;
916*74a4d8c2SCharles.Forsyth }
917*74a4d8c2SCharles.Forsyth goto loop;
918*74a4d8c2SCharles.Forsyth
919*74a4d8c2SCharles.Forsyth eof:
920*74a4d8c2SCharles.Forsyth diag("truncated object file: %s", pn);
921*74a4d8c2SCharles.Forsyth }
922*74a4d8c2SCharles.Forsyth
923*74a4d8c2SCharles.Forsyth Sym*
lookup(char * symb,int v)924*74a4d8c2SCharles.Forsyth lookup(char *symb, int v)
925*74a4d8c2SCharles.Forsyth {
926*74a4d8c2SCharles.Forsyth Sym *s;
927*74a4d8c2SCharles.Forsyth char *p;
928*74a4d8c2SCharles.Forsyth long h;
929*74a4d8c2SCharles.Forsyth int c, l;
930*74a4d8c2SCharles.Forsyth
931*74a4d8c2SCharles.Forsyth h = v;
932*74a4d8c2SCharles.Forsyth for(p=symb; c = *p; p++)
933*74a4d8c2SCharles.Forsyth h = h+h+h + c;
934*74a4d8c2SCharles.Forsyth l = (p - symb) + 1;
935*74a4d8c2SCharles.Forsyth if(h < 0)
936*74a4d8c2SCharles.Forsyth h = ~h;
937*74a4d8c2SCharles.Forsyth h %= NHASH;
938*74a4d8c2SCharles.Forsyth for(s = hash[h]; s != S; s = s->link)
939*74a4d8c2SCharles.Forsyth if(s->version == v)
940*74a4d8c2SCharles.Forsyth if(memcmp(s->name, symb, l) == 0)
941*74a4d8c2SCharles.Forsyth return s;
942*74a4d8c2SCharles.Forsyth
943*74a4d8c2SCharles.Forsyth while(nhunk < sizeof(Sym))
944*74a4d8c2SCharles.Forsyth gethunk();
945*74a4d8c2SCharles.Forsyth s = (Sym*)hunk;
946*74a4d8c2SCharles.Forsyth nhunk -= sizeof(Sym);
947*74a4d8c2SCharles.Forsyth hunk += sizeof(Sym);
948*74a4d8c2SCharles.Forsyth
949*74a4d8c2SCharles.Forsyth s->name = malloc(l + 1);
950*74a4d8c2SCharles.Forsyth memmove(s->name, symb, l);
951*74a4d8c2SCharles.Forsyth
952*74a4d8c2SCharles.Forsyth s->link = hash[h];
953*74a4d8c2SCharles.Forsyth s->type = 0;
954*74a4d8c2SCharles.Forsyth s->version = v;
955*74a4d8c2SCharles.Forsyth s->value = 0;
956*74a4d8c2SCharles.Forsyth hash[h] = s;
957*74a4d8c2SCharles.Forsyth return s;
958*74a4d8c2SCharles.Forsyth }
959*74a4d8c2SCharles.Forsyth
960*74a4d8c2SCharles.Forsyth Prog*
prg(void)961*74a4d8c2SCharles.Forsyth prg(void)
962*74a4d8c2SCharles.Forsyth {
963*74a4d8c2SCharles.Forsyth Prog *p;
964*74a4d8c2SCharles.Forsyth int n;
965*74a4d8c2SCharles.Forsyth
966*74a4d8c2SCharles.Forsyth n = (sizeof(Prog) + 3) & ~3;
967*74a4d8c2SCharles.Forsyth while(nhunk < n)
968*74a4d8c2SCharles.Forsyth gethunk();
969*74a4d8c2SCharles.Forsyth
970*74a4d8c2SCharles.Forsyth p = (Prog*)hunk;
971*74a4d8c2SCharles.Forsyth nhunk -= n;
972*74a4d8c2SCharles.Forsyth hunk += n;
973*74a4d8c2SCharles.Forsyth
974*74a4d8c2SCharles.Forsyth *p = zprg;
975*74a4d8c2SCharles.Forsyth return p;
976*74a4d8c2SCharles.Forsyth }
977*74a4d8c2SCharles.Forsyth
978*74a4d8c2SCharles.Forsyth void
gethunk(void)979*74a4d8c2SCharles.Forsyth gethunk(void)
980*74a4d8c2SCharles.Forsyth {
981*74a4d8c2SCharles.Forsyth char *h;
982*74a4d8c2SCharles.Forsyth long nh;
983*74a4d8c2SCharles.Forsyth
984*74a4d8c2SCharles.Forsyth nh = NHUNK;
985*74a4d8c2SCharles.Forsyth if(tothunk >= 5L*NHUNK) {
986*74a4d8c2SCharles.Forsyth nh = 5L*NHUNK;
987*74a4d8c2SCharles.Forsyth if(tothunk >= 25L*NHUNK)
988*74a4d8c2SCharles.Forsyth nh = 25L*NHUNK;
989*74a4d8c2SCharles.Forsyth }
990*74a4d8c2SCharles.Forsyth h = mysbrk(nh);
991*74a4d8c2SCharles.Forsyth if(h == (char *)-1) {
992*74a4d8c2SCharles.Forsyth diag("out of memory");
993*74a4d8c2SCharles.Forsyth errorexit();
994*74a4d8c2SCharles.Forsyth }
995*74a4d8c2SCharles.Forsyth
996*74a4d8c2SCharles.Forsyth hunk = h;
997*74a4d8c2SCharles.Forsyth nhunk = nh;
998*74a4d8c2SCharles.Forsyth tothunk += nh;
999*74a4d8c2SCharles.Forsyth }
1000*74a4d8c2SCharles.Forsyth
1001*74a4d8c2SCharles.Forsyth void
doprof1(void)1002*74a4d8c2SCharles.Forsyth doprof1(void)
1003*74a4d8c2SCharles.Forsyth {
1004*74a4d8c2SCharles.Forsyth Sym *s;
1005*74a4d8c2SCharles.Forsyth long n;
1006*74a4d8c2SCharles.Forsyth Prog *p, *q;
1007*74a4d8c2SCharles.Forsyth
1008*74a4d8c2SCharles.Forsyth if(debug['v'])
1009*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f profile 1\n", cputime());
1010*74a4d8c2SCharles.Forsyth Bflush(&bso);
1011*74a4d8c2SCharles.Forsyth s = lookup("__mcount", 0);
1012*74a4d8c2SCharles.Forsyth n = 1;
1013*74a4d8c2SCharles.Forsyth for(p = firstp->link; p != P; p = p->link) {
1014*74a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
1015*74a4d8c2SCharles.Forsyth q = prg();
1016*74a4d8c2SCharles.Forsyth q->line = p->line;
1017*74a4d8c2SCharles.Forsyth q->link = datap;
1018*74a4d8c2SCharles.Forsyth datap = q;
1019*74a4d8c2SCharles.Forsyth q->as = ADATA;
1020*74a4d8c2SCharles.Forsyth q->from.type = D_OREG;
1021*74a4d8c2SCharles.Forsyth q->from.name = D_EXTERN;
1022*74a4d8c2SCharles.Forsyth q->from.offset = n*4;
1023*74a4d8c2SCharles.Forsyth q->from.sym = s;
1024*74a4d8c2SCharles.Forsyth q->reg = 4;
1025*74a4d8c2SCharles.Forsyth q->to = p->from;
1026*74a4d8c2SCharles.Forsyth q->to.type = D_CONST;
1027*74a4d8c2SCharles.Forsyth
1028*74a4d8c2SCharles.Forsyth q = prg();
1029*74a4d8c2SCharles.Forsyth q->line = p->line;
1030*74a4d8c2SCharles.Forsyth q->pc = p->pc;
1031*74a4d8c2SCharles.Forsyth q->link = p->link;
1032*74a4d8c2SCharles.Forsyth p->link = q;
1033*74a4d8c2SCharles.Forsyth p = q;
1034*74a4d8c2SCharles.Forsyth p->as = AMOVW;
1035*74a4d8c2SCharles.Forsyth p->from.type = D_OREG;
1036*74a4d8c2SCharles.Forsyth p->from.name = D_EXTERN;
1037*74a4d8c2SCharles.Forsyth p->from.sym = s;
1038*74a4d8c2SCharles.Forsyth p->from.offset = n*4 + 4;
1039*74a4d8c2SCharles.Forsyth p->to.type = D_REG;
1040*74a4d8c2SCharles.Forsyth p->to.reg = REGTMP;
1041*74a4d8c2SCharles.Forsyth
1042*74a4d8c2SCharles.Forsyth q = prg();
1043*74a4d8c2SCharles.Forsyth q->line = p->line;
1044*74a4d8c2SCharles.Forsyth q->pc = p->pc;
1045*74a4d8c2SCharles.Forsyth q->link = p->link;
1046*74a4d8c2SCharles.Forsyth p->link = q;
1047*74a4d8c2SCharles.Forsyth p = q;
1048*74a4d8c2SCharles.Forsyth p->as = AADD;
1049*74a4d8c2SCharles.Forsyth p->from.type = D_CONST;
1050*74a4d8c2SCharles.Forsyth p->from.offset = 1;
1051*74a4d8c2SCharles.Forsyth p->to.type = D_REG;
1052*74a4d8c2SCharles.Forsyth p->to.reg = REGTMP;
1053*74a4d8c2SCharles.Forsyth
1054*74a4d8c2SCharles.Forsyth q = prg();
1055*74a4d8c2SCharles.Forsyth q->line = p->line;
1056*74a4d8c2SCharles.Forsyth q->pc = p->pc;
1057*74a4d8c2SCharles.Forsyth q->link = p->link;
1058*74a4d8c2SCharles.Forsyth p->link = q;
1059*74a4d8c2SCharles.Forsyth p = q;
1060*74a4d8c2SCharles.Forsyth p->as = AMOVW;
1061*74a4d8c2SCharles.Forsyth p->from.type = D_REG;
1062*74a4d8c2SCharles.Forsyth p->from.reg = REGTMP;
1063*74a4d8c2SCharles.Forsyth p->to.type = D_OREG;
1064*74a4d8c2SCharles.Forsyth p->to.name = D_EXTERN;
1065*74a4d8c2SCharles.Forsyth p->to.sym = s;
1066*74a4d8c2SCharles.Forsyth p->to.offset = n*4 + 4;
1067*74a4d8c2SCharles.Forsyth
1068*74a4d8c2SCharles.Forsyth n += 2;
1069*74a4d8c2SCharles.Forsyth continue;
1070*74a4d8c2SCharles.Forsyth }
1071*74a4d8c2SCharles.Forsyth }
1072*74a4d8c2SCharles.Forsyth q = prg();
1073*74a4d8c2SCharles.Forsyth q->line = 0;
1074*74a4d8c2SCharles.Forsyth q->link = datap;
1075*74a4d8c2SCharles.Forsyth datap = q;
1076*74a4d8c2SCharles.Forsyth
1077*74a4d8c2SCharles.Forsyth q->as = ADATA;
1078*74a4d8c2SCharles.Forsyth q->from.type = D_OREG;
1079*74a4d8c2SCharles.Forsyth q->from.name = D_EXTERN;
1080*74a4d8c2SCharles.Forsyth q->from.sym = s;
1081*74a4d8c2SCharles.Forsyth q->reg = 4;
1082*74a4d8c2SCharles.Forsyth q->to.type = D_CONST;
1083*74a4d8c2SCharles.Forsyth q->to.offset = n;
1084*74a4d8c2SCharles.Forsyth
1085*74a4d8c2SCharles.Forsyth s->type = SBSS;
1086*74a4d8c2SCharles.Forsyth s->value = n*4;
1087*74a4d8c2SCharles.Forsyth }
1088*74a4d8c2SCharles.Forsyth
1089*74a4d8c2SCharles.Forsyth void
doprof2(void)1090*74a4d8c2SCharles.Forsyth doprof2(void)
1091*74a4d8c2SCharles.Forsyth {
1092*74a4d8c2SCharles.Forsyth Sym *s2, *s4;
1093*74a4d8c2SCharles.Forsyth Prog *p, *q, *ps2, *ps4;
1094*74a4d8c2SCharles.Forsyth
1095*74a4d8c2SCharles.Forsyth if(debug['v'])
1096*74a4d8c2SCharles.Forsyth Bprint(&bso, "%5.2f profile 2\n", cputime());
1097*74a4d8c2SCharles.Forsyth Bflush(&bso);
1098*74a4d8c2SCharles.Forsyth
1099*74a4d8c2SCharles.Forsyth s2 = lookup("_profin", 0);
1100*74a4d8c2SCharles.Forsyth s4 = lookup("_profout", 0);
1101*74a4d8c2SCharles.Forsyth if(s2->type != STEXT || s4->type != STEXT) {
1102*74a4d8c2SCharles.Forsyth diag("_profin/_profout not defined");
1103*74a4d8c2SCharles.Forsyth return;
1104*74a4d8c2SCharles.Forsyth }
1105*74a4d8c2SCharles.Forsyth
1106*74a4d8c2SCharles.Forsyth ps2 = P;
1107*74a4d8c2SCharles.Forsyth ps4 = P;
1108*74a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
1109*74a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
1110*74a4d8c2SCharles.Forsyth if(p->from.sym == s2) {
1111*74a4d8c2SCharles.Forsyth p->reg = 1;
1112*74a4d8c2SCharles.Forsyth ps2 = p;
1113*74a4d8c2SCharles.Forsyth }
1114*74a4d8c2SCharles.Forsyth if(p->from.sym == s4) {
1115*74a4d8c2SCharles.Forsyth p->reg = 1;
1116*74a4d8c2SCharles.Forsyth ps4 = p;
1117*74a4d8c2SCharles.Forsyth }
1118*74a4d8c2SCharles.Forsyth }
1119*74a4d8c2SCharles.Forsyth }
1120*74a4d8c2SCharles.Forsyth for(p = firstp; p != P; p = p->link) {
1121*74a4d8c2SCharles.Forsyth if(p->as == ATEXT) {
1122*74a4d8c2SCharles.Forsyth curtext = p;
1123*74a4d8c2SCharles.Forsyth
1124*74a4d8c2SCharles.Forsyth if(p->reg & NOPROF) { /* dont profile */
1125*74a4d8c2SCharles.Forsyth for(;;) {
1126*74a4d8c2SCharles.Forsyth q = p->link;
1127*74a4d8c2SCharles.Forsyth if(q == P)
1128*74a4d8c2SCharles.Forsyth break;
1129*74a4d8c2SCharles.Forsyth if(q->as == ATEXT)
1130*74a4d8c2SCharles.Forsyth break;
1131*74a4d8c2SCharles.Forsyth p = q;
1132*74a4d8c2SCharles.Forsyth }
1133*74a4d8c2SCharles.Forsyth continue;
1134*74a4d8c2SCharles.Forsyth }
1135*74a4d8c2SCharles.Forsyth
1136*74a4d8c2SCharles.Forsyth /*
1137*74a4d8c2SCharles.Forsyth * JMPL profin
1138*74a4d8c2SCharles.Forsyth */
1139*74a4d8c2SCharles.Forsyth q = prg();
1140*74a4d8c2SCharles.Forsyth q->line = p->line;
1141*74a4d8c2SCharles.Forsyth q->pc = p->pc;
1142*74a4d8c2SCharles.Forsyth q->link = p->link;
1143*74a4d8c2SCharles.Forsyth p->link = q;
1144*74a4d8c2SCharles.Forsyth p = q;
1145*74a4d8c2SCharles.Forsyth p->as = AJMPL;
1146*74a4d8c2SCharles.Forsyth p->to.type = D_BRANCH;
1147*74a4d8c2SCharles.Forsyth p->cond = ps2;
1148*74a4d8c2SCharles.Forsyth p->to.sym = s2;
1149*74a4d8c2SCharles.Forsyth
1150*74a4d8c2SCharles.Forsyth continue;
1151*74a4d8c2SCharles.Forsyth }
1152*74a4d8c2SCharles.Forsyth if(p->as == ARETURN) {
1153*74a4d8c2SCharles.Forsyth
1154*74a4d8c2SCharles.Forsyth /*
1155*74a4d8c2SCharles.Forsyth * RETURN
1156*74a4d8c2SCharles.Forsyth */
1157*74a4d8c2SCharles.Forsyth q = prg();
1158*74a4d8c2SCharles.Forsyth q->as = ARETURN;
1159*74a4d8c2SCharles.Forsyth q->from = p->from;
1160*74a4d8c2SCharles.Forsyth q->to = p->to;
1161*74a4d8c2SCharles.Forsyth q->link = p->link;
1162*74a4d8c2SCharles.Forsyth p->link = q;
1163*74a4d8c2SCharles.Forsyth
1164*74a4d8c2SCharles.Forsyth /*
1165*74a4d8c2SCharles.Forsyth * JMPL profout
1166*74a4d8c2SCharles.Forsyth */
1167*74a4d8c2SCharles.Forsyth p->as = AJMPL;
1168*74a4d8c2SCharles.Forsyth p->from = zprg.from;
1169*74a4d8c2SCharles.Forsyth p->to = zprg.to;
1170*74a4d8c2SCharles.Forsyth p->to.type = D_BRANCH;
1171*74a4d8c2SCharles.Forsyth p->cond = ps4;
1172*74a4d8c2SCharles.Forsyth p->to.sym = s4;
1173*74a4d8c2SCharles.Forsyth
1174*74a4d8c2SCharles.Forsyth p = q;
1175*74a4d8c2SCharles.Forsyth
1176*74a4d8c2SCharles.Forsyth continue;
1177*74a4d8c2SCharles.Forsyth }
1178*74a4d8c2SCharles.Forsyth }
1179*74a4d8c2SCharles.Forsyth }
1180*74a4d8c2SCharles.Forsyth
1181*74a4d8c2SCharles.Forsyth void
nuxiinit(void)1182*74a4d8c2SCharles.Forsyth nuxiinit(void)
1183*74a4d8c2SCharles.Forsyth {
1184*74a4d8c2SCharles.Forsyth int i, c;
1185*74a4d8c2SCharles.Forsyth
1186*74a4d8c2SCharles.Forsyth for(i=0; i<4; i++) {
1187*74a4d8c2SCharles.Forsyth c = find1(0x01020304L, i+1);
1188*74a4d8c2SCharles.Forsyth if(i >= 2)
1189*74a4d8c2SCharles.Forsyth inuxi2[i-2] = c;
1190*74a4d8c2SCharles.Forsyth if(i >= 3)
1191*74a4d8c2SCharles.Forsyth inuxi1[i-3] = c;
1192*74a4d8c2SCharles.Forsyth inuxi4[i] = c;
1193*74a4d8c2SCharles.Forsyth
1194*74a4d8c2SCharles.Forsyth fnuxi8[i] = c+4;
1195*74a4d8c2SCharles.Forsyth fnuxi8[i+4] = c;
1196*74a4d8c2SCharles.Forsyth }
1197*74a4d8c2SCharles.Forsyth if(debug['v']) {
1198*74a4d8c2SCharles.Forsyth Bprint(&bso, "inuxi = ");
1199*74a4d8c2SCharles.Forsyth for(i=0; i<1; i++)
1200*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d", inuxi1[i]);
1201*74a4d8c2SCharles.Forsyth Bprint(&bso, " ");
1202*74a4d8c2SCharles.Forsyth for(i=0; i<2; i++)
1203*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d", inuxi2[i]);
1204*74a4d8c2SCharles.Forsyth Bprint(&bso, " ");
1205*74a4d8c2SCharles.Forsyth for(i=0; i<4; i++)
1206*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d", inuxi4[i]);
1207*74a4d8c2SCharles.Forsyth Bprint(&bso, "\nfnuxi = ");
1208*74a4d8c2SCharles.Forsyth for(i=0; i<8; i++)
1209*74a4d8c2SCharles.Forsyth Bprint(&bso, "%d", fnuxi8[i]);
1210*74a4d8c2SCharles.Forsyth Bprint(&bso, "\n");
1211*74a4d8c2SCharles.Forsyth }
1212*74a4d8c2SCharles.Forsyth Bflush(&bso);
1213*74a4d8c2SCharles.Forsyth }
1214*74a4d8c2SCharles.Forsyth
1215*74a4d8c2SCharles.Forsyth int
find1(long l,int c)1216*74a4d8c2SCharles.Forsyth find1(long l, int c)
1217*74a4d8c2SCharles.Forsyth {
1218*74a4d8c2SCharles.Forsyth char *p;
1219*74a4d8c2SCharles.Forsyth int i;
1220*74a4d8c2SCharles.Forsyth
1221*74a4d8c2SCharles.Forsyth p = (char*)&l;
1222*74a4d8c2SCharles.Forsyth for(i=0; i<4; i++)
1223*74a4d8c2SCharles.Forsyth if(*p++ == c)
1224*74a4d8c2SCharles.Forsyth return i;
1225*74a4d8c2SCharles.Forsyth return 0;
1226*74a4d8c2SCharles.Forsyth }
1227*74a4d8c2SCharles.Forsyth
1228*74a4d8c2SCharles.Forsyth long
ieeedtof(Ieee * ieeep)1229*74a4d8c2SCharles.Forsyth ieeedtof(Ieee *ieeep)
1230*74a4d8c2SCharles.Forsyth {
1231*74a4d8c2SCharles.Forsyth int exp;
1232*74a4d8c2SCharles.Forsyth long v;
1233*74a4d8c2SCharles.Forsyth
1234*74a4d8c2SCharles.Forsyth if(ieeep->h == 0)
1235*74a4d8c2SCharles.Forsyth return 0;
1236*74a4d8c2SCharles.Forsyth exp = (ieeep->h>>20) & ((1L<<11)-1L);
1237*74a4d8c2SCharles.Forsyth exp -= (1L<<10) - 2L;
1238*74a4d8c2SCharles.Forsyth v = (ieeep->h & 0xfffffL) << 3;
1239*74a4d8c2SCharles.Forsyth v |= (ieeep->l >> 29) & 0x7L;
1240*74a4d8c2SCharles.Forsyth if((ieeep->l >> 28) & 1) {
1241*74a4d8c2SCharles.Forsyth v++;
1242*74a4d8c2SCharles.Forsyth if(v & 0x800000L) {
1243*74a4d8c2SCharles.Forsyth v = (v & 0x7fffffL) >> 1;
1244*74a4d8c2SCharles.Forsyth exp++;
1245*74a4d8c2SCharles.Forsyth }
1246*74a4d8c2SCharles.Forsyth }
1247*74a4d8c2SCharles.Forsyth if(exp <= -126 || exp >= 130)
1248*74a4d8c2SCharles.Forsyth diag("double fp to single fp overflow");
1249*74a4d8c2SCharles.Forsyth v |= ((exp + 126) & 0xffL) << 23;
1250*74a4d8c2SCharles.Forsyth v |= ieeep->h & 0x80000000L;
1251*74a4d8c2SCharles.Forsyth return v;
1252*74a4d8c2SCharles.Forsyth }
1253*74a4d8c2SCharles.Forsyth
1254*74a4d8c2SCharles.Forsyth double
ieeedtod(Ieee * ieeep)1255*74a4d8c2SCharles.Forsyth ieeedtod(Ieee *ieeep)
1256*74a4d8c2SCharles.Forsyth {
1257*74a4d8c2SCharles.Forsyth Ieee e;
1258*74a4d8c2SCharles.Forsyth double fr;
1259*74a4d8c2SCharles.Forsyth int exp;
1260*74a4d8c2SCharles.Forsyth
1261*74a4d8c2SCharles.Forsyth if(ieeep->h & (1L<<31)) {
1262*74a4d8c2SCharles.Forsyth e.h = ieeep->h & ~(1L<<31);
1263*74a4d8c2SCharles.Forsyth e.l = ieeep->l;
1264*74a4d8c2SCharles.Forsyth return -ieeedtod(&e);
1265*74a4d8c2SCharles.Forsyth }
1266*74a4d8c2SCharles.Forsyth if(ieeep->l == 0 && ieeep->h == 0)
1267*74a4d8c2SCharles.Forsyth return 0;
1268*74a4d8c2SCharles.Forsyth fr = ieeep->l & ((1L<<16)-1L);
1269*74a4d8c2SCharles.Forsyth fr /= 1L<<16;
1270*74a4d8c2SCharles.Forsyth fr += (ieeep->l>>16) & ((1L<<16)-1L);
1271*74a4d8c2SCharles.Forsyth fr /= 1L<<16;
1272*74a4d8c2SCharles.Forsyth fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
1273*74a4d8c2SCharles.Forsyth fr /= 1L<<21;
1274*74a4d8c2SCharles.Forsyth exp = (ieeep->h>>20) & ((1L<<11)-1L);
1275*74a4d8c2SCharles.Forsyth exp -= (1L<<10) - 2L;
1276*74a4d8c2SCharles.Forsyth return ldexp(fr, exp);
1277*74a4d8c2SCharles.Forsyth }
1278