]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/2l/span.c
ip/tftpd: use procsetuser() instead of writing #c/user
[plan9front.git] / sys / src / cmd / 2l / span.c
1 #include        "l.h"
2
3 void
4 span(void)
5 {
6         Prog *p, *q;
7         long v, c, idat;
8         Optab *o;
9         int m, n;
10
11         xdefine("etext", STEXT, 0L);
12         xdefine("a6base", STEXT, 0L);
13         idat = INITDAT;
14         for(p = firstp; p != P; p = p->link) {
15                 if(p->as == ATEXT)
16                         curtext = p;
17                 n = 0;
18                 if((q = p->pcond) != P)
19                         if(q->back != 2)
20                                 n = 1;
21                 p->back = n;
22                 if(p->as == AADJSP) {
23                         p->to.type = D_A0+7;
24                         v = -p->from.offset;
25                         p->from.offset = v;
26                         if((v < -8 && v >= -32768L) || (v > 8 && v < 32768L)) {
27                                 p->as = ALEA;
28                                 p->from.type = I_INDIR | (D_A0+7);
29                                 continue;
30                         }
31                         p->as = AADDL;
32                         if(v < 0) {
33                                 p->as = ASUBL;
34                                 v = -v;
35                                 p->from.offset = v;
36                         }
37                         if(v >= 0 && v <= 8)
38                                 p->from.type = D_QUICK;
39                         if(v == 0)
40                                 p->as = ANOP;
41                 }
42         }
43         n = 0;
44
45 start:
46         if(debug['v'])
47                 Bprint(&bso, "%5.2f span\n", cputime());
48         Bflush(&bso);
49         c = INITTEXT;
50         for(p = firstp; p != P; p = p->link) {
51                 if(p->as == ATEXT)
52                         curtext = p;
53                 o = &optab[p->as];
54                 p->pc = c;
55                 m = mmsize[o->optype];
56                 if(m == 0) {
57                         if(p->as == AWORD)
58                                 m = 2;
59                         if(p->as == ALONG)
60                                 m = 4;
61                         p->mark = m;
62                         c += m;
63                         continue;
64                 }
65                 if(p->from.type != D_NONE)
66                         m += andsize(p, &p->from);
67                 if(p->to.type == D_BRANCH) {
68                         if(p->pcond == P)
69                                 p->pcond = p;
70                         c += m;
71                         if(m == 2)
72                                 m |= 0100;
73                         p->mark = m;
74                         continue;
75                 }
76                 if(p->to.type != D_NONE)
77                         m += andsize(p, &p->to);
78                 p->mark = m;
79                 c += m;
80         }
81
82 loop:
83         n++;
84         if(debug['v'])
85                 Bprint(&bso, "%5.2f span %d\n", cputime(), n);
86         Bflush(&bso);
87         if(n > 60) {
88                 diag("span must be looping");
89                 errorexit();
90         }
91         c = INITTEXT;
92         for(p = firstp; p != P; p = p->link) {
93                 if(p->as == ATEXT)
94                         curtext = p;
95                 if((m = p->mark) & 0100) {
96                         q = p->pcond;
97                         v = q->pc - 2;
98                         if(p->back)
99                                 v -= c;
100                         else
101                                 v -= p->pc;
102                         p->pc = c;
103                         if(v < -32768L || v >= 32768L) {
104                                 if(p->as == ABSR && q->pc < 32768L && q->pc >= 0) 
105                                         c += 4;
106                                 else
107                                         c += 6;
108                         } else
109                         if(v < -128 || v >= 128)
110                                 c += 4;
111                         else
112                         if(v == 0) {
113                                 c += 4;
114                                 p->mark = 4;
115                         } else
116                                 c += 2;
117                         continue;
118                 }
119                 p->pc = c;
120                 c += m;
121         }
122         if(c != textsize) {
123                 textsize = c;
124                 goto loop;
125         }
126         if(INITRND)
127                 INITDAT = rnd(c, INITRND);
128         if(INITDAT != idat) {
129                 idat = INITDAT;
130                 goto start;
131         }
132         xdefine("etext", STEXT, c);
133         xdefine("a6base", STEXT, INITDAT+A6OFFSET);
134         if(debug['v'])
135                 Bprint(&bso, "etext = %lux\n", c);
136         Bflush(&bso);
137         for(p = textp; p != P; p = p->pcond)
138                 p->from.sym->value = p->pc;
139         textsize = c - INITTEXT;
140 }
141
142 void
143 xdefine(char *p, int t, long v)
144 {
145         Sym *s;
146
147         s = lookup(p, 0);
148         if(s->type == 0 || s->type == SXREF) {
149                 s->type = t;
150                 s->value = v;
151         }
152         if(s->type == STEXT && s->value == 0)
153                 s->value = v;
154 }
155
156 int
157 andsize(Prog *p, Adr *ap)
158 {
159         int t, n;
160         long v;
161         Optab *o;
162
163         t = ap->type;
164         if(ap->index != D_NONE) {
165                 n = 2;
166                 v = ap->displace;
167                 if(v != 0) {
168                         n += 2;
169                         if(v < -32768L || v >= 32768L)
170                                 n += 2;
171                 }
172                 switch(t) {
173                 default:
174                         v = ap->offset;
175                         break;
176
177                 case D_STATIC:
178                 case D_EXTERN:
179                         if(ap->sym->type == STEXT)
180                                 return n+4;     /* see below */
181                         v = ap->sym->value + ap->offset - A6OFFSET;
182                         if(debug['6'])
183                                 v += INITDAT + A6OFFSET;
184                 }
185                 if(v != 0) {
186                         n += 2;
187                         if(v < -32768L || v >= 32768L)
188                                 n += 2;
189                 }
190                 return n;
191         }
192         n = simple[t];
193         if(n != 0177) {
194                 v = ap->offset;
195                 if(v == 0)
196                         return 0;
197                 if((n&070) != 020)      /* D_INDIR */
198                         return 0;
199                 if(v == 0)
200                         return 0;
201                 if(v < -32768L || v >= 32768L)
202                         return 6;       /* switch to index1 mode */
203                 return 2;
204         }
205         if((t&I_MASK) == I_ADDR)
206                 t = D_CONST;
207         switch(t) {
208
209         default:
210                 return 0;
211
212         case D_STACK:
213         case D_AUTO:
214         case D_PARAM:
215                 v = ap->offset;
216                 if(v == 0)
217                         return 0;
218                 if(v < -32768L || v >= 32768L)
219                         return 6;       /* switch to index1 mode */
220                 return 2;
221
222         case I_INDIR|D_CONST:
223                 v = ap->offset;
224                 goto adr;
225
226         case D_STATIC:
227         case D_EXTERN:
228                 if(ap->sym->type == STEXT)
229                         return 4;       /* too slow to get back into namelist */
230                 v = ap->sym->value + ap->offset - A6OFFSET;
231                 if(debug['6']) {
232                         v += INITDAT + A6OFFSET;
233                         goto adr;
234                 }
235                 if(v == 0)
236                         return 0;
237
238         adr:
239                 if(v < -32768L || v >= 32768L)
240                         return 4;
241                 return 2;
242
243         case D_CONST:
244         case D_FCONST:
245                 o = &optab[p->as];
246                 if(ap == &(p->from))
247                         return o->srcsp;
248                 return o->dstsp;
249
250         case D_CCR:
251         case D_SR:
252                 if(p->as == AMOVW)
253                         return 0;
254                 return 2;
255
256         case D_USP:
257                 t = p->from.type;
258                 if(t >= D_A0 && t <= D_A0+8)
259                         return 0;
260                 t = p->to.type;
261                 if(t >= D_A0 && t <= D_A0+8)
262                         return 0;
263
264         case D_SFC:
265         case D_DFC:
266         case D_CACR:
267         case D_VBR:
268         case D_CAAR:
269         case D_MSP:
270         case D_ISP:
271         case D_FPCR:
272         case D_FPSR:
273         case D_FPIAR:
274         case D_TC:
275         case D_ITT0:
276         case D_ITT1:
277         case D_DTT0:
278         case D_DTT1:
279         case D_MMUSR:
280         case D_URP:
281         case D_SRP:
282                 return 2;
283         }
284 }
285
286 void
287 putsymb(Sym *s, int t, long v)
288 {
289         int i, f;
290         char *n;
291
292         n = s->name;
293         if(t == 'f')
294                 n++;
295         lput(v);
296         if(s->version)
297                 t += 'a' - 'A';
298         CPUT(t+0x80);                   /* 0x80 is variable length */
299
300         if(t == 'Z' || t == 'z') {
301                 CPUT(n[0]);
302                 for(i=1; n[i] != 0 || n[i+1] != 0; i += 2) {
303                         CPUT(n[i]);
304                         CPUT(n[i+1]);
305                 }
306                 CPUT(0);
307                 CPUT(0);
308                 i++;
309         }
310         else {
311                 for(i=0; n[i]; i++)
312                         CPUT(n[i]);
313                 CPUT(0);
314         }
315         symsize += 4 + 1 + i + 1;
316
317         if(debug['n']) {
318                 if(t == 'z' || t == 'Z') {
319                         Bprint(&bso, "%c %.8lux ", t, v);
320                         for(i=1; n[i] != 0 || n[i+1] != 0; i+=2) {
321                                 f = ((n[i]&0xff) << 8) | (n[i+1]&0xff);
322                                 Bprint(&bso, "/%x", f);
323                         }
324                         Bprint(&bso, "\n");
325                         return;
326                 }
327                 if(s->version)
328                         Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, n, s->version);
329                 else
330                         Bprint(&bso, "%c %.8lux %s\n", t, v, n);
331         }
332 }
333
334 void
335 asmsym(void)
336 {
337         Prog *p;
338         Auto *a;
339         Sym *s;
340         int h;
341
342         s = lookup("etext", 0);
343         if(s->type == STEXT)
344                 putsymb(s, 'T', s->value);
345         s = lookup("a6base", 0);
346         if(s->type == STEXT)
347                 putsymb(s, 'D', s->value);
348
349         for(h=0; h<NHASH; h++)
350                 for(s=hash[h]; s!=S; s=s->link)
351                         switch(s->type) {
352                         case SDATA:
353                                 putsymb(s, 'D', s->value+INITDAT);
354                                 continue;
355
356                         case SBSS:
357                                 putsymb(s, 'B', s->value+INITDAT);
358                                 continue;
359
360                         case SFILE:
361                                 putsymb(s, 'f', s->value);
362                                 continue;
363                         }
364
365         for(p=textp; p!=P; p=p->pcond) {
366                 s = p->from.sym;
367                 if(s->type != STEXT)
368                         continue;
369
370                 /* filenames first */
371                 for(a=p->to.autom; a; a=a->link)
372                         if(a->type == D_FILE)
373                                 putsymb(a->asym, 'z', a->aoffset);
374                         else
375                         if(a->type == D_FILE1)
376                                 putsymb(a->asym, 'Z', a->aoffset);
377
378                 putsymb(s, 'T', s->value);
379
380                 /* auto and param after */
381                 for(a=p->to.autom; a; a=a->link)
382                         if(a->type == D_AUTO)
383                                 putsymb(a->asym, 'a', -a->aoffset);
384                         else
385                         if(a->type == D_PARAM)
386                                 putsymb(a->asym, 'p', a->aoffset);
387         }
388         if(debug['v'] || debug['n'])
389                 Bprint(&bso, "symsize = %lud\n", symsize);
390         Bflush(&bso);
391 }
392
393 #define MINLC   2
394 void
395 asmsp(void)
396 {
397         long oldpc, oldsp;
398         Prog *p;
399         int s;
400         long v;
401
402         oldpc = INITTEXT;
403         oldsp = 0;
404         for(p = firstp; p != P; p = p->link) {
405                 if(p->stkoff == oldsp || p->as == ATEXT || p->as == ANOP) {
406                         if(p->as == ATEXT)
407                                 curtext = p;
408                         if(debug['G'])
409                                 Bprint(&bso, "%6lux %4ld%P\n",
410                                         p->pc, p->stkoff, p);
411                         continue;
412                 }
413                 if(debug['G'])
414                         Bprint(&bso, "\t\t%6ld", spsize);
415                 v = (p->pc - oldpc) / MINLC;
416                 while(v) {
417                         s = 127;
418                         if(v < 127)
419                                 s = v;
420                         CPUT(s+128);    /* 129-255 +pc */
421                         if(debug['G'])
422                                 Bprint(&bso, " pc+%d*2(%d)", s, s+128);
423                         v -= s;
424                         spsize++;
425                 }
426                 v = p->stkoff - oldsp;
427                 oldsp = p->stkoff;
428                 oldpc = p->pc + MINLC;
429                 if(v & 3 || v > 64L*4L || v < -64L*4L) {
430                         CPUT(0);        /* 0 vvvv +sp */
431                         lput(v);
432                         if(debug['G']) {
433                                 if(v > 0)
434                                         Bprint(&bso, " sp+%ld*1(%d,%ld)\n",
435                                                 v, 0, v);
436                                 else
437                                         Bprint(&bso, " sp%ld*1(%d,%ld)\n",
438                                                 v, 0, v);
439                                 Bprint(&bso, "%6lux %4ld%P\n",
440                                         p->pc, p->stkoff, p);
441                         }
442                         spsize += 5;
443                         continue;
444                 }
445                 s = v/4;
446                 if(s > 0) {
447                         CPUT(0+s);      /* 1-64 +sp */
448                         if(debug['G']) {
449                                 Bprint(&bso, " sp+%d*4(%d)\n", s, 0+s);
450                                 Bprint(&bso, "%6lux %4ld%P\n",
451                                         p->pc, p->stkoff, p);
452                         }
453                 } else {
454                         CPUT(64-s);     /* 65-128 -sp */
455                         if(debug['G']) {
456                                 Bprint(&bso, " sp%d*4(%d)\n", s, 64-s);
457                                 Bprint(&bso, "%6lux %4ld%P\n",
458                                         p->pc, p->stkoff, p);
459                         }
460                 }
461                 spsize++;
462         }
463         while(spsize & 1) {
464                 s = 129;
465                 CPUT(s);
466                 spsize++;
467         }
468         if(debug['v'] || debug['G'])
469                 Bprint(&bso, "stsize = %ld\n", spsize);
470         Bflush(&bso);
471 }
472
473 void
474 asmlc(void)
475 {
476         long oldpc, oldlc;
477         Prog *p;
478         long v, s;
479
480         oldpc = INITTEXT;
481         oldlc = 0;
482         for(p = firstp; p != P; p = p->link) {
483                 if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
484                         if(p->as == ATEXT)
485                                 curtext = p;
486                         if(debug['L'])
487                                 Bprint(&bso, "%6lux %P\n",
488                                         p->pc, p);
489                         continue;
490                 }
491                 if(debug['L'])
492                         Bprint(&bso, "\t\t%6ld", lcsize);
493                 v = (p->pc - oldpc) / MINLC;
494                 while(v) {
495                         s = 127;
496                         if(v < 127)
497                                 s = v;
498                         CPUT(s+128);    /* 129-255 +pc */
499                         if(debug['L'])
500                                 Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
501                         v -= s;
502                         lcsize++;
503                 }
504                 s = p->line - oldlc;
505                 oldlc = p->line;
506                 oldpc = p->pc + MINLC;
507                 if(s > 64 || s < -64) {
508                         CPUT(0);        /* 0 vv +lc */
509                         CPUT(s>>24);
510                         CPUT(s>>16);
511                         CPUT(s>>8);
512                         CPUT(s);
513                         if(debug['L']) {
514                                 if(s > 0)
515                                         Bprint(&bso, " lc+%ld(%d,%ld)\n",
516                                                 s, 0, s);
517                                 else
518                                         Bprint(&bso, " lc%ld(%d,%ld)\n",
519                                                 s, 0, s);
520                                 Bprint(&bso, "%6lux %P\n",
521                                         p->pc, p);
522                         }
523                         lcsize += 5;
524                         continue;
525                 }
526                 if(s > 0) {
527                         CPUT(0+s);      /* 1-64 +lc */
528                         if(debug['L']) {
529                                 Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
530                                 Bprint(&bso, "%6lux %P\n",
531                                         p->pc, p);
532                         }
533                 } else {
534                         CPUT(64-s);     /* 65-128 -lc */
535                         if(debug['L']) {
536                                 Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
537                                 Bprint(&bso, "%6lux %P\n",
538                                         p->pc, p);
539                         }
540                 }
541                 lcsize++;
542         }
543         while(lcsize & 1) {
544                 s = 129;
545                 CPUT(s);
546                 lcsize++;
547         }
548         if(debug['v'] || debug['L'])
549                 Bprint(&bso, "lcsize = %ld\n", lcsize);
550         Bflush(&bso);
551 }