|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #
3: /*
4: * pi - Pascal interpreter code translator
5: *
6: * Charles Haley, Bill Joy UCB
7: * Version 1.2 November 1978
8: */
9:
10: #include "whoami"
11: #include "opcode.h"
12: #include "0.h"
13:
14: short *obufp = obuf;
15:
16: /*
17: * If DEBUG is defined, include the table
18: * of the printing opcode names.
19: */
20: #ifdef DEBUG
21: char *otext[] = {
22: #include "OPnames.h"
23: };
24: #endif
25:
26: #ifdef OBJ
27: /*
28: * Put is responsible for the interpreter equivalent of code
29: * generation. Since the interpreter is specifically designed
30: * for Pascal, little work is required here.
31: */
32: put(a)
33: {
34: register int *p, i;
35: register char *cp;
36: int n, subop, suboppr, op, oldlc, w;
37: char *string;
38: static int casewrd;
39:
40: /*
41: * It would be nice to do some more
42: * optimizations here. The work
43: * done to collapse offsets in lval
44: * should be done here, the IFEQ etc
45: * relational operators could be used
46: * etc.
47: */
48: oldlc = lc;
49: if (cgenflg)
50: /*
51: * code disabled - do nothing
52: */
53: return (oldlc);
54: p = &a;
55: n = *p++;
56: suboppr = subop = (*p>>8) & 0377;
57: op = *p & 0377;
58: string = 0;
59: #ifdef DEBUG
60: if ((cp = otext[op]) == NIL) {
61: printf("op= %o\n", op);
62: panic("put");
63: }
64: #endif
65: switch (op) {
66: /*****
67: case O_LINO:
68: if (line == codeline)
69: return (oldlc);
70: codeline = line;
71: *****/
72: case O_PUSH:
73: case O_POP:
74: if (p[1] == 0)
75: return (oldlc);
76: case O_NEW:
77: case O_DISPOSE:
78: case O_AS:
79: case O_IND:
80: case O_OFF:
81: case O_INX2:
82: case O_INX4:
83: case O_CARD:
84: case O_ADDT:
85: case O_SUBT:
86: case O_MULT:
87: case O_IN:
88: case O_CASE1OP:
89: case O_CASE2OP:
90: case O_CASE4OP:
91: case O_PACK:
92: case O_UNPACK:
93: case O_RANG2:
94: case O_RSNG2:
95: case O_RANG42:
96: case O_RSNG42:
97: if (p[1] == 0)
98: break;
99: case O_CON2:
100: if (p[1] < 128 && p[1] >= -128) {
101: suboppr = subop = p[1];
102: p++;
103: n--;
104: if (op == O_CON2)
105: op = O_CON1;
106: }
107: break;
108: case O_CON8:
109: {
110: short *sp = &p[1];
111:
112: #ifdef DEBUG
113: if ( opt( 'c' ) )
114: printf ( ")#%5d\tCON8\t%10.3f\n" ,
115: lc - HEAD_BYTES ,
116: * ( ( double * ) &p[1] ) );
117: #endif
118: word ( op );
119: for ( i = 1 ; i <= 4 ; i ++ )
120: word ( *sp ++ );
121: return ( oldlc );
122: }
123: default:
124: if (op >= O_REL2 && op <= O_REL84) {
125: if ((i = (subop >> 1) * 5 ) >= 30)
126: i -= 30;
127: else
128: i += 2;
129: #ifdef DEBUG
130: string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
131: #endif
132: suboppr = 0;
133: }
134: break;
135: case O_IF:
136: case O_TRA:
137: /*****
138: codeline = 0;
139: *****/
140: case O_FOR1U:
141: case O_FOR2U:
142: case O_FOR4U:
143: case O_FOR1D:
144: case O_FOR2D:
145: case O_FOR4D:
146: /* relative addressing */
147: p[1] -= ( unsigned ) lc + 2;
148: break;
149: case O_WRIT82:
150: #ifdef DEBUG
151: string = &"22\024\042\044"[subop*3];
152: #endif
153: suboppr = 0;
154: break;
155: case O_CONG:
156: i = p[1];
157: cp = * ( ( char ** ) &p[2] ) ;
158: #ifdef DEBUG
159: if (opt('c'))
160: printf(")#%5d\tCONG:%d\t%s\n",
161: lc - HEAD_BYTES, i, cp);
162: #endif
163: if (i <= 127)
164: word(O_CON | i << 8);
165: else {
166: word(O_CON);
167: word(i);
168: }
169: while (i > 0) {
170: w = *cp ? *cp++ : ' ';
171: w |= (*cp ? *cp++ : ' ') << 8;
172: word(w);
173: i -= 2;
174: }
175: return (oldlc);
176: case O_CONC:
177: #ifdef DEBUG
178: (string = "'x'")[1] = p[1];
179: #endif
180: suboppr = 0;
181: op = O_CON1;
182: subop = p[1];
183: goto around;
184: case O_CON1:
185: suboppr = subop = p[1];
186: around:
187: n--;
188: break;
189: case O_CASEBEG:
190: casewrd = 0;
191: return (oldlc);
192: case O_CASEEND:
193: if ((unsigned) lc & 1) {
194: lc--;
195: word(casewrd);
196: }
197: return (oldlc);
198: case O_CASE1:
199: #ifdef DEBUG
200: if (opt('c'))
201: printf(")#%5d\tCASE1\t%d\n"
202: , lc - HEAD_BYTES
203: , ( int ) *( ( long * ) &p[1] ) );
204: #endif
205: /*
206: * this to build a byte size case table
207: * saving bytes across calls in casewrd
208: * so they can be put out by word()
209: */
210: lc++;
211: if ((unsigned) lc & 1)
212: casewrd = *( ( long * ) &p[1] );
213: else {
214: lc -= 2;
215: word ( casewrd
216: | ( ( int ) *( ( long * ) &p[1] ) << 8 ) );
217: }
218: return (oldlc);
219: case O_CASE2:
220: #ifdef DEBUG
221: if (opt('c'))
222: printf(")#%5d\tCASE2\t%d\n"
223: , lc - HEAD_BYTES
224: , ( int ) *( ( long * ) &p[1] ) );
225: #endif
226: word( ( short ) *( ( long * ) &p[1] ) );
227: return (oldlc);
228: case O_TRA4:
229: case O_CALL:
230: case O_GOTO:
231: case O_TRACNT:
232: /* absolute long addressing */
233: p[1] -= HEAD_BYTES;
234: n++;
235: case O_CON4:
236: case O_CASE4:
237: case O_RANG4:
238: case O_RANG4 + 1: /* O_RANG24 */
239: case O_RSNG4:
240: case O_RSNG4 + 1: /* O_RSNG24 */
241: {
242: short *sp = &p[1];
243: long *lp = &p[1];
244:
245: #ifdef DEBUG
246: if (opt('c'))
247: {
248: printf( ")#%5d\t%s" , lc - HEAD_BYTES , cp );
249: if (suboppr)
250: printf(":%1d", suboppr);
251: for ( i = 1 ; i < n
252: ; i += sizeof ( long )/sizeof ( short ) )
253: printf( "\t%D " , *lp ++ );
254: pchr ( '\n' );
255: }
256: #endif
257: if ( op != O_CASE4 )
258: word ( op | subop<<8 );
259: for ( i = 1 ; i < n ; i ++ )
260: word ( *sp ++ );
261: return ( oldlc );
262: }
263: }
264: #ifdef DEBUG
265: if (opt('c')) {
266: printf(")#%5d\t%s", lc - HEAD_BYTES, cp);
267: if (suboppr)
268: printf(":%d", suboppr);
269: if (string)
270: printf("\t%s",string);
271: if (n > 1)
272: pchr('\t');
273: for (i=1; i<n; i++)
274: printf("%d ", ( short ) p[i]);
275: pchr('\n');
276: }
277: #endif
278: if (op != NIL)
279: word(op | subop << 8);
280: for (i=1; i<n; i++)
281: word(p[i]);
282: return (oldlc);
283: }
284: #endif OBJ
285:
286: /*
287: * Putspace puts out a table
288: * of nothing to leave space
289: * for the case branch table e.g.
290: */
291: putspace(n)
292: int n;
293: {
294: register i;
295: #ifdef DEBUG
296: if (opt('c'))
297: printf(")#%5d\t.=.+%d\n", lc - HEAD_BYTES, n);
298: #endif
299: for (i = even(n); i > 0; i -= 2)
300: word(0);
301: }
302:
303: /*
304: * Patch repairs the branch
305: * at location loc to come
306: * to the current location.
307: */
308: patch(loc)
309: {
310:
311: patchfil(loc, lc-loc-2, 1);
312: }
313:
314: patch4(loc)
315: {
316:
317: patchfil(loc, lc - HEAD_BYTES, 2);
318: }
319:
320: /*
321: * Patchfil makes loc+2 have value
322: * as its contents.
323: */
324: patchfil(loc, value, words)
325: #ifdef VAX
326: unsigned long loc;
327: #endif
328: #ifdef PDP11
329: char *loc;
330: #endif
331: int value, words;
332: {
333: register i;
334:
335: if (cgenflg < 0)
336: return;
337: if (loc > (unsigned) lc)
338: panic("patchfil");
339: #ifdef DEBUG
340: if (opt('c'))
341: printf(")#\tpatch %u %d\n", loc - HEAD_BYTES, value);
342: #endif
343: do {
344: i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
345: if (i >= 0 && i < 1024)
346: obuf[i] = value;
347: else {
348: lseek(ofil, (long) loc+2, 0);
349: write(ofil, &value, 2);
350: lseek(ofil, (long) 0, 2);
351: }
352: loc += 2;
353: value = value >> 16;
354: } while (--words);
355: }
356:
357: /*
358: * Put the word o into the code
359: */
360: word(o)
361: int o;
362: {
363:
364: *obufp = o;
365: obufp++;
366: lc += 2;
367: if (obufp >= obuf+512)
368: pflush();
369: }
370:
371: extern char *obj;
372: /*
373: * Flush the code buffer
374: */
375: pflush()
376: {
377: register i;
378:
379: i = (obufp - ( ( short * ) obuf ) ) * 2;
380: if (i != 0 && write(ofil, obuf, i) != i)
381: perror(obj), pexit(DIED);
382: obufp = obuf;
383: }
384:
385: /*
386: * Getlab - returns the location counter.
387: * included here for the eventual code generator.
388: */
389: getlab()
390: {
391:
392: return (lc);
393: }
394:
395: /*
396: * Putlab - lay down a label.
397: */
398: putlab(l)
399: int l;
400: {
401:
402: return (l);
403: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.