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