* Decode an instruction opcode. */
| 101 | * Decode an instruction opcode. |
| 102 | */ |
| 103 | static int decodeOpcode(const uint8_t *bytes, unsigned size, int i, |
| 104 | Encoding &encoding, uint8_t &opcode) |
| 105 | { |
| 106 | if (i < 0 || i >= (int)size) |
| 107 | return i; |
| 108 | |
| 109 | encoding = ENCODING_SINGLE_BYTE; |
| 110 | |
| 111 | // Extended encodings: |
| 112 | if (bytes[i] == 0x62) |
| 113 | { |
| 114 | if (size - i > 4 && (~bytes[i+1] & 0x0c) == 0x0c && |
| 115 | (bytes[i+2] & 0x04) == 0x04) |
| 116 | { |
| 117 | // 4-byte EVEX encoding: |
| 118 | switch (bytes[i+1] & 0x03) |
| 119 | { |
| 120 | case 0x01: |
| 121 | encoding = ENCODING_TWO_BYTES_0F; |
| 122 | break; |
| 123 | case 0x02: |
| 124 | encoding = ENCODING_THREE_BYTES_0F38; |
| 125 | break; |
| 126 | case 0x03: |
| 127 | encoding = ENCODING_THREE_BYTES_0F3A; |
| 128 | break; |
| 129 | default: |
| 130 | return -1; |
| 131 | } |
| 132 | i += 4; |
| 133 | opcode = bytes[i++]; |
| 134 | return i; |
| 135 | } |
| 136 | else |
| 137 | return -1; |
| 138 | } |
| 139 | else if (bytes[i] == 0xc4 && (i > 0? (bytes[i-1] & 0xf0) != 0x40: true)) |
| 140 | { |
| 141 | if (size - i > 3) |
| 142 | { |
| 143 | // 3-byte VEX encoding: |
| 144 | switch (bytes[i+1] & 0x1f) |
| 145 | { |
| 146 | case 0x1: |
| 147 | encoding = ENCODING_TWO_BYTES_0F; |
| 148 | break; |
| 149 | case 0x02: |
| 150 | encoding = ENCODING_THREE_BYTES_0F38; |
| 151 | break; |
| 152 | case 0x03: |
| 153 | encoding = ENCODING_THREE_BYTES_0F3A; |
| 154 | break; |
| 155 | default: |
| 156 | return -1; |
| 157 | } |
| 158 | i += 3; |
| 159 | opcode = bytes[i++]; |
| 160 | return i; |
no outgoing calls
no test coverage detected