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