summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--alias.c30
-rw-r--r--all.h12
-rw-r--r--load.c4
3 files changed, 38 insertions, 8 deletions
diff --git a/alias.c b/alias.c
index 44686dd..fd11bd2 100644
--- a/alias.c
+++ b/alias.c
@@ -18,8 +18,8 @@ getalias(Alias *a, Ref r, Fn *fn)
 		c = &fn->con[r.val];
 		if (c->type == CAddr) {
 			a->type = ASym;
-			a->label = c->label;
-			a->reloc = c->reloc;
+			a->u.sym.label = c->label;
+			a->u.sym.con = r.val;
 		} else
 			a->type = ACon;
 		a->offset = c->bits.i;
@@ -52,7 +52,7 @@ alias(Ref p, int sp, Ref q, int sq, int *delta, Fn *fn)
 		/* they conservatively alias if the
 		 * symbols are different, or they
 		 * alias for sure if they overlap */
-		if (ap.label != aq.label)
+		if (ap.u.sym.label != aq.u.sym.label)
 			return MayAlias;
 		if (ovlap)
 			return MustAlias;
@@ -108,9 +108,12 @@ void
 fillalias(Fn *fn)
 {
 	uint n, m;
+	int64_t x;
+	bits w;
 	Blk *b;
 	Phi *p;
 	Ins *i;
+	Con *c;
 	Alias *a, a0, a1;
 
 	for (n=0; n<fn->nblk; ++n) {
@@ -135,6 +138,14 @@ fillalias(Fn *fn)
 				if (Oalloc <= i->op && i->op <= Oalloc1) {
 					a->type = ALoc;
 					a->slot = a;
+					a->u.loc.sz = -1;
+					if (rtype(i->arg[0]) == RCon) {
+						c = &fn->con[i->arg[0].val];
+						x = c->bits.i;
+						if (c->type == CBits)
+						if (0 <= x && x <= NBit)
+							a->u.loc.sz = x;
+					}
 				} else {
 					a->type = AUnk;
 					a->slot = 0;
@@ -165,6 +176,19 @@ fillalias(Fn *fn)
 				if (i->op != Oargc)
 					esc(i->arg[1], fn);
 			}
+			if (isstore(i->op))
+			if (rtype(i->arg[1]) == RTmp) {
+				a = &fn->tmp[i->arg[1].val].alias;
+				if (a->slot) {
+					assert(astack(a->type));
+					x = a->offset;
+					if (0 <= x && x < NBit) {
+						w = BIT(storesz(i)) - 1;
+						a->slot->u.loc.m |= w << x;
+					} else
+						a->slot->u.loc.sz = -1;
+				}
+			}
 		}
 		esc(b->jmp.arg, fn);
 	}
diff --git a/all.h b/all.h
index 4c3c35f..43cdd62 100644
--- a/all.h
+++ b/all.h
@@ -281,9 +281,17 @@ struct Alias {
 	#define astack(t) ((t) & 1)
 	} type;
 	int base;
-	uint32_t label;
 	int64_t offset;
-	int reloc;
+	union {
+		struct {
+			uint32_t label;
+			int con;
+		} sym;
+		struct {
+			int sz; /* -1 if > NBit */
+			bits m;
+		} loc;
+	} u;
 	Alias *slot;
 };
 
diff --git a/load.c b/load.c
index 01718c0..0d7944c 100644
--- a/load.c
+++ b/load.c
@@ -152,10 +152,8 @@ load(Slice sl, bits msk, Loc *l)
 			break;
 		case ACon:
 		case ASym:
-			c.type = CAddr;
-			c.label = a->label;
+			c = curf->con[a->u.sym.con];
 			c.bits.i = a->offset;
-			c.reloc = a->reloc;
 			r = newcon(&c, curf);
 			break;
 		}