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