xref: /csrg-svn/usr.bin/pascal/src/gen.c (revision 62213)
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