# HG changeset patch # User LYH # Date 1395428379 14400 # Node ID 2b548935b33473c609dfe80a7ae995976778b1e0 # Parent 9f72101d109da582b6b020f96e0658f09b5cc450 Fully uint8 type support diff -r 9f72101d109d -r 2b548935b334 libinterp/corefcn/jit-typeinfo.cc --- a/libinterp/corefcn/jit-typeinfo.cc Fri Mar 21 14:59:39 2014 -0400 +++ b/libinterp/corefcn/jit-typeinfo.cc Fri Mar 21 14:59:39 2014 -0400 @@ -73,6 +73,7 @@ #include "ov-int16.h" #include "ov-int32.h" #include "ov-int64.h" +#include "ov-uint8.h" #include "ov-uint16.h" #include "pager.h" @@ -271,6 +272,20 @@ return new octave_int64_scalar (value); } +extern "C" uint8_t +octave_jit_cast_uint8_any (octave_base_value *obv) +{ + uint8_t ret = obv->uint8_scalar_value (); + obv->release (); + return ret; +} + +extern "C" octave_base_value * +octave_jit_cast_any_uint8 (uint8_t value) +{ + return new octave_uint8_scalar (value); +} + extern "C" uint16_t octave_jit_cast_uint16_any (octave_base_value *obv) { @@ -852,6 +867,53 @@ /************************************************************ * + * uint8 related external helper function + * + ************************************************************/ + +extern "C" uint8_t +octave_jit_add_uint8_uint8 (uint8_t lhs, uint8_t rhs) +{ + uint8_t res = lhs + rhs; + res |= -(res < lhs); + + return res; +} + +extern "C" uint8_t +octave_jit_sub_uint8_uint8 (uint8_t lhs, uint8_t rhs) +{ + uint8_t res = lhs - rhs; + res &= -(res <= lhs); + + return res; +} + +extern "C" uint8_t +octave_jit_mul_uint8_uint8 (uint8_t lhs, uint8_t rhs) +{ + uint16_t res = (uint16_t) lhs * (uint16_t) rhs; + + uint8_t hi = res >> 8; + uint8_t lo = res; + + return lo | -!!hi; +} + +extern "C" uint8_t +octave_jit_incr_uint8 (uint8_t val) +{ + return octave_jit_add_uint8_uint8 (val, 1); +} + +extern "C" uint8_t +octave_jit_decr_uint8 (uint8_t val) +{ + return octave_jit_sub_uint8_uint8 (val, 1); +} + +/************************************************************ + * * uint16 related external helper function * ************************************************************/ @@ -1526,6 +1588,7 @@ llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); 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 *bool_t = llvm::Type::getInt1Ty (context); llvm::Type *string_t = llvm::Type::getInt8Ty (context); @@ -1580,6 +1643,7 @@ create_int (32); create_int (64); + create_uint (8); create_uint (16); casts.resize (next_id + 1); @@ -1679,6 +1743,7 @@ grab_fn.add_overload (create_identity (intN (16))); grab_fn.add_overload (create_identity (intN (32))); 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 (scalar_ptr)); grab_fn.add_overload (create_identity (any_ptr)); @@ -1704,6 +1769,7 @@ destroy_fn.add_overload (create_identity(intN (16))); destroy_fn.add_overload (create_identity(intN (32))); 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(boolean)); destroy_fn.add_overload (create_identity(index)); @@ -2185,6 +2251,60 @@ /************************************************************ * + * uint8 related operations + * + ************************************************************/ + + // now for binary uint8 operations + fn = create_external (JIT_FN (octave_jit_add_uint8_uint8), uintN (8), uintN (8), + uintN (8)); + binary_ops[octave_value::op_add].add_overload (fn); + fn = create_external (JIT_FN (octave_jit_sub_uint8_uint8), uintN (8), uintN (8), + uintN (8)); + binary_ops[octave_value::op_sub].add_overload (fn); + fn = create_external (JIT_FN (octave_jit_mul_uint8_uint8), uintN (8), uintN (8), + uintN (8)); + binary_ops[octave_value::op_mul].add_overload (fn); + binary_ops[octave_value::op_el_mul].add_overload (fn); + + add_binary_icmp (uintN (8), octave_value::op_lt, llvm::CmpInst::ICMP_ULT); + add_binary_icmp (uintN (8), octave_value::op_le, llvm::CmpInst::ICMP_ULE); + add_binary_icmp (uintN (8), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); + add_binary_icmp (uintN (8), octave_value::op_ge, llvm::CmpInst::ICMP_UGE); + add_binary_icmp (uintN (8), octave_value::op_gt, llvm::CmpInst::ICMP_UGT); + add_binary_icmp (uintN (8), 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_uint8), uintN (8), uintN (8)); + unary_ops[octave_value::op_incr].add_overload (fn); + + fn = create_external (JIT_FN (octave_jit_decr_uint8), uintN (8), uintN (8)); + unary_ops[octave_value::op_decr].add_overload (fn); + + fn = create_internal ("octave_jit_uminus", uintN (8), uintN (8)); + body = fn.new_block (); + builder.SetInsertPoint (body); + { + llvm::Value *zero = llvm::ConstantInt::get (uint8__t, 0); + + fn.do_return (builder, zero); + } + unary_ops[octave_value::op_uminus].add_overload (fn); + + fn = create_identity (uintN (8)); + 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); + + /************************************************************ + * * uint16 related operations * ************************************************************/ @@ -2651,6 +2771,7 @@ casts[intN (16)->type_id ()].stash_name ("(int16)"); casts[intN (32)->type_id ()].stash_name ("(int32)"); 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[complex->type_id ()].stash_name ("(complex)"); casts[matrix->type_id ()].stash_name ("(matrix)"); @@ -2720,6 +2841,14 @@ fn = create_external (JIT_FN (octave_jit_cast_int64_any), intN (64), any); casts[intN (64)->type_id ()].add_overload (fn); + // cast any <- uint8 + fn = create_external (JIT_FN (octave_jit_cast_any_uint8), any, uintN (8)); + casts[any->type_id ()].add_overload (fn); + + // cast uint8 <- any + fn = create_external (JIT_FN (octave_jit_cast_uint8_any), uintN (8), any); + casts[uintN (8)->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); @@ -2781,6 +2910,10 @@ fn = create_identity (intN (64)); casts[intN (64)->type_id ()].add_overload (fn); + // cast uint8 <- uint8 + fn = create_identity (uintN (8)); + casts[uintN (8)->type_id ()].add_overload (fn); + // cast uint16 <- uint16 fn = create_identity (uintN (16)); casts[uintN (16)->type_id ()].add_overload (fn); @@ -3263,6 +3396,11 @@ return intN (64); } + if (ov.is_uint8_type()) + { + return uintN (8); + } + if (ov.is_uint16_type()) { return uintN (16);