Commit | Line | Data |
---|---|---|
d27a781b CH |
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 "0.h" | |
12 | #include "tree.h" | |
13 | #include "opcode.h" | |
14 | ||
15 | /* | |
16 | * This array tells the type | |
17 | * returned by an arithmetic | |
18 | * operation. It is indexed | |
19 | * by the logarithm of the | |
20 | * lengths base 2. | |
21 | */ | |
22 | #ifndef DEBUG | |
23 | char arret[] = { | |
24 | T4INT, T4INT, T4INT, TDOUBLE, | |
25 | T4INT, T4INT, T4INT, TDOUBLE, | |
26 | T4INT, T4INT, T4INT, TDOUBLE, | |
27 | TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE | |
28 | }; | |
29 | #else | |
30 | char arret0[] = { | |
31 | T4INT, T4INT, T4INT, TDOUBLE, | |
32 | T4INT, T4INT, T4INT, TDOUBLE, | |
33 | T4INT, T4INT, T4INT, TDOUBLE, | |
34 | TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE | |
35 | }; | |
36 | char arret1[] = { | |
37 | T4INT, T4INT, T4INT, TDOUBLE, | |
38 | T4INT, T4INT, T4INT, TDOUBLE, | |
39 | T4INT, T4INT, T4INT, TDOUBLE, | |
40 | TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE | |
41 | }; | |
42 | char *arret = arret0; | |
43 | #endif | |
44 | ||
45 | /* | |
46 | * These array of arithmetic and set | |
47 | * operators are indexed by the | |
48 | * tree nodes and is highly dependent | |
49 | * on their order. They thus take | |
50 | * on the flavor of magic. | |
51 | */ | |
52 | int arop[] = { | |
53 | 0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2, | |
54 | O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2 | |
55 | }; | |
56 | int setop[] = { | |
57 | O_MULT, O_ADDT, O_SUBT, | |
58 | O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, | |
59 | }; | |
60 | ||
61 | /* | |
62 | * The following array is | |
63 | * used when operating on | |
64 | * two reals since they are | |
65 | * shoved off in a corner in | |
66 | * the interpreter table. | |
67 | */ | |
68 | int ar8op[] = { | |
69 | O_DVD8, O_MUL8, O_ADD8, O_SUB8, | |
70 | O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, | |
71 | }; | |
72 | ||
73 | /* | |
74 | * The following arrays, which are linearizations | |
75 | * of two dimensional arrays, are the offsets for | |
76 | * arithmetic, relational and assignment operations | |
77 | * indexed by the logarithms of the argument widths. | |
78 | */ | |
79 | #ifndef DEBUG | |
80 | char artab[] = { | |
81 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, | |
82 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, | |
83 | O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, | |
84 | O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 | |
85 | }; | |
86 | #else | |
87 | char artab0[] = { | |
88 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, | |
89 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, | |
90 | O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, | |
91 | O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 | |
92 | }; | |
93 | char artab1[] = { | |
94 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, | |
95 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, | |
96 | O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD84-O_ADD2, | |
97 | O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD28-O_ADD2, -1 | |
98 | }; | |
99 | char *artab = artab0; | |
100 | #endif | |
101 | #ifndef DEBUG | |
102 | char reltab[] = { | |
103 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, | |
104 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, | |
105 | O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, | |
106 | O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 | |
107 | }; | |
108 | #else | |
109 | char reltab0[] = { | |
110 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, | |
111 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, | |
112 | O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, | |
113 | O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 | |
114 | }; | |
115 | char reltab1[] = { | |
116 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, | |
117 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, | |
118 | O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, | |
119 | O_REL28-O_REL2, O_REL28-O_REL2, O_REL28-O_REL2, O_REL8-O_REL2 | |
120 | }; | |
121 | char *reltab = reltab0; | |
122 | #endif | |
123 | ||
124 | #ifndef DEBUG | |
125 | char asgntab[] = { | |
126 | O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, | |
127 | O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, | |
128 | O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, | |
129 | O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, | |
130 | }; | |
131 | #else | |
132 | char asgntb0[] = { | |
133 | O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, | |
134 | O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, | |
135 | O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, | |
136 | O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, | |
137 | }; | |
138 | char asgntb1[] = { | |
139 | O_AS21-O_AS2, O_AS21-O_AS2, O_AS21-O_AS2, -1, | |
140 | O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, | |
141 | O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, | |
142 | O_AS28-O_AS2, O_AS28-O_AS2, O_AS28-O_AS2, O_AS4-O_AS2, | |
143 | }; | |
144 | char *asgntab = asgntb0; | |
145 | #endif | |
146 | ||
147 | #ifdef DEBUG | |
148 | genmx() | |
149 | { | |
150 | ||
151 | arret = arret1; | |
152 | artab = artab1; | |
153 | reltab = reltab1; | |
154 | asgntab = asgntb1; | |
155 | } | |
156 | #endif | |
157 | ||
158 | /* | |
159 | * Gen generates code for assignments, | |
160 | * and arithmetic and string operations | |
161 | * and comparisons. | |
162 | */ | |
163 | struct nl * | |
164 | gen(p, o, w1, w2) | |
165 | int p, o, w1, w2; | |
166 | { | |
167 | register i, j; | |
168 | int op, off; | |
169 | ||
170 | switch (p) { | |
171 | case O_AS2: | |
172 | case NIL: | |
173 | i = j = -1; | |
174 | /* | |
175 | * Take the log2 of the widths | |
176 | * and linearize them for indexing. | |
177 | * width for indexing. | |
178 | */ | |
179 | #ifdef DEBUG | |
180 | if (hp21mx) { | |
181 | if (w1 == 4) | |
182 | w1 = 8; | |
183 | if (w2 == 4) | |
184 | w2 = 8; | |
185 | } | |
186 | #endif | |
187 | do i++; while (w1 >>= 1); | |
188 | do j++; while (w2 >>= 1); | |
189 | i <<= 2; | |
190 | i |= j; | |
191 | if (p == O_AS2) { | |
192 | put1(O_AS2 + asgntab[i]); | |
193 | return (NIL); | |
194 | } | |
195 | op = arop[o]; | |
196 | if (op == O_REL2) { | |
197 | put1((op + reltab[i]) | (o - T_EQ) << 9); | |
198 | return (nl+TBOOL); | |
199 | } | |
200 | put1(i == 15 ? ar8op[o-T_DIVD] : op | artab[i]); | |
201 | return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]); | |
202 | case TSTR: | |
203 | put2(O_RELG | (o - T_EQ) << 9, w1); | |
204 | return (nl+TBOOL); | |
205 | case TSET: | |
206 | op = setop[o-T_MULT]; | |
207 | if (op == O_RELT) | |
208 | op |= (o - T_EQ)<<9; | |
209 | put2(op, w1); | |
210 | return (o >= T_EQ ? nl+TBOOL : nl+TSET); | |
211 | default: | |
212 | panic("gen"); | |
213 | } | |
214 | } |