Преглед на файлове

add new target-specific abi0 pass

The general idea is to give abis a
chance to talk before we've done all
the optimizations. Currently, all
targets eliminate {par,arg,ret}{sb,ub,...}
during this pass. The forthcoming
arm64_apple will, however, insert
proper extensions during abi0.

Moving forward abis can, for example,
lower small-aggregates passing there
so that memory optimizations can
interact better with function calls.
Quentin Carbonneaux преди 3 години
родител
ревизия
a9a70e30a8
променени са 7 файла, в които са добавени 43 реда и са изтрити 7 реда
  1. 2 2
      Makefile
  2. 25 0
      abi.c
  3. 8 1
      all.h
  4. 2 1
      amd64/targ.c
  5. 2 1
      arm64/targ.c
  6. 2 1
      main.c
  7. 2 1
      rv64/targ.c

+ 2 - 2
Makefile

@@ -4,8 +4,8 @@
 PREFIX = /usr/local
 BINDIR = $(PREFIX)/bin
 
-COMMOBJ  = main.o util.o parse.o cfg.o mem.o ssa.o alias.o load.o copy.o \
-           fold.o live.o spill.o rega.o emit.o
+COMMOBJ  = main.o util.o parse.o abi.o cfg.o mem.o ssa.o alias.o load.o \
+           copy.o fold.o live.o spill.o rega.o emit.o
 AMD64OBJ = amd64/targ.o amd64/sysv.o amd64/isel.o amd64/emit.o
 ARM64OBJ = arm64/targ.o arm64/abi.o arm64/isel.o arm64/emit.o
 RV64OBJ  = rv64/targ.o rv64/abi.o rv64/isel.o rv64/emit.o

+ 25 - 0
abi.c

@@ -0,0 +1,25 @@
+#include "all.h"
+
+/* eliminate sub-word abi op
+ * variants for targets that
+ * treat char/short/... as
+ * words with arbitrary high
+ * bits
+ */
+void
+elimsb(Fn *fn)
+{
+	Blk *b;
+	Ins *i;
+
+	for (b=fn->start; b; b=b->link) {
+		for (i=b->ins; i<&b->ins[b->nins]; i++) {
+			if (isargbh(i->op))
+				i->op = Oarg;
+			if (isparbh(i->op))
+				i->op = Opar;
+		}
+		if (isretbh(b->jmp.type))
+			b->jmp.type = Jretw;
+	}
+}

+ 8 - 1
all.h

@@ -52,7 +52,8 @@ struct Target {
 	bits (*retregs)(Ref, int[2]);
 	bits (*argregs)(Ref, int[2]);
 	int (*memargs)(int);
-	void (*abi)(Fn *);
+	void (*abi0)(Fn *);
+	void (*abi1)(Fn *);
 	void (*isel)(Fn *);
 	void (*emitfn)(Fn *, FILE *);
 	void (*emitfin)(FILE *);
@@ -183,6 +184,9 @@ enum {
 #define ispar(o) INRANGE(o, Opar, Opare)
 #define isarg(o) INRANGE(o, Oarg, Oargv)
 #define isret(j) INRANGE(j, Jretw, Jret0)
+#define isparbh(o) INRANGE(o, Oparsb, Oparuh)
+#define isargbh(o) INRANGE(o, Oargsb, Oarguh)
+#define isretbh(j) INRANGE(j, Jretsb, Jretuh)
 
 enum {
 	Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
@@ -478,6 +482,9 @@ void printfn(Fn *, FILE *);
 void printref(Ref, Fn *, FILE *);
 void err(char *, ...) __attribute__((noreturn));
 
+/* abi.c */
+void elimsb(Fn *);
+
 /* cfg.c */
 Blk *blknew(void);
 void edgedel(Blk *, Blk **);

+ 2 - 1
amd64/targ.c

@@ -24,7 +24,8 @@ amd64_memargs(int op)
 	.retregs = amd64_sysv_retregs, \
 	.argregs = amd64_sysv_argregs, \
 	.memargs = amd64_memargs, \
-	.abi = amd64_sysv_abi, \
+	.abi0 = elimsb, \
+	.abi1 = amd64_sysv_abi, \
 	.isel = amd64_isel, \
 
 Target T_amd64_sysv = {

+ 2 - 1
arm64/targ.c

@@ -38,7 +38,8 @@ Target T_arm64 = {
 	.retregs = arm64_retregs,
 	.argregs = arm64_argregs,
 	.memargs = arm64_memargs,
-	.abi = arm64_abi,
+	.abi0 = elimsb,
+	.abi1 = arm64_abi,
 	.isel = arm64_isel,
 	.emitfn = arm64_emitfn,
 	.emitfin = elf_emitfin,

+ 2 - 1
main.c

@@ -56,6 +56,7 @@ func(Fn *fn)
 		fprintf(stderr, "\n> After parsing:\n");
 		printfn(fn, stderr);
 	}
+	T.abi0(fn);
 	fillrpo(fn);
 	fillpreds(fn);
 	filluse(fn);
@@ -71,7 +72,7 @@ func(Fn *fn)
 	copy(fn);
 	filluse(fn);
 	fold(fn);
-	T.abi(fn);
+	T.abi1(fn);
 	fillpreds(fn);
 	filluse(fn);
 	T.isel(fn);

+ 2 - 1
rv64/targ.c

@@ -44,7 +44,8 @@ Target T_rv64 = {
 	.retregs = rv64_retregs,
 	.argregs = rv64_argregs,
 	.memargs = rv64_memargs,
-	.abi = rv64_abi,
+	.abi0 = elimsb,
+	.abi1 = rv64_abi,
 	.isel = rv64_isel,
 	.emitfn = rv64_emitfn,
 	.emitfin = elf_emitfin,