From 2c3ca6df4cd24ca0d809a93450b78d9e7ff2ee7a Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Mon, 8 Jun 2026 15:10:05 -0400 Subject: [PATCH] GP-5780: Added several missing x86 instructions --- Ghidra/Processors/x86/certification.manifest | 2 + .../x86/data/languages/cmpccxadd.sinc | 27 +++ Ghidra/Processors/x86/data/languages/ia.sinc | 211 +++++++++++++++++- Ghidra/Processors/x86/data/languages/rao.sinc | 44 ++++ Ghidra/Processors/x86/data/languages/sgx.sinc | 45 ++++ .../x86/data/languages/x86-64.slaspec | 1 + .../Processors/x86/data/languages/x86.slaspec | 1 + 7 files changed, 324 insertions(+), 7 deletions(-) create mode 100644 Ghidra/Processors/x86/data/languages/cmpccxadd.sinc create mode 100644 Ghidra/Processors/x86/data/languages/rao.sinc diff --git a/Ghidra/Processors/x86/certification.manifest b/Ghidra/Processors/x86/certification.manifest index 71dfe24947..59a9073fab 100644 --- a/Ghidra/Processors/x86/certification.manifest +++ b/Ghidra/Processors/x86/certification.manifest @@ -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| diff --git a/Ghidra/Processors/x86/data/languages/cmpccxadd.sinc b/Ghidra/Processors/x86/data/languages/cmpccxadd.sinc new file mode 100644 index 0000000000..037ebf7144 --- /dev/null +++ b/Ghidra/Processors/x86/data/languages/cmpccxadd.sinc @@ -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 \ No newline at end of file diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index d216d902dc..234136613c 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -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 diff --git a/Ghidra/Processors/x86/data/languages/rao.sinc b/Ghidra/Processors/x86/data/languages/rao.sinc new file mode 100644 index 0000000000..ed804bfdec --- /dev/null +++ b/Ghidra/Processors/x86/data/languages/rao.sinc @@ -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 + diff --git a/Ghidra/Processors/x86/data/languages/sgx.sinc b/Ghidra/Processors/x86/data/languages/sgx.sinc index 9c124e14e2..54812ed3e2 100644 --- a/Ghidra/Processors/x86/data/languages/sgx.sinc +++ b/Ghidra/Processors/x86/data/languages/sgx.sinc @@ -255,3 +255,48 @@ define pcodeop enclu_unknown; } + +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 ; + RAX = enclv_edecvirtchild( RBX, RCX ); + ZF = (RAX != 0); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x1 ) goto ; + RAX = enclv_eincvirtchild( RBX, RCX ); + ZF = (RAX != 0); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x2 ) goto ; + RAX = enclv_esetcontext( RCX, RDX ); + ZF = (RAX != 0); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + enclv_unknown(); + + + +} diff --git a/Ghidra/Processors/x86/data/languages/x86-64.slaspec b/Ghidra/Processors/x86/data/languages/x86-64.slaspec index 8b442ec169..a682d8aa5d 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64.slaspec +++ b/Ghidra/Processors/x86/data/languages/x86-64.slaspec @@ -3,4 +3,5 @@ with : lockprefx=0 { @include "sgx.sinc" @include "fma.sinc" +@include "cmpccxadd.sinc" } diff --git a/Ghidra/Processors/x86/data/languages/x86.slaspec b/Ghidra/Processors/x86/data/languages/x86.slaspec index 5ec52e50f4..4308771525 100644 --- a/Ghidra/Processors/x86/data/languages/x86.slaspec +++ b/Ghidra/Processors/x86/data/languages/x86.slaspec @@ -18,4 +18,5 @@ with : lockprefx=0 { @include "smx.sinc" @include "cet.sinc" @include "rdrand.sinc" +@include "rao.sinc" }