|
|
1.1 root 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[] = "@(#)stkrval.c 5.2 (Berkeley) 11/12/86";
9: #endif not lint
10:
11: #include "whoami.h"
12: #include "0.h"
13: #include "tree.h"
14: #include "opcode.h"
15: #include "objfmt.h"
16: #include "align.h"
17: #ifdef PC
18: # include <pcc.h>
19: #endif PC
20: #include "tree_ty.h"
21:
22: /*
23: * stkrval Rvalue - an expression, and coerce it to be a stack quantity.
24: *
25: * Contype is the type that the caller would prefer, nand is important
26: * if constant sets or constant strings are involved, the latter
27: * because of string padding.
28: */
29: /*
30: * for the obj version, this is a copy of rvalue hacked to use fancy new
31: * push-onto-stack-and-convert opcodes.
32: * for the pc version, i just call rvalue and convert if i have to,
33: * based on the return type of rvalue.
34: */
35: struct nl *
36: stkrval(r, contype , required )
37: register struct tnode *r;
38: struct nl *contype;
39: long required;
40: {
41: register struct nl *p;
42: register struct nl *q;
43: register char *cp, *cp1;
44: register int c, w;
45: struct tnode *pt;
46: long l;
47: union
48: {
49: double pdouble;
50: long plong[2];
51: }f;
52:
53: if (r == TR_NIL)
54: return (NLNIL);
55: if (nowexp(r))
56: return (NLNIL);
57: /*
58: * The root of the tree tells us what sort of expression we have.
59: */
60: switch (r->tag) {
61:
62: /*
63: * The constant nil
64: */
65: case T_NIL:
66: # ifdef OBJ
67: (void) put(2, O_CON14, 0);
68: # endif OBJ
69: # ifdef PC
70: putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
71: # endif PC
72: return (nl+TNIL);
73:
74: case T_FCALL:
75: case T_VAR:
76: p = lookup(r->var_node.cptr);
77: if (p == NLNIL || p->class == BADUSE)
78: return (NLNIL);
79: switch (p->class) {
80: case VAR:
81: /*
82: * if a variable is
83: * qualified then get
84: * the rvalue by a
85: * stklval and an ind.
86: */
87: if (r->var_node.qual != TR_NIL)
88: goto ind;
89: q = p->type;
90: if (q == NLNIL)
91: return (NLNIL);
92: if (classify(q) == TSTR)
93: return(stklval(r, NOFLAGS));
94: # ifdef OBJ
95: return (stackRV(p));
96: # endif OBJ
97: # ifdef PC
98: q = rvalue( r , contype , (int) required );
99: if (isa(q, "sbci")) {
100: sconv(p2type(q),PCCT_INT);
101: }
102: return q;
103: # endif PC
104:
105: case WITHPTR:
106: case REF:
107: /*
108: * A stklval for these
109: * is actually what one
110: * might consider a rvalue.
111: */
112: ind:
113: q = stklval(r, NOFLAGS);
114: if (q == NLNIL)
115: return (NLNIL);
116: if (classify(q) == TSTR)
117: return(q);
118: # ifdef OBJ
119: w = width(q);
120: switch (w) {
121: case 8:
122: (void) put(1, O_IND8);
123: return(q);
124: case 4:
125: (void) put(1, O_IND4);
126: return(q);
127: case 2:
128: (void) put(1, O_IND24);
129: return(q);
130: case 1:
131: (void) put(1, O_IND14);
132: return(q);
133: default:
134: (void) put(2, O_IND, w);
135: return(q);
136: }
137: # endif OBJ
138: # ifdef PC
139: if ( required == RREQ ) {
140: putop( PCCOM_UNARY PCC_MUL , p2type( q ) );
141: if (isa(q,"sbci")) {
142: sconv(p2type(q),PCCT_INT);
143: }
144: }
145: return q;
146: # endif PC
147:
148: case CONST:
149: if (r->var_node.qual != TR_NIL) {
150: error("%s is a constant and cannot be qualified", r->var_node.cptr);
151: return (NLNIL);
152: }
153: q = p->type;
154: if (q == NLNIL)
155: return (NLNIL);
156: if (q == nl+TSTR) {
157: /*
158: * Find the size of the string
159: * constant if needed.
160: */
161: cp = (char *) p->ptr[0];
162: cstrng:
163: cp1 = cp;
164: for (c = 0; *cp++; c++)
165: continue;
166: w = c;
167: if (contype != NIL && !opt('s')) {
168: if (width(contype) < c && classify(contype) == TSTR) {
169: error("Constant string too long");
170: return (NLNIL);
171: }
172: w = width(contype);
173: }
174: # ifdef OBJ
175: (void) put(2, O_LVCON, lenstr(cp1, w - c));
176: putstr(cp1, w - c);
177: # endif OBJ
178: # ifdef PC
179: putCONG( cp1 , w , LREQ );
180: # endif PC
181: /*
182: * Define the string temporarily
183: * so later people can know its
184: * width.
185: * cleaned out by stat.
186: */
187: q = defnl((char *) 0, STR, NLNIL, w);
188: q->type = q;
189: return (q);
190: }
191: if (q == nl+T1CHAR) {
192: # ifdef OBJ
193: (void) put(2, O_CONC4, (int)p->value[0]);
194: # endif OBJ
195: # ifdef PC
196: putleaf(PCC_ICON, p -> value[0], 0, PCCT_INT,
197: (char *) 0);
198: # endif PC
199: return(q);
200: }
201: /*
202: * Every other kind of constant here
203: */
204: # ifdef OBJ
205: switch (width(q)) {
206: case 8:
207: #ifndef DEBUG
208: (void) put(2, O_CON8, p->real);
209: return(q);
210: #else
211: if (hp21mx) {
212: f.pdouble = p->real;
213: conv((int *) (&f.pdouble));
214: l = f.plong[1];
215: (void) put(2, O_CON4, l);
216: } else
217: (void) put(2, O_CON8, p->real);
218: return(q);
219: #endif
220: case 4:
221: (void) put(2, O_CON4, p->range[0]);
222: return(q);
223: case 2:
224: (void) put(2, O_CON24, (short)p->range[0]);
225: return(q);
226: case 1:
227: (void) put(2, O_CON14, p->value[0]);
228: return(q);
229: default:
230: panic("stkrval");
231: }
232: # endif OBJ
233: # ifdef PC
234: q = rvalue( r , contype , (int) required );
235: if (isa(q,"sbci")) {
236: sconv(p2type(q),PCCT_INT);
237: }
238: return q;
239: # endif PC
240:
241: case FUNC:
242: case FFUNC:
243: /*
244: * Function call
245: */
246: pt = r->var_node.qual;
247: if (pt != TR_NIL) {
248: switch (pt->list_node.list->tag) {
249: case T_PTR:
250: case T_ARGL:
251: case T_ARY:
252: case T_FIELD:
253: error("Can't qualify a function result value");
254: return (NLNIL);
255: }
256: }
257: # ifdef OBJ
258: q = p->type;
259: if (classify(q) == TSTR) {
260: c = width(q);
261: (void) put(2, O_LVCON,
262: roundup(c+1, (long) A_SHORT));
263: putstr("", c);
264: (void) put(1, PTR_DUP);
265: p = funccod(r);
266: (void) put(2, O_AS, c);
267: return(p);
268: }
269: p = funccod(r);
270: if (width(p) <= 2)
271: (void) put(1, O_STOI);
272: # endif OBJ
273: # ifdef PC
274: p = pcfunccod( r );
275: if (isa(p,"sbci")) {
276: sconv(p2type(p),PCCT_INT);
277: }
278: # endif PC
279: return (p);
280:
281: case TYPE:
282: error("Type names (e.g. %s) allowed only in declarations", p->symbol);
283: return (NLNIL);
284:
285: case PROC:
286: case FPROC:
287: error("Procedure %s found where expression required", p->symbol);
288: return (NLNIL);
289: default:
290: panic("stkrvid");
291: }
292: case T_PLUS:
293: case T_MINUS:
294: case T_NOT:
295: case T_AND:
296: case T_OR:
297: case T_DIVD:
298: case T_MULT:
299: case T_SUB:
300: case T_ADD:
301: case T_MOD:
302: case T_DIV:
303: case T_EQ:
304: case T_NE:
305: case T_GE:
306: case T_LE:
307: case T_GT:
308: case T_LT:
309: case T_IN:
310: p = rvalue(r, contype , (int) required );
311: # ifdef OBJ
312: if (width(p) <= 2)
313: (void) put(1, O_STOI);
314: # endif OBJ
315: # ifdef PC
316: if (isa(p,"sbci")) {
317: sconv(p2type(p),PCCT_INT);
318: }
319: # endif PC
320: return (p);
321: case T_CSET:
322: p = rvalue(r, contype , (int) required );
323: return (p);
324: default:
325: if (r->const_node.cptr == (char *) NIL)
326: return (NLNIL);
327: switch (r->tag) {
328: default:
329: panic("stkrval3");
330:
331: /*
332: * An octal number
333: */
334: case T_BINT:
335: f.pdouble = a8tol(r->const_node.cptr);
336: goto conint;
337:
338: /*
339: * A decimal number
340: */
341: case T_INT:
342: f.pdouble = atof(r->const_node.cptr);
343: conint:
344: if (f.pdouble > MAXINT || f.pdouble < MININT) {
345: error("Constant too large for this implementation");
346: return (NLNIL);
347: }
348: l = f.pdouble;
349: if (bytes(l, l) <= 2) {
350: # ifdef OBJ
351: (void) put(2, O_CON24, (short)l);
352: # endif OBJ
353: # ifdef PC
354: putleaf( PCC_ICON , (short) l , 0 , PCCT_INT ,
355: (char *) 0 );
356: # endif PC
357: return(nl+T4INT);
358: }
359: # ifdef OBJ
360: (void) put(2, O_CON4, l);
361: # endif OBJ
362: # ifdef PC
363: putleaf( PCC_ICON , (int) l , 0 , PCCT_INT , (char *) 0 );
364: # endif PC
365: return (nl+T4INT);
366:
367: /*
368: * A floating point number
369: */
370: case T_FINT:
371: # ifdef OBJ
372: (void) put(2, O_CON8, atof(r->const_node.cptr));
373: # endif OBJ
374: # ifdef PC
375: putCON8( atof( r->const_node.cptr ) );
376: # endif PC
377: return (nl+TDOUBLE);
378:
379: /*
380: * Constant strings. Note that constant characters
381: * are constant strings of length one; there is
382: * no constant string of length one.
383: */
384: case T_STRNG:
385: cp = r->const_node.cptr;
386: if (cp[1] == 0) {
387: # ifdef OBJ
388: (void) put(2, O_CONC4, cp[0]);
389: # endif OBJ
390: # ifdef PC
391: putleaf( PCC_ICON , cp[0] , 0 , PCCT_INT ,
392: (char *) 0 );
393: # endif PC
394: return(nl+T1CHAR);
395: }
396: goto cstrng;
397: }
398:
399: }
400: }
401:
402: #ifdef OBJ
403: /*
404: * push a value onto the interpreter stack, longword aligned.
405: */
406: struct nl
407: *stackRV(p)
408: struct nl *p;
409: {
410: struct nl *q;
411: int w, bn;
412:
413: q = p->type;
414: if (q == NLNIL)
415: return (NLNIL);
416: bn = BLOCKNO(p->nl_block);
417: w = width(q);
418: switch (w) {
419: case 8:
420: (void) put(2, O_RV8 | bn << 8+INDX, (int)p->value[0]);
421: break;
422: case 4:
423: (void) put(2, O_RV4 | bn << 8+INDX, (int)p->value[0]);
424: break;
425: case 2:
426: (void) put(2, O_RV24 | bn << 8+INDX, (int)p->value[0]);
427: break;
428: case 1:
429: (void) put(2, O_RV14 | bn << 8+INDX, (int)p->value[0]);
430: break;
431: default:
432: (void) put(3, O_RV | bn << 8+INDX, (int)p->value[0], w);
433: break;
434: }
435: return (q);
436: }
437: #endif OBJ
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.