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