GP-5780: Added several missing x86 instructions

This commit is contained in:
ghidorahrex
2026-06-08 15:10:05 -04:00
parent ed4a5b9809
commit 2c3ca6df4c
7 changed files with 324 additions and 7 deletions

View File

@@ -22,6 +22,7 @@ data/languages/bmi1.sinc||GHIDRA||||END|
data/languages/bmi2.sinc||GHIDRA||||END|
data/languages/cet.sinc||GHIDRA||||END|
data/languages/clwb.sinc||GHIDRA||||END|
data/languages/cmpccxadd.sinc||GHIDRA||||END|
data/languages/fma.sinc||GHIDRA||||END|
data/languages/ia.sinc||GHIDRA||||END|
data/languages/lockable.sinc||GHIDRA||||END|
@@ -61,6 +62,7 @@ data/languages/old/x86smmV2.trans||GHIDRA||||END|
data/languages/old/x86smmV3.lang||GHIDRA||||END|
data/languages/old/x86smmV3.trans||GHIDRA||||END|
data/languages/pclmulqdq.sinc||GHIDRA||||END|
data/languages/rao.sinc||GHIDRA||||END|
data/languages/rdrand.sinc||GHIDRA||||END|
data/languages/sgx.sinc||GHIDRA||||END|
data/languages/sha.sinc||GHIDRA||||END|

View File

@@ -0,0 +1,27 @@
####
#### CMPccXADD instructions
####
@ifdef IA64
:CMP^cc^"XADD" m32, Reg32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32 & row=0xe & cc; Reg32 ... & m32 {
local op1 = m32;
local op2 = Reg32;
subflags(op1, op2);
local tmp = op1 - op2;
resultflags(tmp);
build cc;
if (!cc) goto inst_next;
m32 = vexVVVV_r32;
}
:CMP^cc^"XADD" m64, Reg64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64 & row=0xe & cc; Reg64 ... & m64 {
local op1 = m64;
local op2 = Reg64;
subflags(op1, op2);
local tmp = op1 - op2;
resultflags(tmp);
build cc;
if (!cc) goto inst_next;
m64 = vexVVVV_r64;
}
@endif

View File

@@ -479,6 +479,7 @@ define context contextreg
# For example: CRC32 r32, r16 -- 66 F2 OF 38 F1 C8
@define PRE_NO "mandover=0"
@define PRE_NOFX "(mandover=0 | prefix_66=1)"
@define PRE_66 "prefix_66=1"
@define PRE_F3 "prefix_f3=1"
@define PRE_F2 "prefix_f2=1"
@@ -2418,6 +2419,7 @@ macro fucompe(val1, val2) {
@define VEX_MAP4 "vexMMMMM=4"
@define VEX_MAP5 "vexMMMMM=5"
@define VEX_MAP6 "vexMMMMM=6"
@define VEX_MAP7 "vexMMMMM=7"
# Specification is "WIG", "W0", or "W1".
@define VEX_WIG "rexWprefix"
@@ -3012,12 +3014,17 @@ with : lockprefx=0 {
:CQO is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x99 { tmp:16 = sext(RAX); RDX = tmp(8); }
@endif
define pcodeop cldemote;
:CLDEMOTE m8 is vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x1C; reg_opcode=0 ... & m8 {
cldemote(m8);
}
define pcodeop clflush;
:CLFLUSH m8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=7 ) ... & m8 {
clflush(m8);
}
:CLAC is vexMode=0 & byte=0x0F; byte=0x01; byte=0xCA { AC = 0; }
:CLAC is $(PRE_NO) & vexMode=0 & byte=0x0F; byte=0x01; byte=0xCA { AC = 0; }
:CLC is vexMode=0 & byte=0xf8 { CF = 0; }
:CLD is vexMode=0 & byte=0xfc { DF = 0; }
@@ -3312,6 +3319,23 @@ define pcodeop cpuid_brand_part3_info;
RDX = rem:8; }
@endif
define pcodeop enqcmd;
define pcodeop enqcmds;
macro enqcmdFlags() {
OF = 0;
SF = 0;
AF = 0;
CF = 0;
PF = 0;
}
:ENQCMD Reg32, m512 is $(PRE_F2) & opsize=1 & byte=0x0F; byte=0x38; byte=0xF8; (mod!=3 & Reg32) ... & m512 { ZF = enqcmd(Reg32, m512); enqcmdFlags(); }
:ENQCMDS Reg32, m512 is $(PRE_F3) & opsize=1 & byte=0x0F; byte=0x38; byte=0xF8; (mod!=3 & Reg32) ... & m512 { ZF = enqcmds(Reg32, m512); enqcmdFlags(); }
@ifdef IA64
:ENQCMD Reg64, m512 is $(LONGMODE_ON) & $(PRE_F2) & opsize=2 & byte=0x0F; byte=0x38; byte=0xF8; (mod!=3 & Reg64) ... & m512 { ZF = enqcmd(Reg64, m512); enqcmdFlags(); }
:ENQCMDS Reg64, m512 is $(LONGMODE_ON) & $(PRE_F3) & opsize=2 & byte=0x0F; byte=0x38; byte=0xF8; (mod!=3 & Reg64) ... & m512 { ZF = enqcmds(Reg64, m512); enqcmdFlags(); }
@endif
enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
:ENTER imm16,enterFrames is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xc8; imm16; enterFrames & low5=0x00 {
@@ -3544,7 +3568,39 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
}
@endif
####
#### FRED instructions
####
@ifdef IA64
define pcodeop eretu;
define pcodeop erets;
define pcodeop lkgs;
:ERETU is $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xCA {
eretu();
pop88(RIP);
tmp:8=0; pop88(tmp); CS=tmp(0)|0x3;
pop88(rflags);
pop88(RSP);
pop88(tmp); SS=tmp(0)|0x3;
return [RIP];
}
:ERETS is $(PRE_F2) & byte=0x0F; byte=0x01; byte=0xCA {
erets();
pop88(RIP);
tmp:8=0; pop88(tmp); # Not used to load CS
pop88(rflags);
pop88(RSP);
pop88(tmp); # Not used to load SS
return [RIP];
}
:LKGS rm16 is $(LONGMODE_ON) & $(PRE_F2) & byte=0x0F; byte=0x00; reg_opcode=6 ... & rm16 {
lkgs(rm16);
}
@endif #def IA64
# Informs the 80287 coprocessor of the switch to protected mode, treated as NOP for 80387 and later.
# We used to have a pseudo-op, but as this is a legacy instruction which is now explicitly treated
@@ -3553,6 +3609,16 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
:HLT is vexMode=0 & byte=0xf4 { goto inst_start; }
define pcodeop hreset;
:HRESET imm8 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x3A; byte=0xF0; byte=0xC0; imm8 { EAX = hreset(imm8:1); }
@ifdef IA64
# Indirect Branch History Fence. Treated as a NOP outside of 64-bit mode.
# Used to prevent branch history injection, added as a pseudo-op
define pcodeop ibhf;
:IBHF is $(LONGMODE_ON) & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0x1E; byte=0xF8 { ibhf(); }
@endif
:IDIV rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=7 ... { rm8ext:2 = sext(rm8);
local quotient = AX s/ rm8ext; # DE exception if quotient doesn't fit in AL
local rem = AX s% rm8ext;
@@ -3692,10 +3758,14 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
:IRETQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xcf { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); pop88(rflags); return [RIP]; }
@endif
:J^cc rel8 is vexMode=0 & row=7 & cc; rel8 { if (cc) goto rel8; }
:J^cc rel16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xf; row=8 & cc; rel16 { if (cc) goto rel16; }
:J^cc rel32 is vexMode=0 & opsize=1 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; }
:J^cc rel32 is vexMode=0 & opsize=2 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; }
# Use the gcc binutils style for branch hints
bh: ", pn" is segover=1 {} # HWNT Branch Not Taken hint (prefix 2E)
bh: ", pt" is segover=3 {} # HST Branch Taken hint (prefix 3E)
bh: is epsilon {}
:J^cc rel8^bh is vexMode=0 & row=7 & cc & bh; rel8 { if (cc) goto rel8; }
:J^cc rel16^bh is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xf & bh; row=8 & cc; rel16 { if (cc) goto rel16; }
:J^cc rel32^bh is vexMode=0 & opsize=1 & byte=0xf & bh; row=8 & cc; rel32 { if (cc) goto rel32; }
:J^cc rel32^bh is vexMode=0 & opsize=2 & byte=0xf & bh; row=8 & cc; rel32 { if (cc) goto rel32; }
# The following is vexMode=0 & picked up by the line above. rel32 works for both 32 and 64 bit
#@ifdef IA64
#:J^cc rel32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; }
@@ -4189,6 +4259,19 @@ define pcodeop swap_bytes;
:PAUSE is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x90 { }
:PAUSE is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x90 { }
@ifdef IA64
define pcodeop pbndkb;
:PBNDKB is $(LONGMODE_ON) & vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x01; byte=0xC7 { RAX = pbndkb(RBX, RCX); ZF = (RAX != 0); }
@endif
# leaf function 2 is the only one that uses RCX, and it is only available in 64-bit
# The instruction description mentions RDX, but no leaf functions use RDX
define pcodeop pconfig;
:PCONFIG is $(LONGMODE_OFF) & vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x01; byte=0xC5 { EAX = pconfig(EAX, EBX); ZF = (EAX != 0); }
@ifdef IA64
:PCONFIG is $(LONGMODE_ON) & vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x01; byte=0xC5 { RAX = pconfig(RAX, RBX, RCX); ZF = (RAX != 0); }
@endif
:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { local val:2 = 0; pop22(val); build rm16; rm16 = val; }
:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { local val:2 = 0; pop42(val); build rm16; rm16 = val; }
:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { local val:4 = 0; pop24(val); build rm32; rm32 = val; }
@@ -4584,6 +4667,10 @@ define pcodeop smm_restore_state;
:SCASQ^repe^repetail eseDI8 is $(LONGMODE_ON) & vexMode=0 & repe & repetail & opsize=2 & byte=0xaf & eseDI8 { build repe; build eseDI8; subflags(RAX,eseDI8); local diff=RAX-eseDI8; resultflags(diff); build repetail; }
@endif
define pcodeop serialize;
:SERIALIZE is vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x01; byte=0xE8 { serialize(); }
:SET^cc rm8 is vexMode=0 & byte=0xf; row=9 & cc; rm8 { rm8 = cc; }
# manual is not consistent on operands
@@ -4841,6 +4928,33 @@ define pcodeop invalidInstructionException;
:UD1 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xb9; rm32 & Reg32 ... { local target:$(SIZE) = invalidInstructionException(); goto [target]; }
:UD2 is vexMode=0 & byte=0xf; byte=0xb { local target:$(SIZE) = invalidInstructionException(); goto [target]; }
define pcodeop umonitor;
:UMONITOR Rmr16 is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x0F; byte=0xAE; reg_opcode=6 & mod=3 & Rmr16 {
umonitor(Rmr16);
}
:UMONITOR Rmr32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xAE; reg_opcode=6 & mod=3 & Rmr32 {
umonitor(Rmr32);
}
@ifdef IA64
:UMONITOR Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0xAE; reg_opcode=6 & mod=3 & Rmr64 {
umonitor(Rmr64);
}
@endif
define pcodeop umwait;
:UMWAIT Rmr32 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xAE; reg_opcode=6 & mod=3 & Rmr32 {
umwait(Rmr32, EDX, EAX);
}
define pcodeop tpause;
:TPAUSE Rmr32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; reg_opcode=6 & mod=3 & Rmr32 {
tpause(Rmr32, EDX, EAX);
}
define pcodeop verr;
define pcodeop verw;
:VERR rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=4 ... { ZF = verr(); }
@@ -4853,7 +4967,7 @@ define pcodeop verw;
@ifdef IA64
:VMLOAD RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xda & RAX { vmload(RAX); }
@endif
:VMMCALL is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd9 { vmmcall(); }
:VMMCALL is $(PRE_NOFX) & vexMode=0 & byte=0x0f; byte=0x01; byte=0xd9 { vmmcall(); }
# Limiting the effective address size to 32 and 64 bit. Surely we're not expecting a 16-bit VM address, are we?
:VMRUN EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xd8 & EAX { vmrun(EAX); }
@ifdef IA64
@@ -4864,7 +4978,57 @@ define pcodeop verw;
@ifdef IA64
:VMSAVE RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xdb & RAX { vmsave(RAX); }
@endif
#
@ifdef IA64
define pcodeop rmpFlags;
# rFLAGS bits OF, ZF, AF, PF and SF are set based on return code
macro rmpFlagSet() {
local result:1 = rmpFlags(EAX);
OF = result[0,1];
ZF = result[1,1];
AF = result[2,1];
PF = result[3,1];
SF = result[4,1];
}
# Exit to VMM
define pcodeop vmgexit;
:VMGEXIT is ($(PRE_F2) | $(PRE_F3)) & vexMode=0 & byte=0x0f; byte=0x01; byte=0xd9 { vmgexit(); }
# Page Smash
define pcodeop psmash;
:PSMASH is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0x01; byte=0xff { EAX = psmash(RAX); rmpFlagSet(); }
# Validate guest page RMP entry
define pcodeop pvalidate;
:PVALIDATE is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0f; byte=0x01; byte=0xff { EAX = pvalidate(RAX, RCX, RDX); rmpFlagSet(); }
# Adjust RMP permissions for guest page
define pcodeop rmpadjust;
:RMPADJUST is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0x01; byte=0xfe { EAX = rmpadjust(RAX, RCX, RDX); rmpFlagSet(); }
# Read the RMP permission mask for a guest page
define pcodeop rmpquery;
:RMPQUERY is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0x01; byte=0xfd { EAX = rmpquery(RAX, RDX); rmpFlagSet(); }
# Read an RMP entry
define pcodeop rmpread;
:RMPREAD is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0f; byte=0x01; byte=0xfd { EAX = rmpread(RAX, RCX); rmpFlagSet(); }
# Check RMP dirty status
define pcodeop rmpchkd;
:RMPCHKD is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0x01; byte=0xfc { local result:1 = rmpchkd(RAX, RCX); ZF = result[1,1]; CF = result[2,1]; }
# RMP Optimization
define pcodeop rmpopt;
:RMPOPT is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0f; byte=0x01; byte=0xfc { CF = rmpopt(RAX, RCX); }
# Write a new RMP entry
define pcodeop rmpupdate;
:RMPUPDATE is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0f; byte=0x01; byte=0xfe { EAX = rmpupdate(RAX, RCX); rmpFlagSet(); }
@endif
#
# Intel hardware assisted virtualization opcodes
@@ -4927,6 +5091,23 @@ define pcodeop wrpkru;
define pcodeop wrmsr;
:WRMSR is vexMode=0 & byte=0xf; byte=0x30 { tmp:8 = (zext(EDX) << 32) | zext(EAX); wrmsr(ECX,tmp); }
@ifdef IA64
define pcodeop urdmsr;
define pcodeop uwrmsr;
:URDMSR Rmr64, Reg64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xF8; mod=3 & Reg64 & Rmr64 { Rmr64 = urdmsr(Reg64); }
:URDMSR Rmr64, imm32 is $(LONGMODE_ON) & $(VEX_L128) & $(PRE_F2) & $(VEX_MAP7) & $(VEX_W0) & byte=0xF8; mod=3 & reg_opcode=0 & Rmr64; imm32 { Rmr64 = urdmsr(imm32:4); }
:UWRMSR Reg64, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF8; mod=3 & Reg64 & Rmr64 { Rmr64 = uwrmsr(Reg64, Rmr64); }
:UWRMSR imm32, Rmr64 is $(LONGMODE_ON) & $(VEX_L128) & $(PRE_F3) & $(VEX_MAP7) & $(VEX_W0) & byte=0xF8; mod=3 & reg_opcode=0 & Rmr64; imm32 { uwrmsr(imm32:4, Rmr64); }
define pcodeop rdmsrlist;
define pcodeop wrmsrlist;
define pcodeop wrmsrns;
:RDMSRLIST is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x01; byte=0xC6 { rdmsrlist(RCX, RDI, RSI); }
:WRMSRLIST is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xC6 { wrmsrlist(RCX, RDI, RSI); }
:WRMSRNS is $(LONGMODE_ON) & vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0x01; byte=0xC6 { tmp:8 = (zext(EDX) << 32) | zext(EAX); wrmsrns(ECX,tmp); }
@endif
# See 'lockable.sinc' for memory destination, lockable variants
:XADD Rmr8,Reg8 is vexMode=0 & byte=0x0F; byte=0xC0; mod=3 & Rmr8 & Reg8 { addflags( Rmr8,Reg8 ); local tmp = Rmr8 + Reg8; Reg8 = Rmr8; Rmr8 = tmp; resultflags(tmp); }
:XADD Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x0F; byte=0xC1; mod=3 & Rmr16 & Reg16 { addflags(Rmr16,Reg16); local tmp = Rmr16 + Reg16; Reg16 = Rmr16; Rmr16 = tmp; resultflags(tmp); }
@@ -5051,6 +5232,7 @@ define pcodeop xtest;
:MFENCE is vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0xAE; mod = 0b11 & reg_opcode=6 & r_m=0 { }
:SFENCE is vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0xAE; mod = 0b11 & reg_opcode=7 & r_m=0 { }
#
# floating point instructions
#
@@ -9605,6 +9787,18 @@ define pcodeop rsqrtss;
:RSQRTSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x52; XmmReg ... & m32 { XmmReg = rsqrtss(XmmReg, m32); }
:RSQRTSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x52; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = rsqrtss(XmmReg1, XmmReg2); }
@ifdef IA64
define pcodeop senduipi;
define pcodeop testui;
define pcodeop setui;
define pcodeop clearui;
:SENDUIPI Rmr64 is $(LONGMODE_ON) & $(PRE_F3) & byte=0x0F; byte=0xC7; mod=3 & reg_opcode=0x6 & Rmr64 { senduipi(Rmr64); }
:TESTUI is $(LONGMODE_ON) & $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xED { CF = testui(); }
:UIRET is $(LONGMODE_ON) & $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xEC { pop88(RIP); pop88(rflags); pop88(RSP); unpackflags(rflags); unpackeflags(rflags); setui(); return [RIP]; }
:CLUI is $(LONGMODE_ON) & $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xEE { clearui(); }
:STUI is $(LONGMODE_ON) & $(PRE_F3) & byte=0x0F; byte=0x01; byte=0xEF { setui(); }
@endif
:SHUFPD XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC6; XmmReg1 ... & XmmReg2_m128; imm8
{
local srcLow:8 = XmmReg2_m128[0,64];
@@ -10499,4 +10693,7 @@ lsbOffset: val is imm8 [ val=imm8 & 0x3f; ] { export *[const]:1 val; }
:MOVNTSS m32, XmmReg1 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2B; XmmReg1 ... & m32 {
m32 = XmmReg1[0,32];
}
} # end with : lockprefx=0

View File

@@ -0,0 +1,44 @@
####
#### RAO-INT instructions
####
:AADD m32,Reg32 is vexMode=0 & rexprefix=0 & $(PRE_NO) & byte=0x0F; byte=0x38; byte=0xFC; Reg32 ... & m32 {
m32 = m32 + Reg32;
}
@ifdef IA64
:AADD m64,Reg64 is $(REX_W) & $(PRE_NO) & byte=0x0F; byte=0x38; byte=0xFC; Reg64 ... & m64 {
m64 = m64 + Reg64;
}
@endif
:AAND m32,Reg32 is vexMode=0 & rexprefix=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xFC; Reg32 ... & m32 {
m32 = m32 & Reg32;
}
@ifdef IA64
:AAND m64,Reg64 is $(REX_W) & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xFC; Reg64 ... & m64 {
m64 = m64 & Reg64;
}
@endif
:AOR m32,Reg32 is vexMode=0 & rexprefix=0 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xFC; Reg32 ... & m32 {
m32 = m32 | Reg32;
}
@ifdef IA64
:AOR m64,Reg64 is $(REX_W) & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xFC; Reg64 ... & m64 {
m64 = m64 | Reg64;
}
@endif
:AXOR m32,Reg32 is vexMode=0 & rexprefix=0 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xFC; Reg32 ... & m32 {
m32 = m32 ^ Reg32;
}
@ifdef IA64
:AXOR m64,Reg64 is $(REX_W) & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xFC; Reg64 ... & m64 {
m64 = m64 ^ Reg64;
}
@endif

View File

@@ -255,3 +255,48 @@ define pcodeop enclu_unknown;
<done>
}
define pcodeop enclv_edecvirtchild;
define pcodeop enclv_eincvirtchild;
define pcodeop enclv_esetcontext;
define pcodeop enclv_unknown;
:ENCLV is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc0 {
if ( EAX != 0x0 ) goto <leaf_1>;
RAX = enclv_edecvirtchild( RBX, RCX );
ZF = (RAX != 0);
CF = 0;
PF = 0;
AF = 0;
OF = 0;
SF = 0;
goto <done>;
<leaf_1>
if ( EAX != 0x1 ) goto <leaf_2>;
RAX = enclv_eincvirtchild( RBX, RCX );
ZF = (RAX != 0);
CF = 0;
PF = 0;
AF = 0;
OF = 0;
SF = 0;
goto <done>;
<leaf_2>
if ( EAX != 0x2 ) goto <unknown>;
RAX = enclv_esetcontext( RCX, RDX );
ZF = (RAX != 0);
CF = 0;
PF = 0;
AF = 0;
OF = 0;
SF = 0;
goto <done>;
<unknown>
enclv_unknown();
<done>
}

View File

@@ -3,4 +3,5 @@
with : lockprefx=0 {
@include "sgx.sinc"
@include "fma.sinc"
@include "cmpccxadd.sinc"
}

View File

@@ -18,4 +18,5 @@ with : lockprefx=0 {
@include "smx.sinc"
@include "cet.sinc"
@include "rdrand.sinc"
@include "rao.sinc"
}