summaryrefslogtreecommitdiff
path: root/bcc/loadexp.c
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-03-24 17:45:55 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:29:43 +0200
commitfe22c37817ce338fbbc90b239320248c270957fa (patch)
treed9550410c4a20bdd382fcc58d2d3d7c5e04e5245 /bcc/loadexp.c
parenta7aba15e8efffb1c5d3097656f1a93955a64f01f (diff)
parent42192453ea219b80d0bf9f41e51e36d3d4d0740b (diff)
downloaddev86-fe22c37817ce338fbbc90b239320248c270957fa.tar.gz
Import Dev86-0.0.4.tar.gzv0.0.4
Diffstat (limited to 'bcc/loadexp.c')
-rw-r--r--bcc/loadexp.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/bcc/loadexp.c b/bcc/loadexp.c
new file mode 100644
index 0000000..632c2ad
--- /dev/null
+++ b/bcc/loadexp.c
@@ -0,0 +1,180 @@
+/* loadexp.c - load expressions for bcc */
+
+/* Copyright (C) 1992 Bruce Evans */
+
+#include "const.h"
+#include "types.h"
+#include "byteord.h"
+#include "gencode.h"
+#include "parse.h"
+#include "reg.h"
+#include "sc.h"
+#include "scan.h"
+#include "sizes.h"
+#include "table.h"
+#include "type.h"
+
+PUBLIC value_t constexpression()
+{
+ struct nodestruct *etmark;
+ struct nodestruct *exp;
+ struct symstruct *exprmark;
+ struct symstruct *symptr;
+
+ etmark = etptr;
+ exprmark = exprptr;
+ exp = assignment_exp();
+ etptr = etmark;
+ exprptr = exprmark;
+ if (exp->tag == LEAF && (symptr = exp->left.symptr)->storage == CONSTANT
+ && symptr->type->scalar & ISCALAR)
+ return symptr->offset.offv;
+ error("constant expression required");
+ return 1;
+}
+
+PUBLIC void initexpression(type)
+struct typestruct *type;
+{
+ struct nodestruct *etmark;
+ struct nodestruct *exp;
+ struct symstruct *exprmark;
+ struct nodestruct *lhs;
+ struct symstruct *symptr;
+ uoffset_t value;
+
+ if (gvarsymptr->storage != GLOBAL)
+ reslocals();
+ exprmark = exprptr;
+ etmark = etptr;
+ exp = assignment_exp();
+ if (gvarsymptr->storage != GLOBAL)
+ {
+ lhs = leafnode(exprsym(gvarsymptr));
+ if (!(lhs->nodetype->constructor & (ARRAY | FUNCTION | VOID)))
+ lhs->flags = LVALUE;
+ makeleaf(node(ASSIGNOP, lhs, exp));
+ }
+ else if (exp->tag != LEAF ||
+ ((symptr = exp->left.symptr)->storage != CONSTANT &&
+ (symptr->storage != GLOBAL || symptr->indcount != 0 ||
+ type->scalar & DLONG)) ||
+ (type->constructor | (symptr->type->constructor & ~FUNCTION)) &
+ ~(ARRAY | POINTER))
+ error("initializer too complicated");
+ else
+ {
+ if ((symptr->type->scalar | type->scalar) & RSCALAR)
+ {
+ /* Can only afford castnode if result known constant. */
+ exp = castnode(type, exp);
+ symptr = exp->left.symptr;
+ }
+ if (type->scalar & RSCALAR)
+ {
+ if (type->scalar & FLOAT)
+ {
+ float val;
+
+ val = *symptr->offset.offd;
+ deflong(((uoffset_t *) &val)[0]);
+ }
+ else
+ {
+ deflong(((uoffset_t *) symptr->offset.offd)[0]);
+ deflong(((uoffset_t *) symptr->offset.offd)[1]);
+ }
+ etptr = etmark; /* XXX - stuff from end of function */
+ exprptr = exprmark;
+ return;
+ }
+ if (type->typesize == 1)
+ defbyte();
+ else if (type->typesize == 2)
+ defword();
+#ifdef I8088
+ else if (!(type->scalar & DLONG))
+ defdword();
+#endif
+ switch (symptr->storage)
+ {
+ case CONSTANT:
+ value = (uoffset_t) symptr->offset.offv;
+ if (type->scalar & DLONG)
+ {
+ deflong(value);
+ break;
+ }
+ /* XXX - put sizes in type struct to avoid tests */
+ if (type->scalar & CHAR)
+ value &= CHMASKTO;
+ else if (type->scalar & SHORT)
+ value &= shortmaskto;
+ else if (type->scalar & INT)
+ value &= intmaskto;
+ /* XXX - no longmaskto */
+ outnhex(value);
+ break;
+ case GLOBAL:
+ if (symptr->flags & LABELLED)
+ {
+ outlabel(symptr->name.label);
+ outplus();
+ outnhex((uoffset_t) symptr->offset.offi);
+ break;
+ }
+ if (*symptr->name.namep == 0) /* constant address */
+ {
+ outnhex((uoffset_t) symptr->offset.offi);
+ break;
+ }
+ outccname(symptr->name.namep);
+ if (symptr->offset.offi != 0)
+ {
+ if (symptr->offset.offi > 0)
+ outplus();
+ outshex(symptr->offset.offi);
+ }
+ outnl();
+ break;
+ }
+ }
+ etptr = etmark;
+ exprptr = exprmark;
+}
+
+PUBLIC struct typestruct *loadexpression(targreg, targtype)
+store_pt targreg;
+struct typestruct *targtype;
+{
+ struct nodestruct *etmark;
+ struct nodestruct *exp;
+ struct symstruct *exprmark;
+
+ etmark = etptr;
+ exprmark = exprptr;
+ exp = expression();
+ if (targtype != NULL)
+ exp = castnode(targtype, exp);
+ makeleaf(exp);
+ if (targtype == NULL) /* this is for a switch */
+ {
+ targtype = exp->left.symptr->type;
+ if (!(targtype->scalar & (CHAR | INT))
+ && (targtype->scalar & (LONG | DLONG)) != LONG)
+ {
+ if (targtype->scalar & SHORT)
+ targtype = promote(targtype);
+ else
+ {
+ error("non-integral selector in switch");
+ targtype = itype;
+ }
+ makeleaf(exp = castnode(targtype, exp));
+ }
+ }
+ load(exp->left.symptr, targreg); /* resets stack if value was there */
+ etptr = etmark;
+ exprptr = exprmark;
+ return exp->left.symptr->type;
+}