BSD 3 development
[unix-history] / usr / src / cmd / pi / gen.c
CommitLineData
d27a781b
CH
1/* Copyright (c) 1979 Regents of the University of California */
2#
3/*
4 * pi - Pascal interpreter code translator
5 *
6 * Charles Haley, Bill Joy UCB
7 * Version 1.2 November 1978
8 */
9
10#include "whoami"
11#include "0.h"
12#include "tree.h"
13#include "opcode.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
23char arret[] = {
24 T4INT, T4INT, T4INT, TDOUBLE,
25 T4INT, T4INT, T4INT, TDOUBLE,
26 T4INT, T4INT, T4INT, TDOUBLE,
27 TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
28};
29#else
30char arret0[] = {
31 T4INT, T4INT, T4INT, TDOUBLE,
32 T4INT, T4INT, T4INT, TDOUBLE,
33 T4INT, T4INT, T4INT, TDOUBLE,
34 TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
35};
36char arret1[] = {
37 T4INT, T4INT, T4INT, TDOUBLE,
38 T4INT, T4INT, T4INT, TDOUBLE,
39 T4INT, T4INT, T4INT, TDOUBLE,
40 TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE
41};
42char *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 */
52int 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};
56int 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 */
68int 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
80char 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
87char 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};
93char 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};
99char *artab = artab0;
100#endif
101#ifndef DEBUG
102char 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
109char 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};
115char 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};
121char *reltab = reltab0;
122#endif
123
124#ifndef DEBUG
125char 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
132char 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};
138char 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};
144char *asgntab = asgntb0;
145#endif
146
147#ifdef DEBUG
148genmx()
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 */
163struct nl *
164gen(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) << 9);
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 TSTR:
203 put2(O_RELG | (o - T_EQ) << 9, w1);
204 return (nl+TBOOL);
205 case TSET:
206 op = setop[o-T_MULT];
207 if (op == O_RELT)
208 op |= (o - T_EQ)<<9;
209 put2(op, w1);
210 return (o >= T_EQ ? nl+TBOOL : nl+TSET);
211 default:
212 panic("gen");
213 }
214}