aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/acid/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/acid/exec.c')
-rw-r--r--src/cmd/acid/exec.c187
1 files changed, 119 insertions, 68 deletions
diff --git a/src/cmd/acid/exec.c b/src/cmd/acid/exec.c
index edf2690e..2022da53 100644
--- a/src/cmd/acid/exec.c
+++ b/src/cmd/acid/exec.c
@@ -202,56 +202,6 @@ convflt(Node *r, char *flt)
}
}
-static char*
-regbyoff(ulong addr)
-{
- Regdesc *r;
-
- if(mach == nil)
- error("no mach, no registers");
- for(r=mach->reglist; r->name; r++)
- if(r->offset == addr)
- return r->name;
- error("no register at %#lux", addr);
- return nil;
-}
-
-int
-xget1(Map *m, ulong addr, u8int *a, int n)
-{
- if(addr < 0x100 && correg)
- return lget1(m, correg, locreg(regbyoff(addr)), a, n);
- else
- return get1(m, addr, a, n);
-}
-
-int
-xget2(Map *m, ulong addr, u16int *a)
-{
- if(addr < 0x100 && correg)
- return lget2(m, correg, locreg(regbyoff(addr)), a);
- else
- return get2(m, addr, a);
-}
-
-int
-xget4(Map *m, ulong addr, u32int *a)
-{
- if(addr < 0x100 && correg)
- return lget4(m, correg, locreg(regbyoff(addr)), a);
- else
- return get4(m, addr, a);
-}
-
-int
-xget8(Map *m, ulong addr, u64int *a)
-{
- if(addr < 0x100 && correg)
- return lget8(m, correg, locreg(regbyoff(addr)), a);
- else
- return get8(m, addr, a);
-}
-
void
indir(Map *m, ulong addr, char fmt, Node *r)
{
@@ -272,7 +222,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'C':
case 'b':
r->type = TINT;
- ret = xget1(m, addr, &cval, 1);
+ ret = get1(m, addr, &cval, 1);
if (ret < 0)
error("indir: %r");
r->store.u.ival = cval;
@@ -284,7 +234,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'q':
case 'r':
r->type = TINT;
- ret = xget2(m, addr, &sval);
+ ret = get2(m, addr, &sval);
if (ret < 0)
error("indir: %r");
r->store.u.ival = sval;
@@ -298,7 +248,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'O':
case 'Q':
r->type = TINT;
- ret = xget4(m, addr, &ival);
+ ret = get4(m, addr, &ival);
if (ret < 0)
error("indir: %r");
r->store.u.ival = ival;
@@ -308,7 +258,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'Y':
case 'Z':
r->type = TINT;
- ret = xget8(m, addr, &vval);
+ ret = get8(m, addr, &vval);
if (ret < 0)
error("indir: %r");
r->store.u.ival = vval;
@@ -316,7 +266,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 's':
r->type = TSTRING;
for(i = 0; i < sizeof(buf)-1; i++) {
- ret = xget1(m, addr, (uchar*)&buf[i], 1);
+ ret = get1(m, addr, (uchar*)&buf[i], 1);
if (ret < 0)
error("indir: %r");
addr++;
@@ -331,7 +281,7 @@ indir(Map *m, ulong addr, char fmt, Node *r)
case 'R':
r->type = TSTRING;
for(i = 0; i < sizeof(buf)-2; i += 2) {
- ret = xget1(m, addr, (uchar*)&buf[i], 2);
+ ret = get1(m, addr, (uchar*)&buf[i], 2);
if (ret < 0)
error("indir: %r");
addr += 2;
@@ -351,14 +301,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
r->store.u.string = strnode(buf);
break;
case 'f':
- ret = xget1(m, addr, (uchar*)buf, mach->szfloat);
+ ret = get1(m, addr, (uchar*)buf, mach->szfloat);
if (ret < 0)
error("indir: %r");
mach->ftoa32(buf, sizeof(buf), (void*) buf);
convflt(r, buf);
break;
case 'g':
- ret = xget1(m, addr, (uchar*)buf, mach->szfloat);
+ ret = get1(m, addr, (uchar*)buf, mach->szfloat);
if (ret < 0)
error("indir: %r");
mach->ftoa32(buf, sizeof(buf), (void*) buf);
@@ -366,14 +316,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
r->store.u.string = strnode(buf);
break;
case 'F':
- ret = xget1(m, addr, (uchar*)buf, mach->szdouble);
+ ret = get1(m, addr, (uchar*)buf, mach->szdouble);
if (ret < 0)
error("indir: %r");
mach->ftoa64(buf, sizeof(buf), (void*) buf);
convflt(r, buf);
break;
case '3': /* little endian ieee 80 with hole in bytes 8&9 */
- ret = xget1(m, addr, (uchar*)reg, 10);
+ ret = get1(m, addr, (uchar*)reg, 10);
if (ret < 0)
error("indir: %r");
memmove(reg+10, reg+8, 2); /* open hole */
@@ -382,14 +332,14 @@ indir(Map *m, ulong addr, char fmt, Node *r)
convflt(r, buf);
break;
case '8': /* big-endian ieee 80 */
- ret = xget1(m, addr, (uchar*)reg, 10);
+ ret = get1(m, addr, (uchar*)reg, 10);
if (ret < 0)
error("indir: %r");
beieeeftoa80(buf, sizeof(buf), reg);
convflt(r, buf);
break;
case 'G':
- ret = xget1(m, addr, (uchar*)buf, mach->szdouble);
+ ret = get1(m, addr, (uchar*)buf, mach->szdouble);
if (ret < 0)
error("indir: %r");
mach->ftoa64(buf, sizeof(buf), (void*) buf);
@@ -400,21 +350,70 @@ indir(Map *m, ulong addr, char fmt, Node *r)
}
void
-windir(Map *m, Node *addr, Node *rval, Node *r)
+indirreg(Regs *regs, char *name, char fmt, Node *r)
+{
+ ulong val;
+
+ if(regs == 0)
+ error("no register set for *%s=", name);
+
+ r->op = OCONST;
+ r->store.fmt = fmt;
+ switch(fmt){
+ default:
+ error("bad pointer format '%c' for *%s", fmt, name);
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'x':
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'q':
+ case 'r':
+ case 'a':
+ case 'A':
+ case 'B':
+ case 'X':
+ case 'D':
+ case 'U':
+ case 'O':
+ case 'Q':
+ case 'V':
+ case 'W':
+ case 'Y':
+ case 'Z':
+ if(rget(regs, name, &val) < 0)
+ error("reading %s: %r", name);
+ r->type = TINT;
+ r->store.u.ival = val;
+ break;
+ case 'f':
+ case 'g':
+ case 'F':
+ case '3':
+ case '8':
+ case 'G':
+ error("floating point registers not supported");
+ break;
+ }
+}
+
+void
+windir(Map *m, Node aes, Node *rval, Node *r)
{
uchar cval;
ushort sval;
- Node res, aes;
+ Node res;
int ret;
if(m == 0)
error("no map for */@=");
- expr(rval, &res);
- expr(addr, &aes);
-
if(aes.type != TINT)
- error("bad type lhs of @/*");
+ error("bad type lhs of */@=");
+
+ expr(rval, &res);
if(m != cormap && wtflag == 0)
error("not in write mode");
@@ -466,6 +465,58 @@ windir(Map *m, Node *addr, Node *rval, Node *r)
}
void
+windirreg(Regs *regs, char *name, Node *rval, Node *r)
+{
+ Node res;
+
+ if(regs == 0)
+ error("no register set for *%s=", name);
+
+ expr(rval, &res);
+
+ r->type = res.type;
+ r->store.fmt = res.store.fmt;
+ r->store = res.store;
+
+ switch(res.store.fmt){
+ default:
+ error("bad format '%c' for *%s=", res.store.fmt, name);
+ case 'c':
+ case 'C':
+ case 'b':
+ case 'x':
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'q':
+ case 'r':
+ case 'a':
+ case 'A':
+ case 'B':
+ case 'X':
+ case 'D':
+ case 'U':
+ case 'O':
+ case 'Q':
+ case 'V':
+ case 'W':
+ case 'Y':
+ case 'Z':
+ if(rput(regs, name, res.store.u.ival) < 0)
+ error("writing %s: %r", name);
+ break;
+ case 'f':
+ case 'g':
+ case 'F':
+ case '3':
+ case '8':
+ case 'G':
+ error("floating point registers not supported");
+ break;
+ }
+}
+
+void
call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp)
{
int np, i;