diff options
author | Ian Rogers <irogers@google.com> | 2014-05-23 18:18:07 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-05-23 18:18:07 +0000 |
commit | 82f3c1b76a19f196a482cad9d5c1aac769d5a397 (patch) | |
tree | 92274ad77abaa3a8e86d28e38a3e68a990c6d365 /compiler | |
parent | ae19a731ccd62117d8b14e478caee5ac1b6251d2 (diff) | |
parent | c3db20b7e6f847339d6ecbd89846c173a7ccc967 (diff) | |
download | art-82f3c1b76a19f196a482cad9d5c1aac769d5a397.zip art-82f3c1b76a19f196a482cad9d5c1aac769d5a397.tar.gz art-82f3c1b76a19f196a482cad9d5c1aac769d5a397.tar.bz2 |
Merge "ART: API to dex instructions"
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/mir_graph.cc | 53 | ||||
-rw-r--r-- | compiler/dex/mir_graph.h | 50 |
2 files changed, 103 insertions, 0 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index 0ef66d2..1300071 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -1607,4 +1607,57 @@ uint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) { return res; } +/** + * @brief Given a decoded instruction, it checks whether the instruction + * sets a constant and if it does, more information is provided about the + * constant being set. + * @param ptr_value pointer to a 64-bit holder for the constant. + * @param wide Updated by function whether a wide constant is being set by bytecode. + * @return Returns false if the decoded instruction does not represent a constant bytecode. + */ +bool MIR::DecodedInstruction::GetConstant(int64_t* ptr_value, bool* wide) const { + bool sets_const = true; + int64_t value = vB; + + DCHECK(ptr_value != nullptr); + DCHECK(wide != nullptr); + + switch (opcode) { + case Instruction::CONST_4: + case Instruction::CONST_16: + case Instruction::CONST: + *wide = false; + value <<= 32; // In order to get the sign extend. + value >>= 32; + break; + case Instruction::CONST_HIGH16: + *wide = false; + value <<= 48; // In order to get the sign extend. + value >>= 32; + break; + case Instruction::CONST_WIDE_16: + case Instruction::CONST_WIDE_32: + *wide = true; + value <<= 32; // In order to get the sign extend. + value >>= 32; + break; + case Instruction::CONST_WIDE: + *wide = true; + value = vB_wide; + break; + case Instruction::CONST_WIDE_HIGH16: + *wide = true; + value <<= 48; // In order to get the sign extend. + break; + default: + sets_const = false; + break; + } + + if (sets_const) { + *ptr_value = value; + } + + return sets_const; +} } // namespace art diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index c97dcd6..a849bc1 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -266,6 +266,56 @@ struct MIR { explicit DecodedInstruction():vA(0), vB(0), vB_wide(0), vC(0), opcode(Instruction::NOP) { } + + /* + * Given a decoded instruction representing a const bytecode, it updates + * the out arguments with proper values as dictated by the constant bytecode. + */ + bool GetConstant(int64_t* ptr_value, bool* wide) const; + + bool IsStore() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kStore) == Instruction::kStore); + } + + bool IsLoad() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kLoad) == Instruction::kLoad); + } + + bool IsConditionalBranch() const { + return (Instruction::FlagsOf(opcode) == (Instruction::kContinue | Instruction::kBranch)); + } + + /** + * @brief Is the register C component of the decoded instruction a constant? + */ + bool IsCFieldOrConstant() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kRegCFieldOrConstant) == Instruction::kRegCFieldOrConstant); + } + + /** + * @brief Is the register C component of the decoded instruction a constant? + */ + bool IsBFieldOrConstant() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kRegBFieldOrConstant) == Instruction::kRegBFieldOrConstant); + } + + bool IsCast() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kCast) == Instruction::kCast); + } + + /** + * @brief Does the instruction clobber memory? + * @details Clobber means that the instruction changes the memory not in a punctual way. + * Therefore any supposition on memory aliasing or memory contents should be disregarded + * when crossing such an instruction. + */ + bool Clobbers() const { + return ((Instruction::FlagsOf(opcode) & Instruction::kClobber) == Instruction::kClobber); + } + + bool IsLinear() const { + return (Instruction::FlagsOf(opcode) & (Instruction::kAdd | Instruction::kSubtract)) != 0; + } } dalvikInsn; NarrowDexOffset offset; // Offset of the instruction in code units. |