xref: /csrg-svn/usr.bin/pascal/src/gen.c (revision 754)
1*754Speter /* Copyright (c) 1979 Regents of the University of California */
2*754Speter 
3*754Speter static	char sccsid[] = "@(#)gen.c 1.1 08/27/80";
4*754Speter 
5*754Speter #include "whoami.h"
6*754Speter #ifdef OBJ
7*754Speter     /*
8*754Speter      *	and the rest of the file
9*754Speter      */
10*754Speter #include "0.h"
11*754Speter #include "tree.h"
12*754Speter #include "opcode.h"
13*754Speter #include "objfmt.h"
14*754Speter 
15*754Speter /*
16*754Speter  * This array tells the type
17*754Speter  * returned by an arithmetic
18*754Speter  * operation.  It is indexed
19*754Speter  * by the logarithm of the
20*754Speter  * lengths base 2.
21*754Speter  */
22*754Speter #ifndef	DEBUG
23*754Speter char	arret[]	= {
24*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
25*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
26*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
27*754Speter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
28*754Speter };
29*754Speter #else
30*754Speter char	arret0[] = {
31*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
32*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
33*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
34*754Speter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
35*754Speter };
36*754Speter char	arret1[] = {
37*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
38*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
39*754Speter 	T4INT,		T4INT,		T4INT,		TDOUBLE,
40*754Speter 	TDOUBLE,	TDOUBLE,	TDOUBLE,	TDOUBLE
41*754Speter };
42*754Speter char	*arret = arret0;
43*754Speter #endif
44*754Speter 
45*754Speter /*
46*754Speter  * These array of arithmetic and set
47*754Speter  * operators are indexed by the
48*754Speter  * tree nodes and is highly dependent
49*754Speter  * on their order.  They thus take
50*754Speter  * on the flavor of magic.
51*754Speter  */
52*754Speter int	arop[] = {
53*754Speter 	0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2,
54*754Speter 	O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2
55*754Speter };
56*754Speter int	setop[] = {
57*754Speter 	O_MULT, O_ADDT, O_SUBT,
58*754Speter 	O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT,
59*754Speter };
60*754Speter 
61*754Speter /*
62*754Speter  * The following array is
63*754Speter  * used when operating on
64*754Speter  * two reals since they are
65*754Speter  * shoved off in a corner in
66*754Speter  * the interpreter table.
67*754Speter  */
68*754Speter int	ar8op[] = {
69*754Speter 	O_DVD8, O_MUL8, O_ADD8, O_SUB8,
70*754Speter 	O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8,
71*754Speter };
72*754Speter 
73*754Speter /*
74*754Speter  * The following arrays, which are linearizations
75*754Speter  * of two dimensional arrays, are the offsets for
76*754Speter  * arithmetic, relational and assignment operations
77*754Speter  * indexed by the logarithms of the argument widths.
78*754Speter  */
79*754Speter #ifndef	DEBUG
80*754Speter char artab[] = {
81*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
82*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
83*754Speter 	O_ADD24-O_ADD2,	O_ADD24-O_ADD2,	O_ADD4-O_ADD2,	O_ADD84-O_ADD2,
84*754Speter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD48-O_ADD2,	-1
85*754Speter };
86*754Speter #else
87*754Speter char artab0[] = {
88*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
89*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD42-O_ADD2,	O_ADD82-O_ADD2,
90*754Speter 	O_ADD24-O_ADD2,	O_ADD24-O_ADD2,	O_ADD4-O_ADD2,	O_ADD84-O_ADD2,
91*754Speter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD48-O_ADD2,	-1
92*754Speter };
93*754Speter char artab1[] = {
94*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD82-O_ADD2,
95*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD82-O_ADD2,
96*754Speter 	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD2-O_ADD2,	O_ADD84-O_ADD2,
97*754Speter 	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	O_ADD28-O_ADD2,	-1
98*754Speter };
99*754Speter char	*artab = artab0;
100*754Speter #endif
101*754Speter #ifndef DEBUG
102*754Speter char reltab[] = {
103*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
104*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
105*754Speter 	O_REL24-O_REL2,	O_REL24-O_REL2,	O_REL4-O_REL2,	O_REL84-O_REL2,
106*754Speter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL48-O_REL2,	O_REL8-O_REL2
107*754Speter };
108*754Speter #else
109*754Speter char reltab0[] = {
110*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
111*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL42-O_REL2,	O_REL82-O_REL2,
112*754Speter 	O_REL24-O_REL2,	O_REL24-O_REL2,	O_REL4-O_REL2,	O_REL84-O_REL2,
113*754Speter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL48-O_REL2,	O_REL8-O_REL2
114*754Speter };
115*754Speter char reltab1[] = {
116*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
117*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
118*754Speter 	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL2-O_REL2,	O_REL82-O_REL2,
119*754Speter 	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL28-O_REL2,	O_REL8-O_REL2
120*754Speter };
121*754Speter char *reltab = reltab0;
122*754Speter #endif
123*754Speter 
124*754Speter #ifndef DEBUG
125*754Speter char asgntab[] = {
126*754Speter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS41-O_AS2,	-1,
127*754Speter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS42-O_AS2,	-1,
128*754Speter 	O_AS24-O_AS2,	O_AS24-O_AS2,	O_AS4-O_AS2,	-1,
129*754Speter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS48-O_AS2,	O_AS8-O_AS2,
130*754Speter };
131*754Speter #else
132*754Speter char asgntb0[] = {
133*754Speter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS41-O_AS2,	-1,
134*754Speter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS42-O_AS2,	-1,
135*754Speter 	O_AS24-O_AS2,	O_AS24-O_AS2,	O_AS4-O_AS2,	-1,
136*754Speter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS48-O_AS2,	O_AS8-O_AS2,
137*754Speter };
138*754Speter char asgntb1[] = {
139*754Speter 	O_AS21-O_AS2,	O_AS21-O_AS2,	O_AS21-O_AS2,	-1,
140*754Speter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS2-O_AS2,	-1,
141*754Speter 	O_AS2-O_AS2,	O_AS2-O_AS2,	O_AS2-O_AS2,	-1,
142*754Speter 	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS28-O_AS2,	O_AS4-O_AS2,
143*754Speter };
144*754Speter char *asgntab = asgntb0;
145*754Speter #endif
146*754Speter 
147*754Speter #ifdef DEBUG
148*754Speter genmx()
149*754Speter {
150*754Speter 
151*754Speter 	arret = arret1;
152*754Speter 	artab = artab1;
153*754Speter 	reltab = reltab1;
154*754Speter 	asgntab = asgntb1;
155*754Speter }
156*754Speter #endif
157*754Speter 
158*754Speter /*
159*754Speter  * Gen generates code for assignments,
160*754Speter  * and arithmetic and string operations
161*754Speter  * and comparisons.
162*754Speter  */
163*754Speter struct nl *
164*754Speter gen(p, o, w1, w2)
165*754Speter 	int p, o, w1, w2;
166*754Speter {
167*754Speter 	register i, j;
168*754Speter 	int op, off;
169*754Speter 
170*754Speter 	switch (p) {
171*754Speter 		case O_AS2:
172*754Speter 		case NIL:
173*754Speter 			i = j = -1;
174*754Speter 			/*
175*754Speter 			 * Take the log2 of the widths
176*754Speter 			 * and linearize them for indexing.
177*754Speter 			 * width for indexing.
178*754Speter 			 */
179*754Speter #ifdef DEBUG
180*754Speter 			if (hp21mx) {
181*754Speter 				if (w1 == 4)
182*754Speter 					w1 = 8;
183*754Speter 				if (w2 == 4)
184*754Speter 					w2 = 8;
185*754Speter 			}
186*754Speter #endif
187*754Speter 			do i++; while (w1 >>= 1);
188*754Speter 			do j++; while (w2 >>= 1);
189*754Speter 			i <<= 2;
190*754Speter 			i |= j;
191*754Speter 			if (p == O_AS2) {
192*754Speter 				put1(O_AS2 + asgntab[i]);
193*754Speter 				return (NIL);
194*754Speter 			}
195*754Speter 			op = arop[o];
196*754Speter 			if (op == O_REL2) {
197*754Speter 				put1((op + reltab[i]) | (o - T_EQ) << 8+INDX);
198*754Speter 				return (nl+TBOOL);
199*754Speter 			}
200*754Speter 			put1(i == 15 ? ar8op[o-T_DIVD] : op | artab[i]);
201*754Speter 			return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]);
202*754Speter 		case TREC:
203*754Speter 		case TSTR:
204*754Speter 			put2(O_RELG | (o - T_EQ) << 8+INDX, w1);
205*754Speter 			return (nl+TBOOL);
206*754Speter 		case TSET:
207*754Speter 			op = setop[o-T_MULT];
208*754Speter 			if (op == O_RELT)
209*754Speter 				op |= (o - T_EQ)<<8+INDX;
210*754Speter 			put2(op, w1);
211*754Speter 			return (o >= T_EQ ? nl+TBOOL : nl+TSET);
212*754Speter 		default:
213*754Speter 			panic("gen");
214*754Speter 	}
215*754Speter }
216*754Speter #endif OBJ
217