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 if(suppress)
128 return nstring;
129 r = nstring;
130 while(n) {
131 string[mnstring] = *s++;
132 mnstring++;
133 nstring++;
134 if(mnstring >= NSNAME) {
135 gpseudo(ADATA, symstring, nodconst(0L));
136 p->from.offset += nstring - NSNAME;
137 p->reg = NSNAME;
138 p->to.type = D_SCONST;
139 memmove(p->to.sval, string, NSNAME);
140 mnstring = 0;
141 }
142 n--;
143 }
144 return r;
145 }
146
147 int
mulcon(Node * n,Node * nn)148 mulcon(Node *n, Node *nn)
149 {
150 Node *l, *r, nod1, nod2;
151 Multab *m;
152 long v;
153 int o;
154 char code[sizeof(m->code)+2], *p;
155
156 if(typefd[n->type->etype])
157 return 0;
158 l = n->left;
159 r = n->right;
160 if(l->op == OCONST) {
161 l = r;
162 r = n->left;
163 }
164 if(r->op != OCONST)
165 return 0;
166 v = convvtox(r->vconst, n->type->etype);
167 if(v != r->vconst) {
168 if(debug['M'])
169 print("%L multiply conv: %lld\n", n->lineno, r->vconst);
170 return 0;
171 }
172 m = mulcon0(v);
173 if(!m) {
174 if(debug['M'])
175 print("%L multiply table: %lld\n", n->lineno, r->vconst);
176 return 0;
177 }
178 if(debug['M'] && debug['v'])
179 print("%L multiply: %ld\n", n->lineno, v);
180
181 memmove(code, m->code, sizeof(m->code));
182 code[sizeof(m->code)] = 0;
183
184 p = code;
185 if(p[1] == 'i')
186 p += 2;
187 regalloc(&nod1, n, nn);
188 cgen(l, &nod1);
189 if(v < 0)
190 gopcode(OSUB, &nod1, nodconst(0), &nod1);
191 regalloc(&nod2, n, Z);
192
193 loop:
194 switch(*p) {
195 case 0:
196 regfree(&nod2);
197 gopcode(OAS, &nod1, Z, nn);
198 regfree(&nod1);
199 return 1;
200 case '+':
201 o = OADD;
202 goto addsub;
203 case '-':
204 o = OSUB;
205 addsub: /* number is r,n,l */
206 v = p[1] - '0';
207 r = &nod1;
208 if(v&4)
209 r = &nod2;
210 n = &nod1;
211 if(v&2)
212 n = &nod2;
213 l = &nod1;
214 if(v&1)
215 l = &nod2;
216 gopcode(o, l, n, r);
217 break;
218 default: /* op is shiftcount, number is r,l */
219 v = p[1] - '0';
220 r = &nod1;
221 if(v&2)
222 r = &nod2;
223 l = &nod1;
224 if(v&1)
225 l = &nod2;
226 v = *p - 'a';
227 if(v < 0 || v >= 32) {
228 diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
229 break;
230 }
231 gopcode(OASHL, nodconst(v), l, r);
232 break;
233 }
234 p += 2;
235 goto loop;
236 }
237
238 void
gextern(Sym * s,Node * a,long o,long w)239 gextern(Sym *s, Node *a, long o, long w)
240 {
241
242 if(a->op == OCONST && typev[a->type->etype]) {
243 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
244 gpseudo(ADATA, s, nod32const(a->vconst>>32));
245 else
246 gpseudo(ADATA, s, nod32const(a->vconst));
247 p->from.offset += o;
248 p->reg = 4;
249 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
250 gpseudo(ADATA, s, nod32const(a->vconst));
251 else
252 gpseudo(ADATA, s, nod32const(a->vconst>>32));
253 p->from.offset += o + 4;
254 p->reg = 4;
255 return;
256 }
257 gpseudo(ADATA, s, a);
258 p->from.offset += o;
259 p->reg = w;
260 if(p->to.type == D_OREG)
261 p->to.type = D_CONST;
262 }
263
264 void zname(Biobuf*, Sym*, int);
265 char* zaddr(char*, Adr*, int);
266 void zwrite(Biobuf*, Prog*, int, int);
267 void outhist(Biobuf*);
268
269 void
zwrite(Biobuf * b,Prog * p,int sf,int st)270 zwrite(Biobuf *b, Prog *p, int sf, int st)
271 {
272 char bf[100], *bp;
273
274 bf[0] = p->as;
275 bf[1] = p->reg;
276 bf[2] = p->lineno;
277 bf[3] = p->lineno>>8;
278 bf[4] = p->lineno>>16;
279 bf[5] = p->lineno>>24;
280 bp = zaddr(bf+6, &p->from, sf);
281 bp = zaddr(bp, &p->to, st);
282 Bwrite(b, bf, bp-bf);
283 }
284
285 void
outcode(void)286 outcode(void)
287 {
288 struct { Sym *sym; short type; } h[NSYM];
289 Prog *p;
290 Sym *s;
291 int sf, st, t, sym;
292
293 if(debug['S']) {
294 for(p = firstp; p != P; p = p->link)
295 if(p->as != ADATA && p->as != AGLOBL)
296 pc--;
297 for(p = firstp; p != P; p = p->link) {
298 print("%P\n", p);
299 if(p->as != ADATA && p->as != AGLOBL)
300 pc++;
301 }
302 }
303 outhist(&outbuf);
304 for(sym=0; sym<NSYM; sym++) {
305 h[sym].sym = S;
306 h[sym].type = 0;
307 }
308 sym = 1;
309 for(p = firstp; p != P; p = p->link) {
310 jackpot:
311 sf = 0;
312 s = p->from.sym;
313 while(s != S) {
314 sf = s->sym;
315 if(sf < 0 || sf >= NSYM)
316 sf = 0;
317 t = p->from.name;
318 if(h[sf].type == t)
319 if(h[sf].sym == s)
320 break;
321 s->sym = sym;
322 zname(&outbuf, s, t);
323 h[sym].sym = s;
324 h[sym].type = t;
325 sf = sym;
326 sym++;
327 if(sym >= NSYM)
328 sym = 1;
329 break;
330 }
331 st = 0;
332 s = p->to.sym;
333 while(s != S) {
334 st = s->sym;
335 if(st < 0 || st >= NSYM)
336 st = 0;
337 t = p->to.name;
338 if(h[st].type == t)
339 if(h[st].sym == s)
340 break;
341 s->sym = sym;
342 zname(&outbuf, s, t);
343 h[sym].sym = s;
344 h[sym].type = t;
345 st = sym;
346 sym++;
347 if(sym >= NSYM)
348 sym = 1;
349 if(st == sf)
350 goto jackpot;
351 break;
352 }
353 zwrite(&outbuf, p, sf, st);
354 }
355 firstp = P;
356 lastp = P;
357 }
358
359 void
outhist(Biobuf * b)360 outhist(Biobuf *b)
361 {
362 Hist *h;
363 char *p, *q, *op, c;
364 Prog pg;
365 int n;
366
367 pg = zprog;
368 pg.as = AHISTORY;
369 c = pathchar();
370 for(h = hist; h != H; h = h->link) {
371 p = h->name;
372 op = 0;
373 /* on windows skip drive specifier in pathname */
374 if(systemtype(Windows) && p && p[1] == ':'){
375 p += 2;
376 c = *p;
377 }
378 if(p && p[0] != c && h->offset == 0 && pathname){
379 /* on windows skip drive specifier in pathname */
380 if(systemtype(Windows) && pathname[1] == ':') {
381 op = p;
382 p = pathname+2;
383 c = *p;
384 } else if(pathname[0] == c){
385 op = p;
386 p = pathname;
387 }
388 }
389 while(p) {
390 q = utfrune(p, c);
391 if(q) {
392 n = q-p;
393 if(n == 0){
394 n = 1; /* leading "/" */
395 *p = '/'; /* don't emit "\" on windows */
396 }
397 q++;
398 } else {
399 n = strlen(p);
400 q = 0;
401 }
402 if(n) {
403 Bputc(b, ANAME);
404 Bputc(b, D_FILE);
405 Bputc(b, 1);
406 Bputc(b, '<');
407 Bwrite(b, p, n);
408 Bputc(b, 0);
409 }
410 p = q;
411 if(p == 0 && op) {
412 p = op;
413 op = 0;
414 }
415 }
416 pg.lineno = h->line;
417 pg.to.type = zprog.to.type;
418 pg.to.offset = h->offset;
419 if(h->offset)
420 pg.to.type = D_CONST;
421
422 zwrite(b, &pg, 0, 0);
423 }
424 }
425
426 void
zname(Biobuf * b,Sym * s,int t)427 zname(Biobuf *b, Sym *s, int t)
428 {
429 char *n, bf[7];
430 ulong sig;
431
432 n = s->name;
433 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
434 sig = sign(s);
435 bf[0] = ASIGNAME;
436 bf[1] = sig;
437 bf[2] = sig>>8;
438 bf[3] = sig>>16;
439 bf[4] = sig>>24;
440 bf[5] = t;
441 bf[6] = s->sym;
442 Bwrite(b, bf, 7);
443 s->sig = SIGDONE;
444 }
445 else{
446 bf[0] = ANAME;
447 bf[1] = t; /* type */
448 bf[2] = s->sym; /* sym */
449 Bwrite(b, bf, 3);
450 }
451 Bwrite(b, n, strlen(n)+1);
452 }
453
454 char*
zaddr(char * bp,Adr * a,int s)455 zaddr(char *bp, Adr *a, int s)
456 {
457 long l;
458 Ieee e;
459
460 if(a->type == D_CONST) {
461 l = a->offset;
462 if((vlong)l != a->offset)
463 a->type = D_VCONST;
464 }
465 bp[0] = a->type;
466 bp[1] = a->reg;
467 bp[2] = s;
468 bp[3] = a->name;
469 bp += 4;
470 switch(a->type) {
471 default:
472 diag(Z, "unknown type %d in zaddr", a->type);
473
474 case D_NONE:
475 case D_REG:
476 case D_FREG:
477 case D_MREG:
478 case D_FCREG:
479 case D_LO:
480 case D_HI:
481 break;
482
483 case D_OREG:
484 case D_CONST:
485 case D_BRANCH:
486 l = a->offset;
487 bp[0] = l;
488 bp[1] = l>>8;
489 bp[2] = l>>16;
490 bp[3] = l>>24;
491 bp += 4;
492 break;
493
494 case D_SCONST:
495 memmove(bp, a->sval, NSNAME);
496 bp += NSNAME;
497 break;
498
499 case D_FCONST:
500 ieeedtod(&e, a->dval);
501 l = e.l;
502 bp[0] = l;
503 bp[1] = l>>8;
504 bp[2] = l>>16;
505 bp[3] = l>>24;
506 bp += 4;
507 l = e.h;
508 bp[0] = l;
509 bp[1] = l>>8;
510 bp[2] = l>>16;
511 bp[3] = l>>24;
512 bp += 4;
513 break;
514
515 case D_VCONST:
516 l = a->offset;
517 bp[0] = l;
518 bp[1] = l>>8;
519 bp[2] = l>>16;
520 bp[3] = l>>24;
521 bp += 4;
522 l = a->offset>>32;
523 bp[0] = l;
524 bp[1] = l>>8;
525 bp[2] = l>>16;
526 bp[3] = l>>24;
527 bp += 4;
528 break;
529 }
530 return bp;
531 }
532
533 long
align(long i,Type * t,int op)534 align(long i, Type *t, int op)
535 {
536 long o;
537 Type *v;
538 int w;
539
540 o = i;
541 w = 1;
542 switch(op) {
543 default:
544 diag(Z, "unknown align opcode %d", op);
545 break;
546
547 case Asu2: /* padding at end of a struct */
548 w = SZ_VLONG;
549 if(packflg)
550 w = packflg;
551 break;
552
553 case Ael1: /* initial allign of struct element */
554 for(v=t; v->etype==TARRAY; v=v->link)
555 ;
556 w = ewidth[v->etype];
557 if(w <= 0 || w >= SZ_VLONG)
558 w = SZ_VLONG;
559 if(packflg)
560 w = packflg;
561 break;
562
563 case Ael2: /* width of a struct element */
564 o += t->width;
565 break;
566
567 case Aarg0: /* initial passbyptr argument in arg list */
568 if(typesu[t->etype]) {
569 o = align(o, types[TIND], Aarg1);
570 o = align(o, types[TIND], Aarg2);
571 }
572 break;
573
574 case Aarg1: /* initial allign of parameter */
575 w = ewidth[t->etype];
576 if(w <= 0 || w >= SZ_VLONG) {
577 w = SZ_VLONG;
578 break;
579 }
580 if(thechar == '4')
581 o += SZ_VLONG - w; /* big endian adjustment */
582 w = 1;
583 break;
584
585 case Aarg2: /* width of a parameter */
586 o += t->width;
587 w = SZ_VLONG;
588 break;
589
590 case Aaut3: /* total allign of automatic */
591 o = align(o, t, Ael1);
592 o = align(o, t, Ael2);
593 break;
594 }
595 o = round(o, w);
596 if(debug['A'])
597 print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
598 return o;
599 }
600
601 long
maxround(long max,long v)602 maxround(long max, long v)
603 {
604 v = round(v, SZ_VLONG);
605 if(v > max)
606 return v;
607 return max;
608 }
609