summary refs log tree commit diff
path: root/arm64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-03-14 23:10:39 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2022-03-14 23:14:48 +0100
commitc5769f62b4912e429a332c9aa0bead3a383fe966 (patch)
tree4a10efe9455184ce71bd7e4a8a7429c327ba66e8 /arm64
parent329a18a30b9f8db598db39b7326fc4149bcc1431 (diff)
downloadroux-c5769f62b4912e429a332c9aa0bead3a383fe966.tar.gz
dynamic stack allocs for arm64
I also moved some isel logic
that would have been repeated
a third time in util.c.
Diffstat (limited to 'arm64')
-rw-r--r--arm64/emit.c9
-rw-r--r--arm64/isel.c10
2 files changed, 17 insertions, 2 deletions
diff --git a/arm64/emit.c b/arm64/emit.c
index b25f4f5..47097b7 100644
--- a/arm64/emit.c
+++ b/arm64/emit.c
@@ -385,6 +385,11 @@ emitins(Ins *i, E *e)
 				rn, s & 0xFFFF, rn, s >> 16, rn, rn
 			);
 		break;
+	case Osalloc:
+		emitf("sub sp, sp, %0", i, e);
+		if (!req(i->to, R))
+			emitf("mov %=, sp", i, e);
+		break;
 	}
 }
 
@@ -483,7 +488,7 @@ arm64_emitfn(Fn *fn, FILE *out)
 			"\tstp\tx29, x30, [sp, -16]!\n",
 			e->frame & 0xFFFF, e->frame >> 16
 		);
-	fputs("\tadd\tx29, sp, 0\n", e->f);
+	fputs("\tmov\tx29, sp\n", e->f);
 	s = (e->frame - e->padding) / 4;
 	for (r=arm64_rclob; *r>=0; r++)
 		if (e->fn->reg & BIT(*r)) {
@@ -509,6 +514,8 @@ arm64_emitfn(Fn *fn, FILE *out)
 					i->cls = *r >= V0 ? Kd : Kl;
 					emitins(i, e);
 				}
+			if (e->fn->dynalloc)
+				fputs("\tmov sp, x29\n", e->f);
 			o = e->frame + 16;
 			if (e->fn->vararg)
 				o += 192;
diff --git a/arm64/isel.c b/arm64/isel.c
index 031ba11..bb5c12b 100644
--- a/arm64/isel.c
+++ b/arm64/isel.c
@@ -163,6 +163,12 @@ sel(Ins i, Fn *fn)
 	Ins *i0;
 	int ck, cc;
 
+	if (INRANGE(i.op, Oalloc, Oalloc1)) {
+		i0 = curi - 1;
+		salloc(i.to, i.arg[0], fn);
+		fixarg(&i0->arg[0], Kl, 0, fn);
+		return;
+	}
 	if (iscmp(i.op, &ck, &cc)) {
 		emit(Oflag, i.cls, i.to, R, R);
 		i0 = curi;
@@ -170,7 +176,9 @@ sel(Ins i, Fn *fn)
 			i0->op += cmpop(cc);
 		else
 			i0->op += cc;
-	} else if (i.op != Onop) {
+		return;
+	}
+	if (i.op != Onop) {
 		emiti(i);
 		iarg = curi->arg; /* fixarg() can change curi */
 		fixarg(&iarg[0], argcls(&i, 0), 0, fn);