148116Sbostic /*-
2*62213Sbostic * Copyright (c) 1980, 1993
3*62213Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
622169Sdist */
7754Speter
814733Sthien #ifndef lint
9*62213Sbostic static char sccsid[] = "@(#)gen.c 8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
11754Speter
12754Speter #include "whoami.h"
13754Speter #ifdef OBJ
14754Speter /*
15754Speter * and the rest of the file
16754Speter */
17754Speter #include "0.h"
18754Speter #include "tree.h"
19754Speter #include "opcode.h"
20754Speter #include "objfmt.h"
21754Speter
22754Speter /*
23754Speter * This array tells the type
24754Speter * returned by an arithmetic
25754Speter * operation. It is indexed
26754Speter * by the logarithm of the
27754Speter * lengths base 2.
28754Speter */
29754Speter #ifndef DEBUG
30754Speter char arret[] = {
31754Speter T4INT, T4INT, T4INT, TDOUBLE,
32754Speter T4INT, T4INT, T4INT, TDOUBLE,
33754Speter T4INT, T4INT, T4INT, TDOUBLE,
34754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
35754Speter };
36754Speter #else
37754Speter char arret0[] = {
38754Speter T4INT, T4INT, T4INT, TDOUBLE,
39754Speter T4INT, T4INT, T4INT, TDOUBLE,
40754Speter T4INT, T4INT, T4INT, TDOUBLE,
41754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
42754Speter };
43754Speter char arret1[] = {
44754Speter T4INT, T4INT, T4INT, TDOUBLE,
45754Speter T4INT, T4INT, T4INT, TDOUBLE,
46754Speter T4INT, T4INT, T4INT, TDOUBLE,
47754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
48754Speter };
49754Speter char *arret = arret0;
50754Speter #endif
51754Speter
52754Speter /*
53754Speter * These array of arithmetic and set
54754Speter * operators are indexed by the
55754Speter * tree nodes and is highly dependent
56754Speter * on their order. They thus take
57754Speter * on the flavor of magic.
58754Speter */
59754Speter int arop[] = {
60754Speter 0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2,
61754Speter O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2
62754Speter };
63754Speter int setop[] = {
64754Speter O_MULT, O_ADDT, O_SUBT,
65754Speter O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT,
66754Speter };
67754Speter
68754Speter /*
69754Speter * The following array is
70754Speter * used when operating on
71754Speter * two reals since they are
72754Speter * shoved off in a corner in
73754Speter * the interpreter table.
74754Speter */
75754Speter int ar8op[] = {
76754Speter O_DVD8, O_MUL8, O_ADD8, O_SUB8,
77754Speter O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8,
78754Speter };
79754Speter
80754Speter /*
81754Speter * The following arrays, which are linearizations
82754Speter * of two dimensional arrays, are the offsets for
83754Speter * arithmetic, relational and assignment operations
84754Speter * indexed by the logarithms of the argument widths.
85754Speter */
86754Speter #ifndef DEBUG
87754Speter char artab[] = {
88754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
89754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
90754Speter O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2,
91754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1
92754Speter };
93754Speter #else
94754Speter char artab0[] = {
95754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
96754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2,
97754Speter O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2,
98754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1
99754Speter };
100754Speter char artab1[] = {
101754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2,
102754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2,
103754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD84-O_ADD2,
104754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD28-O_ADD2, -1
105754Speter };
106754Speter char *artab = artab0;
107754Speter #endif
108754Speter #ifndef DEBUG
109754Speter char reltab[] = {
110754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
111754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
112754Speter O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2,
113754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2
114754Speter };
115754Speter #else
116754Speter char reltab0[] = {
117754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
118754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2,
119754Speter O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2,
120754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2
121754Speter };
122754Speter char reltab1[] = {
123754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
124754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
125754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2,
126754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL28-O_REL2, O_REL8-O_REL2
127754Speter };
128754Speter char *reltab = reltab0;
129754Speter #endif
130754Speter
131754Speter #ifndef DEBUG
132754Speter char asgntab[] = {
133754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1,
134754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1,
135754Speter O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1,
136754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2,
137754Speter };
138754Speter #else
139754Speter char asgntb0[] = {
140754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1,
141754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1,
142754Speter O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1,
143754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2,
144754Speter };
145754Speter char asgntb1[] = {
146754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS21-O_AS2, -1,
147754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1,
148754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1,
149754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS28-O_AS2, O_AS4-O_AS2,
150754Speter };
151754Speter char *asgntab = asgntb0;
152754Speter #endif
153754Speter
154754Speter #ifdef DEBUG
genmx()155754Speter genmx()
156754Speter {
157754Speter
158754Speter arret = arret1;
159754Speter artab = artab1;
160754Speter reltab = reltab1;
161754Speter asgntab = asgntb1;
162754Speter }
163754Speter #endif
164754Speter
165754Speter /*
166754Speter * Gen generates code for assignments,
167754Speter * and arithmetic and string operations
168754Speter * and comparisons.
169754Speter */
170754Speter struct nl *
gen(p,o,w1,w2)171754Speter gen(p, o, w1, w2)
172754Speter int p, o, w1, w2;
173754Speter {
174754Speter register i, j;
17514733Sthien int op;
176754Speter
177754Speter switch (p) {
17814733Sthien default:
17914733Sthien panic("gen");
180754Speter case O_AS2:
181754Speter case NIL:
182754Speter i = j = -1;
183754Speter /*
184754Speter * Take the log2 of the widths
185754Speter * and linearize them for indexing.
186754Speter * width for indexing.
187754Speter */
188754Speter #ifdef DEBUG
189754Speter if (hp21mx) {
190754Speter if (w1 == 4)
191754Speter w1 = 8;
192754Speter if (w2 == 4)
193754Speter w2 = 8;
194754Speter }
195754Speter #endif
196754Speter do i++; while (w1 >>= 1);
197754Speter do j++; while (w2 >>= 1);
198754Speter i <<= 2;
199754Speter i |= j;
200754Speter if (p == O_AS2) {
20114733Sthien (void) put(1, O_AS2 + asgntab[i]);
202754Speter return (NIL);
203754Speter }
204754Speter op = arop[o];
205754Speter if (op == O_REL2) {
20614733Sthien (void) put(1, (op + reltab[i]) | (o - T_EQ) << 8+INDX);
207754Speter return (nl+TBOOL);
208754Speter }
20914733Sthien (void) put(1, i == 15 ? ar8op[o-T_DIVD] : op | artab[i]);
210754Speter return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]);
211754Speter case TREC:
212754Speter case TSTR:
21314733Sthien (void) put(2, O_RELG | (o - T_EQ) << 8+INDX, w1);
214754Speter return (nl+TBOOL);
215754Speter case TSET:
216754Speter op = setop[o-T_MULT];
217754Speter if (op == O_RELT)
218754Speter op |= (o - T_EQ)<<8+INDX;
21914733Sthien (void) put(2, op, w1);
220754Speter return (o >= T_EQ ? nl+TBOOL : nl+TSET);
221754Speter }
222754Speter }
223754Speter #endif OBJ
224