aboutsummaryrefslogtreecommitdiff
path: root/sim/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'sim/testsuite')
-rw-r--r--sim/testsuite/ChangeLog4
-rwxr-xr-xsim/testsuite/configure4
-rw-r--r--sim/testsuite/sim/ft32/ChangeLog3
-rw-r--r--sim/testsuite/sim/ft32/allinsn.exp15
-rw-r--r--sim/testsuite/sim/ft32/basic.s862
-rw-r--r--sim/testsuite/sim/ft32/testutils.inc65
6 files changed, 953 insertions, 0 deletions
diff --git a/sim/testsuite/ChangeLog b/sim/testsuite/ChangeLog
index be7ad56..7580586 100644
--- a/sim/testsuite/ChangeLog
+++ b/sim/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-28 James Bowman <james.bowman@ftdichip.com>
+
+ * configure: Regenerate.
+
2014-03-10 Mike Frysinger <vapier@gentoo.org>
* configure: Regenerate.
diff --git a/sim/testsuite/configure b/sim/testsuite/configure
index f90bd47..1dcaa41 100755
--- a/sim/testsuite/configure
+++ b/sim/testsuite/configure
@@ -1918,6 +1918,10 @@ case "${target}" in
powerpc*-*-*)
sim_arch=ppc
;;
+ ft32-*-*)
+ sim_arch=ft32
+ sim_testsuite=yes
+ ;;
v850*-*-*)
sim_arch=v850
sim_igen=yes
diff --git a/sim/testsuite/sim/ft32/ChangeLog b/sim/testsuite/sim/ft32/ChangeLog
new file mode 100644
index 0000000..a0cfa18
--- /dev/null
+++ b/sim/testsuite/sim/ft32/ChangeLog
@@ -0,0 +1,3 @@
+2015-02-28 James Bowman <james.bowman@ftdichip.com>
+
+ * basic.s, allinsn.exp, testutils.inc: New files.
diff --git a/sim/testsuite/sim/ft32/allinsn.exp b/sim/testsuite/sim/ft32/allinsn.exp
new file mode 100644
index 0000000..730b422
--- /dev/null
+++ b/sim/testsuite/sim/ft32/allinsn.exp
@@ -0,0 +1,15 @@
+# ft32 simulator testsuite
+
+if [istarget ft32-*] {
+ # all machines
+ set all_machs "ft32"
+
+ foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.s]] {
+ # If we're only testing specific files and this isn't one of them,
+ # skip it.
+ if ![runtest_file_p $runtests $src] {
+ continue
+ }
+ run_sim_test $src $all_machs
+ }
+}
diff --git a/sim/testsuite/sim/ft32/basic.s b/sim/testsuite/sim/ft32/basic.s
new file mode 100644
index 0000000..c92f295
--- /dev/null
+++ b/sim/testsuite/sim/ft32/basic.s
@@ -0,0 +1,862 @@
+# check that basic insns work.
+# mach: ft32
+
+.include "testutils.inc"
+
+ start
+
+ ldk $r4,10
+ add $r4,$r4,23
+ EXPECT $r4,33
+
+# lda, sta
+ .data
+tmp: .long 0
+ .text
+
+ xor.l $r0,$r0,$r0
+ EXPECT $r0,0x00000000
+ xor.l $r0,$r0,$r0
+ add.l $r0,$r0,1
+ EXPECT $r0,0x00000001
+
+ ldk.l $r0,0x4567
+ EXPECT $r0,0x00004567
+
+ lpm.l $r0,k_12345678
+ EXPECT $r0,0x12345678
+
+ sta.l tmp,$r0
+ lda.l $r1,tmp
+ EXPECT $r1,0x12345678
+
+ lda.b $r1,tmp
+ EXPECT $r1,0x00000078
+
+ lda.b $r1,tmp+1
+ EXPECT $r1,0x00000056
+
+ lda.b $r1,tmp+2
+ EXPECT $r1,0x00000034
+
+ lda.b $r1,tmp+3
+ EXPECT $r1,0x00000012
+
+ sta.b tmp+1,$r0
+ lda.l $r1,tmp+0
+ EXPECT $r1,0x12347878
+
+# immediate
+ ldk.l $r1,12
+ add.l $r1,$r1,4
+ EXPECT $r1,0x00000010
+ add.l $r1,$r1,0x1ff
+ EXPECT $r1,0x0000020f
+ add.l $r1,$r1,-0x200
+ EXPECT $r1,0x0000000f
+
+# addk
+ xor.l $r1,$r0,$r0
+ add.l $r2,$r1,127
+ EXPECT $r2,0x0000007f
+
+ add.l $r2,$r2,127
+ EXPECT $r2,0x000000fe
+
+ add.l $r2,$r2,-127
+ EXPECT $r2,0x0000007f
+
+ add.l $r2,$r2,-128
+ EXPECT $r2,0xffffffff
+
+ add.l $r2,$r2,1
+ EXPECT $r2,0x00000000
+
+# mul
+ ldk.l $r1,100
+ ldk.l $r2,77
+ mul.l $r3,$r1,$r2
+ EXPECT $r3,0x00001e14
+
+ # 0x12345678 ** 2 = 0x14b66dc1df4d840L
+ mul.l $r3,$r0,$r0
+ EXPECT $r3,0x1df4d840
+ muluh.l $r3,$r0,$r0
+ EXPECT $r3,0x014b66dc
+
+# push and pop
+ push.l $r0
+ EXPECT $sp,0x0000fffc
+ ldi.l $r3,$sp,0
+ EXPECT $r3,0x12345678
+
+ pop.l $r4
+ EXPECT $sp,0x00000000
+ EXPECT $r4,0x12345678
+
+ ldk.l $r1,0x1111
+ push.l $r1
+ ldk.l $r1,0x2222
+ push.l $r1
+ ldk.l $r1,0x3333
+ push.l $r1
+ ldk.l $r1,0x4444
+ push.l $r1
+ EXPECT $sp,0x0000fff0
+ pop.l $r1
+ EXPECT $r1,0x00004444
+ pop.l $r1
+ EXPECT $r1,0x00003333
+ pop.l $r1
+ EXPECT $r1,0x00002222
+ pop.l $r1
+ EXPECT $r1,0x00001111
+
+# push and pop with $sp changes
+ ldk.l $r1,0xa111
+ push.l $r1
+ sub.l $sp,$sp,4
+ ldk.l $r1,0xa222
+ push.l $r1
+ add.l $sp,$sp,-36
+ add.l $sp,$sp,36
+ pop.l $r1
+ EXPECT $r1,0x0000a222
+ add.l $sp,$sp,4
+ pop.l $r1
+ EXPECT $r1,0x0000a111
+
+# sti
+ ldk.l $r2,80
+ EXPECT $r2,0x00000050
+ sti.l $r2,0,$r0
+ lda.l $r1,80
+ EXPECT $r1,0x12345678
+
+ ldk.l $r3,0xF0
+ sti.b $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0x123456f0
+
+ add.l $r2,$r2,1
+ sti.l $r2,0,$r0
+ sti.b $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0x1234f078
+
+ add.l $r2,$r2,1
+ sti.l $r2,0,$r0
+ sti.b $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0x12f05678
+
+ add.l $r2,$r2,1
+ sti.l $r2,0,$r0
+ sti.b $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0xf0345678
+
+ ldk.l $r2,80
+ sti.l $r2,0,$r0
+ ldk.s $r3,0xbeef
+ sti.s $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0x1234beef
+ add.l $r2,$r2,2
+ sti.s $r2,0,$r3
+ lda.l $r1,80
+ EXPECT $r1,0xbeefbeef
+
+# lpmi
+
+ ldk.l $r1,k_12345678
+ lpmi.l $r2,$r1,0
+ EXPECT $r2,0x12345678
+
+ lpmi.b $r2,$r1,0
+ EXPECT $r2,0x00000078
+
+ add.l $r1,$r1,1
+ lpmi.b $r2,$r1,0
+ EXPECT $r2,0x00000056
+
+ add.l $r1,$r1,1
+ lpmi.b $r2,$r1,0
+ EXPECT $r2,0x00000034
+
+ add.l $r1,$r1,1
+ lpmi.b $r2,$r1,0
+ EXPECT $r2,0x00000012
+
+ lpmi.l $r2,$r1,4
+ EXPECT $r2,0xabcdef01
+
+ lpmi.l $r2,$r1,-4
+ EXPECT $r2,0x10111213
+
+ lpmi.b $r2,$r1,-4
+ EXPECT $r2,0x00000010
+
+ ldk.l $r1,k_12345678
+ lpmi.s $r2,$r1,0
+ EXPECT $r2,0x00005678
+ lpmi.s $r2,$r1,2
+ EXPECT $r2,0x00001234
+ lpmi.b $r2,$r1,6
+ EXPECT $r2,0x000000cd
+ lpmi.b $r2,$r1,7
+ EXPECT $r2,0x000000ab
+ lpmi.b $r2,$r1,-1
+ EXPECT $r2,0x00000010
+ lpmi.s $r2,$r1,-2
+ EXPECT $r2,0x00001011
+
+ ldk.l $r1,k_12345678-127
+ lpmi.b $r2,$r1,127
+ EXPECT $r2,0x00000078
+
+ ldk.l $r1,k_12345678+128
+ lpmi.b $r2,$r1,-128
+ EXPECT $r2,0x00000078
+
+# shifts
+
+ lpm.l $r0,k_12345678
+ ldk.l $r2,4
+ ashl.l $r1,$r0,$r2
+ EXPECT $r1,0x23456780
+ lshr.l $r1,$r0,$r2
+ EXPECT $r1,0x01234567
+ ashr.l $r1,$r0,$r2
+ EXPECT $r1,0x01234567
+
+ lpm.l $r0,k_abcdef01
+ ashl.l $r1,$r0,$r2
+ EXPECT $r1,0xbcdef010
+ lshr.l $r1,$r0,$r2
+ EXPECT $r1,0x0abcdef0
+ ashr.l $r1,$r0,$r2
+ EXPECT $r1,0xfabcdef0
+
+# rotate right
+
+ lpm.l $r0,k_12345678
+ ror.l $r1,$r0,0
+ EXPECT $r1,0x12345678
+ ror.l $r1,$r0,12
+ EXPECT $r1,0x67812345
+ ror.l $r1,$r0,-4
+ EXPECT $r1,0x23456781
+
+# jmpx
+ ldk $r28,0xaaaaa
+ jmpx 0,$r28,1,failcase
+ jmpx 1,$r28,0,failcase
+ jmpx 2,$r28,1,failcase
+ jmpx 3,$r28,0,failcase
+ jmpx 4,$r28,1,failcase
+ jmpx 5,$r28,0,failcase
+ jmpx 6,$r28,1,failcase
+ jmpx 7,$r28,0,failcase
+ jmpx 8,$r28,1,failcase
+ jmpx 9,$r28,0,failcase
+ jmpx 10,$r28,1,failcase
+ jmpx 11,$r28,0,failcase
+ jmpx 12,$r28,1,failcase
+ jmpx 13,$r28,0,failcase
+ jmpx 14,$r28,1,failcase
+ jmpx 15,$r28,0,failcase
+ jmpx 16,$r28,1,failcase
+ jmpx 17,$r28,0,failcase
+ jmpx 18,$r28,1,failcase
+ jmpx 19,$r28,0,failcase
+
+ move $r29,$r28
+ ldk $r28,0
+ jmpx 0,$r29,1,failcase
+ jmpx 1,$r29,0,failcase
+ jmpx 2,$r29,1,failcase
+ jmpx 3,$r29,0,failcase
+ jmpx 4,$r29,1,failcase
+ jmpx 5,$r29,0,failcase
+ jmpx 6,$r29,1,failcase
+ jmpx 7,$r29,0,failcase
+ jmpx 8,$r29,1,failcase
+ jmpx 9,$r29,0,failcase
+ jmpx 10,$r29,1,failcase
+ jmpx 11,$r29,0,failcase
+ jmpx 12,$r29,1,failcase
+ jmpx 13,$r29,0,failcase
+ jmpx 14,$r29,1,failcase
+ jmpx 15,$r29,0,failcase
+ jmpx 16,$r29,1,failcase
+ jmpx 17,$r29,0,failcase
+ jmpx 18,$r29,1,failcase
+ jmpx 19,$r29,0,failcase
+
+ move $r30,$r29
+ ldk $r29,0
+ jmpx 0,$r30,1,failcase
+ jmpx 1,$r30,0,failcase
+ jmpx 2,$r30,1,failcase
+ jmpx 3,$r30,0,failcase
+ jmpx 4,$r30,1,failcase
+ jmpx 5,$r30,0,failcase
+ jmpx 6,$r30,1,failcase
+ jmpx 7,$r30,0,failcase
+ jmpx 8,$r30,1,failcase
+ jmpx 9,$r30,0,failcase
+ jmpx 10,$r30,1,failcase
+ jmpx 11,$r30,0,failcase
+ jmpx 12,$r30,1,failcase
+ jmpx 13,$r30,0,failcase
+ jmpx 14,$r30,1,failcase
+ jmpx 15,$r30,0,failcase
+ jmpx 16,$r30,1,failcase
+ jmpx 17,$r30,0,failcase
+ jmpx 18,$r30,1,failcase
+ jmpx 19,$r30,0,failcase
+
+# callx
+ ldk $r30,0xaaaaa
+ callx 0,$r30,0,skip1
+ jmp failcase
+ callx 1,$r30,1,skip1
+ jmp failcase
+ callx 2,$r30,0,skip1
+ jmp failcase
+ callx 3,$r30,1,skip1
+ jmp failcase
+
+ callx 0,$r30,1,skip1
+ ldk $r30,0x123
+ EXPECT $r30,0x123
+
+#define BIT(N,M) ((((N) & 15) << 5) | (M))
+# bextu
+ bextu.l $r1,$r0,(0<<5)|0
+ EXPECT $r1,0x00005678
+ bextu.l $r1,$r0,(4<<5)|0
+ EXPECT $r1,0x00000008
+ bextu.l $r1,$r0,(4<<5)|4
+ EXPECT $r1,0x00000007
+ bextu.l $r1,$r0,(4<<5)|28
+ EXPECT $r1,0x00000001
+ bextu.l $r1,$r0,(8<<5)|16
+ EXPECT $r1,0x00000034
+ ldk.l $r2,-1
+ bextu.l $r1,$r2,(6<<5)|(3)
+ EXPECT $r1,0x0000003f
+
+# bexts
+ bexts.l $r1,$r0,(8<<5)|0
+ EXPECT $r1,0x00000078
+ bexts.l $r1,$r0,(0<<5)|16
+ EXPECT $r1,0x00001234
+ bexts.l $r1,$r0,(4<<5)|0
+ EXPECT $r1,0xfffffff8
+ # extract the '5' digit in widths 4-1
+ bexts.l $r1,$r0,(4<<5)|12
+ EXPECT $r1,0x00000005
+ bexts.l $r1,$r0,(3<<5)|12
+ EXPECT $r1,0xfffffffd
+ bexts.l $r1,$r0,(2<<5)|12
+ EXPECT $r1,0x00000001
+ bexts.l $r1,$r0,(1<<5)|12
+ EXPECT $r1,0xffffffff
+
+# btst
+ # low four bits should be 0,0,0,1
+ btst.l $r0,(1<<5)|0
+ jmpc nz,failcase
+ btst.l $r0,(1<<5)|1
+ jmpc nz,failcase
+ btst.l $r0,(1<<5)|2
+ jmpc nz,failcase
+ btst.l $r0,(1<<5)|3
+ jmpc z,failcase
+
+ # the 6 bit field starting at position 24 is positive
+ btst.l $r0,(6<<5)|24
+ jmpc s,failcase
+ # the 5 bit field starting at position 24 is negative
+ btst.l $r0,(5<<5)|24
+ jmpc ns,failcase
+
+ EXPECT $r0,0x12345678
+
+# bins
+ bins.l $r1,$r0,(8 << 5) | (0)
+ EXPECT $r1,0x12345600
+
+ bins.l $r1,$r0,(0 << 5) | (8)
+ EXPECT $r1,0x12000078
+
+ ldk.l $r1,(0xff << 10) | (8 << 5) | (8)
+ bins.l $r1,$r0,$r1
+ EXPECT $r1,0x1234ff78
+
+ call litr1
+ .long (0x8dd1 << 10) | (0 << 5) | (0)
+ bins.l $r1,$r0,$r1
+ EXPECT $r1,0x12348dd1
+
+ call litr1
+ .long (0x8dd1 << 10) | (0 << 5) | (16)
+ bins.l $r1,$r0,$r1
+ EXPECT $r1,0x8dd15678
+
+ ldk.l $r1,(0xde << 10) | (8 << 5) | (0)
+ bins.l $r1,$r0,$r1
+ EXPECT $r1,0x123456de
+
+# ldl
+ ldk.l $r0,0
+ ldl.l $r3,$r0,0
+ EXPECT $r3,0x00000000
+ ldk.l $r0,-1
+ ldl.l $r3,$r0,-1
+ EXPECT $r3,0xffffffff
+ ldk.l $r0,(0x12345678 >> 10)
+ ldl.l $r3,$r0,(0x12345678 & 0x3ff)
+ EXPECT $r3,0x12345678
+ ldk.l $r0,(0xe2345678 >> 10)
+ ldl.l $r3,$r0,(0xe2345678 & 0x3ff)
+ EXPECT $r3,0xe2345678
+
+# flip
+ ldk.l $r0,0x0000001
+ flip.l $r1,$r0,0
+ EXPECT $r1,0x00000001
+
+ lpm.l $r0,k_12345678
+ flip.l $r1,$r0,0
+ EXPECT $r1,0x12345678
+ flip.l $r1,$r0,24
+ EXPECT $r1,0x78563412
+ flip.l $r1,$r0,31
+ EXPECT $r1,0x1e6a2c48
+
+# stack push pop
+
+ EXPECT $sp,0x00000000
+ ldk.l $r6,0x6666
+ push.l $r6
+ or.l $r0,$r0,$r0 # xxx
+ EXPECT $sp,0x0000fffc
+ ldi.l $r1,$sp,0
+ EXPECT $r1,0x00006666
+ pop.l $r1
+ EXPECT $r1,0x00006666
+ EXPECT $sp,0x00000000
+
+# call/return
+ call fowia
+ push.l $r1
+ call fowia
+ pop.l $r2
+ sub.l $r1,$r1,$r2
+ EXPECT $r1,0x00000008
+
+# add,carry
+
+ ldk.l $r0,0
+ ldk.l $r1,0
+ call add64
+ EXPECT $r1,0x00000000
+ EXPECT $r0,0x00000000
+
+ lpm.l $r0,k_abcdef01
+ lpm.l $r1,k_abcdef01
+ call add64
+ EXPECT $r1,0x00000001
+ EXPECT $r0,0x579bde02
+
+ ldk.l $r0,4
+ ldk.l $r1,-5
+ call add64
+ EXPECT $r1,0x00000000
+ EXPECT $r0,0xffffffff
+
+ ldk.l $r0,5
+ ldk.l $r1,-5
+ call add64
+ EXPECT $r1,0x00000001
+ EXPECT $r0,0x00000000
+
+ lpm.l $r0,k_12345678
+ ldk.l $r1,-1
+ call add64
+ EXPECT $r1,0x00000001
+ EXPECT $r0,0x12345677
+
+ ldk.l $r0,-1
+ ldk.l $r1,-1
+ call add64
+ EXPECT $r1,0x00000001
+ EXPECT $r0,0xfffffffe
+
+# inline literal
+ call lit
+ .long 0xdecafbad
+ EXPECT $r0,0xdecafbad
+
+ ldk.l $r1,0xee
+ call lit
+ ldk.l $r1,0xfe
+ EXPECT $r1,0x000000ee
+
+ call lit
+ .long 0x01020304
+ EXPECT $r0,0x01020304
+
+ call lit
+ .long lit
+ calli $r0
+ .long 0xffaa55aa
+ EXPECT $r0,0xffaa55aa
+
+# comparisons
+ ldk.l $r0,-100
+ ldk.l $r1,100
+ cmp.l $r0,$r1
+
+ ldk.l $r2,0
+ jmpc lt,.c1
+ ldk.l $r2,1
+.c1:
+ EXPECT $r2,0x00000000
+
+ ldk.l $r2,0
+ jmpc gt,.c2
+ ldk.l $r2,1
+.c2:
+ EXPECT $r2,0x00000001
+
+ ldk.l $r2,0
+ jmpc a,.c3
+ ldk.l $r2,1
+.c3:
+ EXPECT $r2,0x00000000
+
+ ldk.l $r2,0
+ jmpc b,.c4
+ ldk.l $r2,1
+.c4:
+ EXPECT $r2,0x00000001
+
+ ldk.l $r2,0
+ jmpc be,.c5
+ ldk.l $r2,1
+.c5:
+ EXPECT $r2,0x00000001
+
+# 8-bit comparisons
+ ldk.l $r0,0x8fe
+ ldk.l $r1,0x708
+ cmp.b $r0,$r1
+
+ ldk.l $r2,0
+ jmpc lt,.8c1
+ ldk.l $r2,1
+.8c1:
+ EXPECT $r2,0x00000000
+
+ ldk.l $r2,0
+ jmpc gt,.8c2
+ ldk.l $r2,1
+.8c2:
+ EXPECT $r2,0x00000001
+
+ ldk.l $r2,0
+ jmpc a,.8c3
+ ldk.l $r2,1
+.8c3:
+ EXPECT $r2,0x00000000
+
+ ldk.l $r2,0
+ jmpc b,.8c4
+ ldk.l $r2,1
+.8c4:
+ EXPECT $r2,0x00000001
+
+ ldk.l $r2,0
+ jmpc be,.8c5
+ ldk.l $r2,1
+.8c5:
+ EXPECT $r2,0x00000001
+
+ ldk.l $r0,0x8aa
+ ldk.l $r1,0x7aa
+ cmp.b $r0,$r1
+
+ ldk.l $r2,0
+ jmpc z,.8c6
+ ldk.l $r2,1
+.8c6:
+ EXPECT $r2,0x00000000
+
+ ldk.b $r0,1
+ ldk.b $r2,0xe0
+ cmp.b $r2,0x1c0
+ jmpc a,.8c7
+ ldk.b $r0,0
+.8c7:
+ EXPECT $r0,0x00000001
+
+# conditional call
+ cmp.l $r0,$r0
+ callc z,lit
+ .long 0xccddeeff
+ callc nz,zr0
+ EXPECT $r0,0xccddeeff
+
+# modify return address
+ ldk.l $r0,0x66
+ call skip1
+ ldk.l $r0,0xAA
+ EXPECT $r0,0x00000066
+
+ ldk.l $r0,0x77
+ call skip2
+ ldk.l $r0,0xBB
+ EXPECT $r0,0x00000077
+
+# simple recursive function
+ ldk.l $r0,1
+ call factorial
+ EXPECT $r0,0x00000001
+ ldk.l $r0,2
+ call factorial
+ EXPECT $r0,0x00000002
+ ldk.l $r0,3
+ call factorial
+ EXPECT $r0,0x00000006
+ ldk.l $r0,4
+ call factorial
+ EXPECT $r0,0x00000018
+ ldk.l $r0,5
+ call factorial
+ EXPECT $r0,0x00000078
+ ldk.l $r0,6
+ call factorial
+ EXPECT $r0,0x000002d0
+ ldk.l $r0,7
+ call factorial
+ EXPECT $r0,0x000013b0
+ ldk.l $r0,12
+ call factorial
+ EXPECT $r0,0x1c8cfc00
+
+# read sp after a call
+ call nullfunc
+ EXPECT $sp,0x00000000
+
+# CALLI->RETURN
+ ldk.l $r4,nullfunc
+ calli $r4
+ EXPECT $sp,0x00000000
+
+# Link/unlink
+ ldk.l $r14,0x17566
+
+ link $r14,48
+ EXPECT $r14,0x0000fffc
+ sub.l $sp,$sp,200
+ unlink $r14
+ EXPECT $r14,0x00017566
+
+# LINK->UNLINK
+ link $r14,48
+ unlink $r14
+ EXPECT $r14,0x00017566
+
+# LINK->JUMPI
+ ldk.l $r3,.here
+ link $r14,48
+ jmpi $r3
+ jmp failcase
+.here:
+ unlink $r14
+ EXPECT $r14,0x00017566
+
+# LINK->RETURN
+# (This is a nonsense combination, but can still exericse it by
+# using a negative parameter for the link. "link $r14,-4" leaves
+# $sp exactly unchanged.)
+ ldk.l $r0,.returnhere
+ push.l $r0
+ link $r14,0xfffc
+ return
+.returnhere:
+ EXPECT $sp,0x00000000
+
+# LPMI->CALLI
+ ldk.l $r0,k_abcdef01
+ ldk.l $r1,increment
+ lpmi.l $r0,$r0,0
+ calli $r1
+ EXPECT $r0,0xabcdef02
+
+# STRLen
+ lpm.l $r4,str3
+ sta.l tmp,$r4
+ ldk.l $r0,tmp
+ strlen.b $r1,$r0
+ EXPECT $r1,0x00000003
+ strlen.s $r1,$r0
+ EXPECT $r1,0x00000003
+ strlen.l $r1,$r0
+ EXPECT $r1,0x00000003
+
+ ldk.l $r4,0
+ sta.b 4,$r4
+ strlen.l $r1,$r0
+ EXPECT $r1,0x00000000
+
+ ldk.l $r4,-1
+ sta.l 4,$r4
+ lpm.l $r4,str3
+ sta.l 8,$r4
+ strlen.l $r1,$r0
+ EXPECT $r1,0x00000007
+
+# MEMSet
+ ldk.l $r0,4
+ ldk.l $r1,0xaa
+ memset.s $r0,$r1,8
+ ldk.l $r1,0x55
+ memset.b $r0,$r1,5
+ lda.l $r0,4
+ EXPECT $r0,0x55555555
+ lda.l $r0,8
+ EXPECT $r0,0xaaaaaa55
+
+# first cycle after mispredict
+ ldk.l $r0,3
+ cmp.l $r0,$r0
+ jmpc nz,failcase
+ add.l $r0,$r0,7
+ EXPECT $r0,0x0000000a
+ jmpc nz,failcase
+ push.l $r0
+ EXPECT $sp,0x0000fffc
+ pop.l $r0
+
+# $sp access after stall
+ lpm.l $r13,0
+ push.l $r0
+ EXPECT $sp,0x0000fffc
+ pop.l $r0
+
+ push.l $r0
+ add.l $sp,$sp,-484
+ EXPECT $sp,0x0000fe18
+ EXPECT $sp,0x0000fe18
+ EXPECT $sp,0x0000fe18
+ add.l $sp,$sp,484
+ EXPECT $sp,0x0000fffc
+ pop.l $r0
+
+# atomic exchange
+ lpm.l $r0,k_12345678
+ lpm.l $r1,k_abcdef01
+ sta.l 100,$r1
+ exa.l $r0,100
+ EXPECT $r0,0xabcdef01
+ lda.l $r0,100
+ EXPECT $r0,0x12345678
+
+ lpm.l $r0,k_12345678
+ lpm.l $r1,k_abcdef01
+ sta.l 144,$r1
+ ldk.l $r7,20
+ exi.l $r0,$r7,124
+ EXPECT $r0,0xabcdef01
+ lda.l $r0,144
+ EXPECT $r0,0x12345678
+
+ lpm.l $r0,k_12345678
+ lpm.l $r1,k_abcdef01
+ push $r1
+ exi.l $r0,$sp,0
+ EXPECT $r0,0xabcdef01
+ pop.l $r0
+ EXPECT $r0,0x12345678
+
+# final stack check
+ EXPECT $sp,0x00000000
+
+ PASS
+
+# --------------------------------------------------
+
+skip1: # skip the instruction after the call
+ pop.l $r1
+ add.l $r1,$r1,4
+ push.l $r1
+ return
+
+skipparent: # skip the instruction after the caller's call
+ ldi.l $r1,$sp,4
+ add.l $r1,$r1,4
+ sti.l $sp,4,$r1
+ return
+skip2:
+ call skipparent
+ return
+
+add64:
+ addcc.l $r0,$r1
+ add.l $r0,$r0,$r1
+ ldk.l $r1,0
+ jmpc nc,.done
+ ldk.l $r1,1
+.done:
+ return
+
+fowia: # find out where I'm at
+ ldi.l $r1,$sp,0
+ return
+
+lit: # load literal to $r0
+ pop.l $r14
+ lpmi.l $r0,$r14,0
+ add.l $r14,$r14,4
+ jmpi $r14
+zr0:
+ ldk.l $r0,0
+ return
+litr1:
+ ldi.l $r1,$sp,0
+ add.l $r1,$r1,4
+ sti.l $sp,0,$r1
+ lpmi.l $r1,$r1,-4
+ return
+
+factorial:
+ ldk.l $r1,1
+ cmp.l $r0,$r1
+ jmpc z,.factdone
+ push.l $r0
+ add.l $r0,$r0,-1
+ call factorial
+ pop.l $r1
+ mul.l $r0,$r0,$r1
+.factdone:
+ return
+
+nullfunc:
+ return
+
+increment:
+ add.l $r0,$r0,1
+ return
+
+ .long 0x10111213
+k_12345678:
+ .long 0x12345678
+k_abcdef01:
+ .long 0xabcdef01
+str3:
+ .string "abc"
diff --git a/sim/testsuite/sim/ft32/testutils.inc b/sim/testsuite/sim/ft32/testutils.inc
new file mode 100644
index 0000000..c07811f
--- /dev/null
+++ b/sim/testsuite/sim/ft32/testutils.inc
@@ -0,0 +1,65 @@
+
+# Write ch to the standard output
+ .macro outch ch
+ ldk $r0,\ch
+ sta 0x10000,$r0
+ .endm
+
+# End the test with return code c
+ .macro exit c
+ ldk $r0,\c
+ sta 0x1fffc,$r0
+ .endm
+
+# All assembler tests should start with this macro "start"
+ .macro start
+ .text
+
+ jmp __start
+ jmp __start
+ reti
+
+ .data
+ccsave: .long 0
+ .text
+
+# Fiddling to load $cc from the following word in program memory
+loadcc:
+ exi $r29,$sp,0
+ lpmi $cc,$r29,0
+ add $r29,$r29,4
+ exi $r29,$sp,0
+ return
+
+failcase:
+ outch 'f'
+ outch 'a'
+ outch 'i'
+ outch 'l'
+ outch '\n'
+ exit 1
+
+__start:
+
+ .endm
+
+# At the end of the test, the code should reach this macro PASS
+ .macro PASS
+ outch 'p'
+ outch 'a'
+ outch 's'
+ outch 's'
+ outch '\n'
+ exit 0
+ .endm
+
+# Confirm that reg has value, and fail immediately if not
+# Preserves all registers
+ .macro EXPECT reg,value
+ sta ccsave,$cc
+ call loadcc
+ .long \value
+ cmp \reg,$cc
+ jmpc nz,failcase
+ lda $cc,ccsave
+ .endm