Преглед изворни кода

fix return for big aggregates

The recent changes in arm and riscv
typclass() set ngp to 1 when a struct
is returned via a caller-provided
buffer.  This interacts bogusly with
selret() that ends up declaring a gp
register live when none is set in
the returning sequence.

The fix is simply to set cty to zero
(all registers dead) in case a caller-
provided buffer is used.
Quentin Carbonneaux пре 3 година
родитељ
комит
bf2a90ef7c
2 измењених фајлова са 6 додато и 3 уклоњено
  1. 4 2
      arm64/abi.c
  2. 2 1
      rv64/abi.c

+ 4 - 2
arm64/abi.c

@@ -183,12 +183,14 @@ selret(Blk *b, Fn *fn)
 
 	if (j == Jretc) {
 		typclass(&cr, &typ[fn->retty], gpreg, fpreg);
-		cty = (cr.nfp << 2) | cr.ngp;
 		if (cr.class & Cptr) {
 			assert(rtype(fn->retr) == RTmp);
 			blit0(fn->retr, r, cr.t->size, fn);
-		} else
+			cty = 0;
+		} else {
 			ldregs(cr.reg, cr.cls, cr.nreg, r, fn);
+			cty = (cr.nfp << 2) | cr.ngp;
+		}
 	} else {
 		k = j - Jretw;
 		if (KBASE(k) == 0) {

+ 2 - 1
rv64/abi.c

@@ -220,12 +220,13 @@ selret(Blk *b, Fn *fn)
 
 	if (j == Jretc) {
 		typclass(&cr, &typ[fn->retty], 1, gpreg, fpreg);
-		cty = (cr.nfp << 2) | cr.ngp;
 		if (cr.class & Cptr) {
 			assert(rtype(fn->retr) == RTmp);
 			blit0(fn->retr, r, cr.type->size, fn);
+			cty = 0;
 		} else {
 			ldregs(&cr, r, fn);
+			cty = (cr.nfp << 2) | cr.ngp;
 		}
 	} else {
 		k = j - Jretw;