aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acid/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/acid/expr.c')
-rw-r--r--src/cmd/acid/expr.c129
1 files changed, 109 insertions, 20 deletions
diff --git a/src/cmd/acid/expr.c b/src/cmd/acid/expr.c
index 9cfac9e3..6a0430dc 100644
--- a/src/cmd/acid/expr.c
+++ b/src/cmd/acid/expr.c
@@ -63,11 +63,29 @@ fmtsize(Value *v)
}
}
-void
+Lsym*
chklval(Node *lp)
{
- if(lp->op != ONAME)
- error("need l-value");
+ Node res;
+ Lsym *s;
+
+ if(lp->op == ONAME)
+ return lp->sym;
+
+ if(lp->op == OCALL){
+ s = chklval(lp->left);
+ if(strcmp(s->name, "var") == 0
+ && (lp->builtin || s->proc == 0)){
+ if(lp->right == 0)
+ error("var(string): arg count");
+ expr(lp->right, &res);
+ if(res.type != TSTRING)
+ error("var(string): arg type");
+ return mkvar(res.store.u.string->string);
+ }
+ }
+ error("need l-value");
+ return nil;
}
void
@@ -107,12 +125,24 @@ oindm(Node *n, Node *res)
if(m == 0)
m = symmap;
expr(n->left, &l);
- if(l.type != TINT)
+ switch(l.type){
+ default:
error("bad type for *");
- if(m == 0)
- error("no map for *");
- indir(m, l.store.u.ival, l.store.fmt, res);
- res->store.comt = l.store.comt;
+ case TINT:
+ if(m == 0)
+ error("no map for *");
+ indir(m, l.store.u.ival, l.store.fmt, res);
+ res->store.comt = l.store.comt;
+ break;
+ case TREG:
+ indirreg(correg, l.store.u.reg, l.store.fmt, res);
+ res->store.comt = l.store.comt;
+ break;
+ case TCON:
+ *res = *l.store.u.con;
+ res->store.comt = l.store.comt;
+ break;
+ }
}
void
@@ -145,7 +175,7 @@ oframe(Node *n, Node *res)
while(*p && *p == '$')
p++;
lp = n->left;
- if(localaddr(cormap, correg, p, lp->sym->name, &ival) < 0)
+ if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0)
error("colon: %r");
res->store.u.ival = ival;
@@ -296,19 +326,24 @@ void
oasgn(Node *n, Node *res)
{
Node *lp, r;
+ Node aes;
Value *v;
lp = n->left;
switch(lp->op) {
case OINDM:
- windir(cormap, lp->left, n->right, res);
+ expr(lp->left, &aes);
+ if(aes.type == TREG)
+ windirreg(correg, aes.store.u.reg, n->right, res);
+ else
+ windir(cormap, aes, n->right, res);
break;
case OINDC:
- windir(symmap, lp->left, n->right, res);
+ expr(lp->left, &aes);
+ windir(symmap, aes, n->right, res);
break;
default:
- chklval(lp);
- v = lp->sym->v;
+ v = chklval(lp)->v;
expr(n->right, &r);
v->set = 1;
v->type = r.type;
@@ -871,8 +906,7 @@ oeinc(Node *n, Node *res)
{
Value *v;
- chklval(n->left);
- v = n->left->sym->v;
+ v = chklval(n->left)->v;
res->op = OCONST;
res->type = v->type;
switch(v->type) {
@@ -899,8 +933,7 @@ opinc(Node *n, Node *res)
{
Value *v;
- chklval(n->left);
- v = n->left->sym->v;
+ v = chklval(n->left)->v;
res->op = OCONST;
res->type = v->type;
res->store = v->store;
@@ -932,9 +965,7 @@ ocall(Node *n, Node *res)
res->type = TLIST;
res->store.u.l = 0;
- chklval(n->left);
- s = n->left->sym;
-
+ s = chklval(n->left);
if(n->builtin && !s->builtin){
error("no builtin %s", s->name);
return;
@@ -959,6 +990,12 @@ ofmt(Node *n, Node *res)
}
void
+ouplus(Node *n, Node *res)
+{
+ expr(n->left, res);
+}
+
+void
owhat(Node *n, Node *res)
{
res->op = OCONST; /* Default return value */
@@ -1021,6 +1058,7 @@ initexpop(void)
expop[OFMT] = ofmt;
expop[OEVAL] = oeval;
expop[OWHAT] = owhat;
+ expop[OUPLUS] = ouplus;
}
void
@@ -1030,3 +1068,54 @@ initexpr(void)
initexpop();
}
+int
+acidregsrw(Regs *r, char *name, ulong *u, int isr)
+{
+ Lsym *l;
+ Value *v;
+ Node *n;
+ ulong addr;
+ u32int u32;
+
+ if(!isr){
+ werrstr("cannot write registers");
+ return -1;
+ }
+ USED(r);
+ l = look(name);
+ if(l == nil){
+ werrstr("register %s not found", name);
+ return -1;
+ }
+ v = l->v;
+ switch(v->type){
+ default:
+ werrstr("*%s: bad type", name);
+ return -1;
+ case TREG:
+ if(correg == nil){
+ werrstr("*%s: register %s not mapped", name, v->store.u.reg);
+ return -1;
+ }
+ return rget(correg, v->store.u.reg, u);
+ case TCON:
+ n = v->store.u.con;
+ if(n->op != OCONST || n->type != TINT){
+ werrstr("*%s: bad register constant", name);
+ return -1;
+ }
+ *u = n->store.u.ival;
+ return 0;
+ case TINT:
+ if(cormap == nil){
+ werrstr("*%s: core not mapped", name);
+ return -1;
+ }
+ addr = v->store.u.ival;
+ /* XXX should use format to determine size */
+ if(get4(cormap, addr, &u32) < 0)
+ return -1;
+ *u = u32;
+ return 0;
+ }
+}