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 k31c: return true;
    227     case k31i: return true;
    228     case k31t: return true;
    229     case k32x: return true;
    230     case k35c: return true;
    231     case k3rc: return true;
    232     case k51l: return true;
    233     default: return false;
    234   }
    235 }
    236 
    237 inline bool Instruction::HasWideVRegB() const {
    238   return FormatOf(Opcode()) == k51l;
    239 }
    240 
    241 inline int32_t Instruction::VRegB() const {
    242   switch (FormatOf(Opcode())) {
    243     case k11n: return VRegB_11n();
    244     case k12x: return VRegB_12x();
    245     case k21c: return VRegB_21c();
    246     case k21h: return VRegB_21h();
    247     case k21s: return VRegB_21s();
    248     case k21t: return VRegB_21t();
    249     case k22b: return VRegB_22b();
    250     case k22c: return VRegB_22c();
    251     case k22s: return VRegB_22s();
    252     case k22t: return VRegB_22t();
    253     case k22x: return VRegB_22x();
    254     case k23x: return VRegB_23x();
    255     case k31c: return VRegB_31c();
    256     case k31i: return VRegB_31i();
    257     case k31t: return VRegB_31t();
    258     case k32x: return VRegB_32x();
    259     case k35c: return VRegB_35c();
    260     case k3rc: return VRegB_3rc();
    261     case k51l: return VRegB_51l();
    262     default:
    263       LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
    264       exit(EXIT_FAILURE);
    265   }
    266 }
    267 
    268 inline uint64_t Instruction::WideVRegB() const {
    269   return VRegB_51l();
    270 }
    271 
    272 inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
    273   DCHECK_EQ(FormatOf(Opcode()), k11n);
    274   return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
    275 }
    276 
    277 inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
    278   DCHECK_EQ(FormatOf(Opcode()), k12x);
    279   return InstB(inst_data);
    280 }
    281 
    282 inline uint16_t Instruction::VRegB_21c() const {
    283   DCHECK_EQ(FormatOf(Opcode()), k21c);
    284   return Fetch16(1);
    285 }
    286 
    287 inline uint16_t Instruction::VRegB_21h() const {
    288   DCHECK_EQ(FormatOf(Opcode()), k21h);
    289   return Fetch16(1);
    290 }
    291 
    292 inline int16_t Instruction::VRegB_21s() const {
    293   DCHECK_EQ(FormatOf(Opcode()), k21s);
    294   return static_cast<int16_t>(Fetch16(1));
    295 }
    296 
    297 inline int16_t Instruction::VRegB_21t() const {
    298   DCHECK_EQ(FormatOf(Opcode()), k21t);
    299   return static_cast<int16_t>(Fetch16(1));
    300 }
    301 
    302 inline uint8_t Instruction::VRegB_22b() const {
    303   DCHECK_EQ(FormatOf(Opcode()), k22b);
    304   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    305 }
    306 
    307 inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
    308   DCHECK_EQ(FormatOf(Opcode()), k22c);
    309   return InstB(inst_data);
    310 }
    311 
    312 inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
    313   DCHECK_EQ(FormatOf(Opcode()), k22s);
    314   return InstB(inst_data);
    315 }
    316 
    317 inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
    318   DCHECK_EQ(FormatOf(Opcode()), k22t);
    319   return InstB(inst_data);
    320 }
    321 
    322 inline uint16_t Instruction::VRegB_22x() const {
    323   DCHECK_EQ(FormatOf(Opcode()), k22x);
    324   return Fetch16(1);
    325 }
    326 
    327 inline uint8_t Instruction::VRegB_23x() const {
    328   DCHECK_EQ(FormatOf(Opcode()), k23x);
    329   return static_cast<uint8_t>(Fetch16(1) & 0xff);
    330 }
    331 
    332 inline uint32_t Instruction::VRegB_31c() const {
    333   DCHECK_EQ(FormatOf(Opcode()), k31c);
    334   return Fetch32(1);
    335 }
    336 
    337 inline int32_t Instruction::VRegB_31i() const {
    338   DCHECK_EQ(FormatOf(Opcode()), k31i);
    339   return static_cast<int32_t>(Fetch32(1));
    340 }
    341 
    342 inline int32_t Instruction::VRegB_31t() const {
    343   DCHECK_EQ(FormatOf(Opcode()), k31t);
    344   return static_cast<int32_t>(Fetch32(1));
    345 }
    346 
    347 inline uint16_t Instruction::VRegB_32x() const {
    348   DCHECK_EQ(FormatOf(Opcode()), k32x);
    349   return Fetch16(2);
    350 }
    351 
    352 inline uint16_t Instruction::VRegB_35c() const {
    353   DCHECK_EQ(FormatOf(Opcode()), k35c);
    354   return Fetch16(1);
    355 }
    356 
    357 inline uint16_t Instruction::VRegB_3rc() const {
    358   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    359   return Fetch16(1);
    360 }
    361 
    362 inline uint64_t Instruction::VRegB_51l() const {
    363   DCHECK_EQ(FormatOf(Opcode()), k51l);
    364   uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
    365   return vB_wide;
    366 }
    367 
    368 //------------------------------------------------------------------------------
    369 // VRegC
    370 //------------------------------------------------------------------------------
    371 inline bool Instruction::HasVRegC() const {
    372   switch (FormatOf(Opcode())) {
    373     case k22b: return true;
    374     case k22c: return true;
    375     case k22s: return true;
    376     case k22t: return true;
    377     case k23x: return true;
    378     case k35c: return true;
    379     case k3rc: return true;
    380     default: return false;
    381   }
    382 }
    383 
    384 inline int32_t Instruction::VRegC() const {
    385   switch (FormatOf(Opcode())) {
    386     case k22b: return VRegC_22b();
    387     case k22c: return VRegC_22c();
    388     case k22s: return VRegC_22s();
    389     case k22t: return VRegC_22t();
    390     case k23x: return VRegC_23x();
    391     case k35c: return VRegC_35c();
    392     case k3rc: return VRegC_3rc();
    393     default:
    394       LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
    395       exit(EXIT_FAILURE);
    396   }
    397 }
    398 
    399 inline int8_t Instruction::VRegC_22b() const {
    400   DCHECK_EQ(FormatOf(Opcode()), k22b);
    401   return static_cast<int8_t>(Fetch16(1) >> 8);
    402 }
    403 
    404 inline uint16_t Instruction::VRegC_22c() const {
    405   DCHECK_EQ(FormatOf(Opcode()), k22c);
    406   return Fetch16(1);
    407 }
    408 
    409 inline int16_t Instruction::VRegC_22s() const {
    410   DCHECK_EQ(FormatOf(Opcode()), k22s);
    411   return static_cast<int16_t>(Fetch16(1));
    412 }
    413 
    414 inline int16_t Instruction::VRegC_22t() const {
    415   DCHECK_EQ(FormatOf(Opcode()), k22t);
    416   return static_cast<int16_t>(Fetch16(1));
    417 }
    418 
    419 inline uint8_t Instruction::VRegC_23x() const {
    420   DCHECK_EQ(FormatOf(Opcode()), k23x);
    421   return static_cast<uint8_t>(Fetch16(1) >> 8);
    422 }
    423 
    424 inline uint4_t Instruction::VRegC_35c() const {
    425   DCHECK_EQ(FormatOf(Opcode()), k35c);
    426   return static_cast<uint4_t>(Fetch16(2) & 0x0f);
    427 }
    428 
    429 inline uint16_t Instruction::VRegC_3rc() const {
    430   DCHECK_EQ(FormatOf(Opcode()), k3rc);
    431   return Fetch16(2);
    432 }
    433 
    434 inline bool Instruction::HasVarArgs() const {
    435   return FormatOf(Opcode()) == k35c;
    436 }
    437 
    438 inline void Instruction::GetVarArgs(uint32_t arg[5], uint16_t inst_data) const {
    439   DCHECK_EQ(FormatOf(Opcode()), k35c);
    440 
    441   /*
    442    * Note that the fields mentioned in the spec don't appear in
    443    * their "usual" positions here compared to most formats. This
    444    * was done so that the field names for the argument count and
    445    * reference index match between this format and the corresponding
    446    * range formats (3rc and friends).
    447    *
    448    * Bottom line: The argument count is always in vA, and the
    449    * method constant (or equivalent) is always in vB.
    450    */
    451   uint16_t regList = Fetch16(2);
    452   uint4_t count = InstB(inst_data);  // This is labeled A in the spec.
    453   DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";
    454 
    455   /*
    456    * Copy the argument registers into the arg[] array, and
    457    * also copy the first argument (if any) into vC. (The
    458    * DecodedInstruction structure doesn't have separate
    459    * fields for {vD, vE, vF, vG}, so there's no need to make
    460    * copies of those.) Note that cases 5..2 fall through.
    461    */
    462   switch (count) {
    463     case 5:
    464       arg[4] = InstA(inst_data);
    465       FALLTHROUGH_INTENDED;
    466     case 4:
    467       arg[3] = (regList >> 12) & 0x0f;
    468       FALLTHROUGH_INTENDED;
    469     case 3:
    470       arg[2] = (regList >> 8) & 0x0f;
    471       FALLTHROUGH_INTENDED;
    472     case 2:
    473       arg[1] = (regList >> 4) & 0x0f;
    474       FALLTHROUGH_INTENDED;
    475     case 1:
    476       arg[0] = regList & 0x0f;
    477       break;
    478     default:  // case 0
    479       break;  // Valid, but no need to do anything.
    480   }
    481 }
    482 
    483 }  // namespace art
    484 
    485 #endif  // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
    486