Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 1 | // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 | |
Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 3 | #include "dex_instruction.h" |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 4 | |
| 5 | namespace art { |
| 6 | |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 7 | const char* const Instruction::kInstructionNames[] = { |
| 8 | #define INSTRUCTION_NAME(o, c, pname, f, r, i, a) pname, |
Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 9 | #include "dex_instruction_list.h" |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 10 | DEX_INSTRUCTION_LIST(INSTRUCTION_NAME) |
| 11 | #undef DEX_INSTRUCTION_LIST |
| 12 | #undef INSTRUCTION_NAME |
| 13 | }; |
| 14 | |
| 15 | Instruction::InstructionFormat const Instruction::kInstructionFormats[] = { |
| 16 | #define INSTRUCTION_FORMAT(o, c, p, format, r, i, a) format, |
Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 17 | #include "dex_instruction_list.h" |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 18 | DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT) |
| 19 | #undef DEX_INSTRUCTION_LIST |
| 20 | #undef INSTRUCTION_FORMAT |
| 21 | }; |
| 22 | |
| 23 | int const Instruction::kInstructionFlags[] = { |
| 24 | #define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags) flags, |
Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 25 | #include "dex_instruction_list.h" |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 26 | DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS) |
| 27 | #undef DEX_INSTRUCTION_LIST |
| 28 | #undef INSTRUCTION_FLAGS |
| 29 | }; |
| 30 | |
| 31 | size_t Instruction::Size() const { |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 32 | const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 33 | size_t size = 0; |
| 34 | if (*insns == kPackedSwitchSignature) { |
| 35 | size = 4 + insns[1] * 2; |
| 36 | } else if (*insns == kSparseSwitchSignature) { |
| 37 | size = 2 + insns[1] * 4; |
| 38 | } else if (*insns == kArrayDataSignature) { |
| 39 | uint16_t element_size = insns[1]; |
| 40 | uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16); |
| 41 | // The plus 1 is to round up for odd size and width. |
| 42 | return 4 + (element_size * length + 1) / 2; |
| 43 | } else { |
| 44 | switch (Format()) { |
| 45 | case k10x: |
| 46 | case k12x: |
| 47 | case k11n: |
| 48 | case k11x: |
| 49 | case k10t: |
| 50 | size = 1; |
| 51 | break; |
| 52 | case k20t: |
| 53 | case k22x: |
| 54 | case k21t: |
| 55 | case k21s: |
| 56 | case k21h: |
| 57 | case k21c: |
| 58 | case k23x: |
| 59 | case k22b: |
| 60 | case k22t: |
| 61 | case k22s: |
| 62 | case k22c: |
| 63 | size = 2; |
| 64 | break; |
| 65 | case k32x: |
| 66 | case k30t: |
| 67 | case k31t: |
| 68 | case k31i: |
| 69 | case k31c: |
| 70 | case k35c: |
| 71 | case k3rc: |
| 72 | size = 3; |
| 73 | break; |
| 74 | case k51l: |
| 75 | size = 5; |
| 76 | break; |
| 77 | default: |
| 78 | LOG(FATAL) << "Unreachable"; |
| 79 | } |
| 80 | } |
| 81 | size *= sizeof(uint16_t); |
| 82 | return size; |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 83 | } |
| 84 | |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 85 | Instruction::Code Instruction::Opcode() const { |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 86 | const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 87 | int opcode = *insns & 0xFF; |
| 88 | return static_cast<Code>(opcode); |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 89 | } |
| 90 | |
Carl Shapiro | e4c1ce4 | 2011-07-09 02:31:57 -0700 | [diff] [blame] | 91 | const Instruction* Instruction::Next() const { |
Carl Shapiro | 12eb78e | 2011-06-24 14:51:06 -0700 | [diff] [blame] | 92 | size_t current_size = Size(); |
| 93 | const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this); |
| 94 | return reinterpret_cast<const Instruction*>(ptr + current_size); |
| 95 | } |
| 96 | |
| 97 | } // namespace art |