summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-20 13:04:07 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-30 13:20:42 -0400
commitb284721c8acae244d054dbe8c8b5878f0e649c0a (patch)
tree304446e2680f1b43dd76832fa64d15a25136f631
parent993416481a5d5c89410488fbab311ee0b943f948 (diff)
downloadroux-b284721c8acae244d054dbe8c8b5878f0e649c0a.tar.gz
emit code for extensions, move slots into RAlt
-rw-r--r--lisc/emit.c31
-rw-r--r--lisc/isel.c3
-rw-r--r--lisc/lisc.h35
-rw-r--r--lisc/parse.c20
-rw-r--r--lisc/rega.c2
-rw-r--r--lisc/test/collatz.ssa6
6 files changed, 67 insertions, 30 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 9500dc9..b8365c2 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -37,9 +37,10 @@ emitf(Fn *fn, FILE *f, char *fmt, ...)
static char stoa[] = "qlwb";
va_list ap;
char c, *s, *s1;
- int i, ty;
+ int i, ty, off;
Ref ref;
Con *con;
+ struct { int i:AShift; } x;
va_start(ap, fmt);
ty = SWord;
@@ -81,10 +82,9 @@ Next:
assert(isreg(ref));
fprintf(f, "%%%s", rsub[ref.val][ty]);
break;
- case RSlot:
- Slot: {
- int off;
- struct { int i:14; } x = {ref.val}; /* fixme */
+ case RASlot:
+ Slot:
+ x.i = ref.val & AMask;
assert(NAlign == 3);
if (x.i < 0)
off = -4 * x.i;
@@ -94,7 +94,6 @@ Next:
}
fprintf(f, "%d(%%rbp)", off);
break;
- }
case RCon:
fputc('$', f);
Con:
@@ -117,9 +116,9 @@ Next:
case 'M':
ref = va_arg(ap, Ref);
switch (rtype(ref)) {
- default: diag("emit: invalid memory reference");
- case RSlot: goto Slot;
- case RCon: goto Con;
+ default: diag("emit: invalid memory reference");
+ case RASlot: goto Slot;
+ case RCon: goto Con;
case RTmp:
assert(isreg(ref));
fprintf(f, "(%%%s)", rsub[ref.val][SLong]);
@@ -234,6 +233,20 @@ eins(Ins i, Fn *fn, FILE *f)
emitf(fn, f, "%s%w %M, %R", otoa[i.op],
i.wide, i.arg[0], i.to);
break;
+ case OExt+Tuw:
+ emitf(fn, f, "movl %R, %R", i.arg[0], i.to);
+ break;
+ case OExt+Tsw:
+ case OExt+Tsh:
+ case OExt+Tuh:
+ case OExt+Tsb:
+ case OExt+Tub:
+ emitf(fn, f, "mov%s%t%s %R, %W%R",
+ (i.op-OExt-Tsw)%2 ? "z" : "s",
+ 1+(i.op-OExt-Tsw)/2,
+ i.wide ? "q" : "l",
+ i.arg[0], i.wide, i.to);
+ break;
case OCall:
switch (rtype(i.arg[0])) {
default:
diff --git a/lisc/isel.c b/lisc/isel.c
index c3da2cf..6114bdb 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -373,7 +373,8 @@ classify(Ins *i0, Ins *i1, AClass *ac, int op)
a->size = 8;
a->rty[0] = RInt;
} else {
- aclass(a, &typ[i->arg[0].val]);
+ n = i->arg[0].val & AMask;
+ aclass(a, &typ[n]);
if (a->inmem)
continue;
ni = ns = 0;
diff --git a/lisc/lisc.h b/lisc/lisc.h
index d2f6ef2..a9a53fd 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -75,12 +75,24 @@ struct Ref {
uint16_t val:14;
};
+enum Alt {
+ AType,
+ ACall,
+ ASlot,
+
+ AShift = 12,
+ AMask = (1<<AShift) - 1
+};
+
enum {
RTmp,
RCon,
- RSlot,
RAlt,
- RCallm = 0x1000,
+
+ RAType = RAlt + AType,
+ RACall = RAlt + ACall,
+ RASlot = RAlt + ASlot,
+
NRef = (1<<14) - 1
};
@@ -88,14 +100,21 @@ enum {
#define TMP(x) (Ref){RTmp, x}
#define CON(x) (Ref){RCon, x}
#define CON_Z CON(0) /* reserved zero constant */
-#define SLOT(x) (Ref){RSlot, x}
-#define TYP(x) (Ref){RAlt, x}
-#define CALL(x) (Ref){RAlt, (x)|RCallm}
+#define TYPE(x) (Ref){RAlt, (x)|(AType<<AShift)}
+#define CALL(x) (Ref){RAlt, (x)|(ACall<<AShift)}
+#define SLOT(x) (assert(x<(1<<(AShift-1)) && "too many slots"), \
+ (Ref){RAlt, (x)|(ASlot<<AShift)})
static inline int req(Ref a, Ref b)
{ return a.type == b.type && a.val == b.val; }
static inline int rtype(Ref r)
-{ return req(r, R) ? -1 : r.type; }
+{
+ if (req(r, R))
+ return -1;
+ if (r.type == RAlt)
+ return RAlt + (r.val >> AShift);
+ return r.type;
+}
static inline int isreg(Ref r)
{ return rtype(r) == RTmp && r.val < Tmp0; }
@@ -147,6 +166,10 @@ enum Op {
OCall,
/* reserved instructions */
+ OScale1, /* for memory addressing */
+ OScale2,
+ OScale3,
+ OScale4,
ONop,
OAddr,
OSwap,
diff --git a/lisc/parse.c b/lisc/parse.c
index a4cc484..feb11a0 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -388,9 +388,9 @@ parserefl(int arg)
err("invalid function parameter");
if (w == 2)
if (arg)
- *curi = (Ins){OArgc, 0, R, {TYP(ty), r}};
+ *curi = (Ins){OArgc, 0, R, {TYPE(ty), r}};
else
- *curi = (Ins){OParc, 0, r, {TYP(ty)}};
+ *curi = (Ins){OParc, 0, r, {TYPE(ty)}};
else
if (arg)
*curi = (Ins){OArg, w, R, {r}};
@@ -526,7 +526,7 @@ DoOp:
op = OCall;
if (w == 2) {
w = 0;
- arg[1] = TYP(ty);
+ arg[1] = TYPE(ty);
} else
arg[1] = R;
goto Ins;
@@ -818,14 +818,14 @@ printref(Ref r, Fn *fn, FILE *f)
diag("printref: invalid constant");
}
break;
- case RSlot:
- fprintf(f, "S%d", r.val);
+ case RASlot:
+ fprintf(f, "S%d", r.val & AMask);
break;
- case RAlt:
- if (r.val & RCallm)
- fprintf(f, "%x", r.val & (RCallm-1));
- else
- fprintf(f, ":%s", typ[r.val].name);
+ case RACall:
+ fprintf(f, "%x", r.val & AMask);
+ break;
+ case RAType:
+ fprintf(f, ":%s", typ[r.val & AMask].name);
break;
}
}
diff --git a/lisc/rega.c b/lisc/rega.c
index b0db117..2f6d613 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -398,7 +398,7 @@ rega(Fn *fn)
npm = 0;
for (p=s->phi; p; p=p->link) {
dst = p->to;
- assert(rtype(dst)==RSlot|| rtype(dst)==RTmp);
+ assert(rtype(dst)==RASlot || rtype(dst)==RTmp);
if (rtype(dst) == RTmp) {
r = rfind(&beg[s->id], dst.val);
if (r == -1)
diff --git a/lisc/test/collatz.ssa b/lisc/test/collatz.ssa
index 8bc80cb..0c79a05 100644
--- a/lisc/test/collatz.ssa
+++ b/lisc/test/collatz.ssa
@@ -31,14 +31,14 @@ function $test() {
%n3 =w div %n0, 2
jmp @cloop
@getmemo # get the count for n0 in mem
- %n0l =l sext %n0
+ %n0l =l extsw %n0
%idx0 =l mul %n0l, 4
%loc0 =l add %idx0, %mem
- %cn0 =w load %loc0
+ %cn0 =w loadw %loc0
%c2 =w add %c0, %cn0
@endcl # store the count for n in mem
%c =w phi @getmemo %c2, @cloop %c0
- %nl =l sext %n
+ %nl =l extsw %n
%idx1 =l mul %nl, 4
%loc1 =l add %idx1, %mem
storew %c, %loc1