* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / bcc / loadexp.c
blob30f0b50b2bf178f8ca4221891abccebc58ed326b
1 /* loadexp.c - load expressions for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 #include "bcc.h"
6 #include "byteord.h"
7 #include "gencode.h"
8 #include "parse.h"
9 #include "reg.h"
10 #include "sc.h"
11 #include "scan.h"
12 #include "sizes.h"
13 #include "table.h"
14 #include "type.h"
16 PUBLIC value_t constexpression()
18 struct nodestruct *etmark;
19 struct nodestruct *exp;
20 struct symstruct *exprmark;
21 struct symstruct *symptr;
23 etmark = etptr;
24 exprmark = exprptr;
25 exp = assignment_exp();
26 etptr = etmark;
27 exprptr = exprmark;
28 if (exp->tag == LEAF && (symptr = exp->left.symptr)->storage == CONSTANT
29 && symptr->type->scalar & ISCALAR)
30 return symptr->offset.offv;
31 error("constant expression required");
32 return 1;
35 PUBLIC void initexpression(type)
36 struct typestruct *type;
38 struct nodestruct *etmark;
39 struct nodestruct *exp;
40 struct symstruct *exprmark;
41 struct nodestruct *lhs;
42 struct symstruct *symptr;
43 uoffset_T value;
45 if (gvarsymptr->storage != GLOBAL)
46 reslocals();
47 exprmark = exprptr;
48 etmark = etptr;
49 exp = assignment_exp();
50 if (gvarsymptr->storage != GLOBAL)
52 lhs = leafnode(exprsym(gvarsymptr));
53 if (!(lhs->nodetype->constructor & (ARRAY | FUNCTION | VOID)))
54 lhs->flags = LVALUE;
55 makeleaf(node(ASSIGNOP, lhs, exp));
57 else if (exp->tag != LEAF ||
58 ((symptr = exp->left.symptr)->storage != CONSTANT &&
59 (symptr->storage != GLOBAL || symptr->indcount != 0 ||
60 type->scalar & DLONG)) ||
61 (type->constructor | (symptr->type->constructor & ~FUNCTION)) &
62 ~(ARRAY | POINTER))
63 error("initializer too complicated");
64 else
66 if ((symptr->type->scalar | type->scalar) & RSCALAR)
68 /* Can only afford castnode if result known constant. */
69 exp = castnode(type, exp);
70 symptr = exp->left.symptr;
72 if (type->scalar & RSCALAR)
74 if (type->scalar & FLOAT)
76 float val;
78 val = *symptr->offset.offd;
79 deflong(((uoffset_T *) &val)[0]);
81 else
83 deflong(((uoffset_T *) symptr->offset.offd)[0]);
84 deflong(((uoffset_T *) symptr->offset.offd)[1]);
86 etptr = etmark; /* XXX - stuff from end of function */
87 exprptr = exprmark;
88 return;
90 if (type->typesize == 1)
91 defbyte();
92 else if (type->typesize == 2)
93 defword();
94 #ifdef I8088
95 else if (!(type->scalar & DLONG))
96 defdword();
97 #endif
98 switch (symptr->storage)
100 case CONSTANT:
101 value = (uoffset_T) symptr->offset.offv;
102 if (type->scalar & DLONG)
104 deflong(value);
105 break;
107 /* XXX - put sizes in type struct to avoid tests */
108 if (type->scalar & CHAR)
109 value &= CHMASKTO;
110 else if (type->scalar & SHORT)
111 value &= shortmaskto;
112 else if (type->scalar & INT)
113 value &= intmaskto;
114 /* XXX - no longmaskto */
115 outnhex(value);
116 break;
117 case GLOBAL:
118 if (symptr->flags & LABELLED)
120 outlabel(symptr->name.label);
121 outplus();
122 outnhex((uoffset_T) symptr->offset.offi);
123 break;
125 if (*symptr->name.namep == 0) /* constant address */
127 outnhex((uoffset_T) symptr->offset.offi);
128 break;
130 outccname(symptr->name.namep);
131 if (symptr->offset.offi != 0)
133 if (symptr->offset.offi > 0)
134 outplus();
135 outshex(symptr->offset.offi);
137 outnl();
138 break;
141 etptr = etmark;
142 exprptr = exprmark;
145 PUBLIC struct typestruct *loadexpression(targreg, targtype)
146 store_pt targreg;
147 struct typestruct *targtype;
149 struct nodestruct *etmark;
150 struct nodestruct *exp;
151 struct symstruct *exprmark;
153 etmark = etptr;
154 exprmark = exprptr;
155 exp = expression();
156 if (targtype != NULL)
157 exp = castnode(targtype, exp);
158 makeleaf(exp);
159 if (targtype == NULL) /* this is for a switch */
161 targtype = exp->left.symptr->type;
162 if (!(targtype->scalar & (CHAR | INT))
163 && (targtype->scalar & (LONG | DLONG)) != LONG)
165 if (targtype->scalar & SHORT)
166 targtype = promote(targtype);
167 else
169 error("non-integral selector in switch");
170 targtype = itype;
172 makeleaf(exp = castnode(targtype, exp));
175 load(exp->left.symptr, targreg); /* resets stack if value was there */
176 etptr = etmark;
177 exprptr = exprmark;
178 return exp->left.symptr->type;