1 #include "gc.h"
2
3 void
swit1(C1 * q,int nc,long def,Node * n)4 swit1(C1 *q, int nc, long def, Node *n)
5 {
6 Node tn;
7
8 regalloc(&tn, ®node, Z);
9 swit2(q, nc, def, n, &tn);
10 regfree(&tn);
11 }
12
13 void
swit2(C1 * q,int nc,long def,Node * n,Node * tn)14 swit2(C1 *q, int nc, long def, Node *n, Node *tn)
15 {
16 C1 *r;
17 int i;
18 Prog *sp;
19
20 if(nc < 5) {
21 for(i=0; i<nc; i++) {
22 if(debug['K'])
23 print("case = %.8llux\n", q->val);
24 gmove(nodconst(q->val), tn);
25 gopcode(OEQ, n, tn, Z);
26 patch(p, q->label);
27 q++;
28 }
29 gbranch(OGOTO);
30 patch(p, def);
31 return;
32 }
33 i = nc / 2;
34 r = q+i;
35 if(debug['K'])
36 print("case > %.8llux\n", r->val);
37 gmove(nodconst(r->val), tn);
38 gopcode(OLT, tn, n, Z);
39 sp = p;
40 gopcode(OEQ, n, tn, Z);
41 patch(p, r->label);
42 swit2(q, i, def, n, tn);
43
44 if(debug['K'])
45 print("case < %.8llux\n", r->val);
46 patch(sp, pc);
47 swit2(r+1, nc-i-1, def, n, tn);
48 }
49
50 void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)51 bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
52 {
53 int sh;
54 long v;
55 Node *l;
56
57 /*
58 * n1 gets adjusted/masked value
59 * n2 gets address of cell
60 * n3 gets contents of cell
61 */
62 l = b->left;
63 if(n2 != Z) {
64 regalloc(n1, l, nn);
65 reglcgen(n2, l, Z);
66 regalloc(n3, l, Z);
67 gopcode(OAS, n2, Z, n3);
68 gopcode(OAS, n3, Z, n1);
69 } else {
70 regalloc(n1, l, nn);
71 cgen(l, n1);
72 }
73 if(b->type->shift == 0 && typeu[b->type->etype]) {
74 v = ~0 + (1L << b->type->nbits);
75 gopcode(OAND, nodconst(v), Z, n1);
76 } else {
77 sh = 32 - b->type->shift - b->type->nbits;
78 if(sh > 0)
79 gopcode(OASHL, nodconst(sh), Z, n1);
80 sh += b->type->shift;
81 if(sh > 0)
82 if(typeu[b->type->etype])
83 gopcode(OLSHR, nodconst(sh), Z, n1);
84 else
85 gopcode(OASHR, nodconst(sh), Z, n1);
86 }
87 }
88
89 void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)90 bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
91 {
92 long v;
93 Node nod, *l;
94 int sh;
95
96 /*
97 * n1 has adjusted/masked value
98 * n2 has address of cell
99 * n3 has contents of cell
100 */
101 l = b->left;
102 regalloc(&nod, l, Z);
103 v = ~0 + (1L << b->type->nbits);
104 gopcode(OAND, nodconst(v), Z, n1);
105 gopcode(OAS, n1, Z, &nod);
106 if(nn != Z)
107 gopcode(OAS, n1, Z, nn);
108 sh = b->type->shift;
109 if(sh > 0)
110 gopcode(OASHL, nodconst(sh), Z, &nod);
111 v <<= sh;
112 gopcode(OAND, nodconst(~v), Z, n3);
113 gopcode(OOR, n3, Z, &nod);
114 gopcode(OAS, &nod, Z, n2);
115
116 regfree(&nod);
117 regfree(n1);
118 regfree(n2);
119 regfree(n3);
120 }
121
122 long
outstring(char * s,long n)123 outstring(char *s, long n)
124 {
125 long r;
126
127 r = nstring;
128 while(n) {
129 string[mnstring] = *s++;
130 mnstring++;
131 nstring++;
132 if(mnstring >= NSNAME) {
133 gpseudo(ADATA, symstring, nodconst(0L));
134 p->from.offset += nstring - NSNAME;
135 p->reg = NSNAME;
136 p->to.type = D_SCONST;
137 memmove(p->to.sval, string, NSNAME);
138 mnstring = 0;
139 }
140 n--;
141 }
142 return r;
143 }
144
145 int
mulcon(Node * n,Node * nn)146 mulcon(Node *n, Node *nn)
147 {
148 Node *l, *r, nod1, nod2;
149 Multab *m;
150 long v;
151 int o;
152 char code[sizeof(m->code)+2], *p;
153
154 if(typefd[n->type->etype])
155 return 0;
156 l = n->left;
157 r = n->right;
158 if(l->op == OCONST) {
159 l = r;
160 r = n->left;
161 }
162 if(r->op != OCONST)
163 return 0;
164 v = convvtox(r->vconst, n->type->etype);
165 if(v != r->vconst) {
166 if(debug['M'])
167 print("%L multiply conv: %lld\n", n->lineno, r->vconst);
168 return 0;
169 }
170 m = mulcon0(v);
171 if(!m) {
172 if(debug['M'])
173 print("%L multiply table: %lld\n", n->lineno, r->vconst);
174 return 0;
175 }
176 if(debug['M'] && debug['v'])
177 print("%L multiply: %ld\n", n->lineno, v);
178
179 memmove(code, m->code, sizeof(m->code));
180 code[sizeof(m->code)] = 0;
181
182 p = code;
183 if(p[1] == 'i')
184 p += 2;
185 regalloc(&nod1, n, nn);
186 cgen(l, &nod1);
187 if(v < 0)
188 gopcode(OSUB, &nod1, nodconst(0), &nod1);
189 regalloc(&nod2, n, Z);
190
191 loop:
192 switch(*p) {
193 case 0:
194 regfree(&nod2);
195 gopcode(OAS, &nod1, Z, nn);
196 regfree(&nod1);
197 return 1;
198 case '+':
199 o = OADD;
200 goto addsub;
201 case '-':
202 o = OSUB;
203 addsub: /* number is r,n,l */
204 v = p[1] - '0';
205 r = &nod1;
206 if(v&4)
207 r = &nod2;
208 n = &nod1;
209 if(v&2)
210 n = &nod2;
211 l = &nod1;
212 if(v&1)
213 l = &nod2;
214 gopcode(o, l, n, r);
215 break;
216 default: /* op is shiftcount, number is r,l */
217 v = p[1] - '0';
218 r = &nod1;
219 if(v&2)
220 r = &nod2;
221 l = &nod1;
222 if(v&1)
223 l = &nod2;
224 v = *p - 'a';
225 if(v < 0 || v >= 32) {
226 diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
227 break;
228 }
229 gopcode(OASHL, nodconst(v), l, r);
230 break;
231 }
232 p += 2;
233 goto loop;
234 }
235
236 void
gextern(Sym * s,Node * a,long o,long w)237 gextern(Sym *s, Node *a, long o, long w)
238 {
239
240 if(a->op == OCONST && typev[a->type->etype]) {
241 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
242 gpseudo(ADATA, s, nod32const(a->vconst>>32));
243 else
244 gpseudo(ADATA, s, nod32const(a->vconst));
245 p->from.offset += o;
246 p->reg = 4;
247 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
248 gpseudo(ADATA, s, nod32const(a->vconst));
249 else
250 gpseudo(ADATA, s, nod32const(a->vconst>>32));
251 p->from.offset += o + 4;
252 p->reg = 4;
253 return;
254 }
255 gpseudo(ADATA, s, a);
256 p->from.offset += o;
257 p->reg = w;
258 if(p->to.type == D_OREG)
259 p->to.type = D_CONST;
260 }
261
262 void zname(Biobuf*, Sym*, int);
263 char* zaddr(char*, Adr*, int);
264 void zwrite(Biobuf*, Prog*, int, int);
265 void outhist(Biobuf*);
266
267 void
zwrite(Biobuf * b,Prog * p,int sf,int st)268 zwrite(Biobuf *b, Prog *p, int sf, int st)
269 {
270 char bf[100], *bp;
271
272 bf[0] = p->as;
273 bf[1] = p->reg;
274 bf[2] = p->lineno;
275 bf[3] = p->lineno>>8;
276 bf[4] = p->lineno>>16;
277 bf[5] = p->lineno>>24;
278 bp = zaddr(bf+6, &p->from, sf);
279 bp = zaddr(bp, &p->to, st);
280 Bwrite(b, bf, bp-bf);
281 }
282
283 void
outcode(void)284 outcode(void)
285 {
286 struct { Sym *sym; short type; } h[NSYM];
287 Prog *p;
288 Sym *s;
289 int sf, st, t, sym;
290
291 if(debug['S']) {
292 for(p = firstp; p != P; p = p->link)
293 if(p->as != ADATA && p->as != AGLOBL)
294 pc--;
295 for(p = firstp; p != P; p = p->link) {
296 print("%P\n", p);
297 if(p->as != ADATA && p->as != AGLOBL)
298 pc++;
299 }
300 }
301 outhist(&outbuf);
302 for(sym=0; sym<NSYM; sym++) {
303 h[sym].sym = S;
304 h[sym].type = 0;
305 }
306 sym = 1;
307 for(p = firstp; p != P; p = p->link) {
308 jackpot:
309 sf = 0;
310 s = p->from.sym;
311 while(s != S) {
312 sf = s->sym;
313 if(sf < 0 || sf >= NSYM)
314 sf = 0;
315 t = p->from.name;
316 if(h[sf].type == t)
317 if(h[sf].sym == s)
318 break;
319 s->sym = sym;
320 zname(&outbuf, s, t);
321 h[sym].sym = s;
322 h[sym].type = t;
323 sf = sym;
324 sym++;
325 if(sym >= NSYM)
326 sym = 1;
327 break;
328 }
329 st = 0;
330 s = p->to.sym;
331 while(s != S) {
332 st = s->sym;
333 if(st < 0 || st >= NSYM)
334 st = 0;
335 t = p->to.name;
336 if(h[st].type == t)
337 if(h[st].sym == s)
338 break;
339 s->sym = sym;
340 zname(&outbuf, s, t);
341 h[sym].sym = s;
342 h[sym].type = t;
343 st = sym;
344 sym++;
345 if(sym >= NSYM)
346 sym = 1;
347 if(st == sf)
348 goto jackpot;
349 break;
350 }
351 zwrite(&outbuf, p, sf, st);
352 }
353 firstp = P;
354 lastp = P;
355 }
356
357 void
outhist(Biobuf * b)358 outhist(Biobuf *b)
359 {
360 Hist *h;
361 char *p, *q, *op, c;
362 Prog pg;
363 int n;
364
365 pg = zprog;
366 pg.as = AHISTORY;
367 c = pathchar();
368 for(h = hist; h != H; h = h->link) {
369 p = h->name;
370 op = 0;
371 /* on windows skip drive specifier in pathname */
372 if(systemtype(Windows) && p && p[1] == ':'){
373 p += 2;
374 c = *p;
375 }
376 if(p && p[0] != c && h->offset == 0 && pathname){
377 /* on windows skip drive specifier in pathname */
378 if(systemtype(Windows) && pathname[1] == ':') {
379 op = p;
380 p = pathname+2;
381 c = *p;
382 } else if(pathname[0] == c){
383 op = p;
384 p = pathname;
385 }
386 }
387 while(p) {
388 q = utfrune(p, c);
389 if(q) {
390 n = q-p;
391 if(n == 0){
392 n = 1; /* leading "/" */
393 *p = '/'; /* don't emit "\" on windows */
394 }
395 q++;
396 } else {
397 n = strlen(p);
398 q = 0;
399 }
400 if(n) {
401 Bputc(b, ANAME);
402 Bputc(b, D_FILE);
403 Bputc(b, 1);
404 Bputc(b, '<');
405 Bwrite(b, p, n);
406 Bputc(b, 0);
407 }
408 p = q;
409 if(p == 0 && op) {
410 p = op;
411 op = 0;
412 }
413 }
414 pg.lineno = h->line;
415 pg.to.type = zprog.to.type;
416 pg.to.offset = h->offset;
417 if(h->offset)
418 pg.to.type = D_CONST;
419
420 zwrite(b, &pg, 0, 0);
421 }
422 }
423
424 void
zname(Biobuf * b,Sym * s,int t)425 zname(Biobuf *b, Sym *s, int t)
426 {
427 char *n, bf[7];
428 ulong sig;
429
430 n = s->name;
431 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
432 sig = sign(s);
433 bf[0] = ASIGNAME;
434 bf[1] = sig;
435 bf[2] = sig>>8;
436 bf[3] = sig>>16;
437 bf[4] = sig>>24;
438 bf[5] = t;
439 bf[6] = s->sym;
440 Bwrite(b, bf, 7);
441 s->sig = SIGDONE;
442 }
443 else{
444 bf[0] = ANAME;
445 bf[1] = t; /* type */
446 bf[2] = s->sym; /* sym */
447 Bwrite(b, bf, 3);
448 }
449 Bwrite(b, n, strlen(n)+1);
450 }
451
452 char*
zaddr(char * bp,Adr * a,int s)453 zaddr(char *bp, Adr *a, int s)
454 {
455 long l;
456 Ieee e;
457
458 bp[0] = a->type;
459 bp[1] = a->reg;
460 bp[2] = s;
461 bp[3] = a->name;
462 bp += 4;
463 switch(a->type) {
464 default:
465 diag(Z, "unknown type %d in zaddr", a->type);
466
467 case D_NONE:
468 case D_REG:
469 case D_FREG:
470 case D_MREG:
471 case D_FCREG:
472 case D_LO:
473 case D_HI:
474 break;
475
476 case D_OREG:
477 case D_CONST:
478 case D_BRANCH:
479 l = a->offset;
480 bp[0] = l;
481 bp[1] = l>>8;
482 bp[2] = l>>16;
483 bp[3] = l>>24;
484 bp += 4;
485 break;
486
487 case D_SCONST:
488 memmove(bp, a->sval, NSNAME);
489 bp += NSNAME;
490 break;
491
492 case D_FCONST:
493 ieeedtod(&e, a->dval);
494 l = e.l;
495 bp[0] = l;
496 bp[1] = l>>8;
497 bp[2] = l>>16;
498 bp[3] = l>>24;
499 bp += 4;
500 l = e.h;
501 bp[0] = l;
502 bp[1] = l>>8;
503 bp[2] = l>>16;
504 bp[3] = l>>24;
505 bp += 4;
506 break;
507 }
508 return bp;
509 }
510
511 long
align(long i,Type * t,int op)512 align(long i, Type *t, int op)
513 {
514 long o;
515 Type *v;
516 int w;
517
518 o = i;
519 w = 1;
520 switch(op) {
521 default:
522 diag(Z, "unknown align opcode %d", op);
523 break;
524
525 case Asu2: /* padding at end of a struct */
526 w = SZ_LONG;
527 if(packflg)
528 w = packflg;
529 break;
530
531 case Ael1: /* initial allign of struct element */
532 for(v=t; v->etype==TARRAY; v=v->link)
533 ;
534 w = ewidth[v->etype];
535 if(w <= 0 || w >= SZ_LONG)
536 w = SZ_LONG;
537 if(packflg)
538 w = packflg;
539 break;
540
541 case Ael2: /* width of a struct element */
542 o += t->width;
543 break;
544
545 case Aarg0: /* initial passbyptr argument in arg list */
546 if(typesuv[t->etype]) {
547 o = align(o, types[TIND], Aarg1);
548 o = align(o, types[TIND], Aarg2);
549 }
550 break;
551
552 case Aarg1: /* initial allign of parameter */
553 w = ewidth[t->etype];
554 if(w <= 0 || w >= SZ_LONG) {
555 w = SZ_LONG;
556 break;
557 }
558 if(thechar == 'v')
559 o += SZ_LONG - w; /* big endian adjustment */
560 w = 1;
561 break;
562
563 case Aarg2: /* width of a parameter */
564 o += t->width;
565 w = SZ_LONG;
566 break;
567
568 case Aaut3: /* total allign of automatic */
569 o = align(o, t, Ael1);
570 o = align(o, t, Ael2);
571 break;
572 }
573 o = round(o, w);
574 if(debug['A'])
575 print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
576 return o;
577 }
578
579 long
maxround(long max,long v)580 maxround(long max, long v)
581 {
582 v = round(v, SZ_LONG);
583 if(v > max)
584 return v;
585 return max;
586 }
587