]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/6c/txt.c
disk/format: implement long name support
[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                         i ^= 7;
348                         if(reg[i] == 0 && !resvreg[i])
349                                 goto out;
350                         i ^= 7;
351                 }
352                 diag(tn, "out of fixed registers");
353                 goto err;
354
355         case TFLOAT:
356         case TDOUBLE:
357                 if(o != Z && o->op == OREGISTER) {
358                         i = o->reg;
359                         if(i >= D_X0 && i <= D_X7)
360                                 goto out;
361                 }
362                 for(i=D_X0; i<=D_X7; i++)
363                         if(reg[i] == 0 && !resvreg[i])
364                                 goto out;
365                 diag(tn, "out of float registers");
366                 goto out;
367         }
368         diag(tn, "unknown type in regalloc: %T", tn->type);
369 err:
370         i = 0;
371 out:
372         if(i)
373                 reg[i]++;
374         nodreg(n, tn, i);
375 }
376
377 void
378 regialloc(Node *n, Node *tn, Node *o)
379 {
380         Node nod;
381
382         nod = *tn;
383         nod.type = types[TIND];
384         regalloc(n, &nod, o);
385 }
386
387 void
388 regfree(Node *n)
389 {
390         int i;
391
392         i = 0;
393         if(n->op != OREGISTER && n->op != OINDREG)
394                 goto err;
395         i = n->reg;
396         if(i < 0 || i >= sizeof(reg))
397                 goto err;
398         if(reg[i] <= 0)
399                 goto err;
400         reg[i]--;
401         return;
402 err:
403         diag(n, "error in regfree: %R", i);
404 }
405
406 void
407 regsalloc(Node *n, Node *nn)
408 {
409         cursafe = align(cursafe, nn->type, Aaut3);
410         maxargsafe = maxround(maxargsafe, cursafe+curarg);
411         *n = *nodsafe;
412         n->xoffset = -(stkoff + cursafe);
413         n->type = nn->type;
414         n->etype = nn->type->etype;
415         n->lineno = nn->lineno;
416 }
417
418 void
419 regaalloc1(Node *n, Node *nn)
420 {
421         nodreg(n, nn, REGARG);
422         reg[REGARG]++;
423         curarg = align(curarg, nn->type, Aarg1);
424         curarg = align(curarg, nn->type, Aarg2);
425         maxargsafe = maxround(maxargsafe, cursafe+curarg);
426 }
427
428 void
429 regaalloc(Node *n, Node *nn)
430 {
431         curarg = align(curarg, nn->type, Aarg1);
432         *n = *nn;
433         n->op = OINDREG;
434         n->reg = REGSP;
435         n->xoffset = curarg;
436         n->complex = 0;
437         n->addable = 20;
438         curarg = align(curarg, nn->type, Aarg2);
439         maxargsafe = maxround(maxargsafe, cursafe+curarg);
440 }
441
442 void
443 regind(Node *n, Node *nn)
444 {
445
446         if(n->op != OREGISTER) {
447                 diag(n, "regind not OREGISTER");
448                 return;
449         }
450         n->op = OINDREG;
451         n->type = nn->type;
452 }
453
454 void
455 naddr(Node *n, Adr *a)
456 {
457         long v;
458
459         a->type = D_NONE;
460         if(n == Z)
461                 return;
462         switch(n->op) {
463         default:
464         bad:
465                 diag(n, "bad in naddr: %O %D", n->op, a);
466                 break;
467
468         case OREGISTER:
469                 a->type = n->reg;
470                 a->sym = S;
471                 break;
472
473
474         case OIND:
475                 naddr(n->left, a);
476                 if(a->type >= D_AX && a->type <= D_R15)
477                         a->type += D_INDIR;
478                 else
479                 if(a->type == D_CONST)
480                         a->type = D_NONE+D_INDIR;
481                 else
482                 if(a->type == D_ADDR) {
483                         a->type = a->index;
484                         a->index = D_NONE;
485                 } else
486                         goto bad;
487                 break;
488
489         case OINDEX:
490                 a->type = idx.ptr;
491                 if(n->left->op == OADDR || n->left->op == OCONST)
492                         naddr(n->left, a);
493                 if(a->type >= D_AX && a->type <= D_R15)
494                         a->type += D_INDIR;
495                 else
496                 if(a->type == D_CONST)
497                         a->type = D_NONE+D_INDIR;
498                 else
499                 if(a->type == D_ADDR) {
500                         a->type = a->index;
501                         a->index = D_NONE;
502                 } else
503                         goto bad;
504                 a->index = idx.reg;
505                 a->scale = n->scale;
506                 a->offset += n->xoffset;
507                 break;
508
509         case OINDREG:
510                 a->type = n->reg+D_INDIR;
511                 a->sym = S;
512                 a->offset = n->xoffset;
513                 break;
514
515         case ONAME:
516                 a->etype = n->etype;
517                 a->type = D_STATIC;
518                 a->sym = n->sym;
519                 a->offset = n->xoffset;
520                 if(n->class == CSTATIC)
521                         break;
522                 if(n->class == CEXTERN || n->class == CGLOBL) {
523                         a->type = D_EXTERN;
524                         break;
525                 }
526                 if(n->class == CAUTO) {
527                         a->type = D_AUTO;
528                         break;
529                 }
530                 if(n->class == CPARAM) {
531                         a->type = D_PARAM;
532                         break;
533                 }
534                 goto bad;
535
536         case OCONST:
537                 if(typefd[n->type->etype]) {
538                         a->type = D_FCONST;
539                         a->dval = n->fconst;
540                         break;
541                 }
542                 a->sym = S;
543                 a->type = D_CONST;
544                 if(typev[n->type->etype] || n->type->etype == TIND)
545                         a->offset = n->vconst;
546                 else
547                         a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
548                 break;
549
550         case OADDR:
551                 naddr(n->left, a);
552                 if(a->type >= D_INDIR) {
553                         a->type -= D_INDIR;
554                         break;
555                 }
556                 if(a->type == D_EXTERN || a->type == D_STATIC ||
557                    a->type == D_AUTO || a->type == D_PARAM)
558                         if(a->index == D_NONE) {
559                                 a->index = a->type;
560                                 a->type = D_ADDR;
561                                 break;
562                         }
563                 goto bad;
564
565         case OADD:
566                 if(n->right->op == OCONST) {
567                         v = n->right->vconst;
568                         naddr(n->left, a);
569                 } else
570                 if(n->left->op == OCONST) {
571                         v = n->left->vconst;
572                         naddr(n->right, a);
573                 } else
574                         goto bad;
575                 a->offset += v;
576                 break;
577
578         }
579 }
580
581 void
582 gcmp(int op, Node *n, vlong val)
583 {
584         Node *cn, nod;
585
586         cn = nodgconst(val, n->type);
587         if(!immconst(cn)){
588                 regalloc(&nod, n, Z);
589                 gmove(cn, &nod);
590                 gopcode(op, n->type, n, &nod);
591                 regfree(&nod);
592         }else
593                 gopcode(op, n->type, n, cn);
594 }
595
596 #define CASE(a,b)       ((a<<8)|(b<<0))
597
598 void
599 gmove(Node *f, Node *t)
600 {
601         int ft, tt, t64, a;
602         Node nod, nod1, nod2, nod3;
603         Prog *p1, *p2;
604
605         ft = f->type->etype;
606         tt = t->type->etype;
607         t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
608         if(debug['M'])
609                 print("gop: %O %O[%s],%O[%s]\n", OAS,
610                         f->op, tnames[ft], t->op, tnames[tt]);
611         if(typefd[ft] && f->op == OCONST) {
612                 /* TO DO: pick up special constants, possibly preloaded */
613                 if(f->fconst == 0.0){
614                         regalloc(&nod, t, t);
615                         gins(AXORPD, &nod, &nod);
616                         gmove(&nod, t);
617                         regfree(&nod);
618                         return;
619                 }
620         }
621 /*
622  * load
623  */
624         if(f->op == ONAME || f->op == OINDREG ||
625            f->op == OIND || f->op == OINDEX)
626         switch(ft) {
627         case TCHAR:
628                 a = AMOVBLSX;
629                 if(t64)
630                         a = AMOVBQSX;
631                 goto ld;
632         case TUCHAR:
633                 a = AMOVBLZX;
634                 if(t64)
635                         a = AMOVBQZX;
636                 goto ld;
637         case TSHORT:
638                 a = AMOVWLSX;
639                 if(t64)
640                         a = AMOVWQSX;
641                 goto ld;
642         case TUSHORT:
643                 a = AMOVWLZX;
644                 if(t64)
645                         a = AMOVWQZX;
646                 goto ld;
647         case TINT:
648         case TLONG:
649                 if(typefd[tt]) {
650                         regalloc(&nod, t, t);
651                         if(tt == TDOUBLE)
652                                 a = ACVTSL2SD;
653                         else
654                                 a = ACVTSL2SS;
655                         gins(a, f, &nod);
656                         gmove(&nod, t);
657                         regfree(&nod);
658                         return;
659                 }
660                 a = AMOVL;
661                 if(t64)
662                         a = AMOVLQSX;
663                 goto ld;
664         case TUINT:
665         case TULONG:
666                 a = AMOVL;
667                 if(t64)
668                         a = AMOVLQZX;   /* could probably use plain MOVL */
669                 goto ld;
670         case TVLONG:
671                 if(typefd[tt]) {
672                         regalloc(&nod, t, t);
673                         if(tt == TDOUBLE)
674                                 a = ACVTSQ2SD;
675                         else
676                                 a = ACVTSQ2SS;
677                         gins(a, f, &nod);
678                         gmove(&nod, t);
679                         regfree(&nod);
680                         return;
681                 }
682         case TUVLONG:
683         case TIND:
684                 a = AMOVQ;
685         ld:
686                 regalloc(&nod, f, t);
687                 gins(a, f, &nod);
688                 gmove(&nod, t);
689                 regfree(&nod);
690                 return;
691
692         case TFLOAT:
693                 a = AMOVSS;
694                 goto ld;
695         case TDOUBLE:
696                 a = AMOVSD;
697                 goto ld;
698         }
699
700 /*
701  * store
702  */
703         if(t->op == ONAME || t->op == OINDREG ||
704            t->op == OIND || t->op == OINDEX)
705         switch(tt) {
706         case TCHAR:
707         case TUCHAR:
708                 a = AMOVB;      goto st;
709         case TSHORT:
710         case TUSHORT:
711                 a = AMOVW;      goto st;
712         case TINT:
713         case TUINT:
714         case TLONG:
715         case TULONG:
716                 a = AMOVL;      goto st;
717         case TVLONG:
718         case TUVLONG:
719         case TIND:
720                 a = AMOVQ;      goto st;
721
722         st:
723                 if(f->op == OCONST) {
724                         gins(a, f, t);
725                         return;
726                 }
727         fst:
728                 regalloc(&nod, t, f);
729                 gmove(f, &nod);
730                 gins(a, &nod, t);
731                 regfree(&nod);
732                 return;
733
734         case TFLOAT:
735                 a = AMOVSS;
736                 goto fst;
737         case TDOUBLE:
738                 a = AMOVSD;
739                 goto fst;
740         }
741
742 /*
743  * convert
744  */
745         switch(CASE(ft,tt)) {
746         default:
747 /*
748  * integer to integer
749  ********
750                 a = AGOK;       break;
751
752         case CASE(      TCHAR,  TCHAR):
753         case CASE(      TUCHAR, TCHAR):
754         case CASE(      TSHORT, TCHAR):
755         case CASE(      TUSHORT,TCHAR):
756         case CASE(      TINT,   TCHAR):
757         case CASE(      TUINT,  TCHAR):
758         case CASE(      TLONG,  TCHAR):
759         case CASE(      TULONG, TCHAR):
760
761         case CASE(      TCHAR,  TUCHAR):
762         case CASE(      TUCHAR, TUCHAR):
763         case CASE(      TSHORT, TUCHAR):
764         case CASE(      TUSHORT,TUCHAR):
765         case CASE(      TINT,   TUCHAR):
766         case CASE(      TUINT,  TUCHAR):
767         case CASE(      TLONG,  TUCHAR):
768         case CASE(      TULONG, TUCHAR):
769
770         case CASE(      TSHORT, TSHORT):
771         case CASE(      TUSHORT,TSHORT):
772         case CASE(      TINT,   TSHORT):
773         case CASE(      TUINT,  TSHORT):
774         case CASE(      TLONG,  TSHORT):
775         case CASE(      TULONG, TSHORT):
776
777         case CASE(      TSHORT, TUSHORT):
778         case CASE(      TUSHORT,TUSHORT):
779         case CASE(      TINT,   TUSHORT):
780         case CASE(      TUINT,  TUSHORT):
781         case CASE(      TLONG,  TUSHORT):
782         case CASE(      TULONG, TUSHORT):
783
784         case CASE(      TINT,   TINT):
785         case CASE(      TUINT,  TINT):
786         case CASE(      TLONG,  TINT):
787         case CASE(      TULONG, TINT)::
788
789         case CASE(      TINT,   TUINT):
790         case CASE(      TUINT,  TUINT):
791         case CASE(      TLONG,  TUINT):
792         case CASE(      TULONG, TUINT):
793  *****/
794                 a = AMOVL;
795                 break;
796
797         case CASE(      TINT,   TIND):
798         case CASE(      TINT,   TVLONG):
799         case CASE(      TINT,   TUVLONG):
800         case CASE(      TLONG,  TIND):
801         case CASE(      TLONG,  TVLONG):
802         case CASE(      TLONG,  TUVLONG):
803                 a = AMOVLQSX;
804                 if(f->op == OCONST) {
805                         f->vconst &= (uvlong)0xffffffffU;
806                         if(f->vconst & 0x80000000)
807                                 f->vconst |= (vlong)0xffffffff << 32;
808                         a = AMOVQ;
809                 }
810                 break;
811
812         case CASE(      TUINT,  TIND):
813         case CASE(      TUINT,  TVLONG):
814         case CASE(      TUINT,  TUVLONG):
815         case CASE(      TULONG, TVLONG):
816         case CASE(      TULONG, TUVLONG):
817         case CASE(      TULONG, TIND):
818                 a = AMOVLQZX;
819                 if(f->op == OCONST) {
820                         f->vconst &= (uvlong)0xffffffffU;
821                         a = AMOVQ;
822                 }
823                 break;
824
825         case CASE(      TIND,   TCHAR):
826         case CASE(      TIND,   TUCHAR):
827         case CASE(      TIND,   TSHORT):
828         case CASE(      TIND,   TUSHORT):
829         case CASE(      TIND,   TINT):
830         case CASE(      TIND,   TUINT):
831         case CASE(      TIND,   TLONG):
832         case CASE(      TIND,   TULONG):
833         case CASE(      TVLONG, TCHAR):
834         case CASE(      TVLONG, TUCHAR):
835         case CASE(      TVLONG, TSHORT):
836         case CASE(      TVLONG, TUSHORT):
837         case CASE(      TVLONG, TINT):
838         case CASE(      TVLONG, TUINT):
839         case CASE(      TVLONG, TLONG):
840         case CASE(      TVLONG, TULONG):
841         case CASE(      TUVLONG,        TCHAR):
842         case CASE(      TUVLONG,        TUCHAR):
843         case CASE(      TUVLONG,        TSHORT):
844         case CASE(      TUVLONG,        TUSHORT):
845         case CASE(      TUVLONG,        TINT):
846         case CASE(      TUVLONG,        TUINT):
847         case CASE(      TUVLONG,        TLONG):
848         case CASE(      TUVLONG,        TULONG):
849                 a = AMOVQL;
850                 if(f->op == OCONST) {
851                         f->vconst &= 0xffffffffU;
852                         a = AMOVL;
853                 }
854                 break;
855
856         case CASE(      TIND,   TIND):
857         case CASE(      TIND,   TVLONG):
858         case CASE(      TIND,   TUVLONG):
859         case CASE(      TVLONG, TIND):
860         case CASE(      TVLONG, TVLONG):
861         case CASE(      TVLONG, TUVLONG):
862         case CASE(      TUVLONG,        TIND):
863         case CASE(      TUVLONG,        TVLONG):
864         case CASE(      TUVLONG,        TUVLONG):
865                 a = AMOVQ;
866                 break;
867
868         case CASE(      TSHORT, TINT):
869         case CASE(      TSHORT, TUINT):
870         case CASE(      TSHORT, TLONG):
871         case CASE(      TSHORT, TULONG):
872                 a = AMOVWLSX;
873                 if(f->op == OCONST) {
874                         f->vconst &= 0xffff;
875                         if(f->vconst & 0x8000)
876                                 f->vconst |= 0xffff0000;
877                         a = AMOVL;
878                 }
879                 break;
880
881         case CASE(      TSHORT, TVLONG):
882         case CASE(      TSHORT, TUVLONG):
883         case CASE(      TSHORT, TIND):
884                 a = AMOVWQSX;
885                 if(f->op == OCONST) {
886                         f->vconst &= 0xffff;
887                         if(f->vconst & 0x8000){
888                                 f->vconst |= 0xffff0000;
889                                 f->vconst |= (vlong)~0 << 32;
890                         }
891                         a = AMOVL;
892                 }
893                 break;
894
895         case CASE(      TUSHORT,TINT):
896         case CASE(      TUSHORT,TUINT):
897         case CASE(      TUSHORT,TLONG):
898         case CASE(      TUSHORT,TULONG):
899                 a = AMOVWLZX;
900                 if(f->op == OCONST) {
901                         f->vconst &= 0xffff;
902                         a = AMOVL;
903                 }
904                 break;
905
906         case CASE(      TUSHORT,TVLONG):
907         case CASE(      TUSHORT,TUVLONG):
908         case CASE(      TUSHORT,TIND):
909                 a = AMOVWQZX;
910                 if(f->op == OCONST) {
911                         f->vconst &= 0xffff;
912                         a = AMOVL;      /* MOVL also zero-extends to 64 bits */
913                 }
914                 break;
915
916         case CASE(      TCHAR,  TSHORT):
917         case CASE(      TCHAR,  TUSHORT):
918         case CASE(      TCHAR,  TINT):
919         case CASE(      TCHAR,  TUINT):
920         case CASE(      TCHAR,  TLONG):
921         case CASE(      TCHAR,  TULONG):
922                 a = AMOVBLSX;
923                 if(f->op == OCONST) {
924                         f->vconst &= 0xff;
925                         if(f->vconst & 0x80)
926                                 f->vconst |= 0xffffff00;
927                         a = AMOVL;
928                 }
929                 break;
930
931         case CASE(      TCHAR,  TVLONG):
932         case CASE(      TCHAR,  TUVLONG):
933         case CASE(      TCHAR,  TIND):
934                 a = AMOVBQSX;
935                 if(f->op == OCONST) {
936                         f->vconst &= 0xff;
937                         if(f->vconst & 0x80){
938                                 f->vconst |= 0xffffff00;
939                                 f->vconst |= (vlong)~0 << 32;
940                         }
941                         a = AMOVQ;
942                 }
943                 break;
944
945         case CASE(      TUCHAR, TSHORT):
946         case CASE(      TUCHAR, TUSHORT):
947         case CASE(      TUCHAR, TINT):
948         case CASE(      TUCHAR, TUINT):
949         case CASE(      TUCHAR, TLONG):
950         case CASE(      TUCHAR, TULONG):
951                 a = AMOVBLZX;
952                 if(f->op == OCONST) {
953                         f->vconst &= 0xff;
954                         a = AMOVL;
955                 }
956                 break;
957
958         case CASE(      TUCHAR, TVLONG):
959         case CASE(      TUCHAR, TUVLONG):
960         case CASE(      TUCHAR, TIND):
961                 a = AMOVBQZX;
962                 if(f->op == OCONST) {
963                         f->vconst &= 0xff;
964                         a = AMOVL;      /* zero-extends to 64-bits */
965                 }
966                 break;
967
968 /*
969  * float to fix
970  */
971         case CASE(      TFLOAT, TCHAR):
972         case CASE(      TFLOAT, TUCHAR):
973         case CASE(      TFLOAT, TSHORT):
974         case CASE(      TFLOAT, TUSHORT):
975         case CASE(      TFLOAT, TINT):
976         case CASE(      TFLOAT, TUINT):
977         case CASE(      TFLOAT, TLONG):
978         case CASE(      TFLOAT, TULONG):
979         case CASE(      TFLOAT, TVLONG):
980         case CASE(      TFLOAT, TUVLONG):
981         case CASE(      TFLOAT, TIND):
982
983         case CASE(      TDOUBLE,TCHAR):
984         case CASE(      TDOUBLE,TUCHAR):
985         case CASE(      TDOUBLE,TSHORT):
986         case CASE(      TDOUBLE,TUSHORT):
987         case CASE(      TDOUBLE,TINT):
988         case CASE(      TDOUBLE,TUINT):
989         case CASE(      TDOUBLE,TLONG):
990         case CASE(      TDOUBLE,TULONG):
991         case CASE(      TDOUBLE,TVLONG):
992         case CASE(      TDOUBLE,TUVLONG):
993         case CASE(      TDOUBLE,TIND):
994                 regalloc(&nod, t, Z);
995                 if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
996                         if(ft == TFLOAT)
997                                 a = ACVTTSS2SQ;
998                         else
999                                 a = ACVTTSD2SQ;
1000                 }else{
1001                         if(ft == TFLOAT)
1002                                 a = ACVTTSS2SL;
1003                         else
1004                                 a = ACVTTSD2SL;
1005                 }
1006                 gins(a, f, &nod);
1007                 gmove(&nod, t);
1008                 regfree(&nod);
1009                 return;
1010
1011 /*
1012  * ulong to float
1013  */
1014         case CASE(      TUVLONG,        TDOUBLE):
1015         case CASE(      TUVLONG,        TFLOAT):
1016                 a = ACVTSQ2SS;
1017                 if(tt == TDOUBLE)
1018                         a = ACVTSQ2SD;
1019                 regalloc(&nod, f, f);
1020                 gmove(f, &nod);
1021                 regalloc(&nod1, t, t);
1022                 gins(ACMPQ, &nod, nodconst(0));
1023                 gins(AJLT, Z, Z);
1024                 p1 = p;
1025                 gins(a, &nod, &nod1);
1026                 gins(AJMP, Z, Z);
1027                 p2 = p;
1028                 patch(p1, pc);
1029                 regalloc(&nod2, f, Z);
1030                 regalloc(&nod3, f, Z);
1031                 gmove(&nod, &nod2);
1032                 gins(ASHRQ, nodconst(1), &nod2);
1033                 gmove(&nod, &nod3);
1034                 gins(AANDL, nodconst(1), &nod3);
1035                 gins(AORQ, &nod3, &nod2);
1036                 gins(a, &nod2, &nod1);
1037                 gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
1038                 regfree(&nod2);
1039                 regfree(&nod3);
1040                 patch(p2, pc);
1041                 regfree(&nod);
1042                 regfree(&nod1);
1043                 return;
1044
1045         case CASE(      TULONG, TDOUBLE):
1046         case CASE(      TUINT,  TDOUBLE):
1047         case CASE(      TULONG, TFLOAT):
1048         case CASE(      TUINT,  TFLOAT):
1049                 a = ACVTSQ2SS;
1050                 if(tt == TDOUBLE)
1051                         a = ACVTSQ2SD;
1052                 regalloc(&nod, f, f);
1053                 gins(AMOVLQZX, f, &nod);
1054                 regalloc(&nod1, t, t);
1055                 gins(a, &nod, &nod1);
1056                 gmove(&nod1, t);
1057                 regfree(&nod);
1058                 regfree(&nod1);
1059                 return;
1060
1061 /*
1062  * fix to float
1063  */
1064         case CASE(      TCHAR,  TFLOAT):
1065         case CASE(      TUCHAR, TFLOAT):
1066         case CASE(      TSHORT, TFLOAT):
1067         case CASE(      TUSHORT,TFLOAT):
1068         case CASE(      TINT,   TFLOAT):
1069         case CASE(      TLONG,  TFLOAT):
1070         case CASE(      TVLONG, TFLOAT):
1071         case CASE(      TIND,   TFLOAT):
1072
1073         case CASE(      TCHAR,  TDOUBLE):
1074         case CASE(      TUCHAR, TDOUBLE):
1075         case CASE(      TSHORT, TDOUBLE):
1076         case CASE(      TUSHORT,TDOUBLE):
1077         case CASE(      TINT,   TDOUBLE):
1078         case CASE(      TLONG,  TDOUBLE):
1079         case CASE(      TVLONG, TDOUBLE):
1080         case CASE(      TIND,   TDOUBLE):
1081                 regalloc(&nod, t, t);
1082                 if(ewidth[ft] == SZ_VLONG){
1083                         if(tt == TFLOAT)
1084                                 a = ACVTSQ2SS;
1085                         else
1086                                 a = ACVTSQ2SD;
1087                 }else{
1088                         if(tt == TFLOAT)
1089                                 a = ACVTSL2SS;
1090                         else
1091                                 a = ACVTSL2SD;
1092                 }
1093                 gins(a, f, &nod);
1094                 gmove(&nod, t);
1095                 regfree(&nod);
1096                 return;
1097
1098 /*
1099  * float to float
1100  */
1101         case CASE(      TFLOAT, TFLOAT):
1102                 a = AMOVSS;
1103                 break;
1104         case CASE(      TDOUBLE,TFLOAT):
1105                 a = ACVTSD2SS;
1106                 break;
1107         case CASE(      TFLOAT, TDOUBLE):
1108                 a = ACVTSS2SD;
1109                 break;
1110         case CASE(      TDOUBLE,TDOUBLE):
1111                 a = AMOVSD;
1112                 break;
1113         }
1114         if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])  /* TO DO: check AMOVL */
1115         if(samaddr(f, t))
1116                 return;
1117         gins(a, f, t);
1118 }
1119
1120 static int
1121 regused(Node *n, int r)
1122 {
1123         if(n == nil)
1124                 return 0;
1125         if(isreg(n, r))
1126                 return 1;
1127         return regused(n->left, r) || regused(n->right, r);
1128 }
1129
1130 void
1131 doindex(Node *n, Node *o)
1132 {
1133         Node nod, nod1;
1134         long v;
1135
1136 if(debug['Y'])
1137 prtree(n, "index");
1138
1139 if(n->left->complex >= FNX)
1140 print("botch in doindex\n");
1141
1142         if(n->right->op == OREGISTER)
1143                 o = n->right;
1144         else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
1145                 o = Z;
1146         regalloc(&nod, &qregnode, o);
1147         v = constnode.vconst;
1148         cgen(n->right, &nod);
1149         idx.ptr = D_NONE;
1150         if(n->left->op == OCONST)
1151                 idx.ptr = D_CONST;
1152         else if(n->left->op == OREGISTER)
1153                 idx.ptr = n->left->reg;
1154         else if(n->left->op != OADDR) {
1155                 reg[D_BP]++;    // cant be used as a base
1156                 reg[D_R13]++;
1157                 regalloc(&nod1, &qregnode, Z);
1158                 cgen(n->left, &nod1);
1159                 idx.ptr = nod1.reg;
1160                 regfree(&nod1);
1161                 reg[D_BP]--;
1162                 reg[D_R13]--;
1163         }
1164         idx.reg = nod.reg;
1165         regfree(&nod);
1166         constnode.vconst = v;
1167 }
1168
1169 void
1170 gins(int a, Node *f, Node *t)
1171 {
1172
1173         if(f != Z && f->op == OINDEX)
1174                 doindex(f, a == AMOVL || a == ALEAL
1175                         || a == AMOVQ || a == ALEAQ
1176                         || a == AMOVBLSX || a == AMOVBLZX
1177                         || a == AMOVBQSX || a == AMOVBQZX
1178                         || a == AMOVWLSX || a == AMOVWLZX
1179                         || a == AMOVWQSX || a == AMOVWQZX ? t : Z);
1180         if(t != Z && t->op == OINDEX)
1181                 doindex(t, Z);
1182         nextpc();
1183         p->as = a;
1184         if(f != Z)
1185                 naddr(f, &p->from);
1186         if(t != Z)
1187                 naddr(t, &p->to);
1188         if(debug['g'])
1189                 print("%P\n", p);
1190 }
1191
1192 void
1193 gopcode(int o, Type *ty, Node *f, Node *t)
1194 {
1195         int a, et;
1196
1197         et = TLONG;
1198         if(ty != T)
1199                 et = ty->etype;
1200         if(debug['M']) {
1201                 if(f != Z && f->type != T)
1202                         print("gop: %O %O[%s],", o, f->op, tnames[et]);
1203                 else
1204                         print("gop: %O Z,", o);
1205                 if(t != Z && t->type != T)
1206                         print("%O[%s]\n", t->op, tnames[t->type->etype]);
1207                 else
1208                         print("Z\n");
1209         }
1210         a = AGOK;
1211         switch(o) {
1212         case OCOM:
1213                 a = ANOTL;
1214                 if(et == TCHAR || et == TUCHAR)
1215                         a = ANOTB;
1216                 if(et == TSHORT || et == TUSHORT)
1217                         a = ANOTW;
1218                 if(et == TVLONG || et == TUVLONG || et == TIND)
1219                         a = ANOTQ;
1220                 break;
1221
1222         case ONEG:
1223                 a = ANEGL;
1224                 if(et == TCHAR || et == TUCHAR)
1225                         a = ANEGB;
1226                 if(et == TSHORT || et == TUSHORT)
1227                         a = ANEGW;
1228                 if(et == TVLONG || et == TUVLONG || et == TIND)
1229                         a = ANEGQ;
1230                 break;
1231
1232         case OADDR:
1233                 a = ALEAQ;
1234                 break;
1235
1236         case OASADD:
1237         case OADD:
1238                 a = AADDL;
1239                 if(et == TCHAR || et == TUCHAR)
1240                         a = AADDB;
1241                 if(et == TSHORT || et == TUSHORT)
1242                         a = AADDW;
1243                 if(et == TVLONG || et == TUVLONG || et == TIND)
1244                         a = AADDQ;
1245                 if(et == TFLOAT)
1246                         a = AADDSS;
1247                 if(et == TDOUBLE)
1248                         a = AADDSD;
1249                 break;
1250
1251         case OASSUB:
1252         case OSUB:
1253                 a = ASUBL;
1254                 if(et == TCHAR || et == TUCHAR)
1255                         a = ASUBB;
1256                 if(et == TSHORT || et == TUSHORT)
1257                         a = ASUBW;
1258                 if(et == TVLONG || et == TUVLONG || et == TIND)
1259                         a = ASUBQ;
1260                 if(et == TFLOAT)
1261                         a = ASUBSS;
1262                 if(et == TDOUBLE)
1263                         a = ASUBSD;
1264                 break;
1265
1266         case OASOR:
1267         case OOR:
1268                 a = AORL;
1269                 if(et == TCHAR || et == TUCHAR)
1270                         a = AORB;
1271                 if(et == TSHORT || et == TUSHORT)
1272                         a = AORW;
1273                 if(et == TVLONG || et == TUVLONG || et == TIND)
1274                         a = AORQ;
1275                 break;
1276
1277         case OASAND:
1278         case OAND:
1279                 a = AANDL;
1280                 if(et == TCHAR || et == TUCHAR)
1281                         a = AANDB;
1282                 if(et == TSHORT || et == TUSHORT)
1283                         a = AANDW;
1284                 if(et == TVLONG || et == TUVLONG || et == TIND)
1285                         a = AANDQ;
1286                 break;
1287
1288         case OASXOR:
1289         case OXOR:
1290                 a = AXORL;
1291                 if(et == TCHAR || et == TUCHAR)
1292                         a = AXORB;
1293                 if(et == TSHORT || et == TUSHORT)
1294                         a = AXORW;
1295                 if(et == TVLONG || et == TUVLONG || et == TIND)
1296                         a = AXORQ;
1297                 break;
1298
1299         case OASLSHR:
1300         case OLSHR:
1301                 a = ASHRL;
1302                 if(et == TCHAR || et == TUCHAR)
1303                         a = ASHRB;
1304                 if(et == TSHORT || et == TUSHORT)
1305                         a = ASHRW;
1306                 if(et == TVLONG || et == TUVLONG || et == TIND)
1307                         a = ASHRQ;
1308                 break;
1309
1310         case OASASHR:
1311         case OASHR:
1312                 a = ASARL;
1313                 if(et == TCHAR || et == TUCHAR)
1314                         a = ASARB;
1315                 if(et == TSHORT || et == TUSHORT)
1316                         a = ASARW;
1317                 if(et == TVLONG || et == TUVLONG || et == TIND)
1318                         a = ASARQ;
1319                 break;
1320
1321         case OASASHL:
1322         case OASHL:
1323                 a = ASALL;
1324                 if(et == TCHAR || et == TUCHAR)
1325                         a = ASALB;
1326                 if(et == TSHORT || et == TUSHORT)
1327                         a = ASALW;
1328                 if(et == TVLONG || et == TUVLONG || et == TIND)
1329                         a = ASALQ;
1330                 break;
1331
1332         case OROL:
1333                 a = AROLL;
1334                 if(et == TCHAR || et == TUCHAR)
1335                         a = AROLB;
1336                 if(et == TSHORT || et == TUSHORT)
1337                         a = AROLW;
1338                 if(et == TVLONG || et == TUVLONG || et == TIND)
1339                         a = AROLQ;
1340                 break;
1341
1342         case OFUNC:
1343                 a = ACALL;
1344                 break;
1345
1346         case OASMUL:
1347         case OMUL:
1348                 if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1349                         t = Z;
1350                 a = AIMULL;
1351                 if(et == TVLONG || et == TUVLONG || et == TIND)
1352                         a = AIMULQ;
1353                 if(et == TFLOAT)
1354                         a = AMULSS;
1355                 if(et == TDOUBLE)
1356                         a = AMULSD;
1357                 break;
1358
1359         case OASMOD:
1360         case OMOD:
1361         case OASDIV:
1362         case ODIV:
1363                 a = AIDIVL;
1364                 if(et == TVLONG || et == TUVLONG || et == TIND)
1365                         a = AIDIVQ;
1366                 if(et == TFLOAT)
1367                         a = ADIVSS;
1368                 if(et == TDOUBLE)
1369                         a = ADIVSD;
1370                 break;
1371
1372         case OASLMUL:
1373         case OLMUL:
1374                 a = AMULL;
1375                 if(et == TVLONG || et == TUVLONG || et == TIND)
1376                         a = AMULQ;
1377                 break;
1378
1379         case OASLMOD:
1380         case OLMOD:
1381         case OASLDIV:
1382         case OLDIV:
1383                 a = ADIVL;
1384                 if(et == TVLONG || et == TUVLONG || et == TIND)
1385                         a = ADIVQ;
1386                 break;
1387
1388         case OEQ:
1389         case ONE:
1390         case OLT:
1391         case OLE:
1392         case OGE:
1393         case OGT:
1394         case OLO:
1395         case OLS:
1396         case OHS:
1397         case OHI:
1398                 a = ACMPL;
1399                 if(et == TCHAR || et == TUCHAR)
1400                         a = ACMPB;
1401                 if(et == TSHORT || et == TUSHORT)
1402                         a = ACMPW;
1403                 if(et == TVLONG || et == TUVLONG || et == TIND)
1404                         a = ACMPQ;
1405                 if(et == TFLOAT)
1406                         a = AUCOMISS;
1407                 if(et == TDOUBLE)
1408                         a = AUCOMISD;
1409                 gins(a, f, t);
1410                 switch(o) {
1411                 case OEQ:       a = AJEQ; break;
1412                 case ONE:       a = AJNE; break;
1413                 case OLT:       a = AJLT; break;
1414                 case OLE:       a = AJLE; break;
1415                 case OGE:       a = AJGE; break;
1416                 case OGT:       a = AJGT; break;
1417                 case OLO:       a = AJCS; break;
1418                 case OLS:       a = AJLS; break;
1419                 case OHS:       a = AJCC; break;
1420                 case OHI:       a = AJHI; break;
1421                 }
1422                 gins(a, Z, Z);
1423                 return;
1424         }
1425         if(a == AGOK)
1426                 diag(Z, "bad in gopcode %O", o);
1427         gins(a, f, t);
1428 }
1429
1430 int
1431 samaddr(Node *f, Node *t)
1432 {
1433         return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
1434 }
1435
1436 void
1437 gbranch(int o)
1438 {
1439         int a;
1440
1441         a = AGOK;
1442         switch(o) {
1443         case ORETURN:
1444                 a = ARET;
1445                 break;
1446         case OGOTO:
1447                 a = AJMP;
1448                 break;
1449         }
1450         nextpc();
1451         if(a == AGOK) {
1452                 diag(Z, "bad in gbranch %O",  o);
1453                 nextpc();
1454         }
1455         p->as = a;
1456 }
1457
1458 void
1459 patch(Prog *op, long pc)
1460 {
1461
1462         op->to.offset = pc;
1463         op->to.type = D_BRANCH;
1464 }
1465
1466 void
1467 gpseudo(int a, Sym *s, Node *n)
1468 {
1469
1470         nextpc();
1471         p->as = a;
1472         p->from.type = D_EXTERN;
1473         p->from.sym = s;
1474         p->from.scale = (profileflg ? 0 : NOPROF);
1475         if(s->class == CSTATIC)
1476                 p->from.type = D_STATIC;
1477         naddr(n, &p->to);
1478         if(a == ADATA || a == AGLOBL)
1479                 pc--;
1480 }
1481
1482 int
1483 sconst(Node *n)
1484 {
1485         long v;
1486
1487         if(n->op == OCONST && !typefd[n->type->etype]) {
1488                 v = n->vconst;
1489                 if(v >= -32766L && v < 32766L)
1490                         return 1;
1491         }
1492         return 0;
1493 }
1494
1495 long
1496 exreg(Type *t)
1497 {
1498         long o;
1499
1500         if(typechlpv[t->etype]) {
1501                 if(exregoffset <= REGEXT-4)
1502                         return 0;
1503                 o = exregoffset;
1504                 exregoffset--;
1505                 return o;
1506         }
1507         return 0;
1508 }
1509
1510 schar   ewidth[NTYPE] =
1511 {
1512         -1,             /*[TXXX]*/      
1513         SZ_CHAR,        /*[TCHAR]*/     
1514         SZ_CHAR,        /*[TUCHAR]*/
1515         SZ_SHORT,       /*[TSHORT]*/
1516         SZ_SHORT,       /*[TUSHORT]*/
1517         SZ_INT,         /*[TINT]*/
1518         SZ_INT,         /*[TUINT]*/
1519         SZ_LONG,        /*[TLONG]*/
1520         SZ_LONG,        /*[TULONG]*/
1521         SZ_VLONG,       /*[TVLONG]*/
1522         SZ_VLONG,       /*[TUVLONG]*/
1523         SZ_FLOAT,       /*[TFLOAT]*/
1524         SZ_DOUBLE,      /*[TDOUBLE]*/
1525         SZ_IND,         /*[TIND]*/
1526         0,              /*[TFUNC]*/
1527         -1,             /*[TARRAY]*/
1528         0,              /*[TVOID]*/
1529         -1,             /*[TSTRUCT]*/
1530         -1,             /*[TUNION]*/
1531         SZ_INT,         /*[TENUM]*/
1532 };
1533 long    ncast[NTYPE] =
1534 {
1535         0,                              /*[TXXX]*/
1536         BCHAR|BUCHAR,                   /*[TCHAR]*/
1537         BCHAR|BUCHAR,                   /*[TUCHAR]*/    
1538         BSHORT|BUSHORT,                 /*[TSHORT]*/
1539         BSHORT|BUSHORT,                 /*[TUSHORT]*/
1540         BINT|BUINT|BLONG|BULONG,        /*[TINT]*/              
1541         BINT|BUINT|BLONG|BULONG,        /*[TUINT]*/
1542         BINT|BUINT|BLONG|BULONG,        /*[TLONG]*/
1543         BINT|BUINT|BLONG|BULONG,        /*[TULONG]*/
1544         BVLONG|BUVLONG|BIND,                    /*[TVLONG]*/
1545         BVLONG|BUVLONG|BIND,                    /*[TUVLONG]*/
1546         BFLOAT,                         /*[TFLOAT]*/
1547         BDOUBLE,                        /*[TDOUBLE]*/
1548         BVLONG|BUVLONG|BIND,            /*[TIND]*/
1549         0,                              /*[TFUNC]*/
1550         0,                              /*[TARRAY]*/
1551         0,                              /*[TVOID]*/
1552         BSTRUCT,                        /*[TSTRUCT]*/
1553         BUNION,                         /*[TUNION]*/
1554         0,                              /*[TENUM]*/
1555 };