174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth void
ginit(void)474a4d8c2SCharles.Forsyth ginit(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth Type *t;
774a4d8c2SCharles.Forsyth
874a4d8c2SCharles.Forsyth thechar = 't';
974a4d8c2SCharles.Forsyth thestring = "arm";
1074a4d8c2SCharles.Forsyth exregoffset = REGEXT;
1174a4d8c2SCharles.Forsyth exfregoffset = FREGEXT;
1274a4d8c2SCharles.Forsyth listinit();
1374a4d8c2SCharles.Forsyth nstring = 0;
1474a4d8c2SCharles.Forsyth mnstring = 0;
1574a4d8c2SCharles.Forsyth nrathole = 0;
1674a4d8c2SCharles.Forsyth pc = 0;
1774a4d8c2SCharles.Forsyth breakpc = -1;
1874a4d8c2SCharles.Forsyth continpc = -1;
1974a4d8c2SCharles.Forsyth cases = C;
2074a4d8c2SCharles.Forsyth firstp = P;
2174a4d8c2SCharles.Forsyth lastp = P;
2274a4d8c2SCharles.Forsyth tfield = types[TLONG];
2374a4d8c2SCharles.Forsyth
2474a4d8c2SCharles.Forsyth zprog.link = P;
2574a4d8c2SCharles.Forsyth zprog.as = AGOK;
2674a4d8c2SCharles.Forsyth zprog.reg = NREG;
2774a4d8c2SCharles.Forsyth zprog.from.type = D_NONE;
2874a4d8c2SCharles.Forsyth zprog.from.name = D_NONE;
2974a4d8c2SCharles.Forsyth zprog.from.reg = NREG;
3074a4d8c2SCharles.Forsyth zprog.to = zprog.from;
3174a4d8c2SCharles.Forsyth
3274a4d8c2SCharles.Forsyth regnode.op = OREGISTER;
3374a4d8c2SCharles.Forsyth regnode.class = CEXREG;
3474a4d8c2SCharles.Forsyth regnode.reg = REGTMPT;
3574a4d8c2SCharles.Forsyth regnode.complex = 0;
3674a4d8c2SCharles.Forsyth regnode.addable = 11;
3774a4d8c2SCharles.Forsyth regnode.type = types[TLONG];
3874a4d8c2SCharles.Forsyth
3974a4d8c2SCharles.Forsyth constnode.op = OCONST;
4074a4d8c2SCharles.Forsyth constnode.class = CXXX;
4174a4d8c2SCharles.Forsyth constnode.complex = 0;
4274a4d8c2SCharles.Forsyth constnode.addable = 20;
4374a4d8c2SCharles.Forsyth constnode.type = types[TLONG];
4474a4d8c2SCharles.Forsyth
4574a4d8c2SCharles.Forsyth fconstnode.op = OCONST;
4674a4d8c2SCharles.Forsyth fconstnode.class = CXXX;
4774a4d8c2SCharles.Forsyth fconstnode.complex = 0;
4874a4d8c2SCharles.Forsyth fconstnode.addable = 20;
4974a4d8c2SCharles.Forsyth fconstnode.type = types[TDOUBLE];
5074a4d8c2SCharles.Forsyth
5174a4d8c2SCharles.Forsyth nodsafe = new(ONAME, Z, Z);
5274a4d8c2SCharles.Forsyth nodsafe->sym = slookup(".safe");
5374a4d8c2SCharles.Forsyth nodsafe->type = types[TINT];
5474a4d8c2SCharles.Forsyth nodsafe->etype = types[TINT]->etype;
5574a4d8c2SCharles.Forsyth nodsafe->class = CAUTO;
5674a4d8c2SCharles.Forsyth complex(nodsafe);
5774a4d8c2SCharles.Forsyth
5874a4d8c2SCharles.Forsyth t = typ(TARRAY, types[TCHAR]);
5974a4d8c2SCharles.Forsyth symrathole = slookup(".rathole");
6074a4d8c2SCharles.Forsyth symrathole->class = CGLOBL;
6174a4d8c2SCharles.Forsyth symrathole->type = t;
6274a4d8c2SCharles.Forsyth
6374a4d8c2SCharles.Forsyth nodrat = new(ONAME, Z, Z);
6474a4d8c2SCharles.Forsyth nodrat->sym = symrathole;
6574a4d8c2SCharles.Forsyth nodrat->type = types[TIND];
6674a4d8c2SCharles.Forsyth nodrat->etype = TVOID;
6774a4d8c2SCharles.Forsyth nodrat->class = CGLOBL;
6874a4d8c2SCharles.Forsyth complex(nodrat);
6974a4d8c2SCharles.Forsyth nodrat->type = t;
7074a4d8c2SCharles.Forsyth
7174a4d8c2SCharles.Forsyth nodret = new(ONAME, Z, Z);
7274a4d8c2SCharles.Forsyth nodret->sym = slookup(".ret");
7374a4d8c2SCharles.Forsyth nodret->type = types[TIND];
7474a4d8c2SCharles.Forsyth nodret->etype = TIND;
7574a4d8c2SCharles.Forsyth nodret->class = CPARAM;
7674a4d8c2SCharles.Forsyth nodret = new(OIND, nodret, Z);
7774a4d8c2SCharles.Forsyth complex(nodret);
7874a4d8c2SCharles.Forsyth
7974a4d8c2SCharles.Forsyth com64init();
8074a4d8c2SCharles.Forsyth
8174a4d8c2SCharles.Forsyth memset(reg, 0, sizeof(reg));
8274a4d8c2SCharles.Forsyth // reg[REGTMPT] = 1;
8374a4d8c2SCharles.Forsyth }
8474a4d8c2SCharles.Forsyth
8574a4d8c2SCharles.Forsyth void
gclean(void)8674a4d8c2SCharles.Forsyth gclean(void)
8774a4d8c2SCharles.Forsyth {
8874a4d8c2SCharles.Forsyth int i;
8974a4d8c2SCharles.Forsyth Sym *s;
9074a4d8c2SCharles.Forsyth
9174a4d8c2SCharles.Forsyth for(i=0; i<NREG; i++)
9274a4d8c2SCharles.Forsyth if(reg[i])
9374a4d8c2SCharles.Forsyth diag(Z, "reg %d left allocated", i);
9474a4d8c2SCharles.Forsyth for(i=NREG; i<NREG+NFREG; i++)
9574a4d8c2SCharles.Forsyth if(reg[i])
9674a4d8c2SCharles.Forsyth diag(Z, "freg %d left allocated", i-NREG);
9774a4d8c2SCharles.Forsyth while(mnstring)
9874a4d8c2SCharles.Forsyth outstring("", 1L);
9974a4d8c2SCharles.Forsyth symstring->type->width = nstring;
10074a4d8c2SCharles.Forsyth symrathole->type->width = nrathole;
10174a4d8c2SCharles.Forsyth for(i=0; i<NHASH; i++)
10274a4d8c2SCharles.Forsyth for(s = hash[i]; s != S; s = s->link) {
10374a4d8c2SCharles.Forsyth if(s->type == T)
10474a4d8c2SCharles.Forsyth continue;
10574a4d8c2SCharles.Forsyth if(s->type->width == 0)
10674a4d8c2SCharles.Forsyth continue;
10774a4d8c2SCharles.Forsyth if(s->class != CGLOBL && s->class != CSTATIC)
10874a4d8c2SCharles.Forsyth continue;
10974a4d8c2SCharles.Forsyth if(s->type == types[TENUM])
11074a4d8c2SCharles.Forsyth continue;
11174a4d8c2SCharles.Forsyth gpseudo(AGLOBL, s, nodconst(s->type->width));
11274a4d8c2SCharles.Forsyth }
11374a4d8c2SCharles.Forsyth nextpc();
11474a4d8c2SCharles.Forsyth p->as = AEND;
11574a4d8c2SCharles.Forsyth outcode();
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth
11874a4d8c2SCharles.Forsyth void
nextpc(void)11974a4d8c2SCharles.Forsyth nextpc(void)
12074a4d8c2SCharles.Forsyth {
12174a4d8c2SCharles.Forsyth
12274a4d8c2SCharles.Forsyth p = alloc(sizeof(*p));
12374a4d8c2SCharles.Forsyth *p = zprog;
12474a4d8c2SCharles.Forsyth p->lineno = nearln;
12574a4d8c2SCharles.Forsyth pc++;
12674a4d8c2SCharles.Forsyth if(firstp == P) {
12774a4d8c2SCharles.Forsyth firstp = p;
12874a4d8c2SCharles.Forsyth lastp = p;
12974a4d8c2SCharles.Forsyth return;
13074a4d8c2SCharles.Forsyth }
13174a4d8c2SCharles.Forsyth lastp->link = p;
13274a4d8c2SCharles.Forsyth lastp = p;
13374a4d8c2SCharles.Forsyth }
13474a4d8c2SCharles.Forsyth
13574a4d8c2SCharles.Forsyth void
gargs(Node * n,Node * tn1,Node * tn2)13674a4d8c2SCharles.Forsyth gargs(Node *n, Node *tn1, Node *tn2)
13774a4d8c2SCharles.Forsyth {
13874a4d8c2SCharles.Forsyth long regs;
13974a4d8c2SCharles.Forsyth Node fnxargs[20], *fnxp;
14074a4d8c2SCharles.Forsyth
14174a4d8c2SCharles.Forsyth regs = cursafe;
14274a4d8c2SCharles.Forsyth
14374a4d8c2SCharles.Forsyth fnxp = fnxargs;
14474a4d8c2SCharles.Forsyth garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
14574a4d8c2SCharles.Forsyth
14674a4d8c2SCharles.Forsyth curarg = 0;
14774a4d8c2SCharles.Forsyth fnxp = fnxargs;
14874a4d8c2SCharles.Forsyth garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
14974a4d8c2SCharles.Forsyth
15074a4d8c2SCharles.Forsyth cursafe = regs;
15174a4d8c2SCharles.Forsyth }
15274a4d8c2SCharles.Forsyth
15374a4d8c2SCharles.Forsyth void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)15474a4d8c2SCharles.Forsyth garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
15574a4d8c2SCharles.Forsyth {
15674a4d8c2SCharles.Forsyth Node nod;
15774a4d8c2SCharles.Forsyth
15874a4d8c2SCharles.Forsyth if(n == Z)
15974a4d8c2SCharles.Forsyth return;
16074a4d8c2SCharles.Forsyth if(n->op == OLIST) {
16174a4d8c2SCharles.Forsyth garg1(n->left, tn1, tn2, f, fnxp);
16274a4d8c2SCharles.Forsyth garg1(n->right, tn1, tn2, f, fnxp);
16374a4d8c2SCharles.Forsyth return;
16474a4d8c2SCharles.Forsyth }
16574a4d8c2SCharles.Forsyth if(f == 0) {
16674a4d8c2SCharles.Forsyth if(n->complex >= FNX) {
16774a4d8c2SCharles.Forsyth regsalloc(*fnxp, n);
16874a4d8c2SCharles.Forsyth nod = znode;
16974a4d8c2SCharles.Forsyth nod.op = OAS;
17074a4d8c2SCharles.Forsyth nod.left = *fnxp;
17174a4d8c2SCharles.Forsyth nod.right = n;
17274a4d8c2SCharles.Forsyth nod.type = n->type;
17374a4d8c2SCharles.Forsyth cgen(&nod, Z);
17474a4d8c2SCharles.Forsyth (*fnxp)++;
17574a4d8c2SCharles.Forsyth }
17674a4d8c2SCharles.Forsyth return;
17774a4d8c2SCharles.Forsyth }
17874a4d8c2SCharles.Forsyth if(typesuv[n->type->etype]) {
17974a4d8c2SCharles.Forsyth regaalloc(tn2, n);
18074a4d8c2SCharles.Forsyth if(n->complex >= FNX) {
18174a4d8c2SCharles.Forsyth sugen(*fnxp, tn2, n->type->width);
18274a4d8c2SCharles.Forsyth (*fnxp)++;
18374a4d8c2SCharles.Forsyth } else
18474a4d8c2SCharles.Forsyth sugen(n, tn2, n->type->width);
18574a4d8c2SCharles.Forsyth return;
18674a4d8c2SCharles.Forsyth }
18774a4d8c2SCharles.Forsyth if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
18874a4d8c2SCharles.Forsyth regaalloc1(tn1, n);
18974a4d8c2SCharles.Forsyth if(n->complex >= FNX) {
19074a4d8c2SCharles.Forsyth cgen(*fnxp, tn1);
19174a4d8c2SCharles.Forsyth (*fnxp)++;
19274a4d8c2SCharles.Forsyth } else
19374a4d8c2SCharles.Forsyth cgen(n, tn1);
19474a4d8c2SCharles.Forsyth return;
19574a4d8c2SCharles.Forsyth }
19674a4d8c2SCharles.Forsyth regalloc(tn1, n, Z);
19774a4d8c2SCharles.Forsyth if(n->complex >= FNX) {
19874a4d8c2SCharles.Forsyth cgen(*fnxp, tn1);
19974a4d8c2SCharles.Forsyth (*fnxp)++;
20074a4d8c2SCharles.Forsyth } else
20174a4d8c2SCharles.Forsyth cgen(n, tn1);
20274a4d8c2SCharles.Forsyth regaalloc(tn2, n);
20374a4d8c2SCharles.Forsyth gopcode(OAS, tn1, Z, tn2);
20474a4d8c2SCharles.Forsyth regfree(tn1);
20574a4d8c2SCharles.Forsyth }
20674a4d8c2SCharles.Forsyth
20774a4d8c2SCharles.Forsyth Node*
nodconst(long v)20874a4d8c2SCharles.Forsyth nodconst(long v)
20974a4d8c2SCharles.Forsyth {
21074a4d8c2SCharles.Forsyth constnode.vconst = v;
21174a4d8c2SCharles.Forsyth return &constnode;
21274a4d8c2SCharles.Forsyth }
21374a4d8c2SCharles.Forsyth
21474a4d8c2SCharles.Forsyth Node*
nod32const(vlong v)21574a4d8c2SCharles.Forsyth nod32const(vlong v)
21674a4d8c2SCharles.Forsyth {
21774a4d8c2SCharles.Forsyth constnode.vconst = v & MASK(32);
21874a4d8c2SCharles.Forsyth return &constnode;
21974a4d8c2SCharles.Forsyth }
22074a4d8c2SCharles.Forsyth
22174a4d8c2SCharles.Forsyth Node*
nodfconst(double d)22274a4d8c2SCharles.Forsyth nodfconst(double d)
22374a4d8c2SCharles.Forsyth {
22474a4d8c2SCharles.Forsyth fconstnode.fconst = d;
22574a4d8c2SCharles.Forsyth return &fconstnode;
22674a4d8c2SCharles.Forsyth }
22774a4d8c2SCharles.Forsyth
22874a4d8c2SCharles.Forsyth void
nodreg(Node * n,Node * nn,int reg)22974a4d8c2SCharles.Forsyth nodreg(Node *n, Node *nn, int reg)
23074a4d8c2SCharles.Forsyth {
23174a4d8c2SCharles.Forsyth *n = regnode;
23274a4d8c2SCharles.Forsyth n->reg = reg;
23374a4d8c2SCharles.Forsyth n->type = nn->type;
23474a4d8c2SCharles.Forsyth n->lineno = nn->lineno;
23574a4d8c2SCharles.Forsyth }
23674a4d8c2SCharles.Forsyth
23774a4d8c2SCharles.Forsyth void
regret(Node * n,Node * nn)23874a4d8c2SCharles.Forsyth regret(Node *n, Node *nn)
23974a4d8c2SCharles.Forsyth {
24074a4d8c2SCharles.Forsyth int r;
24174a4d8c2SCharles.Forsyth
24274a4d8c2SCharles.Forsyth r = REGRET;
24374a4d8c2SCharles.Forsyth if(typefd[nn->type->etype])
24474a4d8c2SCharles.Forsyth r = FREGRET+NREG;
24574a4d8c2SCharles.Forsyth nodreg(n, nn, r);
24674a4d8c2SCharles.Forsyth reg[r]++;
24774a4d8c2SCharles.Forsyth }
24874a4d8c2SCharles.Forsyth
24974a4d8c2SCharles.Forsyth int
tmpreg(void)25074a4d8c2SCharles.Forsyth tmpreg(void)
25174a4d8c2SCharles.Forsyth {
25274a4d8c2SCharles.Forsyth int i;
25374a4d8c2SCharles.Forsyth
25474a4d8c2SCharles.Forsyth for(i=REGRET+1; i<NREG; i++)
25574a4d8c2SCharles.Forsyth if(reg[i] == 0)
25674a4d8c2SCharles.Forsyth return i;
25774a4d8c2SCharles.Forsyth diag(Z, "out of fixed tmp registers");
25874a4d8c2SCharles.Forsyth return 0;
25974a4d8c2SCharles.Forsyth }
26074a4d8c2SCharles.Forsyth
26174a4d8c2SCharles.Forsyth void
regalloc(Node * n,Node * tn,Node * o)26274a4d8c2SCharles.Forsyth regalloc(Node *n, Node *tn, Node *o)
26374a4d8c2SCharles.Forsyth {
26474a4d8c2SCharles.Forsyth int i, j;
26574a4d8c2SCharles.Forsyth static int lasti;
26674a4d8c2SCharles.Forsyth
26774a4d8c2SCharles.Forsyth switch(tn->type->etype) {
26874a4d8c2SCharles.Forsyth case TCHAR:
26974a4d8c2SCharles.Forsyth case TUCHAR:
27074a4d8c2SCharles.Forsyth case TSHORT:
27174a4d8c2SCharles.Forsyth case TUSHORT:
27274a4d8c2SCharles.Forsyth case TINT:
27374a4d8c2SCharles.Forsyth case TUINT:
27474a4d8c2SCharles.Forsyth case TLONG:
27574a4d8c2SCharles.Forsyth case TULONG:
27674a4d8c2SCharles.Forsyth case TIND:
27774a4d8c2SCharles.Forsyth if(o != Z && o->op == OREGISTER) {
27874a4d8c2SCharles.Forsyth i = o->reg;
27974a4d8c2SCharles.Forsyth if(i >= 0 && i < NREG)
28074a4d8c2SCharles.Forsyth goto out;
28174a4d8c2SCharles.Forsyth }
28274a4d8c2SCharles.Forsyth j = lasti + REGRET+1;
28374a4d8c2SCharles.Forsyth for(i=REGRET+1; i<REGTMPT; i++) {
28474a4d8c2SCharles.Forsyth if(j >= REGTMPT)
28574a4d8c2SCharles.Forsyth j = REGRET+1;
28674a4d8c2SCharles.Forsyth if(reg[j] == 0) {
28774a4d8c2SCharles.Forsyth i = j;
28874a4d8c2SCharles.Forsyth goto out;
28974a4d8c2SCharles.Forsyth }
29074a4d8c2SCharles.Forsyth j++;
29174a4d8c2SCharles.Forsyth }
29274a4d8c2SCharles.Forsyth diag(tn, "out of fixed registers");
29374a4d8c2SCharles.Forsyth goto err;
29474a4d8c2SCharles.Forsyth
29574a4d8c2SCharles.Forsyth case TFLOAT:
29674a4d8c2SCharles.Forsyth case TDOUBLE:
29774a4d8c2SCharles.Forsyth case TVLONG:
29874a4d8c2SCharles.Forsyth if(o != Z && o->op == OREGISTER) {
29974a4d8c2SCharles.Forsyth i = o->reg;
30074a4d8c2SCharles.Forsyth if(i >= NREG && i < NREG+NFREG)
30174a4d8c2SCharles.Forsyth goto out;
30274a4d8c2SCharles.Forsyth }
30374a4d8c2SCharles.Forsyth j = 0*2 + NREG;
30474a4d8c2SCharles.Forsyth for(i=NREG; i<NREG+NFREG; i++) {
30574a4d8c2SCharles.Forsyth if(j >= NREG+NFREG)
30674a4d8c2SCharles.Forsyth j = NREG;
30774a4d8c2SCharles.Forsyth if(reg[j] == 0) {
30874a4d8c2SCharles.Forsyth i = j;
30974a4d8c2SCharles.Forsyth goto out;
31074a4d8c2SCharles.Forsyth }
31174a4d8c2SCharles.Forsyth j++;
31274a4d8c2SCharles.Forsyth }
31374a4d8c2SCharles.Forsyth diag(tn, "out of float registers");
31474a4d8c2SCharles.Forsyth goto err;
31574a4d8c2SCharles.Forsyth }
31674a4d8c2SCharles.Forsyth diag(tn, "unknown type in regalloc: %T", tn->type);
31774a4d8c2SCharles.Forsyth err:
31874a4d8c2SCharles.Forsyth nodreg(n, tn, 0);
31974a4d8c2SCharles.Forsyth return;
32074a4d8c2SCharles.Forsyth out:
32174a4d8c2SCharles.Forsyth reg[i]++;
32274a4d8c2SCharles.Forsyth /* lasti++; *** StrongARM does register forwarding */
32374a4d8c2SCharles.Forsyth /*
32474a4d8c2SCharles.Forsyth if(lasti >= 5)
32574a4d8c2SCharles.Forsyth lasti = 0;
32674a4d8c2SCharles.Forsyth */
32774a4d8c2SCharles.Forsyth nodreg(n, tn, i);
32874a4d8c2SCharles.Forsyth }
32974a4d8c2SCharles.Forsyth
33074a4d8c2SCharles.Forsyth void
regialloc(Node * n,Node * tn,Node * o)33174a4d8c2SCharles.Forsyth regialloc(Node *n, Node *tn, Node *o)
33274a4d8c2SCharles.Forsyth {
33374a4d8c2SCharles.Forsyth Node nod;
33474a4d8c2SCharles.Forsyth
33574a4d8c2SCharles.Forsyth nod = *tn;
33674a4d8c2SCharles.Forsyth nod.type = types[TIND];
33774a4d8c2SCharles.Forsyth regalloc(n, &nod, o);
33874a4d8c2SCharles.Forsyth }
33974a4d8c2SCharles.Forsyth
34074a4d8c2SCharles.Forsyth void
regfree(Node * n)34174a4d8c2SCharles.Forsyth regfree(Node *n)
34274a4d8c2SCharles.Forsyth {
34374a4d8c2SCharles.Forsyth int i;
34474a4d8c2SCharles.Forsyth
34574a4d8c2SCharles.Forsyth i = 0;
34674a4d8c2SCharles.Forsyth if(n->op != OREGISTER && n->op != OINDREG)
34774a4d8c2SCharles.Forsyth goto err;
34874a4d8c2SCharles.Forsyth i = n->reg;
34974a4d8c2SCharles.Forsyth if(i < 0 || i >= sizeof(reg))
35074a4d8c2SCharles.Forsyth goto err;
35174a4d8c2SCharles.Forsyth if(reg[i] <= 0)
35274a4d8c2SCharles.Forsyth goto err;
35374a4d8c2SCharles.Forsyth reg[i]--;
35474a4d8c2SCharles.Forsyth return;
35574a4d8c2SCharles.Forsyth err:
35674a4d8c2SCharles.Forsyth diag(n, "error in regfree: %d", i);
35774a4d8c2SCharles.Forsyth }
35874a4d8c2SCharles.Forsyth
35974a4d8c2SCharles.Forsyth void
regsalloc(Node * n,Node * nn)36074a4d8c2SCharles.Forsyth regsalloc(Node *n, Node *nn)
36174a4d8c2SCharles.Forsyth {
36274a4d8c2SCharles.Forsyth cursafe = align(cursafe, nn->type, Aaut3);
36374a4d8c2SCharles.Forsyth maxargsafe = maxround(maxargsafe, cursafe+curarg);
36474a4d8c2SCharles.Forsyth *n = *nodsafe;
36574a4d8c2SCharles.Forsyth n->xoffset = -(stkoff + cursafe);
36674a4d8c2SCharles.Forsyth n->type = nn->type;
36774a4d8c2SCharles.Forsyth n->etype = nn->type->etype;
36874a4d8c2SCharles.Forsyth n->lineno = nn->lineno;
36974a4d8c2SCharles.Forsyth }
37074a4d8c2SCharles.Forsyth
37174a4d8c2SCharles.Forsyth void
regaalloc1(Node * n,Node * nn)37274a4d8c2SCharles.Forsyth regaalloc1(Node *n, Node *nn)
37374a4d8c2SCharles.Forsyth {
37474a4d8c2SCharles.Forsyth nodreg(n, nn, REGARG);
37574a4d8c2SCharles.Forsyth reg[REGARG]++;
37674a4d8c2SCharles.Forsyth curarg = align(curarg, nn->type, Aarg1);
37774a4d8c2SCharles.Forsyth curarg = align(curarg, nn->type, Aarg2);
37874a4d8c2SCharles.Forsyth maxargsafe = maxround(maxargsafe, cursafe+curarg);
37974a4d8c2SCharles.Forsyth }
38074a4d8c2SCharles.Forsyth
38174a4d8c2SCharles.Forsyth void
regaalloc(Node * n,Node * nn)38274a4d8c2SCharles.Forsyth regaalloc(Node *n, Node *nn)
38374a4d8c2SCharles.Forsyth {
38474a4d8c2SCharles.Forsyth curarg = align(curarg, nn->type, Aarg1);
38574a4d8c2SCharles.Forsyth *n = *nn;
38674a4d8c2SCharles.Forsyth n->op = OINDREG;
38774a4d8c2SCharles.Forsyth n->reg = REGSP;
38874a4d8c2SCharles.Forsyth n->xoffset = curarg + SZ_LONG;
38974a4d8c2SCharles.Forsyth n->complex = 0;
39074a4d8c2SCharles.Forsyth n->addable = 20;
39174a4d8c2SCharles.Forsyth curarg = align(curarg, nn->type, Aarg2);
39274a4d8c2SCharles.Forsyth maxargsafe = maxround(maxargsafe, cursafe+curarg);
39374a4d8c2SCharles.Forsyth }
39474a4d8c2SCharles.Forsyth
39574a4d8c2SCharles.Forsyth void
regind(Node * n,Node * nn)39674a4d8c2SCharles.Forsyth regind(Node *n, Node *nn)
39774a4d8c2SCharles.Forsyth {
39874a4d8c2SCharles.Forsyth
39974a4d8c2SCharles.Forsyth if(n->op != OREGISTER) {
40074a4d8c2SCharles.Forsyth diag(n, "regind not OREGISTER");
40174a4d8c2SCharles.Forsyth return;
40274a4d8c2SCharles.Forsyth }
40374a4d8c2SCharles.Forsyth n->op = OINDREG;
40474a4d8c2SCharles.Forsyth n->type = nn->type;
40574a4d8c2SCharles.Forsyth }
40674a4d8c2SCharles.Forsyth
40774a4d8c2SCharles.Forsyth void
raddr(Node * n,Prog * p)40874a4d8c2SCharles.Forsyth raddr(Node *n, Prog *p)
40974a4d8c2SCharles.Forsyth {
41074a4d8c2SCharles.Forsyth Adr a;
41174a4d8c2SCharles.Forsyth
41274a4d8c2SCharles.Forsyth naddr(n, &a);
41374a4d8c2SCharles.Forsyth if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
41474a4d8c2SCharles.Forsyth a.type = D_REG;
41574a4d8c2SCharles.Forsyth a.reg = 0;
41674a4d8c2SCharles.Forsyth }
41774a4d8c2SCharles.Forsyth if(a.type != D_REG && a.type != D_FREG) {
41874a4d8c2SCharles.Forsyth if(n)
41974a4d8c2SCharles.Forsyth diag(n, "bad in raddr: %O", n->op);
42074a4d8c2SCharles.Forsyth else
42174a4d8c2SCharles.Forsyth diag(n, "bad in raddr: <null>");
42274a4d8c2SCharles.Forsyth p->reg = NREG;
42374a4d8c2SCharles.Forsyth } else
42474a4d8c2SCharles.Forsyth p->reg = a.reg;
42574a4d8c2SCharles.Forsyth }
42674a4d8c2SCharles.Forsyth
42774a4d8c2SCharles.Forsyth void
naddr(Node * n,Adr * a)42874a4d8c2SCharles.Forsyth naddr(Node *n, Adr *a)
42974a4d8c2SCharles.Forsyth {
43074a4d8c2SCharles.Forsyth long v;
43174a4d8c2SCharles.Forsyth
43274a4d8c2SCharles.Forsyth a->type = D_NONE;
43374a4d8c2SCharles.Forsyth if(n == Z)
43474a4d8c2SCharles.Forsyth return;
43574a4d8c2SCharles.Forsyth switch(n->op) {
43674a4d8c2SCharles.Forsyth default:
43774a4d8c2SCharles.Forsyth bad:
43874a4d8c2SCharles.Forsyth diag(n, "bad in naddr: %O", n->op);
43974a4d8c2SCharles.Forsyth break;
44074a4d8c2SCharles.Forsyth
44174a4d8c2SCharles.Forsyth case OREGISTER:
44274a4d8c2SCharles.Forsyth a->type = D_REG;
44374a4d8c2SCharles.Forsyth a->sym = S;
44474a4d8c2SCharles.Forsyth a->reg = n->reg;
44574a4d8c2SCharles.Forsyth if(a->reg >= NREG) {
44674a4d8c2SCharles.Forsyth a->type = D_FREG;
44774a4d8c2SCharles.Forsyth a->reg -= NREG;
44874a4d8c2SCharles.Forsyth }
44974a4d8c2SCharles.Forsyth break;
45074a4d8c2SCharles.Forsyth
45174a4d8c2SCharles.Forsyth case OIND:
45274a4d8c2SCharles.Forsyth naddr(n->left, a);
45374a4d8c2SCharles.Forsyth if(a->type == D_REG) {
45474a4d8c2SCharles.Forsyth a->type = D_OREG;
45574a4d8c2SCharles.Forsyth break;
45674a4d8c2SCharles.Forsyth }
45774a4d8c2SCharles.Forsyth if(a->type == D_CONST) {
45874a4d8c2SCharles.Forsyth a->type = D_OREG;
45974a4d8c2SCharles.Forsyth break;
46074a4d8c2SCharles.Forsyth }
46174a4d8c2SCharles.Forsyth goto bad;
46274a4d8c2SCharles.Forsyth
46374a4d8c2SCharles.Forsyth case OINDREG:
46474a4d8c2SCharles.Forsyth a->type = D_OREG;
46574a4d8c2SCharles.Forsyth a->sym = S;
46674a4d8c2SCharles.Forsyth a->offset = n->xoffset;
46774a4d8c2SCharles.Forsyth a->reg = n->reg;
46874a4d8c2SCharles.Forsyth break;
46974a4d8c2SCharles.Forsyth
47074a4d8c2SCharles.Forsyth case ONAME:
47174a4d8c2SCharles.Forsyth a->etype = n->etype;
47274a4d8c2SCharles.Forsyth a->type = D_OREG;
47374a4d8c2SCharles.Forsyth a->name = D_STATIC;
47474a4d8c2SCharles.Forsyth a->sym = n->sym;
47574a4d8c2SCharles.Forsyth a->offset = n->xoffset;
47674a4d8c2SCharles.Forsyth if(n->class == CSTATIC)
47774a4d8c2SCharles.Forsyth break;
47874a4d8c2SCharles.Forsyth if(n->class == CEXTERN || n->class == CGLOBL) {
47974a4d8c2SCharles.Forsyth a->name = D_EXTERN;
48074a4d8c2SCharles.Forsyth break;
48174a4d8c2SCharles.Forsyth }
48274a4d8c2SCharles.Forsyth if(n->class == CAUTO) {
48374a4d8c2SCharles.Forsyth a->name = D_AUTO;
48474a4d8c2SCharles.Forsyth break;
48574a4d8c2SCharles.Forsyth }
48674a4d8c2SCharles.Forsyth if(n->class == CPARAM) {
48774a4d8c2SCharles.Forsyth a->name = D_PARAM;
48874a4d8c2SCharles.Forsyth break;
48974a4d8c2SCharles.Forsyth }
49074a4d8c2SCharles.Forsyth goto bad;
49174a4d8c2SCharles.Forsyth
49274a4d8c2SCharles.Forsyth case OCONST:
49374a4d8c2SCharles.Forsyth a->sym = S;
49474a4d8c2SCharles.Forsyth a->reg = NREG;
49574a4d8c2SCharles.Forsyth if(typefd[n->type->etype]) {
49674a4d8c2SCharles.Forsyth a->type = D_FCONST;
49774a4d8c2SCharles.Forsyth a->dval = n->fconst;
49874a4d8c2SCharles.Forsyth } else {
49974a4d8c2SCharles.Forsyth a->type = D_CONST;
50074a4d8c2SCharles.Forsyth a->offset = n->vconst;
50174a4d8c2SCharles.Forsyth }
50274a4d8c2SCharles.Forsyth break;
50374a4d8c2SCharles.Forsyth
50474a4d8c2SCharles.Forsyth case OADDR:
50574a4d8c2SCharles.Forsyth naddr(n->left, a);
50674a4d8c2SCharles.Forsyth if(a->type == D_OREG) {
50774a4d8c2SCharles.Forsyth a->type = D_CONST;
50874a4d8c2SCharles.Forsyth break;
50974a4d8c2SCharles.Forsyth }
51074a4d8c2SCharles.Forsyth goto bad;
51174a4d8c2SCharles.Forsyth
51274a4d8c2SCharles.Forsyth case OADD:
51374a4d8c2SCharles.Forsyth if(n->left->op == OCONST) {
51474a4d8c2SCharles.Forsyth naddr(n->left, a);
51574a4d8c2SCharles.Forsyth v = a->offset;
51674a4d8c2SCharles.Forsyth naddr(n->right, a);
51774a4d8c2SCharles.Forsyth } else {
51874a4d8c2SCharles.Forsyth naddr(n->right, a);
51974a4d8c2SCharles.Forsyth v = a->offset;
52074a4d8c2SCharles.Forsyth naddr(n->left, a);
52174a4d8c2SCharles.Forsyth }
52274a4d8c2SCharles.Forsyth a->offset += v;
52374a4d8c2SCharles.Forsyth break;
52474a4d8c2SCharles.Forsyth
52574a4d8c2SCharles.Forsyth }
52674a4d8c2SCharles.Forsyth }
52774a4d8c2SCharles.Forsyth
52874a4d8c2SCharles.Forsyth void
gmovm(Node * f,Node * t)52974a4d8c2SCharles.Forsyth gmovm(Node *f, Node *t)
53074a4d8c2SCharles.Forsyth {
53174a4d8c2SCharles.Forsyth gins(AMOVM, f, t); // always sets base register now
53274a4d8c2SCharles.Forsyth }
53374a4d8c2SCharles.Forsyth
53474a4d8c2SCharles.Forsyth void
gmove(Node * f,Node * t)53574a4d8c2SCharles.Forsyth gmove(Node *f, Node *t)
53674a4d8c2SCharles.Forsyth {
53774a4d8c2SCharles.Forsyth int ft, tt, a;
53874a4d8c2SCharles.Forsyth Node nod;
53974a4d8c2SCharles.Forsyth
54074a4d8c2SCharles.Forsyth // prtree(f, "gmove src");
54174a4d8c2SCharles.Forsyth // prtree(t, "gmove dst");
54274a4d8c2SCharles.Forsyth ft = f->type->etype;
54374a4d8c2SCharles.Forsyth tt = t->type->etype;
54474a4d8c2SCharles.Forsyth
54574a4d8c2SCharles.Forsyth if(ft == TDOUBLE && f->op == OCONST) {
54674a4d8c2SCharles.Forsyth }
54774a4d8c2SCharles.Forsyth if(ft == TFLOAT && f->op == OCONST) {
54874a4d8c2SCharles.Forsyth }
54974a4d8c2SCharles.Forsyth
55074a4d8c2SCharles.Forsyth /*
55174a4d8c2SCharles.Forsyth * a load --
55274a4d8c2SCharles.Forsyth * put it into a register then
55374a4d8c2SCharles.Forsyth * worry what to do with it.
55474a4d8c2SCharles.Forsyth */
55574a4d8c2SCharles.Forsyth if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
55674a4d8c2SCharles.Forsyth switch(ft) {
55774a4d8c2SCharles.Forsyth default:
55874a4d8c2SCharles.Forsyth a = AMOVW;
55974a4d8c2SCharles.Forsyth break;
56074a4d8c2SCharles.Forsyth case TFLOAT:
56174a4d8c2SCharles.Forsyth a = AMOVF;
56274a4d8c2SCharles.Forsyth break;
56374a4d8c2SCharles.Forsyth case TDOUBLE:
56474a4d8c2SCharles.Forsyth a = AMOVD;
56574a4d8c2SCharles.Forsyth break;
56674a4d8c2SCharles.Forsyth case TCHAR:
56774a4d8c2SCharles.Forsyth a = AMOVB;
56874a4d8c2SCharles.Forsyth break;
56974a4d8c2SCharles.Forsyth case TUCHAR:
57074a4d8c2SCharles.Forsyth a = AMOVBU;
57174a4d8c2SCharles.Forsyth break;
57274a4d8c2SCharles.Forsyth case TSHORT:
57374a4d8c2SCharles.Forsyth a = AMOVH;
57474a4d8c2SCharles.Forsyth break;
57574a4d8c2SCharles.Forsyth case TUSHORT:
57674a4d8c2SCharles.Forsyth a = AMOVHU;
57774a4d8c2SCharles.Forsyth break;
57874a4d8c2SCharles.Forsyth }
57974a4d8c2SCharles.Forsyth if(typechlp[ft] && typeilp[tt])
58074a4d8c2SCharles.Forsyth regalloc(&nod, t, t);
58174a4d8c2SCharles.Forsyth else
58274a4d8c2SCharles.Forsyth regalloc(&nod, f, t);
58374a4d8c2SCharles.Forsyth gins(a, f, &nod);
58474a4d8c2SCharles.Forsyth gmove(&nod, t);
58574a4d8c2SCharles.Forsyth regfree(&nod);
58674a4d8c2SCharles.Forsyth return;
58774a4d8c2SCharles.Forsyth }
58874a4d8c2SCharles.Forsyth
58974a4d8c2SCharles.Forsyth /*
59074a4d8c2SCharles.Forsyth * a store --
59174a4d8c2SCharles.Forsyth * put it into a register then
59274a4d8c2SCharles.Forsyth * store it.
59374a4d8c2SCharles.Forsyth */
59474a4d8c2SCharles.Forsyth if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
59574a4d8c2SCharles.Forsyth switch(tt) {
59674a4d8c2SCharles.Forsyth default:
59774a4d8c2SCharles.Forsyth a = AMOVW;
59874a4d8c2SCharles.Forsyth break;
59974a4d8c2SCharles.Forsyth case TUCHAR:
60074a4d8c2SCharles.Forsyth a = AMOVBU;
60174a4d8c2SCharles.Forsyth break;
60274a4d8c2SCharles.Forsyth case TCHAR:
60374a4d8c2SCharles.Forsyth a = AMOVB;
60474a4d8c2SCharles.Forsyth break;
60574a4d8c2SCharles.Forsyth case TUSHORT:
60674a4d8c2SCharles.Forsyth a = AMOVHU;
60774a4d8c2SCharles.Forsyth break;
60874a4d8c2SCharles.Forsyth case TSHORT:
60974a4d8c2SCharles.Forsyth a = AMOVH;
61074a4d8c2SCharles.Forsyth break;
61174a4d8c2SCharles.Forsyth case TFLOAT:
61274a4d8c2SCharles.Forsyth a = AMOVF;
61374a4d8c2SCharles.Forsyth break;
61474a4d8c2SCharles.Forsyth case TVLONG:
61574a4d8c2SCharles.Forsyth case TDOUBLE:
61674a4d8c2SCharles.Forsyth a = AMOVD;
61774a4d8c2SCharles.Forsyth break;
61874a4d8c2SCharles.Forsyth }
61974a4d8c2SCharles.Forsyth if(ft == tt)
62074a4d8c2SCharles.Forsyth regalloc(&nod, t, f);
62174a4d8c2SCharles.Forsyth else
62274a4d8c2SCharles.Forsyth regalloc(&nod, t, Z);
62374a4d8c2SCharles.Forsyth gmove(f, &nod);
62474a4d8c2SCharles.Forsyth gins(a, &nod, t);
62574a4d8c2SCharles.Forsyth regfree(&nod);
62674a4d8c2SCharles.Forsyth return;
62774a4d8c2SCharles.Forsyth }
62874a4d8c2SCharles.Forsyth
62974a4d8c2SCharles.Forsyth /*
63074a4d8c2SCharles.Forsyth * type x type cross table
63174a4d8c2SCharles.Forsyth */
63274a4d8c2SCharles.Forsyth a = AGOK;
63374a4d8c2SCharles.Forsyth switch(ft) {
63474a4d8c2SCharles.Forsyth case TDOUBLE:
63574a4d8c2SCharles.Forsyth case TVLONG:
63674a4d8c2SCharles.Forsyth case TFLOAT:
63774a4d8c2SCharles.Forsyth switch(tt) {
63874a4d8c2SCharles.Forsyth case TDOUBLE:
63974a4d8c2SCharles.Forsyth case TVLONG:
64074a4d8c2SCharles.Forsyth a = AMOVD;
64174a4d8c2SCharles.Forsyth if(ft == TFLOAT)
64274a4d8c2SCharles.Forsyth a = AMOVFD;
64374a4d8c2SCharles.Forsyth break;
64474a4d8c2SCharles.Forsyth case TFLOAT:
64574a4d8c2SCharles.Forsyth a = AMOVDF;
64674a4d8c2SCharles.Forsyth if(ft == TFLOAT)
64774a4d8c2SCharles.Forsyth a = AMOVF;
64874a4d8c2SCharles.Forsyth break;
64974a4d8c2SCharles.Forsyth case TINT:
65074a4d8c2SCharles.Forsyth case TUINT:
65174a4d8c2SCharles.Forsyth case TLONG:
65274a4d8c2SCharles.Forsyth case TULONG:
65374a4d8c2SCharles.Forsyth case TIND:
65474a4d8c2SCharles.Forsyth case TSHORT:
65574a4d8c2SCharles.Forsyth case TUSHORT:
65674a4d8c2SCharles.Forsyth case TCHAR:
65774a4d8c2SCharles.Forsyth case TUCHAR:
65874a4d8c2SCharles.Forsyth a = AMOVDW;
65974a4d8c2SCharles.Forsyth if(ft == TFLOAT)
66074a4d8c2SCharles.Forsyth a = AMOVFW;
66174a4d8c2SCharles.Forsyth break;
66274a4d8c2SCharles.Forsyth }
66374a4d8c2SCharles.Forsyth break;
66474a4d8c2SCharles.Forsyth case TUINT:
66574a4d8c2SCharles.Forsyth case TINT:
66674a4d8c2SCharles.Forsyth case TULONG:
66774a4d8c2SCharles.Forsyth case TLONG:
66874a4d8c2SCharles.Forsyth case TIND:
66974a4d8c2SCharles.Forsyth switch(tt) {
67074a4d8c2SCharles.Forsyth case TDOUBLE:
67174a4d8c2SCharles.Forsyth case TVLONG:
67274a4d8c2SCharles.Forsyth gins(AMOVWD, f, t);
67374a4d8c2SCharles.Forsyth if(ft == TULONG) {
67474a4d8c2SCharles.Forsyth }
67574a4d8c2SCharles.Forsyth return;
67674a4d8c2SCharles.Forsyth case TFLOAT:
67774a4d8c2SCharles.Forsyth gins(AMOVWF, f, t);
67874a4d8c2SCharles.Forsyth if(ft == TULONG) {
67974a4d8c2SCharles.Forsyth }
68074a4d8c2SCharles.Forsyth return;
68174a4d8c2SCharles.Forsyth case TINT:
68274a4d8c2SCharles.Forsyth case TUINT:
68374a4d8c2SCharles.Forsyth case TLONG:
68474a4d8c2SCharles.Forsyth case TULONG:
68574a4d8c2SCharles.Forsyth case TIND:
68674a4d8c2SCharles.Forsyth case TSHORT:
68774a4d8c2SCharles.Forsyth case TUSHORT:
68874a4d8c2SCharles.Forsyth case TCHAR:
68974a4d8c2SCharles.Forsyth case TUCHAR:
69074a4d8c2SCharles.Forsyth a = AMOVW;
69174a4d8c2SCharles.Forsyth break;
69274a4d8c2SCharles.Forsyth }
69374a4d8c2SCharles.Forsyth break;
69474a4d8c2SCharles.Forsyth case TSHORT:
69574a4d8c2SCharles.Forsyth switch(tt) {
69674a4d8c2SCharles.Forsyth case TDOUBLE:
69774a4d8c2SCharles.Forsyth case TVLONG:
69874a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
69974a4d8c2SCharles.Forsyth gins(AMOVH, f, &nod);
70074a4d8c2SCharles.Forsyth gins(AMOVWD, &nod, t);
70174a4d8c2SCharles.Forsyth regfree(&nod);
70274a4d8c2SCharles.Forsyth return;
70374a4d8c2SCharles.Forsyth case TFLOAT:
70474a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
70574a4d8c2SCharles.Forsyth gins(AMOVH, f, &nod);
70674a4d8c2SCharles.Forsyth gins(AMOVWF, &nod, t);
70774a4d8c2SCharles.Forsyth regfree(&nod);
70874a4d8c2SCharles.Forsyth return;
70974a4d8c2SCharles.Forsyth case TUINT:
71074a4d8c2SCharles.Forsyth case TINT:
71174a4d8c2SCharles.Forsyth case TULONG:
71274a4d8c2SCharles.Forsyth case TLONG:
71374a4d8c2SCharles.Forsyth case TIND:
71474a4d8c2SCharles.Forsyth a = AMOVH;
71574a4d8c2SCharles.Forsyth break;
71674a4d8c2SCharles.Forsyth case TSHORT:
71774a4d8c2SCharles.Forsyth case TUSHORT:
71874a4d8c2SCharles.Forsyth case TCHAR:
71974a4d8c2SCharles.Forsyth case TUCHAR:
72074a4d8c2SCharles.Forsyth a = AMOVW;
72174a4d8c2SCharles.Forsyth break;
72274a4d8c2SCharles.Forsyth }
72374a4d8c2SCharles.Forsyth break;
72474a4d8c2SCharles.Forsyth case TUSHORT:
72574a4d8c2SCharles.Forsyth switch(tt) {
72674a4d8c2SCharles.Forsyth case TDOUBLE:
72774a4d8c2SCharles.Forsyth case TVLONG:
72874a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
72974a4d8c2SCharles.Forsyth gins(AMOVHU, f, &nod);
73074a4d8c2SCharles.Forsyth gins(AMOVWD, &nod, t);
73174a4d8c2SCharles.Forsyth regfree(&nod);
73274a4d8c2SCharles.Forsyth return;
73374a4d8c2SCharles.Forsyth case TFLOAT:
73474a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
73574a4d8c2SCharles.Forsyth gins(AMOVHU, f, &nod);
73674a4d8c2SCharles.Forsyth gins(AMOVWF, &nod, t);
73774a4d8c2SCharles.Forsyth regfree(&nod);
73874a4d8c2SCharles.Forsyth return;
73974a4d8c2SCharles.Forsyth case TINT:
74074a4d8c2SCharles.Forsyth case TUINT:
74174a4d8c2SCharles.Forsyth case TLONG:
74274a4d8c2SCharles.Forsyth case TULONG:
74374a4d8c2SCharles.Forsyth case TIND:
74474a4d8c2SCharles.Forsyth a = AMOVHU;
74574a4d8c2SCharles.Forsyth break;
74674a4d8c2SCharles.Forsyth case TSHORT:
74774a4d8c2SCharles.Forsyth case TUSHORT:
74874a4d8c2SCharles.Forsyth case TCHAR:
74974a4d8c2SCharles.Forsyth case TUCHAR:
75074a4d8c2SCharles.Forsyth a = AMOVW;
75174a4d8c2SCharles.Forsyth break;
75274a4d8c2SCharles.Forsyth }
75374a4d8c2SCharles.Forsyth break;
75474a4d8c2SCharles.Forsyth case TCHAR:
75574a4d8c2SCharles.Forsyth switch(tt) {
75674a4d8c2SCharles.Forsyth case TDOUBLE:
75774a4d8c2SCharles.Forsyth case TVLONG:
75874a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
75974a4d8c2SCharles.Forsyth gins(AMOVB, f, &nod);
76074a4d8c2SCharles.Forsyth gins(AMOVWD, &nod, t);
76174a4d8c2SCharles.Forsyth regfree(&nod);
76274a4d8c2SCharles.Forsyth return;
76374a4d8c2SCharles.Forsyth case TFLOAT:
76474a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
76574a4d8c2SCharles.Forsyth gins(AMOVB, f, &nod);
76674a4d8c2SCharles.Forsyth gins(AMOVWF, &nod, t);
76774a4d8c2SCharles.Forsyth regfree(&nod);
76874a4d8c2SCharles.Forsyth return;
76974a4d8c2SCharles.Forsyth case TINT:
77074a4d8c2SCharles.Forsyth case TUINT:
77174a4d8c2SCharles.Forsyth case TLONG:
77274a4d8c2SCharles.Forsyth case TULONG:
77374a4d8c2SCharles.Forsyth case TIND:
77474a4d8c2SCharles.Forsyth case TSHORT:
77574a4d8c2SCharles.Forsyth case TUSHORT:
77674a4d8c2SCharles.Forsyth a = AMOVB;
77774a4d8c2SCharles.Forsyth break;
77874a4d8c2SCharles.Forsyth case TCHAR:
77974a4d8c2SCharles.Forsyth case TUCHAR:
78074a4d8c2SCharles.Forsyth a = AMOVW;
78174a4d8c2SCharles.Forsyth break;
78274a4d8c2SCharles.Forsyth }
78374a4d8c2SCharles.Forsyth break;
78474a4d8c2SCharles.Forsyth case TUCHAR:
78574a4d8c2SCharles.Forsyth switch(tt) {
78674a4d8c2SCharles.Forsyth case TDOUBLE:
78774a4d8c2SCharles.Forsyth case TVLONG:
78874a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
78974a4d8c2SCharles.Forsyth gins(AMOVBU, f, &nod);
79074a4d8c2SCharles.Forsyth gins(AMOVWD, &nod, t);
79174a4d8c2SCharles.Forsyth regfree(&nod);
79274a4d8c2SCharles.Forsyth return;
79374a4d8c2SCharles.Forsyth case TFLOAT:
79474a4d8c2SCharles.Forsyth regalloc(&nod, f, Z);
79574a4d8c2SCharles.Forsyth gins(AMOVBU, f, &nod);
79674a4d8c2SCharles.Forsyth gins(AMOVWF, &nod, t);
79774a4d8c2SCharles.Forsyth regfree(&nod);
79874a4d8c2SCharles.Forsyth return;
79974a4d8c2SCharles.Forsyth case TINT:
80074a4d8c2SCharles.Forsyth case TUINT:
80174a4d8c2SCharles.Forsyth case TLONG:
80274a4d8c2SCharles.Forsyth case TULONG:
80374a4d8c2SCharles.Forsyth case TIND:
80474a4d8c2SCharles.Forsyth case TSHORT:
80574a4d8c2SCharles.Forsyth case TUSHORT:
80674a4d8c2SCharles.Forsyth a = AMOVBU;
80774a4d8c2SCharles.Forsyth break;
80874a4d8c2SCharles.Forsyth case TCHAR:
80974a4d8c2SCharles.Forsyth case TUCHAR:
81074a4d8c2SCharles.Forsyth a = AMOVW;
81174a4d8c2SCharles.Forsyth break;
81274a4d8c2SCharles.Forsyth }
81374a4d8c2SCharles.Forsyth break;
81474a4d8c2SCharles.Forsyth }
81574a4d8c2SCharles.Forsyth if(a == AGOK)
81674a4d8c2SCharles.Forsyth diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
81774a4d8c2SCharles.Forsyth if(a == AMOVW || a == AMOVF || a == AMOVD)
81874a4d8c2SCharles.Forsyth if(samaddr(f, t))
81974a4d8c2SCharles.Forsyth return;
82074a4d8c2SCharles.Forsyth gins(a, f, t);
82174a4d8c2SCharles.Forsyth }
82274a4d8c2SCharles.Forsyth
82374a4d8c2SCharles.Forsyth void
gins(int a,Node * f,Node * t)82474a4d8c2SCharles.Forsyth gins(int a, Node *f, Node *t)
82574a4d8c2SCharles.Forsyth {
82674a4d8c2SCharles.Forsyth
82774a4d8c2SCharles.Forsyth nextpc();
82874a4d8c2SCharles.Forsyth p->as = a;
82974a4d8c2SCharles.Forsyth if(f != Z)
83074a4d8c2SCharles.Forsyth naddr(f, &p->from);
83174a4d8c2SCharles.Forsyth if(t != Z)
83274a4d8c2SCharles.Forsyth naddr(t, &p->to);
83374a4d8c2SCharles.Forsyth if(debug['g'])
83474a4d8c2SCharles.Forsyth print("%P\n", p);
83574a4d8c2SCharles.Forsyth }
83674a4d8c2SCharles.Forsyth
83774a4d8c2SCharles.Forsyth void
gopcode(int o,Node * f1,Node * f2,Node * t)83874a4d8c2SCharles.Forsyth gopcode(int o, Node *f1, Node *f2, Node *t)
83974a4d8c2SCharles.Forsyth {
84074a4d8c2SCharles.Forsyth int a, et;
84174a4d8c2SCharles.Forsyth Adr ta;
84274a4d8c2SCharles.Forsyth
84374a4d8c2SCharles.Forsyth et = TLONG;
84474a4d8c2SCharles.Forsyth if(f1 != Z && f1->type != T)
84574a4d8c2SCharles.Forsyth et = f1->type->etype;
84674a4d8c2SCharles.Forsyth a = AGOK;
84774a4d8c2SCharles.Forsyth switch(o) {
84874a4d8c2SCharles.Forsyth case OAS:
84974a4d8c2SCharles.Forsyth gmove(f1, t);
85074a4d8c2SCharles.Forsyth return;
85174a4d8c2SCharles.Forsyth
85274a4d8c2SCharles.Forsyth case OASADD:
85374a4d8c2SCharles.Forsyth case OADD:
85474a4d8c2SCharles.Forsyth a = AADD;
85574a4d8c2SCharles.Forsyth if(et == TFLOAT)
85674a4d8c2SCharles.Forsyth a = AADDF;
85774a4d8c2SCharles.Forsyth else
85874a4d8c2SCharles.Forsyth if(et == TDOUBLE || et == TVLONG)
85974a4d8c2SCharles.Forsyth a = AADDD;
86074a4d8c2SCharles.Forsyth break;
86174a4d8c2SCharles.Forsyth
86274a4d8c2SCharles.Forsyth case OASSUB:
86374a4d8c2SCharles.Forsyth case OSUB:
86474a4d8c2SCharles.Forsyth a = ASUB;
86574a4d8c2SCharles.Forsyth if(et == TFLOAT)
86674a4d8c2SCharles.Forsyth a = ASUBF;
86774a4d8c2SCharles.Forsyth else
86874a4d8c2SCharles.Forsyth if(et == TDOUBLE || et == TVLONG)
86974a4d8c2SCharles.Forsyth a = ASUBD;
87074a4d8c2SCharles.Forsyth break;
87174a4d8c2SCharles.Forsyth
87274a4d8c2SCharles.Forsyth case OASOR:
87374a4d8c2SCharles.Forsyth case OOR:
87474a4d8c2SCharles.Forsyth a = AORR;
87574a4d8c2SCharles.Forsyth break;
87674a4d8c2SCharles.Forsyth
87774a4d8c2SCharles.Forsyth case OASAND:
87874a4d8c2SCharles.Forsyth case OAND:
87974a4d8c2SCharles.Forsyth a = AAND;
88074a4d8c2SCharles.Forsyth break;
88174a4d8c2SCharles.Forsyth
88274a4d8c2SCharles.Forsyth case OASXOR:
88374a4d8c2SCharles.Forsyth case OXOR:
88474a4d8c2SCharles.Forsyth a = AEOR;
88574a4d8c2SCharles.Forsyth break;
88674a4d8c2SCharles.Forsyth
88774a4d8c2SCharles.Forsyth case OASLSHR:
88874a4d8c2SCharles.Forsyth case OLSHR:
88974a4d8c2SCharles.Forsyth a = ASRL;
89074a4d8c2SCharles.Forsyth break;
89174a4d8c2SCharles.Forsyth
89274a4d8c2SCharles.Forsyth case OASASHR:
89374a4d8c2SCharles.Forsyth case OASHR:
89474a4d8c2SCharles.Forsyth a = ASRA;
89574a4d8c2SCharles.Forsyth break;
89674a4d8c2SCharles.Forsyth
89774a4d8c2SCharles.Forsyth case OASASHL:
89874a4d8c2SCharles.Forsyth case OASHL:
89974a4d8c2SCharles.Forsyth a = ASLL;
90074a4d8c2SCharles.Forsyth break;
90174a4d8c2SCharles.Forsyth
90274a4d8c2SCharles.Forsyth case OFUNC:
90374a4d8c2SCharles.Forsyth a = ABL;
90474a4d8c2SCharles.Forsyth break;
90574a4d8c2SCharles.Forsyth
90674a4d8c2SCharles.Forsyth case OASMUL:
90774a4d8c2SCharles.Forsyth case OMUL:
90874a4d8c2SCharles.Forsyth a = AMUL;
90974a4d8c2SCharles.Forsyth if(et == TFLOAT)
91074a4d8c2SCharles.Forsyth a = AMULF;
91174a4d8c2SCharles.Forsyth else
91274a4d8c2SCharles.Forsyth if(et == TDOUBLE || et == TVLONG)
91374a4d8c2SCharles.Forsyth a = AMULD;
91474a4d8c2SCharles.Forsyth break;
91574a4d8c2SCharles.Forsyth
91674a4d8c2SCharles.Forsyth case OASDIV:
91774a4d8c2SCharles.Forsyth case ODIV:
91874a4d8c2SCharles.Forsyth a = ADIV;
91974a4d8c2SCharles.Forsyth if(et == TFLOAT)
92074a4d8c2SCharles.Forsyth a = ADIVF;
92174a4d8c2SCharles.Forsyth else
92274a4d8c2SCharles.Forsyth if(et == TDOUBLE || et == TVLONG)
92374a4d8c2SCharles.Forsyth a = ADIVD;
92474a4d8c2SCharles.Forsyth break;
92574a4d8c2SCharles.Forsyth
92674a4d8c2SCharles.Forsyth case OASMOD:
92774a4d8c2SCharles.Forsyth case OMOD:
92874a4d8c2SCharles.Forsyth a = AMOD;
92974a4d8c2SCharles.Forsyth break;
93074a4d8c2SCharles.Forsyth
93174a4d8c2SCharles.Forsyth case OASLMUL:
93274a4d8c2SCharles.Forsyth case OLMUL:
93374a4d8c2SCharles.Forsyth a = AMULU;
93474a4d8c2SCharles.Forsyth break;
93574a4d8c2SCharles.Forsyth
93674a4d8c2SCharles.Forsyth case OASLMOD:
93774a4d8c2SCharles.Forsyth case OLMOD:
93874a4d8c2SCharles.Forsyth a = AMODU;
93974a4d8c2SCharles.Forsyth break;
94074a4d8c2SCharles.Forsyth
94174a4d8c2SCharles.Forsyth case OASLDIV:
94274a4d8c2SCharles.Forsyth case OLDIV:
94374a4d8c2SCharles.Forsyth a = ADIVU;
94474a4d8c2SCharles.Forsyth break;
94574a4d8c2SCharles.Forsyth
94674a4d8c2SCharles.Forsyth case OEQ:
94774a4d8c2SCharles.Forsyth case ONE:
94874a4d8c2SCharles.Forsyth case OLT:
94974a4d8c2SCharles.Forsyth case OLE:
95074a4d8c2SCharles.Forsyth case OGE:
95174a4d8c2SCharles.Forsyth case OGT:
95274a4d8c2SCharles.Forsyth case OLO:
95374a4d8c2SCharles.Forsyth case OLS:
95474a4d8c2SCharles.Forsyth case OHS:
95574a4d8c2SCharles.Forsyth case OHI:
95674a4d8c2SCharles.Forsyth a = ACMP;
95774a4d8c2SCharles.Forsyth if(et == TFLOAT)
95874a4d8c2SCharles.Forsyth a = ACMPF;
95974a4d8c2SCharles.Forsyth else
96074a4d8c2SCharles.Forsyth if(et == TDOUBLE || et == TVLONG)
96174a4d8c2SCharles.Forsyth a = ACMPD;
96274a4d8c2SCharles.Forsyth nextpc();
96374a4d8c2SCharles.Forsyth p->as = a;
96474a4d8c2SCharles.Forsyth naddr(f1, &p->from);
96574a4d8c2SCharles.Forsyth /*
96674a4d8c2SCharles.Forsyth if(a == ACMP && f1->op == OCONST && p->from.offset < 0) {
96774a4d8c2SCharles.Forsyth p->as = ACMN;
96874a4d8c2SCharles.Forsyth p->from.offset = -p->from.offset;
96974a4d8c2SCharles.Forsyth }
97074a4d8c2SCharles.Forsyth */
97174a4d8c2SCharles.Forsyth raddr(f2, p); // expects it to be a register
97274a4d8c2SCharles.Forsyth switch(o) {
97374a4d8c2SCharles.Forsyth case OEQ:
97474a4d8c2SCharles.Forsyth a = ABEQ;
97574a4d8c2SCharles.Forsyth break;
97674a4d8c2SCharles.Forsyth case ONE:
97774a4d8c2SCharles.Forsyth a = ABNE;
97874a4d8c2SCharles.Forsyth break;
97974a4d8c2SCharles.Forsyth case OLT:
98074a4d8c2SCharles.Forsyth a = ABLT;
98174a4d8c2SCharles.Forsyth break;
98274a4d8c2SCharles.Forsyth case OLE:
98374a4d8c2SCharles.Forsyth a = ABLE;
98474a4d8c2SCharles.Forsyth break;
98574a4d8c2SCharles.Forsyth case OGE:
98674a4d8c2SCharles.Forsyth a = ABGE;
98774a4d8c2SCharles.Forsyth break;
98874a4d8c2SCharles.Forsyth case OGT:
98974a4d8c2SCharles.Forsyth a = ABGT;
99074a4d8c2SCharles.Forsyth break;
99174a4d8c2SCharles.Forsyth case OLO:
99274a4d8c2SCharles.Forsyth a = ABLO;
99374a4d8c2SCharles.Forsyth break;
99474a4d8c2SCharles.Forsyth case OLS:
99574a4d8c2SCharles.Forsyth a = ABLS;
99674a4d8c2SCharles.Forsyth break;
99774a4d8c2SCharles.Forsyth case OHS:
99874a4d8c2SCharles.Forsyth a = ABHS;
99974a4d8c2SCharles.Forsyth break;
100074a4d8c2SCharles.Forsyth case OHI:
100174a4d8c2SCharles.Forsyth a = ABHI;
100274a4d8c2SCharles.Forsyth break;
100374a4d8c2SCharles.Forsyth }
100474a4d8c2SCharles.Forsyth f1 = Z;
100574a4d8c2SCharles.Forsyth f2 = Z;
100674a4d8c2SCharles.Forsyth break;
100774a4d8c2SCharles.Forsyth }
100874a4d8c2SCharles.Forsyth if(a == AGOK)
100974a4d8c2SCharles.Forsyth diag(Z, "bad in gopcode %O", o);
101074a4d8c2SCharles.Forsyth nextpc();
101174a4d8c2SCharles.Forsyth p->as = a;
101274a4d8c2SCharles.Forsyth if(f1 != Z)
101374a4d8c2SCharles.Forsyth naddr(f1, &p->from);
101474a4d8c2SCharles.Forsyth if(f2 != Z) {
101574a4d8c2SCharles.Forsyth naddr(f2, &ta);
101674a4d8c2SCharles.Forsyth p->reg = ta.reg;
101774a4d8c2SCharles.Forsyth }
101874a4d8c2SCharles.Forsyth if(t != Z)
101974a4d8c2SCharles.Forsyth naddr(t, &p->to);
102074a4d8c2SCharles.Forsyth if(debug['g'])
102174a4d8c2SCharles.Forsyth print("%P\n", p);
102274a4d8c2SCharles.Forsyth }
102374a4d8c2SCharles.Forsyth
102474a4d8c2SCharles.Forsyth /* put f1 in a register first */
102574a4d8c2SCharles.Forsyth void
gopcode2(int o,Node * f1,Node * f2,Node * t)102674a4d8c2SCharles.Forsyth gopcode2(int o, Node *f1, Node *f2, Node *t)
102774a4d8c2SCharles.Forsyth {
102874a4d8c2SCharles.Forsyth Node nod;
102974a4d8c2SCharles.Forsyth
103074a4d8c2SCharles.Forsyth if(f2 != Z)
103174a4d8c2SCharles.Forsyth diag(Z, "bad parameter in gopcode2");
103274a4d8c2SCharles.Forsyth // regalloc(&nod, t, Z);
103374a4d8c2SCharles.Forsyth nodreg(&nod, t, REGTMPT);
103474a4d8c2SCharles.Forsyth gopcode(OAS, f1, Z, &nod);
103574a4d8c2SCharles.Forsyth gopcode(o, &nod, Z, t);
103674a4d8c2SCharles.Forsyth // regfree(&nod);
103774a4d8c2SCharles.Forsyth }
103874a4d8c2SCharles.Forsyth
1039*45a20ab7Sforsyth int
samaddr(Node * f,Node * t)104074a4d8c2SCharles.Forsyth samaddr(Node *f, Node *t)
104174a4d8c2SCharles.Forsyth {
104274a4d8c2SCharles.Forsyth
104374a4d8c2SCharles.Forsyth if(f->op != t->op)
104474a4d8c2SCharles.Forsyth return 0;
104574a4d8c2SCharles.Forsyth switch(f->op) {
104674a4d8c2SCharles.Forsyth
104774a4d8c2SCharles.Forsyth case OREGISTER:
104874a4d8c2SCharles.Forsyth if(f->reg != t->reg)
104974a4d8c2SCharles.Forsyth break;
105074a4d8c2SCharles.Forsyth return 1;
105174a4d8c2SCharles.Forsyth }
105274a4d8c2SCharles.Forsyth return 0;
105374a4d8c2SCharles.Forsyth }
105474a4d8c2SCharles.Forsyth
105574a4d8c2SCharles.Forsyth void
gbranch(int o)105674a4d8c2SCharles.Forsyth gbranch(int o)
105774a4d8c2SCharles.Forsyth {
105874a4d8c2SCharles.Forsyth int a;
105974a4d8c2SCharles.Forsyth
106074a4d8c2SCharles.Forsyth a = AGOK;
106174a4d8c2SCharles.Forsyth switch(o) {
106274a4d8c2SCharles.Forsyth case ORETURN:
106374a4d8c2SCharles.Forsyth a = ARET;
106474a4d8c2SCharles.Forsyth break;
106574a4d8c2SCharles.Forsyth case OGOTO:
106674a4d8c2SCharles.Forsyth a = AB;
106774a4d8c2SCharles.Forsyth break;
106874a4d8c2SCharles.Forsyth }
106974a4d8c2SCharles.Forsyth nextpc();
107074a4d8c2SCharles.Forsyth if(a == AGOK) {
107174a4d8c2SCharles.Forsyth diag(Z, "bad in gbranch %O", o);
107274a4d8c2SCharles.Forsyth nextpc();
107374a4d8c2SCharles.Forsyth }
107474a4d8c2SCharles.Forsyth p->as = a;
107574a4d8c2SCharles.Forsyth }
107674a4d8c2SCharles.Forsyth
107774a4d8c2SCharles.Forsyth void
patch(Prog * op,long pc)107874a4d8c2SCharles.Forsyth patch(Prog *op, long pc)
107974a4d8c2SCharles.Forsyth {
108074a4d8c2SCharles.Forsyth
108174a4d8c2SCharles.Forsyth op->to.offset = pc;
108274a4d8c2SCharles.Forsyth op->to.type = D_BRANCH;
108374a4d8c2SCharles.Forsyth }
108474a4d8c2SCharles.Forsyth
108574a4d8c2SCharles.Forsyth void
gpseudo(int a,Sym * s,Node * n)108674a4d8c2SCharles.Forsyth gpseudo(int a, Sym *s, Node *n)
108774a4d8c2SCharles.Forsyth {
108874a4d8c2SCharles.Forsyth
108974a4d8c2SCharles.Forsyth nextpc();
109074a4d8c2SCharles.Forsyth p->as = a;
109174a4d8c2SCharles.Forsyth p->from.type = D_OREG;
109274a4d8c2SCharles.Forsyth p->from.sym = s;
109374a4d8c2SCharles.Forsyth p->from.name = D_EXTERN;
109474a4d8c2SCharles.Forsyth if(a == ATEXT)
109574a4d8c2SCharles.Forsyth p->reg = (profileflg ? 0 : NOPROF);
109674a4d8c2SCharles.Forsyth if(s->class == CSTATIC)
109774a4d8c2SCharles.Forsyth p->from.name = D_STATIC;
109874a4d8c2SCharles.Forsyth naddr(n, &p->to);
109974a4d8c2SCharles.Forsyth if(a == ADATA || a == AGLOBL)
110074a4d8c2SCharles.Forsyth pc--;
110174a4d8c2SCharles.Forsyth }
110274a4d8c2SCharles.Forsyth
110374a4d8c2SCharles.Forsyth int
sconst(Node * n)110474a4d8c2SCharles.Forsyth sconst(Node *n)
110574a4d8c2SCharles.Forsyth {
110674a4d8c2SCharles.Forsyth vlong vv;
110774a4d8c2SCharles.Forsyth
110874a4d8c2SCharles.Forsyth if(n->op == OCONST) {
110974a4d8c2SCharles.Forsyth if(!typefd[n->type->etype]) {
111074a4d8c2SCharles.Forsyth vv = n->vconst;
111174a4d8c2SCharles.Forsyth if(vv >= (vlong)0 && vv < (vlong)256)
111274a4d8c2SCharles.Forsyth return 1;
111374a4d8c2SCharles.Forsyth /*
111474a4d8c2SCharles.Forsyth * should be specialised for constant values which will
111574a4d8c2SCharles.Forsyth * fit in different instructionsl; for now, let 5l
111674a4d8c2SCharles.Forsyth * sort it out
111774a4d8c2SCharles.Forsyth */
111874a4d8c2SCharles.Forsyth return 1;
111974a4d8c2SCharles.Forsyth }
112074a4d8c2SCharles.Forsyth }
112174a4d8c2SCharles.Forsyth return 0;
112274a4d8c2SCharles.Forsyth }
112374a4d8c2SCharles.Forsyth
112474a4d8c2SCharles.Forsyth int
sval(long v)112574a4d8c2SCharles.Forsyth sval(long v)
112674a4d8c2SCharles.Forsyth {
112774a4d8c2SCharles.Forsyth if(v >= -32768 && v < 32768)
112874a4d8c2SCharles.Forsyth return 1;
112974a4d8c2SCharles.Forsyth return 0;
113074a4d8c2SCharles.Forsyth }
113174a4d8c2SCharles.Forsyth
113274a4d8c2SCharles.Forsyth long
exreg(Type * t)113374a4d8c2SCharles.Forsyth exreg(Type *t)
113474a4d8c2SCharles.Forsyth {
113574a4d8c2SCharles.Forsyth long o;
113674a4d8c2SCharles.Forsyth
113774a4d8c2SCharles.Forsyth if(typechlp[t->etype]) {
113874a4d8c2SCharles.Forsyth if(exregoffset <= NREG-1)
113974a4d8c2SCharles.Forsyth return 0;
114074a4d8c2SCharles.Forsyth o = exregoffset;
114174a4d8c2SCharles.Forsyth exregoffset--;
114274a4d8c2SCharles.Forsyth return o;
114374a4d8c2SCharles.Forsyth }
114474a4d8c2SCharles.Forsyth if(typefd[t->etype]) {
114574a4d8c2SCharles.Forsyth if(exfregoffset <= NFREG-1)
114674a4d8c2SCharles.Forsyth return 0;
114774a4d8c2SCharles.Forsyth o = exfregoffset + NREG;
114874a4d8c2SCharles.Forsyth exfregoffset--;
114974a4d8c2SCharles.Forsyth return o;
115074a4d8c2SCharles.Forsyth }
115174a4d8c2SCharles.Forsyth return 0;
115274a4d8c2SCharles.Forsyth }
115374a4d8c2SCharles.Forsyth
115474a4d8c2SCharles.Forsyth schar ewidth[NTYPE] =
115574a4d8c2SCharles.Forsyth {
115674a4d8c2SCharles.Forsyth -1, /* [TXXX] */
115774a4d8c2SCharles.Forsyth SZ_CHAR, /* [TCHAR] */
115874a4d8c2SCharles.Forsyth SZ_CHAR, /* [TUCHAR] */
115974a4d8c2SCharles.Forsyth SZ_SHORT, /* [TSHORT] */
116074a4d8c2SCharles.Forsyth SZ_SHORT, /* [TUSHORT] */
116174a4d8c2SCharles.Forsyth SZ_INT, /* [TINT] */
116274a4d8c2SCharles.Forsyth SZ_INT, /* [TUINT] */
116374a4d8c2SCharles.Forsyth SZ_LONG, /* [TLONG] */
116474a4d8c2SCharles.Forsyth SZ_LONG, /* [TULONG] */
116574a4d8c2SCharles.Forsyth SZ_VLONG, /* [TVLONG] */
116674a4d8c2SCharles.Forsyth SZ_VLONG, /* [TUVLONG] */
116774a4d8c2SCharles.Forsyth SZ_FLOAT, /* [TFLOAT] */
116874a4d8c2SCharles.Forsyth SZ_DOUBLE, /* [TDOUBLE] */
116974a4d8c2SCharles.Forsyth SZ_IND, /* [TIND] */
117074a4d8c2SCharles.Forsyth 0, /* [TFUNC] */
117174a4d8c2SCharles.Forsyth -1, /* [TARRAY] */
117274a4d8c2SCharles.Forsyth 0, /* [TVOID] */
117374a4d8c2SCharles.Forsyth -1, /* [TSTRUCT] */
117474a4d8c2SCharles.Forsyth -1, /* [TUNION] */
117574a4d8c2SCharles.Forsyth SZ_INT, /* [TENUM] */
117674a4d8c2SCharles.Forsyth };
117774a4d8c2SCharles.Forsyth
117874a4d8c2SCharles.Forsyth long ncast[NTYPE] =
117974a4d8c2SCharles.Forsyth {
118074a4d8c2SCharles.Forsyth 0, /* [TXXX] */
118174a4d8c2SCharles.Forsyth BCHAR|BUCHAR, /* [TCHAR] */
118274a4d8c2SCharles.Forsyth BCHAR|BUCHAR, /* [TUCHAR] */
118374a4d8c2SCharles.Forsyth BSHORT|BUSHORT, /* [TSHORT] */
118474a4d8c2SCharles.Forsyth BSHORT|BUSHORT, /* [TUSHORT] */
118574a4d8c2SCharles.Forsyth BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
118674a4d8c2SCharles.Forsyth BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
118774a4d8c2SCharles.Forsyth BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
118874a4d8c2SCharles.Forsyth BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
118974a4d8c2SCharles.Forsyth BVLONG|BUVLONG, /* [TVLONG] */
119074a4d8c2SCharles.Forsyth BVLONG|BUVLONG, /* [TUVLONG] */
119174a4d8c2SCharles.Forsyth BFLOAT, /* [TFLOAT] */
119274a4d8c2SCharles.Forsyth BDOUBLE, /* [TDOUBLE] */
119374a4d8c2SCharles.Forsyth BLONG|BULONG|BIND, /* [TIND] */
119474a4d8c2SCharles.Forsyth 0, /* [TFUNC] */
119574a4d8c2SCharles.Forsyth 0, /* [TARRAY] */
119674a4d8c2SCharles.Forsyth 0, /* [TVOID] */
119774a4d8c2SCharles.Forsyth BSTRUCT, /* [TSTRUCT] */
119874a4d8c2SCharles.Forsyth BUNION, /* [TUNION] */
119974a4d8c2SCharles.Forsyth 0, /* [TENUM] */
120074a4d8c2SCharles.Forsyth };
1201