summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--amd64/sysv.c10
-rw-r--r--arm64/abi.c1
2 files changed, 9 insertions, 2 deletions
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 2e3e4a8..7dc5981 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -4,6 +4,7 @@ typedef struct AClass AClass;
 typedef struct RAlloc RAlloc;
 
 struct AClass {
+	Typ *type;
 	int inmem;
 	int align;
 	uint size;
@@ -72,6 +73,7 @@ typclass(AClass *a, Typ *t)
 		al = 8;
 	sz = (sz + al-1) & -al;
 
+	a->type = t;
 	a->size = sz;
 	a->align = t->align;
 
@@ -125,7 +127,7 @@ selret(Blk *b, Fn *fn)
 		if (aret.inmem) {
 			assert(rtype(fn->retr) == RTmp);
 			emit(Ocopy, Kl, TMP(RAX), fn->retr, R);
-			blit(fn->retr, 0, r0, aret.size, fn);
+			blit(fn->retr, 0, r0, aret.type->size, fn);
 			ca = 1;
 		} else {
 			ca = retr(reg, &aret);
@@ -338,6 +340,10 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 			emit(Ocopy, Kl, i1->to, TMP(RAX), R);
 			ca += 1;
 		} else {
+			/* todo, may read out of bounds.
+			 * gcc did this up until 5.2, but
+			 * this should still be fixed.
+			 */
 			if (aret.size > 8) {
 				r = newtmp("abi", Kl, fn);
 				aret.ref[1] = newtmp("abi", aret.cls[1], fn);
@@ -407,7 +413,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 		if (i->op == Oargc) {
 			if (a->align == 4)
 				off += off & 15;
-			blit(r, off, i->arg[1], a->size, fn);
+			blit(r, off, i->arg[1], a->type->size, fn);
 		} else {
 			r1 = newtmp("abi", Kl, fn);
 			emit(Ostorel, 0, R, i->arg[0], r1);
diff --git a/arm64/abi.c b/arm64/abi.c
index f37c892..db794f6 100644
--- a/arm64/abi.c
+++ b/arm64/abi.c
@@ -144,6 +144,7 @@ sttmps(Ref tmp[], int cls[], uint nreg, Ref mem, Fn *fn)
 	}
 }
 
+/* todo, may read out of bounds */
 static void
 ldregs(int reg[], int cls[], int n, Ref mem, Fn *fn)
 {