def test_gt_r_mem(): lib = load_bundle( """ .funcsig sig = (uptr<int<64>> int<64>) -> (int<64>) .funcdef test_gt_r_mem <sig> { entry(<uptr<int<64>>> ptr <int<64>> y): x = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_r_mem") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_r_mem, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (cmp_gt_zero(ptr, ctypes.c_int64(1)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_int64(0)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_int64(-1)) == 1)
def test_gt_mem_f(): lib = load_bundle( """ .funcsig sig = (double uptr<double>) -> (int<64>) .funcdef test_gt_mem_f <sig> { entry(<double> x <uptr<double>> ptr): y = LOAD PTR <double> ptr cond = FOGT <double> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_mem_f") zero = ctypes.c_double(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_mem_f, [ctypes.c_double, ctypes.c_voidp], ctypes.c_int64) assert (cmp_gt_zero(ctypes.c_double(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_double(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_double(-1), ptr) == 0)
def test_nest_loop(): lib = load_bundle( """ .funcdef nest_loop<(int<64>) -> (int<64>)> { entry(<int<64>> n): BRANCH outer_header(n <int<64>> 0 <int<64>> 0) outer_header(<int<64>> n <int<64>> i <int<64>> sum): outer_cond = SLT <int<64>> i n BRANCH2 outer_cond outer_body(n i sum) exit(sum) outer_body(<int<64>> n <int<64>> i <int<64>> sum): BRANCH inner_header(n i <int<64>> 0 sum) outer_step(<int<64>> n <int<64>> i <int<64>> sum): i2 = ADD <int<64>> i <int<64>> 1 BRANCH outer_header(n i2 sum) inner_header(<int<64>> n <int<64>> i <int<64>> j <int<64>> sum): inner_cond = SLT <int<64>> j i BRANCH2 inner_cond inner_body(n i j sum) outer_step(n i sum) inner_body(<int<64>> n <int<64>> i <int<64>> j <int<64>> sum): sum2 = ADD <int<64>> sum j j2 = ADD <int<64>> j <int<64>> 1 BRANCH inner_header(n i j2 sum2) exit(<int<64>> sum): RET sum } """, "nest_loop") nest_loop = get_function(lib.nest_loop, [ctypes.c_int64], ctypes.c_int64) assert (nest_loop(100) == 161700)
def test_gt_mem_r(): lib = load_bundle( """ .funcsig sig = (int<64> uptr<int<64>>) -> (int<64>) .funcdef test_gt_mem_r <sig> { entry(<int<64>> x <uptr<int<64>>> ptr): y = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_mem_r") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_mem_r, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (cmp_gt_zero(ctypes.c_int64(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_int64(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_int64(-1), ptr) == 0)
def test_gt_f_mem(): lib = load_bundle( """ .funcsig sig = (uptr<double> double) -> (int<64>) .funcdef test_gt_f_mem <sig> { entry(<uptr<double>> ptr <double> y): x = LOAD PTR <double> ptr cond = FOGT <double> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_f_mem") zero = ctypes.c_double(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_f_mem, [ctypes.c_voidp, ctypes.c_double], ctypes.c_int64) assert (cmp_gt_zero(ptr, ctypes.c_double(1)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_double(0)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_double(-1)) == 1)
def test_load(): lib = load_bundle( """ .funcdef load <(iref<weakref<void>>)->(ref<void>)> { entry(<iref<weakref<void>>>a): r = LOAD<weakref<void>> a RET r } """, "test_load")
def test_xor(): lib = load_bundle( """ .funcdef xor<(int<8>)->(int<8>)> { entry(<int<8>>v): r = XOR<int<8>> v <int<8>>1 RET r } """, "test_xor")
def test_from_ref_imm(): lib = load_bundle(""" .funcdef tr64_from_tag <(int<6>)->(tagref64)> { entry(<int<6>> tag): res = COMMINST uvm.tr64.from_ref(<ref<void>>NULL tag) RET res }""", "tr64_from_tag"); # type: ctypes.CDLL tr64_from_tag = get_function(lib.tr64_from_tag, [ctypes.c_uint8], ctypes.c_uint64); assert(tr64_from_tag(0x00) == 0x7ff0000000000002); assert(tr64_from_tag(0x3f) == 0x7fff800000000006);
def test_to_ref(): lib = load_bundle(""" .funcdef tr64_to_ref <(tagref64)->(ref<void>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_ref(tr) RET res } """, "tr64_to_ref"); # type: ctypes.CDLL tr64_to_ref = get_function(lib.tr64_to_ref, [ctypes.c_uint64], ctypes.c_void_p); assert(tr64_to_ref(0x7ff0555555555552) == 0x555555555550); assert(tr64_to_ref(0xfff02aaaaaaaaaaa) == 0xffffaaaaaaaaaaa8);
def test_is_ref(): lib = load_bundle(""" .funcdef tr64_is_ref <(tagref64)->(int<1>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.is_ref (tr) RET res } """, "tr64_is_ref"); # type: ctypes.CDLL tr64_is_ref = get_function(lib.tr64_is_ref, [ctypes.c_uint64], ctypes.c_bool); assert(tr64_is_ref(0x7ff0000000000002)); assert(tr64_is_ref(0xfff0000000000002)); assert(tr64_is_ref(0xfffffffffffffffe));
def test_div(): lib = load_bundle( """ .funcdef div<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = UDIV <int<64>> x y RET res } """, "div") div = get_function(lib.div, [ctypes.c_uint64], ctypes.c_uint64) assert (div(6, 2) == 3)
def test_div2(): lib = load_bundle( """ .funcdef div2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = UDIV <int<64>> x <int<64>> 2 RET res } """, "div2") div2 = get_function(lib.div2, [ctypes.c_uint64], ctypes.c_uint64) assert (div2(6) == 3)
def test_to_fp(): lib = load_bundle(""" .funcdef tr64_to_fp <(tagref64)->(double)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_fp(tr) RET res } """, "tr64_to_fp"); # type: ctypes.CDLL tr64_to_fp = get_function(lib.tr64_to_fp, [ctypes.c_uint64], ctypes.c_double); assert(tr64_to_fp(0x0000000000000000) == 0.0); assert(tr64_to_fp(0x8000000000000000) == -0.0); assert(tr64_to_fp(0x3ff0000000000000) == 1.0); assert(math.isnan(tr64_to_fp(0x7ff0000000000008)));
def test_to_int(): lib = load_bundle(""" .funcdef tr64_to_int <(tagref64)->(int<52>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_int(tr) RET res } """, "tr64_to_int"); # type: ctypes.CDLL tr64_to_int = get_function(lib.tr64_to_int, [ctypes.c_uint64], ctypes.c_uint64); assert(tr64_to_int(0x7ff0000000000001) == 0); assert(tr64_to_int(0xfff0000000000001) == 0x8000000000000); assert(tr64_to_int(0xfff5555555555555) == 0xaaaaaaaaaaaaa); assert(tr64_to_int(0x7ffaaaaaaaaaaaab) == 0x5555555555555);
def test_sdiv2(): lib = load_bundle( """ .funcdef sdiv2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = SDIV <int<64>> x <int<64>> 2 RET res } """, "sdiv2") sdiv2 = get_function(lib.sdiv2, [ctypes.c_int64], ctypes.c_int64) assert (sdiv2(ctypes.c_int64(6)) == 3) assert (sdiv2(ctypes.c_int64(-6)) == -3)
def test_to_tag(): lib = load_bundle(""" .funcdef tr64_to_tag <(tagref64)->(int<6>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_tag(tr) RET res } """, "tr64_to_tag"); # type: ctypes.CDLL tr64_to_tag = get_function(lib.tr64_to_tag, [ctypes.c_uint64], ctypes.c_uint8); assert(tr64_to_tag(0x7ff0555555555552) == 0); assert(tr64_to_tag(0x7fff800000000006) == 0x3f); assert(tr64_to_tag(0x7ffa800000000002) == 0x2a); assert(tr64_to_tag(0x7ff5000000000006) == 0x15);
def test_add(): lib = load_bundle( """ .funcdef test_add <(int<64> int<64>)->(int<64>)> { entry(<int<64>>a <int<64>>b): res = ADD <int<64>> a b RET res } """, "test_add") test_add = get_function(lib.test_add, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (test_add(1, 2) == 3) assert (test_add(-40, 60) == 20)
def test_mul2(): lib = load_bundle( """ .funcdef mul2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = MUL <int<64>> x <int<64>> 2 RET res } """, "mul2") mul2 = get_function(lib.mul2, [ctypes.c_int64], ctypes.c_int64) assert (mul2(3) == 6) assert (mul2(-3) == -6)
def test_from_ref(): lib = load_bundle(""" .funcdef tr64_from_ref <(ref<void> int<6>)->(tagref64)> { entry(<ref<void>>%ref <int<6>> tag): res = COMMINST uvm.tr64.from_ref(%ref tag) RET res } """, "tr64_from_ref"); # type: ctypes.CDLL tr64_from_ref = get_function(lib.tr64_from_ref, [ctypes.c_void_p, ctypes.c_uint8], ctypes.c_uint64); assert(tr64_from_ref(0x000000000000, 0x00) == 0x7ff0000000000002); assert(tr64_from_ref(0x7ffffffffff8, 0x00) == 0x7ff07ffffffffffa); assert(tr64_from_ref(0xfffffffffffffff8, 0x00) == 0xfff07ffffffffffa); assert(tr64_from_ref(0x000000000000, 0x3f) == 0x7fff800000000006);
def test_funcref(): lib = load_bundle( """ .funcdef triv<()->()> { entry(): RET } .funcdef ret_funcref <()->(funcref<()->()>)> { entry(): RET triv } """, "test_funcref")
def test_from_int(): lib = load_bundle(""" .funcdef tr64_from_int <(int<52>)->(tagref64)> { entry(<int<52>> val): res = COMMINST uvm.tr64.from_int(val) RET res } """, "tr64_from_int"); # type: ctypes.CDLL tr64_from_int = get_function(lib.tr64_from_int, [ctypes.c_uint64], ctypes.c_uint64); assert(tr64_from_int(0x0000000000000) == 0x7ff0000000000001); assert(tr64_from_int(0xfffffffffffff) == 0xffffffffffffffff); assert(tr64_from_int(0x5555555555555) == 0x7ffaaaaaaaaaaaab); assert(tr64_from_int(0xaaaaaaaaaaaaa) == 0xfff5555555555555);
def test_is_fp(): lib = load_bundle(""" .funcdef tr64_is_fp <(tagref64)->(int<1>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.is_fp(tr) RET res } """, "tr64_is_fp"); # type: ctypes.CDLL tr64_is_fp = get_function(lib.tr64_is_fp, [ctypes.c_uint64], ctypes.c_bool); assert(tr64_is_fp(0x0)); assert(tr64_is_fp(0x123456789abcdef0)); assert(tr64_is_fp(0x7ff123456789abcc)); assert(tr64_is_fp(0xfffffffffffffffc)); assert(tr64_is_fp(transmute_float_to_int(3.1415927)));
def test_from_fp(): lib = load_bundle(""" .funcdef tr64_from_fp <(double)->(tagref64)> { entry(<double> val): res = COMMINST uvm.tr64.from_fp(val) RET res } """, "tr64_from_fp"); # type: ctypes.CDLL tr64_from_fp = get_function(lib.tr64_from_fp, [ctypes.c_double], ctypes.c_uint64); assert(tr64_from_fp(3.14) == transmute_float_to_int(3.14)); assert(tr64_from_fp(-3.14) == transmute_float_to_int(-3.14)); assert(tr64_from_fp(float("inf")) == 0x7ff0000000000000); assert(tr64_from_fp(transmute_int_to_float(0x7ff123456789abcd)) == 0x7ff0000000000008); assert(math.isnan(transmute_int_to_float(tr64_from_fp(transmute_int_to_float(0x7ff123456789abcd)))));
def test_sdiv(): lib = load_bundle( """ .funcdef sdiv<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = SDIV <int<64>> x y RET res } """, "sdiv") sdiv = get_function(lib.sdiv, [ctypes.c_int64], ctypes.c_int64) assert (sdiv(ctypes.c_int64(6), ctypes.c_int64(2)) == 3) assert (sdiv(ctypes.c_int64(-6), ctypes.c_int64(2)) == -3) assert (sdiv(ctypes.c_int64(6), ctypes.c_int64(-2)) == -3) assert (sdiv(ctypes.c_int64(-6), ctypes.c_int64(-2)) == 3)
def test_mul(): lib = load_bundle( """ .funcdef mul<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = MUL <int<64>> x y RET res } """, "mul") mul = get_function(lib.mul, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (mul(3, 2) == 6) assert (mul(-3, 2) == -6) assert (mul(-3, -2) == 6)
def test_eq_f_zero(): lib = load_bundle( """ .funcsig sig = (double) -> (int<8>) .funcdef test_eq_f_zero <sig> { entry(<double> x): cond = FOEQ <double> x <double> 0.00 d res = ZEXT <int<1> int<8>> cond RET res } """, "test_eq_f_zero") eq_zero = get_function(lib.test_eq_f_zero, [ctypes.c_double], ctypes.c_int8) assert (eq_zero(ctypes.c_double(0)) == 1) assert (eq_zero(ctypes.c_double(1)) == 0) assert (eq_zero(ctypes.c_double(-1)) == 0)
def test_double_inline(): lib = load_bundle( """ .funcsig new_sig = ()->(ref<void>) .funcdef new_void <new_sig> { entry(): //res = NEW <ref<void>> res = CCALL #DEFAULT <ufuncptr<new_sig> new_sig> <ufuncptr<new_sig>>EXTERN "malloc"() RET res } .funcdef double_inline <()->(ref<void> ref<void>)> { entry(): a = CALL <()->(ref<void>)> new_void() b = CALL <()->(ref<void>)> new_void() RET (a b) } """, "test_double_inline")
def test_gt_val_mem_r(): lib = load_bundle( """ .funcsig sig = (int<64> uptr<int<64>>) -> (int<8>) .funcdef test_gt_val_mem_r <sig> { entry(<int<64>> x <uptr<int<64>>> ptr): y = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y res = ZEXT <int<1> int<8>> cond RET res } """, "test_gt_val_mem_r") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_val_mem_r, [ctypes.c_int64, ctypes.c_voidp], ctypes.c_int8) assert (cmp_gt_zero(ctypes.c_int64(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_int64(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_int64(-1), ptr) == 0)
def test_cmp_pattern2(): lib = load_bundle( """ .funcdef test_cmp_pattern2 <(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): cond = EQ <int<64>> x y sum = ADD <int<64>> x y BRANCH2 cond ret_true(sum) ret_false(sum) ret_true(<int<64>> sum): RET <int<64>> 1 ret_false(<int<64>> sum): RET <int<64>> 0 } """, "test_cmp_pattern2") eq = get_function(lib.test_cmp_pattern2, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (eq(1, 1) == 1) assert (eq(1, 0) == 0)
def test_stack_args(): lib = load_bundle( """ .funcsig stack_sig = (double double double double double double double double double double)->(int<32>) .funcdef test_stack_args <stack_sig> { entry(<double>d0 <double>d1 <double>d2 <double>d3 <double>d4 <double>d5 <double>d6 <double>d7 <double> d8 <double> d9): ds0 = FMUL <double> d0 <double>0.0 d ds1 = FMUL <double> d1 <double>1.0 d ds2 = FMUL <double> d2 <double>2.0 d ds3 = FMUL <double> d3 <double>3.0 d ds4 = FMUL <double> d4 <double>4.0 d ds5 = FMUL <double> d5 <double>5.0 d ds6 = FMUL <double> d6 <double>6.0 d ds7 = FMUL <double> d7 <double>7.0 d ds8 = FMUL <double> d8 <double>8.0 d ds9 = FMUL <double> d9 <double>9.0 d s1 = FADD <double> ds0 ds1 s2 = FADD <double> s1 ds2 s3 = FADD <double> s2 ds3 s4 = FADD <double> s3 ds4 s5 = FADD <double> s4 ds5 s6 = FADD <double> s5 ds6 s7 = FADD <double> s6 ds7 s8 = FADD <double> s7 ds8 s9 = FADD <double> s8 ds9 r = FPTOSI <double int<32>> s9 RET r } """, "test_stack_args") test_stack_args = get_function(lib.test_stack_args, [ ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double ], ctypes.c_int32) args = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] assert (test_stack_args(*tuple(args)) == sum(map((lambda x: x**2), args)))