|
|
1.1 root 1: #include "gencode.h"
2: char *jeq = "jeql";
3: char *jne = "jneq";
4: char *jgt = "jgtr";
5: char *jge = "jgeq";
6: char *jlt = "jlss";
7: char *jle = "jleq";
8: char *jugt = "jgtru";
9: char *juge = "jgequ";
10: char *jult = "jlssu";
11: char *jule = "jlequ";
12: mnod *gimmemnod();
13:
14: char prbuf[10*1024];
15: extern int bothdebug, nosharp;
16: #define NBUF 256 /* must fit in an unsigned char */
17: char bufs[NBUF][BUF], *buf;
18: char *bufend = (char *)bufs + sizeof(bufs);
19: pr(fmt, list)
20: char *fmt; long list;
21: { char *n;
22: char *sprintxl();
23: nosharp = !bothdebug;
24: prptr = sprintxl(n=prptr, fmt, &list);
25: if(prptr > prbuf + sizeof(prbuf))
26: cerror("prbuf overflow");
27: nosharp = 0;
28: }
29:
30: outpr()
31: {
32: *prptr = 0;
33: printbuf(prbuf, prptr-prbuf);
34: }
35:
36: ret
37: checksize(p, s, regmask)
38: mnod *p;
39: ret s;
40: { ret t;
41: if(p->type != Tdouble)
42: return(s);
43: regmask |= s.regmask;
44: t = allocreg(p, regmask);
45: return(t);
46: }
47:
48: gimmetemp(n)
49: {
50: return(freetemp(n)/8 - maxboff/SZCHAR);
51: }
52:
53: commutes(op)
54: {
55: switch(op) {
56: default:
57: cerror("unexpected op in commutes");
58: case Plus: case Mul: case Or: case Xor: case And:
59: return(1);
60: case Minus: case Div: case Mod:
61: return(0);
62: }
63: }
64:
65: strshift(s, n)
66: char *s;
67: { int i, j;
68: i = strlen(s);
69: if(n > 0)
70: for(j = i; j >= 0; j--)
71: s[j + n] = s[j];
72: else
73: for(j = -n; j <= i; j++)
74: s[j + n] = s[j];
75: }
76:
77: ret
78: tostack()
79: { ret s;
80: sprintx(buf, "-(sp)");
81: done(s, 0, 0);
82: }
83:
84: char *
85: genjbc(n)
86: {
87: if(n == EQ)
88: return("jbc");
89: if(n == NE)
90: return("jbs");
91: cerror("impossible jmp mask type");
92: return("jweird");
93: }
94:
95: char *
96: genjmp(n)
97: {
98: switch(n) {
99: default: cerror("impossible jmp type"); return("jweird");
100: case EQ: return(jeq);
101: case NE: return(jne);
102: case GT: return(jgt);
103: case GE: return(jge);
104: case LT: return(jlt);
105: case LE: return(jle);
106: case UGT: return(jugt);
107: case UGE: return(juge);
108: case ULT: return(jult);
109: case ULE: return(jule);
110: }
111: }
112:
113: pow2(n)
114: { int i;
115: if(n & (n-1))
116: return(-1);
117: for(i = 0; i < 32; i++) /* good old vax */
118: if(n & (1 << i))
119: return(i);
120: return(-1); /* can't happen */
121: }
122:
123: ret
124: indirit(s)
125: ret s;
126: {
127: if(s.flag & ISREG) {
128: strcat(str(s), ")");
129: strshift(str(s), 1);
130: str(s)[0] = '(';
131: return(s);
132: }
133: if(s.flag & CANINDIR) {
134: strshift(str(s), 1);
135: str(s)[0] = '*';
136: return(s);
137: }
138: if(str(s)[0] == '(') { /* (r3)[r11] */
139: strshift(str(s), 1);
140: str(s)[0] = '*';
141: return(s);
142: }
143: if(str(s)[0] == '$') { /* an icon for structure returns */
144: strshift(str(s), -1);
145: return(s);
146: }
147: debugpr("# FAIL ");
148: s.flag = FAIL;
149: return(s);
150: }
151:
152: ret /* unseal the seals for Stasg */
153: addrsimp(a, b)
154: ret a, b;
155: { extern char *index();
156: char *p;
157: if(str(b)[0] == '(') { /* posit register */
158: reg:
159: strshift(str(b), -1);
160: *index(str(b), ')') = 0;
161: return(b);
162: }
163: if(str(a)[0] == '(') { /* posit register */
164: b = a;
165: goto reg;
166: }
167: if(str(b)[0] == '_') { /* posit name of struct */
168: name:
169: pr("#\tmoval\t%s,r0\n", str(b));
170: b.regmask = 1;
171: b.flag = ISREG|SCRATCH;
172: strcpy(str(b), "r0"); /* arrrrrgh */
173: return(b);
174: }
175: if(str(a)[0] == '_') {
176: b = a;
177: goto name;
178: }
179: if(str(b)[0] == '*') {
180: unstar:
181: p = index(str(b), '+');
182: if(!p)
183: p = index(str(b), '-');
184: if(p && (*(p+1) == 0 || *(p+1) == '('))
185: goto bad;
186: strshift(str(b), -1);
187: return(b);
188: }
189: if(str(a)[0] == '*') {
190: b = a;
191: goto unstar;
192: }
193: if(str(b)[0] == 'L') {
194: label:
195: strshift(str(b), 1);
196: str(b)[0] = '&';
197: return(b);
198: }
199: if(str(a)[0] == 'L') {
200: b = a;
201: goto label;
202: }
203: bad:
204: cerror("(addrsimp) rewrite struct asg");
205: }
206:
207: ret
208: simpler(a, b) /* returns b (as dest) preferentially */
209: ret a, b;
210: {
211: if(b.flag & ISREG)
212: return(b);
213: if(a.flag & ISREG)
214: return(a);
215: if(b.flag & SCRATCH)
216: return(b);
217: if(a.flag & SCRATCH)
218: return(a);
219: if(!(b.flag & INDEX))
220: return(b);
221: if(!(a.flag & INDEX))
222: return(a);
223: /* disallow *p++ = *q++ but not p[i]=q[i]*/
224: if(!index(str(b), '-') && !index(str(b), '+'))
225: return(b);
226: if(!index(str(a), '-') && !index(str(a), '+'))
227: return(a);
228: b.flag |= USED;
229: return(b);
230: }
231:
232: hasqnode(p)
233: mnod *p;
234: {
235: if(p->op == Asg && p->left->op == Qnode) {
236: return(1);
237: }
238: if(1) {
239: return(0);
240: }
241: switch(p->op) {
242: default:
243: cerror("hasqnode\n");
244: case Andeq: case And: case Cmp: case Comop: case Decr:
245: case Diveq: case Div: case Xoreq: case Xor:
246: case Incr: case Lseq: case Ls: case Minuseq: case Minus:
247: case Modeq: case Mod: case Muleq: case Mul: case Oreq:
248: case Or: case Pluseq: case Plus: case Rseq: case Rs:
249: case Asg: case Cm:
250: case Call: case Stcall:
251: case Stasg:
252: return(hasqnode(p->left) || hasqnode(p->right));
253: case Compl: case Conv: case Genbr: case Genlab:
254: case Genubr: case Star: case Addr: case Ucall:
255: case Uminus: case Ustcall: case Init: case Funarg:
256: case Fld:case Starg:
257: return(hasqnode(p->left));
258: case Auto: case Reg: case Name: case Param: case Icon:
259: case Snode: case Rnode:
260: return(0);
261: case Qnode:
262: return(1);
263: }
264: }
265:
266: mnod *
267: copytree(p)
268: NODE *p;
269: { mnod *a, *b, *c;
270: c = gimmemnod();
271: switch(p->in.op) {
272: case ASG AND: case AND: case CMP: case COMOP: case DECR:
273: case ASG DIV: case DIV: case ASG ER: case ER:
274: case INCR: case ASG LS: case LS: case ASG MINUS: case MINUS:
275: case ASG MOD: case MOD: case ASG MUL: case MUL: case ASG OR:
276: case OR: case ASG PLUS: case PLUS: case ASG RS: case RS:
277: case ASSIGN: case CM:
278: a = copytree(p->in.left);
279: b = copytree(p->in.right);
280: c->left = a;
281: c->right = b;
282: break;
283: case CALL: case STCALL:
284: a = copytree(p->in.left);
285: b = copytree(p->in.right);
286: c->argsize = p->stn.argsize;
287: c->left = a;
288: c->right = b;
289: break;
290: case STASG:
291: a = copytree(p->in.left);
292: b = copytree(p->in.right);
293: c->stsize = p->stn.stsize;
294: c->left = a;
295: c->right = b;
296: break;
297: case COMPL: case CONV: case GENBR: case GENLAB:
298: case GENUBR: case STAR: case UNARY AND: case UNARY CALL:
299: case UNARY MINUS: case UNARY STCALL: case INIT: case FUNARG:
300: a = copytree(p->in.left);
301: c->label = p->bn.label; /* should be separated out */
302: c->lop = p->bn.lop;
303: c->left = a;
304: break;
305: case FLD:case STARG:
306: a = copytree(p->in.left);
307: c->left = a;
308: c->rval = p->tn.rval;
309: c->stsize = p->stn.stsize;
310: break;
311: case VAUTO: case REG: case NAME: case VPARAM: case ICON:
312: case SNODE: case RNODE: case QNODE:
313: c->name = p->tn.name;
314: c->lval = p->tn.lval;
315: c->rval = p->tn.rval;
316: break;
317: }
318: switch(p->in.op) {
319: default:
320: cerror("unk op in copytree");
321: case ASG AND: c->op = Andeq; break;
322: case AND: c->op = And; break;
323: case CMP: c->op = Cmp; break;
324: case COMOP: c->op = Comop; break;
325: case DECR: c->op = Decr; break;
326: case ASG DIV: c->op = Diveq; break;
327: case DIV: c->op = Div; break;
328: case ASG ER: c->op = Xoreq; break;
329: case ER: c->op = Xor; break;
330: case INCR: c->op = Incr; break;
331: case ASG LS: c->op = Lseq; break;
332: case LS: c->op = Ls; break;
333: case ASG MINUS: c->op = Minuseq; break;
334: case MINUS: c->op = Minus; break;
335: case ASG MOD: c->op = Modeq; break;
336: case MOD: c->op = Mod; break;
337: case ASG MUL: c->op = Muleq; break;
338: case MUL: c->op = Mul; break;
339: case ASG OR: c->op = Oreq; break;
340: case OR: c->op = Or; break;
341: case ASG PLUS: c->op = Pluseq; break;
342: case PLUS: c->op = Plus; break;
343: case ASG RS: c->op = Rseq; break;
344: case RS: c->op = Rs; break;
345: case ASSIGN: c->op = Asg; break;
346: case CM: c->op = Cm; break;
347: case CALL: c->op = Call; break;
348: case STCALL: c->op = Stcall; break;
349: case STASG: c->op = Stasg; break;
350: case COMPL: c->op = Compl; break;
351: case CONV: c->op = Conv; break;
352: case GENBR: c->op = Genbr; break;
353: case GENLAB: c->op = Genlab; break;
354: case GENUBR: c->op = Genubr; break;
355: case STAR: c->op = Star; break;
356: case UNARY AND: c->op = Addr; break;
357: case UNARY CALL: c->op = Ucall; break;
358: case UNARY MINUS: c->op = Uminus; break;
359: case UNARY STCALL: c->op = Ustcall; break;
360: case INIT: c->op = Init; break;
361: case FUNARG: c->op = Funarg; break;
362: case FLD: c->op = Fld; break;
363: case STARG: c->op = Starg; break;
364: case VAUTO: c->op = Auto; break;
365: case REG: c->op = Reg; break;
366: case NAME: c->op = Name; break;
367: case VPARAM: c->op = Param; break;
368: case ICON: c->op = Icon; break;
369: case SNODE: c->op = Snode; break;
370: case QNODE: c->op = Qnode; break;
371: case RNODE: c->op = Rnode; break;
372: }
373: switch(p->in.type) {
374: default:
375: cerror("incomprehensible type");
376: case TCHAR: c->type = Tchar; break;
377: case TUCHAR: c->type = Tuchar; break;
378: case TSHORT: c->type = Tshort; break;
379: case TUSHORT: c->type = Tushort; break;
380: case TINT: c->type = Tint; break;
381: case TUNSIGNED: c->type = Tuint; break;
382: case TLONG: c->type = Tlong; break;
383: case TULONG: c->type = Tulong; break;
384: case TPOINT: c->type = Tpoint; break;
385: case TFLOAT: c->type = Tfloat; break;
386: case TDOUBLE: c->type = Tdouble; break;
387: case TSTRUCT: c->type = Tstruct; break;
388: case TVOID: c->type = Tvoid; break;
389: }
390: }
391:
392: /* does p contain an asgop or Incr (or could it be evaluated twice) */
393: sideffects(p)
394: mnod *p;
395: {
396: switch(p->op) {
397: case Andeq: case Decr: case Diveq: case Xoreq: case Incr:
398: case Lseq: case Minuseq:case Modeq: case Muleq: case Oreq:
399: case Pluseq: case Rseq: case Call: case Stcall: case Ucall:
400: return(1);
401: case And: case Cmp: case Comop: case Div: case Xor:
402: case Ls: case Minus: case Mod: case Mul:
403: case Or: case Plus: case Rs: case Asg: case Cm: case Stasg:
404: return(sideffects(p->left) || sideffects(p->right));
405: case Compl: case Conv: case Genbr: case Genlab:
406: case Genubr: case Star: case Addr:
407: case Uminus: case Ustcall: case Init: case Funarg:
408: case Fld: case Starg:
409: return(sideffects(p->left));
410: case Auto: case Reg: case Name: case Param: case Icon:
411: case Snode: case Rnode: case Qnode:
412: return(0);
413: default:
414: cerror("unk mnod in sideffects");
415: }
416: }
417: /* to make up for pointless 9th edition name change */
418: char *
419: index(s, c)
420: char *s;
421: {
422: return(strchr(s, c));
423: }
424:
425: char *
426: rindex(s, c)
427: {
428: return(strrchr(s, c));
429: }
430:
431: overr()
432: {
433: cerror("expression too complicated");
434: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.