changeset 17529:49fee4b2db60

Fully uint64 type support
author LYH <lyh.kernel@gmail.com>
date Fri, 27 Sep 2013 06:14:51 +0800
parents 58471024eb11
children ef8315ecc0d0
files libinterp/corefcn/jit-typeinfo.cc
diffstat 1 files changed, 138 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/jit-typeinfo.cc
+++ b/libinterp/corefcn/jit-typeinfo.cc
@@ -75,6 +75,7 @@
 #include "ov-int64.h"
 #include "ov-uint8.h"
 #include "ov-uint16.h"
+#include "ov-uint64.h"
 #include "pager.h"
 
 typedef __int128_t int128_t;
@@ -300,6 +301,20 @@
   return new octave_uint16_scalar (value);
 }
 
+extern "C" uint64_t
+octave_jit_cast_uint64_any (octave_base_value *obv)
+{
+  uint64_t ret = obv->uint64_scalar_value ();
+  obv->release ();
+  return ret;
+}
+
+extern "C" octave_base_value *
+octave_jit_cast_any_uint64 (uint64_t value)
+{
+  return new octave_uint64_scalar (value);
+}
+
 extern "C" Complex
 octave_jit_cast_complex_any (octave_base_value *obv)
 {
@@ -959,6 +974,53 @@
   return octave_jit_sub_uint16_uint16 (val, 1);
 }
 
+/************************************************************
+ *
+ * uint64 related external helper function
+ *
+ ************************************************************/
+
+extern "C" uint64_t
+octave_jit_add_uint64_uint64 (uint64_t lhs, uint64_t rhs)
+{
+  uint64_t res = lhs + rhs;
+  res |= -(res < lhs);
+
+  return res;
+}
+
+extern "C" uint64_t
+octave_jit_sub_uint64_uint64 (uint64_t lhs, uint64_t rhs)
+{
+  uint64_t res = lhs - rhs;
+  res &= -(res <= lhs);
+
+  return res;
+}
+
+extern "C" uint64_t
+octave_jit_mul_uint64_uint64 (uint64_t lhs, uint64_t rhs)
+{
+  uint128_t res = (uint128_t) lhs * (uint128_t) rhs;
+
+  uint64_t hi = res >> 64;
+  uint64_t lo = res;
+
+  return lo | -!!hi;
+}
+
+extern "C" uint64_t
+octave_jit_incr_uint64 (uint64_t val)
+{
+  return octave_jit_add_uint64_uint64 (val, 1);
+}
+
+extern "C" uint64_t
+octave_jit_decr_uint64 (uint64_t val)
+{
+  return octave_jit_sub_uint64_uint64 (val, 1);
+}
+
 extern "C" void
 octave_jit_print_matrix (jit_matrix *m)
 {
@@ -1590,6 +1652,7 @@
   llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64);
   llvm::Type *uint8__t = llvm::Type::getIntNTy (context, 8);
   llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16);
+  llvm::Type *uint64__t = llvm::Type::getIntNTy (context, 64);
   llvm::Type *bool_t = llvm::Type::getInt1Ty (context);
   llvm::Type *string_t = llvm::Type::getInt8Ty (context);
   string_t = string_t->getPointerTo ();
@@ -1645,6 +1708,7 @@
 
   create_uint (8);
   create_uint (16);
+  create_uint (64);
 
   casts.resize (next_id + 1);
   identities.resize (next_id + 1);
@@ -1745,6 +1809,7 @@
   grab_fn.add_overload (create_identity (intN (64)));
   grab_fn.add_overload (create_identity (uintN (8)));
   grab_fn.add_overload (create_identity (uintN (16)));
+  grab_fn.add_overload (create_identity (uintN (64)));
   grab_fn.add_overload (create_identity (scalar_ptr));
   grab_fn.add_overload (create_identity (any_ptr));
   grab_fn.add_overload (create_identity (boolean));
@@ -1771,6 +1836,7 @@
   destroy_fn.add_overload (create_identity(intN (64)));
   destroy_fn.add_overload (create_identity(uintN (8)));
   destroy_fn.add_overload (create_identity(uintN (16)));
+  destroy_fn.add_overload (create_identity(uintN (64)));
   destroy_fn.add_overload (create_identity(boolean));
   destroy_fn.add_overload (create_identity(index));
   destroy_fn.add_overload (create_identity(complex));
@@ -2387,6 +2453,60 @@
   unary_ops[octave_value::op_transpose].add_overload (fn);
   unary_ops[octave_value::op_hermitian].add_overload (fn);
 
+  /************************************************************
+   *
+   * uint64 related operations
+   *
+   ************************************************************/
+
+  // now for binary uint64 operations
+  fn = create_external (JIT_FN (octave_jit_add_uint64_uint64), uintN (64), uintN (64),
+                        uintN (64));
+  binary_ops[octave_value::op_add].add_overload (fn);
+  fn = create_external (JIT_FN (octave_jit_sub_uint64_uint64), uintN (64), uintN (64),
+                        uintN (64));
+  binary_ops[octave_value::op_sub].add_overload (fn);
+  fn = create_external (JIT_FN (octave_jit_mul_uint64_uint64), uintN (64), uintN (64),
+                        uintN (64));
+  binary_ops[octave_value::op_mul].add_overload (fn);
+  binary_ops[octave_value::op_el_mul].add_overload (fn);
+
+  add_binary_icmp (uintN (64), octave_value::op_lt, llvm::CmpInst::ICMP_ULT);
+  add_binary_icmp (uintN (64), octave_value::op_le, llvm::CmpInst::ICMP_ULE);
+  add_binary_icmp (uintN (64), octave_value::op_eq, llvm::CmpInst::ICMP_EQ);
+  add_binary_icmp (uintN (64), octave_value::op_ge, llvm::CmpInst::ICMP_UGE);
+  add_binary_icmp (uintN (64), octave_value::op_gt, llvm::CmpInst::ICMP_UGT);
+  add_binary_icmp (uintN (64), octave_value::op_ne, llvm::CmpInst::ICMP_NE);
+
+  // FIXME: saturation divide definition? interpreter convert uint to double, calculate and round.
+  // divide is annoying because it might error
+  // FIXME: Implement div
+
+  // FIXME: Implement pow
+
+  // now for unary uint8 operations
+  // FIXME: Impelment not
+  fn = create_external (JIT_FN (octave_jit_incr_uint64), uintN (64), uintN (64));
+  unary_ops[octave_value::op_incr].add_overload (fn);
+
+  fn = create_external (JIT_FN (octave_jit_decr_uint64), uintN (64), uintN (64));
+  unary_ops[octave_value::op_decr].add_overload (fn);
+
+  fn = create_internal ("octave_jit_uminus", uintN (64), uintN (64));
+  body = fn.new_block ();
+  builder.SetInsertPoint (body);
+  {
+    llvm::Value *zero = llvm::ConstantInt::get (uint64__t, 0);
+
+    fn.do_return (builder, zero);
+  }
+  unary_ops[octave_value::op_uminus].add_overload (fn);
+
+  fn = create_identity (uintN (64));
+  unary_ops[octave_value::op_uplus].add_overload (fn);
+  unary_ops[octave_value::op_transpose].add_overload (fn);
+  unary_ops[octave_value::op_hermitian].add_overload (fn);
+
   fn = create_internal ("octave_jit_*_scalar_complex", complex, scalar,
                         complex);
   jit_function mul_scalar_complex = fn;
@@ -2773,6 +2893,7 @@
   casts[intN (64)->type_id ()].stash_name ("(int64)");
   casts[uintN (8)->type_id ()].stash_name ("(uint8)");
   casts[uintN (16)->type_id ()].stash_name ("(uint16)");
+  casts[uintN (64)->type_id ()].stash_name ("(uint64)");
   casts[complex->type_id ()].stash_name ("(complex)");
   casts[matrix->type_id ()].stash_name ("(matrix)");
   casts[range->type_id ()].stash_name ("(range)");
@@ -2857,6 +2978,14 @@
   fn = create_external (JIT_FN (octave_jit_cast_uint16_any), uintN (16), any);
   casts[uintN (16)->type_id ()].add_overload (fn);
 
+  // cast any <- uint64
+  fn = create_external (JIT_FN (octave_jit_cast_any_uint64), any, uintN (64));
+  casts[any->type_id ()].add_overload (fn);
+
+  // cast uint64 <- any
+  fn = create_external (JIT_FN (octave_jit_cast_uint64_any), uintN (64), any);
+  casts[uintN (64)->type_id ()].add_overload (fn);
+
   // cast any <- complex
   fn = create_external (JIT_FN (octave_jit_cast_any_complex), any, complex);
   casts[any->type_id ()].add_overload (fn);
@@ -2918,6 +3047,10 @@
   fn = create_identity (uintN (16));
   casts[uintN (16)->type_id ()].add_overload (fn);
 
+  // cast uint64 <- uint64
+  fn = create_identity (uintN (64));
+  casts[uintN (64)->type_id ()].add_overload (fn);
+
   // cast complex <- complex
   fn = create_identity (complex);
   casts[complex->type_id ()].add_overload (fn);
@@ -3405,6 +3538,11 @@
       return uintN (16);
     }
 
+  if (ov.is_uint64_type())
+    {
+      return uintN (64);
+    }
+
   if (ov.is_complex_scalar ())
     {
       Complex cv = ov.complex_value ();