diff options
Diffstat (limited to 'runtime/dex_instruction-inl.h')
| -rw-r--r-- | runtime/dex_instruction-inl.h | 147 |
1 files changed, 68 insertions, 79 deletions
diff --git a/runtime/dex_instruction-inl.h b/runtime/dex_instruction-inl.h index e160a103d9..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 //------------------------------------------------------------------------------ @@ -223,13 +237,14 @@ inline bool Instruction::HasVRegB() const { case k22t: return true; case k22x: return true; case k23x: return true; - case k25x: return true; case k31c: return true; case k31i: return true; case k31t: return true; 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; } @@ -253,13 +268,14 @@ inline int32_t Instruction::VRegB() const { case k22t: return VRegB_22t(); case k22x: return VRegB_22x(); case k23x: return VRegB_23x(); - case k25x: return VRegB_25x(); case k31c: return VRegB_31c(); case k31i: return VRegB_31i(); case k31t: return VRegB_31t(); 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."; @@ -331,12 +347,6 @@ inline uint8_t Instruction::VRegB_23x() const { return static_cast<uint8_t>(Fetch16(1) & 0xff); } -// Number of additional registers in this instruction. # of var arg registers = this value + 1. -inline uint4_t Instruction::VRegB_25x() const { - DCHECK_EQ(FormatOf(Opcode()), k25x); - return InstB(Fetch16(0)); -} - inline uint32_t Instruction::VRegB_31c() const { DCHECK_EQ(FormatOf(Opcode()), k31c); return Fetch32(1); @@ -367,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); @@ -383,9 +403,10 @@ inline bool Instruction::HasVRegC() const { case k22s: return true; case k22t: return true; case k23x: return true; - case k25x: return true; case k35c: return true; case k3rc: return true; + case k45cc: return true; + case k4rcc: return true; default: return false; } } @@ -397,9 +418,10 @@ inline int32_t Instruction::VRegC() const { case k22s: return VRegC_22s(); case k22t: return VRegC_22t(); case k23x: return VRegC_23x(); - case k25x: return VRegC_25x(); 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 +453,6 @@ inline uint8_t Instruction::VRegC_23x() const { return static_cast<uint8_t>(Fetch16(1) >> 8); } -inline uint4_t Instruction::VRegC_25x() const { - DCHECK_EQ(FormatOf(Opcode()), k25x); - return static_cast<uint4_t>(Fetch16(1) & 0xf); -} - inline uint4_t Instruction::VRegC_35c() const { DCHECK_EQ(FormatOf(Opcode()), k35c); return static_cast<uint4_t>(Fetch16(2) & 0x0f); @@ -446,77 +463,49 @@ inline uint16_t Instruction::VRegC_3rc() const { return Fetch16(2); } -inline bool Instruction::HasVarArgs35c() const { - return FormatOf(Opcode()) == k35c; +inline uint4_t Instruction::VRegC_45cc() const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return static_cast<uint4_t>(Fetch16(2) & 0x0f); } -inline bool Instruction::HasVarArgs25x() const { - return FormatOf(Opcode()) == k25x; +inline uint16_t Instruction::VRegC_4rcc() const { + DCHECK_EQ(FormatOf(Opcode()), k4rcc); + return Fetch16(2); } -// Copies all of the parameter registers into the arg array. Check the length with VRegB_25x()+2. -inline void Instruction::GetAllArgs25x(uint32_t (&arg)[kMaxVarArgRegs25x]) const { - DCHECK_EQ(FormatOf(Opcode()), k25x); +//------------------------------------------------------------------------------ +// VRegH +//------------------------------------------------------------------------------ +inline bool Instruction::HasVRegH() const { + switch (FormatOf(Opcode())) { + case k45cc: return true; + case k4rcc: return true; + default : return false; + } +} - /* - * The opcode looks like this: - * op vC, {vD, vE, vF, vG} - * - * and vB is the (implicit) register count (0-4) which denotes how far from vD to vG to read. - * - * vC is always present, so with "op vC, {}" the register count will be 0 even though vC - * is valid. - * - * The exact semantic meanings of vC:vG is up to the instruction using the format. - * - * Encoding drawing as a bit stream: - * (Note that each uint16 is little endian, and each register takes up 4 bits) - * - * uint16 ||| uint16 - * 7-0 15-8 7-0 15-8 - * |------|-----|||-----|-----| - * |opcode|vB|vG|||vD|vC|vF|vE| - * |------|-----|||-----|-----| - */ - uint16_t reg_list = Fetch16(1); - uint4_t count = VRegB_25x(); - DCHECK_LE(count, 4U) << "Invalid arg count in 25x (" << count << ")"; +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); + } +} - /* - * TODO(iam): Change instruction encoding to one of: - * - * - (X) vA = args count, vB = closure register, {vC..vG} = args (25x) - * - (Y) vA = args count, vB = method index, {vC..vG} = args (35x) - * - * (do this in conjunction with adding verifier support for invoke-lambda) - */ +inline uint16_t Instruction::VRegH_45cc() const { + DCHECK_EQ(FormatOf(Opcode()), k45cc); + return Fetch16(3); +} - /* - * Copy the argument registers into the arg[] array, and - * also copy the first argument into vC. (The - * DecodedInstruction structure doesn't have separate - * fields for {vD, vE, vF, vG}, so there's no need to make - * copies of those.) Note that all cases fall-through. - */ - switch (count) { - case 4: - arg[5] = (Fetch16(0) >> 8) & 0x0f; // vG - FALLTHROUGH_INTENDED; - case 3: - arg[4] = (reg_list >> 12) & 0x0f; // vF - FALLTHROUGH_INTENDED; - case 2: - arg[3] = (reg_list >> 8) & 0x0f; // vE - FALLTHROUGH_INTENDED; - case 1: - arg[2] = (reg_list >> 4) & 0x0f; // vD - FALLTHROUGH_INTENDED; - default: // case 0 - // The required lambda 'this' is actually a pair, but the pair is implicit. - arg[0] = VRegC_25x(); // vC - arg[1] = arg[0] + 1; // vC + 1 - break; - } +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[kMaxVarArgRegs], uint16_t inst_data) const { |