| 812 | } |
| 813 | |
| 814 | bool Decoder::DecodeInstructionImpl(uint64_t PC) { |
| 815 | InstructionSize = 0; |
| 816 | Instruction.fill(0); |
| 817 | |
| 818 | DecodeInst = &DecodedBuffer[DecodedSize]; |
| 819 | memset(DecodeInst, 0, sizeof(DecodedInst)); |
| 820 | DecodeInst->PC = PC; |
| 821 | |
| 822 | for (;;) { |
| 823 | if (InstructionSize >= MAX_INST_SIZE) { |
| 824 | return false; |
| 825 | } |
| 826 | uint8_t Op = ReadByte(); |
| 827 | switch (Op) { |
| 828 | case 0x0F: { // Escape Op |
| 829 | uint8_t EscapeOp = ReadByte(); |
| 830 | switch (EscapeOp) { |
| 831 | case 0x0F: |
| 832 | [[unlikely]] { // 3DNow! |
| 833 | // 3DNow! Instruction Encoding: 0F 0F [ModRM] [SIB] [Displacement] [Opcode] |
| 834 | // Decode ModRM |
| 835 | uint8_t ModRMByte = ReadByte(); |
| 836 | DecodeInst->ModRM = ModRMByte; |
| 837 | DecodeInst->DecodedModRM = true; |
| 838 | |
| 839 | FEXCore::X86Tables::ModRMDecoded ModRM; |
| 840 | ModRM.Hex = DecodeInst->ModRM; |
| 841 | |
| 842 | const bool Has16BitAddressing = !BlockInfo.Is64BitMode && DecodeInst->Flags & DecodeFlags::FLAG_ADDRESS_SIZE; |
| 843 | |
| 844 | // All 3DNow! instructions have the second argument as the rm handler |
| 845 | // We need to decode it upfront to get the displacement out of the way |
| 846 | if (ModRM.mod != 0b11) { |
| 847 | auto Disp = DecodeModRMs_Disp[Has16BitAddressing]; |
| 848 | (this->*Disp)(&DecodeInst->Src[0], ModRM); |
| 849 | } |
| 850 | |
| 851 | // Take a peek at the op just past the displacement |
| 852 | uint8_t LocalOp = ReadByte(); |
| 853 | return NormalOpHeader(&FEXCore::X86Tables::DDDNowOps[LocalOp], LocalOp); |
| 854 | break; |
| 855 | } |
| 856 | case 0x38: { // F38 Table! |
| 857 | constexpr uint16_t PF_38_NONE = 0; |
| 858 | constexpr uint16_t PF_38_66 = (1U << 0); |
| 859 | constexpr uint16_t PF_38_F2 = (1U << 1); |
| 860 | constexpr uint16_t PF_38_F3 = (1U << 2); |
| 861 | |
| 862 | uint16_t Prefix = PF_38_NONE; |
| 863 | if (DecodeInst->Flags & DecodeFlags::FLAG_OPERAND_SIZE) { |
| 864 | Prefix |= PF_38_66; |
| 865 | } |
| 866 | if (DecodeInst->Flags & DecodeFlags::FLAG_REPNE_PREFIX) { |
| 867 | Prefix |= PF_38_F2; |
| 868 | } |
| 869 | if (DecodeInst->Flags & DecodeFlags::FLAG_REP_PREFIX) { |
| 870 | Prefix |= PF_38_F3; |
| 871 | } |
nothing calls this directly
no test coverage detected