changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/7l/span.c

changeset 7144: d0b9ab522e8b
child: 84d616f1d180
author: cinap_lenrek@felloff.net
date: Mon, 08 Apr 2019 14:05:27 +0200
permissions: -rw-r--r--
description: 7l: add arm64 linker (initial sync)
1 #include "l.h"
2 
3 #define BIT(n) ((uvlong)1<<(n))
4 
5 static struct {
6  ulong start;
7  ulong size;
8 } pool;
9 
10 static void checkpool(Prog*, int);
11 static void flushpool(Prog*, int);
12 static int ispcdisp(long);
13 
14 static Optab *badop;
15 static Oprang oprange[ALAST];
16 
17 void
18 span(void)
19 {
20  Prog *p;
21  Sym *setext, *s;
22  Optab *o;
23  int m, bflag, i;
24  long c, otxt, v;
25 
26  if(debug['v'])
27  Bprint(&bso, "%5.2f span\n", cputime());
28  Bflush(&bso);
29 
30  bflag = 0;
31  c = INITTEXT;
32  otxt = c;
33  for(p = firstp; p != P; p = p->link) {
34  if(p->as == ADWORD && (c&7) != 0)
35  c += 4;
36  p->pc = c;
37  o = oplook(p);
38  m = o->size;
39  if(m == 0) {
40  if(p->as == ATEXT) {
41  curtext = p;
42  autosize = p->to.offset + PCSZ;
43  if(p->from.sym != S)
44  p->from.sym->value = c;
45  /* need passes to resolve branches */
46  if(c-otxt >= 1L<<20)
47  bflag = 1;
48  otxt = c;
49  continue;
50  }
51  diag("zero-width instruction\n%P", p);
52  continue;
53  }
54  switch(o->flag & (LFROM|LTO)) {
55  case LFROM:
56  addpool(p, &p->from);
57  break;
58  case LTO:
59  addpool(p, &p->to);
60  break;
61  }
62  if(p->as == AB || p->as == ARET || p->as == AERET || p->as == ARETURN) /* TO DO: other unconditional operations */
63  checkpool(p, 0);
64  c += m;
65  if(blitrl)
66  checkpool(p, 1);
67  }
68 
69  /*
70  * if any procedure is large enough to
71  * generate a large SBRA branch, then
72  * generate extra passes putting branches
73  * around jmps to fix. this is rare.
74  */
75  while(bflag) {
76  if(debug['v'])
77  Bprint(&bso, "%5.2f span1\n", cputime());
78  bflag = 0;
79  c = INITTEXT;
80  for(p = firstp; p != P; p = p->link) {
81  if(p->as == ADWORD && (c&7) != 0)
82  c += 4;
83  p->pc = c;
84  o = oplook(p);
85 /* very large branches
86  if(o->type == 6 && p->cond) {
87  otxt = p->cond->pc - c;
88  if(otxt < 0)
89  otxt = -otxt;
90  if(otxt >= (1L<<17) - 10) {
91  q = prg();
92  q->link = p->link;
93  p->link = q;
94  q->as = AB;
95  q->to.type = D_BRANCH;
96  q->cond = p->cond;
97  p->cond = q;
98  q = prg();
99  q->link = p->link;
100  p->link = q;
101  q->as = AB;
102  q->to.type = D_BRANCH;
103  q->cond = q->link->link;
104  bflag = 1;
105  }
106  }
107  */
108  m = o->size;
109  if(m == 0) {
110  if(p->as == ATEXT) {
111  curtext = p;
112  autosize = p->to.offset + PCSZ;
113  if(p->from.sym != S)
114  p->from.sym->value = c;
115  continue;
116  }
117  diag("zero-width instruction\n%P", p);
118  continue;
119  }
120  c += m;
121  }
122  }
123 
124  if(debug['t']) {
125  /*
126  * add strings to text segment
127  */
128  c = rnd(c, 8);
129  for(i=0; i<NHASH; i++)
130  for(s = hash[i]; s != S; s = s->link) {
131  if(s->type != SSTRING)
132  continue;
133  v = s->value;
134  while(v & 3)
135  v++;
136  s->value = c;
137  c += v;
138  }
139  }
140 
141  c = rnd(c, 8);
142 
143  setext = lookup("etext", 0);
144  if(setext != S) {
145  setext->value = c;
146  textsize = c - INITTEXT;
147  }
148  if(INITRND)
149  INITDAT = rnd(c, INITRND);
150  if(debug['v'])
151  Bprint(&bso, "tsize = %#llux\n", textsize);
152  Bflush(&bso);
153 }
154 
155 /*
156  * when the first reference to the literal pool threatens
157  * to go out of range of a 1Mb PC-relative offset
158  * drop the pool now, and branch round it.
159  */
160 static void
161 checkpool(Prog *p, int skip)
162 {
163  if(pool.size >= 0xffff0 || !ispcdisp(p->pc+4+pool.size - pool.start+8))
164  flushpool(p, skip);
165  else if(p->link == P)
166  flushpool(p, 2);
167 }
168 
169 static void
170 flushpool(Prog *p, int skip)
171 {
172  Prog *q;
173 
174  if(blitrl) {
175  if(skip){
176  if(debug['v'] && skip == 1)
177  print("note: flush literal pool at %#llux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start);
178  q = prg();
179  q->as = AB;
180  q->to.type = D_BRANCH;
181  q->cond = p->link;
182  q->link = blitrl;
183  blitrl = q;
184  }
185  else if(p->pc+pool.size-pool.start < 1024*1024)
186  return;
187  elitrl->link = p->link;
188  p->link = blitrl;
189  blitrl = 0; /* BUG: should refer back to values until out-of-range */
190  elitrl = 0;
191  pool.size = 0;
192  pool.start = 0;
193  }
194 }
195 
196 /*
197  * TO DO: hash
198  */
199 void
200 addpool(Prog *p, Adr *a)
201 {
202  Prog *q, t;
203  int c, sz;
204 
205  c = aclass(a);
206 
207  t = zprg;
208  t.as = AWORD;
209  sz = 4;
210  if(p->as == AMOV) {
211  t.as = ADWORD;
212  sz = 8;
213  }
214 
215  switch(c) {
216  default:
217  t.to = *a;
218  break;
219 
220  case C_PSAUTO:
221  case C_PPAUTO:
222  case C_UAUTO4K:
223  case C_UAUTO8K:
224  case C_UAUTO16K:
225  case C_UAUTO32K:
226  case C_UAUTO64K:
227  case C_NSAUTO:
228  case C_NPAUTO:
229  case C_LAUTO:
230  case C_PPOREG:
231  case C_PSOREG:
232  case C_UOREG4K:
233  case C_UOREG8K:
234  case C_UOREG16K:
235  case C_UOREG32K:
236  case C_UOREG64K:
237  case C_NSOREG:
238  case C_NPOREG:
239  case C_LOREG:
240  t.to.type = D_CONST;
241  t.to.offset = instoffset;
242  sz = 4;
243  break;
244  }
245 
246  for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */
247  if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
248  p->cond = q;
249  return;
250  }
251 
252  q = prg();
253  *q = t;
254  q->pc = pool.size;
255 
256  if(blitrl == P) {
257  blitrl = q;
258  pool.start = p->pc;
259  } else
260  elitrl->link = q;
261  elitrl = q;
262  pool.size = rnd(pool.size, sz);
263  pool.size += sz;
264 
265  p->cond = q;
266 }
267 
268 int
269 relinv(int a)
270 {
271  switch(a) {
272  case ABEQ: return ABNE;
273  case ABNE: return ABEQ;
274  case ABCS: return ABCC;
275  case ABHS: return ABLO;
276  case ABCC: return ABCS;
277  case ABLO: return ABHS;
278  case ABMI: return ABPL;
279  case ABPL: return ABMI;
280  case ABVS: return ABVC;
281  case ABVC: return ABVS;
282  case ABHI: return ABLS;
283  case ABLS: return ABHI;
284  case ABGE: return ABLT;
285  case ABLT: return ABGE;
286  case ABGT: return ABLE;
287  case ABLE: return ABGT;
288  }
289  diag("unknown relation: %A", a);
290  return a;
291 }
292 
293 void
294 xdefine(char *p, int t, long v)
295 {
296  Sym *s;
297 
298  s = lookup(p, 0);
299  if(s->type == 0 || s->type == SXREF) {
300  s->type = t;
301  s->value = v;
302  }
303 }
304 
305 long
306 regoff(Adr *a)
307 {
308 
309  instoffset = 0;
310  aclass(a);
311  return instoffset;
312 }
313 
314 static int
315 ispcdisp(long v)
316 {
317  /* pc-relative addressing will reach? */
318  return v >= -0xfffff && v <= 0xfffff && (v&3) == 0;
319 }
320 
321 static int
322 isaddcon(vlong v)
323 {
324  /* uimm12 or uimm24? */
325  if(v < 0)
326  return 0;
327  if((v & 0xFFF) == 0)
328  v >>= 12;
329  return v <= 0xFFF;
330 }
331 
332 static int
333 isbitcon(uvlong v)
334 {
335  /* fancy bimm32 or bimm64? */
336  return findmask(v) != nil || (v>>32) == 0 && findmask(v | (v<<32)) != nil;
337 }
338 
339 static int
340 maxstr1(uvlong x)
341 {
342  int i;
343 
344  for(i = 0; x != 0; i++)
345  x &= x<<1;
346  return i;
347 }
348 
349 static uvlong
350 findrotl(uvlong x, int *l)
351 {
352  int i;
353 
354  for(i = 0; (x&1) == 0 || (x&BIT(63)) != 0; i++)
355  x = (x<<1) | ((x&BIT(63))!=0);
356  *l = i;
357  return x;
358 }
359 
360 static int
361 findmask64(Mask *m, uvlong v)
362 {
363  uvlong x, f, fm;
364  int i, lr, l0, l1, e;
365 
366  if(v == 0 || v == ~(uvlong)0)
367  return 0;
368  x = findrotl(v, &lr);
369  l1 = maxstr1(x);
370  l0 = maxstr1(~x);
371  e = l0+l1;
372  if(e == 0 || l1 == 64 || l0 == 64 || 64%e != 0)
373  return 0;
374  if(e != 64){
375  f = BIT(l1)-1;
376  fm = BIT(e)-1;
377  if(e > 32 && x != f)
378  return 0;
379  for(i = 0; i < 64; i += e)
380  if(((x>>i) & fm) != f)
381  return 0;
382  }
383  print("%#llux %#llux 1:%d 0:%d r:%d\n", v, x, l1, l0, lr%e);
384  m->v = v;
385  m->s = l1;
386  m->e = e;
387  m->r = lr%e;
388  return 1;
389 }
390 
391 /*
392  * internal class codes for different constant classes:
393  * they partition the constant/offset range into disjoint ranges that
394  * are somehow treated specially by one or more load/store instructions.
395  */
396 static int autoclass[] = {C_PSAUTO, C_NSAUTO, C_NPAUTO, C_PSAUTO, C_PPAUTO, C_UAUTO4K, C_UAUTO8K, C_UAUTO16K, C_UAUTO32K, C_UAUTO64K, C_LAUTO};
397 static int oregclass[] = {C_ZOREG, C_NSOREG, C_NPOREG, C_PSOREG, C_PPOREG, C_UOREG4K, C_UOREG8K, C_UOREG16K, C_UOREG32K, C_UOREG64K, C_LOREG};
398 static int sextclass[] = {C_SEXT1, C_LEXT, C_LEXT, C_SEXT1, C_SEXT1, C_SEXT1, C_SEXT2, C_SEXT4, C_SEXT8, C_SEXT16, C_LEXT};
399 
400 /*
401  * return appropriate index into tables above
402  */
403 static int
404 constclass(vlong l)
405 {
406  if(l == 0)
407  return 0;
408  if(l < 0){
409  if(l >= -256)
410  return 1;
411  if(l >= -512 && (l&7) == 0)
412  return 2;
413  return 10;
414  }
415  if(l <= 255)
416  return 3;
417  if(l <= 504 && (l&7) == 0)
418  return 4;
419  if(l <= 4095)
420  return 5;
421  if(l <= 8190 && (l&1) == 0)
422  return 6;
423  if(l <= 16380 && (l&3) == 0)
424  return 7;
425  if(l <= 32760 && (l&7) == 0)
426  return 8;
427  if(l <= 65520 && (l&0xF) == 0)
428  return 9;
429  return 10;
430 }
431 
432 /*
433  * given an offset v and a class c (see above)
434  * return the offset value to use in the instruction,
435  * scaled if necessary
436  */
437 vlong
438 offsetshift(vlong v, int c)
439 {
440  vlong vs;
441  int s;
442  static int shifts[] = {0, 1, 2, 3, 4};
443 
444  s = 0;
445  if(c >= C_SEXT1 && c <= C_SEXT16)
446  s = shifts[c-C_SEXT1];
447  else if(c >= C_UAUTO4K && c <= C_UAUTO64K)
448  s = shifts[c-C_UAUTO4K];
449  else if(c >= C_UOREG4K && c <= C_UOREG64K)
450  s = shifts[c-C_UOREG4K];
451  vs = v>>s;
452  if(vs<<s != v)
453  diag("odd offset: %lld\n%P", v, curp);
454  return vs;
455 }
456 
457 /*
458  * if v contains a single 16-bit value aligned
459  * on a 16-bit field, and thus suitable for movk/movn,
460  * return the field index 0 to 3; otherwise return -1
461  */
462 int
463 movcon(vlong v)
464 {
465  int s;
466 
467  for(s = 0; s < 64; s += 16)
468  if((v & ~((uvlong)0xFFFF<<s)) == 0)
469  return s/16;
470  return -1;
471 }
472 
473 int
474 aclass(Adr *a)
475 {
476  vlong v;
477  Sym *s;
478  int t;
479 
480  instoffset = 0;
481  switch(a->type) {
482  case D_NONE:
483  return C_NONE;
484 
485  case D_REG:
486  return C_REG;
487 
488  case D_VREG:
489  return C_VREG;
490 
491  case D_SP:
492  return C_RSP;
493 
494  case D_COND:
495  return C_COND;
496 
497  case D_SHIFT:
498  return C_SHIFT;
499 
500  case D_EXTREG:
501  return C_EXTREG;
502 
503  case D_ROFF:
504  return C_ROFF;
505 
506  case D_XPOST:
507  return C_XPOST;
508 
509  case D_XPRE:
510  return C_XPRE;
511 
512  case D_FREG:
513  return C_FREG;
514 
515  case D_OREG:
516  switch(a->name) {
517  case D_EXTERN:
518  case D_STATIC:
519  if(a->sym == 0 || a->sym->name == 0) {
520  print("null sym external\n");
521  print("%D\n", a);
522  return C_GOK;
523  }
524  s = a->sym;
525  t = s->type;
526  if(t == 0 || t == SXREF) {
527  diag("undefined external: %s in %s",
528  s->name, TNAME);
529  s->type = SDATA;
530  }
531  if(dlm) {
532  switch(t) {
533  default:
534  instoffset = s->value + a->offset + INITDAT;
535  break;
536  case SUNDEF:
537  case STEXT:
538  case SCONST:
539  case SLEAF:
540  case SSTRING:
541  instoffset = s->value + a->offset;
542  break;
543  }
544  return C_ADDR;
545  }
546  instoffset = s->value + a->offset;
547  if(instoffset >= 0)
548  return sextclass[constclass(instoffset)];
549  return C_LEXT;
550 
551  case D_AUTO:
552  instoffset = autosize + a->offset;
553  return autoclass[constclass(instoffset)];
554 
555  case D_PARAM:
556  instoffset = autosize + a->offset + PCSZ;
557  return autoclass[constclass(instoffset)];
558 
559  case D_NONE:
560  instoffset = a->offset;
561  return oregclass[constclass(instoffset)];
562  }
563  return C_GOK;
564 
565  case D_SPR:
566  return C_SPR;
567 
568  case D_OCONST:
569  switch(a->name) {
570  case D_EXTERN:
571  case D_STATIC:
572  s = a->sym;
573  t = s->type;
574  if(t == 0 || t == SXREF) {
575  diag("undefined external: %s in %s",
576  s->name, TNAME);
577  s->type = SDATA;
578  }
579  instoffset = s->value + a->offset + INITDAT;
580  if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF)
581  instoffset = s->value + a->offset;
582  return C_LCON;
583  }
584  return C_GOK;
585 
586  case D_FCONST:
587  return C_FCON;
588 
589  case D_CONST:
590  switch(a->name) {
591 
592  case D_NONE:
593  instoffset = a->offset;
594  if(a->reg != NREG && a->reg != REGZERO)
595  goto aconsize;
596 
597  v = instoffset;
598  if(v == 0)
599  return C_ZCON;
600  if(isaddcon(v)){
601  if(isbitcon(v))
602  return C_ABCON;
603  if(v <= 0xFFF)
604  return C_ADDCON0;
605  return C_ADDCON;
606  }
607  t = movcon(v);
608  if(t >= 0){
609  if(isbitcon(v))
610  return C_MBCON;
611  return C_MOVCON;
612  }
613  t = movcon(~v);
614  if(t >= 0){
615  if(isbitcon(v))
616  return C_MBCON;
617  return C_MOVCON;
618  }
619  if(isbitcon(v))
620  return C_BITCON;
621  return C_LCON;
622 
623  case D_EXTERN:
624  case D_STATIC:
625  s = a->sym;
626  if(s == S)
627  break;
628  t = s->type;
629  switch(t) {
630  case 0:
631  case SXREF:
632  diag("undefined external: %s in %s",
633  s->name, TNAME);
634  s->type = SDATA;
635  break;
636  case SUNDEF:
637  case STEXT:
638  case SSTRING:
639  case SCONST:
640  case SLEAF:
641  instoffset = s->value + a->offset;
642  return C_LCON;
643  }
644  if(!dlm) {
645  instoffset = s->value + a->offset;
646  if(instoffset != 0 && isaddcon(instoffset))
647  return C_AECON;
648  }
649  instoffset = s->value + a->offset + INITDAT;
650  return C_LCON;
651 
652  case D_AUTO:
653  instoffset = autosize + a->offset;
654  goto aconsize;
655 
656  case D_PARAM:
657  instoffset = autosize + a->offset + PCSZ;
658  aconsize:
659  if(isaddcon(instoffset))
660  return C_AACON;
661  return C_LACON;
662  }
663  return C_GOK;
664 
665  case D_BRANCH:
666  return C_SBRA;
667  }
668  return C_GOK;
669 }
670 
671 Optab*
672 oplook(Prog *p)
673 {
674  int a1, a2, a3, r;
675  char *c1, *c2, *c3;
676  Optab *o, *e;
677 
678  a1 = p->optab;
679  if(a1)
680  return optab+(a1-1);
681  a1 = p->from.class;
682  if(a1 == 0) {
683  a1 = aclass(&p->from) + 1;
684  p->from.class = a1;
685  }
686  a1--;
687  a3 = p->to.class;
688  if(a3 == 0) {
689  a3 = aclass(&p->to) + 1;
690  p->to.class = a3;
691  }
692  a3--;
693  a2 = C_NONE;
694  if(p->reg != NREG)
695  a2 = C_REG;
696  r = p->as;
697  o = oprange[r].start;
698  if(o == 0) {
699  a1 = opcross[repop[r]][a1][a2][a3];
700  if(a1) {
701  p->optab = a1+1;
702  return optab+a1;
703  }
704  o = oprange[r].stop; /* just generate an error */
705  }
706  if(0) {
707  print("oplook %A %d %d %d\n",
708  (int)p->as, a1, a2, a3);
709  print(" %d %d\n", p->from.type, p->to.type);
710  }
711  e = oprange[r].stop;
712  c1 = xcmp[a1];
713  c2 = xcmp[a2];
714  c3 = xcmp[a3];
715  for(; o<e; o++)
716  if(o->a2 == a2 || c2[o->a2])
717  if(c1[o->a1])
718  if(c3[o->a3]) {
719  p->optab = (o-optab)+1;
720  return o;
721  }
722  diag("illegal combination %A %R %R %R",
723  p->as, a1, a2, a3);
724  prasm(p);
725  o = badop;
726  if(o == 0)
727  errorexit();
728  return o;
729 }
730 
731 int
732 cmp(int a, int b)
733 {
734 
735  if(a == b)
736  return 1;
737  switch(a) {
738  case C_RSP:
739  if(b == C_REG)
740  return 1;
741  break;
742 
743  case C_REG:
744  if(b == C_ZCON)
745  return 1;
746  break;
747 
748  case C_ADDCON0:
749  if(b == C_ZCON)
750  return 1;
751  break;
752 
753  case C_ADDCON:
754  if(b == C_ZCON || b == C_ADDCON0 || b == C_ABCON)
755  return 1;
756  break;
757 
758  case C_BITCON:
759  if(b == C_ABCON || b == C_MBCON)
760  return 1;
761  break;
762 
763  case C_MOVCON:
764  if(b == C_MBCON || b == C_ZCON || b == C_ADDCON0)
765  return 1;
766  break;
767 
768  case C_LCON:
769  if(b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_MBCON || b == C_MOVCON)
770  return 1;
771  break;
772 
773  case C_VCON:
774  return cmp(C_LCON, b);
775 
776  case C_LACON:
777  if(b == C_AACON)
778  return 1;
779  break;
780 
781  case C_SEXT2:
782  if(b == C_SEXT1)
783  return 1;
784  break;
785 
786  case C_SEXT4:
787  if(b == C_SEXT1 || b == C_SEXT2)
788  return 1;
789  break;
790 
791  case C_SEXT8:
792  if(b >= C_SEXT1 && b <= C_SEXT4)
793  return 1;
794  break;
795 
796  case C_SEXT16:
797  if(b >= C_SEXT1 && b <= C_SEXT8)
798  return 1;
799  break;
800 
801  case C_LEXT:
802  if(b >= C_SEXT1 && b <= C_SEXT16)
803  return 1;
804  break;
805 
806  case C_PPAUTO:
807  if(b == C_PSAUTO)
808  return 1;
809  break;
810 
811  case C_UAUTO4K:
812  if(b == C_PSAUTO || b == C_PPAUTO)
813  return 1;
814  break;
815 
816  case C_UAUTO8K:
817  return cmp(C_UAUTO4K, b);
818 
819  case C_UAUTO16K:
820  return cmp(C_UAUTO8K, b);
821 
822  case C_UAUTO32K:
823  return cmp(C_UAUTO16K, b);
824 
825  case C_UAUTO64K:
826  return cmp(C_UAUTO32K, b);
827 
828  case C_NPAUTO:
829  return cmp(C_NSAUTO, b);
830 
831  case C_LAUTO:
832  return cmp(C_NPAUTO, b) || cmp(C_UAUTO64K, b);
833 
834  case C_PSOREG:
835  if(b == C_ZOREG)
836  return 1;
837  break;
838 
839  case C_PPOREG:
840  if(b == C_ZOREG || b == C_PSOREG)
841  return 1;
842  break;
843 
844  case C_UOREG4K:
845  if(b == C_ZOREG || b == C_PSAUTO || b == C_PSOREG || b == C_PPAUTO || b == C_PPOREG)
846  return 1;
847  break;
848 
849  case C_UOREG8K:
850  return cmp(C_UOREG4K, b);
851 
852  case C_UOREG16K:
853  return cmp(C_UOREG8K, b);
854 
855  case C_UOREG32K:
856  return cmp(C_UOREG16K, b);
857 
858  case C_UOREG64K:
859  return cmp(C_UOREG32K, b);
860 
861  case C_NPOREG:
862  return cmp(C_NSOREG, b);
863 
864  case C_LOREG:
865  return cmp(C_NPOREG, b) || cmp(C_UOREG64K, b);
866 
867  case C_LBRA:
868  if(b == C_SBRA)
869  return 1;
870  break;
871  }
872  return 0;
873 }
874 
875 static int
876 ocmp(const void *a1, const void *a2)
877 {
878  Optab *p1, *p2;
879  int n;
880 
881  p1 = (Optab*)a1;
882  p2 = (Optab*)a2;
883  n = p1->as - p2->as;
884  if(n)
885  return n;
886  n = p1->a1 - p2->a1;
887  if(n)
888  return n;
889  n = p1->a2 - p2->a2;
890  if(n)
891  return n;
892  n = p1->a3 - p2->a3;
893  if(n)
894  return n;
895  return 0;
896 }
897 
898 void
899 buildop(void)
900 {
901  int i, n, r;
902  Oprang t;
903 
904  for(i=0; i<C_GOK; i++)
905  for(n=0; n<C_GOK; n++)
906  xcmp[i][n] = cmp(n, i);
907  for(n=0; optab[n].as != AXXX; n++)
908  ;
909  badop = optab+n;
910  qsort(optab, n, sizeof(optab[0]), ocmp);
911  for(i=0; i<n; i++) {
912  r = optab[i].as;
913  oprange[r].start = optab+i;
914  while(optab[i].as == r)
915  i++;
916  oprange[r].stop = optab+i;
917  i--;
918 
919  t = oprange[r];
920  switch(r){
921  default:
922  diag("unknown op in build: %A", r);
923  errorexit();
924  case AXXX:
925  break;
926  case AADD:
927  oprange[AADDS] = t;
928  oprange[ASUB] = t;
929  oprange[ASUBS] = t;
930  oprange[AADDW] = t;
931  oprange[AADDSW] = t;
932  oprange[ASUBW] = t;
933  oprange[ASUBSW] = t;
934  break;
935  case AAND: /* logical immediate, logical shifted register */
936  oprange[AANDS] = t;
937  oprange[AANDSW] = t;
938  oprange[AANDW] = t;
939  oprange[AEOR] = t;
940  oprange[AEORW] = t;
941  oprange[AORR] = t;
942  oprange[AORRW] = t;
943  break;
944  case ABIC: /* only logical shifted register */
945  oprange[ABICS] = t;
946  oprange[ABICSW] = t;
947  oprange[ABICW] = t;
948  oprange[AEON] = t;
949  oprange[AEONW] = t;
950  oprange[AORN] = t;
951  oprange[AORNW] = t;
952  break;
953  case ANEG:
954  oprange[ANEGS] = t;
955  oprange[ANEGSW] = t;
956  oprange[ANEGW] = t;
957  break;
958  case AADC: /* rn=Rd */
959  oprange[AADCW] = t;
960  oprange[AADCS] = t;
961  oprange[AADCSW] = t;
962  oprange[ASBC] = t;
963  oprange[ASBCW] = t;
964  oprange[ASBCS] = t;
965  oprange[ASBCSW] = t;
966  break;
967  case ANGC: /* rn=REGZERO */
968  oprange[ANGCW] = t;
969  oprange[ANGCS] = t;
970  oprange[ANGCSW] = t;
971  break;
972  case ACMP:
973  oprange[ACMPW] = t;
974  oprange[ACMN] = t;
975  oprange[ACMNW] = t;
976  break;
977  case ATST:
978  oprange[ATSTW] = t;
979  break;
980  case AMVN:
981  /* register/register, and shifted */
982  oprange[AMVNW] = t;
983  break;
984  case AMOVK:
985  oprange[AMOVKW] = t;
986  oprange[AMOVN] = t;
987  oprange[AMOVNW] = t;
988  oprange[AMOVZ] = t;
989  oprange[AMOVZW] = t;
990  break;
991  case ABEQ:
992  oprange[ABNE] = t;
993  oprange[ABCS] = t;
994  oprange[ABHS] = t;
995  oprange[ABCC] = t;
996  oprange[ABLO] = t;
997  oprange[ABMI] = t;
998  oprange[ABPL] = t;
999  oprange[ABVS] = t;
1000  oprange[ABVC] = t;
1001  oprange[ABHI] = t;
1002  oprange[ABLS] = t;
1003  oprange[ABGE] = t;
1004  oprange[ABLT] = t;
1005  oprange[ABGT] = t;
1006  oprange[ABLE] = t;
1007  break;
1008  case ALSL:
1009  oprange[ALSLW] = t;
1010  oprange[ALSR] = t;
1011  oprange[ALSRW] = t;
1012  oprange[AASR] = t;
1013  oprange[AASRW] = t;
1014  oprange[AROR] = t;
1015  oprange[ARORW] = t;
1016  break;
1017  case ACLS:
1018  oprange[ACLSW] = t;
1019  oprange[ACLZ] = t;
1020  oprange[ACLZW] = t;
1021  oprange[ARBIT] = t;
1022  oprange[ARBITW] = t;
1023  oprange[AREV] = t;
1024  oprange[AREVW] = t;
1025  oprange[AREV16] = t;
1026  oprange[AREV16W] = t;
1027  oprange[AREV32] = t;
1028  break;
1029  case ASDIV:
1030  oprange[ASDIVW] = t;
1031  oprange[AUDIV] = t;
1032  oprange[AUDIVW] = t;
1033  oprange[ACRC32B] = t;
1034  oprange[ACRC32CB] = t;
1035  oprange[ACRC32CH] = t;
1036  oprange[ACRC32CW] = t;
1037  oprange[ACRC32CX] = t;
1038  oprange[ACRC32H] = t;
1039  oprange[ACRC32W] = t;
1040  oprange[ACRC32X] = t;
1041  break;
1042  case AMADD:
1043  oprange[AMADDW] = t;
1044  oprange[AMSUB] = t;
1045  oprange[AMSUBW] = t;
1046  oprange[ASMADDL] = t;
1047  oprange[ASMSUBL] = t;
1048  oprange[AUMADDL] = t;
1049  oprange[AUMSUBL] = t;
1050  break;
1051  case AREM:
1052  oprange[AREMW] = t;
1053  oprange[AUREM] = t;
1054  oprange[AUREMW] = t;
1055  break;
1056  case AMUL:
1057  oprange[AMULW] = t;
1058  oprange[AMNEG] = t;
1059  oprange[AMNEGW] = t;
1060  oprange[ASMNEGL] = t;
1061  oprange[ASMULL] = t;
1062  oprange[ASMULH] = t;
1063  oprange[AUMNEGL] = t;
1064  oprange[AUMULH] = t;
1065  oprange[AUMULL] = t;
1066  break;
1067  case AMOVH:
1068  oprange[AMOVHU] = t;
1069  break;
1070  case AMOVW:
1071  oprange[AMOVWU] = t;
1072  break;
1073  case ABFM:
1074  oprange[ABFMW] = t;
1075  oprange[ASBFM] = t;
1076  oprange[ASBFMW] = t;
1077  oprange[AUBFM] = t;
1078  oprange[AUBFMW] = t;
1079  break;
1080  case ABFI:
1081  oprange[ABFIW] = t;
1082  oprange[ABFXIL] = t;
1083  oprange[ABFXILW] = t;
1084  oprange[ASBFIZ] = t;
1085  oprange[ASBFIZW] = t;
1086  oprange[ASBFX] = t;
1087  oprange[ASBFXW] = t;
1088  oprange[AUBFIZ] = t;
1089  oprange[AUBFIZW] = t;
1090  oprange[AUBFX] = t;
1091  oprange[AUBFXW] = t;
1092  break;
1093  case AEXTR:
1094  oprange[AEXTRW] = t;
1095  break;
1096  case ASXTB:
1097  oprange[ASXTBW] = t;
1098  oprange[ASXTH] = t;
1099  oprange[ASXTHW] = t;
1100  oprange[ASXTW] = t;
1101  oprange[AUXTB] = t;
1102  oprange[AUXTH] = t;
1103  oprange[AUXTW] = t;
1104  oprange[AUXTBW] = t;
1105  oprange[AUXTHW] = t;
1106  break;
1107  case ACCMN:
1108  oprange[ACCMNW] = t;
1109  oprange[ACCMP] = t;
1110  oprange[ACCMPW] = t;
1111  break;
1112  case ACSEL:
1113  oprange[ACSELW] = t;
1114  oprange[ACSINC] = t;
1115  oprange[ACSINCW] = t;
1116  oprange[ACSINV] = t;
1117  oprange[ACSINVW] = t;
1118  oprange[ACSNEG] = t;
1119  oprange[ACSNEGW] = t;
1120  // aliases Rm=Rn, !cond
1121  oprange[ACINC] = t;
1122  oprange[ACINCW] = t;
1123  oprange[ACINV] = t;
1124  oprange[ACINVW] = t;
1125  oprange[ACNEG] = t;
1126  oprange[ACNEGW] = t;
1127  break;
1128  case ACSET:
1129  // aliases, Rm=Rn=REGZERO, !cond
1130  oprange[ACSETW] = t;
1131  oprange[ACSETM] = t;
1132  oprange[ACSETMW] = t;
1133  break;
1134  case AMOV:
1135  case AMOVB:
1136  case AMOVBU:
1137  case AB:
1138  case ABL:
1139  case AWORD:
1140  case ADWORD:
1141  case ARET:
1142  case ATEXT:
1143  case ACASE:
1144  case ABCASE:
1145  break;
1146  case AERET:
1147  oprange[ANOP] = t;
1148  oprange[AWFE] = t;
1149  oprange[AWFI] = t;
1150  oprange[AYIELD] = t;
1151  oprange[ASEV] = t;
1152  oprange[ASEVL] = t;
1153  oprange[ADRPS] = t;
1154  break;
1155  case ACBZ:
1156  oprange[ACBZW] = t;
1157  oprange[ACBNZ] = t;
1158  oprange[ACBNZW] = t;
1159  break;
1160  case ATBZ:
1161  oprange[ATBNZ] = t;
1162  break;
1163  case AADR:
1164  case AADRP:
1165  break;
1166  case ACLREX:
1167  break;
1168  case ASVC:
1169  oprange[AHLT] = t;
1170  oprange[AHVC] = t;
1171  oprange[ASMC] = t;
1172  oprange[ABRK] = t;
1173  oprange[ADCPS1] = t;
1174  oprange[ADCPS2] = t;
1175  oprange[ADCPS3] = t;
1176  break;
1177  case AFADDS:
1178  oprange[AFADDD] = t;
1179  oprange[AFSUBS] = t;
1180  oprange[AFSUBD] = t;
1181  oprange[AFMULS] = t;
1182  oprange[AFMULD] = t;
1183  oprange[AFNMULS] = t;
1184  oprange[AFNMULD] = t;
1185  oprange[AFDIVS] = t;
1186  oprange[AFMAXD] = t;
1187  oprange[AFMAXS] = t;
1188  oprange[AFMIND] = t;
1189  oprange[AFMINS] = t;
1190  oprange[AFMAXNMD] = t;
1191  oprange[AFMAXNMS] = t;
1192  oprange[AFMINNMD] = t;
1193  oprange[AFMINNMS] = t;
1194  oprange[AFDIVD] = t;
1195  break;
1196  case AFCVTSD:
1197  oprange[AFCVTDS] = t;
1198  oprange[AFABSD] = t;
1199  oprange[AFABSS] = t;
1200  oprange[AFNEGD] = t;
1201  oprange[AFNEGS] = t;
1202  oprange[AFSQRTD] = t;
1203  oprange[AFSQRTS] = t;
1204  oprange[AFRINTNS] = t;
1205  oprange[AFRINTND] = t;
1206  oprange[AFRINTPS] = t;
1207  oprange[AFRINTPD] = t;
1208  oprange[AFRINTMS] = t;
1209  oprange[AFRINTMD] = t;
1210  oprange[AFRINTZS] = t;
1211  oprange[AFRINTZD] = t;
1212  oprange[AFRINTAS] = t;
1213  oprange[AFRINTAD] = t;
1214  oprange[AFRINTXS] = t;
1215  oprange[AFRINTXD] = t;
1216  oprange[AFRINTIS] = t;
1217  oprange[AFRINTID] = t;
1218  oprange[AFCVTDH] = t;
1219  oprange[AFCVTHS] = t;
1220  oprange[AFCVTHD] = t;
1221  oprange[AFCVTSH] = t;
1222  break;
1223  case AFCMPS:
1224  oprange[AFCMPD] = t;
1225  oprange[AFCMPES] = t;
1226  oprange[AFCMPED] = t;
1227  break;
1228  case AFCCMPS:
1229  oprange[AFCCMPD] = t;
1230  oprange[AFCCMPES] = t;
1231  oprange[AFCCMPED] = t;
1232  break;
1233  case AFCSELD:
1234  oprange[AFCSELS] = t;
1235  break;
1236 
1237  case AFMOVS:
1238  case AFMOVD:
1239  break;
1240 
1241  case AFCVTZSD:
1242  oprange[AFCVTZSDW] = t;
1243  oprange[AFCVTZSS] = t;
1244  oprange[AFCVTZSSW] = t;
1245  oprange[AFCVTZUD] = t;
1246  oprange[AFCVTZUDW] = t;
1247  oprange[AFCVTZUS] = t;
1248  oprange[AFCVTZUSW] = t;
1249  break;
1250  case ASCVTFD:
1251  oprange[ASCVTFS] = t;
1252  oprange[ASCVTFWD] = t;
1253  oprange[ASCVTFWS] = t;
1254  oprange[AUCVTFD] = t;
1255  oprange[AUCVTFS] = t;
1256  oprange[AUCVTFWD] = t;
1257  oprange[AUCVTFWS] = t;
1258  break;
1259 
1260  case ASYS:
1261  oprange[AAT] = t;
1262  oprange[ADC] = t;
1263  oprange[AIC] = t;
1264  oprange[ATLBI] = t;
1265  break;
1266 
1267  case ASYSL:
1268  case AHINT:
1269  break;
1270 
1271  case ADMB:
1272  oprange[ADSB] = t;
1273  oprange[AISB] = t;
1274  break;
1275 
1276  case AMRS:
1277  case AMSR:
1278  break;
1279 
1280  case ALDXR:
1281  oprange[ALDXRB] = t;
1282  oprange[ALDXRH] = t;
1283  oprange[ALDXRW] = t;
1284  break;
1285  case ALDXP:
1286  oprange[ALDXPW] = t;
1287  break;
1288  case ASTXR:
1289  oprange[ASTXRB] = t;
1290  oprange[ASTXRH] = t;
1291  oprange[ASTXRW] = t;
1292  break;
1293  case ASTXP:
1294  oprange[ASTXPW] = t;
1295  break;
1296 
1297  case AAESD:
1298  oprange[AAESE] = t;
1299  oprange[AAESMC] = t;
1300  oprange[AAESIMC] = t;
1301  oprange[ASHA1H] = t;
1302  oprange[ASHA1SU1] = t;
1303  oprange[ASHA256SU0] = t;
1304  break;
1305 
1306  case ASHA1C:
1307  oprange[ASHA1P] = t;
1308  oprange[ASHA1M] = t;
1309  oprange[ASHA1SU0] = t;
1310  oprange[ASHA256H] = t;
1311  oprange[ASHA256H2] = t;
1312  oprange[ASHA256SU1] = t;
1313  break;
1314  }
1315  }
1316 }