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