Mercurial > octave-nkf
comparison libinterp/corefcn/jit-typeinfo.cc @ 18562:2204a9a252c0 draft
jit compiler: Add support for uint64 type
* libinter/corefcn/pt-jit.cc: Add basic operations, casts and overloads
author | LYH <lyh.kernel@gmail.com> |
---|---|
date | Sat, 02 Nov 2013 17:14:07 +0100 |
parents | 7a6da3d7e3f9 |
children | d464edd2552b |
comparison
equal
deleted
inserted
replaced
18561:7a6da3d7e3f9 | 18562:2204a9a252c0 |
---|---|
73 #include "ov-int16.h" | 73 #include "ov-int16.h" |
74 #include "ov-int32.h" | 74 #include "ov-int32.h" |
75 #include "ov-int64.h" | 75 #include "ov-int64.h" |
76 #include "ov-uint8.h" | 76 #include "ov-uint8.h" |
77 #include "ov-uint16.h" | 77 #include "ov-uint16.h" |
78 #include "ov-uint64.h" | |
78 #include "pager.h" | 79 #include "pager.h" |
79 | 80 |
80 static llvm::LLVMContext& context = llvm::getGlobalContext (); | 81 static llvm::LLVMContext& context = llvm::getGlobalContext (); |
81 | 82 |
82 jit_typeinfo *jit_typeinfo::instance = 0; | 83 jit_typeinfo *jit_typeinfo::instance = 0; |
293 | 294 |
294 extern "C" octave_base_value * | 295 extern "C" octave_base_value * |
295 octave_jit_cast_any_uint16 (uint16_t value) | 296 octave_jit_cast_any_uint16 (uint16_t value) |
296 { | 297 { |
297 return new octave_uint16_scalar (value); | 298 return new octave_uint16_scalar (value); |
299 } | |
300 | |
301 extern "C" uint64_t | |
302 octave_jit_cast_uint64_any (octave_base_value *obv) | |
303 { | |
304 uint64_t ret = obv->uint64_scalar_value (); | |
305 obv->release (); | |
306 return ret; | |
307 } | |
308 | |
309 extern "C" octave_base_value * | |
310 octave_jit_cast_any_uint64 (uint64_t value) | |
311 { | |
312 return new octave_uint64_scalar (value); | |
298 } | 313 } |
299 | 314 |
300 extern "C" Complex | 315 extern "C" Complex |
301 octave_jit_cast_complex_any (octave_base_value *obv) | 316 octave_jit_cast_complex_any (octave_base_value *obv) |
302 { | 317 { |
968 octave_jit_decr_uint16 (uint16_t val) | 983 octave_jit_decr_uint16 (uint16_t val) |
969 { | 984 { |
970 return octave_jit_sub_uint16_uint16 (val, 1); | 985 return octave_jit_sub_uint16_uint16 (val, 1); |
971 } | 986 } |
972 | 987 |
988 /************************************************************ | |
989 * | |
990 * uint64 related external helper function | |
991 * | |
992 ************************************************************/ | |
993 | |
994 extern "C" uint64_t | |
995 octave_jit_add_uint64_uint64 (uint64_t lhs, uint64_t rhs) | |
996 { | |
997 uint64_t res = lhs + rhs; | |
998 res |= -(res < lhs); | |
999 | |
1000 return res; | |
1001 } | |
1002 | |
1003 extern "C" uint64_t | |
1004 octave_jit_sub_uint64_uint64 (uint64_t lhs, uint64_t rhs) | |
1005 { | |
1006 uint64_t res = lhs - rhs; | |
1007 res &= -(res <= lhs); | |
1008 | |
1009 return res; | |
1010 } | |
1011 | |
1012 extern "C" uint64_t | |
1013 octave_jit_mul_uint64_uint64 (uint64_t lhs, uint64_t rhs) | |
1014 { | |
1015 #ifdef OCTAVE_INT_USE_LONG_DOUBLE | |
1016 long double p = static_cast<long double> (lhs) * static_cast<long double> (rhs); | |
1017 if (p > static_cast<long double> (std::numeric_limits<uint64_t>::max ())) | |
1018 { | |
1019 return std::numeric_limits<uint64_t>::max (); | |
1020 } | |
1021 else | |
1022 return static_cast<uint64_t> (p); | |
1023 #else | |
1024 __uint128_t res = (__uint128_t) lhs * (__uint128_t) rhs; | |
1025 | |
1026 uint64_t hi = res >> 64; | |
1027 uint64_t lo = res; | |
1028 | |
1029 return lo | -!!hi; | |
1030 #endif | |
1031 } | |
1032 | |
1033 extern "C" uint64_t | |
1034 octave_jit_incr_uint64 (uint64_t val) | |
1035 { | |
1036 return octave_jit_add_uint64_uint64 (val, 1); | |
1037 } | |
1038 | |
1039 extern "C" uint64_t | |
1040 octave_jit_decr_uint64 (uint64_t val) | |
1041 { | |
1042 return octave_jit_sub_uint64_uint64 (val, 1); | |
1043 } | |
1044 | |
973 extern "C" void | 1045 extern "C" void |
974 octave_jit_print_matrix (jit_matrix *m) | 1046 octave_jit_print_matrix (jit_matrix *m) |
975 { | 1047 { |
976 std::cout << *m << std::endl; | 1048 std::cout << *m << std::endl; |
977 } | 1049 } |
1599 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); | 1671 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); |
1600 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); | 1672 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); |
1601 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); | 1673 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); |
1602 llvm::Type *uint8__t = llvm::Type::getIntNTy (context, 8); | 1674 llvm::Type *uint8__t = llvm::Type::getIntNTy (context, 8); |
1603 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); | 1675 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); |
1676 llvm::Type *uint64__t = llvm::Type::getIntNTy (context, 64); | |
1604 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); | 1677 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); |
1605 llvm::Type *string_t = llvm::Type::getInt8Ty (context); | 1678 llvm::Type *string_t = llvm::Type::getInt8Ty (context); |
1606 string_t = string_t->getPointerTo (); | 1679 string_t = string_t->getPointerTo (); |
1607 llvm::Type *index_t = llvm::Type::getIntNTy (context, | 1680 llvm::Type *index_t = llvm::Type::getIntNTy (context, |
1608 sizeof(octave_idx_type) * 8); | 1681 sizeof(octave_idx_type) * 8); |
1654 create_int (32); | 1727 create_int (32); |
1655 create_int (64); | 1728 create_int (64); |
1656 | 1729 |
1657 create_uint (8); | 1730 create_uint (8); |
1658 create_uint (16); | 1731 create_uint (16); |
1732 create_uint (64); | |
1659 | 1733 |
1660 casts.resize (next_id + 1); | 1734 casts.resize (next_id + 1); |
1661 identities.resize (next_id + 1); | 1735 identities.resize (next_id + 1); |
1662 | 1736 |
1663 // specify calling conventions | 1737 // specify calling conventions |
1754 grab_fn.add_overload (create_identity (intN (16))); | 1828 grab_fn.add_overload (create_identity (intN (16))); |
1755 grab_fn.add_overload (create_identity (intN (32))); | 1829 grab_fn.add_overload (create_identity (intN (32))); |
1756 grab_fn.add_overload (create_identity (intN (64))); | 1830 grab_fn.add_overload (create_identity (intN (64))); |
1757 grab_fn.add_overload (create_identity (uintN (8))); | 1831 grab_fn.add_overload (create_identity (uintN (8))); |
1758 grab_fn.add_overload (create_identity (uintN (16))); | 1832 grab_fn.add_overload (create_identity (uintN (16))); |
1833 grab_fn.add_overload (create_identity (uintN (64))); | |
1759 grab_fn.add_overload (create_identity (scalar_ptr)); | 1834 grab_fn.add_overload (create_identity (scalar_ptr)); |
1760 grab_fn.add_overload (create_identity (any_ptr)); | 1835 grab_fn.add_overload (create_identity (any_ptr)); |
1761 grab_fn.add_overload (create_identity (boolean)); | 1836 grab_fn.add_overload (create_identity (boolean)); |
1762 grab_fn.add_overload (create_identity (complex)); | 1837 grab_fn.add_overload (create_identity (complex)); |
1763 grab_fn.add_overload (create_identity (index)); | 1838 grab_fn.add_overload (create_identity (index)); |
1780 destroy_fn.add_overload (create_identity(intN (16))); | 1855 destroy_fn.add_overload (create_identity(intN (16))); |
1781 destroy_fn.add_overload (create_identity(intN (32))); | 1856 destroy_fn.add_overload (create_identity(intN (32))); |
1782 destroy_fn.add_overload (create_identity(intN (64))); | 1857 destroy_fn.add_overload (create_identity(intN (64))); |
1783 destroy_fn.add_overload (create_identity(uintN (8))); | 1858 destroy_fn.add_overload (create_identity(uintN (8))); |
1784 destroy_fn.add_overload (create_identity(uintN (16))); | 1859 destroy_fn.add_overload (create_identity(uintN (16))); |
1860 destroy_fn.add_overload (create_identity(uintN (64))); | |
1785 destroy_fn.add_overload (create_identity(boolean)); | 1861 destroy_fn.add_overload (create_identity(boolean)); |
1786 destroy_fn.add_overload (create_identity(index)); | 1862 destroy_fn.add_overload (create_identity(index)); |
1787 destroy_fn.add_overload (create_identity(complex)); | 1863 destroy_fn.add_overload (create_identity(complex)); |
1788 | 1864 |
1789 // -------------------- scalar related operations -------------------- | 1865 // -------------------- scalar related operations -------------------- |
2392 fn = create_identity (uintN (16)); | 2468 fn = create_identity (uintN (16)); |
2393 unary_ops[octave_value::op_uplus].add_overload (fn); | 2469 unary_ops[octave_value::op_uplus].add_overload (fn); |
2394 unary_ops[octave_value::op_transpose].add_overload (fn); | 2470 unary_ops[octave_value::op_transpose].add_overload (fn); |
2395 unary_ops[octave_value::op_hermitian].add_overload (fn); | 2471 unary_ops[octave_value::op_hermitian].add_overload (fn); |
2396 | 2472 |
2473 /************************************************************ | |
2474 * | |
2475 * uint64 related operations | |
2476 * | |
2477 ************************************************************/ | |
2478 | |
2479 // now for binary uint64 operations | |
2480 fn = create_external (JIT_FN (octave_jit_add_uint64_uint64), uintN (64), uintN (64), | |
2481 uintN (64)); | |
2482 binary_ops[octave_value::op_add].add_overload (fn); | |
2483 fn = create_external (JIT_FN (octave_jit_sub_uint64_uint64), uintN (64), uintN (64), | |
2484 uintN (64)); | |
2485 binary_ops[octave_value::op_sub].add_overload (fn); | |
2486 fn = create_external (JIT_FN (octave_jit_mul_uint64_uint64), uintN (64), uintN (64), | |
2487 uintN (64)); | |
2488 binary_ops[octave_value::op_mul].add_overload (fn); | |
2489 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2490 | |
2491 add_binary_icmp (uintN (64), octave_value::op_lt, llvm::CmpInst::ICMP_ULT); | |
2492 add_binary_icmp (uintN (64), octave_value::op_le, llvm::CmpInst::ICMP_ULE); | |
2493 add_binary_icmp (uintN (64), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2494 add_binary_icmp (uintN (64), octave_value::op_ge, llvm::CmpInst::ICMP_UGE); | |
2495 add_binary_icmp (uintN (64), octave_value::op_gt, llvm::CmpInst::ICMP_UGT); | |
2496 add_binary_icmp (uintN (64), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2497 | |
2498 // FIXME: saturation divide definition? interpreter convert uint to double, calculate and round. | |
2499 // divide is annoying because it might error | |
2500 // FIXME: Implement div | |
2501 | |
2502 // FIXME: Implement pow | |
2503 | |
2504 // now for unary uint8 operations | |
2505 // FIXME: Impelment not | |
2506 fn = create_external (JIT_FN (octave_jit_incr_uint64), uintN (64), uintN (64)); | |
2507 unary_ops[octave_value::op_incr].add_overload (fn); | |
2508 | |
2509 fn = create_external (JIT_FN (octave_jit_decr_uint64), uintN (64), uintN (64)); | |
2510 unary_ops[octave_value::op_decr].add_overload (fn); | |
2511 | |
2512 fn = create_internal ("octave_jit_uminus", uintN (64), uintN (64)); | |
2513 body = fn.new_block (); | |
2514 builder.SetInsertPoint (body); | |
2515 { | |
2516 llvm::Value *zero = llvm::ConstantInt::get (uint64__t, 0); | |
2517 | |
2518 fn.do_return (builder, zero); | |
2519 } | |
2520 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2521 | |
2522 fn = create_identity (uintN (64)); | |
2523 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2524 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2525 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2526 | |
2397 fn = create_internal ("octave_jit_*_scalar_complex", complex, scalar, | 2527 fn = create_internal ("octave_jit_*_scalar_complex", complex, scalar, |
2398 complex); | 2528 complex); |
2399 jit_function mul_scalar_complex = fn; | 2529 jit_function mul_scalar_complex = fn; |
2400 body = fn.new_block (); | 2530 body = fn.new_block (); |
2401 builder.SetInsertPoint (body); | 2531 builder.SetInsertPoint (body); |
2775 casts[intN (16)->type_id ()].stash_name ("(int16)"); | 2905 casts[intN (16)->type_id ()].stash_name ("(int16)"); |
2776 casts[intN (32)->type_id ()].stash_name ("(int32)"); | 2906 casts[intN (32)->type_id ()].stash_name ("(int32)"); |
2777 casts[intN (64)->type_id ()].stash_name ("(int64)"); | 2907 casts[intN (64)->type_id ()].stash_name ("(int64)"); |
2778 casts[uintN (8)->type_id ()].stash_name ("(uint8)"); | 2908 casts[uintN (8)->type_id ()].stash_name ("(uint8)"); |
2779 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); | 2909 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); |
2910 casts[uintN (64)->type_id ()].stash_name ("(uint64)"); | |
2780 casts[complex->type_id ()].stash_name ("(complex)"); | 2911 casts[complex->type_id ()].stash_name ("(complex)"); |
2781 casts[matrix->type_id ()].stash_name ("(matrix)"); | 2912 casts[matrix->type_id ()].stash_name ("(matrix)"); |
2782 casts[range->type_id ()].stash_name ("(range)"); | 2913 casts[range->type_id ()].stash_name ("(range)"); |
2783 | 2914 |
2784 // cast any <- matrix | 2915 // cast any <- matrix |
2858 casts[any->type_id ()].add_overload (fn); | 2989 casts[any->type_id ()].add_overload (fn); |
2859 | 2990 |
2860 // cast uint16 <- any | 2991 // cast uint16 <- any |
2861 fn = create_external (JIT_FN (octave_jit_cast_uint16_any), uintN (16), any); | 2992 fn = create_external (JIT_FN (octave_jit_cast_uint16_any), uintN (16), any); |
2862 casts[uintN (16)->type_id ()].add_overload (fn); | 2993 casts[uintN (16)->type_id ()].add_overload (fn); |
2994 | |
2995 // cast any <- uint64 | |
2996 fn = create_external (JIT_FN (octave_jit_cast_any_uint64), any, uintN (64)); | |
2997 casts[any->type_id ()].add_overload (fn); | |
2998 | |
2999 // cast uint64 <- any | |
3000 fn = create_external (JIT_FN (octave_jit_cast_uint64_any), uintN (64), any); | |
3001 casts[uintN (64)->type_id ()].add_overload (fn); | |
2863 | 3002 |
2864 // cast any <- complex | 3003 // cast any <- complex |
2865 fn = create_external (JIT_FN (octave_jit_cast_any_complex), any, complex); | 3004 fn = create_external (JIT_FN (octave_jit_cast_any_complex), any, complex); |
2866 casts[any->type_id ()].add_overload (fn); | 3005 casts[any->type_id ()].add_overload (fn); |
2867 | 3006 |
2919 casts[uintN (8)->type_id ()].add_overload (fn); | 3058 casts[uintN (8)->type_id ()].add_overload (fn); |
2920 | 3059 |
2921 // cast uint16 <- uint16 | 3060 // cast uint16 <- uint16 |
2922 fn = create_identity (uintN (16)); | 3061 fn = create_identity (uintN (16)); |
2923 casts[uintN (16)->type_id ()].add_overload (fn); | 3062 casts[uintN (16)->type_id ()].add_overload (fn); |
3063 | |
3064 // cast uint64 <- uint64 | |
3065 fn = create_identity (uintN (64)); | |
3066 casts[uintN (64)->type_id ()].add_overload (fn); | |
2924 | 3067 |
2925 // cast complex <- complex | 3068 // cast complex <- complex |
2926 fn = create_identity (complex); | 3069 fn = create_identity (complex); |
2927 casts[complex->type_id ()].add_overload (fn); | 3070 casts[complex->type_id ()].add_overload (fn); |
2928 | 3071 |
3408 if (ov.is_uint16_type()) | 3551 if (ov.is_uint16_type()) |
3409 { | 3552 { |
3410 return uintN (16); | 3553 return uintN (16); |
3411 } | 3554 } |
3412 | 3555 |
3556 if (ov.is_uint64_type()) | |
3557 { | |
3558 return uintN (64); | |
3559 } | |
3560 | |
3413 if (ov.is_complex_scalar ()) | 3561 if (ov.is_complex_scalar ()) |
3414 { | 3562 { |
3415 Complex cv = ov.complex_value (); | 3563 Complex cv = ov.complex_value (); |
3416 | 3564 |
3417 // We don't really represent complex values, instead we represent | 3565 // We don't really represent complex values, instead we represent |