diff options
| author | 2016-08-03 12:46:23 +0100 | |
|---|---|---|
| committer | 2016-08-10 14:00:16 +0100 | |
| commit | 8ec3bd2b31ccbc9027b8e9b1949dd1804bb6d30f (patch) | |
| tree | 6cc457a060c7faade49229010bfe3119e55b254d /runtime/dex_instruction-inl.h | |
| parent | c218427ab96e521e0c4e9a3ffeb87e6c57eea0a5 (diff) | |
Instruction: Add new formats 45cc and 4rcc.
These are new 4 byte formats with the following properties.
- The first three (16 bit) words of these instructions have the same
format as 35c and 3rc respectively.
- The fourth 16 bit word encodes an additional constant index reference.
This change includes placeholder opcodes for invoke-polymorphic and
invoke-polymorphic/range which will be the first dex instructions that
use this new format. In addition to a method_idx that gives the invoked
method, these instructions also provide a proto_idx which gives the
(static) type signature of the call site.
The only reason these are included in this change is because we need
an instruction with a given format to write a unit_test using the Instruction
API.
bug: 30550796
test: make test-art-host
Change-Id: I02612ddee47169757175a8079d82f811f6545945
Diffstat (limited to 'runtime/dex_instruction-inl.h')
| -rw-r--r-- | runtime/dex_instruction-inl.h | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/runtime/dex_instruction-inl.h b/runtime/dex_instruction-inl.h index dd65f2c0c6..3d0fea07ad 100644 --- a/runtime/dex_instruction-inl.h +++ b/runtime/dex_instruction-inl.h @@ -49,6 +49,8 @@ inline bool Instruction::HasVRegA() const { case k32x: return true; case k35c: return true; case k3rc: return true; + case k45cc: return true; + case k4rcc: return true; case k51l: return true; default: return false; } @@ -79,6 +81,8 @@ inline int32_t Instruction::VRegA() const { case k32x: return VRegA_32x(); case k35c: return VRegA_35c(); case k3rc: return VRegA_3rc(); + case k45cc: return VRegA_45cc(); + case k4rcc: return VRegA_4rcc(); case k51l: return VRegA_51l(); default: LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand."; @@ -206,6 +210,16 @@ inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const { return InstAA(inst_data); } +inline uint4_t Instruction::VRegA_45cc(uint16_t inst_data) const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return InstB(inst_data); // This is labeled A in the spec. +} + +inline uint8_t Instruction::VRegA_4rcc(uint16_t inst_data) const { + DCHECK_EQ(FormatOf(Opcode()), k4rcc); + return InstAA(inst_data); +} + //------------------------------------------------------------------------------ // VRegB //------------------------------------------------------------------------------ @@ -229,6 +243,8 @@ inline bool Instruction::HasVRegB() const { case k32x: return true; case k35c: return true; case k3rc: return true; + case k45cc: return true; + case k4rcc: return true; case k51l: return true; default: return false; } @@ -258,6 +274,8 @@ inline int32_t Instruction::VRegB() const { case k32x: return VRegB_32x(); case k35c: return VRegB_35c(); case k3rc: return VRegB_3rc(); + case k45cc: return VRegB_45cc(); + case k4rcc: return VRegB_4rcc(); case k51l: return VRegB_51l(); default: LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand."; @@ -359,6 +377,16 @@ inline uint16_t Instruction::VRegB_3rc() const { return Fetch16(1); } +inline uint16_t Instruction::VRegB_45cc() const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return Fetch16(1); +} + +inline uint16_t Instruction::VRegB_4rcc() const { + DCHECK_EQ(FormatOf(Opcode()), k4rcc); + return Fetch16(1); +} + inline uint64_t Instruction::VRegB_51l() const { DCHECK_EQ(FormatOf(Opcode()), k51l); uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32); @@ -377,6 +405,8 @@ inline bool Instruction::HasVRegC() const { case k23x: return true; case k35c: return true; case k3rc: return true; + case k45cc: return true; + case k4rcc: return true; default: return false; } } @@ -390,6 +420,8 @@ inline int32_t Instruction::VRegC() const { case k23x: return VRegC_23x(); case k35c: return VRegC_35c(); case k3rc: return VRegC_3rc(); + case k45cc: return VRegC_45cc(); + case k4rcc: return VRegC_4rcc(); default: LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand."; exit(EXIT_FAILURE); @@ -431,11 +463,52 @@ inline uint16_t Instruction::VRegC_3rc() const { return Fetch16(2); } +inline uint4_t Instruction::VRegC_45cc() const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return static_cast<uint4_t>(Fetch16(2) & 0x0f); +} + +inline uint16_t Instruction::VRegC_4rcc() const { + DCHECK_EQ(FormatOf(Opcode()), k4rcc); + return Fetch16(2); +} + +//------------------------------------------------------------------------------ +// VRegH +//------------------------------------------------------------------------------ +inline bool Instruction::HasVRegH() const { + switch (FormatOf(Opcode())) { + case k45cc: return true; + case k4rcc: return true; + default : return false; + } +} + +inline int32_t Instruction::VRegH() const { + switch (FormatOf(Opcode())) { + case k45cc: return VRegH_45cc(); + case k4rcc: return VRegH_4rcc(); + default : + LOG(FATAL) << "Tried to access vH of instruction " << Name() << " which has no H operand."; + exit(EXIT_FAILURE); + } +} + +inline uint16_t Instruction::VRegH_45cc() const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return Fetch16(3); +} + +inline uint16_t Instruction::VRegH_4rcc() const { + DCHECK_EQ(FormatOf(Opcode()), k4rcc); + return Fetch16(3); +} + inline bool Instruction::HasVarArgs() const { return FormatOf(Opcode()) == k35c; } -inline void Instruction::GetVarArgs(uint32_t arg[5], uint16_t inst_data) const { +inline void Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const { DCHECK_EQ(FormatOf(Opcode()), k35c); /* |