summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h49
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);
};