Mercurial > octave-nkf
comparison libinterp/corefcn/jit-typeinfo.cc @ 18560:fd138c51ca25 draft
Fully int32 type support
author | LYH <lyh.kernel@gmail.com> |
---|---|
date | Fri, 27 Sep 2013 05:00:42 +0800 |
parents | 1a82df63d65e |
children | 7a6da3d7e3f9 |
comparison
equal
deleted
inserted
replaced
18559:1a82df63d65e | 18560:fd138c51ca25 |
---|---|
69 #include "ov-complex.h" | 69 #include "ov-complex.h" |
70 #include "ov-scalar.h" | 70 #include "ov-scalar.h" |
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-int64.h" | 75 #include "ov-int64.h" |
75 #include "ov-uint16.h" | 76 #include "ov-uint16.h" |
76 #include "pager.h" | 77 #include "pager.h" |
77 | 78 |
78 static llvm::LLVMContext& context = llvm::getGlobalContext (); | 79 static llvm::LLVMContext& context = llvm::getGlobalContext (); |
235 | 236 |
236 extern "C" octave_base_value * | 237 extern "C" octave_base_value * |
237 octave_jit_cast_any_int16 (int16_t value) | 238 octave_jit_cast_any_int16 (int16_t value) |
238 { | 239 { |
239 return new octave_int16_scalar (value); | 240 return new octave_int16_scalar (value); |
241 } | |
242 | |
243 extern "C" int32_t | |
244 octave_jit_cast_int32_any (octave_base_value *obv) | |
245 { | |
246 int32_t ret = obv->int32_scalar_value (); | |
247 obv->release (); | |
248 return ret; | |
249 } | |
250 | |
251 extern "C" octave_base_value * | |
252 octave_jit_cast_any_int32 (int32_t value) | |
253 { | |
254 return new octave_int32_scalar (value); | |
240 } | 255 } |
241 | 256 |
242 extern "C" int64_t | 257 extern "C" int64_t |
243 octave_jit_cast_int64_any (octave_base_value *obv) | 258 octave_jit_cast_int64_any (octave_base_value *obv) |
244 { | 259 { |
694 return octave_jit_sub_int16_int16 (val, 1); | 709 return octave_jit_sub_int16_int16 (val, 1); |
695 } | 710 } |
696 | 711 |
697 /************************************************************ | 712 /************************************************************ |
698 * | 713 * |
714 * int32 related external helper function | |
715 * | |
716 ************************************************************/ | |
717 | |
718 extern "C" int32_t | |
719 octave_jit_add_int32_int32 (int32_t lhs, int32_t rhs) | |
720 { | |
721 uint32_t ulhs = lhs; | |
722 uint32_t urhs = rhs; | |
723 uint32_t res = ulhs + urhs; | |
724 | |
725 /* Calculate overflowed result. (Don't change the sign bit of ux) */ | |
726 ulhs = (ulhs >> 31) + INT_MAX; | |
727 | |
728 /* Force compiler to use cmovns instruction */ | |
729 if ((int32_t) ((ulhs ^ urhs) | ~(urhs ^ res)) >= 0) | |
730 { | |
731 res = ulhs; | |
732 } | |
733 | |
734 return res; | |
735 } | |
736 | |
737 extern "C" int32_t | |
738 octave_jit_sub_int32_int32 (int32_t lhs, int32_t rhs) | |
739 { | |
740 uint32_t ulhs = lhs; | |
741 uint32_t urhs = rhs; | |
742 uint32_t res = ulhs - urhs; | |
743 | |
744 ulhs = (ulhs >> 31) + INT_MAX; | |
745 | |
746 /* Force compiler to use cmovns instruction */ | |
747 if ((int32_t)((ulhs ^ urhs) & (ulhs ^ res)) < 0) | |
748 { | |
749 res = ulhs; | |
750 } | |
751 | |
752 return res; | |
753 } | |
754 | |
755 extern "C" int32_t | |
756 octave_jit_mul_int32_int32 (int32_t lhs, int32_t rhs) | |
757 { | |
758 int64_t res = (int64_t) lhs * (int64_t) rhs; | |
759 uint32_t res2 = ((uint32_t) (lhs ^ rhs) >> 31) + INT_MAX; | |
760 | |
761 int32_t hi = (res >> 32); | |
762 int32_t lo = res; | |
763 | |
764 if (hi != (lo >> 31)) res = res2; | |
765 | |
766 return res; | |
767 } | |
768 | |
769 extern "C" int32_t | |
770 octave_jit_incr_int32 (int32_t val) | |
771 { | |
772 return octave_jit_add_int32_int32 (val, 1); | |
773 } | |
774 | |
775 extern "C" int32_t | |
776 octave_jit_decr_int32 (int32_t val) | |
777 { | |
778 return octave_jit_sub_int32_int32 (val, 1); | |
779 } | |
780 | |
781 /************************************************************ | |
782 * | |
699 * int64 related external helper function | 783 * int64 related external helper function |
700 * | 784 * |
701 ************************************************************/ | 785 ************************************************************/ |
702 | 786 |
703 extern "C" int64_t | 787 extern "C" int64_t |
1449 | 1533 |
1450 llvm::Type *scalar_t = llvm::Type::getDoubleTy (context); | 1534 llvm::Type *scalar_t = llvm::Type::getDoubleTy (context); |
1451 llvm::Type *single_t = llvm::Type::getFloatTy (context); | 1535 llvm::Type *single_t = llvm::Type::getFloatTy (context); |
1452 llvm::Type *int8__t = llvm::Type::getIntNTy (context, 8); | 1536 llvm::Type *int8__t = llvm::Type::getIntNTy (context, 8); |
1453 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); | 1537 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); |
1538 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); | |
1454 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); | 1539 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); |
1455 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); | 1540 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); |
1456 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); | 1541 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); |
1457 llvm::Type *string_t = llvm::Type::getInt8Ty (context); | 1542 llvm::Type *string_t = llvm::Type::getInt8Ty (context); |
1458 string_t = string_t->getPointerTo (); | 1543 string_t = string_t->getPointerTo (); |
1601 | 1686 |
1602 grab_fn.add_overload (create_identity (scalar)); | 1687 grab_fn.add_overload (create_identity (scalar)); |
1603 grab_fn.add_overload (create_identity (single)); | 1688 grab_fn.add_overload (create_identity (single)); |
1604 grab_fn.add_overload (create_identity (intN (8))); | 1689 grab_fn.add_overload (create_identity (intN (8))); |
1605 grab_fn.add_overload (create_identity (intN (16))); | 1690 grab_fn.add_overload (create_identity (intN (16))); |
1691 grab_fn.add_overload (create_identity (intN (32))); | |
1606 grab_fn.add_overload (create_identity (intN (64))); | 1692 grab_fn.add_overload (create_identity (intN (64))); |
1607 grab_fn.add_overload (create_identity (uintN (16))); | 1693 grab_fn.add_overload (create_identity (uintN (16))); |
1608 grab_fn.add_overload (create_identity (scalar_ptr)); | 1694 grab_fn.add_overload (create_identity (scalar_ptr)); |
1609 grab_fn.add_overload (create_identity (any_ptr)); | 1695 grab_fn.add_overload (create_identity (any_ptr)); |
1610 grab_fn.add_overload (create_identity (boolean)); | 1696 grab_fn.add_overload (create_identity (boolean)); |
1625 destroy_fn.stash_name ("destroy"); | 1711 destroy_fn.stash_name ("destroy"); |
1626 destroy_fn.add_overload (create_identity(scalar)); | 1712 destroy_fn.add_overload (create_identity(scalar)); |
1627 destroy_fn.add_overload (create_identity(single)); | 1713 destroy_fn.add_overload (create_identity(single)); |
1628 destroy_fn.add_overload (create_identity(intN (8))); | 1714 destroy_fn.add_overload (create_identity(intN (8))); |
1629 destroy_fn.add_overload (create_identity(intN (16))); | 1715 destroy_fn.add_overload (create_identity(intN (16))); |
1716 destroy_fn.add_overload (create_identity(intN (32))); | |
1630 destroy_fn.add_overload (create_identity(intN (64))); | 1717 destroy_fn.add_overload (create_identity(intN (64))); |
1631 destroy_fn.add_overload (create_identity(uintN (16))); | 1718 destroy_fn.add_overload (create_identity(uintN (16))); |
1632 destroy_fn.add_overload (create_identity(boolean)); | 1719 destroy_fn.add_overload (create_identity(boolean)); |
1633 destroy_fn.add_overload (create_identity(index)); | 1720 destroy_fn.add_overload (create_identity(index)); |
1634 destroy_fn.add_overload (create_identity(complex)); | 1721 destroy_fn.add_overload (create_identity(complex)); |
1991 unary_ops[octave_value::op_transpose].add_overload (fn); | 2078 unary_ops[octave_value::op_transpose].add_overload (fn); |
1992 unary_ops[octave_value::op_hermitian].add_overload (fn); | 2079 unary_ops[octave_value::op_hermitian].add_overload (fn); |
1993 | 2080 |
1994 /************************************************************ | 2081 /************************************************************ |
1995 * | 2082 * |
2083 * int32 related operations | |
2084 * | |
2085 ************************************************************/ | |
2086 | |
2087 // FIXME: interpreter overflow occurs at minus + minus, minus - plus | |
2088 // now for binary int32 operations | |
2089 fn = create_external (JIT_FN (octave_jit_add_int32_int32), intN (32), intN (32), | |
2090 intN (32)); | |
2091 binary_ops[octave_value::op_add].add_overload (fn); | |
2092 fn = create_external (JIT_FN (octave_jit_sub_int32_int32), intN (32), intN (32), | |
2093 intN (32)); | |
2094 binary_ops[octave_value::op_sub].add_overload (fn); | |
2095 fn = create_external (JIT_FN (octave_jit_mul_int32_int32), intN (32), intN (32), | |
2096 intN (32)); | |
2097 binary_ops[octave_value::op_mul].add_overload (fn); | |
2098 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2099 | |
2100 add_binary_icmp (intN (32), octave_value::op_lt, llvm::CmpInst::ICMP_SLT); | |
2101 add_binary_icmp (intN (32), octave_value::op_le, llvm::CmpInst::ICMP_SLE); | |
2102 add_binary_icmp (intN (32), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2103 add_binary_icmp (intN (32), octave_value::op_ge, llvm::CmpInst::ICMP_SGE); | |
2104 add_binary_icmp (intN (32), octave_value::op_gt, llvm::CmpInst::ICMP_SGT); | |
2105 add_binary_icmp (intN (32), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2106 | |
2107 // FIXME: saturation divide definition? interpreter convert int to double, calculate and round. | |
2108 // divide is annoying because it might error | |
2109 // FIXME: Implement div | |
2110 | |
2111 // FIXME: Implement pow | |
2112 | |
2113 // now for unary int32 operations | |
2114 // FIXME: Impelment not | |
2115 fn = create_external (JIT_FN (octave_jit_incr_int32), intN (32), intN (32)); | |
2116 unary_ops[octave_value::op_incr].add_overload (fn); | |
2117 | |
2118 fn = create_external (JIT_FN (octave_jit_decr_int32), intN (32), intN (32)); | |
2119 unary_ops[octave_value::op_decr].add_overload (fn); | |
2120 | |
2121 fn = create_internal ("octave_jit_uminus", intN (32), intN (32)); | |
2122 body = fn.new_block (); | |
2123 builder.SetInsertPoint (body); | |
2124 { | |
2125 llvm::Value *mone = llvm::ConstantInt::get (int32__t, -1); | |
2126 llvm::Value *val = fn.argument (builder, 0); | |
2127 val = builder.CreateMul (val, mone); | |
2128 fn.do_return (builder, val); | |
2129 } | |
2130 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2131 | |
2132 fn = create_identity (intN (32)); | |
2133 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2134 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2135 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2136 | |
2137 /************************************************************ | |
2138 * | |
1996 * int64 related operations | 2139 * int64 related operations |
1997 * | 2140 * |
1998 ************************************************************/ | 2141 ************************************************************/ |
1999 | 2142 |
2000 // FIXME: interpreter overflow occurs at minus + minus, minus - plus | 2143 // FIXME: interpreter overflow occurs at minus + minus, minus - plus |
2508 casts[any->type_id ()].stash_name ("(any)"); | 2651 casts[any->type_id ()].stash_name ("(any)"); |
2509 casts[scalar->type_id ()].stash_name ("(scalar)"); | 2652 casts[scalar->type_id ()].stash_name ("(scalar)"); |
2510 casts[single->type_id ()].stash_name ("(single)"); | 2653 casts[single->type_id ()].stash_name ("(single)"); |
2511 casts[intN (8)->type_id ()].stash_name ("(int8)"); | 2654 casts[intN (8)->type_id ()].stash_name ("(int8)"); |
2512 casts[intN (16)->type_id ()].stash_name ("(int16)"); | 2655 casts[intN (16)->type_id ()].stash_name ("(int16)"); |
2656 casts[intN (32)->type_id ()].stash_name ("(int32)"); | |
2513 casts[intN (64)->type_id ()].stash_name ("(int64)"); | 2657 casts[intN (64)->type_id ()].stash_name ("(int64)"); |
2514 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); | 2658 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); |
2515 casts[complex->type_id ()].stash_name ("(complex)"); | 2659 casts[complex->type_id ()].stash_name ("(complex)"); |
2516 casts[matrix->type_id ()].stash_name ("(matrix)"); | 2660 casts[matrix->type_id ()].stash_name ("(matrix)"); |
2517 casts[range->type_id ()].stash_name ("(range)"); | 2661 casts[range->type_id ()].stash_name ("(range)"); |
2561 casts[any->type_id ()].add_overload (fn); | 2705 casts[any->type_id ()].add_overload (fn); |
2562 | 2706 |
2563 // cast int16 <- any | 2707 // cast int16 <- any |
2564 fn = create_external (JIT_FN (octave_jit_cast_int16_any), intN (16), any); | 2708 fn = create_external (JIT_FN (octave_jit_cast_int16_any), intN (16), any); |
2565 casts[intN (16)->type_id ()].add_overload (fn); | 2709 casts[intN (16)->type_id ()].add_overload (fn); |
2710 | |
2711 // cast any <- int32 | |
2712 fn = create_external (JIT_FN (octave_jit_cast_any_int32), any, intN (32)); | |
2713 casts[any->type_id ()].add_overload (fn); | |
2714 | |
2715 // cast int32 <- any | |
2716 fn = create_external (JIT_FN (octave_jit_cast_int32_any), intN (32), any); | |
2717 casts[intN (32)->type_id ()].add_overload (fn); | |
2566 | 2718 |
2567 // cast any <- int64 | 2719 // cast any <- int64 |
2568 fn = create_external (JIT_FN (octave_jit_cast_any_int64), any, intN (64)); | 2720 fn = create_external (JIT_FN (octave_jit_cast_any_int64), any, intN (64)); |
2569 casts[any->type_id ()].add_overload (fn); | 2721 casts[any->type_id ()].add_overload (fn); |
2570 | 2722 |
2622 casts[intN (8)->type_id ()].add_overload (fn); | 2774 casts[intN (8)->type_id ()].add_overload (fn); |
2623 | 2775 |
2624 // cast int16 <- int16 | 2776 // cast int16 <- int16 |
2625 fn = create_identity (intN (16)); | 2777 fn = create_identity (intN (16)); |
2626 casts[intN (16)->type_id ()].add_overload (fn); | 2778 casts[intN (16)->type_id ()].add_overload (fn); |
2779 | |
2780 // cast int32 <- int32 | |
2781 fn = create_identity (intN (32)); | |
2782 casts[intN (32)->type_id ()].add_overload (fn); | |
2627 | 2783 |
2628 // cast int64 <- int64 | 2784 // cast int64 <- int64 |
2629 fn = create_identity (intN (64)); | 2785 fn = create_identity (intN (64)); |
2630 casts[intN (64)->type_id ()].add_overload (fn); | 2786 casts[intN (64)->type_id ()].add_overload (fn); |
2631 | 2787 |
3099 if (ov.is_int16_type()) | 3255 if (ov.is_int16_type()) |
3100 { | 3256 { |
3101 return intN (16); | 3257 return intN (16); |
3102 } | 3258 } |
3103 | 3259 |
3260 if (ov.is_int32_type()) | |
3261 { | |
3262 return intN (32); | |
3263 } | |
3264 | |
3104 if (ov.is_int64_type()) | 3265 if (ov.is_int64_type()) |
3105 { | 3266 { |
3106 return intN (64); | 3267 return intN (64); |
3107 } | 3268 } |
3108 | 3269 |