| /* | 
 |  * Copyright (C) 2016 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | #ifndef ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ | 
 | #define ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ | 
 |  | 
 | namespace art { | 
 |  | 
 | // Compute the address of the method for MIPS Constant area support. | 
 | class HMipsComputeBaseMethodAddress : public HExpression<0> { | 
 |  public: | 
 |   // Treat the value as an int32_t, but it is really a 32 bit native pointer. | 
 |   HMipsComputeBaseMethodAddress() | 
 |       : HExpression(kMipsComputeBaseMethodAddress, | 
 |                     DataType::Type::kInt32, | 
 |                     SideEffects::None(), | 
 |                     kNoDexPc) { | 
 |   } | 
 |  | 
 |   bool CanBeMoved() const OVERRIDE { return true; } | 
 |  | 
 |   DECLARE_INSTRUCTION(MipsComputeBaseMethodAddress); | 
 |  | 
 |  protected: | 
 |   DEFAULT_COPY_CONSTRUCTOR(MipsComputeBaseMethodAddress); | 
 | }; | 
 |  | 
 | // Mips version of HPackedSwitch that holds a pointer to the base method address. | 
 | class HMipsPackedSwitch FINAL : public HExpression<2> { | 
 |  public: | 
 |   HMipsPackedSwitch(int32_t start_value, | 
 |                     int32_t num_entries, | 
 |                     HInstruction* input, | 
 |                     HMipsComputeBaseMethodAddress* method_base, | 
 |                     uint32_t dex_pc) | 
 |     : HExpression(kMipsPackedSwitch, SideEffects::None(), dex_pc), | 
 |       start_value_(start_value), | 
 |       num_entries_(num_entries) { | 
 |     SetRawInputAt(0, input); | 
 |     SetRawInputAt(1, method_base); | 
 |   } | 
 |  | 
 |   bool IsControlFlow() const OVERRIDE { return true; } | 
 |  | 
 |   int32_t GetStartValue() const { return start_value_; } | 
 |  | 
 |   int32_t GetNumEntries() const { return num_entries_; } | 
 |  | 
 |   HBasicBlock* GetDefaultBlock() const { | 
 |     // Last entry is the default block. | 
 |     return GetBlock()->GetSuccessors()[num_entries_]; | 
 |   } | 
 |  | 
 |   DECLARE_INSTRUCTION(MipsPackedSwitch); | 
 |  | 
 |  protected: | 
 |   DEFAULT_COPY_CONSTRUCTOR(MipsPackedSwitch); | 
 |  | 
 |  private: | 
 |   const int32_t start_value_; | 
 |   const int32_t num_entries_; | 
 | }; | 
 |  | 
 | // This instruction computes part of the array access offset (index offset). | 
 | // | 
 | // For array accesses the element address has the following structure: | 
 | // Address = CONST_OFFSET + base_addr + index << ELEM_SHIFT. The address part | 
 | // (index << ELEM_SHIFT) can be shared across array accesses with | 
 | // the same data type and index. For example, in the following loop 5 accesses can share address | 
 | // computation: | 
 | // | 
 | // void foo(int[] a, int[] b, int[] c) { | 
 | //   for (i...) { | 
 | //     a[i] = a[i] + 5; | 
 | //     b[i] = b[i] + c[i]; | 
 | //   } | 
 | // } | 
 | // | 
 | // Note: as the instruction doesn't involve base array address into computations it has no side | 
 | // effects. | 
 | class HIntermediateArrayAddressIndex FINAL : public HExpression<2> { | 
 |  public: | 
 |   HIntermediateArrayAddressIndex(HInstruction* index, HInstruction* shift, uint32_t dex_pc) | 
 |       : HExpression(kIntermediateArrayAddressIndex, | 
 |                     DataType::Type::kInt32, | 
 |                     SideEffects::None(), | 
 |                     dex_pc) { | 
 |     SetRawInputAt(0, index); | 
 |     SetRawInputAt(1, shift); | 
 |   } | 
 |  | 
 |   bool CanBeMoved() const OVERRIDE { return true; } | 
 |   bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { | 
 |     return true; | 
 |   } | 
 |   bool IsActualObject() const OVERRIDE { return false; } | 
 |  | 
 |   HInstruction* GetIndex() const { return InputAt(0); } | 
 |   HInstruction* GetShift() const { return InputAt(1); } | 
 |  | 
 |   DECLARE_INSTRUCTION(IntermediateArrayAddressIndex); | 
 |  | 
 |  protected: | 
 |   DEFAULT_COPY_CONSTRUCTOR(IntermediateArrayAddressIndex); | 
 | }; | 
 |  | 
 | }  // namespace art | 
 |  | 
 | #endif  // ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ |