From b077bc8ff7c2a39985382339a3f15b7047d066ec Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Fri, 8 Jul 2022 15:05:56 +0200 Subject: [PATCH] x86asm: Add vm* and iret[wlq] insns The no-operand vm* instructions can be interpreted as having a funny modrm byte, but unlike no-operand OPC_MODRM it's also the r/m field which selects the insn, not (only) the reg field (aka group), so we need another insn type. --- i386-asm.c | 4 ++++ tests/asmtest.S | 9 +++++++++ x86_64-asm.h | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/i386-asm.c b/i386-asm.c index 22bb4340..3cc8d18b 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -40,6 +40,8 @@ #define OPC_ARITH 0x30 /* arithmetic opcodes */ #define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ #define OPC_TEST 0x50 /* test opcodes */ +#define OPC_0F01 0x60 /* 0x0f01XX (group 7, XX is 2nd opcode, + no operands and unstructured mod/rm) */ #define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) #define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ @@ -1072,6 +1074,8 @@ again: } if (OPCT_IS(pa->instr_type, OPC_TEST)) v += test_bits[opcode - pa->sym]; + else if (OPCT_IS(pa->instr_type, OPC_0F01)) + v |= 0x0f0100; op1 = v >> 16; if (op1) g(op1); diff --git a/tests/asmtest.S b/tests/asmtest.S index 3d2080bd..481286ee 100644 --- a/tests/asmtest.S +++ b/tests/asmtest.S @@ -632,10 +632,19 @@ int $0x10 leave int3 iret + iretw + iretl +#ifdef __x86_64__ + iretq +#endif rsm hlt wait nop + vmcall + vmlaunch + vmresume + vmxoff /* XXX: handle prefixes */ #if 0 diff --git a/x86_64-asm.h b/x86_64-asm.h index fdfd8bc0..79de0740 100644 --- a/x86_64-asm.h +++ b/x86_64-asm.h @@ -30,6 +30,9 @@ DEF_ASM_OP0(int3, 0xcc) DEF_ASM_OP0(into, 0xce) DEF_ASM_OP0(iret, 0xcf) + DEF_ASM_OP0(iretw, 0x66cf) + DEF_ASM_OP0(iretl, 0xcf) + DEF_ASM_OP0(iretq, 0x48cf) DEF_ASM_OP0(rsm, 0x0faa) DEF_ASM_OP0(hlt, 0xf4) DEF_ASM_OP0(wait, 0x9b) @@ -37,6 +40,11 @@ DEF_ASM_OP0(pause, 0xf390) DEF_ASM_OP0(xlat, 0xd7) + DEF_ASM_OP0L(vmcall, 0xc1, 0, OPC_0F01) + DEF_ASM_OP0L(vmlaunch, 0xc2, 0, OPC_0F01) + DEF_ASM_OP0L(vmresume, 0xc3, 0, OPC_0F01) + DEF_ASM_OP0L(vmxoff, 0xc4, 0, OPC_0F01) + /* strings */ ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX)) ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))