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