summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/mono/.gitignore1
-rw-r--r--test/mono/addsubexist.sail75
-rw-r--r--test/mono/fnreduce.sail69
-rw-r--r--test/mono/set.sail29
-rw-r--r--test/mono/test.ml1
-rwxr-xr-xtest/mono/test.sh44
-rw-r--r--test/mono/tests9
-rw-r--r--test/mono/union-exist.sail33
-rw-r--r--test/mono/varmatch.sail19
-rw-r--r--test/mono/vector.sail21
-rw-r--r--test/ocaml/hello_world/expect2
-rw-r--r--test/ocaml/hello_world/hello_world.sail18
-rw-r--r--test/ocaml/loop/expect100
-rw-r--r--test/ocaml/loop/loop.sail19
-rw-r--r--test/ocaml/lsl/expect4
-rw-r--r--test/ocaml/lsl/lsl.sail28
-rw-r--r--test/ocaml/pattern1/expect1
-rw-r--r--test/ocaml/pattern1/pattern.sail9
-rw-r--r--test/ocaml/prelude.sail288
-rw-r--r--test/ocaml/reg_passing/expect3
-rw-r--r--test/ocaml/reg_passing/reg_passing.sail36
-rwxr-xr-xtest/ocaml/run_tests.sh96
-rw-r--r--test/ocaml/short_circuit/expect1
-rw-r--r--test/ocaml/short_circuit/sc.sail15
-rw-r--r--test/ocaml/string_equality/expect1
-rw-r--r--test/ocaml/string_equality/string_equality.sail3
-rw-r--r--test/ocaml/trycatch/expect2
-rw-r--r--test/ocaml/trycatch/tc.sail23
-rw-r--r--test/ocaml/types/expect5
-rw-r--r--test/ocaml/types/types.sail44
-rw-r--r--test/ocaml/vec_32_64/expect2
-rw-r--r--test/ocaml/vec_32_64/vec_32_64.sail28
-rw-r--r--test/ocaml/void/expect1
-rw-r--r--test/ocaml/void/void.sail14
-rwxr-xr-xtest/run_tests.sh8
-rw-r--r--test/typecheck/fail/assignment_simple1.sail16
-rw-r--r--test/typecheck/fail/assignment_simple2.sail15
-rw-r--r--test/typecheck/fail/assignment_simple3.sail15
-rw-r--r--test/typecheck/fail/bitwise_not_gen1.sail8
-rw-r--r--test/typecheck/fail/bitwise_not_gen2.sail8
-rw-r--r--test/typecheck/fail/bv_simple_index_no_cast.sail9
-rw-r--r--test/typecheck/fail/case_simple1.sail9
-rw-r--r--test/typecheck/fail/cast_lexp1.sail7
-rw-r--r--test/typecheck/fail/cast_simple.sail7
-rw-r--r--test/typecheck/fail/default_order.sail6
-rw-r--r--test/typecheck/fail/eff_escape.sail7
-rw-r--r--test/typecheck/fail/eff_undef.sail7
-rw-r--r--test/typecheck/fail/ex_cast.sail12
-rw-r--r--test/typecheck/fail/exist1.sail30
-rw-r--r--test/typecheck/fail/flow_gt1.sail28
-rw-r--r--test/typecheck/fail/flow_gt2.sail28
-rw-r--r--test/typecheck/fail/flow_gteq1.sail28
-rw-r--r--test/typecheck/fail/flow_gteq2.sail28
-rw-r--r--test/typecheck/fail/flow_lt1.sail19
-rw-r--r--test/typecheck/fail/flow_lt2.sail19
-rw-r--r--test/typecheck/fail/flow_lteq1.sail28
-rw-r--r--test/typecheck/fail/flow_lteq2.sail28
-rw-r--r--test/typecheck/fail/fun_simple_constraints1.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints2.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints3.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints4.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints5.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints6.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints7.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints8.sail18
-rw-r--r--test/typecheck/fail/fun_simple_constraints9.sail8
-rw-r--r--test/typecheck/fail/funret1.sail16
-rw-r--r--test/typecheck/fail/funret2.sail16
-rw-r--r--test/typecheck/fail/funret3.sail16
-rw-r--r--test/typecheck/fail/mips_CP0Cause_BD_assign1.sail27
-rw-r--r--test/typecheck/fail/mips_CauseReg1.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg2.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg3.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg4.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg5.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg6.sail14
-rw-r--r--test/typecheck/fail/mips_CauseReg7.sail15
-rw-r--r--test/typecheck/fail/mismatch_return.sail7
-rw-r--r--test/typecheck/fail/modify_assignment1.sail8
-rw-r--r--test/typecheck/fail/modify_assignment2.sail8
-rw-r--r--test/typecheck/fail/modify_let_bound.sail16
-rw-r--r--test/typecheck/fail/modify_type_chain1.sail8
-rw-r--r--test/typecheck/fail/modify_type_chain2.sail8
-rw-r--r--test/typecheck/fail/modify_type_chain3.sail8
-rw-r--r--test/typecheck/fail/modify_type_chain4.sail8
-rw-r--r--test/typecheck/fail/modify_type_chain5.sail8
-rw-r--r--test/typecheck/fail/my_unsigned1.sail8
-rw-r--r--test/typecheck/fail/nat_set.sail9
-rw-r--r--test/typecheck/fail/nondet.sail10
-rw-r--r--test/typecheck/fail/option_either1.sail35
-rw-r--r--test/typecheck/fail/overlap_field_wreg.sail13
-rw-r--r--test/typecheck/fail/procstate1.sail16
-rw-r--r--test/typecheck/fail/pure_record_arity.sail25
-rw-r--r--test/typecheck/fail/pure_record_arity2.sail25
-rw-r--r--test/typecheck/fail/reg_mod.sail11
-rw-r--r--test/typecheck/fail/return_simple2.sail9
-rw-r--r--test/typecheck/fail/return_simple3.sail8
-rw-r--r--test/typecheck/fail/return_simple4.sail8
-rw-r--r--test/typecheck/fail/return_simple5.sail8
-rw-r--r--test/typecheck/fail/return_simple6.sail8
-rw-r--r--test/typecheck/fail/set_spsr1.sail17
-rw-r--r--test/typecheck/fail/set_spsr2.sail17
-rw-r--r--test/typecheck/fail/set_spsr3.sail17
-rw-r--r--test/typecheck/fail/set_spsr4.sail17
-rw-r--r--test/typecheck/fail/set_spsr5.sail17
-rw-r--r--test/typecheck/fail/vec_pat1.sail17
-rw-r--r--test/typecheck/fail/vector_access1.sail12
-rw-r--r--test/typecheck/fail/vector_access2.sail12
-rw-r--r--test/typecheck/fail/vector_access3.sail12
-rw-r--r--test/typecheck/fail/vector_access4.sail12
-rw-r--r--test/typecheck/fail/vector_append1.sail18
-rw-r--r--test/typecheck/fail/vector_append2.sail18
-rw-r--r--test/typecheck/fail/vector_append3.sail18
-rw-r--r--test/typecheck/fail/vector_append_gen1.sail14
-rw-r--r--test/typecheck/fail/vector_append_gen2.sail14
-rw-r--r--test/typecheck/fail/vector_append_old.sail14
-rw-r--r--test/typecheck/fail/vector_arity.sail4
-rw-r--r--test/typecheck/fail/vector_subrange_gen1.sail20
-rw-r--r--test/typecheck/fail/word_width_bytes_mips.sail11
-rw-r--r--test/typecheck/pass/add_real.sail5
-rw-r--r--test/typecheck/pass/add_vec_exts_no_annot.sail19
-rw-r--r--test/typecheck/pass/add_vec_exts_no_annot_overload.sail19
-rw-r--r--test/typecheck/pass/add_vec_lit.sail10
-rw-r--r--test/typecheck/pass/arm_FPEXC1.sail53
-rw-r--r--test/typecheck/pass/arm_types.sail140
-rw-r--r--test/typecheck/pass/as_pattern.sail7
-rw-r--r--test/typecheck/pass/assignment_simple.sail16
-rw-r--r--test/typecheck/pass/atomcase.sail18
-rw-r--r--test/typecheck/pass/bitwise_not.sail7
-rw-r--r--test/typecheck/pass/bitwise_not_gen.sail8
-rw-r--r--test/typecheck/pass/bitwise_not_x3.sail7
-rw-r--r--test/typecheck/pass/bv_simple_index.sail11
-rw-r--r--test/typecheck/pass/bv_simple_index_bit.sail9
-rw-r--r--test/typecheck/pass/case_simple1.sail9
-rw-r--r--test/typecheck/pass/case_simple2.sail9
-rw-r--r--test/typecheck/pass/case_simple_constraints.sail18
-rw-r--r--test/typecheck/pass/cast_lexp1.sail7
-rw-r--r--test/typecheck/pass/cast_lexp2.sail7
-rw-r--r--test/typecheck/pass/cast_simple.sail7
-rw-r--r--test/typecheck/pass/cons_pattern.sail8
-rw-r--r--test/typecheck/pass/cons_pattern_synonym.sail7
-rw-r--r--test/typecheck/pass/default_order.sail1
-rw-r--r--test/typecheck/pass/deinfix_plus.sail12
-rw-r--r--test/typecheck/pass/ex_cast.sail12
-rw-r--r--test/typecheck/pass/exint.sail22
-rw-r--r--test/typecheck/pass/exist1.sail30
-rw-r--r--test/typecheck/pass/exist2.sail46
-rw-r--r--test/typecheck/pass/exist_pattern.sail42
-rw-r--r--test/typecheck/pass/exist_simple.sail15
-rw-r--r--test/typecheck/pass/exist_subrange.sail12
-rw-r--r--test/typecheck/pass/exist_tlb.sail94
-rw-r--r--test/typecheck/pass/exist_true.sail7
-rw-r--r--test/typecheck/pass/exit1.sail8
-rw-r--r--test/typecheck/pass/exit2.sail7
-rw-r--r--test/typecheck/pass/exit3.sail7
-rw-r--r--test/typecheck/pass/flow_gt1.sail28
-rw-r--r--test/typecheck/pass/flow_gteq1.sail28
-rw-r--r--test/typecheck/pass/flow_lt1.sail25
-rw-r--r--test/typecheck/pass/flow_lt2.sail25
-rw-r--r--test/typecheck/pass/flow_lt_assign.sail29
-rw-r--r--test/typecheck/pass/flow_lteq1.sail28
-rw-r--r--test/typecheck/pass/foreach_var_updates.sail15
-rw-r--r--test/typecheck/pass/fun_simple_constraints1.sail18
-rw-r--r--test/typecheck/pass/fun_simple_constraints2.sail18
-rw-r--r--test/typecheck/pass/guards.sail22
-rw-r--r--test/typecheck/pass/let_subtyp_bug.sail9
-rw-r--r--test/typecheck/pass/lexp_memory.sail68
-rw-r--r--test/typecheck/pass/list_cons.sail1
-rw-r--r--test/typecheck/pass/list_cons2.sail7
-rw-r--r--test/typecheck/pass/list_lit.sail2
-rw-r--r--test/typecheck/pass/mips400.sail785
-rw-r--r--test/typecheck/pass/mips_CP0Cause_BD_assign1.sail32
-rw-r--r--test/typecheck/pass/mips_CP0Cause_BD_assign2.sail32
-rw-r--r--test/typecheck/pass/mips_CP0Cause_access.sail34
-rw-r--r--test/typecheck/pass/mips_CauseReg1.sail15
-rw-r--r--test/typecheck/pass/mips_CauseReg2.sail15
-rw-r--r--test/typecheck/pass/mips_reg_field_bit.sail28
-rw-r--r--test/typecheck/pass/mips_reg_field_bv.sail28
-rw-r--r--test/typecheck/pass/mips_regtyps.sail53
-rw-r--r--test/typecheck/pass/mips_tlbindext_dec.sail5
-rw-r--r--test/typecheck/pass/mips_tlbindext_inc.sail5
-rw-r--r--test/typecheck/pass/modify_assignment1.sail8
-rw-r--r--test/typecheck/pass/modify_type_chain.sail8
-rw-r--r--test/typecheck/pass/nat_set.sail8
-rw-r--r--test/typecheck/pass/nondet.sail12
-rw-r--r--test/typecheck/pass/nondet_assert.sail14
-rw-r--r--test/typecheck/pass/nondet_return.sail13
-rw-r--r--test/typecheck/pass/nzcv.sail13
-rw-r--r--test/typecheck/pass/option_either.sail33
-rw-r--r--test/typecheck/pass/overlap_field.sail13
-rw-r--r--test/typecheck/pass/overload_plus.sail12
-rw-r--r--test/typecheck/pass/patternrefinement.sail19
-rw-r--r--test/typecheck/pass/phantom_num.sail17
-rw-r--r--test/typecheck/pass/procstate1.sail16
-rw-r--r--test/typecheck/pass/pure_record.sail22
-rw-r--r--test/typecheck/pass/pure_record2.sail22
-rw-r--r--test/typecheck/pass/pure_record3.sail25
-rw-r--r--test/typecheck/pass/real.sail2
-rw-r--r--test/typecheck/pass/reg_mod.sail11
-rw-r--r--test/typecheck/pass/regtyp_vec.sail36
-rw-r--r--test/typecheck/pass/return_simple1.sail8
-rw-r--r--test/typecheck/pass/return_simple2.sail11
-rw-r--r--test/typecheck/pass/return_simple3.sail8
-rw-r--r--test/typecheck/pass/return_simple4.sail7
-rw-r--r--test/typecheck/pass/set_mark.sail11
-rw-r--r--test/typecheck/pass/set_mark2.sail11
-rw-r--r--test/typecheck/pass/set_spsr.sail17
-rw-r--r--test/typecheck/pass/simple_record_access.sail16
-rw-r--r--test/typecheck/pass/simple_scattered.sail22
-rw-r--r--test/typecheck/pass/simple_scattered2.sail27
-rw-r--r--test/typecheck/pass/sizeof_vector_start_index.sail12
-rw-r--r--test/typecheck/pass/trycatch.sail20
-rw-r--r--test/typecheck/pass/union_infer.sail16
-rw-r--r--test/typecheck/pass/varity.sail19
-rw-r--r--test/typecheck/pass/vec_pat1.sail20
-rw-r--r--test/typecheck/pass/vector_access.sail15
-rw-r--r--test/typecheck/pass/vector_access_dec.sail15
-rw-r--r--test/typecheck/pass/vector_append.sail14
-rw-r--r--test/typecheck/pass/vector_append_gen.sail12
-rw-r--r--test/typecheck/pass/vector_subrange_gen.sail21
-rw-r--r--test/typecheck/pass/vector_synonym_cast.sail8
-rw-r--r--test/typecheck/pass/while_MM.sail23
-rw-r--r--test/typecheck/pass/while_MP.sail17
-rw-r--r--test/typecheck/pass/while_PM.sail23
-rw-r--r--test/typecheck/pass/while_PP.sail24
-rwxr-xr-xtest/typecheck/run_tests.sh160
226 files changed, 5225 insertions, 0 deletions
diff --git a/test/mono/.gitignore b/test/mono/.gitignore
new file mode 100644
index 00000000..2dd3daa3
--- /dev/null
+++ b/test/mono/.gitignore
@@ -0,0 +1 @@
+test-out \ No newline at end of file
diff --git a/test/mono/addsubexist.sail b/test/mono/addsubexist.sail
new file mode 100644
index 00000000..f59f596e
--- /dev/null
+++ b/test/mono/addsubexist.sail
@@ -0,0 +1,75 @@
+(* Adapted from hand-written ARM model *)
+
+default Order dec
+typedef boolean = bit
+typedef reg_size = bit[5]
+typedef reg_index = [|31|]
+
+val reg_size -> reg_index effect pure UInt_reg
+val unit -> unit effect pure (* probably not pure *) ReservedValue
+function forall Nat 'N. bit['N] NOT((bit['N]) x) = ~(x)
+val forall Nat 'M, Nat 'N. bit['M] -> bit['N] effect pure ZeroExtend
+val forall Nat 'N. (bit['N], bit['N], bit) -> (bit['N],bit[4]) effect pure AddWithCarry
+val forall Nat 'N, 'N IN {8,16,32,64}. (*broken? implicit<'N>*)unit -> bit['N] effect {rreg} rSP
+val forall Nat 'N, 'N IN {8,16,32,64}. ((*ditto implicit<'N>,*)reg_index) -> bit['N] effect {rreg}rX
+val (unit, bit[4]) -> unit effect {wreg} wPSTATE_NZCV
+val forall Nat 'N, 'N IN {32,64}. (unit, bit['N]) -> unit effect {rreg,wreg} wSP
+val forall Nat 'N, 'N IN {32,64}. (reg_index,bit['N]) -> unit effect {wreg} wX
+
+typedef ast = const union
+{
+ (exist 'R, 'R in {32,64}. (reg_index,reg_index,[:'R:],boolean,boolean,bit['R])) AddSubImmediate;
+}
+
+val ast -> unit effect {rreg,wreg(*,rmem,barr,eamem,wmv,escape*)} execute
+scattered function unit execute
+
+val bit[32] -> option<(ast)> effect pure decodeAddSubtractImmediate
+
+(* ADD/ADDS (immediate) *)
+(* SUB/SUBS (immediate) *)
+function option<(ast)> effect pure decodeAddSubtractImmediate ([sf]:[op]:[S]:0b10001:(bit[2]) shift:(bit[12]) imm12:(reg_size) Rn:(reg_size) Rd) =
+{
+ (reg_index) d := UInt_reg(Rd);
+ (reg_index) n := UInt_reg(Rn);
+ let (exist 'R, 'R in {32,64}. [:'R:]) 'datasize = if sf then 64 else 32 in {
+ (boolean) sub_op := op;
+ (boolean) setflags := S;
+ (bit['datasize]) imm := 0; (* ARM: uninitialized *)
+
+ switch shift {
+ case 0b00 -> imm := ZeroExtend(imm12)
+ case 0b01 -> imm := ZeroExtend(imm12 : (0b0 ^^ 12))
+ case [bitone,_] -> ReservedValue()
+ };
+
+ Some(AddSubImmediate( (d,n,datasize,sub_op,setflags,imm) ));
+}}
+
+function clause execute (AddSubImmediate('datasize)) = {
+switch datasize {
+case (d,n,datasize,sub_op,setflags,imm) ->
+{
+ (bit['datasize]) operand1 := if n == 31 then rSP() else rX(n);
+ (bit['datasize]) operand2 := imm;
+ (bit) carry_in := bitzero; (* ARM: uninitialized *)
+
+ if sub_op then {
+ operand2 := NOT(operand2);
+ carry_in := bitone;
+ }
+ else
+ carry_in := bitzero;
+
+ let (result,nzcv) = (AddWithCarry(operand1, operand2, carry_in)) in {
+
+ if setflags then
+ wPSTATE_NZCV() := nzcv;
+
+ if (d == 31 & ~(setflags)) then
+ wSP() := result
+ else
+ wX(d) := result;
+ }
+}}}
+end execute
diff --git a/test/mono/fnreduce.sail b/test/mono/fnreduce.sail
new file mode 100644
index 00000000..f39fb87d
--- /dev/null
+++ b/test/mono/fnreduce.sail
@@ -0,0 +1,69 @@
+(* Test constant propagation part of monomorphisation involving
+ functions. We should reduce a function application when the
+ arguments are suitable values, the function is pure and the result
+ is a value.
+ *)
+
+typedef AnEnum = enumerate { One; Two; Three }
+
+typedef EnumlikeUnion = const union { First; Second }
+
+typedef ProperUnion = const union {
+ (AnEnum) Stuff;
+ (EnumlikeUnion) Nonsense;
+}
+
+function AnEnum canReduce ((AnEnum) x) = {
+ switch (x) {
+ case One -> Two
+ case x -> x
+ }
+}
+
+function nat cannotReduce ((AnEnum) x) = {
+ let (nat) y = switch (x) { case One -> 1 case _ -> 5 } in
+ 2 + y
+}
+
+function AnEnum effect {rreg} fakeUnpure ((AnEnum) x) = {
+ switch (x) {
+ case One -> Two
+ case x -> x
+ }
+}
+
+function EnumlikeUnion canReduceUnion ((AnEnum) x) = {
+ switch (x) {
+ case One -> First
+ case _ -> Second
+ }
+}
+
+function ProperUnion canReduceUnion2 ((AnEnum) x) = {
+ switch (x) {
+ case One -> Nonsense(First)
+ case y -> Stuff(y)
+ }
+}
+
+(* FIXME LATER: once effect handling is in place we should get an error
+ because this isn't pure *)
+
+val AnEnum -> (AnEnum,nat,AnEnum,EnumlikeUnion,ProperUnion) effect pure test
+
+function test (x) = {
+ let a = canReduce(x) in
+ let b = cannotReduce(x) in
+ let c = fakeUnpure(x) in
+ let d = canReduceUnion(x) in
+ let e = canReduceUnion2(x) in
+ (a,b,c,d,e)
+}
+
+val unit -> bool effect pure run
+
+function run () = {
+ test(One) == (Two,3,Two,First,Nonsense(First)) &
+ test(Two) == (Two,7,Two,Second,Stuff(Two)) &
+ test(Three) == (Three,7,Three,Second,Stuff(Three))
+}
diff --git a/test/mono/set.sail b/test/mono/set.sail
new file mode 100644
index 00000000..ecc06137
--- /dev/null
+++ b/test/mono/set.sail
@@ -0,0 +1,29 @@
+default Order dec
+
+(* A function which is merely parametrised by a size does not need to be
+ monomorphised *)
+
+val forall 'n, 'n in {32,64}. [:'n:] -> bit[64] effect pure parametric
+
+function parametric(n) = {
+ let (bit['n]) x = exts(0x80000000) in
+ extz(x)
+}
+
+(* But if we do a calculation on the size then we'll need to case split *)
+
+val forall 'n, 'n in {16,32}. [:'n:] -> bit[64] effect pure depends
+
+function depends(n) = {
+ let 'm = 2 * n in
+ let (bit['m]) x = exts(0x80000000) in
+ extz(x)
+}
+
+val unit -> bool effect pure run
+
+function run () =
+ parametric(32) == 0x0000000080000000 &
+ parametric(64) == 0xffffffff80000000 &
+ depends(16) == 0x0000000080000000 &
+ depends(32) == 0xffffffff80000000
diff --git a/test/mono/test.ml b/test/mono/test.ml
new file mode 100644
index 00000000..f99abfb8
--- /dev/null
+++ b/test/mono/test.ml
@@ -0,0 +1 @@
+if Testout_embed_sequential.run() then print_endline "OK" else print_endline "Failed";;
diff --git a/test/mono/test.sh b/test/mono/test.sh
new file mode 100755
index 00000000..2a5aa80b
--- /dev/null
+++ b/test/mono/test.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+SAILDIR="$DIR/../.."
+LEMDIR="$DIR/../../../lem"
+OUTDIR="$DIR/test-out"
+ZARITH="$LEMDIR/ocaml-lib/dependencies/zarith"
+
+if [ ! -d "$OUTDIR" ]; then
+ mkdir -- "$OUTDIR"
+fi
+cd "$OUTDIR"
+
+TESTONLY="$1"
+if [ -n "$TESTONLY" ]; then shift; fi
+
+LOG="$DIR/log"
+date > "$LOG"
+
+exec 3< "$DIR/tests"
+set +e
+
+while read -u 3 TEST ARGS; do
+ if [ -z "$TESTONLY" -o "$TEST" = "$TESTONLY" ]; then
+# echo "$TEST ocaml"
+# rm -f -- "$OUTDIR"/*
+# "$SAILDIR/sail" -ocaml "$SAILDIR/lib/prelude.sail" "$SAILDIR/lib/prelude_wrappers.sail" "$DIR/$TEST" -o "$OUTDIR/testout" $ARGS
+# cp -- "$SAILDIR"/src/gen_lib/sail_values.ml .
+# cp -- "$DIR"/test.ml .
+# ocamlc -I "$ZARITH" "$ZARITH/zarith.cma" -dllpath "$ZARITH" -I "$LEMDIR/ocaml-lib" "$LEMDIR/ocaml-lib/extract.cma" -I "$SAILDIR/src/_build/lem_interp" "$SAILDIR/src/_build/lem_interp/extract.cma" sail_values.ml testout.ml test.ml -o test
+# ./test
+
+ echo "$TEST lem - ocaml" | tee -a -- "$LOG"
+ rm -f -- "$OUTDIR"/*
+ "$SAILDIR/sail" -lem -lem_sequential -lem_mwords "$SAILDIR/lib/prelude.sail" "$SAILDIR/lib/prelude_wrappers.sail" "$DIR/$TEST".sail -o "$OUTDIR/testout" $ARGS $@ &>> "$LOG" && \
+ "$LEMDIR/bin/lem" -ocaml -lib "$SAILDIR/src/lem_interp" "$SAILDIR/src/gen_lib/sail_values.lem" "$SAILDIR/src/gen_lib/sail_operators_mwords.lem" "$SAILDIR/src/gen_lib/state.lem" testout_embed_types_sequential.lem testout_embed_sequential.lem -outdir "$OUTDIR" &>> "$LOG" && \
+ cp -- "$DIR"/test.ml "$OUTDIR" && \
+ ocamlc -I "$ZARITH" "$ZARITH/zarith.cma" -dllpath "$ZARITH" -I "$LEMDIR/ocaml-lib" "$LEMDIR/ocaml-lib/extract.cma" -I "$SAILDIR/src/_build/lem_interp" "$SAILDIR/src/_build/lem_interp/extract.cma" sail_values.ml sail_operators_mwords.ml state.ml testout_embed_types_sequential.ml testout_embed_sequential.ml test.ml -o test &>> "$LOG" && \
+ ./test |& tee -a -- "$LOG" || \
+ (echo "Failed:"; echo; tail -- "$LOG"; echo; echo)
+ fi
+done
diff --git a/test/mono/tests b/test/mono/tests
new file mode 100644
index 00000000..27e161cf
--- /dev/null
+++ b/test/mono/tests
@@ -0,0 +1,9 @@
+fnreduce -mono-split fnreduce.sail:43:x
+varmatch -mono-split varmatch.sail:7:x
+vector -mono-split vector.sail:7:sel
+union-exist -mono-split union-exist.sail:9:v
+fnreduce -auto_mono
+varmatch -auto_mono
+vector -auto_mono
+union-exist -auto_mono
+set -auto_mono
diff --git a/test/mono/union-exist.sail b/test/mono/union-exist.sail
new file mode 100644
index 00000000..74ab429a
--- /dev/null
+++ b/test/mono/union-exist.sail
@@ -0,0 +1,33 @@
+default Order dec
+
+typedef myunion = const union {
+ (exist 'n, 'n in {8,16}. ([:'n:],bit['n])) MyConstr;
+}
+
+val bit[2] -> myunion effect pure make
+
+function make(v) =
+ (* Can't mention these below without running into exp/nexp parsing conflict! *)
+ let eight = 8 in let sixteen = 16 in
+ switch v {
+ case 0b00 -> MyConstr( ( eight, 0x12) )
+ case 0b01 -> MyConstr( (sixteen,0x1234) )
+ case 0b10 -> MyConstr( ( eight, 0x56) )
+ case 0b11 -> MyConstr( (sixteen,0x5678) )
+ }
+
+val myunion -> bit[32] effect pure use
+
+function use(MyConstr('n)) = {
+ switch n {
+ case (n,v) -> extz(v)
+ }
+}
+val unit -> bool effect pure run
+
+function run () = {
+ use(make(0b00)) == 0x00000012 &
+ use(make(0b01)) == 0x00001234 &
+ use(make(0b10)) == 0x00000056 &
+ use(make(0b11)) == 0x00005678
+}
diff --git a/test/mono/varmatch.sail b/test/mono/varmatch.sail
new file mode 100644
index 00000000..7d2b9b73
--- /dev/null
+++ b/test/mono/varmatch.sail
@@ -0,0 +1,19 @@
+(* Check that when we case split on a variable that the constant propagation
+ handles the default case correctly. *)
+
+typedef AnEnum = enumerate { One; Two; Three }
+
+function AnEnum foo((AnEnum) x) = {
+ switch (x) {
+ case One -> Two
+ case y -> y
+ }
+}
+
+val unit -> bool effect pure run
+
+function run () = {
+ foo(One) == Two &
+ foo(Two) == Two &
+ foo(Three) == Three
+}
diff --git a/test/mono/vector.sail b/test/mono/vector.sail
new file mode 100644
index 00000000..03f36da5
--- /dev/null
+++ b/test/mono/vector.sail
@@ -0,0 +1,21 @@
+(* Check case splitting on a vector *)
+
+default Order dec
+
+val bit[32] -> nat effect pure test
+
+function nat test((bit[2]) sel : (bit[30]) _) = {
+ switch (sel) {
+ case 0b00 -> 5
+ case 0b10 -> 1
+ case _ -> 0
+ }
+}
+
+val unit -> bool effect pure run
+
+function run () = {
+ test(0x0f353533) == 5 &
+ test(0x84534656) == 1 &
+ test(0xf3463903) == 0
+}
diff --git a/test/ocaml/hello_world/expect b/test/ocaml/hello_world/expect
new file mode 100644
index 00000000..3df47a31
--- /dev/null
+++ b/test/ocaml/hello_world/expect
@@ -0,0 +1,2 @@
+Hello, Sail!
+Hello, World!
diff --git a/test/ocaml/hello_world/hello_world.sail b/test/ocaml/hello_world/hello_world.sail
new file mode 100644
index 00000000..bafea2de
--- /dev/null
+++ b/test/ocaml/hello_world/hello_world.sail
@@ -0,0 +1,18 @@
+val hello_world : unit -> string
+
+function hello_world () = {
+ return("Hello, World!");
+ "Unreachable"
+}
+
+val main : unit -> unit effect {wreg, rreg}
+
+register REG : string
+
+function main () = {
+ REG = "Hello, Sail!";
+ print(REG);
+ REG = hello_world();
+ print(REG);
+ return(())
+}
diff --git a/test/ocaml/loop/expect b/test/ocaml/loop/expect
new file mode 100644
index 00000000..190423f8
--- /dev/null
+++ b/test/ocaml/loop/expect
@@ -0,0 +1,100 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
diff --git a/test/ocaml/loop/loop.sail b/test/ocaml/loop/loop.sail
new file mode 100644
index 00000000..3808c19a
--- /dev/null
+++ b/test/ocaml/loop/loop.sail
@@ -0,0 +1,19 @@
+val string_of_int = "string_of_big_int" : int -> string
+
+val add = "add" : (int, int) -> int
+
+val lt = "lt_int" : (int, int) -> bool
+
+overload operator + = {add}
+
+overload operator < = {lt}
+
+val main : unit -> unit
+
+function main () = {
+ x : int = 0;
+ while x < 100 do {
+ x = x + 1;
+ print(string_of_int(x))
+ }
+}
diff --git a/test/ocaml/lsl/expect b/test/ocaml/lsl/expect
new file mode 100644
index 00000000..c72d1eb8
--- /dev/null
+++ b/test/ocaml/lsl/expect
@@ -0,0 +1,4 @@
+pass
+pass
+pass
+pass
diff --git a/test/ocaml/lsl/lsl.sail b/test/ocaml/lsl/lsl.sail
new file mode 100644
index 00000000..8c3e9700
--- /dev/null
+++ b/test/ocaml/lsl/lsl.sail
@@ -0,0 +1,28 @@
+val zeros : forall ('n : Int), 'n >= 0. atom('n) -> bits('n)
+
+function zeros n = replicate_bits(0b0, 'n)
+
+val lslc : forall ('n : Int) ('shift : Int), 'n >= 0.
+ (bits('n), atom('shift)) -> (bits('n), bit) effect {escape}
+
+function lslc (vec, shift) = {
+ assert(constraint('shift >= 1), "shift must be positive");
+ extended : bits('shift + 'n) = vec @ zeros(shift);
+ result : bits('n) = extended[sizeof('n - 1) .. 0];
+ c : bit = extended['n];
+ return((result, c))
+}
+
+val lsl : forall ('n : Int) ('shift : Int), 'n >= 0.
+ (bits('n), atom('shift)) -> bits('n) effect {escape}
+
+function lsl (vec, shift) = if shift == 0 then vec else let (result, _) = lslc(vec, shift) in result
+
+val main : unit -> unit effect {escape}
+
+function main () = {
+ print(if lsl(0b0110, 1) == 0b1100 then "pass" else "fail");
+ print(if lsl(0b1111, 2) == 0b1100 then "pass" else "fail");
+ print(if lsl(0x0F, 4) == 0xF0 then "pass" else "fail");
+ let (result, c) = lslc(0xF000, 2) in print(if (result == 0xC000) & (c == bitone) then "pass" else "fail")
+}
diff --git a/test/ocaml/pattern1/expect b/test/ocaml/pattern1/expect
new file mode 100644
index 00000000..2ae28399
--- /dev/null
+++ b/test/ocaml/pattern1/expect
@@ -0,0 +1 @@
+pass
diff --git a/test/ocaml/pattern1/pattern.sail b/test/ocaml/pattern1/pattern.sail
new file mode 100644
index 00000000..3c28d46e
--- /dev/null
+++ b/test/ocaml/pattern1/pattern.sail
@@ -0,0 +1,9 @@
+val main : unit -> unit
+
+function main () = {
+ vec = 0x4F;
+ match vec {
+ 0b01 @ x : bits(2) @ 0xF => if x == 0b00 then print("pass") else print("x is incorrect"),
+ _ => print("pattern fail")
+ }
+}
diff --git a/test/ocaml/prelude.sail b/test/ocaml/prelude.sail
new file mode 100644
index 00000000..b56ce7e2
--- /dev/null
+++ b/test/ocaml/prelude.sail
@@ -0,0 +1,288 @@
+default Order dec
+
+type bits ('n : Int) = vector('n - 1, 'n, dec, bit)
+
+infix 4 ==
+
+val eq_atom = "eq_int" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val lteq_atom = "lteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val gteq_atom = "gteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val lt_atom = "lt" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val gt_atom = "gt" : forall 'n 'm. (atom('n), atom('m)) -> bool
+
+val eq_int = "eq_int" : (int, int) -> bool
+
+val eq_vec = "eq_list" : forall 'n. (bits('n), bits('n)) -> bool
+
+val eq_string = "eq_string" : (string, string) -> bool
+
+val eq_real = "eq_real" : (real, real) -> bool
+
+val eq_anything = "(fun (x, y) -> x = y)" : forall ('a : Type). ('a, 'a) -> bool
+
+val length = "length" : forall 'n ('a : Type). vector('n - 1, 'n, dec, 'a) -> atom('n)
+
+overload operator == = {eq_atom, eq_int, eq_vec, eq_string, eq_real, eq_anything}
+
+val vector_subrange_A = "subrange" : forall ('n : Int) ('m : Int) ('o : Int), 'o <= 'm <= 'n.
+ (bits('n), atom('m), atom('o)) -> bits('m - ('o - 1))
+
+val vector_subrange_B = "subrange" : forall ('n : Int) ('m : Int) ('o : Int).
+ (bits('n), atom('m), atom('o)) -> bits('m - ('o - 1))
+
+overload vector_subrange = {vector_subrange_A, vector_subrange_B}
+
+val vector_access_A = "access" : forall ('n : Int) ('m : Int) ('a : Type), 0 <= 'm < 'n.
+ (vector('n - 1, 'n, dec, 'a), atom('m)) -> 'a
+
+val vector_access_B = "access" : forall ('n : Int) ('a : Type).
+ (vector('n - 1, 'n, dec, 'a), int) -> 'a
+
+overload vector_access = {vector_access_A, vector_access_B}
+
+val vector_update = "update" : forall 'n ('a : Type).
+ (vector('n - 1, 'n, dec, 'a), int, 'a) -> vector('n - 1, 'n, dec, 'a)
+
+val vector_update_subrange = "update_subrange" : forall 'n 'm 'o.
+ (bits('n), atom('m), atom('o), bits('m - ('o - 1))) -> bits('n)
+
+val vcons : forall ('n : Int) ('a : Type).
+ ('a, vector('n - 1, 'n, dec, 'a)) -> vector('n, 'n + 1, dec, 'a)
+
+val append = "append" : forall ('n : Int) ('m : Int) ('a : Type).
+ (vector('n - 1, 'n, dec, 'a), vector('m - 1, 'm, dec, 'a)) -> vector('n + 'm - 1, 'n + 'm, dec, 'a)
+
+val not_bool = "not" : bool -> bool
+
+val not_vec = "not_vec" : forall 'n. bits('n) -> bits('n)
+
+overload ~ = {not_bool, not_vec}
+
+val neq_atom : forall 'n 'm. (atom('n), atom('m)) -> bool
+
+function neq_atom (x, y) = not_bool(eq_atom(x, y))
+
+val neq_int : (int, int) -> bool
+
+function neq_int (x, y) = not_bool(eq_int(x, y))
+
+val neq_vec : forall 'n. (bits('n), bits('n)) -> bool
+
+function neq_vec (x, y) = not_bool(eq_vec(x, y))
+
+val neq_anything : forall ('a : Type). ('a, 'a) -> bool
+
+function neq_anything (x, y) = not_bool(x == y)
+
+overload operator != = {neq_atom, neq_int, neq_vec, neq_anything}
+
+val and_bool = "and_bool" : (bool, bool) -> bool
+
+val builtin_and_vec = "and_vec" : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+val and_vec : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+function and_vec (xs, ys) = builtin_and_vec(xs, ys)
+
+overload operator & = {and_bool, and_vec}
+
+val or_bool = "or_bool" : (bool, bool) -> bool
+
+val builtin_or_vec = "or_vec" : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+val or_vec : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+function or_vec (xs, ys) = builtin_or_vec(xs, ys)
+
+overload operator | = {or_bool, or_vec}
+
+val UInt = "uint" : forall 'n. bits('n) -> range(0, 2 ^ 'n - 1)
+
+val SInt = "sint" : forall 'n. bits('n) -> range(- (2 ^ ('n - 1)), 2 ^ ('n - 1) - 1)
+
+val hex_slice = "hex_slice" : forall 'n 'm. (string, atom('n), atom('m)) -> bits('n - 'm)
+
+val __SetSlice_bits = "set_slice" : forall 'n 'm.
+ (atom('n), atom('m), bits('n), int, bits('m)) -> bits('n)
+
+val __SetSlice_int = "set_slice_int" : forall 'w. (atom('w), int, int, bits('w)) -> int
+
+val __raw_SetSlice_int : forall 'w. (atom('w), int, int, bits('w)) -> int
+
+val __raw_GetSlice_int = "get_slice_int" : forall 'w. (atom('w), int, int) -> bits('w)
+
+val __GetSlice_int : forall 'n. (atom('n), int, int) -> bits('n)
+
+function __GetSlice_int (n, m, o) = __raw_GetSlice_int(n, m, o)
+
+val __raw_SetSlice_bits : forall 'n 'w.
+ (atom('n), atom('w), bits('n), int, bits('w)) -> bits('n)
+
+val __raw_GetSlice_bits : forall 'n 'w.
+ (atom('n), atom('w), bits('n), int) -> bits('w)
+
+val __ShiftLeft : forall 'm. (bits('m), int) -> bits('m)
+
+val __SignExtendSlice : forall 'm. (bits('m), int, int) -> bits('m)
+
+val __ZeroExtendSlice : forall 'm. (bits('m), int, int) -> bits('m)
+
+val cast cast_unit_vec : bit -> bits(1)
+
+val print = "print_endline" : string -> unit
+
+val putchar = "putchar" : forall ('a : Type). 'a -> unit
+
+val concat_str = "concat_str" : (string, string) -> string
+
+val DecStr : int -> string
+
+val HexStr : int -> string
+
+val BitStr = "string_of_bits" : forall 'n. bits('n) -> string
+
+val xor_vec = "xor_vec" : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+val int_power : (int, int) -> int
+
+val real_power = "real_power" : (real, int) -> real
+
+overload operator ^ = {xor_vec, int_power, real_power}
+
+val add_range = "add" : forall 'n 'm 'o 'p.
+ (range('n, 'm), range('o, 'p)) -> range('n + 'o, 'm + 'p)
+
+val add_int = "add" : (int, int) -> int
+
+val add_vec = "add_vec" : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+val add_vec_int = "add_vec_int" : forall 'n. (bits('n), int) -> bits('n)
+
+val add_real = "add_real" : (real, real) -> real
+
+overload operator + = {add_range, add_int, add_vec, add_vec_int, add_real}
+
+val sub_range = "sub" : forall 'n 'm 'o 'p.
+ (range('n, 'm), range('o, 'p)) -> range('n - 'p, 'm - 'o)
+
+val sub_int = "sub" : (int, int) -> int
+
+val sub_vec : forall 'n. (bits('n), bits('n)) -> bits('n)
+
+val sub_vec_int = "sub_vec_int" : forall 'n. (bits('n), int) -> bits('n)
+
+val sub_real = "sub_real" : (real, real) -> real
+
+val negate_range = "minus_big_int" : forall 'n 'm. range('n, 'm) -> range(- 'm, - 'n)
+
+val negate_int = "minus_big_int" : int -> int
+
+val negate_real = "Num.minus_num" : real -> real
+
+overload operator - = {sub_range, sub_int, sub_vec, sub_vec_int, sub_real}
+
+overload negate = {negate_range, negate_int, negate_real}
+
+val mult_range = "mult" : forall 'n 'm 'o 'p.
+ (range('n, 'm), range('o, 'p)) -> range('n * 'o, 'm * 'p)
+
+val mult_int = "mult" : (int, int) -> int
+
+val mult_real = "mult_real" : (real, real) -> real
+
+overload operator * = {mult_range, mult_int, mult_real}
+
+val Sqrt = "sqrt_real" : real -> real
+
+val gteq_int = "gteq" : (int, int) -> bool
+
+val gteq_real = "gteq_real" : (real, real) -> bool
+
+overload operator >= = {gteq_atom, gteq_int, gteq_real}
+
+val lteq_int = "lteq" : (int, int) -> bool
+
+val lteq_real = "lteq_real" : (real, real) -> bool
+
+overload operator <= = {lteq_atom, lteq_int, lteq_real}
+
+val gt_int = "gt" : (int, int) -> bool
+
+val gt_real = "gt_real" : (real, real) -> bool
+
+overload operator > = {gt_atom, gt_int, gt_real}
+
+val lt_int = "lt" : (int, int) -> bool
+
+val lt_real = "lt_real" : (real, real) -> bool
+
+overload operator < = {lt_atom, lt_int, lt_real}
+
+val RoundDown = "round_down" : real -> int
+
+val RoundUp = "round_up" : real -> int
+
+val abs = "abs_num" : real -> real
+
+val quotient_nat = "quotient" : (nat, nat) -> nat
+
+val quotient_real = "quotient_real" : (real, real) -> real
+
+val quotient = "quotient" : (int, int) -> int
+
+infixl 7 /
+
+overload operator / = {quotient_nat, quotient, quotient_real}
+
+val modulus = "modulus" : (int, int) -> int
+
+infixl 7 %
+
+overload operator % = {modulus}
+
+val Real = "Num.num_of_big_int" : int -> real
+
+val shl_int = "shl_int" : (int, int) -> int
+
+val shr_int = "shr_int" : (int, int) -> int
+
+val min_nat = "min_int" : (nat, nat) -> nat
+
+val min_int = "min_int" : (int, int) -> int
+
+val max_nat = "max_int" : (nat, nat) -> nat
+
+val max_int = "max_int" : (int, int) -> int
+
+overload min = {min_nat, min_int}
+
+overload max = {max_nat, max_int}
+
+val replicate_bits = "replicate_bits" : forall 'n 'm. (bits('n), atom('m)) -> bits('n * 'm)
+
+val cast ex_nat : nat -> {'n, 'n >= 0. atom('n)}
+
+function ex_nat 'n = n
+
+val cast ex_int : int -> {'n, true. atom('n)}
+
+function ex_int 'n = n
+
+val ex_range : forall 'n 'm.
+ range('n, 'm) -> {'o, 'n <= 'o & 'o <= 'm. atom('o)}
+
+val coerce_int_nat : int -> nat effect {escape}
+
+function coerce_int_nat 'x = {
+ assert(constraint('x >= 0));
+ x
+}
+
+val slice = "slice" : forall ('n : Int) ('m : Int), 'm >= 0 & 'n >= 0.
+ (bits('m), int, atom('n)) -> bits('n)
+
+val pow2 = "pow2" : forall 'n. atom('n) -> atom(2 ^ 'n)
+
+val "print_int" : (string, int) -> unit
+
+val "print_bits" : forall 'n. (string, bits('n)) -> unit \ No newline at end of file
diff --git a/test/ocaml/reg_passing/expect b/test/ocaml/reg_passing/expect
new file mode 100644
index 00000000..e64f92f2
--- /dev/null
+++ b/test/ocaml/reg_passing/expect
@@ -0,0 +1,3 @@
+R1 = 10
+R2 = 20
+R3 = 10
diff --git a/test/ocaml/reg_passing/reg_passing.sail b/test/ocaml/reg_passing/reg_passing.sail
new file mode 100644
index 00000000..94acdf7e
--- /dev/null
+++ b/test/ocaml/reg_passing/reg_passing.sail
@@ -0,0 +1,36 @@
+
+register R1 : int
+register R2 : int
+register R3 : int
+
+val cast "reg_deref" : forall ('a : Type). register('a) -> 'a effect {rreg}
+val output = {
+ ocaml: "(fun (str, n) -> print_endline (str ^ string_of_big_int n))"
+ } : (string, int) -> unit
+
+val f : register(int) -> unit effect {rreg, wreg}
+
+function f R = {
+ R1 = R;
+}
+
+val g : unit -> unit effect {rreg, wreg}
+
+function g () = {
+ f(R1);
+ f(R2);
+}
+
+val main : unit -> unit effect {rreg, wreg}
+
+function main () = {
+ R1 = 4;
+ R2 = 5;
+ g ();
+ R3 = 10;
+ f(R3);
+ R2 = 20;
+ output("R1 = ", R1);
+ output("R2 = ", R2);
+ output("R3 = ", R3)
+} \ No newline at end of file
diff --git a/test/ocaml/run_tests.sh b/test/ocaml/run_tests.sh
new file mode 100755
index 00000000..9ed00494
--- /dev/null
+++ b/test/ocaml/run_tests.sh
@@ -0,0 +1,96 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR
+SAILDIR="$DIR/../.."
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[0;33m'
+NC='\033[0m'
+
+rm -f $DIR/tests.xml
+
+pass=0
+fail=0
+XML=""
+
+function green {
+ (( pass += 1 ))
+ printf "$1: ${GREEN}$2${NC}\n"
+ XML+=" <testcase name=\"$1\"/>\n"
+}
+
+function yellow {
+ (( fail += 1 ))
+ printf "$1: ${YELLOW}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function red {
+ (( fail += 1 ))
+ printf "$1: ${RED}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function finish_suite {
+ printf "$1: Passed ${pass} out of $(( pass + fail ))\n"
+ XML=" <testsuite name=\"$1\" tests=\"$(( pass + fail ))\" failures=\"${fail}\" timestamp=\"$(date)\">\n$XML </testsuite>\n"
+ printf "$XML" >> $DIR/tests.xml
+ XML=""
+ pass=0
+ fail=0
+}
+
+SAILLIBDIR="$DIR/../../lib/"
+
+printf "<testsuites>\n" >> $DIR/tests.xml
+
+for i in `ls -d */`;
+do
+ cd $DIR/$i;
+ if $SAILDIR/sail -new_parser -o out -ocaml ../prelude.sail `ls *.sail` 1> /dev/null;
+ then
+ ./out > result;
+ if diff expect result;
+ then
+ green "built $i" "ok"
+ else
+ yellow "bad output $i" "fail"
+ fi;
+ rm out;
+ rm result;
+ rm -r _sbuild
+ else
+ red "building $i" "fail"
+ fi
+done
+
+finish_suite "Ocaml testing"
+
+cd $DIR
+
+for i in `ls -d */`;
+do
+ cd $DIR/$i;
+ if $SAILDIR/sail -new_parser -o out -ocaml_trace ../prelude.sail `ls *.sail` 1> /dev/null;
+ then
+ ./out > result 2> /dev/null;
+ if diff expect result;
+ then
+ green "built $i" "ok"
+ else
+ yellow "bad output $i" "fail"
+ fi;
+ rm out;
+ rm result;
+ rm -r _sbuild
+ else
+ red "building $i" "fail"
+ fi
+done
+
+finish_suite "Ocaml trace testing"
+
+printf "</testsuites>\n" >> $DIR/tests.xml
diff --git a/test/ocaml/short_circuit/expect b/test/ocaml/short_circuit/expect
new file mode 100644
index 00000000..9766475a
--- /dev/null
+++ b/test/ocaml/short_circuit/expect
@@ -0,0 +1 @@
+ok
diff --git a/test/ocaml/short_circuit/sc.sail b/test/ocaml/short_circuit/sc.sail
new file mode 100644
index 00000000..a0f4941d
--- /dev/null
+++ b/test/ocaml/short_circuit/sc.sail
@@ -0,0 +1,15 @@
+
+val fail : unit -> bool effect {escape}
+
+function fail () = {
+ assert(false);
+ true
+}
+
+val main : unit -> unit effect {escape}
+
+function main () = {
+ assert(~(false & fail()));
+ assert(true | fail());
+ print("ok")
+} \ No newline at end of file
diff --git a/test/ocaml/string_equality/expect b/test/ocaml/string_equality/expect
new file mode 100644
index 00000000..27ba77dd
--- /dev/null
+++ b/test/ocaml/string_equality/expect
@@ -0,0 +1 @@
+true
diff --git a/test/ocaml/string_equality/string_equality.sail b/test/ocaml/string_equality/string_equality.sail
new file mode 100644
index 00000000..568052cd
--- /dev/null
+++ b/test/ocaml/string_equality/string_equality.sail
@@ -0,0 +1,3 @@
+val main : unit -> unit
+
+function main () = if "test" == "test" then print("true") else print("false")
diff --git a/test/ocaml/trycatch/expect b/test/ocaml/trycatch/expect
new file mode 100644
index 00000000..0aab34df
--- /dev/null
+++ b/test/ocaml/trycatch/expect
@@ -0,0 +1,2 @@
+Before throw
+Caught!
diff --git a/test/ocaml/trycatch/tc.sail b/test/ocaml/trycatch/tc.sail
new file mode 100644
index 00000000..b805f3fa
--- /dev/null
+++ b/test/ocaml/trycatch/tc.sail
@@ -0,0 +1,23 @@
+
+scattered union exception
+
+union clause exception = Test_int : int
+
+union clause exception = Test_failure : string
+
+val main : unit -> unit effect {escape}
+
+function main () = {
+ try {
+ print("Before throw");
+ throw(Test_failure("Caught!"));
+ print("Not printed")
+ } catch {
+ Test_failure(msg) => print(msg),
+ _ => print("Unknown exception")
+ }
+}
+
+union clause exception = Test_other
+
+end exception \ No newline at end of file
diff --git a/test/ocaml/types/expect b/test/ocaml/types/expect
new file mode 100644
index 00000000..747ef4c9
--- /dev/null
+++ b/test/ocaml/types/expect
@@ -0,0 +1,5 @@
+pass
+pass
+pass
+pass
+pass
diff --git a/test/ocaml/types/types.sail b/test/ocaml/types/types.sail
new file mode 100644
index 00000000..a710eb25
--- /dev/null
+++ b/test/ocaml/types/types.sail
@@ -0,0 +1,44 @@
+enum signal = {Low, High}
+
+enum enum_single = {SingleConstructor}
+
+type byte = bits(8)
+
+type b32 = bits(32)
+
+type b64 = bits(64)
+
+register R64 : b64
+
+register R32 : b32
+
+register R8 : byte
+
+register SIGNALREG : signal
+
+struct TestStruct = {
+ field1 : bits(2),
+ field2 : byte,
+ field3 : bool
+}
+
+register SREG : TestStruct
+
+union option ('a : Type) = {None, Some : 'a}
+
+register OREG : option(byte)
+
+val main : unit -> unit effect {rreg, wreg}
+
+function main () = {
+ R8 = 0xFF;
+ SIGNALREG = Low;
+ print(if SIGNALREG == Low then "pass" else "fail");
+ SIGNALREG = High;
+ print(if SIGNALREG == High then "pass" else "fail");
+ SREG.field1 = 0b00;
+ print(if SREG.field1 == 0b00 then "pass" else "faiL");
+ SREG.field1 = 0b11;
+ print(if SREG.field1 == 0b11 then "pass" else "faiL");
+ print("pass")
+}
diff --git a/test/ocaml/vec_32_64/expect b/test/ocaml/vec_32_64/expect
new file mode 100644
index 00000000..4d4fce36
--- /dev/null
+++ b/test/ocaml/vec_32_64/expect
@@ -0,0 +1,2 @@
+xs = 0x00000000
+zeros(64) = 0x0000000000000000
diff --git a/test/ocaml/vec_32_64/vec_32_64.sail b/test/ocaml/vec_32_64/vec_32_64.sail
new file mode 100644
index 00000000..eb518515
--- /dev/null
+++ b/test/ocaml/vec_32_64/vec_32_64.sail
@@ -0,0 +1,28 @@
+(* This example is more testing the typechecker flow typing rather
+than the ocaml backend, but it does test that recursive functions work
+correctly *)
+
+val get_size : unit -> {|32, 64|}
+
+function get_size () = 32
+
+val only64 = { ocaml: "(fun _ -> ())" } : bits(64) -> unit
+
+val zeros : forall 'n. atom('n) -> vector('n - 1, 'n, dec, bit)
+
+function zeros n =
+ if (n == 1 + 0) then 0b0 else 0b0 @ zeros('n - 1)
+
+val main : unit -> unit
+
+function main () = {
+ let 'length = get_size ();
+ let xs = zeros(length);
+ if (length == 32) then {
+ ()
+ } else {
+ only64(xs)
+ };
+ print_bits("xs = ", xs);
+ print_bits("zeros(64) = ", zeros(64))
+} \ No newline at end of file
diff --git a/test/ocaml/void/expect b/test/ocaml/void/expect
new file mode 100644
index 00000000..559bf40a
--- /dev/null
+++ b/test/ocaml/void/expect
@@ -0,0 +1 @@
+Before
diff --git a/test/ocaml/void/void.sail b/test/ocaml/void/void.sail
new file mode 100644
index 00000000..485ac019
--- /dev/null
+++ b/test/ocaml/void/void.sail
@@ -0,0 +1,14 @@
+
+val void : forall 'n, 'n = 'n + 1. atom('n) -> unit
+
+function void _ = ()
+
+val main : unit -> unit
+
+function main () = {
+ print("Before");
+ if false then {
+ print("After");
+ void(0);
+ }
+} \ No newline at end of file
diff --git a/test/run_tests.sh b/test/run_tests.sh
new file mode 100755
index 00000000..73f622c7
--- /dev/null
+++ b/test/run_tests.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+cd $DIR/..
+./test/typecheck/run_tests.sh
+./test/ocaml/run_tests.sh
diff --git a/test/typecheck/fail/assignment_simple1.sail b/test/typecheck/fail/assignment_simple1.sail
new file mode 100644
index 00000000..1ad9f8bf
--- /dev/null
+++ b/test/typecheck/fail/assignment_simple1.sail
@@ -0,0 +1,16 @@
+
+val ([:10:], unit) -> [:10:] effect pure f
+
+function [:10:] f (x, y) = x
+
+val unit -> [:10:] effect pure test
+
+function [:10:] test () =
+{
+ z := 9;
+ z
+}
+
+val unit -> unit effect pure test2
+
+function unit test2 () = x := 10
diff --git a/test/typecheck/fail/assignment_simple2.sail b/test/typecheck/fail/assignment_simple2.sail
new file mode 100644
index 00000000..db45bbcf
--- /dev/null
+++ b/test/typecheck/fail/assignment_simple2.sail
@@ -0,0 +1,15 @@
+
+val ([:10:], unit) -> [:10:] effect pure f
+
+function [:10:] f (x, y) = x
+
+val unit -> [:10:] effect pure test
+
+function [:10:] test () =
+{
+ f(z, z := 10)
+}
+
+val unit -> unit effect pure test2
+
+function unit test2 () = x := 10
diff --git a/test/typecheck/fail/assignment_simple3.sail b/test/typecheck/fail/assignment_simple3.sail
new file mode 100644
index 00000000..2a596c29
--- /dev/null
+++ b/test/typecheck/fail/assignment_simple3.sail
@@ -0,0 +1,15 @@
+
+val (unit, [:10:]) -> [:10:] effect pure f
+
+function [:10:] f (x, y) = y
+
+val unit -> [:10:] effect pure test
+
+function [:10:] test () =
+{
+ f(z := 10, z)
+}
+
+val unit -> unit effect pure test2
+
+function unit test2 () = x := 10
diff --git a/test/typecheck/fail/bitwise_not_gen1.sail b/test/typecheck/fail/bitwise_not_gen1.sail
new file mode 100644
index 00000000..272b1a65
--- /dev/null
+++ b/test/typecheck/fail/bitwise_not_gen1.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'n, Nat 'm, Order 'o. vector<'n,'m,'o,bit> -> vector<'n,'m,'o,bit> effect pure bitwise_not
+
+default Order dec
+
+val forall 'n. bit['n] -> bit['n - 1] effect pure test
+
+function forall 'n. bit['n - 1] test ((bit['n]) x) = bitwise_not(bitwise_not(x)) \ No newline at end of file
diff --git a/test/typecheck/fail/bitwise_not_gen2.sail b/test/typecheck/fail/bitwise_not_gen2.sail
new file mode 100644
index 00000000..fdf17244
--- /dev/null
+++ b/test/typecheck/fail/bitwise_not_gen2.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'n, Nat 'm, Order 'o. vector<'n,'m,'o,bit> -> vector<'n,'m,'o,bit> effect pure bitwise_not
+
+default Order dec
+
+val forall 'n. bit['n] -> bit['n + 1] effect pure test
+
+function forall 'n. bit['n + 1] test ((bit['n]) x) = bitwise_not(bitwise_not(x)) \ No newline at end of file
diff --git a/test/typecheck/fail/bv_simple_index_no_cast.sail b/test/typecheck/fail/bv_simple_index_no_cast.sail
new file mode 100644
index 00000000..74f46ab7
--- /dev/null
+++ b/test/typecheck/fail/bv_simple_index_no_cast.sail
@@ -0,0 +1,9 @@
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+
+overload vector_access [vector_access_inc; vector_access_dec]
+
+function bool bv ((bit[64]) x) =
+{
+ x[32]
+}
diff --git a/test/typecheck/fail/case_simple1.sail b/test/typecheck/fail/case_simple1.sail
new file mode 100644
index 00000000..471c3565
--- /dev/null
+++ b/test/typecheck/fail/case_simple1.sail
@@ -0,0 +1,9 @@
+
+val forall Nat 'N. ([:10:], [|10:'N|]) -> [|10:'N|] effect pure case_test
+
+function forall Nat 'N. [|10:'N|] case_test (x, y) =
+{
+ switch (x, y) {
+ case _ -> x
+ }
+}
diff --git a/test/typecheck/fail/cast_lexp1.sail b/test/typecheck/fail/cast_lexp1.sail
new file mode 100644
index 00000000..dad4c84c
--- /dev/null
+++ b/test/typecheck/fail/cast_lexp1.sail
@@ -0,0 +1,7 @@
+
+val unit -> nat effect pure test
+
+function nat test () = {
+ (int) y := 10;
+ y
+}
diff --git a/test/typecheck/fail/cast_simple.sail b/test/typecheck/fail/cast_simple.sail
new file mode 100644
index 00000000..19768fbe
--- /dev/null
+++ b/test/typecheck/fail/cast_simple.sail
@@ -0,0 +1,7 @@
+
+val unit -> nat effect pure test
+
+function nat test () = {
+ (int) y := ([|0:10|]) 10;
+ (nat) y
+}
diff --git a/test/typecheck/fail/default_order.sail b/test/typecheck/fail/default_order.sail
new file mode 100644
index 00000000..8de5cc46
--- /dev/null
+++ b/test/typecheck/fail/default_order.sail
@@ -0,0 +1,6 @@
+(* Could make an argument for why this should be ok, but allowing
+default order to change could have unintended consequences if we arn't
+careful, so it seems safer to just forbid it *)
+
+default Order dec
+default Order inc
diff --git a/test/typecheck/fail/eff_escape.sail b/test/typecheck/fail/eff_escape.sail
new file mode 100644
index 00000000..698cf0b1
--- /dev/null
+++ b/test/typecheck/fail/eff_escape.sail
@@ -0,0 +1,7 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ exit ()
+}
diff --git a/test/typecheck/fail/eff_undef.sail b/test/typecheck/fail/eff_undef.sail
new file mode 100644
index 00000000..d5d98a3f
--- /dev/null
+++ b/test/typecheck/fail/eff_undef.sail
@@ -0,0 +1,7 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ undefined
+}
diff --git a/test/typecheck/fail/ex_cast.sail b/test/typecheck/fail/ex_cast.sail
new file mode 100644
index 00000000..5ea22d14
--- /dev/null
+++ b/test/typecheck/fail/ex_cast.sail
@@ -0,0 +1,12 @@
+
+default Order dec
+
+val cast int -> exist 'n. [:'n:] effect pure ex_int
+
+val [:'n:] -> bit['n] effect pure zeros
+
+val int -> unit effect pure test
+
+function test n = {
+ x := zeros(n)
+}
diff --git a/test/typecheck/fail/exist1.sail b/test/typecheck/fail/exist1.sail
new file mode 100644
index 00000000..3fab1366
--- /dev/null
+++ b/test/typecheck/fail/exist1.sail
@@ -0,0 +1,30 @@
+
+let (exist 'n, 'n in {0, 1}. [:'n:]) v1 = 0
+
+val bool -> exist 'n, 'n in {0, 1}. [:'n:] effect pure test
+
+function test flag =
+{
+ if flag then 0 else 1
+}
+
+let ([|0:1|]) v2 = test(true)
+
+val forall 'a, 'b. ([:'a:], [:'b:]) -> [:'a + 'b:] effect pure add
+
+let (exist 'k, 'k in {3, 4}. [:'k:]) v3 = 3
+
+let (exist 'q, 'q in {0, 1}. [:'q + 3:]) v4 = v3
+
+let v5 = add(test(true), 4)
+
+let ([:4:]) v6 = 4
+
+function unit unit_fn (([:4:]) x) = ()
+
+val forall 'a. ([:'a:], [:'a:]) -> [:'a + 'a:] effect pure s_add
+
+let (exist 'k, 'k = 4. [:'k:]) v7 = 4
+
+let v8 = s_add(test(true), 4)
+
diff --git a/test/typecheck/fail/flow_gt1.sail b/test/typecheck/fail/flow_gt1.sail
new file mode 100644
index 00000000..917793cd
--- /dev/null
+++ b/test/typecheck/fail/flow_gt1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x > 31)
+ then x - 33
+ else x + 32
+}
diff --git a/test/typecheck/fail/flow_gt2.sail b/test/typecheck/fail/flow_gt2.sail
new file mode 100644
index 00000000..f5ea4978
--- /dev/null
+++ b/test/typecheck/fail/flow_gt2.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x > 31)
+ then x - 32
+ else x + 33
+}
diff --git a/test/typecheck/fail/flow_gteq1.sail b/test/typecheck/fail/flow_gteq1.sail
new file mode 100644
index 00000000..b55647d3
--- /dev/null
+++ b/test/typecheck/fail/flow_gteq1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x >= 32)
+ then x - 33
+ else x + 32
+}
diff --git a/test/typecheck/fail/flow_gteq2.sail b/test/typecheck/fail/flow_gteq2.sail
new file mode 100644
index 00000000..9d0a6201
--- /dev/null
+++ b/test/typecheck/fail/flow_gteq2.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x >= 32)
+ then x - 32
+ else x + 33
+}
diff --git a/test/typecheck/fail/flow_lt1.sail b/test/typecheck/fail/flow_lt1.sail
new file mode 100644
index 00000000..a127ccb0
--- /dev/null
+++ b/test/typecheck/fail/flow_lt1.sail
@@ -0,0 +1,19 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x < 32)
+ then x + 33
+ else x - 32
+}
diff --git a/test/typecheck/fail/flow_lt2.sail b/test/typecheck/fail/flow_lt2.sail
new file mode 100644
index 00000000..a537a084
--- /dev/null
+++ b/test/typecheck/fail/flow_lt2.sail
@@ -0,0 +1,19 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x < 32)
+ then x + 32
+ else x - 33
+}
diff --git a/test/typecheck/fail/flow_lteq1.sail b/test/typecheck/fail/flow_lteq1.sail
new file mode 100644
index 00000000..3bebcc97
--- /dev/null
+++ b/test/typecheck/fail/flow_lteq1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x <= 32)
+ then x + 32
+ else x - 33
+}
diff --git a/test/typecheck/fail/flow_lteq2.sail b/test/typecheck/fail/flow_lteq2.sail
new file mode 100644
index 00000000..c3ee9c0a
--- /dev/null
+++ b/test/typecheck/fail/flow_lteq2.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range
+
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range
+val forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x <= 32)
+ then x + 31
+ else x - 34
+}
diff --git a/test/typecheck/fail/fun_simple_constraints1.sail b/test/typecheck/fail/fun_simple_constraints1.sail
new file mode 100644
index 00000000..979e0cdf
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints1.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:64|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints2.sail b/test/typecheck/fail/fun_simple_constraints2.sail
new file mode 100644
index 00000000..43a0b6d7
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints2.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(9)
diff --git a/test/typecheck/fail/fun_simple_constraints3.sail b/test/typecheck/fail/fun_simple_constraints3.sail
new file mode 100644
index 00000000..098054e4
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints3.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(plus(sizeof 'N, 1))
diff --git a/test/typecheck/fail/fun_simple_constraints4.sail b/test/typecheck/fail/fun_simple_constraints4.sail
new file mode 100644
index 00000000..07b8c596
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints4.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-54))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints5.sail b/test/typecheck/fail/fun_simple_constraints5.sail
new file mode 100644
index 00000000..7e28db85
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints5.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-9))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints6.sail b/test/typecheck/fail/fun_simple_constraints6.sail
new file mode 100644
index 00000000..6dc5e0e6
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints6.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'k, Nat 'm. ([:'n + 'k:], [:'m:]) -> [:'n + 'k + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints7.sail b/test/typecheck/fail/fun_simple_constraints7.sail
new file mode 100644
index 00000000..00d2a172
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints7.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|11:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints8.sail b/test/typecheck/fail/fun_simple_constraints8.sail
new file mode 100644
index 00000000..e4c02da0
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints8.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|11:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/fail/fun_simple_constraints9.sail b/test/typecheck/fail/fun_simple_constraints9.sail
new file mode 100644
index 00000000..3563ae2d
--- /dev/null
+++ b/test/typecheck/fail/fun_simple_constraints9.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x = ten_id(plus(sizeof 'N, 1))
diff --git a/test/typecheck/fail/funret1.sail b/test/typecheck/fail/funret1.sail
new file mode 100644
index 00000000..09a4fd54
--- /dev/null
+++ b/test/typecheck/fail/funret1.sail
@@ -0,0 +1,16 @@
+
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+ }
+
+typedef Test = const union {
+ A;
+ B;
+ C
+}
+
+let (option<int>) x = C
+
diff --git a/test/typecheck/fail/funret2.sail b/test/typecheck/fail/funret2.sail
new file mode 100644
index 00000000..19536599
--- /dev/null
+++ b/test/typecheck/fail/funret2.sail
@@ -0,0 +1,16 @@
+
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+ }
+
+typedef Test = const union {
+ A;
+ B;
+ C
+}
+
+
+function option<int> test2 () = C
diff --git a/test/typecheck/fail/funret3.sail b/test/typecheck/fail/funret3.sail
new file mode 100644
index 00000000..d178f2ad
--- /dev/null
+++ b/test/typecheck/fail/funret3.sail
@@ -0,0 +1,16 @@
+
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+ }
+
+typedef Test = const union {
+ A;
+ B;
+ C
+}
+
+
+function option<(option<int>)> test () = Some(C)
diff --git a/test/typecheck/fail/mips_CP0Cause_BD_assign1.sail b/test/typecheck/fail/mips_CP0Cause_BD_assign1.sail
new file mode 100644
index 00000000..2f599aa9
--- /dev/null
+++ b/test/typecheck/fail/mips_CP0Cause_BD_assign1.sail
@@ -0,0 +1,27 @@
+val forall Nat 'n, Order 'ord. [:1:] -> vector<'n,1,'ord,bit> effect pure cast_one_bv
+val forall Nat 'n, Order 'ord. [:0:] -> vector<'n,1,'ord,bit> effect pure cast_zero_bv
+
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ CP0Cause.BD := 2
+}
diff --git a/test/typecheck/fail/mips_CauseReg1.sail b/test/typecheck/fail/mips_CauseReg1.sail
new file mode 100644
index 00000000..ae99e625
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg1.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 30 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg2.sail b/test/typecheck/fail/mips_CauseReg2.sail
new file mode 100644
index 00000000..683f5a2a
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg2.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 31 : 3 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg3.sail b/test/typecheck/fail/mips_CauseReg3.sail
new file mode 100644
index 00000000..09e27e27
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg3.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 32 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg4.sail b/test/typecheck/fail/mips_CauseReg4.sail
new file mode 100644
index 00000000..1f14981f
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg4.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 8 .. 15 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg5.sail b/test/typecheck/fail/mips_CauseReg5.sail
new file mode 100644
index 00000000..98fc614a
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg5.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 22 : IV; (* special interrupt vector not supported *)
+ 23 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg6.sail b/test/typecheck/fail/mips_CauseReg6.sail
new file mode 100644
index 00000000..ecb8322e
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg6.sail
@@ -0,0 +1,14 @@
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : BD; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mips_CauseReg7.sail b/test/typecheck/fail/mips_CauseReg7.sail
new file mode 100644
index 00000000..48acd4f5
--- /dev/null
+++ b/test/typecheck/fail/mips_CauseReg7.sail
@@ -0,0 +1,15 @@
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 23 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/fail/mismatch_return.sail b/test/typecheck/fail/mismatch_return.sail
new file mode 100644
index 00000000..85b8b636
--- /dev/null
+++ b/test/typecheck/fail/mismatch_return.sail
@@ -0,0 +1,7 @@
+
+val unit -> unit effect pure test
+
+function int test () =
+{
+ ()
+}
diff --git a/test/typecheck/fail/modify_assignment1.sail b/test/typecheck/fail/modify_assignment1.sail
new file mode 100644
index 00000000..99adc95c
--- /dev/null
+++ b/test/typecheck/fail/modify_assignment1.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ z := 9;
+ z := 10
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_assignment2.sail b/test/typecheck/fail/modify_assignment2.sail
new file mode 100644
index 00000000..6551afff
--- /dev/null
+++ b/test/typecheck/fail/modify_assignment2.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:9|]) z := 9;
+ z := ([|0:10|]) 10
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_let_bound.sail b/test/typecheck/fail/modify_let_bound.sail
new file mode 100644
index 00000000..a2ad1b98
--- /dev/null
+++ b/test/typecheck/fail/modify_let_bound.sail
@@ -0,0 +1,16 @@
+
+default Order dec
+
+register bit[3] test
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ let i = 10 in {
+ i := 20
+ };
+ z := 9;
+ z := 10;
+ test := 3
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_type_chain1.sail b/test/typecheck/fail/modify_type_chain1.sail
new file mode 100644
index 00000000..3fff3b59
--- /dev/null
+++ b/test/typecheck/fail/modify_type_chain1.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ ([|0:9|]) z := ([|0:10|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_type_chain2.sail b/test/typecheck/fail/modify_type_chain2.sail
new file mode 100644
index 00000000..085e7db5
--- /dev/null
+++ b/test/typecheck/fail/modify_type_chain2.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ ([|0:7|]) z := ([|0:8|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_type_chain3.sail b/test/typecheck/fail/modify_type_chain3.sail
new file mode 100644
index 00000000..cfe532aa
--- /dev/null
+++ b/test/typecheck/fail/modify_type_chain3.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:6|]) z := 9;
+ ([|0:7|]) z := ([|0:8|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_type_chain4.sail b/test/typecheck/fail/modify_type_chain4.sail
new file mode 100644
index 00000000..c36a9086
--- /dev/null
+++ b/test/typecheck/fail/modify_type_chain4.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ ([|0:11|]) z := ([|0:13|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/modify_type_chain5.sail b/test/typecheck/fail/modify_type_chain5.sail
new file mode 100644
index 00000000..3c3076a4
--- /dev/null
+++ b/test/typecheck/fail/modify_type_chain5.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ ([|0:9|]) z := ([|0:13|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/my_unsigned1.sail b/test/typecheck/fail/my_unsigned1.sail
new file mode 100644
index 00000000..958340ff
--- /dev/null
+++ b/test/typecheck/fail/my_unsigned1.sail
@@ -0,0 +1,8 @@
+
+default Order inc
+
+val forall Nat 'n, Nat 'm, Nat 'o, Order 'ord, 'o >= 0, 'o + 1 <= 2**'m. vector<'n,'m,'ord,bit> -> [:'o:] effect pure my_unsigned
+
+let MAX = my_unsigned(0xff)
+
+let ([:0:]) MIN = MAX \ No newline at end of file
diff --git a/test/typecheck/fail/nat_set.sail b/test/typecheck/fail/nat_set.sail
new file mode 100644
index 00000000..036183c5
--- /dev/null
+++ b/test/typecheck/fail/nat_set.sail
@@ -0,0 +1,9 @@
+
+function forall Nat 'n, 'n IN {1,2,3}. bool test (([:'n:]) x) =
+{
+ true
+}
+
+let x = test(1)
+let y = test(3)
+let z = test(4) \ No newline at end of file
diff --git a/test/typecheck/fail/nondet.sail b/test/typecheck/fail/nondet.sail
new file mode 100644
index 00000000..bce110c6
--- /dev/null
+++ b/test/typecheck/fail/nondet.sail
@@ -0,0 +1,10 @@
+
+register int z
+
+function int test () = {
+ nondet {
+ z := 0;
+ z := 1;
+ z
+ }
+}
diff --git a/test/typecheck/fail/option_either1.sail b/test/typecheck/fail/option_either1.sail
new file mode 100644
index 00000000..569ba212
--- /dev/null
+++ b/test/typecheck/fail/option_either1.sail
@@ -0,0 +1,35 @@
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+}
+
+function forall Type 'a. option<'a> none () = None
+
+function forall Type 'a. option<'a> some (('a) x) = Some(x)
+
+function forall Type 'a. int test ((option<'a>) x) =
+{
+ switch x {
+ case None -> 0
+ case (Some(y)) -> 1
+ }
+}
+
+typedef either = const union forall Type 'a, Type 'b. {
+ 'a Left;
+ 'b Right
+}
+
+val forall Nat 'n, 'n >= 0. bit['n] -> int effect pure signed
+
+function forall Type 'a, Type 'b. either<'a,'b> right (('b) x) = Right(x)
+
+function int test2 ((either<int,bit[1]>) x) =
+{
+ switch x {
+ case (Left(l)) -> l
+ case (right(r)) -> signed(r)
+ }
+}
diff --git a/test/typecheck/fail/overlap_field_wreg.sail b/test/typecheck/fail/overlap_field_wreg.sail
new file mode 100644
index 00000000..4c4d858d
--- /dev/null
+++ b/test/typecheck/fail/overlap_field_wreg.sail
@@ -0,0 +1,13 @@
+
+typedef A = const struct {bool field_A; int shared}
+typedef B = const struct {bool field_B; int shared}
+
+val (bool, int) -> A effect {undef, wreg} makeA
+
+function makeA (x, y) =
+{
+ (A) record := undefined;
+ record.field_A := x;
+ record.shared := y;
+ record
+}
diff --git a/test/typecheck/fail/procstate1.sail b/test/typecheck/fail/procstate1.sail
new file mode 100644
index 00000000..00dc1ab1
--- /dev/null
+++ b/test/typecheck/fail/procstate1.sail
@@ -0,0 +1,16 @@
+default Order dec
+
+typedef ProcState = const struct forall Num 'n.
+{
+ bit['n] N;
+ bit[1] Z;
+ bit[1] C;
+ bit[1] V
+}
+
+register ProcState<2> PSTATE
+
+function unit test () =
+{
+ PSTATE.N := 0b1
+}
diff --git a/test/typecheck/fail/pure_record_arity.sail b/test/typecheck/fail/pure_record_arity.sail
new file mode 100644
index 00000000..846df2c3
--- /dev/null
+++ b/test/typecheck/fail/pure_record_arity.sail
@@ -0,0 +1,25 @@
+default Order dec
+
+typedef State = const struct forall Type 'a, Nat 'n. {
+ vector<0, 'n, dec, 'a> N;
+ vector<0, 1, dec, bit> Z;
+}
+
+register State procState
+
+let (State<bit,1>) myStateM = {
+ (State<bit,1>) r := undefined;
+ r.N := 0b1;
+ r.Z := 0b1;
+ r
+}
+
+let (State<bit,1>) myState = { N = 0b1; Z = 0b1 }
+
+val unit -> unit effect {undef} test
+
+function test () = {
+ (State<bit,1>) myState1 := undefined;
+ (State<bit,1>) myState2 := { N = undefined; Z = 0b1 };
+ (State<bit,1>) myState3 := { myState2 with N = 0b0 }
+}
diff --git a/test/typecheck/fail/pure_record_arity2.sail b/test/typecheck/fail/pure_record_arity2.sail
new file mode 100644
index 00000000..a9566da8
--- /dev/null
+++ b/test/typecheck/fail/pure_record_arity2.sail
@@ -0,0 +1,25 @@
+default Order dec
+
+typedef State = const struct forall Type 'a, Nat 'n. {
+ vector<0, 'n, dec, 'a> N;
+ vector<0, 1, dec, bit> Z;
+}
+
+register State<bit,inc> procState
+
+let (State<bit,1>) myStateM = {
+ (State<bit,1>) r := undefined;
+ r.N := 0b1;
+ r.Z := 0b1;
+ r
+}
+
+let (State<bit,1>) myState = { N = 0b1; Z = 0b1 }
+
+val unit -> unit effect {undef} test
+
+function test () = {
+ (State<bit,1>) myState1 := undefined;
+ (State<bit,1>) myState2 := { N = undefined; Z = 0b1 };
+ (State<bit,1>) myState3 := { myState2 with N = 0b0 }
+}
diff --git a/test/typecheck/fail/reg_mod.sail b/test/typecheck/fail/reg_mod.sail
new file mode 100644
index 00000000..24b318b4
--- /dev/null
+++ b/test/typecheck/fail/reg_mod.sail
@@ -0,0 +1,11 @@
+
+register [|0:10|] reg
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ reg := 9;
+ reg := 10;
+ reg := 8
+} \ No newline at end of file
diff --git a/test/typecheck/fail/return_simple2.sail b/test/typecheck/fail/return_simple2.sail
new file mode 100644
index 00000000..f212a945
--- /dev/null
+++ b/test/typecheck/fail/return_simple2.sail
@@ -0,0 +1,9 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ x;
+ return x;
+ x
+}
diff --git a/test/typecheck/fail/return_simple3.sail b/test/typecheck/fail/return_simple3.sail
new file mode 100644
index 00000000..df75c5bd
--- /dev/null
+++ b/test/typecheck/fail/return_simple3.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return 9;
+ x
+}
diff --git a/test/typecheck/fail/return_simple4.sail b/test/typecheck/fail/return_simple4.sail
new file mode 100644
index 00000000..aa7c3010
--- /dev/null
+++ b/test/typecheck/fail/return_simple4.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return x;
+ 9
+}
diff --git a/test/typecheck/fail/return_simple5.sail b/test/typecheck/fail/return_simple5.sail
new file mode 100644
index 00000000..d6947d91
--- /dev/null
+++ b/test/typecheck/fail/return_simple5.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N. [|10:'N - 1|] -> [|10:'N - 1|] effect pure return_test
+
+function forall Nat 'N. [|10:'N - 1|] return_test x =
+{
+ return x;
+ sizeof 'N
+}
diff --git a/test/typecheck/fail/return_simple6.sail b/test/typecheck/fail/return_simple6.sail
new file mode 100644
index 00000000..0e118632
--- /dev/null
+++ b/test/typecheck/fail/return_simple6.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return x;
+ sizeof 'N
+}
diff --git a/test/typecheck/fail/set_spsr1.sail b/test/typecheck/fail/set_spsr1.sail
new file mode 100644
index 00000000..27c343b2
--- /dev/null
+++ b/test/typecheck/fail/set_spsr1.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - 'o - 1,dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[32] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[32]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[30..0] := r
+}
diff --git a/test/typecheck/fail/set_spsr2.sail b/test/typecheck/fail/set_spsr2.sail
new file mode 100644
index 00000000..00493444
--- /dev/null
+++ b/test/typecheck/fail/set_spsr2.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - 'o - 1,dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[32] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[32]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[0..31] := r
+}
diff --git a/test/typecheck/fail/set_spsr3.sail b/test/typecheck/fail/set_spsr3.sail
new file mode 100644
index 00000000..c3a6208e
--- /dev/null
+++ b/test/typecheck/fail/set_spsr3.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - 'o - 1,dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[32] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[32]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[32..1] := r
+}
diff --git a/test/typecheck/fail/set_spsr4.sail b/test/typecheck/fail/set_spsr4.sail
new file mode 100644
index 00000000..65596b59
--- /dev/null
+++ b/test/typecheck/fail/set_spsr4.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - 'o - 1,dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[31] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[32]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[31..0] := r
+}
diff --git a/test/typecheck/fail/set_spsr5.sail b/test/typecheck/fail/set_spsr5.sail
new file mode 100644
index 00000000..d8a6588c
--- /dev/null
+++ b/test/typecheck/fail/set_spsr5.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - 'o - 1,dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[32] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[16]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[31..0] := r
+}
diff --git a/test/typecheck/fail/vec_pat1.sail b/test/typecheck/fail/vec_pat1.sail
new file mode 100644
index 00000000..e10838f6
--- /dev/null
+++ b/test/typecheck/fail/vec_pat1.sail
@@ -0,0 +1,17 @@
+default Order inc
+
+val extern forall Num 'n. (bit['n], bit['n]) -> bit['n] effect pure bv_add = "bv_add_inc"
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p, Type 'a.
+ (vector<'n,'m,inc,'a>, vector<'o,'p,inc,'a>) -> vector<'n,'m + 'p,inc,'a>
+ effect pure vector_append_inc
+
+overload (deinfix +) [bv_add]
+overload vector_append [vector_append_inc]
+
+val (bit[3], bit[3]) -> bit[3] effect pure test
+
+function bit[3] test (((bit[0]) x : 0b11 : 0b0), z) =
+{
+ (x : 0b11) + z
+}
diff --git a/test/typecheck/fail/vector_access1.sail b/test/typecheck/fail/vector_access1.sail
new file mode 100644
index 00000000..1eef5250
--- /dev/null
+++ b/test/typecheck/fail/vector_access1.sail
@@ -0,0 +1,12 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+default Order inc
+
+val bit[4] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,0);
+ z := v[4]
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_access2.sail b/test/typecheck/fail/vector_access2.sail
new file mode 100644
index 00000000..0b4ba7c2
--- /dev/null
+++ b/test/typecheck/fail/vector_access2.sail
@@ -0,0 +1,12 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+default Order inc
+
+val bit[4] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,-1);
+ z := v[3]
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_access3.sail b/test/typecheck/fail/vector_access3.sail
new file mode 100644
index 00000000..dd43cfea
--- /dev/null
+++ b/test/typecheck/fail/vector_access3.sail
@@ -0,0 +1,12 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+default Order inc
+
+val bit[0] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,0);
+ z := v[0]
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_access4.sail b/test/typecheck/fail/vector_access4.sail
new file mode 100644
index 00000000..31d34eae
--- /dev/null
+++ b/test/typecheck/fail/vector_access4.sail
@@ -0,0 +1,12 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+default Order inc
+
+val bit[-5] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,([|0:-5|]) -1);
+ z := v[-1]
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append1.sail b/test/typecheck/fail/vector_append1.sail
new file mode 100644
index 00000000..e2429380
--- /dev/null
+++ b/test/typecheck/fail/vector_append1.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+default Order inc
+
+val (bit[4], bit[4]) -> bit[7] effect pure test
+
+function bit[7] test (v1, v2) =
+{
+ z := vector_access(v1, 3);
+ z := v1[0];
+ zv := vector_append(v1, v2);
+ zv := v1 : v2;
+ zv
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append2.sail b/test/typecheck/fail/vector_append2.sail
new file mode 100644
index 00000000..acaeb0b0
--- /dev/null
+++ b/test/typecheck/fail/vector_append2.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+default Order inc
+
+val (bit[4], bit[4]) -> bit[9] effect pure test
+
+function bit[9] test (v1, v2) =
+{
+ z := vector_access(v1, 3);
+ z := v1[0];
+ zv := vector_append(v1, v2);
+ zv := v1 : v2;
+ zv
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append3.sail b/test/typecheck/fail/vector_append3.sail
new file mode 100644
index 00000000..82f0a861
--- /dev/null
+++ b/test/typecheck/fail/vector_append3.sail
@@ -0,0 +1,18 @@
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+default Order inc
+
+val (bit[4], bit[4]) -> bit[7] effect pure test
+
+function bit[7] test (v1, v2) =
+{
+ z := vector_access(v1, 3);
+ z := v1[0];
+ zv := vector_append(v1, v2);
+ zv := v1 : v2;
+ zv
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append_gen1.sail b/test/typecheck/fail/vector_append_gen1.sail
new file mode 100644
index 00000000..727d5c14
--- /dev/null
+++ b/test/typecheck/fail/vector_append_gen1.sail
@@ -0,0 +1,14 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+default Order inc
+
+val forall 'n, 'm. (bit['n], bit['m]) -> bit['n + 'm] effect pure test
+
+function forall 'n, 'm. bit['n + 'm] test (v1, v2) =
+{
+ v1 : v2;
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append_gen2.sail b/test/typecheck/fail/vector_append_gen2.sail
new file mode 100644
index 00000000..8e534253
--- /dev/null
+++ b/test/typecheck/fail/vector_append_gen2.sail
@@ -0,0 +1,14 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+default Order inc
+
+val forall 'n, 'm. (bit['n], bit['m]) -> bit['n + 'm] effect pure test
+
+function forall 'n, 'm. bit['n + 'm] test (v1, v2) =
+{
+ vector_append(v1, v2);
+} \ No newline at end of file
diff --git a/test/typecheck/fail/vector_append_old.sail b/test/typecheck/fail/vector_append_old.sail
new file mode 100644
index 00000000..fb6018b9
--- /dev/null
+++ b/test/typecheck/fail/vector_append_old.sail
@@ -0,0 +1,14 @@
+
+val extern forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,bit>, vector<'n2,'l2,'o,bit>) -> vector<'n1,'l1 + 'l2,'o,bit> effect pure vector_append = "bitvector_concat"
+
+default Order inc
+
+val (bit[4], bit[4]) -> bit[8] effect pure test
+
+function bit[8] test (v1, v2) =
+{
+ zv := vector_append(v1, v2);
+ zv := v1 : v2;
+ zv
+}
diff --git a/test/typecheck/fail/vector_arity.sail b/test/typecheck/fail/vector_arity.sail
new file mode 100644
index 00000000..6ecc9565
--- /dev/null
+++ b/test/typecheck/fail/vector_arity.sail
@@ -0,0 +1,4 @@
+
+val vector<0,5,inc,bit,bit> -> vector<0,5,inc,bit,bit> effect pure test
+
+function vector<0,5,inc,bit,bit> test x = x \ No newline at end of file
diff --git a/test/typecheck/fail/vector_subrange_gen1.sail b/test/typecheck/fail/vector_subrange_gen1.sail
new file mode 100644
index 00000000..0ae6f9f9
--- /dev/null
+++ b/test/typecheck/fail/vector_subrange_gen1.sail
@@ -0,0 +1,20 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'u, Order 'o, Type 'a, 'l >= 0, 'm <= 'u, 'u <= 'l. (vector<'n,'l,'o,'a>, [:'m:], [:'u:]) -> vector<'m,'u - 'm,'o,'a> effect pure vector_subrange
+
+val forall Nat 'n, Nat 'm. ([:'n:], [:'m:]) -> [:'n - 'm:] effect pure minus
+
+default Order inc
+
+val forall 'n, 'm, 'n >= 5. bit['n] -> bit['n - 2] effect pure test
+
+function forall 'n, 'n >= 5. bit['n - 3] test v =
+{
+ z := vector_subrange(v, 0, minus(sizeof 'n, 3));
+ z := v[0 .. minus(sizeof 'n, 2)];
+ z
+} \ No newline at end of file
diff --git a/test/typecheck/fail/word_width_bytes_mips.sail b/test/typecheck/fail/word_width_bytes_mips.sail
new file mode 100644
index 00000000..91f3e787
--- /dev/null
+++ b/test/typecheck/fail/word_width_bytes_mips.sail
@@ -0,0 +1,11 @@
+typedef WordType = enumerate {B; H; W; D}
+
+(* This fails because it's not true for all combinations of 'r and WordType *)
+(* Needs existential types, i.e. return type should be exists Nat 'r, 'r in {1,2,4,8}. [:'r:] *)
+function forall Nat 'r, 'r IN {1,2,4,8}. wordWidthBytes((WordType) w) =
+ switch(w) {
+ case B -> 1
+ case H -> 2
+ case W -> 4
+ case D -> 8
+ }
diff --git a/test/typecheck/pass/add_real.sail b/test/typecheck/pass/add_real.sail
new file mode 100644
index 00000000..38a9cff3
--- /dev/null
+++ b/test/typecheck/pass/add_real.sail
@@ -0,0 +1,5 @@
+val (real, real) -> real effect pure add_real
+
+overload (deinfix +) [add_real]
+
+let (real) r = 2.2 + 0.2
diff --git a/test/typecheck/pass/add_vec_exts_no_annot.sail b/test/typecheck/pass/add_vec_exts_no_annot.sail
new file mode 100644
index 00000000..54aa2d40
--- /dev/null
+++ b/test/typecheck/pass/add_vec_exts_no_annot.sail
@@ -0,0 +1,19 @@
+default Order dec
+
+val forall Nat 'n, Nat 'm, Nat 'o, Nat 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure exts
+
+overload EXTS [exts]
+
+val forall Nat 'n, Nat 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure add_vec
+
+overload (deinfix +) [add_vec]
+
+val (bit[32], bit[32]) -> unit effect pure test
+
+function test (x, y) =
+{
+ let (bit[64]) z = add_vec(exts(x), exts(y)) in
+ ()
+}
diff --git a/test/typecheck/pass/add_vec_exts_no_annot_overload.sail b/test/typecheck/pass/add_vec_exts_no_annot_overload.sail
new file mode 100644
index 00000000..01e3bf7c
--- /dev/null
+++ b/test/typecheck/pass/add_vec_exts_no_annot_overload.sail
@@ -0,0 +1,19 @@
+default Order dec
+
+val forall Nat 'n, Nat 'm, Nat 'o, Nat 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure exts
+
+overload EXTS [exts]
+
+val forall Nat 'n, Nat 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure add_vec
+
+overload (deinfix +) [add_vec]
+
+val (bit[32], bit[32]) -> unit effect pure test
+
+function test (x, y) =
+{
+ let (bit[64]) z = EXTS(x) + EXTS(y) in
+ ()
+}
diff --git a/test/typecheck/pass/add_vec_lit.sail b/test/typecheck/pass/add_vec_lit.sail
new file mode 100644
index 00000000..4d662a8d
--- /dev/null
+++ b/test/typecheck/pass/add_vec_lit.sail
@@ -0,0 +1,10 @@
+default Order inc
+
+val extern forall Num 'n. (bit['n], bit['n]) -> bit['n] effect pure add_vec = "add_vec"
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add_range"
+
+val cast forall Num 'n. bit['n] -> [|0: 2** 'n - 1|] effect pure unsigned
+
+overload (deinfix +) [add_vec; add_range]
+
+let (range<0,30>) x = 0xF + 0x2
diff --git a/test/typecheck/pass/arm_FPEXC1.sail b/test/typecheck/pass/arm_FPEXC1.sail
new file mode 100644
index 00000000..f711a5ad
--- /dev/null
+++ b/test/typecheck/pass/arm_FPEXC1.sail
@@ -0,0 +1,53 @@
+default Order dec
+
+val extern forall Num 'n. (bit['n], int) -> bit effect pure vector_access = "bitvector_access_dec"
+
+val extern forall Num 'n, Num 'm, Num 'o, 'm >= 'o, 'o >= 0, 'n >= 'm + 1.
+ (bit['n], [:'m:], [:'o:]) -> bit['m - ('o - 1)] effect pure vector_subrange = "bitvector_subrange_dec"
+
+register vector<32 - 1, 32, dec, bit> _FPEXC32_EL2
+
+val vector<32 - 1, 32, dec, bit> -> unit effect {wreg} set_FPEXC32_EL2
+
+function set_FPEXC32_EL2 value_name =
+ {
+ _FPEXC32_EL2[0..0] := [value_name[0]];
+ _FPEXC32_EL2[1..1] := [value_name[1]];
+ _FPEXC32_EL2[2..2] := [value_name[2]];
+ _FPEXC32_EL2[3..3] := [value_name[3]];
+ _FPEXC32_EL2[4..4] := [value_name[4]];
+ _FPEXC32_EL2[6..5] := value_name[6 .. 5];
+ _FPEXC32_EL2[7..7] := [value_name[7]];
+ _FPEXC32_EL2[20..11] := value_name[20 .. 11];
+ _FPEXC32_EL2[29..29] := [value_name[29]];
+ _FPEXC32_EL2[30..30] := [value_name[30]]
+ }
+
+val unit -> vector<32 - 1, 32, dec, bit> effect {rreg} get_FPEXC32_EL2
+
+function get_FPEXC32_EL2 () =
+ {
+ (vector<32 - 1, 32, dec, bit> ) value_name := 0x04000700;
+ value_name[0..0] := [_FPEXC32_EL2[0]];
+ value_name[1..1] := [_FPEXC32_EL2[1]];
+ value_name[2..2] := [_FPEXC32_EL2[2]];
+ value_name[3..3] := [_FPEXC32_EL2[3]];
+ value_name[4..4] := [_FPEXC32_EL2[4]];
+ value_name[6..5] := _FPEXC32_EL2[6 .. 5];
+ value_name[7..7] := [_FPEXC32_EL2[7]];
+ value_name[20..11] := _FPEXC32_EL2[20 .. 11];
+ value_name[26..26] := [_FPEXC32_EL2[26]];
+ value_name[29..29] := [_FPEXC32_EL2[29]];
+ value_name[30..30] := [_FPEXC32_EL2[30]];
+ value_name
+ }
+
+val vector<32 - 1, 32, dec, bit> -> unit effect {rreg, wreg} set_FPEXC
+
+function set_FPEXC val_name =
+ {
+ (vector<32 - 1, 32, dec, bit> ) r := val_name;
+ (vector<32 - 1, 32, dec, bit> ) __tmp_45 := get_FPEXC32_EL2();
+ __tmp_45[31..0] := r;
+ set_FPEXC32_EL2(__tmp_45)
+ }
diff --git a/test/typecheck/pass/arm_types.sail b/test/typecheck/pass/arm_types.sail
new file mode 100644
index 00000000..d7244beb
--- /dev/null
+++ b/test/typecheck/pass/arm_types.sail
@@ -0,0 +1,140 @@
+
+typedef boolean = enumerate {FALSE; TRUE}
+
+typedef signal = enumerate {LOW; HIGH}
+
+typedef __RetCode =
+ enumerate {__RC_OK;
+ __RC_UNDEFINED;
+ __RC_UNPREDICTABLE;
+ __RC_SEE;
+ __RC_IMPLEMENTATION_DEFINED;
+ __RC_SUBARCHITECTURE_DEFINED;
+ __RC_EXCEPTION_TAKEN;
+ __RC_ASSERT_FAILED;
+ __RC_UNMATCHED_CASE}
+
+typedef TUBE_Type = bit[32]
+
+typedef ScheduleIRQ_Type = bit[32]
+
+typedef ClearIRQ_Type = bit[32]
+
+typedef ScheduleFIQ_Type = bit[32]
+
+typedef ClearFIQ_Type = bit[32]
+
+typedef TargetCPU_Type = bit[32]
+
+typedef AbortRgn64Lo1_Type = bit[32]
+
+typedef AbortRgn64Lo1_Hi_Type = bit[32]
+
+typedef AbortRgn64Hi1_Type = bit[32]
+
+typedef AbortRgn64Hi1_Hi_Type = bit[32]
+
+typedef AbortRgn64Lo2_Type = bit[32]
+
+typedef AbortRgn64Lo2_Hi_Type = bit[32]
+
+typedef AbortRgn64Hi2_Type = bit[32]
+
+typedef AbortRgn64Hi2_Hi_Type = bit[32]
+
+typedef AXIAbortCtl_Type = bit[32]
+
+typedef GTE_API_Type = bit[32]
+
+typedef GTE_API_PARAM_Type = bit[32]
+
+typedef GTE_API_STATUS_Type = bit[32]
+
+typedef PPURBAR_Type = bit[32]
+
+typedef PPURSER_Type = bit[32]
+
+typedef PPURACR_Type = bit[32]
+
+typedef GTE_API_STATUS_64_Type = bit[32]
+
+typedef GTE_API_STATUS_64_HI_Type = bit[32]
+
+typedef GTE_API_PARAM_64_Type = bit[32]
+
+typedef GTE_API_PARAM_64_HI_Type = bit[32]
+
+typedef MemAtomicOp =
+ enumerate {MemAtomicOp_ADD;
+ MemAtomicOp_BIC;
+ MemAtomicOp_EOR;
+ MemAtomicOp_ORR;
+ MemAtomicOp_SMAX;
+ MemAtomicOp_SMIN;
+ MemAtomicOp_UMAX;
+ MemAtomicOp_UMIN;
+ MemAtomicOp_SWP}
+
+typedef SCRType = bit[32]
+
+typedef SCTLRType = bit[32]
+
+typedef MAIRType = bit[64]
+
+typedef ESRType = bit[32]
+
+typedef FPCRType = bit[32]
+
+typedef FPSRType = bit[32]
+
+typedef FPSCRType = bit[32]
+
+typedef CPSRType = bit[32]
+
+typedef APSRType = bit[32]
+
+typedef ITSTATEType = bit[8]
+
+typedef CPACRType = bit[32]
+
+typedef CNTKCTLType = bit[32]
+
+typedef GTEParamType = enumerate {GTEParam_WORD; GTEParam_LIST; GTEParam_EOACCESS}
+
+typedef GTE_PPU_SizeEn_Type = bit[32]
+
+typedef GTEExtObsAccess_Type = bit[16]
+
+typedef GTEASAccess_Type = bit[32]
+
+typedef GTEASRecordedAccess_Type = bit[32]
+
+typedef AccType =
+ enumerate {AccType_NORMAL;
+ AccType_VEC;
+ AccType_STREAM;
+ AccType_VECSTREAM;
+ AccType_ATOMIC;
+ AccType_ORDERED;
+ AccType_UNPRIV;
+ AccType_IFETCH;
+ AccType_PTW;
+ AccType_DC;
+ AccType_IC;
+ AccType_DCZVA;
+ AccType_AT}
+
+typedef MemType = enumerate {MemType_Normal; MemType_Device}
+
+typedef DeviceType =
+ enumerate {DeviceType_GRE; DeviceType_nGRE; DeviceType_nGnRE; DeviceType_nGnRnE}
+
+typedef MemAttrHints = const struct {bit[2] attrs; bit[2] hints; bool transient;}
+
+typedef MemoryAttributes =
+ const struct {MemType type;
+ DeviceType device;
+ MemAttrHints inner;
+ MemAttrHints outer;
+ bool shareable;
+ bool outershareable;}
diff --git a/test/typecheck/pass/as_pattern.sail b/test/typecheck/pass/as_pattern.sail
new file mode 100644
index 00000000..a1cd9461
--- /dev/null
+++ b/test/typecheck/pass/as_pattern.sail
@@ -0,0 +1,7 @@
+
+val int -> int effect pure test
+
+function test ((int) _ as x) =
+{
+ x
+}
diff --git a/test/typecheck/pass/assignment_simple.sail b/test/typecheck/pass/assignment_simple.sail
new file mode 100644
index 00000000..dc0c78d8
--- /dev/null
+++ b/test/typecheck/pass/assignment_simple.sail
@@ -0,0 +1,16 @@
+
+val ([:10:], unit) -> [:10:] effect pure f
+
+function [:10:] f (x, y) = x
+
+val unit -> [:10:] effect pure test
+
+function [:10:] test () =
+{
+ z := 10;
+ z
+}
+
+val unit -> unit effect pure test2
+
+function unit test2 () = x := 10 \ No newline at end of file
diff --git a/test/typecheck/pass/atomcase.sail b/test/typecheck/pass/atomcase.sail
new file mode 100644
index 00000000..18840867
--- /dev/null
+++ b/test/typecheck/pass/atomcase.sail
@@ -0,0 +1,18 @@
+default Order dec
+
+val extern forall Num 'n, Num 'm. (atom<'n>, atom<'m>) -> bool effect pure eq_atom
+overload (deinfix ==) [eq_atom]
+
+val forall 'n, 'n in {8,16}. [:'n:] -> int effect pure test_fn
+val forall 'n, 'n in {8,16}. [:'n:] -> int effect pure test_switch
+
+function test_fn 8 = 8
+and test_fn 16 = 16
+
+
+function test_switch n =
+ switch(n) {
+ case 8 -> 8
+ case 16 -> 16
+ }
+
diff --git a/test/typecheck/pass/bitwise_not.sail b/test/typecheck/pass/bitwise_not.sail
new file mode 100644
index 00000000..1c4f8d3b
--- /dev/null
+++ b/test/typecheck/pass/bitwise_not.sail
@@ -0,0 +1,7 @@
+val forall Nat 'n, Nat 'm, Order 'o. vector<'n,'m,'o,bit> -> vector<'n,'m,'o,bit> effect pure bitwise_not
+
+default Order dec
+
+val bit[5] -> bit[5] effect pure test
+
+function bit[5] test ((bit[5]) x) = bitwise_not(x) \ No newline at end of file
diff --git a/test/typecheck/pass/bitwise_not_gen.sail b/test/typecheck/pass/bitwise_not_gen.sail
new file mode 100644
index 00000000..6d36c566
--- /dev/null
+++ b/test/typecheck/pass/bitwise_not_gen.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'n, Nat 'm, Order 'o. vector<'n,'m,'o,bit> -> vector<'n,'m,'o,bit> effect pure bitwise_not
+
+default Order dec
+
+val forall 'n. bit['n] -> bit['n] effect pure test
+
+function forall 'n. bit['n] test ((bit['n]) x) = bitwise_not(bitwise_not(x))
diff --git a/test/typecheck/pass/bitwise_not_x3.sail b/test/typecheck/pass/bitwise_not_x3.sail
new file mode 100644
index 00000000..49d962a6
--- /dev/null
+++ b/test/typecheck/pass/bitwise_not_x3.sail
@@ -0,0 +1,7 @@
+val forall Nat 'n, Nat 'm, Order 'o. vector<'n,'m,'o,bit> -> vector<'n,'m,'o,bit> effect pure bitwise_not
+
+default Order dec
+
+val bit[5] -> bit[5] effect pure test
+
+function bit[5] test ((bit[5]) x) = bitwise_not(bitwise_not(bitwise_not(x))) \ No newline at end of file
diff --git a/test/typecheck/pass/bv_simple_index.sail b/test/typecheck/pass/bv_simple_index.sail
new file mode 100644
index 00000000..811b3a5b
--- /dev/null
+++ b/test/typecheck/pass/bv_simple_index.sail
@@ -0,0 +1,11 @@
+val forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,dec,bit>, [|'n - 'l + 1:'n|]) -> bit effect pure bitvector_access_dec
+val forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,inc,bit>, [|'n:'n + 'l - 1|]) -> bit effect pure bitvector_access_inc
+
+overload vector_access [bitvector_access_inc; bitvector_access_dec]
+
+val cast bit -> bool effect pure cast_bit_bool
+
+function bool bv ((bit[64]) x) =
+{
+ x[32]
+}
diff --git a/test/typecheck/pass/bv_simple_index_bit.sail b/test/typecheck/pass/bv_simple_index_bit.sail
new file mode 100644
index 00000000..46bc19d6
--- /dev/null
+++ b/test/typecheck/pass/bv_simple_index_bit.sail
@@ -0,0 +1,9 @@
+val forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,dec,bit>, [|'n - 'l + 1:'n|]) -> bit effect pure bitvector_access_dec
+val forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,inc,bit>, [|'n:'n + 'l - 1|]) -> bit effect pure bitvector_access_inc
+
+overload vector_access [bitvector_access_inc; bitvector_access_dec]
+
+function bit bv ((bit[64]) x) =
+{
+ x[32]
+}
diff --git a/test/typecheck/pass/case_simple1.sail b/test/typecheck/pass/case_simple1.sail
new file mode 100644
index 00000000..e4a81a36
--- /dev/null
+++ b/test/typecheck/pass/case_simple1.sail
@@ -0,0 +1,9 @@
+
+val forall Nat 'N. ([:10:], [|10:'N|]) -> [|10:'N|] effect pure case_test
+
+function forall Nat 'N. [|10:'N|] case_test (x, y) =
+{
+ switch (x, y) {
+ case _ -> y
+ }
+}
diff --git a/test/typecheck/pass/case_simple2.sail b/test/typecheck/pass/case_simple2.sail
new file mode 100644
index 00000000..0ffba780
--- /dev/null
+++ b/test/typecheck/pass/case_simple2.sail
@@ -0,0 +1,9 @@
+
+val forall Nat 'N, 'N >= 10. ([:10:], [|10:'N|]) -> [|10:'N|] effect pure case_test
+
+function forall Nat 'N. [|10:'N|] case_test (x, y) =
+{
+ switch (x, y) {
+ case _ -> x
+ }
+}
diff --git a/test/typecheck/pass/case_simple_constraints.sail b/test/typecheck/pass/case_simple_constraints.sail
new file mode 100644
index 00000000..335e10ee
--- /dev/null
+++ b/test/typecheck/pass/case_simple_constraints.sail
@@ -0,0 +1,18 @@
+
+val extern forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus = "add"
+
+val extern forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id = "id"
+
+val extern forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id = "id"
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ switch x {
+ case ([|10:30|]) y -> y
+ case ([:31:]) _ -> sizeof 'N
+ case ([|31:40|]) _ -> plus(60,3)
+ }
+}
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/pass/cast_lexp1.sail b/test/typecheck/pass/cast_lexp1.sail
new file mode 100644
index 00000000..b8b29b87
--- /dev/null
+++ b/test/typecheck/pass/cast_lexp1.sail
@@ -0,0 +1,7 @@
+
+val unit -> int effect pure test
+
+function int test () = {
+ (int) y := 10;
+ y
+}
diff --git a/test/typecheck/pass/cast_lexp2.sail b/test/typecheck/pass/cast_lexp2.sail
new file mode 100644
index 00000000..a6f6d299
--- /dev/null
+++ b/test/typecheck/pass/cast_lexp2.sail
@@ -0,0 +1,7 @@
+
+val unit -> int effect pure test
+
+function int test () = {
+ (nat) y := 10;
+ y
+}
diff --git a/test/typecheck/pass/cast_simple.sail b/test/typecheck/pass/cast_simple.sail
new file mode 100644
index 00000000..c1507f26
--- /dev/null
+++ b/test/typecheck/pass/cast_simple.sail
@@ -0,0 +1,7 @@
+
+val unit -> int effect pure test
+
+function int test () = {
+ (nat) y := ([|0:10|]) 10;
+ (int) y
+}
diff --git a/test/typecheck/pass/cons_pattern.sail b/test/typecheck/pass/cons_pattern.sail
new file mode 100644
index 00000000..107bd6d5
--- /dev/null
+++ b/test/typecheck/pass/cons_pattern.sail
@@ -0,0 +1,8 @@
+
+function unit test ((list<bit>) xs) =
+{
+ switch xs {
+ case x :: xs -> ()
+ case [||||] -> ()
+ }
+}
diff --git a/test/typecheck/pass/cons_pattern_synonym.sail b/test/typecheck/pass/cons_pattern_synonym.sail
new file mode 100644
index 00000000..f5b26294
--- /dev/null
+++ b/test/typecheck/pass/cons_pattern_synonym.sail
@@ -0,0 +1,7 @@
+typedef ty = list<(bit[8])>
+
+function bool foo ((ty) l) =
+ switch l {
+ case _ :: _ -> false
+ case _ -> true
+ } \ No newline at end of file
diff --git a/test/typecheck/pass/default_order.sail b/test/typecheck/pass/default_order.sail
new file mode 100644
index 00000000..a283b221
--- /dev/null
+++ b/test/typecheck/pass/default_order.sail
@@ -0,0 +1 @@
+default Order dec
diff --git a/test/typecheck/pass/deinfix_plus.sail b/test/typecheck/pass/deinfix_plus.sail
new file mode 100644
index 00000000..8fc7c00e
--- /dev/null
+++ b/test/typecheck/pass/deinfix_plus.sail
@@ -0,0 +1,12 @@
+default Order inc
+
+val extern forall Num 'n. (bit['n], bit['n]) -> bit['n] effect pure bv_add = "add_vec"
+
+overload (deinfix +) [bv_add]
+
+val (bit[3], bit[3]) -> bit[3] effect pure test
+
+function bit[3] test (x, y) =
+{
+ x + y
+}
diff --git a/test/typecheck/pass/ex_cast.sail b/test/typecheck/pass/ex_cast.sail
new file mode 100644
index 00000000..964bfa72
--- /dev/null
+++ b/test/typecheck/pass/ex_cast.sail
@@ -0,0 +1,12 @@
+
+default Order dec
+
+val cast int -> exist 'n. [:'n:] effect pure ex_int
+
+val forall 'n. [:'n:] -> bit['n] effect pure zeros
+
+val int -> unit effect pure test
+
+function test n = {
+ x := zeros(n)
+}
diff --git a/test/typecheck/pass/exint.sail b/test/typecheck/pass/exint.sail
new file mode 100644
index 00000000..1239fa44
--- /dev/null
+++ b/test/typecheck/pass/exint.sail
@@ -0,0 +1,22 @@
+
+typedef Int = exist 'n. [:'n:]
+
+val forall 'n, 'm. ([:'n:], [:'m:]) -> exist 'o, 'o = 'n + 'm. [:'o:] effect pure add
+
+val forall 'n, 'm. ([:'n:], [:'m:]) -> exist 'o, 'o = 'n * 'm. [:'o:] effect pure mult
+
+overload (deinfix +) [add]
+
+overload (deinfix * ) [mult]
+
+let x = 3 + 4
+
+let y = x + x * x
+
+let ([:7 * 8:]) z = y
+
+typedef Range = forall Num 'n, Num 'm, 'n <= 'm. exist 'o, 'n <= 'o & 'o <= 'm. [:'o:]
+
+let (Range<3,4>) a = 3
+
+let (Range<2,5>) b = a + 1 \ No newline at end of file
diff --git a/test/typecheck/pass/exist1.sail b/test/typecheck/pass/exist1.sail
new file mode 100644
index 00000000..31968f36
--- /dev/null
+++ b/test/typecheck/pass/exist1.sail
@@ -0,0 +1,30 @@
+
+let (exist 'n, 'n in {0, 1}. [:'n:]) v1 = 0
+
+val bool -> exist 'n, 'n in {0, 1}. [:'n:] effect pure test
+
+function test flag =
+{
+ if flag then 0 else 1
+}
+
+let ([|0:1|]) v2 = test(true)
+
+val forall 'a, 'b. ([:'a:], [:'b:]) -> [:'a + 'b:] effect pure add
+
+let (exist 'k, 'k in {3, 4}. [:'k:]) v3 = 3
+
+let (exist 'q, 'q in {0, 1}. [:'q + 3:]) v4 = v3
+
+let v5 = add(test(true), 4)
+
+let ([:4:]) v6 = 4
+
+function unit unit_fn (([:4:]) x) = ()
+
+val forall 'a. ([:'a:], [:'a:]) -> [:'a + 'a:] effect pure s_add
+
+let (exist 'k, 'k = 4. [:'k:]) v7 = 4
+
+let v8 = s_add(v7, 4)
+
diff --git a/test/typecheck/pass/exist2.sail b/test/typecheck/pass/exist2.sail
new file mode 100644
index 00000000..04ccb57b
--- /dev/null
+++ b/test/typecheck/pass/exist2.sail
@@ -0,0 +1,46 @@
+
+let (exist 'n, 'n in {0, 1}. [:'n:]) v1 = 0
+
+val bool -> exist 'n, 'n in {0, 1}. [:'n:] effect pure test
+
+function test flag =
+{
+ if flag then 0 else 1
+}
+
+let ([|0:1|]) v2 = test(true)
+
+val forall 'a, 'b. ([:'a:], [:'b:]) -> [:'a + 'b:] effect pure add
+
+let (exist 'k, 'k in {3, 4}. [:'k:]) v3 = 3
+
+let (exist 'q, 'q in {0, 1}. [:'q + 3:]) v4 = v3
+
+let v5 = add(test(true), 4)
+
+let ([:4:]) v6 = 4
+
+function unit unit_fn (([:4:]) x) = ()
+
+val forall 'a. ([:'a:], [:'a:]) -> [:'a + 'a:] effect pure s_add
+
+let (exist 'k, 'k = 4. [:'k:]) v7 = 4
+
+(* let v8 = s_add(test(true), 4) *)
+
+let (exist 'n, 0 = 0. [:'n:]) v9 = 100
+
+let (int) v10 = v9
+
+typedef Int = exist 'n, 0 = 0. [:'n:]
+
+val int -> Int effect pure existential_int
+val forall 'n, 'm. range<'n,'m> -> exist 'e, 'n <= 'e & 'e <= 'm. [:'e:] effect pure existential_range
+
+overload existential [existential_int; existential_range]
+
+let (exist 'n, 0 = 0. [:'n:]) v11 = existential(v10)
+
+let (exist 'e, 0 <= 'e & 'e <= 3. [:'e:]) v12 = existential(([|0:3|]) 2)
+
+let (Int) v13 = existential(v10)
diff --git a/test/typecheck/pass/exist_pattern.sail b/test/typecheck/pass/exist_pattern.sail
new file mode 100644
index 00000000..4561074a
--- /dev/null
+++ b/test/typecheck/pass/exist_pattern.sail
@@ -0,0 +1,42 @@
+default Order inc
+
+register nat n
+register nat x
+register nat y
+
+val (int, int) -> bool effect pure eq_int
+
+overload (deinfix ==) [eq_int]
+
+typedef wordsize = exist 'n, 'n IN {8,16,32}. [|'n|]
+let (wordsize) word = ([|8|]) 8
+
+function nat main () = {
+
+ (* works - x and y are set to 42 *)
+ n := 1;
+ y :=
+ (switch n {
+ case 0 -> { x := 21; x }
+ case 1 -> { x := 42; x }
+ case z -> { x := 99; x }
+ });
+
+ switch word {
+ case ([|8|]) 8 -> { x:= 32; }
+ case ([|16|]) 16 -> { x:= 64; }
+ case ([|32|]) 32 -> { x:= 128; }
+ };
+
+ switch 0b010101 {
+ case (0b01:(bit[1]) _:0b101) -> n:= 42
+ case _ -> n:=0
+ };
+
+ n := 3;
+ switch n {
+ case 0 -> { 21 }
+ case 1 -> { 42 }
+ case u -> { 99 }
+ };
+}
diff --git a/test/typecheck/pass/exist_simple.sail b/test/typecheck/pass/exist_simple.sail
new file mode 100644
index 00000000..87e62b13
--- /dev/null
+++ b/test/typecheck/pass/exist_simple.sail
@@ -0,0 +1,15 @@
+
+register bool reg
+
+let (exist 'n, 0 <= 'n & 'n <= 4. [:'n:]) A = 4
+
+let ([|0:4|]) B = A
+
+val unit -> exist 'n, 'n in {0, 1}. [:'n:] effect {rreg} test
+
+function test () =
+{
+ if reg
+ then 0
+ else 1
+}
diff --git a/test/typecheck/pass/exist_subrange.sail b/test/typecheck/pass/exist_subrange.sail
new file mode 100644
index 00000000..de867b75
--- /dev/null
+++ b/test/typecheck/pass/exist_subrange.sail
@@ -0,0 +1,12 @@
+default Order dec
+
+val forall Num 'n, Num 'm, Num 'o (* , 'm >= 'o, 'o >= 0, 'n >= 'm + 1 *).
+ (bit['n], [:'m:], [:'o:]) -> bit['m - ('o - 1)] effect pure vector_subrange
+
+function unit test ((bit[6]) xs) =
+{
+ (int) len := 4;
+ (exist 'n. [:'n:]) len := 5;
+ ys := xs[len .. 0];
+ ()
+}
diff --git a/test/typecheck/pass/exist_tlb.sail b/test/typecheck/pass/exist_tlb.sail
new file mode 100644
index 00000000..525d29c6
--- /dev/null
+++ b/test/typecheck/pass/exist_tlb.sail
@@ -0,0 +1,94 @@
+
+(* Minimal prelude *)
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure extz
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure exts
+
+overload EXTZ [extz]
+overload EXTS [exts]
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure add_vec
+
+overload (deinfix +) [add_vec]
+
+val bool -> bool effect pure bool_not
+overload ~ [bool_not]
+
+(* MIPS spec subset *)
+
+default Order dec
+
+register (bit[1]) CP0LLBit
+register (bit[64]) CP0LLAddr
+
+typedef MemAccessType = enumerate {Instruction; LoadData; StoreData}
+
+typedef regno = bit[5] (* a register number *)
+typedef imm16 = bit[16] (* 16-bit immediate *)
+
+typedef Exception = enumerate
+{
+ Int; TLBMod; TLBL; TLBS; AdEL; AdES; Sys; Bp; ResI; CpU; Ov; Tr; C2E; C2Trap;
+ XTLBRefillL; XTLBRefillS; XTLBInvL; XTLBInvS; MCheck
+}
+
+typedef WordType = enumerate {B; H; W; D}
+
+val bit[5] -> bit[64] effect {rreg} rGPR
+val (bit[64], WordType) -> bool effect pure isAddressAligned
+val forall Type 'o. (Exception, bit[64]) -> 'o effect pure SignalExceptionBadAddr
+
+val WordType -> exist 'r, 'r in {1,2,4,8}. [:'r:] effect pure wordWidthBytes
+
+function wordWidthBytes w = switch w {
+ case B -> 1
+ case H -> 2
+ case W -> 4
+ case D -> 8
+}
+
+val forall Nat 'n. (bit[64], [:'n:]) -> bit[8 * 'n] effect {rmem} MEMr_reserve_wrapper
+val forall Nat 'n. (bit[64], [:'n:]) -> bit[8 * 'n] effect {rmem} MEMr_wrapper
+val (bit[5], bit[64]) -> unit effect {wreg} wGPR
+
+function bit[64] addrWrapper((bit[64]) addr, (MemAccessType) accessType, (WordType) width) = addr
+
+function (bit[64]) TLBTranslate ((bit[64]) vAddr, (MemAccessType) accessType) = vAddr
+
+scattered typedef ast = const union
+
+val ast -> unit effect {rmem, rreg, wreg} execute
+
+scattered function unit execute
+
+union ast member (WordType, bool, bool, regno, regno, imm16) Load
+
+function clause execute (Load(width, signed, linked, base, rt, offset)) =
+ {
+ (bit[64]) vAddr := addrWrapper(EXTS(offset) + rGPR(base), LoadData, width);
+ if ~ (isAddressAligned(vAddr, width)) then
+ (SignalExceptionBadAddr(AdEL, vAddr)) (* unaligned access *)
+ else
+ let pAddr = (TLBTranslate(vAddr, LoadData)) in
+ {
+ (exist 't, 't in {1,2,4,8}. bit[8 * 't]) memResult := if linked then
+ {
+ CP0LLBit := 0b1;
+ CP0LLAddr := pAddr;
+ MEMr_reserve_wrapper(pAddr, wordWidthBytes(width));
+ }
+ else
+ MEMr_wrapper(pAddr, wordWidthBytes(width));
+ if (signed) then
+ wGPR(rt) := EXTS(memResult)
+ else
+ wGPR(rt) := EXTZ(memResult)
+ }
+ }
+
+end ast
+end execute
diff --git a/test/typecheck/pass/exist_true.sail b/test/typecheck/pass/exist_true.sail
new file mode 100644
index 00000000..a30fb87b
--- /dev/null
+++ b/test/typecheck/pass/exist_true.sail
@@ -0,0 +1,7 @@
+
+function unit test () =
+{
+ (exist 'n. [:'n:]) x := 4;
+ (exist 'n, true. [:'n:]) y := 5;
+ ()
+}
diff --git a/test/typecheck/pass/exit1.sail b/test/typecheck/pass/exit1.sail
new file mode 100644
index 00000000..92515c5a
--- /dev/null
+++ b/test/typecheck/pass/exit1.sail
@@ -0,0 +1,8 @@
+
+val unit -> [:6:] effect {escape} test
+
+function [:6:] test () =
+{
+ exit ();
+ 6
+}
diff --git a/test/typecheck/pass/exit2.sail b/test/typecheck/pass/exit2.sail
new file mode 100644
index 00000000..574302cc
--- /dev/null
+++ b/test/typecheck/pass/exit2.sail
@@ -0,0 +1,7 @@
+
+val unit -> [:6:] effect {escape} test
+
+function [:6:] test () =
+{
+ exit ();
+}
diff --git a/test/typecheck/pass/exit3.sail b/test/typecheck/pass/exit3.sail
new file mode 100644
index 00000000..e26ff95c
--- /dev/null
+++ b/test/typecheck/pass/exit3.sail
@@ -0,0 +1,7 @@
+
+val forall Type 'a. unit -> 'a effect {escape} test
+
+function forall Type 'a. 'a test () =
+{
+ exit ();
+}
diff --git a/test/typecheck/pass/flow_gt1.sail b/test/typecheck/pass/flow_gt1.sail
new file mode 100644
index 00000000..ddeefd53
--- /dev/null
+++ b/test/typecheck/pass/flow_gt1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x > 31)
+ then x - 32
+ else x + 32
+}
diff --git a/test/typecheck/pass/flow_gteq1.sail b/test/typecheck/pass/flow_gteq1.sail
new file mode 100644
index 00000000..47f7aa0f
--- /dev/null
+++ b/test/typecheck/pass/flow_gteq1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x >= 32)
+ then x - 32
+ else x + 32
+}
diff --git a/test/typecheck/pass/flow_lt1.sail b/test/typecheck/pass/flow_lt1.sail
new file mode 100644
index 00000000..c210ed7a
--- /dev/null
+++ b/test/typecheck/pass/flow_lt1.sail
@@ -0,0 +1,25 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x < 32)
+ then x + 32
+ else x - 32
+}
diff --git a/test/typecheck/pass/flow_lt2.sail b/test/typecheck/pass/flow_lt2.sail
new file mode 100644
index 00000000..cccebaa3
--- /dev/null
+++ b/test/typecheck/pass/flow_lt2.sail
@@ -0,0 +1,25 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x < 32)
+ then x + 2
+ else x - 2
+}
diff --git a/test/typecheck/pass/flow_lt_assign.sail b/test/typecheck/pass/flow_lt_assign.sail
new file mode 100644
index 00000000..9601f48f
--- /dev/null
+++ b/test/typecheck/pass/flow_lt_assign.sail
@@ -0,0 +1,29 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ y := x;
+ if (y < 32)
+ then {
+ y := 31;
+ y + 32
+ }
+ else y - 32
+}
diff --git a/test/typecheck/pass/flow_lteq1.sail b/test/typecheck/pass/flow_lteq1.sail
new file mode 100644
index 00000000..ffa4dd8b
--- /dev/null
+++ b/test/typecheck/pass/flow_lteq1.sail
@@ -0,0 +1,28 @@
+default Order inc
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n+'o:'m+'p|] effect pure add_range = "add"
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p. ([|'n:'m|], [|'o:'p|]) -> [|'n-'p:'m-'o|] effect pure sub_range = "sub"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+overload (deinfix +) [add_range]
+overload (deinfix -) [sub_range]
+overload (deinfix <) [lt_atom_range; lt_range_atom]
+overload (deinfix <=) [lteq_atom_range; lteq_range_atom]
+overload (deinfix >) [gt_atom_range; gt_range_atom]
+overload (deinfix >=) [gteq_atom_range; gteq_range_atom]
+
+function ([|63|]) branch (([|63|]) x) =
+{
+ if (x <= 32)
+ then x + 31
+ else x - 33
+}
diff --git a/test/typecheck/pass/foreach_var_updates.sail b/test/typecheck/pass/foreach_var_updates.sail
new file mode 100644
index 00000000..e3e30ce6
--- /dev/null
+++ b/test/typecheck/pass/foreach_var_updates.sail
@@ -0,0 +1,15 @@
+val extern (int, int) -> int effect pure add_int = "add"
+overload (deinfix +) [ add_int ]
+
+val extern (int, int) -> int effect pure sub_int = "sub"
+overload (deinfix -) [ sub_int ]
+
+function (int) foo ((int) w) = {
+ (int) x := w;
+ (int) y := w;
+ foreach (z from 0 to 10) {
+ x := x + z;
+ y := y - z;
+ };
+ x + y;
+}
diff --git a/test/typecheck/pass/fun_simple_constraints1.sail b/test/typecheck/pass/fun_simple_constraints1.sail
new file mode 100644
index 00000000..7fd502b0
--- /dev/null
+++ b/test/typecheck/pass/fun_simple_constraints1.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [:'n:] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N) \ No newline at end of file
diff --git a/test/typecheck/pass/fun_simple_constraints2.sail b/test/typecheck/pass/fun_simple_constraints2.sail
new file mode 100644
index 00000000..338ef8e8
--- /dev/null
+++ b/test/typecheck/pass/fun_simple_constraints2.sail
@@ -0,0 +1,18 @@
+
+val forall Nat 'n, Nat 'm. ([:'n + 20:], [:'m:]) -> [:'n + 20 + 'm:] effect pure plus
+
+val forall Nat 'n, 'n <= -10. [|'n:'n|] -> [:'n:] effect pure minus_ten_id
+
+val forall Nat 'n, 'n >= 10. [:'n:] -> [:'n:] effect pure ten_id
+
+val forall Nat 'N, 'N >= 63. [|10:'N|] -> [|10:'N|] effect pure branch
+
+function forall Nat 'N, 'N >= 63. [|10:'N|] branch x =
+{
+ x
+}
+and branch (([|10:30|]) y) = y
+and branch (([:31:]) _) = sizeof 'N
+and branch (([|31:40|]) _) = plus(60,3)
+and branch (([|41:50|]) _) = plus(sizeof 'N, minus_ten_id(-53))
+and branch (([|51:63|]) _) = ten_id(sizeof 'N)
diff --git a/test/typecheck/pass/guards.sail b/test/typecheck/pass/guards.sail
new file mode 100644
index 00000000..2811c428
--- /dev/null
+++ b/test/typecheck/pass/guards.sail
@@ -0,0 +1,22 @@
+
+val (int, int) -> int effect pure add_int
+overload (deinfix +) [add_int]
+
+val forall Type 'a. ('a, 'a) -> bool effect pure eq
+val forall Type 'a. ('a, 'a) -> bool effect pure neq
+
+overload (deinfix ==) [eq]
+overload (deinfix !=) [neq]
+
+val (int, int) -> int effect pure quotient
+
+overload (deinfix quot) [quotient]
+
+typedef T = const union { int C1; int C2 }
+
+function int test ((int) x, (T) y) =
+ switch y {
+ case (C1(z)) when z == 0 -> 0
+ case (C1(z)) when z != 0 -> x quot z
+ case (C2(z)) -> z
+ }
diff --git a/test/typecheck/pass/let_subtyp_bug.sail b/test/typecheck/pass/let_subtyp_bug.sail
new file mode 100644
index 00000000..e2abde2d
--- /dev/null
+++ b/test/typecheck/pass/let_subtyp_bug.sail
@@ -0,0 +1,9 @@
+let ([|5|]) y = 2
+
+val unit -> nat effect pure test
+
+function test() = {
+ let ([|5|]) x = 2 in
+ x
+}
+ \ No newline at end of file
diff --git a/test/typecheck/pass/lexp_memory.sail b/test/typecheck/pass/lexp_memory.sail
new file mode 100644
index 00000000..321fb315
--- /dev/null
+++ b/test/typecheck/pass/lexp_memory.sail
@@ -0,0 +1,68 @@
+default Order dec
+
+register (bit[64]) GPR00 (* should never be read or written *)
+register (bit[64]) GPR01
+register (bit[64]) GPR02
+register (bit[64]) GPR03
+register (bit[64]) GPR04
+register (bit[64]) GPR05
+register (bit[64]) GPR06
+register (bit[64]) GPR07
+register (bit[64]) GPR08
+register (bit[64]) GPR09
+register (bit[64]) GPR10
+register (bit[64]) GPR11
+register (bit[64]) GPR12
+register (bit[64]) GPR13
+register (bit[64]) GPR14
+register (bit[64]) GPR15
+register (bit[64]) GPR16
+register (bit[64]) GPR17
+register (bit[64]) GPR18
+register (bit[64]) GPR19
+register (bit[64]) GPR20
+register (bit[64]) GPR21
+register (bit[64]) GPR22
+register (bit[64]) GPR23
+register (bit[64]) GPR24
+register (bit[64]) GPR25
+register (bit[64]) GPR26
+register (bit[64]) GPR27
+register (bit[64]) GPR28
+register (bit[64]) GPR29
+register (bit[64]) GPR30
+register (bit[64]) GPR31
+
+let (vector <0, 32, inc, (register<(bit[64])>) >) GPR =
+ [ GPR00, GPR01, GPR02, GPR03, GPR04, GPR05, GPR06, GPR07, GPR08, GPR09, GPR10,
+ GPR11, GPR12, GPR13, GPR14, GPR15, GPR16, GPR17, GPR18, GPR19, GPR20,
+ GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31
+ ]
+
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+
+overload vector_access [vector_access_inc; vector_access_dec]
+
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure eq_vec
+
+overload (deinfix ==) [eq_vec]
+
+val extern forall Num 'l, Num 'm. ([:'l:], [:'m:], int) -> vector<'l,'m,dec,bit> effect pure to_vec_dec
+
+val cast forall Nat 'n, Nat 'l. [|0:1|] -> vector<'n,'l,dec,bit> effect pure cast_01_vec
+function forall Num 'n, Num 'l. (vector<'n,'l,dec,bit>) cast_01_vec i = to_vec_dec (sizeof 'n, sizeof 'l, i)
+val cast forall Nat 'n, Nat 'm, Order 'ord. vector<'n,'m,'ord,bit> -> [|0:2**'m - 1|] effect pure unsigned
+val cast forall Type 'a. register<'a> -> 'a effect {rreg} reg_deref
+
+val (bit[5], bit[64]) -> unit effect {wreg} wGPR
+
+function unit wGPR (idx, v) =
+{
+ if idx == 0 then () else GPR[idx] := v
+}
+
+function unit test () =
+{
+ wGPR(0b00001) := 0
+}
diff --git a/test/typecheck/pass/list_cons.sail b/test/typecheck/pass/list_cons.sail
new file mode 100644
index 00000000..6f103bf6
--- /dev/null
+++ b/test/typecheck/pass/list_cons.sail
@@ -0,0 +1 @@
+function list<int> foo ((int) i, (list<int>) l) = i :: l
diff --git a/test/typecheck/pass/list_cons2.sail b/test/typecheck/pass/list_cons2.sail
new file mode 100644
index 00000000..8c34282b
--- /dev/null
+++ b/test/typecheck/pass/list_cons2.sail
@@ -0,0 +1,7 @@
+function list<int> foo ((int) i, (list<int>) l) = i :: l
+
+function list<int> bar () = [||||]
+
+function list<int> baz ((list<int>) l) = l
+
+function list<int> quux () = baz ([||||])
diff --git a/test/typecheck/pass/list_lit.sail b/test/typecheck/pass/list_lit.sail
new file mode 100644
index 00000000..d4febadf
--- /dev/null
+++ b/test/typecheck/pass/list_lit.sail
@@ -0,0 +1,2 @@
+
+let (list<int>) xs = [||1,2,3,4,5,6||]
diff --git a/test/typecheck/pass/mips400.sail b/test/typecheck/pass/mips400.sail
new file mode 100644
index 00000000..951f5126
--- /dev/null
+++ b/test/typecheck/pass/mips400.sail
@@ -0,0 +1,785 @@
+(* New typechecker prelude *)
+
+val cast forall Num 'n, Num 'm, Order 'ord. vector<'n,'m,'ord,bit> -> [|0:2**'m - 1|] effect pure unsigned
+
+val forall Num 'n, Num 'm, Order 'ord. vector<'n,'m,'ord,bit> -> [|0 - (2**('m - 1)):2**('m - 1) - 1|] effect pure signed
+
+val extern forall Num 'n, Num 'm. [|0:'n|] -> vector<'m - 1,'m,dec,bit> effect pure to_vec = "to_vec_dec"
+
+val extern forall Num 'm. int -> vector<'m - 1,'m,dec,bit> effect pure to_svec = "to_vec_dec"
+
+(* Vector access can't actually be properly polymorphic on vector
+ direction because of the ranges being different for each type, so
+ we overload it instead *)
+val forall Num 'n, Num 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Num 'n, Num 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+val forall Num 'n, Num 'l, 'l >= 0. (vector<'n,'l,dec,bit>, [|'n - 'l + 1:'n|]) -> bit effect pure bitvector_access_dec
+val forall Num 'n, Num 'l, 'l >= 0. (vector<'n,'l,inc,bit>, [|'n:'n + 'l - 1|]) -> bit effect pure bitvector_access_inc
+
+overload vector_access [bitvector_access_inc; bitvector_access_dec; vector_access_inc; vector_access_dec]
+
+(* Type safe vector subrange *)
+(* vector_subrange(v, m, o) returns the subvector of v with elements with
+ indices from m up to and *including* o. *)
+val forall Num 'n, Num 'l, Num 'm, Num 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,('o - 'm) + 1,inc,'a> effect pure vector_subrange_inc
+
+val forall Num 'n, Num 'l, Num 'm, Num 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,('m - 'o) + 1,dec,'a> effect pure vector_subrange_dec
+
+val forall Num 'n, Num 'l, Order 'ord.
+ (vector<'n,'l,'ord,bit>, int, int) -> list<bit> effect pure vector_subrange_bl
+
+val forall Num 'n, Num 'l, Num 'm, Num 'o, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,bit>, [:'m:], [:'o:]) -> vector<'m,('o - 'm) + 1,inc,bit> effect pure bitvector_subrange_inc
+
+val forall Num 'n, Num 'l, Num 'm, Num 'o, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,bit>, [:'m:], [:'o:]) -> vector<'m,('m - 'o) + 1,dec,bit> effect pure bitvector_subrange_dec
+
+overload vector_subrange [bitvector_subrange_inc; bitvector_subrange_dec; vector_subrange_inc; vector_subrange_dec; vector_subrange_bl]
+
+(* Type safe vector append *)
+val extern forall Num 'n1, Num 'l1, Num 'n2, Num 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'l1 + 'l2 - 1,'l1 + 'l2,'o,'a> effect pure vec_append = "vector_concat"
+
+val (list<bit>, list<bit>) -> list<bit> effect pure list_append
+
+val extern forall Num 'n1, Num 'l1, Num 'n2, Num 'l2, Order 'o, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,bit>, vector<'n2,'l2,'o,bit>) -> vector<'l1 + 'l2 - 1,'l1 + 'l2,'o,bit> effect pure bitvec_append = "bitvector_concat"
+
+overload vector_append [bitvec_append; vec_append; list_append]
+
+(* Implicit register dereferencing *)
+val cast forall Type 'a. register<'a> -> 'a effect {rreg} reg_deref
+
+(* Bitvector duplication *)
+val forall Num 'n. (bit, [:'n:]) -> vector<'n - 1,'n,dec,bit> effect pure duplicate
+
+val (bit, int) -> list<bit> effect pure duplicate_to_list
+
+val forall Num 'n, Num 'm, Num 'o, Order 'ord.
+ (vector<'o,'n,'ord,bit>, [:'m:]) -> vector<'o,'m*'n,'ord,bit> effect pure duplicate_bits
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o,'n,'ord,bit>, int) -> list<bit> effect pure duplicate_bits_to_list
+
+overload (deinfix ^^) [duplicate; duplicate_bits; duplicate_to_list; duplicate_bits_to_list]
+
+(* Bitvector extension *)
+val forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure extz
+
+val forall Num 'm, Num 'p, Order 'ord.
+ list<bit> -> vector<'p, 'm, 'ord, bit> effect pure extz_bl
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure exts
+
+val forall Num 'm, Num 'p, Order 'ord.
+ list<bit> -> vector<'p, 'm, 'ord, bit> effect pure exts_bl
+
+(* If we want an automatic bitvector extension, then this is the function to
+ use, but I've disabled the cast because it hides signedness bugs. *)
+val (*cast*) forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord, 'm >= 'n.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure extzi
+
+overload EXTZ [extz; extz_bl]
+overload EXTS [exts; exts_bl]
+
+val forall Type 'a, Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord, 'm >= 'o.
+ vector<'n, 'm, 'ord, 'a> -> vector<'p, 'o, 'ord, 'a> effect pure mask
+
+(* Adjust the start index of a decreasing bitvector *)
+val cast forall Num 'n, Num 'm, 'n >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'m - 1,'m,dec,bit>
+ effect pure norm_dec
+
+val cast forall Num 'n, Num 'm, Num 'o, 'n >= 'm - 1, 'o >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'o,'m,dec,bit>
+ effect pure adjust_dec
+
+(* Various casts from 0 and 1 to bitvectors *)
+val cast forall Num 'n, Num 'l, Order 'ord. [:0:] -> vector<'n,'l,'ord,bit> effect pure cast_0_vec
+val cast forall Num 'n, Num 'l, Order 'ord. [:1:] -> vector<'n,'l,'ord,bit> effect pure cast_1_vec
+val cast forall Num 'n, Num 'l, Order 'ord. [|0:1|] -> vector<'n,'l,'ord,bit> effect pure cast_01_vec
+
+val cast forall Num 'n, Order 'ord. vector<'n,1,'ord,bit> -> bool effect pure cast_vec_bool
+val cast bit -> bool effect pure cast_bit_bool
+
+val cast forall Num 'n, Num 'm, 'n >= 'm - 1, 'm >= 1. bit -> vector<'n,'m,dec,bit> effect pure cast_bit_vec
+
+(* MSB *)
+val forall Num 'n, Num 'm, Order 'ord. vector<'n, 'm, 'ord, bit> -> bit effect pure most_significant
+
+(* Arithmetic *)
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p.
+ ([|'n:'m|], [|'o:'p|]) -> [|'n + 'o:'m + 'p|] effect pure add
+
+val extern (nat, nat) -> nat effect pure add_nat = "add"
+
+val extern (int, int) -> int effect pure add_int = "add"
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure add_vec
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, int) -> vector<'o, 'n, 'ord, bit> effect pure add_vec_int
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> (vector<'o, 'n, 'ord, bit>, bit, bit) effect pure add_overflow_vec
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p.
+ ([|'n:'m|], [|'o:'p|]) -> [|'n - 'p:'m - 'o|] effect pure sub
+
+val extern (int, int) -> int effect pure sub_int = "sub"
+
+val forall Num 'n, Num 'm, Order 'ord.
+ (vector<'n,'m,'ord,bit>, int) -> vector<'n,'m,'ord,bit> effect pure sub_vec_int
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure sub_vec
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> (vector<'o, 'n, 'ord, bit>, bit, bit) effect pure sub_underflow_vec
+
+overload (deinfix +) [
+ add_vec;
+ add_overflow_vec;
+ add_vec_int;
+ add;
+ add_nat;
+ add_int
+]
+
+overload (deinfix -) [
+ sub_vec_int;
+ sub_vec;
+ sub_underflow_vec;
+ sub;
+ sub_int
+]
+
+val extern bool -> bit effect pure bool_to_bit = "bool_to_bitU"
+
+val (int, int) -> int effect pure mul_int
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<2 * 'n - 1, 2 * 'n, 'ord, bit> effect pure mul_vec
+
+overload (deinfix * ) [
+ mul_vec;
+ mul_int
+]
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<2 * 'n - 1, 2 * 'n, 'ord, bit> effect pure mul_svec
+
+overload (deinfix *_s) [
+ mul_svec
+]
+
+val extern (bool, bool) -> bool effect pure bool_xor
+
+val extern forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, vector<'o, 'n, 'ord, bit>) -> vector<'o, 'n, 'ord, bit> effect pure xor_vec = "bitwise_xor"
+
+overload (deinfix ^) [
+ bool_xor;
+ xor_vec
+]
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, int) -> vector<'o, 'n, 'ord, bit> effect pure shiftl
+
+overload (deinfix <<) [
+ shiftl
+]
+
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, int) -> vector<'o, 'n, 'ord, bit> effect pure shiftr
+
+overload (deinfix >>) [
+ shiftr
+]
+
+(* Boolean operators *)
+val extern bool -> bool effect pure bool_not = "not"
+val (bool, bool) -> bool effect pure bool_or
+val (bool, bool) -> bool effect pure bool_and
+
+val forall Num 'n, Num 'm, Order 'ord.
+ vector<'n,'m,'ord,bit> -> vector<'n,'m,'ord,bit> effect pure bitwise_not
+
+val forall Num 'n, Num 'm, Order 'ord.
+ (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> vector<'n,'m,'ord,bit> effect pure bitwise_and
+
+val forall Num 'n, Num 'm, Order 'ord.
+ (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> vector<'n,'m,'ord,bit> effect pure bitwise_or
+
+overload ~ [bool_not; bitwise_not]
+overload (deinfix &) [bool_and; bitwise_and]
+overload (deinfix |) [bool_or; bitwise_or]
+
+(* Equality *)
+
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure eq_vec
+
+val forall Type 'a. ('a, 'a) -> bool effect pure eq
+
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure neq_vec
+
+val forall Type 'a. ('a, 'a) -> bool effect pure neq
+
+function forall Num 'n, Num 'm, Order 'ord. bool neq_vec (v1, v2) = bool_not(eq_vec(v1, v2))
+
+overload (deinfix ==) [eq_vec; eq]
+overload (deinfix !=) [neq_vec; neq]
+
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure gteq_vec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure gt_vec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure lteq_vec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure lt_vec
+
+val extern (int, int) -> bool effect pure gteq_int = "gteq"
+val extern (int, int) -> bool effect pure gt_int = "gt"
+val extern (int, int) -> bool effect pure lteq_int = "lteq"
+val extern (int, int) -> bool effect pure lt_int = "lt"
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lteq_range_atom = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gt_range_atom = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure gteq_range_atom = "gteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lt_atom_range = "lt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure lteq_atom_range = "lteq"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gt_atom_range = "gt"
+val extern forall Num 'n, Num 'm, Num 'o. ([:'n:], [|'m:'o|]) -> bool effect pure gteq_atom_range = "gteq"
+
+val extern forall Num 'n, Num 'm. ([:'n:], [:'m:]) -> bool effect pure lteq_atom_atom = "lteq"
+val extern forall Num 'n, Num 'm. ([:'n:], [:'m:]) -> bool effect pure gteq_atom_atom = "gteq"
+val extern forall Num 'n, Num 'm. ([:'n:], [:'m:]) -> bool effect pure lt_atom_atom = "lt"
+val extern forall Num 'n, Num 'm. ([:'n:], [:'m:]) -> bool effect pure gt_atom_atom = "gt"
+
+overload (deinfix >=) [gteq_atom_atom; gteq_range_atom; gteq_atom_range; gteq_vec; gteq_int]
+overload (deinfix >) [gt_atom_atom; gt_vec; gt_int]
+overload (deinfix <=) [lteq_atom_atom; lteq_range_atom; lteq_atom_range; lteq_vec; lteq_int]
+overload (deinfix <) [lt_atom_atom; lt_vec; lt_int]
+
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure gteq_svec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure gt_svec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure lteq_svec
+val forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure lt_svec
+
+overload (deinfix <_s) [lt_svec]
+overload (deinfix <=_s) [lteq_svec]
+overload (deinfix >_s) [gt_svec]
+overload (deinfix >=_s) [gteq_svec]
+
+val (int, int) -> int effect pure quotient
+
+overload (deinfix quot) [quotient]
+
+val (int, int) -> int effect pure modulo
+
+overload (deinfix mod) [modulo]
+
+val extern forall Num 'n, Num 'm, Order 'ord, Type 'a. vector<'n,'m,'ord,'a> -> [:'m:] effect pure vec_length = "length"
+val forall Type 'a. list<'a> -> nat effect pure list_length
+
+val extern forall Num 'n, Num 'm, Order 'ord. vector<'n,'m,'ord,bit> -> [:'m:] effect pure bitvector_length = "bvlength"
+
+overload length [bitvector_length; vector_length; list_length]
+
+val cast forall Num 'n. [:'n:] -> [|'n|] effect pure upper
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+}
+
+(* Mips spec starts here *)
+
+(*========================================================================*)
+(* *)
+(* Copyright (c) 2015-2017 Robert M. Norton *)
+(* Copyright (c) 2015-2017 Kathyrn Gray *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(*========================================================================*)
+
+(* mips_prelude.sail: declarations of mips registers, and functions common
+ to mips instructions (e.g. address translation) *)
+
+(* bit vectors have indices decreasing from left i.e. msb is highest index *)
+default Order dec
+
+register (bit[64]) PC
+register (bit[64]) nextPC
+
+(* CP0 Registers *)
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+typedef TLBEntryLoReg = register bits [63 : 0] {
+ 63 : CapS;
+ 62 : CapL;
+ 29 .. 6 : PFN;
+ 5 .. 3 : C;
+ 2 : D;
+ 1 : V;
+ 0 : G;
+}
+
+typedef TLBEntryHiReg = register bits [63 : 0] {
+ 63 .. 62 : R;
+ 39 .. 13 : VPN2;
+ 7 .. 0 : ASID;
+}
+
+typedef ContextReg = register bits [63 : 0] {
+ 63 .. 23 : PTEBase;
+ 22 .. 4 : BadVPN2;
+ (*3 .. 0 : ZR;*)
+}
+
+typedef XContextReg = register bits [63 : 0] {
+ 63 .. 33: PTEBase;
+ 32 .. 31: R;
+ 30 .. 4: BadVPN2;
+}
+
+let ([:64:]) TLBNumEntries = 64
+typedef TLBIndexT = (bit[6])
+let (TLBIndexT) TLBIndexMax = 0b111111
+
+let MAX_U64 = unsigned(0xffffffffffffffff)
+let MAX_VA = unsigned(0xffffffffff)
+let MAX_PA = unsigned(0xfffffffff)
+
+typedef TLBEntry = register bits [116 : 0] {
+ 116 .. 101: pagemask;
+ 100 .. 99 : r ;
+ 98 .. 72 : vpn2 ;
+ 71 .. 64 : asid ;
+ 63 : g ;
+ 62 : valid ;
+ 61 : caps1 ;
+ 60 : capl1 ;
+ 59 .. 36 : pfn1 ;
+ 35 .. 33 : c1 ;
+ 32 : d1 ;
+ 31 : v1 ;
+ 30 : caps0 ;
+ 29 : capl0 ;
+ 28 .. 5 : pfn0 ;
+ 4 .. 2 : c0 ;
+ 1 : d0 ;
+ 0 : v0 ;
+}
+
+register (bit[1]) TLBProbe
+register (TLBIndexT) TLBIndex
+register (TLBIndexT) TLBRandom
+register (TLBEntryLoReg) TLBEntryLo0
+register (TLBEntryLoReg) TLBEntryLo1
+register (ContextReg) TLBContext
+register (bit[16]) TLBPageMask
+register (TLBIndexT) TLBWired
+register (TLBEntryHiReg) TLBEntryHi
+register (XContextReg) TLBXContext
+
+register (TLBEntry) TLBEntry00
+register (TLBEntry) TLBEntry01
+register (TLBEntry) TLBEntry02
+register (TLBEntry) TLBEntry03
+register (TLBEntry) TLBEntry04
+register (TLBEntry) TLBEntry05
+register (TLBEntry) TLBEntry06
+register (TLBEntry) TLBEntry07
+register (TLBEntry) TLBEntry08
+register (TLBEntry) TLBEntry09
+register (TLBEntry) TLBEntry10
+register (TLBEntry) TLBEntry11
+register (TLBEntry) TLBEntry12
+register (TLBEntry) TLBEntry13
+register (TLBEntry) TLBEntry14
+register (TLBEntry) TLBEntry15
+register (TLBEntry) TLBEntry16
+register (TLBEntry) TLBEntry17
+register (TLBEntry) TLBEntry18
+register (TLBEntry) TLBEntry19
+register (TLBEntry) TLBEntry20
+register (TLBEntry) TLBEntry21
+register (TLBEntry) TLBEntry22
+register (TLBEntry) TLBEntry23
+register (TLBEntry) TLBEntry24
+register (TLBEntry) TLBEntry25
+register (TLBEntry) TLBEntry26
+register (TLBEntry) TLBEntry27
+register (TLBEntry) TLBEntry28
+register (TLBEntry) TLBEntry29
+register (TLBEntry) TLBEntry30
+register (TLBEntry) TLBEntry31
+register (TLBEntry) TLBEntry32
+register (TLBEntry) TLBEntry33
+register (TLBEntry) TLBEntry34
+register (TLBEntry) TLBEntry35
+register (TLBEntry) TLBEntry36
+register (TLBEntry) TLBEntry37
+register (TLBEntry) TLBEntry38
+register (TLBEntry) TLBEntry39
+register (TLBEntry) TLBEntry40
+register (TLBEntry) TLBEntry41
+register (TLBEntry) TLBEntry42
+register (TLBEntry) TLBEntry43
+register (TLBEntry) TLBEntry44
+register (TLBEntry) TLBEntry45
+register (TLBEntry) TLBEntry46
+register (TLBEntry) TLBEntry47
+register (TLBEntry) TLBEntry48
+register (TLBEntry) TLBEntry49
+register (TLBEntry) TLBEntry50
+register (TLBEntry) TLBEntry51
+register (TLBEntry) TLBEntry52
+register (TLBEntry) TLBEntry53
+register (TLBEntry) TLBEntry54
+register (TLBEntry) TLBEntry55
+register (TLBEntry) TLBEntry56
+register (TLBEntry) TLBEntry57
+register (TLBEntry) TLBEntry58
+register (TLBEntry) TLBEntry59
+register (TLBEntry) TLBEntry60
+register (TLBEntry) TLBEntry61
+register (TLBEntry) TLBEntry62
+register (TLBEntry) TLBEntry63
+
+let (vector <0, 64, inc, (register<TLBEntry>)>) TLBEntries = [
+TLBEntry00,
+TLBEntry01,
+TLBEntry02,
+TLBEntry03,
+TLBEntry04,
+TLBEntry05,
+TLBEntry06,
+TLBEntry07,
+TLBEntry08,
+TLBEntry09,
+TLBEntry10,
+TLBEntry11,
+TLBEntry12,
+TLBEntry13,
+TLBEntry14,
+TLBEntry15,
+TLBEntry16,
+TLBEntry17,
+TLBEntry18,
+TLBEntry19,
+TLBEntry20,
+TLBEntry21,
+TLBEntry22,
+TLBEntry23,
+TLBEntry24,
+TLBEntry25,
+TLBEntry26,
+TLBEntry27,
+TLBEntry28,
+TLBEntry29,
+TLBEntry30,
+TLBEntry31,
+TLBEntry32,
+TLBEntry33,
+TLBEntry34,
+TLBEntry35,
+TLBEntry36,
+TLBEntry37,
+TLBEntry38,
+TLBEntry39,
+TLBEntry40,
+TLBEntry41,
+TLBEntry42,
+TLBEntry43,
+TLBEntry44,
+TLBEntry45,
+TLBEntry46,
+TLBEntry47,
+TLBEntry48,
+TLBEntry49,
+TLBEntry50,
+TLBEntry51,
+TLBEntry52,
+TLBEntry53,
+TLBEntry54,
+TLBEntry55,
+TLBEntry56,
+TLBEntry57,
+TLBEntry58,
+TLBEntry59,
+TLBEntry60,
+TLBEntry61,
+TLBEntry62,
+TLBEntry63
+]
+
+register (bit[32]) CP0Compare
+register (CauseReg) CP0Cause
+register (bit[64]) CP0EPC
+register (bit[64]) CP0ErrorEPC
+register (bit[1]) CP0LLBit
+register (bit[64]) CP0LLAddr
+register (bit[64]) CP0BadVAddr
+register (bit[32]) CP0Count
+register (bit[32]) CP0HWREna
+register (bit[64]) CP0UserLocal
+
+typedef StatusReg = register bits [31:0] {
+ 31 .. 28 : CU; (* co-processor enable bits *)
+ (* RP/FR/RE/MX/PX not implemented *)
+ 22 : BEV; (* use boot exception vectors (initialised to one) *)
+ (* TS/SR/NMI not implemented *)
+ 15 .. 8 : IM; (* Interrupt mask *)
+ 7 : KX; (* kernel 64-bit enable *)
+ 6 : SX; (* supervisor 64-bit enable *)
+ 5 : UX; (* user 64-bit enable *)
+ 4 .. 3 : KSU; (* Processor mode *)
+ 2 : ERL; (* error level (should be initialised to one, but BERI is different) *)
+ 1 : EXL; (* exception level *)
+ 0 : IE; (* interrupt enable *)
+}
+register (StatusReg) CP0Status
+
+(* Implementation registers -- not ISA defined *)
+register (bit[1]) branchPending (* Set by branch instructions to implement branch delay *)
+register (bit[1]) inBranchDelay (* Needs to be set by outside world when in branch delay slot *)
+register (bit[64]) delayedPC (* Set by branch instructions to implement branch delay *)
+
+(* General purpose registers *)
+
+register (bit[64]) GPR00 (* should never be read or written *)
+register (bit[64]) GPR01
+register (bit[64]) GPR02
+register (bit[64]) GPR03
+register (bit[64]) GPR04
+register (bit[64]) GPR05
+register (bit[64]) GPR06
+register (bit[64]) GPR07
+register (bit[64]) GPR08
+register (bit[64]) GPR09
+register (bit[64]) GPR10
+register (bit[64]) GPR11
+register (bit[64]) GPR12
+register (bit[64]) GPR13
+register (bit[64]) GPR14
+register (bit[64]) GPR15
+register (bit[64]) GPR16
+register (bit[64]) GPR17
+register (bit[64]) GPR18
+register (bit[64]) GPR19
+register (bit[64]) GPR20
+register (bit[64]) GPR21
+register (bit[64]) GPR22
+register (bit[64]) GPR23
+register (bit[64]) GPR24
+register (bit[64]) GPR25
+register (bit[64]) GPR26
+register (bit[64]) GPR27
+register (bit[64]) GPR28
+register (bit[64]) GPR29
+register (bit[64]) GPR30
+register (bit[64]) GPR31
+
+(* Special registers For MUL/DIV *)
+register (bit[64]) HI
+register (bit[64]) LO
+
+let (vector <0, 32, inc, (register<(bit[64])>) >) GPR =
+ [ GPR00, GPR01, GPR02, GPR03, GPR04, GPR05, GPR06, GPR07, GPR08, GPR09, GPR10,
+ GPR11, GPR12, GPR13, GPR14, GPR15, GPR16, GPR17, GPR18, GPR19, GPR20,
+ GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31
+ ]
+
+(* JTAG Uart registers *)
+
+register (bit[8]) UART_WDATA
+register (bit[1]) UART_WRITTEN
+register (bit[8]) UART_RDATA
+register (bit[1]) UART_RVALID
+
+(* Check whether a given 64-bit vector is a properly sign extended 32-bit word *)
+val bit[64] -> bool effect pure NotWordVal
+function bool NotWordVal (word) =
+ (word[31] ^^ 32) != word[63..32]
+
+(* Read numbered GP reg. (r0 is always zero) *)
+val bit[5] -> bit[64] effect {rreg} rGPR
+function bit[64] rGPR idx = {
+ if idx == 0 then 0 else GPR[idx]
+}
+
+(* Write numbered GP reg. (writes to r0 ignored) *)
+val (bit[5], bit[64]) -> unit effect {wreg} wGPR
+function unit wGPR (idx, v) = {
+ if idx == 0 then () else GPR[idx] := v
+}
+
+val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr
+val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserve
+val extern unit -> unit effect { barr } MEM_sync
+
+val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea
+val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_conditional
+val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval
+val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> bool effect { wmv } MEMval_conditional
+
+typedef Exception = enumerate
+{
+ Int; TLBMod; TLBL; TLBS; AdEL; AdES; Sys; Bp; ResI; CpU; Ov; Tr; C2E; C2Trap;
+ XTLBRefillL; XTLBRefillS; XTLBInvL; XTLBInvS; MCheck
+}
+
+(* Return the ISA defined code for an exception condition *)
+function (bit[5]) ExceptionCode ((Exception) ex) =
+ switch (ex)
+ {
+ case Int -> mask(0x00) (* Interrupt *)
+ case TLBMod -> mask(0x01) (* TLB modification exception *)
+ case TLBL -> mask(0x02) (* TLB exception (load or fetch) *)
+ case TLBS -> mask(0x03) (* TLB exception (store) *)
+ case AdEL -> mask(0x04) (* Address error (load or fetch) *)
+ case AdES -> mask(0x05) (* Address error (store) *)
+ case Sys -> mask(0x08) (* Syscall *)
+ case Bp -> mask(0x09) (* Breakpoint *)
+ case ResI -> mask(0x0a) (* Reserved instruction *)
+ case CpU -> mask(0x0b) (* Coprocessor Unusable *)
+ case Ov -> mask(0x0c) (* Arithmetic overflow *)
+ case Tr -> mask(0x0d) (* Trap *)
+ case C2E -> mask(0x12) (* C2E coprocessor 2 exception *)
+ case C2Trap -> mask(0x12) (* C2Trap maps to same exception code, different vector *)
+ case XTLBRefillL -> mask(0x02)
+ case XTLBRefillS -> mask(0x03)
+ case XTLBInvL -> mask(0x02)
+ case XTLBInvS -> mask(0x03)
+ case MCheck -> mask(0x18)
+ }
+
+
+
+function forall Type 'o. 'o SignalExceptionMIPS ((Exception) ex, (bit[64]) kccBase) =
+ {
+ (* Only update EPC and BD if not already in EXL mode *)
+ if (~ (CP0Status.EXL)) then
+ {
+ if (inBranchDelay[0]) then
+ {
+ CP0EPC := PC - 4;
+ CP0Cause.BD := 1;
+ }
+ else
+ {
+ CP0EPC := PC;
+ CP0Cause.BD := 0;
+ }
+ };
+
+ (* choose an exception vector to branch to. Some are not supported
+ e.g. Reset *)
+ vectorOffset :=
+ if (CP0Status.EXL) then
+ 0x180 (* Always use common vector if in exception mode already *)
+ else if ((ex == XTLBRefillL) | (ex == XTLBRefillS)) then
+ 0x080
+ else if (ex == C2Trap) then
+ 0x280 (* Special vector for CHERI traps *)
+ else
+ 0x180; (* Common vector *)
+ (bit[64]) vectorBase := if CP0Status.BEV then
+ 0xFFFFFFFFBFC00200
+ else
+ 0xFFFFFFFF80000000;
+ (* On CHERI we have to subtract KCC.base so that we end up at the
+ right absolute vector address after indirecting via new PCC *)
+ nextPC := ((bit[64])(vectorBase + (bit[64])(EXTS(vectorOffset)))) - kccBase;
+ CP0Cause.ExcCode := ExceptionCode(ex);
+ CP0Status.EXL := 1;
+ exit ();
+ }
+
+val forall Type 'o . Exception -> 'o effect {escape, rreg, wreg} SignalException
+
+function forall Type 'o. 'o SignalExceptionBadAddr((Exception) ex, (bit[64]) badAddr) =
+ {
+ CP0BadVAddr := badAddr;
+ SignalException(ex);
+ }
+
+function forall Type 'o. 'o SignalExceptionTLB((Exception) ex, (bit[64]) badAddr) = {
+ CP0BadVAddr := badAddr;
+ (TLBContext.BadVPN2) := (badAddr[31..13]);
+ (TLBXContext.BadVPN2):= (badAddr[39..13]);
+ (TLBXContext.R) := (badAddr[63..62]);
+ (TLBEntryHi.R) := (badAddr[63..62]);
+ (TLBEntryHi.VPN2) := (badAddr[39..13]);
+ SignalException(ex);
+}
+
+typedef MemAccessType = enumerate {Instruction; LoadData; StoreData}
+typedef AccessLevel = enumerate {User; Supervisor; Kernel}
+
+function AccessLevel getAccessLevel() =
+ if ((CP0Status.EXL) | (CP0Status.ERL)) then
+ Kernel
+ else switch (bit[2]) (CP0Status.KSU)
+ {
+ case 0b00 -> Kernel
+ case 0b01 -> Supervisor
+ case 0b10 -> User
+ case _ -> User (* behaviour undefined, assume user *)
+ }
+
+function unit checkCP0Access () =
+ {
+ let accessLevel = getAccessLevel() in
+ if ((accessLevel != Kernel) & (~(CP0Status[28] (*CU0*)))) then
+ {
+ (CP0Cause.CE) := 0b00;
+ SignalException(CpU);
+ }
+ }
+
+function forall Type 'o. 'o SignalException ((Exception) ex) = SignalExceptionMIPS(ex, 0x0000000000000000)
diff --git a/test/typecheck/pass/mips_CP0Cause_BD_assign1.sail b/test/typecheck/pass/mips_CP0Cause_BD_assign1.sail
new file mode 100644
index 00000000..54ae354f
--- /dev/null
+++ b/test/typecheck/pass/mips_CP0Cause_BD_assign1.sail
@@ -0,0 +1,32 @@
+val cast forall Num 'n. [:1:] -> vector<'n,1,dec,bit> effect pure cast_1_vec
+val cast forall Num 'n. [:0:] -> vector<'n,1,dec,bit> effect pure cast_0_vec
+
+val extern forall Num 'l, Num 'm. ([:'l:], [:'m:], int) -> vector<'l,'m,dec,bit> effect pure to_vec_dec
+
+function forall Num 'n. (vector<'n,1,dec,bit>) cast_1_vec i = to_vec_dec (sizeof 'n, 1, i)
+function forall Num 'n. (vector<'n,1,dec,bit>) cast_0_vec i = to_vec_dec (sizeof 'n, 1, i)
+
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ CP0Cause.BD := 1
+}
diff --git a/test/typecheck/pass/mips_CP0Cause_BD_assign2.sail b/test/typecheck/pass/mips_CP0Cause_BD_assign2.sail
new file mode 100644
index 00000000..2e80f538
--- /dev/null
+++ b/test/typecheck/pass/mips_CP0Cause_BD_assign2.sail
@@ -0,0 +1,32 @@
+val cast forall Num 'n. [:1:] -> vector<'n,1,dec,bit> effect pure cast_1_vec
+val cast forall Num 'n. [:0:] -> vector<'n,1,dec,bit> effect pure cast_0_vec
+
+val extern forall Num 'l, Num 'm. ([:'l:], [:'m:], int) -> vector<'l,'m,dec,bit> effect pure to_vec_dec
+
+function forall Num 'n. (vector<'n,1,dec,bit>) cast_1_vec i = to_vec_dec (sizeof 'n, 1, i)
+function forall Num 'n. (vector<'n,1,dec,bit>) cast_0_vec i = to_vec_dec (sizeof 'n, 1, i)
+
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ CP0Cause.BD := 0
+}
diff --git a/test/typecheck/pass/mips_CP0Cause_access.sail b/test/typecheck/pass/mips_CP0Cause_access.sail
new file mode 100644
index 00000000..eb3b9389
--- /dev/null
+++ b/test/typecheck/pass/mips_CP0Cause_access.sail
@@ -0,0 +1,34 @@
+(* val forall Nat 'n, Nat 'm, Nat 'o, 'o >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'o,'m,dec,bit>
+ effect pure ADJUST
+*)
+
+val extern forall Num 'n, Num 'l, 'l >= 0. (vector<'n,'l,dec,bit>, [|'n - 'l + 1:'n|]) -> bit effect pure bitvector_access_dec
+val extern forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,inc,bit>, [|'n:'n + 'l - 1|]) -> bit effect pure bitvector_access_inc
+
+overload vector_access [bitvector_access_inc; bitvector_access_dec]
+
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> bit effect {rreg} test
+
+function bit test () =
+{
+ CP0Cause[30]
+}
diff --git a/test/typecheck/pass/mips_CauseReg1.sail b/test/typecheck/pass/mips_CauseReg1.sail
new file mode 100644
index 00000000..b9503efa
--- /dev/null
+++ b/test/typecheck/pass/mips_CauseReg1.sail
@@ -0,0 +1,15 @@
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/pass/mips_CauseReg2.sail b/test/typecheck/pass/mips_CauseReg2.sail
new file mode 100644
index 00000000..7600c9f1
--- /dev/null
+++ b/test/typecheck/pass/mips_CauseReg2.sail
@@ -0,0 +1,15 @@
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 1 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
diff --git a/test/typecheck/pass/mips_reg_field_bit.sail b/test/typecheck/pass/mips_reg_field_bit.sail
new file mode 100644
index 00000000..4c37a6e9
--- /dev/null
+++ b/test/typecheck/pass/mips_reg_field_bit.sail
@@ -0,0 +1,28 @@
+default Order dec
+
+val cast forall Nat 'n, Nat 'm, Nat 'o, 'o >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'o,'m,dec,bit>
+ effect pure adjust_dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ (CP0Cause.CE)[28] := bitone
+}
diff --git a/test/typecheck/pass/mips_reg_field_bv.sail b/test/typecheck/pass/mips_reg_field_bv.sail
new file mode 100644
index 00000000..0ce19b4f
--- /dev/null
+++ b/test/typecheck/pass/mips_reg_field_bv.sail
@@ -0,0 +1,28 @@
+default Order dec
+
+val cast forall Nat 'n, Nat 'm, Nat 'o, 'o >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'o,'m,dec,bit>
+ effect pure adjust_dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ CP0Cause.CE := 0b11
+}
diff --git a/test/typecheck/pass/mips_regtyps.sail b/test/typecheck/pass/mips_regtyps.sail
new file mode 100644
index 00000000..f7a3ce91
--- /dev/null
+++ b/test/typecheck/pass/mips_regtyps.sail
@@ -0,0 +1,53 @@
+
+(* mips_prelude.sail: declarations of mips registers, and functions common
+ to mips instructions (e.g. address translation) *)
+
+(* bit vectors have indices decreasing from left i.e. msb is highest index *)
+default Order dec
+
+register (bit[64]) PC
+register (bit[64]) nextPC
+
+(* CP0 Registers *)
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+typedef TLBEntryLoReg = register bits [63 : 0] {
+ 63 : CapS;
+ 62 : CapL;
+ 29 .. 6 : PFN;
+ 5 .. 3 : C;
+ 2 : D;
+ 1 : V;
+ 0 : G;
+}
+
+typedef TLBEntryHiReg = register bits [63 : 0] {
+ 63 .. 62 : R;
+ 39 .. 13 : VPN2;
+ 7 .. 0 : ASID;
+}
+
+typedef ContextReg = register bits [63 : 0] {
+ 63 .. 23 : PTEBase;
+ 22 .. 4 : BadVPN2;
+ (*3 .. 0 : ZR;*)
+}
+
+typedef XContextReg = register bits [63 : 0] {
+ 63 .. 33: PTEBase;
+ 32 .. 31: R;
+ 30 .. 4: BadVPN2;
+}
diff --git a/test/typecheck/pass/mips_tlbindext_dec.sail b/test/typecheck/pass/mips_tlbindext_dec.sail
new file mode 100644
index 00000000..af98cd85
--- /dev/null
+++ b/test/typecheck/pass/mips_tlbindext_dec.sail
@@ -0,0 +1,5 @@
+
+default Order dec
+
+typedef TLBIndexT = (bit[6])
+let (TLBIndexT) TLBIndexMax = 0b111111
diff --git a/test/typecheck/pass/mips_tlbindext_inc.sail b/test/typecheck/pass/mips_tlbindext_inc.sail
new file mode 100644
index 00000000..d64ffd68
--- /dev/null
+++ b/test/typecheck/pass/mips_tlbindext_inc.sail
@@ -0,0 +1,5 @@
+
+default Order inc
+
+typedef TLBIndexT = (bit[6])
+let (TLBIndexT) TLBIndexMax = 0b111111
diff --git a/test/typecheck/pass/modify_assignment1.sail b/test/typecheck/pass/modify_assignment1.sail
new file mode 100644
index 00000000..1c7ab614
--- /dev/null
+++ b/test/typecheck/pass/modify_assignment1.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ z := ([|0:9|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/pass/modify_type_chain.sail b/test/typecheck/pass/modify_type_chain.sail
new file mode 100644
index 00000000..14651787
--- /dev/null
+++ b/test/typecheck/pass/modify_type_chain.sail
@@ -0,0 +1,8 @@
+
+val unit -> unit effect pure test
+
+function unit test () =
+{
+ ([|0:10|]) z := 9;
+ ([|0:9|]) z := ([|0:8|]) 8
+} \ No newline at end of file
diff --git a/test/typecheck/pass/nat_set.sail b/test/typecheck/pass/nat_set.sail
new file mode 100644
index 00000000..46338353
--- /dev/null
+++ b/test/typecheck/pass/nat_set.sail
@@ -0,0 +1,8 @@
+
+function forall Nat 'n, 'n IN {1,2,3}. bool test (([:'n:]) x) =
+{
+ true
+}
+
+let x = test(1)
+let y = test(3) \ No newline at end of file
diff --git a/test/typecheck/pass/nondet.sail b/test/typecheck/pass/nondet.sail
new file mode 100644
index 00000000..8a353c66
--- /dev/null
+++ b/test/typecheck/pass/nondet.sail
@@ -0,0 +1,12 @@
+
+register int z
+
+val unit -> unit effect {wreg} test
+
+function unit test () = {
+ nondet {
+ z := 0;
+ z := 1;
+ z := 2;
+ }
+}
diff --git a/test/typecheck/pass/nondet_assert.sail b/test/typecheck/pass/nondet_assert.sail
new file mode 100644
index 00000000..501432d3
--- /dev/null
+++ b/test/typecheck/pass/nondet_assert.sail
@@ -0,0 +1,14 @@
+
+register int z
+
+val unit -> int effect {wreg, rreg, escape} test
+
+function int test () = {
+ nondet {
+ z := 0;
+ assert(false, "Nondeterministic assert");
+ return z;
+ z := 1;
+ };
+ z
+}
diff --git a/test/typecheck/pass/nondet_return.sail b/test/typecheck/pass/nondet_return.sail
new file mode 100644
index 00000000..56fcfd5a
--- /dev/null
+++ b/test/typecheck/pass/nondet_return.sail
@@ -0,0 +1,13 @@
+
+register int z
+
+val unit -> int effect {wreg, rreg} test
+
+function int test () = {
+ nondet {
+ z := 0;
+ return z;
+ z := 1;
+ };
+ z
+}
diff --git a/test/typecheck/pass/nzcv.sail b/test/typecheck/pass/nzcv.sail
new file mode 100644
index 00000000..3e23e529
--- /dev/null
+++ b/test/typecheck/pass/nzcv.sail
@@ -0,0 +1,13 @@
+default Order dec
+
+val bit[4] -> unit effect pure test
+
+function test nzcv =
+{
+ N := 0b0;
+ Z := 0b0;
+ C := 0b0;
+ V := 0b0;
+ (N,Z,C,V) := nzcv;
+ ()
+}
diff --git a/test/typecheck/pass/option_either.sail b/test/typecheck/pass/option_either.sail
new file mode 100644
index 00000000..c466daf4
--- /dev/null
+++ b/test/typecheck/pass/option_either.sail
@@ -0,0 +1,33 @@
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+}
+
+function forall Type 'a. option<'a> none () = None
+
+function forall Type 'a. option<'a> some (('a) x) = Some(x)
+
+function forall Type 'a. int test ((option<'a>) x) =
+{
+ switch x {
+ case None -> 0
+ case (Some(y)) -> 1
+ }
+}
+
+typedef either = const union forall Type 'a, Type 'b. {
+ 'a Left;
+ 'b Right
+}
+
+val forall Nat 'n, 'n >= 0. bit['n] -> int effect pure signed
+
+function int test2 ((either<int,bit[1]>) x) =
+{
+ switch x {
+ case (Left(l)) -> l
+ case (Right(r)) -> signed(r)
+ }
+}
diff --git a/test/typecheck/pass/overlap_field.sail b/test/typecheck/pass/overlap_field.sail
new file mode 100644
index 00000000..82e685ee
--- /dev/null
+++ b/test/typecheck/pass/overlap_field.sail
@@ -0,0 +1,13 @@
+
+typedef A = const struct {bool field_A; int shared}
+typedef B = const struct {bool field_B; int shared}
+
+val (bool, int) -> A effect {undef} makeA
+
+function makeA (x, y) =
+{
+ (A) record := undefined;
+ record.field_A := x;
+ record.shared := y;
+ record
+}
diff --git a/test/typecheck/pass/overload_plus.sail b/test/typecheck/pass/overload_plus.sail
new file mode 100644
index 00000000..2aa8ecc5
--- /dev/null
+++ b/test/typecheck/pass/overload_plus.sail
@@ -0,0 +1,12 @@
+default Order inc
+
+val extern forall Nat 'n. (bit['n], bit['n]) -> bit['n] effect pure bv_add = "add_vec"
+
+overload (deinfix +) [bv_add]
+
+val (bit[3], bit[3]) -> bit[3] effect pure test
+
+function bit[3] test (x, y) =
+{
+ x + y
+}
diff --git a/test/typecheck/pass/patternrefinement.sail b/test/typecheck/pass/patternrefinement.sail
new file mode 100644
index 00000000..5a89372a
--- /dev/null
+++ b/test/typecheck/pass/patternrefinement.sail
@@ -0,0 +1,19 @@
+default Order dec
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p, Order 'ord.
+ vector<'o, 'n, 'ord, bit> -> vector<'p, 'm, 'ord, bit> effect pure extz
+val extern forall Num 'n, Num 'm, Order 'ord, Type 'a. vector<'n,'m,'ord,'a> -> [:'m:] effect pure length
+val extern forall Num 'n, Num 'm, Order 'ord. (vector<'n,'m,'ord,bit>, vector<'n,'m,'ord,bit>) -> bool effect pure eq_vec
+val extern forall Num 'n, Num 'm. ([:'n:],[:'m:]) -> bool effect pure eq_atom
+val extern forall Type 'a. ('a, 'a) -> bool effect pure eq
+overload (deinfix ==) [eq_vec; eq_atom; eq]
+
+
+val forall 'n, 'n in {32,64}. bit['n] -> bit[64] effect pure test
+
+function test(v) = {
+ switch (length(v)) {
+ case 32 -> extz(v)
+ case 64 -> v
+ }
+}
diff --git a/test/typecheck/pass/phantom_num.sail b/test/typecheck/pass/phantom_num.sail
new file mode 100644
index 00000000..c676807d
--- /dev/null
+++ b/test/typecheck/pass/phantom_num.sail
@@ -0,0 +1,17 @@
+
+val extern (int, int) -> bool effect pure gt_int = "gt"
+
+(* val cast forall Num 'n, Num 'm. [|'n:'m|] -> int effect pure cast_range_int *)
+
+overload (deinfix >) [gt_int]
+
+register int z
+
+val forall Nat 'n. unit -> unit effect {wreg} test
+
+function forall Nat 'n. unit test () =
+{
+ if sizeof 'n > 3
+ then z := 0
+ else z := 1
+}
diff --git a/test/typecheck/pass/procstate1.sail b/test/typecheck/pass/procstate1.sail
new file mode 100644
index 00000000..95ba97db
--- /dev/null
+++ b/test/typecheck/pass/procstate1.sail
@@ -0,0 +1,16 @@
+default Order dec
+
+typedef ProcState = const struct forall Num 'n.
+{
+ bit['n] N;
+ bit[1] Z;
+ bit[1] C;
+ bit[1] V
+}
+
+register ProcState<1> PSTATE
+
+function unit test () =
+{
+ PSTATE.N := 0b1
+}
diff --git a/test/typecheck/pass/pure_record.sail b/test/typecheck/pass/pure_record.sail
new file mode 100644
index 00000000..c7bc373a
--- /dev/null
+++ b/test/typecheck/pass/pure_record.sail
@@ -0,0 +1,22 @@
+default Order dec
+
+typedef State = const struct forall Type 'a. {
+ vector<0, 1, dec, 'a> N;
+ vector<0, 1, dec, bit> Z;
+}
+
+let (State<bit>) myStateM = {
+ (State<bit>) r := undefined;
+ r.N := 0b1;
+ r.Z := 0b1;
+ r
+}
+
+let (State<bit>) myState = { N = 0b1; Z = 0b1 }
+
+val unit -> unit effect {undef} test
+
+function test () = {
+ (State<bit>) myState2 := { N = undefined; Z = 0b1 };
+ (State<bit>) myState3 := { myState2 with N = 0b0 }
+}
diff --git a/test/typecheck/pass/pure_record2.sail b/test/typecheck/pass/pure_record2.sail
new file mode 100644
index 00000000..a0a85313
--- /dev/null
+++ b/test/typecheck/pass/pure_record2.sail
@@ -0,0 +1,22 @@
+default Order dec
+
+typedef State = const struct forall Type 'a, Nat 'n. {
+ vector<0, 'n, dec, 'a> N;
+ vector<0, 1, dec, bit> Z;
+}
+
+let (State<bit,1>) myStateM = {
+ (State<bit,1>) r := undefined;
+ r.N := 0b1;
+ r.Z := 0b1;
+ r
+}
+
+let (State<bit,1>) myState = { N = 0b1; Z = 0b1 }
+
+val unit -> unit effect {undef} test
+
+function test () = {
+ (State<bit,1>) myState2 := { N = undefined; Z = 0b1 };
+ (State<bit,1>) myState3 := { myState2 with N = 0b0 }
+}
diff --git a/test/typecheck/pass/pure_record3.sail b/test/typecheck/pass/pure_record3.sail
new file mode 100644
index 00000000..61d74ebf
--- /dev/null
+++ b/test/typecheck/pass/pure_record3.sail
@@ -0,0 +1,25 @@
+default Order dec
+
+typedef State = const struct forall Type 'a, Nat 'n. {
+ vector<0, 'n, dec, 'a> N;
+ vector<0, 1, dec, bit> Z;
+}
+
+register State<bit,1> procState
+
+let (State<bit,1>) myStateM = {
+ (State<bit,1>) r := undefined;
+ r.N := 0b1;
+ r.Z := 0b1;
+ r
+}
+
+let (State<bit,1>) myState = { N = 0b1; Z = 0b1 }
+
+val unit -> unit effect {undef} test
+
+function test () = {
+ (State<bit,1>) myState1 := undefined;
+ (State<bit,1>) myState2 := { N = undefined; Z = 0b1 };
+ (State<bit,1>) myState3 := { myState2 with N = 0b0 }
+}
diff --git a/test/typecheck/pass/real.sail b/test/typecheck/pass/real.sail
new file mode 100644
index 00000000..5ae1456b
--- /dev/null
+++ b/test/typecheck/pass/real.sail
@@ -0,0 +1,2 @@
+
+let (real) r = 2.2
diff --git a/test/typecheck/pass/reg_mod.sail b/test/typecheck/pass/reg_mod.sail
new file mode 100644
index 00000000..37c8d890
--- /dev/null
+++ b/test/typecheck/pass/reg_mod.sail
@@ -0,0 +1,11 @@
+
+register [|0:10|] reg
+
+val unit -> unit effect {wreg} test
+
+function unit test () =
+{
+ reg := 9;
+ reg := 10;
+ reg := 8
+} \ No newline at end of file
diff --git a/test/typecheck/pass/regtyp_vec.sail b/test/typecheck/pass/regtyp_vec.sail
new file mode 100644
index 00000000..28978882
--- /dev/null
+++ b/test/typecheck/pass/regtyp_vec.sail
@@ -0,0 +1,36 @@
+(* val forall Nat 'n, Nat 'm, Nat 'o, 'o >= 'm - 1.
+ vector<'n,'m,dec,bit> -> vector<'o,'m,dec,bit>
+ effect pure ADJUST
+*)
+
+val forall Nat 'n, Nat 'l, 'l >= 0. (vector<'n,'l,dec,bit>, [|'n - 'l + 1:'n|]) -> bit effect pure bitvector_access_dec
+(*
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+*)
+
+overload vector_access [bitvector_access_dec]
+
+default Order dec
+
+typedef CauseReg = register bits [ 31 : 0 ] {
+ 31 : BD; (* branch delay *)
+ (*30 : Z0;*)
+ 29 .. 28 : CE; (* for coprocessor enable exception *)
+ (*27 .. 24 : Z1;*)
+ 23 : IV; (* special interrupt vector not supported *)
+ 22 : WP; (* watchpoint exception occurred *)
+ (*21 .. 16 : Z2; *)
+ 15 .. 8 : IP; (* interrupt pending bits *)
+ (*7 : Z3;*)
+ 6 .. 2 : ExcCode; (* code of last exception *)
+ (*1 .. 0 : Z4;*)
+}
+
+register (CauseReg) CP0Cause
+
+val unit -> bit effect {rreg} test
+
+function bit test () =
+{
+ CP0Cause[30]
+}
diff --git a/test/typecheck/pass/return_simple1.sail b/test/typecheck/pass/return_simple1.sail
new file mode 100644
index 00000000..26e6fc1d
--- /dev/null
+++ b/test/typecheck/pass/return_simple1.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return x;
+ x
+}
diff --git a/test/typecheck/pass/return_simple2.sail b/test/typecheck/pass/return_simple2.sail
new file mode 100644
index 00000000..06ce9757
--- /dev/null
+++ b/test/typecheck/pass/return_simple2.sail
@@ -0,0 +1,11 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return x;
+ return x;
+ return x;
+ return x;
+ x
+}
diff --git a/test/typecheck/pass/return_simple3.sail b/test/typecheck/pass/return_simple3.sail
new file mode 100644
index 00000000..7e81b5b2
--- /dev/null
+++ b/test/typecheck/pass/return_simple3.sail
@@ -0,0 +1,8 @@
+
+val forall Nat 'N, 'N >= 10. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N, 'N >= 10. [|10:'N|] return_test x =
+{
+ return x;
+ sizeof 'N
+}
diff --git a/test/typecheck/pass/return_simple4.sail b/test/typecheck/pass/return_simple4.sail
new file mode 100644
index 00000000..1bbc0e73
--- /dev/null
+++ b/test/typecheck/pass/return_simple4.sail
@@ -0,0 +1,7 @@
+
+val forall Nat 'N. [|10:'N|] -> [|10:'N|] effect pure return_test
+
+function forall Nat 'N. [|10:'N|] return_test x =
+{
+ return x
+}
diff --git a/test/typecheck/pass/set_mark.sail b/test/typecheck/pass/set_mark.sail
new file mode 100644
index 00000000..af0b5ba2
--- /dev/null
+++ b/test/typecheck/pass/set_mark.sail
@@ -0,0 +1,11 @@
+
+val extern forall Num 'l, Num 'm. ([:'l:], [:'m:], int) -> vector<'l,'m,dec,bit> effect pure to_vec_dec
+
+val cast forall Num 'n, Num 'm. [:0:] -> vector<'n,'m,dec,bit> effect pure cast_0_vec
+function forall Num 'n, Num 'm. (vector<'n,'m,dec,bit>) cast_0_vec i = to_vec_dec (sizeof 'n, sizeof 'm, i)
+
+default Order dec
+
+function forall Num 'N, 'N IN {32}. bit['N] Foo32( (bit['N]) x) = x
+
+let x = Foo32( (bit[32]) 0)
diff --git a/test/typecheck/pass/set_mark2.sail b/test/typecheck/pass/set_mark2.sail
new file mode 100644
index 00000000..591c17ad
--- /dev/null
+++ b/test/typecheck/pass/set_mark2.sail
@@ -0,0 +1,11 @@
+
+val extern forall Num 'l, Num 'm. ([:'l:], [:'m:], int) -> vector<'l,'m,dec,bit> effect pure to_vec_dec
+
+val cast forall Num 'n, Num 'm. [:0:] -> vector<'n,'m,dec,bit> effect pure cast_0_vec
+function forall Num 'n, Num 'm. (vector<'n,'m,dec,bit>) cast_0_vec i = to_vec_dec (sizeof 'n, sizeof 'm, i)
+
+default Order dec
+
+function forall Nat 'N, 'N IN {32, 64}. bit['N] Foo32( (bit['N]) x) = x
+
+let x = Foo32( (bit[64]) 0)
diff --git a/test/typecheck/pass/set_spsr.sail b/test/typecheck/pass/set_spsr.sail
new file mode 100644
index 00000000..7fac206c
--- /dev/null
+++ b/test/typecheck/pass/set_spsr.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,'a>, [:'m:], [:'o:]) -> vector<'m,'o - 'm,inc,'a> effect pure vector_subrange_inc
+
+val forall Nat 'n, Nat 'l, Nat 'm, Nat 'o, Type 'a, 'n >= 'm, 'm >= 'o, 'o >= 'n - 'l + 1.
+ (vector<'n,'l,dec,'a>, [:'m:], [:'o:]) -> vector<'m,'m - ('o - 1),dec,'a> effect pure vector_subrange_dec
+
+overload vector_subrange [vector_subrange_inc; vector_subrange_dec]
+
+register bit[32] SPSR_EL2
+
+function unit set_SPSR_hyp (bit[32]) val_name =
+{
+ (bit[32]) r := val_name;
+ SPSR_EL2[31..0] := r
+}
diff --git a/test/typecheck/pass/simple_record_access.sail b/test/typecheck/pass/simple_record_access.sail
new file mode 100644
index 00000000..d4f4d61f
--- /dev/null
+++ b/test/typecheck/pass/simple_record_access.sail
@@ -0,0 +1,16 @@
+typedef signal = enumerate {LOW; HIGH}
+
+typedef Bit32 = bit[32]
+
+typedef Record =
+ const struct {signal rsig;
+ Bit32 bitfield;}
+
+register bit[32] R0
+
+val Record -> unit effect {wreg} test
+
+function unit test ((Record) r) =
+{
+ R0 := r.bitfield;
+}
diff --git a/test/typecheck/pass/simple_scattered.sail b/test/typecheck/pass/simple_scattered.sail
new file mode 100644
index 00000000..a500cd1f
--- /dev/null
+++ b/test/typecheck/pass/simple_scattered.sail
@@ -0,0 +1,22 @@
+
+default Order dec
+
+scattered typedef ast = const union forall Num 'datasize, Num 'destsize, Num 'regsize.
+
+val forall Num 'datasize, Num 'destsize, Num 'regsize.
+ ast<'datasize,'destsize,'regsize> -> unit effect pure execute
+
+scattered function forall Num 'datasize, Num 'destsize, Num 'regsize. unit execute
+
+union ast member (bit[8], bit['regsize]) test
+
+union ast member int test2
+
+function clause execute (test (x, y)) =
+{
+ return ()
+}
+
+end ast
+
+end execute
diff --git a/test/typecheck/pass/simple_scattered2.sail b/test/typecheck/pass/simple_scattered2.sail
new file mode 100644
index 00000000..8cd26e95
--- /dev/null
+++ b/test/typecheck/pass/simple_scattered2.sail
@@ -0,0 +1,27 @@
+
+default Order dec
+
+scattered typedef ast = const union forall Num 'datasize, Num 'destsize, Num 'regsize.
+
+val forall Num 'datasize, Num 'destsize, Num 'regsize.
+ ast<'datasize,'destsize,'regsize> -> unit effect pure execute
+
+scattered function forall Num 'datasize, Num 'destsize, Num 'regsize. unit execute
+
+union ast member (bit[8], bit['regsize]) test
+
+function clause execute (test (x, y)) =
+{
+ return ()
+}
+
+union ast member int test2
+
+function clause execute (test2(x)) =
+{
+ return ()
+}
+
+end ast
+
+end execute
diff --git a/test/typecheck/pass/sizeof_vector_start_index.sail b/test/typecheck/pass/sizeof_vector_start_index.sail
new file mode 100644
index 00000000..6ad8ef06
--- /dev/null
+++ b/test/typecheck/pass/sizeof_vector_start_index.sail
@@ -0,0 +1,12 @@
+val forall Num 'n, Num 'm, Order 'ord, Type 'a. vector<'n,'m,'ord,'a> -> [:'n:] effect pure vector_start_index
+
+function forall Num 'n, Num 'm, Order 'ord, Type 'a. [:'n:] vector_start_index ((vector<'n,'m,'ord,'a>) vec) =
+{
+ sizeof 'n
+}
+
+function int test ((vector<47,11,dec,bit>) vec) =
+{
+ vector_start_index(vec)
+}
+
diff --git a/test/typecheck/pass/trycatch.sail b/test/typecheck/pass/trycatch.sail
new file mode 100644
index 00000000..b7f97dd0
--- /dev/null
+++ b/test/typecheck/pass/trycatch.sail
@@ -0,0 +1,20 @@
+
+scattered typedef exception = const union
+
+union exception member int IntEx
+
+val unit -> unit effect {escape} test2
+
+function test2 () = throw (IntEx(3))
+
+val unit -> unit effect {escape} test
+
+function test () =
+ try {
+ test2();
+ ()
+ } catch {
+ case (IntEx(_)) -> ()
+ }
+
+end exception
diff --git a/test/typecheck/pass/union_infer.sail b/test/typecheck/pass/union_infer.sail
new file mode 100644
index 00000000..397525e0
--- /dev/null
+++ b/test/typecheck/pass/union_infer.sail
@@ -0,0 +1,16 @@
+
+default Order inc
+
+typedef option = const union forall Type 'a. {
+ None;
+ 'a Some
+ }
+
+typedef Test = const union {
+ A;
+ B;
+ C
+}
+
+
+function option<Test> test () = Some(C)
diff --git a/test/typecheck/pass/varity.sail b/test/typecheck/pass/varity.sail
new file mode 100644
index 00000000..750d70eb
--- /dev/null
+++ b/test/typecheck/pass/varity.sail
@@ -0,0 +1,19 @@
+
+val int -> unit effect pure f1
+val (int, int) -> unit effect pure f2
+val (int, int, int) -> unit effect pure f3
+
+function f1 (i1) = ()
+function f2 (i1, i2) = ()
+function f3 (i1, i2, i3) = ()
+
+overload f [f1; f2; f3]
+
+val unit -> unit effect pure test
+
+function test () =
+{
+ f(1);
+ f(2, 3);
+ f(4, 5, 6);
+}
diff --git a/test/typecheck/pass/vec_pat1.sail b/test/typecheck/pass/vec_pat1.sail
new file mode 100644
index 00000000..b22f0029
--- /dev/null
+++ b/test/typecheck/pass/vec_pat1.sail
@@ -0,0 +1,20 @@
+default Order inc
+
+val extern forall Num 'n. (bit['n], bit['n]) -> bit['n] effect pure bv_add = "add_vec"
+
+val extern forall Num 'n, Num 'l, Num 'm, Num 'o, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,bit>, [:'m:], [:'o:]) -> vector<'m,'o + 1 - 'm,inc,bit> effect pure vector_subrange = "bitvector_subrange_inc"
+
+val forall Num 'n, Num 'm, Num 'o, Num 'p.
+ (vector<'n,'m,inc,bit>, vector<'o,'p,inc,bit>) -> vector<'n,'m + 'p,inc,bit>
+ effect pure bitvector_concat
+
+overload (deinfix +) [bv_add]
+overload append [bitvector_concat]
+
+val (bit[3], bit[3]) -> bit[3] effect pure test
+
+function bit[3] test (((bit[1]) x : 0b1 : 0b0), z) =
+{
+ (x : 0b11) + z
+}
diff --git a/test/typecheck/pass/vector_access.sail b/test/typecheck/pass/vector_access.sail
new file mode 100644
index 00000000..4228a62e
--- /dev/null
+++ b/test/typecheck/pass/vector_access.sail
@@ -0,0 +1,15 @@
+
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+
+default Order inc
+
+overload vector_access [vector_access_inc; vector_access_dec]
+
+val bit[4] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,3);
+ z := v[3]
+} \ No newline at end of file
diff --git a/test/typecheck/pass/vector_access_dec.sail b/test/typecheck/pass/vector_access_dec.sail
new file mode 100644
index 00000000..c59100f0
--- /dev/null
+++ b/test/typecheck/pass/vector_access_dec.sail
@@ -0,0 +1,15 @@
+
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,dec,'a>, [|'n - 'l + 1:'n|]) -> 'a effect pure vector_access_dec
+val forall Nat 'n, Nat 'l, Type 'a, 'l >= 0. (vector<'n,'l,inc,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access_inc
+
+overload vector_access [vector_access_inc; vector_access_dec]
+
+default Order dec
+
+val bit[4] -> unit effect pure test
+
+function unit test v =
+{
+ z := vector_access(v,3);
+ z := v[3]
+} \ No newline at end of file
diff --git a/test/typecheck/pass/vector_append.sail b/test/typecheck/pass/vector_append.sail
new file mode 100644
index 00000000..df610fb1
--- /dev/null
+++ b/test/typecheck/pass/vector_append.sail
@@ -0,0 +1,14 @@
+
+val extern forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,bit>, vector<'n2,'l2,'o,bit>) -> vector<'n1,'l1 + 'l2,'o,bit> effect pure append = "bitvector_concat"
+
+default Order inc
+
+val (bit[4], bit[4]) -> bit[8] effect pure test
+
+function bit[8] test (v1, v2) =
+{
+ zv := append(v1, v2);
+ zv := v1 : v2;
+ zv
+}
diff --git a/test/typecheck/pass/vector_append_gen.sail b/test/typecheck/pass/vector_append_gen.sail
new file mode 100644
index 00000000..ce63ed87
--- /dev/null
+++ b/test/typecheck/pass/vector_append_gen.sail
@@ -0,0 +1,12 @@
+
+val extern forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,bit>, vector<'n2,'l2,'o,bit>) -> vector<'n1,'l1 + 'l2,'o,bit> effect pure vector_append = "bitvector_concat"
+
+default Order inc
+
+val forall 'n, 'm, 'n >= 0, 'm >= 0. (bit['n], bit['m]) -> bit['n + 'm] effect pure test
+
+function forall 'n, 'm. bit['n + 'm] test (v1, v2) =
+{
+ vector_append(v1, v2);
+}
diff --git a/test/typecheck/pass/vector_subrange_gen.sail b/test/typecheck/pass/vector_subrange_gen.sail
new file mode 100644
index 00000000..4ec067de
--- /dev/null
+++ b/test/typecheck/pass/vector_subrange_gen.sail
@@ -0,0 +1,21 @@
+
+val forall Nat 'n, Nat 'l, Order 'o, Type 'a, 'l >= 0. (vector<'n,'l,'o,'a>, [|'n:'n + 'l - 1|]) -> 'a effect pure vector_access
+
+val forall Nat 'n1, Nat 'l1, Nat 'n2, Nat 'l2, Order 'o, Type 'a, 'l1 >= 0, 'l2 >= 0.
+ (vector<'n1,'l1,'o,'a>, vector<'n2,'l2,'o,'a>) -> vector<'n1,'l1 + 'l2,'o,'a> effect pure vector_append
+
+val extern forall Num 'n, Num 'l, Num 'm, Num 'o, 'l >= 0, 'm <= 'o, 'o <= 'l.
+ (vector<'n,'l,inc,bit>, [:'m:], [:'o:]) -> vector<'m,('o - 'm) + 1,inc,bit> effect pure vector_subrange = "bitvector_subrange_inc"
+
+val forall Nat 'n, Nat 'm. ([:'n:], [:'m:]) -> [:'n - 'm:] effect pure sub
+
+default Order inc
+
+val forall 'n, 'm, 'n >= 5. bit['n] -> bit['n - 1] effect pure test
+
+function forall 'n, 'n >= 5. bit['n - 1] test v =
+{
+ z := vector_subrange(v, 0, sub(sizeof 'n, 2));
+ z := v[0 .. sub(sizeof 'n, 2)];
+ z
+}
diff --git a/test/typecheck/pass/vector_synonym_cast.sail b/test/typecheck/pass/vector_synonym_cast.sail
new file mode 100644
index 00000000..bd0acaa6
--- /dev/null
+++ b/test/typecheck/pass/vector_synonym_cast.sail
@@ -0,0 +1,8 @@
+
+typedef vecsyn = vector<0,1,dec,bit>
+
+val cast vector<1,1,dec,bit> -> vector<0,1,dec,bit> effect pure norm_dec
+
+val vector<1,1,dec,bit> -> vecsyn effect pure test
+
+function test x = x
diff --git a/test/typecheck/pass/while_MM.sail b/test/typecheck/pass/while_MM.sail
new file mode 100644
index 00000000..e6916edd
--- /dev/null
+++ b/test/typecheck/pass/while_MM.sail
@@ -0,0 +1,23 @@
+default Order dec
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p.
+ ([|'n:'m|], [|'o:'p|]) -> [|'n + 'o:'m + 'p|] effect pure add_range = "add"
+val extern (int, int) -> int effect pure add_int = "add"
+val forall Num 'n, Num 'o, Order 'ord.
+ (vector<'o, 'n, 'ord, bit>, int) -> vector<'o, 'n, 'ord, bit> effect pure add_vec_int
+overload (deinfix +) [add_vec_int; add_range; add_int]
+
+val extern bool -> bool effect pure bool_not = "not"
+
+val cast forall Num 'n, Num 'l. [:0:] -> vector<'n,'l,dec,bit> effect pure cast_0_vec_dec
+
+register (bit[64]) COUNT
+register (bool) INT
+
+function (unit) test () = {
+ COUNT := 0;
+ while (bool_not(INT)) do {
+ COUNT := COUNT + 1;
+ }
+}
+
diff --git a/test/typecheck/pass/while_MP.sail b/test/typecheck/pass/while_MP.sail
new file mode 100644
index 00000000..05d396e2
--- /dev/null
+++ b/test/typecheck/pass/while_MP.sail
@@ -0,0 +1,17 @@
+default Order dec
+
+val extern (int, int) -> int effect pure add_int = "add"
+overload (deinfix +) [add_vec_int; add_range; add_int]
+
+val extern bool -> bool effect pure bool_not = "not"
+
+register (bool) INT
+
+function (int) test () = {
+ (int) count := 0;
+ while (bool_not(INT)) do {
+ count := count + 1;
+ };
+ return count;
+}
+
diff --git a/test/typecheck/pass/while_PM.sail b/test/typecheck/pass/while_PM.sail
new file mode 100644
index 00000000..b03a87dc
--- /dev/null
+++ b/test/typecheck/pass/while_PM.sail
@@ -0,0 +1,23 @@
+default Order dec
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern (int, int) -> bool effect pure lt_int = "lt"
+overload (deinfix <) [lt_range_atom; lt_int]
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p.
+ ([|'n:'m|], [|'o:'p|]) -> [|'n + 'o:'m + 'p|] effect pure add_range = "add"
+val extern (int, int) -> int effect pure add_int = "add"
+overload (deinfix +) [add_range; add_int]
+
+val extern forall Num 'n, Num 'l, 'l >= 0. (vector<'n,'l,dec,bit>, int) -> bit effect pure vector_access = "bitvector_access_dec"
+
+register (bit[64]) GPR00
+
+function (unit) test ((bit) b) = {
+ (int) i := 0;
+ while (i < 64) do {
+ GPR00[i] := b;
+ i := i + 1;
+ }
+}
+
diff --git a/test/typecheck/pass/while_PP.sail b/test/typecheck/pass/while_PP.sail
new file mode 100644
index 00000000..454cc9ac
--- /dev/null
+++ b/test/typecheck/pass/while_PP.sail
@@ -0,0 +1,24 @@
+default Order dec
+
+val extern forall Num 'n, Num 'm, Num 'o. ([|'n:'m|], [:'o:]) -> bool effect pure lt_range_atom = "lt"
+val extern (int, int) -> bool effect pure lt_int = "lt"
+overload (deinfix <) [lt_range_atom; lt_int]
+
+val (int, int) -> int effect pure mult_int
+overload (deinfix * ) [mult_int]
+
+val extern forall Num 'n, Num 'm, Num 'o, Num 'p.
+ ([|'n:'m|], [|'o:'p|]) -> [|'n + 'o:'m + 'p|] effect pure add_range = "add"
+val extern (int, int) -> int effect pure add_int = "add"
+overload (deinfix +) [add_range; add_int]
+
+function (int) test ((int) n) = {
+ (int) i := 1;
+ (int) j := 1;
+ while (i < n) do {
+ j := i * j;
+ i := i + 1;
+ };
+ j
+}
+
diff --git a/test/typecheck/run_tests.sh b/test/typecheck/run_tests.sh
new file mode 100755
index 00000000..a2567d21
--- /dev/null
+++ b/test/typecheck/run_tests.sh
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+SAILDIR="$DIR/../.."
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[0;33m'
+NC='\033[0m'
+
+mkdir -p $DIR/rtpass
+mkdir -p $DIR/rtpass2
+mkdir -p $DIR/lem
+mkdir -p $DIR/rtfail
+
+rm -f $DIR/tests.xml
+
+MIPS="$SAILDIR/mips_new_tc"
+
+cat $SAILDIR/lib/prelude.sail $SAILDIR/lib/prelude_wrappers.sail $MIPS/mips_prelude.sail > $DIR/pass/mips_prelude.sail
+cat $SAILDIR/lib/prelude.sail $SAILDIR/lib/prelude_wrappers.sail $MIPS/mips_prelude.sail $MIPS/mips_tlb.sail > $DIR/pass/mips_tlb.sail
+cat $SAILDIR/lib/prelude.sail $SAILDIR/lib/prelude_wrappers.sail $MIPS/mips_prelude.sail $MIPS/mips_tlb.sail $MIPS/mips_wrappers.sail > $DIR/pass/mips_wrappers.sail
+cat $SAILDIR/lib/prelude.sail $SAILDIR/lib/prelude_wrappers.sail $MIPS/mips_prelude.sail $MIPS/mips_tlb.sail $MIPS/mips_wrappers.sail $MIPS/mips_ast_decl.sail $MIPS/mips_insts.sail $MIPS/mips_epilogue.sail > $DIR/pass/mips_insts.sail
+cat $SAILDIR/lib/prelude.sail $SAILDIR/lib/prelude_wrappers.sail $MIPS/mips_prelude.sail $MIPS/mips_tlb_stub.sail $MIPS/mips_wrappers.sail $MIPS/mips_ast_decl.sail $MIPS/mips_insts.sail $MIPS/mips_epilogue.sail > $DIR/pass/mips_notlb.sail
+
+pass=0
+fail=0
+
+XML=""
+
+function green {
+ (( pass += 1 ))
+ printf "$1: ${GREEN}$2${NC}\n"
+ XML+=" <testcase name=\"$1\"/>\n"
+}
+
+function yellow {
+ (( fail += 1 ))
+ printf "$1: ${YELLOW}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function red {
+ (( fail += 1 ))
+ printf "$1: ${RED}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function finish_suite {
+ printf "$1: Passed ${pass} out of $(( pass + fail ))\n"
+ XML=" <testsuite name=\"$1\" tests=\"$(( pass + fail ))\" failures=\"${fail}\" timestamp=\"$(date)\">\n$XML </testsuite>\n"
+ printf "$XML" >> $DIR/tests.xml
+ XML=""
+ pass=0
+ fail=0
+}
+
+printf "<testsuites>\n" >> $DIR/tests.xml
+
+for i in `ls $DIR/pass/`;
+do
+ if $SAILDIR/sail -ddump_tc_ast -dsanity $DIR/pass/$i 2> /dev/null 1> $DIR/rtpass/$i;
+ then
+ if $SAILDIR/sail -ddump_tc_ast -dmagic_hash -dno_cast -dsanity $DIR/rtpass/$i 2> /dev/null 1> $DIR/rtpass2/$i;
+ then
+ if diff $DIR/rtpass/$i $DIR/rtpass2/$i;
+ then
+ green "tested $i expecting pass" "pass"
+ else
+ yellow "tested $i expecting pass" "re-check AST was different"
+ fi
+ else
+ yellow "tested $i expecting pass" "failed re-check"
+ fi
+ else
+ red "tested $i expecting pass" "fail"
+ fi
+done
+
+finish_suite "Expecting pass"
+
+for i in `ls $DIR/fail/`;
+do
+ if $SAILDIR/sail -ddump_tc_ast -just_check $DIR/fail/$i 2> /dev/null 1> $DIR/rtfail/$i;
+ then
+ red "tested $i expecting fail" "pass"
+ else
+ if $SAILDIR/sail -dno_cast -dmagic_hash -just_check $DIR/rtfail/$i 2> /dev/null;
+ then
+ yellow "tested $i expecting fail" "passed re-check"
+ else
+ green "tested $i expecting fail" "fail"
+ fi
+ fi
+done
+
+finish_suite "Expecting fail"
+
+function test_lem {
+ for i in `ls $DIR/pass/`;
+ do
+ # MIPS requires an additional library, Mips_extras_embed.
+ # It might be useful to allow adding options for specific test cases.
+ # For now, include the library for all test cases, which doesn't seem to hurt.
+ if $SAILDIR/sail -lem -lem_lib Mips_extras_embed -lem_sequential -lem_mwords $DIR/$1/$i 2> /dev/null
+ then
+ green "generated lem for $1/$i" "pass"
+
+ cp $MIPS/mips_extras_embed_sequential.lem $DIR/lem/
+ # mv $SAILDIR/${i%%.*}_embed_types.lem $DIR/lem/
+ mv $SAILDIR/${i%%.*}_embed_types_sequential.lem $DIR/lem/
+ # mv $SAILDIR/${i%%.*}_embed.lem $DIR/lem/
+ mv $SAILDIR/${i%%.*}_embed_sequential.lem $DIR/lem/
+ # Test sequential embedding for now
+ # TODO: Add tests for the free monad
+ if lem -lib $SAILDIR/src/lem_interp -lib $SAILDIR/src/gen_lib/ $DIR/lem/mips_extras_embed_sequential.lem $DIR/lem/${i%%.*}_embed_types_sequential.lem $DIR/lem/${i%%.*}_embed_sequential.lem 2> /dev/null
+ then
+ green "typechecking lem for $1/$i" "pass"
+ else
+ red "typechecking lem for $1/$i" "fail"
+ fi
+ else
+ red "generated lem for $1/$i" "fail"
+ red "typechecking lem for $1/$i" "fail"
+ fi
+ done
+}
+
+test_lem pass
+
+finish_suite "Lem generation 1"
+
+test_lem rtpass
+
+finish_suite "Lem generation 2"
+
+# function test_ocaml {
+# for i in `ls $DIR/pass/`;
+# do
+# if $SAILDIR/sail -ocaml $DIR/$1/$i 2> /dev/null
+# then
+# green "generated ocaml for $1/$i" "pass"
+
+# rm $SAILDIR/${i%%.*}.ml
+# else
+# red "generated ocaml for $1/$i" "fail"
+# fi
+# done
+# }
+
+# test_ocaml pass
+
+# finish_suite "Ocaml generation 1"
+
+# test_ocaml rtpass
+
+# finish_suite "Ocaml generation 2"
+
+printf "</testsuites>\n" >> $DIR/tests.xml