comparison libinterp/corefcn/jit-typeinfo.cc @ 18561:7a6da3d7e3f9 draft

Fully uint8 type support
author LYH <lyh.kernel@gmail.com>
date Fri, 27 Sep 2013 05:44:07 +0800
parents fd138c51ca25
children 2204a9a252c0
comparison
equal deleted inserted replaced
18560:fd138c51ca25 18561:7a6da3d7e3f9
71 #include "ov-float.h" 71 #include "ov-float.h"
72 #include "ov-int8.h" 72 #include "ov-int8.h"
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-uint16.h" 77 #include "ov-uint16.h"
77 #include "pager.h" 78 #include "pager.h"
78 79
79 static llvm::LLVMContext& context = llvm::getGlobalContext (); 80 static llvm::LLVMContext& context = llvm::getGlobalContext ();
80 81
264 265
265 extern "C" octave_base_value * 266 extern "C" octave_base_value *
266 octave_jit_cast_any_int64 (int64_t value) 267 octave_jit_cast_any_int64 (int64_t value)
267 { 268 {
268 return new octave_int64_scalar (value); 269 return new octave_int64_scalar (value);
270 }
271
272 extern "C" uint8_t
273 octave_jit_cast_uint8_any (octave_base_value *obv)
274 {
275 uint8_t ret = obv->uint8_scalar_value ();
276 obv->release ();
277 return ret;
278 }
279
280 extern "C" octave_base_value *
281 octave_jit_cast_any_uint8 (uint8_t value)
282 {
283 return new octave_uint8_scalar (value);
269 } 284 }
270 285
271 extern "C" uint16_t 286 extern "C" uint16_t
272 octave_jit_cast_uint16_any (octave_base_value *obv) 287 octave_jit_cast_uint16_any (octave_base_value *obv)
273 { 288 {
861 return octave_jit_sub_int64_int64 (val, 1); 876 return octave_jit_sub_int64_int64 (val, 1);
862 } 877 }
863 878
864 /************************************************************ 879 /************************************************************
865 * 880 *
881 * uint8 related external helper function
882 *
883 ************************************************************/
884
885 extern "C" uint8_t
886 octave_jit_add_uint8_uint8 (uint8_t lhs, uint8_t rhs)
887 {
888 uint8_t res = lhs + rhs;
889 res |= -(res < lhs);
890
891 return res;
892 }
893
894 extern "C" uint8_t
895 octave_jit_sub_uint8_uint8 (uint8_t lhs, uint8_t rhs)
896 {
897 uint8_t res = lhs - rhs;
898 res &= -(res <= lhs);
899
900 return res;
901 }
902
903 extern "C" uint8_t
904 octave_jit_mul_uint8_uint8 (uint8_t lhs, uint8_t rhs)
905 {
906 uint16_t res = (uint16_t) lhs * (uint16_t) rhs;
907
908 uint8_t hi = res >> 8;
909 uint8_t lo = res;
910
911 return lo | -!!hi;
912 }
913
914 extern "C" uint8_t
915 octave_jit_incr_uint8 (uint8_t val)
916 {
917 return octave_jit_add_uint8_uint8 (val, 1);
918 }
919
920 extern "C" uint8_t
921 octave_jit_decr_uint8 (uint8_t val)
922 {
923 return octave_jit_sub_uint8_uint8 (val, 1);
924 }
925
926 /************************************************************
927 *
866 * uint16 related external helper function 928 * uint16 related external helper function
867 * 929 *
868 ************************************************************/ 930 ************************************************************/
869 931
870 extern "C" uint16_t 932 extern "C" uint16_t
1535 llvm::Type *single_t = llvm::Type::getFloatTy (context); 1597 llvm::Type *single_t = llvm::Type::getFloatTy (context);
1536 llvm::Type *int8__t = llvm::Type::getIntNTy (context, 8); 1598 llvm::Type *int8__t = llvm::Type::getIntNTy (context, 8);
1537 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); 1599 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16);
1538 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); 1600 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32);
1539 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); 1601 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64);
1602 llvm::Type *uint8__t = llvm::Type::getIntNTy (context, 8);
1540 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); 1603 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16);
1541 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); 1604 llvm::Type *bool_t = llvm::Type::getInt1Ty (context);
1542 llvm::Type *string_t = llvm::Type::getInt8Ty (context); 1605 llvm::Type *string_t = llvm::Type::getInt8Ty (context);
1543 string_t = string_t->getPointerTo (); 1606 string_t = string_t->getPointerTo ();
1544 llvm::Type *index_t = llvm::Type::getIntNTy (context, 1607 llvm::Type *index_t = llvm::Type::getIntNTy (context,
1589 create_int (8); 1652 create_int (8);
1590 create_int (16); 1653 create_int (16);
1591 create_int (32); 1654 create_int (32);
1592 create_int (64); 1655 create_int (64);
1593 1656
1657 create_uint (8);
1594 create_uint (16); 1658 create_uint (16);
1595 1659
1596 casts.resize (next_id + 1); 1660 casts.resize (next_id + 1);
1597 identities.resize (next_id + 1); 1661 identities.resize (next_id + 1);
1598 1662
1688 grab_fn.add_overload (create_identity (single)); 1752 grab_fn.add_overload (create_identity (single));
1689 grab_fn.add_overload (create_identity (intN (8))); 1753 grab_fn.add_overload (create_identity (intN (8)));
1690 grab_fn.add_overload (create_identity (intN (16))); 1754 grab_fn.add_overload (create_identity (intN (16)));
1691 grab_fn.add_overload (create_identity (intN (32))); 1755 grab_fn.add_overload (create_identity (intN (32)));
1692 grab_fn.add_overload (create_identity (intN (64))); 1756 grab_fn.add_overload (create_identity (intN (64)));
1757 grab_fn.add_overload (create_identity (uintN (8)));
1693 grab_fn.add_overload (create_identity (uintN (16))); 1758 grab_fn.add_overload (create_identity (uintN (16)));
1694 grab_fn.add_overload (create_identity (scalar_ptr)); 1759 grab_fn.add_overload (create_identity (scalar_ptr));
1695 grab_fn.add_overload (create_identity (any_ptr)); 1760 grab_fn.add_overload (create_identity (any_ptr));
1696 grab_fn.add_overload (create_identity (boolean)); 1761 grab_fn.add_overload (create_identity (boolean));
1697 grab_fn.add_overload (create_identity (complex)); 1762 grab_fn.add_overload (create_identity (complex));
1713 destroy_fn.add_overload (create_identity(single)); 1778 destroy_fn.add_overload (create_identity(single));
1714 destroy_fn.add_overload (create_identity(intN (8))); 1779 destroy_fn.add_overload (create_identity(intN (8)));
1715 destroy_fn.add_overload (create_identity(intN (16))); 1780 destroy_fn.add_overload (create_identity(intN (16)));
1716 destroy_fn.add_overload (create_identity(intN (32))); 1781 destroy_fn.add_overload (create_identity(intN (32)));
1717 destroy_fn.add_overload (create_identity(intN (64))); 1782 destroy_fn.add_overload (create_identity(intN (64)));
1783 destroy_fn.add_overload (create_identity(uintN (8)));
1718 destroy_fn.add_overload (create_identity(uintN (16))); 1784 destroy_fn.add_overload (create_identity(uintN (16)));
1719 destroy_fn.add_overload (create_identity(boolean)); 1785 destroy_fn.add_overload (create_identity(boolean));
1720 destroy_fn.add_overload (create_identity(index)); 1786 destroy_fn.add_overload (create_identity(index));
1721 destroy_fn.add_overload (create_identity(complex)); 1787 destroy_fn.add_overload (create_identity(complex));
1722 1788
2190 unary_ops[octave_value::op_transpose].add_overload (fn); 2256 unary_ops[octave_value::op_transpose].add_overload (fn);
2191 unary_ops[octave_value::op_hermitian].add_overload (fn); 2257 unary_ops[octave_value::op_hermitian].add_overload (fn);
2192 2258
2193 /************************************************************ 2259 /************************************************************
2194 * 2260 *
2261 * uint8 related operations
2262 *
2263 ************************************************************/
2264
2265 // now for binary uint8 operations
2266 fn = create_external (JIT_FN (octave_jit_add_uint8_uint8), uintN (8), uintN (8),
2267 uintN (8));
2268 binary_ops[octave_value::op_add].add_overload (fn);
2269 fn = create_external (JIT_FN (octave_jit_sub_uint8_uint8), uintN (8), uintN (8),
2270 uintN (8));
2271 binary_ops[octave_value::op_sub].add_overload (fn);
2272 fn = create_external (JIT_FN (octave_jit_mul_uint8_uint8), uintN (8), uintN (8),
2273 uintN (8));
2274 binary_ops[octave_value::op_mul].add_overload (fn);
2275 binary_ops[octave_value::op_el_mul].add_overload (fn);
2276
2277 add_binary_icmp (uintN (8), octave_value::op_lt, llvm::CmpInst::ICMP_ULT);
2278 add_binary_icmp (uintN (8), octave_value::op_le, llvm::CmpInst::ICMP_ULE);
2279 add_binary_icmp (uintN (8), octave_value::op_eq, llvm::CmpInst::ICMP_EQ);
2280 add_binary_icmp (uintN (8), octave_value::op_ge, llvm::CmpInst::ICMP_UGE);
2281 add_binary_icmp (uintN (8), octave_value::op_gt, llvm::CmpInst::ICMP_UGT);
2282 add_binary_icmp (uintN (8), octave_value::op_ne, llvm::CmpInst::ICMP_NE);
2283
2284 // FIXME: saturation divide definition? interpreter convert uint to double, calculate and round.
2285 // divide is annoying because it might error
2286 // FIXME: Implement div
2287
2288 // FIXME: Implement pow
2289
2290 // now for unary uint8 operations
2291 // FIXME: Impelment not
2292 fn = create_external (JIT_FN (octave_jit_incr_uint8), uintN (8), uintN (8));
2293 unary_ops[octave_value::op_incr].add_overload (fn);
2294
2295 fn = create_external (JIT_FN (octave_jit_decr_uint8), uintN (8), uintN (8));
2296 unary_ops[octave_value::op_decr].add_overload (fn);
2297
2298 fn = create_internal ("octave_jit_uminus", uintN (8), uintN (8));
2299 body = fn.new_block ();
2300 builder.SetInsertPoint (body);
2301 {
2302 llvm::Value *zero = llvm::ConstantInt::get (uint8__t, 0);
2303
2304 fn.do_return (builder, zero);
2305 }
2306 unary_ops[octave_value::op_uminus].add_overload (fn);
2307
2308 fn = create_identity (uintN (8));
2309 unary_ops[octave_value::op_uplus].add_overload (fn);
2310 unary_ops[octave_value::op_transpose].add_overload (fn);
2311 unary_ops[octave_value::op_hermitian].add_overload (fn);
2312
2313 /************************************************************
2314 *
2195 * uint16 related operations 2315 * uint16 related operations
2196 * 2316 *
2197 ************************************************************/ 2317 ************************************************************/
2198 2318
2199 // now for binary uint16 operations 2319 // now for binary uint16 operations
2653 casts[single->type_id ()].stash_name ("(single)"); 2773 casts[single->type_id ()].stash_name ("(single)");
2654 casts[intN (8)->type_id ()].stash_name ("(int8)"); 2774 casts[intN (8)->type_id ()].stash_name ("(int8)");
2655 casts[intN (16)->type_id ()].stash_name ("(int16)"); 2775 casts[intN (16)->type_id ()].stash_name ("(int16)");
2656 casts[intN (32)->type_id ()].stash_name ("(int32)"); 2776 casts[intN (32)->type_id ()].stash_name ("(int32)");
2657 casts[intN (64)->type_id ()].stash_name ("(int64)"); 2777 casts[intN (64)->type_id ()].stash_name ("(int64)");
2778 casts[uintN (8)->type_id ()].stash_name ("(uint8)");
2658 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); 2779 casts[uintN (16)->type_id ()].stash_name ("(uint16)");
2659 casts[complex->type_id ()].stash_name ("(complex)"); 2780 casts[complex->type_id ()].stash_name ("(complex)");
2660 casts[matrix->type_id ()].stash_name ("(matrix)"); 2781 casts[matrix->type_id ()].stash_name ("(matrix)");
2661 casts[range->type_id ()].stash_name ("(range)"); 2782 casts[range->type_id ()].stash_name ("(range)");
2662 2783
2721 casts[any->type_id ()].add_overload (fn); 2842 casts[any->type_id ()].add_overload (fn);
2722 2843
2723 // cast int64 <- any 2844 // cast int64 <- any
2724 fn = create_external (JIT_FN (octave_jit_cast_int64_any), intN (64), any); 2845 fn = create_external (JIT_FN (octave_jit_cast_int64_any), intN (64), any);
2725 casts[intN (64)->type_id ()].add_overload (fn); 2846 casts[intN (64)->type_id ()].add_overload (fn);
2847
2848 // cast any <- uint8
2849 fn = create_external (JIT_FN (octave_jit_cast_any_uint8), any, uintN (8));
2850 casts[any->type_id ()].add_overload (fn);
2851
2852 // cast uint8 <- any
2853 fn = create_external (JIT_FN (octave_jit_cast_uint8_any), uintN (8), any);
2854 casts[uintN (8)->type_id ()].add_overload (fn);
2726 2855
2727 // cast any <- uint16 2856 // cast any <- uint16
2728 fn = create_external (JIT_FN (octave_jit_cast_any_uint16), any, uintN (16)); 2857 fn = create_external (JIT_FN (octave_jit_cast_any_uint16), any, uintN (16));
2729 casts[any->type_id ()].add_overload (fn); 2858 casts[any->type_id ()].add_overload (fn);
2730 2859
2782 casts[intN (32)->type_id ()].add_overload (fn); 2911 casts[intN (32)->type_id ()].add_overload (fn);
2783 2912
2784 // cast int64 <- int64 2913 // cast int64 <- int64
2785 fn = create_identity (intN (64)); 2914 fn = create_identity (intN (64));
2786 casts[intN (64)->type_id ()].add_overload (fn); 2915 casts[intN (64)->type_id ()].add_overload (fn);
2916
2917 // cast uint8 <- uint8
2918 fn = create_identity (uintN (8));
2919 casts[uintN (8)->type_id ()].add_overload (fn);
2787 2920
2788 // cast uint16 <- uint16 2921 // cast uint16 <- uint16
2789 fn = create_identity (uintN (16)); 2922 fn = create_identity (uintN (16));
2790 casts[uintN (16)->type_id ()].add_overload (fn); 2923 casts[uintN (16)->type_id ()].add_overload (fn);
2791 2924
3265 if (ov.is_int64_type()) 3398 if (ov.is_int64_type())
3266 { 3399 {
3267 return intN (64); 3400 return intN (64);
3268 } 3401 }
3269 3402
3403 if (ov.is_uint8_type())
3404 {
3405 return uintN (8);
3406 }
3407
3270 if (ov.is_uint16_type()) 3408 if (ov.is_uint16_type())
3271 { 3409 {
3272 return uintN (16); 3410 return uintN (16);
3273 } 3411 }
3274 3412