def test_swapstack_spill(): compile_bundle( """ .funcdef test_swapstack_spill_swapee <(stackref)->()> { entry(<stackref>s): SWAPSTACK s KILL_OLD PASS_VALUES<>() } .funcdef test_swapstack_spill <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): BRANCH block(<double>0.0 d <double>1.0 d <double>2.0 d <double>3.0 d <double>4.0 d <double>5.0 d <double>6.0 d <double>7.0 d <double>8.0 d <double>9.0 d) block(<double>d0 <double>d1 <double>d2 <double>d3 <double>d4 <double>d5 <double>d6 <double>d7 <double> d8 <double> d9): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_swapstack_spill_swapee) SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs) s1 = FADD <double> d0 d1 s2 = FADD <double> s1 d2 s3 = FADD <double> s2 d3 s4 = FADD <double> s3 d4 s5 = FADD <double> s4 d5 s6 = FADD <double> s5 d6 s7 = FADD <double> s6 d7 s8 = FADD <double> s7 d8 s9 = FADD <double> s8 d9 r = FPTOSI <double int<32>> s9 RET r } """, "test_swapstack_spill"); assert(execute("test_swapstack_spill", []) == 45);
def test_taillcall_bigger_stack(): compile_bundle( """ .funcsig big_sig = (int<128> int<128> int<128> int<128> int<128> int<128>)->(int<128> int<128>) .funcsig small_sig = (int<128> int<128> int<128> int<128> int<128>) ->(int<128> int<128>) .funcdef test_taillcall_bigger_stack <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): (res_013 res_245) = CALL <small_sig> smaller_stack(<int<128>>0 <int<128>>1 <int<128>>2 <int<128>>3 <int<128>>4) res_128 = ADD<int<128>> res_013 res_245 res = TRUNC <int<128> int<32>> res_128 RET res } .funcdef smaller_stack <small_sig> { entry(<int<128>>a0 <int<128>>a1 <int<128>>a2 <int<128>>a3 <int<128>>a4): TAILCALL <big_sig> bigger_stack(a0 a1 a2 a3 a4 <int<128>>5) } .funcdef bigger_stack <big_sig> { entry(<int<128>>a0 <int<128>>a1 <int<128>>a2 <int<128>>a3 <int<128>>a4 <int<128>>a5): res_01 = ADD<int<128>> a0 a1 res_013 = ADD<int<128>> res_01 a3 res_24 = MUL<int<128>> a2 a4 res_245 = MUL<int<128>> res_24 a5 RET (res_013 res_245) } """, "test_taillcall_bigger_stack"); assert(execute("test_taillcall_bigger_stack") == 44);
def test_swapstack_threadlocal(): compile_bundle( """ .funcdef test_swapstack_threadlocal_stack <(stackref)->()> { entry(<stackref>s): tr = NEW <int<32>> tri = GETIREF <int<32>> tr STORE <int<32>> tri <int<32>> 3 tl = REFCAST <ref<int<32>> ref<void>> tr t = NEWTHREAD s THREADLOCAL (tl) PASS_VALUES<>() COMMINST uvm.thread_exit() } .funcdef test_swapstack_threadlocal <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_swapstack_threadlocal_stack) SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs) tv = COMMINST uvm.get_threadlocal() tr = REFCAST <ref<void> ref<int<32>>> tv tvi = GETIREF <int<32>> tr tv = LOAD <int<32>> tvi RET (tv) } """, "test_swapstack_threadlocal"); assert(execute("test_swapstack_threadlocal", []) == 3);
def test_taillcall_exception(): compile_bundle( """ .funcdef tail_callee <(int<32>)->(int<32>)> { entry(<int<32>> arg): exc = NEW <int<32>> exc_iref = GETIREF <int<32>> exc STORE <int<32>> exc_iref arg THROW exc } .funcdef tail_caller <(int<32>)->(int<32>)> { entry(<int<32>> arg): TAILCALL <(int<32>)->(int<32>)> tail_callee(arg) } .funcdef test_taillcall_exception <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): res = CALL <(int<32>)->(int<32>)> tail_caller(argc) EXC (norm(res) except()) except()[@eparam]: eparam_cast = REFCAST <ref<void> ref<int<32>>> @eparam exc_iref = GETIREF <int<32>> eparam_cast val = LOAD <int<32>> exc_iref RET val norm(<int<32>> status): THROW <ref<void>>NULL // This should crash the program } """, "test_taillcall_exception"); assert(execute("test_taillcall_exception", ["2", "3"]) == 3);
def test_add_load_load(): compile_bundle( """ .funcdef test_add_load_load <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): ref_y = NEW <int<64>> iref_y = GETIREF <int<64>> ref_y STORE <int<64>> iref_y <int<64>> 42 ref_cell = NEW <ref<int<64>>> iref_cell = GETIREF <ref<int<64>>> ref_cell STORE <ref<int<64>>> iref_cell ref_y BRANCH body(<int<64>> 1 ref_cell) body(<int<64>> x <ref<ref<int<64>>>> ref_cell): iref_cell = GETIREF <ref<int<64>>> ref_cell ref_y = LOAD <ref<int<64>>> iref_cell iref_y = GETIREF <int<64>> ref_y y = LOAD <int<64>> iref_y sum = ADD <int<64>> x y BRANCH exit(sum) exit(<int<64>> res): res32 = TRUNC <int<64> int<32>> res RET res32 } """, "test_add_load_load") assert (execute("test_add_load_load") == 43)
def test_swapstack_pass_stack_args(): compile_bundle( """ .funcsig stack_sig = (stackref double double double double double double double double double double)->() .funcdef test_swapstack_pass_stack_args_swapee <stack_sig> { entry(<stackref>s <double>d0 <double>d1 <double>d2 <double>d3 <double>d4 <double>d5 <double>d6 <double>d7 <double> d8 <double> d9): SWAPSTACK s KILL_OLD PASS_VALUES<double double double double double double double double double double>(d0 d1 d2 d3 d4 d5 d6 d7 d8 d9) } .funcdef test_swapstack_pass_stack_args <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[stack_sig]>(test_swapstack_pass_stack_args_swapee) (d0 d1 d2 d3 d4 d5 d6 d7 d8 d9) = SWAPSTACK s RET_WITH<double double double double double double double double double double> PASS_VALUES<stackref double double double double double double double double double double>(cs <double>0.0 d <double>1.0 d <double>2.0 d <double>3.0 d <double>4.0 d <double>5.0 d <double>6.0 d <double>7.0 d <double>8.0 d <double>9.0 d) s1 = FADD <double> d0 d1 s2 = FADD <double> s1 d2 s3 = FADD <double> s2 d3 s4 = FADD <double> s3 d4 s5 = FADD <double> s4 d5 s6 = FADD <double> s5 d6 s7 = FADD <double> s6 d7 s8 = FADD <double> s7 d8 s9 = FADD <double> s8 d9 r = FPTOSI <double int<32>> s9 RET r } """, "test_swapstack_pass_stack_args"); assert(execute("test_swapstack_pass_stack_args", []) == 45);
def test_newthread_stack_args(): compile_bundle( """ .funcsig stack_sig = (stackref double double double double double double double double double double)->() .funcdef test_newthread_stack_args_thread <stack_sig> { entry(<stackref>s <double>d0 <double>d1 <double>d2 <double>d3 <double>d4 <double>d5 <double>d6 <double>d7 <double> d8 <double> d9): s1 = FADD <double> d0 d1 s2 = FADD <double> s1 d2 s3 = FADD <double> s2 d3 s4 = FADD <double> s3 d4 s5 = FADD <double> s4 d5 s6 = FADD <double> s5 d6 s7 = FADD <double> s6 d7 s8 = FADD <double> s7 d8 s9 = FADD <double> s8 d9 r = FPTOSI <double int<32>> s9 CCALL #DEFAULT <exit_type exit_sig> exit(r) RET } .funcdef test_newthread_stack_args <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[stack_sig]>(test_newthread_stack_args_thread) t = NEWTHREAD s PASS_VALUES<stackref double double double double double double double double double double>(cs <double>0.0 d <double>1.0 d <double>2.0 d <double>3.0 d <double>4.0 d <double>5.0 d <double>6.0 d <double>7.0 d <double>8.0 d <double>9.0 d) COMMINST uvm.thread_exit() } """, "test_newthread_stack_args"); assert(execute("test_newthread_stack_args", []) == 45);
def test_exc_pass_values(): compile_bundle( """ .funcsig sig = (ref<void> int<64>)->(int<32>) .funcdef test_exc_pass_values <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): BRANCH blk2(<int<64>>4 <ref<void>>NULL) blk2(<int<64>> v82555 <ref<void>> container_13): index_2893 = CALL <sig> excy(container_13 v82555) EXC(blk3(index_2893) blk4(v82555 container_13)) blk3(<int<32>> v82556): RET v82556 blk4(<int<64>> name_231 <ref<void>> container_14): a_32 = TRUNC <int<64> int<32>> name_231 RET a_32 } .funcdef excy <sig> { entry(<ref<void>>a0 <int<64>>a5): THROW <ref<void>>NULL } """, "test_exc_pass_values") assert (execute("test_exc_pass_values") == 4)
def test_stack_pass_and_return(): compile_bundle( """ .funcsig sig = (int<128> int<128> int<128> int<128> int<128> int<128>) ->(int<128> int<128>) .funcdef test_stack_pass_and_return <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): (res_013 res_245) = CALL <sig> stacky(<int<128>>0 <int<128>>1 <int<128>>2 <int<128>>3 <int<128>>4 <int<128>>5) res_128 = ADD<int<128>> res_013 res_245 res = TRUNC <int<128> int<32>> res_128 RET res } .funcdef stacky <sig> { entry(<int<128>>a0 <int<128>>a1 <int<128>>a2 <int<128>>a3 <int<128>>a4 <int<128>>a5): res_01 = ADD<int<128>> a0 a1 res_013 = ADD<int<128>> res_01 a3 res_24 = MUL<int<128>> a2 a4 res_245 = MUL<int<128>> res_24 a5 RET (res_013 res_245) } """, "test_stack_pass_and_return") assert (execute("test_stack_pass_and_return") == 44)
def test_newthread_threadlocal(): compile_bundle( """ .funcdef test_newthread_threadlocal_thread <()->()> { entry(): tv = COMMINST uvm.get_threadlocal() tr = REFCAST <ref<void> ref<int<32>>> tv tvi = GETIREF <int<32>> tr tv = LOAD <int<32>> tvi CCALL #DEFAULT <exit_type exit_sig> exit(tv) RET } .funcdef test_newthread_threadlocal <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): s = COMMINST uvm.new_stack<[()->()]>(test_newthread_threadlocal_thread) tr = NEW <int<32>> tri = GETIREF <int<32>> tr STORE <int<32>> tri <int<32>> 3 tl = REFCAST <ref<int<32>> ref<void>> tr t = NEWTHREAD s THREADLOCAL (tl) PASS_VALUES<>() COMMINST uvm.thread_exit() } """, "test_newthread_threadlocal"); assert(execute("test_newthread_threadlocal", []) == 3);
def test_newthread_throw(): compile_bundle( """ .funcdef test_newthread_throw_thread <(stackref)->()> { entry(<stackref>s): er = NEW <int<32>> eri = GETIREF <int<32>> er STORE <int<32>> eri <int<32>> 3 ev = REFCAST <ref<int<32>> ref<void>> er t = NEWTHREAD s THROW_EXC ev COMMINST uvm.thread_exit() } .funcdef test_newthread_throw <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_newthread_throw_thread) r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<stackref>(cs) EXC(nor_dest(r) exc_dest()) nor_dest(<int<32>> r): RET <int<32>>0 exc_dest()[exc_param]: e = REFCAST <ref<void> ref<int<32>>> exc_param evi = GETIREF <int<32>> e ev = LOAD <int<32>> evi RET ev } """, "test_newthread_throw"); assert(execute("test_newthread_throw", []) == 3);
def test_argc(): compile_bundle( """ .funcdef test_argc <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): RET argc } """, "test_argc") assert (execute("test_argc", ["2", "3", "4"]) == 4)
def test_allocahybrid_simple(): compile_bundle( """ .funcdef test_allocahybrid_simple <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): a = ALLOCAHYBRID <hybrid<int<1>> int<32>> argc RET argc } """, "test_allocahybrid_simple") assert (execute("test_allocahybrid_simple", ["1", "2", "3"]) == 4)
def test_alloca_simple(): compile_bundle( """ .funcdef test_alloca_simple <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): a = ALLOCA <struct<int<64> double ref<void>>> RET <int<32>>0 } """, "test_alloca_simple") assert (execute("test_alloca_simple") == 0)
def test_name(): compile_bundle( """ .global @-0.a5-1_5 <void> .const @0 <int<32>> = 0 .funcdef @0-main.func <main_sig> { entry(<int<32>>%1.3 <uptr<uptr<char>>>%-): RET @0 } """, "test_name", "0-main.func") assert (execute("test_name") == 0)
def test_int1(): compile_bundle( """ .funcdef test_int <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): res10 = ADD <int<1>> <int<1>>1 <int<1>>1 // = 1 res11 = ADD <int<1>> res10 <int<1>>1 // = 1 res1 = UDIV <int<1>> res11 <int<1>>1 // = 1 res = ZEXT <int<1> int<32>> res1 // = 1 RET res } """, "test_int") assert (execute("test_int") == 1)
def test_taillcall_simple(): compile_bundle( """ .funcdef test_taillcall_simple <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): TAILCALL <main_sig>taillcallee(argc argv) } .funcdef taillcallee <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): RET argc } """, "test_taillcall_simple"); assert(execute("test_taillcall_simple", ["2", "3", "4"]) == 4);
def test_swapstack_kill_old(): compile_bundle( """ .funcdef test_swapstack_kill_old_swapee <()->()> { entry(): CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>3) RET } .funcdef test_swapstack_kill_old <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): s = COMMINST uvm.new_stack<[()->()]>(test_swapstack_kill_old_swapee) SWAPSTACK s KILL_OLD PASS_VALUES<>() } """, "test_swapstack_kill_old"); assert(execute("test_swapstack_kill_old", []) == 3);
def test_newthread_simple(): compile_bundle( """ .funcdef test_newthread_simple_thread <()->()> { entry(): CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>3) RET } .funcdef test_newthread_simple <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): s = COMMINST uvm.new_stack<[()->()]>(test_newthread_simple_thread) t = NEWTHREAD s PASS_VALUES<>() COMMINST uvm.thread_exit() } """, "test_newthread_simple"); assert(execute("test_newthread_simple", []) == 3);
def test_swapstack_swap_back(): compile_bundle( """ .funcdef test_swapstack_swap_back_swapee <(stackref)->()> { entry(<stackref>s): SWAPSTACK s KILL_OLD PASS_VALUES<>() } .funcdef test_swapstack_swap_back <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_swapstack_swap_back_swapee) SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs) RET <int<32>>3 } """, "test_swapstack_swap_back"); assert(execute("test_swapstack_swap_back", []) == 3);
def test_swapstack_ret_values(): compile_bundle( """ .funcdef test_swapstack_ret_values_swapee <(stackref)->()> { entry(<stackref>s): SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32>> 2) } .funcdef test_swapstack_ret_values <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_swapstack_ret_values_swapee) r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<stackref>(cs) rv = ADD <int<32>> argc r RET rv } """, "test_swapstack_ret_values"); assert(execute("test_swapstack_ret_values", []) == 3);
def test_swapstack_throw_back(): compile_bundle( """ .funcdef test_swapstack_throw_back_swapee <(stackref)->()> { entry(<stackref>s): er = NEW <int<32>> eri = GETIREF <int<32>> er STORE <int<32>> eri <int<32>> 1 ev = REFCAST <ref<int<32>> ref<void>> er r = SWAPSTACK s RET_WITH<int<32>> THROW_EXC ev EXC(nor_dest(r) exc_dest()) nor_dest(<int<32>> r): CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>0) RET exc_dest()[exc_param]: e = REFCAST <ref<void> ref<int<32>>> exc_param evi = GETIREF <int<32>> e ev = LOAD <int<32>> evi CCALL #DEFAULT <exit_type exit_sig> exit(ev) RET } .funcdef test_swapstack_throw_back <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_swapstack_throw_back_swapee) r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<stackref>(cs) EXC(nor_dest(r) exc_dest(s)) nor_dest(<int<32>> r): RET <int<32>>0 exc_dest(<stackref> s)[exc_param]: e = REFCAST <ref<void> ref<int<32>>> exc_param evi = GETIREF <int<32>> e ev = LOAD <int<32>> evi newv = ADD <int<32>> ev <int<32>> 2 STORE <int<32>> evi newv // exc_param += 2 // Throw back to new_func SWAPSTACK s KILL_OLD THROW_EXC exc_param } """, "test_swapstack_throw_back"); assert(execute("test_swapstack_throw_back", []) == 3);
def test_except_stack_args(): compile_bundle( """ .funcsig stack_sig = (int<64> int<64> int<64> int<64> int<64> int<64> int<64> int<64> int<64>)->() .funcdef stack_args <stack_sig> { entry(<int<64>> v0 <int<64>> v1 <int<64>> v2 <int<64>> v3 <int<64>> v4 <int<64>> v5 <int<64>> v6 <int<64>> v7 <int<64>> v8): THROW <ref<void>> NULL } .funcdef test_except_stack_args <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): CALL <stack_sig> stack_args(<int<64>>0 <int<64>>1 <int<64>>2 <int<64>>3 <int<64>>4 <int<64>>5 <int<64>>6 <int<64>>7 <int<64>>8) EXC (exit(<int<32>> 0) exit(<int<32>> 1)) exit(<int<32>> status): RET status } """, "test_except_stack_args") assert (execute("test_except_stack_args") == 1)
def test_kill_stack(): compile_bundle( """ .funcdef test_kill_stack_swapee <(stackref)->()> { entry(<stackref>s): COMMINST uvm.kill_stack(s) CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>3) RET } .funcdef test_kill_stack <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_kill_stack_swapee) SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs) RET <int<32>>0 } """, "test_kill_stack"); assert(execute("test_kill_stack", []) == 3);
def test_add_load_global(): compile_bundle( """ .global global_y <int<64>> .funcdef test_add_load_global <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): STORE <int<64>> global_y <int<64>> 42 BRANCH body(<int<64>> 1) body(<int<64>> x): y = LOAD <int<64>> global_y sum = ADD <int<64>> x y BRANCH exit(sum) exit(<int<64>> res): res32 = TRUNC <int<64> int<32>> res RET res32 } """, "test_add_load_global") assert (execute("test_add_load_global") == 43)
def test_add_load_cast_global(): compile_bundle( """ .global global_y <int<64>> .funcdef test_add_load_cast_global <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): STORE <int<64>> global_y <int<64>> 42 BRANCH body(<int<32>> 1) body(<int<32>> x): global32_y = REFCAST <iref<int<64>> iref<int<32>>> global_y y = LOAD <int<32>> global32_y sum = ADD <int<32>> x y BRANCH exit(sum) exit(<int<32>> res): RET res } """, "test_add_load_cast_global") assert (execute("test_add_load_cast_global") == 43)
def test_newthread_swapstack(): compile_bundle( """ .funcdef test_newthread_swapstack_thread <(stackref)->()> { entry(<stackref>s): t = NEWTHREAD s PASS_VALUES<int<32>>(<int<32>> 2) BRANCH loop() loop(): BRANCH loop() } .funcdef test_newthread_swapstack <main_sig> { entry(<int<32>>argc <uptr<uptr<char>>>argv): cs = COMMINST uvm.current_stack() s = COMMINST uvm.new_stack<[(stackref)->()]>(test_newthread_swapstack_thread) r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<stackref>(cs) rv = ADD <int<32>> argc r RET rv // argc = 1 } """, "test_newthread_swapstack"); assert(execute("test_newthread_swapstack", []) == 3);