diff --git a/encode.c b/encode.c index 106d2e8..24c5d4d 100644 --- a/encode.c +++ b/encode.c @@ -322,7 +322,7 @@ fe_enc64_impl(uint8_t** restrict buf, uint64_t mnem, FeOp op0, FeOp op1, const struct EncodeDesc* desc = &descs[desc_idx]; const struct EncodingInfo* ei = &encoding_infos[desc->enc]; uint64_t opc = desc->opc; - int64_t imm; + int64_t imm = 0xcc; if (UNLIKELY(desc->enc == ENC_INVALID)) goto fail; @@ -349,14 +349,17 @@ fe_enc64_impl(uint8_t** restrict buf, uint64_t mnem, FeOp op0, FeOp op1, if (UNLIKELY(mnem & FE_SEG_MASK)) opc |= (mnem & FE_SEG_MASK) << (OPC_SEG_IDX - 16); - if (ei->immctl && ei->immctl != 3) + if (ei->immctl > 0) { imm = ops[ei->immidx]; - if (ei->immctl == 6) { - if (UNLIKELY(mnem & FE_JMPL) && desc->alt) goto next; - imm -= (int64_t) *buf + opc_size(opc) + desc->immsz; + if (ei->immctl == 3) + imm = op_reg_idx(imm) << 4; + if (ei->immctl == 6) { + if (UNLIKELY(mnem & FE_JMPL) && desc->alt) goto next; + imm -= (int64_t) *buf + opc_size(opc) + desc->immsz; + } + if (UNLIKELY(ei->immctl == 1) && imm != 1) goto next; + if (ei->immctl >= 4 && !op_imm_n(imm, desc->immsz)) goto next; } - if (UNLIKELY(ei->immctl == 1) && imm != 1) goto next; - if (ei->immctl >= 2 && !op_imm_n(imm, desc->immsz)) goto next; // NOP has no operands, so this must be the 32-bit OA XCHG if ((desc->opc & ~7) == 0x90 && ops[0] == FE_AX) goto next; diff --git a/parseinstrs.py b/parseinstrs.py index 962c17b..a62f3b3 100644 --- a/parseinstrs.py +++ b/parseinstrs.py @@ -128,8 +128,10 @@ class InstrDesc(NamedTuple): def imm_size(self, opsz): flags = ENCODINGS[self.encoding] - if flags.imm_control < 4: + if flags.imm_control < 3: return 0 + if flags.imm_control == 3: + return 1 if self.mnemonic == "ENTER": return 3 if "IMM_8" in self.flags: diff --git a/tests/test_encode.c b/tests/test_encode.c index dce7233..26eef16 100644 --- a/tests/test_encode.c +++ b/tests/test_encode.c @@ -160,6 +160,12 @@ main(int argc, char** argv) TEST("\xc4\xe2\x71\x9d\xc2", FE_VFNMADD132SSrrr, FE_XMM0, FE_XMM1, FE_XMM2); TEST("\xc4\xe2\xf1\x9d\xc2", FE_VFNMADD132SDrrr, FE_XMM0, FE_XMM1, FE_XMM2); + // Test RVMR encoding + TEST("\xc4\xe3\x71\x4a\xc2\x30", FE_VBLENDVPS128rrrr, FE_XMM0, FE_XMM1, FE_XMM2, FE_XMM3); + TEST("\xc4\xe3\x75\x4a\xc2\x30", FE_VBLENDVPS256rrrr, FE_XMM0, FE_XMM1, FE_XMM2, FE_XMM3); + TEST("\xc4\xe3\x71\x4a\x05\x00\x00\x00\x00\x20", FE_VBLENDVPS128rrmr, FE_XMM0, FE_XMM1, FE_MEM(FE_IP, 0, 0, 10), FE_XMM2); + TEST("\xc4\xe3\x75\x4a\x05\x00\x00\x00\x00\x20", FE_VBLENDVPS256rrmr, FE_XMM0, FE_XMM1, FE_MEM(FE_IP, 0, 0, 10), FE_XMM2); + // VSIB encodings TEST("", FE_VGATHERDPS128rmr, FE_XMM0, FE_XMM0, FE_XMM1); // must have memory operand TEST("", FE_VGATHERDPS128rmr, FE_XMM0, FE_MEM(FE_DI, 8, 0, 0), FE_XMM1); // must have SIB