extract tests out of src

This commit is contained in:
Quentin Carbonneaux 2016-03-27 15:00:45 -04:00
parent aad52241c8
commit 36635660b4
35 changed files with 10 additions and 3 deletions

25
test/_alt.ssa Normal file
View file

@ -0,0 +1,25 @@
# 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
}

33
test/_dragon.ssa Normal file
View file

@ -0,0 +1,33 @@
# 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
}

15
test/_fix1.ssa Normal file
View file

@ -0,0 +1,15 @@
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
}

15
test/_fix2.ssa Normal file
View file

@ -0,0 +1,15 @@
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
}

20
test/_fix3.ssa Normal file
View file

@ -0,0 +1,20 @@
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
}

27
test/_fix4.ssa Normal file
View file

@ -0,0 +1,27 @@
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
}

21
test/_live.ssa Normal file
View file

@ -0,0 +1,21 @@
# 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
}

12
test/_rpo.ssa Normal file
View file

@ -0,0 +1,12 @@
function $test() {
@start
jmp @foo
@baz
jnz 1, @end, @foo
@bar
jmp @end
@foo
jnz 0, @bar, @baz
@end
ret
}

22
test/_spill1.ssa Normal file
View file

@ -0,0 +1,22 @@
# 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
}

22
test/_spill2.ssa Normal file
View file

@ -0,0 +1,22 @@
# 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
}

24
test/_spill3.ssa Normal file
View file

@ -0,0 +1,24 @@
# 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
}

59
test/abi1.ssa Normal file
View file

@ -0,0 +1,59 @@
# 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 <stdio.h>
# 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
# <<<

18
test/abi2.ssa Normal file
View file

@ -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. */
# <<<

43
test/abi3.ssa Normal file
View file

@ -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 <stdio.h>
# 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
# <<<

38
test/abi4.ssa Normal file
View file

@ -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 <stdio.h>
# typedef struct { char t[17]; } mem;
# extern mem test(void);
# int main() { mem m = test(); printf("%s\n", m.t); return 0; }
# <<<
# >>> output
# ABCDEFGHIJKLMNOP
# <<<

105
test/abi5.ssa Normal file
View file

@ -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 <stdio.h>
# 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
# <<<

16
test/align.ssa Normal file
View file

@ -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); }
# <<<

61
test/collatz.ssa Normal file
View file

@ -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); }
# <<<

103
test/cprime.ssa Normal file
View file

@ -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;
# }

17
test/cup.ssa Normal file
View file

@ -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; }
# <<<

30
test/dark.ssa Normal file
View file

@ -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); }
# <<<

24
test/double.ssa Normal file
View file

@ -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); }
# <<<

32
test/echo.ssa Normal file
View file

@ -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
# <<<

24
test/eucl.ssa Normal file
View file

@ -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); }
# <<<

29
test/euclc.ssa Normal file
View file

@ -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); }
# <<<

27
test/fpcnv.ssa Normal file
View file

@ -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;
# }
# <<<

118
test/go.sh Executable file
View file

@ -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
}
/^# <<</ {
if (p)
p = 0
}
p
" $FILE \
| sed -e 's/# //' \
| sed -e 's/#$//'
}
once() {
T="$1"
if ! test -f $T
then
echo "invalid test file $T" >&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

23
test/loop.ssa Normal file
View file

@ -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); }
# <<<

123
test/mandel.ssa Normal file
View file

@ -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
# #
# #
# #
# #
# * #
# **** #
# **** #
# *** #
# ***** #
# ********* #
# ************ #
# ***************** #
# **************** #
# *************** #
# **************** #
# **************** #
# ***************** #
# **************** #
# **************** #
# ************** #
# ************* #
# ************ #
# ********* #
# ***** #
# *********** #
# ***************** #
# ********************** #
# * *********************** ** #
# *************************** #
# ***************************** #
# * ******************************* ** #
# ** *********************************** #
# *********************************** * #
# *********************************** #
# ************************************* #
# ************************************* #
# *************************************** #
# *************************************** #
# *************************************** #
# **************************************** #
# * **************************************** #
# ********************************************** **** #
# **************************************************** #
# * ***************************************************** #
# * ***************************************************** #
# ***** **************************************** **** #
# * **************************************** * #
# **************************************** #
# *************************************** #
# **************************************** #
# *************************************** #
# **************************************** #
# ************************************ #
# *********************************** #
# ********************************* #
# ************************************ #
# *** ************* ************** *** #
# *********** ************ ** #
# ******** ******** #
# ** * * #
# #
# #
# #
# <<<

33
test/max.ssa Normal file
View file

@ -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); }
# <<<

32
test/prime.ssa Normal file
View file

@ -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); }
# <<<

29
test/puts10.ssa Normal file
View file

@ -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
# <<<

31
test/sum.ssa Normal file
View file

@ -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<N; i++) s+=arr[i];
# return !(sum(arr, N) == s);
# }
# <<<