summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--all.h3
-rw-r--r--amd64/sysv.c4
-rw-r--r--arm64/abi.c10
-rw-r--r--doc/rv64.txt2
-rw-r--r--live.c2
-rw-r--r--rv64/abi.c6
-rw-r--r--util.c12
7 files changed, 25 insertions, 14 deletions
diff --git a/all.h b/all.h
index c19b4ae..a62b19b 100644
--- a/all.h
+++ b/all.h
@@ -441,7 +441,8 @@ void chuse(Ref, int, Fn *);
 Ref newcon(Con *, Fn *);
 Ref getcon(int64_t, Fn *);
 int addcon(Con *, Con *);
-void blit(Ref, uint, Ref, uint, Fn *);
+void blit(Ref, uint, Ref, uint, uint, Fn *);
+void blit0(Ref, Ref, uint, Fn *);
 void dumpts(BSet *, Tmp *, FILE *);
 
 void bsinit(BSet *, uint);
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 7dc5981..7287f41 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -127,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.type->size, fn);
+			blit0(fn->retr, r0, aret.type->size, fn);
 			ca = 1;
 		} else {
 			ca = retr(reg, &aret);
@@ -413,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->type->size, fn);
+			blit(r, off, i->arg[1], 0, 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 18e8ef3..f127576 100644
--- a/arm64/abi.c
+++ b/arm64/abi.c
@@ -181,7 +181,7 @@ selret(Blk *b, Fn *fn)
 		cty = (cr.nfp << 2) | cr.ngp;
 		if (cr.class & Cptr) {
 			assert(rtype(fn->retr) == RTmp);
-			blit(fn->retr, 0, r, cr.t->size, fn);
+			blit0(fn->retr, r, cr.t->size, fn);
 		} else
 			ldregs(cr.reg, cr.cls, cr.nreg, r, fn);
 	} else {
@@ -359,6 +359,10 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 		stkblob(i1->to, &cr, fn, ilp);
 		cty |= (cr.nfp << 2) | cr.ngp;
 		if (cr.class & Cptr) {
+			/* spill & rega expect calls to be
+			 * followed by copies from regs,
+			 * so we emit a dummy
+			 */
 			cty |= 1 << 13 | 1;
 			emit(Ocopy, Kw, R, TMP(R0), R);
 		} else {
@@ -407,7 +411,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 			emit(Oadd, Kl, r, TMP(SP), getcon(off, fn));
 		}
 		if (i->op == Oargc)
-			blit(TMP(SP), off, i->arg[1], c->size, fn);
+			blit(TMP(SP), off, i->arg[1], 0, c->size, fn);
 		off += c->size;
 	}
 	if (stk)
@@ -415,7 +419,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 
 	for (i=i0, c=ca; i<i1; i++, c++)
 		if (c->class & Cptr)
-			blit(i->arg[0], 0, i->arg[1], c->t->size, fn);
+			blit0(i->arg[0], i->arg[1], c->t->size, fn);
 }
 
 static Params
diff --git a/doc/rv64.txt b/doc/rv64.txt
index e696d77..17f6072 100644
--- a/doc/rv64.txt
+++ b/doc/rv64.txt
@@ -17,4 +17,4 @@ rv64_isel() could turn compare used only with jnz into b{lt,ge}[u].
 
 RISC-V spec: https://github.com/riscv/riscv-isa-manual/releases/latest/download/riscv-spec.pdf
 ASM manual: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md
-psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
+ABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
diff --git a/live.c b/live.c
index 4198995..a1b4219 100644
--- a/live.c
+++ b/live.c
@@ -103,7 +103,7 @@ Again:
 			if (!req(i->to, R)) {
 				assert(rtype(i->to) == RTmp);
 				t = i->to.val;
-				if (bshas(b->in, i->to.val))
+				if (bshas(b->in, t))
 					nlv[KBASE(f->tmp[t].cls)]--;
 				bsset(b->gen, t);
 				bsclr(b->in, t);
diff --git a/rv64/abi.c b/rv64/abi.c
index ece7a6e..05deabe 100644
--- a/rv64/abi.c
+++ b/rv64/abi.c
@@ -185,7 +185,7 @@ selret(Blk *b, Fn *fn)
 		cty = (cr.nfp << 2) | cr.ngp;
 		if (cr.class & Cptr) {
 			assert(rtype(fn->retr) == RTmp);
-			blit(fn->retr, 0, r, cr.t->size, fn);
+			blit0(fn->retr, r, cr.t->size, fn);
 		} else {
 			ldregs(cr.reg, cr.cls, cr.nreg, r, fn);
 		}
@@ -383,7 +383,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 			emit(Ocast, k, TMP(*c->reg), i->arg[0], R);
 		}
 		if (c->class & Cptr)
-			blit(i->arg[0], 0, i->arg[1], c->t->size, fn);
+			blit0(i->arg[0], i->arg[1], c->t->size, fn);
 	}
 
 	if (!stk)
@@ -419,7 +419,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, Insl **ilp)
 			}
 			emit(Oadd, Kl, r1, r, getcon(off, fn));
 		} else
-			blit(r, off, i->arg[1], c->t->size, fn);
+			blit(r, off, i->arg[1], 0, c->t->size, fn);
 		off += c->size;
 	}
 	emit(Osalloc, Kl, r, getcon(stk, fn), R);
diff --git a/util.c b/util.c
index c8b0b9c..5296b86 100644
--- a/util.c
+++ b/util.c
@@ -399,7 +399,7 @@ addcon(Con *c0, Con *c1)
 }
 
 void
-blit(Ref rdst, uint doff, Ref rsrc, uint sz, Fn *fn)
+blit(Ref rdst, uint doff, Ref rsrc, uint boff, uint sz, Fn *fn)
 {
 	struct { int st, ld, cls, size; } *p, tbl[] = {
 		{ Ostorel, Oload,   Kl, 8 },
@@ -408,9 +408,9 @@ blit(Ref rdst, uint doff, Ref rsrc, uint sz, Fn *fn)
 		{ Ostoreb, Oloadub, Kw, 1 }
 	};
 	Ref r, r1;
-	uint boff, s;
+	uint s;
 
-	for (boff=0, p=tbl; sz; p++)
+	for (p=tbl; sz; p++)
 		for (s=p->size; sz>=s; sz-=s, doff+=s, boff+=s) {
 			r = newtmp("blt", Kl, fn);
 			r1 = newtmp("blt", Kl, fn);
@@ -423,6 +423,12 @@ blit(Ref rdst, uint doff, Ref rsrc, uint sz, Fn *fn)
 }
 
 void
+blit0(Ref rdst, Ref rsrc, uint sz, Fn *fn)
+{
+	blit(rdst, 0, rsrc, 0, sz, fn);
+}
+
+void
 bsinit(BSet *bs, uint n)
 {
 	n = (n + NBit-1) / NBit;