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