| 164 | } |
| 165 | |
| 166 | void Decoder::DecodeModRM_16(X86Tables::DecodedOperand* Operand, X86Tables::ModRMDecoded ModRM) { |
| 167 | // 16bit modrm behaves similar to SIB but encoded directly in modrm |
| 168 | // mod != 0b11 case |
| 169 | // RM | Result |
| 170 | // =============== |
| 171 | // 0b000 | [BX + SI] |
| 172 | // 0b001 | [BX + DI] |
| 173 | // 0b010 | [BP + SI] |
| 174 | // 0b011 | [BP + DI] |
| 175 | // 0b100 | [SI] |
| 176 | // 0b101 | [DI] |
| 177 | // 0b110 | {[BP], disp16} |
| 178 | // 0b111 | [BX] |
| 179 | // if mod = 0b00 |
| 180 | // 0b110 = disp16 |
| 181 | // if mod = 0b01 |
| 182 | // All encodings gain 8bit displacement |
| 183 | // 0b110 = [BP] + disp8 |
| 184 | // if mod = 0b10 |
| 185 | // All encodings gain 16bit displacement |
| 186 | // 0b110 = [BP] + disp16 |
| 187 | uint32_t Literal {}; |
| 188 | uint8_t DisplacementSize {}; |
| 189 | if ((ModRM.mod == 0 && ModRM.rm == 0b110) || ModRM.mod == 0b10) { |
| 190 | DisplacementSize = 2; |
| 191 | } else if (ModRM.mod == 0b01) { |
| 192 | DisplacementSize = 1; |
| 193 | } |
| 194 | if (DisplacementSize) { |
| 195 | Literal = ReadData(DisplacementSize); |
| 196 | if (DisplacementSize == 1) { |
| 197 | Literal = static_cast<int8_t>(Literal); |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | Operand->Type = DecodedOperand::OpType::SIB; |
| 202 | Operand->Data.SIB.Scale = 1; |
| 203 | Operand->Data.SIB.Offset = Literal; |
| 204 | |
| 205 | // Only called when ModRM.mod != 0b11 |
| 206 | struct Encodings { |
| 207 | uint8_t Base; |
| 208 | uint8_t Index; |
| 209 | }; |
| 210 | constexpr static std::array<Encodings, 24> Lookup = {{ |
| 211 | // Mod = 0b00 |
| 212 | {FEXCore::X86State::REG_RBX, FEXCore::X86State::REG_RSI}, |
| 213 | {FEXCore::X86State::REG_RBX, FEXCore::X86State::REG_RDI}, |
| 214 | {FEXCore::X86State::REG_RBP, FEXCore::X86State::REG_RSI}, |
| 215 | {FEXCore::X86State::REG_RBP, FEXCore::X86State::REG_RDI}, |
| 216 | {FEXCore::X86State::REG_RSI, FEXCore::X86State::REG_INVALID}, |
| 217 | {FEXCore::X86State::REG_RDI, FEXCore::X86State::REG_INVALID}, |
| 218 | {FEXCore::X86State::REG_INVALID, FEXCore::X86State::REG_INVALID}, |
| 219 | {FEXCore::X86State::REG_RBX, FEXCore::X86State::REG_INVALID}, |
| 220 | // Mod = 0b01 |
| 221 | {FEXCore::X86State::REG_RBX, FEXCore::X86State::REG_RSI}, |
| 222 | {FEXCore::X86State::REG_RBX, FEXCore::X86State::REG_RDI}, |
| 223 | {FEXCore::X86State::REG_RBP, FEXCore::X86State::REG_RSI}, |
nothing calls this directly
no outgoing calls
no test coverage detected