Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_DEX_INSTRUCTION_INL_H_
     18 #define ART_RUNTIME_DEX_INSTRUCTION_INL_H_
     19 
     20 #include "dex_instruction.h"
     21 
     22 namespace art {
     23 
     24 //------------------------------------------------------------------------------
     25 // VRegA
     26 //------------------------------------------------------------------------------
     27 inline bool Instruction::HasVRegA() const {
     28   switch (FormatOf(Opcode())) {
     29     case k10t: return true;
     30     case k10x: return true;
     31     case k11n: return true;
     32     case k11x: return true;
     33     case k12x: return true;
     34     case k20t: return true;
     35     case k21c: return true;
     36     case k21h: return true;
     37     case k21s: return true;
     38     case k21t: return true;
     39     case k22b: return true;
     40     case k22c: return true;
     41     case k22s: return true;
     42     case k22t: return true;
     43     case k22x: return true;
     44     case k23x: return true;
     45     case k30t: return true;
     46     case k31c: return true;
     47     case k31i: return true;
     48     case k31t: return true;
     49     case k32x: return true;
     50     case k35c: return true;
     51     case k3rc: return true;
     52     case k51l: return true;
     53     default: return false;
     54   }
     55 }
     56 
     57 inline int32_t Instruction::VRegA() const {
     58   switch (FormatOf(Opcode())) {
     59     case k10t: return VRegA_10t();
     60     case k10x: return VRegA_10x();
     61     case k11n: return VRegA_11n();
     62     case k11x: return VRegA_11x();
     63     case k12x: return VRegA_12x();
     64     case k20t: return VRegA_20t();
     65     case k21c: return VRegA_21c();
     66     case k21h: return VRegA_21h();
     67     case k21s: return VRegA_21s();
     68     case k21t: return VRegA_21t();
     69     case k22b: return VRegA_22b();
     70     case k22c: return VRegA_22c();
     71     case k22s: return VRegA_22s();
     72     case k22t: return VRegA_22t();
     73     case k22x: return VRegA_22x();
     74     case k23x: return VRegA_23x();
     75     case k30t: return VRegA_30t();
     76     case k31c: return VRegA_31c();
     77     case k31i: return VRegA_31i();
     78     case k31t: return VRegA_31t();
     79     case k32x: return VRegA_32x();
     80     case k35c: return VRegA_35c();
     81     case k3rc: return VRegA_3rc();
     82     case k51l: return VRegA_51l();
     83     default:
     84       LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand.";
     85       exit(EXIT_FAILURE);
     86   }
     87 }
     88 
     89 inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
     90   DCHECK_EQ(FormatOf(Opcode()), k10t);
     91   return static_cast<int8_t>(InstAA(inst_data));
     92 }
     93 
     94 inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
     95   DCHECK_EQ(FormatOf(Opcode()), k10x);
     96   return InstAA(inst_data);
     97 }
     98 
     99 inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
    100   DCHECK_EQ(FormatOf(Opcode()), k11n);
    101   return InstA(inst_data);
    102 }
    103 
    104 inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
    105   DCHECK_EQ(FormatOf(Opcode()), k11x);
    106   return InstAA(inst_data);
    107 }
    108 
    109 inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
    110   DCHECK_EQ(FormatOf(Opcode()), k12x);
    111   return InstA(inst_data);
    112 }
    113 
    114 inline int16_t Instruction::VRegA_20t() const {
    115   DCHECK_EQ(FormatOf(Opcode()), k20t);
    116   return static_cast<int16_t>(Fetch16(1));
    117 }
    118 
    119 inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
    120   DCHECK_EQ(FormatOf(Opcode()), k21c);
    121   return InstAA(inst_data);
    122 }
    123 
    124 inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
    125   DCHECK_EQ(FormatOf(Opcode()), k21h);
    126   return InstAA(inst_data);
    127 }
    128 
    129 inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
    130   DCHECK_EQ(FormatOf(Opcode()), k21s);
    131   return InstAA(inst_data);
    132 }
    133 
    134 inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
    135   DCHECK_EQ(FormatOf(Opcode()), k21t);
    136   return InstAA(inst_data);
    137 }
    138 
    139 inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
    140   DCHECK_EQ(FormatOf(Opcode()), k22b);
    141   return InstAA(inst_data);
    142 }
    143 
    144 inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
    145   DCHECK_EQ(FormatOf(Opcode()), k22c);
    146   return InstA(inst_data);
    147 }
    148 
    149 inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
    150   DCHECK_EQ(FormatOf(Opcode()), k22s);
    151   return InstA(inst_data);
    152 }
    153 
    154 inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
    155   DCHECK_EQ(FormatOf(Opcode()), k22t);
    156   return InstA(inst_data);
    157 }
    158 
    159 inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
    160   DCHECK_EQ(FormatOf(Opcode()), k22x);
    161   return InstAA(inst_data);
    162 }
    163 
    164 inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
    165   DCHECK_EQ(FormatOf(Opcode()), k23x);
    166   return InstAA(inst_data);
    167 }
    168 
    169 inline int32_t Instruction::VRegA_30t() const {
    170   DCHECK_EQ(FormatOf(Opcode()), k30t);
    171   return static_cast<int32_t>(Fetch32(1));
    172 }
    173 
    174 inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
    175   DCHECK_EQ(FormatOf(Opcode()), k31c);
    176   return InstAA(inst_data);
    177 }
    178 
    179 inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
    180   DCHECK_EQ(FormatOf(Opcode()), k31i);
    181   return InstAA(inst_data);
    182 }
    183 
    184 inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
    185   DCHECK_EQ(FormatOf(Opcode()), k31t);
    186   return InstAA(inst_data);
    187 }
    188 
    189 inline uint16_t Instruction::VRegA_32x() const {
    190   DCHECK_EQ(FormatOf(Opcode()), k32x);
    191   return Fetch16(1);
    192 }
    193 
    194 inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
    195   DCHECK_EQ(FormatOf(Opcode()), k35c);
    196   return InstB(inst_data);  // This is labeled A in the spec.
    197 }
    198 
    199 inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
    200   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    201   return InstAA(inst_data);
    202 }
    203 
    204 inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
    205   DCHECK_EQ(FormatOf(Opcode()), k51l);
    206   return InstAA(inst_data);
    207 }
    208 
    209 //------------------------------------------------------------------------------
    210 // VRegB
    211 //------------------------------------------------------------------------------
    212 inline bool Instruction::HasVRegB() const {
    213   switch (FormatOf(Opcode())) {
    214     case k11n: return true;
    215     case k12x: return true;
    216     case k21c: return true;
    217     case k21h: return true;
    218     case k21s: return true;
    219     case k21t: return true;
    220     case k22b: return true;
    221     case k22c: return true;
    222     case k22s: return true;
    223     case k22t: return true;
    224     case k22x: return true;
    225     case k23x: return true;
    226     case k25x: return true;
    227     case k31c: return true;
    228     case k31i: return true;
    229     case k31t: return true;
    230     case k32x: return true;
    231     case k35c: return true;
    232     case k3rc: return true;
    233     case k51l: return true;
    234     default: return false;
    235   }
    236 }
    237 
    238 inline bool Instruction::HasWideVRegB() const {
    239   return FormatOf(Opcode()) == k51l;
    240 }
    241 
    242 inline int32_t Instruction::VRegB() const {
    243   switch (FormatOf(Opcode())) {
    244     case k11n: return VRegB_11n();
    245     case k12x: return VRegB_12x();
    246     case k21c: return VRegB_21c();
    247     case k21h: return VRegB_21h();
    248     case k21s: return VRegB_21s();
    249     case k21t: return VRegB_21t();
    250     case k22b: return VRegB_22b();
    251     case k22c: return VRegB_22c();
    252     case k22s: return VRegB_22s();
    253     case k22t: return VRegB_22t();
    254     case k22x: return VRegB_22x();
    255     case k23x: return VRegB_23x();
    256     case k25x: return VRegB_25x();
    257     case k31c: return VRegB_31c();
    258     case k31i: return VRegB_31i();
    259     case k31t: return VRegB_31t();
    260     case k32x: return VRegB_32x();
    261     case k35c: return VRegB_35c();
    262     case k3rc: return VRegB_3rc();
    263     case k51l: return VRegB_51l();
    264     default:
    265       LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
    266       exit(EXIT_FAILURE);
    267   }
    268 }
    269 
    270 inline uint64_t Instruction::WideVRegB() const {
    271   return VRegB_51l();
    272 }
    273 
    274 inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
    275   DCHECK_EQ(FormatOf(Opcode()), k11n);
    276   return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
    277 }
    278 
    279 inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
    280   DCHECK_EQ(FormatOf(Opcode()), k12x);
    281   return InstB(inst_data);
    282 }
    283 
    284 inline uint16_t Instruction::VRegB_21c() const {
    285   DCHECK_EQ(FormatOf(Opcode()), k21c);
    286   return Fetch16(1);
    287 }
    288 
    289 inline uint16_t Instruction::VRegB_21h() const {
    290   DCHECK_EQ(FormatOf(Opcode()), k21h);
    291   return Fetch16(1);
    292 }
    293 
    294 inline int16_t Instruction::VRegB_21s() const {
    295   DCHECK_EQ(FormatOf(Opcode()), k21s);
    296   return static_cast<int16_t>(Fetch16(1));
    297 }
    298 
    299 inline int16_t Instruction::VRegB_21t() const {
    300   DCHECK_EQ(FormatOf(Opcode()), k21t);
    301   return static_cast<int16_t>(Fetch16(1));
    302 }
    303 
    304 inline uint8_t Instruction::VRegB_22b() const {
    305   DCHECK_EQ(FormatOf(Opcode()), k22b);
    306   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    307 }
    308 
    309 inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
    310   DCHECK_EQ(FormatOf(Opcode()), k22c);
    311   return InstB(inst_data);
    312 }
    313 
    314 inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
    315   DCHECK_EQ(FormatOf(Opcode()), k22s);
    316   return InstB(inst_data);
    317 }
    318 
    319 inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
    320   DCHECK_EQ(FormatOf(Opcode()), k22t);
    321   return InstB(inst_data);
    322 }
    323 
    324 inline uint16_t Instruction::VRegB_22x() const {
    325   DCHECK_EQ(FormatOf(Opcode()), k22x);
    326   return Fetch16(1);
    327 }
    328 
    329 inline uint8_t Instruction::VRegB_23x() const {
    330   DCHECK_EQ(FormatOf(Opcode()), k23x);
    331   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    332 }
    333 
    334 // Number of additional registers in this instruction. # of var arg registers = this value + 1.
    335 inline uint4_t Instruction::VRegB_25x() const {
    336   DCHECK_EQ(FormatOf(Opcode()), k25x);
    337   return InstB(Fetch16(0));
    338 }
    339 
    340 inline uint32_t Instruction::VRegB_31c() const {
    341   DCHECK_EQ(FormatOf(Opcode()), k31c);
    342   return Fetch32(1);
    343 }
    344 
    345 inline int32_t Instruction::VRegB_31i() const {
    346   DCHECK_EQ(FormatOf(Opcode()), k31i);
    347   return static_cast<int32_t>(Fetch32(1));
    348 }
    349 
    350 inline int32_t Instruction::VRegB_31t() const {
    351   DCHECK_EQ(FormatOf(Opcode()), k31t);
    352   return static_cast<int32_t>(Fetch32(1));
    353 }
    354 
    355 inline uint16_t Instruction::VRegB_32x() const {
    356   DCHECK_EQ(FormatOf(Opcode()), k32x);
    357   return Fetch16(2);
    358 }
    359 
    360 inline uint16_t Instruction::VRegB_35c() const {
    361   DCHECK_EQ(FormatOf(Opcode()), k35c);
    362   return Fetch16(1);
    363 }
    364 
    365 inline uint16_t Instruction::VRegB_3rc() const {
    366   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    367   return Fetch16(1);
    368 }
    369 
    370 inline uint64_t Instruction::VRegB_51l() const {
    371   DCHECK_EQ(FormatOf(Opcode()), k51l);
    372   uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
    373   return vB_wide;
    374 }
    375 
    376 //------------------------------------------------------------------------------
    377 // VRegC
    378 //------------------------------------------------------------------------------
    379 inline bool Instruction::HasVRegC() const {
    380   switch (FormatOf(Opcode())) {
    381     case k22b: return true;
    382     case k22c: return true;
    383     case k22s: return true;
    384     case k22t: return true;
    385     case k23x: return true;
    386     case k25x: return true;
    387     case k35c: return true;
    388     case k3rc: return true;
    389     default: return false;
    390   }
    391 }
    392 
    393 inline int32_t Instruction::VRegC() const {
    394   switch (FormatOf(Opcode())) {
    395     case k22b: return VRegC_22b();
    396     case k22c: return VRegC_22c();
    397     case k22s: return VRegC_22s();
    398     case k22t: return VRegC_22t();
    399     case k23x: return VRegC_23x();
    400     case k25x: return VRegC_25x();
    401     case k35c: return VRegC_35c();
    402     case k3rc: return VRegC_3rc();
    403     default:
    404       LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
    405       exit(EXIT_FAILURE);
    406   }
    407 }
    408 
    409 inline int8_t Instruction::VRegC_22b() const {
    410   DCHECK_EQ(FormatOf(Opcode()), k22b);
    411   return static_cast<int8_t>(Fetch16(1) >> 8);
    412 }
    413 
    414 inline uint16_t Instruction::VRegC_22c() const {
    415   DCHECK_EQ(FormatOf(Opcode()), k22c);
    416   return Fetch16(1);
    417 }
    418 
    419 inline int16_t Instruction::VRegC_22s() const {
    420   DCHECK_EQ(FormatOf(Opcode()), k22s);
    421   return static_cast<int16_t>(Fetch16(1));
    422 }
    423 
    424 inline int16_t Instruction::VRegC_22t() const {
    425   DCHECK_EQ(FormatOf(Opcode()), k22t);
    426   return static_cast<int16_t>(Fetch16(1));
    427 }
    428 
    429 inline uint8_t Instruction::VRegC_23x() const {
    430   DCHECK_EQ(FormatOf(Opcode()), k23x);
    431   return static_cast<uint8_t>(Fetch16(1) >> 8);
    432 }
    433 
    434 inline uint4_t Instruction::VRegC_25x() const {
    435   DCHECK_EQ(FormatOf(Opcode()), k25x);
    436   return static_cast<uint4_t>(Fetch16(1) & 0xf);
    437 }
    438 
    439 inline uint4_t Instruction::VRegC_35c() const {
    440   DCHECK_EQ(FormatOf(Opcode()), k35c);
    441   return static_cast<uint4_t>(Fetch16(2) & 0x0f);
    442 }
    443 
    444 inline uint16_t Instruction::VRegC_3rc() const {
    445   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    446   return Fetch16(2);
    447 }
    448 
    449 inline bool Instruction::HasVarArgs35c() const {
    450   return FormatOf(Opcode()) == k35c;
    451 }
    452 
    453 inline bool Instruction::HasVarArgs25x() const {
    454   return FormatOf(Opcode()) == k25x;
    455 }
    456 
    457 // Copies all of the parameter registers into the arg array. Check the length with VRegB_25x()+2.
    458 inline void Instruction::GetAllArgs25x(uint32_t (&arg)[kMaxVarArgRegs25x]) const {
    459   DCHECK_EQ(FormatOf(Opcode()), k25x);
    460 
    461   /*
    462    * The opcode looks like this:
    463    *   op vC, {vD, vE, vF, vG}
    464    *
    465    *  and vB is the (implicit) register count (0-4) which denotes how far from vD to vG to read.
    466    *
    467    *  vC is always present, so with "op vC, {}" the register count will be 0 even though vC
    468    *  is valid.
    469    *
    470    *  The exact semantic meanings of vC:vG is up to the instruction using the format.
    471    *
    472    *  Encoding drawing as a bit stream:
    473    *  (Note that each uint16 is little endian, and each register takes up 4 bits)
    474    *
    475    *       uint16  |||   uint16
    476    *   7-0     15-8    7-0   15-8
    477    *  |------|-----|||-----|-----|
    478    *  |opcode|vB|vG|||vD|vC|vF|vE|
    479    *  |------|-----|||-----|-----|
    480    */
    481   uint16_t reg_list = Fetch16(1);
    482   uint4_t count = VRegB_25x();
    483   DCHECK_LE(count, 4U) << "Invalid arg count in 25x (" << count << ")";
    484 
    485   /*
    486    * TODO(iam): Change instruction encoding to one of:
    487    *
    488    * - (X) vA = args count, vB = closure register, {vC..vG} = args (25x)
    489    * - (Y) vA = args count, vB = method index, {vC..vG} = args (35x)
    490    *
    491    * (do this in conjunction with adding verifier support for invoke-lambda)
    492    */
    493 
    494   /*
    495    * Copy the argument registers into the arg[] array, and
    496    * also copy the first argument into vC. (The
    497    * DecodedInstruction structure doesn't have separate
    498    * fields for {vD, vE, vF, vG}, so there's no need to make
    499    * copies of those.) Note that all cases fall-through.
    500    */
    501   switch (count) {
    502     case 4:
    503       arg[5] = (Fetch16(0) >> 8) & 0x0f;  // vG
    504       FALLTHROUGH_INTENDED;
    505     case 3:
    506       arg[4] = (reg_list >> 12) & 0x0f;  // vF
    507       FALLTHROUGH_INTENDED;
    508     case 2:
    509       arg[3] = (reg_list >> 8) & 0x0f;  // vE
    510       FALLTHROUGH_INTENDED;
    511     case 1:
    512       arg[2] = (reg_list >> 4) & 0x0f;  // vD
    513       FALLTHROUGH_INTENDED;
    514     default:  // case 0
    515       // The required lambda 'this' is actually a pair, but the pair is implicit.
    516       arg[0] = VRegC_25x();  // vC
    517       arg[1] = arg[0] + 1;   // vC + 1
    518       break;
    519   }
    520 }
    521 
    522 inline void Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const {
    523   DCHECK_EQ(FormatOf(Opcode()), k35c);
    524 
    525   /*
    526    * Note that the fields mentioned in the spec don't appear in
    527    * their "usual" positions here compared to most formats. This
    528    * was done so that the field names for the argument count and
    529    * reference index match between this format and the corresponding
    530    * range formats (3rc and friends).
    531    *
    532    * Bottom line: The argument count is always in vA, and the
    533    * method constant (or equivalent) is always in vB.
    534    */
    535   uint16_t regList = Fetch16(2);
    536   uint4_t count = InstB(inst_data);  // This is labeled A in the spec.
    537   DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
    538 
    539   /*
    540    * Copy the argument registers into the arg[] array, and
    541    * also copy the first argument (if any) into vC. (The
    542    * DecodedInstruction structure doesn't have separate
    543    * fields for {vD, vE, vF, vG}, so there's no need to make
    544    * copies of those.) Note that cases 5..2 fall through.
    545    */
    546   switch (count) {
    547     case 5:
    548       arg[4] = InstA(inst_data);
    549       FALLTHROUGH_INTENDED;
    550     case 4:
    551       arg[3] = (regList >> 12) & 0x0f;
    552       FALLTHROUGH_INTENDED;
    553     case 3:
    554       arg[2] = (regList >> 8) & 0x0f;
    555       FALLTHROUGH_INTENDED;
    556     case 2:
    557       arg[1] = (regList >> 4) & 0x0f;
    558       FALLTHROUGH_INTENDED;
    559     case 1:
    560       arg[0] = regList & 0x0f;
    561       break;
    562     default:  // case 0
    563       break;  // Valid, but no need to do anything.
    564   }
    565 }
    566 
    567 }  // namespace art
    568 
    569 #endif  // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
    570