Commit: a56c9b65a80fbadb3a8e9e6676581da4c9a3e9d9
Parent: 9c18e4ff933fec19ee048caf6aa6d7b297da350d
Author: Randy Palamar
Date:   Thu,  9 Nov 2023 22:15:53 -0700
add qbe from oasis bumped to latest
Diffstat:
8 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -17,6 +17,10 @@
 	path = pkg/devel/git/src
 	url = https://github.com/git/git.git
 	ignore = all
+[submodule "pkg/devel/qbe/src"]
+	path = pkg/devel/qbe/src
+	url = git://c9x.me/qbe.git
+	ignore = all
 [submodule "pkg/devel/samurai/src"]
 	path = pkg/devel/samurai/src
 	url = https://github.com/michaelforney/samurai.git
diff --git a/pkg/devel/gen.lua b/pkg/devel/gen.lua
@@ -2,6 +2,7 @@ subgen('fspec-sync')
 subgen('git')
 subgen('linux-headers')
 subgen('man-pages-posix')
+subgen('qbe')
 subgen('samurai')
 subgen('strace')
 subgen('the_silver_searcher')
diff --git a/pkg/devel/qbe/config.h b/pkg/devel/qbe/config.h
@@ -0,0 +1,2 @@
+#define Defasm Gaself
+#define Deftgt T_amd64_sysv
diff --git a/pkg/devel/qbe/gen.lua b/pkg/devel/qbe/gen.lua
@@ -0,0 +1,16 @@
+cflags({
+	'-std=c99', '-Wall', '-Wextra', '-Wpedantic',
+	'-Wno-format-overflow', '-Wno-format-truncation', '-Wno-maybe-uninitialized',
+	'-I $dir',
+})
+
+exe('qbe', [[
+        abi.c alias.c cfg.c copy.c emit.c fold.c live.c load.c
+        main.c mem.c parse.c rega.c simpl.c spill.c ssa.c util.c
+	amd64/(targ.c sysv.c isel.c emit.c)
+	arm64/(targ.c abi.c isel.c emit.c)
+	rv64/(targ.c abi.c isel.c emit.c)
+]])
+file('bin/qbe', '755', '$outdir/qbe')
+
+fetch('git')
diff --git a/pkg/devel/qbe/patch/0001-amd64-optimize-loading-0-into-registers.patch b/pkg/devel/qbe/patch/0001-amd64-optimize-loading-0-into-registers.patch
@@ -0,0 +1,83 @@
+From 60bd04e4ff652b29139f0670aeb4401c50035e19 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=89rico=20Nogueira?= <erico.erc@gmail.com>
+Date: Sun, 11 Jul 2021 19:19:12 -0300
+Subject: [PATCH] amd64: optimize loading 0 into registers
+
+Loading +0 into a floating point register can be done using pxor or
+xorps instructions. Per [1], we went with pxor because it can run on all
+vector ALU ports, even if it's one byte longer.
+
+Similarly, an integer register can be zeroed with xor, which has a
+smaller encoding than mov with 0 immediate.
+
+To implement this, we special case fixarg to allow Ocopy when the
+value is +0 for floating point, and change emitins to emit pxor/xor
+when it encounters a copy from 0.
+
+Co-authored-by: Michael Forney <mforney@mforney.org>
+
+[1] https://stackoverflow.com/questions/39811577/does-using-mix-of-pxor-and-xorps-affect-performance/39828976
+---
+ amd64/emit.c | 12 ++++++++++++
+ amd64/isel.c | 12 +++++++-----
+ 2 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/amd64/emit.c b/amd64/emit.c
+index 297cc76..0f0437c 100644
+--- a/amd64/emit.c
++++ b/amd64/emit.c
+@@ -458,6 +458,18 @@ emitins(Ins i, Fn *fn, FILE *f)
+ 		if (req(i.to, i.arg[0]))
+ 			break;
+ 		t0 = rtype(i.arg[0]);
++		if (t0 == RCon
++		&& fn->con[i.arg[0].val].type == CBits
++		&& fn->con[i.arg[0].val].bits.i == 0) {
++			if (isreg(i.to)) {
++				if (KBASE(i.cls) == 0)
++					emitf("xor%k %=, %=", &i, fn, f);
++				else
++					emitf("pxor %D=, %D=", &i, fn, f);
++				break;
++			}
++			i.cls = KWIDE(i.cls) ? Kl : Kw;
++		}
+ 		if (i.cls == Kl
+ 		&& t0 == RCon
+ 		&& fn->con[i.arg[0].val].type == CBits) {
+diff --git a/amd64/isel.c b/amd64/isel.c
+index e29c8bf..4bec2e1 100644
+--- a/amd64/isel.c
++++ b/amd64/isel.c
+@@ -85,7 +85,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
+ 	r1 = r0 = *r;
+ 	s = rslot(r0, fn);
+ 	op = i ? i->op : Ocopy;
+-	if (KBASE(k) == 1 && rtype(r0) == RCon) {
++	if (KBASE(k) == 1 && rtype(r0) == RCon && fn->con[r0.val].bits.i != 0) {
+ 		/* load floating points from memory
+ 		 * slots, they can't be used as
+ 		 * immediates
+@@ -99,13 +99,15 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
+ 		a.offset.sym.id = intern(buf);
+ 		fn->mem[fn->nmem-1] = a;
+ 	}
+-	else if (op != Ocopy && k == Kl && noimm(r0, fn)) {
++	else if (op != Ocopy && ((k == Kl && noimm(r0, fn)) || (KBASE(k) == 1 && rtype(r0) == RCon))) {
+ 		/* load constants that do not fit in
+ 		 * a 32bit signed integer into a
+-		 * long temporary
++		 * long temporary OR
++		 * load positive zero into a floating
++		 * point register
+ 		 */
+-		r1 = newtmp("isel", Kl, fn);
+-		emit(Ocopy, Kl, r1, r0, R);
++		r1 = newtmp("isel", k, fn);
++		emit(Ocopy, k, r1, r0, R);
+ 	}
+ 	else if (s != -1) {
+ 		/* load fast locals' addresses into
+-- 
+2.42.0
+
diff --git a/pkg/devel/qbe/src b/pkg/devel/qbe/src
@@ -0,0 +1 @@
+Subproject commit e694febd827715c8f5c326dfea3f1d4cb1134ca9
diff --git a/pkg/devel/qbe/ver b/pkg/devel/qbe/ver
@@ -0,0 +1 @@
+d023bda r0
diff --git a/sets.lua b/sets.lua
@@ -13,6 +13,7 @@ S.bin = {
 	'openbsd',
 	'pigz',
 	'pwgen',
+	'qbe',
 	'samurai',
 	'sbase',
 	'sfeed',