plan9fox/sys/src/cmd/2c/txt.c
2011-03-30 19:35:09 +03:00

941 lines
17 KiB
C

#include "gc.h"
void
tindex(Type *tf, Type *tt)
{
int i, j;
j = 0;
if(tt != T) {
j = tt->etype;
if(j >= NTYPE)
j = 0;
}
i = 0;
if(tf != T) {
i = tf->etype;
if(i >= NTYPE)
if(typesu[i])
i = j;
else
i = 0;
}
txtp = &txt[i][j];
}
void
ginit(void)
{
int i, j, si, sj;
thestring = "68020";
thechar = '2';
exregoffset = 7;
exaregoffset = 5;
exfregoffset = 7;
listinit();
for(i=0; i<NREG; i++) {
regused[i] = 0;
fregused[i] = 0;
aregused[i] = 0;
}
regaddr(D_A0+6);
regaddr(D_A0+7);
for(i=0; i<sizeof(regbase); i++)
regbase[i] = D_NONE;
for(i=0; i<NREG; i++) {
regbase[D_R0+i] = D_R0+i;
regbase[D_A0+i] = D_A0+i;
regbase[D_F0+i] = D_F0+i;
}
regbase[D_TOS] = D_TOS;
for(i=0; i<NTYPE; i++)
for(j=0; j<NTYPE; j++) {
txtp = &txt[i][j];
txtp->movas = AGOK;
txtp->preclr = 0;
txtp->postext = AGOK;
if(!(typechlp[i] && typechlp[j]))
continue;
si = types[i]->width;
sj = types[j]->width;
if(sj < si)
txtp->preclr = -1;
if(sj > si) {
if(typeu[i]) {
txtp->preclr = 1;
} else {
if(sj == 2)
txtp->postext = AEXTBW;
if(sj == 4)
if(si == 1)
txtp->postext = AEXTBL;
else
txtp->postext = AEXTWL;
}
sj = si;
}
if(sj == 1)
txtp->movas = AMOVB;
if(sj == 2)
txtp->movas = AMOVW;
if(sj == 4)
txtp->movas = AMOVL;
}
for(i=0; i<ALLOP; i++)
for(j=0; j<NTYPE; j++)
opxt[i][j] = AGOK;
oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
nstring = 0;
mnstring = 0;
nrathole = 0;
nstatic = 0;
pc = 0;
breakpc = -1;
continpc = -1;
cases = C;
firstp = P;
lastp = P;
tfield = types[TLONG];
zprog.link = P;
zprog.as = AGOK;
zprog.from.type = D_NONE;
zprog.from.index = D_NONE;
zprog.to = zprog.from;
nodret = new(ONAME, Z, Z);
nodret->sym = slookup(".ret");
nodret->type = types[TIND];
nodret->etype = types[TIND]->etype;
nodret->class = CPARAM;
nodret = new(OIND, nodret, Z);
complex(nodret);
symrathole = slookup(".rathole");
symrathole->class = CGLOBL;
symrathole->type = typ(TARRAY, types[TCHAR]);
nodrat = new(ONAME, Z, Z);
nodrat->sym = symrathole;
nodrat->type = types[TIND];
nodrat->etype = TVOID;
nodrat->class = CGLOBL;
complex(nodrat);
nodrat->type = symrathole->type;
com64init();
symstatic = slookup(".static");
symstatic->class = CSTATIC;
symstatic->type = typ(TARRAY, types[TLONG]);
}
void
gclean(void)
{
int i;
Sym *s;
regfree(D_A0+6);
regfree(D_A0+7);
for(i=0; i<NREG; i++) {
if(regused[i])
diag(Z, "missing R%d", i);
if(aregused[i])
diag(Z, "missing A%d", i);
if(fregused[i])
diag(Z, "missing F%d", i);
}
while(mnstring)
outstring("", 1L);
symstring->type->width = nstring;
symstatic->type->width = nstatic;
symrathole->type->width = nrathole;
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
if(s->type == T)
continue;
if(s->type->width == 0)
continue;
if(s->class != CGLOBL && s->class != CSTATIC)
continue;
if(s->type == types[TENUM])
continue;
gpseudo(AGLOBL, s, D_CONST, s->type->width);
pc--;
}
nextpc();
p->as = AEND;
outcode();
}
void
oinit(int o, int ab, int aw, int al, int af, int ad)
{
int i;
i = o;
if(i >= ALLOP) {
diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP);
errorexit();
}
opxt[i][TCHAR] = ab;
opxt[i][TUCHAR] = ab;
opxt[i][TSHORT] = aw;
opxt[i][TUSHORT] = aw;
opxt[i][TINT] = al;
opxt[i][TUINT] = al;
opxt[i][TLONG] = al;
opxt[i][TULONG] = al;
opxt[i][TIND] = al;
opxt[i][TFLOAT] = af;
opxt[i][TDOUBLE] = ad;
}
Prog*
prg(void)
{
Prog *p;
p = alloc(sizeof(*p));
*p = zprog;
return p;
}
void
nextpc(void)
{
p = prg();
pc++;
p->lineno = nearln;
if(firstp == P) {
firstp = p;
lastp = p;
return;
}
lastp->link = p;
lastp = p;
}
void
gargs(Node *n)
{
long s;
loop:
if(n == Z)
return;
if(n->op == OLIST) {
gargs(n->right);
n = n->left;
goto loop;
}
s = argoff;
cgen(n, D_TOS, n);
argoff = s + n->type->width;
}
void
naddr(Node *n, Adr *a, int x)
{
Node *l;
long v;
switch(n->op) {
default:
bad:
diag(n, "bad in naddr: %O", n->op);
break;
case OADDR:
case OIND:
naddr(n->left, a, x);
goto noadd;
case OREGISTER:
a->sym = S;
a->type = n->reg;
a->offset = n->xoffset;
a->displace = 0;
break;
case ONAME:
a->etype = n->etype;
a->displace = 0;
a->sym = n->sym;
a->offset = n->xoffset;
a->type = D_STATIC;
if(n->class == CSTATIC)
break;
if(n->class == CEXTERN || n->class == CGLOBL) {
a->type = D_EXTERN;
break;
}
if(n->class == CAUTO) {
a->type = D_AUTO;
break;
}
if(n->class == CPARAM) {
a->type = D_PARAM;
break;
}
goto bad;
case OINDEX:
naddr(n->left, a, x);
switch(n->left->addable) {
default:
goto bad;
case 1:
case 12:
a->index = x | I_INDEX1;
a->type &= D_MASK;
break;
case 2:
case 10:
case 11:
a->index = x | I_INDEX2;
break;
}
a->scale = n->scale;
break;
case OCONST:
a->displace = 0;
if(typefd[n->type->etype]) {
a->type = D_FCONST;
a->dval = n->fconst;
break;
}
a->type = D_CONST;
a->offset = n->vconst;
break;
case OADD:
l = n->left;
if(l->addable == 20) {
v = l->vconst;
naddr(n->right, a, x);
goto add;
}
l = n->right;
if(l->addable == 20) {
v = l->vconst;
naddr(n->left, a, x);
goto add;
}
goto bad;
noadd:
v = 0;
add:
switch(n->addable) {
default:
goto bad;
case 2:
a->displace += v;
break;
case 21:
a->type &= D_MASK;
a->type |= I_INDIR;
break;
case 1:
case 12:
a->offset += v;
a->type &= D_MASK;
a->type |= I_ADDR;
break;
case 13:
a->index = D_NONE|I_INDEX3;
case 10:
case 11:
case 20:
a->type &= D_MASK;
a->type |= I_DIR;
break;
}
break;
case OPREINC:
case OPREDEC:
case OPOSTINC:
case OPOSTDEC:
case OAS:
case OASLMUL:
case OASLDIV:
case OASLMOD:
case OASMUL:
case OASDIV:
case OASMOD:
case OASXOR:
case OASOR:
case OASADD:
case OASSUB:
case OASLSHR:
case OASASHR:
case OASASHL:
case OASAND:
naddr(n->left, a, x);
break;
}
}
int
regalloc(Type *t, int g)
{
if(t == T)
return D_NONE;
g &= D_MASK;
if(typefd[t->etype]) {
if(g >= D_F0 && g < D_F0+NREG) {
fregused[g-D_F0]++;
return g;
}
for(g=0; g<NREG; g++)
if(fregused[g] == 0) {
fregused[g]++;
return g + D_F0;
}
} else {
if(g >= D_R0 && g < D_R0+NREG) {
regused[g-D_R0]++;
return g;
}
for(g=0; g<NREG; g++)
if(regused[g] == 0) {
regused[g]++;
return g + D_R0;
}
}
diag(Z, "out of registers");
return D_TOS;
}
int
regaddr(int g)
{
if(g >= D_A0 && g < D_A0+NREG) {
aregused[g-D_A0]++;
return g;
}
for(g=0; g<NREG; g++)
if(aregused[g] == 0) {
aregused[g]++;
return g + D_A0;
}
diag(Z, "out of addr registers");
return D_TOS;
}
int
regpair(int g)
{
if(g >= D_R0+1 && g < D_R0+NREG)
if(!regused[g-D_R0-1]) {
regused[g-D_R0-1]++;
regused[g-D_R0]++;
return g-1;
}
if(g >= D_R0 && g < D_R0+NREG-1)
if(!regused[g-D_R0+1]) {
regused[g-D_R0+1]++;
regused[g-D_R0]++;
return g;
}
for(g = 0; g < NREG-1; g++)
if(!regused[g])
if(!regused[g+1]) {
regused[g]++;
regused[g+1]++;
return g + D_R0;
}
diag(Z, "out of register pairs");
return D_TOS;
}
int
regret(Type *t)
{
if(t == T)
return D_NONE;
if(typefd[t->etype])
return D_F0;
return D_R0;
}
void
regfree(int g)
{
g &= D_MASK;
if(g == D_TOS || g == D_TREE || g == D_NONE)
return;
if(g >= D_R0 && g < D_R0+NREG) {
regused[g-D_R0]--;
return;
}
if(g >= D_A0 && g < D_A0+NREG) {
aregused[g-D_A0]--;
return;
}
if(g >= D_F0 && g < D_F0+NREG) {
fregused[g-D_F0]--;
return;
}
diag(Z, "bad in regfree: %d", g);
}
void
gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
{
int g, a, b;
Prog *p1;
tindex(tf, tt);
if(txtp->preclr) {
if(gf >= D_R0 && gf < D_R0+NREG)
if(txtp->preclr < 0) {
gmove(tt, tt, gf, f, gt, t);
return;
}
g = regalloc(types[TLONG], gt);
if(g == gf) {
g = regalloc(types[TLONG], D_NONE);
regfree(gf);
}
if(txtp->preclr > 0)
gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
gopcode(OAS, tf, gf, f, g, Z);
if(g != gt)
gopcode(OAS, tt, g, Z, gt, t);
regfree(g);
return;
}
a = txtp->postext;
if(a != AGOK) {
if(gf >= D_R0 && gf < D_R0+NREG)
g = regalloc(types[TLONG], gf);
else
g = regalloc(types[TLONG], gt);
if(g != gf)
gopcode(OAS, tf, gf, f, g, Z);
nextpc();
p->as = a;
p->to.type = g;
if(debug['g'])
print("%P\n", p);
if(g != gt)
gopcode(OAS, tt, g, Z, gt, t);
regfree(g);
return;
}
if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
(gf == D_TREE && gt == D_TREE && f == t))
return;
if(typefd[tf->etype] || typefd[tt->etype]) {
if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
a = regalloc(types[TLONG], D_NONE);
gmove(tf, types[TLONG], gf, f, a, t);
if(tf->etype == TULONG) {
b = regalloc(types[TDOUBLE], D_NONE);
gmove(types[TLONG], tt, a, t, b, t);
gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
gbranch(OGE);
p1 = p;
gopcode(OASADD, types[TDOUBLE],
D_CONST, nodconst(100), b, t);
p->from.dval = 4294967296.;
patch(p1, pc);
gmove(types[TDOUBLE], tt, b, t, gt, t);
regfree(b);
} else
gmove(types[TLONG], tt, a, t, gt, t);
regfree(a);
return;
}
if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
a = regalloc(types[TLONG], D_NONE);
gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
}
if(gf < D_F0 || gf >= D_F0+NREG) {
g = regalloc(types[TDOUBLE], gt);
gopcode(OFAS, tf, gf, f, g, t);
if(g != gt)
gopcode(OFAS, tt, g, t, gt, t);
regfree(g);
} else
gopcode(OFAS, tt, gf, f, gt, t);
if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
regfree(a);
}
return;
}
gopcode(OAS, tt, gf, f, gt, t);
}
void
gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
{
int i, fidx, tidx;
long v;
if(o == OAS)
if(gf == gt)
if(gf != D_TREE || f == t)
return;
fidx = D_NONE;
if(gf == D_TREE) {
if(f->op == OINDEX) {
fidx = regalloc(types[TIND], fidx);
cgen(f->right, fidx, f->right);
}
}
tidx = D_NONE;
if(gt == D_TREE) {
if(t->op == OINDEX) {
v = argoff;
tidx = regalloc(types[TIND], tidx);
cgen(t->right, tidx, t->right);
if(gf == D_TOS)
adjsp(v - argoff);
}
}
i = 0;
if(ty != T) {
i = ty->etype;
if(i >= NTYPE)
i = 0;
}
nextpc();
if(gf == D_TREE) {
naddr(f, &p->from, fidx);
} else {
p->from.type = gf;
if(gf == D_CONST) {
p->from.offset = (long)(uintptr)f;
if(typefd[i]) {
p->from.type = D_FCONST;
p->from.dval = (long)(uintptr)f;
}
}
}
p->as = opxt[o][i];
if(gt == D_TREE) {
naddr(t, &p->to, tidx);
} else {
p->to.type = gt;
if(gt == D_CONST)
p->to.offset = (long)(uintptr)t;
}
if(o == OBIT) {
p->from.field = f->type->nbits;
p->to.field = f->type->shift;
if(p->from.field == 0)
diag(Z, "BIT zero width bit field");
}
if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
asopt();
if(debug['g'])
print("%P\n", p);
if(p->as == AGOK)
diag(Z, "GOK in gopcode: %s", onames[o]);
if(fidx != D_NONE)
regfree(fidx);
if(tidx != D_NONE)
regfree(tidx);
}
void
asopt(void)
{
long v;
int g;
Prog *q;
/*
* mov $0, ...
* ==>
* clr , ...
*/
v = 0;
if(p->from.type == D_CONST) {
v = p->from.offset;
if(v == 0) {
p->from.type = D_NONE;
if(p->as == AMOVL)
p->as = ACLRL;
if(p->as == AMOVW)
p->as = ACLRW;
if(p->as == AMOVB)
p->as = ACLRB;
return;
}
}
/*
* mov ..., TOS
* ==>
* pea (...)
*/
if(p->as == AMOVL && p->to.type == D_TOS && p->from.index == D_NONE)
switch(p->from.type) {
case D_CONST:
p->from.type |= I_INDIR;
p->to = p->from;
p->from = zprog.from;
p->as = APEA;
return;
case I_ADDR|D_EXTERN:
case I_ADDR|D_STATIC:
p->from.type &= ~I_ADDR;
p->to = p->from;
p->from = zprog.from;
p->as = APEA;
return;
}
/*
* movL $Qx, ...
* ==>
* movL $Qx,R
* movL R, ...
*/
if(p->as == AMOVL && p->from.type == D_CONST)
if(v >= -128 && v < 128)
if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
g = regalloc(types[TLONG], D_NONE);
q = p;
nextpc();
p->as = AMOVL;
p->from.type = g;
p->to = q->to;
q->to = p->from;
regfree(g);
if(debug['g'])
print("%P\n", q);
return;
}
}
void
gbranch(int o)
{
int a;
a = ABNE;
switch(o) {
case ORETURN: a = ARTS; break;
case OGOTO: a = ABRA; break;
case OEQ: a = ABEQ; break;
case ONE: a = ABNE; break;
case OLE: a = ABLE; break;
case OLS: a = ABLS; break;
case OLT: a = ABLT; break;
case OLO: a = ABCS; break;
case OGE: a = ABGE; break;
case OHS: a = ABCC; break;
case OGT: a = ABGT; break;
case OHI: a = ABHI; break;
case OBIT: a = ABCS; break;
case OCASE: a = ABCASE; break;
}
nextpc();
p->from.type = D_NONE;
p->to.type = D_NONE;
p->as = a;
}
void
fpbranch(void)
{
int a;
a = p->as;
switch(a) {
case ABEQ: a = AFBEQ; break;
case ABNE: a = AFBNE; break;
case ABLE: a = AFBLE; break;
case ABLT: a = AFBLT; break;
case ABGE: a = AFBGE; break;
case ABGT: a = AFBGT; break;
}
p->as = a;
}
void
patch(Prog *op, long pc)
{
op->to.offset = pc;
op->to.type = D_BRANCH;
}
void
gpseudo(int a, Sym *s, int g, long v)
{
nextpc();
if(a == ADATA)
pc--;
p->as = a;
if(g == D_TREE)
abort(); /* obsolete */
p->to.type = g;
p->to.offset = v;
p->from.sym = s;
p->from.type = D_EXTERN;
if(s->class == CSTATIC)
p->from.type = D_STATIC;
}
void
gpseudotree(int a, Sym *s, Node *n)
{
nextpc();
if(a == ADATA)
pc--;
p->as = a;
naddr(n, &p->to, D_NONE);
p->from.sym = s;
p->from.type = D_EXTERN;
if(s->class == CSTATIC)
p->from.type = D_STATIC;
}
long
exreg(Type *t)
{
long o;
if(typechl[t->etype]) {
if(exregoffset <= 5)
return 0;
o = exregoffset + D_R0;
exregoffset--;
return o;
}
if(t->etype == TIND) {
if(exaregoffset <= 3)
return 0;
o = exaregoffset + D_A0;
exaregoffset--;
return o;
}
if(typefd[t->etype]) {
if(exfregoffset <= 5)
return 0;
o = exfregoffset + D_F0;
exfregoffset--;
return o;
}
return 0;
}
schar ewidth[NTYPE] =
{
-1, /* [TXXX] */
SZ_CHAR, /* [TCHAR] */
SZ_CHAR, /* [TUCHAR] */
SZ_SHORT, /* [TSHORT] */
SZ_SHORT, /* [TUSHORT] */
SZ_INT, /* [TINT] */
SZ_INT, /* [TUINT] */
SZ_LONG, /* [TLONG] */
SZ_LONG, /* [TULONG] */
SZ_VLONG, /* [TVLONG] */
SZ_VLONG, /* [TUVLONG] */
SZ_FLOAT, /* [TFLOAT] */
SZ_DOUBLE, /* [TDOUBLE] */
SZ_IND, /* [TIND] */
0, /* [TFUNC] */
-1, /* [TARRAY] */
0, /* [TVOID] */
-1, /* [TSTRUCT] */
-1, /* [TUNION] */
SZ_INT, /* [TENUM] */
};
long ncast[NTYPE] =
{
0, /* [TXXX] */
BCHAR|BUCHAR, /* [TCHAR] */
BCHAR|BUCHAR, /* [TUCHAR] */
BSHORT|BUSHORT, /* [TSHORT] */
BSHORT|BUSHORT, /* [TUSHORT] */
BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
BVLONG|BUVLONG, /* [TVLONG] */
BVLONG|BUVLONG, /* [TUVLONG] */
BFLOAT, /* [TFLOAT] */
BDOUBLE, /* [TDOUBLE] */
BLONG|BULONG|BIND, /* [TIND] */
0, /* [TFUNC] */
0, /* [TARRAY] */
0, /* [TVOID] */
BSTRUCT, /* [TSTRUCT] */
BUNION, /* [TUNION] */
0, /* [TENUM] */
};