summary refs log tree commit diff
path: root/test
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2019-04-26 12:05:47 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2019-04-26 12:05:47 +0200
commit82f5ba58cf76bc431afe0c738cdcfe1f5998ae95 (patch)
treebc2da23db0330bff79a2096f4ca7b62085da6b20 /test
parentb4a98c3fa8b880f58b04f5d632ab89ad15725bd4 (diff)
downloadroux-82f5ba58cf76bc431afe0c738cdcfe1f5998ae95.tar.gz
restore some code from b4a98c
I had forgotten that %rip can only be
used as base when there is no index.

I also added a test which stresses
addressing selection with and without
constants.
Diffstat (limited to 'test')
-rw-r--r--test/conaddr.ssa65
1 files changed, 65 insertions, 0 deletions
diff --git a/test/conaddr.ssa b/test/conaddr.ssa
new file mode 100644
index 0000000..3f0aba7
--- /dev/null
+++ b/test/conaddr.ssa
@@ -0,0 +1,65 @@
+# test amd64 addressing modes
+
+export
+function w $f0(l %o) {
+@start
+	%addr =l add $a, %o
+	%char =w loadub %addr
+	ret %char
+}
+
+export
+function w $f1(l %o) {
+@start
+	%o1 =l mul %o, 1
+	%addr =l add 10, %o1
+	%char =w loadub %addr
+	ret %char
+}
+
+export
+function w $f2(l %o1, l %o2) {
+@start
+	%o22 =l mul %o2, 2
+	%o =l add %o1, %o22
+	%addr =l add $a, %o
+	%char =w loadub %addr
+	ret %char
+}
+
+export
+function l $f3(l %o) {
+@start
+	%addr =l add %o, $a
+	ret %addr
+}
+
+export
+function $writeto0() {
+@start
+	storel 0, 0
+	ret
+}
+
+# >>> driver
+# #include <stdlib.h>
+# #include <signal.h>
+# char a[] = "qbe rocks";
+# int ok = 1;
+# extern unsigned f0(long), f1(long), f2(long, long);
+# extern char *f3(long);
+# extern void writeto0();
+# void h(int sig, siginfo_t *si, void *unused) {
+# 	ok &= si->si_addr == 0;
+# 	exit(!ok);
+# }
+# int main() {
+# 	struct sigaction sa = {.sa_flags=SA_SIGINFO, .sa_sigaction=h};
+# 	sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, 0);
+# 	ok &= f0(2) == 'e';
+# 	ok &= f1((long)a-5) == 'o';
+# 	ok &= f2(4, 2) == 's';
+# 	ok &= *f3(0) == 'q';
+# 	writeto0(); /* will segfault */
+# }
+# <<<