Commit | Line | Data |
---|---|---|
ca82b6dc DR |
1 | /* |
2 | ||
3 | C compiler, part 2 | |
4 | ||
5 | Copyright 1972 Bell Telephone Laboratories, Inc. | |
6 | ||
7 | */ | |
8 | ||
9 | waste() /* waste space */ | |
10 | { | |
11 | waste(waste(waste),waste(waste),waste(waste)); | |
12 | waste(waste(waste),waste(waste),waste(waste)); | |
13 | waste(waste(waste),waste(waste),waste(waste)); | |
14 | waste(waste(waste),waste(waste),waste(waste)); | |
15 | waste(waste(waste),waste(waste),waste(waste)); | |
16 | waste(waste(waste),waste(waste),waste(waste)); | |
17 | waste(waste(waste),waste(waste),waste(waste)); | |
18 | waste(waste(waste),waste(waste),waste(waste)); | |
19 | } | |
20 | main(argc, argv) | |
21 | char argv[][]; | |
22 | { | |
23 | extern fout, fin, nerror, line; | |
24 | extern getwrd, rcexpr, tmpfil; | |
25 | extern cctab[], regtab[], efftab[], sptab[]; | |
26 | int sp[], c, table[], tabtab[3][], tree; | |
27 | ||
28 | if (argc<4) { | |
29 | error("Arg count"); | |
30 | exit(1); | |
31 | } | |
32 | if((fin=open(argv[1],0))<0) { | |
33 | error("Cant't find %s", argv[1]); | |
34 | exit(1); | |
35 | } | |
36 | if((fout=creat(argv[3],017))<0) { | |
37 | error("Can't create %s", argv[3]); | |
38 | exit(1); | |
39 | } | |
40 | tmpfil = argv[2]; | |
41 | ||
42 | tabtab[0] = regtab; | |
43 | tabtab[1] = efftab; | |
44 | tabtab[2] = cctab; | |
45 | tabtab[3] = sptab; | |
46 | while(c=getchar()) { | |
47 | if(c=='#') { | |
48 | sp = 0; | |
49 | c = getwrd(); | |
50 | tree = getwrd(); | |
51 | table = tabtab[getwrd()]; | |
52 | line = getwrd(); | |
53 | while(c--) | |
54 | *sp++ = getwrd(); | |
55 | rcexpr(tree, table, 0); | |
56 | } else | |
57 | putchar(c); | |
58 | } | |
59 | flush(); | |
60 | exit(nerror!=0); | |
61 | } | |
62 | ||
63 | match(tree, table, nreg) | |
64 | int tree[], table[]; { | |
65 | extern opdope[], cctab, maprel; | |
66 | int op, d1, d2, t1, t2, p1[], p2[], dope, cctab[]; | |
67 | int maprel[]; | |
68 | char mp[]; | |
69 | ||
70 | if (tree==0) | |
71 | return(0); | |
72 | op = *tree; | |
73 | if (op>=29) /* if not leaf */ | |
74 | p1 = tree[3]; | |
75 | else | |
76 | p1 = tree; | |
77 | t1 = p1[1]; | |
78 | d1 = dcalc(p1, nreg); | |
79 | if (((dope=opdope[op])&01)!=0) { /* binary? */ | |
80 | p2 = tree[4]; | |
81 | t2 = p2[1]; | |
82 | d2 = dcalc(p2, nreg); | |
83 | if (d2>d1 & (dope&0100)!=0) /* commute? */ | |
84 | if (table!=cctab | (op!=47&op!=48)) { /* commute? */ | |
85 | if ((dope&04)!=0) /* relation? */ | |
86 | *tree = op = maprel[op-60]; | |
87 | dope = t1; | |
88 | t1 = t2; | |
89 | t2 = dope; | |
90 | dope = p1; | |
91 | tree[3] = p1 = p2; | |
92 | tree[4] = p2 = dope; | |
93 | dope = d1; | |
94 | d1 = d2; | |
95 | d2 = dope; | |
96 | dope = t1; | |
97 | t1 = t2; | |
98 | t2 = dope; | |
99 | } | |
100 | } | |
101 | while(*table) { | |
102 | if (*table++ == op) goto foundop; | |
103 | table++; | |
104 | } | |
105 | return(0); | |
106 | foundop: | |
107 | table = *table; | |
108 | nxtry: | |
109 | mp = table; | |
110 | if (*mp == 0) | |
111 | return(0); | |
112 | if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36)) | |
113 | goto notyet; | |
114 | if (notcompat(t1, mp[1])) | |
115 | goto notyet; | |
116 | if ((opdope[op]&01)!=0 & p2!=0) { | |
117 | if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36)) | |
118 | goto notyet; | |
119 | if (notcompat(t2,mp[3])) | |
120 | goto notyet; | |
121 | } | |
122 | now: | |
123 | return(table[2]); | |
124 | notyet: | |
125 | table = table+3; | |
126 | goto nxtry; | |
127 | } | |
128 | ||
129 | rcexpr(tree, table, reg) | |
130 | int tree[]; { | |
131 | extern cexpr, regtab, cctab, sptab, printf, error; | |
132 | extern jumpc, cbranch; | |
133 | int r, modf; | |
134 | ||
135 | if(tree==0) | |
136 | return(0); | |
137 | if(*tree == 103 | *tree==104) { | |
138 | (*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0); | |
139 | return(0); | |
140 | } | |
141 | modf = isfloat(tree)? 'f':0; | |
142 | if (*tree == 110) { /* force r0 */ | |
143 | if((r=rcexpr(tree[3], table, reg)) != 0) | |
144 | printf("mov%c r%d,r0\n", modf, r); | |
145 | return(0); | |
146 | } | |
147 | if ((r=cexpr(tree, table, reg))>=0) | |
148 | return(r); | |
149 | if (table!=regtab) | |
150 | if((r=cexpr(tree, regtab, reg))>=0) { | |
151 | if (table==sptab) | |
152 | printf("mov%c r%d,-(sp)\n", modf, r); | |
153 | if (table==cctab) { | |
154 | if (modf=='f') | |
155 | printf("cfcc\n"); | |
156 | printf("tst%c r%d\n", modf, r); | |
157 | } | |
158 | return(0); | |
159 | } | |
160 | error("No match for op %d", *tree); | |
161 | } | |
162 | ||
163 | cexpr(tree, table, reg) | |
164 | int tree[][], table[]; { | |
165 | extern match, nreg, printf, pname, putchar, regtab; | |
166 | extern sptab, cctab, rcexpr, prins, rlength, popstk; | |
167 | extern collcon, isn, label, branch, cbranch; | |
168 | extern maprel[]; | |
169 | int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[]; | |
170 | int sptab[]; | |
171 | char string[], match[]; | |
172 | int reg1, rreg; | |
173 | ||
174 | if ((c = *tree)==100) { /* call */ | |
175 | p1 = tree[3]; | |
176 | p2 = tree[4]; | |
177 | r = 0; | |
178 | if(*p2) { | |
179 | while (*p2==9) { /* comma */ | |
180 | rcexpr(p2[4], sptab, 0); | |
181 | r =+ arlength((p=p2[4])[1]); | |
182 | p2 = p2[3]; | |
183 | } | |
184 | rcexpr(p2, sptab, 0); | |
185 | r =+ arlength(p2[1]); | |
186 | } | |
187 | *tree = 101; | |
188 | tree[2] = r; /* save arg length */ | |
189 | } | |
190 | if(c==90) { /* ? */ | |
191 | cbranch(tree[3], c=isn++, 0, reg); | |
192 | rcexpr(tree[4][3], table, reg); | |
193 | branch(r=isn++, 0); | |
194 | label(c); | |
195 | reg = rcexpr(tree[4][4], table, reg); | |
196 | label(r); | |
197 | goto retrn; | |
198 | } | |
199 | reg = oddreg(tree, reg); | |
200 | reg1 = reg+1; | |
201 | if ((string=match(tree, table, nreg-reg))==0) | |
202 | return(-1); | |
203 | p1 = tree[3]; | |
204 | p2 = tree[4]; | |
205 | loop: | |
206 | switch(c = *string++) { | |
207 | ||
208 | case '\0': | |
209 | p = tree; | |
210 | if (*p==101) { | |
211 | if (p[2]>0) | |
212 | popstk(p[2]); | |
213 | reg = 0; | |
214 | } | |
215 | retrn: | |
216 | c = isfloat(tree); | |
217 | if (table==cctab & c) | |
218 | printf("cfcc\n"); | |
219 | if (!c) | |
220 | if ((c = *tree)==43 | c==73) | |
221 | reg--; | |
222 | return(reg); | |
223 | ||
224 | /* A1 */ | |
225 | case 'A': | |
226 | p = tree[3]; | |
227 | goto adr; | |
228 | ||
229 | /* A2 */ | |
230 | case 'B': | |
231 | p = tree[4]; | |
232 | goto adr; | |
233 | ||
234 | /* A */ | |
235 | case 'O': | |
236 | p = tree; | |
237 | adr: | |
238 | pname(p); | |
239 | goto loop; | |
240 | ||
241 | /* I */ | |
242 | case 'M': | |
243 | if ((c = *string)=='\'') | |
244 | string++; else | |
245 | c = 0; | |
246 | prins(*tree, c); | |
247 | goto loop; | |
248 | ||
249 | /* B1 */ | |
250 | case 'C': | |
251 | if ((c = *tree)<28) | |
252 | p = tree; | |
253 | else | |
254 | p = tree[3]; | |
255 | goto pbyte; | |
256 | ||
257 | /* BF */ | |
258 | case 'P': | |
259 | p = tree; | |
260 | goto pb1; | |
261 | ||
262 | /* B2 */ | |
263 | case 'D': | |
264 | p = tree[4]; | |
265 | pbyte: | |
266 | if (p[1]==1) /* char type? */ | |
267 | putchar('b'); | |
268 | pb1: | |
269 | if (isfloat(p)) | |
270 | putchar('f'); | |
271 | goto loop; | |
272 | ||
273 | /* BE */ | |
274 | case 'L': | |
275 | if (tree[3][1]==1 | tree[4][1]==1) | |
276 | putchar('b'); | |
277 | p = tree; | |
278 | goto pb1; | |
279 | ||
280 | /* C1 */ | |
281 | case 'E': | |
282 | p = p1[3]; | |
283 | goto const; | |
284 | ||
285 | /* C2 */ | |
286 | case 'F': | |
287 | p = p2[3]; | |
288 | const: | |
289 | printf("%o", p); | |
290 | goto loop; | |
291 | ||
292 | /* F */ | |
293 | case 'G': | |
294 | p = p1; | |
295 | goto subtre; | |
296 | ||
297 | /* S */ | |
298 | case 'K': | |
299 | p = p2; | |
300 | goto subtre; | |
301 | ||
302 | /* H */ | |
303 | case 'H': | |
304 | p = tree; | |
305 | ||
306 | subtre: | |
307 | ctable = regtab; | |
308 | r = reg; | |
309 | c = *string++ - 'A'; | |
310 | if ((c&02)!=0) | |
311 | ctable = sptab; | |
312 | if ((c&04)!=0) | |
313 | ctable = cctab; | |
314 | if((c&010)!=0) | |
315 | r = reg1; | |
316 | if((c&01)!=0) | |
317 | if(*p==36) { | |
318 | p = p[3]; | |
319 | if(collcon(p) & ctable!=sptab) | |
320 | p = p[3]; | |
321 | } | |
322 | rreg = rcexpr(p, ctable, r); | |
323 | if (rreg==r | ctable!=regtab) | |
324 | goto loop; | |
325 | if (string[-2]=='G') /* left operand */ | |
326 | if (oddreg(tree, 0)==1) { | |
327 | printf("mov r%d,r%d\n", rreg, r); | |
328 | goto loop; | |
329 | } | |
330 | if (r==reg) { | |
331 | reg = rreg; | |
332 | reg1 = rreg+1; | |
333 | } else | |
334 | reg1 = rreg; | |
335 | goto loop; | |
336 | ||
337 | /* R */ | |
338 | case 'I': | |
339 | r = reg; | |
340 | if (*string=='-') { | |
341 | string++; | |
342 | r--; | |
343 | } | |
344 | goto preg; | |
345 | ||
346 | /* R1 */ | |
347 | case 'J': | |
348 | r = reg1; | |
349 | preg: | |
350 | if (r>=5) | |
351 | error("Register overflow: simplify expression"); | |
352 | printf("r%d", r); | |
353 | goto loop; | |
354 | ||
355 | case '#': | |
356 | p = p1[3]; | |
357 | goto nmbr; | |
358 | ||
359 | case '"': | |
360 | p = p2[3]; | |
361 | goto nmbr; | |
362 | ||
363 | case '~': | |
364 | p = tree[3]; | |
365 | ||
366 | nmbr: | |
367 | if(collcon(p)) { | |
368 | if (*p==41) /* - */ | |
369 | putchar('-'); | |
370 | switch (*(p = p[4])) { | |
371 | ||
372 | case 21: /* number */ | |
373 | if (p[3]) | |
374 | printf("%d.", p[3]); | |
375 | break; | |
376 | ||
377 | case 35: /* & name */ | |
378 | pname(p[3]); | |
379 | break; | |
380 | ||
381 | } | |
382 | } | |
383 | goto loop; | |
384 | ||
385 | /* V */ | |
386 | case 'V': | |
387 | tree[0] = maprel[(c=tree[0])-60]; | |
388 | goto loop; | |
389 | ||
390 | /* Z */ | |
391 | case 'Z': | |
392 | printf("$%o", p1[5]+p1[4]); | |
393 | goto loop; | |
394 | ||
395 | case '^': /* for ++ -- */ | |
396 | printf("%o", tree[4]); | |
397 | goto loop; | |
398 | } | |
399 | putchar(c); | |
400 | goto loop; | |
401 | } | |
402 | ||
403 | pname(p) | |
404 | int p[][]; { | |
405 | char np[]; | |
406 | int i; | |
407 | ||
408 | loop: | |
409 | switch(*p) { | |
410 | ||
411 | case 21: /* const */ | |
412 | printf("$%o", p[3]); | |
413 | return; | |
414 | ||
415 | case 23: /* float const */ | |
416 | printf("L%d", p[3]); | |
417 | return; | |
418 | ||
419 | casename: | |
420 | case 20: /* name */ | |
421 | if (i=p[4]) | |
422 | printf("%d.+", i); | |
423 | switch(p[3]) { | |
424 | ||
425 | case 5: /* auto, param */ | |
426 | printf("%d.(r5)", p[5]); | |
427 | return; | |
428 | ||
429 | /* extern */ | |
430 | case 6: | |
431 | printf("%p", &p[5]); | |
432 | return; | |
433 | ||
434 | case 4: | |
435 | error("Illegal structure reference"); | |
436 | printf("$0"); | |
437 | return; | |
438 | ||
439 | } | |
440 | printf("L%d", p[5]); | |
441 | return; | |
442 | ||
443 | case 35: /* & */ | |
444 | putchar('$'); | |
445 | p = p[3]; | |
446 | goto loop; | |
447 | ||
448 | case 36: /* * */ | |
449 | putchar('*'); | |
450 | p = p[3]; | |
451 | goto loop; | |
452 | ||
453 | } | |
454 | error("pname called illegally"); | |
455 | } | |
456 | ||
457 | dcalc(p, nreg) | |
458 | int p[]; { | |
459 | int op, t, p1[], p2[]; | |
460 | ||
461 | if (p==0) | |
462 | return(0); | |
463 | op = *p; | |
464 | switch (op) { | |
465 | ||
466 | case 20: /* name */ | |
467 | case 35: /* & (non-automatic) */ | |
468 | return(12); | |
469 | ||
470 | case 21: /* short constant */ | |
471 | return(p[3]==0? 4:8); | |
472 | ||
473 | case 23: /* float const */ | |
474 | return(p[3]==0? 4:12); | |
475 | ||
476 | case 36: /* * */ | |
477 | p1 = p[3]; | |
478 | if (*p1==20) /* name or offset name */ | |
479 | return(12); | |
480 | } | |
481 | ||
482 | def: | |
483 | return(p[2]<=nreg? 20: 24); | |
484 | } | |
485 | ||
486 | notcompat(at, st) { | |
487 | ||
488 | if (st==0) /* word, byte */ | |
489 | return(at>1 & at<=07); | |
490 | if (st==1) /* word */ | |
491 | return(at>0 & at<=07); | |
492 | st =- 2; | |
493 | if ((at&077740) != 0) | |
494 | at = 020; /* *int for **stuff */ | |
495 | if ((at&077770) != 0) | |
496 | at = at&07 | 020; | |
497 | if (st==2 & at==3) | |
498 | at = 2; | |
499 | return(st != at); | |
500 | } | |
501 | ||
502 | prins(op, c) { | |
503 | extern instab[], printf; | |
504 | int insp[]; | |
505 | ||
506 | insp = instab; | |
507 | while(*insp) { | |
508 | if (*insp++ == op) { | |
509 | if ((c = insp[c!=0])==0) | |
510 | goto err; | |
511 | printf("%s", c); | |
512 | return; | |
513 | } else | |
514 | insp = insp + 2; | |
515 | } | |
516 | err: | |
517 | error("No match' for op %d", op); | |
518 | } | |
519 | ||
520 | collcon(p) | |
521 | int p[]; { | |
522 | int p1[], t[]; | |
523 | ||
524 | if(*p==40 | *p==41) { | |
525 | if(*(p1=p[4])==21) { /* number */ | |
526 | return(1); | |
527 | } | |
528 | if (*p1==35) | |
529 | return(1); | |
530 | if (*(p1=p[3])==35) { | |
531 | p1 = p[3]; | |
532 | p[3] = p[4]; | |
533 | p[4] = p1; | |
534 | return(1); | |
535 | } | |
536 | } | |
537 | return(0); | |
538 | } | |
539 | ||
540 | isfloat(t) | |
541 | int t[]; | |
542 | { | |
543 | extern opdope[]; | |
544 | int rt; | |
545 | ||
546 | if ((opdope[t[0]]&04)!=0) /* relational */ | |
547 | t = t[3]; | |
548 | if ((rt=t[1])>=2 & rt<=3) | |
549 | return(rt); | |
550 | return(0); | |
551 | } | |
552 | ||
553 | nreg 3; | |
554 | isn 10000; | |
555 | namsiz 8; | |
556 | line; | |
557 | tmpfil; | |
558 | nerror; | |
559 | ||
560 | oddreg(t, reg) | |
561 | int t[]; | |
562 | { | |
563 | if (!isfloat(t)) | |
564 | switch(*t) { | |
565 | case 43: /* / */ | |
566 | case 44: /* % */ | |
567 | case 73: /* =/ */ | |
568 | case 74: /* =% */ | |
569 | reg++; | |
570 | ||
571 | case 42: /* * */ | |
572 | case 72: /* =* */ | |
573 | return(reg|1); | |
574 | } | |
575 | return(reg); | |
576 | } | |
577 | ||
578 | arlength(t) | |
579 | { | |
580 | int arl; | |
581 | ||
582 | if ((arl=rlength(t)) == 4) | |
583 | return(8); | |
584 | return(arl); | |
585 | } | |
586 | ||
587 | maprel[] 60, 61, 64, 65, 62, 63, 68, 69, 66, 67; | |
588 |