]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/6c/txt.c
861cdfde4e2cdac4ccfe24ba911f717639e46ebd
[plan9front.git] / sys / src / cmd / 6c / txt.c
1 #include "gc.h"
2
3 static  int     resvreg[nelem(reg)];
4
5 void
6 ginit(void)
7 {
8         int i;
9         Type *t;
10
11         thechar = '6';
12         thestring = "amd64";
13         exregoffset = REGEXT;
14         exfregoffset = FREGEXT;
15         listinit();
16         nstring = 0;
17         mnstring = 0;
18         nrathole = 0;
19         pc = 0;
20         breakpc = -1;
21         continpc = -1;
22         cases = C;
23         firstp = P;
24         lastp = P;
25         tfield = types[TINT];
26
27         typeword = typechlvp;
28         typeswitch = typechlv;
29         typecmplx = typesu;
30
31         /* TO DO */
32         memmove(typechlpv, typechlp, sizeof(typechlpv));
33         typechlpv[TVLONG] = 1;
34         typechlpv[TUVLONG] = 1;
35
36         zprog.link = P;
37         zprog.as = AGOK;
38         zprog.from.type = D_NONE;
39         zprog.from.index = D_NONE;
40         zprog.from.scale = 0;
41         zprog.to = zprog.from;
42
43         lregnode.op = OREGISTER;
44         lregnode.class = CEXREG;
45         lregnode.reg = REGTMP;
46         lregnode.complex = 0;
47         lregnode.addable = 11;
48         lregnode.type = types[TLONG];
49
50         qregnode = lregnode;
51         qregnode.type = types[TVLONG];
52
53         constnode.op = OCONST;
54         constnode.class = CXXX;
55         constnode.complex = 0;
56         constnode.addable = 20;
57         constnode.type = types[TLONG];
58
59         vconstnode = constnode;
60         vconstnode.type = types[TVLONG];
61
62         fconstnode.op = OCONST;
63         fconstnode.class = CXXX;
64         fconstnode.complex = 0;
65         fconstnode.addable = 20;
66         fconstnode.type = types[TDOUBLE];
67
68         nodsafe = new(ONAME, Z, Z);
69         nodsafe->sym = slookup(".safe");
70         nodsafe->type = types[TINT];
71         nodsafe->etype = types[TINT]->etype;
72         nodsafe->class = CAUTO;
73         complex(nodsafe);
74
75         t = typ(TARRAY, types[TCHAR]);
76         symrathole = slookup(".rathole");
77         symrathole->class = CGLOBL;
78         symrathole->type = t;
79
80         nodrat = new(ONAME, Z, Z);
81         nodrat->sym = symrathole;
82         nodrat->type = types[TIND];
83         nodrat->etype = TVOID;
84         nodrat->class = CGLOBL;
85         complex(nodrat);
86         nodrat->type = t;
87
88         nodret = new(ONAME, Z, Z);
89         nodret->sym = slookup(".ret");
90         nodret->type = types[TIND];
91         nodret->etype = TIND;
92         nodret->class = CPARAM;
93         nodret = new(OIND, nodret, Z);
94         complex(nodret);
95
96         if(0)
97                 com64init();
98
99         memset(reg, 0, sizeof(reg));
100         for(i=0; i<nelem(reg); i++) {
101                 reg[i] = 1;
102                 if(i >= D_AX && i <= D_R15 && i != D_SP)
103                         reg[i] = 0;
104                 if(i >= D_X0 && i <= D_X7)
105                         reg[i] = 0;
106         }
107         /* keep two external registers */
108         reg[REGEXT] = 1;
109         reg[REGEXT-1] = 1;
110         memmove(resvreg, reg, sizeof(resvreg));
111 }
112
113 void
114 gclean(void)
115 {
116         int i;
117         Sym *s;
118
119         reg[D_SP]--;
120         for(i=D_AX; i<=D_R15; i++)
121                 if(reg[i] && !resvreg[i])
122                         diag(Z, "reg %R left allocated", i);
123         for(i=D_X0; i<=D_X7; i++)
124                 if(reg[i] && !resvreg[i])
125                         diag(Z, "reg %R left allocated", i);
126         while(mnstring)
127                 outstring("", 1L);
128         symstring->type->width = nstring;
129         symrathole->type->width = nrathole;
130         for(i=0; i<NHASH; i++)
131         for(s = hash[i]; s != S; s = s->link) {
132                 if(s->type == T)
133                         continue;
134                 if(s->type->width == 0)
135                         continue;
136                 if(s->class != CGLOBL && s->class != CSTATIC)
137                         continue;
138                 if(s->type == types[TENUM])
139                         continue;
140                 gpseudo(AGLOBL, s, nodconst(s->type->width));
141         }
142         nextpc();
143         p->as = AEND;
144         outcode();
145 }
146
147 void
148 nextpc(void)
149 {
150
151         p = alloc(sizeof(*p));
152         *p = zprog;
153         p->lineno = nearln;
154         pc++;
155         if(firstp == P) {
156                 firstp = p;
157                 lastp = p;
158                 return;
159         }
160         lastp->link = p;
161         lastp = p;
162 }
163
164 void
165 gargs(Node *n, Node *tn1, Node *tn2)
166 {
167         long regs;
168         Node fnxargs[20], *fnxp;
169
170         regs = cursafe;
171
172         fnxp = fnxargs;
173         garg1(n, tn1, tn2, 0, &fnxp);   /* compile fns to temps */
174
175         curarg = 0;
176         fnxp = fnxargs;
177         garg1(n, tn1, tn2, 1, &fnxp);   /* compile normal args and temps */
178
179         cursafe = regs;
180 }
181
182 int
183 nareg(void)
184 {
185         int i, n;
186
187         n = 0;
188         for(i=D_AX; i<=D_R15; i++)
189                 if(reg[i] == 0 && !resvreg[i])
190                         n++;
191         return n;
192 }
193
194 void
195 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
196 {
197         Node nod;
198
199         if(n == Z)
200                 return;
201         if(n->op == OLIST) {
202                 garg1(n->left, tn1, tn2, f, fnxp);
203                 garg1(n->right, tn1, tn2, f, fnxp);
204                 return;
205         }
206         if(f == 0) {
207                 if(n->complex >= FNX) {
208                         regsalloc(*fnxp, n);
209                         nod = znode;
210                         nod.op = OAS;
211                         nod.left = *fnxp;
212                         nod.right = n;
213                         nod.type = n->type;
214                         cgen(&nod, Z);
215                         (*fnxp)++;
216                 }
217                 return;
218         }
219         if(typesu[n->type->etype]) {
220                 regaalloc(tn2, n);
221                 if(n->complex >= FNX) {
222                         sugen(*fnxp, tn2, n->type->width);
223                         (*fnxp)++;
224                 } else
225                         sugen(n, tn2, n->type->width);
226                 return;
227         }
228         if(REGARG && curarg == 0 && typechlpv[n->type->etype]) {
229                 regaalloc1(tn1, n);
230                 if(n->complex >= FNX) {
231                         cgen(*fnxp, tn1);
232                         (*fnxp)++;
233                 } else
234                         cgen(n, tn1);
235                 return;
236         }
237         if(vconst(n) == 0) {
238                 regaalloc(tn2, n);
239                 gmove(n, tn2);
240                 return;
241         }
242         regalloc(tn1, n, Z);
243         if(n->complex >= FNX) {
244                 cgen(*fnxp, tn1);
245                 (*fnxp)++;
246         } else
247                 cgen(n, tn1);
248         regaalloc(tn2, n);
249         gmove(tn1, tn2);
250         regfree(tn1);
251 }
252
253 Node*
254 nodgconst(vlong v, Type *t)
255 {
256         if(!typev[t->etype])
257                 return nodconst((long)v);
258         vconstnode.vconst = v;
259         return &vconstnode;
260 }
261
262 Node*
263 nodconst(long v)
264 {
265         constnode.vconst = v;
266         return &constnode;
267 }
268
269 Node*
270 nodfconst(double d)
271 {
272         fconstnode.fconst = d;
273         return &fconstnode;
274 }
275
276 int
277 isreg(Node *n, int r)
278 {
279
280         if(n->op == OREGISTER)
281                 if(n->reg == r)
282                         return 1;
283         return 0;
284 }
285
286 int
287 nodreg(Node *n, Node *nn, int r)
288 {
289         int et;
290
291         *n = qregnode;
292         n->reg = r;
293         if(nn != Z){
294                 et = nn->type->etype;
295                 if(!typefd[et] && nn->type->width <= SZ_LONG && 0)
296                         n->type = typeu[et]? types[TUINT]: types[TINT];
297                 else
298                         n->type = nn->type;
299 //print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]);
300                 n->lineno = nn->lineno;
301         }
302         if(reg[r] == 0)
303                 return 0;
304         if(nn != Z) {
305                 if(nn->op == OREGISTER)
306                 if(nn->reg == r)
307                         return 0;
308         }
309         return 1;
310 }
311
312 void
313 regret(Node *n, Node *nn)
314 {
315         int r;
316
317         r = REGRET;
318         if(typefd[nn->type->etype])
319                 r = FREGRET;
320         nodreg(n, nn, r);
321         reg[r]++;
322 }
323
324 void
325 regalloc(Node *n, Node *tn, Node *o)
326 {
327         int i;
328
329         switch(tn->type->etype) {
330         case TCHAR:
331         case TUCHAR:
332         case TSHORT:
333         case TUSHORT:
334         case TINT:
335         case TUINT:
336         case TLONG:
337         case TULONG:
338         case TVLONG:
339         case TUVLONG:
340         case TIND:
341                 if(o != Z && o->op == OREGISTER) {
342                         i = o->reg;
343                         if(i >= D_AX && i <= D_R15)
344                                 goto out;
345                 }
346                 for(i=D_AX; i<=D_R15; i++)
347                         if(reg[i] == 0 && !resvreg[i])
348                                 goto out;
349                 diag(tn, "out of fixed registers");
350                 goto err;
351
352         case TFLOAT:
353         case TDOUBLE:
354                 if(o != Z && o->op == OREGISTER) {
355                         i = o->reg;
356                         if(i >= D_X0 && i <= D_X7)
357                                 goto out;
358                 }
359                 for(i=D_X0; i<=D_X7; i++)
360                         if(reg[i] == 0 && !resvreg[i])
361                                 goto out;
362                 diag(tn, "out of float registers");
363                 goto out;
364         }
365         diag(tn, "unknown type in regalloc: %T", tn->type);
366 err:
367         i = 0;
368 out:
369         if(i)
370                 reg[i]++;
371         nodreg(n, tn, i);
372 }
373
374 void
375 regialloc(Node *n, Node *tn, Node *o)
376 {
377         Node nod;
378
379         nod = *tn;
380         nod.type = types[TIND];
381         regalloc(n, &nod, o);
382 }
383
384 void
385 regfree(Node *n)
386 {
387         int i;
388
389         i = 0;
390         if(n->op != OREGISTER && n->op != OINDREG)
391                 goto err;
392         i = n->reg;
393         if(i < 0 || i >= sizeof(reg))
394                 goto err;
395         if(reg[i] <= 0)
396                 goto err;
397         reg[i]--;
398         return;
399 err:
400         diag(n, "error in regfree: %R", i);
401 }
402
403 void
404 regsalloc(Node *n, Node *nn)
405 {
406         cursafe = align(cursafe, nn->type, Aaut3);
407         maxargsafe = maxround(maxargsafe, cursafe+curarg);
408         *n = *nodsafe;
409         n->xoffset = -(stkoff + cursafe);
410         n->type = nn->type;
411         n->etype = nn->type->etype;
412         n->lineno = nn->lineno;
413 }
414
415 void
416 regaalloc1(Node *n, Node *nn)
417 {
418         nodreg(n, nn, REGARG);
419         reg[REGARG]++;
420         curarg = align(curarg, nn->type, Aarg1);
421         curarg = align(curarg, nn->type, Aarg2);
422         maxargsafe = maxround(maxargsafe, cursafe+curarg);
423 }
424
425 void
426 regaalloc(Node *n, Node *nn)
427 {
428         curarg = align(curarg, nn->type, Aarg1);
429         *n = *nn;
430         n->op = OINDREG;
431         n->reg = REGSP;
432         n->xoffset = curarg;
433         n->complex = 0;
434         n->addable = 20;
435         curarg = align(curarg, nn->type, Aarg2);
436         maxargsafe = maxround(maxargsafe, cursafe+curarg);
437 }
438
439 void
440 regind(Node *n, Node *nn)
441 {
442
443         if(n->op != OREGISTER) {
444                 diag(n, "regind not OREGISTER");
445                 return;
446         }
447         n->op = OINDREG;
448         n->type = nn->type;
449 }
450
451 void
452 naddr(Node *n, Adr *a)
453 {
454         long v;
455
456         a->type = D_NONE;
457         if(n == Z)
458                 return;
459         switch(n->op) {
460         default:
461         bad:
462                 diag(n, "bad in naddr: %O %D", n->op, a);
463                 break;
464
465         case OREGISTER:
466                 a->type = n->reg;
467                 a->sym = S;
468                 break;
469
470
471         case OIND:
472                 naddr(n->left, a);
473                 if(a->type >= D_AX && a->type <= D_R15)
474                         a->type += D_INDIR;
475                 else
476                 if(a->type == D_CONST)
477                         a->type = D_NONE+D_INDIR;
478                 else
479                 if(a->type == D_ADDR) {
480                         a->type = a->index;
481                         a->index = D_NONE;
482                 } else
483                         goto bad;
484                 break;
485
486         case OINDEX:
487                 a->type = idx.ptr;
488                 if(n->left->op == OADDR || n->left->op == OCONST)
489                         naddr(n->left, a);
490                 if(a->type >= D_AX && a->type <= D_R15)
491                         a->type += D_INDIR;
492                 else
493                 if(a->type == D_CONST)
494                         a->type = D_NONE+D_INDIR;
495                 else
496                 if(a->type == D_ADDR) {
497                         a->type = a->index;
498                         a->index = D_NONE;
499                 } else
500                         goto bad;
501                 a->index = idx.reg;
502                 a->scale = n->scale;
503                 a->offset += n->xoffset;
504                 break;
505
506         case OINDREG:
507                 a->type = n->reg+D_INDIR;
508                 a->sym = S;
509                 a->offset = n->xoffset;
510                 break;
511
512         case ONAME:
513                 a->etype = n->etype;
514                 a->type = D_STATIC;
515                 a->sym = n->sym;
516                 a->offset = n->xoffset;
517                 if(n->class == CSTATIC)
518                         break;
519                 if(n->class == CEXTERN || n->class == CGLOBL) {
520                         a->type = D_EXTERN;
521                         break;
522                 }
523                 if(n->class == CAUTO) {
524                         a->type = D_AUTO;
525                         break;
526                 }
527                 if(n->class == CPARAM) {
528                         a->type = D_PARAM;
529                         break;
530                 }
531                 goto bad;
532
533         case OCONST:
534                 if(typefd[n->type->etype]) {
535                         a->type = D_FCONST;
536                         a->dval = n->fconst;
537                         break;
538                 }
539                 a->sym = S;
540                 a->type = D_CONST;
541                 if(typev[n->type->etype] || n->type->etype == TIND)
542                         a->offset = n->vconst;
543                 else
544                         a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
545                 break;
546
547         case OADDR:
548                 naddr(n->left, a);
549                 if(a->type >= D_INDIR) {
550                         a->type -= D_INDIR;
551                         break;
552                 }
553                 if(a->type == D_EXTERN || a->type == D_STATIC ||
554                    a->type == D_AUTO || a->type == D_PARAM)
555                         if(a->index == D_NONE) {
556                                 a->index = a->type;
557                                 a->type = D_ADDR;
558                                 break;
559                         }
560                 goto bad;
561
562         case OADD:
563                 if(n->right->op == OCONST) {
564                         v = n->right->vconst;
565                         naddr(n->left, a);
566                 } else
567                 if(n->left->op == OCONST) {
568                         v = n->left->vconst;
569                         naddr(n->right, a);
570                 } else
571                         goto bad;
572                 a->offset += v;
573                 break;
574
575         }
576 }
577
578 void
579 gcmp(int op, Node *n, vlong val)
580 {
581         Node *cn, nod;
582
583         cn = nodgconst(val, n->type);
584         if(!immconst(cn)){
585                 regalloc(&nod, n, Z);
586                 gmove(cn, &nod);
587                 gopcode(op, n->type, n, &nod);
588                 regfree(&nod);
589         }else
590                 gopcode(op, n->type, n, cn);
591 }
592
593 #define CASE(a,b)       ((a<<8)|(b<<0))
594
595 void
596 gmove(Node *f, Node *t)
597 {
598         int ft, tt, t64, a;
599         Node nod, nod1, nod2, nod3;
600         Prog *p1, *p2;
601
602         ft = f->type->etype;
603         tt = t->type->etype;
604         t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
605         if(debug['M'])
606                 print("gop: %O %O[%s],%O[%s]\n", OAS,
607                         f->op, tnames[ft], t->op, tnames[tt]);
608         if(typefd[ft] && f->op == OCONST) {
609                 /* TO DO: pick up special constants, possibly preloaded */
610                 if(f->fconst == 0.0){
611                         regalloc(&nod, t, t);
612                         gins(AXORPD, &nod, &nod);
613                         gmove(&nod, t);
614                         regfree(&nod);
615                         return;
616                 }
617         }
618 /*
619  * load
620  */
621         if(f->op == ONAME || f->op == OINDREG ||
622            f->op == OIND || f->op == OINDEX)
623         switch(ft) {
624         case TCHAR:
625                 a = AMOVBLSX;
626                 if(t64)
627                         a = AMOVBQSX;
628                 goto ld;
629         case TUCHAR:
630                 a = AMOVBLZX;
631                 if(t64)
632                         a = AMOVBQZX;
633                 goto ld;
634         case TSHORT:
635                 a = AMOVWLSX;
636                 if(t64)
637                         a = AMOVWQSX;
638                 goto ld;
639         case TUSHORT:
640                 a = AMOVWLZX;
641                 if(t64)
642                         a = AMOVWQZX;
643                 goto ld;
644         case TINT:
645         case TLONG:
646                 if(typefd[tt]) {
647                         regalloc(&nod, t, t);
648                         if(tt == TDOUBLE)
649                                 a = ACVTSL2SD;
650                         else
651                                 a = ACVTSL2SS;
652                         gins(a, f, &nod);
653                         gmove(&nod, t);
654                         regfree(&nod);
655                         return;
656                 }
657                 a = AMOVL;
658                 if(t64)
659                         a = AMOVLQSX;
660                 goto ld;
661         case TUINT:
662         case TULONG:
663                 a = AMOVL;
664                 if(t64)
665                         a = AMOVLQZX;   /* could probably use plain MOVL */
666                 goto ld;
667         case TVLONG:
668                 if(typefd[tt]) {
669                         regalloc(&nod, t, t);
670                         if(tt == TDOUBLE)
671                                 a = ACVTSQ2SD;
672                         else
673                                 a = ACVTSQ2SS;
674                         gins(a, f, &nod);
675                         gmove(&nod, t);
676                         regfree(&nod);
677                         return;
678                 }
679         case TUVLONG:
680         case TIND:
681                 a = AMOVQ;
682         ld:
683                 regalloc(&nod, f, t);
684                 gins(a, f, &nod);
685                 gmove(&nod, t);
686                 regfree(&nod);
687                 return;
688
689         case TFLOAT:
690                 a = AMOVSS;
691                 goto ld;
692         case TDOUBLE:
693                 a = AMOVSD;
694                 goto ld;
695         }
696
697 /*
698  * store
699  */
700         if(t->op == ONAME || t->op == OINDREG ||
701            t->op == OIND || t->op == OINDEX)
702         switch(tt) {
703         case TCHAR:
704         case TUCHAR:
705                 a = AMOVB;      goto st;
706         case TSHORT:
707         case TUSHORT:
708                 a = AMOVW;      goto st;
709         case TINT:
710         case TUINT:
711         case TLONG:
712         case TULONG:
713                 a = AMOVL;      goto st;
714         case TVLONG:
715         case TUVLONG:
716         case TIND:
717                 a = AMOVQ;      goto st;
718
719         st:
720                 if(f->op == OCONST) {
721                         gins(a, f, t);
722                         return;
723                 }
724         fst:
725                 regalloc(&nod, t, f);
726                 gmove(f, &nod);
727                 gins(a, &nod, t);
728                 regfree(&nod);
729                 return;
730
731         case TFLOAT:
732                 a = AMOVSS;
733                 goto fst;
734         case TDOUBLE:
735                 a = AMOVSD;
736                 goto fst;
737         }
738
739 /*
740  * convert
741  */
742         switch(CASE(ft,tt)) {
743         default:
744 /*
745  * integer to integer
746  ********
747                 a = AGOK;       break;
748
749         case CASE(      TCHAR,  TCHAR):
750         case CASE(      TUCHAR, TCHAR):
751         case CASE(      TSHORT, TCHAR):
752         case CASE(      TUSHORT,TCHAR):
753         case CASE(      TINT,   TCHAR):
754         case CASE(      TUINT,  TCHAR):
755         case CASE(      TLONG,  TCHAR):
756         case CASE(      TULONG, TCHAR):
757
758         case CASE(      TCHAR,  TUCHAR):
759         case CASE(      TUCHAR, TUCHAR):
760         case CASE(      TSHORT, TUCHAR):
761         case CASE(      TUSHORT,TUCHAR):
762         case CASE(      TINT,   TUCHAR):
763         case CASE(      TUINT,  TUCHAR):
764         case CASE(      TLONG,  TUCHAR):
765         case CASE(      TULONG, TUCHAR):
766
767         case CASE(      TSHORT, TSHORT):
768         case CASE(      TUSHORT,TSHORT):
769         case CASE(      TINT,   TSHORT):
770         case CASE(      TUINT,  TSHORT):
771         case CASE(      TLONG,  TSHORT):
772         case CASE(      TULONG, TSHORT):
773
774         case CASE(      TSHORT, TUSHORT):
775         case CASE(      TUSHORT,TUSHORT):
776         case CASE(      TINT,   TUSHORT):
777         case CASE(      TUINT,  TUSHORT):
778         case CASE(      TLONG,  TUSHORT):
779         case CASE(      TULONG, TUSHORT):
780
781         case CASE(      TINT,   TINT):
782         case CASE(      TUINT,  TINT):
783         case CASE(      TLONG,  TINT):
784         case CASE(      TULONG, TINT)::
785
786         case CASE(      TINT,   TUINT):
787         case CASE(      TUINT,  TUINT):
788         case CASE(      TLONG,  TUINT):
789         case CASE(      TULONG, TUINT):
790  *****/
791                 a = AMOVL;
792                 break;
793
794         case CASE(      TINT,   TIND):
795         case CASE(      TINT,   TVLONG):
796         case CASE(      TINT,   TUVLONG):
797         case CASE(      TLONG,  TIND):
798         case CASE(      TLONG,  TVLONG):
799         case CASE(      TLONG,  TUVLONG):
800                 a = AMOVLQSX;
801                 if(f->op == OCONST) {
802                         f->vconst &= (uvlong)0xffffffffU;
803                         if(f->vconst & 0x80000000)
804                                 f->vconst |= (vlong)0xffffffff << 32;
805                         a = AMOVQ;
806                 }
807                 break;
808
809         case CASE(      TUINT,  TIND):
810         case CASE(      TUINT,  TVLONG):
811         case CASE(      TUINT,  TUVLONG):
812         case CASE(      TULONG, TVLONG):
813         case CASE(      TULONG, TUVLONG):
814         case CASE(      TULONG, TIND):
815                 a = AMOVLQZX;
816                 if(f->op == OCONST) {
817                         f->vconst &= (uvlong)0xffffffffU;
818                         a = AMOVQ;
819                 }
820                 break;
821
822         case CASE(      TIND,   TCHAR):
823         case CASE(      TIND,   TUCHAR):
824         case CASE(      TIND,   TSHORT):
825         case CASE(      TIND,   TUSHORT):
826         case CASE(      TIND,   TINT):
827         case CASE(      TIND,   TUINT):
828         case CASE(      TIND,   TLONG):
829         case CASE(      TIND,   TULONG):
830         case CASE(      TVLONG, TCHAR):
831         case CASE(      TVLONG, TUCHAR):
832         case CASE(      TVLONG, TSHORT):
833         case CASE(      TVLONG, TUSHORT):
834         case CASE(      TVLONG, TINT):
835         case CASE(      TVLONG, TUINT):
836         case CASE(      TVLONG, TLONG):
837         case CASE(      TVLONG, TULONG):
838         case CASE(      TUVLONG,        TCHAR):
839         case CASE(      TUVLONG,        TUCHAR):
840         case CASE(      TUVLONG,        TSHORT):
841         case CASE(      TUVLONG,        TUSHORT):
842         case CASE(      TUVLONG,        TINT):
843         case CASE(      TUVLONG,        TUINT):
844         case CASE(      TUVLONG,        TLONG):
845         case CASE(      TUVLONG,        TULONG):
846                 a = AMOVQL;
847                 if(f->op == OCONST) {
848                         f->vconst &= 0xffffffffU;
849                         a = AMOVL;
850                 }
851                 break;
852
853         case CASE(      TIND,   TIND):
854         case CASE(      TIND,   TVLONG):
855         case CASE(      TIND,   TUVLONG):
856         case CASE(      TVLONG, TIND):
857         case CASE(      TVLONG, TVLONG):
858         case CASE(      TVLONG, TUVLONG):
859         case CASE(      TUVLONG,        TIND):
860         case CASE(      TUVLONG,        TVLONG):
861         case CASE(      TUVLONG,        TUVLONG):
862                 a = AMOVQ;
863                 break;
864
865         case CASE(      TSHORT, TINT):
866         case CASE(      TSHORT, TUINT):
867         case CASE(      TSHORT, TLONG):
868         case CASE(      TSHORT, TULONG):
869                 a = AMOVWLSX;
870                 if(f->op == OCONST) {
871                         f->vconst &= 0xffff;
872                         if(f->vconst & 0x8000)
873                                 f->vconst |= 0xffff0000;
874                         a = AMOVL;
875                 }
876                 break;
877
878         case CASE(      TSHORT, TVLONG):
879         case CASE(      TSHORT, TUVLONG):
880         case CASE(      TSHORT, TIND):
881                 a = AMOVWQSX;
882                 if(f->op == OCONST) {
883                         f->vconst &= 0xffff;
884                         if(f->vconst & 0x8000){
885                                 f->vconst |= 0xffff0000;
886                                 f->vconst |= (vlong)~0 << 32;
887                         }
888                         a = AMOVL;
889                 }
890                 break;
891
892         case CASE(      TUSHORT,TINT):
893         case CASE(      TUSHORT,TUINT):
894         case CASE(      TUSHORT,TLONG):
895         case CASE(      TUSHORT,TULONG):
896                 a = AMOVWLZX;
897                 if(f->op == OCONST) {
898                         f->vconst &= 0xffff;
899                         a = AMOVL;
900                 }
901                 break;
902
903         case CASE(      TUSHORT,TVLONG):
904         case CASE(      TUSHORT,TUVLONG):
905         case CASE(      TUSHORT,TIND):
906                 a = AMOVWQZX;
907                 if(f->op == OCONST) {
908                         f->vconst &= 0xffff;
909                         a = AMOVL;      /* MOVL also zero-extends to 64 bits */
910                 }
911                 break;
912
913         case CASE(      TCHAR,  TSHORT):
914         case CASE(      TCHAR,  TUSHORT):
915         case CASE(      TCHAR,  TINT):
916         case CASE(      TCHAR,  TUINT):
917         case CASE(      TCHAR,  TLONG):
918         case CASE(      TCHAR,  TULONG):
919                 a = AMOVBLSX;
920                 if(f->op == OCONST) {
921                         f->vconst &= 0xff;
922                         if(f->vconst & 0x80)
923                                 f->vconst |= 0xffffff00;
924                         a = AMOVL;
925                 }
926                 break;
927
928         case CASE(      TCHAR,  TVLONG):
929         case CASE(      TCHAR,  TUVLONG):
930         case CASE(      TCHAR,  TIND):
931                 a = AMOVBQSX;
932                 if(f->op == OCONST) {
933                         f->vconst &= 0xff;
934                         if(f->vconst & 0x80){
935                                 f->vconst |= 0xffffff00;
936                                 f->vconst |= (vlong)~0 << 32;
937                         }
938                         a = AMOVQ;
939                 }
940                 break;
941
942         case CASE(      TUCHAR, TSHORT):
943         case CASE(      TUCHAR, TUSHORT):
944         case CASE(      TUCHAR, TINT):
945         case CASE(      TUCHAR, TUINT):
946         case CASE(      TUCHAR, TLONG):
947         case CASE(      TUCHAR, TULONG):
948                 a = AMOVBLZX;
949                 if(f->op == OCONST) {
950                         f->vconst &= 0xff;
951                         a = AMOVL;
952                 }
953                 break;
954
955         case CASE(      TUCHAR, TVLONG):
956         case CASE(      TUCHAR, TUVLONG):
957         case CASE(      TUCHAR, TIND):
958                 a = AMOVBQZX;
959                 if(f->op == OCONST) {
960                         f->vconst &= 0xff;
961                         a = AMOVL;      /* zero-extends to 64-bits */
962                 }
963                 break;
964
965 /*
966  * float to fix
967  */
968         case CASE(      TFLOAT, TCHAR):
969         case CASE(      TFLOAT, TUCHAR):
970         case CASE(      TFLOAT, TSHORT):
971         case CASE(      TFLOAT, TUSHORT):
972         case CASE(      TFLOAT, TINT):
973         case CASE(      TFLOAT, TUINT):
974         case CASE(      TFLOAT, TLONG):
975         case CASE(      TFLOAT, TULONG):
976         case CASE(      TFLOAT, TVLONG):
977         case CASE(      TFLOAT, TUVLONG):
978         case CASE(      TFLOAT, TIND):
979
980         case CASE(      TDOUBLE,TCHAR):
981         case CASE(      TDOUBLE,TUCHAR):
982         case CASE(      TDOUBLE,TSHORT):
983         case CASE(      TDOUBLE,TUSHORT):
984         case CASE(      TDOUBLE,TINT):
985         case CASE(      TDOUBLE,TUINT):
986         case CASE(      TDOUBLE,TLONG):
987         case CASE(      TDOUBLE,TULONG):
988         case CASE(      TDOUBLE,TVLONG):
989         case CASE(      TDOUBLE,TUVLONG):
990         case CASE(      TDOUBLE,TIND):
991                 regalloc(&nod, t, Z);
992                 if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
993                         if(ft == TFLOAT)
994                                 a = ACVTTSS2SQ;
995                         else
996                                 a = ACVTTSD2SQ;
997                 }else{
998                         if(ft == TFLOAT)
999                                 a = ACVTTSS2SL;
1000                         else
1001                                 a = ACVTTSD2SL;
1002                 }
1003                 gins(a, f, &nod);
1004                 gmove(&nod, t);
1005                 regfree(&nod);
1006                 return;
1007
1008 /*
1009  * ulong to float
1010  */
1011         case CASE(      TUVLONG,        TDOUBLE):
1012         case CASE(      TUVLONG,        TFLOAT):
1013                 a = ACVTSQ2SS;
1014                 if(tt == TDOUBLE)
1015                         a = ACVTSQ2SD;
1016                 regalloc(&nod, f, f);
1017                 gmove(f, &nod);
1018                 regalloc(&nod1, t, t);
1019                 gins(ACMPQ, &nod, nodconst(0));
1020                 gins(AJLT, Z, Z);
1021                 p1 = p;
1022                 gins(a, &nod, &nod1);
1023                 gins(AJMP, Z, Z);
1024                 p2 = p;
1025                 patch(p1, pc);
1026                 regalloc(&nod2, f, Z);
1027                 regalloc(&nod3, f, Z);
1028                 gmove(&nod, &nod2);
1029                 gins(ASHRQ, nodconst(1), &nod2);
1030                 gmove(&nod, &nod3);
1031                 gins(AANDL, nodconst(1), &nod3);
1032                 gins(AORQ, &nod3, &nod2);
1033                 gins(a, &nod2, &nod1);
1034                 gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
1035                 regfree(&nod2);
1036                 regfree(&nod3);
1037                 patch(p2, pc);
1038                 regfree(&nod);
1039                 regfree(&nod1);
1040                 return;
1041
1042         case CASE(      TULONG, TDOUBLE):
1043         case CASE(      TUINT,  TDOUBLE):
1044         case CASE(      TULONG, TFLOAT):
1045         case CASE(      TUINT,  TFLOAT):
1046                 a = ACVTSQ2SS;
1047                 if(tt == TDOUBLE)
1048                         a = ACVTSQ2SD;
1049                 regalloc(&nod, f, f);
1050                 gins(AMOVLQZX, f, &nod);
1051                 regalloc(&nod1, t, t);
1052                 gins(a, &nod, &nod1);
1053                 gmove(&nod1, t);
1054                 regfree(&nod);
1055                 regfree(&nod1);
1056                 return;
1057
1058 /*
1059  * fix to float
1060  */
1061         case CASE(      TCHAR,  TFLOAT):
1062         case CASE(      TUCHAR, TFLOAT):
1063         case CASE(      TSHORT, TFLOAT):
1064         case CASE(      TUSHORT,TFLOAT):
1065         case CASE(      TINT,   TFLOAT):
1066         case CASE(      TLONG,  TFLOAT):
1067         case CASE(      TVLONG, TFLOAT):
1068         case CASE(      TIND,   TFLOAT):
1069
1070         case CASE(      TCHAR,  TDOUBLE):
1071         case CASE(      TUCHAR, TDOUBLE):
1072         case CASE(      TSHORT, TDOUBLE):
1073         case CASE(      TUSHORT,TDOUBLE):
1074         case CASE(      TINT,   TDOUBLE):
1075         case CASE(      TLONG,  TDOUBLE):
1076         case CASE(      TVLONG, TDOUBLE):
1077         case CASE(      TIND,   TDOUBLE):
1078                 regalloc(&nod, t, t);
1079                 if(ewidth[ft] == SZ_VLONG){
1080                         if(tt == TFLOAT)
1081                                 a = ACVTSQ2SS;
1082                         else
1083                                 a = ACVTSQ2SD;
1084                 }else{
1085                         if(tt == TFLOAT)
1086                                 a = ACVTSL2SS;
1087                         else
1088                                 a = ACVTSL2SD;
1089                 }
1090                 gins(a, f, &nod);
1091                 gmove(&nod, t);
1092                 regfree(&nod);
1093                 return;
1094
1095 /*
1096  * float to float
1097  */
1098         case CASE(      TFLOAT, TFLOAT):
1099                 a = AMOVSS;
1100                 break;
1101         case CASE(      TDOUBLE,TFLOAT):
1102                 a = ACVTSD2SS;
1103                 break;
1104         case CASE(      TFLOAT, TDOUBLE):
1105                 a = ACVTSS2SD;
1106                 break;
1107         case CASE(      TDOUBLE,TDOUBLE):
1108                 a = AMOVSD;
1109                 break;
1110         }
1111         if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])  /* TO DO: check AMOVL */
1112         if(samaddr(f, t))
1113                 return;
1114         gins(a, f, t);
1115 }
1116
1117 void
1118 doindex(Node *n)
1119 {
1120         Node nod, nod1;
1121         long v;
1122
1123 if(debug['Y'])
1124 prtree(n, "index");
1125
1126 if(n->left->complex >= FNX)
1127 print("botch in doindex\n");
1128
1129         regalloc(&nod, &qregnode, Z);
1130         v = constnode.vconst;
1131         cgen(n->right, &nod);
1132         idx.ptr = D_NONE;
1133         if(n->left->op == OCONST)
1134                 idx.ptr = D_CONST;
1135         else if(n->left->op == OREGISTER)
1136                 idx.ptr = n->left->reg;
1137         else if(n->left->op != OADDR) {
1138                 reg[D_BP]++;    // cant be used as a base
1139                 regalloc(&nod1, &qregnode, Z);
1140                 cgen(n->left, &nod1);
1141                 idx.ptr = nod1.reg;
1142                 regfree(&nod1);
1143                 reg[D_BP]--;
1144         }
1145         idx.reg = nod.reg;
1146         regfree(&nod);
1147         constnode.vconst = v;
1148 }
1149
1150 void
1151 gins(int a, Node *f, Node *t)
1152 {
1153
1154         if(f != Z && f->op == OINDEX)
1155                 doindex(f);
1156         if(t != Z && t->op == OINDEX)
1157                 doindex(t);
1158         nextpc();
1159         p->as = a;
1160         if(f != Z)
1161                 naddr(f, &p->from);
1162         if(t != Z)
1163                 naddr(t, &p->to);
1164         if(debug['g'])
1165                 print("%P\n", p);
1166 }
1167
1168 void
1169 gopcode(int o, Type *ty, Node *f, Node *t)
1170 {
1171         int a, et;
1172
1173         et = TLONG;
1174         if(ty != T)
1175                 et = ty->etype;
1176         if(debug['M']) {
1177                 if(f != Z && f->type != T)
1178                         print("gop: %O %O[%s],", o, f->op, tnames[et]);
1179                 else
1180                         print("gop: %O Z,", o);
1181                 if(t != Z && t->type != T)
1182                         print("%O[%s]\n", t->op, tnames[t->type->etype]);
1183                 else
1184                         print("Z\n");
1185         }
1186         a = AGOK;
1187         switch(o) {
1188         case OCOM:
1189                 a = ANOTL;
1190                 if(et == TCHAR || et == TUCHAR)
1191                         a = ANOTB;
1192                 if(et == TSHORT || et == TUSHORT)
1193                         a = ANOTW;
1194                 if(et == TVLONG || et == TUVLONG || et == TIND)
1195                         a = ANOTQ;
1196                 break;
1197
1198         case ONEG:
1199                 a = ANEGL;
1200                 if(et == TCHAR || et == TUCHAR)
1201                         a = ANEGB;
1202                 if(et == TSHORT || et == TUSHORT)
1203                         a = ANEGW;
1204                 if(et == TVLONG || et == TUVLONG || et == TIND)
1205                         a = ANEGQ;
1206                 break;
1207
1208         case OADDR:
1209                 a = ALEAQ;
1210                 break;
1211
1212         case OASADD:
1213         case OADD:
1214                 a = AADDL;
1215                 if(et == TCHAR || et == TUCHAR)
1216                         a = AADDB;
1217                 if(et == TSHORT || et == TUSHORT)
1218                         a = AADDW;
1219                 if(et == TVLONG || et == TUVLONG || et == TIND)
1220                         a = AADDQ;
1221                 if(et == TFLOAT)
1222                         a = AADDSS;
1223                 if(et == TDOUBLE)
1224                         a = AADDSD;
1225                 break;
1226
1227         case OASSUB:
1228         case OSUB:
1229                 a = ASUBL;
1230                 if(et == TCHAR || et == TUCHAR)
1231                         a = ASUBB;
1232                 if(et == TSHORT || et == TUSHORT)
1233                         a = ASUBW;
1234                 if(et == TVLONG || et == TUVLONG || et == TIND)
1235                         a = ASUBQ;
1236                 if(et == TFLOAT)
1237                         a = ASUBSS;
1238                 if(et == TDOUBLE)
1239                         a = ASUBSD;
1240                 break;
1241
1242         case OASOR:
1243         case OOR:
1244                 a = AORL;
1245                 if(et == TCHAR || et == TUCHAR)
1246                         a = AORB;
1247                 if(et == TSHORT || et == TUSHORT)
1248                         a = AORW;
1249                 if(et == TVLONG || et == TUVLONG || et == TIND)
1250                         a = AORQ;
1251                 break;
1252
1253         case OASAND:
1254         case OAND:
1255                 a = AANDL;
1256                 if(et == TCHAR || et == TUCHAR)
1257                         a = AANDB;
1258                 if(et == TSHORT || et == TUSHORT)
1259                         a = AANDW;
1260                 if(et == TVLONG || et == TUVLONG || et == TIND)
1261                         a = AANDQ;
1262                 break;
1263
1264         case OASXOR:
1265         case OXOR:
1266                 a = AXORL;
1267                 if(et == TCHAR || et == TUCHAR)
1268                         a = AXORB;
1269                 if(et == TSHORT || et == TUSHORT)
1270                         a = AXORW;
1271                 if(et == TVLONG || et == TUVLONG || et == TIND)
1272                         a = AXORQ;
1273                 break;
1274
1275         case OASLSHR:
1276         case OLSHR:
1277                 a = ASHRL;
1278                 if(et == TCHAR || et == TUCHAR)
1279                         a = ASHRB;
1280                 if(et == TSHORT || et == TUSHORT)
1281                         a = ASHRW;
1282                 if(et == TVLONG || et == TUVLONG || et == TIND)
1283                         a = ASHRQ;
1284                 break;
1285
1286         case OASASHR:
1287         case OASHR:
1288                 a = ASARL;
1289                 if(et == TCHAR || et == TUCHAR)
1290                         a = ASARB;
1291                 if(et == TSHORT || et == TUSHORT)
1292                         a = ASARW;
1293                 if(et == TVLONG || et == TUVLONG || et == TIND)
1294                         a = ASARQ;
1295                 break;
1296
1297         case OASASHL:
1298         case OASHL:
1299                 a = ASALL;
1300                 if(et == TCHAR || et == TUCHAR)
1301                         a = ASALB;
1302                 if(et == TSHORT || et == TUSHORT)
1303                         a = ASALW;
1304                 if(et == TVLONG || et == TUVLONG || et == TIND)
1305                         a = ASALQ;
1306                 break;
1307
1308         case OROL:
1309                 a = AROLL;
1310                 if(et == TCHAR || et == TUCHAR)
1311                         a = AROLB;
1312                 if(et == TSHORT || et == TUSHORT)
1313                         a = AROLW;
1314                 if(et == TVLONG || et == TUVLONG || et == TIND)
1315                         a = AROLQ;
1316                 break;
1317
1318         case OFUNC:
1319                 a = ACALL;
1320                 break;
1321
1322         case OASMUL:
1323         case OMUL:
1324                 if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1325                         t = Z;
1326                 a = AIMULL;
1327                 if(et == TVLONG || et == TUVLONG || et == TIND)
1328                         a = AIMULQ;
1329                 if(et == TFLOAT)
1330                         a = AMULSS;
1331                 if(et == TDOUBLE)
1332                         a = AMULSD;
1333                 break;
1334
1335         case OASMOD:
1336         case OMOD:
1337         case OASDIV:
1338         case ODIV:
1339                 a = AIDIVL;
1340                 if(et == TVLONG || et == TUVLONG || et == TIND)
1341                         a = AIDIVQ;
1342                 if(et == TFLOAT)
1343                         a = ADIVSS;
1344                 if(et == TDOUBLE)
1345                         a = ADIVSD;
1346                 break;
1347
1348         case OASLMUL:
1349         case OLMUL:
1350                 a = AMULL;
1351                 if(et == TVLONG || et == TUVLONG || et == TIND)
1352                         a = AMULQ;
1353                 break;
1354
1355         case OASLMOD:
1356         case OLMOD:
1357         case OASLDIV:
1358         case OLDIV:
1359                 a = ADIVL;
1360                 if(et == TVLONG || et == TUVLONG || et == TIND)
1361                         a = ADIVQ;
1362                 break;
1363
1364         case OEQ:
1365         case ONE:
1366         case OLT:
1367         case OLE:
1368         case OGE:
1369         case OGT:
1370         case OLO:
1371         case OLS:
1372         case OHS:
1373         case OHI:
1374                 a = ACMPL;
1375                 if(et == TCHAR || et == TUCHAR)
1376                         a = ACMPB;
1377                 if(et == TSHORT || et == TUSHORT)
1378                         a = ACMPW;
1379                 if(et == TVLONG || et == TUVLONG || et == TIND)
1380                         a = ACMPQ;
1381                 if(et == TFLOAT)
1382                         a = AUCOMISS;
1383                 if(et == TDOUBLE)
1384                         a = AUCOMISD;
1385                 gins(a, f, t);
1386                 switch(o) {
1387                 case OEQ:       a = AJEQ; break;
1388                 case ONE:       a = AJNE; break;
1389                 case OLT:       a = AJLT; break;
1390                 case OLE:       a = AJLE; break;
1391                 case OGE:       a = AJGE; break;
1392                 case OGT:       a = AJGT; break;
1393                 case OLO:       a = AJCS; break;
1394                 case OLS:       a = AJLS; break;
1395                 case OHS:       a = AJCC; break;
1396                 case OHI:       a = AJHI; break;
1397                 }
1398                 gins(a, Z, Z);
1399                 return;
1400         }
1401         if(a == AGOK)
1402                 diag(Z, "bad in gopcode %O", o);
1403         gins(a, f, t);
1404 }
1405
1406 int
1407 samaddr(Node *f, Node *t)
1408 {
1409         return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
1410 }
1411
1412 void
1413 gbranch(int o)
1414 {
1415         int a;
1416
1417         a = AGOK;
1418         switch(o) {
1419         case ORETURN:
1420                 a = ARET;
1421                 break;
1422         case OGOTO:
1423                 a = AJMP;
1424                 break;
1425         }
1426         nextpc();
1427         if(a == AGOK) {
1428                 diag(Z, "bad in gbranch %O",  o);
1429                 nextpc();
1430         }
1431         p->as = a;
1432 }
1433
1434 void
1435 patch(Prog *op, long pc)
1436 {
1437
1438         op->to.offset = pc;
1439         op->to.type = D_BRANCH;
1440 }
1441
1442 void
1443 gpseudo(int a, Sym *s, Node *n)
1444 {
1445
1446         nextpc();
1447         p->as = a;
1448         p->from.type = D_EXTERN;
1449         p->from.sym = s;
1450         p->from.scale = (profileflg ? 0 : NOPROF);
1451         if(s->class == CSTATIC)
1452                 p->from.type = D_STATIC;
1453         naddr(n, &p->to);
1454         if(a == ADATA || a == AGLOBL)
1455                 pc--;
1456 }
1457
1458 int
1459 sconst(Node *n)
1460 {
1461         long v;
1462
1463         if(n->op == OCONST && !typefd[n->type->etype]) {
1464                 v = n->vconst;
1465                 if(v >= -32766L && v < 32766L)
1466                         return 1;
1467         }
1468         return 0;
1469 }
1470
1471 long
1472 exreg(Type *t)
1473 {
1474         long o;
1475
1476         if(typechlpv[t->etype]) {
1477                 if(exregoffset <= REGEXT-4)
1478                         return 0;
1479                 o = exregoffset;
1480                 exregoffset--;
1481                 return o;
1482         }
1483         return 0;
1484 }
1485
1486 schar   ewidth[NTYPE] =
1487 {
1488         -1,             /*[TXXX]*/      
1489         SZ_CHAR,        /*[TCHAR]*/     
1490         SZ_CHAR,        /*[TUCHAR]*/
1491         SZ_SHORT,       /*[TSHORT]*/
1492         SZ_SHORT,       /*[TUSHORT]*/
1493         SZ_INT,         /*[TINT]*/
1494         SZ_INT,         /*[TUINT]*/
1495         SZ_LONG,        /*[TLONG]*/
1496         SZ_LONG,        /*[TULONG]*/
1497         SZ_VLONG,       /*[TVLONG]*/
1498         SZ_VLONG,       /*[TUVLONG]*/
1499         SZ_FLOAT,       /*[TFLOAT]*/
1500         SZ_DOUBLE,      /*[TDOUBLE]*/
1501         SZ_IND,         /*[TIND]*/
1502         0,              /*[TFUNC]*/
1503         -1,             /*[TARRAY]*/
1504         0,              /*[TVOID]*/
1505         -1,             /*[TSTRUCT]*/
1506         -1,             /*[TUNION]*/
1507         SZ_INT,         /*[TENUM]*/
1508 };
1509 long    ncast[NTYPE] =
1510 {
1511         0,                              /*[TXXX]*/
1512         BCHAR|BUCHAR,                   /*[TCHAR]*/
1513         BCHAR|BUCHAR,                   /*[TUCHAR]*/    
1514         BSHORT|BUSHORT,                 /*[TSHORT]*/
1515         BSHORT|BUSHORT,                 /*[TUSHORT]*/
1516         BINT|BUINT|BLONG|BULONG,        /*[TINT]*/              
1517         BINT|BUINT|BLONG|BULONG,        /*[TUINT]*/
1518         BINT|BUINT|BLONG|BULONG,        /*[TLONG]*/
1519         BINT|BUINT|BLONG|BULONG,        /*[TULONG]*/
1520         BVLONG|BUVLONG|BIND,                    /*[TVLONG]*/
1521         BVLONG|BUVLONG|BIND,                    /*[TUVLONG]*/
1522         BFLOAT,                         /*[TFLOAT]*/
1523         BDOUBLE,                        /*[TDOUBLE]*/
1524         BVLONG|BUVLONG|BIND,            /*[TIND]*/
1525         0,                              /*[TFUNC]*/
1526         0,                              /*[TARRAY]*/
1527         0,                              /*[TVOID]*/
1528         BSTRUCT,                        /*[TSTRUCT]*/
1529         BUNION,                         /*[TUNION]*/
1530         0,                              /*[TENUM]*/
1531 };