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