summaryrefslogtreecommitdiff
path: root/runtime/dex_instruction-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/dex_instruction-inl.h')
-rw-r--r--runtime/dex_instruction-inl.h147
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 {