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