Home | History | Annotate | Download | only in dex
      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_LIBDEXFILE_DEX_DEX_INSTRUCTION_INL_H_
     18 #define ART_LIBDEXFILE_DEX_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 k45cc: return true;
     53     case k4rcc: return true;
     54     case k51l: return true;
     55     default: return false;
     56   }
     57 }
     58 
     59 inline int32_t Instruction::VRegA() const {
     60   switch (FormatOf(Opcode())) {
     61     case k10t: return VRegA_10t();
     62     case k10x: return VRegA_10x();
     63     case k11n: return VRegA_11n();
     64     case k11x: return VRegA_11x();
     65     case k12x: return VRegA_12x();
     66     case k20t: return VRegA_20t();
     67     case k21c: return VRegA_21c();
     68     case k21h: return VRegA_21h();
     69     case k21s: return VRegA_21s();
     70     case k21t: return VRegA_21t();
     71     case k22b: return VRegA_22b();
     72     case k22c: return VRegA_22c();
     73     case k22s: return VRegA_22s();
     74     case k22t: return VRegA_22t();
     75     case k22x: return VRegA_22x();
     76     case k23x: return VRegA_23x();
     77     case k30t: return VRegA_30t();
     78     case k31c: return VRegA_31c();
     79     case k31i: return VRegA_31i();
     80     case k31t: return VRegA_31t();
     81     case k32x: return VRegA_32x();
     82     case k35c: return VRegA_35c();
     83     case k3rc: return VRegA_3rc();
     84     case k45cc: return VRegA_45cc();
     85     case k4rcc: return VRegA_4rcc();
     86     case k51l: return VRegA_51l();
     87     default:
     88       LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand.";
     89       exit(EXIT_FAILURE);
     90   }
     91 }
     92 
     93 inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
     94   DCHECK_EQ(FormatOf(Opcode()), k10t);
     95   return static_cast<int8_t>(InstAA(inst_data));
     96 }
     97 
     98 inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
     99   DCHECK_EQ(FormatOf(Opcode()), k10x);
    100   return InstAA(inst_data);
    101 }
    102 
    103 inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
    104   DCHECK_EQ(FormatOf(Opcode()), k11n);
    105   return InstA(inst_data);
    106 }
    107 
    108 inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
    109   DCHECK_EQ(FormatOf(Opcode()), k11x);
    110   return InstAA(inst_data);
    111 }
    112 
    113 inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
    114   DCHECK_EQ(FormatOf(Opcode()), k12x);
    115   return InstA(inst_data);
    116 }
    117 
    118 inline int16_t Instruction::VRegA_20t() const {
    119   DCHECK_EQ(FormatOf(Opcode()), k20t);
    120   return static_cast<int16_t>(Fetch16(1));
    121 }
    122 
    123 inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
    124   DCHECK_EQ(FormatOf(Opcode()), k21c);
    125   return InstAA(inst_data);
    126 }
    127 
    128 inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
    129   DCHECK_EQ(FormatOf(Opcode()), k21h);
    130   return InstAA(inst_data);
    131 }
    132 
    133 inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
    134   DCHECK_EQ(FormatOf(Opcode()), k21s);
    135   return InstAA(inst_data);
    136 }
    137 
    138 inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
    139   DCHECK_EQ(FormatOf(Opcode()), k21t);
    140   return InstAA(inst_data);
    141 }
    142 
    143 inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
    144   DCHECK_EQ(FormatOf(Opcode()), k22b);
    145   return InstAA(inst_data);
    146 }
    147 
    148 inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
    149   DCHECK_EQ(FormatOf(Opcode()), k22c);
    150   return InstA(inst_data);
    151 }
    152 
    153 inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
    154   DCHECK_EQ(FormatOf(Opcode()), k22s);
    155   return InstA(inst_data);
    156 }
    157 
    158 inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
    159   DCHECK_EQ(FormatOf(Opcode()), k22t);
    160   return InstA(inst_data);
    161 }
    162 
    163 inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
    164   DCHECK_EQ(FormatOf(Opcode()), k22x);
    165   return InstAA(inst_data);
    166 }
    167 
    168 inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
    169   DCHECK_EQ(FormatOf(Opcode()), k23x);
    170   return InstAA(inst_data);
    171 }
    172 
    173 inline int32_t Instruction::VRegA_30t() const {
    174   DCHECK_EQ(FormatOf(Opcode()), k30t);
    175   return static_cast<int32_t>(Fetch32(1));
    176 }
    177 
    178 inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
    179   DCHECK_EQ(FormatOf(Opcode()), k31c);
    180   return InstAA(inst_data);
    181 }
    182 
    183 inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
    184   DCHECK_EQ(FormatOf(Opcode()), k31i);
    185   return InstAA(inst_data);
    186 }
    187 
    188 inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
    189   DCHECK_EQ(FormatOf(Opcode()), k31t);
    190   return InstAA(inst_data);
    191 }
    192 
    193 inline uint16_t Instruction::VRegA_32x() const {
    194   DCHECK_EQ(FormatOf(Opcode()), k32x);
    195   return Fetch16(1);
    196 }
    197 
    198 inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
    199   DCHECK_EQ(FormatOf(Opcode()), k35c);
    200   return InstB(inst_data);  // This is labeled A in the spec.
    201 }
    202 
    203 inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
    204   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    205   return InstAA(inst_data);
    206 }
    207 
    208 inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
    209   DCHECK_EQ(FormatOf(Opcode()), k51l);
    210   return InstAA(inst_data);
    211 }
    212 
    213 inline uint4_t Instruction::VRegA_45cc(uint16_t inst_data) const {
    214   DCHECK_EQ(FormatOf(Opcode()), k45cc);
    215   return InstB(inst_data);  // This is labeled A in the spec.
    216 }
    217 
    218 inline uint8_t Instruction::VRegA_4rcc(uint16_t inst_data) const {
    219   DCHECK_EQ(FormatOf(Opcode()), k4rcc);
    220   return InstAA(inst_data);
    221 }
    222 
    223 //------------------------------------------------------------------------------
    224 // VRegB
    225 //------------------------------------------------------------------------------
    226 inline bool Instruction::HasVRegB() const {
    227   switch (FormatOf(Opcode())) {
    228     case k11n: return true;
    229     case k12x: return true;
    230     case k21c: return true;
    231     case k21h: return true;
    232     case k21s: return true;
    233     case k21t: return true;
    234     case k22b: return true;
    235     case k22c: return true;
    236     case k22s: return true;
    237     case k22t: return true;
    238     case k22x: return true;
    239     case k23x: return true;
    240     case k31c: return true;
    241     case k31i: return true;
    242     case k31t: return true;
    243     case k32x: return true;
    244     case k35c: return true;
    245     case k3rc: return true;
    246     case k45cc: return true;
    247     case k4rcc: return true;
    248     case k51l: return true;
    249     default: return false;
    250   }
    251 }
    252 
    253 inline bool Instruction::HasWideVRegB() const {
    254   return FormatOf(Opcode()) == k51l;
    255 }
    256 
    257 inline int32_t Instruction::VRegB() const {
    258   switch (FormatOf(Opcode())) {
    259     case k11n: return VRegB_11n();
    260     case k12x: return VRegB_12x();
    261     case k21c: return VRegB_21c();
    262     case k21h: return VRegB_21h();
    263     case k21s: return VRegB_21s();
    264     case k21t: return VRegB_21t();
    265     case k22b: return VRegB_22b();
    266     case k22c: return VRegB_22c();
    267     case k22s: return VRegB_22s();
    268     case k22t: return VRegB_22t();
    269     case k22x: return VRegB_22x();
    270     case k23x: return VRegB_23x();
    271     case k31c: return VRegB_31c();
    272     case k31i: return VRegB_31i();
    273     case k31t: return VRegB_31t();
    274     case k32x: return VRegB_32x();
    275     case k35c: return VRegB_35c();
    276     case k3rc: return VRegB_3rc();
    277     case k45cc: return VRegB_45cc();
    278     case k4rcc: return VRegB_4rcc();
    279     case k51l: return VRegB_51l();
    280     default:
    281       LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
    282       exit(EXIT_FAILURE);
    283   }
    284 }
    285 
    286 inline uint64_t Instruction::WideVRegB() const {
    287   return VRegB_51l();
    288 }
    289 
    290 inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
    291   DCHECK_EQ(FormatOf(Opcode()), k11n);
    292   return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
    293 }
    294 
    295 inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
    296   DCHECK_EQ(FormatOf(Opcode()), k12x);
    297   return InstB(inst_data);
    298 }
    299 
    300 inline uint16_t Instruction::VRegB_21c() const {
    301   DCHECK_EQ(FormatOf(Opcode()), k21c);
    302   return Fetch16(1);
    303 }
    304 
    305 inline uint16_t Instruction::VRegB_21h() const {
    306   DCHECK_EQ(FormatOf(Opcode()), k21h);
    307   return Fetch16(1);
    308 }
    309 
    310 inline int16_t Instruction::VRegB_21s() const {
    311   DCHECK_EQ(FormatOf(Opcode()), k21s);
    312   return static_cast<int16_t>(Fetch16(1));
    313 }
    314 
    315 inline int16_t Instruction::VRegB_21t() const {
    316   DCHECK_EQ(FormatOf(Opcode()), k21t);
    317   return static_cast<int16_t>(Fetch16(1));
    318 }
    319 
    320 inline uint8_t Instruction::VRegB_22b() const {
    321   DCHECK_EQ(FormatOf(Opcode()), k22b);
    322   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    323 }
    324 
    325 inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
    326   DCHECK_EQ(FormatOf(Opcode()), k22c);
    327   return InstB(inst_data);
    328 }
    329 
    330 inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
    331   DCHECK_EQ(FormatOf(Opcode()), k22s);
    332   return InstB(inst_data);
    333 }
    334 
    335 inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
    336   DCHECK_EQ(FormatOf(Opcode()), k22t);
    337   return InstB(inst_data);
    338 }
    339 
    340 inline uint16_t Instruction::VRegB_22x() const {
    341   DCHECK_EQ(FormatOf(Opcode()), k22x);
    342   return Fetch16(1);
    343 }
    344 
    345 inline uint8_t Instruction::VRegB_23x() const {
    346   DCHECK_EQ(FormatOf(Opcode()), k23x);
    347   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    348 }
    349 
    350 inline uint32_t Instruction::VRegB_31c() const {
    351   DCHECK_EQ(FormatOf(Opcode()), k31c);
    352   return Fetch32(1);
    353 }
    354 
    355 inline int32_t Instruction::VRegB_31i() const {
    356   DCHECK_EQ(FormatOf(Opcode()), k31i);
    357   return static_cast<int32_t>(Fetch32(1));
    358 }
    359 
    360 inline int32_t Instruction::VRegB_31t() const {
    361   DCHECK_EQ(FormatOf(Opcode()), k31t);
    362   return static_cast<int32_t>(Fetch32(1));
    363 }
    364 
    365 inline uint16_t Instruction::VRegB_32x() const {
    366   DCHECK_EQ(FormatOf(Opcode()), k32x);
    367   return Fetch16(2);
    368 }
    369 
    370 inline uint16_t Instruction::VRegB_35c() const {
    371   DCHECK_EQ(FormatOf(Opcode()), k35c);
    372   return Fetch16(1);
    373 }
    374 
    375 inline uint16_t Instruction::VRegB_3rc() const {
    376   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    377   return Fetch16(1);
    378 }
    379 
    380 inline uint16_t Instruction::VRegB_45cc() const {
    381   DCHECK_EQ(FormatOf(Opcode()), k45cc);
    382   return Fetch16(1);
    383 }
    384 
    385 inline uint16_t Instruction::VRegB_4rcc() const {
    386   DCHECK_EQ(FormatOf(Opcode()), k4rcc);
    387   return Fetch16(1);
    388 }
    389 
    390 inline uint64_t Instruction::VRegB_51l() const {
    391   DCHECK_EQ(FormatOf(Opcode()), k51l);
    392   uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
    393   return vB_wide;
    394 }
    395 
    396 //------------------------------------------------------------------------------
    397 // VRegC
    398 //------------------------------------------------------------------------------
    399 inline bool Instruction::HasVRegC() const {
    400   switch (FormatOf(Opcode())) {
    401     case k22b: return true;
    402     case k22c: return true;
    403     case k22s: return true;
    404     case k22t: return true;
    405     case k23x: return true;
    406     case k35c: return true;
    407     case k3rc: return true;
    408     case k45cc: return true;
    409     case k4rcc: return true;
    410     default: return false;
    411   }
    412 }
    413 
    414 inline int32_t Instruction::VRegC() const {
    415   switch (FormatOf(Opcode())) {
    416     case k22b: return VRegC_22b();
    417     case k22c: return VRegC_22c();
    418     case k22s: return VRegC_22s();
    419     case k22t: return VRegC_22t();
    420     case k23x: return VRegC_23x();
    421     case k35c: return VRegC_35c();
    422     case k3rc: return VRegC_3rc();
    423     case k45cc: return VRegC_45cc();
    424     case k4rcc: return VRegC_4rcc();
    425     default:
    426       LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
    427       exit(EXIT_FAILURE);
    428   }
    429 }
    430 
    431 inline int8_t Instruction::VRegC_22b() const {
    432   DCHECK_EQ(FormatOf(Opcode()), k22b);
    433   return static_cast<int8_t>(Fetch16(1) >> 8);
    434 }
    435 
    436 inline uint16_t Instruction::VRegC_22c() const {
    437   DCHECK_EQ(FormatOf(Opcode()), k22c);
    438   return Fetch16(1);
    439 }
    440 
    441 inline int16_t Instruction::VRegC_22s() const {
    442   DCHECK_EQ(FormatOf(Opcode()), k22s);
    443   return static_cast<int16_t>(Fetch16(1));
    444 }
    445 
    446 inline int16_t Instruction::VRegC_22t() const {
    447   DCHECK_EQ(FormatOf(Opcode()), k22t);
    448   return static_cast<int16_t>(Fetch16(1));
    449 }
    450 
    451 inline uint8_t Instruction::VRegC_23x() const {
    452   DCHECK_EQ(FormatOf(Opcode()), k23x);
    453   return static_cast<uint8_t>(Fetch16(1) >> 8);
    454 }
    455 
    456 inline uint4_t Instruction::VRegC_35c() const {
    457   DCHECK_EQ(FormatOf(Opcode()), k35c);
    458   return static_cast<uint4_t>(Fetch16(2) & 0x0f);
    459 }
    460 
    461 inline uint16_t Instruction::VRegC_3rc() const {
    462   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    463   return Fetch16(2);
    464 }
    465 
    466 inline uint4_t Instruction::VRegC_45cc() const {
    467   DCHECK_EQ(FormatOf(Opcode()), k45cc);
    468   return static_cast<uint4_t>(Fetch16(2) & 0x0f);
    469 }
    470 
    471 inline uint16_t Instruction::VRegC_4rcc() const {
    472   DCHECK_EQ(FormatOf(Opcode()), k4rcc);
    473   return Fetch16(2);
    474 }
    475 
    476 //------------------------------------------------------------------------------
    477 // VRegH
    478 //------------------------------------------------------------------------------
    479 inline bool Instruction::HasVRegH() const {
    480   switch (FormatOf(Opcode())) {
    481     case k45cc: return true;
    482     case k4rcc: return true;
    483     default : return false;
    484   }
    485 }
    486 
    487 inline int32_t Instruction::VRegH() const {
    488   switch (FormatOf(Opcode())) {
    489     case k45cc: return VRegH_45cc();
    490     case k4rcc: return VRegH_4rcc();
    491     default :
    492       LOG(FATAL) << "Tried to access vH of instruction " << Name() << " which has no H operand.";
    493       exit(EXIT_FAILURE);
    494   }
    495 }
    496 
    497 inline uint16_t Instruction::VRegH_45cc() const {
    498   DCHECK_EQ(FormatOf(Opcode()), k45cc);
    499   return Fetch16(3);
    500 }
    501 
    502 inline uint16_t Instruction::VRegH_4rcc() const {
    503   DCHECK_EQ(FormatOf(Opcode()), k4rcc);
    504   return Fetch16(3);
    505 }
    506 
    507 inline bool Instruction::HasVarArgs() const {
    508   return (FormatOf(Opcode()) == k35c) || (FormatOf(Opcode()) == k45cc);
    509 }
    510 
    511 inline void Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const {
    512   DCHECK(HasVarArgs());
    513 
    514   /*
    515    * Note that the fields mentioned in the spec don't appear in
    516    * their "usual" positions here compared to most formats. This
    517    * was done so that the field names for the argument count and
    518    * reference index match between this format and the corresponding
    519    * range formats (3rc and friends).
    520    *
    521    * Bottom line: The argument count is always in vA, and the
    522    * method constant (or equivalent) is always in vB.
    523    */
    524   uint16_t regList = Fetch16(2);
    525   uint4_t count = InstB(inst_data);  // This is labeled A in the spec.
    526   DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
    527 
    528   /*
    529    * Copy the argument registers into the arg[] array, and
    530    * also copy the first argument (if any) into vC. (The
    531    * DecodedInstruction structure doesn't have separate
    532    * fields for {vD, vE, vF, vG}, so there's no need to make
    533    * copies of those.) Note that cases 5..2 fall through.
    534    */
    535   switch (count) {
    536     case 5:
    537       arg[4] = InstA(inst_data);
    538       FALLTHROUGH_INTENDED;
    539     case 4:
    540       arg[3] = (regList >> 12) & 0x0f;
    541       FALLTHROUGH_INTENDED;
    542     case 3:
    543       arg[2] = (regList >> 8) & 0x0f;
    544       FALLTHROUGH_INTENDED;
    545     case 2:
    546       arg[1] = (regList >> 4) & 0x0f;
    547       FALLTHROUGH_INTENDED;
    548     case 1:
    549       arg[0] = regList & 0x0f;
    550       break;
    551     default:  // case 0
    552       break;  // Valid, but no need to do anything.
    553   }
    554 }
    555 
    556 }  // namespace art
    557 
    558 #endif  // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_INL_H_
    559