1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)gen.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
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
genmx()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 *
gen(p,o,w1,w2)171 gen(p, o, w1, w2)
172 int p, o, w1, w2;
173 {
174 register i, j;
175 int op;
176
177 switch (p) {
178 default:
179 panic("gen");
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) {
201 (void) put(1, O_AS2 + asgntab[i]);
202 return (NIL);
203 }
204 op = arop[o];
205 if (op == O_REL2) {
206 (void) put(1, (op + reltab[i]) | (o - T_EQ) << 8+INDX);
207 return (nl+TBOOL);
208 }
209 (void) put(1, i == 15 ? ar8op[o-T_DIVD] : op | artab[i]);
210 return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]);
211 case TREC:
212 case TSTR:
213 (void) put(2, O_RELG | (o - T_EQ) << 8+INDX, w1);
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;
219 (void) put(2, op, w1);
220 return (o >= T_EQ ? nl+TBOOL : nl+TSET);
221 }
222 }
223 #endif OBJ
224