From 36635660b40573f6a0c19d50dfdd9277589030de Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Sun, 27 Mar 2016 15:00:45 -0400 Subject: extract tests out of src --- Makefile | 5 +++ src/Makefile | 4 +- src/test/_alt.ssa | 25 ----------- src/test/_dragon.ssa | 33 -------------- src/test/_fix1.ssa | 15 ------- src/test/_fix2.ssa | 15 ------- src/test/_fix3.ssa | 20 --------- src/test/_fix4.ssa | 27 ----------- src/test/_live.ssa | 21 --------- src/test/_rpo.ssa | 12 ----- src/test/_spill1.ssa | 22 --------- src/test/_spill2.ssa | 22 --------- src/test/_spill3.ssa | 24 ---------- src/test/abi1.ssa | 59 ------------------------ src/test/abi2.ssa | 18 -------- src/test/abi3.ssa | 43 ------------------ src/test/abi4.ssa | 38 ---------------- src/test/abi5.ssa | 105 ------------------------------------------- src/test/align.ssa | 16 ------- src/test/collatz.ssa | 61 ------------------------- src/test/cprime.ssa | 103 ------------------------------------------ src/test/cup.ssa | 17 ------- src/test/dark.ssa | 30 ------------- src/test/double.ssa | 24 ---------- src/test/echo.ssa | 32 -------------- src/test/eucl.ssa | 24 ---------- src/test/euclc.ssa | 29 ------------ src/test/fpcnv.ssa | 27 ----------- src/test/go.sh | 116 ------------------------------------------------ src/test/loop.ssa | 23 ---------- src/test/mandel.ssa | 123 --------------------------------------------------- src/test/max.ssa | 33 -------------- src/test/prime.ssa | 32 -------------- src/test/puts10.ssa | 29 ------------ src/test/sum.ssa | 31 ------------- test/_alt.ssa | 25 +++++++++++ test/_dragon.ssa | 33 ++++++++++++++ test/_fix1.ssa | 15 +++++++ test/_fix2.ssa | 15 +++++++ test/_fix3.ssa | 20 +++++++++ test/_fix4.ssa | 27 +++++++++++ test/_live.ssa | 21 +++++++++ test/_rpo.ssa | 12 +++++ test/_spill1.ssa | 22 +++++++++ test/_spill2.ssa | 22 +++++++++ test/_spill3.ssa | 24 ++++++++++ test/abi1.ssa | 59 ++++++++++++++++++++++++ test/abi2.ssa | 18 ++++++++ test/abi3.ssa | 43 ++++++++++++++++++ test/abi4.ssa | 38 ++++++++++++++++ test/abi5.ssa | 105 +++++++++++++++++++++++++++++++++++++++++++ test/align.ssa | 16 +++++++ test/collatz.ssa | 61 +++++++++++++++++++++++++ test/cprime.ssa | 103 ++++++++++++++++++++++++++++++++++++++++++ test/cup.ssa | 17 +++++++ test/dark.ssa | 30 +++++++++++++ test/double.ssa | 24 ++++++++++ test/echo.ssa | 32 ++++++++++++++ test/eucl.ssa | 24 ++++++++++ test/euclc.ssa | 29 ++++++++++++ test/fpcnv.ssa | 27 +++++++++++ test/go.sh | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ test/loop.ssa | 23 ++++++++++ test/mandel.ssa | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/max.ssa | 33 ++++++++++++++ test/prime.ssa | 32 ++++++++++++++ test/puts10.ssa | 29 ++++++++++++ test/sum.ssa | 31 +++++++++++++ 68 files changed, 1258 insertions(+), 1251 deletions(-) create mode 100644 Makefile delete mode 100644 src/test/_alt.ssa delete mode 100644 src/test/_dragon.ssa delete mode 100644 src/test/_fix1.ssa delete mode 100644 src/test/_fix2.ssa delete mode 100644 src/test/_fix3.ssa delete mode 100644 src/test/_fix4.ssa delete mode 100644 src/test/_live.ssa delete mode 100644 src/test/_rpo.ssa delete mode 100644 src/test/_spill1.ssa delete mode 100644 src/test/_spill2.ssa delete mode 100644 src/test/_spill3.ssa delete mode 100644 src/test/abi1.ssa delete mode 100644 src/test/abi2.ssa delete mode 100644 src/test/abi3.ssa delete mode 100644 src/test/abi4.ssa delete mode 100644 src/test/abi5.ssa delete mode 100644 src/test/align.ssa delete mode 100644 src/test/collatz.ssa delete mode 100644 src/test/cprime.ssa delete mode 100644 src/test/cup.ssa delete mode 100644 src/test/dark.ssa delete mode 100644 src/test/double.ssa delete mode 100644 src/test/echo.ssa delete mode 100644 src/test/eucl.ssa delete mode 100644 src/test/euclc.ssa delete mode 100644 src/test/fpcnv.ssa delete mode 100755 src/test/go.sh delete mode 100644 src/test/loop.ssa delete mode 100644 src/test/mandel.ssa delete mode 100644 src/test/max.ssa delete mode 100644 src/test/prime.ssa delete mode 100644 src/test/puts10.ssa delete mode 100644 src/test/sum.ssa create mode 100644 test/_alt.ssa create mode 100644 test/_dragon.ssa create mode 100644 test/_fix1.ssa create mode 100644 test/_fix2.ssa create mode 100644 test/_fix3.ssa create mode 100644 test/_fix4.ssa create mode 100644 test/_live.ssa create mode 100644 test/_rpo.ssa create mode 100644 test/_spill1.ssa create mode 100644 test/_spill2.ssa create mode 100644 test/_spill3.ssa create mode 100644 test/abi1.ssa create mode 100644 test/abi2.ssa create mode 100644 test/abi3.ssa create mode 100644 test/abi4.ssa create mode 100644 test/abi5.ssa create mode 100644 test/align.ssa create mode 100644 test/collatz.ssa create mode 100644 test/cprime.ssa create mode 100644 test/cup.ssa create mode 100644 test/dark.ssa create mode 100644 test/double.ssa create mode 100644 test/echo.ssa create mode 100644 test/eucl.ssa create mode 100644 test/euclc.ssa create mode 100644 test/fpcnv.ssa create mode 100755 test/go.sh create mode 100644 test/loop.ssa create mode 100644 test/mandel.ssa create mode 100644 test/max.ssa create mode 100644 test/prime.ssa create mode 100644 test/puts10.ssa create mode 100644 test/sum.ssa diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b49f0cc --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY: all check +all: + @make -C src +check: all + test/go.sh all diff --git a/src/Makefile b/src/Makefile index 9f13008..1c0c4c7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,7 @@ config.h: .PHONY: clean check syndoc clean: rm -f $(BIN) $(OBJ) -check: $(BIN) - test/go.sh all +check: + make -C .. check syndoc: unison -auto doc ssh://qcar@h/data/d/ssa-doc diff --git a/src/test/_alt.ssa b/src/test/_alt.ssa deleted file mode 100644 index 3f89e5e..0000000 --- a/src/test/_alt.ssa +++ /dev/null @@ -1,25 +0,0 @@ -# an example with reducible control -# flow graph that exposes poor -# handling of looping constructs - -function $test() { -@start - %ten =w copy 10 - %dum =w copy 0 # dummy live-through temporary -@loop - %alt =w phi @start 0, @left %alt1, @right %alt1 - %cnt =w phi @start 100, @left %cnt, @right %cnt1 - %alt1 =w sub 1, %alt - jnz %alt1, @right, @left -@left - %x =w phi @loop 10, @left %x1 - %x1 =w sub %x, 1 - %z =w copy %x - jnz %z, @left, @loop -@right - %cnt1 =w sub %cnt, %ten - jnz %cnt1, @loop, @end -@end - %ret =w add %cnt, %dum - ret -} diff --git a/src/test/_dragon.ssa b/src/test/_dragon.ssa deleted file mode 100644 index b169e1b..0000000 --- a/src/test/_dragon.ssa +++ /dev/null @@ -1,33 +0,0 @@ -# a moderately complex test for -# dominators computation from -# the dragon book -# because branching is limited to -# two, I had to split some blocks - -function $dragon() { -@start -@b1 - jnz 0, @b2, @b3 -@b2 - jmp @b3 -@b3 - jmp @b4.1 -@b4.1 - jnz 0, @b3, @b4.2 -@b4.2 - jnz 0, @b5, @b6 -@b5 - jmp @b7 -@b6 - jmp @b7 -@b7 - jnz 0, @b8.1, @b4.1 -@b8.1 - jnz 0, @b3, @b8.2 -@b8.2 - jnz 0, @b9, @b10 -@b9 - jmp @b1 -@b10 - jmp @b7 -} diff --git a/src/test/_fix1.ssa b/src/test/_fix1.ssa deleted file mode 100644 index e89307f..0000000 --- a/src/test/_fix1.ssa +++ /dev/null @@ -1,15 +0,0 @@ -function $test() { -@start - %x =w copy 1 -@loop - jnz %x, @noz, @isz -@noz - %x =w copy 0 - jmp @end -@isz - %x =w copy 1 - jmp @loop -@end - %z =w add 10, %x - ret -} diff --git a/src/test/_fix2.ssa b/src/test/_fix2.ssa deleted file mode 100644 index 89f236d..0000000 --- a/src/test/_fix2.ssa +++ /dev/null @@ -1,15 +0,0 @@ -function $test() { -@start - %x =w copy 1 -@loop - jnz %x, @noz, @isz -@noz - %x =w copy 0 - jnz %x, @loop, @end -@isz - %x =w copy 1 - jmp @loop -@end - %z =w add 10, %x - ret -} diff --git a/src/test/_fix3.ssa b/src/test/_fix3.ssa deleted file mode 100644 index 283e5a1..0000000 --- a/src/test/_fix3.ssa +++ /dev/null @@ -1,20 +0,0 @@ -function w $test() { -@start - %x =w copy 100 - %s =w copy 0 -@l - %c =w cslew %x, 10 - jnz %c, @a, @b -@a - %s =w add %s, %x - %x =w sub %x, 1 - jmp @c -@b - %s =w sub %s, %x - jmp @c -@c - %x =w sub %x, 1 - jnz %x, @l, @end -@end - ret %s -} diff --git a/src/test/_fix4.ssa b/src/test/_fix4.ssa deleted file mode 100644 index 181768d..0000000 --- a/src/test/_fix4.ssa +++ /dev/null @@ -1,27 +0,0 @@ -function $test() { -@start - %x =w copy 3 - %n =w copy 2 -@loop - %c =w ceqw %n, 10000 - jnz %c, @end, @next -@next - %t =w copy 3 - %x =w add %x, 2 -@tloop - %s =w mul %t, %t - %c =w csgtw %s, %x - jnz %c, @prime, @test -@test - %r =w rem %x, %t - jnz %r, @tnext, @loop -@tnext - %t =w add %t, 2 - jmp @tloop -@prime - %n =w add %n, 1 - jmp @loop -@end - storew %x, $a - ret -} diff --git a/src/test/_live.ssa b/src/test/_live.ssa deleted file mode 100644 index fce4cb9..0000000 --- a/src/test/_live.ssa +++ /dev/null @@ -1,21 +0,0 @@ -# this control flow graph is irreducible -# yet, we expecet the liveness analysis -# to work properly and make %x live in -# the block @left -# -# nothing should ever be live at the entry - -function $test() { -@start - %b =w copy 0 - %x =w copy 10 - jnz 0, @loop, @left -@left - jmp @inloop -@loop - %x1 =w add %x, 1 -@inloop - %b1 =w add %b, 1 -@endloop - jmp @loop -} diff --git a/src/test/_rpo.ssa b/src/test/_rpo.ssa deleted file mode 100644 index a10c6b1..0000000 --- a/src/test/_rpo.ssa +++ /dev/null @@ -1,12 +0,0 @@ -function $test() { -@start - jmp @foo -@baz - jnz 1, @end, @foo -@bar - jmp @end -@foo - jnz 0, @bar, @baz -@end - ret -} diff --git a/src/test/_spill1.ssa b/src/test/_spill1.ssa deleted file mode 100644 index df5e4c2..0000000 --- a/src/test/_spill1.ssa +++ /dev/null @@ -1,22 +0,0 @@ -# test with NReg == 3 -# there must be a spill -# happening on %c -# -# if you replace the sub -# by an add or comment -# the two marked lines -# there should be no -# spill -# - -function $test() { -@start - %f =w copy 0 # here - %b =w copy 1 - %c =w copy 2 - %a =w sub %b, %c - %d =w copy %b - %e =w copy %f # and there - %g =w copy %a - ret -} diff --git a/src/test/_spill2.ssa b/src/test/_spill2.ssa deleted file mode 100644 index d462d0b..0000000 --- a/src/test/_spill2.ssa +++ /dev/null @@ -1,22 +0,0 @@ -# stupid spilling test - -function $test() { -@start - %x1 =w copy 10 - %x2 =w add %x1, %x1 - %x3 =w sub %x2, %x1 - %x4 =w add %x3, %x1 - %x5 =w sub %x4, %x1 - %x6 =w add %x5, %x1 - %x7 =w sub %x6, %x1 - %x8 =w add %x7, %x1 - %x9 =w sub %x8, %x8 - %x10 =w add %x9, %x7 - %x11 =w sub %x10, %x6 - %x12 =w add %x11, %x5 - %x13 =w sub %x12, %x4 - %x14 =w add %x13, %x3 - %x15 =w sub %x14, %x2 - %x16 =w add %x15, %x1 - ret -} diff --git a/src/test/_spill3.ssa b/src/test/_spill3.ssa deleted file mode 100644 index cdfda2d..0000000 --- a/src/test/_spill3.ssa +++ /dev/null @@ -1,24 +0,0 @@ -# make sure comparisons -# never get their two -# operands in memory -# run with NReg == 3, or -# adapt it! - -function $test() { -@start - %a =w loadw $a - %b =w loadw $a - -@loop - %c =w phi @start 0, @loop %f - %d =w phi @start 0, @loop %g - %e =w phi @start 0, @loop %h - %f =w add %c, %d - %g =w add %c, %e - %h =w add %e, %d - %x =w cslew %a, %b - jnz %x, @loop, @end - -@end - ret -} diff --git a/src/test/abi1.ssa b/src/test/abi1.ssa deleted file mode 100644 index 69cce44..0000000 --- a/src/test/abi1.ssa +++ /dev/null @@ -1,59 +0,0 @@ -# test calling into C with two -# large struct arguments (passed -# on the stack) - -type :mem = { b 17 } - -function $alpha(l %p, w %l, l %n) { -@ini - %pe =l add %p, %n -@lop - %p1 =l phi @ini %p, @lop %p2 - %l1 =w phi @ini %l, @lop %l2 - storeb %l1, %p1 - %p2 =l add %p1, 1 - %l2 =w add %l1, 1 - %c1 =w ceql %p1, %pe - jnz %c1, @end, @lop -@end - storeb 0, %pe - ret -} - -function $test() { -@start - %p =l alloc4 17 - %q =l alloc4 17 - %r0 =w call $alpha(l %p, w 65, l 16) - %r1 =w call $alpha(l %q, w 97, l 16) - %r2 =w call $fcb(:mem %p, w 1, w 2, w 3, w 4, w 5, w 6, w 7, w 8, w 9, :mem %q) - ret -} - - -# >>> driver -# #include -# typedef struct { char t[17]; } mem; -# extern void test(); -# void fcb(mem m, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, mem n) { -# printf("fcb: m = (mem){ t = \"%s\" }\n", m.t); -# printf(" n = (mem){ t = \"%s\" }\n", n.t); -# #define T(n) printf(" i%d = %d\n", n, i##n); -# T(1) T(2) T(3) T(4) T(5) T(6) T(7) T(8) T(9) -# } -# int main() { test(); return 0; } -# <<< - -# >>> output -# fcb: m = (mem){ t = "ABCDEFGHIJKLMNOP" } -# n = (mem){ t = "abcdefghijklmnop" } -# i1 = 1 -# i2 = 2 -# i3 = 3 -# i4 = 4 -# i5 = 5 -# i6 = 6 -# i7 = 7 -# i8 = 8 -# i9 = 9 -# <<< diff --git a/src/test/abi2.ssa b/src/test/abi2.ssa deleted file mode 100644 index b82c80c..0000000 --- a/src/test/abi2.ssa +++ /dev/null @@ -1,18 +0,0 @@ -type :fps = { s, b, s } - -function s $sum(:fps %p) { -@start - %f1 =s load %p - %p8 =l add 8, %p - %f2 =s load %p8 - %s =s add %f1, %f2 - ret %s -} - -# >>> driver -# typedef struct { float f1; char b; float f2; } fps; -# extern float sum(fps); -# int main() { fps x = { 1.23, -1, 2.34 }; return !(sum(x) == 1.23f+2.34f); } -# /* Note the f suffixes above are important -# * otherwise C does double operations. */ -# <<< diff --git a/src/test/abi3.ssa b/src/test/abi3.ssa deleted file mode 100644 index 608d1db..0000000 --- a/src/test/abi3.ssa +++ /dev/null @@ -1,43 +0,0 @@ -type :four = {l, b, w} - -data $z = { w 0 } - -function $test() { - @start - %a =w loadw $z - %y =w add %a, %a - - %s =l alloc8 16 # allocate a :four struct - %s1 =l add %s, 12 # get address of the w - storel 4, %s # set the l - storew 5, %s1 # set the w - - # only the last argument should be on the stack - %f =l add $F, %y - %x =w call %f(w %y, w 1, w 2, w 3, :four %s, w 6) - - # store the result in the - # global variable a - - %x1 =w add %y, %x - storew %x1, $a - ret -} - -# >>> driver -# #include -# struct four { long l; char c; int i; }; -# extern void test(void); -# int F(int a0, int a1, int a2, int a3, struct four s, int a6) { -# printf("%d %d %d %d %d %d %d\n", -# a0, a1, a2, a3, (int)s.l, s.i, a6); -# return 42; -# } -# int a; -# int main() { test(); printf("%d\n", a); return 0; } -# <<< - -# >>> output -# 0 1 2 3 4 5 6 -# 42 -# <<< diff --git a/src/test/abi4.ssa b/src/test/abi4.ssa deleted file mode 100644 index 4c3d89b..0000000 --- a/src/test/abi4.ssa +++ /dev/null @@ -1,38 +0,0 @@ -# return a large struct to C - -type :mem = { b 17 } - -function $alpha(l %p, w %l, l %n) { -@ini - %pe =l add %p, %n -@lop - %p1 =l phi @ini %p, @lop %p2 - %l1 =w phi @ini %l, @lop %l2 - storeb %l1, %p1 - %p2 =l add %p1, 1 - %l2 =w add %l1, 1 - %c1 =w ceql %p1, %pe - jnz %c1, @end, @lop -@end - storeb 0, %pe - ret -} - -function :mem $test() { -@start - %p =l alloc4 17 - %r0 =w call $alpha(l %p, w 65, l 16) - ret %p -} - - -# >>> driver -# #include -# typedef struct { char t[17]; } mem; -# extern mem test(void); -# int main() { mem m = test(); printf("%s\n", m.t); return 0; } -# <<< - -# >>> output -# ABCDEFGHIJKLMNOP -# <<< diff --git a/src/test/abi5.ssa b/src/test/abi5.ssa deleted file mode 100644 index 4c5eaea..0000000 --- a/src/test/abi5.ssa +++ /dev/null @@ -1,105 +0,0 @@ -# returning structs from C - -type :st1 = { b 17 } -type :st2 = { w } -type :st3 = { s, w } -type :st4 = { w, d } -type :st5 = { s, l } -type :st6 = { b 16 } -type :st7 = { s, d } -type :st8 = { w 4 } - -data $fmt1 = { b "t1: %s\n", b 0 } -data $fmt2 = { b "t2: %d\n", b 0 } -data $fmt3 = { b "t3: %f %d\n", b 0 } -data $fmt4 = { b "t4: %d %f\n", b 0 } -data $fmt5 = { b "t5: %f %lld\n", b 0 } -data $fmt6 = { b "t6: %s\n", b 0 } -data $fmt7 = { b "t7: %f %f\n", b 0 } -data $fmt8 = { b "t8: %d %d %d %d\n", b 0 } - -function $test() { -@start - %r1 =:st1 call $t1() - %i1 =w call $printf(l $fmt1, l %r1) - - %r2 =:st2 call $t2() - %w2 =w loadw %r2 - %i2 =w call $printf(l $fmt2, w %w2) - - %r3 =:st3 call $t3() - %s3 =s loads %r3 - %r34 =l add %r3, 4 - %w3 =w loadw %r34 - %p3 =d exts %s3 - %i3 =w call $printf(l $fmt3, d %p3, w %w3) - - %r4 =:st4 call $t4() - %w4 =w loadw %r4 - %r48 =l add 8, %r4 - %d4 =d loadd %r48 - %i4 =w call $printf(l $fmt4, w %w4, d %d4) - - %r5 =:st5 call $t5() - %s5 =s loads %r5 - %d5 =d exts %s5 - %r58 =l add %r5, 8 - %l5 =l loadl %r58 - %i5 =w call $printf(l $fmt5, d %d5, l %l5) - - %r6 =:st6 call $t6() - %i6 =w call $printf(l $fmt6, l %r6) - - %r7 =:st7 call $t7() - %s7 =s loads %r7 - %d71 =d exts %s7 - %r78 =l add %r7, 8 - %d72 =d loadd %r78 - %i7 =w call $printf(l $fmt7, d %d71, d %d72) - - %r8 =:st8 call $t8() - %r84 =l add 4, %r8 - %r88 =l add 4, %r84 - %r812 =l add 4, %r88 - %w81 =w loadw %r8 - %w82 =w loadw %r84 - %w83 =w loadw %r88 - %w84 =w loadw %r812 - %i8 =w call $printf(l $fmt8, w %w81, w %w82, w %w83, w %w84) - - ret -} - - -# >>> driver -# #include -# typedef struct { char t[17]; } st1; -# typedef struct { int i; } st2; -# typedef struct { float f; int i; } st3; -# typedef struct { int i; double d; } st4; -# typedef struct { float f; long l; } st5; -# typedef struct { char t[16]; } st6; -# typedef struct { float f; double d; } st7; -# typedef struct { int i[4]; } st8; -# extern void test(void); -# st1 t1() { return (st1){"abcdefghijklmnop"}; } -# st2 t2() { return (st2){2}; } -# st3 t3() { return (st3){3.0,30}; } -# st4 t4() { return (st4){4,-40}; } -# st5 t5() { return (st5){5.5,-55}; } -# st6 t6() { return (st6){"abcdefghijklmno"}; } -# st7 t7() { return (st7){7.77,77.7}; } -# st8 t8() { return (st8){-8,88,-888,8888}; } -# int main() { test(); return 0; } -# <<< - -# >>> output -# t1: abcdefghijklmnop -# t2: 2 -# t3: 3.000000 30 -# t4: 4 -40.000000 -# t5: 5.500000 -55 -# t6: abcdefghijklmno -# t7: 7.770000 77.700000 -# t8: -8 88 -888 8888 -# <<< diff --git a/src/test/align.ssa b/src/test/align.ssa deleted file mode 100644 index 84d1fb9..0000000 --- a/src/test/align.ssa +++ /dev/null @@ -1,16 +0,0 @@ -function $test() { -@start - %x =l alloc16 16 - %y =l add %x, 8 - %m =w rem %y, 16 - storew %m, %y - %n =w loadw %y - storew %n, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 8 || a == -8); } -# <<< diff --git a/src/test/collatz.ssa b/src/test/collatz.ssa deleted file mode 100644 index 373ecac..0000000 --- a/src/test/collatz.ssa +++ /dev/null @@ -1,61 +0,0 @@ -# a solution for N=1000 to -# https://projecteuler.net/problem=14 -# we use a fast local array to -# memoize small collatz numbers - -function $test() { -@start - %mem =l alloc4 4000 -@loop - %n =w phi @start 1, @newm %n9, @oldm %n9 - %cmax =w phi @start 0, @newm %c, @oldm %cmax - %fin =w csltw %n, 1000 - jnz %fin, @cloop, @end -@cloop - %n0 =w phi @loop %n, @odd %n2, @even %n3 - %c0 =w phi @loop 0, @odd %c1, @even %c1 - %no1 =w cnew %n0, 1 - jnz %no1, @iter0, @endcl -@iter0 - %ism =w csltw %n0, %n - jnz %ism, @getmemo, @iter1 -@iter1 - %c1 =w add %c0, 1 - %p =w and %n0, 1 - jnz %p, @odd, @even -@odd - %n1 =w mul 3, %n0 - %n2 =w add %n1, 1 - jmp @cloop -@even - %n3 =w div %n0, 2 - jmp @cloop -@getmemo # get the count for n0 in mem - %n0l =l extsw %n0 - %idx0 =l mul %n0l, 4 - %loc0 =l add %idx0, %mem - %cn0 =w loadw %loc0 - %c2 =w add %c0, %cn0 -@endcl # store the count for n in mem - %c =w phi @getmemo %c2, @cloop %c0 - %nl =l extsw %n - %idx1 =l mul %nl, 4 - %loc1 =l add %idx1, %mem - storew %c, %loc1 - %n9 =w add 1, %n - %big =w cslew %cmax, %c - jnz %big, @newm, @oldm -@newm - jmp @loop -@oldm - jmp @loop -@end - storew %cmax, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 178); } -# <<< diff --git a/src/test/cprime.ssa b/src/test/cprime.ssa deleted file mode 100644 index 1ca60e1..0000000 --- a/src/test/cprime.ssa +++ /dev/null @@ -1,103 +0,0 @@ -# generated by Andrew Chambers' -# compiler from the C program -# following in comments - -function w $main() { -@start - %v0 =l alloc8 4 - %v1 =l alloc8 4 - %v2 =l alloc8 4 - %v3 =l alloc8 4 - %v4 =l alloc8 4 - storew 5, %v1 - storew 11, %v2 - storew 12, %v3 -@L0 - %v5 =w loadw %v1 - %v6 =w cnew %v5, 201 - jnz %v6, @L8, @L1 -@L8 - storew 1, %v4 - %v7 =w loadw %v3 - %v8 =w rem %v7, 2 - %v9 =w ceqw %v8, 0 - jnz %v9, @L9, @L5 -@L9 - storew 0, %v4 -@L5 - storew 3, %v0 -@L2 - %v10 =w loadw %v0 - %v11 =w loadw %v3 - %v12 =w csltw %v10, %v11 - jnz %v12, @L10, @L3 -@L10 - %v13 =w loadw %v3 - %v14 =w loadw %v0 - %v15 =w rem %v13, %v14 - %v16 =w ceqw %v15, 0 - jnz %v16, @L11, @L4 -@L11 - storew 0, %v4 - jmp @L3 -@L4 - %v17 =w loadw %v0 - %v18 =w add %v17, 2 - storew %v18, %v0 - jmp @L2 -@L3 - %v19 =w loadw %v4 - jnz %v19, @L12, @L6 -@L12 - %v20 =w loadw %v3 - storew %v20, %v2 - %v21 =w loadw %v1 - %v22 =w add %v21, 1 - storew %v22, %v1 -@L6 - %v23 =w loadw %v3 - %v24 =w add %v23, 1 - storew %v24, %v3 - jmp @L0 -@L1 - %v25 =w loadw %v2 - %v26 =w cnew %v25, 1229 - jnz %v26, @L13, @L7 -@L13 - ret 1 -@L7 - ret 0 -@end - ret 0 -} - -# int -# main() -# { -# int i, n, p, next, isprime; -# -# n = 5; -# p = 11; -# next = 12; -# while(n != 201) { -# isprime = 1; -# if(next % 2 == 0) { -# isprime = 0; -# } else { -# for(i = 3; i < next; i = i + 2) { -# if(next % i == 0) { -# isprime = 0; -# break; -# } -# } -# } -# if(isprime) { -# p = next; -# n = n + 1; -# } -# next = next + 1; -# } -# if(p != 1229) -# return 1; -# return 0; -# } diff --git a/src/test/cup.ssa b/src/test/cup.ssa deleted file mode 100644 index 013394f..0000000 --- a/src/test/cup.ssa +++ /dev/null @@ -1,17 +0,0 @@ -# counts up from -1988 to 1991 - -function $test() { -@start -@loop - %n0 =l phi @start -1988, @loop %n1 - %n1 =l add 1, %n0 - %cmp =w cslel 1991, %n1 - jnz %cmp, @end, @loop -@end - ret -} - -# >>> driver -# extern void test(void); -# int main() { test(); return 0; } -# <<< diff --git a/src/test/dark.ssa b/src/test/dark.ssa deleted file mode 100644 index 5046af3..0000000 --- a/src/test/dark.ssa +++ /dev/null @@ -1,30 +0,0 @@ -# a hack example, -# we use a dark type to get -# a pointer to the stack. - -type :magic = align 1 { 0 } - -data $ret = { l 0 } - -function $test(:magic %p) { -@start - %av =w loadw $a - %a1 =w add 1, %av - storew %a1, $a # increment $a - %r1 =l loadl $ret # fetch from $ret - %p1 =l add %p, -8 - %r2 =l loadl %p1 # get the return address - storel %r2, $ret # store it in $ret - %c =w ceql %r1, %r2 - jnz %c, @fin, @cal -@cal - %i =w call $test() # no argument given, intentionally! -@fin - ret -} - -# >>> driver -# extern void test(void); -# int a = 2; -# int main() { test(); return !(a == 5); } -# <<< diff --git a/src/test/double.ssa b/src/test/double.ssa deleted file mode 100644 index d885d28..0000000 --- a/src/test/double.ssa +++ /dev/null @@ -1,24 +0,0 @@ -function $test() { -@start - %x1 =d copy d_0.1 - %x2 =d add d_0.2, %x1 - %x3 =d sub %x2, d_0.3 - -@loop - %x4 =d phi @start %x3, @loop %x5 - %i1 =w phi @start 0, @loop %i2 - %x5 =d add %x4, %x4 - %i2 =w add %i1, 1 - %c0 =w cled %x5, 4607182418800017408 # d_1.0 - jnz %c0, @loop, @end - -@end - storew %i2, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 55); } -# <<< diff --git a/src/test/echo.ssa b/src/test/echo.ssa deleted file mode 100644 index d3c8a25..0000000 --- a/src/test/echo.ssa +++ /dev/null @@ -1,32 +0,0 @@ -function w $main(w %argc, l %argv) { -@start - %fmt =l alloc8 8 - storel 1663398693, %fmt # "%s%c" - %av0 =l add %argv, 8 - %ac0 =w sub %argc, 1 -@loop - %av =l phi @start %av0, @loop2 %av1 - %ac =w phi @start %ac0, @loop2 %ac1 - %c0 =w ceqw %ac, 0 - jnz %c0, @end, @loop1 -@loop1 - %c1 =w ceqw %ac, 1 - jnz %c1, @last, @nolast -@last - jmp @loop2 -@nolast - jmp @loop2 -@loop2 - %sep =w phi @last 10, @nolast 32 - %arg =l loadl %av - %r =w call $printf(l %fmt, l %arg, w %sep) - %av1 =l add %av, 8 - %ac1 =w sub %ac, 1 - jmp @loop -@end - ret 0 -} - -# >>> output -# a b c -# <<< diff --git a/src/test/eucl.ssa b/src/test/eucl.ssa deleted file mode 100644 index f50fd2c..0000000 --- a/src/test/eucl.ssa +++ /dev/null @@ -1,24 +0,0 @@ -# euclide's algorithm in ssa -# it is a fairly interesting -# ssa program because of the -# swap of b and a - -function $test() { -@start - -@loop - %a =w phi @start 380, @loop %r - %b =w phi @start 747, @loop %a - %r =w rem %b, %a - jnz %r, @loop, @end - -@end - storew %a, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 1); } -# <<< diff --git a/src/test/euclc.ssa b/src/test/euclc.ssa deleted file mode 100644 index c76db2f..0000000 --- a/src/test/euclc.ssa +++ /dev/null @@ -1,29 +0,0 @@ -function w $test() { -@l0 - %a =l alloc4 4 - %b =l alloc4 4 - %r =l alloc4 4 - storew 747, %a - storew 380, %b -@l1 - %t4 =w loadw %b - jnz %t4, @l2, @l3 -@l2 - %t7 =w loadw %a - %t8 =w loadw %b - %t6 =w rem %t7, %t8 - storew %t6, %r - %t10 =w loadw %b - storew %t10, %a - %t12 =w loadw %r - storew %t12, %b - jmp @l1 -@l3 - %t13 =w loadw %a - ret %t13 -} - -# >>> driver -# extern int test(void); -# int main() { return !(test() == 1); } -# <<< diff --git a/src/test/fpcnv.ssa b/src/test/fpcnv.ssa deleted file mode 100644 index 5fd3be9..0000000 --- a/src/test/fpcnv.ssa +++ /dev/null @@ -1,27 +0,0 @@ -# floating point casts and conversions - -function s $fneg(s %f) { -@fneg - %b0 =w cast %f - %b1 =w xor 2147483648, %b0 - %rs =s cast %b1 - ret %rs -} - -function d $ftrunc(d %f) { -@ftrunc - %l0 =l ftosi %f - %rt =d sitof %l0 - ret %rt -} - -# >>> driver -# extern float fneg(float); -# extern double ftrunc(double); -# int main() { -# if (fneg(1.23f) != -1.23f) return 1; -# if (ftrunc(3.1415) != 3.0) return 2; -# if (ftrunc(-1.234) != -1.0) return 3; -# return 0; -# } -# <<< diff --git a/src/test/go.sh b/src/test/go.sh deleted file mode 100755 index 696f690..0000000 --- a/src/test/go.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/sh - -TMP=/tmp/qbe.zzzz - -DRV=$TMP.c -ASM=$TMP.s -BIN=$TMP.bin -OUT=$TMP.out - -cleanup() { - rm -f $DRV $ASM $BIN $OUT -} - -extract() { - WHAT="$1" - FILE="$2" - - awk " - /^# >>> $WHAT/ { - p = 1 - next - } - /^# <<&2 - exit 1 - fi - - echo "$T... " - - if ! ./qbe -o $ASM $T - then - echo "[qbe fail]" - return 1 - fi - - extract driver $T > $DRV - extract output $T > $OUT - - if test -s $DRV - then - LNK="$DRV $ASM" - else - LNK="$ASM" - fi - - if ! cc -g -o $BIN $LNK - then - echo "[cc fail]" - return 1 - fi - - if test -s $OUT - then - $BIN a b c | diff - $OUT - RET=$? - REASON="output" - else - $BIN a b c - RET=$? - REASON="returned $RET" - fi - - if test $RET -ne 0 - then - echo "[$REASON fail]" - return 1 - fi - - printf "\033[1A\033[45C[ok]\n" -} - - -#trap cleanup TERM QUIT - -if test -z "$1" -then - echo "usage: test/go.sh {all, SSAFILE}" 2>&1 - exit 1 -fi - -case $1 in - "all") - F=0 - for T in test/[!_]*.ssa - do - once $T - F=`expr $F + $?` - done - if test $F -ge 1 - then - echo - echo "$F test(s) failed!" - else - echo - echo "All is fine!" - fi - ;; - *) - once $1 - exit $? - ;; -esac diff --git a/src/test/loop.ssa b/src/test/loop.ssa deleted file mode 100644 index c8c4ee0..0000000 --- a/src/test/loop.ssa +++ /dev/null @@ -1,23 +0,0 @@ -# simple looping program -# sums all integers from 100 to 0 - -function $test() { -@start - -@loop - %s =w phi @start 0, @loop %s1 - %n =w phi @start 100, @loop %n1 - %s1 =w add %s, %n - %n1 =w sub %n, 1 - jnz %n1, @loop, @end - -@end - storew %s1, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 5050); } -# <<< diff --git a/src/test/mandel.ssa b/src/test/mandel.ssa deleted file mode 100644 index efefeb3..0000000 --- a/src/test/mandel.ssa +++ /dev/null @@ -1,123 +0,0 @@ -# Print the Mandelbrot set on the -# terminal line output. - -function w $mandel(d %x, d %y) { -@mandel - %cr =d sub %y, d_0.5 - %ci =d copy %x -@loop - %i =w phi @mandel 0, @loop1 %i1 - %zr =d phi @mandel d_0, @loop1 %zr1 - %zi =d phi @mandel d_0, @loop1 %zi1 - %i1 =w add 1, %i - %tmp =d mul %zr, %zi - %zr2 =d mul %zr, %zr - %zi2 =d mul %zi, %zi - %zrx =d sub %zr2, %zi2 - %zr1 =d add %zrx, %cr - %zix =d add %tmp, %tmp - %zi1 =d add %zix, %ci - %sum =d add %zi2, %zr2 - %cmp1 =w cgtd %sum, d_16 - jnz %cmp1, @reti, @loop1 -@loop1 - %cmp2 =w csgtw %i1, 1000 - jnz %cmp2, @ret0, @loop -@reti - ret %i1 -@ret0 - ret 0 -} - -function w $main() { -@main -@loopy - %y =d phi @main d_-1, @loopy1 %y1 -@loopx - %x =d phi @loopy d_-1, @loopx1 %x1 - %i =w call $mandel(d %x, d %y) - jnz %i, @out, @in -@in - %r0 =w call $putchar(w 42) # '*' - jmp @loopx1 -@out - %r1 =w call $putchar(w 32) # ' ' - jmp @loopx1 -@loopx1 - %x1 =d add %x, d_0.032 - %cmp1 =w cgtd %x1, d_1 - jnz %cmp1, @loopy1, @loopx -@loopy1 - %r2 =w call $putchar(w 10) # '\n' - %y1 =d add %y, d_0.032 - %cmp2 =w cgtd %y1, d_1 - jnz %cmp2, @ret, @loopy -@ret - ret 0 -} - -# >>> output -# # -# # -# # -# # -# * # -# **** # -# **** # -# *** # -# ***** # -# ********* # -# ************ # -# ***************** # -# **************** # -# *************** # -# **************** # -# **************** # -# ***************** # -# **************** # -# **************** # -# ************** # -# ************* # -# ************ # -# ********* # -# ***** # -# *********** # -# ***************** # -# ********************** # -# * *********************** ** # -# *************************** # -# ***************************** # -# * ******************************* ** # -# ** *********************************** # -# *********************************** * # -# *********************************** # -# ************************************* # -# ************************************* # -# *************************************** # -# *************************************** # -# *************************************** # -# **************************************** # -# * **************************************** # -# ********************************************** **** # -# **************************************************** # -# * ***************************************************** # -# * ***************************************************** # -# ***** **************************************** **** # -# * **************************************** * # -# **************************************** # -# *************************************** # -# **************************************** # -# *************************************** # -# **************************************** # -# ************************************ # -# *********************************** # -# ********************************* # -# ************************************ # -# *** ************* ************** *** # -# *********** ************ ** # -# ******** ******** # -# ** * * # -# # -# # -# # -# <<< diff --git a/src/test/max.ssa b/src/test/max.ssa deleted file mode 100644 index 547e9d4..0000000 --- a/src/test/max.ssa +++ /dev/null @@ -1,33 +0,0 @@ -# find the maximum value -# in a nul-terminated array -# of unsigned bytes -# -# the output is stored in $a - -data $arr = { b 10, b -60, b 10, b 100, b 200, b 0 } - -function $test() { -@start -@loop - %max =w phi @start -1, @new %byt, @old %max - %loc =l phi @start $arr, @new %loc1, @old %loc1 - %byt =w loadub %loc - %loc1 =l add 1, %loc - jnz %byt, @iter, @end -@iter - %cmp =w cslew %max, %byt - jnz %cmp, @new, @old -@new - jmp @loop -@old - jmp @loop -@end - storew %max, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 200); } -# <<< diff --git a/src/test/prime.ssa b/src/test/prime.ssa deleted file mode 100644 index 12d0273..0000000 --- a/src/test/prime.ssa +++ /dev/null @@ -1,32 +0,0 @@ -# find the 10,001st prime -# store it in a - -function $test() { -@start -@loop - %n =w phi @start 5, @tloop %n, @yes %n1 - %p =w phi @start 13, @tloop %p1, @yes %p1 - %p1 =w add %p, 2 -@tloop - %t =w phi @loop 3, @next %t1 - %r =w rem %p, %t - jnz %r, @next, @loop -@next - %t1 =w add 2, %t - %tsq =w mul %t1, %t1 - %c0 =w csgtw %tsq, %p - jnz %c0, @yes, @tloop -@yes - %n1 =w add 1, %n - %c1 =w ceqw 10001, %n1 - jnz %c1, @end, @loop -@end - storew %p, $a - ret -} - -# >>> driver -# extern void test(void); -# int a; -# int main() { test(); return !(a == 104743); } -# <<< diff --git a/src/test/puts10.ssa b/src/test/puts10.ssa deleted file mode 100644 index 1dcf227..0000000 --- a/src/test/puts10.ssa +++ /dev/null @@ -1,29 +0,0 @@ -function $main() { -@start - %y =l alloc4 4 - %y1 =l add %y, 1 - storeb 0, %y1 -@loop - %n =w phi @start 0, @loop %n1 - %c =w add %n, 48 - storeb %c, %y - %r =w call $puts(l %y) - %n1 =w add %n, 1 - %cmp =w cslew %n1, 9 - jnz %cmp, @loop, @end -@end - ret -} - -# >>> output -# 0 -# 1 -# 2 -# 3 -# 4 -# 5 -# 6 -# 7 -# 8 -# 9 -# <<< diff --git a/src/test/sum.ssa b/src/test/sum.ssa deleted file mode 100644 index 266054e..0000000 --- a/src/test/sum.ssa +++ /dev/null @@ -1,31 +0,0 @@ -# Simple test for addressing modes. - -function w $sum(l %arr, w %num) { -@start -@loop - %n1 =w phi @start %num, @loop1 %n2 - %s0 =w phi @start 0, @loop1 %s1 - %n2 =w sub %n1, 1 - %c =w cslew %n1, 0 - jnz %c, @end, @loop1 -@loop1 - %idx0 =l extsw %n2 - %idx1 =l mul 4, %idx0 - %idx2 =l add %idx1, %arr - %w =w loadw %idx2 - %s1 =w add %w, %s0 - jmp @loop -@end - ret %s0 -} - -# >>> driver -# extern int sum(int *, int); -# int arr[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21 }; -# #define N sizeof arr / sizeof arr[0] -# int main() { -# int i, s; -# for (s=i=0; i>> driver +# #include +# typedef struct { char t[17]; } mem; +# extern void test(); +# void fcb(mem m, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, mem n) { +# printf("fcb: m = (mem){ t = \"%s\" }\n", m.t); +# printf(" n = (mem){ t = \"%s\" }\n", n.t); +# #define T(n) printf(" i%d = %d\n", n, i##n); +# T(1) T(2) T(3) T(4) T(5) T(6) T(7) T(8) T(9) +# } +# int main() { test(); return 0; } +# <<< + +# >>> output +# fcb: m = (mem){ t = "ABCDEFGHIJKLMNOP" } +# n = (mem){ t = "abcdefghijklmnop" } +# i1 = 1 +# i2 = 2 +# i3 = 3 +# i4 = 4 +# i5 = 5 +# i6 = 6 +# i7 = 7 +# i8 = 8 +# i9 = 9 +# <<< diff --git a/test/abi2.ssa b/test/abi2.ssa new file mode 100644 index 0000000..b82c80c --- /dev/null +++ b/test/abi2.ssa @@ -0,0 +1,18 @@ +type :fps = { s, b, s } + +function s $sum(:fps %p) { +@start + %f1 =s load %p + %p8 =l add 8, %p + %f2 =s load %p8 + %s =s add %f1, %f2 + ret %s +} + +# >>> driver +# typedef struct { float f1; char b; float f2; } fps; +# extern float sum(fps); +# int main() { fps x = { 1.23, -1, 2.34 }; return !(sum(x) == 1.23f+2.34f); } +# /* Note the f suffixes above are important +# * otherwise C does double operations. */ +# <<< diff --git a/test/abi3.ssa b/test/abi3.ssa new file mode 100644 index 0000000..608d1db --- /dev/null +++ b/test/abi3.ssa @@ -0,0 +1,43 @@ +type :four = {l, b, w} + +data $z = { w 0 } + +function $test() { + @start + %a =w loadw $z + %y =w add %a, %a + + %s =l alloc8 16 # allocate a :four struct + %s1 =l add %s, 12 # get address of the w + storel 4, %s # set the l + storew 5, %s1 # set the w + + # only the last argument should be on the stack + %f =l add $F, %y + %x =w call %f(w %y, w 1, w 2, w 3, :four %s, w 6) + + # store the result in the + # global variable a + + %x1 =w add %y, %x + storew %x1, $a + ret +} + +# >>> driver +# #include +# struct four { long l; char c; int i; }; +# extern void test(void); +# int F(int a0, int a1, int a2, int a3, struct four s, int a6) { +# printf("%d %d %d %d %d %d %d\n", +# a0, a1, a2, a3, (int)s.l, s.i, a6); +# return 42; +# } +# int a; +# int main() { test(); printf("%d\n", a); return 0; } +# <<< + +# >>> output +# 0 1 2 3 4 5 6 +# 42 +# <<< diff --git a/test/abi4.ssa b/test/abi4.ssa new file mode 100644 index 0000000..4c3d89b --- /dev/null +++ b/test/abi4.ssa @@ -0,0 +1,38 @@ +# return a large struct to C + +type :mem = { b 17 } + +function $alpha(l %p, w %l, l %n) { +@ini + %pe =l add %p, %n +@lop + %p1 =l phi @ini %p, @lop %p2 + %l1 =w phi @ini %l, @lop %l2 + storeb %l1, %p1 + %p2 =l add %p1, 1 + %l2 =w add %l1, 1 + %c1 =w ceql %p1, %pe + jnz %c1, @end, @lop +@end + storeb 0, %pe + ret +} + +function :mem $test() { +@start + %p =l alloc4 17 + %r0 =w call $alpha(l %p, w 65, l 16) + ret %p +} + + +# >>> driver +# #include +# typedef struct { char t[17]; } mem; +# extern mem test(void); +# int main() { mem m = test(); printf("%s\n", m.t); return 0; } +# <<< + +# >>> output +# ABCDEFGHIJKLMNOP +# <<< diff --git a/test/abi5.ssa b/test/abi5.ssa new file mode 100644 index 0000000..4c5eaea --- /dev/null +++ b/test/abi5.ssa @@ -0,0 +1,105 @@ +# returning structs from C + +type :st1 = { b 17 } +type :st2 = { w } +type :st3 = { s, w } +type :st4 = { w, d } +type :st5 = { s, l } +type :st6 = { b 16 } +type :st7 = { s, d } +type :st8 = { w 4 } + +data $fmt1 = { b "t1: %s\n", b 0 } +data $fmt2 = { b "t2: %d\n", b 0 } +data $fmt3 = { b "t3: %f %d\n", b 0 } +data $fmt4 = { b "t4: %d %f\n", b 0 } +data $fmt5 = { b "t5: %f %lld\n", b 0 } +data $fmt6 = { b "t6: %s\n", b 0 } +data $fmt7 = { b "t7: %f %f\n", b 0 } +data $fmt8 = { b "t8: %d %d %d %d\n", b 0 } + +function $test() { +@start + %r1 =:st1 call $t1() + %i1 =w call $printf(l $fmt1, l %r1) + + %r2 =:st2 call $t2() + %w2 =w loadw %r2 + %i2 =w call $printf(l $fmt2, w %w2) + + %r3 =:st3 call $t3() + %s3 =s loads %r3 + %r34 =l add %r3, 4 + %w3 =w loadw %r34 + %p3 =d exts %s3 + %i3 =w call $printf(l $fmt3, d %p3, w %w3) + + %r4 =:st4 call $t4() + %w4 =w loadw %r4 + %r48 =l add 8, %r4 + %d4 =d loadd %r48 + %i4 =w call $printf(l $fmt4, w %w4, d %d4) + + %r5 =:st5 call $t5() + %s5 =s loads %r5 + %d5 =d exts %s5 + %r58 =l add %r5, 8 + %l5 =l loadl %r58 + %i5 =w call $printf(l $fmt5, d %d5, l %l5) + + %r6 =:st6 call $t6() + %i6 =w call $printf(l $fmt6, l %r6) + + %r7 =:st7 call $t7() + %s7 =s loads %r7 + %d71 =d exts %s7 + %r78 =l add %r7, 8 + %d72 =d loadd %r78 + %i7 =w call $printf(l $fmt7, d %d71, d %d72) + + %r8 =:st8 call $t8() + %r84 =l add 4, %r8 + %r88 =l add 4, %r84 + %r812 =l add 4, %r88 + %w81 =w loadw %r8 + %w82 =w loadw %r84 + %w83 =w loadw %r88 + %w84 =w loadw %r812 + %i8 =w call $printf(l $fmt8, w %w81, w %w82, w %w83, w %w84) + + ret +} + + +# >>> driver +# #include +# typedef struct { char t[17]; } st1; +# typedef struct { int i; } st2; +# typedef struct { float f; int i; } st3; +# typedef struct { int i; double d; } st4; +# typedef struct { float f; long l; } st5; +# typedef struct { char t[16]; } st6; +# typedef struct { float f; double d; } st7; +# typedef struct { int i[4]; } st8; +# extern void test(void); +# st1 t1() { return (st1){"abcdefghijklmnop"}; } +# st2 t2() { return (st2){2}; } +# st3 t3() { return (st3){3.0,30}; } +# st4 t4() { return (st4){4,-40}; } +# st5 t5() { return (st5){5.5,-55}; } +# st6 t6() { return (st6){"abcdefghijklmno"}; } +# st7 t7() { return (st7){7.77,77.7}; } +# st8 t8() { return (st8){-8,88,-888,8888}; } +# int main() { test(); return 0; } +# <<< + +# >>> output +# t1: abcdefghijklmnop +# t2: 2 +# t3: 3.000000 30 +# t4: 4 -40.000000 +# t5: 5.500000 -55 +# t6: abcdefghijklmno +# t7: 7.770000 77.700000 +# t8: -8 88 -888 8888 +# <<< diff --git a/test/align.ssa b/test/align.ssa new file mode 100644 index 0000000..84d1fb9 --- /dev/null +++ b/test/align.ssa @@ -0,0 +1,16 @@ +function $test() { +@start + %x =l alloc16 16 + %y =l add %x, 8 + %m =w rem %y, 16 + storew %m, %y + %n =w loadw %y + storew %n, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 8 || a == -8); } +# <<< diff --git a/test/collatz.ssa b/test/collatz.ssa new file mode 100644 index 0000000..373ecac --- /dev/null +++ b/test/collatz.ssa @@ -0,0 +1,61 @@ +# a solution for N=1000 to +# https://projecteuler.net/problem=14 +# we use a fast local array to +# memoize small collatz numbers + +function $test() { +@start + %mem =l alloc4 4000 +@loop + %n =w phi @start 1, @newm %n9, @oldm %n9 + %cmax =w phi @start 0, @newm %c, @oldm %cmax + %fin =w csltw %n, 1000 + jnz %fin, @cloop, @end +@cloop + %n0 =w phi @loop %n, @odd %n2, @even %n3 + %c0 =w phi @loop 0, @odd %c1, @even %c1 + %no1 =w cnew %n0, 1 + jnz %no1, @iter0, @endcl +@iter0 + %ism =w csltw %n0, %n + jnz %ism, @getmemo, @iter1 +@iter1 + %c1 =w add %c0, 1 + %p =w and %n0, 1 + jnz %p, @odd, @even +@odd + %n1 =w mul 3, %n0 + %n2 =w add %n1, 1 + jmp @cloop +@even + %n3 =w div %n0, 2 + jmp @cloop +@getmemo # get the count for n0 in mem + %n0l =l extsw %n0 + %idx0 =l mul %n0l, 4 + %loc0 =l add %idx0, %mem + %cn0 =w loadw %loc0 + %c2 =w add %c0, %cn0 +@endcl # store the count for n in mem + %c =w phi @getmemo %c2, @cloop %c0 + %nl =l extsw %n + %idx1 =l mul %nl, 4 + %loc1 =l add %idx1, %mem + storew %c, %loc1 + %n9 =w add 1, %n + %big =w cslew %cmax, %c + jnz %big, @newm, @oldm +@newm + jmp @loop +@oldm + jmp @loop +@end + storew %cmax, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 178); } +# <<< diff --git a/test/cprime.ssa b/test/cprime.ssa new file mode 100644 index 0000000..1ca60e1 --- /dev/null +++ b/test/cprime.ssa @@ -0,0 +1,103 @@ +# generated by Andrew Chambers' +# compiler from the C program +# following in comments + +function w $main() { +@start + %v0 =l alloc8 4 + %v1 =l alloc8 4 + %v2 =l alloc8 4 + %v3 =l alloc8 4 + %v4 =l alloc8 4 + storew 5, %v1 + storew 11, %v2 + storew 12, %v3 +@L0 + %v5 =w loadw %v1 + %v6 =w cnew %v5, 201 + jnz %v6, @L8, @L1 +@L8 + storew 1, %v4 + %v7 =w loadw %v3 + %v8 =w rem %v7, 2 + %v9 =w ceqw %v8, 0 + jnz %v9, @L9, @L5 +@L9 + storew 0, %v4 +@L5 + storew 3, %v0 +@L2 + %v10 =w loadw %v0 + %v11 =w loadw %v3 + %v12 =w csltw %v10, %v11 + jnz %v12, @L10, @L3 +@L10 + %v13 =w loadw %v3 + %v14 =w loadw %v0 + %v15 =w rem %v13, %v14 + %v16 =w ceqw %v15, 0 + jnz %v16, @L11, @L4 +@L11 + storew 0, %v4 + jmp @L3 +@L4 + %v17 =w loadw %v0 + %v18 =w add %v17, 2 + storew %v18, %v0 + jmp @L2 +@L3 + %v19 =w loadw %v4 + jnz %v19, @L12, @L6 +@L12 + %v20 =w loadw %v3 + storew %v20, %v2 + %v21 =w loadw %v1 + %v22 =w add %v21, 1 + storew %v22, %v1 +@L6 + %v23 =w loadw %v3 + %v24 =w add %v23, 1 + storew %v24, %v3 + jmp @L0 +@L1 + %v25 =w loadw %v2 + %v26 =w cnew %v25, 1229 + jnz %v26, @L13, @L7 +@L13 + ret 1 +@L7 + ret 0 +@end + ret 0 +} + +# int +# main() +# { +# int i, n, p, next, isprime; +# +# n = 5; +# p = 11; +# next = 12; +# while(n != 201) { +# isprime = 1; +# if(next % 2 == 0) { +# isprime = 0; +# } else { +# for(i = 3; i < next; i = i + 2) { +# if(next % i == 0) { +# isprime = 0; +# break; +# } +# } +# } +# if(isprime) { +# p = next; +# n = n + 1; +# } +# next = next + 1; +# } +# if(p != 1229) +# return 1; +# return 0; +# } diff --git a/test/cup.ssa b/test/cup.ssa new file mode 100644 index 0000000..013394f --- /dev/null +++ b/test/cup.ssa @@ -0,0 +1,17 @@ +# counts up from -1988 to 1991 + +function $test() { +@start +@loop + %n0 =l phi @start -1988, @loop %n1 + %n1 =l add 1, %n0 + %cmp =w cslel 1991, %n1 + jnz %cmp, @end, @loop +@end + ret +} + +# >>> driver +# extern void test(void); +# int main() { test(); return 0; } +# <<< diff --git a/test/dark.ssa b/test/dark.ssa new file mode 100644 index 0000000..5046af3 --- /dev/null +++ b/test/dark.ssa @@ -0,0 +1,30 @@ +# a hack example, +# we use a dark type to get +# a pointer to the stack. + +type :magic = align 1 { 0 } + +data $ret = { l 0 } + +function $test(:magic %p) { +@start + %av =w loadw $a + %a1 =w add 1, %av + storew %a1, $a # increment $a + %r1 =l loadl $ret # fetch from $ret + %p1 =l add %p, -8 + %r2 =l loadl %p1 # get the return address + storel %r2, $ret # store it in $ret + %c =w ceql %r1, %r2 + jnz %c, @fin, @cal +@cal + %i =w call $test() # no argument given, intentionally! +@fin + ret +} + +# >>> driver +# extern void test(void); +# int a = 2; +# int main() { test(); return !(a == 5); } +# <<< diff --git a/test/double.ssa b/test/double.ssa new file mode 100644 index 0000000..d885d28 --- /dev/null +++ b/test/double.ssa @@ -0,0 +1,24 @@ +function $test() { +@start + %x1 =d copy d_0.1 + %x2 =d add d_0.2, %x1 + %x3 =d sub %x2, d_0.3 + +@loop + %x4 =d phi @start %x3, @loop %x5 + %i1 =w phi @start 0, @loop %i2 + %x5 =d add %x4, %x4 + %i2 =w add %i1, 1 + %c0 =w cled %x5, 4607182418800017408 # d_1.0 + jnz %c0, @loop, @end + +@end + storew %i2, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 55); } +# <<< diff --git a/test/echo.ssa b/test/echo.ssa new file mode 100644 index 0000000..d3c8a25 --- /dev/null +++ b/test/echo.ssa @@ -0,0 +1,32 @@ +function w $main(w %argc, l %argv) { +@start + %fmt =l alloc8 8 + storel 1663398693, %fmt # "%s%c" + %av0 =l add %argv, 8 + %ac0 =w sub %argc, 1 +@loop + %av =l phi @start %av0, @loop2 %av1 + %ac =w phi @start %ac0, @loop2 %ac1 + %c0 =w ceqw %ac, 0 + jnz %c0, @end, @loop1 +@loop1 + %c1 =w ceqw %ac, 1 + jnz %c1, @last, @nolast +@last + jmp @loop2 +@nolast + jmp @loop2 +@loop2 + %sep =w phi @last 10, @nolast 32 + %arg =l loadl %av + %r =w call $printf(l %fmt, l %arg, w %sep) + %av1 =l add %av, 8 + %ac1 =w sub %ac, 1 + jmp @loop +@end + ret 0 +} + +# >>> output +# a b c +# <<< diff --git a/test/eucl.ssa b/test/eucl.ssa new file mode 100644 index 0000000..f50fd2c --- /dev/null +++ b/test/eucl.ssa @@ -0,0 +1,24 @@ +# euclide's algorithm in ssa +# it is a fairly interesting +# ssa program because of the +# swap of b and a + +function $test() { +@start + +@loop + %a =w phi @start 380, @loop %r + %b =w phi @start 747, @loop %a + %r =w rem %b, %a + jnz %r, @loop, @end + +@end + storew %a, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 1); } +# <<< diff --git a/test/euclc.ssa b/test/euclc.ssa new file mode 100644 index 0000000..c76db2f --- /dev/null +++ b/test/euclc.ssa @@ -0,0 +1,29 @@ +function w $test() { +@l0 + %a =l alloc4 4 + %b =l alloc4 4 + %r =l alloc4 4 + storew 747, %a + storew 380, %b +@l1 + %t4 =w loadw %b + jnz %t4, @l2, @l3 +@l2 + %t7 =w loadw %a + %t8 =w loadw %b + %t6 =w rem %t7, %t8 + storew %t6, %r + %t10 =w loadw %b + storew %t10, %a + %t12 =w loadw %r + storew %t12, %b + jmp @l1 +@l3 + %t13 =w loadw %a + ret %t13 +} + +# >>> driver +# extern int test(void); +# int main() { return !(test() == 1); } +# <<< diff --git a/test/fpcnv.ssa b/test/fpcnv.ssa new file mode 100644 index 0000000..5fd3be9 --- /dev/null +++ b/test/fpcnv.ssa @@ -0,0 +1,27 @@ +# floating point casts and conversions + +function s $fneg(s %f) { +@fneg + %b0 =w cast %f + %b1 =w xor 2147483648, %b0 + %rs =s cast %b1 + ret %rs +} + +function d $ftrunc(d %f) { +@ftrunc + %l0 =l ftosi %f + %rt =d sitof %l0 + ret %rt +} + +# >>> driver +# extern float fneg(float); +# extern double ftrunc(double); +# int main() { +# if (fneg(1.23f) != -1.23f) return 1; +# if (ftrunc(3.1415) != 3.0) return 2; +# if (ftrunc(-1.234) != -1.0) return 3; +# return 0; +# } +# <<< diff --git a/test/go.sh b/test/go.sh new file mode 100755 index 0000000..7bc795f --- /dev/null +++ b/test/go.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +QBE=`readlink -f $0 | xargs dirname`/../src/qbe + +TMP=/tmp/qbe.zzzz + +DRV=$TMP.c +ASM=$TMP.s +BIN=$TMP.bin +OUT=$TMP.out + +cleanup() { + rm -f $DRV $ASM $BIN $OUT +} + +extract() { + WHAT="$1" + FILE="$2" + + awk " + /^# >>> $WHAT/ { + p = 1 + next + } + /^# <<&2 + exit 1 + fi + + echo "$T... " + + if ! $QBE -o $ASM $T + then + echo "[qbe fail]" + return 1 + fi + + extract driver $T > $DRV + extract output $T > $OUT + + if test -s $DRV + then + LNK="$DRV $ASM" + else + LNK="$ASM" + fi + + if ! cc -g -o $BIN $LNK + then + echo "[cc fail]" + return 1 + fi + + if test -s $OUT + then + $BIN a b c | diff - $OUT + RET=$? + REASON="output" + else + $BIN a b c + RET=$? + REASON="returned $RET" + fi + + if test $RET -ne 0 + then + echo "[$REASON fail]" + return 1 + fi + + printf "\033[1A\033[45C[ok]\n" +} + + +#trap cleanup TERM QUIT + +if test -z "$1" +then + echo "usage: test/go.sh {all, SSAFILE}" 2>&1 + exit 1 +fi + +case $1 in + "all") + F=0 + for T in test/[!_]*.ssa + do + once $T + F=`expr $F + $?` + done + if test $F -ge 1 + then + echo + echo "$F test(s) failed!" + else + echo + echo "All is fine!" + fi + ;; + *) + once $1 + exit $? + ;; +esac diff --git a/test/loop.ssa b/test/loop.ssa new file mode 100644 index 0000000..c8c4ee0 --- /dev/null +++ b/test/loop.ssa @@ -0,0 +1,23 @@ +# simple looping program +# sums all integers from 100 to 0 + +function $test() { +@start + +@loop + %s =w phi @start 0, @loop %s1 + %n =w phi @start 100, @loop %n1 + %s1 =w add %s, %n + %n1 =w sub %n, 1 + jnz %n1, @loop, @end + +@end + storew %s1, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 5050); } +# <<< diff --git a/test/mandel.ssa b/test/mandel.ssa new file mode 100644 index 0000000..efefeb3 --- /dev/null +++ b/test/mandel.ssa @@ -0,0 +1,123 @@ +# Print the Mandelbrot set on the +# terminal line output. + +function w $mandel(d %x, d %y) { +@mandel + %cr =d sub %y, d_0.5 + %ci =d copy %x +@loop + %i =w phi @mandel 0, @loop1 %i1 + %zr =d phi @mandel d_0, @loop1 %zr1 + %zi =d phi @mandel d_0, @loop1 %zi1 + %i1 =w add 1, %i + %tmp =d mul %zr, %zi + %zr2 =d mul %zr, %zr + %zi2 =d mul %zi, %zi + %zrx =d sub %zr2, %zi2 + %zr1 =d add %zrx, %cr + %zix =d add %tmp, %tmp + %zi1 =d add %zix, %ci + %sum =d add %zi2, %zr2 + %cmp1 =w cgtd %sum, d_16 + jnz %cmp1, @reti, @loop1 +@loop1 + %cmp2 =w csgtw %i1, 1000 + jnz %cmp2, @ret0, @loop +@reti + ret %i1 +@ret0 + ret 0 +} + +function w $main() { +@main +@loopy + %y =d phi @main d_-1, @loopy1 %y1 +@loopx + %x =d phi @loopy d_-1, @loopx1 %x1 + %i =w call $mandel(d %x, d %y) + jnz %i, @out, @in +@in + %r0 =w call $putchar(w 42) # '*' + jmp @loopx1 +@out + %r1 =w call $putchar(w 32) # ' ' + jmp @loopx1 +@loopx1 + %x1 =d add %x, d_0.032 + %cmp1 =w cgtd %x1, d_1 + jnz %cmp1, @loopy1, @loopx +@loopy1 + %r2 =w call $putchar(w 10) # '\n' + %y1 =d add %y, d_0.032 + %cmp2 =w cgtd %y1, d_1 + jnz %cmp2, @ret, @loopy +@ret + ret 0 +} + +# >>> output +# # +# # +# # +# # +# * # +# **** # +# **** # +# *** # +# ***** # +# ********* # +# ************ # +# ***************** # +# **************** # +# *************** # +# **************** # +# **************** # +# ***************** # +# **************** # +# **************** # +# ************** # +# ************* # +# ************ # +# ********* # +# ***** # +# *********** # +# ***************** # +# ********************** # +# * *********************** ** # +# *************************** # +# ***************************** # +# * ******************************* ** # +# ** *********************************** # +# *********************************** * # +# *********************************** # +# ************************************* # +# ************************************* # +# *************************************** # +# *************************************** # +# *************************************** # +# **************************************** # +# * **************************************** # +# ********************************************** **** # +# **************************************************** # +# * ***************************************************** # +# * ***************************************************** # +# ***** **************************************** **** # +# * **************************************** * # +# **************************************** # +# *************************************** # +# **************************************** # +# *************************************** # +# **************************************** # +# ************************************ # +# *********************************** # +# ********************************* # +# ************************************ # +# *** ************* ************** *** # +# *********** ************ ** # +# ******** ******** # +# ** * * # +# # +# # +# # +# <<< diff --git a/test/max.ssa b/test/max.ssa new file mode 100644 index 0000000..547e9d4 --- /dev/null +++ b/test/max.ssa @@ -0,0 +1,33 @@ +# find the maximum value +# in a nul-terminated array +# of unsigned bytes +# +# the output is stored in $a + +data $arr = { b 10, b -60, b 10, b 100, b 200, b 0 } + +function $test() { +@start +@loop + %max =w phi @start -1, @new %byt, @old %max + %loc =l phi @start $arr, @new %loc1, @old %loc1 + %byt =w loadub %loc + %loc1 =l add 1, %loc + jnz %byt, @iter, @end +@iter + %cmp =w cslew %max, %byt + jnz %cmp, @new, @old +@new + jmp @loop +@old + jmp @loop +@end + storew %max, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 200); } +# <<< diff --git a/test/prime.ssa b/test/prime.ssa new file mode 100644 index 0000000..12d0273 --- /dev/null +++ b/test/prime.ssa @@ -0,0 +1,32 @@ +# find the 10,001st prime +# store it in a + +function $test() { +@start +@loop + %n =w phi @start 5, @tloop %n, @yes %n1 + %p =w phi @start 13, @tloop %p1, @yes %p1 + %p1 =w add %p, 2 +@tloop + %t =w phi @loop 3, @next %t1 + %r =w rem %p, %t + jnz %r, @next, @loop +@next + %t1 =w add 2, %t + %tsq =w mul %t1, %t1 + %c0 =w csgtw %tsq, %p + jnz %c0, @yes, @tloop +@yes + %n1 =w add 1, %n + %c1 =w ceqw 10001, %n1 + jnz %c1, @end, @loop +@end + storew %p, $a + ret +} + +# >>> driver +# extern void test(void); +# int a; +# int main() { test(); return !(a == 104743); } +# <<< diff --git a/test/puts10.ssa b/test/puts10.ssa new file mode 100644 index 0000000..1dcf227 --- /dev/null +++ b/test/puts10.ssa @@ -0,0 +1,29 @@ +function $main() { +@start + %y =l alloc4 4 + %y1 =l add %y, 1 + storeb 0, %y1 +@loop + %n =w phi @start 0, @loop %n1 + %c =w add %n, 48 + storeb %c, %y + %r =w call $puts(l %y) + %n1 =w add %n, 1 + %cmp =w cslew %n1, 9 + jnz %cmp, @loop, @end +@end + ret +} + +# >>> output +# 0 +# 1 +# 2 +# 3 +# 4 +# 5 +# 6 +# 7 +# 8 +# 9 +# <<< diff --git a/test/sum.ssa b/test/sum.ssa new file mode 100644 index 0000000..266054e --- /dev/null +++ b/test/sum.ssa @@ -0,0 +1,31 @@ +# Simple test for addressing modes. + +function w $sum(l %arr, w %num) { +@start +@loop + %n1 =w phi @start %num, @loop1 %n2 + %s0 =w phi @start 0, @loop1 %s1 + %n2 =w sub %n1, 1 + %c =w cslew %n1, 0 + jnz %c, @end, @loop1 +@loop1 + %idx0 =l extsw %n2 + %idx1 =l mul 4, %idx0 + %idx2 =l add %idx1, %arr + %w =w loadw %idx2 + %s1 =w add %w, %s0 + jmp @loop +@end + ret %s0 +} + +# >>> driver +# extern int sum(int *, int); +# int arr[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21 }; +# #define N sizeof arr / sizeof arr[0] +# int main() { +# int i, s; +# for (s=i=0; i