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: arg[4] = InstA(inst_data); 464 case 4: arg[3] = (regList >> 12) & 0x0f; 465 case 3: arg[2] = (regList >> 8) & 0x0f; 466 case 2: arg[1] = (regList >> 4) & 0x0f; 467 case 1: arg[0] = regList & 0x0f; break; 468 default: // case 0 469 break; // Valid, but no need to do anything. 470 } 471 } 472 473 } // namespace art 474 475 #endif // ART_RUNTIME_DEX_INSTRUCTION_INL_H_ 476