|
|
1.1 root 1: /* C compiler: VAX subset code generator */
2:
3: #include "c.h"
4:
5: #ifdef DEBUG
6: #define debug(x,y) if (x) y
7: static void lprint(Node, char *);
8: static void nprint(Node);
9: static char *rnames(unsigned);
10: static int id;
11: static Node lhead;
12:
13: #else
14: #define debug(x,y)
15: #endif
16:
17: static int rflag; /* != 0 to trace register allocation */
18: static int framesize; /* size of activation record */
19: static int offset; /* current frame offset */
20: static int argbuildsize; /* size of argument build area */
21: static int argoffset; /* offset from top of stack for next argument */
22: static int nregs = 12; /* number of allocatable registers */
23: static unsigned rmask; /* rmask&(1<<r) == 0 if register r is free */
24: static unsigned usedmask; /* usedmask&(1<<r) == 1 if register r was used */
25: static int reginfo[] = { /* 1<<x if op+x is legal; */
26: 0, /* 0x1000<<x if op+x needs a register */
27: #include "reginfo.h"
28: };
29:
30: static void genreloads(Node, Node, Symbol);
31: static Symbol genspill(Node);
32: static void getreg(Node);
33: static Node *linearize(Node, Node *, Node);
34: static int needsreg(Node);
35: static void putreg(Node);
36: static void ralloc(Node);
37: static void restore(unsigned);
38: static void save(unsigned);
39: static int spillee(Node, unsigned);
40: static void spill(int, unsigned, Node);
41: static unsigned uses(Node);
42: static int valid(int);
43:
44: #define typecode(p) (optype(p->op) == U ? I : optype(p->op) == B ? P : optype(p->op))
45: #define sets(p) ((p)->x.rmask<<(p)->x.reg)
46:
47: /* address - initialize q for addressing expression p+n */
48: static void address(Symbol q, Symbol p, int n) {
49: if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
50: q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
51: else {
52: q->x.offset = p->x.offset + n;
53: q->x.name = stringf("%d(%s)", q->x.offset,
54: p->scope == PARAM ? "ap" : "fp");
55: }
56: }
57:
58: /* blockbeg - begin a compound statement */
59: static void blockbeg(Env *e) {
60: assert(rmask == (((~0)<<nregs)|1));
61: e->rmask = rmask;
62: e->offset = offset;
63: }
64:
65: /* blockend - end a compound statement */
66: static void blockend(Env *e) {
67: if (offset > framesize)
68: framesize = offset;
69: offset = e->offset;
70: rmask = e->rmask;
71: }
72:
73: /* defaddress - initialize an address */
74: static void defaddress(Symbol p) {
75: print(".long %s\n", p->x.name);
76: }
77:
78: /* defconst - define a constant */
79: static void defconst(int ty, Value v) {
80: switch (ty) {
81: case C: print(".byte %d\n", v.uc); break;
82: case S: print(".word %d\n", v.us); break;
83: case I: print(".long %d\n", v.i ); break;
84: case U: print(".long 0x%x\n", v.u ); break;
85: case P: print(".long 0x%x\n", v.p ); break;
86: #ifdef vax
87: case F:
88: print(".long 0x%x\n", ((unsigned *) &v.f)[0]);
89: break;
90: case D:
91: print(".long 0x%x,0x%x\n", ((unsigned *) &v.d)[0],
92: ((unsigned *) &v.d)[1]);
93: break;
94: #else
95: case F: {
96: char buf[MAXLINE];
97: sprintf(buf, ".float 0f%.8e\n", v.f);
98: outs(buf);
99: break;
100: }
101: case D: {
102: char buf[MAXLINE];
103: sprintf(buf, ".double 0d%.18e\n", v.d);
104: outs(buf);
105: break;
106: }
107: #endif
108: default: assert(0);
109: }
110: }
111:
112: /* defstring - emit a string constant */
113: static void defstring(int len, char *s) {
114: while (len-- > 0)
115: print(".byte %d\n", *s++);
116: }
117:
118: /* defsymbol - initialize p's Xsymbol fields */
119: static void defsymbol(Symbol p) {
120: if (p->scope == CONSTANTS)
121: p->x.name = p->name;
122: else if (p->scope >= LOCAL && p->sclass == STATIC)
123: p->x.name = stringf("L%d", genlabel(1));
124: else if (p->generated)
125: p->x.name = stringf("L%s", p->name);
126: else
127: p->x.name = stringf("_%s", p->name);
128: }
129:
130: /* " FDCSIUPVB" */
131: #define suffix(p) ".fdbwllll."[optype((p)->op)]
132: #define binary(inst) print("%s%c3 r%d,r%d,r%d\n", inst, suffix(p), \
133: b->x.reg, a->x.reg, r)
134: #define unary(inst) print("%s%c r%d,r%d\n", inst, suffix(p), a->x.reg, r)
135: #define compare(cp) print("cmp%c r%d,r%d; j%s %s\n", suffix(p), \
136: a->x.reg, b->x.reg, cp, p->syms[0]->x.name)
137:
138: /* emit - emit the dags on list p */
139: static void emit(Node p) {
140: for (; p; p = p->x.next) {
141: Node a = p->kids[0], b = p->kids[1];
142: int r = p->x.reg;
143: switch (p->op) {
144: case BANDU: binary("bic"); break;
145: case BORU: binary("bis"); break;
146: case BXORU: binary("xor"); break;
147: case ADDD: case ADDF: binary("add"); break;
148: case ADDI: case ADDP: case ADDU: binary("add"); break;
149: case SUBD: case SUBF: binary("sub"); break;
150: case SUBI: case SUBP: case SUBU: binary("sub"); break;
151: case MULD: case MULF: binary("mul"); break;
152: case MULI: case MULU: binary("mul"); break;
153: case DIVD: case DIVF: case DIVI: binary("div"); break;
154: case DIVU:
155: save(p->x.busy&0x3e);
156: print("pushl r%d; pushl r%d; calls $2,udiv; movl r0,r%d\n",
157: b->x.reg, a->x.reg, r);
158: restore(p->x.busy&0x3e);
159: break;
160: case MODI:
161: print("divl3 r%d,r%d,r0; mull2 r%d,r0; subl3 r0,r%d,r%d\n",
162: b->x.reg, a->x.reg, b->x.reg, a->x.reg, r);
163: break;
164: case MODU:
165: save(p->x.busy&0x3e);
166: print("pushl r%d; pushl r%d; calls $2,urem; movl r0,r%d\n",
167: b->x.reg, a->x.reg, r);
168: restore(p->x.busy&0x3e);
169: break;
170: case RSHU:
171: print("subl3 r%d,$32,r0; extzv r%d,r0,r%d,r%d\n",
172: b->x.reg, b->x.reg, a->x.reg, r);
173: break;
174: case RSHI: case LSHI: case LSHU:
175: print("ashl r%d,r%d,r%d\n", b->x.reg, a->x.reg, r);
176: break;
177: case INDIRB:
178: print("moval (r%d),r%d\n", a->x.reg, r);
179: break;
180: case INDIRC: case INDIRD: case INDIRF: case INDIRI:
181: case INDIRP: case INDIRS:
182: print("mov%c (r%d),r%d\n", suffix(p), a->x.reg, r);
183: break;
184: case BCOMU: unary("mcom" ); break;
185: case NEGD: case NEGF: case NEGI: unary("mneg" ); break;
186: case CVCI: unary("cvtb" ); break;
187: case CVCU: unary("movzb"); break;
188: case CVSI: unary("cvtw" ); break;
189: case CVSU: unary("movzw"); break;
190: case CVDF: case CVDI: unary("cvtd" ); break;
191: case CVFD: unary("cvtf" ); break;
192: case CVUC: case CVUS: unary("cvtl" ); break;
193: case CVIC: case CVIS: case CVID: unary("cvtl" ); break;
194: case CVIU: case CVUI: unary("mov" ); break;
195: case CVPU: case CVUP: unary("mov" ); break;
196: case RETD: case RETF: case RETI:
197: print("mov%c r%d,r0; ret\n", suffix(p), a->x.reg);
198: break;
199: case RETV:
200: print("ret\n");
201: break;
202: case ADDRGP: case ADDRFP: case ADDRLP:
203: print("moval %s,r%d\n", p->syms[0]->x.name, r);
204: break;
205: case CNSTC: case CNSTI: case CNSTP:
206: case CNSTS: case CNSTU:
207: print("movl $%s,r%d\n", p->syms[0]->x.name, r);
208: break;
209: case JUMPV:
210: print("jmp (r%d)\n", a->x.reg);
211: break;
212: case ASGNB:
213: save(p->x.busy&0x3f);
214: print("movc3 $%s,(r%d),(r%d)\n", p->syms[0]->x.name,
215: b->x.reg, a->x.reg);
216: restore(p->x.busy&0x3f);
217: break;
218: case ASGNC: case ASGND: case ASGNF: case ASGNI: case ASGNP: case ASGNS:
219: print("mov%c r%d,(r%d)\n", suffix(p), b->x.reg, a->x.reg);
220: break;
221: case ARGB:
222: save(p->x.busy&0x3f);
223: print("movc3 $%s,(r%d),%d(sp)\n", p->syms[0]->x.name,
224: a->x.reg, p->x.argoffset);
225: restore(p->x.busy&0x3f);
226: break;
227: case ARGD: case ARGF: case ARGI: case ARGP:
228: print("mov%c r%d,%d(sp)\n", suffix(p),
229: a->x.reg, p->x.argoffset);
230: break;
231: case CALLB:
232: save(p->x.busy&0x3e);
233: if (a->x.reg == 1) {
234: print("movl r1,r0\n");
235: a->x.reg = 0;
236: }
237: if (b->x.reg != 1)
238: print("movl r%d,r1\n", b->x.reg);
239: print("calls $0,(r%d)\n", a->x.reg);
240: restore(p->x.busy&0x3e);
241: break;
242: case CALLD: case CALLF: case CALLI: case CALLV:
243: save(p->x.busy&0x3e);
244: print("calls $0,(r%d)\n", a->x.reg);
245: if (p->op != CALLV)
246: print("mov%c r0,r%d\n", suffix(p), r);
247: restore(p->x.busy&0x3e);
248: break;
249: case EQD: case EQF: case EQI: compare("eql" ); break;
250: case GED: case GEF: case GEI: compare("geq" ); break;
251: case GEU: compare("gequ"); break;
252: case GTD: case GTF: case GTI: compare("gtr" ); break;
253: case GTU: compare("gtru"); break;
254: case LED: case LEF: case LEI: compare("leq" ); break;
255: case LEU: compare("lequ"); break;
256: case LTD: case LTF: case LTI: compare("lss" ); break;
257: case LTU: compare("lssu"); break;
258: case NED: case NEF: case NEI: compare("neq" ); break;
259: case LABELV:
260: print("%s:", p->syms[0]->x.name);
261: break;
262: default: assert(0);
263: }
264: }
265: }
266:
267: /* export - announce an exported symbol */
268: static void export(Symbol p) {
269: print(".globl %s\n", p->x.name);
270: }
271:
272: /* function - generate code for a function */
273: static void function(Symbol f, Symbol caller[],
274: Symbol callee[], int ncalls) {
275: int i;
276:
277: offset = 4;
278: for (i = 0; caller[i] && callee[i]; i++) {
279: offset = roundup(offset, caller[i]->type->align);
280: callee[i]->x.offset = caller[i]->x.offset = offset;
281: callee[i]->x.name = caller[i]->x.name = stringf("%d(ap)", offset);
282: offset += caller[i]->type->size;
283: callee[i]->sclass = AUTO;
284: }
285: usedmask = argbuildsize = framesize = offset = 0;
286: gencode(caller, callee);
287: print("%s:.word 0x%x\n", f->x.name, usedmask&~0x3f);
288: framesize += 4*nregs + argbuildsize;
289: print("subl2 $%d,sp\n", framesize);
290: if (isstruct(freturn(f->type)))
291: print("movl r1,-4(fp)\n");
292: emitcode();
293: if (glevel > 1)
294: print("ret\n");
295: }
296:
297: /* gen - generate code for the dags on list p */
298: static Node gen(Node p) {
299: Node head, *last;
300:
301: debug(1,id = 0);
302: for (last = &head; p; p = p->link)
303: last = linearize(p, last, 0);
304: debug(rflag,(lhead = head, lprint(head," before ralloc")));
305: for (p = head; p; p = p->x.next) {
306: ralloc(p);
307: if (p->count == 0 && sets(p))
308: putreg(p);
309: }
310: debug(rflag,lprint(lhead," after ralloc"));
311: return head;
312: }
313:
314: /* getreg - allocate 1 or 2 registers for node p */
315: static void getreg(Node p) {
316: int r, m = optype(p->op) == D ? 3 : 1;
317:
318: for (r = 0; r < nregs; r++)
319: if ((rmask&(m<<r)) == 0) {
320: p->x.rmask = m;
321: p->x.reg = r;
322: rmask |= sets(p);
323: usedmask |= sets(p);
324: debug(rflag,fprint(2,"allocating %s to node #%d\n", rnames(sets(p)), p->x.id));
325: return;
326: }
327: debug(rflag,lprint(lhead, " before spillee"));
328: r = spillee(p, m);
329: spill(r, m, p);
330: debug(rflag,lprint(lhead, " after spill"));
331: assert((rmask&(m<<r)) == 0);
332: getreg(p);
333: }
334:
335: /* genreloads - make the nodes after dot use reloads of temp instead of p's register */
336: static void genreloads(Node dot, Node p, Symbol temp) {
337: int i;
338: Node last;
339:
340: for (last = dot; dot = dot->x.next; last = dot)
341: for (i = 0; i < MAXKIDS; i++)
342: if (dot->kids[i] == p) {
343: dot->kids[i] = newnode(INDIR + typecode(p),
344: newnode(ADDRL+P, 0, 0, temp), 0, 0);
345: dot->kids[i]->count = 1;
346: p->count--;
347: linearize(dot->kids[i], &last->x.next, last->x.next);
348: last = dot->kids[i];
349: }
350: assert(p->count == 0);
351: }
352:
353: /* genspill - generate code to spill p's register and return the temporary used */
354: static Symbol genspill(Node p) {
355: Symbol temp = newtemp(AUTO, typecode(p));
356: Node q = p->x.next;
357:
358: linearize(newnode(ASGN + typecode(p),
359: newnode(ADDRLP, 0, 0, temp), p, 0),
360: &p->x.next, p->x.next);
361: rmask &= ~1;
362: for (p = p->x.next; p != q; p = p->x.next)
363: ralloc(p);
364: rmask |= 1;
365: return temp;
366: }
367:
368: /* global - global id */
369: static void global(Symbol p) {
370: switch (p->type->align) {
371: case 2: print(".align 1; "); break;
372: case 4: print(".align 2; "); break;
373: case 8: print(".align 3; "); break;
374: }
375: print("%s:", p->x.name);
376: }
377:
378: /* import - announce an imported symbol */
379: static void import(Symbol p) {
380: }
381:
382: /* linearize - linearize node list p */
383: static Node *linearize(Node p, Node *last, Node next) {
384: if (p && !p->x.visited) {
385: last = linearize(p->kids[0], last, 0);
386: last = linearize(p->kids[1], last, 0);
387: p->x.visited = 1;
388: *last = p;
389: last = &p->x.next;
390: debug(1,if (p->x.id == 0) p->x.id = ++id);
391: debug(rflag,{fprint(2,"listing node "); nprint(p);})
392: }
393: *last = next;
394: return last;
395: }
396:
397: /* local - local variable */
398: static void local(Symbol p) {
399: offset = roundup(offset + p->type->size, p->type->align);
400: offset = roundup(offset, 4);
401: p->x.offset = -offset;
402: p->x.name = stringf("%d(fp)", -offset);
403: p->sclass = AUTO;
404: }
405:
406: /* needsreg - does p need a register? */
407: static int needsreg(p) Node p; {
408: assert(opindex(p->op) > 0 && opindex(p->op) < sizeof reginfo/sizeof reginfo[0]);
409: return reginfo[opindex(p->op)]&(0x1000<<optype(p->op));
410: }
411:
412: /* progbeg - beginning of program */
413: static void progbeg(int argc, char *argv[]) {
414: extern int atoi(char *); /* (omit) */
415: while (--argc > 0)
416: if (**++argv == '-' && argv[0][1] >= '0' && argv[0][1] <= '9')
417: nregs = atoi(*argv + 1);
418: else if (strcmp(*argv, "-r") == 0) /* (omit) */
419: rflag++; /* (omit) */
420: rmask = ((~0)<<nregs)|1;
421: }
422:
423: /* progend - end of program */
424: static void progend(void) {
425: }
426:
427: /* putreg - decrement register usage */
428: static void putreg(Node p) {
429: if (p && --p->count <= 0)
430: { assert(p->x.rmask);
431: rmask &= ~sets(p);
432: debug(rflag,fprint(2,"deallocating %s from node #%d\n", rnames(sets(p)), p->x.id)); }
433: }
434:
435: /* ralloc - assign a register for p */
436: static void ralloc(Node p) {
437: int i;
438:
439: assert(p);
440: assert(p->x.rmask == 0);
441: switch (generic(p->op)) {
442: case ARG:
443: argoffset = roundup(argoffset, p->syms[1]->u.c.v.i);
444: p->x.argoffset = argoffset;
445: argoffset += p->syms[0]->u.c.v.i;
446: if (argoffset > argbuildsize)
447: argbuildsize = roundup(argoffset, 4);
448: break;
449: case CALL:
450: argoffset = 0;
451: break;
452: default:assert(valid(p->op));
453: }
454: for (i = 0; i < MAXKIDS; i++)
455: putreg(p->kids[i]);
456: p->x.busy = rmask;
457: if (needsreg(p))
458: getreg(p);
459: }
460:
461: /* restore - restore registers in mask */
462: static void restore(unsigned mask) {
463: int i;
464:
465: for (i = 1; i < nregs; i++)
466: if (mask&(1<<i))
467: print("movl %d(fp),r%d\n",
468: 4*i - framesize + argbuildsize, i);
469: }
470:
471: /* save - save registers in mask */
472: static void save(unsigned mask) {
473: int i;
474:
475: for (i = 1; i < nregs; i++)
476: if (mask&(1<<i))
477: print("movl r%d,%d(fp)\n", i,
478: 4*i - framesize + argbuildsize);
479: }
480:
481: /* segment - switch to logical segment s */
482: static void segment(int s) {
483: switch (s) {
484: case CODE: print(".text\n"); break;
485: case LIT: print(".text 1\n"); break;
486: case DATA:
487: case BSS: print(".data\n"); break;
488: default: assert(0);
489: }
490: }
491:
492: /* space - initialize n bytes of space */
493: static void space(int n) {
494: print(".space %d\n", n);
495: }
496:
497: /* spill - spill all registers that overlap (r,m) */
498: static void spill(int r, unsigned m, Node dot) {
499: int i;
500: Node p = dot;
501:
502: while (p = p->x.next)
503: for (i = 0; i < MAXKIDS; i++)
504: if (p->kids[i] && sets(p->kids[i])&(m<<r)) {
505: Symbol temp = genspill(p->kids[i]);
506: rmask &= ~sets(p->kids[i]);
507: genreloads(dot, p->kids[i], temp);
508: }
509: }
510:
511: /* spillee - identify the most-distantly-used register */
512: static int spillee(Node dot, unsigned m) {
513: int bestdist = -1, bestreg = 0, dist, r;
514: Node q;
515:
516: debug(rflag,fprint(2,"spillee: dot is node #%d\n", dot->x.id));
517: for (r = 1; r < nregs - (m>>1); r++) {
518: dist = 0;
519: for (q = dot->x.next; q && !(uses(q)&(m<<r)); q = q->x.next)
520: dist++;
521: assert(q); /* (omit) */
522: debug(rflag,fprint(2,"r%d used in node #%d at distance %d\n", r, q->x.id, dist));
523: if (dist > bestdist) {
524: bestdist = dist;
525: bestreg = r;
526: }
527: }
528: debug(rflag,fprint(2,"spilling %s\n",rnames(m<<bestreg)));
529: assert(bestreg); /* (omit) */
530: return bestreg;
531: }
532:
533: /* uses - return mask of registers used by node p */
534: static unsigned uses(Node p) {
535: int i;
536: unsigned m = 0;
537:
538: for (i = 0; i < MAXKIDS; i++)
539: if (p->kids[i])
540: m |= sets(p->kids[i]);
541: return m;
542: }
543:
544: /* valid - is operator op a valid operator ? */
545: static int valid(op) {
546: return opindex(op) > 0 && opindex(op) < sizeof reginfo/sizeof reginfo[0] ?
547: reginfo[opindex(op)]&(1<<optype(op)) : 0;
548: }
549:
550: #ifdef DEBUG
551: /* lprint - print the nodelist beginning at p */
552: static void lprint(Node p, char *s) {
553: fprint(2, "node list%s:\n", s);
554: if (p) {
555: char buf[100];
556: sprintf(buf, "%-4s%-8s%-8s%-8s%-7s%-13s%s",
557: " #", "op", "kids", "syms", "count", "uses", "sets");
558: fprint(2, "%s\n", buf);
559: }
560: for ( ; p; p = p->x.next)
561: nprint(p);
562: }
563:
564: /* nprint - print a line describing node p */
565: static void nprint(Node p) {
566: int i;
567: char *kids = "", *syms = "", buf[200];
568:
569: if (p->kids[0]) {
570: static char buf[100];
571: buf[0] = 0;
572: for (i = 0; i < MAXKIDS && p->kids[i]; i++)
573: sprintf(buf + strlen(buf), "%3d", p->kids[i]->x.id);
574: kids = &buf[1];
575: }
576: if (p->syms[0] && p->syms[0]->x.name) {
577: static char buf[100];
578: buf[0] = 0;
579: for (i = 0; i < MAXSYMS && p->syms[i]; i++) {
580: if (p->syms[i]->x.name)
581: sprintf(buf + strlen(buf), " %s", p->syms[i]->x.name);
582: if (p->syms[i]->u.c.loc)
583: sprintf(buf + strlen(buf), "=%s", p->syms[i]->u.c.loc->name);
584: }
585: syms = &buf[1];
586: }
587: sprintf(buf, "%2d. %-8s%-8s%-8s %2d %-13s",
588: p->x.id, opname(p->op), kids, syms, p->count, rnames(uses(p)));
589: sprintf(buf + strlen(buf), "%s", rnames(sets(p)));
590: fprint(2, "%s\n", buf);
591: }
592:
593: /* rnames - return names of registers given by mask m */
594: static char *rnames(unsigned m) {
595: static char buf[100];
596: int r;
597:
598: buf[0] = buf[1] = 0;
599: for (r = 0; r < nregs; r++)
600: if (m&(1<<r))
601: sprintf(buf + strlen(buf), " r%d", r);
602: return &buf[1];
603: }
604: #endif
605:
606: #ifndef V9
607: #include <errno.h>
608: #ifndef errno
609: extern int errno;
610: #endif
611:
612: /* strtol - interpret str as a base b number; if ptr!=0, *ptr gets updated str */
613: long strtol(str, ptr, b) char *str, **ptr; {
614: long n = 0;
615: char *s, sign = '+';
616: int d, overflow = 0;
617:
618: if (ptr)
619: *ptr = str;
620: if (b < 0 || b == 1 || b > 36)
621: return 0;
622: while (*str==' '||*str=='\f'||*str=='\n'||*str=='\r'||*str=='\t'||*str=='\v')
623: str++;
624: if (*str == '-' || *str == '+')
625: sign = *str++;
626: if (b == 0)
627: if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
628: b = 16;
629: str += 2;
630: } else if (str[0] == '0')
631: b = 8;
632: else
633: b = 10;
634: for (s = str; *str; str++) {
635: if (*str >= '0' && *str <= '9')
636: d = *str - '0';
637: else if (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z')
638: d = (*str&~040) - 'A' + 10;
639: else
640: break;
641: if (d >= b)
642: break;
643: if (n < (LONG_MIN + d)/b)
644: overflow = 1;
645: n = b*n - d;
646: }
647: if (s == str)
648: return 0;
649: if (ptr)
650: *ptr = str;
651: if (overflow || (sign == '+' && n == LONG_MIN)) {
652: errno = ERANGE;
653: return sign == '+' ? LONG_MAX : LONG_MIN;
654: }
655: return sign == '+' ? -n : n;
656: }
657: #endif
658:
659: static Interface naiveVAX = {
660: "naiveVAX",
661: 1, 1, 0, /* char */
662: 2, 2, 0, /* short */
663: 4, 4, 0, /* int */
664: 4, 4, 1, /* float */
665: 8, 4, 1, /* double */
666: 4, 4, 0, /* T * */
667: 0, 1, 0, /* struct */
668: 1, /* left_to_right */
669: 1, /* little_endian */
670: 0, /* jump_on_return */
671: 0, /* mulops_are_calls */
672: 1, /* compl_band */
673: 0, /* no_argb */
674: 0, /* no_dag */
675: address,
676: blockbeg,
677: blockend,
678: defaddress,
679: defconst,
680: defstring,
681: defsymbol,
682: emit,
683: export,
684: function,
685: gen,
686: global,
687: import,
688: local,
689: progbeg,
690: progend,
691: segment,
692: space,
693: };
694: Interface *interfaces[] = { &naiveVAX, 0 };
695:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.