Commit | Line | Data |
---|---|---|
47621762 BJ |
1 | /* |
2 | * INTERMEDIATE CODE GENERATION PROCEDURES COMMON TO BOTH | |
3 | * JOHNSON AND RITCHIE FAMILIES OF SECOND PASSES | |
4 | */ | |
5 | ||
6 | #include "defs" | |
7 | ||
8 | #if FAMILY == PCC | |
9 | # include "pccdefs" | |
10 | #else | |
11 | # include "dmrdefs" | |
12 | #endif | |
13 | ||
14 | /* | |
15 | char *ops [ ] = | |
16 | { | |
17 | "??", "+", "-", "*", "/", "**", "-", | |
18 | "OR", "AND", "EQV", "NEQV", "NOT", | |
19 | "CONCAT", | |
20 | "<", "==", ">", "<=", "!=", ">=", | |
21 | " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ", | |
22 | " , ", " ? ", " : " | |
23 | " abs ", " min ", " max ", " addr ", " indirect ", | |
24 | " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", | |
25 | }; | |
26 | */ | |
27 | ||
28 | int ops2 [ ] = | |
29 | { | |
30 | P2BAD, P2PLUS, P2MINUS, P2STAR, P2SLASH, P2BAD, P2NEG, | |
31 | P2OROR, P2ANDAND, P2EQ, P2NE, P2NOT, | |
32 | P2BAD, | |
33 | P2LT, P2EQ, P2GT, P2LE, P2NE, P2GE, | |
34 | P2CALL, P2CALL, P2ASSIGN, P2PLUSEQ, P2STAREQ, P2CONV, P2LSHIFT, P2MOD, | |
35 | P2COMOP, P2QUEST, P2COLON, | |
36 | P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, | |
37 | P2BITOR, P2BITAND, P2BITXOR, P2BITNOT, P2RSHIFT | |
38 | }; | |
39 | ||
40 | ||
41 | int types2 [ ] = | |
42 | { | |
43 | P2BAD, P2INT|P2PTR, P2SHORT, P2LONG, P2REAL, P2DREAL, | |
44 | #if TARGET == INTERDATA | |
45 | P2BAD, P2BAD, P2LONG, P2CHAR, P2INT, P2BAD | |
46 | #else | |
47 | P2REAL, P2DREAL, P2LONG, P2CHAR, P2INT, P2BAD | |
48 | #endif | |
49 | }; | |
50 | ||
51 | ||
52 | setlog() | |
53 | { | |
54 | types2[TYLOGICAL] = types2[tylogical]; | |
55 | typesize[TYLOGICAL] = typesize[tylogical]; | |
56 | typealign[TYLOGICAL] = typealign[tylogical]; | |
57 | } | |
58 | ||
59 | ||
60 | putex1(p) | |
61 | expptr p; | |
62 | { | |
63 | putx( fixtype(p) ); | |
64 | templist = hookup(templist, holdtemps); | |
65 | holdtemps = NULL; | |
66 | } | |
67 | ||
68 | ||
69 | ||
70 | ||
71 | ||
72 | putassign(lp, rp) | |
73 | expptr lp, rp; | |
74 | { | |
75 | putx( fixexpr( mkexpr(OPASSIGN, lp, rp) )); | |
76 | } | |
77 | ||
78 | ||
79 | ||
80 | ||
81 | puteq(lp, rp) | |
82 | expptr lp, rp; | |
83 | { | |
84 | putexpr( mkexpr(OPASSIGN, lp, rp) ); | |
85 | } | |
86 | ||
87 | ||
88 | ||
89 | ||
90 | /* put code for a *= b */ | |
91 | ||
92 | putsteq(a, b) | |
93 | expptr a, b; | |
94 | { | |
95 | putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) )); | |
96 | } | |
97 | ||
98 | ||
99 | ||
100 | ||
101 | ||
102 | struct Addrblock *realpart(p) | |
103 | register struct Addrblock *p; | |
104 | { | |
105 | register struct Addrblock *q; | |
106 | ||
107 | q = cpexpr(p); | |
108 | if( ISCOMPLEX(p->vtype) ) | |
109 | q->vtype += (TYREAL-TYCOMPLEX); | |
110 | return(q); | |
111 | } | |
112 | ||
113 | ||
114 | ||
115 | ||
116 | struct Addrblock *imagpart(p) | |
117 | register struct Addrblock *p; | |
118 | { | |
119 | register struct Addrblock *q; | |
120 | struct Constblock *mkrealcon(); | |
121 | ||
122 | if( ISCOMPLEX(p->vtype) ) | |
123 | { | |
124 | q = cpexpr(p); | |
125 | q->vtype += (TYREAL-TYCOMPLEX); | |
126 | q->memoffset = mkexpr(OPPLUS, q->memoffset, ICON(typesize[q->vtype])); | |
127 | } | |
128 | else | |
129 | q = mkrealcon( ISINT(p->vtype) ? TYDREAL : p->vtype , 0.0); | |
130 | return(q); | |
131 | } | |
132 | \f | |
133 | struct Addrblock *putconst(p) | |
134 | register struct Constblock *p; | |
135 | { | |
136 | register struct Addrblock *q; | |
137 | struct Literal *litp, *lastlit; | |
138 | int i, k, type; | |
139 | int litflavor; | |
140 | ||
141 | if( p->tag != TCONST ) | |
142 | fatali("putconst: bad tag %d", p->tag); | |
143 | ||
144 | q = ALLOC(Addrblock); | |
145 | q->tag = TADDR; | |
146 | type = p->vtype; | |
147 | q->vtype = ( type==TYADDR ? TYINT : type ); | |
148 | q->vleng = cpexpr(p->vleng); | |
149 | q->vstg = STGCONST; | |
150 | q->memno = newlabel(); | |
151 | q->memoffset = ICON(0); | |
152 | ||
153 | /* check for value in literal pool, and update pool if necessary */ | |
154 | ||
155 | switch(type = p->vtype) | |
156 | { | |
157 | case TYCHAR: | |
158 | if(p->vleng->constblock.const.ci > XL) | |
159 | break; /* too long for literal table */ | |
160 | litflavor = 1; | |
161 | goto loop; | |
162 | ||
163 | case TYREAL: | |
164 | case TYDREAL: | |
165 | litflavor = 2; | |
166 | goto loop; | |
167 | ||
168 | case TYLOGICAL: | |
169 | type = tylogical; | |
170 | case TYSHORT: | |
171 | case TYLONG: | |
172 | litflavor = 3; | |
173 | ||
174 | loop: | |
175 | lastlit = litpool + nliterals; | |
176 | for(litp = litpool ; litp<lastlit ; ++litp) | |
177 | if(type == litp->littype) switch(litflavor) | |
178 | { | |
179 | case 1: | |
180 | if(p->vleng->constblock.const.ci != litp->litval.litcval.litclen) | |
181 | break; | |
182 | if(! eqn( (int) p->vleng->constblock.const.ci, p->const.ccp, | |
183 | litp->litval.litcval.litcstr) ) | |
184 | break; | |
185 | ||
186 | ret: | |
187 | q->memno = litp->litnum; | |
188 | frexpr(p); | |
189 | return(q); | |
190 | ||
191 | case 2: | |
192 | if(p->const.cd[0] == litp->litval.litdval) | |
193 | goto ret; | |
194 | break; | |
195 | ||
196 | case 3: | |
197 | if(p->const.ci == litp->litval.litival) | |
198 | goto ret; | |
199 | break; | |
200 | } | |
201 | if(nliterals < MAXLITERALS) | |
202 | { | |
203 | ++nliterals; | |
204 | litp->littype = type; | |
205 | litp->litnum = q->memno; | |
206 | switch(litflavor) | |
207 | { | |
208 | case 1: | |
209 | litp->litval.litcval.litclen = | |
210 | p->vleng->constblock.const.ci; | |
211 | cpn( (int) litp->litval.litcval.litclen, | |
212 | p->const.ccp, | |
213 | litp->litval.litcval.litcstr); | |
214 | break; | |
215 | ||
216 | case 2: | |
217 | litp->litval.litdval = p->const.cd[0]; | |
218 | break; | |
219 | ||
220 | case 3: | |
221 | litp->litval.litival = p->const.ci; | |
222 | break; | |
223 | } | |
224 | } | |
225 | default: | |
226 | break; | |
227 | } | |
228 | ||
229 | preven(typealign[ type==TYCHAR ? TYLONG : type ]); | |
230 | prlabel(asmfile, q->memno); | |
231 | ||
232 | k = 1; | |
233 | switch(type) | |
234 | { | |
235 | case TYLOGICAL: | |
236 | case TYSHORT: | |
237 | case TYLONG: | |
238 | prconi(asmfile, type, p->const.ci); | |
239 | break; | |
240 | ||
241 | case TYCOMPLEX: | |
242 | k = 2; | |
243 | case TYREAL: | |
244 | type = TYREAL; | |
245 | goto flpt; | |
246 | ||
247 | case TYDCOMPLEX: | |
248 | k = 2; | |
249 | case TYDREAL: | |
250 | type = TYDREAL; | |
251 | ||
252 | flpt: | |
253 | for(i = 0 ; i < k ; ++i) | |
254 | prconr(asmfile, type, p->const.cd[i]); | |
255 | break; | |
256 | ||
257 | case TYCHAR: | |
258 | putstr(asmfile, p->const.ccp, p->vleng->constblock.const.ci); | |
259 | break; | |
260 | ||
261 | case TYADDR: | |
262 | prcona(asmfile, p->const.ci); | |
263 | break; | |
264 | ||
265 | default: | |
266 | fatali("putconst: bad type %d", p->vtype); | |
267 | } | |
268 | ||
269 | frexpr(p); | |
270 | return( q ); | |
271 | } | |
272 | \f | |
273 | /* | |
274 | * put out a character string constant. begin every one on | |
275 | * a long integer boundary, and pad with nulls | |
276 | */ | |
277 | putstr(fp, s, n) | |
278 | FILEP fp; | |
279 | char *s; | |
280 | ftnint n; | |
281 | { | |
282 | int b[SZSHORT]; | |
283 | int i; | |
284 | ||
285 | i = 0; | |
286 | while(--n >= 0) | |
287 | { | |
288 | b[i++] = *s++; | |
289 | if(i == SZSHORT) | |
290 | { | |
291 | prchars(fp, b); | |
292 | i = 0; | |
293 | } | |
294 | } | |
295 | ||
296 | while(i < SZSHORT) | |
297 | b[i++] = '\0'; | |
298 | prchars(fp, b); | |
299 | } |