]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ql/span.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / ql / span.c
1 #include        "l.h"
2 #define r0iszero        1
3
4 void
5 span(void)
6 {
7         Prog *p, *q;
8         Sym *setext;
9         Optab *o;
10         int m, bflag;
11         long c, otxt;
12
13         if(debug['v'])
14                 Bprint(&bso, "%5.2f span\n", cputime());
15         Bflush(&bso);
16
17         bflag = 0;
18         c = INITTEXT;
19         otxt = c;
20         for(p = firstp; p != P; p = p->link) {
21                 p->pc = c;
22                 o = oplook(p);
23                 m = o->size;
24                 if(m == 0) {
25                         if(p->as == ATEXT) {
26                                 curtext = p;
27                                 autosize = p->to.offset + 4;
28                                 if(p->from3.type == D_CONST) {
29                                         if(p->from3.offset & 3)
30                                                 diag("illegal origin\n%P", p);
31                                         if(c > p->from3.offset)
32                                                 diag("passed origin (#%lux)\n%P", c, p);
33                                         else
34                                                 c = p->from3.offset;
35                                         p->pc = c;
36                                 }
37                                 if(p->from.sym != S)
38                                         p->from.sym->value = c;
39                                 /* need passes to resolve branches? */
40                                 if(c-otxt >= (1L<<15))
41                                         bflag = c;
42                                 otxt = c;
43                                 continue;
44                         }
45                         if(p->as != ANOP)
46                                 diag("zero-width instruction\n%P", p);
47                         continue;
48                 }
49                 c += m;
50         }
51
52         /*
53          * if any procedure is large enough to
54          * generate a large SBRA branch, then
55          * generate extra passes putting branches
56          * around jmps to fix. this is rare.
57          */
58         while(bflag) {
59                 if(debug['v'])
60                         Bprint(&bso, "%5.2f span1\n", cputime());
61                 bflag = 0;
62                 c = INITTEXT;
63                 for(p = firstp; p != P; p = p->link) {
64                         p->pc = c;
65                         o = oplook(p);
66                         if((o->type == 16 || o->type == 17) && p->cond) {
67                                 otxt = p->cond->pc - c;
68                                 if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
69                                         q = prg();
70                                         q->link = p->link;
71                                         p->link = q;
72                                         q->as = ABR;
73                                         q->to.type = D_BRANCH;
74                                         q->cond = p->cond;
75                                         p->cond = q;
76                                         q = prg();
77                                         q->link = p->link;
78                                         p->link = q;
79                                         q->as = ABR;
80                                         q->to.type = D_BRANCH;
81                                         q->cond = q->link->link;
82                                         addnop(p->link);
83                                         addnop(p);
84                                         bflag = 1;
85                                 }
86                         }
87                         m = o->size;
88                         if(m == 0) {
89                                 if(p->as == ATEXT) {
90                                         curtext = p;
91                                         autosize = p->to.offset + 4;
92                                         if(p->from.sym != S)
93                                                 p->from.sym->value = c;
94                                         continue;
95                                 }
96                                 if(p->as != ANOP)
97                                         diag("zero-width instruction\n%P", p);
98                                 continue;
99                         }
100                         c += m;
101                 }
102         }
103
104         c = rnd(c, 8);
105
106         setext = lookup("etext", 0);
107         if(setext != S) {
108                 setext->value = c;
109                 textsize = c - INITTEXT;
110         }
111         if(INITRND)
112                 INITDAT = rnd(c, INITRND);
113         if(debug['v'])
114                 Bprint(&bso, "tsize = %lux\n", textsize);
115         Bflush(&bso);
116 }
117                 
118 void
119 xdefine(char *p, int t, long v)
120 {
121         Sym *s;
122
123         s = lookup(p, 0);
124         if(s->type == 0 || s->type == SXREF) {
125                 s->type = t;
126                 s->value = v;
127         }
128 }
129
130 long
131 regoff(Adr *a)
132 {
133
134         instoffset = 0;
135         aclass(a);
136         return instoffset;
137 }
138
139 int
140 aclass(Adr *a)
141 {
142         Sym *s;
143         int t;
144
145         switch(a->type) {
146         case D_NONE:
147                 return C_NONE;
148
149         case D_REG:
150                 return C_REG;
151
152         case D_FREG:
153                 return C_FREG;
154
155         case D_CREG:
156                 return C_CREG;
157
158         case D_SPR:
159                 if(a->offset == D_LR)
160                         return C_LR;
161                 if(a->offset == D_XER)
162                         return C_XER;
163                 if(a->offset == D_CTR)
164                         return C_CTR;
165                 return C_SPR;
166
167         case D_DCR:
168                 return C_SPR;
169
170         case D_SREG:
171                 return C_SREG;
172
173         case D_FPSCR:
174                 return C_FPSCR;
175
176         case D_MSR:
177                 return C_MSR;
178
179         case D_OREG:
180                 switch(a->name) {
181                 case D_EXTERN:
182                 case D_STATIC:
183                         if(a->sym == S)
184                                 break;
185                         t = a->sym->type;
186                         if(t == 0 || t == SXREF) {
187                                 diag("undefined external: %s in %s",
188                                         a->sym->name, TNAME);
189                                 a->sym->type = SDATA;
190                         }
191                         if(dlm){
192                                 instoffset = a->sym->value + a->offset;
193                                 switch(a->sym->type){
194                                 case STEXT:
195                                 case SLEAF:
196                                 case SCONST:
197                                 case SUNDEF:
198                                         break;
199                                 default:
200                                         instoffset += INITDAT;
201                                 }
202                                 return C_ADDR;
203                         }
204                         instoffset = a->sym->value + a->offset - BIG;
205                         if(instoffset >= -BIG && instoffset < BIG)
206                                 return C_SEXT;
207                         return C_LEXT;
208                 case D_AUTO:
209                         instoffset = autosize + a->offset;
210                         if(instoffset >= -BIG && instoffset < BIG)
211                                 return C_SAUTO;
212                         return C_LAUTO;
213
214                 case D_PARAM:
215                         instoffset = autosize + a->offset + 4L;
216                         if(instoffset >= -BIG && instoffset < BIG)
217                                 return C_SAUTO;
218                         return C_LAUTO;
219                 case D_NONE:
220                         instoffset = a->offset;
221                         if(instoffset == 0)
222                                 return C_ZOREG;
223                         if(instoffset >= -BIG && instoffset < BIG)
224                                 return C_SOREG;
225                         return C_LOREG;
226                 }
227                 return C_GOK;
228
229         case D_OPT:
230                 instoffset = a->offset & 31L;
231                 if(a->name == D_NONE)
232                         return C_SCON;
233                 return C_GOK;
234
235         case D_CONST:
236                 switch(a->name) {
237
238                 case D_NONE:
239                         instoffset = a->offset;
240                 consize:
241                         if(instoffset >= 0) {
242                                 if(r0iszero && instoffset == 0)
243                                         return C_ZCON;
244                                 if(instoffset <= 0x7fff)
245                                         return C_SCON;
246                                 if(instoffset <= 0xffff)
247                                         return C_ANDCON;
248                                 if((instoffset & 0xffff) == 0)
249                                         return C_UCON;
250                                 return C_LCON;
251                         }
252                         if(instoffset >= -0x8000)
253                                 return C_ADDCON;
254                         if((instoffset & 0xffff) == 0)
255                                 return C_UCON;
256                         return C_LCON;
257
258                 case D_EXTERN:
259                 case D_STATIC:
260                         s = a->sym;
261                         if(s == S)
262                                 break;
263                         t = s->type;
264                         if(t == 0 || t == SXREF) {
265                                 diag("undefined external: %s in %s",
266                                         s->name, TNAME);
267                                 s->type = SDATA;
268                         }
269                         if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
270                                 instoffset = s->value + a->offset;
271                                 return C_LCON;
272                         }
273                         if(s->type == SCONST) {
274                                 instoffset = s->value + a->offset;
275                                 if(dlm)
276                                         return C_LCON;
277                                 goto consize;
278                         }
279                         if(!dlm){
280                                 instoffset = s->value + a->offset - BIG;
281                                 if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
282                                         return C_SECON;
283                         }
284                         instoffset = s->value + a->offset + INITDAT;
285                         if(dlm)
286                                 return C_LCON;
287                         /* not sure why this barfs */
288                         return C_LCON;
289                 /*
290                         if(instoffset == 0)
291                                 return C_ZCON;
292                         if(instoffset >= -0x8000 && instoffset <= 0xffff)
293                                 return C_SCON;
294                         if((instoffset & 0xffff) == 0)
295                                 return C_UCON;
296                         return C_LCON;
297                 */
298
299                 case D_AUTO:
300                         instoffset = autosize + a->offset;
301                         if(instoffset >= -BIG && instoffset < BIG)
302                                 return C_SACON;
303                         return C_LACON;
304
305                 case D_PARAM:
306                         instoffset = autosize + a->offset + 4L;
307                         if(instoffset >= -BIG && instoffset < BIG)
308                                 return C_SACON;
309                         return C_LACON;
310                 }
311                 return C_GOK;
312
313         case D_BRANCH:
314                 return C_SBRA;
315         }
316         return C_GOK;
317 }
318
319 Optab*
320 oplook(Prog *p)
321 {
322         int a1, a2, a3, a4, r;
323         char *c1, *c3, *c4;
324         Optab *o, *e;
325
326         a1 = p->optab;
327         if(a1)
328                 return optab+(a1-1);
329         a1 = p->from.class;
330         if(a1 == 0) {
331                 a1 = aclass(&p->from) + 1;
332                 p->from.class = a1;
333         }
334         a1--;
335         a3 = p->from3.class;
336         if(a3 == 0) {
337                 a3 = aclass(&p->from3) + 1;
338                 p->from3.class = a3;
339         }
340         a3--;
341         a4 = p->to.class;
342         if(a4 == 0) {
343                 a4 = aclass(&p->to) + 1;
344                 p->to.class = a4;
345         }
346         a4--;
347         a2 = C_NONE;
348         if(p->reg != NREG)
349                 a2 = C_REG;
350         r = p->as;
351         o = oprange[r].start;
352         if(o == 0)
353                 o = oprange[r].stop; /* just generate an error */
354         e = oprange[r].stop;
355         c1 = xcmp[a1];
356         c3 = xcmp[a3];
357         c4 = xcmp[a4];
358         for(; o<e; o++)
359                 if(o->a2 == a2)
360                 if(c1[o->a1])
361                 if(c3[o->a3])
362                 if(c4[o->a4]) {
363                         p->optab = (o-optab)+1;
364                         return o;
365                 }
366         diag("illegal combination %A %R %R %R %R",
367                 p->as, a1, a2, a3, a4);
368         if(1||!debug['a'])
369                 prasm(p);
370         if(o == 0)
371                 errorexit();
372         return o;
373 }
374
375 int
376 cmp(int a, int b)
377 {
378
379         if(a == b)
380                 return 1;
381         switch(a) {
382         case C_LCON:
383                 if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
384                         return 1;
385                 break;
386         case C_ADDCON:
387                 if(b == C_ZCON || b == C_SCON)
388                         return 1;
389                 break;
390         case C_ANDCON:
391                 if(b == C_ZCON || b == C_SCON)
392                         return 1;
393                 break;
394         case C_SPR:
395                 if(b == C_LR || b == C_XER || b == C_CTR)
396                         return 1;
397                 break;
398         case C_UCON:
399                 if(b == C_ZCON)
400                         return 1;
401                 break;
402         case C_SCON:
403                 if(b == C_ZCON)
404                         return 1;
405                 break;
406         case C_LACON:
407                 if(b == C_SACON)
408                         return 1;
409                 break;
410         case C_LBRA:
411                 if(b == C_SBRA)
412                         return 1;
413                 break;
414         case C_LEXT:
415                 if(b == C_SEXT)
416                         return 1;
417                 break;
418         case C_LAUTO:
419                 if(b == C_SAUTO)
420                         return 1;
421                 break;
422         case C_REG:
423                 if(r0iszero && b == C_ZCON)
424                         return 1;
425                 break;
426         case C_LOREG:
427                 if(b == C_ZOREG || b == C_SOREG)
428                         return 1;
429                 break;
430         case C_SOREG:
431                 if(b == C_ZOREG)
432                         return 1;
433                 break;
434
435         case C_ANY:
436                 return 1;
437         }
438         return 0;
439 }
440
441 int
442 ocmp(void *a1, void *a2)
443 {
444         Optab *p1, *p2;
445         int n;
446
447         p1 = a1;
448         p2 = a2;
449         n = p1->as - p2->as;
450         if(n)
451                 return n;
452         n = p1->a1 - p2->a1;
453         if(n)
454                 return n;
455         n = p1->a2 - p2->a2;
456         if(n)
457                 return n;
458         n = p1->a3 - p2->a3;
459         if(n)
460                 return n;
461         n = p1->a4 - p2->a4;
462         if(n)
463                 return n;
464         return 0;
465 }
466
467 void
468 buildop(void)
469 {
470         int i, n, r;
471
472         for(i=0; i<C_NCLASS; i++)
473                 for(n=0; n<C_NCLASS; n++)
474                         xcmp[i][n] = cmp(n, i);
475         for(n=0; optab[n].as != AXXX; n++)
476                 ;
477         qsort(optab, n, sizeof(optab[0]), ocmp);
478         for(i=0; i<n; i++) {
479                 r = optab[i].as;
480                 oprange[r].start = optab+i;
481                 while(optab[i].as == r)
482                         i++;
483                 oprange[r].stop = optab+i;
484                 i--;
485                 
486                 switch(r)
487                 {
488                 default:
489                         diag("unknown op in build: %A", r);
490                         errorexit();
491                 case ADCBF:     /* unary indexed: op (b+a); op (b) */
492                         oprange[ADCBI] = oprange[r];
493                         oprange[ADCBST] = oprange[r];
494                         oprange[ADCBT] = oprange[r];
495                         oprange[ADCBTST] = oprange[r];
496                         oprange[ADCBZ] = oprange[r];
497                         oprange[AICBI] = oprange[r];
498                         break;
499                 case AECOWX:    /* indexed store: op s,(b+a); op s,(b) */
500                         oprange[ASTWCCC] = oprange[r];
501                         break;
502                 case AREM:      /* macro */
503                         oprange[AREMCC] = oprange[r];
504                         oprange[AREMV] = oprange[r];
505                         oprange[AREMVCC] = oprange[r];
506                         oprange[AREMU] = oprange[r];
507                         oprange[AREMUCC] = oprange[r];
508                         oprange[AREMUV] = oprange[r];
509                         oprange[AREMUVCC] = oprange[r];
510                         break;
511                 case ADIVW:     /* op Rb[,Ra],Rd */
512                         oprange[AMULHW] = oprange[r];
513                         oprange[AMULHWCC] = oprange[r];
514                         oprange[AMULHWU] = oprange[r];
515                         oprange[AMULHWUCC] = oprange[r];
516                         oprange[AMULLWCC] = oprange[r];
517                         oprange[AMULLWVCC] = oprange[r];
518                         oprange[AMULLWV] = oprange[r];
519                         oprange[ADIVWCC] = oprange[r];
520                         oprange[ADIVWV] = oprange[r];
521                         oprange[ADIVWVCC] = oprange[r];
522                         oprange[ADIVWU] = oprange[r];
523                         oprange[ADIVWUCC] = oprange[r];
524                         oprange[ADIVWUV] = oprange[r];
525                         oprange[ADIVWUVCC] = oprange[r];
526                         oprange[AADDCC] = oprange[r];
527                         oprange[AADDCV] = oprange[r];
528                         oprange[AADDCVCC] = oprange[r];
529                         oprange[AADDV] = oprange[r];
530                         oprange[AADDVCC] = oprange[r];
531                         oprange[AADDE] = oprange[r];
532                         oprange[AADDECC] = oprange[r];
533                         oprange[AADDEV] = oprange[r];
534                         oprange[AADDEVCC] = oprange[r];
535                         oprange[ACRAND] = oprange[r];
536                         oprange[ACRANDN] = oprange[r];
537                         oprange[ACREQV] = oprange[r];
538                         oprange[ACRNAND] = oprange[r];
539                         oprange[ACRNOR] = oprange[r];
540                         oprange[ACROR] = oprange[r];
541                         oprange[ACRORN] = oprange[r];
542                         oprange[ACRXOR] = oprange[r];
543                         oprange[AMULCHW] = oprange[r];
544                         oprange[AMULCHWCC] = oprange[r];
545                         oprange[AMULCHWU] = oprange[r];
546                         oprange[AMULCHWUCC] = oprange[r];
547                         oprange[AMULHHW] = oprange[r];
548                         oprange[AMULHHWCC] = oprange[r];
549                         oprange[AMULHHWU] = oprange[r];
550                         oprange[AMULHHWUCC] = oprange[r];
551                         oprange[AMULLHW] = oprange[r];
552                         oprange[AMULLHWCC] = oprange[r];
553                         oprange[AMULLHWU] = oprange[r];
554                         oprange[AMULLHWUCC] = oprange[r];
555                         break;
556                 case AMACCHW:   /* strictly 3 registers */
557                         oprange[AMACCHWCC] = oprange[r];
558                         oprange[AMACCHWS] = oprange[r];
559                         oprange[AMACCHWSCC] = oprange[r];
560                         oprange[AMACCHWSU] = oprange[r];
561                         oprange[AMACCHWSUCC] = oprange[r];
562                         oprange[AMACCHWSUV] = oprange[r];
563                         oprange[AMACCHWSUVCC] = oprange[r];
564                         oprange[AMACCHWSV] = oprange[r];
565                         oprange[AMACCHWSVCC] = oprange[r];
566                         oprange[AMACCHWU] = oprange[r];
567                         oprange[AMACCHWUCC] = oprange[r];
568                         oprange[AMACCHWUV] = oprange[r];
569                         oprange[AMACCHWUVCC] = oprange[r];
570                         oprange[AMACCHWV] = oprange[r];
571                         oprange[AMACCHWVCC] = oprange[r];
572                         oprange[AMACHHW] = oprange[r];
573                         oprange[AMACHHWCC] = oprange[r];
574                         oprange[AMACHHWS] = oprange[r];
575                         oprange[AMACHHWSCC] = oprange[r];
576                         oprange[AMACHHWSU] = oprange[r];
577                         oprange[AMACHHWSUCC] = oprange[r];
578                         oprange[AMACHHWSUV] = oprange[r];
579                         oprange[AMACHHWSUVCC] = oprange[r];
580                         oprange[AMACHHWSV] = oprange[r];
581                         oprange[AMACHHWSVCC] = oprange[r];
582                         oprange[AMACHHWU] = oprange[r];
583                         oprange[AMACHHWUCC] = oprange[r];
584                         oprange[AMACHHWUV] = oprange[r];
585                         oprange[AMACHHWUVCC] = oprange[r];
586                         oprange[AMACHHWV] = oprange[r];
587                         oprange[AMACHHWVCC] = oprange[r];
588                         oprange[AMACLHW] = oprange[r];
589                         oprange[AMACLHWCC] = oprange[r];
590                         oprange[AMACLHWS] = oprange[r];
591                         oprange[AMACLHWSCC] = oprange[r];
592                         oprange[AMACLHWSU] = oprange[r];
593                         oprange[AMACLHWSUCC] = oprange[r];
594                         oprange[AMACLHWSUV] = oprange[r];
595                         oprange[AMACLHWSUVCC] = oprange[r];
596                         oprange[AMACLHWSV] = oprange[r];
597                         oprange[AMACLHWSVCC] = oprange[r];
598                         oprange[AMACLHWU] = oprange[r];
599                         oprange[AMACLHWUCC] = oprange[r];
600                         oprange[AMACLHWUV] = oprange[r];
601                         oprange[AMACLHWUVCC] = oprange[r];
602                         oprange[AMACLHWV] = oprange[r];
603                         oprange[AMACLHWVCC] = oprange[r];
604                         oprange[ANMACCHW] = oprange[r];
605                         oprange[ANMACCHWCC] = oprange[r];
606                         oprange[ANMACCHWS] = oprange[r];
607                         oprange[ANMACCHWSCC] = oprange[r];
608                         oprange[ANMACCHWSV] = oprange[r];
609                         oprange[ANMACCHWSVCC] = oprange[r];
610                         oprange[ANMACCHWV] = oprange[r];
611                         oprange[ANMACCHWVCC] = oprange[r];
612                         oprange[ANMACHHW] = oprange[r];
613                         oprange[ANMACHHWCC] = oprange[r];
614                         oprange[ANMACHHWS] = oprange[r];
615                         oprange[ANMACHHWSCC] = oprange[r];
616                         oprange[ANMACHHWSV] = oprange[r];
617                         oprange[ANMACHHWSVCC] = oprange[r];
618                         oprange[ANMACHHWV] = oprange[r];
619                         oprange[ANMACHHWVCC] = oprange[r];
620                         oprange[ANMACLHW] = oprange[r];
621                         oprange[ANMACLHWCC] = oprange[r];
622                         oprange[ANMACLHWS] = oprange[r];
623                         oprange[ANMACLHWSCC] = oprange[r];
624                         oprange[ANMACLHWSV] = oprange[r];
625                         oprange[ANMACLHWSVCC] = oprange[r];
626                         oprange[ANMACLHWV] = oprange[r];
627                         oprange[ANMACLHWVCC] = oprange[r];
628                         break;
629                 case AMOVBZ:    /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
630                         oprange[AMOVH] = oprange[r];
631                         oprange[AMOVHZ] = oprange[r];
632                         break;
633                 case AMOVBZU:   /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
634                         oprange[AMOVHU] = oprange[r];
635                         oprange[AMOVHZU] = oprange[r];
636                         oprange[AMOVWU] = oprange[r];
637                         oprange[AMOVMW] = oprange[r];
638                         break;
639                 case AAND:      /* logical op Rb,Rs,Ra; no literal */
640                         oprange[AANDN] = oprange[r];
641                         oprange[AANDNCC] = oprange[r];
642                         oprange[AEQV] = oprange[r];
643                         oprange[AEQVCC] = oprange[r];
644                         oprange[ANAND] = oprange[r];
645                         oprange[ANANDCC] = oprange[r];
646                         oprange[ANOR] = oprange[r];
647                         oprange[ANORCC] = oprange[r];
648                         oprange[AORCC] = oprange[r];
649                         oprange[AORN] = oprange[r];
650                         oprange[AORNCC] = oprange[r];
651                         oprange[AXORCC] = oprange[r];
652                         break;
653                 case AADDME:    /* op Ra, Rd */
654                         oprange[AADDMECC] = oprange[r];
655                         oprange[AADDMEV] = oprange[r];
656                         oprange[AADDMEVCC] = oprange[r];
657                         oprange[AADDZE] = oprange[r];
658                         oprange[AADDZECC] = oprange[r];
659                         oprange[AADDZEV] = oprange[r];
660                         oprange[AADDZEVCC] = oprange[r];
661                         oprange[ASUBME] = oprange[r];
662                         oprange[ASUBMECC] = oprange[r];
663                         oprange[ASUBMEV] = oprange[r];
664                         oprange[ASUBMEVCC] = oprange[r];
665                         oprange[ASUBZE] = oprange[r];
666                         oprange[ASUBZECC] = oprange[r];
667                         oprange[ASUBZEV] = oprange[r];
668                         oprange[ASUBZEVCC] = oprange[r];
669                         break;
670                 case AADDC:
671                         oprange[AADDCCC] = oprange[r];
672                         break;
673                 case ABEQ:
674                         oprange[ABGE] = oprange[r];
675                         oprange[ABGT] = oprange[r];
676                         oprange[ABLE] = oprange[r];
677                         oprange[ABLT] = oprange[r];
678                         oprange[ABNE] = oprange[r];
679                         oprange[ABVC] = oprange[r];
680                         oprange[ABVS] = oprange[r];
681                         break;
682                 case ABR:
683                         oprange[ABL] = oprange[r];
684                         break;
685                 case ABC:
686                         oprange[ABCL] = oprange[r];
687                         break;
688                 case AEXTSB:    /* op Rs, Ra */
689                         oprange[AEXTSBCC] = oprange[r];
690                         oprange[AEXTSH] = oprange[r];
691                         oprange[AEXTSHCC] = oprange[r];
692                         oprange[ACNTLZW] = oprange[r];
693                         oprange[ACNTLZWCC] = oprange[r];
694                         break;
695                 case AFABS:     /* fop [s,]d */
696                         oprange[AFABSCC] = oprange[r];
697                         oprange[AFNABS] = oprange[r];
698                         oprange[AFNABSCC] = oprange[r];
699                         oprange[AFNEG] = oprange[r];
700                         oprange[AFNEGCC] = oprange[r];
701                         oprange[AFRSP] = oprange[r];
702                         oprange[AFRSPCC] = oprange[r];
703                         oprange[AFCTIW] = oprange[r];
704                         oprange[AFCTIWCC] = oprange[r];
705                         oprange[AFCTIWZ] = oprange[r];
706                         oprange[AFCTIWZCC] = oprange[r];
707                         oprange[AFRES] = oprange[r];
708                         oprange[AFRESCC] = oprange[r];
709                         oprange[AFRSQRTE] = oprange[r];
710                         oprange[AFRSQRTECC] = oprange[r];
711                         oprange[AFSQRT] = oprange[r];
712                         oprange[AFSQRTCC] = oprange[r];
713                         oprange[AFSQRTS] = oprange[r];
714                         oprange[AFSQRTSCC] = oprange[r];
715                         oprange[AFPRE] = oprange[r];
716                         oprange[AFPRSQRTE] = oprange[r];
717                         oprange[AFPABS] = oprange[r];
718                         oprange[AFPNEG] = oprange[r];
719                         oprange[AFPRSP] = oprange[r];
720                         oprange[AFPNABS] = oprange[r];
721                         oprange[AFSABS] = oprange[r];
722                         oprange[AFSNEG] = oprange[r];
723                         oprange[AFSNABS] = oprange[r];
724                         oprange[AFPCTIW] = oprange[r];
725                         oprange[AFPCTIWZ] = oprange[r];
726                         break;
727                 case AFADD:
728                         oprange[AFADDS] = oprange[r];
729                         oprange[AFADDCC] = oprange[r];
730                         oprange[AFADDSCC] = oprange[r];
731                         oprange[AFDIV] = oprange[r];
732                         oprange[AFDIVS] = oprange[r];
733                         oprange[AFDIVCC] = oprange[r];
734                         oprange[AFDIVSCC] = oprange[r];
735                         oprange[AFSUB] = oprange[r];
736                         oprange[AFSUBS] = oprange[r];
737                         oprange[AFSUBCC] = oprange[r];
738                         oprange[AFSUBSCC] = oprange[r];
739                         oprange[AFPADD] = oprange[r];
740                         oprange[AFPSUB] = oprange[r];
741                         break;
742                 case AFMADD:
743                         oprange[AFMADDCC] = oprange[r];
744                         oprange[AFMADDS] = oprange[r];
745                         oprange[AFMADDSCC] = oprange[r];
746                         oprange[AFMSUB] = oprange[r];
747                         oprange[AFMSUBCC] = oprange[r];
748                         oprange[AFMSUBS] = oprange[r];
749                         oprange[AFMSUBSCC] = oprange[r];
750                         oprange[AFNMADD] = oprange[r];
751                         oprange[AFNMADDCC] = oprange[r];
752                         oprange[AFNMADDS] = oprange[r];
753                         oprange[AFNMADDSCC] = oprange[r];
754                         oprange[AFNMSUB] = oprange[r];
755                         oprange[AFNMSUBCC] = oprange[r];
756                         oprange[AFNMSUBS] = oprange[r];
757                         oprange[AFNMSUBSCC] = oprange[r];
758                         oprange[AFSEL] = oprange[r];
759                         oprange[AFSELCC] = oprange[r];
760                         oprange[AFPSEL] = oprange[r];
761                         oprange[AFPMADD] = oprange[r];
762                         oprange[AFXMADD] = oprange[r];
763                         oprange[AFXCPMADD] = oprange[r];
764                         oprange[AFXCSMADD] = oprange[r];
765                         oprange[AFPNMADD] = oprange[r];
766                         oprange[AFXNMADD] = oprange[r];
767                         oprange[AFXCPNMADD] = oprange[r];
768                         oprange[AFXCSNMADD] = oprange[r];
769                         oprange[AFPMSUB] = oprange[r];
770                         oprange[AFXMSUB] = oprange[r];
771                         oprange[AFXCPMSUB] = oprange[r];
772                         oprange[AFXCSMSUB] = oprange[r];
773                         oprange[AFPNMSUB] = oprange[r];
774                         oprange[AFXNMSUB] = oprange[r];
775                         oprange[AFXCPNMSUB] = oprange[r];
776                         oprange[AFXCSNMSUB] = oprange[r];
777                         oprange[AFXCPNPMA] = oprange[r];
778                         oprange[AFXCSNPMA] = oprange[r];
779                         oprange[AFXCPNSMA] = oprange[r];
780                         oprange[AFXCSNSMA] = oprange[r];
781                         oprange[AFXCXNPMA] = oprange[r];
782                         oprange[AFXCXNSMA] = oprange[r];
783                         oprange[AFXCXMA] = oprange[r];
784                         oprange[AFXCXNMS] = oprange[r];
785                         break;
786                 case AFMUL:
787                         oprange[AFMULS] = oprange[r];
788                         oprange[AFMULCC] = oprange[r];
789                         oprange[AFMULSCC] = oprange[r];
790                         oprange[AFPMUL] = oprange[r];
791                         oprange[AFXMUL] = oprange[r];
792                         oprange[AFXPMUL] = oprange[r];
793                         oprange[AFXSMUL] = oprange[r];
794                         break;
795                 case AFCMPO:
796                         oprange[AFCMPU] = oprange[r];
797                         break;
798                 case AMTFSB0:
799                         oprange[AMTFSB0CC] = oprange[r];
800                         oprange[AMTFSB1] = oprange[r];
801                         oprange[AMTFSB1CC] = oprange[r];
802                         break;
803                 case ANEG:      /* op [Ra,] Rd */
804                         oprange[ANEGCC] = oprange[r];
805                         oprange[ANEGV] = oprange[r];
806                         oprange[ANEGVCC] = oprange[r];
807                         break;
808                 case AOR:       /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
809                         oprange[AXOR] = oprange[r];
810                         break;
811                 case ASLW:
812                         oprange[ASLWCC] = oprange[r];
813                         oprange[ASRW] = oprange[r];
814                         oprange[ASRWCC] = oprange[r];
815                         break;
816                 case ASRAW:     /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
817                         oprange[ASRAWCC] = oprange[r];
818                         break;
819                 case ASUB:      /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
820                         oprange[ASUB] = oprange[r];
821                         oprange[ASUBCC] = oprange[r];
822                         oprange[ASUBV] = oprange[r];
823                         oprange[ASUBVCC] = oprange[r];
824                         oprange[ASUBCCC] = oprange[r];
825                         oprange[ASUBCV] = oprange[r];
826                         oprange[ASUBCVCC] = oprange[r];
827                         oprange[ASUBE] = oprange[r];
828                         oprange[ASUBECC] = oprange[r];
829                         oprange[ASUBEV] = oprange[r];
830                         oprange[ASUBEVCC] = oprange[r];
831                         break;
832                 case ASYNC:
833                         oprange[AISYNC] = oprange[r];
834                         break;
835                 case ARLWMI:
836                         oprange[ARLWMICC] = oprange[r];
837                         oprange[ARLWNM] = oprange[r];
838                         oprange[ARLWNMCC] = oprange[r];
839                         break;
840                 case AFMOVD:
841                         oprange[AFMOVDCC] = oprange[r];
842                         oprange[AFMOVDU] = oprange[r];
843                         oprange[AFMOVS] = oprange[r];
844                         oprange[AFMOVSU] = oprange[r];
845                         break;
846                 case AECIWX:
847                         oprange[ALWAR] = oprange[r];
848                         break;
849                 case ASYSCALL:  /* just the op; flow of control */
850                         oprange[ARFI] = oprange[r];
851                         oprange[ARFCI] = oprange[r];
852                         break;
853                 case AMOVHBR:
854                         oprange[AMOVWBR] = oprange[r];
855                         break;
856                 case AFSMOVS:   /* indexed floating loads and stores (fp2) */
857                         oprange[AFSMOVSU] = oprange[r];
858                         oprange[AFSMOVDU] = oprange[r];
859                         oprange[AFXMOVS] = oprange[r];
860                         oprange[AFXMOVSU] = oprange[r];
861                         oprange[AFXMOVDU] = oprange[r];
862                         oprange[AFPMOVS] = oprange[r];
863                         oprange[AFPMOVSU] = oprange[r];
864                         oprange[AFPMOVDU] = oprange[r];
865                         oprange[AFPMOVIW] = oprange[r];
866                         break;
867                 case AFPMOVD:   /* indexed load/store and moves (fp2) */
868                         oprange[AFSMOVD] = oprange[r];
869                         oprange[AFXMOVD] = oprange[r];
870                         break;
871                 case AFMOVSPD:  /* move between fp reg sets (fp2) */
872                         oprange[AFMOVPSD] = oprange[r];
873                         break;
874                 case AADD:
875                 case AANDCC:    /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
876                 case ACMP:
877                 case ACMPU:
878                 case AEIEIO:
879                 case ALSW:
880                 case AMOVB:     /* macro: move byte with sign extension */
881                 case AMOVBU:    /* macro: move byte with sign extension & update */
882                 case AMOVW:
883                 case AMOVFL:
884                 case AMULLW:    /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
885                 case ASUBC:     /* op r1,$s,r3; op r1[,r2],r3 */
886                 case ASTSW:
887                 case ATLBIE:
888                 case ATW:
889                 case AWORD:
890                 case ANOP:
891                 case ATEXT:
892                         break;
893                 }
894         }
895 }
896
897 enum{
898         ABSD = 0,
899         ABSU = 1,
900         RELD = 2,
901         RELU = 3,
902 };
903
904 int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
905
906 typedef struct Reloc Reloc;
907
908 struct Reloc
909 {
910         int n;
911         int t;
912         uchar *m;
913         ulong *a;
914 };
915
916 Reloc rels;
917
918 static void
919 grow(Reloc *r)
920 {
921         int t;
922         uchar *m, *nm;
923         ulong *a, *na;
924
925         t = r->t;
926         r->t += 64;
927         m = r->m;
928         a = r->a;
929         r->m = nm = malloc(r->t*sizeof(uchar));
930         r->a = na = malloc(r->t*sizeof(ulong));
931         memmove(nm, m, t*sizeof(uchar));
932         memmove(na, a, t*sizeof(ulong));
933         free(m);
934         free(a);
935 }
936
937 void
938 dynreloc(Sym *s, long v, int abs, int split, int sext)
939 {
940         int i, k, n;
941         uchar *m;
942         ulong *a;
943         Reloc *r;
944
945         if(v&3)
946                 diag("bad relocation address");
947         v >>= 2;
948         if(s->type == SUNDEF)
949                 k = abs ? ABSU : RELU;
950         else
951                 k = abs ? ABSD : RELD;
952         if(split)
953                 k += 4;
954         if(sext)
955                 k += 2;
956         /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
957         k = modemap[k];
958         r = &rels;
959         n = r->n;
960         if(n >= r->t)
961                 grow(r);
962         m = r->m;
963         a = r->a;
964         for(i = n; i > 0; i--){
965                 if(v < a[i-1]){ /* happens occasionally for data */
966                         m[i] = m[i-1];
967                         a[i] = a[i-1];
968                 }
969                 else
970                         break;
971         }
972         m[i] = k;
973         a[i] = v;
974         r->n++;
975 }
976
977 static int
978 sput(char *s)
979 {
980         char *p;
981
982         p = s;
983         while(*s)
984                 cput(*s++);
985         cput(0);
986         return s-p+1;
987 }
988
989 void
990 asmdyn()
991 {
992         int i, n, t, c;
993         Sym *s;
994         ulong la, ra, *a;
995         vlong off;
996         uchar *m;
997         Reloc *r;
998
999         cflush();
1000         off = seek(cout, 0, 1);
1001         lput(0);
1002         t = 0;
1003         lput(imports);
1004         t += 4;
1005         for(i = 0; i < NHASH; i++)
1006                 for(s = hash[i]; s != S; s = s->link)
1007                         if(s->type == SUNDEF){
1008                                 lput(s->sig);
1009                                 t += 4;
1010                                 t += sput(s->name);
1011                         }
1012         
1013         la = 0;
1014         r = &rels;
1015         n = r->n;
1016         m = r->m;
1017         a = r->a;
1018         lput(n);
1019         t += 4;
1020         for(i = 0; i < n; i++){
1021                 ra = *a-la;
1022                 if(*a < la)
1023                         diag("bad relocation order");
1024                 if(ra < 256)
1025                         c = 0;
1026                 else if(ra < 65536)
1027                         c = 1;
1028                 else
1029                         c = 2;
1030                 cput((c<<6)|*m++);
1031                 t++;
1032                 if(c == 0){
1033                         cput(ra);
1034                         t++;
1035                 }
1036                 else if(c == 1){
1037                         wput(ra);
1038                         t += 2;
1039                 }
1040                 else{
1041                         lput(ra);
1042                         t += 4;
1043                 }
1044                 la = *a++;
1045         }
1046
1047         cflush();
1048         seek(cout, off, 0);
1049         lput(t);
1050
1051         if(debug['v']){
1052                 Bprint(&bso, "import table entries = %d\n", imports);
1053                 Bprint(&bso, "export table entries = %d\n", exports);
1054         }
1055 }