]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/kl/span.c
Import sources from 2011-03-30 iso image - lib
[plan9front.git] / sys / src / cmd / kl / span.c
1 #include        "l.h"
2
3 void
4 span(void)
5 {
6         Prog *p;
7         Sym *setext;
8         Optab *o;
9         int m;
10         long c;
11
12         if(debug['v'])
13                 Bprint(&bso, "%5.2f span\n", cputime());
14         Bflush(&bso);
15         c = INITTEXT;
16         for(p = firstp; p != P; p = p->link) {
17                 p->pc = c;
18                 o = oplook(p);
19                 m = o->size;
20                 if(m == 0) {
21                         if(p->as == ATEXT) {
22                                 curtext = p;
23                                 autosize = p->to.offset + 4;
24                                 if(p->from.sym != S)
25                                         p->from.sym->value = c;
26                                 continue;
27                         }
28                         if(p->as != ANOP)
29                                 diag("zero-width instruction\n%P", p);
30                         continue;
31                 }
32                 c += m;
33         }
34         c = rnd(c, 8);
35
36         setext = lookup("etext", 0);
37         if(setext != S) {
38                 setext->value = c;
39                 textsize = c - INITTEXT;
40         }
41         if(INITRND)
42                 INITDAT = rnd(c, INITRND);
43         if(debug['v'])
44                 Bprint(&bso, "tsize = %lux\n", textsize);
45         Bflush(&bso);
46 }
47                 
48 void
49 xdefine(char *p, int t, long v)
50 {
51         Sym *s;
52
53         s = lookup(p, 0);
54         if(s->type == 0 || s->type == SXREF) {
55                 s->type = t;
56                 s->value = v;
57         }
58 }
59
60 long
61 regoff(Adr *a)
62 {
63
64         instoffset = 0;
65         aclass(a);
66         return instoffset;
67 }
68
69 int
70 aclass(Adr *a)
71 {
72         Sym *s;
73         int t;
74
75         switch(a->type) {
76         case D_NONE:
77                 return C_NONE;
78
79         case D_REG:
80                 return C_REG;
81
82         case D_FREG:
83                 return C_FREG;
84
85         case D_CREG:
86                 return C_CREG;
87
88         case D_PREG:
89                 if(a->reg == D_FSR)
90                         return C_FSR;
91                 if(a->reg == D_FPQ)
92                         return C_FQ;
93                 return C_PREG;
94
95         case D_OREG:
96                 switch(a->name) {
97                 case D_EXTERN:
98                 case D_STATIC:
99                         if(a->sym == S)
100                                 break;
101                         t = a->sym->type;
102                         if(t == 0 || t == SXREF) {
103                                 diag("undefined external: %s in %s",
104                                         a->sym->name, TNAME);
105                                 a->sym->type = SDATA;
106                         }
107                         instoffset = a->sym->value + a->offset - BIG;
108                         if(instoffset >= -BIG && instoffset < BIG) {
109                                 if(instoffset & 7)
110                                         return C_OSEXT;
111                                 return C_ESEXT;
112                         }
113                         if(instoffset & 7)
114                                 return C_OLEXT;
115                         return C_ELEXT;
116                 case D_AUTO:
117                         instoffset = autosize + a->offset;
118                         goto dauto;
119
120                 case D_PARAM:
121                         instoffset = autosize + a->offset + 4L;
122                 dauto:
123                         if(instoffset >= -BIG && instoffset < BIG) {
124                                 if(instoffset & 7)
125                                         return C_OSAUTO;
126                                 return C_ESAUTO;
127                         }
128                         if(instoffset & 7)
129                                 return C_OLAUTO;
130                         return C_ELAUTO;
131                 case D_NONE:
132                         instoffset = a->offset;
133                         if(instoffset == 0)
134                                 return C_ZOREG;
135                         if(instoffset >= -BIG && instoffset < BIG)
136                                 return C_SOREG;
137                         return C_LOREG;
138                 }
139                 return C_GOK;
140
141         case D_ASI:
142                 if(a->name == D_NONE)
143                         return C_ASI;
144                 return C_GOK;
145
146         case D_CONST:
147                 switch(a->name) {
148
149                 case D_NONE:
150                         instoffset = a->offset;
151                 consize:
152                         if(instoffset == 0)
153                                 return C_ZCON;
154                         if(instoffset >= -0x1000 && instoffset <= 0xfff)
155                                 return C_SCON;
156                         if((instoffset & 0x3ff) == 0)
157                                 return C_UCON;
158                         return C_LCON;
159
160                 case D_EXTERN:
161                 case D_STATIC:
162                         s = a->sym;
163                         if(s == S)
164                                 break;
165                         t = s->type;
166                         if(t == 0 || t == SXREF) {
167                                 diag("undefined external: %s in %s",
168                                         s->name, TNAME);
169                                 s->type = SDATA;
170                         }
171                         if(s->type == STEXT || s->type == SLEAF) {
172                                 instoffset = s->value + a->offset;
173                                 return C_LCON;
174                         }
175                         if(s->type == SCONST) {
176                                 instoffset = s->value + a->offset;
177                                 goto consize;
178                         }
179                         instoffset = s->value + a->offset - BIG;
180                         if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
181                                 return C_SECON;
182                         instoffset = s->value + a->offset + INITDAT;
183 /* not sure why this barfs */
184 return C_LCON;
185 /*
186                         if(instoffset == 0)
187                                 return C_ZCON;
188                         if(instoffset >= -0x1000 && instoffset <= 0xfff)
189                                 return C_SCON;
190                         if((instoffset & 0x3ff) == 0)
191                                 return C_UCON;
192                         return C_LCON;
193 */
194
195                 case D_AUTO:
196                         instoffset = autosize + a->offset;
197                         if(instoffset >= -BIG && instoffset < BIG)
198                                 return C_SACON;
199                         return C_LACON;
200
201                 case D_PARAM:
202                         instoffset = autosize + a->offset + 4L;
203                         if(instoffset >= -BIG && instoffset < BIG)
204                                 return C_SACON;
205                         return C_LACON;
206                 }
207                 return C_GOK;
208
209         case D_BRANCH:
210                 return C_SBRA;
211         }
212         return C_GOK;
213 }
214
215 Optab*
216 oplook(Prog *p)
217 {
218         int a1, a2, a3, r;
219         char *c1, *c3;
220         Optab *o, *e;
221
222         a1 = p->optab;
223         if(a1)
224                 return optab+(a1-1);
225         a1 = p->from.class;
226         if(a1 == 0) {
227                 a1 = aclass(&p->from) + 1;
228                 p->from.class = a1;
229         }
230         a1--;
231         a3 = p->to.class;
232         if(a3 == 0) {
233                 a3 = aclass(&p->to) + 1;
234                 p->to.class = a3;
235         }
236         a3--;
237         a2 = C_NONE;
238         if(p->reg != NREG)
239                 a2 = C_REG;
240         r = p->as;
241         o = oprange[r].start;
242         if(o == 0)
243                 o = oprange[r].stop; /* just generate an error */
244         e = oprange[r].stop;
245         c1 = xcmp[a1];
246         c3 = xcmp[a3];
247         for(; o<e; o++)
248                 if(o->a2 == a2)
249                 if(c1[o->a1])
250                 if(c3[o->a3]) {
251                         p->optab = (o-optab)+1;
252                         return o;
253                 }
254         diag("illegal combination %A %d %d %d",
255                 p->as, a1, a2, a3);
256         if(1||!debug['a'])
257                 prasm(p);
258         if(o == 0)
259                 errorexit();
260         return o;
261 }
262
263 int
264 cmp(int a, int b)
265 {
266
267         if(a == b)
268                 return 1;
269         switch(a) {
270         case C_LCON:
271                 if(b == C_ZCON || b == C_SCON || b == C_UCON)
272                         return 1;
273                 break;
274         case C_UCON:
275                 if(b == C_ZCON)
276                         return 1;
277                 break;
278         case C_SCON:
279                 if(b == C_ZCON)
280                         return 1;
281                 break;
282         case C_LACON:
283                 if(b == C_SACON)
284                         return 1;
285                 break;
286         case C_LBRA:
287                 if(b == C_SBRA)
288                         return 1;
289                 break;
290         case C_ELEXT:
291                 if(b == C_ESEXT)
292                         return 1;
293                 break;
294         case C_LEXT:
295                 if(b == C_SEXT ||
296                    b == C_ESEXT || b == C_OSEXT ||
297                    b == C_ELEXT || b == C_OLEXT)
298                         return 1;
299                 break;
300         case C_SEXT:
301                 if(b == C_ESEXT || b == C_OSEXT)
302                         return 1;
303                 break;
304         case C_ELAUTO:
305                 if(b == C_ESAUTO)
306                         return 1;
307                 break;
308         case C_LAUTO:
309                 if(b == C_SAUTO ||
310                    b == C_ESAUTO || b == C_OSAUTO ||
311                    b == C_ELAUTO || b == C_OLAUTO)
312                         return 1;
313                 break;
314         case C_SAUTO:
315                 if(b == C_ESAUTO || b == C_OSAUTO)
316                         return 1;
317                 break;
318         case C_REG:
319                 if(b == C_ZCON)
320                         return 1;
321                 break;
322         case C_LOREG:
323                 if(b == C_ZOREG || b == C_SOREG)
324                         return 1;
325                 break;
326         case C_SOREG:
327                 if(b == C_ZOREG)
328                         return 1;
329                 break;
330
331         case C_ANY:
332                 return 1;
333         }
334         return 0;
335 }
336
337 int
338 ocmp(const void *a1, const void *a2)
339 {
340         Optab *p1, *p2;
341         int n;
342
343         p1 = (Optab*)a1;
344         p2 = (Optab*)a2;
345         n = p1->as - p2->as;
346         if(n)
347                 return n;
348         n = p1->a1 - p2->a1;
349         if(n)
350                 return n;
351         n = p1->a2 - p2->a2;
352         if(n)
353                 return n;
354         n = p1->a3 - p2->a3;
355         if(n)
356                 return n;
357         return 0;
358 }
359
360 void
361 buildop(void)
362 {
363         int i, n, r;
364
365         for(i=0; i<C_NCLASS; i++)
366                 for(n=0; n<C_NCLASS; n++)
367                         xcmp[i][n] = cmp(n, i);
368         for(n=0; optab[n].as != AXXX; n++)
369                 ;
370         qsort(optab, n, sizeof(optab[0]), ocmp);
371         for(i=0; i<n; i++) {
372                 r = optab[i].as;
373                 oprange[r].start = optab+i;
374                 while(optab[i].as == r)
375                         i++;
376                 oprange[r].stop = optab+i;
377                 i--;
378                 
379                 switch(r)
380                 {
381                 default:
382                         diag("unknown op in build: %A", r);
383                         errorexit();
384                 case AADD:
385                         oprange[AADDX] = oprange[r];
386                         oprange[ASUB] = oprange[r];
387                         oprange[ASUBX] = oprange[r];
388                         oprange[AMUL] = oprange[r];
389                         oprange[AXOR] = oprange[r];
390                         oprange[AXNOR] = oprange[r];
391                         oprange[AAND] = oprange[r];
392                         oprange[AANDN] = oprange[r];
393                         oprange[AOR] = oprange[r];
394                         oprange[AORN] = oprange[r];
395                         oprange[ASLL] = oprange[r];
396                         oprange[ASRL] = oprange[r];
397                         oprange[ASRA] = oprange[r];
398                         oprange[AADDCC] = oprange[r];
399                         oprange[AADDXCC] = oprange[r];
400                         oprange[ATADDCC] = oprange[r];
401                         oprange[ATADDCCTV] = oprange[r];
402                         oprange[ASUBCC] = oprange[r];
403                         oprange[ASUBXCC] = oprange[r];
404                         oprange[ATSUBCC] = oprange[r];
405                         oprange[ATSUBCCTV] = oprange[r];
406                         oprange[AXORCC] = oprange[r];
407                         oprange[AXNORCC] = oprange[r];
408                         oprange[AANDCC] = oprange[r];
409                         oprange[AANDNCC] = oprange[r];
410                         oprange[AORCC] = oprange[r];
411                         oprange[AORNCC] = oprange[r];
412                         oprange[AMULSCC] = oprange[r];
413                         oprange[ASAVE] = oprange[r];
414                         oprange[ARESTORE] = oprange[r];
415                         break;
416                 case AMOVB:
417                         oprange[AMOVH] = oprange[r];
418                         oprange[AMOVHU] = oprange[r];
419                         oprange[AMOVBU] = oprange[r];
420                         oprange[ASWAP] = oprange[r];
421                         oprange[ATAS] = oprange[r];
422                         break;
423                 case ABA:
424                         oprange[ABN] = oprange[r];
425                         oprange[AFBA] = oprange[r];
426                         oprange[AFBN] = oprange[r];
427                         break;
428                 case ABE:
429                         oprange[ABCC] = oprange[r];
430                         oprange[ABCS] = oprange[r];
431                         oprange[ABGE] = oprange[r];
432                         oprange[ABGU] = oprange[r];
433                         oprange[ABG] = oprange[r];
434                         oprange[ABLEU] = oprange[r];
435                         oprange[ABLE] = oprange[r];
436                         oprange[ABL] = oprange[r];
437                         oprange[ABNEG] = oprange[r];
438                         oprange[ABNE] = oprange[r];
439                         oprange[ABPOS] = oprange[r];
440                         oprange[ABVC] = oprange[r];
441                         oprange[ABVS] = oprange[r];
442
443                         oprange[AFBE] = oprange[r];
444                         oprange[AFBG] = oprange[r];
445                         oprange[AFBGE] = oprange[r];
446                         oprange[AFBL] = oprange[r];
447                         oprange[AFBLE] = oprange[r];
448                         oprange[AFBLG] = oprange[r];
449                         oprange[AFBNE] = oprange[r];
450                         oprange[AFBO] = oprange[r];
451                         oprange[AFBU] = oprange[r];
452                         oprange[AFBUE] = oprange[r];
453                         oprange[AFBUG] = oprange[r];
454                         oprange[AFBUGE] = oprange[r];
455                         oprange[AFBUL] = oprange[r];
456                         oprange[AFBULE] = oprange[r];
457                         break;
458                 case ATA:
459                         oprange[ATCC] = oprange[r];
460                         oprange[ATCS] = oprange[r];
461                         oprange[ATE] = oprange[r];
462                         oprange[ATGE] = oprange[r];
463                         oprange[ATGU] = oprange[r];
464                         oprange[ATG] = oprange[r];
465                         oprange[ATLEU] = oprange[r];
466                         oprange[ATLE] = oprange[r];
467                         oprange[ATL] = oprange[r];
468                         oprange[ATNEG] = oprange[r];
469                         oprange[ATNE] = oprange[r];
470                         oprange[ATN] = oprange[r];
471                         oprange[ATPOS] = oprange[r];
472                         oprange[ATVC] = oprange[r];
473                         oprange[ATVS] = oprange[r];
474                         break;
475                 case AFADDD:
476                         oprange[AFADDF] = oprange[r];
477                         oprange[AFADDX] = oprange[r];
478                         oprange[AFDIVD] = oprange[r];
479                         oprange[AFDIVF] = oprange[r];
480                         oprange[AFDIVX] = oprange[r];
481                         oprange[AFMULD] = oprange[r];
482                         oprange[AFMULF] = oprange[r];
483                         oprange[AFMULX] = oprange[r];
484                         oprange[AFSUBD] = oprange[r];
485                         oprange[AFSUBF] = oprange[r];
486                         oprange[AFSUBX] = oprange[r];
487                         break;
488                 case AFCMPD:
489                         oprange[AFCMPF] = oprange[r];
490                         oprange[AFCMPX] = oprange[r];
491                         oprange[AFCMPED] = oprange[r];
492                         oprange[AFCMPEF] = oprange[r];
493                         oprange[AFCMPEX] = oprange[r];
494                         break;
495                 case AFABSF:
496                         oprange[AFMOVDF] = oprange[r];
497                         oprange[AFMOVDW] = oprange[r];
498                         oprange[AFMOVFD] = oprange[r];
499                         oprange[AFMOVFW] = oprange[r];
500                         oprange[AFMOVWD] = oprange[r];
501                         oprange[AFMOVWF] = oprange[r];
502                         oprange[AFNEGF] = oprange[r];
503                         oprange[AFSQRTD] = oprange[r];
504                         oprange[AFSQRTF] = oprange[r];
505                         break;
506                 case AFMOVF:
507                 case AFMOVD:
508                 case AMOVW:
509                 case AMOVD:
510                 case AWORD:
511                 case ARETT:
512                 case AJMPL:
513                 case AJMP:
514                 case ACMP:
515                 case ANOP:
516                 case ATEXT:
517                 case ADIV:
518                 case ADIVL:
519                 case AMOD:
520                 case AMODL:
521                         break;
522                 }
523         }
524 }