122194Sdist /* 222194Sdist * Copyright (c) 1980 Regents of the University of California. 322194Sdist * All rights reserved. The Berkeley software License Agreement 422194Sdist * specifies the terms and conditions for redistribution. 522194Sdist */ 6775Speter 714743Sthien #ifndef lint 8*30037Smckusick static char sccsid[] = "@(#)stkrval.c 5.2 (Berkeley) 11/12/86"; 922194Sdist #endif not lint 10775Speter 11775Speter #include "whoami.h" 12775Speter #include "0.h" 13775Speter #include "tree.h" 14775Speter #include "opcode.h" 15775Speter #include "objfmt.h" 16*30037Smckusick #include "align.h" 17775Speter #ifdef PC 1818471Sralph # include <pcc.h> 19775Speter #endif PC 2014743Sthien #include "tree_ty.h" 21775Speter 22775Speter /* 23775Speter * stkrval Rvalue - an expression, and coerce it to be a stack quantity. 24775Speter * 25775Speter * Contype is the type that the caller would prefer, nand is important 26775Speter * if constant sets or constant strings are involved, the latter 27775Speter * because of string padding. 28775Speter */ 29775Speter /* 30775Speter * for the obj version, this is a copy of rvalue hacked to use fancy new 31775Speter * push-onto-stack-and-convert opcodes. 32775Speter * for the pc version, i just call rvalue and convert if i have to, 33775Speter * based on the return type of rvalue. 34775Speter */ 35775Speter struct nl * 36775Speter stkrval(r, contype , required ) 3714743Sthien register struct tnode *r; 38775Speter struct nl *contype; 39775Speter long required; 40775Speter { 41775Speter register struct nl *p; 42775Speter register struct nl *q; 43775Speter register char *cp, *cp1; 44775Speter register int c, w; 4514743Sthien struct tnode *pt; 46775Speter long l; 4714743Sthien union 4814743Sthien { 4914743Sthien double pdouble; 5014743Sthien long plong[2]; 5114743Sthien }f; 52775Speter 5314743Sthien if (r == TR_NIL) 5414743Sthien return (NLNIL); 55775Speter if (nowexp(r)) 5614743Sthien return (NLNIL); 57775Speter /* 58775Speter * The root of the tree tells us what sort of expression we have. 59775Speter */ 6014743Sthien switch (r->tag) { 61775Speter 62775Speter /* 63775Speter * The constant nil 64775Speter */ 65775Speter case T_NIL: 66775Speter # ifdef OBJ 6714743Sthien (void) put(2, O_CON14, 0); 68775Speter # endif OBJ 69775Speter # ifdef PC 7018471Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 71775Speter # endif PC 72775Speter return (nl+TNIL); 73775Speter 74775Speter case T_FCALL: 75775Speter case T_VAR: 7614743Sthien p = lookup(r->var_node.cptr); 7714743Sthien if (p == NLNIL || p->class == BADUSE) 7814743Sthien return (NLNIL); 79775Speter switch (p->class) { 80775Speter case VAR: 81775Speter /* 823080Smckusic * if a variable is 83775Speter * qualified then get 84775Speter * the rvalue by a 85775Speter * stklval and an ind. 86775Speter */ 8714743Sthien if (r->var_node.qual != TR_NIL) 88775Speter goto ind; 89775Speter q = p->type; 9014743Sthien if (q == NLNIL) 9114743Sthien return (NLNIL); 92775Speter if (classify(q) == TSTR) 93775Speter return(stklval(r, NOFLAGS)); 94775Speter # ifdef OBJ 9510568Smckusick return (stackRV(p)); 96775Speter # endif OBJ 97775Speter # ifdef PC 9814743Sthien q = rvalue( r , contype , (int) required ); 9910360Smckusick if (isa(q, "sbci")) { 10018471Sralph sconv(p2type(q),PCCT_INT); 10110360Smckusick } 10210360Smckusick return q; 103775Speter # endif PC 104775Speter 105775Speter case WITHPTR: 106775Speter case REF: 107775Speter /* 108775Speter * A stklval for these 109775Speter * is actually what one 110775Speter * might consider a rvalue. 111775Speter */ 112775Speter ind: 113775Speter q = stklval(r, NOFLAGS); 11414743Sthien if (q == NLNIL) 11514743Sthien return (NLNIL); 116775Speter if (classify(q) == TSTR) 117775Speter return(q); 118775Speter # ifdef OBJ 119775Speter w = width(q); 120775Speter switch (w) { 121775Speter case 8: 12214743Sthien (void) put(1, O_IND8); 123775Speter return(q); 124775Speter case 4: 12514743Sthien (void) put(1, O_IND4); 126775Speter return(q); 127775Speter case 2: 12814743Sthien (void) put(1, O_IND24); 129775Speter return(q); 130775Speter case 1: 13114743Sthien (void) put(1, O_IND14); 132775Speter return(q); 133775Speter default: 13414743Sthien (void) put(2, O_IND, w); 135775Speter return(q); 136775Speter } 137775Speter # endif OBJ 138775Speter # ifdef PC 139775Speter if ( required == RREQ ) { 14018471Sralph putop( PCCOM_UNARY PCC_MUL , p2type( q ) ); 14110360Smckusick if (isa(q,"sbci")) { 14218471Sralph sconv(p2type(q),PCCT_INT); 14310360Smckusick } 144775Speter } 145775Speter return q; 146775Speter # endif PC 147775Speter 148775Speter case CONST: 14914743Sthien if (r->var_node.qual != TR_NIL) { 15014743Sthien error("%s is a constant and cannot be qualified", r->var_node.cptr); 15114743Sthien return (NLNIL); 152775Speter } 153775Speter q = p->type; 15414743Sthien if (q == NLNIL) 15514743Sthien return (NLNIL); 156775Speter if (q == nl+TSTR) { 157775Speter /* 158775Speter * Find the size of the string 159775Speter * constant if needed. 160775Speter */ 16114743Sthien cp = (char *) p->ptr[0]; 162775Speter cstrng: 163775Speter cp1 = cp; 164775Speter for (c = 0; *cp++; c++) 165775Speter continue; 16610841Speter w = c; 167775Speter if (contype != NIL && !opt('s')) { 168775Speter if (width(contype) < c && classify(contype) == TSTR) { 169775Speter error("Constant string too long"); 17014743Sthien return (NLNIL); 171775Speter } 17210841Speter w = width(contype); 173775Speter } 174775Speter # ifdef OBJ 17514743Sthien (void) put(2, O_LVCON, lenstr(cp1, w - c)); 17610841Speter putstr(cp1, w - c); 177775Speter # endif OBJ 178775Speter # ifdef PC 17910841Speter putCONG( cp1 , w , LREQ ); 180775Speter # endif PC 181775Speter /* 182775Speter * Define the string temporarily 183775Speter * so later people can know its 184775Speter * width. 185775Speter * cleaned out by stat. 186775Speter */ 18714743Sthien q = defnl((char *) 0, STR, NLNIL, w); 188775Speter q->type = q; 189775Speter return (q); 190775Speter } 191775Speter if (q == nl+T1CHAR) { 192775Speter # ifdef OBJ 19314743Sthien (void) put(2, O_CONC4, (int)p->value[0]); 194775Speter # endif OBJ 195775Speter # ifdef PC 19618471Sralph putleaf(PCC_ICON, p -> value[0], 0, PCCT_INT, 19714743Sthien (char *) 0); 198775Speter # endif PC 199775Speter return(q); 200775Speter } 201775Speter /* 202775Speter * Every other kind of constant here 203775Speter */ 204775Speter # ifdef OBJ 205775Speter switch (width(q)) { 206775Speter case 8: 207775Speter #ifndef DEBUG 20814743Sthien (void) put(2, O_CON8, p->real); 209775Speter return(q); 210775Speter #else 211775Speter if (hp21mx) { 21214743Sthien f.pdouble = p->real; 21314743Sthien conv((int *) (&f.pdouble)); 21414743Sthien l = f.plong[1]; 21514743Sthien (void) put(2, O_CON4, l); 216775Speter } else 21714743Sthien (void) put(2, O_CON8, p->real); 218775Speter return(q); 219775Speter #endif 220775Speter case 4: 22114743Sthien (void) put(2, O_CON4, p->range[0]); 222775Speter return(q); 223775Speter case 2: 22414743Sthien (void) put(2, O_CON24, (short)p->range[0]); 225775Speter return(q); 226775Speter case 1: 22714743Sthien (void) put(2, O_CON14, p->value[0]); 228775Speter return(q); 229775Speter default: 230775Speter panic("stkrval"); 231775Speter } 232775Speter # endif OBJ 233775Speter # ifdef PC 23414743Sthien q = rvalue( r , contype , (int) required ); 23510360Smckusick if (isa(q,"sbci")) { 23618471Sralph sconv(p2type(q),PCCT_INT); 23710360Smckusick } 23810360Smckusick return q; 239775Speter # endif PC 240775Speter 241775Speter case FUNC: 2421201Speter case FFUNC: 243775Speter /* 244775Speter * Function call 245775Speter */ 24614743Sthien pt = r->var_node.qual; 24714743Sthien if (pt != TR_NIL) { 24814743Sthien switch (pt->list_node.list->tag) { 249775Speter case T_PTR: 250775Speter case T_ARGL: 251775Speter case T_ARY: 252775Speter case T_FIELD: 253775Speter error("Can't qualify a function result value"); 25414743Sthien return (NLNIL); 255775Speter } 256775Speter } 257775Speter # ifdef OBJ 258775Speter q = p->type; 259775Speter if (classify(q) == TSTR) { 260775Speter c = width(q); 261*30037Smckusick (void) put(2, O_LVCON, 262*30037Smckusick roundup(c+1, (long) A_SHORT)); 263775Speter putstr("", c); 26414743Sthien (void) put(1, PTR_DUP); 265775Speter p = funccod(r); 26614743Sthien (void) put(2, O_AS, c); 267775Speter return(p); 268775Speter } 269775Speter p = funccod(r); 270775Speter if (width(p) <= 2) 27114743Sthien (void) put(1, O_STOI); 272775Speter # endif OBJ 273775Speter # ifdef PC 274775Speter p = pcfunccod( r ); 27510360Smckusick if (isa(p,"sbci")) { 27618471Sralph sconv(p2type(p),PCCT_INT); 27710360Smckusick } 278775Speter # endif PC 279775Speter return (p); 280775Speter 281775Speter case TYPE: 282775Speter error("Type names (e.g. %s) allowed only in declarations", p->symbol); 28314743Sthien return (NLNIL); 284775Speter 285775Speter case PROC: 2861201Speter case FPROC: 287775Speter error("Procedure %s found where expression required", p->symbol); 28814743Sthien return (NLNIL); 289775Speter default: 290775Speter panic("stkrvid"); 291775Speter } 292775Speter case T_PLUS: 293775Speter case T_MINUS: 294775Speter case T_NOT: 295775Speter case T_AND: 296775Speter case T_OR: 297775Speter case T_DIVD: 298775Speter case T_MULT: 299775Speter case T_SUB: 300775Speter case T_ADD: 301775Speter case T_MOD: 302775Speter case T_DIV: 303775Speter case T_EQ: 304775Speter case T_NE: 305775Speter case T_GE: 306775Speter case T_LE: 307775Speter case T_GT: 308775Speter case T_LT: 309775Speter case T_IN: 31014743Sthien p = rvalue(r, contype , (int) required ); 311775Speter # ifdef OBJ 312775Speter if (width(p) <= 2) 31314743Sthien (void) put(1, O_STOI); 314775Speter # endif OBJ 31510360Smckusick # ifdef PC 31610360Smckusick if (isa(p,"sbci")) { 31718471Sralph sconv(p2type(p),PCCT_INT); 31810360Smckusick } 31910360Smckusick # endif PC 320775Speter return (p); 321909Speter case T_CSET: 32214743Sthien p = rvalue(r, contype , (int) required ); 323909Speter return (p); 324775Speter default: 32514743Sthien if (r->const_node.cptr == (char *) NIL) 32614743Sthien return (NLNIL); 32714743Sthien switch (r->tag) { 328775Speter default: 329775Speter panic("stkrval3"); 330775Speter 331775Speter /* 332775Speter * An octal number 333775Speter */ 334775Speter case T_BINT: 33514743Sthien f.pdouble = a8tol(r->const_node.cptr); 336775Speter goto conint; 337775Speter 338775Speter /* 339775Speter * A decimal number 340775Speter */ 341775Speter case T_INT: 34214743Sthien f.pdouble = atof(r->const_node.cptr); 343775Speter conint: 34414743Sthien if (f.pdouble > MAXINT || f.pdouble < MININT) { 345775Speter error("Constant too large for this implementation"); 34614743Sthien return (NLNIL); 347775Speter } 34814743Sthien l = f.pdouble; 349775Speter if (bytes(l, l) <= 2) { 350775Speter # ifdef OBJ 35114743Sthien (void) put(2, O_CON24, (short)l); 352775Speter # endif OBJ 353775Speter # ifdef PC 35418471Sralph putleaf( PCC_ICON , (short) l , 0 , PCCT_INT , 35514743Sthien (char *) 0 ); 356775Speter # endif PC 357775Speter return(nl+T4INT); 358775Speter } 359775Speter # ifdef OBJ 36014743Sthien (void) put(2, O_CON4, l); 361775Speter # endif OBJ 362775Speter # ifdef PC 36318471Sralph putleaf( PCC_ICON , (int) l , 0 , PCCT_INT , (char *) 0 ); 364775Speter # endif PC 365775Speter return (nl+T4INT); 366775Speter 367775Speter /* 368775Speter * A floating point number 369775Speter */ 370775Speter case T_FINT: 371775Speter # ifdef OBJ 37214743Sthien (void) put(2, O_CON8, atof(r->const_node.cptr)); 373775Speter # endif OBJ 374775Speter # ifdef PC 37514743Sthien putCON8( atof( r->const_node.cptr ) ); 376775Speter # endif PC 377775Speter return (nl+TDOUBLE); 378775Speter 379775Speter /* 380775Speter * Constant strings. Note that constant characters 381775Speter * are constant strings of length one; there is 382775Speter * no constant string of length one. 383775Speter */ 384775Speter case T_STRNG: 38514743Sthien cp = r->const_node.cptr; 386775Speter if (cp[1] == 0) { 387775Speter # ifdef OBJ 38814743Sthien (void) put(2, O_CONC4, cp[0]); 389775Speter # endif OBJ 390775Speter # ifdef PC 39118471Sralph putleaf( PCC_ICON , cp[0] , 0 , PCCT_INT , 39214743Sthien (char *) 0 ); 393775Speter # endif PC 394775Speter return(nl+T1CHAR); 395775Speter } 396775Speter goto cstrng; 397775Speter } 398775Speter 399775Speter } 400775Speter } 40110568Smckusick 40210568Smckusick #ifdef OBJ 40310568Smckusick /* 40410568Smckusick * push a value onto the interpreter stack, longword aligned. 40510568Smckusick */ 40614743Sthien struct nl 40714743Sthien *stackRV(p) 40810568Smckusick struct nl *p; 40910568Smckusick { 41010568Smckusick struct nl *q; 41110568Smckusick int w, bn; 41210568Smckusick 41310568Smckusick q = p->type; 41414743Sthien if (q == NLNIL) 41514743Sthien return (NLNIL); 41610568Smckusick bn = BLOCKNO(p->nl_block); 41710568Smckusick w = width(q); 41810568Smckusick switch (w) { 41910568Smckusick case 8: 42014743Sthien (void) put(2, O_RV8 | bn << 8+INDX, (int)p->value[0]); 42110568Smckusick break; 42210568Smckusick case 4: 42314743Sthien (void) put(2, O_RV4 | bn << 8+INDX, (int)p->value[0]); 42410568Smckusick break; 42510568Smckusick case 2: 42614743Sthien (void) put(2, O_RV24 | bn << 8+INDX, (int)p->value[0]); 42710568Smckusick break; 42810568Smckusick case 1: 42914743Sthien (void) put(2, O_RV14 | bn << 8+INDX, (int)p->value[0]); 43010568Smckusick break; 43110568Smckusick default: 43214743Sthien (void) put(3, O_RV | bn << 8+INDX, (int)p->value[0], w); 43310568Smckusick break; 43410568Smckusick } 43510568Smckusick return (q); 43610568Smckusick } 43710568Smckusick #endif OBJ 438