changeset 18582:c31fe3239c8b draft

partial support of single/uint16
author LYH <lyh.kernel@gmail.com>
date Fri, 21 Mar 2014 14:59:38 -0400
parents f3314c4b9266
children 3b7490456101
files libinterp/corefcn/jit-typeinfo.cc libinterp/corefcn/jit-typeinfo.h
diffstat 2 files changed, 180 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/jit-typeinfo.cc	Fri Mar 21 14:59:38 2014 -0400
+++ b/libinterp/corefcn/jit-typeinfo.cc	Fri Mar 21 14:59:38 2014 -0400
@@ -66,6 +66,8 @@
 #include "ov-builtin.h"
 #include "ov-complex.h"
 #include "ov-scalar.h"
+#include "ov-float.h"
+#include "ov-uint16.h"
 #include "pager.h"
 
 static llvm::LLVMContext& context = llvm::getGlobalContext ();
@@ -190,6 +192,34 @@
   return new octave_scalar (value);
 }
 
+extern "C" float
+octave_jit_cast_single_any (octave_base_value *obv)
+{
+  float ret = obv->float_value ();
+  obv->release ();
+  return ret;
+}
+
+extern "C" octave_base_value *
+octave_jit_cast_any_single (float value)
+{
+  return new octave_float_scalar (value);
+}
+
+extern "C" uint16_t
+octave_jit_cast_uint16_any (octave_base_value *obv)
+{
+  uint16_t ret = obv->uint16_scalar_value ();
+  obv->release ();
+  return ret;
+}
+
+extern "C" octave_base_value *
+octave_jit_cast_any_uint16 (uint16_t value)
+{
+  return new octave_uint16_scalar (value);
+}
+
 extern "C" Complex
 octave_jit_cast_complex_any (octave_base_value *obv)
 {
@@ -460,6 +490,21 @@
   return std::pow (lhs, rhs);
 }
 
+extern "C" uint16_t
+octave_jit_add_uint16_uint16 (uint16_t lhs, uint16_t rhs)
+{
+  uint16_t res = lhs + rhs;
+  res |= -(res < lhs);
+
+  return res;
+}
+
+extern "C" uint16_t
+octave_jit_incr_uint16 (uint16_t val)
+{
+  return octave_jit_add_uint16_uint16 (val, 1);
+}
+
 extern "C" void
 octave_jit_print_matrix (jit_matrix *m)
 {
@@ -1080,6 +1125,7 @@
   any_t = any_t->getPointerTo ();
 
   llvm::Type *scalar_t = llvm::Type::getDoubleTy (context);
+  llvm::Type *single_t = llvm::Type::getFloatTy (context);
   llvm::Type *bool_t = llvm::Type::getInt1Ty (context);
   llvm::Type *string_t = llvm::Type::getInt8Ty (context);
   string_t = string_t->getPointerTo ();
@@ -1120,6 +1166,7 @@
   matrix = new_type ("matrix", any, matrix_t);
   complex = new_type ("complex", any, complex_t);
   scalar = new_type ("scalar", complex, scalar_t);
+  single = new_type ("single", any, single_t);
   scalar_ptr = new_type ("scalar_ptr", 0, scalar_t->getPointerTo ());
   any_ptr = new_type ("any_ptr", 0, any_t->getPointerTo ());
   range = new_type ("range", any, range_t);
@@ -1132,6 +1179,8 @@
   create_int (32);
   create_int (64);
 
+  create_uint (16);
+
   casts.resize (next_id + 1);
   identities.resize (next_id + 1);
 
@@ -1224,6 +1273,8 @@
   grab_fn.add_overload (fn);
 
   grab_fn.add_overload (create_identity (scalar));
+  grab_fn.add_overload (create_identity (single));
+  grab_fn.add_overload (create_identity (uintN (16)));
   grab_fn.add_overload (create_identity (scalar_ptr));
   grab_fn.add_overload (create_identity (any_ptr));
   grab_fn.add_overload (create_identity (boolean));
@@ -1243,6 +1294,8 @@
   destroy_fn = release_fn;
   destroy_fn.stash_name ("destroy");
   destroy_fn.add_overload (create_identity(scalar));
+  destroy_fn.add_overload (create_identity(single));
+  destroy_fn.add_overload (create_identity(uintN (16)));
   destroy_fn.add_overload (create_identity(boolean));
   destroy_fn.add_overload (create_identity(index));
   destroy_fn.add_overload (create_identity(complex));
@@ -1263,6 +1316,26 @@
   jit_function gripe_div0 = create_external (JIT_FN (gripe_divide_by_zero), 0);
   gripe_div0.mark_can_error ();
 
+  // now for binary single operations
+  add_binary_op (single, octave_value::op_add, llvm::Instruction::FAdd);
+  add_binary_op (single, octave_value::op_sub, llvm::Instruction::FSub);
+  add_binary_op (single, octave_value::op_mul, llvm::Instruction::FMul);
+  add_binary_op (single, octave_value::op_el_mul, llvm::Instruction::FMul);
+
+  add_binary_fcmp (single, octave_value::op_lt, llvm::CmpInst::FCMP_ULT);
+  add_binary_fcmp (single, octave_value::op_le, llvm::CmpInst::FCMP_ULE);
+  add_binary_fcmp (single, octave_value::op_eq, llvm::CmpInst::FCMP_UEQ);
+  add_binary_fcmp (single, octave_value::op_ge, llvm::CmpInst::FCMP_UGE);
+  add_binary_fcmp (single, octave_value::op_gt, llvm::CmpInst::FCMP_UGT);
+  add_binary_fcmp (single, octave_value::op_ne, llvm::CmpInst::FCMP_UNE);
+
+  // now for binary uint16 operations
+  fn = create_external (JIT_FN (octave_jit_add_uint16_uint16), uintN (16), uintN (16),
+                        uintN (16));
+  binary_ops[octave_value::op_add].add_overload (fn);
+
+  add_binary_icmp (uintN (16), octave_value::op_eq, llvm::CmpInst::ICMP_EQ);
+
   // divide is annoying because it might error
   fn = create_internal ("octave_jit_div_scalar_scalar", scalar, scalar, scalar);
   fn.mark_can_error ();
@@ -1341,6 +1414,50 @@
   unary_ops[octave_value::op_transpose].add_overload (fn);
   unary_ops[octave_value::op_hermitian].add_overload (fn);
 
+  // now for unary single operations
+  // FIXME: Impelment not
+  fn = create_internal ("octave_jit_++", single, single);
+  body = fn.new_block ();
+  builder.SetInsertPoint (body);
+  {
+    llvm::Value *one = llvm::ConstantFP::get (single_t, 1);
+    llvm::Value *val = fn.argument (builder, 0);
+    val = builder.CreateFAdd (val, one);
+    fn.do_return (builder, val);
+  }
+  unary_ops[octave_value::op_incr].add_overload (fn);
+
+  fn = create_internal ("octave_jit_--", single, single);
+  body = fn.new_block ();
+  builder.SetInsertPoint (body);
+  {
+    llvm::Value *one = llvm::ConstantFP::get (single_t, 1);
+    llvm::Value *val = fn.argument (builder, 0);
+    val = builder.CreateFSub (val, one);
+    fn.do_return (builder, val);
+  }
+  unary_ops[octave_value::op_decr].add_overload (fn);
+
+  fn = create_internal ("octave_jit_uminus", single, single);
+  body = fn.new_block ();
+  builder.SetInsertPoint (body);
+  {
+    llvm::Value *mone = llvm::ConstantFP::get (single_t, -1);
+    llvm::Value *val = fn.argument (builder, 0);
+    val = builder.CreateFMul (val, mone);
+    fn.do_return (builder, val);
+  }
+
+  fn = create_identity (single);
+  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);
+
+  // now for unary uint16 operations
+  // FIXME: Impelment not
+  fn = create_external (JIT_FN (octave_jit_incr_uint16), uintN (16), uintN (16));
+  unary_ops[octave_value::op_incr].add_overload (fn);
+
   // now for binary complex operations
   fn = create_internal ("octave_jit_+_complex_complex", complex, complex,
                         complex);
@@ -1767,6 +1884,8 @@
 
   casts[any->type_id ()].stash_name ("(any)");
   casts[scalar->type_id ()].stash_name ("(scalar)");
+  casts[single->type_id ()].stash_name ("(single)");
+  casts[uintN (16)->type_id ()].stash_name ("(uint16)");
   casts[complex->type_id ()].stash_name ("(complex)");
   casts[matrix->type_id ()].stash_name ("(matrix)");
   casts[range->type_id ()].stash_name ("(range)");
@@ -1795,6 +1914,22 @@
   fn = create_external (JIT_FN (octave_jit_cast_scalar_any), scalar, any);
   casts[scalar->type_id ()].add_overload (fn);
 
+  // cast any <- single
+  fn = create_external (JIT_FN (octave_jit_cast_any_single), any, single);
+  casts[any->type_id ()].add_overload (fn);
+
+  // cast single <- any
+  fn = create_external (JIT_FN (octave_jit_cast_single_any), single, any);
+  casts[single->type_id ()].add_overload (fn);
+
+  // cast any <- uint16
+  fn = create_external (JIT_FN (octave_jit_cast_any_uint16), any, uintN (16));
+  casts[any->type_id ()].add_overload (fn);
+
+  // cast uint16 <- any
+  fn = create_external (JIT_FN (octave_jit_cast_uint16_any), uintN (16), any);
+  casts[uintN (16)->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);
@@ -1828,6 +1963,14 @@
   fn = create_identity (scalar);
   casts[scalar->type_id ()].add_overload (fn);
 
+  // cast single <- single
+  fn = create_identity (single);
+  casts[single->type_id ()].add_overload (fn);
+
+  // cast uint16 <- uint16
+  fn = create_identity (uintN (16));
+  casts[uintN (16)->type_id ()].add_overload (fn);
+
   // cast complex <- complex
   fn = create_identity (complex);
   casts[complex->type_id ()].add_overload (fn);
@@ -2226,6 +2369,15 @@
                                                                     nbits));
 }
 
+void
+jit_typeinfo::create_uint (size_t nbits)
+{
+  std::stringstream tname;
+  tname << "uint" << nbits;
+  uints[nbits] = new_type (tname.str (), any, llvm::Type::getIntNTy (context,
+                                                                     nbits));
+}
+
 jit_type *
 jit_typeinfo::intN (size_t nbits) const
 {
@@ -2237,6 +2389,16 @@
 }
 
 jit_type *
+jit_typeinfo::uintN (size_t nbits) const
+{
+  std::map<size_t, jit_type *>::const_iterator iter = uints.find (nbits);
+  if (iter != uints.end ())
+    return iter->second;
+
+  throw jit_fail_exception ("No such unsigned integer type");
+}
+
+jit_type *
 jit_typeinfo::do_type_of (const octave_value &ov) const
 {
   if (ov.is_function ())
@@ -2261,6 +2423,16 @@
         return get_matrix ();
     }
 
+  if (ov.is_float_type ())
+    {
+      return get_single ();
+    }
+
+  if (ov.is_uint16_type())
+    {
+      return uintN (16);
+    }
+
   if (ov.is_complex_scalar ())
     {
       Complex cv = ov.complex_value ();
--- a/libinterp/corefcn/jit-typeinfo.h	Fri Mar 21 14:59:38 2014 -0400
+++ b/libinterp/corefcn/jit-typeinfo.h	Fri Mar 21 14:59:38 2014 -0400
@@ -458,6 +458,8 @@
   static llvm::Type *get_scalar_llvm (void)
   { return instance->scalar->to_llvm (); }
 
+  static jit_type *get_single (void) { return instance->single; }
+
   static jit_type *get_scalar_ptr (void) { return instance->scalar_ptr; }
 
   static jit_type *get_any_ptr (void) { return instance->any_ptr; }
@@ -790,8 +792,12 @@
 
   void create_int (size_t nbits);
 
+  void create_uint (size_t nbits);
+
   jit_type *intN (size_t nbits) const;
 
+  jit_type *uintN (size_t nbits) const;
+
   static jit_typeinfo *instance;
 
   llvm::Module *module;
@@ -807,6 +813,7 @@
   jit_type *any;
   jit_type *matrix;
   jit_type *scalar;
+  jit_type *single;
   jit_type *scalar_ptr; // a fake type for interfacing with C++
   jit_type *any_ptr; // a fake type for interfacing with C++
   jit_type *range;
@@ -816,6 +823,7 @@
   jit_type *complex;
   jit_type *unknown_function;
   std::map<size_t, jit_type *> ints;
+  std::map<size_t, jit_type *> uints;
   std::map<std::string, jit_type *> builtins;
 
   llvm::StructType *complex_ret;