From 1735e73f4e63eff6c3740a767ad58da0cf665ea3 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Mon, 31 Aug 2026 08:07:52 -0400 Subject: [PATCH] GP-7027: Fixed issue with x86 64 not zeroing out 32-bit partial regs --- Ghidra/Processors/x86/data/languages/avx.sinc | 87 +++++++++------ .../Processors/x86/data/languages/avx512.sinc | 63 ++++++----- .../x86/data/languages/avx512_manual.sinc | 9 +- Ghidra/Processors/x86/data/languages/ia.sinc | 103 +++++++++++++----- .../x86/data/languages/lockable.sinc | 7 +- .../Processors/x86/data/languages/rdrand.sinc | 6 +- .../Processors/x86/data/languages/x86.ldefs | 12 +- 7 files changed, 183 insertions(+), 104 deletions(-) diff --git a/Ghidra/Processors/x86/data/languages/avx.sinc b/Ghidra/Processors/x86/data/languages/avx.sinc index 607489e390..3bf015e263 100644 --- a/Ghidra/Processors/x86/data/languages/avx.sinc +++ b/Ghidra/Processors/x86/data/languages/avx.sinc @@ -661,10 +661,10 @@ define pcodeop vcvtps2pd_avx ; } # CVTSD2SI 3-253 PAGE 823 LINE 44315 -:VCVTSD2SI Reg32, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m64 +:VCVTSD2SI Reg32, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; (Reg32 & check_Reg32_dest) ... & XmmReg2_m64 { Reg32 = trunc(round(XmmReg2_m64[0,64])); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # CVTSD2SI 3-253 PAGE 823 LINE 44317 @@ -998,11 +998,9 @@ define pcodeop vldmxcsr_avx ; } # MASKMOVDQU 4-8 PAGE 1128 LINE 59041 -define pcodeop vmaskmovdqu_avx ; -:VMASKMOVDQU XmmReg1, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xF7; XmmReg1 & (mod=0x3 & XmmReg2) +:VMASKMOVDQU XmmReg1, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xF7; XmmReg1 & mod=0x3 & XmmReg2 & maskMovDI { - vmaskmovdqu_avx( XmmReg1, XmmReg2 ); - # TODO missing destination or side effects + maskMovDI = maskmovdqu( XmmReg1, XmmReg2 ); } # MAXPD 4-12 PAGE 1132 LINE 59201 @@ -1112,9 +1110,10 @@ define pcodeop vminss_avx ; @endif # MOVD/MOVQ 4-55 PAGE 1175 LINE 61362 -:VMOVD rm32, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x7E; XmmReg1 ... & rm32 +:VMOVD rm32, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x7E; (XmmReg1 & check_rm32_dest) ... & rm32 { rm32 = XmmReg1 [0,32]; + build check_rm32_dest; } # MOVD/MOVQ 4-55 PAGE 1175 LINE 61364 @@ -1253,32 +1252,32 @@ define pcodeop vmovlps_avx ; # MOVMSKPD 4-88 PAGE 1208 LINE 62906 define pcodeop vmovmskpd_avx ; -:VMOVMSKPD Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & (mod=0x3 & XmmReg2) +:VMOVMSKPD Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & check_Reg32_dest & (mod=0x3 & XmmReg2) { Reg32 = vmovmskpd_avx( XmmReg2 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # MOVMSKPD 4-88 PAGE 1208 LINE 62910 -:VMOVMSKPD Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & (mod=0x3 & YmmReg2) +:VMOVMSKPD Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & check_Reg32_dest & (mod=0x3 & YmmReg2) { Reg32 = vmovmskpd_avx( YmmReg2 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # MOVMSKPS 4-90 PAGE 1210 LINE 62986 define pcodeop vmovmskps_avx ; -:VMOVMSKPS Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & (mod=0x3 & XmmReg2) +:VMOVMSKPS Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & check_Reg32_dest & (mod=0x3 & XmmReg2) { Reg32 = vmovmskps_avx( XmmReg2 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # MOVMSKPS 4-90 PAGE 1210 LINE 62990 -:VMOVMSKPS Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & (mod=0x3 & YmmReg2) +:VMOVMSKPS Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x50; Reg32 & check_Reg32_dest & (mod=0x3 & YmmReg2) { Reg32 = vmovmskps_avx( YmmReg2 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # MOVNTDQA 4-92 PAGE 1212 LINE 63084 @@ -1766,20 +1765,34 @@ define pcodeop vpcmpeqd_avx ; # PCMPESTRI 4-253 PAGE 1373 LINE 71311 define pcodeop vpcmpestri_avx ; -:VPCMPESTRI XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A); byte=0x61; XmmReg1 ... & XmmReg2_m128; imm8 +:VPCMPESTRI XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x61 & check_ECX_dest; XmmReg1 ... & XmmReg2_m128; imm8 { - vpcmpestri_avx( XmmReg1, XmmReg2_m128, imm8:1 ); - # TODO missing destination or side effects + ECX = vpcmpestri_avx( XmmReg1, XmmReg2_m128, imm8:1, EAX, EDX ); + build check_ECX_dest; } +@ifdef IA64 +:VPCMPESTRI XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x61 & check_ECX_dest; XmmReg1 ... & XmmReg2_m128; imm8 +{ + ECX = vpcmpestri_avx( XmmReg1, XmmReg2_m128, imm8:1, RAX, RDX ); + build check_ECX_dest; +} +@endif + # PCMPESTRM 4-255 PAGE 1375 LINE 71395 define pcodeop vpcmpestrm_avx ; -:VPCMPESTRM XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A); byte=0x60; XmmReg1 ... & XmmReg2_m128; imm8 +:VPCMPESTRM XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x60; XmmReg1 ... & XmmReg2_m128; imm8 { - vpcmpestrm_avx( XmmReg1, XmmReg2_m128, imm8:1 ); - # TODO missing destination or side effects + XMM0 = vpcmpestrm_avx( XmmReg1, XmmReg2_m128, imm8:1, EAX, EDX ); } +@ifdef IA64 +:VPCMPESTRM XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x60; XmmReg1 ... & XmmReg2_m128; imm8 +{ + XMM0 = vpcmpestrm_avx( XmmReg1, XmmReg2_m128, imm8:1, RAX, RDX ); +} +@endif + # PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71499 define pcodeop vpcmpgtb_avx ; :VPCMPGTB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x64; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128 @@ -1814,22 +1827,20 @@ define pcodeop vpcmpgtq_avx ; # PCMPISTRI 4-266 PAGE 1386 LINE 71966 define pcodeop vpcmpistri_avx ; -:VPCMPISTRI XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x63; XmmReg1 ... & XmmReg2_m128; imm8 +:VPCMPISTRI XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x63 & check_ECX_dest; XmmReg1 ... & XmmReg2_m128; imm8 { - vpcmpistri_avx( XmmReg1, XmmReg2_m128, imm8:1 ); - # TODO missing destination or side effects + ECX = vpcmpistri_avx( XmmReg1, XmmReg2_m128, imm8:1 ); + build check_ECX_dest; } # PCMPISTRM 4-268 PAGE 1388 LINE 72052 define pcodeop vpcmpistrm_avx ; :VPCMPISTRM XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x62; XmmReg1 ... & XmmReg2_m128; imm8 { - vpcmpistrm_avx( XmmReg1, XmmReg2_m128, imm8:1 ); - # TODO missing destination or side effects + XMM0 = vpcmpistrm_avx( XmmReg1, XmmReg2_m128, imm8:1 ); } # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72322 -define pcodeop vpextrb_avx ; :VPEXTRB Rmr32, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x14; mod=3 & XmmReg1 & Rmr32 & check_Rmr32_dest; imm8 { local tmp8:1 = imm8 & 0xf; @@ -1846,7 +1857,6 @@ define pcodeop vpextrb_avx ; } # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72326 -define pcodeop vpextrd_avx ; :VPEXTRD Rmr32, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x16; mod=3 & XmmReg1 & Rmr32 & check_Rmr32_dest; imm8 { local tmp8:1 = imm8 & 3; @@ -1875,8 +1885,8 @@ define pcodeop vpextrd_avx ; # PEXTRW 4-277 PAGE 1397 LINE 72478 :VPEXTRW Reg32, XmmReg2, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xC5; Reg32 & check_Reg32_dest & (mod=0x3 & XmmReg2); imm8 { - local tmp8:1 = imm8 & 7; - local tmp = XmmReg2 >> (tmp8*16); + local sel:1 = imm8 & 0x7; + local tmp = XmmReg2 >> (sel * 16); Reg32 = zext(tmp[0,16]); build check_Reg32_dest; } @@ -1884,19 +1894,28 @@ define pcodeop vpextrd_avx ; # PEXTRW 4-277 PAGE 1397 LINE 72483 :VPEXTRW Reg32, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x15; XmmReg1 & mod=3 & Reg32 & check_Reg32_dest; imm8 { - local tmp8:1 = imm8 & 7; - local tmp = XmmReg1 >> (tmp8*16); + local sel:1 = imm8 & 0x7; + local tmp = XmmReg1 >> (sel * 16); Reg32 = zext(tmp[0,16]); build check_Reg32_dest; } :VPEXTRW m16, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x15; XmmReg1 ... & m16; imm8 { - local tmp8:1 = imm8 & 7; - local tmp = XmmReg1 >> (tmp8*16); + local sel:1 = imm8 & 7; + local tmp = XmmReg1 >> (sel*16); m16 = tmp[0,16]; } +:VPEXTRW m16, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x15; XmmReg1 ... & m16; imm8 +{ + local sel:1 = imm8 & 0x7; + local tmp = XmmReg1 >> (sel * 16); + local res:2 = tmp(0); + m16 = res; +} + + # PHADDW/PHADDD 4-280 PAGE 1400 LINE 72627 define pcodeop vphaddw_avx ; :VPHADDW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x01; (XmmReg1 & ZmmReg1) ... & XmmReg2_m128 diff --git a/Ghidra/Processors/x86/data/languages/avx512.sinc b/Ghidra/Processors/x86/data/languages/avx512.sinc index 5fbec89db3..b58d1290b0 100644 --- a/Ghidra/Processors/x86/data/languages/avx512.sinc +++ b/Ghidra/Processors/x86/data/languages/avx512.sinc @@ -511,11 +511,11 @@ define pcodeop vcvtps2pd_avx512f ; # CVTSD2SI 3-253 PAGE 823 LINE 44320 define pcodeop vcvtsd2si_avx512f ; -:VCVTSD2SI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m64 +:VCVTSD2SI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; (Reg32 & check_Reg32_dest) ... & XmmReg2_m64 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvtsd2si_avx512f( XmmReg2_m64 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # CVTSD2SI 3-253 PAGE 823 LINE 44322 @@ -591,11 +591,11 @@ define pcodeop vcvtss2sd_avx512f ; # CVTSS2SI 3-263 PAGE 833 LINE 44839 define pcodeop vcvtss2si_avx512f ; -:VCVTSS2SI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m32 +:VCVTSS2SI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2D; (Reg32 & check_Reg32_dest) ... & XmmReg2_m32 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvtss2si_avx512f( XmmReg2_m32 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # CVTSS2SI 3-263 PAGE 833 LINE 44841 @@ -673,11 +673,11 @@ define pcodeop vcvttps2dq_avx512f ; # CVTTSD2SI 3-274 PAGE 844 LINE 45385 define pcodeop vcvttsd2si_avx512f ; -:VCVTTSD2SI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2C; Reg32 ... & XmmReg2_m64 +:VCVTTSD2SI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2C; (Reg32 & check_Reg32_dest) ... & XmmReg2_m64 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvttsd2si_avx512f( XmmReg2_m64 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # CVTTSD2SI 3-274 PAGE 844 LINE 45388 @@ -691,11 +691,11 @@ define pcodeop vcvttsd2si_avx512f ; # CVTTSS2SI 3-276 PAGE 846 LINE 45479 define pcodeop vcvttss2si_avx512f ; -:VCVTTSS2SI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2C; Reg32 ... & XmmReg2_m32 +:VCVTTSS2SI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2C; (Reg32 & check_Reg32_dest) ... & XmmReg2_m32 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvttss2si_avx512f( XmmReg2_m32 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # CVTTSS2SI 3-276 PAGE 846 LINE 45482 @@ -1175,10 +1175,11 @@ define pcodeop vmovaps_avx512f ; @endif # MOVD/MOVQ 4-55 PAGE 1175 LINE 61370 -:VMOVD rm32, XmmReg1 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x7E; XmmReg1 ... & rm32 +:VMOVD rm32, XmmReg1 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x7E; (XmmReg1 & check_rm32_dest) ... & rm32 [ evexD8Type = 1; evexTType = 3; ] # (TupleType T1S-MR) { rm32 = XmmReg1[0,32]; + build check_rm32_dest; } # MOVD/MOVQ 4-55 PAGE 1175 LINE 61372 @@ -3146,15 +3147,14 @@ define pcodeop vpcmpgtq_avx512f ; } # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72334 -:VPEXTRB Reg32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x14; XmmReg1 & mod=3 & Reg32 & check_Reg32_dest; imm8 +:VPEXTRB Rmr32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x14; XmmReg1 & mod=3 & Rmr32 & check_Rmr32_dest; imm8 { local tmp8:1 = imm8 & 0xf; local tmp = XmmReg1 >> (tmp8*8); - Reg32 = zext(tmp[0,8]); - build check_Reg32_dest; + Rmr32 = zext(tmp[0,8]); + build check_Rmr32_dest; } - :VPEXTRB m8, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x14; XmmReg1 ... & m8; imm8 { local tmp8:1 = imm8 & 0xf; @@ -3163,11 +3163,12 @@ define pcodeop vpcmpgtq_avx512f ; } # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72339 -:VPEXTRD rm32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x16; XmmReg1 ... & rm32; imm8 +:VPEXTRD rm32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x16; XmmReg1 ... & (rm32 & check_rm32_dest); imm8 { local tmp8:1 = imm8 & 0x3; local tmp = XmmReg1 >> (tmp8*32); rm32 = tmp[0,32]; + build check_rm32_dest; } # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72343 @@ -3190,11 +3191,11 @@ define pcodeop vpcmpgtq_avx512f ; # PEXTRW 4-277 PAGE 1397 LINE 72494 -:VPEXTRW Reg32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x15; XmmReg1 & mod=3 & Reg32 & check_Reg32_dest; imm8 +:VPEXTRW Rmr32, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x15; XmmReg1 & mod=3 & Rmr32 & check_Rmr32_dest; imm8 { local tmp = XmmReg1 >> (imm8*16); - Reg32 = zext(tmp[0,16]); - build check_Reg32_dest; + Rmr32 = zext(tmp[0,16]); + build check_Rmr32_dest; } :VPEXTRW m16, XmmReg1, imm8 is $(EVEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x15; XmmReg1 ... & m16; imm8 @@ -6910,11 +6911,11 @@ define pcodeop vcvtqq2ps_avx512dq ; # VCVTSD2USI 5-54 PAGE 1878 LINE 96907 define pcodeop vcvtsd2usi_avx512f ; -:VCVTSD2USI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x79; Reg32 ... & XmmReg2_m64 +:VCVTSD2USI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x79; (Reg32 & check_Reg32_dest) ... & XmmReg2_m64 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvtsd2usi_avx512f( XmmReg2_m64 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # VCVTSD2USI 5-54 PAGE 1878 LINE 96909 @@ -6928,11 +6929,11 @@ define pcodeop vcvtsd2usi_avx512f ; # VCVTSS2USI 5-55 PAGE 1879 LINE 96967 define pcodeop vcvtss2usi_avx512f ; -:VCVTSS2USI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x79; Reg32 ... & XmmReg2_m32 +:VCVTSS2USI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x79; (Reg32 & check_Reg32_dest) ... & XmmReg2_m32 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvtss2usi_avx512f( XmmReg2_m32 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # VCVTSS2USI 5-55 PAGE 1879 LINE 96969 @@ -7138,11 +7139,11 @@ define pcodeop vcvttps2uqq_avx512dq ; # VCVTTSD2USI 5-70 PAGE 1894 LINE 97722 define pcodeop vcvttsd2usi_avx512f ; -:VCVTTSD2USI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x78; Reg32 ... & XmmReg2_m64 +:VCVTTSD2USI Reg32, XmmReg2_m64 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x78; (Reg32 & check_Reg32_dest) ... & XmmReg2_m64 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvttsd2usi_avx512f( XmmReg2_m64 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # VCVTTSD2USI 5-70 PAGE 1894 LINE 97725 @@ -7156,11 +7157,11 @@ define pcodeop vcvttsd2usi_avx512f ; # VCVTTSS2USI 5-71 PAGE 1895 LINE 97782 define pcodeop vcvttss2usi_avx512f ; -:VCVTTSS2USI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x78; Reg32 ... & XmmReg2_m32 +:VCVTTSS2USI Reg32, XmmReg2_m32 is $(EVEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x78; (Reg32 & check_Reg32_dest) ... & XmmReg2_m32 [ evexD8Type = 1; evexTType = 5; ] # (TupleType T1F) { Reg32 = vcvttss2usi_avx512f( XmmReg2_m32 ); - # TODO Reg64 = zext(Reg32) + build check_Reg32_dest; } # VCVTTSS2USI 5-71 PAGE 1895 LINE 97785 @@ -14356,9 +14357,10 @@ define pcodeop vcvtsh2sd_avx512fp16 ; # VCVTSH2SI 5-86 PAGE 1910 LINE 105738 define pcodeop vcvtsh2si_avx512fp16 ; -:VCVTSH2SI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m16 +:VCVTSH2SI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x2D; (Reg32 & check_Reg32_dest) ... & XmmReg2_m16 { Reg32 = vcvtsh2si_avx512fp16( XmmReg2_m16 ); + build check_Reg32_dest; } # VCVTSH2SI 5-86 PAGE 1910 LINE 105740 @@ -14383,9 +14385,10 @@ define pcodeop vcvtsh2ss_avx512fp16 ; # VCVTSH2USI 5-88 PAGE 1912 LINE 105851 define pcodeop vcvtsh2usi_avx512fp16 ; -:VCVTSH2USI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x79; Reg32 ... & XmmReg2_m16 +:VCVTSH2USI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x79; (Reg32 & check_Reg32_dest) ... & XmmReg2_m16 { Reg32 = vcvtsh2usi_avx512fp16( XmmReg2_m16 ); + build check_Reg32_dest; } # VCVTSH2USI 5-88 PAGE 1912 LINE 105853 @@ -14607,9 +14610,10 @@ define pcodeop vcvttph2w_avx512fp16 ; # VCVTTSH2SI 5-119 PAGE 1943 LINE 107355 define pcodeop vcvttsh2si_avx512fp16 ; -:VCVTTSH2SI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x2C; Reg32 ... & XmmReg2_m16 +:VCVTTSH2SI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x2C; (Reg32 & check_Reg32_dest)... & XmmReg2_m16 { Reg32 = vcvttsh2si_avx512fp16( XmmReg2_m16 ); + build check_Reg32_dest; } # VCVTTSH2SI 5-119 PAGE 1943 LINE 107358 @@ -14622,9 +14626,10 @@ define pcodeop vcvttsh2si_avx512fp16 ; # VCVTTSH2USI 5-120 PAGE 1944 LINE 107409 define pcodeop vcvttsh2usi_avx512fp16 ; -:VCVTTSH2USI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x78; Reg32 ... & XmmReg2_m16 +:VCVTTSH2USI Reg32, XmmReg2_m16 is $(EVEX_NONE) & $(EVEX_LLIG) & $(VEX_PRE_F3) & $(VEX_MAP5) & $(VEX_W0); byte=0x78; (Reg32 & check_Reg32_dest) ... & XmmReg2_m16 { Reg32 = vcvttsh2usi_avx512fp16( XmmReg2_m16 ); + build check_Reg32_dest; } # VCVTTSH2USI 5-120 PAGE 1944 LINE 107412 diff --git a/Ghidra/Processors/x86/data/languages/avx512_manual.sinc b/Ghidra/Processors/x86/data/languages/avx512_manual.sinc index 27e2c70803..80501bb757 100644 --- a/Ghidra/Processors/x86/data/languages/avx512_manual.sinc +++ b/Ghidra/Processors/x86/data/languages/avx512_manual.sinc @@ -159,15 +159,17 @@ } # KMOVW/KMOVB/KMOVQ/KMOVD 3-499 PAGE 1069 LINE 56184 -:KMOVW Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm +:KMOVW Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm & check_Reg32_dest { Reg32 = zext(KReg_rm[0,16]); + build check_Reg32_dest; } # KMOVW/KMOVB/KMOVQ/KMOVD 3-499 PAGE 1069 LINE 56186 -:KMOVB Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm +:KMOVB Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm & check_Reg32_dest { Reg32 = zext(KReg_rm[0,8]); + build check_Reg32_dest; } # KMOVW/KMOVB/KMOVQ/KMOVD 3-499 PAGE 1069 LINE 56188 @@ -179,9 +181,10 @@ @endif # KMOVW/KMOVB/KMOVQ/KMOVD 3-499 PAGE 1069 LINE 56190 -:KMOVD Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm +:KMOVD Reg32, KReg_rm is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x93; Reg32 & KReg_rm & check_Reg32_dest { Reg32 = KReg_rm[0,32]; + build check_Reg32_dest; } # KNOTW/KNOTB/KNOTQ/KNOTD 3-501 PAGE 1071 LINE 56266 diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index ec21f18a47..fad8c59580 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -1503,12 +1503,14 @@ check_Rmr32_dest: is rexBprefix=0 & r32 & r64 { r64 = zext(r32); } check_Rmr32_dest: is rexBprefix=1 & r32_x & r64_x { r64_x = zext(r32_x); } check_rm32_dest: is mod=3 & check_Rmr32_dest { build check_Rmr32_dest; } check_EAX_dest: is epsilon { RAX = zext(EAX); } +check_ECX_dest: is epsilon { RCX = zext(ECX); } check_EDX_dest: is epsilon { RDX = zext(EDX); } check_vexVVVV_r32_dest: is bit64=1 & vexVVVV_r64 & vexVVVV_r32 { vexVVVV_r64 = zext(vexVVVV_r32);} @else check_Reg32_dest: is epsilon { } check_Rmr32_dest: is epsilon { } check_EAX_dest: is epsilon { } +check_ECX_dest: is epsilon { } check_EDX_dest: is epsilon { } check_vexVVVV_r32_dest: is epsilon { } @endif @@ -3906,7 +3908,7 @@ define pcodeop LocalDescriptorTableRegister; :LODSB^rep^reptail dseSI1 is vexMode=0 & rep & reptail & byte=0xAC & dseSI1 { build rep; build dseSI1; AL=dseSI1; build reptail; } :LODSW^rep^reptail dseSI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xAD & dseSI2 { build rep; build dseSI2; AX=dseSI2; build reptail; } -:LODSD^rep^reptail dseSI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xAD & dseSI4 { build rep; build dseSI4; EAX=dseSI4; build reptail; } +:LODSD^rep^reptail dseSI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xAD & dseSI4 & check_EAX_dest { build rep; build dseSI4; EAX=dseSI4; build check_EAX_dest; build reptail; } @ifdef IA64 :LODSQ^rep^reptail dseSI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xAD & dseSI8 { build rep; build dseSI8; RAX=dseSI8; build reptail; } @endif @@ -3937,10 +3939,11 @@ define pcodeop SegmentLimit; ZF = tmp[16,1]; } -:LSL Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x3; rm32 & Reg32 ... +:LSL Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x3; rm32 & (Reg32 & check_Reg32_dest) ... { tmp:3 = SegmentLimit(rm32); Reg32 = zext(tmp:2); + build check_Reg32_dest; ZF = tmp[16,1]; } @@ -4078,9 +4081,10 @@ define pcodeop TaskRegister; :MOV creg_x, Rmr64 is $(LONGMODE_ON) & vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr64 & creg_x { creg_x=Rmr64; } @endif -:MOV Rmr32, creg is $(LONGMODE_OFF) & vexMode=0 & byte=0xf; byte=0x20; Rmr32 & creg { +:MOV Rmr32, creg is $(LONGMODE_OFF) & vexMode=0 & byte=0xf; byte=0x20; Rmr32 & check_Rmr32_dest & creg { @ifdef IA64 Rmr32 = creg:4; + build check_Rmr32_dest; @else Rmr32 = creg; @endif @@ -4090,9 +4094,10 @@ define pcodeop TaskRegister; :MOV Rmr64, creg_x is $(LONGMODE_ON) & vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr64 & creg_x { Rmr64 = creg_x; } @endif -:MOV Rmr32, debugreg is $(LONGMODE_OFF) & vexMode=0 & byte=0xf; byte=0x21; Rmr32 & debugreg { +:MOV Rmr32, debugreg is $(LONGMODE_OFF) & vexMode=0 & byte=0xf; byte=0x21; Rmr32 & check_Rmr32_dest & debugreg { @ifdef IA64 Rmr32 = debugreg:4; + build check_Rmr32_dest; @else Rmr32 = debugreg; @endif @@ -4120,14 +4125,55 @@ define pcodeop TaskRegister; :MOV testreg, r32 is vexMode=0 & byte=0xf; byte=0x26; r32 & testreg & mod=3 { testreg = r32; } @endif -define pcodeop swap_bytes; -:MOVBE Reg16, m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x38; byte=0xf0; Reg16 ... & m16 { Reg16 = swap_bytes( m16 ); } -:MOVBE Reg32, m32 is vexMode=0 & opsize=1 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; Reg32 ... & m32 { Reg32 = swap_bytes( m32 ); } -:MOVBE m16, Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x38; byte=0xf1; Reg16 ... & m16 { m16 = swap_bytes( Reg16 ); } -:MOVBE m32, Reg32 is vexMode=0 & opsize=1 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg32 ... & m32 { m32 = swap_bytes( Reg32 ); } +:MOVBE Reg16, m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x38; byte=0xf0; Reg16 ... & m16 { local tmp = m16; local dest:2 = 0; dest[0,8] = tmp[8,8]; dest[8,8] = tmp[0,8]; Reg16 = dest; } +:MOVBE m16, Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x38; byte=0xf1; Reg16 ... & m16 { local tmp = Reg16; local dest:2 = 0; dest[0,8] = tmp[8,8]; dest[8,8] = tmp[0,8]; m16 = dest; } +:MOVBE Reg32, m32 is vexMode=0 & opsize=1 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; (Reg32 & check_Reg32_dest) ... & m32 { + local tmp = m32; + local dest:4 = 0; + dest[0,8] = tmp[24,8]; + dest[8,8] = tmp[16,8]; + dest[16,8] = tmp[8,8]; + dest[24,8] = tmp[0,8]; + Reg32 = dest; + build check_Reg32_dest; +} +:MOVBE m32, Reg32 is vexMode=0 & opsize=1 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg32 ... & m32 { + local tmp = Reg32; + local dest:4 = 0; + dest[0,8] = tmp[24,8]; + dest[8,8] = tmp[16,8]; + dest[16,8] = tmp[8,8]; + dest[24,8] = tmp[0,8]; + m32 = dest; +} @ifdef IA64 -:MOVBE Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; Reg64 ... & m64 { Reg64 = swap_bytes( m64 ); } -:MOVBE m64, Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg64 ... & m64 { m64 = swap_bytes( Reg64 ); } +:MOVBE Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; Reg64 ... & m64 { + local tmp = m64; + local dest:8 = 0; + dest[0,8] = tmp[56,8]; + dest[8,8] = tmp[48,8]; + dest[16,8] = tmp[40,8]; + dest[24,8] = tmp[32,8]; + dest[32,8] = tmp[24,8]; + dest[40,8] = tmp[16,8]; + dest[48,8] = tmp[8,8]; + dest[56,8] = tmp[0,8]; + Reg64 = dest; +} + +:MOVBE m64, Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg64 ... & m64 { + local tmp = Reg64; + local dest:8 = 0; + dest[0,8] = tmp[56,8]; + dest[8,8] = tmp[48,8]; + dest[16,8] = tmp[40,8]; + dest[24,8] = tmp[32,8]; + dest[32,8] = tmp[24,8]; + dest[40,8] = tmp[16,8]; + dest[48,8] = tmp[8,8]; + dest[56,8] = tmp[0,8]; + m64 = dest; +} @endif @@ -5148,7 +5194,7 @@ define pcodeop wrmsrns; @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 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); } :XADD Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x0F; byte=0xC1; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 & check_Reg32_dest { addflags(Rmr32,Reg32); local tmp = Rmr32 + Reg32; Reg32 = Rmr32; Rmr32 = tmp; build check_Rmr32_dest; build check_Reg32_dest; resultflags(tmp); } @ifdef IA64 @@ -7370,15 +7416,15 @@ define pcodeop divps; define pcodeop lddqu; :LDDQU XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xF0; XmmReg ... & m128 { XmmReg = lddqu(XmmReg, m128); } -maskMovDI: seg16^DI is addrsize=0 & seg16 & DI { tmp:$(SIZE) = segment(seg16,DI); export tmp; } -maskMovDI: segWide^EDI is addrsize=1 & segWide & EDI { tmp:$(SIZE) = zext(EDI); export tmp; } -maskMovDI: segWide^EDI is addrsize=1 & segWide & highseg=1 & EDI { tmp:$(SIZE) = segWide + zext(EDI); export tmp; } +maskMovDI: seg16^DI is addrsize=0 & seg16 & DI { tmp:$(SIZE) = segment(seg16,DI); export *:16 tmp; } +maskMovDI: segWide^EDI is addrsize=1 & segWide & EDI { tmp:$(SIZE) = zext(EDI); export *:16 tmp; } +maskMovDI: segWide^EDI is addrsize=1 & segWide & highseg=1 & EDI { tmp:$(SIZE) = segWide + zext(EDI); export *:16 tmp; } @ifdef IA64 -maskMovDI: segWide^RDI is $(LONGMODE_ON) & addrsize=2 & segWide & RDI { tmp:$(SIZE) = RDI; export tmp; } -maskMovDI: segWide^RDI is $(LONGMODE_ON) & addrsize=2 & segWide & highseg=1 & RDI { tmp:$(SIZE) = segWide + RDI; export tmp; } +maskMovDI: segWide^RDI is $(LONGMODE_ON) & addrsize=2 & segWide & RDI { tmp:$(SIZE) = RDI; export *:16 tmp; } +maskMovDI: segWide^RDI is $(LONGMODE_ON) & addrsize=2 & segWide & highseg=1 & RDI { tmp:$(SIZE) = segWide + RDI; export *:16 tmp; } @endif define pcodeop maskmovdqu; -:MASKMOVDQU XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF7 & maskMovDI; XmmReg1 & XmmReg2 { maskmovdqu(XmmReg1, XmmReg2, maskMovDI); } +:MASKMOVDQU XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF7 & maskMovDI; XmmReg1 & XmmReg2 { maskMovDI = maskmovdqu(XmmReg1, XmmReg2); } define pcodeop maxpd; :MAXPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5F; XmmReg ... & m128 { XmmReg = maxpd(XmmReg, m128); } @@ -7619,10 +7665,10 @@ define pcodeop movdq2q; :MOVLPS m64, XmmReg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x13; XmmReg ... & m64 { m64 = XmmReg[0,64]; } define pcodeop movmskpd; -:MOVMSKPD Reg32, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x50; XmmReg2 & Reg32 { Reg32 = movmskpd(Reg32, XmmReg2); } +:MOVMSKPD Reg32, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x50; XmmReg2 & Reg32 & check_Reg32_dest { Reg32 = movmskpd(Reg32, XmmReg2); build check_Reg32_dest; } define pcodeop movmskps; -:MOVMSKPS Reg32, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x50; XmmReg2 & Reg32 { Reg32 = movmskps(Reg32, XmmReg2); } +:MOVMSKPS Reg32, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x50; XmmReg2 & Reg32 & check_Reg32_dest { Reg32 = movmskps(Reg32, XmmReg2); build check_Reg32_dest; } :MOVNTQ m64, mmxreg is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE7; mmxreg ... & m64 { m64 = mmxreg; } @@ -8617,10 +8663,11 @@ define pcodeop pavgw; XmmReg1[96,32] = zext(XmmReg1[96,32] s> XmmReg2[96,32]) * 0xFFFFFFFF; } -:PEXTRW Reg32, mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC5; Reg32 & mmxreg2; imm8 +:PEXTRW Reg32, mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC5; Reg32 & check_Reg32_dest & mmxreg2; imm8 { temp:8 = mmxreg2 >> ( (imm8 & 0x03) * 16 ); Reg32 = zext(temp:2); + build check_Reg32_dest; } :PEXTRW Reg32, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC5; Reg32 & XmmReg2 & check_Reg32_dest; imm8 @@ -10501,11 +10548,11 @@ define pcodeop crc32; @endif define pcodeop pcmpestri; -:PCMPESTRI XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61; XmmReg ... & m128; imm8 { ECX = pcmpestri(XmmReg, m128, imm8:8, EAX, EDX); } -:PCMPESTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpestri(XmmReg1, XmmReg2, imm8:8, EAX, EDX); } +:PCMPESTRI XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61 & check_ECX_dest; XmmReg ... & m128; imm8 { ECX = pcmpestri(XmmReg, m128, imm8:8, EAX, EDX); build check_ECX_dest; } +:PCMPESTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61 & check_ECX_dest; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpestri(XmmReg1, XmmReg2, imm8:8, EAX, EDX); build check_ECX_dest; } @ifdef IA64 -:PCMPESTRI XmmReg, m128, imm8 is vexMode=0 & $(REX_W) & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61; XmmReg ... & m128; imm8 { ECX = pcmpestri(XmmReg, m128, imm8:8, RAX, RDX); } -:PCMPESTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(REX_W) & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpestri(XmmReg1, XmmReg2, imm8:8, RAX, RDX); } +:PCMPESTRI XmmReg, m128, imm8 is vexMode=0 & $(REX_W) & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61 & check_ECX_dest; XmmReg ... & m128; imm8 { ECX = pcmpestri(XmmReg, m128, imm8:8, RAX, RDX); build check_ECX_dest; } +:PCMPESTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(REX_W) & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x61 & check_ECX_dest; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpestri(XmmReg1, XmmReg2, imm8:8, RAX, RDX); build check_ECX_dest; } @endif define pcodeop pcmpestrm; @@ -10517,8 +10564,8 @@ define pcodeop pcmpestrm; @endif define pcodeop pcmpistri; -:PCMPISTRI XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x63; XmmReg ... & m128; imm8 { ECX = pcmpistri(XmmReg, m128, imm8:8); } -:PCMPISTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x63; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpistri(XmmReg1, XmmReg2, imm8:8); } +:PCMPISTRI XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x63 & check_ECX_dest; XmmReg ... & m128; imm8 { ECX = pcmpistri(XmmReg, m128, imm8:8); build check_ECX_dest; } +:PCMPISTRI XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x63 & check_ECX_dest; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { ECX = pcmpistri(XmmReg1, XmmReg2, imm8:8); build check_ECX_dest;} define pcodeop pcmpistrm; :PCMPISTRM XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x62; XmmReg ... & m128; imm8 { XMM0 = pcmpistrm(XmmReg, m128, imm8:8); } @@ -10716,7 +10763,7 @@ define pcodeop PackedSwapDWords; :PSWAPD mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xBB & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedSwapDWords(mmxreg1, mmxreg2); } define pcodeop MaskedMoveQWord; -:MASKMOVQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF7 & maskMovDI; mmxmod = 3 & mmxreg1 & mmxreg2 { MaskedMoveQWord(mmxreg1, mmxreg2, maskMovDI); } +:MASKMOVQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF7 & maskMovDI; mmxmod = 3 & mmxreg1 & mmxreg2 { maskMovDI = MaskedMoveQWord(mmxreg1, mmxreg2); } #### diff --git a/Ghidra/Processors/x86/data/languages/lockable.sinc b/Ghidra/Processors/x86/data/languages/lockable.sinc index 9f8e7c7baa..ebcbe976fe 100644 --- a/Ghidra/Processors/x86/data/languages/lockable.sinc +++ b/Ghidra/Processors/x86/data/languages/lockable.sinc @@ -643,7 +643,7 @@ } @endif -:CMPXCHG8B^lockx m64 is vexMode=0 & lockx & unlock & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 ) ... & m64 +:CMPXCHG8B^lockx m64 is vexMode=0 & lockx & unlock & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 & check_EAX_dest & check_EDX_dest ) ... & m64 { build lockx; local dest = m64; @@ -651,6 +651,8 @@ if (ZF == 1) goto ; EDX = dest(4); EAX = dest:4; + build check_EAX_dest; + build check_EDX_dest; goto ; m64 = (zext(ECX) << 32) | zext(EBX); @@ -1196,13 +1198,14 @@ build unlock; } -:XADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x0F; byte=0xC1; m32 & Reg32 ... +:XADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x0F; byte=0xC1; (check_Reg32_dest & Reg32) ... & m32 { build lockx; build m32; addflags(m32,Reg32); local tmp = m32 + Reg32; Reg32 = m32; + build check_Reg32_dest; m32 = tmp; resultflags(tmp); build unlock; diff --git a/Ghidra/Processors/x86/data/languages/rdrand.sinc b/Ghidra/Processors/x86/data/languages/rdrand.sinc index 4037bb95dc..3372e900d1 100644 --- a/Ghidra/Processors/x86/data/languages/rdrand.sinc +++ b/Ghidra/Processors/x86/data/languages/rdrand.sinc @@ -12,11 +12,12 @@ macro rdflags(){ rdflags(); } -:RDRAND Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=6 +:RDRAND Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & check_Reg32_dest & reg_opcode=6 { Rmr32 = rdrand(); CF=rdrandIsValid(); rdflags(); + build check_Reg32_dest; } @ifdef IA64 :RDRAND Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=6 @@ -35,11 +36,12 @@ define pcodeop rdseedIsValid; CF=rdseedIsValid(); rdflags(); } -:RDSEED Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=7 +:RDSEED Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=7 { Rmr32 = rdseed(); CF=rdseedIsValid(); rdflags(); + build check_Rmr32_dest; } @ifdef IA64 :RDSEED Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=7 diff --git a/Ghidra/Processors/x86/data/languages/x86.ldefs b/Ghidra/Processors/x86/data/languages/x86.ldefs index 089bee449a..778d26bbda 100644 --- a/Ghidra/Processors/x86/data/languages/x86.ldefs +++ b/Ghidra/Processors/x86/data/languages/x86.ldefs @@ -5,7 +5,7 @@ endian="little" size="32" variant="default" - version="4.8" + version="4.9" slafile="x86.sla" processorspec="x86.pspec" manualindexfile="../manuals/x86.idx" @@ -37,7 +37,7 @@ endian="little" size="32" variant="System Management Mode" - version="4.8" + version="4.9" slafile="x86.sla" processorspec="x86-16.pspec" manualindexfile="../manuals/x86.idx" @@ -50,7 +50,7 @@ endian="little" size="16" variant="Real Mode" - version="4.8" + version="4.9" slafile="x86.sla" processorspec="x86-16-real.pspec" manualindexfile="../manuals/x86.idx" @@ -70,7 +70,7 @@ endian="little" size="16" variant="Protected Mode" - version="4.8" + version="4.9" slafile="x86.sla" processorspec="x86-16.pspec" manualindexfile="../manuals/x86.idx" @@ -85,7 +85,7 @@ endian="little" size="64" variant="default" - version="4.8" + version="4.9" slafile="x86-64.sla" processorspec="x86-64.pspec" manualindexfile="../manuals/x86.idx" @@ -108,7 +108,7 @@ endian="little" size="64" variant="compat32" - version="4.8" + version="4.9" slafile="x86-64.sla" processorspec="x86-64-compat32.pspec" manualindexfile="../manuals/x86.idx"