diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 3e38e9f2a4..1f8ef4717c 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1082,6 +1082,7 @@ class HLoopInformationOutwardIterator : public ValueObject { M(Rem, BinaryOperation) \ M(Return, Instruction) \ M(ReturnVoid, Instruction) \ + M(Ror, BinaryOperation) \ M(Shl, BinaryOperation) \ M(Shr, BinaryOperation) \ M(StaticFieldGet, Instruction) \ @@ -4198,6 +4199,44 @@ class HXor : public HBinaryOperation { DISALLOW_COPY_AND_ASSIGN(HXor); }; +class HRor : public HBinaryOperation { + public: + HRor(Primitive::Type result_type, HInstruction* value, HInstruction* distance) + : HBinaryOperation(result_type, value, distance) {} + + template <typename T, typename U, typename V> + T Compute(T x, U y, V max_shift_value) const { + static_assert(std::is_same<V, typename std::make_unsigned<T>::type>::value, + "V is not the unsigned integer type corresponding to T"); + V ux = static_cast<V>(x); + if ((y & max_shift_value) == 0) { + return static_cast<T>(ux); + } else { + const V reg_bits = sizeof(T) * 8; + return static_cast<T>(ux >> (y & max_shift_value)) | + (x << (reg_bits - (y & max_shift_value))); + } + } + + HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { + return GetBlock()->GetGraph()->GetIntConstant( + Compute(x->GetValue(), y->GetValue(), kMaxIntShiftValue), GetDexPc()); + } + HConstant* Evaluate(HLongConstant* x, HIntConstant* y) const OVERRIDE { + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + } + HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { + return GetBlock()->GetGraph()->GetLongConstant( + Compute(x->GetValue(), y->GetValue(), kMaxLongShiftValue), GetDexPc()); + } + + DECLARE_INSTRUCTION(Ror); + + private: + DISALLOW_COPY_AND_ASSIGN(HRor); +}; + // The value of a parameter in this method. Its location depends on // the calling convention. class HParameterValue : public HExpression<0> { @@ -4925,9 +4964,13 @@ class HLoadClass : public HExpression<1> { class HLoadString : public HExpression<1> { public: - HLoadString(HCurrentMethod* current_method, uint32_t string_index, uint32_t dex_pc) + HLoadString(HCurrentMethod* current_method, + uint32_t string_index, + uint32_t dex_pc, + bool is_in_dex_cache) : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc), - string_index_(string_index) { + string_index_(string_index), + is_in_dex_cache_(is_in_dex_cache) { SetRawInputAt(0, current_method); } @@ -4945,6 +4988,7 @@ class HLoadString : public HExpression<1> { bool NeedsEnvironment() const OVERRIDE { return false; } bool NeedsDexCacheOfDeclaringClass() const OVERRIDE { return true; } bool CanBeNull() const OVERRIDE { return false; } + bool IsInDexCache() const { return is_in_dex_cache_; } static SideEffects SideEffectsForArchRuntimeCalls() { return SideEffects::CanTriggerGC(); @@ -4954,6 +4998,7 @@ class HLoadString : public HExpression<1> { private: const uint32_t string_index_; + const bool is_in_dex_cache_; DISALLOW_COPY_AND_ASSIGN(HLoadString); }; |