From 8de5c7be3ab5a072f6633b00e14a4a995014390e Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Fri, 4 Apr 2025 14:53:31 +0200 Subject: [PATCH 1/6] Run icicle tests --- .github/workflows/build.yml | 15 +++++++++++++-- src/windows-emulator/windows_emulator.cpp | 8 ++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77423174..ab0b53d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -268,6 +268,9 @@ jobs: - Linux x86_64 Clang - macOS arm64 - macOS x86_64 + emulator: + - Unicorn + - Icicle emulation-root: - Windows 2025 - Windows 2022 @@ -298,11 +301,16 @@ jobs: with: submodules: recursive - - name: Setup Environment Variables + - name: Setup Asan Environment Variables if: ${{ contains(matrix.platform, 'Sanitizer') }} run: | echo "ASAN_OPTIONS=detect_odr_violation=0" >> $GITHUB_ENV + - name: Setup Icicle Environment Variables + if: ${{ matrix.emulator == 'Icicle' }} + run: | + echo "EMULATOR_ICICLE=1" >> $GITHUB_ENV + - name: Download Test Configuration uses: actions/download-artifact@v4.2.1 with: @@ -348,6 +356,9 @@ jobs: architecture: - x86_64 #- arm64-v8a + emulator: + - Unicorn + - Icicle emulation-root: - Windows 2025 - Windows 2022 @@ -398,7 +409,7 @@ jobs: with: api-level: 29 arch: ${{matrix.architecture}} - script: "adb push build/${{matrix.preset}}/artifacts/* /data/local/tmp && adb shell \"cd /data/local/tmp && export LD_LIBRARY_PATH=. && chmod +x ./analyzer && ./analyzer -e ./root c:/test-sample.exe\"" + script: "adb push build/${{matrix.preset}}/artifacts/* /data/local/tmp && adb shell \"cd /data/local/tmp && export LD_LIBRARY_PATH=. && chmod +x ./analyzer && EMULATOR_ICICLE=${{ matrix.emulator == 'Icicle' }} ./analyzer -e ./root c:/test-sample.exe\"" summary: name: Pipeline Summary diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index cccbb3fb..b9abddab 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -210,6 +210,14 @@ namespace std::unique_ptr create_default_x64_emulator() { +#if MOMO_ENABLE_RUST_CODE + const auto* env = getenv("EMULATOR_ICICLE"); + if (env && (env == "1"sv || env == "true"sv)) + { + return icicle::create_x64_emulator(); + } +#endif + return unicorn::create_x64_emulator(); } From d6a419d5f6184a7b31509a943139954a8c58185a Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Fri, 4 Apr 2025 15:11:25 +0200 Subject: [PATCH 2/6] Add Ghidra processor specification --- src/icicle/CMakeLists.txt | 6 + .../Processors/x86/data/languages/adx.sinc | 33 + .../Processors/x86/data/languages/avx.sinc | 3275 ++++++ .../Processors/x86/data/languages/avx2.sinc | 1221 +++ .../x86/data/languages/avx2_manual.sinc | 252 + .../x86/data/languages/avx_manual.sinc | 287 + .../Processors/x86/data/languages/bmi1.sinc | 195 + .../Processors/x86/data/languages/bmi2.sinc | 209 + .../Processors/x86/data/languages/cet.sinc | 84 + .../Processors/x86/data/languages/clwb.sinc | 14 + .../Processors/x86/data/languages/fma.sinc | 800 ++ .../Processors/x86/data/languages/ia.sinc | 9100 +++++++++++++++++ .../x86/data/languages/lockable.sinc | 1380 +++ .../Processors/x86/data/languages/lzcnt.sinc | 32 + .../Processors/x86/data/languages/macros.sinc | 3 + .../Processors/x86/data/languages/mpx.sinc | 234 + .../x86/data/languages/old/x86RealV1.lang | 150 + .../x86/data/languages/old/x86RealV1.trans | 7 + .../x86/data/languages/old/x86V1.lang | 151 + .../x86/data/languages/old/x86V1.trans | 8 + .../x86/data/languages/old/x86_64bit_v1.lang | 221 + .../x86/data/languages/old/x86_64bit_v1.trans | 8 + .../x86/data/languages/old/x86smmV1.lang | 150 + .../x86/data/languages/old/x86smmV1.trans | 7 + .../x86/data/languages/pclmulqdq.sinc | 173 + .../Processors/x86/data/languages/rdrand.sinc | 51 + .../Processors/x86/data/languages/sgx.sinc | 257 + .../Processors/x86/data/languages/sha.sinc | 53 + .../Processors/x86/data/languages/smx.sinc | 67 + .../x86/data/languages/x86-16-real.pspec | 33 + .../x86/data/languages/x86-16.cspec | 174 + .../Processors/x86/data/languages/x86-16.gdis | 3 + .../x86/data/languages/x86-16.pspec | 34 + .../x86/data/languages/x86-64-gcc.cspec | 242 + .../x86/data/languages/x86-64-win.cspec | 224 + .../x86/data/languages/x86-64.dwarf | 34 + .../x86/data/languages/x86-64.pspec | 160 + .../x86/data/languages/x86-64.slaspec | 6 + .../Processors/x86/data/languages/x86.dwarf | 34 + .../Processors/x86/data/languages/x86.ldefs | 98 + .../Processors/x86/data/languages/x86.opinion | 81 + .../Processors/x86/data/languages/x86.pspec | 121 + .../Processors/x86/data/languages/x86.slaspec | 19 + .../x86/data/languages/x86borland.cspec | 150 + .../x86/data/languages/x86delphi.cspec | 99 + .../x86/data/languages/x86gcc.cspec | 377 + .../x86/data/languages/x86win.cspec | 380 + 47 files changed, 20697 insertions(+) create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/adx.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/avx.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/avx2.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/avx2_manual.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/avx_manual.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/bmi1.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/bmi2.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/cet.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/clwb.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/fma.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/ia.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/lockable.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/lzcnt.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/macros.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/mpx.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.lang create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.trans create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.lang create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.trans create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.lang create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.trans create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.lang create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.trans create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/pclmulqdq.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/rdrand.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/sgx.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/sha.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/smx.sinc create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16-real.pspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.gdis create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.pspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-gcc.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-win.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.dwarf create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.pspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.slaspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86.dwarf create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86.ldefs create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86.opinion create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86.pspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86.slaspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86borland.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86delphi.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86gcc.cspec create mode 100644 src/icicle/data/Ghidra/Processors/x86/data/languages/x86win.cspec diff --git a/src/icicle/CMakeLists.txt b/src/icicle/CMakeLists.txt index be4badc7..992f2f33 100644 --- a/src/icicle/CMakeLists.txt +++ b/src/icicle/CMakeLists.txt @@ -45,6 +45,12 @@ ExternalProject_Add( BUILD_BYPRODUCTS ${ICICLE_RUST_LIB} ) +add_custom_command( + TARGET icicle-rust-project POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_LIST_DIR}/data" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + COMMENT "Copying Ghidra Processor Specification" +) + add_library(icicle INTERFACE) add_dependencies(icicle icicle-rust-project) target_link_libraries(icicle INTERFACE ${ICICLE_RUST_LIB}) diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/adx.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/adx.sinc new file mode 100644 index 00000000..1612b389 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/adx.sinc @@ -0,0 +1,33 @@ +:ADCX Reg32, rm32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; rm32 & Reg32 ... & check_Reg32_dest ... { + tmp:5 = zext(Reg32) + zext(rm32) + zext(CF); + tmpCF:1 = tmp(4); # just the carry byte + CF = tmpCF != 0; + Reg32 = tmp:4; + build check_Reg32_dest; +} + +@ifdef IA64 +:ADCX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 { + tmp:9 = zext(Reg64) + zext(rm64) + zext(CF); + tmpCF:1 = tmp(8); # just the carry byte + CF = tmpCF != 0; + Reg64 = tmp:8; +} +@endif + +:ADOX Reg32, rm32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; rm32 & Reg32 ... & check_Reg32_dest ... { + tmp:5 = zext(Reg32) + zext(rm32) + zext(OF); + tmpOF:1 = tmp(4); # just the carry byte + OF = tmpOF != 0; + Reg32 = tmp:4; + build check_Reg32_dest; +} + +@ifdef IA64 +:ADOX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 { + tmp:9 = zext(Reg64) + zext(rm64) + zext(OF); + tmpOF:1 = tmp(8); # just the carry byte + OF = tmpOF != 0; + Reg64 = tmp:8; +} +@endif diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/avx.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx.sinc new file mode 100644 index 00000000..cd42ee5a --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx.sinc @@ -0,0 +1,3275 @@ +# INFO This file automatically generated by andre on Thu May 10 10:49:02 2018 +# INFO Direct edits to this file may be lost in future updates +# INFO Command line arguments: ['--sinc', '--cpuid-match', '^AVX\\b', '--skip-sinc', '../../../Processors/x86/data/languages/avx_manual.sinc'] + +# ADDPD 3-33 PAGE 603 LINE 33405 +define pcodeop vaddpd_avx ; +:VADDPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vaddpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDPD 3-33 PAGE 603 LINE 33408 +:VADDPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x58; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vaddpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ADDPS 3-36 PAGE 606 LINE 33558 +define pcodeop vaddps_avx ; +:VADDPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vaddps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDPS 3-36 PAGE 606 LINE 33560 +:VADDPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x58; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vaddps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ADDSD 3-39 PAGE 609 LINE 33718 +define pcodeop vaddsd_avx ; +:VADDSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vaddsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDSS 3-41 PAGE 611 LINE 33812 +define pcodeop vaddss_avx ; +:VADDSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x58; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vaddss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDSUBPD 3-43 PAGE 613 LINE 33906 +define pcodeop vaddsubpd_avx ; +:VADDSUBPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD0; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vaddsubpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDSUBPD 3-43 PAGE 613 LINE 33909 +:VADDSUBPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD0; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vaddsubpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ADDSUBPS 3-45 PAGE 615 LINE 34013 +define pcodeop vaddsubps_avx ; +:VADDSUBPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD0; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vaddsubps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ADDSUBPS 3-45 PAGE 615 LINE 34016 +:VADDSUBPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD0; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vaddsubps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ANDPD 3-64 PAGE 634 LINE 34821 +define pcodeop vandpd_avx ; +:VANDPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x54; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vandpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ANDPD 3-64 PAGE 634 LINE 34824 +:VANDPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x54; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vandpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ANDPS 3-67 PAGE 637 LINE 34947 +define pcodeop vandps_avx ; +:VANDPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x54; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vandps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ANDPS 3-67 PAGE 637 LINE 34950 +:VANDPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x54; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vandps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ANDNPD 3-70 PAGE 640 LINE 35081 +define pcodeop vandnpd_avx ; +:VANDNPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x55; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vandnpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ANDNPD 3-70 PAGE 640 LINE 35084 +:VANDNPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x55; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vandnpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ANDNPS 3-73 PAGE 643 LINE 35207 +define pcodeop vandnps_avx ; +:VANDNPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x55; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vandnps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ANDNPS 3-73 PAGE 643 LINE 35210 +:VANDNPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x55; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vandnps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# BLENDPD 3-78 PAGE 648 LINE 35433 +define pcodeop vblendpd_avx ; +:VBLENDPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8_3_0 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8_3_0 +{ + local tmp:16 = vblendpd_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8_3_0:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# BLENDPD 3-78 PAGE 648 LINE 35436 +:VBLENDPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8_3_0 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0D; YmmReg1 ... & YmmReg2_m256; imm8_3_0 +{ + YmmReg1 = vblendpd_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8_3_0:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# BLENDPS 3-81 PAGE 651 LINE 35580 +define pcodeop vblendps_avx ; +:VBLENDPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vblendps_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# BLENDPS 3-81 PAGE 651 LINE 35583 +:VBLENDPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0C; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vblendps_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# BLENDVPD 3-83 PAGE 653 LINE 35684 +define pcodeop vblendvpd_avx ; +:VBLENDVPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x4B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; Xmm_imm8_7_4 +{ + local tmp:16 = vblendvpd_avx( vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# BLENDVPD 3-83 PAGE 653 LINE 35688 +:VBLENDVPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x4B; YmmReg1 ... & YmmReg2_m256; Ymm_imm8_7_4 +{ + YmmReg1 = vblendvpd_avx( vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# BLENDVPS 3-85 PAGE 655 LINE 35789 +define pcodeop vblendvps_avx ; +:VBLENDVPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x4A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; Xmm_imm8_7_4 +{ + local tmp:16 = vblendvps_avx( vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# BLENDVPS 3-85 PAGE 655 LINE 35793 +:VBLENDVPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x4A; YmmReg1 ... & YmmReg2_m256; Ymm_imm8_7_4 +{ + YmmReg1 = vblendvps_avx( vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CMPPD 3-155 PAGE 725 LINE 39240 +VCMPPD_mon: "VCMPEQPD" is imm8=0x0 { } +VCMPPD_op: "" is imm8=0x0 { export 0x0:1; } +VCMPPD_mon: "VCMPLTPD" is imm8=0x1 { } +VCMPPD_op: "" is imm8=0x1 { export 0x1:1; } +VCMPPD_mon: "VCMPLEPD" is imm8=0x2 { } +VCMPPD_op: "" is imm8=0x2 { export 0x2:1; } +VCMPPD_mon: "VCMPUNORDPD" is imm8=0x3 { } +VCMPPD_op: "" is imm8=0x3 { export 0x3:1; } +VCMPPD_mon: "VCMPNEQPD" is imm8=0x4 { } +VCMPPD_op: "" is imm8=0x4 { export 0x4:1; } +VCMPPD_mon: "VCMPNLTPD" is imm8=0x5 { } +VCMPPD_op: "" is imm8=0x5 { export 0x5:1; } +VCMPPD_mon: "VCMPNLEPD" is imm8=0x6 { } +VCMPPD_op: "" is imm8=0x6 { export 0x6:1; } +VCMPPD_mon: "VCMPORDPD" is imm8=0x7 { } +VCMPPD_op: "" is imm8=0x7 { export 0x7:1; } +VCMPPD_mon: "VCMPEQ_UQPD" is imm8=0x8 { } +VCMPPD_op: "" is imm8=0x8 { export 0x8:1; } +VCMPPD_mon: "VCMPNGEPD" is imm8=0x9 { } +VCMPPD_op: "" is imm8=0x9 { export 0x9:1; } +VCMPPD_mon: "VCMPNGTPD" is imm8=0xa { } +VCMPPD_op: "" is imm8=0xa { export 0xa:1; } +VCMPPD_mon: "VCMPFALSEPD" is imm8=0xb { } +VCMPPD_op: "" is imm8=0xb { export 0xb:1; } +VCMPPD_mon: "VCMPNEQ_OQPD" is imm8=0xc { } +VCMPPD_op: "" is imm8=0xc { export 0xc:1; } +VCMPPD_mon: "VCMPGEPD" is imm8=0xd { } +VCMPPD_op: "" is imm8=0xd { export 0xd:1; } +VCMPPD_mon: "VCMPGTPD" is imm8=0xe { } +VCMPPD_op: "" is imm8=0xe { export 0xe:1; } +VCMPPD_mon: "VCMPTRUEPD" is imm8=0xf { } +VCMPPD_op: "" is imm8=0xf { export 0xf:1; } +VCMPPD_mon: "VCMPEQ_OSPD" is imm8=0x10 { } +VCMPPD_op: "" is imm8=0x10 { export 0x10:1; } +VCMPPD_mon: "VCMPLT_OQPD" is imm8=0x11 { } +VCMPPD_op: "" is imm8=0x11 { export 0x11:1; } +VCMPPD_mon: "VCMPLE_OQPD" is imm8=0x12 { } +VCMPPD_op: "" is imm8=0x12 { export 0x12:1; } +VCMPPD_mon: "VCMPUNORD_SPD" is imm8=0x13 { } +VCMPPD_op: "" is imm8=0x13 { export 0x13:1; } +VCMPPD_mon: "VCMPNEQ_USPD" is imm8=0x14 { } +VCMPPD_op: "" is imm8=0x14 { export 0x14:1; } +VCMPPD_mon: "VCMPNLT_UQPD" is imm8=0x15 { } +VCMPPD_op: "" is imm8=0x15 { export 0x15:1; } +VCMPPD_mon: "VCMPNLE_UQPD" is imm8=0x16 { } +VCMPPD_op: "" is imm8=0x16 { export 0x16:1; } +VCMPPD_mon: "VCMPORD_SPD" is imm8=0x17 { } +VCMPPD_op: "" is imm8=0x17 { export 0x17:1; } +VCMPPD_mon: "VCMPEQ_USPD" is imm8=0x18 { } +VCMPPD_op: "" is imm8=0x18 { export 0x18:1; } +VCMPPD_mon: "VCMPNGE_UQPD" is imm8=0x19 { } +VCMPPD_op: "" is imm8=0x19 { export 0x19:1; } +VCMPPD_mon: "VCMPNGT_UQPD" is imm8=0x1a { } +VCMPPD_op: "" is imm8=0x1a { export 0x1a:1; } +VCMPPD_mon: "VCMPFALSE_OSPD" is imm8=0x1b { } +VCMPPD_op: "" is imm8=0x1b { export 0x1b:1; } +VCMPPD_mon: "VCMPNEQ_OSPD" is imm8=0x1c { } +VCMPPD_op: "" is imm8=0x1c { export 0x1c:1; } +VCMPPD_mon: "VCMPGE_OQPD" is imm8=0x1d { } +VCMPPD_op: "" is imm8=0x1d { export 0x1d:1; } +VCMPPD_mon: "VCMPGT_OQPD" is imm8=0x1e { } +VCMPPD_op: "" is imm8=0x1e { export 0x1e:1; } +VCMPPD_mon: "VCMPTRUE_USPD" is imm8=0x1f { } +VCMPPD_op: "" is imm8=0x1f { export 0x1f:1; } +VCMPPD_mon: "VCMPPD" is imm8 { } +VCMPPD_op: ", "^imm8 is imm8 { export *[const]:1 imm8; } +define pcodeop vcmppd_avx ; +:^VCMPPD_mon XmmReg1, vexVVVV_XmmReg, XmmReg2_m128^VCMPPD_op is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC2; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; VCMPPD_mon & VCMPPD_op +{ + local tmp:16 = vcmppd_avx( vexVVVV_XmmReg, XmmReg2_m128, VCMPPD_op ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CMPPD 3-155 PAGE 725 LINE 39243 +:^VCMPPD_mon YmmReg1, vexVVVV_YmmReg, YmmReg2_m256^VCMPPD_op is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xC2; YmmReg1 ... & YmmReg2_m256; VCMPPD_mon & VCMPPD_op +{ + YmmReg1 = vcmppd_avx( vexVVVV_YmmReg, YmmReg2_m256, VCMPPD_op ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CMPPS 3-162 PAGE 732 LINE 39607 +VCMPPS_mon: "VCMPEQPS" is imm8=0x0 { } +VCMPPS_op: "" is imm8=0x0 { export 0x0:1; } +VCMPPS_mon: "VCMPLTPS" is imm8=0x1 { } +VCMPPS_op: "" is imm8=0x1 { export 0x1:1; } +VCMPPS_mon: "VCMPLEPS" is imm8=0x2 { } +VCMPPS_op: "" is imm8=0x2 { export 0x2:1; } +VCMPPS_mon: "VCMPUNORDPS" is imm8=0x3 { } +VCMPPS_op: "" is imm8=0x3 { export 0x3:1; } +VCMPPS_mon: "VCMPNEQPS" is imm8=0x4 { } +VCMPPS_op: "" is imm8=0x4 { export 0x4:1; } +VCMPPS_mon: "VCMPNLTPS" is imm8=0x5 { } +VCMPPS_op: "" is imm8=0x5 { export 0x5:1; } +VCMPPS_mon: "VCMPNLEPS" is imm8=0x6 { } +VCMPPS_op: "" is imm8=0x6 { export 0x6:1; } +VCMPPS_mon: "VCMPORDPS" is imm8=0x7 { } +VCMPPS_op: "" is imm8=0x7 { export 0x7:1; } +VCMPPS_mon: "VCMPEQ_UQPS" is imm8=0x8 { } +VCMPPS_op: "" is imm8=0x8 { export 0x8:1; } +VCMPPS_mon: "VCMPNGEPS" is imm8=0x9 { } +VCMPPS_op: "" is imm8=0x9 { export 0x9:1; } +VCMPPS_mon: "VCMPNGTPS" is imm8=0xa { } +VCMPPS_op: "" is imm8=0xa { export 0xa:1; } +VCMPPS_mon: "VCMPFALSEPS" is imm8=0xb { } +VCMPPS_op: "" is imm8=0xb { export 0xb:1; } +VCMPPS_mon: "VCMPNEQ_OQPS" is imm8=0xc { } +VCMPPS_op: "" is imm8=0xc { export 0xc:1; } +VCMPPS_mon: "VCMPGEPS" is imm8=0xd { } +VCMPPS_op: "" is imm8=0xd { export 0xd:1; } +VCMPPS_mon: "VCMPGTPS" is imm8=0xe { } +VCMPPS_op: "" is imm8=0xe { export 0xe:1; } +VCMPPS_mon: "VCMPTRUEPS" is imm8=0xf { } +VCMPPS_op: "" is imm8=0xf { export 0xf:1; } +VCMPPS_mon: "VCMPEQ_OSPS" is imm8=0x10 { } +VCMPPS_op: "" is imm8=0x10 { export 0x10:1; } +VCMPPS_mon: "VCMPLT_OQPS" is imm8=0x11 { } +VCMPPS_op: "" is imm8=0x11 { export 0x11:1; } +VCMPPS_mon: "VCMPLE_OQPS" is imm8=0x12 { } +VCMPPS_op: "" is imm8=0x12 { export 0x12:1; } +VCMPPS_mon: "VCMPUNORD_SPS" is imm8=0x13 { } +VCMPPS_op: "" is imm8=0x13 { export 0x13:1; } +VCMPPS_mon: "VCMPNEQ_USPS" is imm8=0x14 { } +VCMPPS_op: "" is imm8=0x14 { export 0x14:1; } +VCMPPS_mon: "VCMPNLT_UQPS" is imm8=0x15 { } +VCMPPS_op: "" is imm8=0x15 { export 0x15:1; } +VCMPPS_mon: "VCMPNLE_UQPS" is imm8=0x16 { } +VCMPPS_op: "" is imm8=0x16 { export 0x16:1; } +VCMPPS_mon: "VCMPORD_SPS" is imm8=0x17 { } +VCMPPS_op: "" is imm8=0x17 { export 0x17:1; } +VCMPPS_mon: "VCMPEQ_USPS" is imm8=0x18 { } +VCMPPS_op: "" is imm8=0x18 { export 0x18:1; } +VCMPPS_mon: "VCMPNGE_UQPS" is imm8=0x19 { } +VCMPPS_op: "" is imm8=0x19 { export 0x19:1; } +VCMPPS_mon: "VCMPNGT_UQPS" is imm8=0x1a { } +VCMPPS_op: "" is imm8=0x1a { export 0x1a:1; } +VCMPPS_mon: "VCMPFALSE_OSPS" is imm8=0x1b { } +VCMPPS_op: "" is imm8=0x1b { export 0x1b:1; } +VCMPPS_mon: "VCMPNEQ_OSPS" is imm8=0x1c { } +VCMPPS_op: "" is imm8=0x1c { export 0x1c:1; } +VCMPPS_mon: "VCMPGE_OQPS" is imm8=0x1d { } +VCMPPS_op: "" is imm8=0x1d { export 0x1d:1; } +VCMPPS_mon: "VCMPGT_OQPS" is imm8=0x1e { } +VCMPPS_op: "" is imm8=0x1e { export 0x1e:1; } +VCMPPS_mon: "VCMPTRUE_USPS" is imm8=0x1f { } +VCMPPS_op: "" is imm8=0x1f { export 0x1f:1; } +VCMPPS_mon: "VCMPPS" is imm8 { } +VCMPPS_op: ", "^imm8 is imm8 { export *[const]:1 imm8; } +define pcodeop vcmpps_avx ; +:^VCMPPS_mon XmmReg1, vexVVVV_XmmReg, XmmReg2_m128^VCMPPS_op is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC2; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; VCMPPS_mon & VCMPPS_op +{ + local tmp:16 = vcmpps_avx( vexVVVV_XmmReg, XmmReg2_m128, VCMPPS_op ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CMPPS 3-162 PAGE 732 LINE 39610 +:^VCMPPS_mon YmmReg1, vexVVVV_YmmReg, YmmReg2_m256^VCMPPS_op is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xC2; YmmReg1 ... & YmmReg2_m256; VCMPPS_mon & VCMPPS_op +{ + YmmReg1 = vcmpps_avx( vexVVVV_YmmReg, YmmReg2_m256, VCMPPS_op ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CMPSD 3-173 PAGE 743 LINE 40154 +VCMPSD_mon: "VCMPEQSD" is imm8=0x0 { } +VCMPSD_op: "" is imm8=0x0 { export 0x0:1; } +VCMPSD_mon: "VCMPLTSD" is imm8=0x1 { } +VCMPSD_op: "" is imm8=0x1 { export 0x1:1; } +VCMPSD_mon: "VCMPLESD" is imm8=0x2 { } +VCMPSD_op: "" is imm8=0x2 { export 0x2:1; } +VCMPSD_mon: "VCMPUNORDSD" is imm8=0x3 { } +VCMPSD_op: "" is imm8=0x3 { export 0x3:1; } +VCMPSD_mon: "VCMPNEQSD" is imm8=0x4 { } +VCMPSD_op: "" is imm8=0x4 { export 0x4:1; } +VCMPSD_mon: "VCMPNLTSD" is imm8=0x5 { } +VCMPSD_op: "" is imm8=0x5 { export 0x5:1; } +VCMPSD_mon: "VCMPNLESD" is imm8=0x6 { } +VCMPSD_op: "" is imm8=0x6 { export 0x6:1; } +VCMPSD_mon: "VCMPORDSD" is imm8=0x7 { } +VCMPSD_op: "" is imm8=0x7 { export 0x7:1; } +VCMPSD_mon: "VCMPEQ_UQSD" is imm8=0x8 { } +VCMPSD_op: "" is imm8=0x8 { export 0x8:1; } +VCMPSD_mon: "VCMPNGESD" is imm8=0x9 { } +VCMPSD_op: "" is imm8=0x9 { export 0x9:1; } +VCMPSD_mon: "VCMPNGTSD" is imm8=0xa { } +VCMPSD_op: "" is imm8=0xa { export 0xa:1; } +VCMPSD_mon: "VCMPFALSESD" is imm8=0xb { } +VCMPSD_op: "" is imm8=0xb { export 0xb:1; } +VCMPSD_mon: "VCMPNEQ_OQSD" is imm8=0xc { } +VCMPSD_op: "" is imm8=0xc { export 0xc:1; } +VCMPSD_mon: "VCMPGESD" is imm8=0xd { } +VCMPSD_op: "" is imm8=0xd { export 0xd:1; } +VCMPSD_mon: "VCMPGTSD" is imm8=0xe { } +VCMPSD_op: "" is imm8=0xe { export 0xe:1; } +VCMPSD_mon: "VCMPTRUESD" is imm8=0xf { } +VCMPSD_op: "" is imm8=0xf { export 0xf:1; } +VCMPSD_mon: "VCMPEQ_OSSD" is imm8=0x10 { } +VCMPSD_op: "" is imm8=0x10 { export 0x10:1; } +VCMPSD_mon: "VCMPLT_OQSD" is imm8=0x11 { } +VCMPSD_op: "" is imm8=0x11 { export 0x11:1; } +VCMPSD_mon: "VCMPLE_OQSD" is imm8=0x12 { } +VCMPSD_op: "" is imm8=0x12 { export 0x12:1; } +VCMPSD_mon: "VCMPUNORD_SSD" is imm8=0x13 { } +VCMPSD_op: "" is imm8=0x13 { export 0x13:1; } +VCMPSD_mon: "VCMPNEQ_USSD" is imm8=0x14 { } +VCMPSD_op: "" is imm8=0x14 { export 0x14:1; } +VCMPSD_mon: "VCMPNLT_UQSD" is imm8=0x15 { } +VCMPSD_op: "" is imm8=0x15 { export 0x15:1; } +VCMPSD_mon: "VCMPNLE_UQSD" is imm8=0x16 { } +VCMPSD_op: "" is imm8=0x16 { export 0x16:1; } +VCMPSD_mon: "VCMPORD_SSD" is imm8=0x17 { } +VCMPSD_op: "" is imm8=0x17 { export 0x17:1; } +VCMPSD_mon: "VCMPEQ_USSD" is imm8=0x18 { } +VCMPSD_op: "" is imm8=0x18 { export 0x18:1; } +VCMPSD_mon: "VCMPNGE_UQSD" is imm8=0x19 { } +VCMPSD_op: "" is imm8=0x19 { export 0x19:1; } +VCMPSD_mon: "VCMPNGT_UQSD" is imm8=0x1a { } +VCMPSD_op: "" is imm8=0x1a { export 0x1a:1; } +VCMPSD_mon: "VCMPFALSE_OSSD" is imm8=0x1b { } +VCMPSD_op: "" is imm8=0x1b { export 0x1b:1; } +VCMPSD_mon: "VCMPNEQ_OSSD" is imm8=0x1c { } +VCMPSD_op: "" is imm8=0x1c { export 0x1c:1; } +VCMPSD_mon: "VCMPGE_OQSD" is imm8=0x1d { } +VCMPSD_op: "" is imm8=0x1d { export 0x1d:1; } +VCMPSD_mon: "VCMPGT_OQSD" is imm8=0x1e { } +VCMPSD_op: "" is imm8=0x1e { export 0x1e:1; } +VCMPSD_mon: "VCMPTRUE_USSD" is imm8=0x1f { } +VCMPSD_op: "" is imm8=0x1f { export 0x1f:1; } +VCMPSD_mon: "VCMPSD" is imm8 { } +VCMPSD_op: ", "^imm8 is imm8 { export *[const]:1 imm8; } +define pcodeop vcmpsd_avx ; +:^VCMPSD_mon XmmReg1, vexVVVV_XmmReg, XmmReg2_m64^VCMPSD_op is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC2; (XmmReg1 & YmmReg1) ... & XmmReg2_m64; VCMPSD_mon & VCMPSD_op +{ + local tmp:16 = vcmpsd_avx( vexVVVV_XmmReg, XmmReg2_m64, VCMPSD_op ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CMPSS 3-177 PAGE 747 LINE 40390 +VCMPSS_mon: "VCMPEQSS" is imm8=0x0 { } +VCMPSS_op: "" is imm8=0x0 { export 0x0:1; } +VCMPSS_mon: "VCMPLTSS" is imm8=0x1 { } +VCMPSS_op: "" is imm8=0x1 { export 0x1:1; } +VCMPSS_mon: "VCMPLESS" is imm8=0x2 { } +VCMPSS_op: "" is imm8=0x2 { export 0x2:1; } +VCMPSS_mon: "VCMPUNORDSS" is imm8=0x3 { } +VCMPSS_op: "" is imm8=0x3 { export 0x3:1; } +VCMPSS_mon: "VCMPNEQSS" is imm8=0x4 { } +VCMPSS_op: "" is imm8=0x4 { export 0x4:1; } +VCMPSS_mon: "VCMPNLTSS" is imm8=0x5 { } +VCMPSS_op: "" is imm8=0x5 { export 0x5:1; } +VCMPSS_mon: "VCMPNLESS" is imm8=0x6 { } +VCMPSS_op: "" is imm8=0x6 { export 0x6:1; } +VCMPSS_mon: "VCMPORDSS" is imm8=0x7 { } +VCMPSS_op: "" is imm8=0x7 { export 0x7:1; } +VCMPSS_mon: "VCMPEQ_UQSS" is imm8=0x8 { } +VCMPSS_op: "" is imm8=0x8 { export 0x8:1; } +VCMPSS_mon: "VCMPNGESS" is imm8=0x9 { } +VCMPSS_op: "" is imm8=0x9 { export 0x9:1; } +VCMPSS_mon: "VCMPNGTSS" is imm8=0xa { } +VCMPSS_op: "" is imm8=0xa { export 0xa:1; } +VCMPSS_mon: "VCMPFALSESS" is imm8=0xb { } +VCMPSS_op: "" is imm8=0xb { export 0xb:1; } +VCMPSS_mon: "VCMPNEQ_OQSS" is imm8=0xc { } +VCMPSS_op: "" is imm8=0xc { export 0xc:1; } +VCMPSS_mon: "VCMPGESS" is imm8=0xd { } +VCMPSS_op: "" is imm8=0xd { export 0xd:1; } +VCMPSS_mon: "VCMPGTSS" is imm8=0xe { } +VCMPSS_op: "" is imm8=0xe { export 0xe:1; } +VCMPSS_mon: "VCMPTRUESS" is imm8=0xf { } +VCMPSS_op: "" is imm8=0xf { export 0xf:1; } +VCMPSS_mon: "VCMPEQ_OSSS" is imm8=0x10 { } +VCMPSS_op: "" is imm8=0x10 { export 0x10:1; } +VCMPSS_mon: "VCMPLT_OQSS" is imm8=0x11 { } +VCMPSS_op: "" is imm8=0x11 { export 0x11:1; } +VCMPSS_mon: "VCMPLE_OQSS" is imm8=0x12 { } +VCMPSS_op: "" is imm8=0x12 { export 0x12:1; } +VCMPSS_mon: "VCMPUNORD_SSS" is imm8=0x13 { } +VCMPSS_op: "" is imm8=0x13 { export 0x13:1; } +VCMPSS_mon: "VCMPNEQ_USSS" is imm8=0x14 { } +VCMPSS_op: "" is imm8=0x14 { export 0x14:1; } +VCMPSS_mon: "VCMPNLT_UQSS" is imm8=0x15 { } +VCMPSS_op: "" is imm8=0x15 { export 0x15:1; } +VCMPSS_mon: "VCMPNLE_UQSS" is imm8=0x16 { } +VCMPSS_op: "" is imm8=0x16 { export 0x16:1; } +VCMPSS_mon: "VCMPORD_SSS" is imm8=0x17 { } +VCMPSS_op: "" is imm8=0x17 { export 0x17:1; } +VCMPSS_mon: "VCMPEQ_USSS" is imm8=0x18 { } +VCMPSS_op: "" is imm8=0x18 { export 0x18:1; } +VCMPSS_mon: "VCMPNGE_UQSS" is imm8=0x19 { } +VCMPSS_op: "" is imm8=0x19 { export 0x19:1; } +VCMPSS_mon: "VCMPNGT_UQSS" is imm8=0x1a { } +VCMPSS_op: "" is imm8=0x1a { export 0x1a:1; } +VCMPSS_mon: "VCMPFALSE_OSSS" is imm8=0x1b { } +VCMPSS_op: "" is imm8=0x1b { export 0x1b:1; } +VCMPSS_mon: "VCMPNEQ_OSSS" is imm8=0x1c { } +VCMPSS_op: "" is imm8=0x1c { export 0x1c:1; } +VCMPSS_mon: "VCMPGE_OQSS" is imm8=0x1d { } +VCMPSS_op: "" is imm8=0x1d { export 0x1d:1; } +VCMPSS_mon: "VCMPGT_OQSS" is imm8=0x1e { } +VCMPSS_op: "" is imm8=0x1e { export 0x1e:1; } +VCMPSS_mon: "VCMPTRUE_USSS" is imm8=0x1f { } +VCMPSS_op: "" is imm8=0x1f { export 0x1f:1; } +VCMPSS_mon: "VCMPSS" is imm8 { } +VCMPSS_op: ", "^imm8 is imm8 { export *[const]:1 imm8; } +define pcodeop vcmpss_avx ; +:^VCMPSS_mon XmmReg1, vexVVVV_XmmReg, XmmReg2_m32^VCMPSS_op is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC2; (XmmReg1 & YmmReg1) ... & XmmReg2_m32; VCMPSS_mon & VCMPSS_op +{ + local tmp:16 = vcmpss_avx( vexVVVV_XmmReg, XmmReg2_m32, VCMPSS_op ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# COMISD 3-186 PAGE 756 LINE 40860 +define pcodeop vcomisd_avx ; +:VCOMISD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2F; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vcomisd_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# COMISS 3-188 PAGE 758 LINE 40938 +define pcodeop vcomiss_avx ; +:VCOMISS XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2F; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vcomiss_avx( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTDQ2PD 3-228 PAGE 798 LINE 43074 +define pcodeop vcvtdq2pd_avx ; +:VCVTDQ2PD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vcvtdq2pd_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTDQ2PD 3-228 PAGE 798 LINE 43077 +:VCVTDQ2PD YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vcvtdq2pd_avx( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CVTDQ2PS 3-232 PAGE 802 LINE 43242 +define pcodeop vcvtdq2ps_avx ; +:VCVTDQ2PS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvtdq2ps_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTDQ2PS 3-232 PAGE 802 LINE 43245 +:VCVTDQ2PS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vcvtdq2ps_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CVTPD2DQ 3-235 PAGE 805 LINE 43408 +define pcodeop vcvtpd2dq_avx ; +:VCVTPD2DQ XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvtpd2dq_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPD2DQ 3-235 PAGE 805 LINE 43411 +:VCVTPD2DQ XmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; (XmmReg1 & YmmReg1) ... & YmmReg2_m256 +{ + local tmp:16 = vcvtpd2dq_avx( YmmReg2_m256 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPD2PS 3-240 PAGE 810 LINE 43643 +define pcodeop vcvtpd2ps_avx ; +:VCVTPD2PS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x5A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvtpd2ps_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPD2PS 3-240 PAGE 810 LINE 43646 +:VCVTPD2PS XmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x5A; (XmmReg1 & YmmReg1) ... & YmmReg2_m256 +{ + local tmp:16 = vcvtpd2ps_avx( YmmReg2_m256 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPS2DQ 3-246 PAGE 816 LINE 43927 +define pcodeop vcvtps2dq_avx ; +:VCVTPS2DQ XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvtps2dq_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPS2DQ 3-246 PAGE 816 LINE 43930 +:VCVTPS2DQ YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vcvtps2dq_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CVTPS2PD 3-249 PAGE 819 LINE 44098 +define pcodeop vcvtps2pd_avx ; +:VCVTPS2PD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x5A; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vcvtps2pd_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTPS2PD 3-249 PAGE 819 LINE 44101 +:VCVTPS2PD YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x5A; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vcvtps2pd_avx( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VCVTPH2PS 5-33 PAGE 1857 LINE 96839 +define pcodeop vcvtph2ps_f16c ; +:VCVTPH2PS XmmReg1, XmmReg2_m64 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x13; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vcvtph2ps_f16c( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VCVTPH2PS 5-33 PAGE 1857 LINE 96842 +:VCVTPH2PS YmmReg1, XmmReg2_m128 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x13; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vcvtph2ps_f16c( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VCVTPS2PH 5-36 PAGE 1860 LINE 96992 +define pcodeop vcvtps2ph_f16c ; +:VCVTPS2PH XmmReg2_m64, XmmReg1, imm8 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x1D; XmmReg1 ... & XmmReg2_m64; imm8 +{ + XmmReg2_m64 = vcvtps2ph_f16c( XmmReg1, imm8:1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# VCVTPS2PH 5-36 PAGE 1860 LINE 96995 +:VCVTPS2PH XmmReg2_m128, YmmReg1, imm8 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x1D; YmmReg1 ... & XmmReg2_m128; imm8 +{ + XmmReg2_m128 = vcvtps2ph_f16c( YmmReg1, imm8:1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + + +# CVTSD2SI 3-253 PAGE 823 LINE 44315 +define pcodeop vcvtsd2si_avx ; +:VCVTSD2SI Reg32, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m64 +{ + Reg32 = vcvtsd2si_avx( XmmReg2_m64 ); + # TODO Reg64 = zext(Reg32) +} + +# CVTSD2SI 3-253 PAGE 823 LINE 44317 +@ifdef IA64 +:VCVTSD2SI Reg64, XmmReg2_m64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m64 +{ + Reg64 = vcvtsd2si_avx( XmmReg2_m64 ); +} +@endif + +# CVTSD2SS 3-255 PAGE 825 LINE 44414 +define pcodeop vcvtsd2ss_avx ; +:VCVTSD2SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5A; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vcvtsd2ss_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTSI2SD 3-257 PAGE 827 LINE 44516 +define pcodeop vcvtsi2sd_avx ; +:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm32 +{ + local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTSI2SD 3-257 PAGE 827 LINE 44519 +@ifdef IA64 +:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64 +{ + local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} +@endif + +# CVTSI2SS 3-259 PAGE 829 LINE 44632 +define pcodeop vcvtsi2ss_avx ; +:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm32 +{ + local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTSI2SS 3-259 PAGE 829 LINE 44634 +@ifdef IA64 +:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64 +{ + local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} +@endif + +# CVTSS2SD 3-261 PAGE 831 LINE 44744 +define pcodeop vcvtss2sd_avx ; +:VCVTSS2SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5A; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vcvtss2sd_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTSS2SI 3-263 PAGE 833 LINE 44835 +define pcodeop vcvtss2si_avx ; +:VCVTSS2SI Reg32, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2D; Reg32 ... & XmmReg2_m32 +{ + Reg32 = vcvtss2si_avx( XmmReg2_m32 ); + # TODO Reg64 = zext(Reg32) +} + +# CVTSS2SI 3-263 PAGE 833 LINE 44837 +@ifdef IA64 +:VCVTSS2SI Reg64, XmmReg2_m32 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m32 +{ + Reg64 = vcvtss2si_avx( XmmReg2_m32 ); +} +@endif + +# CVTTPD2DQ 3-265 PAGE 835 LINE 44930 +define pcodeop vcvttpd2dq_avx ; +:VCVTTPD2DQ XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvttpd2dq_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTTPD2DQ 3-265 PAGE 835 LINE 44933 +:VCVTTPD2DQ XmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xE6; (XmmReg1 & YmmReg1) ... & YmmReg2_m256 +{ + local tmp:16 = vcvttpd2dq_avx( YmmReg2_m256 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTTPS2DQ 3-270 PAGE 840 LINE 45163 +define pcodeop vcvttps2dq_avx ; +:VCVTTPS2DQ XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vcvttps2dq_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# CVTTPS2DQ 3-270 PAGE 840 LINE 45166 +:VCVTTPS2DQ YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x5B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vcvttps2dq_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# CVTTSD2SI 3-274 PAGE 844 LINE 45379 +define pcodeop vcvttsd2si_avx ; +:VCVTTSD2SI Reg32, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W0); byte=0x2C; Reg32 ... & XmmReg2_m64 +{ + Reg32 = vcvttsd2si_avx( XmmReg2_m64 ); + # TODO Reg64 = zext(Reg32) +} + +# CVTTSD2SI 3-274 PAGE 844 LINE 45382 +@ifdef IA64 +:VCVTTSD2SI Reg64, XmmReg2_m64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m64 +{ + Reg64 = vcvttsd2si_avx( XmmReg2_m64 ); +} +@endif + +# CVTTSS2SI 3-276 PAGE 846 LINE 45473 +define pcodeop vcvttss2si_avx ; +:VCVTTSS2SI Reg32, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W0); byte=0x2C; Reg32 ... & XmmReg2_m32 +{ + Reg32 = vcvttss2si_avx( XmmReg2_m32 ); + # TODO Reg64 = zext(Reg32) +} + +# CVTTSS2SI 3-276 PAGE 846 LINE 45476 +@ifdef IA64 +:VCVTTSS2SI Reg64, XmmReg2_m32 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m32 +{ + Reg64 = vcvttss2si_avx( XmmReg2_m32 ); +} +@endif + +# DIVPD 3-288 PAGE 858 LINE 46023 +define pcodeop vdivpd_avx ; +:VDIVPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vdivpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DIVPD 3-288 PAGE 858 LINE 46026 +:VDIVPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vdivpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# DIVPS 3-291 PAGE 861 LINE 46164 +define pcodeop vdivps_avx ; +:VDIVPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vdivps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DIVPS 3-291 PAGE 861 LINE 46167 +:VDIVPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vdivps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# DIVSD 3-294 PAGE 864 LINE 46312 +define pcodeop vdivsd_avx ; +:VDIVSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5E; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vdivsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DIVSS 3-296 PAGE 866 LINE 46410 +define pcodeop vdivss_avx ; +:VDIVSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5E; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vdivss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DPPD 3-298 PAGE 868 LINE 46509 +define pcodeop vdppd_avx ; +:VDPPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x41; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vdppd_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DPPS 3-300 PAGE 870 LINE 46612 +define pcodeop vdpps_avx ; +:VDPPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x40; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vdpps_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# DPPS 3-300 PAGE 870 LINE 46616 +:VDPPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x40; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vdpps_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# EXTRACTPS 3-307 PAGE 877 LINE 46978 +define pcodeop vextractps_avx ; +:VEXTRACTPS rm32, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x17; XmmReg1 ... & rm32; imm8 +{ + rm32 = vextractps_avx( XmmReg1, imm8:1 ); +} + +# HADDPD 3-427 PAGE 997 LINE 52447 +define pcodeop vhaddpd_avx ; +:VHADDPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x7C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vhaddpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# HADDPD 3-427 PAGE 997 LINE 52450 +:VHADDPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x7C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vhaddpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# HADDPS 3-430 PAGE 1000 LINE 52586 +define pcodeop vhaddps_avx ; +:VHADDPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x7C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vhaddps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# HADDPS 3-430 PAGE 1000 LINE 52589 +:VHADDPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x7C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vhaddps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# HSUBPD 3-434 PAGE 1004 LINE 52795 +define pcodeop vhsubpd_avx ; +:VHSUBPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x7D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vhsubpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# HSUBPD 3-434 PAGE 1004 LINE 52798 +:VHSUBPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x7D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vhsubpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# HSUBPS 3-437 PAGE 1007 LINE 52933 +define pcodeop vhsubps_avx ; +:VHSUBPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x7D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vhsubps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# HSUBPS 3-437 PAGE 1007 LINE 52936 +:VHSUBPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x7D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vhsubps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# INSERTPS 3-454 PAGE 1024 LINE 53780 +define pcodeop vinsertps_avx ; +:VINSERTPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x21; (XmmReg1 & YmmReg1) ... & XmmReg2_m32; imm8 +{ + local tmp:16 = vinsertps_avx( vexVVVV_XmmReg, XmmReg2_m32, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# LDDQU 3-518 PAGE 1088 LINE 57123 +define pcodeop vlddqu_avx ; +:VLDDQU XmmReg1, m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0xF0; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vlddqu_avx( m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# LDDQU 3-518 PAGE 1088 LINE 57126 +:VLDDQU YmmReg1, m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0xF0; YmmReg1 ... & m256 +{ + YmmReg1 = vlddqu_avx( m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# LDMXCSR 3-520 PAGE 1090 LINE 57208 +define pcodeop vldmxcsr_avx ; +:VLDMXCSR m32 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0xAE; reg_opcode=2 ... & m32 +{ + vldmxcsr_avx( m32 ); + # TODO missing destination or side effects +} + +# 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_avx( XmmReg1, XmmReg2 ); + # TODO missing destination or side effects +} + +# MAXPD 4-12 PAGE 1132 LINE 59201 +define pcodeop vmaxpd_avx ; +:VMAXPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmaxpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MAXPD 4-12 PAGE 1132 LINE 59203 +:VMAXPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmaxpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MAXPS 4-15 PAGE 1135 LINE 59350 +define pcodeop vmaxps_avx ; +:VMAXPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmaxps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MAXPS 4-15 PAGE 1135 LINE 59353 +:VMAXPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmaxps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MAXSD 4-18 PAGE 1138 LINE 59503 +define pcodeop vmaxsd_avx ; +:VMAXSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5F; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vmaxsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MAXSS 4-20 PAGE 1140 LINE 59606 +define pcodeop vmaxss_avx ; +:VMAXSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5F; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vmaxss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MINPD 4-23 PAGE 1143 LINE 59765 +define pcodeop vminpd_avx ; +:VMINPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vminpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MINPD 4-23 PAGE 1143 LINE 59768 +:VMINPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vminpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MINPS 4-26 PAGE 1146 LINE 59909 +define pcodeop vminps_avx ; +:VMINPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vminps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MINPS 4-26 PAGE 1146 LINE 59912 +:VMINPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vminps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MINSD 4-29 PAGE 1149 LINE 60061 +define pcodeop vminsd_avx ; +:VMINSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5D; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vminsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MINSS 4-31 PAGE 1151 LINE 60164 +define pcodeop vminss_avx ; +:VMINSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5D; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vminss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVD/MOVQ 4-55 PAGE 1175 LINE 61358 +define pcodeop vmovd_avx ; +:VMOVD XmmReg1, rm32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0x6E; (XmmReg1 & YmmReg1) ... & rm32 +{ + local tmp:16 = vmovd_avx( rm32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVD/MOVQ 4-55 PAGE 1175 LINE 61360 +define pcodeop vmovq_avx ; +@ifdef IA64 +:VMOVQ XmmReg1, rm64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x6E; (XmmReg1 & YmmReg1) ... & rm64 +{ + local tmp:16 = vmovq_avx( rm64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} +@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 +{ + rm32 = vmovd_avx( XmmReg1 ); +} + +# MOVD/MOVQ 4-55 PAGE 1175 LINE 61364 +@ifdef IA64 +:VMOVQ rm64, XmmReg1 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x7E; XmmReg1 ... & rm64 +{ + rm64 = vmovq_avx( XmmReg1 ); +} +@endif + +# MOVDDUP 4-59 PAGE 1179 LINE 61521 +define pcodeop vmovddup_avx ; +:VMOVDDUP XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x12; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vmovddup_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVDDUP 4-59 PAGE 1179 LINE 61523 +:VMOVDDUP YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x12; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmovddup_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61930 +define pcodeop vmovdqu_avx ; +:VMOVDQU XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmovdqu_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61932 +:VMOVDQU XmmReg2_m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 ... & XmmReg2_m128 +{ + XmmReg2_m128 = vmovdqu_avx( XmmReg1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61934 +:VMOVDQU YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmovdqu_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVDQU,VMOVDQU8/16/32/64 4-67 PAGE 1187 LINE 61936 +:VMOVDQU YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = vmovdqu_avx( YmmReg1 ); + # TODO ZmmReg2 = zext(YmmReg2) +} + +# MOVHLPS 4-76 PAGE 1196 LINE 62410 +define pcodeop vmovhlps_avx ; +:VMOVHLPS XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x12; (XmmReg1 & YmmReg1) & (mod=0x3 & XmmReg2) +{ + local tmp:16 = vmovhlps_avx( vexVVVV_XmmReg, XmmReg2 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVHPD 4-78 PAGE 1198 LINE 62483 +define pcodeop vmovhpd_avx ; +:VMOVHPD XmmReg1, vexVVVV_XmmReg, m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x16; (XmmReg1 & YmmReg1) ... & m64 +{ + local tmp:16 = vmovhpd_avx( vexVVVV_XmmReg, m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVHPD 4-78 PAGE 1198 LINE 62489 +:VMOVHPD m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x17; XmmReg1 ... & m64 +{ + m64 = vmovhpd_avx( XmmReg1 ); +} + +# MOVHPS 4-80 PAGE 1200 LINE 62570 +define pcodeop vmovhps_avx ; +:VMOVHPS XmmReg1, vexVVVV_XmmReg, m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x16; (XmmReg1 & YmmReg1) ... & m64 +{ + local tmp:16 = vmovhps_avx( vexVVVV_XmmReg, m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVHPS 4-80 PAGE 1200 LINE 62576 +:VMOVHPS m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x17; XmmReg1 ... & m64 +{ + m64 = vmovhps_avx( XmmReg1 ); +} + +# MOVLHPS 4-82 PAGE 1202 LINE 62658 +define pcodeop vmovlhps_avx ; +:VMOVLHPS XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x16; (XmmReg1 & YmmReg1) & (mod=0x3 & XmmReg2) +{ + local tmp:16 = vmovlhps_avx( vexVVVV_XmmReg, XmmReg2 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVLPD 4-84 PAGE 1204 LINE 62731 +define pcodeop vmovlpd_avx ; +:VMOVLPD XmmReg1, vexVVVV_XmmReg, m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x12; (XmmReg1 & YmmReg1) ... & m64 +{ + local tmp:16 = vmovlpd_avx( vexVVVV_XmmReg, m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVLPD 4-84 PAGE 1204 LINE 62737 +:VMOVLPD m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x13; XmmReg1 ... & m64 +{ + m64 = vmovlpd_avx( XmmReg1 ); +} + +# MOVLPS 4-86 PAGE 1206 LINE 62816 +define pcodeop vmovlps_avx ; +:VMOVLPS XmmReg1, vexVVVV_XmmReg, m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x12; (XmmReg1 & YmmReg1) ... & m64 +{ + local tmp:16 = vmovlps_avx( vexVVVV_XmmReg, m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVLPS 4-86 PAGE 1206 LINE 62822 +:VMOVLPS m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x13; XmmReg1 ... & m64 +{ + m64 = vmovlps_avx( XmmReg1 ); +} + +# 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) +{ + Reg32 = vmovmskpd_avx( XmmReg2 ); + # TODO Reg64 = zext(Reg32) +} + +# 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) +{ + Reg32 = vmovmskpd_avx( YmmReg2 ); + # TODO Reg64 = zext(Reg32) +} + +# 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) +{ + Reg32 = vmovmskps_avx( XmmReg2 ); + # TODO Reg64 = zext(Reg32) +} + +# 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) +{ + Reg32 = vmovmskps_avx( YmmReg2 ); + # TODO Reg64 = zext(Reg32) +} + +# MOVNTDQA 4-92 PAGE 1212 LINE 63084 +define pcodeop vmovntdqa_avx ; +:VMOVNTDQA XmmReg1, m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x2A; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vmovntdqa_avx( m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVNTDQ 4-94 PAGE 1214 LINE 63187 +define pcodeop vmovntdq_avx ; +:VMOVNTDQ m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xE7; XmmReg1 ... & m128 +{ + m128 = vmovntdq_avx( XmmReg1 ); +} + +# MOVNTDQ 4-94 PAGE 1214 LINE 63189 +:VMOVNTDQ m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xE7; YmmReg1 ... & m256 +{ + m256 = vmovntdq_avx( YmmReg1 ); +} + +# MOVNTPD 4-98 PAGE 1218 LINE 63357 +define pcodeop vmovntpd_avx ; +:VMOVNTPD m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2B; XmmReg1 ... & m128 +{ + m128 = vmovntpd_avx( XmmReg1 ); +} + +# MOVNTPD 4-98 PAGE 1218 LINE 63359 +:VMOVNTPD m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2B; YmmReg1 ... & m256 +{ + m256 = vmovntpd_avx( YmmReg1 ); +} + +# MOVNTPS 4-100 PAGE 1220 LINE 63441 +define pcodeop vmovntps_avx ; +:VMOVNTPS m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2B; XmmReg1 ... & m128 +{ + m128 = vmovntps_avx( XmmReg1 ); +} + +# MOVNTPS 4-100 PAGE 1220 LINE 63443 +:VMOVNTPS m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2B; YmmReg1 ... & m256 +{ + m256 = vmovntps_avx( YmmReg1 ); +} + +# MOVQ 4-103 PAGE 1223 LINE 63579 +:VMOVQ XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x7E; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vmovq_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVQ 4-103 PAGE 1223 LINE 63585 +:VMOVQ XmmReg2_m64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD6; XmmReg1 ... & XmmReg2_m64 +{ + XmmReg2_m64 = vmovq_avx( XmmReg1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVSD 4-111 PAGE 1231 LINE 63970 +# INFO mnemonic VMOVSD was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVSD 4-111 PAGE 1231 LINE 63972 +# INFO mnemonic VMOVSD was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVSD 4-111 PAGE 1231 LINE 63974 +# INFO mnemonic VMOVSD was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVSD 4-111 PAGE 1231 LINE 63976 +# INFO mnemonic VMOVSD was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVSHDUP 4-114 PAGE 1234 LINE 64126 +define pcodeop vmovshdup_avx ; +:VMOVSHDUP XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x16; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmovshdup_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSHDUP 4-114 PAGE 1234 LINE 64128 +:VMOVSHDUP YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x16; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmovshdup_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVSLDUP 4-117 PAGE 1237 LINE 64280 +define pcodeop vmovsldup_avx ; +:VMOVSLDUP XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x12; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmovsldup_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSLDUP 4-117 PAGE 1237 LINE 64282 +:VMOVSLDUP YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x12; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmovsldup_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVSS 4-120 PAGE 1240 LINE 64433 +define pcodeop vmovss_avx ; +:VMOVSS XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x10; (XmmReg1 & YmmReg1) & (mod=0x3 & XmmReg2) +{ + local tmp:16 = vmovss_avx( vexVVVV_XmmReg, XmmReg2 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSS 4-120 PAGE 1240 LINE 64435 +:VMOVSS XmmReg1, m32 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & m32 +{ + local tmp:16 = vmovss_avx( m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSS 4-120 PAGE 1240 LINE 64439 +:VMOVSS XmmReg2, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x11; XmmReg1 & (mod=0x3 & (XmmReg2 & YmmReg2)) +{ + local tmp:16 = vmovss_avx( vexVVVV_XmmReg, XmmReg1 ); + YmmReg2 = zext(tmp); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVSS 4-120 PAGE 1240 LINE 64441 +:VMOVSS m32, XmmReg1 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m32 +{ + m32 = vmovss_avx( XmmReg1 ); +} + +# MOVUPD 4-126 PAGE 1246 LINE 64687 +define pcodeop vmovupd_avx ; +:VMOVUPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmovupd_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVUPD 4-126 PAGE 1246 LINE 64689 +:VMOVUPD XmmReg2_m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & XmmReg2_m128 +{ + XmmReg2_m128 = vmovupd_avx( XmmReg1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVUPD 4-126 PAGE 1246 LINE 64691 +:VMOVUPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x10; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmovupd_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVUPD 4-126 PAGE 1246 LINE 64693 +:VMOVUPD YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = vmovupd_avx( YmmReg1 ); + # TODO ZmmReg2 = zext(YmmReg2) +} + +# MOVUPS 4-130 PAGE 1250 LINE 64872 +# INFO mnemonic VMOVUPS was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVUPS 4-130 PAGE 1250 LINE 64874 +# INFO mnemonic VMOVUPS was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVUPS 4-130 PAGE 1250 LINE 64876 +# INFO mnemonic VMOVUPS was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MOVUPS 4-130 PAGE 1250 LINE 64878 +# INFO mnemonic VMOVUPS was found in ../../../Processors/x86/data/languages/avx_manual.sinc + +# MPSADBW 4-136 PAGE 1256 LINE 65135 +define pcodeop vmpsadbw_avx ; +:VMPSADBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x42; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vmpsadbw_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MULPD 4-146 PAGE 1266 LINE 65682 +define pcodeop vmulpd_avx ; +:VMULPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmulpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MULPD 4-146 PAGE 1266 LINE 65684 +:VMULPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x59; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmulpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MULPS 4-149 PAGE 1269 LINE 65813 +define pcodeop vmulps_avx ; +:VMULPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vmulps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MULPS 4-149 PAGE 1269 LINE 65815 +:VMULPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x59; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vmulps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MULSD 4-152 PAGE 1272 LINE 65956 +define pcodeop vmulsd_avx ; +:VMULSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vmulsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MULSS 4-154 PAGE 1274 LINE 66052 +define pcodeop vmulss_avx ; +:VMULSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x59; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vmulss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ORPD 4-168 PAGE 1288 LINE 66720 +define pcodeop vorpd_avx ; +:VORPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x56; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vorpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ORPD 4-168 PAGE 1288 LINE 66722 +:VORPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x56; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vorpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ORPS 4-171 PAGE 1291 LINE 66846 +define pcodeop vorps_avx ; +:VORPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_XmmReg; byte=0x56; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vorps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ORPS 4-171 PAGE 1291 LINE 66848 +:VORPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & vexVVVV_YmmReg; byte=0x56; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vorps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67302 +define pcodeop vpabsb_avx ; +:VPABSB XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpabsb_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67305 +define pcodeop vpabsw_avx ; +:VPABSW XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpabsw_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67308 +define pcodeop vpabsd_avx ; +:VPABSD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpabsd_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PACKSSWB/PACKSSDW 4-186 PAGE 1306 LINE 67629 +define pcodeop vpacksswb_avx ; +:VPACKSSWB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x63; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpacksswb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PACKSSWB/PACKSSDW 4-186 PAGE 1306 LINE 67633 +define pcodeop vpackssdw_avx ; +:VPACKSSDW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x6B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpackssdw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PACKUSDW 4-194 PAGE 1314 LINE 68086 +define pcodeop vpackusdw_avx ; +:VPACKUSDW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_XmmReg; byte=0x2B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpackusdw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PACKUSWB 4-199 PAGE 1319 LINE 68366 +define pcodeop vpackuswb_avx ; +:VPACKUSWB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x67; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpackuswb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68658 +define pcodeop vpaddb_avx ; +:VPADDB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xFC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68660 +define pcodeop vpaddw_avx ; +:VPADDW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xFD; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68662 +define pcodeop vpaddd_avx ; +:VPADDD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xFE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68664 +define pcodeop vpaddq_avx ; +:VPADDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD4; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDSB/PADDSW 4-211 PAGE 1331 LINE 69040 +define pcodeop vpaddsb_avx ; +:VPADDSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xEC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddsb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDSB/PADDSW 4-211 PAGE 1331 LINE 69042 +define pcodeop vpaddsw_avx ; +:VPADDSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xED; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDUSB/PADDUSW 4-215 PAGE 1335 LINE 69257 +define pcodeop vpaddusb_avx ; +:VPADDUSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xDC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddusb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PADDUSB/PADDUSW 4-215 PAGE 1335 LINE 69260 +define pcodeop vpaddusw_avx ; +:VPADDUSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xDD; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpaddusw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PALIGNR 4-219 PAGE 1339 LINE 69485 +define pcodeop vpalignr_avx ; +:VPALIGNR XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpalignr_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PAND 4-223 PAGE 1343 LINE 69678 +define pcodeop vpand_avx ; +:VPAND XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xDB; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpand_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PANDN 4-226 PAGE 1346 LINE 69854 +define pcodeop vpandn_avx ; +:VPANDN XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xDF; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpandn_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PAVGB/PAVGW 4-230 PAGE 1350 LINE 70085 +define pcodeop vpavgb_avx ; +:VPAVGB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE0; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpavgb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PAVGB/PAVGW 4-230 PAGE 1350 LINE 70088 +define pcodeop vpavgw_avx ; +:VPAVGW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE3; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpavgw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PBLENDVB 4-234 PAGE 1354 LINE 70296 +define pcodeop vpblendvb_avx ; +:VPBLENDVB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x4C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; Xmm_imm8_7_4 +{ + local tmp:16 = vpblendvb_avx( vexVVVV_XmmReg, XmmReg2_m128, Xmm_imm8_7_4 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PBLENDW 4-238 PAGE 1358 LINE 70522 +define pcodeop vpblendw_avx ; +:VPBLENDW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpblendw_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + + + + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70821 +define pcodeop vpcmpeqb_avx ; +:VPCMPEQB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x74; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpeqb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70824 +define pcodeop vpcmpeqw_avx ; +:VPCMPEQW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x75; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpeqw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70827 +define pcodeop vpcmpeqd_avx ; +:VPCMPEQD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x76; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpeqd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# 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_avx( XmmReg1, XmmReg2_m128, imm8:1 ); + # TODO missing destination or side effects +} + +# 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_avx( XmmReg1, XmmReg2_m128, imm8:1 ); + # TODO missing destination or side effects +} + +# 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 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpgtb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71502 +define pcodeop vpcmpgtw_avx ; +:VPCMPGTW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x65; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpgtw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71505 +define pcodeop vpcmpgtd_avx ; +:VPCMPGTD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x66; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpgtd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PCMPGTQ 4-263 PAGE 1383 LINE 71833 +define pcodeop vpcmpgtq_avx ; +:VPCMPGTQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x37; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpcmpgtq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# 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_avx( XmmReg1, XmmReg2_m128, imm8:1 ); + # TODO missing destination or side effects +} + +# 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 +} + +# PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72322 +define pcodeop vpextrb_avx ; +:VPEXTRB Reg32_m8, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x14; XmmReg1 ... & Reg32_m8; imm8 +{ + Reg32_m8 = vpextrb_avx( XmmReg1, imm8:1 ); + # TODO Reg64 = zext(Reg32) +} + +# PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72326 +define pcodeop vpextrd_avx ; +:VPEXTRD rm32, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x16; XmmReg1 ... & rm32; imm8 +{ + rm32 = vpextrd_avx( XmmReg1, imm8:1 ); +} + +# PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72330 +define pcodeop vpextrq_avx ; +@ifdef IA64 +:VPEXTRQ rm64, XmmReg1, imm8 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x16; XmmReg1 ... & rm64; imm8 +{ + rm64 = vpextrq_avx( XmmReg1, imm8:1 ); +} +@endif + +# PEXTRW 4-277 PAGE 1397 LINE 72478 +define pcodeop vpextrw_avx ; +:VPEXTRW Reg32, XmmReg2, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0); byte=0xC5; Reg32 & (mod=0x3 & XmmReg2); imm8 +{ + Reg32 = vpextrw_avx( XmmReg2, imm8:1 ); + # TODO Reg64 = zext(Reg32) +} + +# PEXTRW 4-277 PAGE 1397 LINE 72483 +:VPEXTRW Reg32_m16, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x15; XmmReg1 ... & Reg32_m16; imm8 +{ + Reg32_m16 = vpextrw_avx( XmmReg1, imm8:1 ); + # TODO Reg64 = zext(Reg32) +} + +# 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 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphaddw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHADDW/PHADDD 4-280 PAGE 1400 LINE 72630 +define pcodeop vphaddd_avx ; +:VPHADDD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x02; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphaddd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHADDSW 4-284 PAGE 1404 LINE 72821 +define pcodeop vphaddsw_avx ; +:VPHADDSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x03; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphaddsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHMINPOSUW 4-286 PAGE 1406 LINE 72939 +define pcodeop vphminposuw_avx ; +:VPHMINPOSUW XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x41; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphminposuw_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHSUBW/PHSUBD 4-288 PAGE 1408 LINE 73032 +define pcodeop vphsubw_avx ; +:VPHSUBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x05; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphsubw_avx( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHSUBW/PHSUBD 4-288 PAGE 1408 LINE 73035 +define pcodeop vphsubd_avx ; +:VPHSUBD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x06; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphsubd_avx( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PHSUBSW 4-291 PAGE 1411 LINE 73197 +define pcodeop vphsubsw_avx ; +:VPHSUBSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x07; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vphsubsw_avx( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73321 +define pcodeop vpinsrb_avx ; +:VPINSRB XmmReg1, vexVVVV_XmmReg, Reg32_m8, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x20; (XmmReg1 & YmmReg1) ... & Reg32_m8; imm8 +{ + local tmp:16 = vpinsrb_avx( vexVVVV_XmmReg, Reg32_m8, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73324 +define pcodeop vpinsrd_avx ; +:VPINSRD XmmReg1, vexVVVV_XmmReg, rm32, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x22; (XmmReg1 & YmmReg1) ... & rm32; imm8 +{ + local tmp:16 = vpinsrd_avx( vexVVVV_XmmReg, rm32, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73327 +define pcodeop vpinsrq_avx ; +@ifdef IA64 +:VPINSRQ XmmReg1, vexVVVV_XmmReg, rm64, imm8 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x22; (XmmReg1 & YmmReg1) ... & rm64; imm8 +{ + local tmp:16 = vpinsrq_avx( vexVVVV_XmmReg, rm64, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} +@endif + +# PINSRW 4-296 PAGE 1416 LINE 73446 +define pcodeop vpinsrw_avx ; +:VPINSRW XmmReg1, vexVVVV_XmmReg, Reg32_m16, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xC4; (XmmReg1 & YmmReg1) ... & Reg32_m16; imm8 +{ + local tmp:16 = vpinsrw_avx( vexVVVV_XmmReg, Reg32_m16, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMADDUBSW 4-298 PAGE 1418 LINE 73552 +define pcodeop vpmaddubsw_avx ; +:VPMADDUBSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x04; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaddubsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMADDWD 4-301 PAGE 1421 LINE 73700 +define pcodeop vpmaddwd_avx ; +:VPMADDWD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF5; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaddwd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73882 +define pcodeop vpmaxsb_avx ; +:VPMAXSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x3C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxsb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73885 +define pcodeop vpmaxsw_avx ; +:VPMAXSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xEE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73888 +define pcodeop vpmaxsd_avx ; +:VPMAXSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x3D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxsd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXUB/PMAXUW 4-311 PAGE 1431 LINE 74283 +define pcodeop vpmaxub_avx ; +:VPMAXUB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0xDE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxub_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXUB/PMAXUW 4-311 PAGE 1431 LINE 74286 +define pcodeop vpmaxuw_avx ; +:VPMAXUW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_XmmReg; byte=0x3E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxuw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMAXUD/PMAXUQ 4-316 PAGE 1436 LINE 74534 +define pcodeop vpmaxud_avx ; +:VPMAXUD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x3F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmaxud_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINSB/PMINSW 4-320 PAGE 1440 LINE 74736 +define pcodeop vpminsb_avx ; +:VPMINSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_XmmReg; byte=0x38; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminsb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINSB/PMINSW 4-320 PAGE 1440 LINE 74739 +define pcodeop vpminsw_avx ; +:VPMINSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0xEA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINSD/PMINSQ 4-325 PAGE 1445 LINE 74989 +define pcodeop vpminsd_avx ; +:VPMINSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x39; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminsd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINUB/PMINUW 4-329 PAGE 1449 LINE 75195 +define pcodeop vpminub_avx ; +:VPMINUB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_XmmReg; byte=0xDA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminub_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINUB/PMINUW 4-329 PAGE 1449 LINE 75198 +define pcodeop vpminuw_avx ; +:VPMINUW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_XmmReg; byte=0x3A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminuw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMINUD/PMINUQ 4-334 PAGE 1454 LINE 75445 +define pcodeop vpminud_avx ; +:VPMINUD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x3B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpminud_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75770 +define pcodeop vpmovsxbw_avx ; +:VPMOVSXBW XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x20; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovsxbw_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75772 +define pcodeop vpmovsxbd_avx ; +:VPMOVSXBD XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x21; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vpmovsxbd_avx( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75774 +define pcodeop vpmovsxbq_avx ; +:VPMOVSXBQ XmmReg1, XmmReg2_m16 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x22; (XmmReg1 & YmmReg1) ... & XmmReg2_m16 +{ + local tmp:16 = vpmovsxbq_avx( XmmReg2_m16 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75776 +define pcodeop vpmovsxwd_avx ; +:VPMOVSXWD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x23; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovsxwd_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75778 +define pcodeop vpmovsxwq_avx ; +:VPMOVSXWQ XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x24; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vpmovsxwq_avx( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75780 +define pcodeop vpmovsxdq_avx ; +:VPMOVSXDQ XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x25; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovsxdq_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76285 +define pcodeop vpmovzxbw_avx ; +:VPMOVZXBW XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x30; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovzxbw_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76288 +define pcodeop vpmovzxbd_avx ; +:VPMOVZXBD XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x31; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vpmovzxbd_avx( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76291 +define pcodeop vpmovzxbq_avx ; +:VPMOVZXBQ XmmReg1, XmmReg2_m16 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x32; (XmmReg1 & YmmReg1) ... & XmmReg2_m16 +{ + local tmp:16 = vpmovzxbq_avx( XmmReg2_m16 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76294 +define pcodeop vpmovzxwd_avx ; +:VPMOVZXWD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x33; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovzxwd_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76297 +define pcodeop vpmovzxwq_avx ; +:VPMOVZXWQ XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x34; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vpmovzxwq_avx( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76301 +define pcodeop vpmovzxdq_avx ; +:VPMOVZXDQ XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x35; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpmovzxdq_avx( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULDQ 4-359 PAGE 1479 LINE 76788 +define pcodeop vpmuldq_avx ; +:VPMULDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x28; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmuldq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULHRSW 4-362 PAGE 1482 LINE 76928 +define pcodeop vpmulhrsw_avx ; +:VPMULHRSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0B; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmulhrsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULHUW 4-366 PAGE 1486 LINE 77141 +define pcodeop vpmulhuw_avx ; +:VPMULHUW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE4; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmulhuw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULHW 4-370 PAGE 1490 LINE 77370 +define pcodeop vpmulhw_avx ; +:VPMULHW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE5; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmulhw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULLD/PMULLQ 4-374 PAGE 1494 LINE 77576 +define pcodeop vpmulld_avx ; +:VPMULLD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x40; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmulld_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULLW 4-378 PAGE 1498 LINE 77775 +define pcodeop vpmullw_avx ; +:VPMULLW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD5; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmullw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PMULUDQ 4-382 PAGE 1502 LINE 77969 +define pcodeop vpmuludq_avx ; +:VPMULUDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF4; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpmuludq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# POR 4-399 PAGE 1519 LINE 78850 +define pcodeop vpor_avx ; +:VPOR XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xEB; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpor_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSADBW 4-408 PAGE 1528 LINE 79240 +define pcodeop vpsadbw_avx ; +:VPSADBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsadbw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSHUFB 4-412 PAGE 1532 LINE 79460 +define pcodeop vpshufb_avx ; +:VPSHUFB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x00; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpshufb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSHUFD 4-416 PAGE 1536 LINE 79651 +define pcodeop vpshufd_avx ; +:VPSHUFD XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x70; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpshufd_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSHUFHW 4-420 PAGE 1540 LINE 79857 +define pcodeop vpshufhw_avx ; +:VPSHUFHW XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x70; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpshufhw_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSHUFLW 4-423 PAGE 1543 LINE 80032 +define pcodeop vpshuflw_avx ; +:VPSHUFLW XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x70; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpshuflw_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80269 +define pcodeop vpsignb_avx ; +:VPSIGNB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x08; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsignb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80272 +define pcodeop vpsignw_avx ; +:VPSIGNW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x09; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsignw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80275 +define pcodeop vpsignd_avx ; +:VPSIGND XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsignd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSLLDQ 4-431 PAGE 1551 LINE 80485 +define pcodeop vpslldq_avx ; +:VPSLLDQ vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x73; reg_opcode=7 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpslldq_avx( XmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80620 +define pcodeop vpsllw_avx ; +:VPSLLW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF1; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsllw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80623 +:VPSLLW vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x71; reg_opcode=6 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsllw_avx( XmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80626 +define pcodeop vpslld_avx ; +:VPSLLD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF2; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpslld_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80629 +:VPSLLD vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x72; reg_opcode=6 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpslld_avx( XmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80632 +define pcodeop vpsllq_avx ; +:VPSLLQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF3; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsllq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80635 +:VPSLLQ vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x73; reg_opcode=6 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsllq_avx( XmmReg2, imm8:1 ); +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81305 +define pcodeop vpsraw_avx ; +:VPSRAW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE1; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsraw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81308 +:VPSRAW vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x71; reg_opcode=4 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsraw_avx( XmmReg2, imm8:1 ); +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81311 +define pcodeop vpsrad_avx ; +:VPSRAD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE2; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrad_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81314 +:VPSRAD vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x72; reg_opcode=4 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsrad_avx( XmmReg2, imm8:1 ); +} + +# PSRLDQ 4-455 PAGE 1575 LINE 81873 +define pcodeop vpsrldq_avx ; +:VPSRLDQ vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x73; reg_opcode=3 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsrldq_avx( XmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82012 +define pcodeop vpsrlw_avx ; +:VPSRLW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD1; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrlw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82015 +:VPSRLW vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x71; reg_opcode=2 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsrlw_avx( XmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82018 +define pcodeop vpsrld_avx ; +:VPSRLD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD2; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrld_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82021 +:VPSRLD vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x72; reg_opcode=2 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsrld_avx( XmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82024 +define pcodeop vpsrlq_avx ; +:VPSRLQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD3; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrlq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82027 +:VPSRLQ vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDD) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x73; reg_opcode=2 & (mod=0x3 & XmmReg2); imm8 +{ + vexVVVV_XmmReg = vpsrlq_avx( XmmReg2, imm8:1 ); +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82689 +define pcodeop vpsubb_avx ; +:VPSUBB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82691 +define pcodeop vpsubw_avx ; +:VPSUBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xF9; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82694 +define pcodeop vpsubd_avx ; +:VPSUBD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xFA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBQ 4-476 PAGE 1596 LINE 83101 +define pcodeop vpsubq_avx ; +:VPSUBQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xFB; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBSB/PSUBSW 4-479 PAGE 1599 LINE 83258 +define pcodeop vpsubsb_avx ; +:VPSUBSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubsb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBSB/PSUBSW 4-479 PAGE 1599 LINE 83261 +define pcodeop vpsubsw_avx ; +:VPSUBSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xE9; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubsw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBUSB/PSUBUSW 4-483 PAGE 1603 LINE 83498 +define pcodeop vpsubusb_avx ; +:VPSUBUSB XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubusb_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PSUBUSB/PSUBUSW 4-483 PAGE 1603 LINE 83501 +define pcodeop vpsubusw_avx ; +:VPSUBUSW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xD9; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsubusw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PTEST 4-487 PAGE 1607 LINE 83728 +define pcodeop vptest_avx ; +:VPTEST XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x17; XmmReg1 ... & XmmReg2_m128 +{ + vptest_avx( XmmReg1, XmmReg2_m128 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# PTEST 4-487 PAGE 1607 LINE 83730 +:VPTEST YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x17; YmmReg1 ... & YmmReg2_m256 +{ + vptest_avx( YmmReg1, YmmReg2_m256 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83929 +define pcodeop vpunpckhbw_avx ; +:VPUNPCKHBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x68; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpckhbw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83932 +define pcodeop vpunpckhwd_avx ; +:VPUNPCKHWD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x69; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpckhwd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83935 +define pcodeop vpunpckhdq_avx ; +:VPUNPCKHDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x6A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpckhdq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83938 +define pcodeop vpunpckhqdq_avx ; +:VPUNPCKHQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x6D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpckhqdq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84529 +define pcodeop vpunpcklbw_avx ; +:VPUNPCKLBW XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x60; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpcklbw_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84532 +define pcodeop vpunpcklwd_avx ; +:VPUNPCKLWD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x61; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpcklwd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84535 +define pcodeop vpunpckldq_avx ; +:VPUNPCKLDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x62; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpckldq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84538 +define pcodeop vpunpcklqdq_avx ; +:VPUNPCKLQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x6C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpunpcklqdq_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# PXOR 4-518 PAGE 1638 LINE 85495 +define pcodeop vpxor_avx ; +:VPXOR XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xEF; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpxor_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# RCPPS 4-526 PAGE 1646 LINE 85950 +define pcodeop vrcpps_avx ; +:VRCPPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x53; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vrcpps_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# RCPPS 4-526 PAGE 1646 LINE 85953 +:VRCPPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x53; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vrcpps_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# RCPSS 4-528 PAGE 1648 LINE 86052 +define pcodeop vrcpss_avx ; +:VRCPSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x53; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vrcpss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ROUNDPD 4-564 PAGE 1684 LINE 87791 +define pcodeop vroundpd_avx ; +:VROUNDPD XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x09; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vroundpd_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ROUNDPD 4-564 PAGE 1684 LINE 87795 +:VROUNDPD YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x09; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vroundpd_avx( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ROUNDPS 4-567 PAGE 1687 LINE 87934 +define pcodeop vroundps_avx ; +:VROUNDPS XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x08; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vroundps_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ROUNDPS 4-567 PAGE 1687 LINE 87938 +:VROUNDPS YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0x08; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vroundps_avx( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# ROUNDSD 4-570 PAGE 1690 LINE 88058 +define pcodeop vroundsd_avx ; +:VROUNDSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64, imm8 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0B; (XmmReg1 & YmmReg1) ... & XmmReg2_m64; imm8 +{ + local tmp:16 = vroundsd_avx( vexVVVV_XmmReg, XmmReg2_m64, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# ROUNDSS 4-572 PAGE 1692 LINE 88145 +define pcodeop vroundss_avx ; +:VROUNDSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32, imm8 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x0A; (XmmReg1 & YmmReg1) ... & XmmReg2_m32; imm8 +{ + local tmp:16 = vroundss_avx( vexVVVV_XmmReg, XmmReg2_m32, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# RSQRTPS 4-576 PAGE 1696 LINE 88301 +define pcodeop vrsqrtps_avx ; +:VRSQRTPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x52; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vrsqrtps_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# RSQRTPS 4-576 PAGE 1696 LINE 88304 +:VRSQRTPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x52; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vrsqrtps_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# RSQRTSS 4-578 PAGE 1698 LINE 88399 +define pcodeop vrsqrtss_avx ; +:VRSQRTSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x52; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vrsqrtss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SHUFPD 4-617 PAGE 1737 LINE 90223 +define pcodeop vshufpd_avx ; +:VSHUFPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vshufpd_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SHUFPD 4-617 PAGE 1737 LINE 90227 +:VSHUFPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xC6; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vshufpd_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SHUFPS 4-622 PAGE 1742 LINE 90483 +define pcodeop vshufps_avx ; +:VSHUFPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xC6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vshufps_avx( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SHUFPS 4-622 PAGE 1742 LINE 90486 +:VSHUFPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xC6; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vshufps_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SQRTPD 4-632 PAGE 1752 LINE 91001 +define pcodeop vsqrtpd_avx ; +:VSQRTPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x51; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vsqrtpd_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SQRTPD 4-632 PAGE 1752 LINE 91004 +:VSQRTPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x51; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vsqrtpd_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SQRTPS 4-635 PAGE 1755 LINE 91133 +define pcodeop vsqrtps_avx ; +:VSQRTPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x51; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vsqrtps_avx( XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SQRTPS 4-635 PAGE 1755 LINE 91136 +:VSQRTPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x51; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vsqrtps_avx( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SQRTSD 4-638 PAGE 1758 LINE 91272 +define pcodeop vsqrtsd_avx ; +:VSQRTSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x51; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vsqrtsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SQRTSS 4-640 PAGE 1760 LINE 91367 +define pcodeop vsqrtss_avx ; +:VSQRTSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x51; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vsqrtss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# STMXCSR 4-647 PAGE 1767 LINE 91697 +define pcodeop vstmxcsr_avx ; +:VSTMXCSR m32 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0xAE; reg_opcode=3 ... & m32 +{ + m32 = vstmxcsr_avx( ); +} + +# SUBPD 4-656 PAGE 1776 LINE 92116 +define pcodeop vsubpd_avx ; +:VSUBPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vsubpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SUBPD 4-656 PAGE 1776 LINE 92118 +:VSUBPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vsubpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SUBPS 4-659 PAGE 1779 LINE 92265 +define pcodeop vsubps_avx ; +:VSUBPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vsubps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SUBPS 4-659 PAGE 1779 LINE 92267 +:VSUBPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x5C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vsubps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# SUBSD 4-662 PAGE 1782 LINE 92419 +define pcodeop vsubsd_avx ; +:VSUBSD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vsubsd_avx( vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# SUBSS 4-664 PAGE 1784 LINE 92512 +define pcodeop vsubss_avx ; +:VSUBSS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x5C; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vsubss_avx( vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# UCOMISD 4-683 PAGE 1803 LINE 93421 +define pcodeop vucomisd_avx ; +:VUCOMISD XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x2E; XmmReg1 ... & XmmReg2_m64 +{ + vucomisd_avx( XmmReg1, XmmReg2_m64 ); + # TODO set flags AF, CF, OF, PF, SF, ZF +} + +# UCOMISS 4-685 PAGE 1805 LINE 93504 +define pcodeop vucomiss_avx ; +:VUCOMISS XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x2E; XmmReg1 ... & XmmReg2_m32 +{ + vucomiss_avx( XmmReg1, XmmReg2_m32 ); + # TODO set flags AF, CF, OF, PF, SF, ZF +} + +# UNPCKHPD 4-688 PAGE 1808 LINE 93623 +define pcodeop vunpckhpd_avx ; +:VUNPCKHPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x15; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vunpckhpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# UNPCKHPD 4-688 PAGE 1808 LINE 93626 +:VUNPCKHPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x15; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vunpckhpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# UNPCKHPS 4-692 PAGE 1812 LINE 93807 +define pcodeop vunpckhps_avx ; +:VUNPCKHPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x15; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vunpckhps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# UNPCKHPS 4-692 PAGE 1812 LINE 93810 +:VUNPCKHPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x15; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vunpckhps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# UNPCKLPD 4-696 PAGE 1816 LINE 94039 +define pcodeop vunpcklpd_avx ; +:VUNPCKLPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x14; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vunpcklpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# UNPCKLPD 4-696 PAGE 1816 LINE 94042 +:VUNPCKLPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x14; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vunpcklpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# UNPCKLPS 4-700 PAGE 1820 LINE 94225 +define pcodeop vunpcklps_avx ; +:VUNPCKLPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x14; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vunpcklps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# UNPCKLPS 4-700 PAGE 1820 LINE 94228 +:VUNPCKLPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x14; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vunpcklps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + + +# VBROADCAST 5-12 PAGE 1836 LINE 95843 +define pcodeop vbroadcastss_avx ; +:VBROADCASTSS XmmReg1, m32 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x18; (XmmReg1 & YmmReg1) ... & m32 +{ + local tmp:16 = vbroadcastss_avx( m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95845 +:VBROADCASTSS YmmReg1, m32 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x18; YmmReg1 ... & m32 +{ + YmmReg1 = vbroadcastss_avx( m32 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95847 +define pcodeop vbroadcastsd_avx ; +:VBROADCASTSD YmmReg1, m64 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x19; YmmReg1 ... & m64 +{ + YmmReg1 = vbroadcastsd_avx( m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95849 +define pcodeop vbroadcastf128_avx ; +:VBROADCASTF128 YmmReg1, m128 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x1A; YmmReg1 ... & m128 +{ + YmmReg1 = vbroadcastf128_avx( m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95851 +# WARNING: duplicate opcode VEX.128.66.0F38.W0 18 /r last seen on 5-12 PAGE 1836 LINE 95843 for "VBROADCASTSS xmm1, xmm2" +define pcodeop vbroadcastss_avx2 ; +:VBROADCASTSS XmmReg1, XmmReg2 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x18; (XmmReg1 & YmmReg1) & (mod=0x3 & XmmReg2) +{ + local tmp:16 = vbroadcastss_avx2( XmmReg2 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95854 +# WARNING: duplicate opcode VEX.256.66.0F38.W0 18 /r last seen on 5-12 PAGE 1836 LINE 95845 for "VBROADCASTSS ymm1, xmm2" +:VBROADCASTSS YmmReg1, XmmReg2 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x18; YmmReg1 & (mod=0x3 & XmmReg2) +{ + YmmReg1 = vbroadcastss_avx2( XmmReg2 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VBROADCAST 5-12 PAGE 1836 LINE 95856 +# WARNING: duplicate opcode VEX.256.66.0F38.W0 19 /r last seen on 5-12 PAGE 1836 LINE 95847 for "VBROADCASTSD ymm1, xmm2" +define pcodeop vbroadcastsd_avx2 ; +:VBROADCASTSD YmmReg1, XmmReg2 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x19; YmmReg1 & (mod=0x3 & XmmReg2) +{ + YmmReg1 = vbroadcastsd_avx2( XmmReg2 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + + +# VEXTRACTF128/VEXTRACTF32x4/VEXTRACTF64x2/VEXTRACTF32x8/VEXTRACTF64x4 5-99 PAGE 1923 LINE 99102 +define pcodeop vextractf128_avx ; +:VEXTRACTF128 XmmReg2_m128, YmmReg1, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x19; YmmReg1 ... & XmmReg2_m128; imm8 +{ + XmmReg2_m128 = vextractf128_avx( YmmReg1, imm8:1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# VINSERTF128/VINSERTF32x4/VINSERTF64x2/VINSERTF32x8/VINSERTF64x4 5-310 PAGE 2134 LINE 109703 +define pcodeop vinsertf128_avx ; +:VINSERTF128 YmmReg1, vexVVVV_YmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x18; YmmReg1 ... & XmmReg2_m128; imm8 +{ + YmmReg1 = vinsertf128_avx( vexVVVV_YmmReg, XmmReg2_m128, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110151 +define pcodeop vmaskmovps_avx ; +:VMASKMOVPS XmmReg1, vexVVVV_XmmReg, m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2C; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vmaskmovps_avx( vexVVVV_XmmReg, m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110154 +:VMASKMOVPS YmmReg1, vexVVVV_YmmReg, m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x2C; YmmReg1 ... & m256 +{ + YmmReg1 = vmaskmovps_avx( vexVVVV_YmmReg, m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110157 +define pcodeop vmaskmovpd_avx ; +:VMASKMOVPD XmmReg1, vexVVVV_XmmReg, m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2D; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vmaskmovpd_avx( vexVVVV_XmmReg, m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110160 +:VMASKMOVPD YmmReg1, vexVVVV_YmmReg, m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x2D; YmmReg1 ... & m256 +{ + YmmReg1 = vmaskmovpd_avx( vexVVVV_YmmReg, m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110163 +:VMASKMOVPS m128, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2E; XmmReg1 ... & m128 +{ + m128 = vmaskmovps_avx( vexVVVV_XmmReg, XmmReg1 ); +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110166 +:VMASKMOVPS m256, vexVVVV_YmmReg, YmmReg1 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x2E; YmmReg1 ... & m256 +{ + m256 = vmaskmovps_avx( vexVVVV_YmmReg, YmmReg1 ); +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110168 +:VMASKMOVPD m128, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x2F; XmmReg1 ... & m128 +{ + m128 = vmaskmovpd_avx( vexVVVV_XmmReg, XmmReg1 ); +} + +# VMASKMOV 5-318 PAGE 2142 LINE 110171 +:VMASKMOVPD m256, vexVVVV_YmmReg, YmmReg1 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x2F; YmmReg1 ... & m256 +{ + m256 = vmaskmovpd_avx( vexVVVV_YmmReg, YmmReg1 ); +} + +# VPERM2F128 5-358 PAGE 2182 LINE 112216 +define pcodeop vperm2f128_avx ; +:VPERM2F128 YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x06; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vperm2f128_avx( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMILPD 5-371 PAGE 2195 LINE 112860 +define pcodeop vpermilpd_avx ; +:VPERMILPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x0D; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpermilpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPERMILPD 5-371 PAGE 2195 LINE 112863 +:VPERMILPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x0D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpermilpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMILPD 5-371 PAGE 2195 LINE 112875 +:VPERMILPD XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x05; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpermilpd_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPERMILPD 5-371 PAGE 2195 LINE 112877 +:VPERMILPD YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x05; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpermilpd_avx( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMILPS 5-376 PAGE 2200 LINE 113158 +define pcodeop vpermilps_avx ; +:VPERMILPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x0C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpermilps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPERMILPS 5-376 PAGE 2200 LINE 113161 +:VPERMILPS XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x04; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpermilps_avx( XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPERMILPS 5-376 PAGE 2200 LINE 113164 +:VPERMILPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x0C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpermilps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMILPS 5-376 PAGE 2200 LINE 113167 +:VPERMILPS YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x04; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpermilps_avx( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VTESTPD/VTESTPS 5-560 PAGE 2384 LINE 122257 +define pcodeop vtestps_avx ; +:VTESTPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x0E; XmmReg1 ... & XmmReg2_m128 +{ + vtestps_avx( XmmReg1, XmmReg2_m128 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# VTESTPD/VTESTPS 5-560 PAGE 2384 LINE 122260 +:VTESTPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x0E; YmmReg1 ... & YmmReg2_m256 +{ + vtestps_avx( YmmReg1, YmmReg2_m256 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# VTESTPD/VTESTPS 5-560 PAGE 2384 LINE 122263 +define pcodeop vtestpd_avx ; +:VTESTPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x0F; XmmReg1 ... & XmmReg2_m128 +{ + vtestpd_avx( XmmReg1, XmmReg2_m128 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# VTESTPD/VTESTPS 5-560 PAGE 2384 LINE 122266 +:VTESTPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x0F; YmmReg1 ... & YmmReg2_m256 +{ + vtestpd_avx( YmmReg1, YmmReg2_m256 ); + # TODO set flags AF, CF, PF, SF, ZF +} + +# XORPD 5-596 PAGE 2420 LINE 123828 +define pcodeop vxorpd_avx ; +:VXORPD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x57; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vxorpd_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# XORPD 5-596 PAGE 2420 LINE 123831 +:VXORPD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x57; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vxorpd_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# XORPS 5-599 PAGE 2423 LINE 123953 +define pcodeop vxorps_avx ; +:VXORPS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x57; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vxorps_avx( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# XORPS 5-599 PAGE 2423 LINE 123956 +:VXORPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x57; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vxorps_avx( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2.sinc new file mode 100644 index 00000000..2f96ccf8 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2.sinc @@ -0,0 +1,1221 @@ +# INFO This file automatically generated by andre on Thu May 10 11:02:19 2018 +# INFO Direct edits to this file may be lost in future updates +# INFO Command line arguments: ['--sinc', '--cpuid-match', '^AVX2\\b', '--skip-sinc', '../../../Processors/x86/data/languages/avx2_manual.sinc'] + +# MOVNTDQA 4-92 PAGE 1212 LINE 63086 +define pcodeop vmovntdqa_avx2 ; +:VMOVNTDQA YmmReg1, m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x2A; YmmReg1 ... & m256 +{ + YmmReg1 = vmovntdqa_avx2( m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MPSADBW 4-136 PAGE 1256 LINE 65140 +define pcodeop vmpsadbw_avx2 ; +:VMPSADBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x42; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vmpsadbw_avx2( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67311 +define pcodeop vpabsb_avx2 ; +:VPABSB YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpabsb_avx2( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67314 +define pcodeop vpabsw_avx2 ; +:VPABSW YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpabsw_avx2( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PABSB/PABSW/PABSD/PABSQ 4-180 PAGE 1300 LINE 67317 +define pcodeop vpabsd_avx2 ; +:VPABSD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x1E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpabsd_avx2( YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PACKSSWB/PACKSSDW 4-186 PAGE 1306 LINE 67637 +define pcodeop vpacksswb_avx2 ; +:VPACKSSWB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x63; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpacksswb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PACKSSWB/PACKSSDW 4-186 PAGE 1306 LINE 67641 +define pcodeop vpackssdw_avx2 ; +:VPACKSSDW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x6B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpackssdw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PACKUSDW 4-194 PAGE 1314 LINE 68090 +define pcodeop vpackusdw_avx2 ; +:VPACKUSDW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0x2B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpackusdw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PACKUSWB 4-199 PAGE 1319 LINE 68370 +define pcodeop vpackuswb_avx2 ; +:VPACKUSWB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x67; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpackuswb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68666 +define pcodeop vpaddb_avx2 ; +:VPADDB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xFC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68668 +define pcodeop vpaddw_avx2 ; +:VPADDW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xFD; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68670 +define pcodeop vpaddd_avx2 ; +:VPADDD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xFE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDB/PADDW/PADDD/PADDQ 4-204 PAGE 1324 LINE 68672 +define pcodeop vpaddq_avx2 ; +:VPADDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD4; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDSB/PADDSW 4-211 PAGE 1331 LINE 69045 +define pcodeop vpaddsb_avx2 ; +:VPADDSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xEC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddsb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDSB/PADDSW 4-211 PAGE 1331 LINE 69048 +define pcodeop vpaddsw_avx2 ; +:VPADDSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xED; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDUSB/PADDUSW 4-215 PAGE 1335 LINE 69263 +define pcodeop vpaddusb_avx2 ; +:VPADDUSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xDC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddusb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PADDUSB/PADDUSW 4-215 PAGE 1335 LINE 69266 +define pcodeop vpaddusw_avx2 ; +:VPADDUSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xDD; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpaddusw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PALIGNR 4-219 PAGE 1339 LINE 69489 +define pcodeop vpalignr_avx2 ; +:VPALIGNR YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0F; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpalignr_avx2( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PAND 4-223 PAGE 1343 LINE 69680 +define pcodeop vpand_avx2 ; +:VPAND YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xDB; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpand_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PANDN 4-226 PAGE 1346 LINE 69856 +define pcodeop vpandn_avx2 ; +:VPANDN YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xDF; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpandn_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PAVGB/PAVGW 4-230 PAGE 1350 LINE 70091 +define pcodeop vpavgb_avx2 ; +:VPAVGB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE0; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpavgb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PAVGB/PAVGW 4-230 PAGE 1350 LINE 70094 +define pcodeop vpavgw_avx2 ; +:VPAVGW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE3; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpavgw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PBLENDVB 4-234 PAGE 1354 LINE 70300 +define pcodeop vpblendvb_avx2 ; +:VPBLENDVB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x4C; YmmReg1 ... & YmmReg2_m256; Ymm_imm8_7_4 +{ + YmmReg1 = vpblendvb_avx2( vexVVVV_YmmReg, YmmReg2_m256, Ymm_imm8_7_4 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PBLENDW 4-238 PAGE 1358 LINE 70525 +define pcodeop vpblendw_avx2 ; +:VPBLENDW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0E; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpblendw_avx2( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70830 +define pcodeop vpcmpeqb_avx2 ; +:VPCMPEQB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x74; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpeqb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70833 +define pcodeop vpcmpeqw_avx2 ; +:VPCMPEQW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x75; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpeqw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPEQB/PCMPEQW/PCMPEQD 4-244 PAGE 1364 LINE 70837 +define pcodeop vpcmpeqd_avx2 ; +:VPCMPEQD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x76; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpeqd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71508 +define pcodeop vpcmpgtb_avx2 ; +:VPCMPGTB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x64; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpgtb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71511 +define pcodeop vpcmpgtw_avx2 ; +:VPCMPGTW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x65; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpgtw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPGTB/PCMPGTW/PCMPGTD 4-257 PAGE 1377 LINE 71514 +define pcodeop vpcmpgtd_avx2 ; +:VPCMPGTD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x66; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpgtd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PCMPGTQ 4-263 PAGE 1383 LINE 71835 +define pcodeop vpcmpgtq_avx2 ; +:VPCMPGTQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x37; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpcmpgtq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHADDW/PHADDD 4-280 PAGE 1400 LINE 72633 +define pcodeop vphaddw_avx2 ; +:VPHADDW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x01; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphaddw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHADDW/PHADDD 4-280 PAGE 1400 LINE 72636 +define pcodeop vphaddd_avx2 ; +:VPHADDD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x02; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphaddd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHADDSW 4-284 PAGE 1404 LINE 72824 +define pcodeop vphaddsw_avx2 ; +:VPHADDSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x03; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphaddsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHSUBW/PHSUBD 4-288 PAGE 1408 LINE 73038 +define pcodeop vphsubw_avx2 ; +:VPHSUBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x05; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphsubw_avx2( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHSUBW/PHSUBD 4-288 PAGE 1408 LINE 73041 +define pcodeop vphsubd_avx2 ; +:VPHSUBD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x06; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphsubd_avx2( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PHSUBSW 4-291 PAGE 1411 LINE 73200 +define pcodeop vphsubsw_avx2 ; +:VPHSUBSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x07; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vphsubsw_avx2( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMADDUBSW 4-298 PAGE 1418 LINE 73555 +define pcodeop vpmaddubsw_avx2 ; +:VPMADDUBSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x04; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaddubsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMADDWD 4-301 PAGE 1421 LINE 73704 +define pcodeop vpmaddwd_avx2 ; +:VPMADDWD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF5; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaddwd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73891 +define pcodeop vpmaxsb_avx2 ; +:VPMAXSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x3C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxsb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73894 +define pcodeop vpmaxsw_avx2 ; +:VPMAXSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xEE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXSB/PMAXSW/PMAXSD/PMAXSQ 4-304 PAGE 1424 LINE 73897 +define pcodeop vpmaxsd_avx2 ; +:VPMAXSD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x3D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxsd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXUB/PMAXUW 4-311 PAGE 1431 LINE 74289 +define pcodeop vpmaxub_avx2 ; +:VPMAXUB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0xDE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxub_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXUB/PMAXUW 4-311 PAGE 1431 LINE 74292 +define pcodeop vpmaxuw_avx2 ; +:VPMAXUW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0x3E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxuw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMAXUD/PMAXUQ 4-316 PAGE 1436 LINE 74537 +define pcodeop vpmaxud_avx2 ; +:VPMAXUD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x3F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmaxud_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINSB/PMINSW 4-320 PAGE 1440 LINE 74742 +define pcodeop vpminsb_avx2 ; +:VPMINSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0x38; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminsb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINSB/PMINSW 4-320 PAGE 1440 LINE 74745 +define pcodeop vpminsw_avx2 ; +:VPMINSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0xEA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINSD/PMINSQ 4-325 PAGE 1445 LINE 74992 +define pcodeop vpminsd_avx2 ; +:VPMINSD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x39; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminsd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINUB/PMINUW 4-329 PAGE 1449 LINE 75201 +define pcodeop vpminub_avx2 ; +:VPMINUB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & vexVVVV_YmmReg; byte=0xDA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminub_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINUB/PMINUW 4-329 PAGE 1449 LINE 75204 +define pcodeop vpminuw_avx2 ; +:VPMINUW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0x3A; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminuw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMINUD/PMINUQ 4-334 PAGE 1454 LINE 75448 +define pcodeop vpminud_avx2 ; +:VPMINUD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x3B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpminud_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75782 +define pcodeop vpmovsxbw_avx2 ; +:VPMOVSXBW YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x20; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovsxbw_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75784 +define pcodeop vpmovsxbd_avx2 ; +:VPMOVSXBD YmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x21; YmmReg1 ... & XmmReg2_m64 +{ + YmmReg1 = vpmovsxbd_avx2( XmmReg2_m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75786 +define pcodeop vpmovsxbq_avx2 ; +:VPMOVSXBQ YmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x22; YmmReg1 ... & XmmReg2_m32 +{ + YmmReg1 = vpmovsxbq_avx2( XmmReg2_m32 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75788 +define pcodeop vpmovsxwd_avx2 ; +:VPMOVSXWD YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x23; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovsxwd_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75791 +define pcodeop vpmovsxwq_avx2 ; +:VPMOVSXWQ YmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x24; YmmReg1 ... & XmmReg2_m64 +{ + YmmReg1 = vpmovsxwq_avx2( XmmReg2_m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVSX 4-340 PAGE 1460 LINE 75793 +define pcodeop vpmovsxdq_avx2 ; +:VPMOVSXDQ YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x25; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovsxdq_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76304 +define pcodeop vpmovzxbw_avx2 ; +:VPMOVZXBW YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x30; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovzxbw_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76306 +define pcodeop vpmovzxbd_avx2 ; +:VPMOVZXBD YmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x31; YmmReg1 ... & XmmReg2_m64 +{ + YmmReg1 = vpmovzxbd_avx2( XmmReg2_m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76309 +define pcodeop vpmovzxbq_avx2 ; +:VPMOVZXBQ YmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x32; YmmReg1 ... & XmmReg2_m32 +{ + YmmReg1 = vpmovzxbq_avx2( XmmReg2_m32 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76312 +define pcodeop vpmovzxwd_avx2 ; +:VPMOVZXWD YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x33; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovzxwd_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76314 +define pcodeop vpmovzxwq_avx2 ; +:VPMOVZXWQ YmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x34; YmmReg1 ... & XmmReg2_m64 +{ + YmmReg1 = vpmovzxwq_avx2( XmmReg2_m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMOVZX 4-350 PAGE 1470 LINE 76317 +define pcodeop vpmovzxdq_avx2 ; +:VPMOVZXDQ YmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0x35; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpmovzxdq_avx2( XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULDQ 4-359 PAGE 1479 LINE 76791 +define pcodeop vpmuldq_avx2 ; +:VPMULDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x28; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmuldq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULHRSW 4-362 PAGE 1482 LINE 76931 +define pcodeop vpmulhrsw_avx2 ; +:VPMULHRSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0B; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmulhrsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULHUW 4-366 PAGE 1486 LINE 77144 +define pcodeop vpmulhuw_avx2 ; +:VPMULHUW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE4; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmulhuw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULHW 4-370 PAGE 1490 LINE 77373 +define pcodeop vpmulhw_avx2 ; +:VPMULHW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE5; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmulhw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULLD/PMULLQ 4-374 PAGE 1494 LINE 77579 +define pcodeop vpmulld_avx2 ; +:VPMULLD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x40; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmulld_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULLW 4-378 PAGE 1498 LINE 77778 +define pcodeop vpmullw_avx2 ; +:VPMULLW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD5; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmullw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PMULUDQ 4-382 PAGE 1502 LINE 77973 +define pcodeop vpmuludq_avx2 ; +:VPMULUDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF4; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpmuludq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# POR 4-399 PAGE 1519 LINE 78852 +define pcodeop vpor_avx2 ; +:VPOR YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xEB; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpor_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSADBW 4-408 PAGE 1528 LINE 79245 +define pcodeop vpsadbw_avx2 ; +:VPSADBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF6; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsadbw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSHUFB 4-412 PAGE 1532 LINE 79463 +define pcodeop vpshufb_avx2 ; +:VPSHUFB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x00; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpshufb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSHUFD 4-416 PAGE 1536 LINE 79653 +define pcodeop vpshufd_avx2 ; +:VPSHUFD YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x70; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpshufd_avx2( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSHUFHW 4-420 PAGE 1540 LINE 79860 +define pcodeop vpshufhw_avx2 ; +:VPSHUFHW YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_WIG); byte=0x70; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpshufhw_avx2( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSHUFLW 4-423 PAGE 1543 LINE 80035 +define pcodeop vpshuflw_avx2 ; +:VPSHUFLW YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x70; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpshuflw_avx2( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80278 +define pcodeop vpsignb_avx2 ; +:VPSIGNB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x08; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsignb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80281 +define pcodeop vpsignw_avx2 ; +:VPSIGNW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x09; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsignw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSIGNB/PSIGNW/PSIGND 4-427 PAGE 1547 LINE 80284 +define pcodeop vpsignd_avx2 ; +:VPSIGND YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x0A; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsignd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSLLDQ 4-431 PAGE 1551 LINE 80488 +define pcodeop vpslldq_avx2 ; +:VPSLLDQ vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x73; reg_opcode=7 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpslldq_avx2( YmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80638 +define pcodeop vpsllw_avx2 ; +:VPSLLW YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF1; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsllw_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-433 PAGE 1553 LINE 80641 +:VPSLLW vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x71; reg_opcode=6 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsllw_avx2( YmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-434 PAGE 1554 LINE 80656 +define pcodeop vpslld_avx2 ; +:VPSLLD YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF2; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpslld_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-434 PAGE 1554 LINE 80659 +:VPSLLD vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x72; reg_opcode=6 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpslld_avx2( YmmReg2, imm8:1 ); +} + +# PSLLW/PSLLD/PSLLQ 4-434 PAGE 1554 LINE 80662 +define pcodeop vpsllq_avx2 ; +:VPSLLQ YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF3; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsllq_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSLLW/PSLLD/PSLLQ 4-434 PAGE 1554 LINE 80664 +:VPSLLQ vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x73; reg_opcode=6 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsllq_avx2( YmmReg2, imm8:1 ); +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81317 +define pcodeop vpsraw_avx2 ; +:VPSRAW YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE1; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsraw_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81320 +:VPSRAW vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x71; reg_opcode=4 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsraw_avx2( YmmReg2, imm8:1 ); +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81323 +define pcodeop vpsrad_avx2 ; +:VPSRAD YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE2; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsrad_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSRAW/PSRAD/PSRAQ 4-445 PAGE 1565 LINE 81326 +:VPSRAD vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x72; reg_opcode=4 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsrad_avx2( YmmReg2, imm8:1 ); +} + +# PSRLDQ 4-455 PAGE 1575 LINE 81876 +define pcodeop vpsrldq_avx2 ; +:VPSRLDQ vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x73; reg_opcode=3 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsrldq_avx2( YmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82030 +define pcodeop vpsrlw_avx2 ; +:VPSRLW YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD1; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsrlw_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-457 PAGE 1577 LINE 82033 +:VPSRLW vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x71; reg_opcode=2 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsrlw_avx2( YmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-458 PAGE 1578 LINE 82048 +define pcodeop vpsrld_avx2 ; +:VPSRLD YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD2; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsrld_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-458 PAGE 1578 LINE 82051 +:VPSRLD vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x72; reg_opcode=2 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsrld_avx2( YmmReg2, imm8:1 ); +} + +# PSRLW/PSRLD/PSRLQ 4-458 PAGE 1578 LINE 82054 +define pcodeop vpsrlq_avx2 ; +:VPSRLQ YmmReg1, vexVVVV_YmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD3; YmmReg1 ... & XmmReg2_m128 +{ + YmmReg1 = vpsrlq_avx2( vexVVVV_YmmReg, XmmReg2_m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSRLW/PSRLD/PSRLQ 4-458 PAGE 1578 LINE 82056 +:VPSRLQ vexVVVV_YmmReg, YmmReg2, imm8 is $(VEX_NDD) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x73; reg_opcode=2 & (mod=0x3 & YmmReg2); imm8 +{ + vexVVVV_YmmReg = vpsrlq_avx2( YmmReg2, imm8:1 ); +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82696 +define pcodeop vpsubb_avx2 ; +:VPSUBB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82698 +define pcodeop vpsubw_avx2 ; +:VPSUBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xF9; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBB/PSUBW/PSUBD 4-469 PAGE 1589 LINE 82700 +define pcodeop vpsubd_avx2 ; +:VPSUBD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xFA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBQ 4-476 PAGE 1596 LINE 83104 +define pcodeop vpsubq_avx2 ; +:VPSUBQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xFB; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBSB/PSUBSW 4-479 PAGE 1599 LINE 83264 +define pcodeop vpsubsb_avx2 ; +:VPSUBSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubsb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBSB/PSUBSW 4-479 PAGE 1599 LINE 83267 +define pcodeop vpsubsw_avx2 ; +:VPSUBSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xE9; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubsw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBUSB/PSUBUSW 4-483 PAGE 1603 LINE 83504 +define pcodeop vpsubusb_avx2 ; +:VPSUBUSB YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubusb_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PSUBUSB/PSUBUSW 4-483 PAGE 1603 LINE 83507 +define pcodeop vpsubusw_avx2 ; +:VPSUBUSW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xD9; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsubusw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83940 +define pcodeop vpunpckhbw_avx2 ; +:VPUNPCKHBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x68; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpckhbw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83942 +define pcodeop vpunpckhwd_avx2 ; +:VPUNPCKHWD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x69; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpckhwd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83944 +define pcodeop vpunpckhdq_avx2 ; +:VPUNPCKHDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x6A; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpckhdq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ/PUNPCKHQDQ 4-491 PAGE 1611 LINE 83946 +define pcodeop vpunpckhqdq_avx2 ; +:VPUNPCKHQDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x6D; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpckhqdq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84541 +define pcodeop vpunpcklbw_avx2 ; +:VPUNPCKLBW YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x60; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpcklbw_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84544 +define pcodeop vpunpcklwd_avx2 ; +:VPUNPCKLWD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x61; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpcklwd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84547 +define pcodeop vpunpckldq_avx2 ; +:VPUNPCKLDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x62; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpckldq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ/PUNPCKLQDQ 4-501 PAGE 1621 LINE 84550 +define pcodeop vpunpcklqdq_avx2 ; +:VPUNPCKLQDQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x6C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpunpcklqdq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# PXOR 4-518 PAGE 1638 LINE 85497 +define pcodeop vpxor_avx2 ; +:VPXOR YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0xEF; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpxor_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VEXTRACTI128/VEXTRACTI32x4/VEXTRACTI64x2/VEXTRACTI32x8/VEXTRACTI64x4 5-106 PAGE 1930 LINE 99432 +define pcodeop vextracti128_avx2 ; +:VEXTRACTI128 XmmReg2_m128, YmmReg1, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0); byte=0x39; YmmReg1 ... & XmmReg2_m128; imm8 +{ + XmmReg2_m128 = vextracti128_avx2( YmmReg1, imm8:1 ); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106903 +# INFO mnemonic VGATHERDPD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908 +# INFO mnemonic VGATHERQPD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106913 +# INFO mnemonic VGATHERDPD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918 +# INFO mnemonic VGATHERQPD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107130 +# INFO mnemonic VGATHERDPS was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135 +# INFO mnemonic VGATHERQPS was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107140 +# INFO mnemonic VGATHERDPS was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145 +# INFO mnemonic VGATHERQPS was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107884 +# INFO mnemonic VPGATHERDD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888 +# INFO mnemonic VPGATHERQD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107892 +# INFO mnemonic VPGATHERDD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896 +# INFO mnemonic VPGATHERQD was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108234 +# INFO mnemonic VPGATHERDQ was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238 +# INFO mnemonic VPGATHERQQ was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108242 +# INFO mnemonic VPGATHERDQ was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246 +# INFO mnemonic VPGATHERQQ was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4 5-314 PAGE 2138 LINE 109927 +# INFO mnemonic VINSERTI128 was found in ../../../Processors/x86/data/languages/avx2_manual.sinc + +# VPBLENDD 5-321 PAGE 2145 LINE 110309 +define pcodeop vpblendd_avx2 ; +:VPBLENDD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x02; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + local tmp:16 = vpblendd_avx2( vexVVVV_XmmReg, XmmReg2_m128, imm8:1 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPBLENDD 5-321 PAGE 2145 LINE 110312 +:VPBLENDD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x02; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpblendd_avx2( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110776 +define pcodeop vpbroadcastb_avx2 ; +:VPBROADCASTB XmmReg1, XmmReg2_m8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x78; (XmmReg1 & YmmReg1) ... & XmmReg2_m8 +{ + local tmp:16 = vpbroadcastb_avx2( XmmReg2_m8 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110778 +:VPBROADCASTB YmmReg1, XmmReg2_m8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x78; YmmReg1 ... & XmmReg2_m8 +{ + YmmReg1 = vpbroadcastb_avx2( XmmReg2_m8 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110787 +define pcodeop vpbroadcastw_avx2 ; +:VPBROADCASTW XmmReg1, XmmReg2_m16 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x79; (XmmReg1 & YmmReg1) ... & XmmReg2_m16 +{ + local tmp:16 = vpbroadcastw_avx2( XmmReg2_m16 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110789 +:VPBROADCASTW YmmReg1, XmmReg2_m16 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x79; YmmReg1 ... & XmmReg2_m16 +{ + YmmReg1 = vpbroadcastw_avx2( XmmReg2_m16 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110800 +define pcodeop vpbroadcastd_avx2 ; +:VPBROADCASTD XmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x58; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vpbroadcastd_avx2( XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110802 +:VPBROADCASTD YmmReg1, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x58; YmmReg1 ... & XmmReg2_m32 +{ + YmmReg1 = vpbroadcastd_avx2( XmmReg2_m32 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110813 +define pcodeop vpbroadcastq_avx2 ; +:VPBROADCASTQ XmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x59; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vpbroadcastq_avx2( XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPBROADCAST 5-331 PAGE 2155 LINE 110815 +:VPBROADCASTQ YmmReg1, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x59; YmmReg1 ... & XmmReg2_m64 +{ + YmmReg1 = vpbroadcastq_avx2( XmmReg2_m64 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPBROADCAST 5-332 PAGE 2156 LINE 110843 +define pcodeop vbroadcasti128_avx2 ; +:VBROADCASTI128 YmmReg1, m128 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0); byte=0x5A; YmmReg1 ... & m128 +{ + YmmReg1 = vbroadcasti128_avx2( m128 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERM2I128 5-360 PAGE 2184 LINE 112312 +define pcodeop vperm2i128_avx2 ; +:VPERM2I128 YmmReg1, vexVVVV_YmmReg, YmmReg2_m256, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x46; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vperm2i128_avx2( vexVVVV_YmmReg, YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMD/VPERMW 5-362 PAGE 2186 LINE 112405 +define pcodeop vpermd_avx2 ; +:VPERMD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x36; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpermd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMPD 5-381 PAGE 2205 LINE 113452 +define pcodeop vpermpd_avx2 ; +:VPERMPD YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x01; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpermpd_avx2( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMPS 5-384 PAGE 2208 LINE 113633 +define pcodeop vpermps_avx2 ; +:VPERMPS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x16; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpermps_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPERMQ 5-387 PAGE 2211 LINE 113768 +define pcodeop vpermq_avx2 ; +:VPERMQ YmmReg1, YmmReg2_m256, imm8 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x00; YmmReg1 ... & YmmReg2_m256; imm8 +{ + YmmReg1 = vpermq_avx2( YmmReg2_m256, imm8:1 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114262 +define pcodeop vpmaskmovd_avx2 ; +:VPMASKMOVD XmmReg1, vexVVVV_XmmReg, m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x8C; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vpmaskmovd_avx2( vexVVVV_XmmReg, m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114264 +:VPMASKMOVD YmmReg1, vexVVVV_YmmReg, m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x8C; YmmReg1 ... & m256 +{ + YmmReg1 = vpmaskmovd_avx2( vexVVVV_YmmReg, m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114266 +define pcodeop vpmaskmovq_avx2 ; +:VPMASKMOVQ XmmReg1, vexVVVV_XmmReg, m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x8C; (XmmReg1 & YmmReg1) ... & m128 +{ + local tmp:16 = vpmaskmovq_avx2( vexVVVV_XmmReg, m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114268 +:VPMASKMOVQ YmmReg1, vexVVVV_YmmReg, m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x8C; YmmReg1 ... & m256 +{ + YmmReg1 = vpmaskmovq_avx2( vexVVVV_YmmReg, m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114270 +:VPMASKMOVD m128, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x8E; XmmReg1 ... & m128 +{ + m128 = vpmaskmovd_avx2( vexVVVV_XmmReg, XmmReg1 ); +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114272 +:VPMASKMOVD m256, vexVVVV_YmmReg, YmmReg1 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x8E; YmmReg1 ... & m256 +{ + m256 = vpmaskmovd_avx2( vexVVVV_YmmReg, YmmReg1 ); +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114274 +:VPMASKMOVQ m128, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x8E; XmmReg1 ... & m128 +{ + m128 = vpmaskmovq_avx2( vexVVVV_XmmReg, XmmReg1 ); +} + +# VPMASKMOV 5-397 PAGE 2221 LINE 114276 +:VPMASKMOVQ m256, vexVVVV_YmmReg, YmmReg1 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x8E; YmmReg1 ... & m256 +{ + m256 = vpmaskmovq_avx2( vexVVVV_YmmReg, YmmReg1 ); +} + +# VPSLLVW/VPSLLVD/VPSLLVQ 5-445 PAGE 2269 LINE 116620 +define pcodeop vpsllvd_avx2 ; +:VPSLLVD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x47; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsllvd_avx2( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPSLLVW/VPSLLVD/VPSLLVQ 5-445 PAGE 2269 LINE 116623 +define pcodeop vpsllvq_avx2 ; +:VPSLLVQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x47; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsllvq_avx2( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPSLLVW/VPSLLVD/VPSLLVQ 5-445 PAGE 2269 LINE 116626 +:VPSLLVD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x47; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsllvd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPSLLVW/VPSLLVD/VPSLLVQ 5-445 PAGE 2269 LINE 116629 +:VPSLLVQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x47; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsllvq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPSRAVW/VPSRAVD/VPSRAVQ 5-450 PAGE 2274 LINE 116874 +define pcodeop vpsravd_avx2 ; +:VPSRAVD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x46; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsravd_avx2( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPSRAVW/VPSRAVD/VPSRAVQ 5-450 PAGE 2274 LINE 116877 +:VPSRAVD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x46; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsravd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPSRLVW/VPSRLVD/VPSRLVQ 5-455 PAGE 2279 LINE 117139 +define pcodeop vpsrlvd_avx2 ; +:VPSRLVD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x45; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrlvd_avx2( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPSRLVW/VPSRLVD/VPSRLVQ 5-455 PAGE 2279 LINE 117142 +define pcodeop vpsrlvq_avx2 ; +:VPSRLVQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x45; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vpsrlvq_avx2( vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VPSRLVW/VPSRLVD/VPSRLVQ 5-455 PAGE 2279 LINE 117145 +:VPSRLVD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x45; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsrlvd_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPSRLVW/VPSRLVD/VPSRLVQ 5-455 PAGE 2279 LINE 117148 +:VPSRLVQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x45; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vpsrlvq_avx2( vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2_manual.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2_manual.sinc new file mode 100644 index 00000000..221b22ba --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx2_manual.sinc @@ -0,0 +1,252 @@ +# VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4 5-314 PAGE 2138 LINE 109785 +define pcodeop vinserti128 ; +:VINSERTI128 YmmReg1, vexVVVV_YmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x38; YmmReg1 ... & XmmReg2_m128; imm8 & imm8_0 { + local tmp:16 = XmmReg2_m128; + + # ignoring all but the least significant bit + if (imm8_0:1 == 0) goto ; + if (imm8_0:1 == 1) goto ; + + + YmmReg1[0,128] = tmp; + YmmReg1[128,128] = vexVVVV_YmmReg[128,128]; + goto ; + + + YmmReg1[0,128] = vexVVVV_YmmReg[0,128]; + YmmReg1[128,128] = tmp; + + +} + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106903 +define pcodeop vgatherdpd ; +:VGATHERDPD XmmReg1, q_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x92; (XmmReg1 & YmmReg1) ... & q_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vgatherdpd(XmmReg1, q_vm32x, vexVVVV_XmmReg); + local tmp:16 = vgatherdpd(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908 +@ifdef IA64 +define pcodeop vgatherqpd ; +:VGATHERQPD XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & q_vm64x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vgatherqpd(XmmReg1, q_vm64x, vexVVVV_XmmReg); + local tmp:16 = vgatherqpd(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106913 +:VGATHERDPD YmmReg1, q_vm32x, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x92; YmmReg1 ... & q_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vgatherdpd(YmmReg1, q_vm32x, vexVVVV_YmmReg); + YmmReg1 = vgatherdpd(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} + +# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918 +@ifdef IA64 +:VGATHERQPD YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x93; YmmReg1 ... & q_vm64y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vgatherqpd(YmmReg1, q_vm64y, vexVVVV_YmmReg); + YmmReg1 = vgatherqpd(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} +@endif + + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107130 +define pcodeop vgatherdps ; +:VGATHERDPS XmmReg1, d_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x92; (XmmReg1 & YmmReg1) ... & d_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vgatherdps(XmmReg1, d_vm32x, vexVVVV_XmmReg); + local tmp:16 = vgatherdps(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135 +@ifdef IA64 +define pcodeop vgatherqps ; +:VGATHERQPS XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vgatherqps(XmmReg1, d_vm64x, vexVVVV_XmmReg); + local tmp:16 = vgatherqps(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107140 +:VGATHERDPS YmmReg1, d_vm32y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x92; YmmReg1 ... & d_vm32y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vgatherdps(YmmReg1, d_vm32y, vexVVVV_YmmReg); + YmmReg1 = vgatherdps(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} + +# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145 +@ifdef IA64 +:VGATHERQPS XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vgatherqps(XmmReg1, d_vm64y, vexVVVV_XmmReg); + XmmReg1 = vgatherqps(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(XmmReg1); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + +# PCMPEQQ 4-250 PAGE 1370 LINE 71171 +:VPCMPEQQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x29; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1[0,64] = zext(vexVVVV_YmmReg[0,64] == YmmReg2_m256[0,64]) * 0xffffffffffffffff:8; + YmmReg1[64,64] = zext(vexVVVV_YmmReg[64,64] == YmmReg2_m256[64,64]) * 0xffffffffffffffff:8; + YmmReg1[128,64] = zext(vexVVVV_YmmReg[128,64] == YmmReg2_m256[128,64]) * 0xffffffffffffffff:8; + YmmReg1[192,64] = zext(vexVVVV_YmmReg[192,64] == YmmReg2_m256[192,64]) * 0xffffffffffffffff:8; + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107884 +define pcodeop vpgatherdd ; +:VPGATHERDD XmmReg1, d_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x90; (XmmReg1 & YmmReg1) ... & d_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vpgatherdd(XmmReg1, d_vm32x, vexVVVV_XmmReg); + local tmp:16 = vpgatherdd(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888 +@ifdef IA64 +define pcodeop vpgatherqd ; +:VPGATHERQD XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vpgatherqd(XmmReg1, d_vm64x, vexVVVV_XmmReg); + local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107892 +:VPGATHERDD YmmReg1, d_vm32y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x90; YmmReg1 ... & d_vm32y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vpgatherdd(YmmReg1, d_vm32y, vexVVVV_YmmReg); + YmmReg1 = vpgatherdd(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} + +# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896 +@ifdef IA64 +:VPGATHERQD XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vpgatherqd(XmmReg1, d_vm64y, vexVVVV_XmmReg); + local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108234 +define pcodeop vpgatherdq ; +:VPGATHERDQ XmmReg1, q_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x90; (XmmReg1 & YmmReg1) ... & q_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vpgatherdq(XmmReg1, q_vm32x, vexVVVV_XmmReg); + local tmp:16 = vpgatherdq(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238 +@ifdef IA64 +define pcodeop vpgatherqq ; +:VPGATHERQQ XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & q_vm64x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# XmmReg1 = vpgatherqq(XmmReg1, q_vm64x, vexVVVV_XmmReg); + local tmp:16 = vpgatherqq(XmmReg1, vexVVVV_XmmReg); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) + vexVVVV_XmmReg = 0; +} +@endif + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108242 +:VPGATHERDQ YmmReg1, q_vm32x, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x90; YmmReg1 ... & q_vm32x { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vpgatherdq(YmmReg1, q_vm32x, vexVVVV_YmmReg); + YmmReg1 = vpgatherdq(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} + +# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246 +@ifdef IA64 +:VPGATHERQQ YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x91; YmmReg1 ... & q_vm64y { +# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now +# YmmReg1 = vpgatherqq(YmmReg1, q_vm64y, vexVVVV_YmmReg); + YmmReg1 = vpgatherqq(YmmReg1, vexVVVV_YmmReg); + # TODO ZmmReg1 = zext(YmmReg1) + vexVVVV_YmmReg = 0; +} +@endif + + +# PMOVMSKB 4-338 PAGE 1458 LINE 75655 +:VPMOVMSKB Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD7; Reg32 & (mod=0x3 & YmmReg2) & check_Reg32_dest +{ + local byte_mask:4 = 0:4; + byte_mask[0,1] = YmmReg2[7,1]; + byte_mask[1,1] = YmmReg2[15,1]; + byte_mask[2,1] = YmmReg2[23,1]; + byte_mask[3,1] = YmmReg2[31,1]; + byte_mask[4,1] = YmmReg2[39,1]; + byte_mask[5,1] = YmmReg2[47,1]; + byte_mask[6,1] = YmmReg2[55,1]; + byte_mask[7,1] = YmmReg2[63,1]; + byte_mask[8,1] = YmmReg2[71,1]; + byte_mask[9,1] = YmmReg2[79,1]; + byte_mask[10,1] = YmmReg2[87,1]; + byte_mask[11,1] = YmmReg2[95,1]; + byte_mask[12,1] = YmmReg2[103,1]; + byte_mask[13,1] = YmmReg2[111,1]; + byte_mask[14,1] = YmmReg2[119,1]; + byte_mask[15,1] = YmmReg2[127,1]; + byte_mask[16,1] = YmmReg2[135,1]; + byte_mask[17,1] = YmmReg2[143,1]; + byte_mask[18,1] = YmmReg2[151,1]; + byte_mask[19,1] = YmmReg2[159,1]; + byte_mask[20,1] = YmmReg2[167,1]; + byte_mask[21,1] = YmmReg2[175,1]; + byte_mask[22,1] = YmmReg2[183,1]; + byte_mask[23,1] = YmmReg2[191,1]; + byte_mask[24,1] = YmmReg2[199,1]; + byte_mask[25,1] = YmmReg2[207,1]; + byte_mask[26,1] = YmmReg2[215,1]; + byte_mask[27,1] = YmmReg2[223,1]; + byte_mask[28,1] = YmmReg2[231,1]; + byte_mask[29,1] = YmmReg2[239,1]; + byte_mask[30,1] = YmmReg2[247,1]; + byte_mask[31,1] = YmmReg2[255,1]; + Reg32 = zext(byte_mask); + build check_Reg32_dest; +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/avx_manual.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx_manual.sinc new file mode 100644 index 00000000..2c235ab4 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/avx_manual.sinc @@ -0,0 +1,287 @@ +# MOVAPD 4-45 PAGE 1165 LINE 60844 +:VMOVAPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x28; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + YmmReg1 = zext(XmmReg2_m128); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVAPD 4-45 PAGE 1165 LINE 60846 +:VMOVAPD XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; mod=3 & XmmReg1 & (XmmReg2 & YmmReg2) +{ + YmmReg2 = zext(XmmReg1); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVAPD 4-45 PAGE 1165 LINE 60846 +:VMOVAPD m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; XmmReg1 ... & m128 +{ + m128 = XmmReg1; + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVAPD 4-45 PAGE 1165 LINE 60848 +:VMOVAPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x28; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = YmmReg2_m256; + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVAPD 4-45 PAGE 1165 LINE 60850 +:VMOVAPD YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = YmmReg1; + # TODO ZmmReg2 = zext(YmmReg2) +} + +# MOVAPS 4-49 PAGE 1169 LINE 61039 +:VMOVAPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x28; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + YmmReg1 = zext(XmmReg2_m128); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVAPS 4-49 PAGE 1169 LINE 61041 +:VMOVAPS XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; mod=3 & XmmReg1 & (XmmReg2 & YmmReg2) +{ + YmmReg2 = zext(XmmReg1); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVAPS 4-49 PAGE 1169 LINE 61041 +:VMOVAPS m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; XmmReg1 ... & m128 +{ + m128 = XmmReg1; + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVAPS 4-49 PAGE 1169 LINE 61043 +:VMOVAPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x28; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = YmmReg2_m256; + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVAPS 4-49 PAGE 1169 LINE 61045 +:VMOVAPS YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = YmmReg1; + # TODO ZmmReg2 = zext(YmmReg2) +} + +# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61667 +# Note: we do not model the exception generated if VMOVDQA is used with a memory operand which is not 16-bye aligned +:VMOVDQA XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + YmmReg1 = zext(XmmReg2_m128); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61669 +:VMOVDQA XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 & (mod = 3 & XmmReg2 & YmmReg2) +{ + YmmReg2 = zext(XmmReg1); + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61669 +:VMOVDQA m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 ... & m128 +{ + m128 = XmmReg1; + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61671 +:VMOVDQA YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = YmmReg2_m256; + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61673 +:VMOVDQA YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = YmmReg1; + # TODO ZmmReg2 = zext(YmmReg2) +} + +# MOVSD 4-111 PAGE 1231 LINE 63970 +:VMOVSD XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x10; XmmReg1 & YmmReg1 & (mod=0x3 & XmmReg2) +{ + local tmpa:8 = XmmReg2[0,64]; + local tmpb:8 = vexVVVV_XmmReg[64,64]; + YmmReg1 = 0; + XmmReg1[0,64] = tmpa; + XmmReg1[64,64] = tmpb; + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSD 4-111 PAGE 1231 LINE 63972 +:VMOVSD XmmReg1, m64 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & m64 +{ + YmmReg1[0,64] = m64; + YmmReg1[64,64] = 0; + # TODO ZmmReg1 = zext(XmmReg1) +} + +# MOVSD 4-111 PAGE 1231 LINE 63974 +:VMOVSD XmmReg2, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x11; XmmReg1 & (mod=0x3 & (XmmReg2 & YmmReg2)) +{ + local tmpa:8 = XmmReg1[0,64]; + local tmpb:8 = vexVVVV_XmmReg[64,64]; + YmmReg2 = 0; + XmmReg2[0,64] = tmpa; + XmmReg2[64,64] = tmpb; + # TODO ZmmReg2 = zext(XmmReg2) +} + +# MOVSD 4-111 PAGE 1231 LINE 63976 +:VMOVSD m64, XmmReg1 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m64 +{ + m64 = XmmReg1[0,64]; +} + +# MOVUPS 4-130 PAGE 1250 LINE 64872 +:VMOVUPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = XmmReg2_m128; + YmmReg1[0,128] = tmp; + YmmReg1[128,64] = 0; + YmmReg1[192,64] = 0; +} + +# MOVUPS 4-130 PAGE 1250 LINE 64874 +# break this into two constructors to handle the zext for the register destination case +:VMOVUPS XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 & (mod = 3 & XmmReg2 & YmmReg2) +{ + XmmReg2 = XmmReg1; + YmmReg2 = zext(XmmReg2); +} + +# MOVUPS 4-130 PAGE 1250 LINE 64874 +:VMOVUPS m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m128 +{ + m128 = XmmReg1; +} + +# MOVUPS 4-130 PAGE 1250 LINE 64876 +:VMOVUPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x10; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = YmmReg2_m256; + # TODO ZmmReg1 = zext(YmmReg1) +} + +# MOVUPS 4-130 PAGE 1250 LINE 64878 +# TODO in general, what do we do with the zext of only the register case; needs investigation +:VMOVUPS YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg2_m256 = YmmReg1; +} + +# PCMPEQQ 4-250 PAGE 1370 LINE 71169 +:VPCMPEQQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x29; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1[0,64] = zext(vexVVVV_XmmReg[0,64] == XmmReg2_m128[0,64]) * 0xffffffffffffffff:8; + XmmReg1[64,64] = zext(vexVVVV_XmmReg[64,64] == XmmReg2_m128[64,64]) * 0xffffffffffffffff:8; + YmmReg1 = zext(XmmReg1); + # TODO ZmmReg1 = zext(XmmReg1) +} + + +# PMOVMSKB 4-338 PAGE 1458 LINE 75651 +:VPMOVMSKB Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD7; Reg32 & (mod=0x3 & XmmReg2) & check_Reg32_dest +{ + local byte_mask:2 = 0:2; + byte_mask[0,1] = XmmReg2[7,1]; + byte_mask[1,1] = XmmReg2[15,1]; + byte_mask[2,1] = XmmReg2[23,1]; + byte_mask[3,1] = XmmReg2[31,1]; + byte_mask[4,1] = XmmReg2[39,1]; + byte_mask[5,1] = XmmReg2[47,1]; + byte_mask[6,1] = XmmReg2[55,1]; + byte_mask[7,1] = XmmReg2[63,1]; + byte_mask[8,1] = XmmReg2[71,1]; + byte_mask[9,1] = XmmReg2[79,1]; + byte_mask[10,1] = XmmReg2[87,1]; + byte_mask[11,1] = XmmReg2[95,1]; + byte_mask[12,1] = XmmReg2[103,1]; + byte_mask[13,1] = XmmReg2[111,1]; + byte_mask[14,1] = XmmReg2[119,1]; + byte_mask[15,1] = XmmReg2[127,1]; + Reg32 = zext(byte_mask); + build check_Reg32_dest; +} + +# VZEROALL 5-563 PAGE 2387 LINE 122405 +:VZEROALL is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77 +{ + YMM0[0,64] = 0:8; YMM0[64,64] = 0:8; YMM0[128,64] = 0:8; YMM0[192,64] = 0:8; + YMM1[0,64] = 0:8; YMM1[64,64] = 0:8; YMM1[128,64] = 0:8; YMM1[192,64] = 0:8; + YMM2[0,64] = 0:8; YMM2[64,64] = 0:8; YMM2[128,64] = 0:8; YMM2[192,64] = 0:8; + YMM3[0,64] = 0:8; YMM3[64,64] = 0:8; YMM3[128,64] = 0:8; YMM3[192,64] = 0:8; + YMM4[0,64] = 0:8; YMM4[64,64] = 0:8; YMM4[128,64] = 0:8; YMM4[192,64] = 0:8; + YMM5[0,64] = 0:8; YMM5[64,64] = 0:8; YMM5[128,64] = 0:8; YMM5[192,64] = 0:8; + YMM6[0,64] = 0:8; YMM6[64,64] = 0:8; YMM6[128,64] = 0:8; YMM6[192,64] = 0:8; + YMM7[0,64] = 0:8; YMM7[64,64] = 0:8; YMM7[128,64] = 0:8; YMM7[192,64] = 0:8; + #TODO: Zmm +} + +@ifdef IA64 +:VZEROALL is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77 +{ + YMM0[0,64] = 0:8; YMM0[64,64] = 0:8; YMM0[128,64] = 0:8; YMM0[192,64] = 0:8; + YMM1[0,64] = 0:8; YMM1[64,64] = 0:8; YMM1[128,64] = 0:8; YMM1[192,64] = 0:8; + YMM2[0,64] = 0:8; YMM2[64,64] = 0:8; YMM2[128,64] = 0:8; YMM2[192,64] = 0:8; + YMM3[0,64] = 0:8; YMM3[64,64] = 0:8; YMM3[128,64] = 0:8; YMM3[192,64] = 0:8; + YMM4[0,64] = 0:8; YMM4[64,64] = 0:8; YMM4[128,64] = 0:8; YMM4[192,64] = 0:8; + YMM5[0,64] = 0:8; YMM5[64,64] = 0:8; YMM5[128,64] = 0:8; YMM5[192,64] = 0:8; + YMM6[0,64] = 0:8; YMM6[64,64] = 0:8; YMM6[128,64] = 0:8; YMM6[192,64] = 0:8; + YMM7[0,64] = 0:8; YMM7[64,64] = 0:8; YMM7[128,64] = 0:8; YMM7[192,64] = 0:8; + YMM8[0,64] = 0:8; YMM8[64,64] = 0:8; YMM8[128,64] = 0:8; YMM8[192,64] = 0:8; + YMM9[0,64] = 0:8; YMM9[64,64] = 0:8; YMM9[128,64] = 0:8; YMM9[192,64] = 0:8; + YMM10[0,64] = 0:8; YMM10[64,64] = 0:8; YMM10[128,64] = 0:8; YMM10[192,64] = 0:8; + YMM11[0,64] = 0:8; YMM11[64,64] = 0:8; YMM11[128,64] = 0:8; YMM11[192,64] = 0:8; + YMM12[0,64] = 0:8; YMM12[64,64] = 0:8; YMM12[128,64] = 0:8; YMM12[192,64] = 0:8; + YMM13[0,64] = 0:8; YMM13[64,64] = 0:8; YMM13[128,64] = 0:8; YMM13[192,64] = 0:8; + YMM14[0,64] = 0:8; YMM14[64,64] = 0:8; YMM14[128,64] = 0:8; YMM14[192,64] = 0:8; + YMM15[0,64] = 0:8; YMM15[64,64] = 0:8; YMM15[128,64] = 0:8; YMM15[192,64] = 0:8; + #TODO: Zmm +} +@endif + +# VZEROUPPER 5-565 PAGE 2389 LINE 122480 +:VZEROUPPER is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77 +{ + YMM0[128,64] = 0:8; YMM0[192,64] = 0:8; + YMM1[128,64] = 0:8; YMM1[192,64] = 0:8; + YMM2[128,64] = 0:8; YMM2[192,64] = 0:8; + YMM3[128,64] = 0:8; YMM3[192,64] = 0:8; + YMM4[128,64] = 0:8; YMM4[192,64] = 0:8; + YMM5[128,64] = 0:8; YMM5[192,64] = 0:8; + YMM6[128,64] = 0:8; YMM6[192,64] = 0:8; + YMM7[128,64] = 0:8; YMM7[192,64] = 0:8; + #TODO: Zmm +} + +@ifdef IA64 +:VZEROUPPER is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77 +{ + YMM0[128,64] = 0:8; YMM0[192,64] = 0:8; + YMM1[128,64] = 0:8; YMM1[192,64] = 0:8; + YMM2[128,64] = 0:8; YMM2[192,64] = 0:8; + YMM3[128,64] = 0:8; YMM3[192,64] = 0:8; + YMM4[128,64] = 0:8; YMM4[192,64] = 0:8; + YMM5[128,64] = 0:8; YMM5[192,64] = 0:8; + YMM6[128,64] = 0:8; YMM6[192,64] = 0:8; + YMM7[128,64] = 0:8; YMM7[192,64] = 0:8; + YMM8[128,64] = 0:8; YMM8[192,64] = 0:8; + YMM9[128,64] = 0:8; YMM9[192,64] = 0:8; + YMM10[128,64] = 0:8; YMM10[192,64] = 0:8; + YMM11[128,64] = 0:8; YMM11[192,64] = 0:8; + YMM12[128,64] = 0:8; YMM12[192,64] = 0:8; + YMM13[128,64] = 0:8; YMM13[192,64] = 0:8; + YMM14[128,64] = 0:8; YMM14[192,64] = 0:8; + YMM15[128,64] = 0:8; YMM15[192,64] = 0:8; + #TODO: Zmm +} +@endif + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi1.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi1.sinc new file mode 100644 index 00000000..561711ff --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi1.sinc @@ -0,0 +1,195 @@ +macro tzcntflags(input, output) { + ZF = (output == 0); + CF = (input == 0); + # OF, SF, PF, AF are undefined +} + + +#### +#### BMI1 instructions +#### + +# TODO remove ANDN from ia.sinc ????? +:ANDN Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf2; Reg32 ... & check_Reg32_dest ... &rm32 +{ + Reg32 = ~(vexVVVV_r32) & rm32; + resultflags(Reg32); + OF = 0; + CF = 0; + build check_Reg32_dest; +} + +@ifdef IA64 +# TODO remove ANDN from ia.sinc ????? +:ANDN Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf2; Reg64 ... & rm64 +{ + Reg64 = ~(vexVVVV_r64) & rm64; + resultflags(Reg64); + OF = 0; + CF = 0; +} +@endif + + +:BEXTR Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32 +{ + sourceTmp:1 = vexVVVV_r32[0,8]; + lengthTmp:1 = vexVVVV_r32[8,8]; + + Reg32 = (rm32 >> sourceTmp) & ((1 << lengthTmp) - 1); + build check_Reg32_dest; + + ZF = (Reg32 == 0); + OF = 0; + CF = 0; + # AF, SF, and PF are undefined +} + +@ifdef IA64 +:BEXTR Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64 +{ + sourceTmp:1 = vexVVVV_r64[0,8]; + lengthTmp:1 = vexVVVV_r64[8,8]; + + Reg64 = (rm64 >> sourceTmp) & ((1 << lengthTmp) - 1); + + ZF = (Reg64 == 0); + OF = 0; + CF = 0; + # AF, SF, and PF are undefined +} +@endif + + +:BLSI vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=3 ... & check_vexVVVV_r32_dest ... & rm32 +{ + vexVVVV_r32 = -rm32 & rm32; + build check_vexVVVV_r32_dest; + + ZF = (vexVVVV_r32 == 0); + SF = (vexVVVV_r32 s< 0); + CF = (rm32 != 0); + OF = 0; + # AF and PF are undefined +} + +@ifdef IA64 +:BLSI vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=3 ... & rm64 +{ + vexVVVV_r64 = -rm64 & rm64; + + ZF = (vexVVVV_r64 == 0); + SF = (vexVVVV_r64 s< 0); + CF = (rm64 != 0); + OF = 0; + # AF and PF are undefined +} +@endif + + +:BLSMSK vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=2 ... & check_vexVVVV_r32_dest ... &rm32 +{ + CF = (rm32 == 0); + vexVVVV_r32 = (rm32 - 1) ^ rm32; + + SF = (vexVVVV_r32 s< 0); + build check_vexVVVV_r32_dest; + ZF = 0; + OF = 0; + # AF and PF are undefined +} + +@ifdef IA64 +:BLSMSK vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=2 ... & rm64 +{ + CF = (rm64 == 0); + vexVVVV_r64 = (rm64 - 1) ^ rm64; + + SF = (vexVVVV_r64 s< 0); + ZF = 0; + OF = 0; + # AF and PF are undefined +} +@endif + + +:BLSR vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=1 ... & check_vexVVVV_r32_dest ... &rm32 +{ + CF = (rm32 == 0); + vexVVVV_r32 = (rm32 - 1) & rm32; + build check_vexVVVV_r32_dest; + + ZF = (vexVVVV_r32 == 0); + SF = (vexVVVV_r32 s< 0); + OF = 0; + # AF and PF are undefined +} + +@ifdef IA64 +:BLSR vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=1 ... & rm64 +{ + CF = (rm64 == 0); + vexVVVV_r64 = (rm64 - 1) & rm64; + + ZF = (vexVVVV_r64 == 0); + SF = (vexVVVV_r64 s< 0); + OF = 0; + # AF and PF are undefined +} +@endif + +# not as documented in manual; requires PRE_66 prefix to get 16-bit operation +:TZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg16 ... & rm16 { + + countTmp:2 = 0; + inputTmp:2 = rm16; + + + if ((inputTmp & 1) != 0) goto ; + + countTmp = countTmp + 1; + inputTmp = (inputTmp >> 1) | 0x8000; + goto ; + + + tzcntflags(rm16, countTmp); + Reg16 = countTmp; + +} + +:TZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg32 ... & check_Reg32_dest ... & rm32 { + + countTmp:4 = 0; + inputTmp:4 = rm32; + + + if ((inputTmp & 1) != 0) goto ; + + countTmp = countTmp + 1; + inputTmp = (inputTmp >> 1) | 0x80000000; + goto ; + + + tzcntflags(rm32, countTmp); + Reg32 = countTmp; + build check_Reg32_dest; +} + +@ifdef IA64 +:TZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBC; Reg64 ... & rm64 { + + countTmp:8 = 0; + inputTmp:8 = rm64; + + + if ((inputTmp & 1) != 0) goto ; + + countTmp = countTmp + 1; + inputTmp = (inputTmp >> 1) | 0x8000000000000000; + goto ; + + + tzcntflags(rm64, countTmp); + Reg64 = countTmp; +} +@endif diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi2.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi2.sinc new file mode 100644 index 00000000..3ac2841a --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/bmi2.sinc @@ -0,0 +1,209 @@ +#### +#### BMI2 instructions +#### + + +:BZHI Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32 +{ + indexTmp:1 = vexVVVV_r32:1; + + # saturate index amount to 32; operand size or higher does not clear any bits + shift:1 = (indexTmp <= 32) * (32 - indexTmp); + + # clear the upper bits + Reg32 = (rm32 << shift) >> shift; + build check_Reg32_dest; + + ZF = (Reg32 == 0); + SF = (Reg32 s< 0); + CF = indexTmp > 31; + OF = 0; + # AF and PF are undefined +} + +@ifdef IA64 +:BZHI Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64 +{ + indexTmp:1 = vexVVVV_r64:1; + + # saturate index amount to 64; operand size or higher does not clear any bits + shift:1 = (indexTmp <= 64) * (64 - indexTmp); + + # clear the upper bits + Reg64 = (rm64 << shift) >> shift; + + ZF = (Reg64 == 0); + SF = (Reg64 s< 0); + CF = indexTmp > 63; + OF = 0; + # AF and PF are undefined +} +@endif + + +:MULX Reg32, vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf6; Reg32 ... & check_Reg32_dest ... & check_vexVVVV_r32_dest ... & rm32 +{ + temp:8 = zext(EDX) * zext(rm32); + + vexVVVV_r32 = temp:4; + build check_vexVVVV_r32_dest; + Reg32 = temp(4); + build check_Reg32_dest; +} + +@ifdef IA64 +:MULX Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf6; Reg64 ... & rm64 +{ + temp:16 = zext(RDX) * zext(rm64); + + vexVVVV_r64 = temp:8; + Reg64 = temp(8); +} +@endif + + +:PDEP Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32 +{ + sourceTmp:4 = vexVVVV_r32; + + indexTmp:4 = 1; + resultTmp:4 = 0; + + + maskBit:4 = rm32 & indexTmp; + + if (maskBit == 0) goto ; + resultTmp = resultTmp | (maskBit * (sourceTmp & 1)); + sourceTmp = sourceTmp >> 1; + + + indexTmp = indexTmp << 1; + if (indexTmp != 0) goto ; + + Reg32 = resultTmp; + build check_Reg32_dest; +} + +@ifdef IA64 +:PDEP Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64 +{ + sourceTmp:8 = vexVVVV_r64; + + indexTmp:8 = 1; + resultTmp:8 = 0; + + + maskBit:8 = rm64 & indexTmp; + + if (maskBit == 0) goto ; + resultTmp = resultTmp | (maskBit * (sourceTmp & 1)); + sourceTmp = sourceTmp >> 1; + + + indexTmp = indexTmp << 1; + if (indexTmp != 0) goto ; + + Reg64 = resultTmp; +} +@endif + + +:PEXT Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32 +{ + indexTmp:4 = 0x80000000; + resultTmp:4 = 0; + + + maskBit:4 = rm32 & indexTmp; + + if (maskBit == 0) goto ; + resultTmp = (resultTmp << 1) | zext((maskBit & vexVVVV_r32) != 0); + + + indexTmp = indexTmp >> 1; + if (indexTmp != 0) goto ; + + build check_Reg32_dest; + Reg32 = resultTmp; +} + +@ifdef IA64 +:PEXT Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64 +{ + indexTmp:8 = 0x8000000000000000; + resultTmp:8 = 0; + + + maskBit:8 = rm64 & indexTmp; + + if (maskBit == 0) goto ; + resultTmp = (resultTmp << 1) | zext((maskBit & vexVVVV_r64) != 0); + + + indexTmp = indexTmp >> 1; + if (indexTmp != 0) goto ; + + Reg64 = resultTmp; +} +@endif + + +:RORX Reg32, rm32, imm8 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W0); byte=0xf0; Reg32 ... & check_Reg32_dest ... & rm32; imm8 +{ + shiftTmp:1 = (imm8:1 & 0x1F); + + Reg32 = (rm32 >> shiftTmp) | ( rm32 << (32 - shiftTmp)); + build check_Reg32_dest; +} + +@ifdef IA64 +:RORX Reg64, rm64, imm8 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W1); byte=0xf0; Reg64 ... & rm64; imm8 +{ + shiftTmp:1 = (imm8:1 & 0x3F); + + Reg64 = (rm64 >> shiftTmp) | ( rm64 << (64 - shiftTmp)); +} +@endif + + +:SARX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32 +{ + Reg32 = rm32 s>> (vexVVVV_r32 & 0x0000001F); + build check_Reg32_dest; +} + +@ifdef IA64 +:SARX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64 +{ + Reg64 = rm64 s>> (vexVVVV_r64 & 0x000000000000003F); +} +@endif + + +:SHLX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32 +{ + Reg32 = rm32 << (vexVVVV_r32 & 0x0000001F); + build check_Reg32_dest; +} + +@ifdef IA64 +:SHLX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64 +{ + Reg64 = rm64 << (vexVVVV_r64 & 0x000000000000003F); +} +@endif + + +:SHRX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32 +{ + Reg32 = rm32 >> (vexVVVV_r32 & 0x0000001F); + build check_Reg32_dest; +} + +@ifdef IA64 +:SHRX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64 +{ + Reg64 = rm64 >> (vexVVVV_r64 & 0x000000000000003F); +} +@endif + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/cet.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/cet.sinc new file mode 100644 index 00000000..ea707de8 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/cet.sinc @@ -0,0 +1,84 @@ +# +# Instructions based on Intel Control-flow Enforcement Technology Preview +# +# Note: Shadow Stack semantics is not currently implemented correctly in these instructions +# nor in the instructions affected by CET +# + + +define pcodeop ShadowStackPush8B; +define pcodeop ShadowStackPush4B; + +define pcodeop ShadowStackLoad8B; +define pcodeop ShadowStackLoad4B; + +:INCSSPD r32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0xae; reg_opcode=5 & r32 { + SSP = SSP + zext(4 * r32:1); +} +@ifdef IA64 +:INCSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0xae; reg_opcode=5 & r64 { + SSP = SSP + zext(8 * r64:1); +} +@endif + +:RDSSPD r32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r32 { + r32 = SSP:4; +} +@ifdef IA64 +:RDSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r64 { + r64 = SSP; +} +@endif + +:SAVEPREVSSP is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; byte=0xea { + tmp:8 = SSP; + SSP = SSP & ~0x7; + ShadowStackPush8B(tmp); +} + + +:RSTORSSP m64 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; ( mod != 0b11 & reg_opcode=5 ) ... & m64 { + tmp_SSP:8 = m64; + SSP = tmp_SSP & ~0x01; +} + +define pcodeop writeToShadowStack; +define pcodeop writeToUserShadowStack; + + +:WRSSD rm32,Reg32 is vexMode=0 & byte=0x0f; byte=0x38; byte=0xf6; rm32 & Reg32 ... { + writeToShadowStack(rm32, Reg32); +} +@ifdef IA64 +:WRSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf6; rm64 & Reg64 ... { + writeToShadowStack(rm64, Reg64); +} +@endif + +:WRUSSD rm32,Reg32 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0xf5; rm32 & Reg32 ... { + writeToUserShadowStack(rm32, Reg32); +} +@ifdef IA64 +:WRUSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf5; rm64 & Reg64 ... { + writeToUserShadowStack(rm64, Reg64); +} +@endif + +define pcodeop markShadowStackBusy; +define pcodeop clearShadowStackBusy; + +:SETSSBSY is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; byte=0xe8 { + SSP = markShadowStackBusy(IA32_PL0_SSP); +} + +:CLRSSBSY m64 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0xae; reg_opcode=6 ... & m64 { + clearShadowStackBusy(m64); + SSP=0; +} + +:ENDBR32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfb {} +@ifdef IA64 +:ENDBR64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfa {} +@endif + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/clwb.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/clwb.sinc new file mode 100644 index 00000000..72195f8b --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/clwb.sinc @@ -0,0 +1,14 @@ +define pcodeop clwb; +:CLWB m8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=6 ... { + clwb(m8); +} + +@ifdef IA64 +define pcodeop clflushopt; +:CLFLUSHOPT m8 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=7 ... { + clflushopt(m8); +} +@endif + +# Note: PCOMMIT was deprecated prior to it ever being implemented in production processors. +# I never found the encoding for it. Therefore, no constructor. diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/fma.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/fma.sinc new file mode 100644 index 00000000..46a98430 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/fma.sinc @@ -0,0 +1,800 @@ +# +# x86 FMA instructions +# + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101211 +define pcodeop vfmadd132pd_fma ; +:VFMADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x98; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101214 +define pcodeop vfmadd213pd_fma ; +:VFMADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101217 +define pcodeop vfmadd231pd_fma ; +:VFMADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101220 +:VFMADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x98; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101223 +:VFMADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101226 +:VFMADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101572 +define pcodeop vfmadd132ps_fma ; +:VFMADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x98; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101575 +define pcodeop vfmadd213ps_fma ; +:VFMADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101578 +define pcodeop vfmadd231ps_fma ; +:VFMADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101581 +:VFMADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x98; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101584 +:VFMADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101587 +# WARNING: did not recognize VEX field 0 for "VFMADD231PS ymm1, ymm2, ymm3/m256" +:VFMADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xB8; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101931 +define pcodeop vfmadd132sd_fma ; +:VFMADD132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x99; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmadd132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101934 +define pcodeop vfmadd213sd_fma ; +:VFMADD213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA9; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmadd213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101937 +define pcodeop vfmadd231sd_fma ; +:VFMADD231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB9; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmadd231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102099 +define pcodeop vfmadd132ss_fma ; +:VFMADD132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x99; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmadd132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102102 +define pcodeop vfmadd213ss_fma ; +:VFMADD213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA9; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmadd213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102105 +define pcodeop vfmadd231ss_fma ; +:VFMADD231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB9; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmadd231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102272 +define pcodeop vfmaddsub132pd_fma ; +:VFMADDSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x96; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102275 +define pcodeop vfmaddsub213pd_fma ; +:VFMADDSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102278 +define pcodeop vfmaddsub231pd_fma ; +:VFMADDSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102281 +:VFMADDSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x96; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102284 +:VFMADDSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA6; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102287 +:VFMADDSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB6; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102711 +define pcodeop vfmaddsub132ps_fma ; +:VFMADDSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x96; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102714 +define pcodeop vfmaddsub213ps_fma ; +:VFMADDSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102717 +define pcodeop vfmaddsub231ps_fma ; +:VFMADDSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmaddsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102720 +:VFMADDSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x96; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102723 +:VFMADDSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA6; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102726 +:VFMADDSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xB6; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmaddsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103141 +define pcodeop vfmsubadd132pd_fma ; +:VFMSUBADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x97; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103144 +define pcodeop vfmsubadd213pd_fma ; +:VFMSUBADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103147 +define pcodeop vfmsubadd231pd_fma ; +:VFMSUBADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103150 +:VFMSUBADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x97; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103153 +:VFMSUBADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA7; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103156 +:VFMSUBADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB7; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103581 +define pcodeop vfmsubadd132ps_fma ; +:VFMSUBADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x97; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103584 +define pcodeop vfmsubadd213ps_fma ; +:VFMSUBADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103587 +define pcodeop vfmsubadd231ps_fma ; +:VFMSUBADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsubadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103590 +:VFMSUBADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x97; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103593 +:VFMSUBADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA7; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103596 +:VFMSUBADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xB7; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsubadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104019 +define pcodeop vfmsub132pd_fma ; +:VFMSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104022 +define pcodeop vfmsub213pd_fma ; +:VFMSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104025 +define pcodeop vfmsub231pd_fma ; +:VFMSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104028 +:VFMSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9A; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104031 +:VFMSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104034 +:VFMSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104379 +define pcodeop vfmsub132ps_fma ; +:VFMSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104382 +define pcodeop vfmsub213ps_fma ; +:VFMSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104385 +define pcodeop vfmsub231ps_fma ; +:VFMSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfmsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104388 +:VFMSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9A; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104391 +:VFMSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104394 +# WARNING: did not recognize VEX field 0 for "VFMSUB231PS ymm1, ymm2, ymm3/m256" +:VFMSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBA; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfmsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104738 +define pcodeop vfmsub132sd_fma ; +:VFMSUB132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9B; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmsub132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104741 +define pcodeop vfmsub213sd_fma ; +:VFMSUB213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAB; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmsub213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104744 +define pcodeop vfmsub231sd_fma ; +:VFMSUB231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBB; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfmsub231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104913 +define pcodeop vfmsub132ss_fma ; +:VFMSUB132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9B; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmsub132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104916 +define pcodeop vfmsub213ss_fma ; +:VFMSUB213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAB; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmsub213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104919 +define pcodeop vfmsub231ss_fma ; +:VFMSUB231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBB; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfmsub231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105088 +define pcodeop vfnmadd132pd_fma ; +:VFNMADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105091 +define pcodeop vfnmadd213pd_fma ; +:VFNMADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105094 +define pcodeop vfnmadd231pd_fma ; +:VFNMADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105097 +:VFNMADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105100 +:VFNMADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105103 +:VFNMADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105447 +define pcodeop vfnmadd132ps_fma ; +:VFNMADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105450 +define pcodeop vfnmadd213ps_fma ; +:VFNMADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105453 +define pcodeop vfnmadd231ps_fma ; +:VFNMADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105456 +:VFNMADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9C; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105459 +:VFNMADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105462 +# WARNING: did not recognize VEX field 0 for "VFNMADD231PS ymm1, ymm2, ymm3/m256" +:VFNMADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBC; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105794 +define pcodeop vfnmadd132sd_fma ; +:VFNMADD132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9D; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmadd132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105797 +define pcodeop vfnmadd213sd_fma ; +:VFNMADD213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAD; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmadd213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105800 +define pcodeop vfnmadd231sd_fma ; +:VFNMADD231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBD; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmadd231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105966 +define pcodeop vfnmadd132ss_fma ; +:VFNMADD132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9D; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmadd132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105969 +define pcodeop vfnmadd213ss_fma ; +:VFNMADD213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAD; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmadd213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105972 +define pcodeop vfnmadd231ss_fma ; +:VFNMADD231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBD; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmadd231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106138 +define pcodeop vfnmsub132pd_fma ; +:VFNMSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106141 +define pcodeop vfnmsub213pd_fma ; +:VFNMSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106144 +define pcodeop vfnmsub231pd_fma ; +:VFNMSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106147 +:VFNMSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106150 +:VFNMSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106153 +:VFNMSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106487 +define pcodeop vfnmsub132ps_fma ; +:VFNMSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106490 +define pcodeop vfnmsub213ps_fma ; +:VFNMSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106493 +define pcodeop vfnmsub231ps_fma ; +:VFNMSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + local tmp:16 = vfnmsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106496 +:VFNMSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9E; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106499 +:VFNMSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106502 +# WARNING: did not recognize VEX field 0 for "VFNMSUB231PS ymm1, ymm2, ymm3/m256" +:VFNMSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBE; YmmReg1 ... & YmmReg2_m256 +{ + YmmReg1 = vfnmsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 ); + # TODO ZmmReg1 = zext(YmmReg1) +} + +# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106832 +define pcodeop vfnmsub132sd_fma ; +:VFNMSUB132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9F; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmsub132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106835 +define pcodeop vfnmsub213sd_fma ; +:VFNMSUB213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAF; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmsub213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106838 +define pcodeop vfnmsub231sd_fma ; +:VFNMSUB231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBF; (XmmReg1 & YmmReg1) ... & XmmReg2_m64 +{ + local tmp:16 = vfnmsub231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107004 +define pcodeop vfnmsub132ss_fma ; +:VFNMSUB132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9F; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmsub132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107007 +define pcodeop vfnmsub213ss_fma ; +:VFNMSUB213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAF; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmsub213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + +# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107010 +define pcodeop vfnmsub231ss_fma ; +:VFNMSUB231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBF; (XmmReg1 & YmmReg1) ... & XmmReg2_m32 +{ + local tmp:16 = vfnmsub231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 ); + YmmReg1 = zext(tmp); + # TODO ZmmReg1 = zext(XmmReg1) +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/ia.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/ia.sinc new file mode 100644 index 00000000..7a200dd1 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/ia.sinc @@ -0,0 +1,9100 @@ +# SLA specification file for Intel x86 + +@ifdef IA64 +@define SIZE "8" +@define STACKPTR "RSP" +@else +@define SIZE "4" +@define STACKPTR "ESP" +@endif + +define endian=little; + +define space ram type=ram_space size=$(SIZE) default; +define space register type=register_space size=4; + +# General purpose registers + +@ifdef IA64 +define register offset=0 size=8 [ RAX RCX RDX RBX RSP RBP RSI RDI ]; +define register offset=0 size=4 [ EAX _ ECX _ EDX _ EBX _ ESP _ EBP _ ESI _ EDI ]; +define register offset=0 size=2 [ AX _ _ _ CX _ _ _ DX _ _ _ BX _ _ _ SP _ _ _ BP _ _ _ SI _ _ _ DI ]; +define register offset=0 size=1 [ AL AH _ _ _ _ _ _ CL CH _ _ _ _ _ _ DL DH _ _ _ _ _ _ BL BH _ _ _ _ _ _ SPL _ _ _ _ _ _ _ BPL _ _ _ _ _ _ _ SIL _ _ _ _ _ _ _ DIL ]; + +define register offset=0x80 size=8 [ R8 R9 R10 R11 R12 R13 R14 R15 ]; +define register offset=0x80 size=4 [ R8D _ R9D _ R10D _ R11D _ R12D _ R13D _ R14D _ R15D _ ]; +define register offset=0x80 size=2 [ R8W _ _ _ R9W _ _ _ R10W _ _ _ R11W _ _ _ R12W _ _ _ R13W _ _ _ R14W _ _ _ R15W _ _ _ ]; +define register offset=0x80 size=1 [ R8B _ _ _ _ _ _ _ R9B _ _ _ _ _ _ _ R10B _ _ _ _ _ _ _ R11B _ _ _ _ _ _ _ R12B _ _ _ _ _ _ _ R13B _ _ _ _ _ _ _ R14B _ _ _ _ _ _ _ R15B _ _ _ _ _ _ _ ]; +@else +define register offset=0 size=4 [ EAX ECX EDX EBX ESP EBP ESI EDI ]; +define register offset=0 size=2 [ AX _ CX _ DX _ BX _ SP _ BP _ SI _ DI ]; +define register offset=0 size=1 [ AL AH _ _ CL CH _ _ DL DH _ _ BL BH ]; +@endif + +# Segment registers +define register offset=0x100 size=2 [ ES CS SS DS FS GS ]; +define register offset=0x110 size=$(SIZE) [ FS_OFFSET GS_OFFSET ]; + +# Flags +define register offset=0x200 size=1 [ CF F1 PF F3 AF F5 ZF SF + TF IF DF OF IOPL NT F15 + RF VM AC VIF VIP ID ]; +@ifdef IA64 +define register offset=0x280 size=8 [ rflags RIP ]; +define register offset=0x280 size=4 [ eflags _ EIP _ ]; +define register offset=0x280 size=2 [ flags _ _ _ IP _ _ _]; +@else +define register offset=0x280 size=4 [ eflags EIP] ; +define register offset=0x280 size=2 [ flags _ IP] ; +@endif + +# Debug and control registers + +@ifdef IA64 +define register offset=0x300 size=8 [ DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7 + DR8 DR9 DR10 DR11 DR12 DR13 DR14 DR15 + CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 + CR8 CR9 CR10 CR11 CR12 CR13 CR14 CR15 ]; +@else +define register offset=0x300 size=4 [ DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7 + CR0 _ CR2 CR3 CR4 ]; +define register offset=0x400 size=4 [ TR0 TR1 TR2 TR3 TR4 TR5 TR6 TR7 ]; +@endif + +#Processor State Register - currently only XFEATURE_ENABLED_MASK=XCR0 is defined +# +define register offset=0x600 size=8 [ XCR0 ]; + +# Memory Protection Extensions (MPX) +define register offset=0x700 size=8 [ BNDCFGS BNDCFGU BNDSTATUS ]; + +define register offset=0x740 size=16 [ BND0 BND1 BND2 BND3 _ _ _ _ ]; +define register offset=0x740 size=8 [ BND0_LB BND0_UB BND1_LB BND1_UB BND2_LB BND2_UB BND3_LB BND3_UB _ _ _ _ _ _ _ _ ]; + +# Control Flow Extensions +define register offset=0x7c0 size=8 [ SSP IA32_PL2_SSP IA32_PL1_SSP IA32_PL0_SSP ]; + +# Floating point registers - as they are in 32-bit protected mode +# See MMx registers below +define register offset=0x1106 size=10 [ ST0 ]; +define register offset=0x1116 size=10 [ ST1 ]; +define register offset=0x1126 size=10 [ ST2 ]; +define register offset=0x1136 size=10 [ ST3 ]; +define register offset=0x1146 size=10 [ ST4 ]; +define register offset=0x1156 size=10 [ ST5 ]; +define register offset=0x1166 size=10 [ ST6 ]; +define register offset=0x1176 size=10 [ ST7 ]; +define register offset=0x1090 size=1 [ C0 C1 C2 C3 ]; +define register offset=0x1094 size=4 [ MXCSR ]; +define register offset=0x10a0 size=2 [ FPUControlWord FPUStatusWord FPUTagWord + FPULastInstructionOpcode ]; +define register offset=0x10a8 size=$(SIZE) [ FPUDataPointer FPUInstructionPointer ]; +define register offset=0x10c8 size=2 [ FPUPointerSelector FPUDataSelector]; #FCS FDS + + # FCS is not modeled, deprecated as 0. + # FDS not modeled, deprecated as 0. + +# +# YMM0 - YMM7 - available in 32 bit mode +# YMM0 - YMM15 - available in 64 bit mode +# +define register offset=0x1100 size=8 [ _ MM0 _ MM1 _ MM2 _ MM3 _ MM4 _ MM5 _ MM6 _ MM7 ]; +define register offset=0x1100 size=4 [ + _ _ MM0_Da MM0_Db + _ _ MM1_Da MM1_Db + _ _ MM2_Da MM2_Db + _ _ MM3_Da MM3_Db + _ _ MM4_Da MM4_Db + _ _ MM5_Da MM5_Db + _ _ MM6_Da MM6_Db + _ _ MM7_Da MM7_Db +]; +define register offset=0x1100 size=2 [ + _ _ _ _ MM0_Wa MM0_Wb MM0_Wc MM0_Wd + _ _ _ _ MM1_Wa MM1_Wb MM1_Wc MM1_Wd + _ _ _ _ MM2_Wa MM2_Wb MM2_Wc MM2_Wd + _ _ _ _ MM3_Wa MM3_Wb MM3_Wc MM3_Wd + _ _ _ _ MM4_Wa MM4_Wb MM4_Wc MM4_Wd + _ _ _ _ MM5_Wa MM5_Wb MM5_Wc MM5_Wd + _ _ _ _ MM6_Wa MM6_Wb MM6_Wc MM6_Wd + _ _ _ _ MM7_Wa MM7_Wb MM7_Wc MM7_Wd +]; +define register offset=0x1100 size=1 [ + _ _ _ _ _ _ _ _ + MM0_Ba MM0_Bb MM0_Bc MM0_Bd MM0_Be MM0_Bf MM0_Bg MM0_Bh + _ _ _ _ _ _ _ _ + MM1_Ba MM1_Bb MM1_Bc MM1_Bd MM1_Be MM1_Bf MM1_Bg MM1_Bh + _ _ _ _ _ _ _ _ + MM2_Ba MM2_Bb MM2_Bc MM2_Bd MM2_Be MM2_Bf MM2_Bg MM2_Bh + _ _ _ _ _ _ _ _ + MM3_Ba MM3_Bb MM3_Bc MM3_Bd MM3_Be MM3_Bf MM3_Bg MM3_Bh + _ _ _ _ _ _ _ _ + MM4_Ba MM4_Bb MM4_Bc MM4_Bd MM4_Be MM4_Bf MM4_Bg MM4_Bh + _ _ _ _ _ _ _ _ + MM5_Ba MM5_Bb MM5_Bc MM5_Bd MM5_Be MM5_Bf MM5_Bg MM5_Bh + _ _ _ _ _ _ _ _ + MM6_Ba MM6_Bb MM6_Bc MM6_Bd MM6_Be MM6_Bf MM6_Bg MM6_Bh + _ _ _ _ _ _ _ _ + MM7_Ba MM7_Bb MM7_Bc MM7_Bd MM7_Be MM7_Bf MM7_Bg MM7_Bh +]; + + +# YMMx_H is the formal name for the high double quadword of the YMMx register, XMMx is the overlay in the XMM register set +define register offset=0x1200 size=16 [ + XMM0 YMM0_H + XMM1 YMM1_H + XMM2 YMM2_H + XMM3 YMM3_H + XMM4 YMM4_H + XMM5 YMM5_H + XMM6 YMM6_H + XMM7 YMM7_H + XMM8 YMM8_H + XMM9 YMM9_H + XMM10 YMM10_H + XMM11 YMM11_H + XMM12 YMM12_H + XMM13 YMM13_H + XMM14 YMM14_H + XMM15 YMM15_H +]; + +define register offset=0x1200 size=8 [ + XMM0_Qa XMM0_Qb _ _ + XMM1_Qa XMM1_Qb _ _ + XMM2_Qa XMM2_Qb _ _ + XMM3_Qa XMM3_Qb _ _ + XMM4_Qa XMM4_Qb _ _ + XMM5_Qa XMM5_Qb _ _ + XMM6_Qa XMM6_Qb _ _ + XMM7_Qa XMM7_Qb _ _ + XMM8_Qa XMM8_Qb _ _ + XMM9_Qa XMM9_Qb _ _ + XMM10_Qa XMM10_Qb _ _ + XMM11_Qa XMM11_Qb _ _ + XMM12_Qa XMM12_Qb _ _ + XMM13_Qa XMM13_Qb _ _ + XMM14_Qa XMM14_Qb _ _ + XMM15_Qa XMM15_Qb _ _ +]; +define register offset=0x1200 size=4 [ + XMM0_Da XMM0_Db XMM0_Dc XMM0_Dd _ _ _ _ + XMM1_Da XMM1_Db XMM1_Dc XMM1_Dd _ _ _ _ + XMM2_Da XMM2_Db XMM2_Dc XMM2_Dd _ _ _ _ + XMM3_Da XMM3_Db XMM3_Dc XMM3_Dd _ _ _ _ + XMM4_Da XMM4_Db XMM4_Dc XMM4_Dd _ _ _ _ + XMM5_Da XMM5_Db XMM5_Dc XMM5_Dd _ _ _ _ + XMM6_Da XMM6_Db XMM6_Dc XMM6_Dd _ _ _ _ + XMM7_Da XMM7_Db XMM7_Dc XMM7_Dd _ _ _ _ + XMM8_Da XMM8_Db XMM8_Dc XMM8_Dd _ _ _ _ + XMM9_Da XMM9_Db XMM9_Dc XMM9_Dd _ _ _ _ + XMM10_Da XMM10_Db XMM10_Dc XMM10_Dd _ _ _ _ + XMM11_Da XMM11_Db XMM11_Dc XMM11_Dd _ _ _ _ + XMM12_Da XMM12_Db XMM12_Dc XMM12_Dd _ _ _ _ + XMM13_Da XMM13_Db XMM13_Dc XMM13_Dd _ _ _ _ + XMM14_Da XMM14_Db XMM14_Dc XMM14_Dd _ _ _ _ + XMM15_Da XMM15_Db XMM15_Dc XMM15_Dd _ _ _ _ +]; +define register offset=0x1200 size=2 [ + XMM0_Wa XMM0_Wb XMM0_Wc XMM0_Wd XMM0_We XMM0_Wf XMM0_Wg XMM0_Wh _ _ _ _ _ _ _ _ + XMM1_Wa XMM1_Wb XMM1_Wc XMM1_Wd XMM1_We XMM1_Wf XMM1_Wg XMM1_Wh _ _ _ _ _ _ _ _ + XMM2_Wa XMM2_Wb XMM2_Wc XMM2_Wd XMM2_We XMM2_Wf XMM2_Wg XMM2_Wh _ _ _ _ _ _ _ _ + XMM3_Wa XMM3_Wb XMM3_Wc XMM3_Wd XMM3_We XMM3_Wf XMM3_Wg XMM3_Wh _ _ _ _ _ _ _ _ + XMM4_Wa XMM4_Wb XMM4_Wc XMM4_Wd XMM4_We XMM4_Wf XMM4_Wg XMM4_Wh _ _ _ _ _ _ _ _ + XMM5_Wa XMM5_Wb XMM5_Wc XMM5_Wd XMM5_We XMM5_Wf XMM5_Wg XMM5_Wh _ _ _ _ _ _ _ _ + XMM6_Wa XMM6_Wb XMM6_Wc XMM6_Wd XMM6_We XMM6_Wf XMM6_Wg XMM6_Wh _ _ _ _ _ _ _ _ + XMM7_Wa XMM7_Wb XMM7_Wc XMM7_Wd XMM7_We XMM7_Wf XMM7_Wg XMM7_Wh _ _ _ _ _ _ _ _ + XMM8_Wa XMM8_Wb XMM8_Wc XMM8_Wd XMM8_We XMM8_Wf XMM8_Wg XMM8_Wh _ _ _ _ _ _ _ _ + XMM9_Wa XMM9_Wb XMM9_Wc XMM9_Wd XMM9_We XMM9_Wf XMM9_Wg XMM9_Wh _ _ _ _ _ _ _ _ + XMM10_Wa XMM10_Wb XMM10_Wc XMM10_Wd XMM10_We XMM10_Wf XMM10_Wg XMM10_Wh _ _ _ _ _ _ _ _ + XMM11_Wa XMM11_Wb XMM11_Wc XMM11_Wd XMM11_We XMM11_Wf XMM11_Wg XMM11_Wh _ _ _ _ _ _ _ _ + XMM12_Wa XMM12_Wb XMM12_Wc XMM12_Wd XMM12_We XMM12_Wf XMM12_Wg XMM12_Wh _ _ _ _ _ _ _ _ + XMM13_Wa XMM13_Wb XMM13_Wc XMM13_Wd XMM13_We XMM13_Wf XMM13_Wg XMM13_Wh _ _ _ _ _ _ _ _ + XMM14_Wa XMM14_Wb XMM14_Wc XMM14_Wd XMM14_We XMM14_Wf XMM14_Wg XMM14_Wh _ _ _ _ _ _ _ _ + XMM15_Wa XMM15_Wb XMM15_Wc XMM15_Wd XMM15_We XMM15_Wf XMM15_Wg XMM15_Wh _ _ _ _ _ _ _ _ +]; +define register offset=0x1200 size=1 [ + XMM0_Ba XMM0_Bb XMM0_Bc XMM0_Bd XMM0_Be XMM0_Bf XMM0_Bg XMM0_Bh XMM0_Bi XMM0_Bj XMM0_Bk XMM0_Bl XMM0_Bm XMM0_Bn XMM0_Bo XMM0_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM1_Ba XMM1_Bb XMM1_Bc XMM1_Bd XMM1_Be XMM1_Bf XMM1_Bg XMM1_Bh XMM1_Bi XMM1_Bj XMM1_Bk XMM1_Bl XMM1_Bm XMM1_Bn XMM1_Bo XMM1_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM2_Ba XMM2_Bb XMM2_Bc XMM2_Bd XMM2_Be XMM2_Bf XMM2_Bg XMM2_Bh XMM2_Bi XMM2_Bj XMM2_Bk XMM2_Bl XMM2_Bm XMM2_Bn XMM2_Bo XMM2_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM3_Ba XMM3_Bb XMM3_Bc XMM3_Bd XMM3_Be XMM3_Bf XMM3_Bg XMM3_Bh XMM3_Bi XMM3_Bj XMM3_Bk XMM3_Bl XMM3_Bm XMM3_Bn XMM3_Bo XMM3_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM4_Ba XMM4_Bb XMM4_Bc XMM4_Bd XMM4_Be XMM4_Bf XMM4_Bg XMM4_Bh XMM4_Bi XMM4_Bj XMM4_Bk XMM4_Bl XMM4_Bm XMM4_Bn XMM4_Bo XMM4_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM5_Ba XMM5_Bb XMM5_Bc XMM5_Bd XMM5_Be XMM5_Bf XMM5_Bg XMM5_Bh XMM5_Bi XMM5_Bj XMM5_Bk XMM5_Bl XMM5_Bm XMM5_Bn XMM5_Bo XMM5_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM6_Ba XMM6_Bb XMM6_Bc XMM6_Bd XMM6_Be XMM6_Bf XMM6_Bg XMM6_Bh XMM6_Bi XMM6_Bj XMM6_Bk XMM6_Bl XMM6_Bm XMM6_Bn XMM6_Bo XMM6_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM7_Ba XMM7_Bb XMM7_Bc XMM7_Bd XMM7_Be XMM7_Bf XMM7_Bg XMM7_Bh XMM7_Bi XMM7_Bj XMM7_Bk XMM7_Bl XMM7_Bm XMM7_Bn XMM7_Bo XMM7_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM8_Ba XMM8_Bb XMM8_Bc XMM8_Bd XMM8_Be XMM8_Bf XMM8_Bg XMM8_Bh XMM8_Bi XMM8_Bj XMM8_Bk XMM8_Bl XMM8_Bm XMM8_Bn XMM8_Bo XMM8_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM9_Ba XMM9_Bb XMM9_Bc XMM9_Bd XMM9_Be XMM9_Bf XMM9_Bg XMM9_Bh XMM9_Bi XMM9_Bj XMM9_Bk XMM9_Bl XMM9_Bm XMM9_Bn XMM9_Bo XMM9_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM10_Ba XMM10_Bb XMM10_Bc XMM10_Bd XMM10_Be XMM10_Bf XMM10_Bg XMM10_Bh XMM10_Bi XMM10_Bj XMM10_Bk XMM10_Bl XMM10_Bm XMM10_Bn XMM10_Bo XMM10_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM11_Ba XMM11_Bb XMM11_Bc XMM11_Bd XMM11_Be XMM11_Bf XMM11_Bg XMM11_Bh XMM11_Bi XMM11_Bj XMM11_Bk XMM11_Bl XMM11_Bm XMM11_Bn XMM11_Bo XMM11_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM12_Ba XMM12_Bb XMM12_Bc XMM12_Bd XMM12_Be XMM12_Bf XMM12_Bg XMM12_Bh XMM12_Bi XMM12_Bj XMM12_Bk XMM12_Bl XMM12_Bm XMM12_Bn XMM12_Bo XMM12_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM13_Ba XMM13_Bb XMM13_Bc XMM13_Bd XMM13_Be XMM13_Bf XMM13_Bg XMM13_Bh XMM13_Bi XMM13_Bj XMM13_Bk XMM13_Bl XMM13_Bm XMM13_Bn XMM13_Bo XMM13_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM14_Ba XMM14_Bb XMM14_Bc XMM14_Bd XMM14_Be XMM14_Bf XMM14_Bg XMM14_Bh XMM14_Bi XMM14_Bj XMM14_Bk XMM14_Bl XMM14_Bm XMM14_Bn XMM14_Bo XMM14_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + XMM15_Ba XMM15_Bb XMM15_Bc XMM15_Bd XMM15_Be XMM15_Bf XMM15_Bg XMM15_Bh XMM15_Bi XMM15_Bj XMM15_Bk XMM15_Bl XMM15_Bm XMM15_Bn XMM15_Bo XMM15_Bp _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ +]; +define register offset=0x1200 size=32 [ YMM0 YMM1 YMM2 YMM3 YMM4 YMM5 YMM6 YMM7 YMM8 YMM9 YMM10 YMM11 YMM12 YMM13 YMM14 YMM15 ]; + +# 0x1400 is next spot +define register offset=0x1400 size=16 [ xmmTmp1 xmmTmp2 ]; +define register offset=0x1400 size=8 [ + xmmTmp1_Qa xmmTmp1_Qb + xmmTmp2_Qa xmmTmp2_Qb +]; +define register offset=0x1400 size=4 [ + xmmTmp1_Da xmmTmp1_Db xmmTmp1_Dc xmmTmp1_Dd + xmmTmp2_Da xmmTmp2_Db xmmTmp2_Dc xmmTmp2_Dd +]; + +# Define context bits +define register offset=0x2000 size=8 contextreg; + +# +# +# This context layout is important: the 32 bit version sees addrsize as just the +# low-order bit, whereas the 64 bit sees both bits. This ensures that the 32 and 64 +# are technically binary compatible, but since the 32 bit language can't see that +# addrsize is 2 bits, they won't be pulled up into constructors where bit 0 is always +# 0 (which it is), and then you don't get the decision conflicts that choose +# context over table order +# +# + +define context contextreg +@ifdef IA64 + # Stored context + longMode=(0,0) # 0 for 32-bit emulation, 1 for 64-bit mode + reserved=(1,3) + addrsize=(4,5) # =0 16-bit addressing =1 32-bit addressing =2 64-bit addressing +@else + # Stored context + reserved=(0,3) + addrsize=(5,5) # =0 16-bit addressing =1 32-bit addressing +@endif + bit64=(4,4) # =0 16/32 bit =1 64-bit + opsize=(6,7) # =0 16-bit operands =1 32-bit operands =2 64-bit operands + segover=(8,10) # 0=default 1=cs 2=ss 3=ds 4=es 5=fs 6=gs + highseg=(8,8) # high bit of segover will be set for ES, FS, GS + protectedMode=(11,11) # 0 for real mode, 1 for protected mode + # End stored context + + repneprefx=(12,12) # 0xf2 REPNE prefix + repprefx=(13,13) # 0xf3 REP prefix + xacquireprefx=(12,12) # 0xf2 XACQUIRE prefix + xreleaseprefx=(13,13) # 0xf3 XRELEASE prefix + prefix_66=(14,14) # This is not really a OPSIZE override, it means there is an real(read)/implied(vex) 66 byte + prefix_f3=(13,13) # This is not really a REP override, it means there is an real(read)/implied(vex) f3 byte + prefix_f2=(12,12) # This is not really a REPNE override, it means there is a real(read)/implied(vex) f2 byte + mandover=(12,14) # 0x66 0xf2 or 0xf3 overrides (for mandatory prefixes) + + rexWprefix=(15,15) # REX.W bit prefix (opsize=2 when REX.W is set) + rexRprefix=(16,16) # REX.R bit prefix extend r + rexXprefix=(17,17) # REX.X bit prefix extend SIB index field to 4 bits + rexBprefix=(18,18) # REX.B bit prefix extend r/m, SIB base, Reg operand + rexWRXBprefix=(15,18) # REX.WRXB bits + rexprefix=(19,19) # True if the Rex prefix is present - note, if present, vex_mode is not supported + # rexWRXB bits can be re-used since they are incompatible. + vexMode=(20,20) # 1 for vex instruction, 0 for normal + vexL=(21,21) # 0 for 128, 1 for 256 + vexVVVV=(22,25) # value of vex byte for matching + vexVVVV_r32=(22,25) # value of vex byte for matching a normal 32 bit register + vexVVVV_r64=(22,25) # value of vex byte for matching a normal 64 bit register + vexVVVV_XmmReg=(22,25) # value of vex byte for matching XmmReg + vexVVVV_YmmReg=(22,25) # value of vex byte for matching YmmReg + vexMMMMM=(26,30) # need to match for preceding bytes 1=0x0F, 2=0x0F 0x38, 3=0x0F 0x3A + + suffix3D=(21,28) # 3DNow suffix byte (overlaps un-modified vex context region) + instrPhase=(31,31) # 0: initial/prefix phase, 1: primary instruction phase + + lockprefx=(32,32) # 0xf0 LOCK prefix +; + + +# These are only to be used with pre-REX (original 8086, 80386) and REX encoding. Do not use with VEX encoding. +# These are to be used to designate that the opcode sequence begins with one of these "mandatory" prefix values. +# This allows the other prefixes to come before the mandatory value. +# For example: CRC32 r32, r16 -- 66 F2 OF 38 F1 C8 + +@define PRE_NO "mandover=0" +@define PRE_66 "prefix_66=1" +@define PRE_F3 "prefix_f3=1" +@define PRE_F2 "prefix_f2=1" + + + +# Define special registers for debugger +@ifdef IA64 +define register offset=0x2200 size=4 [ IDTR_Limit ]; +define register offset=0x2200 size=12 [ IDTR ]; +define register offset=0x2204 size=8 [ IDTR_Address ]; + +define register offset=0x2220 size=4 [ GDTR_Limit ]; +define register offset=0x2220 size=12 [ GDTR ]; +define register offset=0x2224 size=8 [ GDTR_Address ]; + +define register offset=0x2240 size=4 [ LDTR_Limit ]; +define register offset=0x2240 size=14 [ LDTR ]; +define register offset=0x2244 size=8 [ LDTR_Address ]; +define register offset=0x2248 size=2 [ LDTR_Attributes ]; + +define register offset=0x2260 size=4 [ TR_Limit ]; +define register offset=0x2260 size=14 [ TR ]; +define register offset=0x2264 size=8 [ TR_Address ]; +define register offset=0x2268 size=2 [ TR_Attributes ]; +@else +define register offset=0x2200 size=6 [ IDTR ]; +define register offset=0x2200 size=2 [ IDTR_Limit ]; +define register offset=0x2202 size=4 [ IDTR_Address ]; + +define register offset=0x2210 size=6 [ GDTR ]; +define register offset=0x2210 size=2 [ GDTR_Limit ]; +define register offset=0x2212 size=4 [ GDTR_Address ]; + +define register offset=0x2220 size=6 [ LDTR ]; +define register offset=0x2220 size=2 [ LDTR_Limit ]; +define register offset=0x2222 size=4 [ LDTR_Address ]; + +define register offset=0x2230 size=6 [ TR ]; +define register offset=0x2230 size=2 [ TR_Limit ]; +define register offset=0x2232 size=4 [ TR_Address ]; +@endif + +define token opbyte (8) + byte=(0,7) + high4=(4,7) + high5=(3,7) + low5=(0,4) + byte_4=(4,4) + byte_0=(0,0) +; + +define token modrm (8) + mod = (6,7) + reg_opcode = (3,5) + reg_opcode_hb = (5,5) + r_m = (0,2) + row = (4,7) + col = (0,2) + page = (3,3) + cond = (0,3) + reg8 = (3,5) + reg16 = (3,5) + reg32 = (3,5) + reg64 = (3,5) + reg8_x0 = (3,5) + reg8_x1 = (3,5) + reg16_x = (3,5) + reg32_x = (3,5) + reg64_x = (3,5) + Sreg = (3,5) + creg = (3,5) + creg_x = (3,5) + debugreg = (3,5) + debugreg_x = (3,5) + testreg = (3,5) + r8 = (0,2) + r16 = (0,2) + r32 = (0,2) + r64 = (0,2) + r8_x0 = (0,2) + r8_x1 = (0,2) + r16_x = (0,2) + r32_x = (0,2) + r64_x = (0,2) + frow = (4,7) + fpage = (3,3) + freg = (0,2) + rexw = (3,3) + rexr = (2,2) + rexx = (1,1) + rexb = (0,0) + mmxmod = (6,7) + mmxreg = (3,5) + mmxreg1 = (3,5) + mmxreg2 = (0,2) + xmmmod = (6,7) + xmmreg = (3,5) + ymmreg = (3,5) + + xmmreg1 = (3,5) + ymmreg1 = (3,5) + xmmreg2 = (0,2) + ymmreg2 = (0,2) + + xmmreg_x = (3,5) + ymmreg_x = (3,5) + xmmreg1_x = (3,5) + ymmreg1_x = (3,5) + xmmreg2_x = (0,2) + ymmreg2_x = (0,2) + vex_pp = (0,1) + vex_l = (2,2) + vex_vvvv = (3,6) + vex_r = (7,7) + vex_x = (6,6) + vex_b = (5,5) + vex_w = (7,7) + vex_mmmmm = (0,4) + bnd1 = (3,5) + bnd1_lb = (3,5) + bnd1_ub = (3,5) + bnd2 = (0,2) + bnd2_lb = (0,2) + bnd2_ub = (0,2) +; + +define token sib (8) + ss = (6,7) + index = (3,5) + index_x = (3,5) + index64 = (3,5) + index64_x = (3,5) + xmm_vsib = (3,5) + xmm_vsib_x = (3,5) + ymm_vsib = (3,5) + ymm_vsib_x = (3,5) + base = (0,2) + base_x = (0,2) + base64 = (0,2) + base64_x = (0,2) +; + +define token I8 (8) + imm8_7=(7,7) + Xmm_imm8_7_4=(4,7) + Ymm_imm8_7_4=(4,7) + imm8_4=(4,4) + imm8_0=(0,0) + imm8_3_0=(0,3) + imm8=(0,7) + simm8=(0,7) signed +; + +define token I16 (16) imm16_15=(15,15) imm16=(0,15) simm16=(0,15) signed j16=(0,15); +define token I32 (32) imm32=(0,31) simm32=(0,31) signed; +define token I64 (64) imm64=(0,63) simm64=(0,63) signed; +define token override (8) over=(0,7); + +attach variables [ r32 reg32 base index ] [ EAX ECX EDX EBX ESP EBP ESI EDI ]; +attach variables [ r16 reg16 ] [ AX CX DX BX SP BP SI DI ]; +attach variables [ r8 reg8 ] [ AL CL DL BL AH CH DH BH ]; +attach variables Sreg [ ES CS SS DS FS GS _ _ ]; +attach variables freg [ ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 ]; +attach variables [ debugreg ] [ DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7 ]; +@ifdef IA64 +attach variables [ r64 reg64 base64 index64 ] [ RAX RCX RDX RBX RSP RBP RSI RDI ]; +attach variables [ r64_x reg64_x base64_x index64_x ] [ R8 R9 R10 R11 R12 R13 R14 R15 ]; +attach variables [ r32_x reg32_x base_x index_x ] [ R8D R9D R10D R11D R12D R13D R14D R15D ]; +attach variables [ r16_x reg16_x ] [ R8W R9W R10W R11W R12W R13W R14W R15W ]; +attach variables [ r8_x0 reg8_x0 ] [ AL CL DL BL SPL BPL SIL DIL ]; +attach variables [ r8_x1 reg8_x1 ] [ R8B R9B R10B R11B R12B R13B R14B R15B ]; +attach variables [ debugreg_x ] [ DR8 DR9 DR10 DR11 DR12 DR13 DR14 DR15 ]; +attach variables creg [ CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 ]; +attach variables creg_x [ CR8 CR9 CR10 CR11 CR12 CR13 CR14 CR15 ]; +@else +attach variables [ testreg ] [ TR0 TR1 TR2 TR3 TR6 TR7 TR6 TR7 ]; +attach variables creg [ CR0 _ CR2 CR3 CR4 _ _ _ ]; +@endif + +attach values ss [ 1 2 4 8]; + +attach variables [ mmxreg mmxreg1 mmxreg2 ] [ MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 ]; + +attach variables [ xmmreg xmmreg1 xmmreg2 xmm_vsib ] [ XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 ]; + +attach variables [ xmmreg_x xmmreg1_x xmmreg2_x xmm_vsib_x ] [ XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 ]; + +attach variables [ vexVVVV_XmmReg Xmm_imm8_7_4 ] [ XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 ]; + +attach variables [ vexVVVV_YmmReg Ymm_imm8_7_4 ] [ YMM0 YMM1 YMM2 YMM3 YMM4 YMM5 YMM6 YMM7 YMM8 YMM9 YMM10 YMM11 YMM12 YMM13 YMM14 YMM15 ]; + +@ifdef IA64 +attach variables [ vexVVVV_r32 ] [ EAX ECX EDX EBX ESP EBP ESI EDI R8D R9D R10D R11D R12D R13D R14D R15D ]; +attach variables [ vexVVVV_r64 ] [ RAX RCX RDX RBX RSP RBP RSI RDI R8 R9 R10 R11 R12 R13 R14 R15 ]; +@else +attach variables [ vexVVVV_r32 ] [ EAX ECX EDX EBX ESP EBP ESI EDI _ _ _ _ _ _ _ _ ]; +@endif + + +attach variables [ ymmreg ymmreg1 ymmreg2 ymm_vsib ] [ YMM0 YMM1 YMM2 YMM3 YMM4 YMM5 YMM6 YMM7 ]; +attach variables [ ymmreg_x ymmreg1_x ymmreg2_x ymm_vsib_x ] [ YMM8 YMM9 YMM10 YMM11 YMM12 YMM13 YMM14 YMM15 ]; + +attach variables [ bnd1 bnd2 ] [ BND0 BND1 BND2 BND3 _ _ _ _ ]; +attach variables [ bnd1_lb bnd2_lb ] [ BND0_LB BND1_LB BND2_LB BND3_LB _ _ _ _ ]; +attach variables [ bnd1_ub bnd2_ub ] [ BND0_UB BND1_UB BND2_UB BND3_UB _ _ _ _ ]; + +define pcodeop segment; # Define special pcodeop that calculates the RAM address + # given the segment selector and offset as input + +define pcodeop in; # force in/out to show up in decompiler +define pcodeop out; +define pcodeop sysenter; +define pcodeop sysexit; +define pcodeop syscall; +define pcodeop sysret; +define pcodeop swapgs; +define pcodeop invlpg; +define pcodeop invlpga; +define pcodeop invpcid; +define pcodeop rdtscp; +define pcodeop mwait; +define pcodeop mwaitx; +define pcodeop monitor; +define pcodeop monitorx; +define pcodeop swi; # for INT instruction + +define pcodeop LOCK; # for LOCK prefix +define pcodeop UNLOCK; # for LOCK prefix +define pcodeop XACQUIRE; # for XACQUIRE prefix +define pcodeop XRELEASE; # for XRELEASE prefix + +# MFL: definitions for AMD hardware assisted virtualization instructions +define pcodeop clgi; # clear global interrupt flag (GIF) +define pcodeop stgi; # set global interrupt flag (GIF) +define pcodeop vmload; # Load state from VMCD, opcode 0f 01 da +define pcodeop vmmcall; # Call VMM, opcode 0f 01 d9 +define pcodeop vmrun; # Run virtual machine, opcode 0f 01 d8 +define pcodeop vmsave; # Save state to VMCB, opcode 0f 0a db + +# MFL: definitions for Intel IA hardware assisted virtualization instructions +define pcodeop invept; # Invalidate Translations Derived from extended page tables (EPT); opcode 66 0f 38 80 +define pcodeop invvpid; # Invalidate Translations Based on virtual-processor identifier (VPID); opcode 66 0f 38 81 +define pcodeop vmcall; # Call to VM monitor by causing VM exit, opcode 0f 01 c1 +define pcodeop vmclear; # Clear virtual-machine control structure, opcode 66 0f c7 /6 +define pcodeop vmfunc; # call virtual-machine function refernced by EAX +define pcodeop vmlaunch; # Launch virtual machine managed by current VMCCS; opcode 0f 01 c2 +define pcodeop vmresume; # Resume virtual machine managed by current VMCS; opcode 0f 01 c3 +define pcodeop vmptrld; # Load pointer to virtual-machine control structure; opcode 0f c6 /6 +define pcodeop vmptrst; # Store pointer to virtual-machine control structure; opcode 0f c7 /7 +define pcodeop vmread; # Read field from virtual-machine control structure; opcode 0f 78 +define pcodeop vmwrite; # Write field to virtual-machine control structure; opcode 0f 79 +define pcodeop vmxoff; # Leave VMX operation; opcode 0f 01 c4 +define pcodeop vmxon; # Enter VMX operation; opcode f3 0f C7 /6 + +@ifdef IA64 +@define LONGMODE_ON "longMode=1" +@define LONGMODE_OFF "longMode=0" +@else +@define LONGMODE_OFF "epsilon" # NOP +@endif + +# When not running in 64-bit mode opcode 0x82 is an alias for 0x80 + +@ifdef IA64 +@define BYTE_80_82 "(byte=0x80 | (longMode=0 & byte=0x82))" +@else +@define BYTE_80_82 "(byte=0x80 | byte=0x82)" +@endif + +@ifdef IA64 +Reg8: reg8 is rexprefix=0 & reg8 { export reg8; } +Reg8: reg8_x0 is rexprefix=1 & rexRprefix=0 & reg8_x0 { export reg8_x0; } +Reg8: reg8_x1 is rexprefix=1 & rexRprefix=1 & reg8_x1 { export reg8_x1; } +Reg16: reg16 is rexRprefix=0 & reg16 { export reg16; } +Reg16: reg16_x is rexRprefix=1 & reg16_x { export reg16_x; } +Reg32: reg32 is rexRprefix=0 & reg32 { export reg32; } +Reg32: reg32_x is rexRprefix=1 & reg32_x { export reg32_x; } +Reg64: reg64 is rexRprefix=0 & reg64 { export reg64; } +Reg64: reg64_x is rexRprefix=1 & reg64_x { export reg64_x; } +Rmr8: r8 is rexprefix=0 & r8 { export r8; } +Rmr8: r8_x0 is rexprefix=1 & rexBprefix=0 & r8_x0 { export r8_x0; } +Rmr8: r8_x1 is rexprefix=1 & rexBprefix=1 & r8_x1 { export r8_x1; } +CRmr8: r8 is rexBprefix=0 & r8 { export r8; } +CRmr8: r8 is addrsize=2 & rexBprefix=0 & r8 { export r8; } +CRmr8: r8_x0 is addrsize=2 & rexprefix=1 & rexBprefix=0 & r8_x0 { export r8_x0; } +CRmr8: r8_x1 is addrsize=2 & rexprefix=1 & rexBprefix=1 & r8_x1 { export r8_x1; } +Rmr16: r16 is rexBprefix=0 & r16 { export r16; } +Rmr16: r16_x is rexBprefix=1 & r16_x { export r16_x; } +CRmr16: r16 is rexBprefix=0 & r16 { export r16; } +CRmr16: r16_x is rexBprefix=1 & r16_x { export r16_x; } +Rmr32: r32 is rexBprefix=0 & r32 { export r32; } +Rmr32: r32_x is rexBprefix=1 & r32_x { export r32_x; } +CRmr32: r32 is rexBprefix=0 & r32 & r64 { export r64; } +CRmr32: r32_x is rexBprefix=1 & r32_x & r64_x { export r64_x; } +Rmr64: r64 is rexBprefix=0 & r64 { export r64; } +Rmr64: r64_x is rexBprefix=1 & r64_x { export r64_x; } +Base: base is rexBprefix=0 & base { export base; } +Base: base_x is rexBprefix=1 & base_x { export base_x; } +Index: index is rexXprefix=0 & index { export index; } +Index: index_x is rexXprefix=1 & index_x { export index_x; } +Base64: base64 is rexBprefix=0 & base64 { export base64; } +Base64: base64_x is rexBprefix=1 & base64_x { export base64_x; } +Index64: index64 is rexXprefix=0 & index64 { export index64; } +Index64: index64_x is rexXprefix=1 & index64_x { export index64_x; } +XmmReg: xmmreg is rexRprefix=0 & xmmreg { export xmmreg; } +XmmReg: xmmreg_x is rexRprefix=1 & xmmreg_x { export xmmreg_x; } +XmmReg1: xmmreg1 is rexRprefix=0 & xmmreg1 { export xmmreg1; } +XmmReg1: xmmreg1_x is rexRprefix=1 & xmmreg1_x { export xmmreg1_x; } +XmmReg2: xmmreg2 is rexBprefix=0 & xmmreg2 { export xmmreg2; } +XmmReg2: xmmreg2_x is rexBprefix=1 & xmmreg2_x { export xmmreg2_x; } +YmmReg1: ymmreg1 is rexRprefix=0 & ymmreg1 { export ymmreg1; } +YmmReg1: ymmreg1_x is rexRprefix=1 & ymmreg1_x { export ymmreg1_x; } +YmmReg2: ymmreg2 is rexBprefix=0 & ymmreg2 { export ymmreg2; } +YmmReg2: ymmreg2_x is rexBprefix=1 & ymmreg2_x { export ymmreg2_x; } +Xmm_vsib: xmm_vsib is rexXprefix=0 & xmm_vsib { export xmm_vsib; } +Xmm_vsib: xmm_vsib_x is rexXprefix=1 & xmm_vsib_x { export xmm_vsib_x; } +Ymm_vsib: ymm_vsib is rexXprefix=0 & ymm_vsib { export ymm_vsib; } +Ymm_vsib: ymm_vsib_x is rexXprefix=1 & ymm_vsib_x { export ymm_vsib_x; } +@else +Reg8: reg8 is reg8 { export reg8; } +Reg16: reg16 is reg16 { export reg16; } +Reg32: reg32 is reg32 { export reg32; } +Rmr8: r8 is r8 { export r8; } +CRmr8: r8 is r8 { export r8; } +Rmr16: r16 is r16 { export r16; } +CRmr16: r16 is r16 { export r16; } +Rmr32: r32 is r32 { export r32; } +CRmr32: r32 is r32 { export r32; } +Base: base is base { export base; } +Index: index is index { export index; } +XmmReg: xmmreg is xmmreg { export xmmreg; } +XmmReg1: xmmreg1 is xmmreg1 { export xmmreg1; } +XmmReg2: xmmreg2 is xmmreg2 { export xmmreg2; } +YmmReg1: ymmreg1 is ymmreg1 { export ymmreg1; } +YmmReg2: ymmreg2 is ymmreg2 { export ymmreg2; } +Xmm_vsib: xmm_vsib is xmm_vsib { export xmm_vsib; } +Ymm_vsib: ymm_vsib is ymm_vsib { export ymm_vsib; } +@endif + +# signed immediate value subconstructors + +simm8_16: simm8 is simm8 { export *[const]:2 simm8; } +simm8_32: simm8 is simm8 { export *[const]:4 simm8; } +@ifdef IA64 +simm8_64: simm8 is simm8 { export *[const]:8 simm8; } +@endif +simm16_16: simm16 is simm16 { export *[const]:2 simm16; } +simm32_32: simm32 is simm32 { export *[const]:4 simm32; } +@ifdef IA64 +simm32_64: simm32 is simm32 { export *[const]:8 simm32; } +imm32_64: imm32 is imm32 { export *[const]:8 imm32; } +@endif + +usimm8_16: imm8 is imm8 & imm8_7=0 { export *[const]:2 imm8; } +usimm8_16: val is imm8 & imm8_7=1 [ val = 0xff00 | imm8; ] { export *[const]:2 val; } +usimm8_32: imm8 is imm8 & imm8_7=0 { export *[const]:4 imm8; } +usimm8_32: val is imm8 & imm8_7=1 [ val = 0xffffff00 | imm8; ] { export *[const]:4 val; } +@ifdef IA64 +usimm8_64: imm8 is imm8 & imm8_7=0 { export *[const]:8 imm8; } +usimm8_64: val is imm8 & imm8_7=1 [ val = 0xffffffffffffff00 | imm8; ] { export *[const]:8 val; } +@endif + +# unused +#usimm16_32: imm16 is imm16 & imm16_15=0 { export *[const]:4 imm16; } +#usimm16_32: val is imm16 & imm16_15=1 [ val = 0xffff0000 | imm16; ] { export *[const]:4 val; } + +# RIP/EIP relative address - NOTE: export of size 0 is intentional so it may be adjusted +pcRelSimm32: addr is simm32 [ addr=inst_next+simm32; ] { export addr; } + +# 16-bit addressing modes (the offset portion) +addr16: [BX + SI] is mod=0 & r_m=0 & BX & SI { local tmp=BX+SI; export tmp; } +addr16: [BX + DI] is mod=0 & r_m=1 & BX & DI { local tmp=BX+DI; export tmp; } +addr16: [BP + SI] is mod=0 & r_m=2 & BP & SI { local tmp=BP+SI; export tmp; } +addr16: [BP + DI] is mod=0 & r_m=3 & BP & DI { local tmp=BP+DI; export tmp; } +addr16: [SI] is mod=0 & r_m=4 & SI { export SI; } +addr16: [DI] is mod=0 & r_m=5 & DI { export DI; } +addr16: [imm16] is mod=0 & r_m=6; imm16 { export *[const]:2 imm16; } +addr16: [BX] is mod=0 & r_m=7 & BX { export BX; } +addr16: [BX + SI + simm8_16] is mod=1 & r_m=0 & BX & SI; simm8_16 { local tmp=BX+SI+simm8_16; export tmp; } +addr16: [BX + DI + simm8_16] is mod=1 & r_m=1 & BX & DI; simm8_16 { local tmp=BX+DI+simm8_16; export tmp; } +addr16: [BP + SI + simm8_16] is mod=1 & r_m=2 & BP & SI; simm8_16 { local tmp=BP+SI+simm8_16; export tmp; } +addr16: [BP + DI + simm8_16] is mod=1 & r_m=3 & BP & DI; simm8_16 { local tmp=BP+DI+simm8_16; export tmp; } +addr16: [SI + simm8_16] is mod=1 & r_m=4 & SI; simm8_16 { local tmp=SI+simm8_16; export tmp; } +addr16: [DI + simm8_16] is mod=1 & r_m=5 & DI; simm8_16 { local tmp=DI+simm8_16; export tmp; } +addr16: [BP + simm8_16] is mod=1 & r_m=6 & BP; simm8_16 { local tmp=BP+simm8_16; export tmp; } +addr16: [BX + simm8_16] is mod=1 & r_m=7 & BX; simm8_16 { local tmp=BX+simm8_16; export tmp; } +addr16: [BX + SI + imm16] is mod=2 & r_m=0 & BX & SI; imm16 { local tmp=BX+SI+imm16; export tmp; } +addr16: [BX + DI + imm16] is mod=2 & r_m=1 & BX & DI; imm16 { local tmp=BX+DI+imm16; export tmp; } +addr16: [BP + SI + imm16] is mod=2 & r_m=2 & BP & SI; imm16 { local tmp=BP+SI+imm16; export tmp; } +addr16: [BP + DI + imm16] is mod=2 & r_m=3 & BP & DI; imm16 {local tmp=BP+DI+imm16; export tmp; } +addr16: [SI + imm16] is mod=2 & r_m=4 & SI; imm16 { local tmp=SI+imm16; export tmp; } +addr16: [DI + imm16] is mod=2 & r_m=5 & DI; imm16 { local tmp=DI+imm16; export tmp; } +addr16: [BP + imm16] is mod=2 & r_m=6 & BP; imm16 { local tmp=BP+imm16; export tmp; } +addr16: [BX + imm16] is mod=2 & r_m=7 & BX; imm16 { local tmp=BX+imm16; export tmp; } + +# 32-bit addressing modes (the offset portion) +addr32: [Rmr32] is mod=0 & Rmr32 { export Rmr32; } +addr32: [Rmr32 + simm8_32] is mod=1 & Rmr32; simm8_32 { local tmp=Rmr32+simm8_32; export tmp; } +addr32: [Rmr32] is mod=1 & r_m!=4 & Rmr32; simm8=0 { export Rmr32; } +addr32: [Rmr32 + imm32] is mod=2 & Rmr32; imm32 { local tmp=Rmr32+imm32; export tmp; } +addr32: [Rmr32] is mod=2 & r_m!=4 & Rmr32; imm32=0 { export Rmr32; } +addr32: [imm32] is mod=0 & r_m=5; imm32 { export *[const]:4 imm32; } +addr32: [Base + Index*ss] is mod=0 & r_m=4; Index & Base & ss { local tmp=Base+Index*ss; export tmp; } +addr32: [Base] is mod=0 & r_m=4; index=4 & Base { export Base; } +addr32: [Index*ss + imm32] is mod=0 & r_m=4; Index & base=5 & ss; imm32 { local tmp=imm32+Index*ss; export tmp; } +addr32: [imm32] is mod=0 & r_m=4; index=4 & base=5; imm32 { export *[const]:4 imm32; } +addr32: [Base + Index*ss + simm8_32] is mod=1 & r_m=4; Index & Base & ss; simm8_32 { local tmp=simm8_32+Base+Index*ss; export tmp; } +addr32: [Base + simm8_32] is mod=1 & r_m=4; index=4 & Base; simm8_32 { local tmp=simm8_32+Base; export tmp; } +addr32: [Base + Index*ss] is mod=1 & r_m=4; Index & Base & ss; simm8=0 { local tmp=Base+Index*ss; export tmp; } +addr32: [Base] is mod=1 & r_m=4; index=4 & Base; simm8=0 { export Base; } +addr32: [Base + Index*ss + imm32] is mod=2 & r_m=4; Index & Base & ss; imm32 { local tmp=imm32+Base+Index*ss; export tmp; } +addr32: [Base + imm32] is mod=2 & r_m=4; index=4 & Base; imm32 { local tmp=imm32+Base; export tmp; } +addr32: [Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32=0 { local tmp=Base+Index*ss; export tmp; } +addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export Base; } +@ifdef IA64 +addr32: [pcRelSimm32] is bit64=1 & mod=0 & r_m=4; index=4 & base=5; pcRelSimm32 { export *[const]:4 pcRelSimm32; } + +Addr32_64: [pcRelSimm32] is $(LONGMODE_ON) & mod=0 & r_m=5; pcRelSimm32 { export *[const]:8 pcRelSimm32; } +Addr32_64: [imm32] is $(LONGMODE_ON) & mod=0 & r_m=4; index=4 & base=5; imm32 { export *[const]:8 imm32; } +Addr32_64: addr32 is addr32 { tmp:8 = sext(addr32); export tmp; } + +@endif + +# 64-bit addressing modes (the offset portion) + +@ifdef IA64 +addr64: [Rmr64] is mod=0 & Rmr64 { export Rmr64; } +addr64: [Rmr64 + simm8_64] is mod=1 & Rmr64; simm8_64 { local tmp=Rmr64+simm8_64; export tmp; } +addr64: [Rmr64 + simm32_64] is mod=2 & Rmr64; simm32_64 { local tmp=Rmr64+simm32_64; export tmp; } +addr64: [Rmr64] is mod=1 & r_m!=4 & Rmr64; simm8=0 { export Rmr64; } +addr64: [Rmr64] is mod=2 & r_m!=4 & Rmr64; simm32=0 { export Rmr64; } +addr64: [pcRelSimm32] is mod=0 & r_m=5; pcRelSimm32 { export *[const]:8 pcRelSimm32; } +addr64: [Base64 + Index64*ss] is mod=0 & r_m=4; Index64 & Base64 & ss { local tmp=Base64+Index64*ss; export tmp; } +addr64: [Base64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & Base64 { export Base64; } +addr64: [simm32_64 + Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; simm32_64 { local tmp=simm32_64+Index64*ss; export tmp; } +addr64: [Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; imm32=0 { local tmp=Index64*ss; export tmp; } +addr64: [simm32_64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & base64=5; simm32_64 { export *[const]:8 simm32_64; } +addr64: [Base64 + simm8_64] is mod=1 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm8_64 { local tmp=simm8_64+Base64; export tmp; } +addr64: [Base64 + Index64*ss + simm8_64] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8_64 { local tmp=simm8_64+Base64+Index64*ss; export tmp; } +addr64: [Base64 + Index64*ss] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8=0 { local tmp=Base64+Index64*ss; export tmp; } +addr64: [Base64 + simm32_64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm32_64 { local tmp=simm32_64+Base64; export tmp; } +addr64: [Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; imm32=0 { export Base64; } +addr64: [Base64 + Index64*ss + simm32_64] is mod=2 & r_m=4; Index64 & Base64 & ss; simm32_64 { local tmp=simm32_64+Base64+Index64*ss; export tmp; } +addr64: [Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; imm32=0 { local tmp=Base64+Index64*ss; export tmp; } +@endif + +currentCS: CS is protectedMode=0 & CS { tmp:4 = (inst_next >> 4) & 0xf000; CS = tmp:2; export CS; } +currentCS: CS is protectedMode=1 & CS { tmp:4 = (inst_next >> 16) & 0xffff; CS = tmp:2; export CS; } + +segWide: is segover=0 { export 0:$(SIZE); } +segWide: CS: is segover=1 & CS { export 0:$(SIZE); } +segWide: SS: is segover=2 & SS { export 0:$(SIZE); } +segWide: DS: is segover=3 & DS { export 0:$(SIZE); } +segWide: ES: is segover=4 & ES { export 0:$(SIZE); } +segWide: FS: is segover=5 & FS { export FS_OFFSET; } +segWide: GS: is segover=6 & GS { export GS_OFFSET; } + +seg16: is segover=0 { export DS; } +seg16: currentCS: is segover=1 & currentCS { export currentCS; } +seg16: SS: is segover=2 & SS { export SS; } +seg16: DS: is segover=3 & DS { export DS; } +seg16: ES: is segover=4 & ES { export ES; } +seg16: FS: is segover=5 & FS { export FS; } +seg16: GS: is segover=6 & GS { export GS; } + +Mem16: addr16 is (segover=0 & mod=0 & r_m=2) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=0 & r_m=3) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=1 & r_m=2) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=1 & r_m=3) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=1 & r_m=6) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=2 & r_m=2) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=2 & r_m=3) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: addr16 is (segover=0 & mod=2 & r_m=6) ... & addr16 { tmp:$(SIZE) = segment(SS,addr16); export tmp; } +Mem16: seg16^addr16 is seg16; addr16 { tmp:$(SIZE) = segment(seg16,addr16); export tmp; } + +Mem: Mem16 is addrsize=0 & Mem16 { export Mem16; } + +@ifdef IA64 +Mem: segWide^Addr32_64 is $(LONGMODE_ON) & addrsize=1 & segWide; Addr32_64 { export Addr32_64; } +Mem: segWide^Addr32_64 is $(LONGMODE_ON) & addrsize=1 & segWide & highseg=1; Addr32_64 { tmp:8 = segWide + Addr32_64; export tmp; } +Mem: segWide^addr64 is $(LONGMODE_ON) & addrsize=2 & segWide; addr64 { export addr64; } +Mem: segWide^addr64 is $(LONGMODE_ON) & addrsize=2 & segWide & highseg=1; addr64 { tmp:$(SIZE) = segWide + addr64; export tmp; } +Mem: segWide^addr32 is $(LONGMODE_OFF) & addrsize=1 & segWide; addr32 { tmp:$(SIZE) = zext(addr32); export tmp; } +@else +Mem: segWide^addr32 is $(LONGMODE_OFF) & addrsize=1 & segWide; addr32 { export addr32; } +@endif +Mem: segWide^addr32 is $(LONGMODE_OFF) & addrsize=1 & segWide & highseg=1; addr32 { tmp:$(SIZE) = segWide + zext(addr32); export tmp; } + +rel8: reloc is simm8 [ reloc=inst_next+simm8; ] { export *[ram]:$(SIZE) reloc; } +rel16: reloc is simm16 [ reloc=((inst_next >> 16) << 16) | ((inst_next + simm16) & 0xFFFF); ] { export *[ram]:$(SIZE) reloc; } +rel32: reloc is simm32 [ reloc=inst_next+simm32; ] { export *[ram]:$(SIZE) reloc; } + + +m8: "byte ptr" Mem is Mem { export *:1 Mem; } +m16: "word ptr" Mem is Mem { export *:2 Mem; } +m32: "dword ptr" Mem is Mem { export *:4 Mem; } +m64: "qword ptr" Mem is Mem { export *:8 Mem; } +# m80: Mem is Mem { export *:10 Mem; } +m128: "xmmword ptr" Mem is Mem { export *:16 Mem; } +m256: "ymmword ptr" Mem is Mem { export *:32 Mem; } + +# spec versions of the m8/m16/m32/... tables explicitly print the operand size +spec_m8: "byte ptr "^Mem is Mem { export *:1 Mem; } +spec_m16: "word ptr "^Mem is Mem { export *:2 Mem; } +spec_m32: "dword ptr "^Mem is Mem { export *:4 Mem; } +spec_m64: "qword ptr "^Mem is Mem { export *:8 Mem; } +spec_m80: "tword ptr "^Mem is Mem { export *:10 Mem; } +# spec_m128: "16-byte ptr "^Mem is Mem { export *:16 Mem; } +# spec_m512: "64-byte ptr "^Mem is Mem { export *:64 Mem; } + + + +## +## VSIB +## + +vaddr32x: [Base + Xmm_vsib*ss] is mod=0 & r_m=4; Xmm_vsib & Base & ss { } +vaddr32x: [Xmm_vsib*ss + simm32_32] is mod=0 & r_m=4; Xmm_vsib & base=5 & ss; simm32_32 { } +vaddr32x: [Base + Xmm_vsib*ss + simm8_32] is mod=1 & r_m=4; Xmm_vsib & Base & ss; simm8_32 { } +vaddr32x: [Base + Xmm_vsib*ss + simm32_32] is mod=2 & r_m=4; Xmm_vsib & Base & ss; simm32_32 { } + +vaddr32y: [Base + Ymm_vsib*ss] is mod=0 & r_m=4; Ymm_vsib & Base & ss { } +vaddr32y: [Ymm_vsib*ss + simm32_32] is mod=0 & r_m=4; Ymm_vsib & base=5 & ss; simm32_32 { } +vaddr32y: [Base + Ymm_vsib*ss + simm8_32] is mod=1 & r_m=4; Ymm_vsib & Base & ss; simm8_32 { } +vaddr32y: [Base + Ymm_vsib*ss + simm32_32] is mod=2 & r_m=4; Ymm_vsib & Base & ss; simm32_32 { } + +@ifdef IA64 +vaddr64x: [Base64 + Xmm_vsib*ss] is mod=0 & r_m=4; Xmm_vsib & Base64 & ss { } +vaddr64x: [Xmm_vsib*ss + simm32_64] is mod=0 & r_m=4; Xmm_vsib & base64=5 & ss; simm32_64 { } +vaddr64x: [Base64 + Xmm_vsib*ss + simm8_64] is mod=1 & r_m=4; Xmm_vsib & Base64 & ss; simm8_64 { } +vaddr64x: [Base64 + Xmm_vsib*ss + simm32_64] is mod=2 & r_m=4; Xmm_vsib & Base64 & ss; simm32_64 { } + +vaddr64y: [Base64 + Ymm_vsib*ss] is mod=0 & r_m=4; Ymm_vsib & Base64 & ss { } +vaddr64y: [Ymm_vsib*ss + simm32_64] is mod=0 & r_m=4; Ymm_vsib & base64=5 & ss; simm32_64 { } +vaddr64y: [Base64 + Ymm_vsib*ss + simm8_64] is mod=1 & r_m=4; Ymm_vsib & Base64 & ss; simm8_64 { } +vaddr64y: [Base64 + Ymm_vsib*ss + simm32_64] is mod=2 & r_m=4; Ymm_vsib & Base64 & ss; simm32_64 { } +@endif + + +vMem32x: segWide^vaddr32x is addrsize=1 & segWide; vaddr32x { } +vMem32x: segWide^vaddr32x is addrsize=1 & segWide & highseg=1; vaddr32x { } + +vMem32y: segWide^vaddr32y is addrsize=1 & segWide; vaddr32y { } +vMem32y: segWide^vaddr32y is addrsize=1 & segWide & highseg=1; vaddr32y { } + +@ifdef IA64 +# GAS always inserts a 0x67 prefix before a VSIB instruction with a 32-bit base. +# Behavior is coded to match Binutils; exceeds what the manual indicates is possible. +vMem32x: segWide^vaddr64x is addrsize=2 & segWide; vaddr64x { } +vMem32x: segWide^vaddr64x is addrsize=2 & segWide & highseg=1; vaddr64x { } + +# GAS always inserts a 0x67 prefix before a VSIB instruction with a 32-bit base. +# Behavior is coded to match Binutils; exceeds what the manual indicates is possible. +vMem32y: segWide^vaddr64y is addrsize=2 & segWide; vaddr64y { } +vMem32y: segWide^vaddr64y is addrsize=2 & segWide & highseg=1; vaddr64y { } + +# GAS always inserts a 0x67 prefix before a VSIB instruction with a 32-bit base. +# Behavior is coded to match Binutils; exceeds what the manual indicates is possible. +vMem64x: segWide^vaddr32x is addrsize=1 & segWide; vaddr32x { } +vMem64x: segWide^vaddr32x is addrsize=1 & segWide & highseg=1; vaddr32x { } + +vMem64x: segWide^vaddr64x is addrsize=2 & segWide; vaddr64x { } +vMem64x: segWide^vaddr64x is addrsize=2 & segWide & highseg=1; vaddr64x { } + +# GAS always inserts a 0x67 prefix before a VSIB instruction with a 32-bit base. +# Behavior is coded to match Binutils; exceeds what the manual indicates is possible. +vMem64y: segWide^vaddr32y is addrsize=1 & segWide; vaddr32y { } +vMem64y: segWide^vaddr32y is addrsize=1 & segWide & highseg=1; vaddr32y { } + +vMem64y: segWide^vaddr64y is addrsize=2 & segWide; vaddr64y { } +vMem64y: segWide^vaddr64y is addrsize=2 & segWide & highseg=1; vaddr64y { } +@endif + + +d_vm32x: "dword ptr "^vMem32x is vMem32x { } +d_vm32y: "dword ptr "^vMem32y is vMem32y { } + +@ifdef IA64 +d_vm64x: "dword ptr "^vMem64x is vMem64x { } +d_vm64y: "dword ptr "^vMem64y is vMem64y { } +@endif + + +q_vm32x: "qword ptr "^vMem32x is vMem32x { } +# not used q_vm32y: "qword ptr "^vMem32y is vMem32y { } + +@ifdef IA64 +q_vm64x: "qword ptr "^vMem64x is vMem64x { } +q_vm64y: "qword ptr "^vMem64y is vMem64y { } +@endif + +Reg32_m8: Rmr32 is mod=3 & Rmr32 { export Rmr32; } +Reg32_m8: m8 is m8 { local tmp:4 = zext(m8); export tmp; } +Reg32_m16: Rmr32 is mod=3 & Rmr32 { export Rmr32; } +Reg32_m16: m16 is m16 { local tmp:4 = zext(m16); export tmp; } + +mmxreg2_m64: mmxreg2 is mod=3 & mmxreg2 { export mmxreg2; } +mmxreg2_m64: m64 is m64 { export m64; } + +XmmReg2_m8: XmmReg2 is mod=3 & XmmReg2 { export XmmReg2; } +XmmReg2_m8: m8 is m8 { local tmp:16 = zext(m8); export tmp; } +XmmReg2_m16: XmmReg2 is mod=3 & XmmReg2 { export XmmReg2; } +XmmReg2_m16: m16 is m16 { local tmp:16 = zext(m16); export tmp; } +XmmReg2_m32: XmmReg2 is mod=3 & XmmReg2 { export XmmReg2; } +XmmReg2_m32: m32 is m32 { local tmp:16 = zext(m32); export tmp; } +XmmReg2_m64: XmmReg2 is mod=3 & XmmReg2 { export XmmReg2; } +XmmReg2_m64: m64 is m64 { local tmp:16 = zext(m64); export tmp; } +XmmReg2_m128: XmmReg2 is mod=3 & XmmReg2 { export XmmReg2; } +XmmReg2_m128: m128 is m128 { export m128; } + +YmmReg2_m256: YmmReg2 is mod=3 & YmmReg2 { export YmmReg2; } +YmmReg2_m256: m256 is m256 { export m256; } + +moffs8: seg16^[imm16] is addrsize=0 & seg16 & imm16 { tmp:$(SIZE) = segment(seg16,imm16:2); export *:1 tmp; } +moffs8: segWide^[imm32] is addrsize=1 & highseg=1 & segWide & imm32 { tmp:$(SIZE) = segWide + imm32; export *:1 tmp; } +moffs8: segWide^[imm32] is addrsize=1 & segWide & imm32 { export *:1 imm32; } +@ifdef IA64 +moffs8: segWide^[imm64] is addrsize=2 & highseg=1 & segWide & imm64 { tmp:8 = segWide + imm64; export *:1 tmp; } +moffs8: segWide^[imm64] is addrsize=2 & segWide & imm64 { export *:1 imm64; } +@endif +moffs16: seg16^[imm16] is addrsize=0 & seg16 & imm16 { tmp:$(SIZE) = segment(seg16,imm16:2); export *:2 tmp; } +moffs16: segWide^[imm32] is addrsize=1 & highseg=1 & segWide & imm32 { tmp:$(SIZE) = segWide + imm32; export *:2 tmp; } +moffs16: segWide^[imm32] is addrsize=1 & segWide & imm32 { export *:2 imm32; } +@ifdef IA64 +moffs16: segWide^[imm64] is addrsize=2 & highseg=1 & segWide & imm64 { tmp:8 = segWide + imm64; export *:2 tmp; } +moffs16: segWide^[imm64] is addrsize=2 & segWide & imm64 { export *:2 imm64; } +@endif + +moffs32: seg16^[imm16] is addrsize=0 & seg16 & imm16 { tmp:$(SIZE) = segment(seg16,imm16:2); export *:4 tmp; } +moffs32: segWide^[imm32] is addrsize=1 & segWide & imm32 { export *:4 imm32; } +moffs32: segWide^[imm32] is addrsize=1 & highseg=1 & segWide & imm32 { tmp:$(SIZE) = segWide + imm32; export *:4 tmp; } +@ifdef IA64 +moffs32: segWide^[imm64] is addrsize=2 & segWide & imm64 { export *:4 imm64; } +moffs32: segWide^[imm64] is addrsize=2 & highseg=1 & segWide & imm64 { tmp:8 = segWide + imm64; export *:4 tmp; } +@endif + +@ifdef IA64 +moffs64: segWide^[imm64] is addrsize=2 & segWide & imm64 { export *:8 imm64; } +moffs64: segWide^[imm64] is addrsize=2 & highseg=1 & segWide & imm64 { tmp:8 = segWide + imm64; export *:8 tmp; } +moffs64: segWide^[imm32] is addrsize=1 & segWide & imm32 { export *:8 imm32; } +moffs64: segWide^[imm32] is addrsize=1 & highseg=1 & segWide & imm32 { tmp:8 = segWide + imm32; export *:8 tmp; } +@endif +# TODO: segment register offset in 64bit might not be right + +# String memory access +dseSI1: seg16^SI is addrsize=0 & seg16 & SI { tmp:4 = segment(seg16,SI); SI = SI + 1-2*zext(DF); export *:1 tmp; } +dseSI1: segWide^ESI is addrsize=1 & segWide & ESI { tmp:4 = ESI; ESI = ESI + 1-2*zext(DF); export *:1 tmp; } +dseSI2: seg16^SI is addrsize=0 & seg16 & SI { tmp:4 = segment(seg16,SI); SI = SI + 2-4*zext(DF); export *:2 tmp; } +dseSI2: segWide^ESI is addrsize=1 & segWide & ESI { tmp:4 = ESI; ESI = ESI + 2-4*zext(DF); export *:2 tmp; } +dseSI4: seg16^SI is addrsize=0 & seg16 & SI { tmp:4 = segment(seg16,SI); SI = SI + 4-8*zext(DF); export *:4 tmp; } +dseSI4: segWide^ESI is addrsize=1 & segWide & ESI { tmp:4 = ESI; ESI = ESI + 4-8*zext(DF); export *:4 tmp; } +eseDI1: ES:DI is addrsize=0 & ES & DI { tmp:4 = segment(ES,DI); DI = DI + 1-2*zext(DF); export *:1 tmp; } +eseDI1: ES:EDI is addrsize=1 & ES & EDI { tmp:4 = EDI; EDI=EDI+1-2*zext(DF); export *:1 tmp; } +eseDI2: ES:DI is addrsize=0 & ES & DI { tmp:4 = segment(ES,DI); DI = DI + 2-4*zext(DF); export *:2 tmp; } +eseDI2: ES:EDI is addrsize=1 & ES & EDI { tmp:4 = EDI; EDI=EDI+2-4*zext(DF); export *:2 tmp; } +eseDI4: ES:DI is addrsize=0 & ES & DI { tmp:4 = segment(ES,DI); DI = DI + 4-8*zext(DF); export *:4 tmp; } +eseDI4: ES:EDI is addrsize=1 & ES & EDI { tmp:4 = EDI; EDI=EDI+4-8*zext(DF); export *:4 tmp; } + +@ifdef IA64 +# quadword string functions +dseSI8: seg16^SI is addrsize=0 & seg16 & SI { tmp:4 = segment(seg16,SI); SI = SI + 8-16*zext(DF); export *:8 tmp; } +dseSI8: segWide^ESI is addrsize=1 & segWide & ESI { tmp:4 = ESI; ESI = ESI + 8-16*zext(DF); export *:8 tmp; } +eseDI8: ES:DI is addrsize=0 & ES & DI { tmp:4 = segment(ES,DI); DI = DI + 8-16*zext(DF); export *:8 tmp; } +eseDI8: ES:EDI is addrsize=1 & ES & EDI { tmp:4 = EDI; EDI=EDI+8-16*zext(DF); export *:8 tmp; } + +dseSI1: RSI is addrsize=2 & RSI { local tmp = RSI; RSI = RSI + 1-2*zext(DF); export *:1 tmp; } +dseSI2: RSI is addrsize=2 & RSI { local tmp = RSI; RSI = RSI + 2-4*zext(DF); export *:2 tmp; } +dseSI4: RSI is addrsize=2 & RSI { local tmp = RSI; RSI = RSI + 4-8*zext(DF); export *:4 tmp; } +dseSI8: RSI is addrsize=2 & RSI { local tmp = RSI; RSI = RSI + 8-16*zext(DF); export *:8 tmp; } +eseDI1: RDI is addrsize=2 & RDI { local tmp = RDI; RDI=RDI+1-2*zext(DF); export *:1 tmp; } +eseDI2: RDI is addrsize=2 & RDI { local tmp = RDI; RDI=RDI+2-4*zext(DF); export *:2 tmp; } +eseDI4: RDI is addrsize=2 & RDI { local tmp = RDI; RDI=RDI+4-8*zext(DF); export *:4 tmp; } +eseDI8: RDI is addrsize=2 & RDI { local tmp = RDI; RDI=RDI+8-16*zext(DF); export *:8 tmp; } +@endif + +rm8: Rmr8 is mod=3 & Rmr8 { export Rmr8; } +rm8: "byte ptr" Mem is Mem { export *:1 Mem; } + +spec_rm8: Rmr8 is mod=3 & Rmr8 { export Rmr8; } +spec_rm8: "byte ptr "^Mem is Mem { export *:1 Mem; } + +rm16: Rmr16 is mod=3 & Rmr16 { export Rmr16; } +rm16: "word ptr" Mem is Mem { export *:2 Mem; } + +spec_rm16: Rmr16 is mod=3 & Rmr16 { export Rmr16; } +spec_rm16: "word ptr "^Mem is Mem { export *:2 Mem; } + +rm32: Rmr32 is mod=3 & Rmr32 { export Rmr32; } +rm32: "dword ptr" Mem is Mem { export *:4 Mem; } + +spec_rm32: Rmr32 is mod=3 & Rmr32 { export Rmr32; } +spec_rm32: "dword ptr "^Mem is Mem { export *:4 Mem; } + +@ifdef IA64 +rm64: Rmr64 is mod=3 & Rmr64 { export Rmr64; } +rm64: "qword ptr" Mem is Mem { export *:8 Mem; } + +spec_rm64: Rmr64 is mod=3 & Rmr64 { export Rmr64; } +spec_rm64: "qword ptr "^Mem is Mem { export *:8 Mem; } +@endif + +n1: one is epsilon [ one = 1; ] { export *[const]:1 one; } + +@ifdef IA64 +# Handle zero extension in 64-bit mode for 32-bit destination registers +check_Reg32_dest: is $(LONGMODE_ON) & Reg32 & Reg64 { Reg64 = zext(Reg32); } +check_Rmr32_dest: is $(LONGMODE_ON) & Rmr32 & Rmr64 { Rmr64 = zext(Rmr32); } +check_rm32_dest: is $(LONGMODE_ON) & mod=3 & check_Rmr32_dest { build check_Rmr32_dest; } + +check_Rmr16_dest: is $(LONGMODE_ON) & Rmr16 & Rmr64 { Rmr64 = zext(Rmr16); } +check_rm16_dest: is $(LONGMODE_ON) & mod=3 & check_Rmr16_dest { build check_Rmr16_dest; } + +check_EAX_dest: is $(LONGMODE_ON) { RAX = zext(EAX); } +check_EDX_dest: is $(LONGMODE_ON) { RDX = zext(EDX); } +check_vexVVVV_r32_dest: is $(LONGMODE_ON) & vexVVVV_r64 & vexVVVV_r32 { vexVVVV_r64 = zext(vexVVVV_r32);} +@endif +check_Reg32_dest: is epsilon { } +check_Rmr32_dest: is epsilon { } + +check_Rmr16_dest: is $(LONGMODE_OFF) & Rmr16 & Rmr32 { Rmr32 = zext(Rmr16); } +check_rm16_dest: is $(LONGMODE_OFF) & mod=3 & check_Rmr16_dest { build check_Rmr16_dest; } +check_Rmr16_dest: is epsilon { } +check_rm16_dest: is epsilon { } + +check_EAX_dest: is epsilon { } +check_EDX_dest: is epsilon { } +check_vexVVVV_r32_dest: is epsilon { } +check_rm32_dest: is epsilon { } + + +ptr1616: reloc is protectedMode=0 & imm16; j16 [ reloc = j16*0x10 + imm16; ] { CS = j16; export *[ram]:4 reloc; } +ptr1616: reloc is protectedMode=1 & imm16; j16 [ reloc = j16*0x10000 + imm16; ] { CS = j16; export *[ram]:4 reloc; } +ptr1632: j16":"imm32 is imm32; j16 { CS = j16; export *:4 imm32; } + +# conditions + +cc: "O" is cond=0 { export OF; } +cc: "NO" is cond=1 { local tmp = !OF; export tmp; } +cc: "C" is cond=2 { export CF; } +cc: "NC" is cond=3 { local tmp = !CF; export tmp; } +cc: "Z" is cond=4 { export ZF; } +cc: "NZ" is cond=5 { local tmp = !ZF; export tmp; } +cc: "BE" is cond=6 { local tmp = CF || ZF; export tmp; } +cc: "A" is cond=7 { local tmp = !(CF || ZF); export tmp; } +cc: "S" is cond=8 { export SF; } +cc: "NS" is cond=9 { local tmp = !SF; export tmp; } +cc: "P" is cond=10 { export PF; } +cc: "NP" is cond=11 { local tmp = !PF; export tmp; } +cc: "L" is cond=12 { local tmp = OF != SF; export tmp; } +cc: "GE" is cond=13 { local tmp = OF == SF; export tmp; } +cc: "LE" is cond=14 { local tmp = ZF || (OF != SF); export tmp; } +cc: "G" is cond=15 { local tmp = !ZF && (OF == SF); export tmp; } + +# repeat prefixes +rep_check: is addrsize=0 { if (CX==0) goto inst_next; } +rep_check: is addrsize=1 { if (ECX==0) goto inst_next; } +@ifdef IA64 +rep_check: is addrsize=2 { if (RCX==0) goto inst_next; } +@endif + +rep_update: is addrsize=0 { CX=CX-1; } +rep_update: is addrsize=1 { ECX=ECX-1; } +@ifdef IA64 +rep_update: is addrsize=2 { RCX=RCX-1; } +@endif + +rep: ".REP" is repprefx=1 & repneprefx=0 & rep_check { } +rep: ".REPNE" is repprefx=0 & repneprefx=1 & rep_check { } # Although undocumented, either rep prefix is allowed but ZF is always ignored +rep: is repprefx=0 & repneprefx=0 { } + + +reptail: is (repprefx=1 | repneprefx=1) & rep_update { goto inst_start; } +reptail: is repprefx=0 & repneprefx=0 { } + +repe: ".REPE" is repprefx=1 & repneprefx=0 & rep_check { } +repe: ".REPNE" is repprefx=0 & repneprefx=1 & rep_check { } +repe: is repprefx=0 & repneprefx=0 { } + +repetail: is repprefx=1 & repneprefx=0 & rep_update { if (ZF) goto inst_start; } +repetail: is repprefx=0 & repneprefx=1 & rep_update { if (!ZF) goto inst_start; } +repetail: is repprefx=0 & repneprefx=0 { } + +# XACQUIRE/XRELEASE prefix +xacq_xrel_prefx: ".XACQUIRE" is xacquireprefx=1 & xreleaseprefx=0 { XACQUIRE(); } +xacq_xrel_prefx: ".XRELEASE" is xacquireprefx=0 & xreleaseprefx=1 { XRELEASE(); } +xacq_xrel_prefx: is epsilon { } + +#the XRELEASE prefix can be used with several variants of MOV (without the LOCK prefix) +xrelease: ".XRELEASE" is xacquireprefx=0 & xreleaseprefx=1 { XRELEASE(); } +xrelease: is epsilon { } + +#XCHG with a memory destination asserts a LOCK signal whether or not there is a LOCK prefix (f0) +#"alwaysLock" constructor will place "LOCK" in the disassembly if the prefix occurs +alwaysLock: ".LOCK" is lockprefx=1 { LOCK(); } +alwaysLock: is epsilon { LOCK(); } + +#check for LOCK prefix and the optional XACQUIRE/XRELEASE +lockx: xacq_xrel_prefx^".LOCK" is lockprefx=1 & xacq_xrel_prefx { build xacq_xrel_prefx; LOCK(); } +lockx: is epsilon { } + +#"unlock" constructor is used to pair every LOCK pcodeop with a matching UNLOCK pcodeop +unlock: is lockprefx=1 { UNLOCK(); } +unlock: is epsilon { } + +# Some macros + +@include "macros.sinc" + +macro ptr2(r,x) { + r = zext(x); +} + +macro ptr4(r,x) { +@ifdef IA64 + r = zext(x); +@else + r = x; +@endif +} + +macro ptr8(r,x) { +@ifdef IA64 + r = x; +@else + r = x:$(SIZE); +@endif +} + +macro push22(x) { + mysave:2 = x; + SP = SP -2; + tmp:$(SIZE) = segment(SS,SP); + *:2 tmp = mysave; +} + +macro push24(x) { + mysave:4 = x; + SP = SP-4; + tmp:$(SIZE) = segment(SS,SP); + *:4 tmp = mysave; +} + +macro push28(x) { + mysave:8 = x; + SP = SP-8; + tmp:$(SIZE) = segment(SS,SP); + *:8 tmp = mysave; +} + +macro push42(x) { + mysave:2 = x; + $(STACKPTR) = $(STACKPTR) - 2; + *:2 $(STACKPTR) = mysave; +} + +macro push44(x) { + mysave:4 = x; + $(STACKPTR) = $(STACKPTR) - 4; + *:4 $(STACKPTR) = mysave; +} + +macro pushseg44(x) { + mysave:2 = x; + $(STACKPTR) = $(STACKPTR) - 4; + *:2 $(STACKPTR) = mysave; +} + +macro push48(x) { + mysave:8 = x; + $(STACKPTR) = $(STACKPTR) - 8; + *:8 $(STACKPTR) = mysave; +} + +@ifdef IA64 +macro push82(x) { + mysave:2 = x; + $(STACKPTR) = $(STACKPTR) - 2; + *:2 $(STACKPTR) = mysave; +} + +macro push84(x) { + mysave:4 = x; + $(STACKPTR) = $(STACKPTR) - 4; + *:4 $(STACKPTR) = mysave; +} + +macro push88(x) { + mysave:8 = x; + $(STACKPTR) = $(STACKPTR) - 8; + *:8 $(STACKPTR) = mysave; +} + +macro pushseg82(x) { + mysave:2 = x; + $(STACKPTR) = $(STACKPTR) - 2; + *:2 $(STACKPTR) = mysave; +} + +macro pushseg88(x) { + mysave:2 = x; + $(STACKPTR) = $(STACKPTR) - 8; + *:2 $(STACKPTR) = mysave; +} +@endif + +# Note: for each pop operation we are careful to order the operations such that is correct for +# both 'POP [RSP + offset]' and 'POP RSP' + +macro pop22(x) { + tmp:$(SIZE) = segment(SS,SP); + value = *:2 tmp; + SP = SP+2; + x = value; +} + +macro pop24(x) { + tmp:$(SIZE) = segment(SS,SP); + value = *:4 tmp; + SP = SP+4; + x = value; +} + +macro pop28(x) { + tmp:$(SIZE) = segment(SS,SP); + value = *:8 tmp; + SP = SP+8; + x = value; +} + +macro pop42(x) { + value = *:2 $(STACKPTR); + ESP = ESP + 2; + x = value; +} + +macro pop44(x) { + value = *:4 $(STACKPTR); + ESP = ESP + 4; + x = value; +} + +macro popseg44(x) { + value = *:2 $(STACKPTR); + ESP = ESP + 4; + x = value; +} + +macro pop48(x) { + value = *:8 $(STACKPTR); + ESP = ESP + 8; + x = value; +} + +@ifdef IA64 +macro pop82(x) { + value = *:2 $(STACKPTR); + RSP = RSP + 2; + x = value; +} + +macro pop84(x) { + value = *:4 $(STACKPTR); + RSP = RSP + 4; + x = value; +} + +macro pop88(x) { + value = *:8 $(STACKPTR); + RSP = RSP + 8; + x = value; +} + +macro popseg82(x) { + value = *:2 $(STACKPTR); + RSP = RSP + 2; + x = value; +} + +macro popseg88(x) { + value = *:2 $(STACKPTR); + RSP = RSP + 8; + x = value; +} + +@endif + +macro unpackflags(tmp) { + NT = (tmp & 0x4000) != 0; +# IOPL = (tmp & 0x1000) != 0; + OF = (tmp & 0x0800) != 0; + DF = (tmp & 0x0400) != 0; + IF = (tmp & 0x0200) != 0; + TF = (tmp & 0x0100) != 0; + SF = (tmp & 0x0080) != 0; + ZF = (tmp & 0x0040) != 0; + AF = (tmp & 0x0010) != 0; + PF = (tmp & 0x0004) != 0; + CF = (tmp & 0x0001) != 0; +} + +macro unpackeflags(tmp) { + ID = (tmp & 0x00200000) != 0; + AC = (tmp & 0x00040000) != 0; +# RF = (tmp & 0x00010000) != 0; + VIP = 0; + VIF = 0; +} + +macro packflags(tmp) { + tmp= (0x4000 * zext(NT&1)) +# | (0x1000 * zext(IOPL&1)) + | (0x0800 * zext(OF&1)) + | (0x0400 * zext(DF&1)) | (0x0200 * zext(IF&1)) | (0x0100 * zext(TF&1)) + | (0x0080 * zext(SF&1)) | (0x0040 * zext(ZF&1)) | (0x0010 * zext(AF&1)) + | (0x0004 * zext(PF&1)) | (0x0001 * zext(CF&1)); +} + +macro packeflags(tmp) { + tmp = tmp | (0x00200000 * zext(ID&1)) | (0x00100000 * zext(VIP&1)) + | (0x00080000 * zext(VIF&1)) | (0x00040000 * zext(AC&1)); +} + +macro addflags(op1,op2) { + CF = carry(op1,op2); + OF = scarry(op1,op2); +} + +# +# full-adder carry and overflow calculations +# +macro addCarryFlags ( op1, op2 ) { + local CFcopy = zext(CF); + CF = carry( op1, op2 ); + OF = scarry( op1, op2 ); + local result = op1 + op2; + CF = CF || carry( result, CFcopy ); + OF = OF ^^ scarry( result, CFcopy ); + op1 = result + CFcopy; + # AF not implemented +} + + +macro subCarryFlags ( op1, op2 ) { + local CFcopy = zext(CF); + CF = op1 < op2; + OF = sborrow( op1, op2 ); + local result = op1 - op2; + CF = CF || (result < CFcopy); + OF = OF ^^ sborrow( result, CFcopy ); + op1 = result - CFcopy; + # AF not implemented +} + +macro resultflags(result) { + SF = result s< 0; + ZF = result == 0; + PF = ((popcount(result & 0xff) & 1:1) == 0); + # AF not implemented +} + +macro shiftresultflags(result,count) { + + local notzero = (count != 0); + + local newSF = (result s< 0); + SF = (!notzero && SF) || (notzero && newSF); + + local newZF = (result == 0); + ZF = (!notzero && ZF) || (notzero && newZF); + + local newPF = ((popcount(result & 0xff) & 1:1) == 0); + PF = (!notzero && PF) || (notzero && newPF); + # AF not implemented +} + +macro subflags(op1,op2) { + CF = op1 < op2; + OF = sborrow(op1,op2); +} + +macro negflags(op1) { + CF = (op1 != 0); + OF = sborrow(0,op1); +} + +macro logicalflags() { + CF = 0; + OF = 0; +} + +macro imultflags(low,total){ + CF = sext(low) != total; + OF = CF; +} + +macro multflags(highhalf) { + CF = highhalf != 0; + OF = CF; +} + +macro rolflags(result,count) { + + local notzero = (count != 0); + local newCF = ((result & 1) != 0); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + local newOF = CF ^^ (result s< 0); + OF = (!one && OF) || (one && newOF); +} + +macro rorflags(result,count) { + + local notzero = (count != 0); + local newCF = (result s< 0); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + local newOF = (result s< 0) ^^ ((result << 1) s< 0); + OF = (!one && OF) || (one && newOF); +} + +macro shlflags(op1,result,count) { # works for shld also + + local notzero = (count != 0); + local newCF = ( (op1 << (count - 1)) s< 0 ); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + local newOF = CF ^^ (result s< 0); + OF = (!one && OF) || (one && newOF); +} + +macro sarflags(op1,result,count) { + + local notzero = (count != 0); + local newCF = ( ( (op1 s>> (count - 1)) & 1 ) != 0 ); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + OF = (!one && OF); +} + +macro shrflags(op1,result,count) { + + local notzero = (count != 0); + local newCF = ( ( (op1 >> (count - 1)) & 1 ) != 0 ); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + local newOF = (op1 s< 0); + OF = (!one && OF) || (one && newOF); +} + +macro shrdflags(op1,result,count) { + + local notzero = (count != 0); + local newCF = ( ( (op1 >> (count - 1)) & 1 ) != 0 ); + CF = (!notzero && CF) || (notzero && newCF); + + local one = (count == 1); + local newOF = ((op1 s< 0) ^^ (result s< 0)); + OF = (!one && OF) || (one && newOF); +} + +macro fdec() { + local tmp = ST7; + ST7 = ST6; + ST6 = ST5; + ST5 = ST4; + ST4 = ST3; + ST3 = ST2; + ST2 = ST1; + ST1 = ST0; + ST0 = tmp; +} + +macro finc() { + local tmp = ST0; + ST0 = ST1; + ST1 = ST2; + ST2 = ST3; + ST3 = ST4; + ST4 = ST5; + ST5 = ST6; + ST6 = ST7; + ST7 = tmp; +} + +macro fpop() { + ST0 = ST1; + ST1 = ST2; + ST2 = ST3; + ST3 = ST4; + ST4 = ST5; + ST5 = ST6; + ST6 = ST7; +} + + macro fpushv(val) { + ST7 = ST6; + ST6 = ST5; + ST5 = ST4; + ST4 = ST3; + ST3 = ST2; + ST2 = ST1; + ST1 = ST0; + ST0 = val; +} + +macro fpopv(val) { + val = ST0; + ST0 = ST1; + ST1 = ST2; + ST2 = ST3; + ST3 = ST4; + ST4 = ST5; + ST5 = ST6; + ST6 = ST7; +} + +macro fcom(val) { + C1 = 0; + + C2 = nan(ST0) || nan(val); + C0 = C2 | ( ST0 f< val ); + C3 = C2 | ( ST0 f== val ); + + FPUStatusWord = (zext(C0)<<8) | (zext(C1)<<9) | (zext(C2)<<10) | (zext(C3)<<14); +} + +macro fcomi(val) { + PF = nan(ST0) || nan(val); + ZF = PF | ( ST0 f== val ); + CF = PF | ( ST0 f< val ); + + OF = 0; + AF = 0; + SF = 0; + + FPUStatusWord = FPUStatusWord & 0xfdff; # Clear C1 + C1 = 0; +} + +# floating point NaN comparison into EFLAGS +macro fucompe(val1, val2) { + PF = nan(val1) || nan(val2 ); + ZF = PF | ( val1 f== val2 ); + CF = PF | ( val1 f< val2 ); + + OF = 0; + AF = 0; + SF = 0; +} + +# The base level constructors +# The prefixes +:^instruction is instrPhase=0 & over=0x2e; instruction [ segover=1; ] {} # CS override +:^instruction is instrPhase=0 & over=0x36; instruction [ segover=2; ] {} # SS override +:^instruction is instrPhase=0 & over=0x3e; instruction [ segover=3; ] {} # DS override +:^instruction is instrPhase=0 & over=0x26; instruction [ segover=4; ] {} # ES override +:^instruction is instrPhase=0 & over=0x64; instruction [ segover=5; ] {} # FS override +:^instruction is instrPhase=0 & over=0x65; instruction [ segover=6; ] {} # GS override +:^instruction is instrPhase=0 & over=0x66; instruction [ opsize=opsize $xor 1; mandover = mandover $xor 1; ] {} # Operand size override +:^instruction is instrPhase=0 & over=0x67; instruction [ addrsize=addrsize $xor 1; ] {} # Address size override +:^instruction is instrPhase=0 & over=0xf2; instruction [ repneprefx=1; repprefx=0; ] {} +:^instruction is instrPhase=0 & over=0xf3; instruction [ repneprefx=0; repprefx=1; ] {} +:^instruction is instrPhase=0 & over=0xf0; instruction [ lockprefx=1; ] {} +@ifdef IA64 + +# +# REX opcode extension prefixes +# + +# REX prefix present +# Specification is "REX" +@define REX "longMode=1 & rexprefix=1 & rexWprefix=0" + +# Specification is "REX.W" +@define REX_W "longMode=1 & rexprefix=1 & rexWprefix=1" + + + +# TODO I don't think the following line can really happen because the 66 67 prefix must come before REX prefix +:^instruction is $(LONGMODE_ON) & instrPhase=0 & over=0x66 & opsize=2; instruction [ opsize=0; mandover=mandover $xor 1; ] {} # Operand size override +:^instruction is $(LONGMODE_ON) & instrPhase=0 & over=0x67 & addrsize=2; instruction [ addrsize=1; ] {} # Address size override + +:^instruction is $(LONGMODE_ON) & instrPhase=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=1; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & opsize=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=0; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & opsize=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} + + # if longmode is off (on 64-bit processor in 32-bit compatibility mode), there is no 64-bit addressing, make sure is off before parsing + # +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & addrsize=2 & instruction [ addrsize=1; ] {} +@endif + +# +# VEX definitions: One from each group must be present in the decoding; following the specification from the manual. +# + +# VEX encoding for type of VEX data flow. +# Specification is "VEX.", "VEX.NDS", "VEX.NDD", or "VEX.DDS". If only "VEX." is present, then "VEX_NONE" must be used. +@define VEX_NONE "vexMode=1 & vexVVVV=0" +@define VEX_NDS "vexMode=1" +@define VEX_NDD "vexMode=1" +@define VEX_DDS "vexMode=1" + +# Specification is "LIG", "LZ", "128", or "256". +@define VEX_LIG "vexL" +@define VEX_LZ "vexL=0" +@define VEX_L128 "vexL=0" +@define VEX_L256 "vexL=1" + +# These are only to be used with VEX or EVEX decoding, where only one "mandatory" prefix is encoded in the VEX or EVEX. +# If no prefix is specified, then VEX_PRE_NONE must be used. +# No other "physical" prefixes are allowed. +# Specification is "(empty)", "66", "F3", or "F2". If none of these are present (empty), then "VEX_PRE_NONE" must be used. +@define VEX_PRE_NONE "mandover=0" +@define VEX_PRE_66 "mandover=1" +@define VEX_PRE_F3 "mandover=2" +@define VEX_PRE_F2 "mandover=4" + +# Specification is "0F", "0F38", or "0F3A". +@define VEX_0F "vexMMMMM=1" +@define VEX_0F38 "vexMMMMM=2" +@define VEX_0F3A "vexMMMMM=3" + +# Specification is "WIG", "W0", or "W1". +@define VEX_WIG "rexWprefix" +@define VEX_W0 "rexWprefix=0" +@define VEX_W1 "rexWprefix=1" + + + +@ifdef IA64 + +# 64-bit 3-byte VEX +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_66=1; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f3=1; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f2=1; ] {} + +# 64-bit 2-byte VEX +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=0; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=1; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_66=1; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=2; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f3=1; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=3; instruction + [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f2=1; ] {} + +@endif + +# 32-bit 3-byte VEX +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction + [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction + [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_66=1; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction + [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f3=1; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction + [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f2=1; ] {} + +# 32-bit 2-byte VEX +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_x=1 & vex_vvvv & vex_l & vex_pp=0; instruction + [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_x=1 & vex_vvvv & vex_l & vex_pp=1; instruction + [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_66=1; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_x=1 & vex_vvvv & vex_l & vex_pp=2; instruction + [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f3=1; ] {} +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_x=1 & vex_vvvv & vex_l & vex_pp=3; instruction + [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f2=1; ] {} + + +# Many of the multimedia instructions have a "mandatory" prefix, either 0x66, 0xf2 or 0xf3 +# where the prefix really becomes part of the encoding. We collect the three possible prefixes of this +# sort in the mandover context variable so we can pattern all three at once + +# 3DNow pre-parse to isolate suffix byte into context (suffix3D) +# - general format: 0x0f 0x0f [sib] [displacement] +# - must determine number of bytes consumed by addressing modes +# TODO: determine supported prefixes? (e.g., 0x26) + +Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } + +:^instruction is instrPhase=0 & (byte=0x0f; byte=0x0f; XmmReg ... & m64; Suffix3D) ... & instruction ... [ instrPhase=1; ] { } +:^instruction is instrPhase=0 & (byte=0x0f; byte=0x0f; mmxmod=3; Suffix3D) ... & instruction ... [ instrPhase=1; ] { } + + +# Instructions in alphabetical order + +# See 'lockable.sinc' file for instructions that are lockable +with : lockprefx=0 { + +:AAA is $(LONGMODE_OFF) & vexMode=0 & byte=0x37 { local car = ((AL & 0xf) > 9) | AF; AL = (AL+6*car)&0xf; AH=AH+car; CF=car; AF=car; } +:AAD imm8 is $(LONGMODE_OFF) & vexMode=0 & byte=0xd5; imm8 { AL = AL + imm8*AH; AH=0; resultflags(AX); } +:AAM imm8 is $(LONGMODE_OFF) & vexMode=0 & byte=0xd4; imm8 { AH = AL/imm8; AL = AL % imm8; resultflags(AX); } +:AAS is $(LONGMODE_OFF) & vexMode=0 & byte=0x3f { local car = ((AL & 0xf) > 9) | AF; AL = (AL-6*car)&0xf; AH=AH-car; CF=car; AF=car; } + +# See 'lockable.sinc' for memory destination, lockable variants +:ADC AL,imm8 is vexMode=0 & byte=0x14; AL & imm8 { addCarryFlags( AL, imm8:1 ); resultflags( AL ); } +:ADC AX,imm16 is vexMode=0 & opsize=0 & byte=0x15; AX & imm16 { addCarryFlags( AX, imm16:2 ); resultflags( AX ); } +:ADC EAX,imm32 is vexMode=0 & opsize=1 & byte=0x15; EAX & check_EAX_dest & imm32 { addCarryFlags( EAX, imm32:4 ); build check_EAX_dest; resultflags( EAX ); } +@ifdef IA64 +:ADC RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x15; RAX & simm32 { addCarryFlags( RAX, simm32 ); resultflags( RAX ); } +@endif +:ADC Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=2; imm8 { addCarryFlags( Rmr8, imm8:1 ); resultflags( Rmr8 ); } +:ADC Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=2; imm16 { addCarryFlags( Rmr16, imm16:2 ); resultflags( Rmr16 ); } +:ADC Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=2; imm32 { addCarryFlags( Rmr32, imm32:4 ); build check_Rmr32_dest; resultflags( Rmr32 ); } +@ifdef IA64 +:ADC Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=2; simm32 { addCarryFlags( Rmr64, simm32 ); resultflags( Rmr64 ); } +@endif +:ADC Rmr16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=2; simm8_16 { addCarryFlags( Rmr16, simm8_16 ); resultflags( Rmr16 ); } +:ADC Rmr32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=2; simm8_32 { addCarryFlags( Rmr32, simm8_32 ); build check_Rmr32_dest; resultflags( Rmr32 ); } +@ifdef IA64 +:ADC Rmr64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=2; simm8_64 { addCarryFlags( Rmr64, simm8_64 ); resultflags( Rmr64 ); } +@endif +:ADC Rmr8,Reg8 is vexMode=0 & byte=0x10; mod=3 & Rmr8 & Reg8 { addCarryFlags( Rmr8, Reg8 ); resultflags( Rmr8 ); } +:ADC Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x11; mod=3 & Rmr16 & Reg16 { addCarryFlags( Rmr16, Reg16 ); resultflags( Rmr16 ); } +:ADC Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x11; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { addCarryFlags( Rmr32, Reg32 ); build check_Rmr32_dest; resultflags( Rmr32 ); } +@ifdef IA64 +:ADC Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x11; mod=3 & Rmr64 & Reg64 { addCarryFlags( Rmr64, Reg64 ); resultflags( Rmr64 ); } +@endif +:ADC Reg8,rm8 is vexMode=0 & byte=0x12; rm8 & Reg8 ... { addCarryFlags( Reg8, rm8 ); resultflags( Reg8 ); } +:ADC Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x13; rm16 & Reg16 ... { addCarryFlags( Reg16, rm16 ); resultflags( Reg16 ); } +:ADC Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x13; rm32 & Reg32 ... & check_Reg32_dest ... { addCarryFlags( Reg32, rm32 ); build check_Reg32_dest; resultflags( Reg32 ); } +@ifdef IA64 +:ADC Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x13; rm64 & Reg64 ... { addCarryFlags( Reg64, rm64 ); resultflags( Reg64 ); } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:ADD AL,imm8 is vexMode=0 & byte=0x4; AL & imm8 { addflags( AL,imm8 ); AL = AL + imm8; resultflags( AL); } +:ADD AX,imm16 is vexMode=0 & opsize=0 & byte=0x5; AX & imm16 { addflags( AX,imm16); AX = AX + imm16; resultflags( AX); } +:ADD EAX,imm32 is vexMode=0 & opsize=1 & byte=0x5; EAX & check_EAX_dest & imm32 { addflags( EAX,imm32); EAX = EAX + imm32; build check_EAX_dest; resultflags( EAX); } +@ifdef IA64 +:ADD RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x5; RAX & simm32 { addflags( RAX,simm32); RAX = RAX + simm32; resultflags( RAX); } +@endif +:ADD Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=0; imm8 { addflags( Rmr8,imm8 ); Rmr8 = Rmr8 + imm8; resultflags( Rmr8); } +:ADD Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=0; imm16 { addflags( Rmr16,imm16); Rmr16 = Rmr16 + imm16; resultflags( Rmr16); } +:ADD Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=0; imm32 { addflags( Rmr32,imm32); Rmr32 = Rmr32 + imm32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:ADD Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=0; simm32 { addflags( Rmr64,simm32); Rmr64 = Rmr64 + simm32; resultflags( Rmr64); } +@endif +:ADD Rmr16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=0; simm8_16 { addflags( Rmr16,simm8_16); Rmr16 = Rmr16 + simm8_16; resultflags( Rmr16); } +:ADD Rmr32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=0; simm8_32 { addflags( Rmr32,simm8_32); Rmr32 = Rmr32 + simm8_32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:ADD Rmr64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=0; simm8_64 { addflags( Rmr64,simm8_64); Rmr64 = Rmr64 + simm8_64; resultflags( Rmr64); } +@endif +:ADD Rmr8,Reg8 is vexMode=0 & byte=0x00; mod=3 & Rmr8 & Reg8 { addflags( Rmr8,Reg8 ); Rmr8 = Rmr8 + Reg8; resultflags( Rmr8); } +:ADD Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x1; mod=3 & Rmr16 & Reg16 { addflags( Rmr16,Reg16); Rmr16 = Rmr16 + Reg16; resultflags( Rmr16); } +:ADD Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x1; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { addflags( Rmr32,Reg32); Rmr32 = Rmr32 + Reg32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:ADD Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1; mod=3 & Rmr64 & Reg64 { addflags( Rmr64,Reg64); Rmr64 = Rmr64 + Reg64; resultflags( Rmr64); } +@endif +:ADD Reg8,rm8 is vexMode=0 & byte=0x2; rm8 & Reg8 ... { addflags( Reg8,rm8 ); Reg8 = Reg8 + rm8; resultflags( Reg8); } +:ADD Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x3; rm16 & Reg16 ... { addflags(Reg16,rm16 ); Reg16 = Reg16 + rm16; resultflags(Reg16); } +:ADD Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x3; rm32 & Reg32 ... & check_Reg32_dest ... { addflags(Reg32,rm32 ); Reg32 = Reg32 + rm32; build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:ADD Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x3; rm64 & Reg64 ... { addflags(Reg64,rm64 ); Reg64 = Reg64 + rm64; resultflags(Reg64); } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:AND AL,imm8 is vexMode=0 & byte=0x24; AL & imm8 { logicalflags(); AL = AL & imm8; resultflags( AL); } +:AND AX,imm16 is vexMode=0 & opsize=0 & byte=0x25; AX & imm16 { logicalflags(); AX = AX & imm16; resultflags( AX); } +:AND EAX,imm32 is vexMode=0 & opsize=1 & byte=0x25; EAX & check_EAX_dest & imm32 { logicalflags(); EAX = EAX & imm32; build check_EAX_dest; resultflags( EAX); } +@ifdef IA64 +:AND RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x25; RAX & simm32 { logicalflags(); RAX = RAX & simm32; resultflags( RAX); } +@endif +:AND Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=4; imm8 { logicalflags(); Rmr8 = Rmr8 & imm8; resultflags( Rmr8); } +:AND Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=4; imm16 { logicalflags(); Rmr16 = Rmr16 & imm16; resultflags( Rmr16); } +:AND Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=4; imm32 { logicalflags(); Rmr32 = Rmr32 & imm32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:AND Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=4; simm32 { logicalflags(); Rmr64 = Rmr64 & simm32; resultflags( Rmr64); } +@endif +:AND Rmr16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=4; usimm8_16 { logicalflags(); Rmr16 = Rmr16 & usimm8_16; resultflags( Rmr16); } +:AND Rmr32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=4; usimm8_32 { logicalflags(); Rmr32 = Rmr32 & usimm8_32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:AND Rmr64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=4; usimm8_64 { logicalflags(); Rmr64 = Rmr64 & usimm8_64; resultflags( Rmr64); } +@endif +:AND Rmr8,Reg8 is vexMode=0 & byte=0x20; mod=3 & Rmr8 & Reg8 { logicalflags(); Rmr8 = Rmr8 & Reg8; resultflags( Rmr8); } +:AND Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x21; mod=3 & Rmr16 & Reg16 { logicalflags(); Rmr16 = Rmr16 & Reg16; resultflags( Rmr16); } +:AND Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x21; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { logicalflags(); Rmr32 = Rmr32 & Reg32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:AND Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x21; mod=3 & Rmr64 & Reg64 { logicalflags(); Rmr64 = Rmr64 & Reg64; resultflags( Rmr64); } +@endif +:AND Reg8,rm8 is vexMode=0 & byte=0x22; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 & rm8; resultflags( Reg8); } +:AND Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x23; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 & rm16; resultflags(Reg16); } +:AND Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x23; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 & rm32; build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:AND Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x23; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 & rm64; resultflags(Reg64); } +@endif + +#ARPL is not encodable in 64-bit mode +:ARPL rm16,Reg16 is $(LONGMODE_OFF) & vexMode=0 & bit64=0 & byte=0x63; rm16 & Reg16 ... { local rpldest=rm16&3; local rplsrc=Reg16&3; local rpldiff=rplsrc-rpldest; + ZF = rpldiff s> 0; rm16 = rm16 + (zext(CF) * rpldiff); } + +:BOUND Reg16,m16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0x62; m16 & Reg16 ... { } +:BOUND Reg32,m32 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0x62; m32 & Reg32 ... { } + +#:BSF Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbc; rm16 & Reg16 ... { ZF = rm16 == 0; +# choose = 0xffff * (zext((0xff & rm16) == 0)); +# mask = (0xf00 & choose) | (0xf | ~choose); +# pos = 8 & choose; +# choose = 0xffff * (zext((mask & rm16) == 0)); +# mask1 = (mask << 2) & (mask << 4); +# mask2 = (mask >> 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (4 & choose); +# choose = 0xffff * (zext((mask & rm16) == 0)); +# mask1 = (mask << 1) & (mask << 2); +# mask2 = (mask >> 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (2 & choose); +# choose = zext((mask & rm16) == 0); +# Reg16 = pos + choose; } + +:BSF Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbc; rm16 & Reg16 ... +{ + bitIndex:2 = 0; + + ZF = ( rm16 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( ((rm16 >> bitIndex) & 0x0001) != 0 ) goto ; + bitIndex = bitIndex + 1; + goto ; + + + Reg16 = bitIndex; +} + +#:BSF Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbc; rm32 & Reg32 ... & check_Reg32_dest ... { ZF = rm32 == 0; +# choose = 0xffffffff * (zext((0xffff & rm32) == 0)); +# mask = (0xff0000 & choose) | (0xff | ~choose); +# pos = 16 & choose; +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask << 4) & (mask << 8); +# mask2 = (mask >> 4) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (8 & choose); +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask << 2) & (mask << 4); +# mask2 = (mask >> 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (4 & choose); +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask << 1) & (mask << 2); +# mask2 = (mask >> 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (2 & choose); +# choose = zext((mask & rm32) == 0); +# Reg32 = pos + choose; +# build check_Reg32_dest; } + +:BSF Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbc; rm32 & Reg32 ... & check_Reg32_dest ... +{ + bitIndex:4 = 0; + + ZF = ( rm32 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( ((rm32 >> bitIndex) & 0x00000001) != 0 ) goto ; + bitIndex = bitIndex + 1; + goto ; + + + Reg32 = bitIndex; + build check_Reg32_dest; +} + +@ifdef IA64 +#:BSF Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbc; rm64 & Reg64 ... { ZF = rm64 == 0; +## TODO: NEED TO EXTEND THIS TO 64bit op +# choose = 0xffffffff * (zext((0xffff & rm64) == 0)); +# mask = (0xff0000 & choose) | (0xff | ~choose); +# pos = 16 & choose; +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask << 4) & (mask << 8); +# mask2 = (mask >> 4) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (8 & choose); +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask << 2) & (mask << 4); +# mask2 = (mask >> 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (4 & choose); +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask << 1) & (mask << 2); +# mask2 = (mask >> 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos + (2 & choose); +# choose = zext((mask & rm64) == 0); +# Reg64 = pos + choose; } + +:BSF Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbc; rm64 & Reg64 ... +{ + bitIndex:8 = 0; + + ZF = ( rm64 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( ((rm64 >> bitIndex) & 0x0000000000000001) != 0 ) goto ; + bitIndex = bitIndex + 1; + goto ; + + + Reg64 = bitIndex; +} +@endif + +#:BSR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbd; rm16 & Reg16 ... { ZF = rm16 == 0; +# choose = 0xffff * (zext((0xff00 & rm16) == 0)); +# mask = (0xf000 & ~choose) | (0xf0 | choose); +# pos = 16 - (8 & choose); +# choose = 0xffff * (zext((mask & rm16) == 0)); +# mask1 = (mask >> 2) & (mask >> 4); +# mask2 = (mask << 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (4 & choose); +# choose = 0xffff * (zext((mask & rm16) == 0)); +# mask1 = (mask >> 1) & (mask >> 2); +# mask2 = (mask << 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (2 & choose); +# choose = zext((mask & rm16) == 0); +# Reg16 = pos - choose; } + +:BSR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbd; rm16 & Reg16 ... +{ + bitIndex:2 = 15; + + ZF = ( rm16 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( (rm16 >> bitIndex) != 0 ) goto ; + bitIndex = bitIndex - 1; + goto ; + + + Reg16 = bitIndex; +} + +#:BSR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbd; rm32 & Reg32 ... & check_Reg32_dest ... { ZF = rm32 == 0; +# choose = 0xffffffff * (zext((0xffff0000 & rm32) == 0)); +# mask = (0xff000000 & ~choose) | (0xff00 | choose); +# pos = 32 - (16 & choose); +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask >> 4) & (mask >> 8); +# mask2 = (mask << 4) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (8 & choose); +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask >> 2) & (mask >> 4); +# mask2 = (mask << 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (4 & choose); +# choose = 0xffffffff * (zext((mask & rm32) == 0)); +# mask1 = (mask >> 1) & (mask >> 2); +# mask2 = (mask << 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (2 & choose); +# choose = zext((mask & rm32) == 0); +# Reg32 = pos - choose; +# build check_Reg32_dest; } + +:BSR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbd; rm32 & Reg32 ... & check_Reg32_dest ... +{ + bitIndex:4 = 31; + + ZF = ( rm32 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( (rm32 >> bitIndex) != 0 ) goto ; + bitIndex = bitIndex - 1; + goto ; + + + Reg32 = bitIndex; + build check_Reg32_dest; +} + + +@ifdef IA64 +#:BSR Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbd; rm64 & Reg64 ... { ZF = rm64 == 0; +## TODO: NEED TO EXTEND THIS TO 64bit op +# choose = 0xffffffff * (zext((0xffff0000 & rm64) == 0)); +# mask = (0xff000000 & ~choose) | (0xff00 | choose); +# pos = 32 - (16 & choose); +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask >> 4) & (mask >> 8); +# mask2 = (mask << 4) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (8 & choose); +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask >> 2) & (mask >> 4); +# mask2 = (mask << 2) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (4 & choose); +# choose = 0xffffffff * (zext((mask & rm64) == 0)); +# mask1 = (mask >> 1) & (mask >> 2); +# mask2 = (mask << 1) & mask; +# mask = (mask1 & choose) | (mask2 | ~choose); +# pos = pos - (2 & choose); +# choose = zext((mask & rm64) == 0); +# Reg64 = pos - choose; } + +:BSR Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbd; rm64 & Reg64 ... +{ + bitIndex:8 = 63; + + ZF = ( rm64 == 0 ); + + if ( ZF == 1 ) goto ; + + + if ( (rm64 >> bitIndex) != 0 ) goto ; + bitIndex = bitIndex - 1; + goto ; + + + Reg64 = bitIndex; +} + +@endif + +:BSWAP Rmr32 is vexMode=0 & byte=0xf; row=12 & page=1 & Rmr32 & check_Rmr32_dest + { local tmp = (Rmr32 & 0xff000000) >> 24 ; + tmp = tmp | ((Rmr32 & 0x00ff0000) >> 8 ); + tmp = tmp | ((Rmr32 & 0x0000ff00) << 8 ); + Rmr32 = tmp | ((Rmr32 & 0x000000ff) << 24); + build check_Rmr32_dest; } +@ifdef IA64 +:BSWAP Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; row=12 & page=1 & Rmr64 + { local tmp = (Rmr64 & 0xff00000000000000) >> 56 ; + tmp = tmp | ((Rmr64 & 0x00ff000000000000) >> 40 ); + tmp = tmp | ((Rmr64 & 0x0000ff0000000000) >> 24 ); + tmp = tmp | ((Rmr64 & 0x000000ff00000000) >> 8 ); + tmp = tmp | ((Rmr64 & 0x00000000ff000000) << 8 ); + tmp = tmp | ((Rmr64 & 0x0000000000ff0000) << 24 ); + tmp = tmp | ((Rmr64 & 0x000000000000ff00) << 40 ); + Rmr64 = tmp | ((Rmr64 & 0x00000000000000ff) << 56); } +@endif + +:BT Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xa3; mod=3 & Rmr16 & Reg16 { CF = ((Rmr16 >> (Reg16 & 0xf)) & 1) != 0; } +:BT Mem,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xa3; Mem & Reg16 ... { local ptr = Mem + (sext(Reg16) s>> 3); + CF = ((*:1 ptr >> (Reg16 & 0x7)) & 1) != 0; } +:BT Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xa3; mod=3 & Rmr32 & Reg32 { CF = ((Rmr32 >> (Reg32 & 0x1f)) & 1) != 0; } +:BT Mem,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xa3; Mem & Reg32 ... { +@ifdef IA64 + local ptr = Mem + (sext(Reg32) s>> 3); +@else + local ptr = Mem + (Reg32 s>> 3); +@endif + CF = ((*:1 ptr >> (Reg32 & 0x7)) & 1) != 0; +} +@ifdef IA64 +:BT Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; mod=3 & Rmr64 & Reg64 { CF = ((Rmr64 >> (Reg64 & 0x3f)) & 1) != 0; } +:BT Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>> 3); + CF = ((*:1 ptr >> (Reg64 & 0x7)) & 1) != 0; } +@endif +:BT rm16,imm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xba; (rm16 & reg_opcode=4 ...); imm8 { CF = ((rm16 >> (imm8 & 0x0f)) & 1) != 0; } +:BT rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=4 ...); imm8 { CF = ((rm32 >> (imm8 & 0x1f)) & 1) != 0; } +@ifdef IA64 +:BT rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=4 ...); imm8 { CF = ((rm64 >> (imm8 & 0x3f)) & 1) != 0; } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:BTC Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbb; mod=3 & Rmr16 & Reg16 { local bit=Reg16&0xf; local val=(Rmr16>>bit)&1; Rmr16=Rmr16^(1<>bit)&1; CF=(val!=0); Rmr32=Rmr32^(1<>bit)&1; Rmr64=Rmr64^(1<>bit)&1; Rmr16=Rmr16^(1<>bit)&1; CF=(val!=0); Rmr32=Rmr32^(1<>bit)&1; Rmr64=Rmr64^(1<>bit)&1; Rmr16=Rmr16 & ~(1<>bit)&1; CF=(val!=0); Rmr32=Rmr32 & ~(1<>bit)&1; Rmr64=Rmr64 & ~(1<>bit)&1; Rmr16=Rmr16 & ~(1<>bit)&1; CF=(val!=0); Rmr32=Rmr32 & ~(1<>bit)&1; Rmr64=Rmr64 & ~(1<>bit)&1; Rmr16=Rmr16 | (1<>bit)&1; CF=(val!=0); Rmr32=Rmr32 | (1<>bit)&1; Rmr64=Rmr64 | (1<>bit)&1; Rmr16=Rmr16 | (1<>bit)&1; CF=(val!=0); Rmr32=Rmr32 | (1<>bit)&1; Rmr64=Rmr64 | (1<; + EAX = Rmr32; + build check_EAX_dest; + goto inst_next; + + Rmr32 = Reg32; + build check_Rmr32_dest; +} +@ifdef IA64 +:CMPXCHG Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xb1; mod=3 & Rmr64 & Reg64 { subflags(RAX,Rmr64); local tmp=RAX-Rmr64; resultflags(tmp); + local diff = Rmr64^Reg64; Rmr64 = Rmr64 ^ (zext(ZF) * diff); + diff = RAX ^ Rmr64; RAX = RAX ^ (zext(ZF==0) * diff); } +@endif + +# CMPXCHG8B See 'lockable.sinc' for memory destination, lockable variants + +# This "bad_CMPXCHG8B" instruction encoding was not meant to be part of the x86 language. +# It was allowed by a toolchain (at Intel) and was encoded into at least one library. +# GCC does not recognize it. It does not make any semantic sense. +define pcodeop bad_CMPXCHG8B; +:bad_CMPXCHG8B r32 is vexMode=0 & byte=0xf; byte=0xc7; ( mod = 0b11 & reg_opcode=0b001 ) & r32 { + r32 = bad_CMPXCHG8B(r32); +} + +# CMPXCHG16B See 'lockable.sinc' for memory destination, lockable variants + +define pcodeop cpuid; +define pcodeop cpuid_basic_info; +define pcodeop cpuid_Version_info; +define pcodeop cpuid_cache_tlb_info; +define pcodeop cpuid_serial_info; +define pcodeop cpuid_Deterministic_Cache_Parameters_info; +define pcodeop cpuid_MONITOR_MWAIT_Features_info; +define pcodeop cpuid_Thermal_Power_Management_info; +define pcodeop cpuid_Extended_Feature_Enumeration_info; +define pcodeop cpuid_Direct_Cache_Access_info; +define pcodeop cpuid_Architectural_Performance_Monitoring_info; +define pcodeop cpuid_Extended_Topology_info; +define pcodeop cpuid_Processor_Extended_States_info; +define pcodeop cpuid_Quality_of_Service_info; +define pcodeop cpuid_brand_part1_info; +define pcodeop cpuid_brand_part2_info; +define pcodeop cpuid_brand_part3_info; + +# CPUID is very difficult to implement correctly +# The side-effects of the call will show up, but not the correct values + +:CPUID is vexMode=0 & byte=0xf; byte=0xa2 { + local tmp:16; + if (EAX == 0) goto ; + if (EAX == 1) goto ; + if (EAX == 2) goto ; + if (EAX == 3) goto ; + if (EAX == 0x4) goto ; + if (EAX == 0x5) goto ; + if (EAX == 0x6) goto ; + if (EAX == 0x7) goto ; + if (EAX == 0x9) goto ; + if (EAX == 0xa) goto ; + if (EAX == 0xb) goto ; + if (EAX == 0xd) goto ; + if (EAX == 0xf) goto ; + if (EAX == 0x80000002) goto ; + if (EAX == 0x80000003) goto ; + if (EAX == 0x80000004) goto ; + tmp = cpuid(EAX, ECX); + goto ; + + tmp = cpuid_basic_info(EAX, ECX); + goto ; + + tmp = cpuid_Version_info(EAX, ECX); + goto ; + + tmp = cpuid_cache_tlb_info(EAX, ECX); + goto ; + + tmp = cpuid_serial_info(EAX, ECX); + goto ; + + tmp = cpuid_Deterministic_Cache_Parameters_info(EAX, ECX); + goto ; + + tmp = cpuid_MONITOR_MWAIT_Features_info(EAX, ECX); + goto ; + + tmp = cpuid_Thermal_Power_Management_info(EAX, ECX); + goto ; + + tmp = cpuid_Extended_Feature_Enumeration_info(EAX, ECX); + goto ; + + tmp = cpuid_Direct_Cache_Access_info(EAX, ECX); + goto ; + + tmp = cpuid_Architectural_Performance_Monitoring_info(EAX, ECX); + goto ; + + tmp = cpuid_Extended_Topology_info(EAX, ECX); + goto ; + + tmp = cpuid_Processor_Extended_States_info(EAX, ECX); + goto ; + + tmp = cpuid_Quality_of_Service_info(EAX, ECX); + goto ; + + tmp = cpuid_brand_part1_info(EAX, ECX); + goto ; + + tmp = cpuid_brand_part2_info(EAX, ECX); + goto ; + + tmp = cpuid_brand_part3_info(EAX, ECX); + goto ; + +@ifdef IA64 + RAX = zext(tmp[0,32]); + RBX = zext(tmp[32,32]); + RDX = zext(tmp[64,32]); + RCX = zext(tmp[96,32]); +@else + EAX = tmp[0,32]; + EBX = tmp[32,32]; + EDX = tmp[64,32]; + ECX = tmp[96,32]; +@endif +} + + +:DAA is $(LONGMODE_OFF) & vexMode=0 & byte=0x27 { local car = ((AL & 0xf) > 9) | AF; + AL = AL + 6 * car; + CF = CF | car * carry(AL,6); + AF = car; + car = ((AL & 0xf0) > 0x90) | CF; + AL = AL + 0x60 * car; + CF = car; } +:DAS is $(LONGMODE_OFF) & vexMode=0 & byte=0x2f { local car = ((AL & 0xf) > 9) | AF; + AL = AL - 6 * car; + CF = CF | car * (AL < 6); + AF = car; + car = (AL > 0x9f) | CF; + AL = AL - 0x60 * car; + CF = car; } + +# See 'lockable.sinc' for memory destination, lockable variants +:DEC Rmr8 is vexMode=0 & byte=0xfe; mod=3 & Rmr8 & reg_opcode=1 { OF = sborrow(Rmr8,1); Rmr8 = Rmr8 - 1; resultflags( Rmr8); } +:DEC Rmr16 is vexMode=0 & opsize=0 & byte=0xff; mod=3 & Rmr16 & reg_opcode=1 { OF = sborrow(Rmr16,1); Rmr16 = Rmr16 - 1; resultflags(Rmr16); } +:DEC Rmr32 is vexMode=0 & opsize=1 & byte=0xff; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=1 { OF = sborrow(Rmr32,1); Rmr32 = Rmr32 - 1; build check_rm32_dest; resultflags(Rmr32); } +@ifdef IA64 +:DEC Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xff; mod=3 & Rmr64 & reg_opcode=1 { OF = sborrow(Rmr64,1); Rmr64 = Rmr64 - 1; resultflags(Rmr64); } +@endif + +:DEC Rmr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & row=4 & page=1 & Rmr16 { OF = sborrow(Rmr16,1); Rmr16 = Rmr16 - 1; resultflags( Rmr16); } +:DEC Rmr32 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & row=4 & page=1 & Rmr32 & check_Rmr32_dest { OF = sborrow(Rmr32,1); Rmr32 = Rmr32 - 1; build check_Rmr32_dest; resultflags( Rmr32); } + +:DIV rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=6 ... { rm8ext:2 = zext(rm8); + local quotient = AX / rm8ext; # DE exception if quotient doesn't fit in AL + local rem = AX % rm8ext; + AL = quotient:1; + AH = rem:1; } +:DIV rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=6 ... { rm16ext:4 = zext(rm16); + tmp:4 = (zext(DX) << 16) | zext(AX); # DE exception if quotient doesn't fit in AX + local quotient = tmp / rm16ext; + AX = quotient:2; + local rem = tmp % rm16ext; + DX = rem:2; } +:DIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EDX_dest ... & check_EAX_dest ... & reg_opcode=6 ... { rm32ext:8 = zext(rm32); + tmp:8 = (zext(EDX) << 32) | zext(EAX); # DE exception if quotient doesn't fit in EAX + local quotient = tmp / rm32ext; + EAX = quotient:4; + build check_EAX_dest; + local rem = tmp % rm32ext; + EDX = rem:4; + build check_EDX_dest; } +@ifdef IA64 +:DIV rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=6 ... { rm64ext:16 = zext(rm64); + tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX + local quotient = tmp / rm64ext; + RAX = quotient:8; + local rem = tmp % rm64ext; + RDX = rem:8; } +@endif + +enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } + +@ifdef IA64 +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x00 { + push88(RBP); + RBP = RSP; + RSP = RSP - imm16; +} + +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x01 { + push88(RBP); + frameTemp:8 = RSP; + + push88(frameTemp); + RBP = frameTemp; + RSP = RSP - imm16; +} + +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xc8; imm16; enterFrames { + push88(RBP); + frameTemp:8 = RSP; + + RSPt:$(SIZE) = RSP; + RBPt:$(SIZE) = RBP; + ii:1 = enterFrames - 1; + + RBPt = RBPt - 8; + RSPt = RSPt - 8; + *:8 RSPt = *:8 RBPt; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:8 = 8 * zext(enterFrames - 1); + RSP = RSP - tmp_offset; + RBP = RBP - tmp_offset; + + push88(frameTemp); + RBP = frameTemp; + RSP = RSP - imm16; +} + +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xc8; imm16; enterFrames { + push88(RBP); + frameTemp:8 = RSP; + + RSPt:$(SIZE) = RSP; + RBPt:$(SIZE) = RBP; + ii:1 = enterFrames - 1; + + RBPt = RBPt - 4; + RSPt = RSPt - 4; + *:4 RSPt = *:4 RBPt; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:8 = 4 * zext(enterFrames - 1); + RSP = RSP - tmp_offset; + RBP = RBP - tmp_offset; + + push88(frameTemp); + RBP = frameTemp; + RSP = RSP - imm16; +} + +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xc8; imm16; enterFrames { + push88(RBP); + frameTemp:8 = RSP; + + RSPt:$(SIZE) = RSP; + RBPt:$(SIZE) = RBP; + ii:1 = enterFrames - 1; + + RBPt = RBPt - 2; + RSPt = RSPt - 2; + *:2 RSPt = *:2 RBPt; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:8 = 2 * zext(enterFrames - 1); + RSP = RSP - tmp_offset; + RBP = RBP - tmp_offset; + + push88(frameTemp); + RBP = frameTemp; + RSP = RSP - imm16; +} +@endif + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=1 & byte=0xc8; imm16; enterFrames & low5=0x00 { + push44(EBP); + EBP = ESP; + ESP = ESP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=1 & byte=0xc8; imm16; enterFrames & low5=0x01 { + push44(EBP); + frameTemp:4 = ESP; + + push44(frameTemp); + EBP = frameTemp; + ESP = ESP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=1 & opsize=1 & byte=0xc8; imm16; enterFrames { + push44(EBP); + frameTemp:4 = ESP; + +@ifdef IA64 + ESPt:$(SIZE) = zext(ESP); + EBPt:$(SIZE) = zext(EBP); +@else + ESPt:$(SIZE) = ESP; + EBPt:$(SIZE) = EBP; +@endif + ii:1 = enterFrames - 1; + + EBPt = EBPt - 4; + ESPt = ESPt - 4; + *:4 ESPt = *:4 EBPt; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:4 = 4 * zext(enterFrames - 1); + ESP = ESP - tmp_offset; + EBP = EBP - tmp_offset; + + push44(frameTemp); + EBP = frameTemp; + ESP = ESP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=1 & opsize=0 & byte=0xc8; imm16; enterFrames { + push44(EBP); + frameTemp:4 = ESP; + +@ifdef IA64 + ESPt:$(SIZE) = zext(ESP); + EBPt:$(SIZE) = zext(EBP); +@else + ESPt:$(SIZE) = ESP; + EBPt:$(SIZE) = EBP; +@endif + ii:1 = enterFrames - 1; + + EBPt = EBPt - 2; + ESPt = ESPt - 2; + *:2 ESPt = *:2 EBPt; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:4 = 2 * zext(enterFrames - 1); + ESP = ESP - tmp_offset; + EBP = EBP - tmp_offset; + + push44(frameTemp); + EBP = frameTemp; + ESP = ESP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=0 & byte=0xc8; imm16; enterFrames & low5=0x00 { + push22(BP); + BP = SP; + SP = SP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & addrsize=0 & byte=0xc8; imm16; enterFrames & low5=0x01 { + push22(BP); + frameTemp:2 = SP; + + push22(frameTemp); + BP = frameTemp; + SP = SP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & seg16 & addrsize=0 & opsize=1 & byte=0xc8; imm16; enterFrames { + push24(zext(BP)); + frameTemp:2 = SP; + + SPt:2 = SP; + BPt:2 = BP; + ii:1 = enterFrames - 1; + + + BPt = BPt - 4; + tmp2:$(SIZE) = segment(seg16,BPt); + SPt = SPt - 4; + tmp:$(SIZE) = segment(SS,SPt); + *:4 tmp = *:4 tmp2; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:2 = 4 * zext(enterFrames - 1); + SP = SP - tmp_offset; + BP = BP - tmp_offset; + + push24(zext(frameTemp)); + BP = frameTemp; + SP = SP - imm16; +} + +:ENTER imm16,enterFrames is vexMode=0 & seg16 & addrsize=0 & opsize=0 & byte=0xc8; imm16; enterFrames { + push22(BP); + frameTemp:2 = SP; + + SPt:2 = SP; + BPt:2 = BP; + ii:1 = enterFrames - 1; + + BPt = BPt - 2; + tmp2:$(SIZE) = segment(seg16,BPt); + SPt = SPt - 2; + tmp:$(SIZE) = segment(SS,SPt); + *:2 tmp = *:2 tmp2; + ii = ii - 1; + if (ii s> 0) goto ; + + tmp_offset:2 = 2 * zext(enterFrames - 1); + SP = SP - tmp_offset; + BP = BP - tmp_offset; + + push22(frameTemp); + BP = frameTemp; + SP = SP - imm16; +} + +# 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 +# as a NOP. We treat it as a NOP as well. +:FSETPM is vexMode=0 & byte=0xdb; byte=0xe4 { } # 80287 set protected mode + +:HLT is vexMode=0 & byte=0xf4 { goto inst_start; } + +: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; + AL = quotient:1; + AH = rem:1; } +:IDIV rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=7 ... { rm16ext:4 = sext(rm16); + tmp:4 = (zext(DX) << 16) | zext(AX); # DE exception if quotient doesn't fit in AX + local quotient = tmp s/ rm16ext; + AX = quotient:2; + local rem = tmp s% rm16ext; + DX = rem:2; } +:IDIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=7 ... { rm32ext:8 = sext(rm32); + tmp:8 = (zext(EDX) << 32) | zext(EAX); # DE exception if quotient doesn't fit in EAX + local quotient = tmp s/ rm32ext; + EAX = quotient:4; + build check_EAX_dest; + local rem = tmp s% rm32ext; + EDX = rem:4; + build check_EDX_dest; } +@ifdef IA64 +:IDIV rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=7 ... { rm64ext:16 = sext(rm64); + tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX + local quotient = tmp s/ rm64ext; + RAX = quotient:8; + local rem = tmp s% rm64ext; + RDX = rem:8; } +@endif + +:IMUL rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=5 ... { AX = sext(AL) * sext(rm8); imultflags(AL,AX); } +:IMUL rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=5 ... { tmp:4 = sext(AX) * sext(rm16); + DX = tmp(2); AX = tmp(0); imultflags(AX,tmp); } +:IMUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=5 ... { tmp:8 = sext(EAX) * sext(rm32); + EDX = tmp(4); build check_EDX_dest; EAX = tmp(0); build check_EAX_dest; imultflags(EAX,tmp); } +@ifdef IA64 +# We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct +:IMUL rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=5 ... { tmp:16 = sext(RAX) * sext(rm64); + RAX = RAX * rm64; RDX = tmp(8); imultflags(RAX,tmp); } +@endif +:IMUL Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xaf; rm16 & Reg16 ... { tmp:4 = sext(Reg16) * sext(rm16); + Reg16 = tmp(0); high:2 = tmp(2); imultflags(Reg16,tmp);} +:IMUL Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xaf; rm32 & Reg32 ... & check_Reg32_dest ... { tmp:8 = sext(Reg32) * sext(rm32); + Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } +@ifdef IA64 +# We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct +:IMUL Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xaf; rm64 & Reg64 ... { tmp:16 = sext(Reg64) * sext(rm64); + Reg64 = Reg64 * rm64; high:8 = tmp(8); imultflags(Reg64,tmp);} +@endif +:IMUL Reg16,rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x6b; (rm16 & Reg16 ...) ; simm8_16 { tmp:4 = sext(rm16) * sext(simm8_16); + Reg16 = tmp(0); high:2 = tmp(2); imultflags(Reg16,tmp);} +:IMUL Reg32,rm32,simm8_32 is vexMode=0 & opsize=1 & byte=0x6b; (rm32 & Reg32 ... & check_Reg32_dest ... ) ; simm8_32 { tmp:8 = sext(rm32) * sext(simm8_32); + Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } +@ifdef IA64 +# We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct +:IMUL Reg64,rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x6b; (rm64 & Reg64 ...) ; simm8_64 { tmp:16 = sext(rm64) * sext(simm8_64); + Reg64 = rm64 * simm8_64; high:8 = tmp(8); imultflags(Reg64,tmp);} +@endif +:IMUL Reg16,rm16,simm16_16 is vexMode=0 & opsize=0 & byte=0x69; (rm16 & Reg16 ...) ; simm16_16 { tmp:4 = sext(rm16) * sext(simm16_16); + Reg16 = tmp(0); high:2 = tmp(2); imultflags(Reg16,tmp);} +:IMUL Reg32,rm32,simm32_32 is vexMode=0 & opsize=1 & byte=0x69; (rm32 & Reg32 ... & check_Reg32_dest ...) ; simm32_32 { tmp:8 = sext(rm32) * sext(simm32_32); + Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } +@ifdef IA64 +:IMUL Reg64,rm64,simm32_32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x69; (rm64 & Reg64 ...) ; simm32_32 { tmp:16 = sext(rm64) * sext(simm32_32); + Reg64 = rm64 * sext(simm32_32); high:8 = tmp(8); imultflags(Reg64,tmp);} +@endif + +# these appear in intelman2.pdf, but do they really exist? +#:IMUL Reg16,simm8_16 is vexMode=0 & opsize=0 & byte=0x6b; Reg16; simm8_16 +#:IMUL Reg32,simm8_32 is vexMode=0 & opsize=1 & byte=0x6b; Reg32; simm8_32 +#:IMUL Reg16,simm16 is vexMode=0 & opsize=0 & byte=0x69; Reg16; simm16 +#:IMUL Reg32,simm32 is vexMode=0 & opsize=1 & byte=0x69; Reg32; simm32 + +:IN AL, imm8 is vexMode=0 & AL & (byte=0xe4; imm8) { tmp:1 = imm8; AL = in(tmp); } +:IN AX, imm8 is vexMode=0 & opsize=0 & AX & (byte=0xe5; imm8) { tmp:1 = imm8; AX = in(tmp); } +:IN EAX, imm8 is vexMode=0 & opsize=1 & EAX & check_EAX_dest & (byte=0xe5; imm8) { tmp:1 = imm8; EAX = in(tmp); build check_EAX_dest; } +@ifdef IA64 +:IN RAX, imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & RAX & (byte=0xe5; imm8) { tmp:1 = imm8; RAX = in(tmp); } +@endif +:IN AL, DX is vexMode=0 & AL & DX & (byte=0xec) { AL = in(DX); } +:IN AX, DX is vexMode=0 & opsize=0 & AX & DX & (byte=0xed) { AX = in(DX); } +:IN EAX, DX is vexMode=0 & opsize=1 & EAX & check_EAX_dest & DX & (byte=0xed) { EAX = in(DX); build check_EAX_dest; } +@ifdef IA64 +:IN RAX, DX is $(LONGMODE_ON) & vexMode=0 & opsize=2 & RAX & DX & (byte=0xed) { RAX = in(DX); } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:INC Rmr8 is vexMode=0 & byte=0xfe; mod=3 & Rmr8 & reg_opcode=0 { OF = scarry(Rmr8,1); Rmr8 = Rmr8 + 1; resultflags( Rmr8); } +:INC Rmr16 is vexMode=0 & opsize=0 & byte=0xff; mod=3 & Rmr16 & reg_opcode=0 { OF = scarry(Rmr16,1); Rmr16 = Rmr16 + 1; resultflags(Rmr16); } +:INC Rmr32 is vexMode=0 & opsize=1 & byte=0xff; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=0 { OF = scarry(Rmr32,1); Rmr32 = Rmr32 + 1; build check_Rmr32_dest; resultflags(Rmr32); } +@ifdef IA64 +:INC Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xff; mod=3 & Rmr64 & reg_opcode=0 { OF = scarry(Rmr64,1); Rmr64 = Rmr64 + 1; resultflags(Rmr64); } +@endif + +:INC Rmr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & row = 4 & page = 0 & Rmr16 { OF = scarry(Rmr16,1); Rmr16 = Rmr16 + 1; resultflags( Rmr16); } +:INC Rmr32 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & row = 4 & page = 0 & Rmr32 { OF = scarry(Rmr32,1); Rmr32 = Rmr32 + 1; resultflags( Rmr32); } + +:INSB^rep^reptail eseDI1,DX is vexMode=0 & rep & reptail & byte=0x6c & eseDI1 & DX { build rep; build eseDI1; eseDI1 = in(DX); build reptail; } +:INSW^rep^reptail eseDI2,DX is vexMode=0 & rep & reptail & opsize=0 & byte=0x6d & eseDI2 & DX { build rep; build eseDI2; eseDI2 = in(DX); build reptail; } +:INSD^rep^reptail eseDI4,DX is vexMode=0 & rep & reptail & opsize=1 & byte=0x6d & eseDI4 & DX { build rep; build eseDI4; eseDI4 = in(DX); build reptail; } +:INSD^rep^reptail eseDI4,DX is vexMode=0 & rep & reptail & opsize=2 & byte=0x6d & eseDI4 & DX { build rep; build eseDI4; eseDI4 = in(DX); build reptail; } + +:INT1 is vexMode=0 & byte=0xf1 { tmp:1 = 0x1; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; } +:INT3 is vexMode=0 & byte=0xcc { tmp:1 = 0x3; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; } +:INT imm8 is vexMode=0 & byte=0xcd; imm8 { tmp:1 = imm8; intloc:$(SIZE) = swi(tmp); call [intloc]; } +:INTO is $(LONGMODE_OFF) & vexMode=0 & byte=0xce +{ + tmp:1 = 0x4; + intloc:$(SIZE) = swi(tmp); + + if (OF != 1) goto ; + call [intloc]; + +} + +:INVD is vexMode=0 & byte=0xf; byte=0x8 {} +:INVLPG Mem is vexMode=0 & byte=0xf; byte=0x1; ( reg_opcode=7 ) ... & Mem { invlpg(Mem); } + +:INVLPGA is vexMode=0 & addrsize=0 & byte=0xf; byte=0x1; byte=0xDF { invlpga(AX,ECX); } +:INVLPGA is vexMode=0 & addrsize=1 & byte=0xf; byte=0x1; byte=0xDF { invlpga(EAX,ECX); } +@ifdef IA64 +:INVLPGA is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0x1; byte=0xDF { invlpga(RAX,ECX); } +@endif + +:INVPCID r32, m128 is vexMode=0 & addrsize=1 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x82; r32 ... & m128 { invpcid(r32, m128); } +@ifdef IA64 +:INVPCID r64, m128 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x82; r64 ... & m128 { invpcid(r64, m128); } +@endif + +:IRET is vexMode=0 & addrsize=0 & opsize=0 & byte=0xcf { pop22(IP); EIP=zext(IP); pop22(CS); pop22(flags); return [EIP]; } +:IRET is vexMode=0 & addrsize=1 & opsize=0 & byte=0xcf { pop42(IP); EIP=zext(IP); pop42(CS); pop42(flags); return [EIP]; } +@ifdef IA64 +:IRET is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xcf { pop82(IP); RIP=zext(IP); pop82(CS); pop82(flags); return [RIP]; } +@endif +:IRETD is vexMode=0 & addrsize=0 & opsize=1 & byte=0xcf { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); pop24(tmp); flags=tmp(0); return [EIP]; } +:IRETD is vexMode=0 & addrsize=1 & opsize=1 & byte=0xcf { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); pop44(eflags); return [EIP]; } +@ifdef IA64 +:IRETD is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xcf { pop84(EIP); RIP=zext(EIP); tmp:4=0; pop84(tmp); CS=tmp(0); pop84(eflags); return [RIP]; } +: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 vexMode=0 & bit64=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; } +# 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; } +#@endif + +:JCXZ rel8 is vexMode=0 & opsize=0 & byte=0xe3; rel8 { if (CX==0) goto rel8; } +:JECXZ rel8 is vexMode=0 & opsize=1 & byte=0xe3; rel8 { if (ECX==0) goto rel8; } +@ifdef IA64 +:JRCXZ rel8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xe3; rel8 { if (RCX==0) goto rel8; } +@endif + +:JMP rel8 is vexMode=0 & byte=0xeb; rel8 { goto rel8; } +:JMP rel16 is vexMode=0 & opsize=0 & byte=0xe9; rel16 { goto rel16; } +:JMP rel32 is vexMode=0 & opsize=1 & byte=0xe9; rel32 { goto rel32; } +:JMP rel32 is vexMode=0 & opsize=2 & byte=0xe9; rel32 { goto rel32; } +:JMP rm16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0xff & currentCS; rm16 & reg_opcode=4 ... { target:4 = segment(currentCS,rm16); goto [target]; } +:JMP rm16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0xff; rm16 & reg_opcode=4 ... { goto [rm16]; } +:JMP rm32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xff; rm32 & reg_opcode=4 ... { goto [rm32]; } +@ifdef IA64 +:JMP rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=4 ... { goto [rm64]; } +@endif + +:JMPF ptr1616 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xea; ptr1616 { goto ptr1616; } +:JMPF ptr1632 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xea; ptr1632 { goto ptr1632; } +:JMPF Mem is vexMode=0 & opsize=0 & byte=0xff; Mem & reg_opcode=5 ... { target:$(SIZE) = zext(*:2 Mem); goto [target]; } +:JMPF Mem is vexMode=0 & opsize=1 & byte=0xff; Mem & reg_opcode=5 ... { +@ifdef IA64 + target:$(SIZE) = zext(*:4 Mem); +@else + target:$(SIZE) = *:4 Mem; +@endif + goto [target]; +} +@ifdef IA64 +:JMPF Mem is vexMode=0 & opsize=2 & byte=0xff; Mem & reg_opcode=5 ... { target:$(SIZE) = *:8 Mem; goto [target]; } +@endif + +# Initially disallowed in 64bit mode, but later reintroduced +:LAHF is vexMode=0 & byte=0x9f { AH=(SF<<7)|(ZF<<6)|(AF<<4)|(PF<<2)|2|CF; } + +:LAR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x2; rm16 & Reg16 ... { Reg16 = rm16 & 0xff00; ZF=1; } +:LAR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x2; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32 & 0xffff00; build check_Reg32_dest; ZF=1; } +@ifdef IA64 +:LAR Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x2; rm32 & Reg64 ... { Reg64 = zext( rm32 & 0xffff00 ); ZF=1; } +@endif + +:LDMXCSR m32 is vexMode=0 & byte=0xf; byte=0xae; ( mod != 0b11 & reg_opcode=2 ) ... & m32 { MXCSR = m32; } + +# 16 & 32-bit only +:LDS Reg16,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xC5; Mem & Reg16 ... { tmp:4 = *Mem; DS = tmp(2); Reg16 = tmp(0); } +:LDS Reg32,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xC5 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; DS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } + +:LSS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB2; Mem & Reg16 ... { tmp:4 = *Mem; SS = tmp(2); Reg16 = tmp(0); } +:LSS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB2; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; SS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } +@ifdef IA64 +:LSS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB2; Mem & Reg64 ... { tmp:10 = *Mem; SS = tmp(8); Reg64 = tmp(0); } +@endif + +# 16 & 32-bit only +:LES Reg16,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xC4; Mem & Reg16 ... { tmp:4 = *Mem; ES = tmp(2); Reg16 = tmp(0); } +:LES Reg32,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xC4 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; ES = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } + +:LFS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB4; Mem & Reg16 ... { tmp:4 = *Mem; FS = tmp(2); Reg16 = tmp(0); } +:LFS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB4; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; FS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } +@ifdef IA64 +:LFS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB4; Mem & Reg64 ... { tmp:10 = *Mem; FS = tmp(8); Reg64 = tmp(0); } +@endif +:LGS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB5; Mem & Reg16 ... { tmp:4 = *Mem; GS = tmp(2); Reg16 = tmp(0); } +:LGS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB5; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; GS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } +@ifdef IA64 +:LGS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB5; Mem & Reg64 ... { tmp:10 = *Mem; GS = tmp(8); Reg64 = tmp(0); } +@endif + +#in 64-bit mode address size of 16 is not encodable +:LEA Reg16,addr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & addrsize=0 & byte=0x8D; addr16 & Reg16 ... { Reg16 = addr16; } +:LEA Reg32,addr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & addrsize=0 & byte=0x8D; addr16 & Reg32 ... { Reg32 = zext(addr16); } + +:LEA Reg16,addr32 is vexMode=0 & opsize=0 & addrsize=1 & byte=0x8D; addr32 & Reg16 ... { Reg16 = addr32(0); } +:LEA Reg32,addr32 is vexMode=0 & opsize=1 & addrsize=1 & byte=0x8D; addr32 & Reg32 ... & check_Reg32_dest ... { + Reg32 = addr32; + build check_Reg32_dest; +} + +@ifdef IA64 +:LEA Reg16,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & addrsize=2 & byte=0x8D; addr64 & Reg16 ... { Reg16 = addr64(0); } +:LEA Reg32,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=1 & addrsize=2 & byte=0x8D; addr64 & Reg32 ... & check_Reg32_dest ... { + Reg32 = addr64(0); + build check_Reg32_dest; +} +:LEA Reg64,addr32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & addrsize=1 & byte=0x8D; addr32 & Reg64 ... { Reg64 = zext(addr32); } +:LEA Reg64,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & addrsize=2 & byte=0x8D; addr64 & Reg64 ... { Reg64 = addr64; } +@endif + +:LEAVE is vexMode=0 & addrsize=0 & byte=0xc9 { SP = BP; tmp:$(SIZE) = segment(SS,SP); BP = *tmp; SP = SP + 2; } +:LEAVE is vexMode=0 & addrsize=1 & byte=0xc9 { ESP = EBP; EBP = *$(STACKPTR); ESP=ESP+4; } +@ifdef IA64 +:LEAVE is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc9 { RSP = RBP; RBP = *RSP; RSP=RSP+8; } +@endif + +define pcodeop GlobalDescriptorTableRegister; +:LGDT m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=2 ) ... & m16 +{ + GlobalDescriptorTableRegister(m16); +} + +:LGDT m32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=2 ) ... & m32 +{ + GlobalDescriptorTableRegister(m32); +} + +@ifdef IA64 +:LGDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=2 ) ... & m64 +{ + GlobalDescriptorTableRegister(m64); +} +@endif + +define pcodeop InterruptDescriptorTableRegister; +:LIDT m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=3 ) ... & m16 +{ + InterruptDescriptorTableRegister(m16); +} + +:LIDT m32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=3 ) ... & m32 +{ + InterruptDescriptorTableRegister(m32); +} +@ifdef IA64 +:LIDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=3 ) ... & m64 +{ + InterruptDescriptorTableRegister(m64); +} +@endif + +define pcodeop LocalDescriptorTableRegister; +:LLDT rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=2 ... +{ + LocalDescriptorTableRegister(rm16); +} + +@ifdef IA64 +:LMSW rm16 is vexMode=0 & byte=0xf; byte=0x01; rm16 & reg_opcode=6 ... +{ + CR0 = (CR0 & 0xFFFFFFFFFFFFFFF0) | zext(rm16 & 0x000F); +} +@else +:LMSW rm16 is vexMode=0 & byte=0xf; byte=0x01; rm16 & reg_opcode=6 ... +{ + CR0 = (CR0 & 0xFFFFFFF0) | zext(rm16 & 0x000F); +} +@endif + +: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; } +@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 + +:LOOP rel8 is vexMode=0 & addrsize=0 & byte=0xE2; rel8 { CX = CX -1; if (CX!=0) goto rel8; } +:LOOP rel8 is vexMode=0 & addrsize=1 & byte=0xE2; rel8 { ECX = ECX -1; if (ECX!=0) goto rel8; } +@ifdef IA64 +:LOOP rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE2; rel8 { RCX = RCX -1; if (RCX!=0) goto rel8; } +@endif + +:LOOPZ rel8 is vexMode=0 & addrsize=0 & byte=0xE1; rel8 { CX = CX -1; if (CX!=0 && ZF!=0) goto rel8; } +:LOOPZ rel8 is vexMode=0 & addrsize=1 & byte=0xE1; rel8 { ECX = ECX -1; if (ECX!=0 && ZF!=0) goto rel8; } +@ifdef IA64 +:LOOPZ rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE1; rel8 { RCX = RCX -1; if (RCX!=0 && ZF!=0) goto rel8; } +@endif + +:LOOPNZ rel8 is vexMode=0 & addrsize=0 & byte=0xE0; rel8 { CX = CX -1; if (CX!=0 && ZF==0) goto rel8; } +:LOOPNZ rel8 is vexMode=0 & addrsize=1 & byte=0xE0; rel8 { ECX = ECX -1; if (ECX!=0 && ZF==0) goto rel8; } +@ifdef IA64 +:LOOPNZ rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE0; rel8 { RCX = RCX -1; if (RCX!=0 && ZF==0) goto rel8; } +@endif + +define pcodeop SegmentLimit; +:LSL Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x3; rm16 & Reg16 ... +{ + tmp:3 = SegmentLimit(rm16); + Reg16 = tmp:2; + ZF = tmp[16,1]; +} + +:LSL Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x3; rm32 & Reg32 ... +{ + tmp:3 = SegmentLimit(rm32); + Reg32 = zext(tmp:2); + ZF = tmp[16,1]; +} + +@ifdef IA64 +:LSL Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x3; rm32 & Reg64 ... +{ + tmp:3 = SegmentLimit(rm32); + Reg64 = zext(tmp:2); + ZF = tmp[16,1]; +} +@endif + +define pcodeop TaskRegister; +:LTR rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=3 ... { TaskRegister(rm16); } + +:MOV Rmr8,Reg8 is vexMode=0 & byte=0x88; mod=3 & Rmr8 & Reg8 { Rmr8=Reg8; } + +:MOV^xrelease m8,Reg8 is vexMode=0 & xrelease & byte=0x88; m8 & Reg8 ... +{ + build xrelease; + build m8; + m8=Reg8; + } + +:MOV Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x89; mod=3 & Rmr16 & Reg16 { Rmr16=Reg16; } + +:MOV^xrelease m16,Reg16 is vexMode=0 & xrelease & opsize=0 & byte=0x89; m16 & Reg16 ... +{ + build xrelease; + build m16; + m16=Reg16; + } + +:MOV Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x89; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { Rmr32=Reg32; build check_Rmr32_dest; } + +:MOV^xrelease m32,Reg32 is vexMode=0 & xrelease & opsize=1 & byte=0x89; m32 & Reg32 ... +{ + build xrelease; + build m32; + m32=Reg32; +} + +@ifdef IA64 +:MOV Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x89; mod=3 & Rmr64 & Reg64 { Rmr64=Reg64; } + +:MOV^xrelease m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & xrelease & opsize=2 & byte=0x89; m64 & Reg64 ... +{ + build xrelease; + build m64; + m64=Reg64; + } + +@endif +:MOV Reg8,rm8 is vexMode=0 & byte=0x8a; rm8 & Reg8 ... { Reg8 = rm8; } +:MOV Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x8b; rm16 & Reg16 ... { Reg16 = rm16; } +:MOV Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x8b; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32; build check_Reg32_dest; } +@ifdef IA64 +:MOV Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x8b; rm64 & Reg64 ... { Reg64 = rm64; } +@endif +:MOV rm16,Sreg is vexMode=0 & byte=0x8c; rm16 & check_rm16_dest ... & Sreg ... { rm16 = Sreg; build check_rm16_dest; } +:MOV Sreg,rm16 is vexMode=0 & byte=0x8e; rm16 & Sreg ... { Sreg=rm16; } +:MOV AL,moffs8 is vexMode=0 & byte=0xa0; AL & moffs8 { AL=moffs8; } +:MOV AX,moffs16 is vexMode=0 & opsize=0 & byte=0xa1; AX & moffs16 { AX=moffs16; } +:MOV EAX,moffs32 is vexMode=0 & opsize=1 & byte=0xa1; EAX & check_EAX_dest & moffs32 { EAX=moffs32; build check_EAX_dest; } +@ifdef IA64 +:MOV RAX,moffs64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xa1; RAX & moffs64 { RAX=moffs64; } +@endif +:MOV moffs8,AL is vexMode=0 & byte=0xa2; AL & moffs8 { moffs8=AL; } +:MOV moffs16,AX is vexMode=0 & opsize=0 & byte=0xa3; AX & moffs16 { moffs16=AX; } +:MOV moffs32,EAX is vexMode=0 & opsize=1 & byte=0xa3; EAX & moffs32 { moffs32=EAX; } +@ifdef IA64 +:MOV moffs64,RAX is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xa3; RAX & moffs64 { moffs64=RAX; } +@endif +:MOV CRmr8,imm8 is vexMode=0 & row=11 & page=0 & CRmr8; imm8 { CRmr8 = imm8; } +:MOV CRmr16,imm16 is vexMode=0 & opsize=0 & row=11 & page=1 & CRmr16; imm16 { CRmr16 = imm16; } +:MOV CRmr32,imm32 is vexMode=0 & opsize=1 & row=11 & page=1 & CRmr32; imm32 { CRmr32 = imm32; } +@ifdef IA64 +:MOV Rmr64,imm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & row=11 & page=1 & Rmr64; imm64 { Rmr64 = imm64; } +@endif +:MOV Rmr8,imm8 is vexMode=0 & byte=0xc6; (mod=3 & Rmr8 & reg_opcode=0); imm8 { Rmr8 = imm8; } + +:MOV^xrelease spec_m8,imm8 is vexMode=0 & xrelease & byte=0xc6; spec_m8 & reg_opcode=0 ...; imm8 +{ + build xrelease; + build spec_m8; + spec_m8 = imm8; +} +:MOV Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0xc7; (mod=3 & Rmr16 & reg_opcode=0); imm16 { Rmr16 = imm16; } + +:MOV^xrelease spec_m16,imm16 is vexMode=0 & xrelease & opsize=0 & byte=0xc7; spec_m16 & reg_opcode=0 ...; imm16 +{ + build xrelease; + build spec_m16; + spec_m16 = imm16; +} + +:MOV Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0xc7; (mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=0); imm32 { Rmr32 = imm32; build check_Rmr32_dest; } + +:MOV^xrelease spec_m32,imm32 is vexMode=0 & xrelease & opsize=1 & byte=0xc7; (spec_m32 & reg_opcode=0 ...); imm32 +{ + build xrelease; + build spec_m32; + spec_m32 = imm32; +} +@ifdef IA64 +:MOV Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xc7; (mod=3 & Rmr64 & reg_opcode=0); simm32 { Rmr64 = simm32; } + +:MOV^xrelease spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & xrelease & opsize=2 & byte=0xc7; (spec_m64 & reg_opcode=0 ...); simm32 +{ + build xrelease; + build spec_m64; + spec_m64 = simm32; +} +@endif + +:MOV creg, Rmr32 is vexMode=0 & byte=0xf; byte=0x22; Rmr32 & creg { +@ifdef IA64 + creg=zext(Rmr32); +@else + creg=Rmr32; +@endif +} +@ifdef IA64 +:MOV creg_x, Rmr32 is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr32 & creg_x { creg_x=zext(Rmr32); } +:MOV creg, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x22; Rmr64 & creg { creg=Rmr64; } +:MOV creg_x, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr64 & creg_x { creg_x=Rmr64; } +@endif +:MOV Rmr32, creg is vexMode=0 & byte=0xf; byte=0x20; Rmr32 & creg { +@ifdef IA64 + Rmr32 = creg:4; +@else + Rmr32 = creg; +@endif +} +:MOV Rmr32, creg_x is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr32 & creg_x { Rmr32 = creg_x:4; } +@ifdef IA64 +:MOV Rmr64, creg is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x20; Rmr64 & creg { Rmr64 = creg; } +:MOV Rmr64, creg_x is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr64 & creg_x { Rmr64 = creg_x; } +@endif +:MOV Rmr32, debugreg is vexMode=0 & byte=0xf; byte=0x21; Rmr32 & debugreg { +@ifdef IA64 + Rmr32 = debugreg:4; +@else + Rmr32 = debugreg; +@endif +} +:MOV Rmr32, debugreg_x is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x21; Rmr32 & debugreg_x { Rmr32 = debugreg_x:4; } +@ifdef IA64 +:MOV Rmr64, debugreg is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x21; Rmr64 & debugreg { Rmr64 = debugreg; } +:MOV Rmr64, debugreg_x is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x21; Rmr64 & debugreg_x { Rmr64 = debugreg_x; } +@endif +:MOV debugreg, Rmr32 is vexMode=0 & byte=0xf; byte=0x23; Rmr32 & debugreg { +@ifdef IA64 + debugreg = zext(Rmr32); +@else + debugreg = Rmr32; +@endif +} +@ifdef IA64 +:MOV debugreg_x, Rmr32 is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x23; Rmr32 & debugreg_x & mod=3 { debugreg_x = zext(Rmr32); } +:MOV debugreg, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x23; Rmr64 & debugreg & mod=3 { debugreg = Rmr64; } +:MOV debugreg_x, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x23; Rmr64 & debugreg_x & mod=3 { debugreg_x = Rmr64; } +@endif + +@ifndef IA64 +# These are obsolete instructions after the 486 generation. +# They were erroneously placed in the IA64 build. +# They were removed to facilitate instruction patching to generate "MOV EAX, 0x2" correctly. +#:MOV r32, testreg is vexMode=0 & byte=0xf; byte=0x24; r32 & testreg & mod=3 { r32 = testreg; } +#: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 ); } +@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 ); } +@endif + + +:MOVNTI Mem,Reg32 is vexMode=0 & opsize = 1; byte=0xf; byte=0xc3; Mem & Reg32 ... { *Mem = Reg32; } +@ifdef IA64 +:MOVNTI Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize = 2; byte=0xf; byte=0xc3; Mem & Reg64 ... { *Mem = Reg64; } +@endif + +:MOVSB^rep^reptail eseDI1,dseSI1 is vexMode=0 & rep & reptail & byte=0xa4 & eseDI1 & dseSI1 { build rep; build eseDI1; build dseSI1; eseDI1 = dseSI1; build reptail; } +:MOVSW^rep^reptail eseDI2,dseSI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xa5 & eseDI2 & dseSI2 { build rep; build eseDI2; build dseSI2; eseDI2 = dseSI2; build reptail; } +:MOVSD^rep^reptail eseDI4,dseSI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xa5 & eseDI4 & dseSI4 { build rep; build eseDI4; build dseSI4; eseDI4 = dseSI4; build reptail; } +@ifdef IA64 +:MOVSQ^rep^reptail eseDI8,dseSI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xa5 & eseDI8 & dseSI8 { build rep; build eseDI8; build dseSI8; eseDI8 = dseSI8; build reptail; } +@endif + +:MOVSX Reg16,spec_rm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbe; spec_rm8 & Reg16 ... { Reg16 = sext(spec_rm8); } +:MOVSX Reg32,spec_rm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbe; spec_rm8 & Reg32 ... & check_Reg32_dest ... { Reg32 = sext(spec_rm8); build check_Reg32_dest; } +@ifdef IA64 +:MOVSX Reg64,spec_rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbe; spec_rm8 & Reg64 ... { Reg64 = sext(spec_rm8); } +@endif +:MOVSX Reg32,spec_rm16 is vexMode=0 & byte=0xf; byte=0xbf; spec_rm16 & Reg32 ... & check_Reg32_dest ... { Reg32 = sext(spec_rm16); build check_Reg32_dest; } +@ifdef IA64 +:MOVSX Reg64,spec_rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbf; spec_rm16 & Reg64 ... { Reg64 = sext(spec_rm16); } +@endif + +# Overlaps with ARPL in non-64bit modes +@ifdef IA64 +:MOVSXD Reg32,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=1 & byte=0x63; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32; build check_Reg32_dest; } +:MOVSXD Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x63; rm32 & Reg64 ... { Reg64 = sext(rm32); } +@endif + +:MOVZX Reg16,spec_rm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xb6; spec_rm8 & Reg16 ... { Reg16 = zext(spec_rm8); } +:MOVZX Reg32,spec_rm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb6; spec_rm8 & Reg32 ... & check_Reg32_dest ... { Reg32 = zext(spec_rm8); build check_Reg32_dest; } +@ifdef IA64 +:MOVZX Reg64,spec_rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xb6; spec_rm8 & Reg64 ... { Reg64 = zext(spec_rm8); } +@endif + +:MOVZX Reg32,spec_rm16 is vexMode=0 & byte=0xf; byte=0xb7; spec_rm16 & Reg32 ... & check_Reg32_dest ... { Reg32 = zext(spec_rm16); build check_Reg32_dest; } +@ifdef IA64 +:MOVZX Reg64,spec_rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xb7; spec_rm16 & Reg64 ... { Reg64 = zext(spec_rm16); } +@endif + +:MUL rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=4 ... { AX=zext(AL)*zext(rm8); multflags(AH); } +:MUL rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=4 ... { tmp:4=zext(AX)*zext(rm16); DX=tmp(2); AX=tmp(0); multflags(DX); } +:MUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=4 ... { tmp:8=zext(EAX)*zext(rm32); EDX=tmp(4); build check_EDX_dest; multflags(EDX); EAX=tmp(0); build check_EAX_dest; } +@ifdef IA64 +:MUL rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=4 ... { tmp:16=zext(RAX)*zext(rm64); RDX=tmp(8); RAX=tmp(0); multflags(RDX); } +@endif + +:MWAIT is vexMode=0 & byte=0x0f; byte=0x01; byte=0xC9 { mwait(); } +:MWAITX is vexMode=0 & byte=0x0f; byte=0x01; byte=0xFB { mwaitx(); } +:MONITOR is vexMode=0 & byte=0x0f; byte=0x01; byte=0xC8 { monitor(); } +:MONITORX is vexMode=0 & byte=0x0f; byte=0x01; byte=0xFA { monitorx(); } + +# See 'lockable.sinc' for memory destination, lockable variants +:NEG Rmr8 is vexMode=0 & byte=0xf6; mod=3 & Rmr8 & reg_opcode=3 { negflags(Rmr8); Rmr8 = -Rmr8; resultflags(Rmr8 ); } +:NEG Rmr16 is vexMode=0 & opsize=0 & byte=0xf7; mod=3 & Rmr16 & reg_opcode=3 { negflags(Rmr16); Rmr16 = -Rmr16; resultflags(Rmr16); } +:NEG Rmr32 is vexMode=0 & opsize=1 & byte=0xf7; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=3 { negflags(Rmr32); Rmr32 = -Rmr32; resultflags(Rmr32); build check_Rmr32_dest;} +@ifdef IA64 +:NEG Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; mod=3 & Rmr64 & reg_opcode=3 { negflags(Rmr64); Rmr64 = -Rmr64; resultflags(Rmr64); } +@endif + +:NOP is vexMode=0 & byte=0x90 & (mandover=0 | mandover=4) & (rexprefix=0 | rexWRXBprefix=8) { } +:NOP rm16 is vexMode=0 & mandover & opsize=0 & byte=0x0f; high5=3; rm16 ... { } +:NOP rm32 is vexMode=0 & mandover & opsize=1 & byte=0x0f; high5=3; rm32 ... { } +:NOP^"/reserved" rm16 is vexMode=0 & mandover & opsize=0 & byte=0x0f; byte=0x18; rm16 & reg_opcode_hb=1 ... { } +:NOP^"/reserved" rm32 is vexMode=0 & mandover & opsize=1 & byte=0x0f; byte=0x18; rm32 & reg_opcode_hb=1 ... { } +:NOP rm16 is vexMode=0 & mandover & opsize=0 & byte=0x0f; byte=0x1f; rm16 & reg_opcode=0 ... { } +:NOP rm32 is vexMode=0 & mandover & opsize=1 & byte=0x0f; byte=0x1f; rm32 & reg_opcode=0 ... { } + +# See 'lockable.sinc' for memory destination, lockable variants +:NOT Rmr8 is vexMode=0 & byte=0xf6; mod=3 & Rmr8 & reg_opcode=2 { Rmr8 = ~Rmr8; } +:NOT Rmr16 is vexMode=0 & opsize=0 & byte=0xf7; mod=3 & Rmr16 & reg_opcode=2 { Rmr16 = ~Rmr16; } +:NOT Rmr32 is vexMode=0 & opsize=1 & byte=0xf7; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=2 { Rmr32 = ~Rmr32; build check_Rmr32_dest;} +@ifdef IA64 +:NOT Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; mod=3 & Rmr64 & reg_opcode=2 { Rmr64 = ~Rmr64; } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:OR AL,imm8 is vexMode=0 & byte=0x0c; AL & imm8 { logicalflags(); AL = AL | imm8; resultflags( AL); } +:OR AX,imm16 is vexMode=0 & opsize=0 & byte=0xd; AX & imm16 { logicalflags(); AX = AX | imm16; resultflags( AX); } +:OR EAX,imm32 is vexMode=0 & opsize=1 & byte=0xd; EAX & check_EAX_dest & imm32 { logicalflags(); EAX = EAX | imm32; build check_EAX_dest; resultflags( EAX); } +@ifdef IA64 +:OR RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xd; RAX & simm32 { logicalflags(); RAX = RAX | simm32; resultflags( RAX); } +@endif +:OR Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=1; imm8 { logicalflags(); Rmr8 = Rmr8 | imm8; resultflags( Rmr8); } +:OR Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=1; imm16 { logicalflags(); Rmr16 = Rmr16 | imm16; resultflags( Rmr16); } +:OR Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=1; imm32 { logicalflags(); Rmr32 = Rmr32 | imm32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:OR Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=1; simm32 { logicalflags(); tmp:8 = Rmr64; Rmr64 = tmp | simm32; resultflags( Rmr64); } +@endif +:OR Rmr16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=1; usimm8_16 { logicalflags(); Rmr16 = Rmr16 | usimm8_16; resultflags( Rmr16); } +:OR Rmr32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=1; usimm8_32 { logicalflags(); Rmr32 = Rmr32 | usimm8_32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:OR Rmr64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=1; usimm8_64 { logicalflags(); Rmr64 = Rmr64 | usimm8_64; resultflags( Rmr64); } +@endif +:OR Rmr8,Reg8 is vexMode=0 & byte=0x8; mod=3 & Rmr8 & Reg8 { logicalflags(); Rmr8 = Rmr8 | Reg8; resultflags( Rmr8); } +:OR Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x9; mod=3 & Rmr16 & Reg16 { logicalflags(); Rmr16 = Rmr16 | Reg16; resultflags( Rmr16); } +:OR Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x9; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { logicalflags(); Rmr32 = Rmr32 | Reg32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:OR Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x9; mod=3 & Rmr64 & Reg64 { logicalflags(); Rmr64 = Rmr64 | Reg64; resultflags( Rmr64); } +@endif +:OR Reg8,rm8 is vexMode=0 & byte=0xa; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 | rm8; resultflags( Reg8); } +:OR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xb; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 | rm16; resultflags(Reg16); } +:OR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xb; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 | rm32; build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:OR Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xb; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 | rm64; resultflags(Reg64); } +@endif + +:OUT imm8,AL is vexMode=0 & byte=0xe6; imm8 & AL { tmp:1 = imm8; out(tmp,AL); } +:OUT imm8,AX is vexMode=0 & opsize=0 & byte=0xe7; imm8 & AX { tmp:1 = imm8; out(tmp,AX); } +:OUT imm8,EAX is vexMode=0 & byte=0xe7; imm8 & EAX { tmp:1 = imm8; out(tmp,EAX); } +:OUT DX,AL is vexMode=0 & byte=0xee & DX & AL { out(DX,AL); } +:OUT DX,AX is vexMode=0 & opsize=0 & byte=0xef & DX & AX { out(DX,AX); } +:OUT DX,EAX is vexMode=0 & byte=0xef & DX & EAX { out(DX,EAX); } + +:OUTSB^rep^reptail DX,dseSI1 is vexMode=0 & rep & reptail & byte=0x6e & DX & dseSI1 { build rep; build dseSI1; out(dseSI1,DX); build reptail;} +:OUTSW^rep^reptail DX,dseSI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0x6f & DX & dseSI2 { build rep; build dseSI2; out(dseSI2,DX); build reptail;} +:OUTSD^rep^reptail DX,dseSI4 is vexMode=0 & rep & reptail & byte=0x6f & DX & dseSI4 { build rep; build dseSI4; out(dseSI4,DX); build reptail;} + +:PAUSE is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x90 { } +:PAUSE is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x90 { } + +:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop22(rm16); } +:POP rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop42(rm16); } +:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop24(rm32); } +:POP rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop44(rm32); } +@ifdef IA64 +:POP rm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop82(rm16); } +:POP rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x8f; rm64 & reg_opcode=0 ... { pop88(rm64); } +@endif + +:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=1 & Rmr16 { pop22(Rmr16); } +:POP Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & row=5 & page=1 & Rmr16 { pop42(Rmr16); } +:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=1 & Rmr32 { pop24(Rmr32); } +:POP Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=1 & Rmr32 { pop44(Rmr32); } +@ifdef IA64 +:POP Rmr16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=1 & Rmr16 { pop82(Rmr16); } +:POP Rmr64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & row=5 & page=1 & Rmr64 { pop88(Rmr64); } +@endif + +:POP DS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x1f & DS { pop22(DS); } +:POP DS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x1f & DS { popseg44(DS); } +:POP ES is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x7 & ES { pop22(ES); } +:POP ES is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x7 & ES { popseg44(ES); } +:POP SS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x17 & SS { pop22(SS); } +:POP SS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x17 & SS { popseg44(SS); } +:POP FS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0xf; byte=0xa1 & FS { pop22(FS); } +:POP FS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0xf; byte=0xa1 & FS { popseg44(FS); } +@ifdef IA64 +:POP FS is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0xf; byte=0xa1 & FS { popseg82(FS); } +:POP FS is $(LONGMODE_ON) & vexMode=0 & byte=0xf; byte=0xa1 & FS { popseg88(FS); } +@endif +:POP GS is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xf; byte=0xa9 & GS { pop22(GS); } +:POP GS is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xf; byte=0xa9 & GS { popseg44(GS); } +@ifdef IA64 +:POP GS is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0xf; byte=0xa9 & GS { popseg82(GS); } +:POP GS is $(LONGMODE_ON) & vexMode=0 & byte=0xf; byte=0xa9 & GS { popseg88(GS); } +@endif + +:POPA is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x61 { pop22(DI); pop22(SI); pop22(BP); tmp:2=0; pop22(tmp); pop22(BX); pop22(DX); pop22(CX); pop22(AX); } +:POPA is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x61 { pop42(DI); pop42(SI); pop42(BP); tmp:2=0; pop42(tmp); pop42(BX); pop42(DX); pop42(CX); pop42(AX); } +:POPAD is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x61 { pop24(EDI); pop24(ESI); pop24(EBP); tmp:4=0; pop24(tmp); pop24(EBX); pop24(EDX); pop24(ECX); pop24(EAX); } +:POPAD is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x61 { pop44(EDI); pop44(ESI); pop44(EBP); tmp:4=0; pop44(tmp); pop44(EBX); pop44(EDX); pop44(ECX); pop44(EAX); } +:POPF is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x9d { pop22(flags); unpackflags(flags); } +:POPF is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x9d { pop42(flags); unpackflags(flags); } +:POPFD is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x9d { pop24(eflags); unpackflags(eflags); unpackeflags(eflags); } +:POPFD is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x9d { pop44(eflags); unpackflags(eflags); unpackeflags(eflags); } +@ifdef IA64 +:POPF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x9d { pop82(flags); unpackflags(flags); } +:POPFQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x9d { pop88(rflags); unpackflags(rflags); unpackeflags(rflags); } +@endif + +:PREFETCH m8 is vexMode=0 & byte=0x0f; byte=0x0d; m8 & reg_opcode=0 ... { } +:PREFETCH m8 is vexMode=0 & byte=0x0f; byte=0x0d; m8 & reg_opcode ... { } # rest aliased to /0 +:PREFETCHW m8 is vexMode=0 & byte=0x0f; byte=0x0d; m8 & reg_opcode=1 ... { } +:PREFETCHWT1 m8 is vexMode=0 & byte=0x0f; byte=0x0d; m8 & reg_opcode=2 ... { } + +:PREFETCHT0 m8 is vexMode=0 & byte=0x0f; byte=0x18; ( mod != 0b11 & reg_opcode=1 ) ... & m8 { } +:PREFETCHT1 m8 is vexMode=0 & byte=0x0f; byte=0x18; ( mod != 0b11 & reg_opcode=2 ) ... & m8 { } +:PREFETCHT2 m8 is vexMode=0 & byte=0x0f; byte=0x18; ( mod != 0b11 & reg_opcode=3 ) ... & m8 { } +:PREFETCHNTA m8 is vexMode=0 & byte=0x0f; byte=0x18; ( mod != 0b11 & reg_opcode=0 ) ... & m8 { } + +define pcodeop ptwrite; + +:PTWRITE rm32 is vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0xae; rm32 & reg_opcode=4 ... { ptwrite(rm32); } + +:PUSH rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0xff; rm16 & reg_opcode=6 ... { push22(rm16); } +:PUSH rm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xff; rm16 & reg_opcode=6 ... { push42(rm16); } +:PUSH rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0xff; rm32 & reg_opcode=6 ... { push24(rm32); } +:PUSH rm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xff; rm32 & reg_opcode=6 ... { push44(rm32); } +@ifdef IA64 +:PUSH rm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xff; rm16 & reg_opcode=6 ... { push82(rm16); } +:PUSH rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=6 ... { push88(rm64); } +@endif +:PUSH Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=0 & Rmr16 { push22(Rmr16); } +:PUSH Rmr16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & row=5 & page=0 & Rmr16 { push42(Rmr16); } +:PUSH Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=0 & Rmr32 { push24(Rmr32); } +:PUSH Rmr32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=0 & Rmr32 { push44(Rmr32); } +@ifdef IA64 +:PUSH Rmr16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=0 & Rmr16 { push82(Rmr16); } +:PUSH Rmr64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & row=5 & page=0 & Rmr64 { push88(Rmr64); } +@endif +:PUSH simm8_16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push22(tmp); } +:PUSH simm8_16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push42(tmp); } +@ifdef IA64 +:PUSH simm8_16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push82(tmp); } +@endif +:PUSH simm8_32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x6a; simm8_32 { tmp:4=simm8_32; push24(tmp); } +:PUSH simm8_32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x6a; simm8_32 { tmp:4=simm8_32; push44(tmp); } +@ifdef IA64 +:PUSH simm8_64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } +:PUSH simm8_64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } +@endif +:PUSH simm16_16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push22(tmp); } +:PUSH simm16_16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push42(tmp); } +@ifdef IA64 +:PUSH simm16_16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push82(tmp); } +@endif +:PUSH imm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x68; imm32 { tmp:4=imm32; push24(tmp); } +:PUSH imm32 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x68; imm32 { tmp:4=imm32; push44(tmp); } +@ifdef IA64 +:PUSH simm32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } +:PUSH simm32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } +@endif + +:PUSH CS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0xe & CS { push22(CS); } +:PUSH CS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0xe & CS { pushseg44(CS); } +:PUSH SS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x16 & SS { push22(SS); } +:PUSH SS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x16 & SS { pushseg44(SS); } +:PUSH DS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x1e & DS { push22(DS); } +:PUSH DS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x1e & DS { pushseg44(DS); } +:PUSH ES is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0x6 & ES { push22(ES); } +:PUSH ES is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0x6 & ES { pushseg44(ES); } +:PUSH FS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0xf; byte=0xa0 & FS { push22(FS); } +:PUSH FS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0xf; byte=0xa0 & FS { pushseg44(FS); } +@ifdef IA64 +:PUSH FS is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0xf; byte=0xa0 & FS { pushseg82(FS); } +:PUSH FS is $(LONGMODE_ON) & vexMode=0 & byte=0xf; byte=0xa0 & FS { pushseg88(FS); } +@endif +:PUSH GS is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & byte=0xf; byte=0xa8 & GS { push22(GS); } +:PUSH GS is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & byte=0xf; byte=0xa8 & GS { pushseg44(GS); } +@ifdef IA64 +:PUSH GS is $(LONGMODE_ON) & vexMode=0 & opsize=0 & byte=0xf; byte=0xa8 & GS { pushseg82(GS); } +:PUSH GS is $(LONGMODE_ON) & vexMode=0 & byte=0xf; byte=0xa8 & GS { pushseg88(GS); } +@endif + +:PUSHA is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x60 { local tmp=SP; push22(AX); push22(CX); push22(DX); push22(BX); push22(tmp); push22(BP); push22(SI); push22(DI); } +:PUSHA is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x60 { local tmp=SP; push42(AX); push42(CX); push42(DX); push42(BX); push42(tmp); push42(BP); push42(SI); push42(DI); } +:PUSHAD is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x60 { local tmp=ESP; push24(EAX); push24(ECX); push24(EDX); push24(EBX); push24(tmp); push24(EBP); push24(ESI); push24(EDI); } +:PUSHAD is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x60 { local tmp=ESP; push44(EAX); push44(ECX); push44(EDX); push44(EBX); push44(tmp); push44(EBP); push44(ESI); push44(EDI); } + +:PUSHF is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0x9c { packflags(flags); push22(flags); } +:PUSHF is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0x9c { packflags(flags); push42(flags); } +:PUSHFD is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0x9c { packflags(eflags); packeflags(eflags); push24(eflags); } +:PUSHFD is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0x9c { packflags(eflags); packeflags(eflags); push44(eflags); } +@ifdef IA64 +:PUSHF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x9c { packflags(flags); push82(flags); } +:PUSHFQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x9c { packflags(rflags); packeflags(rflags); push88(rflags); } +@endif + +:RCL rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=2 ... { local tmpCF = CF; CF = rm8 s< 0; rm8 = (rm8 << 1) | tmpCF; OF = CF ^ (rm8 s< 0); } +:RCL rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=2 ... { local cnt=(CL&0x1f)%9; tmp:2=(zext(CF)<<8)|zext(rm8); tmp=(tmp<>(9-cnt));rm8=tmp(0); CF=(tmp&0x100)!=0; } +:RCL rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=2 ... ; imm8 { local cnt=(imm8&0x1f)%9; tmp:2=(zext(CF)<<8)|zext(rm8); tmp=(tmp<>(9-cnt)); rm8=tmp(0); CF=(tmp&0x100)!=0; } +:RCL rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=2 ... { local tmpCF = CF; CF = rm16 s< 0; rm16 = (rm16 << 1) | zext(tmpCF); OF = CF ^ (rm16 s< 0);} +:RCL rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=2 ... {local cnt=(CL&0x1f)%17; tmp:4=(zext(CF)<<16)|zext(rm16); tmp=(tmp<>(17-cnt)); rm16=tmp(0); CF=(tmp&0x10000)!=0; } +:RCL rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=2 ... ; imm8 { local cnt=(imm8&0x1f)%17; tmp:4=(zext(CF)<<16)|zext(rm16); tmp=(tmp<>(17-cnt)); rm16=tmp(0); CF=(tmp&0x10000)!=0; } +:RCL rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=2 ... { local tmpCF=CF; CF=rm32 s< 0; rm32=(rm32<<1)|zext(tmpCF); OF=CF^(rm32 s< 0); build check_rm32_dest; } +:RCL rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=2 ... { local cnt=CL&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp<>(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } +:RCL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=2 ... ; imm8 { local cnt=imm8&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp<>(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } +@ifdef IA64 +:RCL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=2 ... { local tmpCF=CF; CF=rm64 s< 0; rm64=(rm64<<1)|zext(tmpCF); OF=CF^(rm64 s< 0);} +:RCL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=2 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=2 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +@endif + +:RCR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm8 s< 0; CF=(rm8&1)!=0; rm8=(rm8>>1)|(tmpCF<<7); OF=OF^(rm8 s< 0); } +:RCR rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=3 ... { local cnt=(CL&0x1f)%9; tmp:2=(zext(CF)<<8)|zext(rm8); tmp=(tmp>>cnt)|(tmp<<(9-cnt)); rm8=tmp(0); CF=(tmp&0x100)!=0; } +:RCR rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=3 ... ; imm8 { local cnt=(imm8&0x1f)%9; tmp:2=(zext(CF)<<8)|zext(rm8); tmp=(tmp>>cnt)|(tmp<<(9-cnt)); rm8=tmp(0); CF=(tmp&0x100)!=0; } +:RCR rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm16 s< 0; CF=(rm16&1)!=0; rm16=(rm16>>1)|(zext(tmpCF)<<15); OF=OF^(rm16 s< 0); } +:RCR rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=3 ... { local cnt=(CL&0x1f)%17; tmp:4=(zext(CF)<<16)|zext(rm16); tmp=(tmp>>cnt)|(tmp<<(17-cnt)); rm16=tmp(0); CF=(tmp&0x10000)!=0; } +:RCR rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=3 ... ; imm8 { local cnt=(imm8&0x1f)%17; tmp:4=(zext(CF)<<16)|zext(rm16); tmp=(tmp>>cnt)|(tmp<<(17-cnt)); rm16=tmp(0); CF=(tmp&0x10000)!=0; } +:RCR rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=3 ... { local tmpCF=CF; OF=rm32 s< 0; CF=(rm32&1)!=0; rm32=(rm32>>1)|(zext(tmpCF)<<31); OF=OF^(rm32 s< 0); build check_rm32_dest; } +:RCR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=3 ... { local cnt=CL&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp>>cnt)|(tmp<<(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } +:RCR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=3 ... ; imm8 { local cnt=imm8&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp>>cnt)|(tmp<<(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } +@ifdef IA64 +:RCR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm64 s< 0; CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(tmpCF)<<63); OF=OF^(rm64 s< 0); } +:RCR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=3 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=3 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +@endif + +@ifdef IA64 +define pcodeop readfsbase; +:RDFSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=0 & r32 { r32 = readfsbase(); } +:RDFSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=0 & r64 { r64 = readfsbase(); } + +define pcodeop readgsbase; +:RDGSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=1 & r32 { r32 = readgsbase(); } +:RDGSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=1 & r64 { r64 = readgsbase(); } +@endif + +define pcodeop rdmsr; +:RDMSR is vexMode=0 & byte=0xf; byte=0x32 & check_EAX_dest & check_EDX_dest { + tmp:8 = rdmsr(ECX); + EDX = tmp(4); build check_EDX_dest; + EAX = tmp(0); build check_EAX_dest; +} + +define pcodeop readPID; +:RDPID r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xc7; reg_opcode=7 & r32 { r32 = readPID(); } +@ifdef IA64 +:RDPID r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xc7; reg_opcode=7 & r64 { r64 = readPID(); } +@endif + +define pcodeop rdpkru_u32; +:RDPKRU is vexMode=0 & byte=0x0f; byte=0x01; byte=0xee { EAX = rdpkru_u32(); } + +define pcodeop rdpmc; +:RDPMC is vexMode=0 & byte=0xf; byte=0x33 { tmp:8 = rdpmc(ECX); EDX = tmp(4); EAX = tmp:4; } + +define pcodeop rdtsc; +:RDTSC is vexMode=0 & byte=0xf; byte=0x31 { tmp:8 = rdtsc(); EDX = tmp(4); EAX = tmp(0); } + +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0xc3 { pop22(IP); EIP=segment(CS,IP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xc3 { pop42(IP); EIP=zext(IP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0xc3 { pop24(EIP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xc3 { pop44(EIP); return [EIP]; } +@ifdef IA64 +:RET is $(LONGMODE_ON) & vexMode=0 & byte=0xc3 { pop88(RIP); return [RIP]; } +@endif + +:RETF is vexMode=0 & addrsize=0 & opsize=0 & byte=0xcb { pop22(IP); pop22(CS); EIP = segment(CS,IP); return [EIP]; } +:RETF is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop42(IP); EIP=zext(IP); pop42(CS); return [EIP]; } +@ifdef IA64 +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } +@endif +:RETF is vexMode=0 & addrsize=0 & opsize=1 & byte=0xcb { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); return [EIP]; } +:RETF is vexMode=0 & addrsize=1 & opsize=1 & byte=0xcb { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); return [EIP]; } +@ifdef IA64 +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xcb { pop84(EIP); RIP=zext(EIP); tmp:4=0; pop84(tmp); CS=tmp(0); return [RIP]; } +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xcb { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); return [RIP]; } +@endif + +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0xc2; imm16 { pop22(IP); EIP=zext(IP); SP=SP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xc2; imm16 { pop42(IP); EIP=zext(IP); ESP=ESP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0xc2; imm16 { pop24(EIP); SP=SP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xc2; imm16 { pop44(EIP); ESP=ESP+imm16; return [EIP]; } +@ifdef IA64 +:RET imm16 is $(LONGMODE_ON) & vexMode=0 & byte=0xc2; imm16 { pop88(RIP); RSP=RSP+imm16; return [RIP]; } +@endif + +:RETF imm16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0xca; imm16 { pop22(IP); EIP=zext(IP); pop22(CS); SP=SP+imm16; return [EIP]; } +:RETF imm16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0xca; imm16 { pop42(IP); EIP=zext(IP); pop42(CS); ESP=ESP+imm16; return [EIP]; } +@ifdef IA64 +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xca; imm16 { pop42(IP); RIP=zext(IP); pop42(CS); RSP=RSP+imm16; return [RIP]; } +@endif + +:RETF imm16 is vexMode=0 & addrsize=0 & opsize=1 & byte=0xca; imm16 { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); SP=SP+imm16; return [EIP]; } +:RETF imm16 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xca; imm16 { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); ESP=ESP+imm16; return [EIP]; } +@ifdef IA64 +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xca; imm16 { pop44(EIP); tmp:4=0; pop44(tmp); RIP=zext(EIP); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xca; imm16 { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } +@endif + +:ROL rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=0 ... { CF = rm8 s< 0; rm8 = (rm8 << 1) | CF; OF = CF ^ (rm8 s< 0); } +:ROL rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=0 ... { local cnt = CL & 0x7; local count_and_mask = CL & 0x1f;rm8 = (rm8 << cnt) | (rm8 >> (8 - cnt)); rolflags(rm8, count_and_mask);} +:ROL rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x7; rm8 = (rm8 << cnt) | (rm8 >> (8 - cnt)); rolflags(rm8,imm8 & 0x1f:1);} +:ROL rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=0 ... { CF = rm16 s< 0; rm16 = (rm16 << 1) | zext(CF); OF = CF ^ (rm16 s< 0); } +:ROL rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=0 ... { local cnt = CL & 0xf; local count_and_mask = CL & 0x1f;rm16 = (rm16 << cnt) | (rm16 >> (16 - cnt)); rolflags(rm16,count_and_mask);} +:ROL rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0xf; rm16 = (rm16 << cnt) | (rm16 >> (16 - cnt)); rolflags(rm16,imm8 & 0x1f:1);} +:ROL rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=0 ... { CF = rm32 s< 0; rm32 = (rm32 << 1) | zext(CF); OF = CF ^ (rm32 s< 0); build check_rm32_dest; } +:ROL rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=0 ... { local cnt = CL & 0x1f; rm32 = (rm32 << cnt) | (rm32 >> (32 - cnt)); rolflags(rm32,cnt); build check_rm32_dest; } +:ROL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x1f; rm32 = (rm32 << cnt) | (rm32 >> (32 - cnt)); rolflags(rm32,cnt); build check_rm32_dest; } +@ifdef IA64 +:ROL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=0 ... { CF = rm64 s< 0; rm64 = (rm64 << 1) | zext(CF); OF = CF ^ (rm64 s< 0); } +:ROL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=0 ... { local cnt = CL & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} +:ROL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} +@endif + +:ROR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=1 ... { CF = rm8 & 1; rm8 = (rm8 >> 1) | (CF << 7); OF = ((rm8 & 0x40) != 0) ^ (rm8 s< 0); } +:ROR rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=1 ... { local cnt = CL & 0x7; local count_and_mask = CL & 0x1f;rm8 = (rm8 >> cnt) | (rm8 << (8 - cnt)); rorflags(rm8,count_and_mask);} +:ROR rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x7; rm8 = (rm8 >> cnt) | (rm8 << (8 - cnt)); rorflags(rm8,imm8 & 0x1f:1);} +:ROR rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=1 ... { CF=(rm16 & 1)!=0; rm16=(rm16>>1)|(zext(CF)<<15); OF=((rm16 & 0x4000) != 0) ^ (rm16 s< 0); } +:ROR rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=1 ... { local cnt = CL & 0xf; local count_and_mask = CL & 0x1f; rm16 = (rm16 >> cnt) | (rm16 << (16 - cnt)); rorflags(rm16,count_and_mask);} +:ROR rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0xf; rm16 = (rm16 >> cnt) | (rm16 << (16 - cnt)); rorflags(rm16,imm8 & 0x1f:1);} +:ROR rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=1 ... { CF=(rm32&1)!=0; rm32=(rm32>>1)|(zext(CF)<<31); OF=((rm32&0x40000000)!=0) ^ (rm32 s< 0); build check_rm32_dest; } +:ROR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=1 ... { local cnt = CL & 0x1f; rm32 = (rm32 >> cnt) | (rm32 << (32 - cnt)); rorflags(rm32,cnt); build check_rm32_dest; } +:ROR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x1f; rm32 = (rm32 >> cnt) | (rm32 << (32 - cnt)); rorflags(rm32,cnt); build check_rm32_dest; } +@ifdef IA64 +:ROR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=1 ... { CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(CF)<<63); OF=((rm64&0x4000000000000000)!=0) ^ (rm64 s< 0); } +:ROR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=1 ... { local cnt = CL & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} +:ROR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} +@endif + +define pcodeop smm_restore_state; +:RSM is vexMode=0 & byte=0xf; byte=0xaa { tmp:4 = smm_restore_state(); return [tmp]; } + +# Initially disallowed in 64bit mode, but later reintroduced +:SAHF is vexMode=0 & byte=0x9e { SF = (AH & 0x80) != 0; + ZF = (AH & 0x40) != 0; + AF = (AH & 0x10) != 0; + PF = (AH & 0x04) != 0; + CF = (AH & 0x01) != 0; } + +:SALC is $(LONGMODE_OFF) & vexMode=0 & byte=0xd6 { AL = CF * 0xff; } + +:SAR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=7 ... { CF = rm8 & 1; OF = 0; rm8 = rm8 s>> 1; resultflags(rm8); } +:SAR rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=7 ... { local count = CL & 0x1f; local tmp = rm8; rm8 = rm8 s>> count; + sarflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SAR rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm8; rm8 = rm8 s>> count; + sarflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SAR rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=7 ... { CF = (rm16 & 1) != 0; OF = 0; rm16 = rm16 s>> 1; resultflags(rm16); } +:SAR rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=7 ... { local count = CL & 0x1f; local tmp = rm16; rm16 = rm16 s>> count; + sarflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SAR rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm16; rm16 = rm16 s>> count; + sarflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SAR rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=7 ... { CF = (rm32 & 1) != 0; OF = 0; rm32 = rm32 s>> 1; build check_rm32_dest; resultflags(rm32); } +:SAR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=7 ... { local count = CL & 0x1f; local tmp = rm32; rm32 = rm32 s>> count; build check_rm32_dest; + sarflags(tmp, rm32,count); shiftresultflags(rm32,count); } +:SAR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 s>> count; build check_rm32_dest; + sarflags(tmp, rm32,count); shiftresultflags(rm32,count); } +@ifdef IA64 +:SAR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=7 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 s>> 1; resultflags(rm64); } +:SAR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=7 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; + sarflags(tmp, rm64,count); shiftresultflags(rm64,count); } +:SAR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; + sarflags(tmp, rm64,count); shiftresultflags(rm64,count); } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:SBB AL,imm8 is vexMode=0 & byte=0x1c; AL & imm8 { subCarryFlags( AL, imm8 ); resultflags(AL); } +:SBB AX,imm16 is vexMode=0 & opsize=0 & byte=0x1d; AX & imm16 { subCarryFlags( AX, imm16 ); resultflags(AX); } +:SBB EAX,imm32 is vexMode=0 & opsize=1 & byte=0x1d; EAX & check_EAX_dest & imm32 { subCarryFlags( EAX, imm32 ); build check_EAX_dest; resultflags(EAX); } +@ifdef IA64 +:SBB RAX,simm32_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1d; RAX & simm32_64 { subCarryFlags( RAX, simm32_64 ); resultflags(RAX); } +@endif +:SBB Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=3; imm8 { subCarryFlags( Rmr8, imm8 ); resultflags(Rmr8); } +:SBB Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=3; imm16 { subCarryFlags( Rmr16, imm16 ); resultflags(Rmr16); } +:SBB Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=3; imm32 { subCarryFlags( Rmr32, imm32 ); build check_Rmr32_dest; resultflags(Rmr32); } +@ifdef IA64 +:SBB Rmr64,imm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=3; imm32 { subCarryFlags( Rmr64, imm32 ); resultflags(Rmr64); } +@endif + +:SBB Rmr16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=3; simm8_16 { subCarryFlags( Rmr16, simm8_16 ); resultflags(Rmr16); } +:SBB Rmr32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_Rmr32_dest & reg_opcode=3; simm8_32 { subCarryFlags( Rmr32, simm8_32 ); build check_Rmr32_dest; resultflags(Rmr32); } +@ifdef IA64 +:SBB Rmr64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=3; simm8_64 { subCarryFlags( Rmr64, simm8_64 ); resultflags(Rmr64); } +@endif + +:SBB Rmr8,Reg8 is vexMode=0 & byte=0x18; mod=3 & Rmr8 & Reg8 { subCarryFlags( Rmr8, Reg8 ); resultflags(Rmr8); } +:SBB Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x19; mod=3 & Rmr16 & Reg16 { subCarryFlags( Rmr16, Reg16 ); resultflags(Rmr16); } +:SBB Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x19; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { subCarryFlags( Rmr32, Reg32 ); build check_Rmr32_dest; resultflags(Rmr32); } +@ifdef IA64 +:SBB Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x19; mod=3 & Rmr64 & Reg64 { subCarryFlags( Rmr64, Reg64 ); resultflags(Rmr64); } +@endif + +:SBB Reg8,rm8 is vexMode=0 & byte=0x1a; rm8 & Reg8 ... { subCarryFlags( Reg8, rm8 ); resultflags(Reg8); } +:SBB Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x1b; rm16 & Reg16 ... { subCarryFlags( Reg16, rm16 ); resultflags(Reg16); } +:SBB Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x1b; rm32 & Reg32 ... & check_Reg32_dest ... { subCarryFlags( Reg32, rm32 ); build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:SBB Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1b; rm64 & Reg64 ... { subCarryFlags( Reg64, rm64 ); resultflags(Reg64); } +@endif + +:SCASB^repe^repetail eseDI1 is vexMode=0 & repe & repetail & byte=0xae & eseDI1 { build repe; build eseDI1; subflags(AL,eseDI1); local diff=AL-eseDI1; resultflags(diff); build repetail; } +:SCASW^repe^repetail eseDI2 is vexMode=0 & repe & repetail & opsize=0 & byte=0xaf & eseDI2 { build repe; build eseDI2; subflags(AX,eseDI2); local diff=AX-eseDI2; resultflags(diff); build repetail; } +:SCASD^repe^repetail eseDI4 is vexMode=0 & repe & repetail & opsize=1 & byte=0xaf & eseDI4 { build repe; build eseDI4; subflags(EAX,eseDI4); local diff=EAX-eseDI4; resultflags(diff); build repetail; } +@ifdef IA64 +: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 + +:SET^cc rm8 is vexMode=0 & byte=0xf; row=9 & cc; rm8 { rm8 = cc; } + +# manual is not consistent on operands +:SGDT m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=0 ) ... & m16 +{ + m16 = GlobalDescriptorTableRegister(); +} + +:SGDT m32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=0 ) ... & m32 +{ + m32 = GlobalDescriptorTableRegister(); +} + +@ifdef IA64 +:SGDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=0 ) ... & m64 +{ + m64 = GlobalDescriptorTableRegister(); +} +@endif + + +:SHL rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 &(reg_opcode=4|reg_opcode=6) ... { CF = rm8 s< 0; rm8 = rm8 << 1; OF = CF ^^ (rm8 s< 0); resultflags(rm8); } +:SHL rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x1f; local tmp = rm8; rm8 = rm8 << count; + shlflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SHL rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm8; rm8 = rm8 << count; + shlflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SHL rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & (reg_opcode=4|reg_opcode=6) ... { CF = rm16 s< 0; rm16 = rm16 << 1; OF = CF ^^ (rm16 s< 0); resultflags(rm16); } +:SHL rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x1f; local tmp = rm16; rm16 = rm16 << count; + shlflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SHL rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm16; rm16 = rm16 << count; + shlflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SHL rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & (reg_opcode=4|reg_opcode=6) ... { CF = rm32 s< 0; rm32 = rm32 << 1; OF = CF ^^ (rm32 s< 0); build check_rm32_dest; resultflags(rm32); } +:SHL rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x1f; local tmp = rm32; rm32 = rm32 << count; build check_rm32_dest; + shlflags(tmp, rm32,count); shiftresultflags(rm32,count); } +:SHL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 << count; build check_rm32_dest; + shlflags(tmp, rm32,count); shiftresultflags(rm32,count); } +@ifdef IA64 +:SHL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & (reg_opcode=4|reg_opcode=6) ... { CF = rm64 s< 0; rm64 = rm64 << 1; OF = CF ^^ (rm64 s< 0); resultflags(rm64); } +:SHL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 << count; + shlflags(tmp, rm64,count); shiftresultflags(rm64,count); } +:SHL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 << count; + shlflags(tmp, rm64,count); shiftresultflags(rm64,count); } +@endif + +:SHLD rm16,Reg16,imm8 is vexMode=0 & opsize=0; byte=0x0F; byte=0xA4; rm16 & Reg16 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm16; + rm16 = (rm16 << count) | (Reg16 >> (16 - count)); + shlflags(tmp,rm16,count); shiftresultflags(rm16,count);} +:SHLD rm16,Reg16,CL is vexMode=0 & opsize=0; byte=0x0F; byte=0xA5; CL & rm16 & Reg16 ... { local count = CL & 0x1f; local tmp = rm16; + rm16 = (rm16 << count) | (Reg16 >> (16 - count)); + shlflags(tmp,rm16,count); shiftresultflags(rm16,count); } +:SHLD rm32,Reg32,imm8 is vexMode=0 & opsize=1; byte=0x0F; byte=0xA4; rm32 & check_rm32_dest ... & Reg32 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; + rm32 = (rm32 << count) | (Reg32 >> (32 - count)); build check_rm32_dest; + shlflags(tmp,rm32,count); shiftresultflags(rm32,count); } +:SHLD rm32,Reg32,CL is vexMode=0 & opsize=1; byte=0x0F; byte=0xA5; CL & rm32 & check_rm32_dest ... & Reg32 ... { local count = CL & 0x1f; local tmp = rm32; + rm32 = (rm32 << count) | (Reg32 >> (32 - count)); build check_rm32_dest; + shlflags(tmp,rm32,count); shiftresultflags(rm32,count); } +@ifdef IA64 +:SHLD rm64,Reg64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xA4; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; + rm64 = (rm64 << count) | (Reg64 >> (64 - count)); + shlflags(tmp,rm64,count); shiftresultflags(rm64,count); } +:SHLD rm64,Reg64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xA5; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; + rm64 = (rm64 << count) | (Reg64 >> (64 - count)); + shlflags(tmp,rm64,count); shiftresultflags(rm64,count); } +@endif + +:SHRD rm16,Reg16,imm8 is vexMode=0 & opsize=0; byte=0x0F; byte=0xAC; rm16 & Reg16 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm16; + rm16 = (rm16 >> count) | (Reg16 << (16 - count)); + shrdflags(tmp,rm16,count); shiftresultflags(rm16,count); } +:SHRD rm16,Reg16,CL is vexMode=0 & opsize=0; byte=0x0F; byte=0xAD; CL & rm16 & Reg16 ... { local count = CL & 0x1f; local tmp = rm16; + rm16 = (rm16 >> count) | (Reg16 << (16 - count)); + shrdflags(tmp,rm16,count); shiftresultflags(rm16,count); } +:SHRD rm32,Reg32,imm8 is vexMode=0 & opsize=1; byte=0x0F; byte=0xAC; rm32 & check_rm32_dest ... & Reg32 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; + rm32 = (rm32 >> count) | (Reg32 << (32 - count)); build check_rm32_dest; + shrdflags(tmp,rm32,count); shiftresultflags(rm32,count); } +:SHRD rm32,Reg32,CL is vexMode=0 & opsize=1; byte=0x0F; byte=0xAD; CL & rm32 & check_rm32_dest ... & Reg32 ... { local count = CL & 0x1f; local tmp = rm32; + rm32 = (rm32 >> count) | (Reg32 << (32 - count)); build check_rm32_dest; + shrdflags(tmp,rm32,count); shiftresultflags(rm32,count); } +@ifdef IA64 +:SHRD rm64,Reg64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xAC; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; + rm64 = (rm64 >> count) | (Reg64 << (64 - count)); + shrdflags(tmp,rm64,count); shiftresultflags(rm64,count); } +:SHRD rm64,Reg64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xAD; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; + rm64 = (rm64 >> count) | (Reg64 << (64 - count)); + shrdflags(tmp,rm64,count); shiftresultflags(rm64,count); } +@endif + +:SHR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=5 ... { CF = rm8 & 1; OF = 0; rm8 = rm8 >> 1; resultflags(rm8); } +:SHR rm8,CL is vexMode=0 & byte=0xD2; CL & rm8 & reg_opcode=5 ... { local count = CL & 0x1f; local tmp = rm8; rm8 = rm8 >> count; + shrflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SHR rm8,imm8 is vexMode=0 & byte=0xC0; rm8 & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm8; rm8 = rm8 >> count; + shrflags(tmp, rm8,count); shiftresultflags(rm8,count); } +:SHR rm16,n1 is vexMode=0 & opsize=0 & byte=0xD1; rm16 & n1 & reg_opcode=5 ... { CF = (rm16 & 1) != 0; OF = 0; rm16 = rm16 >> 1; resultflags(rm16); } +:SHR rm16,CL is vexMode=0 & opsize=0 & byte=0xD3; CL & rm16 & reg_opcode=5 ... { local count = CL & 0x1f; local tmp = rm16; rm16 = rm16 >> count; + shrflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SHR rm16,imm8 is vexMode=0 & opsize=0 & byte=0xC1; rm16 & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm16; rm16 = rm16 >> count; + shrflags(tmp, rm16,count); shiftresultflags(rm16,count); } +:SHR rm32,n1 is vexMode=0 & opsize=1 & byte=0xD1; rm32 & n1 & check_rm32_dest ... & reg_opcode=5 ... { CF = (rm32 & 1) != 0; OF = 0; rm32 = rm32 >> 1; build check_rm32_dest; resultflags(rm32); } +:SHR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=5 ... { local count = CL & 0x1f; local tmp = rm32; rm32 = rm32 >> count; build check_rm32_dest; + shrflags(tmp, rm32,count); shiftresultflags(rm32,count); } +:SHR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 >> count; build check_rm32_dest; + shrflags(tmp, rm32,count); shiftresultflags(rm32,count); } +@ifdef IA64 +:SHR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 ®_opcode=5 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 >> 1; resultflags(rm64); } +:SHR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=5 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 >> count; + shrflags(tmp, rm64,count); shiftresultflags(rm64,count); } +:SHR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 >> count; + shrflags(tmp, rm64,count); shiftresultflags(rm64,count); } +@endif + +:SIDT m16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=1 ) ... & m16 +{ + m16 = InterruptDescriptorTableRegister(); +} + +:SIDT m32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=1 ) ... & m32 +{ + m32 = InterruptDescriptorTableRegister(); +} +@ifdef IA64 +:SIDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=1 ) ... & m64 +{ + m64 = InterruptDescriptorTableRegister(); +} +@endif + +define pcodeop skinit; +:SKINIT EAX is vexMode=0 & byte=0x0f; byte=0x01; byte=0xde & EAX { skinit(EAX); } + +:SLDT rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=0 ... +{ + rm16 = LocalDescriptorTableRegister(); +} +:SLDT rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x0; rm32 & reg_opcode=0 ... +{ + rm32 = LocalDescriptorTableRegister(); +} +@ifdef IA64 +:SLDT rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x0; rm64 & reg_opcode=0 ... +{ + rm64 = LocalDescriptorTableRegister(); +} +@endif + +:SMSW rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x01; rm16 & reg_opcode=4 ... { rm16 = CR0:2; } +:SMSW rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x01; rm32 & reg_opcode=4 ... { rm32 = zext(CR0:2); } +@ifdef IA64 +:SMSW rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x01; rm64 & reg_opcode=4 ... { rm64 = CR0; } +@endif + +:STAC is vexMode=0 & byte=0x0f; byte=0x01; byte=0xcb { AC = 1; } +:STC is vexMode=0 & byte=0xf9 { CF = 1; } +:STD is vexMode=0 & byte=0xfd { DF = 1; } +# MFL: AMD instruction +# TODO: define the action. +# STGI: set global interrupt flag (GIF); while GIF is zero, all external interrupts are disabled. +:STGI is vexMode=0 & byte=0x0f; byte=0x01; byte=0xdc { stgi(); } +:STI is vexMode=0 & byte=0xfb { IF = 1; } + +:STMXCSR m32 is vexMode=0 & byte=0xf; byte=0xae; ( mod != 0b11 & reg_opcode=3 ) ... & m32 { m32 = MXCSR; } + +:STOSB^rep^reptail eseDI1 is vexMode=0 & rep & reptail & byte=0xaa & eseDI1 { build rep; build eseDI1; eseDI1=AL; build reptail; } +:STOSW^rep^reptail eseDI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xab & eseDI2 { build rep; build eseDI2; eseDI2=AX; build reptail; } +:STOSD^rep^reptail eseDI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xab & eseDI4 { build rep; build eseDI4; eseDI4=EAX; build reptail; } +@ifdef IA64 +:STOSQ^rep^reptail eseDI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xab & eseDI8 { build rep; build eseDI8; eseDI8=RAX; build reptail; } +@endif + +:STR rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=1 ... { rm16 = TaskRegister(); } + +# See 'lockable.sinc' for memory destination, lockable variants +:SUB AL,imm8 is vexMode=0 & byte=0x2c; AL & imm8 { subflags( AL,imm8 ); AL = AL - imm8; resultflags( AL); } +:SUB AX,imm16 is vexMode=0 & opsize=0 & byte=0x2d; AX & imm16 { subflags( AX,imm16); AX = AX - imm16; resultflags( AX); } +:SUB EAX,imm32 is vexMode=0 & opsize=1 & byte=0x2d; EAX & check_EAX_dest & imm32 { subflags( EAX,imm32); EAX = EAX - imm32; build check_EAX_dest; resultflags( EAX); } +@ifdef IA64 +:SUB RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x2d; RAX & simm32 { subflags( RAX,simm32); RAX = RAX - simm32; resultflags( RAX); } +@endif +:SUB Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=5; imm8 { subflags( Rmr8,imm8 ); Rmr8 = Rmr8 - imm8; resultflags( Rmr8); } +:SUB Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=5; imm16 { subflags( Rmr16,imm16); Rmr16 = Rmr16 - imm16; resultflags( Rmr16); } +:SUB Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=5; imm32 { subflags( Rmr32,imm32); Rmr32 = Rmr32 - imm32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:SUB Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=5; simm32 { subflags( Rmr64,simm32); Rmr64 = Rmr64 - simm32; resultflags( Rmr64); } +@endif +:SUB Rmr16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=5; simm8_16 { subflags( Rmr16,simm8_16); Rmr16 = Rmr16 - simm8_16; resultflags( Rmr16); } +:SUB Rmr32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=5; simm8_32 { subflags( Rmr32,simm8_32); Rmr32 = Rmr32 - simm8_32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:SUB Rmr64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=5; simm8_64 { subflags( Rmr64,simm8_64); Rmr64 = Rmr64 - simm8_64; resultflags( Rmr64); } +@endif +:SUB Rmr8,Reg8 is vexMode=0 & byte=0x28; mod=3 & Rmr8 & Reg8 { subflags( Rmr8,Reg8 ); Rmr8 = Rmr8 - Reg8; resultflags( Rmr8); } +:SUB Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x29; mod=3 & Rmr16 & Reg16 { subflags( Rmr16,Reg16); Rmr16 = Rmr16 - Reg16; resultflags( Rmr16); } +:SUB Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x29; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { subflags( Rmr32,Reg32); Rmr32 = Rmr32 - Reg32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:SUB Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x29; mod=3 & Rmr64 & Reg64 { subflags( Rmr64,Reg64); Rmr64 = Rmr64 - Reg64; resultflags( Rmr64); } +@endif +:SUB Reg8,rm8 is vexMode=0 & byte=0x2a; rm8 & Reg8 ... { subflags( Reg8,rm8 ); Reg8 = Reg8 - rm8; resultflags( Reg8); } +:SUB Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x2b; rm16 & Reg16 ... { subflags(Reg16,rm16 ); Reg16 = Reg16 - rm16; resultflags(Reg16); } +:SUB Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x2b; rm32 & Reg32 ... & check_Reg32_dest ... { subflags(Reg32,rm32 ); Reg32 = Reg32 - rm32; build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:SUB Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x2b; rm64 & Reg64 ... { subflags(Reg64,rm64 ); Reg64 = Reg64 - rm64; resultflags(Reg64); } +@endif + +:SYSENTER is vexMode=0 & byte=0x0f; byte=0x34 { sysenter(); } +:SYSEXIT is vexMode=0 & byte=0x0f; byte=0x35 { sysexit(); +@ifdef IA64 + RIP=RCX; return [RIP]; +@endif + } + +:SYSCALL is vexMode=0 & byte=0x0f; byte=0x05 { + RCX = inst_next; + packflags(R11); + syscall(); +} + +# returning to 32bit mode loads ECX +# returning to 64bit mode loads RCX +:SYSRET is vexMode=0 & byte=0x0f; byte=0x07 { sysret(); +@ifdef IA64 + RIP=RCX; return [RIP]; +@endif + } + +:SWAPGS is vexMode=0 & bit64=1 & byte=0x0f; byte=0x01; byte=0xf8 { swapgs(); } + +:RDTSCP is vexMode=0 & bit64=1 & byte=0x0f; byte=0x01; byte=0xf9 { rdtscp(); } + +:TEST AL,imm8 is vexMode=0 & byte=0xA8; AL & imm8 { logicalflags(); local tmp = AL & imm8; resultflags(tmp); } +:TEST AX,imm16 is vexMode=0 & opsize=0; byte=0xA9; AX & imm16 { logicalflags(); local tmp = AX & imm16; resultflags(tmp); } +:TEST EAX,imm32 is vexMode=0 & opsize=1; byte=0xA9; EAX & imm32 { logicalflags(); local tmp = EAX & imm32; resultflags(tmp); } +@ifdef IA64 +:TEST RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0xA9; RAX & simm32 { logicalflags(); local tmp = RAX & simm32; resultflags(tmp); } +@endif +:TEST spec_rm8,imm8 is vexMode=0 & byte=0xF6; spec_rm8 & (reg_opcode=0 | reg_opcode=1) ... ; imm8 { logicalflags(); local tmp = spec_rm8 & imm8; resultflags(tmp); } +:TEST spec_rm16,imm16 is vexMode=0 & opsize=0; byte=0xF7; spec_rm16 & (reg_opcode=0 | reg_opcode=1) ... ; imm16 { logicalflags(); local tmp = spec_rm16 & imm16; resultflags(tmp); } +:TEST spec_rm32,imm32 is vexMode=0 & opsize=1; byte=0xF7; spec_rm32 & (reg_opcode=0 | reg_opcode=1) ... ; imm32 { logicalflags(); local tmp = spec_rm32 & imm32; resultflags(tmp); } +@ifdef IA64 +:TEST spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0xF7; spec_rm64 & (reg_opcode=0 | reg_opcode=1) ... ; simm32 { logicalflags(); local tmp = spec_rm64 & simm32; resultflags(tmp); } +@endif +:TEST rm8,Reg8 is vexMode=0 & byte=0x84; rm8 & Reg8 ... { logicalflags(); local tmp = rm8 & Reg8; resultflags(tmp); } +:TEST rm16,Reg16 is vexMode=0 & opsize=0; byte=0x85; rm16 & Reg16 ... { logicalflags(); local tmp = rm16 & Reg16; resultflags(tmp); } +:TEST rm32,Reg32 is vexMode=0 & opsize=1; byte=0x85; rm32 & Reg32 ... { logicalflags(); local tmp = rm32 & Reg32; resultflags(tmp); } +@ifdef IA64 +:TEST rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x85; rm64 & Reg64 ... { logicalflags(); local tmp = rm64 & Reg64; resultflags(tmp); } +@endif + +define pcodeop invalidInstructionException; +:UD0 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xff; rm32 & Reg32 ... { invalidInstructionException(); goto inst_start; } +:UD1 Reg32, rm32 is vexMode=0 & byte=0x0f; byte=0xb9; rm32 & Reg32 ... { invalidInstructionException(); goto inst_start; } +:UD2 is vexMode=0 & byte=0xf; byte=0xb { invalidInstructionException(); goto inst_start; } + +define pcodeop verr; +define pcodeop verw; +:VERR rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=4 ... { ZF = verr(); } +:VERW rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=5 ... { ZF = verw(); } + +# MFL added VMX opcodes +# +# AMD hardware assisted virtualization opcodes +:VMLOAD EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xda & EAX { vmload(EAX); } +@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(); } +# 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 +:VMRUN RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xd8 & RAX { vmrun(RAX); } +@endif +# Limiting the effective address size to 32 and 64 bit. Surely we're not expecting a 16-bit VM address, are we? +:VMSAVE EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xdb & EAX { vmsave(EAX); } +@ifdef IA64 +:VMSAVE RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xdb & RAX { vmsave(RAX); } +@endif +# + +# +# Intel hardware assisted virtualization opcodes +@ifdef IA64 +:INVEPT Reg64, m128 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x80; Reg64 ... & m128 { invept(Reg64, m128); } +@endif +:INVEPT Reg32, m128 is vexMode=0 & bit64=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x80; Reg32 ... & m128 { invept(Reg32, m128); } +@ifdef IA64 +:INVVPID Reg64, m128 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x81; Reg64 ... & m128 { invvpid(Reg64, m128); } +@endif +:INVVPID Reg32, m128 is vexMode=0 & bit64=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x81; Reg32 ... & m128 { invvpid(Reg32, m128); } +:VMCALL is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc1 { vmcall(); } +@ifdef IA64 +:VMCLEAR m64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=6 ) ... & m64 { vmclear(m64); } +@endif +#TODO: invokes a VM function specified in EAX +:VMFUNC EAX is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd4 & EAX { vmfunc(EAX); } +#TODO: this launches the VM managed by the current VMCS. How is the VMCS expressed for the emulator? For Ghidra analysis? +:VMLAUNCH is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc2 { vmlaunch(); } +#TODO: this resumes the VM managed by the current VMCS. How is the VMCS expressed for the emulator? For Ghidra analysis? +:VMRESUME is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc3 { vmresume(); } +#TODO: this loads the VMCS pointer from the m64 memory address and makes the VMCS pointer valid; how to express +# this for analysis and emulation? +:VMPTRLD m64 is vexMode=0 & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=6 ) ... & m64 { vmptrld(m64); } +#TODO: stores the current VMCS pointer into the specified 64-bit memory address; how to express this for analysis and emulation? +#TODO: note that the Intel manual does not specify m64 (which it does for VMPTRLD, yet it does state that "the operand +# of this instruction is always 64-bits and is always in memory". Is it an error that the "Instruction" entry in the +# box giving the definition does not specify m64? +:VMPTRST m64 is vexMode=0 & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=7 ) ... & m64 { vmptrst(m64); } +:VMREAD rm32, Reg32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0x78; rm32 & check_rm32_dest ... & Reg32 ... { rm32 = vmread(Reg32); build check_rm32_dest; } +@ifdef IA64 +:VMREAD rm64, Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0f; byte=0x78; rm64 & Reg64 ... { rm64 = vmread(Reg64); } +@endif +:VMWRITE Reg32, rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0x79; rm32 & Reg32 ... & check_Reg32_dest ... { vmwrite(rm32,Reg32); build check_Reg32_dest; } +@ifdef IA64 +:VMWRITE Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0f; byte=0x79; rm64 & Reg64 ... { vmwrite(rm64,Reg64); } +@endif +:VMXOFF is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc4 { vmxoff(); } +# NB: this opcode is incorrect in the 2005 edition of the Intel manual. Opcode below is taken from the 2008 version. +:VMXON m64 is vexMode=0 & $(PRE_F3) & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=6 ) ... & m64 { vmxon(m64); } + +#END of changes for VMX opcodes + +:WAIT is vexMode=0 & byte=0x9b { } +:WBINVD is vexMode=0 & byte=0xf; byte=0x9 { } + +@ifdef IA64 +define pcodeop writefsbase; +:WRFSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=2 & r32 { tmp:8 = zext(r32); writefsbase(tmp); } +:WRFSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=2 & r64 { writefsbase(r64); } + +define pcodeop writegsbase; +:WRGSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=3 & r32 { tmp:8 = zext(r32); writegsbase(tmp); } +:WRGSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=3 & r64 { writegsbase(r64); } +@endif + +define pcodeop wrpkru; +:WRPKRU is byte=0x0F; byte=0x01; byte=0xEF { wrpkru(EAX); } + +define pcodeop wrmsr; +:WRMSR is vexMode=0 & byte=0xf; byte=0x30 { tmp:8 = (zext(EDX) << 32) | zext(EAX); wrmsr(ECX,tmp); } + +# 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); } +: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 +:XADD Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xC1; mod=3 & Rmr64 & Reg64 { addflags(Rmr64,Reg64); local tmp = Rmr64 + Reg64; Reg64 = Rmr64; Rmr64 = tmp; resultflags(tmp); } +@endif + +define pcodeop xabort; + +:XABORT imm8 is vexMode=0 & byte=0xc6; byte=0xf8; imm8 { tmp:1 = imm8; xabort(tmp); } + +define pcodeop xbegin; +define pcodeop xend; + +:XBEGIN rel16 is vexMode=0 & opsize=0 & byte=0xc7; byte=0xf8; rel16 { xbegin(&:$(SIZE) rel16); } +:XBEGIN rel32 is vexMode=0 & (opsize=1 | opsize=2) & byte=0xc7; byte=0xf8; rel32 { xbegin(&:$(SIZE) rel32); } + +:XEND is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd5 { xend(); } + +# See 'lockable.sinc' for memory destination, lockable variants +:XCHG AX,Rmr16 is vexMode=0 & opsize=0 & row = 9 & page = 0 & AX & Rmr16 { local tmp = AX; AX = Rmr16; Rmr16 = tmp; } +:XCHG EAX,Rmr32 is vexMode=0 & opsize=1 & row = 9 & page = 0 & EAX & check_EAX_dest & Rmr32 & check_Rmr32_dest { local tmp = EAX; EAX = Rmr32; build check_EAX_dest; Rmr32 = tmp; build check_Rmr32_dest; } +@ifdef IA64 +:XCHG RAX,Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & row = 9 & page = 0 & RAX & Rmr64 { local tmp = RAX; RAX = Rmr64; Rmr64 = tmp; } +@endif + +:XCHG Rmr8,Reg8 is vexMode=0 & byte=0x86; mod=3 & Rmr8 & Reg8 { local tmp = Rmr8; Rmr8 = Reg8; Reg8 = tmp; } +:XCHG Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x87; mod=3 & Rmr16 & Reg16 { local tmp = Rmr16; Rmr16 = Reg16; Reg16 = tmp; } +:XCHG Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x87; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 & check_Reg32_dest { local tmp = Rmr32; Rmr32 = Reg32; build check_Rmr32_dest; Reg32 = tmp; build check_Reg32_dest;} +@ifdef IA64 +:XCHG Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x87; mod=3 & Rmr64 & Reg64 { local tmp = Rmr64; Rmr64 = Reg64; Reg64 = tmp; } +@endif + +:XLAT seg16^BX is vexMode=0 & addrsize=0 & seg16 & byte=0xd7; BX { tmp:$(SIZE)= 0; ptr2(tmp,BX+zext(AL)); AL = *tmp; } +:XLAT segWide^EBX is vexMode=0 & addrsize=1 & segWide & byte=0xd7; EBX { tmp:$(SIZE)= 0; ptr4(tmp,EBX+zext(AL)); AL = *tmp; } +@ifdef IA64 +:XLAT segWide^RBX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & segWide & byte=0xd7; RBX { tmp:$(SIZE)= 0; ptr8(tmp,RBX+zext(AL)); AL = *tmp; } +@endif + +# See 'lockable.sinc' for memory destination, lockable variants +:XOR AL,imm8 is vexMode=0 & byte=0x34; AL & imm8 { logicalflags(); AL = AL ^ imm8; resultflags( AL); } +:XOR AX,imm16 is vexMode=0 & opsize=0 & byte=0x35; AX & imm16 { logicalflags(); AX = AX ^ imm16; resultflags( AX); } +:XOR EAX,imm32 is vexMode=0 & opsize=1 & byte=0x35; EAX & imm32 & check_EAX_dest { logicalflags(); EAX = EAX ^ imm32; build check_EAX_dest; resultflags( EAX);} +@ifdef IA64 +:XOR RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x35; RAX & simm32 { logicalflags(); RAX = RAX ^ simm32; resultflags( RAX); } +@endif +:XOR Rmr8,imm8 is vexMode=0 & $(BYTE_80_82); mod=3 & Rmr8 & reg_opcode=6; imm8 { logicalflags(); Rmr8 = Rmr8 ^ imm8; resultflags( Rmr8); } +:XOR Rmr16,imm16 is vexMode=0 & opsize=0 & byte=0x81; mod=3 & Rmr16 & reg_opcode=6; imm16 { logicalflags(); Rmr16 = Rmr16 ^ imm16; resultflags( Rmr16); } +:XOR Rmr32,imm32 is vexMode=0 & opsize=1 & byte=0x81; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=6; imm32 { logicalflags(); Rmr32 = Rmr32 ^ imm32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:XOR Rmr64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; mod=3 & Rmr64 & reg_opcode=6; simm32 { logicalflags(); Rmr64 = Rmr64 ^ simm32; resultflags( Rmr64); } +@endif +:XOR Rmr16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; mod=3 & Rmr16 & reg_opcode=6; usimm8_16 { logicalflags(); Rmr16 = Rmr16 ^ usimm8_16; resultflags( Rmr16); } +:XOR Rmr32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; mod=3 & Rmr32 & check_rm32_dest & reg_opcode=6; usimm8_32 { logicalflags(); Rmr32 = Rmr32 ^ usimm8_32; build check_rm32_dest; resultflags( Rmr32); } +@ifdef IA64 +:XOR Rmr64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; mod=3 & Rmr64 & reg_opcode=6; usimm8_64 { logicalflags(); Rmr64 = Rmr64 ^ usimm8_64; resultflags( Rmr64); } +@endif +:XOR Rmr8,Reg8 is vexMode=0 & byte=0x30; mod=3 & Rmr8 & Reg8 { logicalflags(); Rmr8 = Rmr8 ^ Reg8; resultflags( Rmr8); } +:XOR Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0x31; mod=3 & Rmr16 & Reg16 { logicalflags(); Rmr16 = Rmr16 ^ Reg16; resultflags( Rmr16); } +:XOR Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0x31; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { logicalflags(); Rmr32 = Rmr32 ^ Reg32; build check_Rmr32_dest; resultflags( Rmr32); } +@ifdef IA64 +:XOR Rmr64,Reg64 is vexMode=0 & $(LONGMODE_ON) & opsize=2 & byte=0x31; mod=3 & Rmr64 & Reg64 { logicalflags(); Rmr64 = Rmr64 ^ Reg64; resultflags( Rmr64); } +@endif +:XOR Reg8,rm8 is vexMode=0 & byte=0x32; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 ^ rm8; resultflags( Reg8); } +:XOR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x33; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 ^ rm16; resultflags(Reg16); } +:XOR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x33; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 ^ rm32; build check_Reg32_dest; resultflags(Reg32); } +@ifdef IA64 +:XOR Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x33; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 ^ rm64; resultflags(Reg64); } +@endif + +:XGETBV is vexMode=0 & byte=0x0F; byte=0x01; byte=0xD0 { local tmp = XCR0 >> 32; EDX = tmp:4; EAX = XCR0:4; } +:XSETBV is vexMode=0 & byte=0x0F; byte=0x01; byte=0xD1 { XCR0 = (zext(EDX) << 32) | zext(EAX); } + +define pcodeop xsave; +define pcodeop xsave64; +define pcodeop xsavec; +define pcodeop xsavec64; +define pcodeop xsaveopt; +define pcodeop xsaveopt64; +define pcodeop xsaves; +define pcodeop xsaves64; +define pcodeop xrstor; +define pcodeop xrstor64; +define pcodeop xrstors; +define pcodeop xrstors64; + +:XRSTOR Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xrstor(Mem, tmp); } +@ifdef IA64 +:XRSTOR64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xrstor64(Mem, tmp); } +@endif + +:XRSTORS Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=3 ) ... & Mem { tmp:4 = 512; xrstors(Mem, tmp); } +@ifdef IA64 +:XRSTORS64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=3 ) ... & Mem { tmp:4 = 512; xrstors64(Mem, tmp); } +@endif + +:XSAVE Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsave(Mem, tmp); } +@ifdef IA64 +:XSAVE64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsave64(Mem, tmp); } +@endif + +:XSAVEC Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsavec(Mem, tmp); } +@ifdef IA64 +:XSAVEC64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsavec64(Mem, tmp); } +@endif + +:XSAVEOPT Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=6 ) ... & Mem { tmp:4 = 512; xsaveopt(Mem, tmp); } +@ifdef IA64 +:XSAVEOPT64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=6 ) ... & Mem { tmp:4 = 512; xsaveopt64(Mem, tmp); } +@endif + +:XSAVES Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xsaves(Mem, tmp); } +@ifdef IA64 +:XSAVES64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xsaves64(Mem, tmp); } +@endif + +define pcodeop xtest; +:XTEST is byte=0x0F; byte=0x01; byte=0xD6 { ZF = xtest(); } + +:LFENCE is vexMode=0 & $(PRE_NO) & byte=0x0F; byte=0xAE; mod = 0b11 & reg_opcode=5 & r_m=0 { } +: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 +# +define pcodeop f2xm1; +:F2XM1 is vexMode=0 & byte=0xD9; byte=0xF0 { ST0 = f2xm1(ST0); } # compute 2^x-1 + +:FABS is vexMode=0 & byte=0xD9; byte=0xE1 { ST0 = abs(ST0); } + +:FADD spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=0 ... & spec_m32 { ST0 = ST0 f+ float2float(spec_m32); } +:FADD spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=0 ... & spec_m64 { ST0 = ST0 f+ float2float(spec_m64); } +:FADD ST0, freg is vexMode=0 & byte=0xD8; frow=12 & fpage=0 & freg & ST0 { ST0 = ST0 f+ freg; } +:FADD freg, ST0 is vexMode=0 & byte=0xDC; frow=12 & fpage=0 & freg & ST0 { freg = freg f+ ST0; } +:FADDP is vexMode=0 & byte=0xDE; byte=0xC1 { ST1 = ST0 f+ ST1; fpop(); } +:FADDP freg, ST0 is vexMode=0 & byte=0xDE; frow=12 & fpage=0 & freg & ST0 { freg = ST0 f+ freg; fpop(); } +:FIADD spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=0 ... & spec_m32 { ST0 = ST0 f+ int2float(spec_m32); } +:FIADD spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=0 ... & spec_m16 { ST0 = ST0 f+ int2float(spec_m16); } + +define pcodeop convert_bcd; +:FBLD spec_m80 is vexMode=0 & byte=0xDF; reg_opcode=4 ... & spec_m80 { fdec(); ST0 = convert_bcd(spec_m80); } + +:FBSTP spec_m80 is vexMode=0 & byte=0xDF; reg_opcode=6 ... & spec_m80 { spec_m80 = convert_bcd(ST0); fpop(); } + +:FCHS is vexMode=0 & byte=0xD9; byte=0xE0 { ST0 = f- ST0; } + +:FCLEX is vexMode=0 & byte=0x9B; byte=0xDB; byte=0xE2 { FPUStatusWord[0,8] = 0; FPUStatusWord[15,1] = 0; } +:FNCLEX is vexMode=0 & byte=0xDB; byte=0xE2 { FPUStatusWord[0,8] = 0; FPUStatusWord[15,1] = 0; } + +:FCMOVB ST0, freg is vexMode=0 & byte=0xDA; frow=12 & fpage=0 & freg & ST0 { if ( !CF ) goto inst_next; ST0 = freg; } +:FCMOVE ST0, freg is vexMode=0 & byte=0xDA; frow=12 & fpage=1 & freg & ST0 { if ( !ZF ) goto inst_next; ST0 = freg; } +:FCMOVBE ST0, freg is vexMode=0 & byte=0xDA; frow=13 & fpage=0 & freg & ST0 { if ( !CF & !ZF ) goto inst_next; ST0 = freg; } +:FCMOVU ST0, freg is vexMode=0 & byte=0xDA; frow=13 & fpage=1 & freg & ST0 { if ( !PF ) goto inst_next; ST0 = freg; } +:FCMOVNB ST0, freg is vexMode=0 & byte=0xDB; frow=12 & fpage=0 & freg & ST0 { if ( CF ) goto inst_next; ST0 = freg; } +:FCMOVNE ST0, freg is vexMode=0 & byte=0xDB; frow=12 & fpage=1 & freg & ST0 { if ( ZF ) goto inst_next; ST0 = freg; } +:FCMOVNBE ST0, freg is vexMode=0 & byte=0xDB; frow=13 & fpage=0 & freg & ST0 { if ( CF & ZF ) goto inst_next; ST0 = freg; } +:FCMOVNU ST0, freg is vexMode=0 & byte=0xDB; frow=13 & fpage=1 & freg & ST0 { if ( PF ) goto inst_next; ST0 = freg; } + +:FCOM spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=2 ... & spec_m32 { local tmp=float2float(spec_m32); fcom(tmp); } +:FCOM spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=2 ... & spec_m64 { local tmp=float2float(spec_m64); fcom(tmp); } +:FCOM freg is vexMode=0 & byte=0xD8; frow=13 & fpage=0 & freg { fcom(freg); } +:FCOM is vexMode=0 & byte=0xD8; byte=0xD1 { fcom(ST1); } +:FCOMP spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=3 ... & spec_m32 { local tmp=float2float(spec_m32); fcom(tmp); fpop(); } +:FCOMP spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=3 ... & spec_m64 { local tmp=float2float(spec_m64); fcom(tmp); fpop(); } +:FCOMP freg is vexMode=0 & byte=0xD8; frow=13 & fpage=1 & freg { fcom(freg); fpop(); } +:FCOMP is vexMode=0 & byte=0xD8; byte=0xD9 { fcom(ST1); fpop(); } +:FCOMPP is vexMode=0 & byte=0xDE; byte=0xD9 { fcom(ST1); fpop(); fpop(); } + +:FCOMI ST0, freg is vexMode=0 & byte=0xDB; frow=15 & fpage=0 & freg & ST0 { fcomi(freg); } +:FCOMIP ST0, freg is vexMode=0 & byte=0xDF; frow=15 & fpage=0 & freg & ST0 { fcomi(freg); fpop(); } +:FUCOMI ST0, freg is vexMode=0 & byte=0xDB; frow=14 & fpage=1 & freg & ST0 { fcomi(freg); } +:FUCOMIP ST0, freg is vexMode=0 & byte=0xDF; frow=14 & fpage=1 & freg & ST0 { fcomi(freg); fpop(); } + +define pcodeop fcos; +:FCOS is vexMode=0 & byte=0xD9; byte=0xFF { ST0 = fcos(ST0); } + +:FDECSTP is vexMode=0 & byte=0xD9; byte=0xF6 { fdec(); FPUStatusWord = FPUStatusWord & 0xfeff; C0 = 0; } #Clear C0 + +# Legacy 8087 instructions. Still valid but treated as NOP instructions. +:FDISI is vexMode=0 & byte=0x9B; byte=0xDB; byte=0xE1 {} +:FNDISI is vexMode=0 & byte=0xDB; byte=0xE1 {} +:FENI is vexMode=0 & byte=0x9B; byte=0xDB; byte=0xE0 {} +:FNENI is vexMode=0 & byte=0xDB; byte=0xE0 {} + +:FDIV spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=6 ... & spec_m32 { ST0 = ST0 f/ float2float(spec_m32); } +:FDIV spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=6 ... & spec_m64 { ST0 = ST0 f/ float2float(spec_m64); } +:FDIV ST0,freg is vexMode=0 & byte=0xD8; frow=15 & fpage=0 & freg & ST0 { ST0 = ST0 f/ freg; } +:FDIV freg,ST0 is vexMode=0 & byte=0xDC; frow=15 & fpage=1 & freg & ST0 { freg = freg f/ ST0; } +:FDIVP freg,ST0 is vexMode=0 & byte=0xDE; frow=15 & fpage=1 & freg & ST0 { freg = ST0 f/ freg; fpop(); } +:FDIVP is vexMode=0 & byte=0xDE; byte=0xF9 { ST1 = ST1 f/ ST0; fpop(); } +:FIDIV spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=6 ... & spec_m32 { ST0 = ST0 f/ int2float(spec_m32); } +:FIDIV spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=6 ... & spec_m16 { ST0 = ST0 f/ int2float(spec_m16); } + +:FDIVR spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=7 ... & spec_m32 { ST0 = float2float(spec_m32) f/ ST0; } +:FDIVR spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=7 ... & spec_m64 { ST0 = float2float(spec_m64) f/ ST0; } +:FDIVR ST0,freg is vexMode=0 & byte=0xD8; frow=15 & fpage=1 & freg & ST0 { ST0 = freg f/ ST0; } +:FDIVR freg,ST0 is vexMode=0 & byte=0xDC; frow=15 & fpage=0 & freg & ST0 { freg = ST0 f/ freg; } +:FDIVRP freg,ST0 is vexMode=0 & byte=0xDE; frow=15 & fpage=0 & freg & ST0 { freg = freg f/ ST0; fpop(); } +:FDIVRP is vexMode=0 & byte=0xDE; byte=0xF1 { ST1 = ST0 f/ ST1; fpop(); } +:FIDIVR spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=7 ... & spec_m32 { ST0 = int2float(spec_m32) f/ ST0; } +:FIDIVR spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=7 ... & spec_m16 { ST0 = int2float(spec_m16) f/ ST0; } + +define pcodeop ffree; +:FFREE freg is vexMode=0 & byte=0xDD; frow=12 & fpage=0 & freg { FPUTagWord = ffree(freg); } # Set freg to invalid value +:FFREEP freg is vexMode=0 & byte=0xDF; frow=12 & fpage=0 & freg { FPUTagWord = ffree(freg); fpop(); } # FFREE and pop + +:FICOM spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=2 ... & spec_m16 { local tmp = int2float(spec_m16); fcom(tmp); } +:FICOM spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=2 ... & spec_m32 { local tmp = int2float(spec_m32); fcom(tmp); } +:FICOMP spec_m16 is vexMode=0 & byte=0xDE; (mod != 0b11 & reg_opcode=3) ... & spec_m16 { local tmp = int2float(spec_m16); fcom(tmp); fpop(); } +:FICOMP spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=3 ... & spec_m32 { local tmp = int2float(spec_m32); fcom(tmp); fpop(); } + +:FILD spec_m16 is vexMode=0 & byte=0xDF; reg_opcode=0 ... & spec_m16 { fdec(); ST0 = int2float(spec_m16); } +:FILD spec_m32 is vexMode=0 & byte=0xDB; reg_opcode=0 ... & spec_m32 { fdec(); ST0 = int2float(spec_m32); } +:FILD spec_m64 is vexMode=0 & byte=0xDF; reg_opcode=5 ... & spec_m64 { fdec(); ST0 = int2float(spec_m64); } + +:FINCSTP is vexMode=0 & byte=0xD9; byte=0xF7 { finc(); } + +:FINIT is vexMode=0 & byte=0x9B; byte=0xDB; byte=0xE3 { + FPUControlWord = 0x037f; + FPUStatusWord = 0x0000; + FPUTagWord = 0xffff; + FPUDataPointer = 0x00000000; + FPUInstructionPointer = 0x00000000; + FPULastInstructionOpcode = 0x0000; + C0 = 0; + C1 = 0; + C2 = 0; + C3 = 0; } + +:FNINIT is vexMode=0 & byte=0xDB; byte=0xE3 { + FPUControlWord = 0x037f; + FPUStatusWord = 0x0000; + FPUTagWord = 0xffff; + FPUDataPointer = 0x00000000; + FPUInstructionPointer = 0x00000000; + FPULastInstructionOpcode = 0x0000; + C0 = 0; + C1 = 0; + C2 = 0; + C3 = 0; } + +:FIST spec_m16 is vexMode=0 & byte=0xDF; (mod != 0b11 & reg_opcode=2) ... & spec_m16 { tmp:10 = round(ST0); spec_m16 = trunc(tmp); } +:FIST spec_m32 is vexMode=0 & byte=0xDB; (mod != 0b11 & reg_opcode=2) ... & spec_m32 { tmp:10 = round(ST0); spec_m32 = trunc(tmp); } +:FISTP spec_m16 is vexMode=0 & byte=0xDF; reg_opcode=3 ... & spec_m16 { tmp:10 = round(ST0); fpop(); spec_m16 = trunc(tmp); } +:FISTP spec_m32 is vexMode=0 & byte=0xDB; reg_opcode=3 ... & spec_m32 { tmp:10 = round(ST0); fpop(); spec_m32 = trunc(tmp); } +:FISTP spec_m64 is vexMode=0 & byte=0xDF; reg_opcode=7 ... & spec_m64 { tmp:10 = round(ST0); fpop(); spec_m64 = trunc(tmp); } + +:FISTTP spec_m16 is vexMode=0 & byte=0xDF; reg_opcode=1 ... & spec_m16 { spec_m16 = trunc(ST0); fpop(); } +:FISTTP spec_m32 is vexMode=0 & byte=0xDB; reg_opcode=1 ... & spec_m32 { spec_m32 = trunc(ST0); fpop(); } +:FISTTP spec_m64 is vexMode=0 & byte=0xDD; reg_opcode=1 ... & spec_m64 { spec_m64 = trunc(ST0); fpop(); } + +:FLD spec_m32 is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=0) ... & spec_m32 { fdec(); ST0 = float2float(spec_m32); } +:FLD spec_m64 is vexMode=0 & byte=0xDD; reg_opcode=0 ... & spec_m64 { fdec(); ST0 = float2float(spec_m64);} +:FLD spec_m80 is vexMode=0 & byte=0xDB; reg_opcode=5 ... & spec_m80 { fpushv(spec_m80); } + +# Be careful that you don't clobber freg during fpushv, need a tmp to hold the value +:FLD freg is vexMode=0 & byte=0xD9; frow=12 & fpage=0 & freg { tmp:10 = freg; fpushv(tmp); } + +:FLD1 is vexMode=0 & byte=0xD9; byte=0xE8 { one:4 = 1; tmp:10 = int2float(one); fpushv(tmp); } +:FLDL2T is vexMode=0 & byte=0xD9; byte=0xE9 { src:8 = 0x400a934f0979a371; tmp:10 = float2float(src); fpushv(tmp); } +:FLDL2E is vexMode=0 & byte=0xD9; byte=0xEA { src:8 = 0x3ff71547652b82fe; tmp:10 = float2float(src); fpushv(tmp); } +:FLDPI is vexMode=0 & byte=0xD9; byte=0xEB { src:8 = 0x400921fb54442d18; tmp:10 = float2float(src); fpushv(tmp); } +:FLDLG2 is vexMode=0 & byte=0xD9; byte=0xEC { src:8 = 0x3fd34413509f79ff; tmp:10 = float2float(src); fpushv(tmp); } +:FLDLN2 is vexMode=0 & byte=0xD9; byte=0xED { src:8 = 0x3fe62e42fefa39ef; tmp:10 = float2float(src); fpushv(tmp); } +:FLDZ is vexMode=0 & byte=0xD9; byte=0xEE { zero:4 = 0; tmp:10 = int2float(zero); fpushv(tmp); } + +:FLDCW m16 is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=5) ... & m16 { FPUControlWord = m16; } + +define pcodeop fldenv; +:FLDENV Mem is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=4) ... & Mem +{ + FPUControlWord = *:2 (Mem); + FPUStatusWord = *:2 (Mem + 4); + FPUTagWord = *:2 (Mem + 8); + FPUDataPointer = *:4 (Mem + 20); + FPUInstructionPointer = *:4 (Mem + 12); + FPULastInstructionOpcode = *:2 (Mem + 18); +} + +:FMUL spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=1 ... & spec_m32 { ST0 = ST0 f* float2float(spec_m32); } +:FMUL spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=1 ... & spec_m64 { ST0 = ST0 f* float2float(spec_m64); } +:FMUL freg is vexMode=0 & byte=0xD8; frow=12 & fpage=1 & freg { ST0 = ST0 f* freg; } +:FMUL freg is vexMode=0 & byte=0xDC; frow=12 & fpage=1 & freg { freg = freg f* ST0; } +:FMULP freg is vexMode=0 & byte=0xDE; frow=12 & fpage=1 & freg { freg = ST0 f* freg; fpop(); } +:FMULP is vexMode=0 & byte=0xDE; byte=0xC9 { ST1 = ST0 f* ST1; fpop(); } +:FIMUL spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=1 ... & spec_m32 { ST0 = ST0 f* int2float(spec_m32); } +:FIMUL spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=1 ... & spec_m16 { ST0 = ST0 f* int2float(spec_m16); } + +:FNOP is vexMode=0 & byte=0xD9; byte=0xD0 { } + +define pcodeop fpatan; +:FPATAN is vexMode=0 & byte=0xD9; byte=0xF3 { ST1 = fpatan(ST1, ST0); fpop(); } + +:FPREM is vexMode=0 & byte=0xD9; byte=0xF8 { local tmp = ST0 f/ ST1; tmp = tmp f* ST1; ST0 = ST0 f- tmp; } + +:FPREM1 is vexMode=0 & byte=0xD9; byte=0xF5 { local tmp = ST0 f/ ST1; tmp = tmp f* ST1; ST0 = ST0 f- tmp; } + +define pcodeop fptan; +:FPTAN is vexMode=0 & byte=0xD9; byte=0xF2 { ST0 = fptan(ST0); one:4 = 1; tmp:10 = int2float(one); fpushv(tmp); } + +:FRNDINT is vexMode=0 & byte=0xD9; byte=0xFC { local tmp = round(ST0); ST0 = tmp; } + +:FRSTOR Mem is vexMode=0 & byte=0xDD; reg_opcode=4 ... & Mem +{ + FPUControlWord = *:2 (Mem); + FPUStatusWord = *:2 (Mem + 4); + FPUTagWord = *:2 (Mem + 8); + FPUDataPointer = *:4 (Mem + 20); + FPUInstructionPointer = *:4 (Mem + 12); + FPULastInstructionOpcode = *:2 (Mem + 18); + + ST0 = *:10 (Mem + 28); + ST1 = *:10 (Mem + 38); + ST2 = *:10 (Mem + 48); + ST3 = *:10 (Mem + 58); + ST4 = *:10 (Mem + 68); + ST5 = *:10 (Mem + 78); + ST6 = *:10 (Mem + 88); + ST7 = *:10 (Mem + 98); +} + +:FSAVE Mem is vexMode=0 & byte=0x9B; byte=0xDD; reg_opcode=6 ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 4) = FPUStatusWord; + *:2 (Mem + 8) = FPUTagWord; + *:4 (Mem + 20) = FPUDataPointer; + *:4 (Mem + 12) = FPUInstructionPointer; + *:2 (Mem + 18) = FPULastInstructionOpcode; + + *:10 (Mem + 28) = ST0; + *:10 (Mem + 38) = ST1; + *:10 (Mem + 48) = ST2; + *:10 (Mem + 58) = ST3; + *:10 (Mem + 68) = ST4; + *:10 (Mem + 78) = ST5; + *:10 (Mem + 88) = ST6; + *:10 (Mem + 98) = ST7; + + FPUControlWord = 0x037f; + FPUStatusWord = 0x0000; + FPUTagWord = 0xffff; + FPUDataPointer = 0x00000000; + FPUInstructionPointer = 0x00000000; + FPULastInstructionOpcode = 0x0000; +} + +:FNSAVE Mem is vexMode=0 & byte=0xDD; reg_opcode=6 ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 4) = FPUStatusWord; + *:2 (Mem + 8) = FPUTagWord; + *:4 (Mem + 20) = FPUDataPointer; + *:4 (Mem + 12) = FPUInstructionPointer; + *:2 (Mem + 18) = FPULastInstructionOpcode; + + *:10 (Mem + 28) = ST0; + *:10 (Mem + 38) = ST1; + *:10 (Mem + 48) = ST2; + *:10 (Mem + 58) = ST3; + *:10 (Mem + 68) = ST4; + *:10 (Mem + 78) = ST5; + *:10 (Mem + 88) = ST6; + *:10 (Mem + 98) = ST7; + + FPUControlWord = 0x037f; + FPUStatusWord = 0x0000; + FPUTagWord = 0xffff; + FPUDataPointer = 0x00000000; + FPUInstructionPointer = 0x00000000; + FPULastInstructionOpcode = 0x0000; +} + +define pcodeop fscale; +:FSCALE is vexMode=0 & byte=0xD9; byte=0xFD { ST0 = fscale(ST0, ST1); } + +define pcodeop fsin; +:FSIN is vexMode=0 & byte=0xD9; byte=0xFE { ST0 = fsin(ST0); } +:FSINCOS is vexMode=0 & byte=0xD9; byte=0xFB { tmp:10 = fcos(ST0); ST0 = fsin(ST0); fpushv(tmp); } +:FSQRT is vexMode=0 & byte=0xD9; byte=0xFA { ST0 = sqrt(ST0); } + +:FST spec_m32 is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=2) ... & spec_m32 { spec_m32 = float2float(ST0); } +:FST spec_m64 is vexMode=0 & byte=0xDD; reg_opcode=2 ... & spec_m64 { spec_m64 = float2float(ST0); } +:FST freg is vexMode=0 & byte=0xDD; frow=13 & fpage=0 & freg { freg = ST0; } +:FSTP spec_m32 is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=3) ... & spec_m32 { spec_m32 = float2float(ST0); fpop(); } +:FSTP spec_m64 is vexMode=0 & byte=0xDD; reg_opcode=3 ... & spec_m64 { spec_m64 = float2float(ST0); fpop(); } +:FSTP spec_m80 is vexMode=0 & byte=0xDB; reg_opcode=7 ... & spec_m80 { fpopv(spec_m80); } +:FSTP freg is vexMode=0 & byte=0xDD; frow=13 & fpage=1 & freg { fpopv(freg); } + +:FSTCW m16 is vexMode=0 & byte=0x9B; byte=0xD9; (mod != 0b11 & reg_opcode=7) ... & m16 { m16 = FPUControlWord; } +:FNSTCW m16 is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=7) ... & m16 { m16 = FPUControlWord; } + +:FSTENV Mem is vexMode=0 & byte=0x9B; byte=0xD9; (mod != 0b11 & reg_opcode=6) ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 4) = FPUStatusWord; + *:2 (Mem + 8) = FPUTagWord; + *:4 (Mem + 20) = FPUDataPointer; + *:4 (Mem + 12) = FPUInstructionPointer; + *:2 (Mem + 18) = FPULastInstructionOpcode; +} + +:FNSTENV Mem is vexMode=0 & byte=0xD9; (mod != 0b11 & reg_opcode=6) ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 4) = FPUStatusWord; + *:2 (Mem + 8) = FPUTagWord; + *:4 (Mem + 20) = FPUDataPointer; + *:4 (Mem + 12) = FPUInstructionPointer; + *:2 (Mem + 18) = FPULastInstructionOpcode; +} + +:FSTSW m16 is vexMode=0 & byte=0x9B; byte=0xDD; reg_opcode=7 ... & m16 { m16 = FPUStatusWord; } +:FSTSW AX is vexMode=0 & byte=0x9B; byte=0xDF; byte=0xE0 & AX { AX = FPUStatusWord; } +:FNSTSW m16 is vexMode=0 & byte=0xDD; reg_opcode=7 ... & m16 { m16 = FPUStatusWord; } +:FNSTSW AX is vexMode=0 & byte=0xDF; byte=0xE0 & AX { AX = FPUStatusWord; } + +:FSUB spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=4 ... & spec_m32 { ST0 = ST0 f- float2float(spec_m32); } +:FSUB spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=4 ... & spec_m64 { ST0 = ST0 f- float2float(spec_m64); } +:FSUB ST0,freg is vexMode=0 & byte=0xD8; frow=14 & fpage=0 & freg & ST0 { ST0 = ST0 f- freg; } +:FSUB freg,ST0 is vexMode=0 & byte=0xDC; frow=14 & fpage=1 & freg & ST0 { freg = freg f- ST0; } +:FSUBP is vexMode=0 & byte=0xDE; byte=0xE9 { ST1 = ST1 f- ST0; fpop(); } +:FSUBP freg,ST0 is vexMode=0 & byte=0xDE; frow=14 & fpage=1 & freg & ST0 { freg = freg f- ST0; fpop(); } +:FISUB spec_m32 is vexMode=0 & byte=0xDA; (mod != 0b11 & reg_opcode=4) ... & spec_m32 { ST0 = ST0 f- int2float(spec_m32); } +:FISUB spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=4 ... & spec_m16 { ST0 = ST0 f- int2float(spec_m16); } + +:FSUBR spec_m32 is vexMode=0 & byte=0xD8; reg_opcode=5 ... & spec_m32 { ST0 = float2float(spec_m32) f- ST0; } +:FSUBR spec_m64 is vexMode=0 & byte=0xDC; reg_opcode=5 ... & spec_m64 { ST0 = float2float(spec_m64) f- ST0; } +:FSUBR ST0,freg is vexMode=0 & byte=0xD8; frow=14 & fpage=1 & freg & ST0 { ST0 = freg f- ST0; } +:FSUBR freg,ST0 is vexMode=0 & byte=0xDC; frow=14 & fpage=0 & freg & ST0 { freg = ST0 f- freg; } +:FSUBRP is vexMode=0 & byte=0xDE; byte=0xE1 { ST1 = ST0 f- ST1; fpop(); } +:FSUBRP freg,ST0 is vexMode=0 & byte=0xDE; frow=14 & fpage=0 & freg & ST0 { freg = ST0 f- freg; fpop(); } +:FISUBR spec_m32 is vexMode=0 & byte=0xDA; reg_opcode=5 ... & spec_m32 { ST0 = int2float(spec_m32) f- ST0; } +:FISUBR spec_m16 is vexMode=0 & byte=0xDE; reg_opcode=5 ... & spec_m16 { ST0 = int2float(spec_m16) f- ST0; } + +:FTST is vexMode=0 & byte=0xD9; byte=0xE4 { zero:4 = 0; tmp:10 = int2float(zero); fcom(tmp); } + +:FUCOM freg is vexMode=0 & byte=0xDD; frow=14 & fpage=0 & freg { fcom(freg); } +:FUCOM is vexMode=0 & byte=0xDD; byte=0xE1 { fcom(ST1); } +:FUCOMP freg is vexMode=0 & byte=0xDD; frow=14 & fpage=1 & freg { fcom(freg); fpop(); } +:FUCOMP is vexMode=0 & byte=0xDD; byte=0xE9 { fcom(ST1); fpop(); } +:FUCOMPP is vexMode=0 & byte=0xDA; byte=0xE9 { fcom(ST1); fpop(); fpop(); } + +:FXAM is vexMode=0 & byte=0xD9; byte=0xE5 +{ + # this is not an exact implementation, but gets the sign and zero tests right + izero:4 = 0; + fzero:10 = int2float(izero); + + # did not know how test for infinity or empty + C0 = nan(ST0); + + # sign of ST0 + C1 = ( ST0 f< fzero ); + + # assume normal if not zero + C2 = ( ST0 f!= fzero ); + + # equal to zero + C3 = ( ST0 f== fzero ); + + FPUStatusWord = (zext(C0)<<8) | (zext(C1)<<9) | (zext(C2)<<10) | (zext(C3)<<14); +} + +:FXCH freg is vexMode=0 & byte=0xD9; frow=12 & fpage=1 & freg { local tmp = ST0; ST0 = freg; freg = tmp; } +:FXCH is vexMode=0 & byte=0xD9; byte=0xC9 { local tmp = ST0; ST0 = ST1; ST1 = tmp; } + +@ifndef IA64 +# this saves the FPU state into 512 bytes of memory similar to the 32-bit mode +:FXSAVE Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=0 ) ... & Mem +{ +# not saved in the same spacing as the actual processor + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 2) = FPUStatusWord; + *:2 (Mem + 4) = FPUTagWord; #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + *:2 (Mem + 6) = FPULastInstructionOpcode; + *:4 (Mem + 8) = FPUInstructionPointer; + *:2 (Mem + 12) = FPUPointerSelector; + *:4 (Mem + 16) = FPUDataPointer; + *:2 (Mem + 20) = FPUDataSelector; + *:4 (Mem + 24) = MXCSR; + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + +# saved the FPU ST registers to the ST/MM area of the structure, + *:10 (Mem + 32) = ST0; + *:10 (Mem + 48) = ST1; + *:10 (Mem + 64) = ST2; + *:10 (Mem + 80) = ST3; + *:10 (Mem + 96) = ST4; + *:10 (Mem + 112) = ST5; + *:10 (Mem + 128) = ST6; + *:10 (Mem + 144) = ST7; + + *:16 (Mem + 160) = XMM0; + *:16 (Mem + 176) = XMM1; + *:16 (Mem + 192) = XMM2; + *:16 (Mem + 208) = XMM3; + *:16 (Mem + 224) = XMM4; + *:16 (Mem + 240) = XMM5; + *:16 (Mem + 256) = XMM6; + *:16 (Mem + 272) = XMM7; +} + +@else +# this saves the FPU state into 512 bytes of memory similar to the 32-bit mode +:FXSAVE Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=0 ) ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 2) = FPUStatusWord; + *:2 (Mem + 4) = FPUTagWord; #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + *:2 (Mem + 6) = FPULastInstructionOpcode; + *:4 (Mem + 8) = FPUInstructionPointer; + *:2 (Mem + 12) = FPUPointerSelector; + *:4 (Mem + 16) = FPUDataPointer; + *:2 (Mem + 20) = FPUDataSelector; + *:4 (Mem + 24) = MXCSR; + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + + +# saved the FPU ST registers to the ST/MM area of the structure, + *:10 (Mem + 32) = ST0; + *:10 (Mem + 48) = ST1; + *:10 (Mem + 64) = ST2; + *:10 (Mem + 80) = ST3; + *:10 (Mem + 96) = ST4; + *:10 (Mem + 112) = ST5; + *:10 (Mem + 128) = ST6; + *:10 (Mem + 144) = ST7; + + *:16 (Mem + 160) = XMM0; + *:16 (Mem + 176) = XMM1; + *:16 (Mem + 192) = XMM2; + *:16 (Mem + 208) = XMM3; + *:16 (Mem + 224) = XMM4; + *:16 (Mem + 240) = XMM5; + *:16 (Mem + 256) = XMM6; + *:16 (Mem + 272) = XMM7; + *:16 (Mem + 288) = XMM8; + *:16 (Mem + 304) = XMM9; + *:16 (Mem + 320) = XMM10; + *:16 (Mem + 336) = XMM11; + *:16 (Mem + 352) = XMM12; + *:16 (Mem + 368) = XMM13; + *:16 (Mem + 384) = XMM14; + *:16 (Mem + 400) = XMM15; +} + +# this saves the FPU state into 512 bytes of memory similar to the 32-bit mode +:FXSAVE64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=0 ) ... & Mem +{ + *:2 (Mem) = FPUControlWord; + *:2 (Mem + 2) = FPUStatusWord; + *:2 (Mem + 4) = FPUTagWord; #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + *:2 (Mem + 6) = FPULastInstructionOpcode; + *:8 (Mem + 8) = FPUInstructionPointer; + *:8 (Mem + 16) = FPUDataPointer; + *:4 (Mem + 24) = MXCSR; + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + +# saved the FPU ST registers to the ST/MM area of the structure, + *:10 (Mem + 32) = ST0; + *:10 (Mem + 48) = ST1; + *:10 (Mem + 64) = ST2; + *:10 (Mem + 80) = ST3; + *:10 (Mem + 96) = ST4; + *:10 (Mem + 112) = ST5; + *:10 (Mem + 128) = ST6; + *:10 (Mem + 144) = ST7; + + + *:16 (Mem + 160) = XMM0; + *:16 (Mem + 176) = XMM1; + *:16 (Mem + 192) = XMM2; + *:16 (Mem + 208) = XMM3; + *:16 (Mem + 224) = XMM4; + *:16 (Mem + 240) = XMM5; + *:16 (Mem + 256) = XMM6; + *:16 (Mem + 272) = XMM7; + *:16 (Mem + 288) = XMM8; + *:16 (Mem + 304) = XMM9; + *:16 (Mem + 320) = XMM10; + *:16 (Mem + 336) = XMM11; + *:16 (Mem + 352) = XMM12; + *:16 (Mem + 368) = XMM13; + *:16 (Mem + 384) = XMM14; + *:16 (Mem + 400) = XMM15; +} +@endif + +@ifndef IA64 +:FXRSTOR Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=1 ) ... & Mem +{ + FPUControlWord = *:2 (Mem); + FPUStatusWord = *:2 (Mem + 2); + FPUTagWord = *:2 (Mem + 4); #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + FPULastInstructionOpcode = *:2 (Mem + 6); + FPUInstructionPointer = *:4 (Mem + 8); + FPUPointerSelector = *:2 (Mem + 12); + FPUDataPointer = *:4 (Mem + 16); + FPUDataSelector = *:2 (Mem + 20); + MXCSR = *:4 (Mem + 24); + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + +# saved the FPU ST registers to the ST/MM area of the structure, + ST0 = *:10 (Mem + 32); + ST1 = *:10 (Mem + 48); + ST2 = *:10 (Mem + 64); + ST3 = *:10 (Mem + 80); + ST4 = *:10 (Mem + 96); + ST5 = *:10 (Mem + 112); + ST6 = *:10 (Mem + 128); + ST7 = *:10 (Mem + 144); + + XMM0 = *:16 (Mem + 160); + XMM1 = *:16 (Mem + 176); + XMM2 = *:16 (Mem + 192); + XMM3 = *:16 (Mem + 208); + XMM4 = *:16 (Mem + 224); + XMM5 = *:16 (Mem + 240); + XMM6 = *:16 (Mem + 256); + XMM7 = *:16 (Mem + 272); +} + +@else +:FXRSTOR64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=1 ) ... & Mem +{ + FPUControlWord = *:2 (Mem); + FPUStatusWord = *:2 (Mem + 2); + FPUTagWord = *:2 (Mem + 4); #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + FPULastInstructionOpcode = *:2 (Mem + 6); + FPUInstructionPointer = *:8 (Mem + 8); + FPUDataPointer = *:8 (Mem + 16); + MXCSR = *:4 (Mem + 24); + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + +# saved the FPU ST registers to the ST/MM area of the structure, + ST0 = *:10 (Mem + 32); + ST1 = *:10 (Mem + 48); + ST2 = *:10 (Mem + 64); + ST3 = *:10 (Mem + 80); + ST4 = *:10 (Mem + 96); + ST5 = *:10 (Mem + 112); + ST6 = *:10 (Mem + 128); + ST7 = *:10 (Mem + 144); + + XMM0 = *:16 (Mem + 160); + XMM1 = *:16 (Mem + 176); + XMM2 = *:16 (Mem + 192); + XMM3 = *:16 (Mem + 208); + XMM4 = *:16 (Mem + 224); + XMM5 = *:16 (Mem + 240); + XMM6 = *:16 (Mem + 256); + XMM7 = *:16 (Mem + 272); + XMM8 = *:16 (Mem + 288); + XMM9 = *:16 (Mem + 304); + XMM10 = *:16 (Mem + 320); + XMM11 = *:16 (Mem + 336); + XMM12 = *:16 (Mem + 352); + XMM13 = *:16 (Mem + 368); + XMM14 = *:16 (Mem + 384); + XMM15 = *:16 (Mem + 400); +} + +:FXRSTOR Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=1 ) ... & Mem +{ + FPUControlWord = *:2 (Mem); + FPUStatusWord = *:2 (Mem + 2); + FPUTagWord = *:2 (Mem + 4); #The real implementation saves an 'abridged' tag word, but that is a non-trivial operation + FPULastInstructionOpcode = *:2 (Mem + 6); + FPUInstructionPointer = *:4 (Mem + 8); + FPUPointerSelector = *:2 (Mem + 12); + FPUDataPointer = *:4 (Mem + 16); + FPUDataSelector = *:2 (Mem + 20); + MXCSR = *:4 (Mem + 24); + # MXCSR_MASK not modeled, since it is processor specific, set to 0. + +# saved the FPU ST registers to the ST/MM area of the structure, + ST0 = *:10 (Mem + 32); + ST1 = *:10 (Mem + 48); + ST2 = *:10 (Mem + 64); + ST3 = *:10 (Mem + 80); + ST4 = *:10 (Mem + 96); + ST5 = *:10 (Mem + 112); + ST6 = *:10 (Mem + 128); + ST7 = *:10 (Mem + 144); + + + XMM0 = *:16 (Mem + 160); + XMM1 = *:16 (Mem + 176); + XMM2 = *:16 (Mem + 192); + XMM3 = *:16 (Mem + 208); + XMM4 = *:16 (Mem + 224); + XMM5 = *:16 (Mem + 240); + XMM6 = *:16 (Mem + 256); + XMM7 = *:16 (Mem + 272); + XMM8 = *:16 (Mem + 288); + XMM9 = *:16 (Mem + 304); + XMM10 = *:16 (Mem + 320); + XMM11 = *:16 (Mem + 336); + XMM12 = *:16 (Mem + 352); + XMM13 = *:16 (Mem + 368); + XMM14 = *:16 (Mem + 384); + XMM15 = *:16 (Mem + 400); +} +@endif + +:FXTRACT is vexMode=0 & byte=0xD9; byte=0xF4 { significand:10 = ST0; exponent:10 = ST0; ST0 = exponent; fpushv(significand); } + +:FYL2X is vexMode=0 & byte=0xD9; byte=0xF1 { local log2st0 = ST0; ST1 = ST1 f* log2st0; fpop(); } +:FYL2XP1 is vexMode=0 & byte=0xD9; byte=0xF9 { one:4 = 1; tmp:10 = int2float(one); log2st0:10 = ST0 f+ tmp; ST1 = ST1 f* log2st0; fpop(); } + + +# +# MMX instructions +# + +:ADDPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x58; XmmReg ... & m128 +{ + XmmReg[0,64] = XmmReg[0,64] f+ m128[0,64]; + XmmReg[64,64] = XmmReg[64,64] f+ m128[64,64]; +} + +:ADDPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x58; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f+ XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] f+ XmmReg2[64,64]; +} + +:ADDPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x58; m128 & XmmReg ... +{ + local m:16 = m128; # Guarantee value is in a fixed location + XmmReg[0,32] = XmmReg[0,32] f+ m[0,32]; + XmmReg[32,32] = XmmReg[32,32] f+ m[32,32]; + XmmReg[64,32] = XmmReg[64,32] f+ m[64,32]; + XmmReg[96,32] = XmmReg[96,32] f+ m[96,32]; +} + +:ADDPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x58; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f+ XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] f+ XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] f+ XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] f+ XmmReg2[96,32]; +} + +:ADDSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x58; m64 & XmmReg ... +{ + XmmReg[0,64] = XmmReg[0,64] f+ m64; +} + +:ADDSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x58; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f+ XmmReg2[0,64]; +} + +:ADDSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x58; m32 & XmmReg ... +{ + XmmReg[0,32] = XmmReg[0,32] f+ m32; +} + +:ADDSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x58; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f+ XmmReg2[0,32]; +} + +:ADDSUBPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD0; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] f- m[0,64]; + XmmReg[64,64] = XmmReg[64,64] f+ m[64,64]; +} + +:ADDSUBPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD0; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f- XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] f+ XmmReg2[64,64]; +} + +:ADDSUBPS XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xD0; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] f- m[0,32]; + XmmReg[32,32] = XmmReg[32,32] f+ m[32,32]; + XmmReg[64,32] = XmmReg[64,32] f- m[64,32]; + XmmReg[96,32] = XmmReg[96,32] f+ m[96,32]; +} + +:ADDSUBPS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xD0; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f- XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] f+ XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] f- XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] f+ XmmReg2[96,32]; +} + +# special FLOATING POINT bitwise AND +:ANDPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x54; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] & m[0,64]; + XmmReg[64,64] = XmmReg[64,64] & m[64,64]; +} + +# special FLOATING POINT bitwise AND +:ANDPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x54; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] & XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] & XmmReg2[64,64]; +} + +# special FLOATING POINT bitwise AND +:ANDPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x54; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] & m[0,32]; + XmmReg[32,32] = XmmReg[32,32] & m[32,32]; + XmmReg[64,32] = XmmReg[64,32] & m[64,32]; + XmmReg[96,32] = XmmReg[96,32] & m[96,32]; +} + +# special FLOATING POINT bitwise AND +:ANDPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x54; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] & XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] & XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] & XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] & XmmReg2[96,32]; +} + +# special FLOATING POINT bitwise AND NOT +:ANDNPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x55; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = ~XmmReg[0,64] & m[0,64]; + XmmReg[64,64] = ~XmmReg[64,64] & m[64,64]; +} + +:ANDNPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x55; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = ~XmmReg1[0,64] & XmmReg2[0,64]; + XmmReg1[64,64] = ~XmmReg1[64,64] & XmmReg2[64,64]; +} + +# special FLOATING POINT bitwise AND NOT +:ANDNPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x55; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = ~XmmReg[0,32] & m[0,32]; + XmmReg[32,32] = ~XmmReg[32,32] & m[32,32]; + XmmReg[64,32] = ~XmmReg[64,32] & m[64,32]; + XmmReg[96,32] = ~XmmReg[96,32] & m[96,32]; +} + +:ANDNPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x55; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = ~XmmReg1[0,32] & XmmReg2[0,32]; + XmmReg1[32,32] = ~XmmReg1[32,32] & XmmReg2[32,32]; + XmmReg1[64,32] = ~XmmReg1[64,32] & XmmReg2[64,32]; + XmmReg1[96,32] = ~XmmReg1[96,32] & XmmReg2[96,32]; +} + +# predicate mnemonics for "CMP...PD" opcode +XmmCondPD: "EQ" is imm8=0 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f== xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( xmmTmp1_Qb f== xmmTmp2_Qb ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "LT" is imm8=1 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f< xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( xmmTmp1_Qb f< xmmTmp2_Qb ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "LE" is imm8=2 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f<= xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( xmmTmp1_Qb f<= xmmTmp2_Qb ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "UNORD" is imm8=3 { + xmmTmp1_Qa = zext( nan(xmmTmp1_Qa) || nan(xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( nan(xmmTmp1_Qb) || nan(xmmTmp2_Qb) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "NEQ" is imm8=4 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f!= xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( xmmTmp1_Qb f!= xmmTmp2_Qb ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "NLT" is imm8=5 { + xmmTmp1_Qa = zext( !(xmmTmp1_Qa f< xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( !(xmmTmp1_Qb f< xmmTmp2_Qb) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "NLE" is imm8=6 { + xmmTmp1_Qa = zext( !(xmmTmp1_Qa f<= xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( !(xmmTmp1_Qb f<= xmmTmp2_Qb) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondPD: "ORD" is imm8=7 { + xmmTmp1_Qa = zext( !(nan(xmmTmp1_Qa) || nan(xmmTmp2_Qa)) ) * 0xFFFFFFFFFFFFFFFF; + xmmTmp1_Qb = zext( !(nan(xmmTmp1_Qb) || nan(xmmTmp2_Qb)) ) * 0xFFFFFFFFFFFFFFFF; +} + +define pcodeop cmppd; +XmmCondPD: is imm8 { + xmmTmp1_Qa = cmppd(xmmTmp1_Qa, xmmTmp2_Qa, imm8:1); + xmmTmp1_Qb = cmppd(xmmTmp1_Qb, xmmTmp2_Qb, imm8:1); +} + +# immediate operand for "CMP...PD" opcode +# note: normally blank, "imm8" emits for all out of range cases +CMPPD_OPERAND: is imm8<8 { } +CMPPD_OPERAND: ", "^imm8 is imm8 { } + +:CMP^XmmCondPD^"PD" XmmReg,m128^CMPPD_OPERAND is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC2; (m128 & XmmReg ...); XmmCondPD & CMPPD_OPERAND +{ + local m:16 = m128; + xmmTmp1_Qa = XmmReg[0,64]; + xmmTmp1_Qb = XmmReg[64,64]; + + xmmTmp2_Qa = m[0,64]; + xmmTmp2_Qb = m[64,64]; + + build XmmCondPD; + + XmmReg[0,64] = xmmTmp1_Qa; + XmmReg[64,64] = xmmTmp1_Qb; +} + +:CMP^XmmCondPD^"PD" XmmReg1,XmmReg2^CMPPD_OPERAND is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC2; xmmmod=3 & XmmReg1 & XmmReg2; XmmCondPD & CMPPD_OPERAND +{ + xmmTmp1_Qa = XmmReg1[0,64]; + xmmTmp1_Qb = XmmReg1[64,64]; + + xmmTmp2_Qa = XmmReg2[0,64]; + xmmTmp2_Qb = XmmReg2[64,64]; + + build XmmCondPD; + + XmmReg1[0,64] = xmmTmp1_Qa; + XmmReg1[64,64] = xmmTmp1_Qb; +} + + +# predicate mnemonics for "CMP...PS" opcode +XmmCondPS: "EQ" is imm8=0 { + xmmTmp1_Da = zext( xmmTmp1_Da f== xmmTmp2_Da ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( xmmTmp1_Db f== xmmTmp2_Db ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( xmmTmp1_Dc f== xmmTmp2_Dc ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( xmmTmp1_Dd f== xmmTmp2_Dd ) * 0xFFFFFFFF; +} + +XmmCondPS: "LT" is imm8=1 { + xmmTmp1_Da = zext( xmmTmp1_Da f< xmmTmp2_Da ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( xmmTmp1_Db f< xmmTmp2_Db ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( xmmTmp1_Dc f< xmmTmp2_Dc ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( xmmTmp1_Dd f< xmmTmp2_Dd ) * 0xFFFFFFFF; +} + +XmmCondPS: "LE" is imm8=2 { + xmmTmp1_Da = zext( xmmTmp1_Da f<= xmmTmp2_Da ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( xmmTmp1_Db f<= xmmTmp2_Db ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( xmmTmp1_Dc f<= xmmTmp2_Dc ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( xmmTmp1_Dd f<= xmmTmp2_Dd ) * 0xFFFFFFFF; +} + +XmmCondPS: "UNORD" is imm8=3 { + xmmTmp1_Da = zext( nan(xmmTmp1_Da) || nan(xmmTmp2_Da) ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( nan(xmmTmp1_Db) || nan(xmmTmp2_Db) ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( nan(xmmTmp1_Dc) || nan(xmmTmp2_Dc) ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( nan(xmmTmp1_Dd) || nan(xmmTmp2_Dd) ) * 0xFFFFFFFF; +} + +XmmCondPS: "NEQ" is imm8=4 { + xmmTmp1_Da = zext( xmmTmp1_Da f!= xmmTmp2_Da ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( xmmTmp1_Db f!= xmmTmp2_Db ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( xmmTmp1_Dc f!= xmmTmp2_Dc ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( xmmTmp1_Dd f!= xmmTmp2_Dd ) * 0xFFFFFFFF; +} + +XmmCondPS: "NLT" is imm8=5 { + xmmTmp1_Da = zext( !(xmmTmp1_Da f< xmmTmp2_Da) ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( !(xmmTmp1_Db f< xmmTmp2_Db) ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( !(xmmTmp1_Dc f< xmmTmp2_Dc) ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( !(xmmTmp1_Dd f< xmmTmp2_Dd) ) * 0xFFFFFFFF; +} + +XmmCondPS: "NLE" is imm8=6 { + xmmTmp1_Da = zext( !(xmmTmp1_Da f<= xmmTmp2_Da) ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( !(xmmTmp1_Db f<= xmmTmp2_Db) ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( !(xmmTmp1_Dc f<= xmmTmp2_Dc) ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( !(xmmTmp1_Dd f<= xmmTmp2_Dd) ) * 0xFFFFFFFF; +} + +XmmCondPS: "ORD" is imm8=7 { + xmmTmp1_Da = zext( !(nan(xmmTmp1_Da) || nan(xmmTmp2_Da)) ) * 0xFFFFFFFF; + xmmTmp1_Db = zext( !(nan(xmmTmp1_Db) || nan(xmmTmp2_Db)) ) * 0xFFFFFFFF; + xmmTmp1_Dc = zext( !(nan(xmmTmp1_Dc) || nan(xmmTmp2_Dc)) ) * 0xFFFFFFFF; + xmmTmp1_Dd = zext( !(nan(xmmTmp1_Dd) || nan(xmmTmp2_Dd)) ) * 0xFFFFFFFF; +} + +define pcodeop cmpps; +XmmCondPS: is imm8 { + xmmTmp1_Da = cmpps(xmmTmp1_Da, xmmTmp2_Da, imm8:1); + xmmTmp1_Db = cmpps(xmmTmp1_Db, xmmTmp2_Db, imm8:1); + xmmTmp1_Dc = cmpps(xmmTmp1_Dc, xmmTmp2_Dc, imm8:1); + xmmTmp1_Dd = cmpps(xmmTmp1_Dd, xmmTmp2_Dd, imm8:1); +} + +# immediate operand for "CMP...PS" opcode +# note: normally blank, "imm8" emits for all out of range cases +CMPPS_OPERAND: is imm8<8 { } +CMPPS_OPERAND: ", "^imm8 is imm8 { } + +:CMP^XmmCondPS^"PS" XmmReg,m128^CMPPS_OPERAND is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC2; (m128 & XmmReg ...); XmmCondPS & CMPPS_OPERAND +{ + local m:16 = m128; + xmmTmp1_Da = XmmReg[0,32]; + xmmTmp1_Db = XmmReg[32,32]; + xmmTmp1_Dc = XmmReg[64,32]; + xmmTmp1_Dd = XmmReg[96,32]; + + xmmTmp2_Da = m[0,32]; + xmmTmp2_Db = m[32,32]; + xmmTmp2_Dc = m[64,32]; + xmmTmp2_Dd = m[96,32]; + + build XmmCondPS; + + XmmReg[0,32] = xmmTmp1_Da; + XmmReg[32,32] = xmmTmp1_Db; + XmmReg[64,32] = xmmTmp1_Dc; + XmmReg[96,32] = xmmTmp1_Dd; +} + +:CMP^XmmCondPS^"PS" XmmReg1,XmmReg2^CMPPS_OPERAND is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC2; xmmmod=3 & XmmReg1 & XmmReg2; XmmCondPS & CMPPS_OPERAND +{ + xmmTmp1_Da = XmmReg1[0,32]; + xmmTmp1_Db = XmmReg1[32,32]; + xmmTmp1_Dc = XmmReg1[64,32]; + xmmTmp1_Dd = XmmReg1[96,32]; + + xmmTmp2_Da = XmmReg2[0,32]; + xmmTmp2_Db = XmmReg2[32,32]; + xmmTmp2_Dc = XmmReg2[64,32]; + xmmTmp2_Dc = XmmReg2[96,32]; + + build XmmCondPS; + + XmmReg1[0,32] = xmmTmp1_Da; + XmmReg1[32,32] = xmmTmp1_Db; + XmmReg1[64,32] = xmmTmp1_Dc; + XmmReg1[96,32] = xmmTmp1_Dd; +} + + +# predicate mnemonics for "CMP...SD" opcode +XmmCondSD: "EQ" is imm8=0 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f== xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "LT" is imm8=1 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f< xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "LE" is imm8=2 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f<= xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "UNORD" is imm8=3 { + xmmTmp1_Qa = zext( nan(xmmTmp1_Qa) || nan(xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "NEQ" is imm8=4 { + xmmTmp1_Qa = zext( xmmTmp1_Qa f!= xmmTmp2_Qa ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "NLT" is imm8=5 { + xmmTmp1_Qa = zext( !(xmmTmp1_Qa f< xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "NLE" is imm8=6 { + xmmTmp1_Qa = zext( !(xmmTmp1_Qa f<= xmmTmp2_Qa) ) * 0xFFFFFFFFFFFFFFFF; +} + +XmmCondSD: "ORD" is imm8=7 { + xmmTmp1_Qa = zext( !(nan(xmmTmp1_Qa) || nan(xmmTmp2_Qa)) ) * 0xFFFFFFFFFFFFFFFF; +} + + +define pcodeop cmpsd; +XmmCondSD: is imm8 { + xmmTmp1_Qa = cmpsd(xmmTmp1_Qa, xmmTmp2_Qa, imm8:1); +} + +# immediate operand for "CMP...SD" opcode +# note: normally blank, "imm8" emits for all out of range cases +CMPSD_OPERAND: is imm8<8 { } +CMPSD_OPERAND: ", "^imm8 is imm8 { } + +:CMP^XmmCondSD^"SD" XmmReg, m64^CMPSD_OPERAND is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xC2; (m64 & XmmReg ...); XmmCondSD & CMPSD_OPERAND +{ + xmmTmp1_Qa = XmmReg[0,64]; + xmmTmp2_Qa = m64; + build XmmCondSD; + XmmReg[0,64] = xmmTmp1_Qa; +} + +:CMP^XmmCondSD^"SD" XmmReg1, XmmReg2^CMPSD_OPERAND is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xC2; xmmmod=3 & XmmReg1 & XmmReg2; XmmCondSD & CMPSD_OPERAND +{ + xmmTmp1_Qa = XmmReg1[0,64]; + xmmTmp2_Qa = XmmReg2[0,64]; + build XmmCondSD; + XmmReg1[0,64] = xmmTmp1_Qa; +} + + +# predicate mnemonics for "CMP...SS" opcode +XmmCondSS: "EQ" is imm8=0 { + xmmTmp1_Da = zext( xmmTmp1_Da f== xmmTmp2_Da ) * 0xFFFFFFFF; +} + +XmmCondSS: "LT" is imm8=1 { + xmmTmp1_Da = zext( xmmTmp1_Da f< xmmTmp2_Da ) * 0xFFFFFFFF; +} + +XmmCondSS: "LE" is imm8=2 { + xmmTmp1_Da = zext( xmmTmp1_Da f<= xmmTmp2_Da ) * 0xFFFFFFFF; +} + +XmmCondSS: "UNORD" is imm8=3 { + xmmTmp1_Da = zext( nan(xmmTmp1_Da) || nan(xmmTmp2_Da) ) * 0xFFFFFFFF; +} + +XmmCondSS: "NEQ" is imm8=4 { + xmmTmp1_Da = zext( xmmTmp1_Da f!= xmmTmp2_Da ) * 0xFFFFFFFF; +} + +XmmCondSS: "NLT" is imm8=5 { + xmmTmp1_Da = zext( !(xmmTmp1_Da f< xmmTmp2_Da) ) * 0xFFFFFFFF; +} + +XmmCondSS: "NLE" is imm8=6 { + xmmTmp1_Da = zext( !(xmmTmp1_Da f<= xmmTmp2_Da) ) * 0xFFFFFFFF; +} + +XmmCondSS: "ORD" is imm8=7 { + xmmTmp1_Da = zext( !(nan(xmmTmp1_Da) || nan(xmmTmp2_Da)) ) * 0xFFFFFFFF; +} + + +define pcodeop cmpss; +XmmCondSS: is imm8 { + xmmTmp1_Da = cmpss(xmmTmp1_Da, xmmTmp2_Da, imm8:1); +} + +# immediate operand for "CMP...SS" opcode +# note: normally blank, "imm8" emits for all out of range cases +CMPSS_OPERAND: is imm8<8 { } +CMPSS_OPERAND: ", "^imm8 is imm8 { } + +:CMP^XmmCondSS^"SS" XmmReg, m32^CMPSS_OPERAND is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xC2; (m32 & XmmReg ...); XmmCondSS & CMPSS_OPERAND +{ + xmmTmp1_Da = XmmReg[0,32]; + xmmTmp2_Da = m32; + build XmmCondSS; + XmmReg[0,32] = xmmTmp1_Da; +} + +:CMP^XmmCondSS^"SS" XmmReg1, XmmReg2^CMPSS_OPERAND is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xC2; xmmmod=3 & XmmReg1 & XmmReg2; XmmCondSS & CMPSS_OPERAND +{ + xmmTmp1_Da = XmmReg1[0,32]; + xmmTmp2_Da = XmmReg2[0,32]; + build XmmCondSS; + XmmReg1[0,32] = xmmTmp1_Da; +} + + +:COMISD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2F; m64 & XmmReg ... +{ + fucompe(XmmReg[0,64], m64); +} + +:COMISD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2F; xmmmod=3 & XmmReg1 & XmmReg2 +{ + fucompe(XmmReg1[0,64], XmmReg2[0,64]); +} + +:COMISS XmmReg, m32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2F; m32 & XmmReg ... +{ + fucompe(XmmReg[0,32], m32); +} + +:COMISS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2F; xmmmod=3 & XmmReg1 & XmmReg2 +{ + fucompe(XmmReg1[0,32], XmmReg2[0,32]); +} + +:CVTDQ2PD XmmReg, m64 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xE6; m64 & XmmReg ... +{ + local m:8 = m64; + XmmReg[0,64] = int2float( m[0,32] ); + XmmReg[64,64] = int2float( m[32,32] ); +} + +:CVTDQ2PD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xE6; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = int2float( XmmReg2[0,32] ); + XmmReg1[64,64] = int2float( XmmReg2[32,32] ); +} + +:CVTDQ2PS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5B; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = int2float( m[0,32] ); + XmmReg[32,32] = int2float( m[32,32] ); + XmmReg[64,32] = int2float( m[64,32] ); + XmmReg[96,32] = int2float( m[96,32] ); +} + +:CVTDQ2PS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5B; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = int2float( XmmReg2[0,32] ); + XmmReg1[32,32] = int2float( XmmReg2[32,32] ); + XmmReg1[64,32] = int2float( XmmReg2[64,32] ); + XmmReg1[96,32] = int2float( XmmReg2[96,32] ); +} + +:CVTPD2DQ XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xE6; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = trunc( m[0,64] ); + XmmReg[32,32] = trunc( m[64,64] ); + XmmReg[64,32] = 0; + XmmReg[96,32] = 0; +} + +:CVTPD2DQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xE6; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = trunc( XmmReg2[0,64] ); + XmmReg1[32,32] = trunc( XmmReg2[64,64] ); + XmmReg1[64,32] = 0; + XmmReg1[96,32] = 0; +} + +:CVTPD2PI mmxreg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2D; mmxreg ... & m128 +{ + local m:16 = m128; + mmxreg[0,32] = trunc( m[0,64] ); + mmxreg[32,32] = trunc( m[64,64] ); +} + +:CVTPD2PI mmxreg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2D; xmmmod=3 & mmxreg1 & XmmReg2 +{ + mmxreg1[0,32] = trunc( XmmReg2[0,64] ); + mmxreg1[32,32] = trunc( XmmReg2[64,64] ); +} + +:CVTPD2PS XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5A; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = float2float( m[0,64] ); + XmmReg[32,32] = float2float( m[64,64] ); + XmmReg[64,32] = 0; + XmmReg[96,32] = 0; +} + +:CVTPD2PS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5A; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = float2float( XmmReg2[0,64] ); + XmmReg1[32,32] = float2float( XmmReg2[64,64] ); + XmmReg1[64,32] = 0; + XmmReg1[96,32] = 0; +} + +:CVTPI2PD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2A; m64 & XmmReg ... +{ + local m:8 = m64; + XmmReg[0,64] = int2float(m[0,32]); + XmmReg[64,64] = int2float(m[32,32]); +} + +:CVTPI2PD XmmReg1, mmxreg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2A; xmmmod=3 & XmmReg1 & mmxreg2 +{ + XmmReg1[0,64] = int2float(mmxreg2[0,32]); + XmmReg1[64,64] = int2float(mmxreg2[32,32]); +} + +:CVTPI2PS XmmReg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2A; m64 & XmmReg ... +{ + local m:8 = m64; + XmmReg[0,32] = int2float(m[0,32]); + XmmReg[32,32] = int2float(m[32,32]); +} + +:CVTPI2PS XmmReg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2A; xmmmod=3 & XmmReg1 & mmxreg2 +{ + XmmReg1[0,32] = int2float(mmxreg2[0,32]); + XmmReg1[32,32] = int2float(mmxreg2[32,32]); +} + +:CVTPS2DQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5B; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = trunc( m[0,32] ); + XmmReg[32,32] = trunc( m[32,32] ); + XmmReg[64,32] = trunc( m[64,32] ); + XmmReg[96,32] = trunc( m[96,32] ); +} + +:CVTPS2DQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5B; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = trunc( XmmReg2[0,32] ); + XmmReg1[32,32] = trunc( XmmReg2[32,32] ); + XmmReg1[64,32] = trunc( XmmReg2[64,32] ); + XmmReg1[96,32] = trunc( XmmReg2[96,32] ); +} + +:CVTPS2PD XmmReg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5A; m64 & XmmReg ... +{ + local m:8 = m64; + XmmReg[0,64] = float2float( m[0,32] ); + XmmReg[64,64] = float2float( m[32,32] ); +} + +:CVTPS2PD XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5A; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = float2float( XmmReg2[0,32] ); + XmmReg1[64,64] = float2float( XmmReg2[32,32] ); +} + +:CVTPS2PI mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2D; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,32] = round(m[0,32]); + mmxreg[32,32] = round(m[32,32]); + FPUTagWord = 0x0000; +} + +:CVTPS2PI mmxreg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2D; xmmmod=3 & mmxreg1 & XmmReg2 +{ + mmxreg1[0,32] = round(XmmReg2[0,32]); + mmxreg1[32,32] = round(XmmReg2[32,32]); + FPUTagWord = 0x0000; +} + +:CVTSD2SI Reg32, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x2D; Reg32 ... & m64 +{ + Reg32 = trunc(round(m64)); +} + +:CVTSD2SI Reg32, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x2D; xmmmod=3 & Reg32 & XmmReg2 +{ + Reg32 = trunc(round(XmmReg2[0,64])); +} + +@ifdef IA64 +:CVTSD2SI Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2D; Reg64 ... & m64 +{ + Reg64 = round(m64); +} + +:CVTSD2SI Reg64, XmmReg2 is vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2D; xmmmod=3 & Reg64 & XmmReg2 +{ + Reg64 = round(XmmReg2[0,64]); +} +@endif + +:CVTSD2SS XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5A; m64 & XmmReg ... +{ + XmmReg[0,32] = float2float(m64); +} + +:CVTSD2SS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5A; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = float2float(XmmReg2[0,64]); +} + +:CVTSI2SD XmmReg, rm32 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x2A; rm32 & XmmReg ... +{ + XmmReg[0,64] = int2float(rm32); +} + +@ifdef IA64 +:CVTSI2SD XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... +{ + XmmReg[0,64] = int2float(rm64); +} +@endif + +:CVTSI2SS XmmReg, rm32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2A; rm32 & XmmReg ... +{ + XmmReg[0,32] = int2float(rm32); +} + +@ifdef IA64 +:CVTSI2SS XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... +{ + XmmReg[0,32] = int2float(rm64); +} +@endif + +:CVTSS2SD XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5A; m32 & XmmReg ... +{ + XmmReg[0,64] = float2float(m32); +} + +:CVTSS2SD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5A; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = float2float(XmmReg2[0,32]); +} + +:CVTSS2SI Reg32, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2D; Reg32 ... & m32 +{ + Reg32 = round(m32); +} + +:CVTSS2SI Reg32, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2D; xmmmod=3 & Reg32 & XmmReg2 +{ + Reg32 = round(XmmReg2[0,32]); +} + +@ifdef IA64 +:CVTSS2SI Reg64, m32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2D; Reg64 ... & m32 +{ + Reg64 = trunc(round(m32)); +} + +:CVTSS2SI Reg64, XmmReg2 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2D; xmmmod=3 & Reg64 & XmmReg2 +{ + Reg64 = trunc(round(XmmReg2[0,32])); +} +@endif + +:CVTTPD2PI mmxreg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2C; mmxreg ... & m128 +{ + local m:16 = m128; + mmxreg[0,32] = trunc(m[0,64]); + mmxreg[32,32] = trunc(m[64,64]); + FPUTagWord = 0x0000; +} + +:CVTTPD2PI mmxreg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2C; xmmmod=3 & mmxreg1 & XmmReg2 +{ + mmxreg1[0,32] = trunc(XmmReg2[0,64]); + mmxreg1[32,32] = trunc(XmmReg2[64,64]); + FPUTagWord = 0x0000; +} + +:CVTTPD2DQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE6; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = trunc(m[0,64]); + XmmReg[32,32] = trunc(m[64,64]); + XmmReg[64,32] = 0; + XmmReg[96,32] = 0; +} + +:CVTTPD2DQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE6; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = trunc(XmmReg2[0,64]); + XmmReg1[32,32] = trunc(XmmReg2[64,64]); + XmmReg1[64,32] = 0; + XmmReg1[96,32] = 0; +} + +:CVTTPS2DQ XmmReg, m128 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5B; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = trunc(m[0,32]); + XmmReg[32,32] = trunc(m[32,32]); + XmmReg[64,32] = trunc(m[64,32]); + XmmReg[96,32] = trunc(m[96,32]); +} + +:CVTTPS2DQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5B; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = trunc(XmmReg2[0,32]); + XmmReg1[32,32] = trunc(XmmReg2[32,32]); + XmmReg1[64,32] = trunc(XmmReg2[64,32]); + XmmReg1[96,32] = trunc(XmmReg2[96,32]); +} + +:CVTTPS2PI mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2C; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,32] = trunc(m[0,32]); + mmxreg[32,32] = trunc(m[32,32]); + FPUTagWord = 0x0000; +} + +:CVTTPS2PI mmxreg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2C; xmmmod=3 & mmxreg1 & XmmReg2 +{ + mmxreg1[0,32] = trunc(XmmReg2[0,32]); + mmxreg1[32,32] = trunc(XmmReg2[32,32]); + FPUTagWord = 0x0000; +} + +:CVTTSD2SI Reg32, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x2C; Reg32 ... & check_Reg32_dest ... & m64 +{ + Reg32 = trunc(m64); + build check_Reg32_dest; +} + +:CVTTSD2SI Reg32, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x2C; xmmmod=3 & Reg32 & check_Reg32_dest & XmmReg2 +{ + Reg32 = trunc(XmmReg2[0,64]); + build check_Reg32_dest; +} + +@ifdef IA64 +:CVTTSD2SI Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2C; Reg64 ... & m64 +{ + Reg64 = trunc(m64); +} + +:CVTTSD2SI Reg64, XmmReg2 is vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2C; xmmmod=3 & Reg64 & XmmReg2 +{ + Reg64 = trunc(XmmReg2[0,64]); +} +@endif + +:CVTTSS2SI Reg32, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2C; Reg32 ... & check_Reg32_dest ... & m32 +{ + Reg32 = trunc(m32); + build check_Reg32_dest; +} + +:CVTTSS2SI Reg32, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x2C; xmmmod=3 & Reg32 & check_Reg32_dest & XmmReg2 +{ + Reg32 = trunc(XmmReg2[0,32]); + build check_Reg32_dest; +} + +@ifdef IA64 +:CVTTSS2SI Reg64, m32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2C; Reg64 ... & m32 +{ + Reg64 = trunc(m32); +} + +:CVTTSS2SI Reg64, XmmReg2 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2C; xmmmod=3 & Reg64 & XmmReg2 +{ + Reg64 = trunc(XmmReg2[0,32]); +} +@endif + +define pcodeop divpd; +:DIVPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5E; XmmReg ... & m128 { XmmReg = divpd(XmmReg, m128); } +:DIVPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5E; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = divpd(XmmReg1, XmmReg2); } + +define pcodeop divps; +:DIVPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5E; XmmReg ... & m128 { XmmReg = divps(XmmReg, m128); } +:DIVPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5E; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = divps(XmmReg1, XmmReg2); } + +:DIVSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5E; m64 & XmmReg ... +{ + XmmReg[0,64] = XmmReg[0,64] f/ m64; +} + +:DIVSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5E; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f/ XmmReg2[0,64]; +} + +:DIVSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5E; m32 & XmmReg ... +{ + XmmReg[0,32] = XmmReg[0,32] f/ m32; +} + +:DIVSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5E; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f/ XmmReg2[0,32]; +} + +:EMMS is vexMode=0 & byte=0x0F; byte=0x77 { FPUTagWord = 0xFFFF; } + +:HADDPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7C; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] f+ XmmReg[64,64]; + XmmReg[64,64] = m[0,64] f+ m[64,64]; +} + +:HADDPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7C; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f+ XmmReg1[64,64]; + XmmReg1[64,64] = XmmReg2[0,64] f+ XmmReg2[64,64]; +} + +:HADDPS XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x7C; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] f+ XmmReg[32,32]; + XmmReg[32,32] = XmmReg[64,32] f+ XmmReg[96,32]; + XmmReg[64,32] = m[0,32] f+ m[32,32]; + XmmReg[96,32] = m[64,32] f+ m[96,32]; +} + +:HADDPS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x7C; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f+ XmmReg1[32,32]; + XmmReg1[32,32] = XmmReg1[64,32] f+ XmmReg1[96,32]; + XmmReg1[64,32] = XmmReg2[0,32] f+ XmmReg2[32,32]; + XmmReg1[96,32] = XmmReg2[64,32] f+ XmmReg2[96,32]; +} + +:HSUBPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7D; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] f- XmmReg[64,64]; + XmmReg[64,64] = m[0,64] f- m[64,64]; +} + +:HSUBPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7D; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f- XmmReg1[64,64]; + XmmReg1[64,64] = XmmReg2[0,64] f- XmmReg2[64,64]; +} + +:HSUBPS XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x7D; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] f- XmmReg[32,32]; + XmmReg[32,32] = XmmReg[64,32] f- XmmReg[96,32]; + XmmReg[64,32] = m[0,32] f- m[32,32]; + XmmReg[96,32] = m[64,32] f- m[96,32]; +} + +:HSUBPS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x7D; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f- XmmReg1[32,32]; + XmmReg1[32,32] = XmmReg1[64,32] f- XmmReg1[96,32]; + XmmReg1[64,32] = XmmReg2[0,32] f- XmmReg2[32,32]; + XmmReg1[96,32] = XmmReg2[64,32] f- XmmReg2[96,32]; +} + +#-------------------- +#SSE3... +#-------------------- + +define pcodeop lddqu; +:LDDQU XmmReg, m128 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xF0; XmmReg ... & m128 { XmmReg = lddqu(XmmReg, m128); } + +define pcodeop maskmovdqu; +:MASKMOVDQU XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF7; XmmReg1 & XmmReg2 { XmmReg1 = maskmovdqu(XmmReg1, XmmReg2); } + +define pcodeop maxpd; +:MAXPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5F; XmmReg ... & m128 { XmmReg = maxpd(XmmReg, m128); } +:MAXPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = maxpd(XmmReg1, XmmReg2); } + +define pcodeop maxps; +:MAXPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5F; XmmReg ... & m128 { XmmReg = maxps(XmmReg, m128); } +:MAXPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = maxps(XmmReg1, XmmReg2); } + +:MAXSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5F; XmmReg ... & m64 +{ + local tmp:8 = m64; + if (tmp f< XmmReg[0,64]) goto inst_next; + XmmReg[0,64] = tmp; +} + +:MAXSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5F; xmmmod=3 & XmmReg1 & XmmReg2 +{ + if (XmmReg2[0,64] f< XmmReg1[0,64]) goto inst_next; + XmmReg1[0,64] = XmmReg2[0,64]; +} + +:MAXSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5F; XmmReg ... & m32 +{ + local tmp:4 = m32; + if (tmp f< XmmReg[0,32]) goto inst_next; + XmmReg[0,32] = tmp; +} + +:MAXSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5F; xmmmod=3 & XmmReg1 & XmmReg2 +{ + if (XmmReg2[0,32] f< XmmReg1[0,32]) goto inst_next; + XmmReg1[0,32] = XmmReg2[0,32]; +} + +define pcodeop minpd; +:MINPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5D; XmmReg ... & m128 { XmmReg = minpd(XmmReg, m128); } +:MINPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5D; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = minpd(XmmReg1, XmmReg2); } + +define pcodeop minps; +:MINPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5D; XmmReg ... & m128 { XmmReg = minps(XmmReg, m128); } +:MINPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5D; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = minps(XmmReg1, XmmReg2); } + +:MINSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5D; XmmReg ... & m64 +{ + local tmp:8 = m64; + if (XmmReg[0,64] f< tmp) goto inst_next; + XmmReg[0,64] = tmp; +} + +:MINSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5D; xmmmod=3 & XmmReg1 & XmmReg2 +{ + if (XmmReg1[0,64] f< XmmReg2[0,64]) goto inst_next; + XmmReg1[0,64] = XmmReg2[0,64]; +} + +:MINSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5D; XmmReg ... & m32 +{ + local tmp:4 = m32; + if (XmmReg[0,32] f< tmp) goto inst_next; + XmmReg[0,32] = tmp; +} + +:MINSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5D; xmmmod=3 & XmmReg1 & XmmReg2 +{ + if (XmmReg1[0,32] f< XmmReg2[0,32]) goto inst_next; + XmmReg1[0,32] = XmmReg2[0,32]; +} + +:MOVAPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x28; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = m[0,64]; + XmmReg[64,64] = m[64,64]; +} + +:MOVAPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x28; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg2[64,64]; +} + +:MOVAPD m128, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x29; m128 & XmmReg ... +{ + m128 = XmmReg; +} + +:MOVAPD XmmReg2, XmmReg1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x29; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,64] = XmmReg1[0,64]; + XmmReg2[64,64] = XmmReg1[64,64]; +} + +:MOVAPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x28; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = m[0,32]; + XmmReg[32,32] = m[32,32]; + XmmReg[64,32] = m[64,32]; + XmmReg[96,32] = m[96,32]; +} + +:MOVAPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x28; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg2[96,32]; +} + +:MOVAPS m128, XmmReg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x29; m128 & XmmReg ... +{ + m128 = XmmReg; +} + +:MOVAPS XmmReg2, XmmReg1 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x29; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,32] = XmmReg1[0,32]; + XmmReg2[32,32] = XmmReg1[32,32]; + XmmReg2[64,32] = XmmReg1[64,32]; + XmmReg2[96,32] = XmmReg1[96,32]; +} + +:MOVD mmxreg, rm32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6E; rm32 & mmxreg ... { mmxreg = zext(rm32); } +:MOVD rm32, mmxreg is vexMode=0 & rexWprefix=0 & mandover=0 & byte=0x0F; byte=0x7E; rm32 & check_rm32_dest ... & mmxreg ... { rm32 = mmxreg(0); build check_rm32_dest; } +:MOVD XmmReg, rm32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6E; rm32 & XmmReg ... { XmmReg = zext(rm32); } +:MOVD rm32, XmmReg is vexMode=0 & $(PRE_66) & rexWprefix=0 & byte=0x0F; byte=0x7E; rm32 & check_rm32_dest ... & XmmReg ... { rm32 = XmmReg(0); build check_rm32_dest; } +@ifdef IA64 +:MOVQ mmxreg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x6E; rm64 & mmxreg ... { mmxreg = rm64; } +:MOVQ rm64, mmxreg is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x7E; rm64 & mmxreg ... { rm64 = mmxreg; } +:MOVQ XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x6E; rm64 & XmmReg ... { XmmReg = zext(rm64); } +:MOVQ rm64, XmmReg is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x7E; rm64 & XmmReg ... { rm64 = XmmReg(0); } +@endif + +:MOVDDUP XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x12; m64 & XmmReg ... +{ + XmmReg[0,64] = m64; + XmmReg[64,64] = m64; +} + +:MOVDDUP XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x12; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg2[0,64]; +} + +:MOVSHDUP XmmReg, m128 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x16; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = m[32,32]; + XmmReg[32,32] = m[32,32]; + XmmReg[64,32] = m[96,32]; + XmmReg[96,32] = m[96,32]; +} + +:MOVSHDUP XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x16; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg2[32,32]; + XmmReg1[32,32] = XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg2[96,32]; + XmmReg1[96,32] = XmmReg2[96,32]; +} + +:MOVSLDUP XmmReg, m128 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x12; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = m[0,32]; + XmmReg[32,32] = m[0,32]; + XmmReg[64,32] = m[64,32]; + XmmReg[96,32] = m[64,32]; +} + +:MOVSLDUP XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x12; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg2[0,32]; + XmmReg1[64,32] = XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg2[64,32]; +} + +:MOVDQA XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6F; XmmReg ... & m128 { XmmReg = m128; } +:MOVDQA XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg2; } +:MOVDQA m128, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7F; XmmReg ... & m128 { m128 = XmmReg; } +:MOVDQA XmmReg2, XmmReg1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x7F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg2 = XmmReg1; } + +:MOVDQU XmmReg, m128 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x6F; XmmReg ... & m128 { XmmReg = m128; } +:MOVDQU XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x6F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg2; } +:MOVDQU m128, XmmReg is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x7F; XmmReg ... & m128 { m128 = XmmReg; } +:MOVDQU XmmReg2, XmmReg1 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x7F; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg2 = XmmReg1; } + +# TODO: this vexMode=0 & is potentially wrong + +define pcodeop movdq2q; +:MOVDQ2Q mmxreg2, XmmReg1 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0xD6; XmmReg1 & mmxreg2 { mmxreg2 = movdq2q(mmxreg2, XmmReg1); } + +:MOVHLPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x12; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[0,64] = XmmReg2[64,64]; } + +:MOVHPD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x16; XmmReg ... & m64 { XmmReg[64,64] = m64; } + +:MOVHPD m64, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x17; XmmReg ... & m64 { m64 = XmmReg[64,64]; } + +:MOVHPS XmmReg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x16; XmmReg ... & m64 { XmmReg[64,64] = m64; } + +:MOVHPS m64, XmmReg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x17; XmmReg ... & m64 { m64 = XmmReg[64,64]; } + +:MOVLHPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x16; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[64,64] = XmmReg2[0,64]; } + +:MOVLPD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x12; XmmReg ... & m64 { XmmReg[0,64] = m64; } + +:MOVLPD m64, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x13; XmmReg ... & m64 { m64 = XmmReg[0,64]; } + +:MOVLPS XmmReg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x12; XmmReg ... & m64 { XmmReg[0,64] = m64; } + +: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); } + +define pcodeop movmskps; +:MOVMSKPS Reg32, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x50; XmmReg2 & Reg32 { Reg32 = movmskps(Reg32, XmmReg2); } + +:MOVNTQ m64, mmxreg is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE7; mmxreg ... & m64 { m64 = mmxreg; } + +:MOVNTDQ m128, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE7; XmmReg ... & m128 { m128 = XmmReg; } + +:MOVNTPD m128, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2B; XmmReg ... & m128 { m128 = XmmReg; } + +:MOVNTPS m128, XmmReg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2B; XmmReg ... & m128 { m128 = XmmReg; } + +:MOVQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6F; mmxreg ... & m64 { mmxreg = m64; } +:MOVQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg2; } +:MOVQ m64, mmxreg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x7F; mmxreg ... & m64 { m64 = mmxreg; } +:MOVQ mmxreg2, mmxreg1 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x7F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg2 = mmxreg1; } + +:MOVQ XmmReg, m64 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x7E; XmmReg ... & m64 +{ + XmmReg = zext(m64); +} + +:MOVQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x7E; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1 = zext(XmmReg2[0,64]); +} + +:MOVQ m64, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD6; m64 & XmmReg ... +{ + m64 = XmmReg[0,64]; +} + +:MOVQ XmmReg2, XmmReg1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD6; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg2 = zext(XmmReg1[0,64]); +} + +:MOVQ2DQ XmmReg, mmxreg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xD6; XmmReg & mmxreg2 +{ + XmmReg = zext(mmxreg2); +# may need to model x87 FPU state changes too ????? +} + +:MOVSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x10; m64 & XmmReg ... +{ + XmmReg[0,64] = m64; + XmmReg[64,64] = 0; +} + +:MOVSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x10; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg2[0,64]; +} + +:MOVSD m64, XmmReg is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x11; m64 & XmmReg ... +{ + m64 = XmmReg[0,64]; +} + +:MOVSD XmmReg2, XmmReg1 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x11; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,64] = XmmReg1[0,64]; +} + +:MOVSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x10; m32 & XmmReg ... +{ + XmmReg[0,32] = m32; + XmmReg[32,32] = 0; + XmmReg[64,32] = 0; + XmmReg[96,32] = 0; +} + +:MOVSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x10; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg2[0,32]; +} + +:MOVSS m32, XmmReg is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x11; m32 & XmmReg ... +{ + m32 = XmmReg[0,32]; +} + +:MOVSS XmmReg2, XmmReg1 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x11; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,32] = XmmReg1[0,32]; +} + +:MOVUPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x10; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = m[0,64]; + XmmReg[64,64] = m[64,64]; +} + +:MOVUPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x10; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg2[64,64]; +} + +:MOVUPD m128, XmmReg is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x11; m128 & XmmReg ... +{ + m128 = XmmReg; +} + +:MOVUPD XmmReg2, XmmReg1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x11; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,64] = XmmReg1[0,64]; + XmmReg2[64,64] = XmmReg1[64,64]; +} + +# Not sure why someone had done it this way ????? +#Xmm2m128: m128 is vexMode=0 & m128 { export m128; } +#Xmm2m128: XmmReg2 is vexMode=0 & xmmmod=3 & XmmReg2 { export XmmReg2; } +# +#define pcodeop movups; +##:MOVUPS XmmReg, m128 is vexMode=0 & byte=0x0F; byte=0x10; XmmReg ... & m128 { XmmReg = movups(XmmReg, m128); } +##:MOVUPS XmmReg1, XmmReg2 is vexMode=0 & byte=0x0F; byte=0x10; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = movups(XmmReg1, XmmReg2); } +# +#:MOVUPS XmmReg,Xmm2m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x10; XmmReg ... & Xmm2m128 { XmmReg = movups(XmmReg, Xmm2m128); } + +:MOVUPS XmmReg, m128 is vexMode=0 & byte=0x0F; byte=0x10; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = m[0,32]; + XmmReg[32,32] = m[32,32]; + XmmReg[64,32] = m[64,32]; + XmmReg[96,32] = m[96,32]; +} + +:MOVUPS XmmReg1, XmmReg2 is vexMode=0 & byte=0x0F; byte=0x10; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg2[96,32]; +} + +:MOVUPS m128, XmmReg is vexMode=0 & mandover=0 & byte=0x0F; byte=0x11; m128 & XmmReg ... +{ + m128 = XmmReg; +} + +:MOVUPS XmmReg2, XmmReg1 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x11; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg2[0,32] = XmmReg1[0,32]; + XmmReg2[32,32] = XmmReg1[32,32]; + XmmReg2[64,32] = XmmReg1[64,32]; + XmmReg2[96,32] = XmmReg1[96,32]; +} + +:MULPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x59; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] f* m[0,64]; + XmmReg[64,64] = XmmReg[64,64] f* m[64,64]; +} + +:MULPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x59; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f* XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] f* XmmReg2[64,64]; +} + +:MULPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x59; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] f* m[0,32]; + XmmReg[32,32] = XmmReg[32,32] f* m[32,32]; + XmmReg[64,32] = XmmReg[64,32] f* m[64,32]; + XmmReg[96,32] = XmmReg[96,32] f* m[96,32]; +} + +:MULPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x59; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f* XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] f* XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] f* XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] f* XmmReg2[96,32]; +} + +:MULSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x59; m64 & XmmReg ... +{ + XmmReg[0,64] = XmmReg[0,64] f* m64; +} + +:MULSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x59; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f* XmmReg2[0,64]; +} + +:MULSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x59; m32 & XmmReg ... +{ + XmmReg[0,32] = XmmReg[0,32] f* m32; +} + +:MULSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x59; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f* XmmReg2[0,32]; +} + +:ORPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x56; XmmReg ... & m128 { XmmReg = XmmReg | m128; } +:ORPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x56; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg1 | XmmReg2; } + +:ORPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x56; XmmReg ... & m128 { XmmReg = XmmReg | m128; } +:ORPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x56; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg1 | XmmReg2; } + +#sword < 0xff80: sbyte = 0x80 +#sword > 0x007f: sbyte = 0x7f +#otherwise sbyte = sword +macro sswsb(sword, sbyte) { + local less = (sword s< 0xff80:2); + local greater = (sword s> 0x007f:2); + local inbounds = !(less || greater); + sbyte = (sword:1 * inbounds) + (0x80:1 * less) + (0x7f:1 * greater); +} + +macro packsswb_mmx(dst, src) { + local a:8 = dst; + local b:8 = src; + + sswsb(a[ 0,16], dst[ 0,8]); + sswsb(a[16,16], dst[ 8,8]); + sswsb(a[32,16], dst[16,8]); + sswsb(a[48,16], dst[24,8]); + + sswsb(b[ 0,16], dst[32,8]); + sswsb(b[16,16], dst[40,8]); + sswsb(b[32,16], dst[48,8]); + sswsb(b[48,16], dst[56,8]); +} +:PACKSSWB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x63; mmxreg ... & m64 { packsswb_mmx(mmxreg, m64); } +:PACKSSWB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x63; mmxmod = 3 & mmxreg1 & mmxreg2 { packsswb_mmx(mmxreg1, mmxreg2); } + +#sdword < 0xffff_8000: sword = 0x8000 +#sdword > 0x0000_7fff: sword = 0x7fff +#otherwise sbyte = sword +macro ssdsw(sword, sbyte) { + local less = (sword s< 0xffff8000:4); + local greater = (sword s> 0x00007fff:4); + local inbounds = !(less || greater); + sbyte = (sword:2 * zext(inbounds)) + (0x8000:2 * zext(less)) + (0x7fff:2 * zext(greater)); +} + +macro packssdw_mmx(dst, src) { + local a:8 = dst; + local b:8 = src; + + ssdsw(a[ 0,32], dst[ 0,16]); + ssdsw(a[32,32], dst[16,16]); + + ssdsw(b[ 0,32], dst[32,16]); + ssdsw(b[32,32], dst[48,16]); +} +:PACKSSDW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6B; mmxreg ... & m64 { packssdw_mmx(mmxreg, m64); } +:PACKSSDW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6B; mmxmod = 3 & mmxreg1 & mmxreg2 { packssdw_mmx(mmxreg1, mmxreg2); } + +macro packsswb_xmm(dst, src) { + local a:16 = dst; + local b:16 = src; + + sswsb(a[ 0,16], dst[ 0,8]); + sswsb(a[ 16,16], dst[ 8,8]); + sswsb(a[ 32,16], dst[ 16,8]); + sswsb(a[ 48,16], dst[ 24,8]); + sswsb(a[ 64,16], dst[ 32,8]); + sswsb(a[ 80,16], dst[ 40,8]); + sswsb(a[ 96,16], dst[ 48,8]); + sswsb(a[112,16], dst[ 56,8]); + + sswsb(b[ 0,16], dst[ 64,8]); + sswsb(b[ 16,16], dst[ 72,8]); + sswsb(b[ 32,16], dst[ 80,8]); + sswsb(b[ 48,16], dst[ 88,8]); + sswsb(b[ 64,16], dst[ 96,8]); + sswsb(b[ 80,16], dst[104,8]); + sswsb(b[ 96,16], dst[112,8]); + sswsb(b[112,16], dst[120,8]); +} +:PACKSSWB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x63; XmmReg ... & m128 { packsswb_xmm(XmmReg, m128); } +:PACKSSWB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x63; xmmmod = 3 & XmmReg1 & XmmReg2 { packsswb_xmm(XmmReg1, XmmReg2); } + +macro packssdw_xmm(dst, src) { + local a:16 = dst; + local b:16 = src; + + ssdsw(a[ 0,32], dst[ 0,16]); + ssdsw(a[32,32], dst[ 16,16]); + ssdsw(a[64,32], dst[ 32,16]); + ssdsw(a[96,32], dst[ 48,16]); + + ssdsw(b[ 0,32], dst[ 64,16]); + ssdsw(b[32,32], dst[ 80,16]); + ssdsw(b[64,32], dst[ 96,16]); + ssdsw(b[96,32], dst[112,16]); +} +:PACKSSDW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6B; XmmReg ... & m128 { packssdw_xmm(XmmReg, m128); } +:PACKSSDW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6B; xmmmod = 3 & XmmReg1 & XmmReg2 { packssdw_xmm(XmmReg1, XmmReg2); } + +#sword < 0 : ubyte = 0 +#sword > 0xff: ubyte = 0xff +#otherwise ubyte = sword +macro sswub(sword, ubyte) { + ubyte = (sword s> 0xff:2) * 0xff:1; + ubyte = ubyte + (sword s> 0:2) * (sword s<= 0xff:2) * sword:1; +} + +:PACKUSWB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x67; mmxreg ... & m64 +{ + local dest_copy:8 = mmxreg; + local src_copy:8 = m64; + local ubyte:1 = 0; + sswub(dest_copy[0,16],ubyte); + mmxreg[0,8] = ubyte; + sswub(dest_copy[16,16],ubyte); + mmxreg[8,8] = ubyte; + sswub(dest_copy[32,16],ubyte); + mmxreg[16,8] = ubyte; + sswub(dest_copy[48,16],ubyte); + mmxreg[24,8] = ubyte; + sswub(src_copy[0,16],ubyte); + mmxreg[32,8] = ubyte; + sswub(src_copy[16,16],ubyte); + mmxreg[40,8] = ubyte; + sswub(src_copy[32,16],ubyte); + mmxreg[48,8] = ubyte; + sswub(src_copy[48,16],ubyte); + mmxreg[56,8] = ubyte; +} + +:PACKUSWB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x67; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + local dest_copy:8 = mmxreg1; + local src_copy:8 = mmxreg2; + local ubyte:1 = 0; + sswub(dest_copy[0,16],ubyte); + mmxreg1[0,8] = ubyte; + sswub(dest_copy[16,16],ubyte); + mmxreg1[8,8] = ubyte; + sswub(dest_copy[32,16],ubyte); + mmxreg1[16,8] = ubyte; + sswub(dest_copy[48,16],ubyte); + mmxreg1[24,8] = ubyte; + sswub(src_copy[0,16],ubyte); + mmxreg1[32,8] = ubyte; + sswub(src_copy[16,16],ubyte); + mmxreg1[40,8] = ubyte; + sswub(src_copy[32,16],ubyte); + mmxreg1[48,8] = ubyte; + sswub(src_copy[48,16],ubyte); + mmxreg1[56,8] = ubyte; +} + +:PACKUSWB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x67; XmmReg ... & m128 +{ + local dest_copy:16 = XmmReg; + local src_copy:16 = m128; + local ubyte:1 = 0; + sswub(dest_copy[0,16],ubyte); + XmmReg[0,8] = ubyte; + sswub(dest_copy[16,16],ubyte); + XmmReg[8,8] = ubyte; + sswub(dest_copy[32,16],ubyte); + XmmReg[16,8] = ubyte; + sswub(dest_copy[48,16],ubyte); + XmmReg[24,8] = ubyte; + sswub(dest_copy[64,16],ubyte); + XmmReg[32,8] = ubyte; + sswub(dest_copy[80,16],ubyte); + XmmReg[40,8] = ubyte; + sswub(dest_copy[96,16],ubyte); + XmmReg[48,8] = ubyte; + sswub(dest_copy[112,16],ubyte); + XmmReg[56,8] = ubyte; + + sswub(src_copy[0,16],ubyte); + XmmReg[64,8] = ubyte; + sswub(src_copy[16,16],ubyte); + XmmReg[72,8] = ubyte; + sswub(src_copy[32,16],ubyte); + XmmReg[80,8] = ubyte; + sswub(src_copy[48,16],ubyte); + XmmReg[88,8] = ubyte; + sswub(src_copy[64,16],ubyte); + XmmReg[96,8] = ubyte; + sswub(src_copy[80,16],ubyte); + XmmReg[104,8] = ubyte; + sswub(src_copy[96,16],ubyte); + XmmReg[112,8] = ubyte; + sswub(src_copy[112,16],ubyte); + XmmReg[120,8] = ubyte; +} + +:PACKUSWB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x67; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + local dest_copy:16 = XmmReg1; + local src_copy:16 = XmmReg2; + local ubyte:1 = 0; + sswub(dest_copy[0,16],ubyte); + XmmReg1[0,8] = ubyte; + sswub(dest_copy[16,16],ubyte); + XmmReg1[8,8] = ubyte; + sswub(dest_copy[32,16],ubyte); + XmmReg1[16,8] = ubyte; + sswub(dest_copy[48,16],ubyte); + XmmReg1[24,8] = ubyte; + sswub(dest_copy[64,16],ubyte); + XmmReg1[32,8] = ubyte; + sswub(dest_copy[80,16],ubyte); + XmmReg1[40,8] = ubyte; + sswub(dest_copy[96,16],ubyte); + XmmReg1[48,8] = ubyte; + sswub(dest_copy[112,16],ubyte); + XmmReg1[56,8] = ubyte; + + sswub(src_copy[0,16],ubyte); + XmmReg1[64,8] = ubyte; + sswub(src_copy[16,16],ubyte); + XmmReg1[72,8] = ubyte; + sswub(src_copy[32,16],ubyte); + XmmReg1[80,8] = ubyte; + sswub(src_copy[48,16],ubyte); + XmmReg1[88,8] = ubyte; + sswub(src_copy[64,16],ubyte); + XmmReg1[96,8] = ubyte; + sswub(src_copy[80,16],ubyte); + XmmReg1[104,8] = ubyte; + sswub(src_copy[96,16],ubyte); + XmmReg1[112,8] = ubyte; + sswub(src_copy[112,16],ubyte); + XmmReg1[120,8] = ubyte; +} + +define pcodeop pabsb; +:PABSB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1c; mmxreg ... & m64 { mmxreg=pabsb(mmxreg,m64); } +:PABSB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1c; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=pabsb(mmxreg1,mmxreg2); } +:PABSB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1c; XmmReg ... & m128 { XmmReg=pabsb(XmmReg,m128); } +:PABSB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1c; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pabsb(XmmReg1,XmmReg2); } + +define pcodeop pabsw; +:PABSW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1d; mmxreg ... & m64 { mmxreg=pabsw(mmxreg,m64); } +:PABSW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1d; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=pabsw(mmxreg1,mmxreg2); } +:PABSW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1d; XmmReg ... & m128 { XmmReg=pabsw(XmmReg,m128); } +:PABSW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1d; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pabsw(XmmReg1,XmmReg2); } + +define pcodeop pabsd; +:PABSD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1e; mmxreg ... & m64 { mmxreg=pabsd(mmxreg,m64); } +:PABSD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x1e; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=pabsd(mmxreg1,mmxreg2); } +:PABSD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1e; XmmReg ... & m128 { XmmReg=pabsd(XmmReg,m128); } +:PABSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x1e; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pabsd(XmmReg1,XmmReg2); } + +:PADDB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFC; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,8] = mmxreg[0,8] + m[0,8]; + mmxreg[8,8] = mmxreg[8,8] + m[8,8]; + mmxreg[16,8] = mmxreg[16,8] + m[16,8]; + mmxreg[24,8] = mmxreg[24,8] + m[24,8]; + mmxreg[32,8] = mmxreg[32,8] + m[32,8]; + mmxreg[40,8] = mmxreg[40,8] + m[40,8]; + mmxreg[48,8] = mmxreg[48,8] + m[48,8]; + mmxreg[56,8] = mmxreg[56,8] + m[56,8]; +} + +:PADDB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFC; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = mmxreg1[0,8] + mmxreg2[0,8]; + mmxreg1[8,8] = mmxreg1[8,8] + mmxreg2[8,8]; + mmxreg1[16,8] = mmxreg1[16,8] + mmxreg2[16,8]; + mmxreg1[24,8] = mmxreg1[24,8] + mmxreg2[24,8]; + mmxreg1[32,8] = mmxreg1[32,8] + mmxreg2[32,8]; + mmxreg1[40,8] = mmxreg1[40,8] + mmxreg2[40,8]; + mmxreg1[48,8] = mmxreg1[48,8] + mmxreg2[48,8]; + mmxreg1[56,8] = mmxreg1[56,8] + mmxreg2[56,8]; +} + +:PADDW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFD; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = mmxreg[0,16] + m[0,16]; + mmxreg[16,16] = mmxreg[16,16] + m[16,16]; + mmxreg[32,16] = mmxreg[32,16] + m[32,16]; + mmxreg[48,16] = mmxreg[48,16] + m[48,16]; +} + +:PADDW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFD; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = mmxreg1[0,16] + mmxreg2[0,16]; + mmxreg1[16,16] = mmxreg1[16,16] + mmxreg2[16,16]; + mmxreg1[32,16] = mmxreg1[32,16] + mmxreg2[32,16]; + mmxreg1[48,16] = mmxreg1[48,16] + mmxreg2[48,16]; +} + +:PADDD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFE; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,32] = mmxreg[0,32] + m[0,32]; + mmxreg[32,32] = mmxreg[32,32] + m[32,32]; +} + +:PADDD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFE; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = mmxreg1[0,32] + mmxreg2[0,32]; + mmxreg1[32,32] = mmxreg1[32,32] + mmxreg2[32,32]; +} + +:PADDB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFC; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,8] = XmmReg[0,8] + m[0,8]; + XmmReg[8,8] = XmmReg[8,8] + m[8,8]; + XmmReg[16,8] = XmmReg[16,8] + m[16,8]; + XmmReg[24,8] = XmmReg[24,8] + m[24,8]; + XmmReg[32,8] = XmmReg[32,8] + m[32,8]; + XmmReg[40,8] = XmmReg[40,8] + m[40,8]; + XmmReg[48,8] = XmmReg[48,8] + m[48,8]; + XmmReg[56,8] = XmmReg[56,8] + m[56,8]; + XmmReg[64,8] = XmmReg[64,8] + m[64,8]; + XmmReg[72,8] = XmmReg[72,8] + m[72,8]; + XmmReg[80,8] = XmmReg[80,8] + m[80,8]; + XmmReg[88,8] = XmmReg[88,8] + m[88,8]; + XmmReg[96,8] = XmmReg[96,8] + m[96,8]; + XmmReg[104,8] = XmmReg[104,8] + m[104,8]; + XmmReg[112,8] = XmmReg[112,8] + m[112,8]; + XmmReg[120,8] = XmmReg[120,8] + m[120,8]; +} + +## example of bitfield solution +#:PADDB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFC; xmmmod = 3 & XmmReg1 & XmmReg2 +#{ +# XmmReg1[ 0,8] = XmmReg1[ 0,8] + XmmReg2[ 0,8]; +# XmmReg1[ 8,8] = XmmReg1[ 8,8] + XmmReg2[ 8,8]; +# XmmReg1[ 16,8] = XmmReg1[ 16,8] + XmmReg2[ 16,8]; +# XmmReg1[ 24,8] = XmmReg1[ 24,8] + XmmReg2[ 24,8]; +# XmmReg1[ 32,8] = XmmReg1[ 32,8] + XmmReg2[ 32,8]; +# XmmReg1[ 40,8] = XmmReg1[ 40,8] + XmmReg2[ 40,8]; +# XmmReg1[ 48,8] = XmmReg1[ 48,8] + XmmReg2[ 48,8]; +# XmmReg1[ 56,8] = XmmReg1[ 56,8] + XmmReg2[ 56,8]; +## XmmReg1[ 64,8] = XmmReg1[ 64,8] + XmmReg2[ 64,8]; +## XmmReg1[ 72,8] = XmmReg1[ 72,8] + XmmReg2[ 72,8]; +## XmmReg1[ 80,8] = XmmReg1[ 80,8] + XmmReg2[ 80,8]; +## XmmReg1[ 88,8] = XmmReg1[ 88,8] + XmmReg2[ 88,8]; +## XmmReg1[ 96,8] = XmmReg1[ 96,8] + XmmReg2[ 96,8]; +## XmmReg1[104,8] = XmmReg1[104,8] + XmmReg2[104,8]; +## XmmReg1[112,8] = XmmReg1[112,8] + XmmReg2[112,8]; +## XmmReg1[120,8] = XmmReg1[120,8] + XmmReg2[120,8]; +#} + +# full set of XMM byte registers +:PADDB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFC; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = XmmReg1[0,8] + XmmReg2[0,8]; + XmmReg1[8,8] = XmmReg1[8,8] + XmmReg2[8,8]; + XmmReg1[16,8] = XmmReg1[16,8] + XmmReg2[16,8]; + XmmReg1[24,8] = XmmReg1[24,8] + XmmReg2[24,8]; + XmmReg1[32,8] = XmmReg1[32,8] + XmmReg2[32,8]; + XmmReg1[40,8] = XmmReg1[40,8] + XmmReg2[40,8]; + XmmReg1[48,8] = XmmReg1[48,8] + XmmReg2[48,8]; + XmmReg1[56,8] = XmmReg1[56,8] + XmmReg2[56,8]; + XmmReg1[64,8] = XmmReg1[64,8] + XmmReg2[64,8]; + XmmReg1[72,8] = XmmReg1[72,8] + XmmReg2[72,8]; + XmmReg1[80,8] = XmmReg1[80,8] + XmmReg2[80,8]; + XmmReg1[88,8] = XmmReg1[88,8] + XmmReg2[88,8]; + XmmReg1[96,8] = XmmReg1[96,8] + XmmReg2[96,8]; + XmmReg1[104,8] = XmmReg1[104,8] + XmmReg2[104,8]; + XmmReg1[112,8] = XmmReg1[112,8] + XmmReg2[112,8]; + XmmReg1[120,8] = XmmReg1[120,8] + XmmReg2[120,8]; +} + +:PADDW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFD; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = XmmReg[0,16] + m[0,16]; + XmmReg[16,16] = XmmReg[16,16] + m[16,16]; + XmmReg[32,16] = XmmReg[32,16] + m[32,16]; + XmmReg[48,16] = XmmReg[48,16] + m[48,16]; + XmmReg[64,16] = XmmReg[64,16] + m[64,16]; + XmmReg[80,16] = XmmReg[80,16] + m[80,16]; + XmmReg[96,16] = XmmReg[96,16] + m[96,16]; + XmmReg[112,16] = XmmReg[112,16] + m[112,16]; +} + +:PADDW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFD; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = XmmReg1[0,16] + XmmReg2[0,16]; + XmmReg1[16,16] = XmmReg1[16,16] + XmmReg2[16,16]; + XmmReg1[32,16] = XmmReg1[32,16] + XmmReg2[32,16]; + XmmReg1[48,16] = XmmReg1[48,16] + XmmReg2[48,16]; + XmmReg1[64,16] = XmmReg1[64,16] + XmmReg2[64,16]; + XmmReg1[80,16] = XmmReg1[80,16] + XmmReg2[80,16]; + XmmReg1[96,16] = XmmReg1[96,16] + XmmReg2[96,16]; + XmmReg1[112,16] = XmmReg1[112,16] + XmmReg2[112,16]; +} + +:PADDD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFE; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] + m[0,32]; + XmmReg[32,32] = XmmReg[32,32] + m[32,32]; + XmmReg[64,32] = XmmReg[64,32] + m[64,32]; + XmmReg[96,32] = XmmReg[96,32] + m[96,32]; +} + +:PADDD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFE; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] + XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] + XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] + XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] + XmmReg2[96,32]; +} + +:PADDQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD4; mmxreg ... & m64 +{ + mmxreg = mmxreg + m64; +} + +:PADDQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD4; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1 = mmxreg1 + mmxreg2; +} + +:PADDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD4; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] + m[0,64]; + XmmReg[64,64] = XmmReg[64,64] + m[64,64]; +} + +:PADDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD4; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] + XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] + XmmReg2[64,64]; +} + +define pcodeop paddsb; +:PADDSB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEC; mmxreg1 ... & mmxreg2_m64 { mmxreg1 = paddsb(mmxreg1, mmxreg2_m64); } + +define pcodeop paddsw; +:PADDSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xED; mmxreg1 ... & mmxreg2_m64 { mmxreg1 = paddsw(mmxreg1, mmxreg2_m64); } + +:PADDSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEC; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = paddsb(XmmReg1, XmmReg2_m128); } +:PADDSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xED; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = paddsw(XmmReg1, XmmReg2_m128); } + +define pcodeop paddusb; +:PADDUSB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDC; mmxreg1 ... & mmxreg2_m64 { mmxreg1 = paddusb(mmxreg1, mmxreg2_m64); } + +define pcodeop paddusw; +:PADDUSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDD; mmxreg1 ... & mmxreg2_m64 { mmxreg1 = paddusw(mmxreg1, mmxreg2_m64); } + +:PADDUSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDC; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = paddusb(XmmReg1, XmmReg2_m128); } +:PADDUSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDD; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = paddusw(XmmReg1, XmmReg2_m128); } + +:PALIGNR mmxreg, m64, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x3A; byte=0x0F; m64 & mmxreg ...; imm8 +{ + temp:16 = ( ( zext(mmxreg) << 64 ) | zext( m64 ) ) >> ( imm8 * 8 ); + mmxreg = temp:8; +} + +:PALIGNR mmxreg1, mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x3A; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2; imm8 +{ + temp:16 = ( ( zext(mmxreg1) << 64 ) | zext( mmxreg2 ) ) >> ( imm8 * 8 ); + mmxreg1 = temp:8; +} + +:PALIGNR XmmReg1, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0F; m128 & XmmReg1 ...; imm8 +{ + temp:32 = ( ( zext(XmmReg1) << 128 ) | zext( m128 ) ) >> ( imm8 * 8 ); + XmmReg1 = temp:16; +} + +:PALIGNR XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0F; xmmmod=3 & XmmReg1 & XmmReg2; imm8 +{ + temp:32 = ( ( zext(XmmReg1) << 128 ) | zext( XmmReg2 ) ) >> ( imm8 * 8 ); + XmmReg1 = temp:16; +} + +:PAND mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDB; mmxreg ... & m64 { mmxreg = mmxreg & m64; } +:PAND mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDB; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg1 & mmxreg2; } +:PAND XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDB; XmmReg ... & m128 { XmmReg = XmmReg & m128; } +:PAND XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDB; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg1 & XmmReg2; } + +:PANDN mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDF; mmxreg ... & m64 { mmxreg = ~mmxreg & m64; } +:PANDN mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDF; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = ~mmxreg1 & mmxreg2; } +:PANDN XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDF; XmmReg ... & m128 { XmmReg = ~XmmReg & m128; } +:PANDN XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDF; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = ~XmmReg1 & XmmReg2; } + +define pcodeop pavgb; +:PAVGB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE0; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,8] = pavgb(mmxreg[0,8], m[0,8]); + mmxreg[8,8] = pavgb(mmxreg[8,8], m[8,8]); + mmxreg[16,8] = pavgb(mmxreg[16,8], m[16,8]); + mmxreg[24,8] = pavgb(mmxreg[24,8], m[24,8]); + mmxreg[32,8] = pavgb(mmxreg[32,8], m[32,8]); + mmxreg[40,8] = pavgb(mmxreg[40,8], m[40,8]); + mmxreg[48,8] = pavgb(mmxreg[48,8], m[48,8]); + mmxreg[56,8] = pavgb(mmxreg[56,8], m[56,8]); +} + +:PAVGB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE0; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = pavgb(mmxreg1[0,8], mmxreg2[0,8]); + mmxreg1[8,8] = pavgb(mmxreg1[8,8], mmxreg2[8,8]); + mmxreg1[16,8] = pavgb(mmxreg1[16,8], mmxreg2[16,8]); + mmxreg1[24,8] = pavgb(mmxreg1[24,8], mmxreg2[24,8]); + mmxreg1[32,8] = pavgb(mmxreg1[32,8], mmxreg2[32,8]); + mmxreg1[40,8] = pavgb(mmxreg1[40,8], mmxreg2[40,8]); + mmxreg1[48,8] = pavgb(mmxreg1[48,8], mmxreg2[48,8]); + mmxreg1[56,8] = pavgb(mmxreg1[56,8], mmxreg2[56,8]); +} + +define pcodeop pavgw; +:PAVGW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE3; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = pavgw(mmxreg[0,16], m[0,16]); + mmxreg[16,16] = pavgw(mmxreg[16,16], m[16,16]); + mmxreg[32,16] = pavgw(mmxreg[32,16], m[32,16]); + mmxreg[48,16] = pavgw(mmxreg[48,16], m[48,16]); +} + +:PAVGW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE3; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = pavgw(mmxreg1[0,16], mmxreg2[0,16]); + mmxreg1[16,16] = pavgw(mmxreg1[16,16], mmxreg2[16,16]); + mmxreg1[32,16] = pavgw(mmxreg1[32,16], mmxreg2[32,16]); + mmxreg1[48,16] = pavgw(mmxreg1[48,16], mmxreg2[48,16]); +} + +:PAVGB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE0; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,8] = pavgb(XmmReg[0,8], m[0,8]); + XmmReg[8,8] = pavgb(XmmReg[8,8], m[8,8]); + XmmReg[16,8] = pavgb(XmmReg[16,8], m[16,8]); + XmmReg[24,8] = pavgb(XmmReg[24,8], m[24,8]); + XmmReg[32,8] = pavgb(XmmReg[32,8], m[32,8]); + XmmReg[40,8] = pavgb(XmmReg[40,8], m[40,8]); + XmmReg[48,8] = pavgb(XmmReg[48,8], m[48,8]); + XmmReg[56,8] = pavgb(XmmReg[56,8], m[56,8]); + XmmReg[64,8] = pavgb(XmmReg[64,8], m[64,8]); + XmmReg[72,8] = pavgb(XmmReg[72,8], m[72,8]); + XmmReg[80,8] = pavgb(XmmReg[80,8], m[80,8]); + XmmReg[88,8] = pavgb(XmmReg[88,8], m[88,8]); + XmmReg[96,8] = pavgb(XmmReg[96,8], m[96,8]); + XmmReg[104,8] = pavgb(XmmReg[104,8], m[104,8]); + XmmReg[112,8] = pavgb(XmmReg[112,8], m[112,8]); + XmmReg[120,8] = pavgb(XmmReg[120,8], m[120,8]); +} + +# full set of XMM byte registers +:PAVGB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE0; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = pavgb(XmmReg1[0,8], XmmReg2[0,8]); + XmmReg1[8,8] = pavgb(XmmReg1[8,8], XmmReg2[8,8]); + XmmReg1[16,8] = pavgb(XmmReg1[16,8], XmmReg2[16,8]); + XmmReg1[24,8] = pavgb(XmmReg1[24,8], XmmReg2[24,8]); + XmmReg1[32,8] = pavgb(XmmReg1[32,8], XmmReg2[32,8]); + XmmReg1[40,8] = pavgb(XmmReg1[40,8], XmmReg2[40,8]); + XmmReg1[48,8] = pavgb(XmmReg1[48,8], XmmReg2[48,8]); + XmmReg1[56,8] = pavgb(XmmReg1[56,8], XmmReg2[56,8]); + XmmReg1[64,8] = pavgb(XmmReg1[64,8], XmmReg2[64,8]); + XmmReg1[72,8] = pavgb(XmmReg1[72,8], XmmReg2[72,8]); + XmmReg1[80,8] = pavgb(XmmReg1[80,8], XmmReg2[80,8]); + XmmReg1[88,8] = pavgb(XmmReg1[88,8], XmmReg2[88,8]); + XmmReg1[96,8] = pavgb(XmmReg1[96,8], XmmReg2[96,8]); + XmmReg1[104,8] = pavgb(XmmReg1[104,8], XmmReg2[104,8]); + XmmReg1[112,8] = pavgb(XmmReg1[112,8], XmmReg2[112,8]); + XmmReg1[120,8] = pavgb(XmmReg1[120,8], XmmReg2[120,8]); +} + +:PAVGW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE3; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = pavgw(XmmReg[0,16], m[0,16]); + XmmReg[16,16] = pavgw(XmmReg[16,16], m[16,16]); + XmmReg[32,16] = pavgw(XmmReg[32,16], m[32,16]); + XmmReg[48,16] = pavgw(XmmReg[48,16], m[48,16]); + XmmReg[64,16] = pavgw(XmmReg[64,16], m[64,16]); + XmmReg[80,16] = pavgw(XmmReg[80,16], m[80,16]); + XmmReg[96,16] = pavgw(XmmReg[96,16], m[96,16]); + XmmReg[112,16] = pavgw(XmmReg[112,16], m[112,16]); +} + +:PAVGW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE3; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = pavgw(XmmReg1[0,16], XmmReg2[0,16]); + XmmReg1[16,16] = pavgw(XmmReg1[16,16], XmmReg2[16,16]); + XmmReg1[32,16] = pavgw(XmmReg1[32,16], XmmReg2[32,16]); + XmmReg1[48,16] = pavgw(XmmReg1[48,16], XmmReg2[48,16]); + XmmReg1[64,16] = pavgw(XmmReg1[64,16], XmmReg2[64,16]); + XmmReg1[80,16] = pavgw(XmmReg1[80,16], XmmReg2[80,16]); + XmmReg1[96,16] = pavgw(XmmReg1[96,16], XmmReg2[96,16]); + XmmReg1[112,16] = pavgw(XmmReg1[112,16], XmmReg2[112,16]); +} + +:PCMPEQB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x74; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,8] = (mmxreg[0,8] == m[0,8]) * 0xFF; + mmxreg[8,8] = (mmxreg[8,8] == m[8,8]) * 0xFF; + mmxreg[16,8] = (mmxreg[16,8] == m[16,8]) * 0xFF; + mmxreg[24,8] = (mmxreg[24,8] == m[24,8]) * 0xFF; + mmxreg[32,8] = (mmxreg[32,8] == m[32,8]) * 0xFF; + mmxreg[40,8] = (mmxreg[40,8] == m[40,8]) * 0xFF; + mmxreg[48,8] = (mmxreg[48,8] == m[48,8]) * 0xFF; + mmxreg[56,8] = (mmxreg[56,8] == m[56,8]) * 0xFF; +} + +:PCMPEQB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x74; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = (mmxreg1[0,8] == mmxreg2[0,8]) * 0xFF; + mmxreg1[8,8] = (mmxreg1[8,8] == mmxreg2[8,8]) * 0xFF; + mmxreg1[16,8] = (mmxreg1[16,8] == mmxreg2[16,8]) * 0xFF; + mmxreg1[24,8] = (mmxreg1[24,8] == mmxreg2[24,8]) * 0xFF; + mmxreg1[32,8] = (mmxreg1[32,8] == mmxreg2[32,8]) * 0xFF; + mmxreg1[40,8] = (mmxreg1[40,8] == mmxreg2[40,8]) * 0xFF; + mmxreg1[48,8] = (mmxreg1[48,8] == mmxreg2[48,8]) * 0xFF; + mmxreg1[56,8] = (mmxreg1[56,8] == mmxreg2[56,8]) * 0xFF; +} + +:PCMPEQW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x75; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = zext(mmxreg[0,16] == m[0,16]) * 0xFFFF; + mmxreg[16,16] = zext(mmxreg[16,16] == m[16,16]) * 0xFFFF; + mmxreg[32,16] = zext(mmxreg[32,16] == m[32,16]) * 0xFFFF; + mmxreg[48,16] = zext(mmxreg[48,16] == m[48,16]) * 0xFFFF; +} + +:PCMPEQW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x75; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = zext(mmxreg1[0,16] == mmxreg2[0,16]) * 0xFFFF; + mmxreg1[16,16] = zext(mmxreg1[16,16] == mmxreg2[16,16]) * 0xFFFF; + mmxreg1[32,16] = zext(mmxreg1[32,16] == mmxreg2[32,16]) * 0xFFFF; + mmxreg1[48,16] = zext(mmxreg1[48,16] == mmxreg2[48,16]) * 0xFFFF; +} + +:PCMPEQD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x76; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,32] = zext(mmxreg[0,32] == m[0,32]) * 0xFFFFFFFF; + mmxreg[32,32] = zext(mmxreg[32,32] == m[32,32]) * 0xFFFFFFFF; +} + +:PCMPEQD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x76; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = zext(mmxreg1[0,32] == mmxreg2[0,32]) * 0xFFFFFFFF; + mmxreg1[32,32] = zext(mmxreg1[32,32] == mmxreg2[32,32]) * 0xFFFFFFFF; +} + +:PCMPEQB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x74; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,8] = (XmmReg[0,8] == m[0,8]) * 0xFF; + XmmReg[8,8] = (XmmReg[8,8] == m[8,8]) * 0xFF; + XmmReg[16,8] = (XmmReg[16,8] == m[16,8]) * 0xFF; + XmmReg[24,8] = (XmmReg[24,8] == m[24,8]) * 0xFF; + XmmReg[32,8] = (XmmReg[32,8] == m[32,8]) * 0xFF; + XmmReg[40,8] = (XmmReg[40,8] == m[40,8]) * 0xFF; + XmmReg[48,8] = (XmmReg[48,8] == m[48,8]) * 0xFF; + XmmReg[56,8] = (XmmReg[56,8] == m[56,8]) * 0xFF; + XmmReg[64,8] = (XmmReg[64,8] == m[64,8]) * 0xFF; + XmmReg[72,8] = (XmmReg[72,8] == m[72,8]) * 0xFF; + XmmReg[80,8] = (XmmReg[80,8] == m[80,8]) * 0xFF; + XmmReg[88,8] = (XmmReg[88,8] == m[88,8]) * 0xFF; + XmmReg[96,8] = (XmmReg[96,8] == m[96,8]) * 0xFF; + XmmReg[104,8] = (XmmReg[104,8] == m[104,8]) * 0xFF; + XmmReg[112,8] = (XmmReg[112,8] == m[112,8]) * 0xFF; + XmmReg[120,8] = (XmmReg[120,8] == m[120,8]) * 0xFF; +} + +# full set of XMM byte registers +:PCMPEQB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x74; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = (XmmReg1[0,8] == XmmReg2[0,8]) * 0xFF; + XmmReg1[8,8] = (XmmReg1[8,8] == XmmReg2[8,8]) * 0xFF; + XmmReg1[16,8] = (XmmReg1[16,8] == XmmReg2[16,8]) * 0xFF; + XmmReg1[24,8] = (XmmReg1[24,8] == XmmReg2[24,8]) * 0xFF; + XmmReg1[32,8] = (XmmReg1[32,8] == XmmReg2[32,8]) * 0xFF; + XmmReg1[40,8] = (XmmReg1[40,8] == XmmReg2[40,8]) * 0xFF; + XmmReg1[48,8] = (XmmReg1[48,8] == XmmReg2[48,8]) * 0xFF; + XmmReg1[56,8] = (XmmReg1[56,8] == XmmReg2[56,8]) * 0xFF; + XmmReg1[64,8] = (XmmReg1[64,8] == XmmReg2[64,8]) * 0xFF; + XmmReg1[72,8] = (XmmReg1[72,8] == XmmReg2[72,8]) * 0xFF; + XmmReg1[80,8] = (XmmReg1[80,8] == XmmReg2[80,8]) * 0xFF; + XmmReg1[88,8] = (XmmReg1[88,8] == XmmReg2[88,8]) * 0xFF; + XmmReg1[96,8] = (XmmReg1[96,8] == XmmReg2[96,8]) * 0xFF; + XmmReg1[104,8] = (XmmReg1[104,8] == XmmReg2[104,8]) * 0xFF; + XmmReg1[112,8] = (XmmReg1[112,8] == XmmReg2[112,8]) * 0xFF; + XmmReg1[120,8] = (XmmReg1[120,8] == XmmReg2[120,8]) * 0xFF; +} + +:PCMPEQW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x75; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = zext(XmmReg[0,16] == m[0,16]) * 0xFFFF; + XmmReg[16,16] = zext(XmmReg[16,16] == m[16,16]) * 0xFFFF; + XmmReg[32,16] = zext(XmmReg[32,16] == m[32,16]) * 0xFFFF; + XmmReg[48,16] = zext(XmmReg[48,16] == m[48,16]) * 0xFFFF; + XmmReg[64,16] = zext(XmmReg[64,16] == m[64,16]) * 0xFFFF; + XmmReg[80,16] = zext(XmmReg[80,16] == m[80,16]) * 0xFFFF; + XmmReg[96,16] = zext(XmmReg[96,16] == m[96,16]) * 0xFFFF; + XmmReg[112,16] = zext(XmmReg[112,16] == m[112,16]) * 0xFFFF; +} + +:PCMPEQW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x75; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = zext(XmmReg1[0,16] == XmmReg2[0,16]) * 0xFFFF; + XmmReg1[16,16] = zext(XmmReg1[16,16] == XmmReg2[16,16]) * 0xFFFF; + XmmReg1[32,16] = zext(XmmReg1[32,16] == XmmReg2[32,16]) * 0xFFFF; + XmmReg1[48,16] = zext(XmmReg1[48,16] == XmmReg2[48,16]) * 0xFFFF; + XmmReg1[64,16] = zext(XmmReg1[64,16] == XmmReg2[64,16]) * 0xFFFF; + XmmReg1[80,16] = zext(XmmReg1[80,16] == XmmReg2[80,16]) * 0xFFFF; + XmmReg1[96,16] = zext(XmmReg1[96,16] == XmmReg2[96,16]) * 0xFFFF; + XmmReg1[112,16] = zext(XmmReg1[112,16] == XmmReg2[112,16]) * 0xFFFF; +} + +:PCMPEQD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x76; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = zext(XmmReg[0,32] == m[0,32]) * 0xFFFFFFFF; + XmmReg[32,32] = zext(XmmReg[32,32] == m[32,32]) * 0xFFFFFFFF; + XmmReg[64,32] = zext(XmmReg[64,32] == m[64,32]) * 0xFFFFFFFF; + XmmReg[96,32] = zext(XmmReg[96,32] == m[96,32]) * 0xFFFFFFFF; +} + +:PCMPEQD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x76; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = zext(XmmReg1[0,32] == XmmReg2[0,32]) * 0xFFFFFFFF; + XmmReg1[32,32] = zext(XmmReg1[32,32] == XmmReg2[32,32]) * 0xFFFFFFFF; + XmmReg1[64,32] = zext(XmmReg1[64,32] == XmmReg2[64,32]) * 0xFFFFFFFF; + XmmReg1[96,32] = zext(XmmReg1[96,32] == XmmReg2[96,32]) * 0xFFFFFFFF; +} + +:PCMPGTB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x64; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,8] = (mmxreg[0,8] s> m[0,8]) * 0xFF; + mmxreg[8,8] = (mmxreg[8,8] s> m[8,8]) * 0xFF; + mmxreg[16,8] = (mmxreg[16,8] s> m[16,8]) * 0xFF; + mmxreg[24,8] = (mmxreg[24,8] s> m[24,8]) * 0xFF; + mmxreg[32,8] = (mmxreg[32,8] s> m[32,8]) * 0xFF; + mmxreg[40,8] = (mmxreg[40,8] s> m[40,8]) * 0xFF; + mmxreg[48,8] = (mmxreg[48,8] s> m[48,8]) * 0xFF; + mmxreg[56,8] = (mmxreg[56,8] s> m[56,8]) * 0xFF; +} + +:PCMPGTB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x64; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = (mmxreg1[0,8] s> mmxreg2[0,8]) * 0xFF; + mmxreg1[8,8] = (mmxreg1[8,8] s> mmxreg2[8,8]) * 0xFF; + mmxreg1[16,8] = (mmxreg1[16,8] s> mmxreg2[16,8]) * 0xFF; + mmxreg1[24,8] = (mmxreg1[24,8] s> mmxreg2[24,8]) * 0xFF; + mmxreg1[32,8] = (mmxreg1[32,8] s> mmxreg2[32,8]) * 0xFF; + mmxreg1[40,8] = (mmxreg1[40,8] s> mmxreg2[40,8]) * 0xFF; + mmxreg1[48,8] = (mmxreg1[48,8] s> mmxreg2[48,8]) * 0xFF; + mmxreg1[56,8] = (mmxreg1[56,8] s> mmxreg2[56,8]) * 0xFF; +} + +:PCMPGTW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x65; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = zext(mmxreg[0,16] s> m[0,16]) * 0xFFFF; + mmxreg[16,16] = zext(mmxreg[16,16] s> m[16,16]) * 0xFFFF; + mmxreg[32,16] = zext(mmxreg[32,16] s> m[32,16]) * 0xFFFF; + mmxreg[48,16] = zext(mmxreg[48,16] s> m[48,16]) * 0xFFFF; +} + +:PCMPGTW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x65; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = zext(mmxreg1[0,16] s> mmxreg2[0,16]) * 0xFFFF; + mmxreg1[16,16] = zext(mmxreg1[16,16] s> mmxreg2[16,16]) * 0xFFFF; + mmxreg1[32,16] = zext(mmxreg1[32,16] s> mmxreg2[32,16]) * 0xFFFF; + mmxreg1[48,16] = zext(mmxreg1[48,16] s> mmxreg2[48,16]) * 0xFFFF; +} + +:PCMPGTD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x66; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,32] = zext(mmxreg[0,32] s> m[0,32]) * 0xFFFFFFFF; + mmxreg[32,32] = zext(mmxreg[32,32] s> m[32,32]) * 0xFFFFFFFF; +} + +:PCMPGTD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x66; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = zext(mmxreg1[0,32] s> mmxreg2[0,32]) * 0xFFFFFFFF; + mmxreg1[32,32] = zext(mmxreg1[32,32] s> mmxreg2[32,32]) * 0xFFFFFFFF; +} + +:PCMPGTB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x64; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,8] = (XmmReg[0,8] s> m[0,8]) * 0xFF; + XmmReg[8,8] = (XmmReg[8,8] s> m[8,8]) * 0xFF; + XmmReg[16,8] = (XmmReg[16,8] s> m[16,8]) * 0xFF; + XmmReg[24,8] = (XmmReg[24,8] s> m[24,8]) * 0xFF; + XmmReg[32,8] = (XmmReg[32,8] s> m[32,8]) * 0xFF; + XmmReg[40,8] = (XmmReg[40,8] s> m[40,8]) * 0xFF; + XmmReg[48,8] = (XmmReg[48,8] s> m[48,8]) * 0xFF; + XmmReg[56,8] = (XmmReg[56,8] s> m[56,8]) * 0xFF; + XmmReg[64,8] = (XmmReg[64,8] s> m[64,8]) * 0xFF; + XmmReg[72,8] = (XmmReg[72,8] s> m[72,8]) * 0xFF; + XmmReg[80,8] = (XmmReg[80,8] s> m[80,8]) * 0xFF; + XmmReg[88,8] = (XmmReg[88,8] s> m[88,8]) * 0xFF; + XmmReg[96,8] = (XmmReg[96,8] s> m[96,8]) * 0xFF; + XmmReg[104,8] = (XmmReg[104,8] s> m[104,8]) * 0xFF; + XmmReg[112,8] = (XmmReg[112,8] s> m[112,8]) * 0xFF; + XmmReg[120,8] = (XmmReg[120,8] s> m[120,8]) * 0xFF; +} + +# full set of XMM byte registers +:PCMPGTB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x64; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = (XmmReg1[0,8] s> XmmReg2[0,8]) * 0xFF; + XmmReg1[8,8] = (XmmReg1[8,8] s> XmmReg2[8,8]) * 0xFF; + XmmReg1[16,8] = (XmmReg1[16,8] s> XmmReg2[16,8]) * 0xFF; + XmmReg1[24,8] = (XmmReg1[24,8] s> XmmReg2[24,8]) * 0xFF; + XmmReg1[32,8] = (XmmReg1[32,8] s> XmmReg2[32,8]) * 0xFF; + XmmReg1[40,8] = (XmmReg1[40,8] s> XmmReg2[40,8]) * 0xFF; + XmmReg1[48,8] = (XmmReg1[48,8] s> XmmReg2[48,8]) * 0xFF; + XmmReg1[56,8] = (XmmReg1[56,8] s> XmmReg2[56,8]) * 0xFF; + XmmReg1[64,8] = (XmmReg1[64,8] s> XmmReg2[64,8]) * 0xFF; + XmmReg1[72,8] = (XmmReg1[72,8] s> XmmReg2[72,8]) * 0xFF; + XmmReg1[80,8] = (XmmReg1[80,8] s> XmmReg2[80,8]) * 0xFF; + XmmReg1[88,8] = (XmmReg1[88,8] s> XmmReg2[88,8]) * 0xFF; + XmmReg1[96,8] = (XmmReg1[96,8] s> XmmReg2[96,8]) * 0xFF; + XmmReg1[104,8] = (XmmReg1[104,8] s> XmmReg2[104,8]) * 0xFF; + XmmReg1[112,8] = (XmmReg1[112,8] s> XmmReg2[112,8]) * 0xFF; + XmmReg1[120,8] = (XmmReg1[120,8] s> XmmReg2[120,8]) * 0xFF; +} + +:PCMPGTW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x65; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = zext(XmmReg[0,16] s> m[0,16]) * 0xFFFF; + XmmReg[16,16] = zext(XmmReg[16,16] s> m[16,16]) * 0xFFFF; + XmmReg[32,16] = zext(XmmReg[32,16] s> m[32,16]) * 0xFFFF; + XmmReg[48,16] = zext(XmmReg[48,16] s> m[48,16]) * 0xFFFF; + XmmReg[64,16] = zext(XmmReg[64,16] s> m[64,16]) * 0xFFFF; + XmmReg[80,16] = zext(XmmReg[80,16] s> m[80,16]) * 0xFFFF; + XmmReg[96,16] = zext(XmmReg[96,16] s> m[96,16]) * 0xFFFF; + XmmReg[112,16] = zext(XmmReg[112,16] s> m[112,16]) * 0xFFFF; +} + +:PCMPGTW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x65; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = zext(XmmReg1[0,16] s> XmmReg2[0,16]) * 0xFFFF; + XmmReg1[16,16] = zext(XmmReg1[16,16] s> XmmReg2[16,16]) * 0xFFFF; + XmmReg1[32,16] = zext(XmmReg1[32,16] s> XmmReg2[32,16]) * 0xFFFF; + XmmReg1[48,16] = zext(XmmReg1[48,16] s> XmmReg2[48,16]) * 0xFFFF; + XmmReg1[64,16] = zext(XmmReg1[64,16] s> XmmReg2[64,16]) * 0xFFFF; + XmmReg1[80,16] = zext(XmmReg1[80,16] s> XmmReg2[80,16]) * 0xFFFF; + XmmReg1[96,16] = zext(XmmReg1[96,16] s> XmmReg2[96,16]) * 0xFFFF; + XmmReg1[112,16] = zext(XmmReg1[112,16] s> XmmReg2[112,16]) * 0xFFFF; +} + +:PCMPGTD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x66; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = zext(XmmReg[0,32] s> m[0,32]) * 0xFFFFFFFF; + XmmReg[32,32] = zext(XmmReg[32,32] s> m[32,32]) * 0xFFFFFFFF; + XmmReg[64,32] = zext(XmmReg[64,32] s> m[64,32]) * 0xFFFFFFFF; + XmmReg[96,32] = zext(XmmReg[96,32] s> m[96,32]) * 0xFFFFFFFF; +} + +:PCMPGTD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x66; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = zext(XmmReg1[0,32] s> XmmReg2[0,32]) * 0xFFFFFFFF; + XmmReg1[32,32] = zext(XmmReg1[32,32] s> XmmReg2[32,32]) * 0xFFFFFFFF; + XmmReg1[64,32] = zext(XmmReg1[64,32] s> XmmReg2[64,32]) * 0xFFFFFFFF; + 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 & 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 +{ + local shift:1 = (imm8 & 0x7) * 16:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg2[0,64] >> shift, XmmReg2[64,64] >> (shift-64)); + Reg32 = zext(temp:2); + build check_Reg32_dest; +} + +#break PEXTRW with reg/mem dest into two constructors to handle zext in register case +:PEXTRW Rmr32, XmmReg1, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x15; (mod = 3 & Rmr32 & check_Rmr32_dest) & XmmReg1 ; imm8 +{ + local shift:1 = (imm8 & 0x7) * 16:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg1[0,64] >> shift,XmmReg1[64,64] >> (shift - 64)); + Rmr32 = zext(temp:2); + build check_Rmr32_dest; +} + +:PEXTRW m16, XmmReg1, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x15; XmmReg1 ... & m16; imm8 +{ + local shift:1 = (imm8 & 0x7) * 16:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg1[0,64] >> shift,XmmReg1[64,64] >> (shift - 64)); + m16 = temp:2; +} + +define pcodeop phaddd; +:PHADDD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x02; mmxreg ... & m64 { mmxreg=phaddd(mmxreg,m64); } +:PHADDD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x02; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phaddd(mmxreg1,mmxreg2); } +:PHADDD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x02; XmmReg ... & m128 { XmmReg=phaddd(XmmReg,m128); } +:PHADDD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x02; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phaddd(XmmReg1,XmmReg2); } + +define pcodeop phaddw; +:PHADDW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x01; mmxreg ... & m64 { mmxreg=phaddw(mmxreg,m64); } +:PHADDW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x01; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phaddw(mmxreg1,mmxreg2); } +:PHADDW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x01; XmmReg ... & m128 { XmmReg=phaddw(XmmReg,m128); } +:PHADDW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x01; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phaddw(XmmReg1,XmmReg2); } + +define pcodeop phaddsw; +:PHADDSW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x03; mmxreg ... & m64 { mmxreg=phaddsw(mmxreg,m64); } +:PHADDSW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x03; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phaddsw(mmxreg1,mmxreg2); } +:PHADDSW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x03; XmmReg ... & m128 { XmmReg=phaddsw(XmmReg,m128); } +:PHADDSW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x03; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phaddsw(XmmReg1,XmmReg2); } + +define pcodeop phsubd; +:PHSUBD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x06; mmxreg ... & m64 { mmxreg=phsubd(mmxreg,m64); } +:PHSUBD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x06; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phsubd(mmxreg1,mmxreg2); } +:PHSUBD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x06; XmmReg ... & m128 { XmmReg=phsubd(XmmReg,m128); } +:PHSUBD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x06; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phsubd(XmmReg1,XmmReg2); } + +define pcodeop phsubw; +:PHSUBW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x05; mmxreg ... & m64 { mmxreg=phsubw(mmxreg,m64); } +:PHSUBW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x05; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phsubw(mmxreg1,mmxreg2); } +:PHSUBW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x05; XmmReg ... & m128 { XmmReg=phsubw(XmmReg,m128); } +:PHSUBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x05; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phsubw(XmmReg1,XmmReg2); } + +define pcodeop phsubsw; +:PHSUBSW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x07; mmxreg ... & m64 { mmxreg=phsubsw(mmxreg,m64); } +:PHSUBSW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x07; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=phsubsw(mmxreg1,mmxreg2); } +:PHSUBSW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x07; XmmReg ... & m128 { XmmReg=phsubsw(XmmReg,m128); } +:PHSUBSW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x07; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=phsubsw(XmmReg1,XmmReg2); } + +:PINSRW mmxreg, Rmr32, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC4; mmxmod=3 & Rmr32 & mmxreg; imm8 +{ + local destIndex:1 = (imm8 & 0x7) * 16:1; + mmxreg = mmxreg & ~(0xffff:8 << destIndex); + local newVal:8 = zext(Rmr32[0,16]); + mmxreg = mmxreg | (newVal << destIndex); +} + +:PINSRW mmxreg, m16, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC4; m16 & mmxreg ... ; imm8 +{ + local destIndex:1 = (imm8 & 0x7) * 16:1; + mmxreg = mmxreg & ~(0xffff:8 << destIndex); + local newVal:8 = zext(m16); + mmxreg = mmxreg | (newVal << destIndex); +} + +:PINSRW XmmReg, Rmr32, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC4; xmmmod=3 & Rmr32 & XmmReg; imm8 +{ + local destIndex:1 = (imm8 & 0x7) * 16:1; + local useLow:1 = destIndex < 64:1; + local newLow:8 = zext(Rmr32:2) << destIndex; + newLow = (XmmReg[0,64] & ~(0xffff:8 << destIndex)) | newLow; + local newHigh:8 = zext(Rmr32:2) << (destIndex-64:1); + newHigh = (XmmReg[64,64] & ~(0xffff:8 << (destIndex - 64:1))) | newHigh; + conditionalAssign(XmmReg[0,64],useLow,newLow,XmmReg[0,64]); + conditionalAssign(XmmReg[64,64],!useLow,newHigh,XmmReg[64,64]); +} + +:PINSRW XmmReg, m16, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xC4; m16 & XmmReg ...; imm8 +{ + local destIndex:1 = (imm8 & 0x7) * 16:1; + local useLow:1 = destIndex < 64:1; + local newLow:8 = zext(m16) << destIndex; + newLow = (XmmReg[0,64] & ~(0xffff:8 << destIndex)) | newLow; + local newHigh:8 = zext(m16) << (destIndex-64:1); + newHigh = (XmmReg[64,64] & ~(0xffff:8 << (destIndex - 64:1))) | newHigh; + conditionalAssign(XmmReg[0,64],useLow,newLow,XmmReg[0,64]); + conditionalAssign(XmmReg[64,64],!useLow,newHigh,XmmReg[64,64]); +} + +define pcodeop pmaddubsw; +:PMADDUBSW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x04; mmxreg ... & m64 { mmxreg=pmaddubsw(mmxreg,m64); } +:PMADDUBSW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x04; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=pmaddubsw(mmxreg1,mmxreg2); } +:PMADDUBSW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x04; XmmReg ... & m128 { XmmReg=pmaddubsw(XmmReg,m128); } +:PMADDUBSW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x04; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pmaddubsw(XmmReg1,XmmReg2); } + +define pcodeop pmaddwd; +:PMADDWD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF5; mmxreg ... & m64 { mmxreg = pmaddwd(mmxreg, m64); } +:PMADDWD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF5; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = pmaddwd(mmxreg1, mmxreg2); } +:PMADDWD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF5; XmmReg ... & m128 { XmmReg = pmaddwd(XmmReg, m128); } +:PMADDWD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF5; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = pmaddwd(XmmReg1, XmmReg2); } + +:PMAXSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEE; mmxreg1 ... & mmxreg2_m64 +{ + local srcCopy:8 = mmxreg2_m64; + conditionalAssign(mmxreg1[0,16],srcCopy[0,16] s> mmxreg1[0,16],srcCopy[0,16],mmxreg1[0,16]); + conditionalAssign(mmxreg1[16,16],srcCopy[16,16] s> mmxreg1[16,16],srcCopy[16,16],mmxreg1[16,16]); + conditionalAssign(mmxreg1[32,16],srcCopy[32,16] s> mmxreg1[32,16],srcCopy[32,16],mmxreg1[32,16]); + conditionalAssign(mmxreg1[48,16],srcCopy[48,16] s> mmxreg1[48,16],srcCopy[48,16],mmxreg1[48,16]); +} + +:PMAXSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEE; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,16],srcCopy[0,16] s> XmmReg1[0,16],srcCopy[0,16],XmmReg1[0,16]); + conditionalAssign(XmmReg1[16,16],srcCopy[16,16] s> XmmReg1[16,16],srcCopy[16,16],XmmReg1[16,16]); + conditionalAssign(XmmReg1[32,16],srcCopy[32,16] s> XmmReg1[32,16],srcCopy[32,16],XmmReg1[32,16]); + conditionalAssign(XmmReg1[48,16],srcCopy[48,16] s> XmmReg1[48,16],srcCopy[48,16],XmmReg1[48,16]); + conditionalAssign(XmmReg1[64,16],srcCopy[64,16] s> XmmReg1[64,16],srcCopy[64,16],XmmReg1[64,16]); + conditionalAssign(XmmReg1[80,16],srcCopy[80,16] s> XmmReg1[80,16],srcCopy[80,16],XmmReg1[80,16]); + conditionalAssign(XmmReg1[96,16],srcCopy[96,16] s> XmmReg1[96,16],srcCopy[96,16],XmmReg1[96,16]); + conditionalAssign(XmmReg1[112,16],srcCopy[112,16] s> XmmReg1[112,16],srcCopy[112,16],XmmReg1[112,16]); +} + +:PMAXUB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDE; mmxreg1 ... & mmxreg2_m64 +{ + local srcCopy:8 = mmxreg2_m64; + conditionalAssign(mmxreg1[0,8],srcCopy[0,8] > mmxreg1[0,8],srcCopy[0,8],mmxreg1[0,8]); + conditionalAssign(mmxreg1[8,8],srcCopy[8,8] > mmxreg1[8,8],srcCopy[8,8],mmxreg1[8,8]); + conditionalAssign(mmxreg1[16,8],srcCopy[16,8] > mmxreg1[16,8],srcCopy[16,8],mmxreg1[16,8]); + conditionalAssign(mmxreg1[24,8],srcCopy[24,8] > mmxreg1[24,8],srcCopy[24,8],mmxreg1[24,8]); + conditionalAssign(mmxreg1[32,8],srcCopy[32,8] > mmxreg1[32,8],srcCopy[32,8],mmxreg1[32,8]); + conditionalAssign(mmxreg1[40,8],srcCopy[40,8] > mmxreg1[40,8],srcCopy[40,8],mmxreg1[40,8]); + conditionalAssign(mmxreg1[48,8],srcCopy[48,8] > mmxreg1[48,8],srcCopy[48,8],mmxreg1[48,8]); + conditionalAssign(mmxreg1[56,8],srcCopy[56,8] > mmxreg1[56,8],srcCopy[56,8],mmxreg1[56,8]); +} + +:PMAXUB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDE; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,8],srcCopy[0,8] > XmmReg1[0,8],srcCopy[0,8],XmmReg1[0,8]); + conditionalAssign(XmmReg1[8,8],srcCopy[8,8] > XmmReg1[8,8],srcCopy[8,8],XmmReg1[8,8]); + conditionalAssign(XmmReg1[16,8],srcCopy[16,8] > XmmReg1[16,8],srcCopy[16,8],XmmReg1[16,8]); + conditionalAssign(XmmReg1[24,8],srcCopy[24,8] > XmmReg1[24,8],srcCopy[24,8],XmmReg1[24,8]); + conditionalAssign(XmmReg1[32,8],srcCopy[32,8] > XmmReg1[32,8],srcCopy[32,8],XmmReg1[32,8]); + conditionalAssign(XmmReg1[40,8],srcCopy[40,8] > XmmReg1[40,8],srcCopy[40,8],XmmReg1[40,8]); + conditionalAssign(XmmReg1[48,8],srcCopy[48,8] > XmmReg1[48,8],srcCopy[48,8],XmmReg1[48,8]); + conditionalAssign(XmmReg1[56,8],srcCopy[56,8] > XmmReg1[56,8],srcCopy[56,8],XmmReg1[56,8]); + conditionalAssign(XmmReg1[64,8],srcCopy[64,8] > XmmReg1[64,8],srcCopy[64,8],XmmReg1[64,8]); + conditionalAssign(XmmReg1[72,8],srcCopy[72,8] > XmmReg1[72,8],srcCopy[72,8],XmmReg1[72,8]); + conditionalAssign(XmmReg1[80,8],srcCopy[80,8] > XmmReg1[80,8],srcCopy[80,8],XmmReg1[80,8]); + conditionalAssign(XmmReg1[88,8],srcCopy[88,8] > XmmReg1[88,8],srcCopy[88,8],XmmReg1[88,8]); + conditionalAssign(XmmReg1[96,8],srcCopy[96,8] > XmmReg1[96,8],srcCopy[96,8],XmmReg1[96,8]); + conditionalAssign(XmmReg1[104,8],srcCopy[104,8] > XmmReg1[104,8],srcCopy[104,8],XmmReg1[104,8]); + conditionalAssign(XmmReg1[112,8],srcCopy[112,8] > XmmReg1[112,8],srcCopy[112,8],XmmReg1[112,8]); + conditionalAssign(XmmReg1[120,8],srcCopy[120,8] > XmmReg1[120,8],srcCopy[120,8],XmmReg1[120,8]); +} + +:PMINSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEA; mmxreg1 ... & mmxreg2_m64 +{ + local srcCopy:8 = mmxreg2_m64; + conditionalAssign(mmxreg1[0,16],srcCopy[0,16] s< mmxreg1[0,16],srcCopy[0,16],mmxreg1[0,16]); + conditionalAssign(mmxreg1[16,16],srcCopy[16,16] s< mmxreg1[16,16],srcCopy[16,16],mmxreg1[16,16]); + conditionalAssign(mmxreg1[32,16],srcCopy[32,16] s< mmxreg1[32,16],srcCopy[32,16],mmxreg1[32,16]); + conditionalAssign(mmxreg1[48,16],srcCopy[48,16] s< mmxreg1[48,16],srcCopy[48,16],mmxreg1[48,16]); +} + +:PMINSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEA; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,16],srcCopy[0,16] s< XmmReg1[0,16],srcCopy[0,16],XmmReg1[0,16]); + conditionalAssign(XmmReg1[16,16],srcCopy[16,16] s< XmmReg1[16,16],srcCopy[16,16],XmmReg1[16,16]); + conditionalAssign(XmmReg1[32,16],srcCopy[32,16] s< XmmReg1[32,16],srcCopy[32,16],XmmReg1[32,16]); + conditionalAssign(XmmReg1[48,16],srcCopy[48,16] s< XmmReg1[48,16],srcCopy[48,16],XmmReg1[48,16]); + conditionalAssign(XmmReg1[64,16],srcCopy[64,16] s< XmmReg1[64,16],srcCopy[64,16],XmmReg1[64,16]); + conditionalAssign(XmmReg1[80,16],srcCopy[80,16] s< XmmReg1[80,16],srcCopy[80,16],XmmReg1[80,16]); + conditionalAssign(XmmReg1[96,16],srcCopy[96,16] s< XmmReg1[96,16],srcCopy[96,16],XmmReg1[96,16]); + conditionalAssign(XmmReg1[112,16],srcCopy[112,16] s< XmmReg1[112,16],srcCopy[112,16],XmmReg1[112,16]); +} + +:PMINUB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xDA; mmxreg1 ... & mmxreg2_m64 +{ + local srcCopy:8 = mmxreg2_m64; + conditionalAssign(mmxreg1[0,8],srcCopy[0,8] < mmxreg1[0,8],srcCopy[0,8],mmxreg1[0,8]); + conditionalAssign(mmxreg1[8,8],srcCopy[8,8] < mmxreg1[8,8],srcCopy[8,8],mmxreg1[8,8]); + conditionalAssign(mmxreg1[16,8],srcCopy[16,8] < mmxreg1[16,8],srcCopy[16,8],mmxreg1[16,8]); + conditionalAssign(mmxreg1[24,8],srcCopy[24,8] < mmxreg1[24,8],srcCopy[24,8],mmxreg1[24,8]); + conditionalAssign(mmxreg1[32,8],srcCopy[32,8] < mmxreg1[32,8],srcCopy[32,8],mmxreg1[32,8]); + conditionalAssign(mmxreg1[40,8],srcCopy[40,8] < mmxreg1[40,8],srcCopy[40,8],mmxreg1[40,8]); + conditionalAssign(mmxreg1[48,8],srcCopy[48,8] < mmxreg1[48,8],srcCopy[48,8],mmxreg1[48,8]); + conditionalAssign(mmxreg1[56,8],srcCopy[56,8] < mmxreg1[56,8],srcCopy[56,8],mmxreg1[56,8]); +} + +:PMINUB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xDA; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,8],srcCopy[0,8] < XmmReg1[0,8],srcCopy[0,8],XmmReg1[0,8]); + conditionalAssign(XmmReg1[8,8],srcCopy[8,8] < XmmReg1[8,8],srcCopy[8,8],XmmReg1[8,8]); + conditionalAssign(XmmReg1[16,8],srcCopy[16,8] < XmmReg1[16,8],srcCopy[16,8],XmmReg1[16,8]); + conditionalAssign(XmmReg1[24,8],srcCopy[24,8] < XmmReg1[24,8],srcCopy[24,8],XmmReg1[24,8]); + conditionalAssign(XmmReg1[32,8],srcCopy[32,8] < XmmReg1[32,8],srcCopy[32,8],XmmReg1[32,8]); + conditionalAssign(XmmReg1[40,8],srcCopy[40,8] < XmmReg1[40,8],srcCopy[40,8],XmmReg1[40,8]); + conditionalAssign(XmmReg1[48,8],srcCopy[48,8] < XmmReg1[48,8],srcCopy[48,8],XmmReg1[48,8]); + conditionalAssign(XmmReg1[56,8],srcCopy[56,8] < XmmReg1[56,8],srcCopy[56,8],XmmReg1[56,8]); + conditionalAssign(XmmReg1[64,8],srcCopy[64,8] < XmmReg1[64,8],srcCopy[64,8],XmmReg1[64,8]); + conditionalAssign(XmmReg1[72,8],srcCopy[72,8] < XmmReg1[72,8],srcCopy[72,8],XmmReg1[72,8]); + conditionalAssign(XmmReg1[80,8],srcCopy[80,8] < XmmReg1[80,8],srcCopy[80,8],XmmReg1[80,8]); + conditionalAssign(XmmReg1[88,8],srcCopy[88,8] < XmmReg1[88,8],srcCopy[88,8],XmmReg1[88,8]); + conditionalAssign(XmmReg1[96,8],srcCopy[96,8] < XmmReg1[96,8],srcCopy[96,8],XmmReg1[96,8]); + conditionalAssign(XmmReg1[104,8],srcCopy[104,8] < XmmReg1[104,8],srcCopy[104,8],XmmReg1[104,8]); + conditionalAssign(XmmReg1[112,8],srcCopy[112,8] < XmmReg1[112,8],srcCopy[112,8],XmmReg1[112,8]); + conditionalAssign(XmmReg1[120,8],srcCopy[120,8] < XmmReg1[120,8],srcCopy[120,8],XmmReg1[120,8]); +} + +#in 64-bit mode the default operand size is 64 bits +#note that gcc assembles pmovmskb eax, mm0 and pmovmskb rax, mm0 to 0f d7 c0 +:PMOVMSKB Reg32, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD7; mod = 3 & Reg32 & mmxreg2 & check_Reg32_dest +{ + local byte_mask:1 = 0:1; + byte_mask[0,1] = mmxreg2[7,1]; + byte_mask[1,1] = mmxreg2[15,1]; + byte_mask[2,1] = mmxreg2[23,1]; + byte_mask[3,1] = mmxreg2[31,1]; + byte_mask[4,1] = mmxreg2[39,1]; + byte_mask[5,1] = mmxreg2[47,1]; + byte_mask[6,1] = mmxreg2[55,1]; + byte_mask[7,1] = mmxreg2[63,1]; + Reg32 = zext(byte_mask); + build check_Reg32_dest; +} + +#in 64-bit mode the default operand size is 64 bits +#note that gcc assembles pmovmskb eax, xmm0 and pmovmskb rax, xmm0 to 66 0f d7 c0 +:PMOVMSKB Reg32, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD7; mod = 3 & Reg32 & XmmReg2 & check_Reg32_dest +{ + local byte_mask:2 = 0:2; + byte_mask[0,1] = XmmReg2[7,1]; + byte_mask[1,1] = XmmReg2[15,1]; + byte_mask[2,1] = XmmReg2[23,1]; + byte_mask[3,1] = XmmReg2[31,1]; + byte_mask[4,1] = XmmReg2[39,1]; + byte_mask[5,1] = XmmReg2[47,1]; + byte_mask[6,1] = XmmReg2[55,1]; + byte_mask[7,1] = XmmReg2[63,1]; + byte_mask[8,1] = XmmReg2[71,1]; + byte_mask[9,1] = XmmReg2[79,1]; + byte_mask[10,1] = XmmReg2[87,1]; + byte_mask[11,1] = XmmReg2[95,1]; + byte_mask[12,1] = XmmReg2[103,1]; + byte_mask[13,1] = XmmReg2[111,1]; + byte_mask[14,1] = XmmReg2[119,1]; + byte_mask[15,1] = XmmReg2[127,1]; + Reg32 = zext(byte_mask); + build check_Reg32_dest; +} + +define pcodeop pmulhrsw; +:PMULHRSW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x0B; mmxreg ... & m64 { mmxreg=pmulhrsw(mmxreg,m64); } +:PMULHRSW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x0B; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=pmulhrsw(mmxreg1,mmxreg2); } +:PMULHRSW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x0B; XmmReg ... & m128 { XmmReg=pmulhrsw(XmmReg,m128); } +:PMULHRSW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x0B; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pmulhrsw(XmmReg1,XmmReg2); } + +define pcodeop pmulhuw; +:PMULHUW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE4; mmxreg ... & m64 { mmxreg = pmulhuw(mmxreg, m64); } +:PMULHUW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE4; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = pmulhuw(mmxreg1, mmxreg2); } +:PMULHUW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE4; XmmReg ... & m128 { XmmReg = pmulhuw(XmmReg, m128); } +:PMULHUW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE4; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = pmulhuw(XmmReg1, XmmReg2); } + +macro pmulhw64(mmx1, mmx2) { + local tmp0:8 = sext(mmx1[ 0,16]) * sext(mmx2[ 0,16]); + mmx1[ 0,16] = tmp0[16,16]; + local tmp1:8 = sext(mmx1[16,16]) * sext(mmx2[16,16]); + mmx1[16,16] = tmp1[16,16]; + local tmp2:8 = sext(mmx1[32,16]) * sext(mmx2[32,16]); + mmx1[32,16] = tmp2[16,16]; + local tmp3:8 = sext(mmx1[48,16]) * sext(mmx2[48,16]); + mmx1[48,16] = tmp3[16,16]; +} +:PMULHW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE5; mmxreg ... & m64 { pmulhw64(mmxreg, m64); } +:PMULHW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE5; mmxmod = 3 & mmxreg1 & mmxreg2 { pmulhw64(mmxreg1, mmxreg2); } + +macro pmulhw128(xmm1, xmm2) { + local tmp0:8 = sext(xmm1[ 0,16]) * sext(xmm2[ 0,16]); + xmm1[ 0,16] = tmp0[16,16]; + local tmp1:8 = sext(xmm1[ 16,16]) * sext(xmm2[ 16,16]); + xmm1[ 16,16] = tmp1[16,16]; + local tmp2:8 = sext(xmm1[ 32,16]) * sext(xmm2[ 32,16]); + xmm1[ 32,16] = tmp2[16,16]; + local tmp3:8 = sext(xmm1[ 48,16]) * sext(xmm2[ 48,16]); + xmm1[ 48,16] = tmp3[16,16]; + local tmp4:8 = sext(xmm1[ 64,16]) * sext(xmm2[ 64,16]); + xmm1[ 64,16] = tmp4[16,16]; + local tmp5:8 = sext(xmm1[ 80,16]) * sext(xmm2[ 80,16]); + xmm1[ 80,16] = tmp5[16,16]; + local tmp6:8 = sext(xmm1[ 96,16]) * sext(xmm2[ 96,16]); + xmm1[ 96,16] = tmp6[16,16]; + local tmp7:8 = sext(xmm1[112,16]) * sext(xmm2[112,16]); + xmm1[112,16] = tmp7[16,16]; +} +:PMULHW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE5; XmmReg ... & m128 { pmulhw128(XmmReg, m128); } +:PMULHW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE5; xmmmod = 3 & XmmReg1 & XmmReg2 { pmulhw128(XmmReg1, XmmReg2); } + +:PMULLW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD5; mmxreg ... & m64 { + local m:8 = m64; + mmxreg[0,16] = mmxreg[0,16] * m[0,16]; + mmxreg[16,16] = mmxreg[16,16] * m[16,16]; + mmxreg[32,16] = mmxreg[32,16] * m[32,16]; + mmxreg[48,16] = mmxreg[48,16] * m[48,16]; +} + +:PMULLW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD5; mmxmod = 3 & mmxreg1 & mmxreg2 { + mmxreg1[0,16] = mmxreg1[0,16] * mmxreg2[0,16]; + mmxreg1[16,16] = mmxreg1[16,16] * mmxreg2[16,16]; + mmxreg1[32,16] = mmxreg1[32,16] * mmxreg2[32,16]; + mmxreg1[48,16] = mmxreg1[48,16] * mmxreg2[48,16]; +} + +:PMULLW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD5; XmmReg ... & m128 { + local m:16 = m128; + XmmReg[0,16] = XmmReg[0,16] * m[0,16]; + XmmReg[16,16] = XmmReg[16,16] * m[16,16]; + XmmReg[32,16] = XmmReg[32,16] * m[32,16]; + XmmReg[48,16] = XmmReg[48,16] * m[48,16]; + XmmReg[64,16] = XmmReg[64,16] * m[64,16]; + XmmReg[80,16] = XmmReg[80,16] * m[80,16]; + XmmReg[96,16] = XmmReg[96,16] * m[96,16]; + XmmReg[112,16] = XmmReg[112,16] * m[112,16]; +} + +:PMULLW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD5; xmmmod = 3 & XmmReg1 & XmmReg2 { + XmmReg1[0,16] = XmmReg1[0,16] * XmmReg2[0,16]; + XmmReg1[16,16] = XmmReg1[16,16] * XmmReg2[16,16]; + XmmReg1[32,16] = XmmReg1[32,16] * XmmReg2[32,16]; + XmmReg1[48,16] = XmmReg1[48,16] * XmmReg2[48,16]; + XmmReg1[64,16] = XmmReg1[64,16] * XmmReg2[64,16]; + XmmReg1[80,16] = XmmReg1[80,16] * XmmReg2[80,16]; + XmmReg1[96,16] = XmmReg1[96,16] * XmmReg2[96,16]; + XmmReg1[112,16] = XmmReg1[112,16] * XmmReg2[112,16]; + } + +:PMULUDQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF4; mmxreg ... & m64 +{ + local a:8 = zext(mmxreg[0,32]); + local b:8 = zext(m64[0,32]); + mmxreg = a * b; +} + +:PMULUDQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF4; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + local a:8 = zext(mmxreg1[0,32]); + local b:8 = zext(mmxreg2[0,32]); + mmxreg1 = a * b; +} + +:PMULUDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF4; XmmReg ... & m128 +{ + local a:8 = zext(XmmReg[0,32]); + local b:8 = zext(m128[0,32]); + XmmReg[0,64] = a * b; + local c:8 = zext(XmmReg[64,32]); + local d:8 = zext(m128[64,32]); + XmmReg[64,64] = c * d; +} + +:PMULUDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF4; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + local a:8 = zext(XmmReg1[0,32]); + local b:8 = zext(XmmReg2[0,32]); + XmmReg1[0,64] = a * b; + local c:8 = zext(XmmReg1[64,32]); + local d:8 = zext(XmmReg2[64,32]); + XmmReg1[64,64] = c * d; +} + +:POR mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEB; mmxreg ... & m64 { mmxreg = mmxreg | m64; } +:POR mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEB; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg1 | mmxreg2; } +:POR XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEB; XmmReg ... & m128 { XmmReg = XmmReg | m128; } +:POR XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEB; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg1 | XmmReg2; } + +define pcodeop psadbw; +:PSADBW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF6; mmxreg ... & m64 { mmxreg = psadbw(mmxreg, m64); } +:PSADBW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF6; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = psadbw(mmxreg1, mmxreg2); } +:PSADBW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF6; XmmReg ... & m128 { XmmReg = psadbw(XmmReg, m128); } +:PSADBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF6; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = psadbw(XmmReg1, XmmReg2); } + +# these byte and word shuffles need to be done also ????? +define pcodeop pshufb; +:PSHUFB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x00; mmxreg1 ... & mmxreg2_m64 { mmxreg1=pshufb(mmxreg1,mmxreg2_m64); } +:PSHUFB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x00; XmmReg1 ... & XmmReg2_m128 { XmmReg1=pshufb(XmmReg1,XmmReg2_m128); } + +# determine the total shift required by the bit fields in a shuffle opcode +Order0: order0 is imm8 [ order0 = ( imm8 & 0x3); ] { export *[const]:1 order0; } +Order1: order1 is imm8 [ order1 = ((imm8 >> 2) & 0x3); ] { export *[const]:1 order1; } +Order2: order2 is imm8 [ order2 = ((imm8 >> 4) & 0x3); ] { export *[const]:1 order2; } +Order3: order3 is imm8 [ order3 = ((imm8 >> 6) & 0x3); ] { export *[const]:1 order3; } + +macro shuffle_4(dest,ord,c0,c1,c2,c3){ + dest = zext(ord == 0) * c0 + zext(ord == 1) * c1 + zext(ord == 2) * c2 + zext(ord == 3) * c3; +} + +:PSHUFD XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x70; (XmmReg2_m128 & XmmReg1 ...); imm8 & Order0 & Order1 & Order2 & Order3 +{ + local c0 = XmmReg2_m128[0,32]; + local c1 = XmmReg2_m128[32,32]; + local c2 = XmmReg2_m128[64,32]; + local c3 = XmmReg2_m128[96,32]; + + shuffle_4(XmmReg1[0,32],Order0,c0,c1,c2,c3); + shuffle_4(XmmReg1[32,32],Order1,c0,c1,c2,c3); + shuffle_4(XmmReg1[64,32],Order2,c0,c1,c2,c3); + shuffle_4(XmmReg1[96,32],Order3,c0,c1,c2,c3); +} + +define pcodeop pshufhw; +:PSHUFHW XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x70; XmmReg2_m128 & XmmReg1 ...; imm8 { XmmReg1 = pshufhw(XmmReg1, XmmReg2_m128, imm8:8); } + +define pcodeop pshuflw; +:PSHUFLW XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x70; XmmReg2_m128 & XmmReg1 ...; imm8 { XmmReg1 = pshuflw(XmmReg1, XmmReg2_m128, imm8:8); } + +define pcodeop pshufw; +:PSHUFW mmxreg1, mmxreg2_m64, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x70; mmxreg2_m64 & mmxreg1 ...; imm8 { mmxreg1 = pshufw(mmxreg1, mmxreg2_m64, imm8:8); } + +define pcodeop psignb; +:PSIGNB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x08; mmxreg ... & m64 { mmxreg=psignb(mmxreg,m64); } +:PSIGNB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x08; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=psignb(mmxreg1,mmxreg2); } +:PSIGNB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x08; XmmReg ... & m128 { XmmReg=psignb(XmmReg,m128); } +:PSIGNB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x08; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=psignb(XmmReg1,XmmReg2); } + +define pcodeop psignw; +:PSIGNW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x09; mmxreg ... & m64 { mmxreg=psignw(mmxreg,m64); } +:PSIGNW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x09; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=psignw(mmxreg1,mmxreg2); } +:PSIGNW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x09; XmmReg ... & m128 { XmmReg=psignw(XmmReg,m128); } +:PSIGNW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x09; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=psignw(XmmReg1,XmmReg2); } + +define pcodeop psignd; +:PSIGND mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x0a; mmxreg ... & m64 { mmxreg=psignd(mmxreg,m64); } +:PSIGND mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x38; byte=0x0a; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1=psignd(mmxreg1,mmxreg2); } +:PSIGND XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x0a; XmmReg ... & m128 { XmmReg=psignd(XmmReg,m128); } +:PSIGND XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x0a; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=psignd(XmmReg1,XmmReg2); } + +#break into two 64-bit chunks so decompiler can follow constants +:PSLLDQ XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x73; xmmmod = 3 & reg_opcode=7 & XmmReg2; imm8 +{ + if (imm8:1 > 15:1) goto ; + local low64copy:8 = XmmReg2[0,64]; + XmmReg2[0,64] = XmmReg2[0,64] << (8:1 * imm8:1); + if (imm8:1 > 8:1) goto ; + XmmReg2[64,64] = (XmmReg2[64,64] << (8:1 * imm8:1)) | (low64copy >> (8:1 * (8 - imm8:1))); + goto ; + + XmmReg2[64,64] = low64copy << (8:1 * (imm8 - 8)); + goto ; + + XmmReg2[0,64] = 0:8; + XmmReg2[64,64] = 0:8; + +} + +macro psllw64(mmx, count) { + local tmp:8 = count; + mmx[ 0,16] = mmx[ 0,16] << tmp; + mmx[16,16] = mmx[16,16] << tmp; + mmx[32,16] = mmx[32,16] << tmp; + mmx[48,16] = mmx[48,16] << tmp; +} +:PSLLW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF1; mmxreg ... & m64 ... { psllw64(mmxreg, m64); } +:PSLLW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF1; mmxmod = 3 & mmxreg1 & mmxreg2 { psllw64(mmxreg1, mmxreg2); } +:PSLLW mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=6 & mmxreg2; imm8 { psllw64(mmxreg2, imm8:8); } + +:PSLLD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF2; mmxreg ... & m64 ... { + local m:8 = m64; + mmxreg[0,32] = mmxreg[0,32] << m[0,32]; + mmxreg[32,32] = mmxreg[32,32] << m[32,32]; +} + +:PSLLD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF2; mmxmod = 3 & mmxreg1 & mmxreg2 { + mmxreg1[0,32] = mmxreg1[0,32] << mmxreg2[0,32]; + mmxreg1[32,32] = mmxreg1[32,32] << mmxreg2[32,32]; +} + +:PSLLD mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=6 & mmxreg2; imm8 { + mmxreg2[0,32] = mmxreg2[0,32] << imm8; + mmxreg2[32,32] = mmxreg2[32,32] << imm8; +} + +:PSLLQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF3; mmxreg ... & m64 ... { mmxreg = mmxreg << m64; } +:PSLLQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF3; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg1 << mmxreg2; } +:PSLLQ mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x73; mod = 0b11 & reg_opcode=6 & mmxreg2; imm8 { mmxreg2 = mmxreg2 << imm8:8; } + +macro psllw128(xmm, count) { + local tmp:8 = count:8; + xmm[ 0,16] = xmm[ 0,16] << tmp; + xmm[ 16,16] = xmm[ 16,16] << tmp; + xmm[ 32,16] = xmm[ 32,16] << tmp; + xmm[ 48,16] = xmm[ 48,16] << tmp; + xmm[ 64,16] = xmm[ 64,16] << tmp; + xmm[ 80,16] = xmm[ 80,16] << tmp; + xmm[ 96,16] = xmm[ 96,16] << tmp; + xmm[112,16] = xmm[112,16] << tmp; +} +:PSLLW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF1; XmmReg ... & m128 ... { psllw128(XmmReg, m128); } +:PSLLW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF1; xmmmod = 3 & XmmReg1 & XmmReg2 { psllw128(XmmReg1, XmmReg2); } +:PSLLW XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=6 & XmmReg2; imm8 { local count:8 = imm8; psllw128(XmmReg2, count); } + +:PSLLD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF2; XmmReg ... & m128 ... { + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] << m[0,32]; + XmmReg[32,32] = XmmReg[32,32] << m[32,32]; + XmmReg[64,32] = XmmReg[64,32] << m[64,32]; + XmmReg[96,32] = XmmReg[96,32] << m[96,32]; +} + +:PSLLD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF2; xmmmod = 3 & XmmReg1 & XmmReg2 { + XmmReg1[0,32] = XmmReg1[0,32] << XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] << XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] << XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] << XmmReg2[96,32]; +} + +:PSLLD XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=6 & XmmReg2; imm8 { + XmmReg2[0,32] = XmmReg2[0,32] << imm8; + XmmReg2[32,32] = XmmReg2[32,32] << imm8; + XmmReg2[64,32] = XmmReg2[64,32] << imm8; + XmmReg2[96,32] = XmmReg2[96,32] << imm8; +} + +:PSLLQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF3; XmmReg ... & m128 ... { + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] << m[0,64]; + XmmReg[64,64] = XmmReg[64,64] << m[64,64]; +} + +:PSLLQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF3; xmmmod = 3 & XmmReg1 & XmmReg2 { + XmmReg1[0,64] = XmmReg1[0,64] << XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] << XmmReg2[64,64]; +} + +:PSLLQ XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x73; mod = 0b11 & reg_opcode=6 & XmmReg2; imm8 { + XmmReg2[0,64] = XmmReg2[0,64] << imm8; + XmmReg2[64,64] = XmmReg2[64,64] << imm8; +} + +macro psraw64(mmx, count) { + local tmp:8 = count; + mmx[ 0,16] = mmx[ 0,16] s>> tmp; + mmx[16,16] = mmx[16,16] s>> tmp; + mmx[32,16] = mmx[32,16] s>> tmp; + mmx[48,16] = mmx[48,16] s>> tmp; +} +:PSRAW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE1; mmxreg ... & m64 ... { psraw64(mmxreg, m64); } +:PSRAW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE1; mmxmod = 3 & mmxreg1 & mmxreg2 { psraw64(mmxreg1, mmxreg2); } +:PSRAW mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=4 & mmxreg2; imm8 { psraw64(mmxreg2, imm8:8); } + +:PSRAD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE2; mmxreg ... & m64 +{ +# a count greater than 31 just clears all the bits + mmxreg[0,32] = mmxreg[0,32] s>> m64; + mmxreg[32,32] = mmxreg[32,32] s>> m64; +} + +:PSRAD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE2; mmxmod = 3 & mmxreg1 & mmxreg2 +{ +# a count greater than 31 just clears all the bits + mmxreg1[0,32] = mmxreg1[0,32] s>> mmxreg2; + mmxreg1[32,32] = mmxreg1[32,32] s>> mmxreg2; +} + +:PSRAD mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=4 & mmxreg2; imm8 +{ +# a count greater than 31 just clears all the bits + mmxreg2[0,32] = mmxreg2[0,32] s>> imm8; + mmxreg2[32,32] = mmxreg2[32,32] s>> imm8; +} + +macro psraw128(xmm, count) { + local tmp:8 = count:8; + xmm[ 0,16] = xmm[ 0,16] s>> tmp; + xmm[ 16,16] = xmm[ 16,16] s>> tmp; + xmm[ 32,16] = xmm[ 32,16] s>> tmp; + xmm[ 48,16] = xmm[ 48,16] s>> tmp; + xmm[ 64,16] = xmm[ 64,16] s>> tmp; + xmm[ 80,16] = xmm[ 80,16] s>> tmp; + xmm[ 96,16] = xmm[ 96,16] s>> tmp; + xmm[112,16] = xmm[112,16] s>> tmp; +} +:PSRAW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE1; XmmReg ... & m128 ... { psraw128(XmmReg, m128); } +:PSRAW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE1; xmmmod = 3 & XmmReg1 & XmmReg2 { psraw128(XmmReg1, XmmReg2); } +:PSRAW XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=4 & XmmReg2; imm8 { local count:8 = imm8; psraw128(XmmReg2, count); } + +:PSRAD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE2; m128 & XmmReg ... +{ +# a count greater than 31 just clears all the bits + XmmReg[0,32] = XmmReg[0,32] s>> m128; + XmmReg[32,32] = XmmReg[32,32] s>> m128; + XmmReg[64,32] = XmmReg[64,32] s>> m128; + XmmReg[96,32] = XmmReg[96,32] s>> m128; +} + +:PSRAD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE2; xmmmod = 3 & XmmReg1 & XmmReg2 +{ +# a count greater than 31 just clears all the bits + XmmReg1[0,32] = XmmReg1[0,32] s>> XmmReg2; + XmmReg1[32,32] = XmmReg1[32,32] s>> XmmReg2; + XmmReg1[64,32] = XmmReg1[64,32] s>> XmmReg2; + XmmReg1[96,32] = XmmReg1[96,32] s>> XmmReg2; +} + +:PSRAD XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=4 & XmmReg2; imm8 +{ +# a count greater than 31 just clears all the bits + XmmReg2[0,32] = XmmReg2[0,32] s>> imm8; + XmmReg2[32,32] = XmmReg2[32,32] s>> imm8; + XmmReg2[64,32] = XmmReg2[64,32] s>> imm8; + XmmReg2[96,32] = XmmReg2[96,32] s>> imm8; +} + +:PSRLDQ XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x73; xmmmod=3 & reg_opcode=3 & XmmReg2; imm8 +{ +# a count greater than 15 just clears all the bits + XmmReg2 = XmmReg2 >> (imm8 * 8); +} + +:PSRLW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD1; mmxreg ... & m64 ... +{ + mmxreg[0,16] = mmxreg[0,16] >> m64; + mmxreg[16,16] = mmxreg[16,16] >> m64; + mmxreg[32,16] = mmxreg[32,16] >> m64; + mmxreg[48,16] = mmxreg[48,16] >> m64; +} + +:PSRLW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD1; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = mmxreg1[0,16] >> mmxreg2; + mmxreg1[16,16] = mmxreg1[16,16] >> mmxreg2; + mmxreg1[32,16] = mmxreg1[32,16] >> mmxreg2; + mmxreg1[48,16] = mmxreg1[48,16] >> mmxreg2; +} + +:PSRLW mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=2 & mmxreg2; imm8 +{ + mmxreg2[0,16] = mmxreg2[0,16] >> imm8; + mmxreg2[16,16] = mmxreg2[16,16] >> imm8; + mmxreg2[32,16] = mmxreg2[32,16] >> imm8; + mmxreg2[48,16] = mmxreg2[48,16] >> imm8; +} + +:PSRLD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD2; mmxreg ... & m64 ... +{ + mmxreg[0,32] = mmxreg[0,32] >> m64; + mmxreg[32,32] = mmxreg[32,32] >> m64; +} + +:PSRLD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD2; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = mmxreg1[0,32] >> mmxreg2; + mmxreg1[32,32] = mmxreg1[32,32] >> mmxreg2; +} + +:PSRLD mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=2 & mmxreg2; imm8 +{ + mmxreg2[0,32] = mmxreg2[0,32] >> imm8; + mmxreg2[32,32] = mmxreg2[32,32] >> imm8; +} + +:PSRLQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD3; mmxreg ... & m64 ... +{ + mmxreg = mmxreg >> m64; + } + +:PSRLQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD3; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1 = mmxreg1 >> mmxreg2; +} + +:PSRLQ mmxreg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x73; mod = 0b11 & reg_opcode=2 & mmxreg2; imm8 +{ + mmxreg2 = mmxreg2 >> imm8; +} + +:PSRLW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD1; XmmReg ... & m128 ... +{ + XmmReg[0,16] = XmmReg[0,16] >> m128[0,64]; + XmmReg[16,16] = XmmReg[16,16] >> m128[0,64]; + XmmReg[32,16] = XmmReg[32,16] >> m128[0,64]; + XmmReg[48,16] = XmmReg[48,16] >> m128[0,64]; + XmmReg[64,16] = XmmReg[64,16] >> m128[0,64]; + XmmReg[80,16] = XmmReg[80,16] >> m128[0,64]; + XmmReg[96,16] = XmmReg[96,16] >> m128[0,64]; + XmmReg[112,16] = XmmReg[112,16] >> m128[0,64]; +} + +:PSRLW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD1; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + #save this off in case XmmReg1 and XmmReg2 are the same register + local count:8 = XmmReg2[0,64]; + + XmmReg1[0,16] = XmmReg1[0,16] >> count; + XmmReg1[16,16] = XmmReg1[16,16] >> count; + XmmReg1[32,16] = XmmReg1[32,16] >> count; + XmmReg1[48,16] = XmmReg1[48,16] >> count; + XmmReg1[64,16] = XmmReg1[64,16] >> count; + XmmReg1[80,16] = XmmReg1[80,16] >> count; + XmmReg1[96,16] = XmmReg1[96,16] >> count; + XmmReg1[112,16] = XmmReg1[112,16] >> count; +} + +:PSRLW XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x71; mod = 0b11 & reg_opcode=2 & XmmReg2; imm8 +{ + XmmReg2[0,16] = XmmReg2[0,16] >> imm8; + XmmReg2[16,16] = XmmReg2[16,16] >> imm8; + XmmReg2[32,16] = XmmReg2[32,16] >> imm8; + XmmReg2[48,16] = XmmReg2[48,16] >> imm8; + XmmReg2[64,16] = XmmReg2[64,16] >> imm8; + XmmReg2[80,16] = XmmReg2[80,16] >> imm8; + XmmReg2[96,16] = XmmReg2[96,16] >> imm8; + XmmReg2[112,16] = XmmReg2[112,16] >> imm8; +} + +:PSRLD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD2; XmmReg ... & m128 ... +{ + XmmReg[0,32] = XmmReg[0,32] >> m128[0,64]; + XmmReg[32,32] = XmmReg[32,32] >> m128[0,64]; + XmmReg[64,32] = XmmReg[64,32] >> m128[0,64]; + XmmReg[96,32] = XmmReg[96,32] >> m128[0,64]; +} + +:PSRLD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD2; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + #save this off in case XmmReg1 and XmmReg2 are the same register + local count = XmmReg2[0,64]; + + XmmReg1[0,32] = XmmReg1[0,32] >> count; + XmmReg1[32,32] = XmmReg1[32,32] >> count; + XmmReg1[64,32] = XmmReg1[64,32] >> count; + XmmReg1[96,32] = XmmReg1[96,32] >> count; +} + +:PSRLD XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x72; mod = 0b11 & reg_opcode=2 & XmmReg2; imm8 +{ + XmmReg2[0,32] = XmmReg2[0,32] >> imm8; + XmmReg2[32,32] = XmmReg2[32,32] >> imm8; + XmmReg2[64,32] = XmmReg2[64,32] >> imm8; + XmmReg2[96,32] = XmmReg2[96,32] >> imm8; +} + +:PSRLQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD3; XmmReg ... & m128 ... +{ + XmmReg[0,64] = XmmReg[0,64] >> m128[0,64]; + XmmReg[64,64] = XmmReg[64,64] >> m128[0,64]; +} + +:PSRLQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD3; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + #save this off in case XmmReg1 and XmmReg2 are the same register + local count = XmmReg2[0,64]; + + XmmReg1[0,64] = XmmReg1[0,64] >> count; + XmmReg1[64,64] = XmmReg1[64,64] >> count; +} + +:PSRLQ XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x73; mod = 0b11 & reg_opcode=2 & XmmReg2; imm8 +{ + XmmReg2[0,64] = XmmReg2[0,64] >> imm8; + XmmReg2[64,64] = XmmReg2[64,64] >> imm8; +} + +:PSUBB mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF8; mmxreg ... & m64 ... +{ + local m:8 = m64; + mmxreg[0,8] = mmxreg[0,8] - m[0,8]; + mmxreg[8,8] = mmxreg[8,8] - m[8,8]; + mmxreg[16,8] = mmxreg[16,8] - m[16,8]; + mmxreg[24,8] = mmxreg[24,8] - m[24,8]; + mmxreg[32,8] = mmxreg[32,8] - m[32,8]; + mmxreg[40,8] = mmxreg[40,8] - m[40,8]; + mmxreg[48,8] = mmxreg[48,8] - m[48,8]; + mmxreg[56,8] = mmxreg[56,8] - m[56,8]; +} + +:PSUBB mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF8; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = mmxreg1[0,8] - mmxreg2[0,8]; + mmxreg1[16,8] = mmxreg1[16,8] - mmxreg2[16,8]; + mmxreg1[24,8] = mmxreg1[24,8] - mmxreg2[24,8]; + mmxreg1[32,8] = mmxreg1[32,8] - mmxreg2[32,8]; + mmxreg1[40,8] = mmxreg1[40,8] - mmxreg2[40,8]; + mmxreg1[48,8] = mmxreg1[48,8] - mmxreg2[48,8]; + mmxreg1[56,8] = mmxreg1[56,8] - mmxreg2[56,8]; +} + +:PSUBW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF9; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = mmxreg[0,16] - m[0,16]; + mmxreg[16,16] = mmxreg[16,16] - m[16,16]; + mmxreg[32,16] = mmxreg[32,16] - m[32,16]; + mmxreg[48,16] = mmxreg[48,16] - m[48,16]; +} + +:PSUBW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xF9; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = mmxreg1[0,16] - mmxreg2[0,16]; + mmxreg1[16,16] = mmxreg1[16,16] - mmxreg2[16,16]; + mmxreg1[32,16] = mmxreg1[32,16] - mmxreg2[32,16]; + mmxreg1[48,16] = mmxreg1[48,16] - mmxreg2[48,16]; +} + +:PSUBD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFA; mmxreg ... & m64 ... +{ + local m:8 = m64; + mmxreg[0,32] = mmxreg[0,32] - m[0,32]; + mmxreg[32,32] = mmxreg[32,32] - m[32,32]; +} + +:PSUBD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFA; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = mmxreg1[0,32] - mmxreg2[0,32]; + mmxreg1[32,32] = mmxreg1[32,32] - mmxreg2[32,32]; +} + +:PSUBQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFB; mmxreg ... & m64 ... { mmxreg = mmxreg - m64; } +:PSUBQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xFB; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg1 - mmxreg2; } +:PSUBQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFB; XmmReg ... & m128 ... +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] - m[0,64]; + XmmReg[64,64] = XmmReg[64,64] - m[64,64]; +} + +:PSUBQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFB; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] - XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] - XmmReg2[64,64]; +} + +:PSUBB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF8; XmmReg ... & m128 ... +{ + local m:16 = m128; + XmmReg[0,8] = XmmReg[0,8] - m[0,8]; + XmmReg[8,8] = XmmReg[8,8] - m[8,8]; + XmmReg[16,8] = XmmReg[16,8] - m[16,8]; + XmmReg[24,8] = XmmReg[24,8] - m[24,8]; + XmmReg[32,8] = XmmReg[32,8] - m[32,8]; + XmmReg[40,8] = XmmReg[40,8] - m[40,8]; + XmmReg[48,8] = XmmReg[48,8] - m[48,8]; + XmmReg[56,8] = XmmReg[56,8] - m[56,8]; + XmmReg[64,8] = XmmReg[64,8] - m[64,8]; + XmmReg[72,8] = XmmReg[72,8] - m[72,8]; + XmmReg[80,8] = XmmReg[80,8] - m[80,8]; + XmmReg[88,8] = XmmReg[88,8] - m[88,8]; + XmmReg[96,8] = XmmReg[96,8] - m[96,8]; + XmmReg[104,8] = XmmReg[104,8] - m[104,8]; + XmmReg[112,8] = XmmReg[112,8] - m[112,8]; + XmmReg[120,8] = XmmReg[120,8] - m[120,8]; +} + +:PSUBB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF8; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = XmmReg1[0,8] - XmmReg2[0,8]; + XmmReg1[8,8] = XmmReg1[8,8] - XmmReg2[8,8]; + XmmReg1[16,8] = XmmReg1[16,8] - XmmReg2[16,8]; + XmmReg1[24,8] = XmmReg1[24,8] - XmmReg2[24,8]; + XmmReg1[32,8] = XmmReg1[32,8] - XmmReg2[32,8]; + XmmReg1[40,8] = XmmReg1[40,8] - XmmReg2[40,8]; + XmmReg1[48,8] = XmmReg1[48,8] - XmmReg2[48,8]; + XmmReg1[56,8] = XmmReg1[56,8] - XmmReg2[56,8]; + XmmReg1[64,8] = XmmReg1[64,8] - XmmReg2[64,8]; + XmmReg1[72,8] = XmmReg1[72,8] - XmmReg2[72,8]; + XmmReg1[80,8] = XmmReg1[80,8] - XmmReg2[80,8]; + XmmReg1[88,8] = XmmReg1[88,8] - XmmReg2[88,8]; + XmmReg1[96,8] = XmmReg1[96,8] - XmmReg2[96,8]; + XmmReg1[104,8] = XmmReg1[104,8] - XmmReg2[104,8]; + XmmReg1[112,8] = XmmReg1[112,8] - XmmReg2[112,8]; + XmmReg1[120,8] = XmmReg1[120,8] - XmmReg2[120,8]; +} + +:PSUBW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF9; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = XmmReg[0,16] - m[0,16]; + XmmReg[16,16] = XmmReg[16,16] - m[16,16]; + XmmReg[32,16] = XmmReg[32,16] - m[32,16]; + XmmReg[48,16] = XmmReg[48,16] - m[48,16]; + XmmReg[64,16] = XmmReg[64,16] - m[64,16]; + XmmReg[80,16] = XmmReg[80,16] - m[80,16]; + XmmReg[96,16] = XmmReg[96,16] - m[96,16]; + XmmReg[112,16] = XmmReg[112,16] - m[112,16]; +} + +:PSUBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xF9; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = XmmReg1[0,16] - XmmReg2[0,16]; + XmmReg1[16,16] = XmmReg1[16,16] - XmmReg2[16,16]; + XmmReg1[32,16] = XmmReg1[32,16] - XmmReg2[32,16]; + XmmReg1[48,16] = XmmReg1[48,16] - XmmReg2[48,16]; + XmmReg1[64,16] = XmmReg1[64,16] - XmmReg2[64,16]; + XmmReg1[80,16] = XmmReg1[80,16] - XmmReg2[80,16]; + XmmReg1[96,16] = XmmReg1[96,16] - XmmReg2[96,16]; + XmmReg1[112,16] = XmmReg1[112,16] - XmmReg2[112,16]; +} + +:PSUBD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFA; XmmReg ... & m128 ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] - m[0,32]; + XmmReg[32,32] = XmmReg[32,32] - m[32,32]; + XmmReg[64,32] = XmmReg[64,32] - m[64,32]; + XmmReg[96,32] = XmmReg[96,32] - m[96,32]; +} + +:PSUBD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xFA; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] - XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] - XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] - XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] - XmmReg2[96,32]; +} + +define pcodeop psubsb; +:PSUBSB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE8; mmxreg1 ... & mmxreg2_m64 ... { mmxreg1 = psubsb(mmxreg1, mmxreg2_m64); } + +define pcodeop psubsw; +:PSUBSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xE9; mmxreg1 ... & mmxreg2_m64 ... { mmxreg1 = psubsw(mmxreg1, mmxreg2_m64); } + +:PSUBSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE8; XmmReg1 ... & XmmReg2_m128 ... { XmmReg1 = psubsb(XmmReg1, XmmReg2_m128); } + +:PSUBSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xE9; XmmReg1 ... & XmmReg2_m128 ... { XmmReg1 = psubsw(XmmReg1, XmmReg2_m128); } + +define pcodeop psubusb; +:PSUBUSB mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD8; mmxreg1 ... & mmxreg2_m64 ... { mmxreg1 = psubusb(mmxreg1, mmxreg2_m64); } + +define pcodeop psubusw; +:PSUBUSW mmxreg1, mmxreg2_m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xD9; mmxreg1 ... & mmxreg2_m64 ... { mmxreg1 = psubusw(mmxreg1, mmxreg2_m64); } + +:PSUBUSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD8; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = psubusb(XmmReg1, XmmReg2_m128); } + +:PSUBUSW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xD9; XmmReg1 ... & XmmReg2_m128 { XmmReg1 = psubusw(XmmReg1, XmmReg2_m128); } + +:PUNPCKHBW mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x68; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,8] = mmxreg[32,8]; + mmxreg[8,8] = m[32,8]; + mmxreg[16,8] = mmxreg[40,8]; + mmxreg[24,8] = m[40,8]; + mmxreg[32,8] = mmxreg[48,8]; + mmxreg[40,8] = m[48,8]; + mmxreg[48,8] = mmxreg[56,8]; + mmxreg[56,8] = m[56,8]; +} + +:PUNPCKHBW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x68; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,8] = mmxreg1[32,8]; + mmxreg1[8,8] = mmxreg2[32,8]; + mmxreg1[16,8] = mmxreg1[40,8]; + mmxreg1[24,8] = mmxreg2[40,8]; + mmxreg1[32,8] = mmxreg1[48,8]; + mmxreg1[40,8] = mmxreg2[48,8]; + mmxreg1[48,8] = mmxreg1[56,8]; + mmxreg1[56,8] = mmxreg2[56,8]; +} + +:PUNPCKHWD mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x69; mmxreg ... & m64 +{ + local m:8 = m64; + mmxreg[0,16] = mmxreg[32,16]; + mmxreg[16,16] = m[32,16]; + mmxreg[32,16] = mmxreg[48,16]; + mmxreg[48,16] = m[48,16]; +} + +:PUNPCKHWD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x69; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,16] = mmxreg1[32,16]; + mmxreg1[16,16] = mmxreg2[32,16]; + mmxreg1[32,16] = mmxreg1[48,16]; + mmxreg1[48,16] = mmxreg2[48,16]; +} + +:PUNPCKHDQ mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6A; mmxreg ... & m64 +{ + mmxreg[0,32] = mmxreg[32,32]; + mmxreg[32,32] = m64[32,32]; +} + +:PUNPCKHDQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x6A; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[0,32] = mmxreg1[32,32]; + mmxreg1[32,32] = mmxreg2[32,32]; +} + +:PUNPCKHBW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x68; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,8] = XmmReg[64,8]; + XmmReg[8,8] = m[64,8]; + XmmReg[16,8] = XmmReg[72,8]; + XmmReg[24,8] = m[72,8]; + XmmReg[32,8] = XmmReg[80,8]; + XmmReg[40,8] = m[80,8]; + XmmReg[48,8] = XmmReg[88,8]; + XmmReg[56,8] = m[88,8]; + XmmReg[64,8] = XmmReg[96,8]; + XmmReg[72,8] = m[96,8]; + XmmReg[80,8] = XmmReg[104,8]; + XmmReg[88,8] = m[104,8]; + XmmReg[96,8] = XmmReg[112,8]; + XmmReg[104,8] = m[112,8]; + XmmReg[112,8] = XmmReg[120,8]; + XmmReg[120,8] = m[120,8]; +} + +# full set of XMM byte registers +:PUNPCKHBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x68; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,8] = XmmReg1[64,8]; + XmmReg1[8,8] = XmmReg2[64,8]; + XmmReg1[16,8] = XmmReg1[72,8]; + XmmReg1[24,8] = XmmReg2[72,8]; + XmmReg1[32,8] = XmmReg1[80,8]; + XmmReg1[40,8] = XmmReg2[80,8]; + XmmReg1[48,8] = XmmReg1[88,8]; + XmmReg1[56,8] = XmmReg2[88,8]; + XmmReg1[64,8] = XmmReg1[96,8]; + XmmReg1[72,8] = XmmReg2[96,8]; + XmmReg1[80,8] = XmmReg1[104,8]; + XmmReg1[88,8] = XmmReg2[104,8]; + XmmReg1[96,8] = XmmReg1[112,8]; + XmmReg1[104,8] = XmmReg2[112,8]; + XmmReg1[112,8] = XmmReg1[120,8]; + XmmReg1[120,8] = XmmReg2[120,8]; +} + +:PUNPCKHWD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x69; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,16] = XmmReg[64,16]; + XmmReg[16,16] = m[64,16]; + XmmReg[32,16] = XmmReg[80,16]; + XmmReg[48,16] = m[80,16]; + XmmReg[64,16] = XmmReg[96,16]; + XmmReg[80,16] = m[96,16]; + XmmReg[96,16] = XmmReg[112,16]; + XmmReg[112,16] = m[112,16]; +} + +:PUNPCKHWD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x69; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,16] = XmmReg1[64,16]; + XmmReg1[16,16] = XmmReg2[64,16]; + XmmReg1[32,16] = XmmReg1[80,16]; + XmmReg1[48,16] = XmmReg2[80,16]; + XmmReg1[64,16] = XmmReg1[96,16]; + XmmReg1[80,16] = XmmReg2[96,16]; + XmmReg1[96,16] = XmmReg1[112,16]; + XmmReg1[112,16] = XmmReg2[112,16]; +} + +:PUNPCKHDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6A; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[64,32]; + XmmReg[32,32] = m[64,32]; + XmmReg[64,32] = XmmReg[96,32]; + XmmReg[96,32] = m[96,32]; +} + +:PUNPCKHDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6A; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[64,32]; + XmmReg1[32,32] = XmmReg2[64,32]; + XmmReg1[64,32] = XmmReg1[96,32]; + XmmReg1[96,32] = XmmReg2[96,32]; +} + +:PUNPCKHQDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6D; m128 & XmmReg ... +{ + XmmReg[0,64] = XmmReg[64,64]; + XmmReg[64,64] = m128[64,64]; +} + +:PUNPCKHQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6D; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[64,64]; + XmmReg1[64,64] = XmmReg2[64,64]; +} + +:PUNPCKLBW mmxreg, m32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x60; mmxreg ... & m32 +{ + local m:4 = m32; + mmxreg[56,8] = m[24,8]; + mmxreg[48,8] = mmxreg[24,8]; + mmxreg[40,8] = m[16,8]; + mmxreg[32,8] = mmxreg[16,8]; + mmxreg[24,8] = m[8,8]; + mmxreg[16,8] = mmxreg[8,8]; + mmxreg[8,8] = m[0,8]; +# mmxreg[0,8] = mmxreg[0,8]; superfluous +} + +:PUNPCKLBW mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x60; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[56,8] = mmxreg2[24,8]; + mmxreg1[48,8] = mmxreg1[24,8]; + mmxreg1[40,8] = mmxreg2[16,8]; + mmxreg1[32,8] = mmxreg1[16,8]; + mmxreg1[24,8] = mmxreg2[8,8]; + mmxreg1[16,8] = mmxreg1[8,8]; + mmxreg1[8,8] = mmxreg2[0,8]; +# mmxreg1[0,8] = mmxreg1[0,8]; superfluous +} + +:PUNPCKLWD mmxreg, m32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x61; mmxreg ... & m32 +{ + local m:4 = m32; + mmxreg[48,16] = m[16,16]; + mmxreg[32,16] = mmxreg[16,16]; + mmxreg[16,16] = m[0,16]; +# mmxreg[0,16] = mmxreg[0,16]; superfluous +} + +:PUNPCKLWD mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x61; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[48,16] = mmxreg2[16,16]; + mmxreg1[32,16] = mmxreg1[16,16]; + mmxreg1[16,16] = mmxreg2[0,16]; +# mmxreg1[0,16] = mmxreg1[0,16]; superfluous +} + +:PUNPCKLDQ mmxreg, m32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x62; mmxreg ... & m32 +{ + mmxreg[32,32] = m32; +# mmxreg[0,32] = mmxreg[0,32]; superfluous +} + +:PUNPCKLDQ mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x62; mmxmod = 3 & mmxreg1 & mmxreg2 +{ + mmxreg1[32,32] = mmxreg2[0,32]; +# mmxreg1[0,32] = mmxreg1[0,32]; superfluous +} + +:PUNPCKLBW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x60; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[120,8] = m[56,8]; + XmmReg[112,8] = XmmReg[56,8]; + XmmReg[104,8] = m[48,8]; + XmmReg[96,8] = XmmReg[48,8]; + XmmReg[88,8] = m[40,8]; + XmmReg[80,8] = XmmReg[40,8]; + XmmReg[72,8] = m[32,8]; + XmmReg[64,8] = XmmReg[32,8]; + XmmReg[56,8] = m[24,8]; + XmmReg[48,8] = XmmReg[24,8]; + XmmReg[40,8] = m[16,8]; + XmmReg[32,8] = XmmReg[16,8]; + XmmReg[24,8] = m[8,8]; + XmmReg[16,8] = XmmReg[8,8]; + XmmReg[8,8] = m[0,8]; +# XmmReg[0,8] = XmmReg[0,8]; superfluous +} + +:PUNPCKLBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x60; xmmmod = 3 & +XmmReg1 & XmmReg2 +{ + XmmReg1[120,8] = XmmReg2[56,8]; + XmmReg1[112,8] = XmmReg1[56,8]; + XmmReg1[104,8] = XmmReg2[48,8]; + XmmReg1[96,8] = XmmReg1[48,8]; + XmmReg1[88,8] = XmmReg2[40,8]; + XmmReg1[80,8] = XmmReg1[40,8]; + XmmReg1[72,8] = XmmReg2[32,8]; + XmmReg1[64,8] = XmmReg1[32,8]; + XmmReg1[56,8] = XmmReg2[24,8]; + XmmReg1[48,8] = XmmReg1[24,8]; + XmmReg1[40,8] = XmmReg2[16,8]; + XmmReg1[32,8] = XmmReg1[16,8]; + XmmReg1[24,8] = XmmReg2[8,8]; + XmmReg1[16,8] = XmmReg1[8,8]; + XmmReg1[8,8] = XmmReg2[0,8]; +# XmmReg1[0,8] = XmmReg1[0,8]; superfluous +} + +:PUNPCKLWD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x61; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[112,16] = m[48,16]; + XmmReg[96,16] = XmmReg[48,16]; + XmmReg[80,16] = m[32,16]; + XmmReg[64,16] = XmmReg[32,16]; + XmmReg[48,16] = m[16,16]; + XmmReg[32,16] = XmmReg[16,16]; + XmmReg[16,16] = m[0,16]; +# XmmReg[0,16] = XmmReg[0,16]; superfluous +} + +:PUNPCKLWD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x61; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[112,16] = XmmReg2[48,16]; + XmmReg1[96,16] = XmmReg1[48,16]; + XmmReg1[80,16] = XmmReg2[32,16]; + XmmReg1[64,16] = XmmReg1[32,16]; + XmmReg1[48,16] = XmmReg2[16,16]; + XmmReg1[32,16] = XmmReg1[16,16]; + XmmReg1[16,16] = XmmReg2[0,16]; +# XmmReg1[0,16] = XmmReg1[0,16]; superfluous +} + +:PUNPCKLDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x62; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[96,32] = m[32,32]; + XmmReg[64,32] = XmmReg[32,32]; + XmmReg[32,32] = m[0,32]; +# XmmReg[0,32] = XmmReg[0,32]; superfluous +} + +:PUNPCKLDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x62; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[96,32] = XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[32,32]; + XmmReg1[32,32] = XmmReg2[0,32]; +# XmmReg1[0,32] = XmmReg1[0,32]; superfluous +} + +define pcodeop punpcklqdq; +:PUNPCKLQDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6C; m128 & XmmReg ... +{ + XmmReg[64,64] = m128[0,64]; +# XmmReg[0,64] = XmmReg[0,64]; superfluous +} + +:PUNPCKLQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6C; xmmmod = 3 & XmmReg1 & XmmReg2 +{ + XmmReg1[64,64] = XmmReg2[0,64]; +# XmmReg1[0,64] = XmmReg1[0,64]; superfluous +} + +:PXOR mmxreg, m64 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEF; mmxreg ... & m64 { mmxreg = mmxreg ^ m64; } +:PXOR mmxreg1, mmxreg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xEF; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = mmxreg1 ^ mmxreg2; } +:PXOR XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEF; XmmReg ... & m128 { XmmReg = XmmReg ^ m128; } +:PXOR XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xEF; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = XmmReg1 ^ XmmReg2; } + +define pcodeop rcpps; +:RCPPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x53; XmmReg ... & m128 { XmmReg = rcpps(XmmReg, m128); } +:RCPPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x53; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = rcpps(XmmReg1, XmmReg2); } + +define pcodeop rcpss; +:RCPSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x53; XmmReg ... & m32 { XmmReg = rcpss(XmmReg, m32); } +:RCPSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x53; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = rcpss(XmmReg1, XmmReg2); } + +define pcodeop rsqrtps; +:RSQRTPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x52; XmmReg ... & m128 { XmmReg = rsqrtps(XmmReg, m128); } +:RSQRTPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x52; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1 = rsqrtps(XmmReg1, XmmReg2); } + +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); } + +: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]; + local srcHigh:8 = XmmReg2_m128[64,64]; + local destLow:8 = XmmReg1[0,64]; + local destHigh:8 = XmmReg1[64,64]; + local control:1 = (imm8 & 0x1)== 0:1; + conditionalAssign(XmmReg1[0,64],control,destLow,destHigh); + control = (imm8 & 0x2) == 0:1; + conditionalAssign(XmmReg1[64,64],control,srcLow,srcHigh); +} + +:SHUFPS XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC6; (XmmReg2_m128 & XmmReg1 ...); imm8 & Order0 & Order1 & Order2 & Order3 +{ + local xmmreg2_m128_c0 = XmmReg2_m128[0,32]; + local xmmreg2_m128_c1 = XmmReg2_m128[32,32]; + local xmmreg2_m128_c2 = XmmReg2_m128[64,32]; + local xmmreg2_m128_c3 = XmmReg2_m128[96,32]; + + local xmm_c0 = XmmReg1[0,32]; + local xmm_c1 = XmmReg1[32,32]; + local xmm_c2 = XmmReg1[64,32]; + local xmm_c3 = XmmReg1[96,32]; + + shuffle_4(XmmReg1[0,32],Order0,xmm_c0,xmm_c1,xmm_c2,xmm_c3); + shuffle_4(XmmReg1[32,32],Order1,xmm_c0,xmm_c1,xmm_c2,xmm_c3); + shuffle_4(XmmReg1[64,32],Order2,xmmreg2_m128_c0,xmmreg2_m128_c1,xmmreg2_m128_c2,xmmreg2_m128_c3); + shuffle_4(XmmReg1[96,32],Order3,xmmreg2_m128_c0,xmmreg2_m128_c1,xmmreg2_m128_c2,xmmreg2_m128_c3); +} + +define pcodeop sqrtpd; +:SQRTPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x51; XmmReg ... & m128 { XmmReg = sqrtpd(XmmReg, m128); } +:SQRTPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x51; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = sqrtpd(XmmReg1, XmmReg2); } + +define pcodeop sqrtps; +:SQRTPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x51; XmmReg ... & m128 { XmmReg = sqrtps(XmmReg, m128); } +:SQRTPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x51; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = sqrtps(XmmReg1, XmmReg2); } + +:SQRTSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x51; XmmReg ... & m64 { XmmReg[0,64] = sqrt(m64); } +:SQRTSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x51; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[0,64] = sqrt(XmmReg2[0,64]); } + +:SQRTSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x51; XmmReg ... & m32 { XmmReg[0,32] = sqrt(m32); } +:SQRTSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x51; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[0,32] = sqrt(XmmReg2[0,32]); } + +:SUBPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5C;XmmReg ... & m128 +{ + local m:16 = m128; + XmmReg[0,64] = XmmReg[0,64] f- m[0,64]; + XmmReg[64,64] = XmmReg[64,64] f- m[64,64]; +} + +:SUBPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x5C; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[0,64] f- XmmReg2[0,64]; + XmmReg1[64,64] = XmmReg1[64,64] f- XmmReg2[64,64]; +} + +:SUBPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5C; XmmReg ... & m128 +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[0,32] f- m[0,32]; + XmmReg[32,32] = XmmReg[32,32] f- m[32,32]; + XmmReg[64,32] = XmmReg[64,32] f- m[64,32]; + XmmReg[96,32] = XmmReg[96,32] f- m[96,32]; +} + +:SUBPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x5C; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[0,32] f- XmmReg2[0,32]; + XmmReg1[32,32] = XmmReg1[32,32] f- XmmReg2[32,32]; + XmmReg1[64,32] = XmmReg1[64,32] f- XmmReg2[64,32]; + XmmReg1[96,32] = XmmReg1[96,32] f- XmmReg2[96,32]; +} + +:SUBSD XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5C; XmmReg ... & m64 { XmmReg[0,64] = XmmReg[0,64] f- m64; } +:SUBSD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x5C; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[0,64] = XmmReg1[0,64] f- XmmReg2[0,64]; } + +:SUBSS XmmReg, m32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5C; XmmReg ...& m32 { XmmReg[0,32] = XmmReg[0,32] f- m32; } +:SUBSS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x5C; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1[0,32] = XmmReg1[0,32] f- XmmReg2[0,32]; } + +#Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS +# RESULT <- UnorderedCompare(SRC1[63-0] <> SRC2[63-0]) { +# * Set EFLAGS *CASE (RESULT) OF +# UNORDERED: ZF,PF,CF <- 111; +# GREATER_THAN: ZF,PF,CF <- 000; +# LESS_THAN: ZF,PF,CF <- 001; +# EQUAL: ZF,PF,CF <- 100; +# ESAC; +# OF,AF,SF <- 0;} + +:UCOMISD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2E; m64 & XmmReg ... +{ + fucompe(XmmReg[0,64], m64); +} + +:UCOMISD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x2E; xmmmod=3 & XmmReg1 & XmmReg2 +{ + fucompe(XmmReg1[0,64], XmmReg2[0,64]); +} + +#Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS +# RESULT <- UnorderedCompare(SRC1[31-0] <> SRC2[31-0]) { +# * Set EFLAGS *CASE (RESULT) OF +# UNORDERED: ZF,PF,CF <- 111; +# GREATER_THAN: ZF,PF,CF <- 000; +# LESS_THAN: ZF,PF,CF <- 001; +# EQUAL: ZF,PF,CF <- 100; +# ESAC; +# OF,AF,SF <- 0;} + +:UCOMISS XmmReg, m32 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2E; m32 & XmmReg ... +{ + fucompe(XmmReg[0,32], m32); +} + +:UCOMISS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x2E; xmmmod=3 & XmmReg1 & XmmReg2 +{ + fucompe(XmmReg1[0,32], XmmReg2[0,32]); +} + +:UNPCKHPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x15; m128 & XmmReg ... +{ + XmmReg[0,64] = XmmReg[64,64]; + XmmReg[64,64] = m128[64,64]; +} + +:UNPCKHPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x15; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = XmmReg1[64,64]; + XmmReg1[64,64] = XmmReg2[64,64]; +} + +:UNPCKHPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x15; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = XmmReg[64,32]; + XmmReg[64,32] = XmmReg[96,32]; + XmmReg[32,32] = m[64,32]; + XmmReg[96,32] = m[96,32]; +} + +:UNPCKHPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x15; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = XmmReg1[64,32]; + XmmReg1[32,32] = XmmReg2[64,32]; + XmmReg1[64,32] = XmmReg1[96,32]; # XmmReg1 and XmmReg2 could be the same register, preserve XmmReg1[64,32] till later + XmmReg1[96,32] = XmmReg2[96,32]; +} + +:UNPCKLPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x14; m128 & XmmReg ... +{ +# XmmReg[0,64] = XmmReg[0,64]; superfluous + XmmReg[64,64] = m128[0,64]; +} + +:UNPCKLPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x14; xmmmod=3 & XmmReg1 & XmmReg2 +{ +# XmmReg1[0,64] = XmmReg1[0,64]; superfluous + XmmReg1[64,64] = XmmReg2[0,64]; +} + +:UNPCKLPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x14; m128 & XmmReg ... +{ + local m:16 = m128; +# XmmReg[0,32] = XmmReg[0,32]; superfluous + XmmReg[64,32] = XmmReg[32,32]; + XmmReg[32,32] = m[0,32]; + XmmReg[96,32] = m[32,32]; +} + +:UNPCKLPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x14; xmmmod=3 & XmmReg1 & XmmReg2 +{ +# XmmReg1[0,32] = XmmReg1[0,32]; superfluous + XmmReg1[64,32] = XmmReg1[32,32]; + XmmReg1[96,32] = XmmReg2[32,32]; + XmmReg1[32,32] = XmmReg2[0,32]; # XmmReg1 and XmmReg2 could be the same register, preserve Db till last +} + +:XORPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x57; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,64] = ( XmmReg[0,64] ^ m[0,64] ); + XmmReg[64,64] = ( XmmReg[64,64] ^ m[64,64] ); +} + +:XORPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x57; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = ( XmmReg1[0,64] ^ XmmReg2[0,64] ); + XmmReg1[64,64] = ( XmmReg1[64,64] ^ XmmReg2[64,64] ); +} + +:XORPS XmmReg, m128 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x57; m128 & XmmReg ... +{ + local m:16 = m128; + XmmReg[0,32] = ( XmmReg[0,32] ^ m[0,32] ); + XmmReg[32,32] = ( XmmReg[32,32] ^ m[32,32] ); + XmmReg[64,32] = ( XmmReg[64,32] ^ m[64,32] ); + XmmReg[96,32] = ( XmmReg[96,32] ^ m[96,32] ); +} + +:XORPS XmmReg1, XmmReg2 is vexMode=0 & mandover=0 & byte=0x0F; byte=0x57; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,32] = ( XmmReg1[0,32] ^ XmmReg2[0,32] ); + XmmReg1[32,32] = ( XmmReg1[32,32] ^ XmmReg2[32,32] ); + XmmReg1[64,32] = ( XmmReg1[64,32] ^ XmmReg2[64,32] ); + XmmReg1[96,32] = ( XmmReg1[96,32] ^ XmmReg2[96,32] ); +} + +#### +#### VIA Padlock instructions +#### + +define pcodeop xstore_available; +define pcodeop xstore; +define pcodeop xcrypt_ecb; +define pcodeop xcrypt_cbc; +define pcodeop xcrypt_ctr; +define pcodeop xcrypt_cfb; +define pcodeop xcrypt_ofb; +define pcodeop montmul; +define pcodeop xsha1; +define pcodeop xsha256; + +:XSTORE is vexMode=0 & mandover=0 & byte=0x0F; byte=0xA7; byte=0xC0 { + EAX = xstore_available(EDX,EDI); +} + +:XSTORE.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xC0 { + EAX = xstore(ECX,EDX,EDI); + ECX = 0; +} + +:XCRYPTECB.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xC8 { + xcrypt_ecb(ECX,EDX,EBX,ESI,EDI); +} + +:XCRYPTCBC.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xD0 { + xcrypt_cbc(ECX,EAX,EDX,EBX,ESI,EDI); +} + +:XCRYPTCTR.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xD8 { + xcrypt_ctr(ECX,EAX,EDX,EBX,ESI,EDI); +} + +:XCRYPTCFB.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xE0 { + xcrypt_cfb(ECX,EAX,EDX,EBX,ESI,EDI); +} + +:XCRYPTOFB.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA7; byte=0xE8 { + xcrypt_ofb(ECX,EAX,EDX,EBX,ESI,EDI); +} + +:MONTMUL.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA6; byte=0xC0 { + montmul(EAX,ECX,ESI); + ECX=0; + EDX=0; +} + +:XSHA1.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA6; byte=0xC8 { + xsha1(ECX,ESI,EDI); + EAX = ECX; +} + +:XSHA256.REP is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0xA6; byte=0xD0 { + xsha256(ECX,ESI,EDI); + EAX = ECX; +} + +#### +#### SSE4.1 instructions +#### + +define pcodeop mpsadbw; +:MPSADBW XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x42; XmmReg ... & m128; imm8 { XmmReg = mpsadbw(XmmReg, m128, imm8:8); } +:MPSADBW XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x42; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = mpsadbw(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop phminposuw; +:PHMINPOSUW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x41; XmmReg ... & m128 { XmmReg = phminposuw(m128); } +:PHMINPOSUW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x41; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = phminposuw(XmmReg2); } + +define pcodeop pmuldq; +:PMULDQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x28; XmmReg ... & m128 { XmmReg = pmuldq(XmmReg, m128); } +:PMULDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x28; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmuldq(XmmReg1, XmmReg2); } + +define pcodeop pmulld; +:PMULLD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x40; XmmReg ... & m128 { XmmReg = pmulld(XmmReg, m128); } +:PMULLD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x40; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmulld(XmmReg1, XmmReg2); } + +define pcodeop dpps; +:DPPS XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x40; XmmReg ... & m128; imm8 { XmmReg = dpps(XmmReg, m128, imm8:8); } +:DPPS XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x40; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = dpps(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop dppd; +:DPPD XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x41; XmmReg ... & m128; imm8 { XmmReg = dppd(XmmReg, m128, imm8:8); } +:DPPD XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x41; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = dppd(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop blendps; +:BLENDPS XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0C; XmmReg ... & m128; imm8 { XmmReg = blendps(XmmReg, m128, imm8:8); } +:BLENDPS XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0C; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = blendps(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop blendpd; +:BLENDPD XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0D; XmmReg ... & m128; imm8 { XmmReg = blendpd(XmmReg, m128, imm8:8); } +:BLENDPD XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0D; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = blendpd(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop blendvps; +:BLENDVPS XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x14; XmmReg ... & m128 { XmmReg = blendvps(XmmReg, m128, XMM0); } +:BLENDVPS XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x14; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = blendvps(XmmReg1, XmmReg2, XMM0); } + +define pcodeop blendvpd; +:BLENDVPD XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x15; XmmReg ... & m128 { XmmReg = blendvpd(XmmReg, m128, XMM0); } +:BLENDVPD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x15; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = blendvpd(XmmReg1, XmmReg2, XMM0); } + +define pcodeop pblendvb; +:PBLENDVB XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x10; XmmReg ... & m128 { XmmReg = pblendvb(XmmReg, m128, XMM0); } +:PBLENDVB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x10; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pblendvb(XmmReg1, XmmReg2, XMM0); } + +define pcodeop pblendw; +:PBLENDW XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0E; XmmReg ... & m128; imm8 { XmmReg = pblendw(XmmReg, m128, imm8:8); } +:PBLENDW XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0E; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = pblendw(XmmReg1, XmmReg2, imm8:8); } + +:PMINSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x38; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,8],srcCopy[0,8] s< XmmReg1[0,8],srcCopy[0,8],XmmReg1[0,8]); + conditionalAssign(XmmReg1[8,8],srcCopy[8,8] s< XmmReg1[8,8],srcCopy[8,8],XmmReg1[8,8]); + conditionalAssign(XmmReg1[16,8],srcCopy[16,8] s< XmmReg1[16,8],srcCopy[16,8],XmmReg1[16,8]); + conditionalAssign(XmmReg1[24,8],srcCopy[24,8] s< XmmReg1[24,8],srcCopy[24,8],XmmReg1[24,8]); + conditionalAssign(XmmReg1[32,8],srcCopy[32,8] s< XmmReg1[32,8],srcCopy[32,8],XmmReg1[32,8]); + conditionalAssign(XmmReg1[40,8],srcCopy[40,8] s< XmmReg1[40,8],srcCopy[40,8],XmmReg1[40,8]); + conditionalAssign(XmmReg1[48,8],srcCopy[48,8] s< XmmReg1[48,8],srcCopy[48,8],XmmReg1[48,8]); + conditionalAssign(XmmReg1[56,8],srcCopy[56,8] s< XmmReg1[56,8],srcCopy[56,8],XmmReg1[56,8]); + conditionalAssign(XmmReg1[64,8],srcCopy[64,8] s< XmmReg1[64,8],srcCopy[64,8],XmmReg1[64,8]); + conditionalAssign(XmmReg1[72,8],srcCopy[72,8] s< XmmReg1[72,8],srcCopy[72,8],XmmReg1[72,8]); + conditionalAssign(XmmReg1[80,8],srcCopy[80,8] s< XmmReg1[80,8],srcCopy[80,8],XmmReg1[80,8]); + conditionalAssign(XmmReg1[88,8],srcCopy[88,8] s< XmmReg1[88,8],srcCopy[88,8],XmmReg1[88,8]); + conditionalAssign(XmmReg1[96,8],srcCopy[96,8] s< XmmReg1[96,8],srcCopy[96,8],XmmReg1[96,8]); + conditionalAssign(XmmReg1[104,8],srcCopy[104,8] s< XmmReg1[104,8],srcCopy[104,8],XmmReg1[104,8]); + conditionalAssign(XmmReg1[112,8],srcCopy[112,8] s< XmmReg1[112,8],srcCopy[112,8],XmmReg1[112,8]); + conditionalAssign(XmmReg1[120,8],srcCopy[120,8] s< XmmReg1[120,8],srcCopy[120,8],XmmReg1[120,8]); +} + +:PMINUW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3A; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,16],srcCopy[0,16] < XmmReg1[0,16],srcCopy[0,16],XmmReg1[0,16]); + conditionalAssign(XmmReg1[16,16],srcCopy[16,16] < XmmReg1[16,16],srcCopy[16,16],XmmReg1[16,16]); + conditionalAssign(XmmReg1[32,16],srcCopy[32,16] < XmmReg1[32,16],srcCopy[32,16],XmmReg1[32,16]); + conditionalAssign(XmmReg1[48,16],srcCopy[48,16] < XmmReg1[48,16],srcCopy[48,16],XmmReg1[48,16]); + conditionalAssign(XmmReg1[64,16],srcCopy[64,16] < XmmReg1[64,16],srcCopy[64,16],XmmReg1[64,16]); + conditionalAssign(XmmReg1[80,16],srcCopy[80,16] < XmmReg1[80,16],srcCopy[80,16],XmmReg1[80,16]); + conditionalAssign(XmmReg1[96,16],srcCopy[96,16] < XmmReg1[96,16],srcCopy[96,16],XmmReg1[96,16]); + conditionalAssign(XmmReg1[112,16],srcCopy[112,16] < XmmReg1[112,16],srcCopy[112,16],XmmReg1[112,16]); +} + +:PMINUD XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3B; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,32],srcCopy[0,32] < XmmReg1[0,32],srcCopy[0,32],XmmReg1[0,32]); + conditionalAssign(XmmReg1[32,32],srcCopy[32,32] < XmmReg1[32,32],srcCopy[32,32],XmmReg1[32,32]); + conditionalAssign(XmmReg1[64,32],srcCopy[64,32] < XmmReg1[64,32],srcCopy[64,32],XmmReg1[64,32]); + conditionalAssign(XmmReg1[96,32],srcCopy[96,32] < XmmReg1[96,32],srcCopy[96,32],XmmReg1[96,32]); +} + +:PMINSD XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x39; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,32],srcCopy[0,32] s< XmmReg1[0,32],srcCopy[0,32],XmmReg1[0,32]); + conditionalAssign(XmmReg1[32,32],srcCopy[32,32] s< XmmReg1[32,32],srcCopy[32,32],XmmReg1[32,32]); + conditionalAssign(XmmReg1[64,32],srcCopy[64,32] s< XmmReg1[64,32],srcCopy[64,32],XmmReg1[64,32]); + conditionalAssign(XmmReg1[96,32],srcCopy[96,32] s< XmmReg1[96,32],srcCopy[96,32],XmmReg1[96,32]); +} + +:PMAXSB XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3C; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,8],srcCopy[0,8] s> XmmReg1[0,8],srcCopy[0,8],XmmReg1[0,8]); + conditionalAssign(XmmReg1[8,8],srcCopy[8,8] s> XmmReg1[8,8],srcCopy[8,8],XmmReg1[8,8]); + conditionalAssign(XmmReg1[16,8],srcCopy[16,8] s> XmmReg1[16,8],srcCopy[16,8],XmmReg1[16,8]); + conditionalAssign(XmmReg1[24,8],srcCopy[24,8] s> XmmReg1[24,8],srcCopy[24,8],XmmReg1[24,8]); + conditionalAssign(XmmReg1[32,8],srcCopy[32,8] s> XmmReg1[32,8],srcCopy[32,8],XmmReg1[32,8]); + conditionalAssign(XmmReg1[40,8],srcCopy[40,8] s> XmmReg1[40,8],srcCopy[40,8],XmmReg1[40,8]); + conditionalAssign(XmmReg1[48,8],srcCopy[48,8] s> XmmReg1[48,8],srcCopy[48,8],XmmReg1[48,8]); + conditionalAssign(XmmReg1[56,8],srcCopy[56,8] s> XmmReg1[56,8],srcCopy[56,8],XmmReg1[56,8]); + conditionalAssign(XmmReg1[64,8],srcCopy[64,8] s> XmmReg1[64,8],srcCopy[64,8],XmmReg1[64,8]); + conditionalAssign(XmmReg1[72,8],srcCopy[72,8] s> XmmReg1[72,8],srcCopy[72,8],XmmReg1[72,8]); + conditionalAssign(XmmReg1[80,8],srcCopy[80,8] s> XmmReg1[80,8],srcCopy[80,8],XmmReg1[80,8]); + conditionalAssign(XmmReg1[88,8],srcCopy[88,8] s> XmmReg1[88,8],srcCopy[88,8],XmmReg1[88,8]); + conditionalAssign(XmmReg1[96,8],srcCopy[96,8] s> XmmReg1[96,8],srcCopy[96,8],XmmReg1[96,8]); + conditionalAssign(XmmReg1[104,8],srcCopy[104,8] s> XmmReg1[104,8],srcCopy[104,8],XmmReg1[104,8]); + conditionalAssign(XmmReg1[112,8],srcCopy[112,8] s> XmmReg1[112,8],srcCopy[112,8],XmmReg1[112,8]); + conditionalAssign(XmmReg1[120,8],srcCopy[120,8] s> XmmReg1[120,8],srcCopy[120,8],XmmReg1[120,8]); +} + + +:PMAXUW XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3E; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,16],srcCopy[0,16] > XmmReg1[0,16],srcCopy[0,16],XmmReg1[0,16]); + conditionalAssign(XmmReg1[16,16],srcCopy[16,16] > XmmReg1[16,16],srcCopy[16,16],XmmReg1[16,16]); + conditionalAssign(XmmReg1[32,16],srcCopy[32,16] > XmmReg1[32,16],srcCopy[32,16],XmmReg1[32,16]); + conditionalAssign(XmmReg1[48,16],srcCopy[48,16] > XmmReg1[48,16],srcCopy[48,16],XmmReg1[48,16]); + conditionalAssign(XmmReg1[64,16],srcCopy[64,16] > XmmReg1[64,16],srcCopy[64,16],XmmReg1[64,16]); + conditionalAssign(XmmReg1[80,16],srcCopy[80,16] > XmmReg1[80,16],srcCopy[80,16],XmmReg1[80,16]); + conditionalAssign(XmmReg1[96,16],srcCopy[96,16] > XmmReg1[96,16],srcCopy[96,16],XmmReg1[96,16]); + conditionalAssign(XmmReg1[112,16],srcCopy[112,16] > XmmReg1[112,16],srcCopy[112,16],XmmReg1[112,16]); +} + +:PMAXUD XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3F; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,32],srcCopy[0,32] > XmmReg1[0,32],srcCopy[0,32],XmmReg1[0,32]); + conditionalAssign(XmmReg1[32,32],srcCopy[32,32] > XmmReg1[32,32],srcCopy[32,32],XmmReg1[32,32]); + conditionalAssign(XmmReg1[64,32],srcCopy[64,32] > XmmReg1[64,32],srcCopy[64,32],XmmReg1[64,32]); + conditionalAssign(XmmReg1[96,32],srcCopy[96,32] > XmmReg1[96,32],srcCopy[96,32],XmmReg1[96,32]); +} + +:PMAXSD XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x3D; XmmReg1 ... & XmmReg2_m128 +{ + local srcCopy:16 = XmmReg2_m128; + conditionalAssign(XmmReg1[0,32],srcCopy[0,32] s> XmmReg1[0,32],srcCopy[0,32],XmmReg1[0,32]); + conditionalAssign(XmmReg1[32,32],srcCopy[32,32] s> XmmReg1[32,32],srcCopy[32,32],XmmReg1[32,32]); + conditionalAssign(XmmReg1[64,32],srcCopy[64,32] s> XmmReg1[64,32],srcCopy[64,32],XmmReg1[64,32]); + conditionalAssign(XmmReg1[96,32],srcCopy[96,32] s> XmmReg1[96,32],srcCopy[96,32],XmmReg1[96,32]); +} + +define pcodeop roundps; +:ROUNDPS XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x08; XmmReg ... & m128; imm8 { XmmReg = roundps(XmmReg, m128, imm8:8); } +:ROUNDPS XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x08; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = roundps(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop roundss; +:ROUNDSS XmmReg, m32, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0A; XmmReg ... & m32; imm8 { XmmReg = roundss(XmmReg, m32, imm8:8); } +:ROUNDSS XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0A; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = roundss(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop roundpd; +:ROUNDPD XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x09; XmmReg ... & m128; imm8 { XmmReg = roundpd(XmmReg, m128, imm8:8); } +:ROUNDPD XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x09; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = roundpd(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop roundsd; +:ROUNDSD XmmReg, m64, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0B; XmmReg ... & m64; imm8 { XmmReg = roundsd(XmmReg, m64, imm8:8); } +:ROUNDSD XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x0B; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = roundsd(XmmReg1, XmmReg2, imm8:8); } + +define pcodeop insertps; +:INSERTPS XmmReg, m32, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x21; XmmReg ... & m32; imm8 { XmmReg = insertps(XmmReg, m32, imm8:8); } +:INSERTPS XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x21; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XmmReg1 = insertps(XmmReg1, XmmReg2, imm8:8); } + +:PINSRB XmmReg, rm32, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x20; XmmReg ... & rm32; imm8 +{ + local destIndex:1 = (imm8 & 0xf) * 8:1; + local useLow:1 = destIndex < 64:1; + local newLow:8 = zext(rm32:1) << destIndex; + newLow = (XmmReg[0,64] & ~(0xff:8 << destIndex)) | newLow; + local newHigh:8 = zext(rm32:1) << (destIndex-64:1); + newHigh = (XmmReg[64,64] & ~(0xff:8 << (destIndex - 64:1))) | newHigh; + conditionalAssign(XmmReg[0,64],useLow,newLow,XmmReg[0,64]); + conditionalAssign(XmmReg[64,64],!useLow,newHigh,XmmReg[64,64]); +} + +:PINSRD XmmReg, rm32, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x22; XmmReg ... & rm32; imm8 +{ + local destIndex:1 = (imm8 & 0x3) * 32:1; + local useLow:1 = destIndex < 64:1; + local newLow:8 = zext(rm32) << destIndex; + newLow = (XmmReg[0,64] & ~(0xffffffff:8 << destIndex)) | newLow; + local newHigh:8 = zext(rm32) << (destIndex-64:1); + newHigh = (XmmReg[64,64] & ~(0xffffffff:8 << (destIndex - 64:1))) | newHigh; + conditionalAssign(XmmReg[0,64],useLow,newLow,XmmReg[0,64]); + conditionalAssign(XmmReg[64,64],!useLow,newHigh,XmmReg[64,64]); +} + +@ifdef IA64 +:PINSRQ XmmReg, rm64, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x22; XmmReg ... & rm64; imm8 +{ + local useHigh:1 = imm8 & 0x1; + conditionalAssign(XmmReg[0,64],!useHigh,rm64,XmmReg[0,64]); + conditionalAssign(XmmReg[64,64],useHigh,rm64,XmmReg[64,64]); +} +@endif + +define pcodeop extractps; +@ifdef IA64 +:EXTRACTPS rm64, XmmReg, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x17; XmmReg ... & rm64; imm8 { rm64 = extractps(XmmReg, imm8:8); } +@endif +:EXTRACTPS rm32, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x17; XmmReg ... & rm32 & check_rm32_dest ...; imm8 { rm32 = extractps(XmmReg, imm8:8); build check_rm32_dest; } + +:PEXTRB Rmr32, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x14; mod=3 & XmmReg & Rmr32 & check_Rmr32_dest; imm8 +{ + local shift:1 = (imm8 & 0xf) * 8:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg[0,64] >> shift,XmmReg[64,64] >> (shift - 64)); + Rmr32 = zext(temp:1); + build check_Rmr32_dest; +} + +:PEXTRB Mem, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x14; XmmReg ... & Mem; imm8 +{ + local shift:1 = (imm8 & 0xf) * 8:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg[0,64] >> shift,XmmReg[64,64] >> (shift - 64)); + Mem = temp:1; +} + +:PEXTRD Rmr32, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x16; mod=3 & XmmReg & Rmr32 & check_Rmr32_dest; imm8 +{ + local shift:1 = (imm8 & 0x3) * 32:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg[0,64] >> shift,XmmReg[64,64] >> (shift - 64)); + Rmr32 = zext(temp:4); + build check_Rmr32_dest; +} + +:PEXTRD Mem, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x16; XmmReg ... & Mem; imm8 +{ + local shift:1 = (imm8 & 0x3) * 32:1; + local low:1 = shift < 64:1; + local temp:8; + conditionalAssign(temp,low,XmmReg[0,64] >> shift,XmmReg[64,64] >> (shift - 64)); + Mem = temp:4; +} + +@ifdef IA64 +:PEXTRQ Rmr64, XmmReg, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x16; mod=3 & XmmReg & Rmr64; imm8 +{ + local high:1 = imm8 & 0x1; + conditionalAssign(Rmr64,high,XmmReg[64,64],XmmReg[0,64]); +} + +:PEXTRQ Mem, XmmReg, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x16; XmmReg ... & Mem; imm8 +{ + local high:1 = imm8 & 0x1; + conditionalAssign(Mem,high,XmmReg[64,64],XmmReg[0,64]); +} +@endif + +define pcodeop pmovsxbw; +:PMOVSXBW XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x20; XmmReg ... & m64 { XmmReg = pmovsxbw(XmmReg, m64); } +:PMOVSXBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x20; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxbw(XmmReg1, XmmReg2); } + +define pcodeop pmovsxbd; +:PMOVSXBD XmmReg, m32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x21; XmmReg ... & m32 { XmmReg = pmovsxbd(XmmReg, m32); } +:PMOVSXBD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x21; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxbd(XmmReg1, XmmReg2); } + +define pcodeop pmovsxbq; +:PMOVSXBQ XmmReg, m16 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x22; XmmReg ... & m16 { XmmReg = pmovsxbq(XmmReg, m16); } +:PMOVSXBQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x22; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxbq(XmmReg1, XmmReg2); } + +define pcodeop pmovsxwd; +:PMOVSXWD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x23; XmmReg ... & m64 { XmmReg = pmovsxwd(XmmReg, m64); } +:PMOVSXWD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x23; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxwd(XmmReg1, XmmReg2); } + +define pcodeop pmovsxwq; +:PMOVSXWQ XmmReg, m32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x24; XmmReg ... & m32 { XmmReg = pmovsxwq(XmmReg, m32); } +:PMOVSXWQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x24; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxwq(XmmReg1, XmmReg2); } + +define pcodeop pmovsxdq; +:PMOVSXDQ XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x25; XmmReg ... & m64 { XmmReg = pmovsxdq(XmmReg, m64); } +:PMOVSXDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x25; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovsxdq(XmmReg1, XmmReg2); } + +define pcodeop pmovzxbw; +:PMOVZXBW XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x30; XmmReg ... & m64 { XmmReg = pmovzxbw(XmmReg, m64); } +:PMOVZXBW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x30; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxbw(XmmReg1, XmmReg2); } + +define pcodeop pmovzxbd; +:PMOVZXBD XmmReg, m32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x31; XmmReg ... & m32 { XmmReg = pmovzxbd(XmmReg, m32); } +:PMOVZXBD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x31; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxbd(XmmReg1, XmmReg2); } + +define pcodeop pmovzxbq; +:PMOVZXBQ XmmReg, m16 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x32; XmmReg ... & m16 { XmmReg = pmovzxbq(XmmReg, m16); } +:PMOVZXBQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x32; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxbq(XmmReg1, XmmReg2); } + +define pcodeop pmovzxwd; +:PMOVZXWD XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x33; XmmReg ... & m64 { XmmReg = pmovzxwd(XmmReg, m64); } +:PMOVZXWD XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x33; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxwd(XmmReg1, XmmReg2); } + +define pcodeop pmovzxwq; +:PMOVZXWQ XmmReg, m32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x34; XmmReg ... & m32 { XmmReg = pmovzxwq(XmmReg, m32); } +:PMOVZXWQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x34; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxwq(XmmReg1, XmmReg2); } + +define pcodeop pmovzxdq; +:PMOVZXDQ XmmReg, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x35; XmmReg ... & m64 { XmmReg = pmovzxdq(XmmReg, m64); } +:PMOVZXDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x35; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = pmovzxdq(XmmReg1, XmmReg2); } + +:PTEST XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x17; XmmReg ... & m128 { + local tmp = m128 & XmmReg; + ZF = tmp == 0; + local tmp2 = m128 & ~XmmReg; + CF = tmp2 == 0; + AF = 0; + OF = 0; + PF = 0; + SF = 0; +} + +:PTEST XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x17; xmmmod=3 & XmmReg1 & XmmReg2 { + local tmp = XmmReg2 & XmmReg1; + ZF = tmp == 0; + local tmp2 = XmmReg2 & ~XmmReg1; + CF = tmp2 == 0; + AF = 0; + OF = 0; + PF = 0; + SF = 0; +} + +:PCMPEQQ XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x29; XmmReg ... & m128 +{ + XmmReg[0,64] = zext(XmmReg[0,64] == m128[0,64]) * 0xffffffffffffffff:8; + XmmReg[64,64] = zext(XmmReg[64,64] == m128[64,64]) * 0xffffffffffffffff:8; +} +:PCMPEQQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x29; xmmmod=3 & XmmReg1 & XmmReg2 +{ + XmmReg1[0,64] = zext(XmmReg1[0,64] == XmmReg2[0,64]) * 0xffffffffffffffff:8; + XmmReg1[64,64] = zext(XmmReg1[64,64] == XmmReg2[64,64]) * 0xffffffffffffffff:8; +} + +define pcodeop packusdw; +:PACKUSDW XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x2B; XmmReg ... & m128 { XmmReg = packusdw(XmmReg, m128); } +:PACKUSDW XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x2B; xmmmod=3 & XmmReg1 & XmmReg2 { XmmReg1 = packusdw(XmmReg1, XmmReg2); } + +define pcodeop movntdqa; +:MOVNTDQA XmmReg, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x2A; XmmReg ... & m128 { XmmReg = movntdqa(XmmReg, m128); } + +#### +#### SSE4.2 instructions +#### + +define pcodeop crc32; +:CRC32 Reg32, rm8 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xF0; Reg32 ... & check_Reg32_dest ... & rm8 { Reg32 = crc32(Reg32, rm8); build check_Reg32_dest; } +:CRC32 Reg32, rm16 is vexMode=0 & opsize=0 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xF1; Reg32 ... & check_Reg32_dest ... & rm16 { Reg32 = crc32(Reg32, rm16); build check_Reg32_dest; } +:CRC32 Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xF1; Reg32 ... & check_Reg32_dest ... & rm32 { Reg32 = crc32(Reg32, rm32); build check_Reg32_dest; } +@ifdef IA64 +:CRC32 Reg32, rm8 is vexMode=0 & opsize=1 & $(PRE_F2) & $(REX) & byte=0x0F; byte=0x38; byte=0xF0; Reg32 ... & check_Reg32_dest ... & rm8 { Reg32 = crc32(Reg32, rm8); build check_Reg32_dest; } +:CRC32 Reg64, rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF0; Reg64 ... & rm8 { Reg64 = crc32(Reg64, rm8); } +:CRC32 Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF1; Reg64 ... & rm64 { Reg64 = crc32(Reg64, rm64); } +@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); } +: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); } + +define pcodeop pcmpestrm; +:PCMPESTRM XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x60; XmmReg ... & m128; imm8 { XMM0 = pcmpestrm(XmmReg, m128, imm8:8); } +:PCMPESTRM XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x60; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XMM0 = pcmpestrm(XmmReg1, XmmReg2, imm8:8); } + +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); } + +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); } +:PCMPISTRM XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x62; xmmmod=3 & XmmReg1 & XmmReg2; imm8 { XMM0 = pcmpistrm(XmmReg1, XmmReg2, imm8:8); } + +:PCMPGTQ XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x37; XmmReg1 ... & XmmReg2_m128 +{ + XmmReg1[0,64] = 0xffffffffffffffff:8 * (zext(XmmReg1[0,64] s> XmmReg2_m128[0,64])); + XmmReg1[64,64] = 0xffffffffffffffff:8 * (zext(XmmReg1[64,64] s> XmmReg2_m128[64,64])); +} + +macro popcountflags(src){ + OF = 0:1; + SF = 0:1; + AF = 0:1; + CF = 0:1; + PF = 0:1; + ZF = (src == 0); +} +:POPCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x0F; byte=0xB8; Reg16 ... & rm16 { popcountflags(rm16); Reg16 = popcount(rm16); } +:POPCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xB8; Reg32 ... & check_Reg32_dest ... & rm32 { popcountflags(rm32); Reg32 = popcount(rm32); build check_Reg32_dest; } +@ifdef IA64 +:POPCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xB8; Reg64 ... & rm64 { popcountflags(rm64); Reg64 = popcount(rm64); } +@endif + +#### +#### AESNI instructions +#### + +define pcodeop aesdec; +:AESDEC XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xde; XmmReg1 ... & XmmReg2_m128 { + XmmReg1 = aesdec(XmmReg1, XmmReg2_m128); +} +:VAESDEC XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xde; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 { + XmmReg1 = aesdec(vexVVVV_XmmReg, XmmReg2_m128); + YmmReg1 = zext(XmmReg1); +} + +define pcodeop aesdeclast; +:AESDECLAST XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xdf; XmmReg1 ... & XmmReg2_m128 { + XmmReg1 = aesdeclast(XmmReg1, XmmReg2_m128); +} +:VAESDECLAST XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xdf; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 { + XmmReg1 = aesdeclast(vexVVVV_XmmReg, XmmReg2_m128); + YmmReg1 = zext(XmmReg1); +} + +define pcodeop aesenc; +:AESENC XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xdc; XmmReg1 ... & XmmReg2_m128 { + XmmReg1 = aesenc(XmmReg1, XmmReg2_m128); +} +:VAESENC XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xdc; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 { + XmmReg1 = aesenc(vexVVVV_XmmReg, XmmReg2_m128); + YmmReg1 = zext(XmmReg1); +} + +define pcodeop aesenclast; +:AESENCLAST XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xdd; XmmReg1 ... & XmmReg2_m128 { + XmmReg1 = aesenclast(XmmReg1, XmmReg2_m128); +} +:VAESENCLAST XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0xdd; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 { + XmmReg1 = aesenclast(vexVVVV_XmmReg, XmmReg2_m128); + YmmReg1 = zext(XmmReg1); +} + +define pcodeop aesimc; +:AESIMC XmmReg1, XmmReg2_m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xdb; XmmReg1 ... & XmmReg2_m128 { + XmmReg1 = aesimc(XmmReg2_m128); +} +:VAESIMC XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG); byte=0xdb; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 { + XmmReg1 = aesimc(XmmReg2_m128); + YmmReg1 = zext(XmmReg1); +} + +define pcodeop aeskeygenassist; +:AESKEYGENASSIST XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0xdf; XmmReg1 ... & XmmReg2_m128; imm8 { + XmmReg1 = aeskeygenassist(XmmReg2_m128, imm8:1); +} +:VAESKEYGENASSIST XmmReg1, XmmReg2_m128, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG); byte=0xdf; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 { + XmmReg1 = aeskeygenassist(XmmReg2_m128, imm8:1); + YmmReg1 = zext(XmmReg1); +} + + + +#### +#### Deprecated 3DNow! instructions +#### + +define pcodeop PackedIntToFloatingDwordConv; +:PI2FD mmxreg, m64 is vexMode=0 & suffix3D=0x0D & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedIntToFloatingDwordConv(mmxreg, m64); } +:PI2FD mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x0D & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedIntToFloatingDwordConv(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingToIntDwordConv; +:PF2ID mmxreg, m64 is vexMode=0 & suffix3D=0x1D & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingToIntDwordConv(mmxreg, m64); } +:PF2ID mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x1D & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingToIntDwordConv(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingCompareGE; +:PFCMPGE mmxreg, m64 is vexMode=0 & suffix3D=0x90 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingCompareGE(mmxreg, m64); } +:PFCMPGE mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x90 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingCompareGE(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingCompareGT; +:PFCMPGT mmxreg, m64 is vexMode=0 & suffix3D=0xA0 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingCompareGT(mmxreg, m64); } +:PFCMPGT mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xA0 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingCompareGT(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingCompareEQ; +:PFCMPEQ mmxreg, m64 is vexMode=0 & suffix3D=0xB0 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingCompareEQ(mmxreg, m64); } +:PFCMPEQ mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xB0 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingCompareEQ(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingAccumulate; +:PFACC mmxreg, m64 is vexMode=0 & suffix3D=0xAE & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingAccumulate(mmxreg, m64); } +:PFACC mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xAE & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingAccumulate(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingADD; +:PFADD mmxreg, m64 is vexMode=0 & suffix3D=0x9E & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingADD(mmxreg, m64); } +:PFADD mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x9E & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingADD(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingSUB; +:PFSUB mmxreg, m64 is vexMode=0 & suffix3D=0x9A & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingSUB(mmxreg, m64); } +:PFSUB mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x9A & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingSUB(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingSUBR; +:PFSUBR mmxreg, m64 is vexMode=0 & suffix3D=0xAA & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingSUBR(mmxreg, m64); } +:PFSUBR mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xAA & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingSUBR(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingMIN; +:PFMIN mmxreg, m64 is vexMode=0 & suffix3D=0x94 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingMIN(mmxreg, m64); } +:PFMIN mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x94 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingMIN(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingMAX; +:PFMAX mmxreg, m64 is vexMode=0 & suffix3D=0xA4 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingMAX(mmxreg, m64); } +:PFMAX mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xA4 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingMAX(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingMUL; +:PFMUL mmxreg, m64 is vexMode=0 & suffix3D=0xB4 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingMUL(mmxreg, m64); } +:PFMUL mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xB4 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingMUL(mmxreg1, mmxreg2); } + +define pcodeop FloatingReciprocalAprox; +:PFRCP mmxreg, m64 is vexMode=0 & suffix3D=0x96 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = FloatingReciprocalAprox(mmxreg, m64); } +:PFRCP mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x96 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = FloatingReciprocalAprox(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingReciprocalSQRAprox; +:PFRSQRT mmxreg, m64 is vexMode=0 & suffix3D=0x97 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingReciprocalSQRAprox(mmxreg, m64); } +:PFRSQRT mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x97 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingReciprocalSQRAprox(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingReciprocalIter1; +:PFRCPIT1 mmxreg, m64 is vexMode=0 & suffix3D=0xA6 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingReciprocalIter1(mmxreg, m64); } +:PFRCPIT1 mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xA6 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingReciprocalIter1(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingReciprocalSQRIter1; +:PFRSQIT1 mmxreg, m64 is vexMode=0 & suffix3D=0xA7 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingReciprocalSQRIter1(mmxreg, m64); } +:PFRSQIT1 mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xA7 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingReciprocalSQRIter1(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingReciprocalIter2; +:PFRCPIT2 mmxreg, m64 is vexMode=0 & suffix3D=0xB6 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingReciprocalIter2(mmxreg, m64); } +:PFRCPIT2 mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xB6 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingReciprocalIter2(mmxreg1, mmxreg2); } + +define pcodeop PackedAverageUnsignedBytes; +:PAVGUSB mmxreg, m64 is vexMode=0 & suffix3D=0xBF & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedAverageUnsignedBytes(mmxreg, m64); } +:PAVGUSB mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xBF & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedAverageUnsignedBytes(mmxreg1, mmxreg2); } + +define pcodeop PackedAverageHighRoundedWord; +:PMULHRW mmxreg, m64 is vexMode=0 & suffix3D=0xB7 & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedAverageHighRoundedWord(mmxreg, m64); } +:PMULHRW mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0xB7 & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedAverageHighRoundedWord(mmxreg1, mmxreg2); } + +define pcodeop FastExitMediaState; +:FEMMS is vexMode=0 & byte=0x0F; byte=0x0E { FastExitMediaState(); } + +#define pcodeop PrefetchDataIntoCache; +#:PREFETCH m8 is vexMode=0 & byte=0x0F; byte=0x18; m8 { PrefetchDataIntoCache(m8); } + +#define pcodeop PrefetchDataIntoCacheWrite; +#:PREFETCHW m8 is vexMode=0 & byte=0x0F; byte=0x0D; reg_opcode=1 ... & m8 { PrefetchDataIntoCacheWrite(m8); } + +# 3DNow! extensions + +define pcodeop PackedFloatingToIntWord; +:PF2IW mmxreg, m64 is vexMode=0 & suffix3D=0x1C & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingToIntWord(mmxreg, m64); } +:PF2IW mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x1C & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingToIntWord(mmxreg1, mmxreg2); } + +define pcodeop PackedIntToFloatingWord; +:PI2FW mmxreg, m64 is vexMode=0 & suffix3D=0x0C & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedIntToFloatingWord(mmxreg, m64); } +:PI2FW mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x0C & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedIntToFloatingWord(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingNegAccumulate; +:PFNACC mmxreg, m64 is vexMode=0 & suffix3D=0x8A & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingNegAccumulate(mmxreg, m64); } +:PFNACC mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x8A & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingNegAccumulate(mmxreg1, mmxreg2); } + +define pcodeop PackedFloatingPosNegAccumulate; +:PFPNACC mmxreg, m64 is vexMode=0 & suffix3D=0x8E & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedFloatingPosNegAccumulate(mmxreg, m64); } +:PFPNACC mmxreg1, mmxreg2 is vexMode=0 & suffix3D=0x8E & mandover=0 & byte=0x0F; byte=0x0F; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = PackedFloatingPosNegAccumulate(mmxreg1, mmxreg2); } + +define pcodeop PackedSwapDWords; +:PSWAPD mmxreg, m64 is vexMode=0 & suffix3D=0xBB & mandover=0 & byte=0x0F; byte=0x0F; mmxreg ... & m64 { mmxreg = PackedSwapDWords(mmxreg, m64); } +: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; mmxmod = 3 & mmxreg1 & mmxreg2 { mmxreg1 = MaskedMoveQWord(mmxreg1, mmxreg2); } + +} # end with : lockprefx=0 diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/lockable.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/lockable.sinc new file mode 100644 index 00000000..be1876b1 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/lockable.sinc @@ -0,0 +1,1380 @@ +# The LOCK prefix is only valid for certain instructions, otherwise, from the +# Intel instruction manual: +# An undefined opcode exception will also be generated if the LOCK prefix +# is used with any instruction not in the above list. +# The instructions in this file have their non-lockable counterparts in ia.sinc + +:ADC^lockx spec_m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); spec_m8 & reg_opcode=2 ... ; imm8 +{ + build lockx; + build spec_m8; + addCarryFlags( spec_m8, imm8:1 ); + resultflags( spec_m8 ); + build unlock; +} + +:ADC^lockx spec_m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; spec_m16 & reg_opcode=2 ...; imm16 +{ + build lockx; + build spec_m16; + addCarryFlags( spec_m16, imm16:2 ); + resultflags( spec_m16 ); + build unlock; +} + +:ADC^lockx spec_m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; spec_m32 & reg_opcode=2 ...; imm32 +{ + build lockx; + build spec_m32; + addCarryFlags( spec_m32, imm32:4 ); + resultflags( spec_m32 ); + build unlock; +} + +@ifdef IA64 +:ADC^lockx spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; spec_m64 & reg_opcode=2 ...; simm32 +{ + build lockx; + build spec_m64; + addCarryFlags( spec_m64, simm32 ); + resultflags( spec_m64 ); + build unlock; +} +@endif + +:ADC^lockx spec_m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; spec_m16 & reg_opcode=2 ...; simm8_16 +{ + build lockx; + build spec_m16; + addCarryFlags( spec_m16, simm8_16 ); + resultflags( spec_m16 ); + build unlock; +} + +:ADC^lockx spec_m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; spec_m32 & reg_opcode=2 ...; simm8_32 +{ + build lockx; + build spec_m32; + addCarryFlags( spec_m32, simm8_32 ); + resultflags( spec_m32 ); + build unlock; +} + +@ifdef IA64 +:ADC^lockx spec_m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; spec_m64 & reg_opcode=2 ...; simm8_64 +{ + build lockx; + build spec_m64; + addCarryFlags( spec_m64, simm8_64 ); + resultflags( spec_m64 ); + build unlock; +} +@endif + +:ADC^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x10; m8 & Reg8 ... +{ + build lockx; + build m8; + addCarryFlags( m8, Reg8 ); + resultflags( m8 ); + build unlock; +} + +:ADC^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x11; m16 & Reg16 ... +{ + build lockx; + build m16; + addCarryFlags( m16, Reg16 ); + resultflags( m16 ); + build unlock; +} + +:ADC^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x11; m32 & Reg32 ... +{ + build lockx; + build m32; + addCarryFlags( m32, Reg32 ); + resultflags( m32 ); + build unlock; +} + +@ifdef IA64 +:ADC^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x11; m64 & Reg64 ... +{ + build lockx; + build m64; + addCarryFlags( m64, Reg64 ); + resultflags( m64 ); + build unlock; +} +@endif + +:ADD^lockx spec_m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); spec_m8 & reg_opcode=0 ...; imm8 +{ + build lockx; + build spec_m8; + addflags( spec_m8,imm8 ); + spec_m8 = spec_m8 + imm8; + resultflags( spec_m8); + build unlock; +} + +:ADD^lockx spec_m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; spec_m16 & reg_opcode=0 ...; imm16 +{ + build lockx; + build spec_m16; + addflags( spec_m16,imm16); + spec_m16 = spec_m16 + imm16; + resultflags( spec_m16); + build unlock; +} + +:ADD^lockx spec_m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; spec_m32 & reg_opcode=0 ...; imm32 +{ + build lockx; + build spec_m32; + addflags( spec_m32,imm32); + spec_m32 = spec_m32 + imm32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:ADD^lockx spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; spec_m64 & reg_opcode=0 ...; simm32 +{ + build lockx; + build spec_m64; + addflags( spec_m64,simm32); + spec_m64 = spec_m64 + simm32; + resultflags( spec_m64); + build unlock; +} +@endif + +:ADD^lockx spec_m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; spec_m16 & reg_opcode=0 ...; simm8_16 +{ + build lockx; + build spec_m16; + addflags( spec_m16,simm8_16); + spec_m16 = spec_m16 + simm8_16; + resultflags( spec_m16); + build unlock; +} + +:ADD^lockx spec_m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; spec_m32 & reg_opcode=0 ...; simm8_32 +{ + build lockx; + build spec_m32; + addflags( spec_m32,simm8_32); + spec_m32 = spec_m32 + simm8_32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:ADD^lockx spec_m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; spec_m64 & reg_opcode=0 ...; simm8_64 +{ + build lockx; + build spec_m64; + addflags( spec_m64,simm8_64); + spec_m64 = spec_m64 + simm8_64; + resultflags( spec_m64); + build unlock; +} +@endif + +:ADD^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x00; m8 & Reg8 ... +{ + build lockx; + build m8; + addflags( m8,Reg8 ); + m8 = m8 + Reg8; + resultflags( m8); + build unlock; +} + +:ADD^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x1; m16 & Reg16 ... +{ + build lockx; + build m16; + addflags( m16,Reg16); + m16 = m16 + Reg16; + resultflags( m16); + build unlock; +} + +:ADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x1; m32 & Reg32 ... +{ + build lockx; + build m32; + addflags( m32,Reg32); + m32 = m32 + Reg32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:ADD^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x1; m64 & Reg64 ... +{ + build lockx; + build m64; + addflags( m64,Reg64); + m64 = m64 + Reg64; + resultflags( m64); + build unlock; +} +@endif + +:AND^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=4 ...; imm8 +{ + build lockx; + build m8; + logicalflags(); + m8 = m8 & imm8; + resultflags( m8); + build unlock; +} + +:AND^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=4 ...; imm16 +{ + build lockx; + build m16; + logicalflags(); + m16 = m16 & imm16; + resultflags( m16); + build unlock; +} + +:AND^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=4 ...; imm32 +{ + build lockx; + build m32; + logicalflags(); + m32 = m32 & imm32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:AND^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=4 ...; simm32 +{ + build lockx; + build m64; + logicalflags(); + m64 = m64 & simm32; + resultflags( m64); + build unlock; +} +@endif + +:AND^lockx m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=4 ...; usimm8_16 +{ + build lockx; + build m16; + logicalflags(); + m16 = m16 & usimm8_16; + resultflags( m16); + build unlock; +} + +:AND^lockx m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=4 ...; usimm8_32 +{ + build lockx; + build m32; + logicalflags(); + m32 = m32 & usimm8_32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:AND^lockx m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=4 ...; usimm8_64 +{ + build lockx; + build m64; + logicalflags(); + m64 = m64 & usimm8_64; + resultflags( m64); + build unlock; +} +@endif + +:AND^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x20; m8 & Reg8 ... +{ + build lockx; + build m8; + logicalflags(); + m8 = m8 & Reg8; + resultflags( m8); + build unlock; +} + +:AND^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x21; m16 & Reg16 ... +{ + build lockx; + build m16; + logicalflags(); + m16 = m16 & Reg16; + resultflags( m16); + build unlock; +} + +:AND^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x21; m32 & Reg32 ... +{ + build lockx; + build m32; + logicalflags(); + m32 = m32 & Reg32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:AND^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x21; m64 & Reg64 ... +{ + build lockx; + build m64; + logicalflags(); + m64 = m64 & Reg64; + resultflags( m64); + build unlock; +} +@endif + +:BTC^lockx Mem,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xbb; Mem & Reg16 ... +{ + build lockx; + build Mem; + local ptr = Mem + (sext(Reg16) s>> 3); + local bit=Reg16&7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr= *:1 ptr ^(1<> 3); +@else + local ptr = Mem + (Reg32 s>> 3); +@endif + local bit=Reg32&7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr ^ (1<> 3); + local bit=Reg64&7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr ^ (1<>bit)&1; + m16=m16^(1<>bit)&1; + CF=(val!=0); + m32=m32^(1<>bit)&1; + m64=m64^(1<> 3); + local bit=Reg16&7; + local val=(*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr & ~(1<> 3); +@else + local ptr = Mem + (Reg32 s>> 3); +@endif + local bit = Reg32 & 7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr & ~(1<> 3); + local bit = Reg64 & 7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr & ~(1<>bit)&1; + m16=m16 & ~(1<>bit)&1; + CF=(val!=0); + m32=m32 & ~(1<>bit)&1; + m64=m64 & ~(1<> 3); + local bit = Reg16&7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr | (1<>3); +@else + local ptr = Mem + (Reg32 s>>3); +@endif + local bit = Reg32 & 7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr | (1<>3); + local bit = Reg64 & 7; + local val = (*:1 ptr >> bit) & 1; + *:1 ptr = *:1 ptr | (1<>bit)&1; + m16=m16 | (1<>bit)&1; + CF=(val!=0); + m32=m32 | (1<>bit)&1; + m64=m64 | (1<; + EAX = m32; + build check_EAX_dest; + goto ; + + m32 = Reg32; + + build unlock; +} + +@ifdef IA64 +:CMPXCHG^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xb1; m64 & Reg64 ... +{ + build lockx; + build m64; + subflags(RAX,m64); + local tmp=RAX-m64; + resultflags(tmp); + local diff = m64^Reg64; + m64 = m64 ^ (zext(ZF) * diff); + diff = RAX ^ m64; + RAX = RAX ^ (zext(ZF==0) * diff); + build unlock; +} +@endif + +:CMPXCHG8B^lockx m64 is vexMode=0 & lockx & unlock & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 ) ... & m64 +{ + build lockx; + build m64; + ZF = ((zext(EDX) << 32) | zext(EAX)) == m64; + if (ZF == 1) goto ; + EDX = m64(4); + EAX = m64:4; + goto ; + + m64 = (zext(ECX) << 32) | zext(EBX); + + build unlock; +} + +@ifdef IA64 +:CMPXCHG16B^lockx m128 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 ) ... & ( m128 ) { + build lockx; + build m128; + ZF = ((zext(RDX) << 64) | zext(RAX)) == m128; + if (ZF == 1) goto ; + RDX = m128(8); + RAX = m128:8; + goto ; + + m128 = ((zext(RCX) << 64) | zext(RBX)); + + build unlock; +} +@endif + +:DEC^lockx spec_m8 is vexMode=0 & lockx & unlock & byte=0xfe; spec_m8 & reg_opcode=1 ... +{ + build lockx; + build spec_m8; + OF = sborrow(spec_m8,1); + spec_m8 = spec_m8 - 1; + resultflags( spec_m8); + build unlock; +} + +:DEC^lockx spec_m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xff; spec_m16 & reg_opcode=1 ... +{ + build lockx; + build spec_m16; + OF = sborrow(spec_m16,1); + spec_m16 = spec_m16 - 1; + resultflags(spec_m16); + build unlock; +} + +:DEC^lockx spec_m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xff; spec_m32 & reg_opcode=1 ... +{ + build lockx; + build spec_m32; + OF = sborrow(spec_m32,1); + spec_m32 = spec_m32 - 1; + resultflags(spec_m32); + build unlock; +} + +@ifdef IA64 +:DEC^lockx spec_m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xff; spec_m64 & reg_opcode=1 ... +{ + build lockx; + build spec_m64; + OF = sborrow(spec_m64,1); + spec_m64 = spec_m64 - 1; + resultflags(spec_m64); + build unlock; +} +@endif + +:INC^lockx spec_m8 is vexMode=0 & lockx & unlock & byte=0xfe; spec_m8 ... +{ + build lockx; + build spec_m8; + OF = scarry(spec_m8,1); + spec_m8 = spec_m8 + 1; + resultflags( spec_m8); + build unlock; +} + +:INC^lockx spec_m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xff; spec_m16 ... +{ + build lockx; + build spec_m16; + OF = scarry(spec_m16,1); + spec_m16 = spec_m16 + 1; + resultflags(spec_m16); + build unlock; +} + +:INC^lockx spec_m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xff; spec_m32 ... +{ + build lockx; + build spec_m32; + OF = scarry(spec_m32,1); + spec_m32 = spec_m32 + 1; + resultflags(spec_m32); + build unlock; +} + +@ifdef IA64 +:INC^lockx spec_m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xff; spec_m64 ... +{ + build lockx; + build spec_m64; + OF = scarry(spec_m64,1); + spec_m64 = spec_m64 + 1; + resultflags(spec_m64); + build unlock; +} +@endif + +:NEG^lockx m8 is vexMode=0 & lockx & unlock & byte=0xf6; m8 & reg_opcode=3 ... +{ + build lockx; + build m8; + negflags(m8); + m8 = -m8; + resultflags(m8 ); + build unlock; +} + +:NEG^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf7; m16 & reg_opcode=3 ... +{ + build lockx; + build m16; + negflags(m16); + m16 = -m16; + resultflags(m16); + build unlock; +} + +:NEG^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf7; m32 & reg_opcode=3 ... +{ + build lockx; + build m32; + negflags(m32); + m32 = -m32; + resultflags(m32); + build unlock; +} + +@ifdef IA64 +:NEG^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf7; m64 & reg_opcode=3 ... +{ + build lockx; + build m64; + negflags(m64); + m64 = -m64; + resultflags(m64); + build unlock; +} +@endif + +:NOT^lockx m8 is vexMode=0 & lockx & unlock & byte=0xf6; m8 & reg_opcode=2 ... +{ + build lockx; + build m8; + m8 = ~m8; + build unlock; +} + +:NOT^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf7; m16 & reg_opcode=2 ... +{ + build lockx; + build m16; + m16 = ~m16; + build unlock; +} + +:NOT^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf7; m32 & reg_opcode=2 ... +{ + build lockx; + build m32; + m32 = ~m32; + build unlock; +} + +@ifdef IA64 +:NOT^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf7; m64 & reg_opcode=2 ... +{ + build lockx; + build m64; + m64 = ~m64; + build unlock; +} +@endif + +:OR^lockx spec_m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); spec_m8 & reg_opcode=1 ...; imm8 +{ + build lockx; + build spec_m8; + logicalflags(); + spec_m8 = spec_m8 | imm8; + resultflags( spec_m8); + build unlock; +} + +:OR^lockx spec_m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; spec_m16 & reg_opcode=1 ...; imm16 +{ + build lockx; + build spec_m16; + logicalflags(); + spec_m16 = spec_m16 | imm16; + resultflags( spec_m16); + build unlock; +} + +:OR^lockx spec_m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; spec_m32 & reg_opcode=1 ...; imm32 +{ + build lockx; + build spec_m32; + logicalflags(); + spec_m32 = spec_m32 | imm32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:OR^lockx spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; spec_m64 & reg_opcode=1 ...; simm32 +{ + build lockx; + build spec_m64; + logicalflags(); + tmp:8 = spec_m64; + spec_m64 = tmp | simm32; + resultflags( spec_m64); + build unlock; +} +@endif + +:OR^lockx spec_m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; spec_m16 & reg_opcode=1 ...; usimm8_16 +{ + build lockx; + build spec_m16; + logicalflags(); + spec_m16 = spec_m16 | usimm8_16; + resultflags( spec_m16); + build unlock; +} + +:OR^lockx spec_m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; spec_m32 & reg_opcode=1 ...; usimm8_32 +{ + build lockx; + build spec_m32; + logicalflags(); + spec_m32 = spec_m32 | usimm8_32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:OR^lockx spec_m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; spec_m64 & reg_opcode=1 ...; usimm8_64 +{ + build lockx; + build spec_m64; + logicalflags(); + spec_m64 = spec_m64 | usimm8_64; + resultflags( spec_m64); + build unlock; +} +@endif + +:OR^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x8; m8 & Reg8 ... +{ + build lockx; + build m8; + logicalflags(); + m8 = m8 | Reg8; + resultflags( m8); + build unlock; +} + +:OR^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x9; m16 & Reg16 ... +{ + build lockx; + build m16; + logicalflags(); + m16 = m16 | Reg16; + resultflags( m16); + build unlock; +} + +:OR^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x9; m32 & Reg32 ... +{ + build lockx; + build m32; + logicalflags(); + m32 = m32 | Reg32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:OR^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x9; m64 & Reg64 ... +{ + build lockx; + build m64; + logicalflags(); + m64 = m64 | Reg64; + resultflags( m64); + build unlock; +} +@endif + +:SBB^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=3 ...; imm8 +{ + build lockx; + build m8; + subCarryFlags( m8, imm8 ); + resultflags(m8); + build unlock; +} + +:SBB^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=3 ...; imm16 +{ + build lockx; + build m16; + subCarryFlags( m16, imm16 ); + resultflags(m16); + build unlock; +} + +:SBB^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=3 ...; imm32 +{ + build lockx; + build m32; + subCarryFlags( m32, imm32 ); + resultflags(m32); + build unlock; +} + +@ifdef IA64 +:SBB^lockx m64,imm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=3 ...; imm32 +{ + build lockx; + build m64; + subCarryFlags( m64, imm32 ); + resultflags(m64); + build unlock; +} +@endif + +:SBB^lockx m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=3 ...; simm8_16 +{ + build lockx; + build m16; + subCarryFlags( m16, simm8_16 ); + resultflags(m16); + build unlock; +} + +:SBB^lockx m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=3 ...; simm8_32 +{ + build lockx; + build m32; + subCarryFlags( m32, simm8_32 ); + resultflags(m32); + build unlock; +} + +@ifdef IA64 +:SBB^lockx m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=3 ...; simm8_64 +{ + build lockx; + build m64; + subCarryFlags( m64, simm8_64 ); + resultflags(m64); + build unlock; +} +@endif + +:SBB^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x18; m8 & Reg8 ... +{ + build lockx; + build m8; + subCarryFlags( m8, Reg8 ); + resultflags(m8); + build unlock; +} + +:SBB^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x19; m16 & Reg16 ... +{ + build lockx; + build m16; + subCarryFlags( m16, Reg16 ); + resultflags(m16); + build unlock; +} + +:SBB^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x19; m32 & Reg32 ... +{ + build lockx; + build m32; + subCarryFlags( m32, Reg32 ); + resultflags(m32); + build unlock; +} + +@ifdef IA64 +:SBB^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x19; m64 & Reg64 ... +{ + build lockx; + build m64; + subCarryFlags( m64, Reg64 ); + resultflags(m64); + build unlock; +} +@endif + +:SUB^lockx spec_m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); spec_m8 & reg_opcode=5 ...; imm8 +{ + build lockx; + build spec_m8; + subflags( spec_m8,imm8 ); + spec_m8 = spec_m8 - imm8; + resultflags( spec_m8); + build unlock; +} + +:SUB^lockx spec_m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; spec_m16 & reg_opcode=5 ...; imm16 +{ + build lockx; + build spec_m16; + subflags( spec_m16,imm16); + spec_m16 = spec_m16 - imm16; + resultflags( spec_m16); + build unlock; +} + +:SUB^lockx spec_m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; spec_m32 & reg_opcode=5 ...; imm32 +{ + build lockx; + build spec_m32; + subflags( spec_m32,imm32); + spec_m32 = spec_m32 - imm32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:SUB^lockx spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; spec_m64 & reg_opcode=5 ...; simm32 +{ + build lockx; + build spec_m64; + subflags( spec_m64,simm32); + spec_m64 = spec_m64 - simm32; + resultflags( spec_m64); + build unlock; +} +@endif + +:SUB^lockx spec_m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; spec_m16 & reg_opcode=5 ...; simm8_16 +{ + build lockx; + build spec_m16; + subflags( spec_m16,simm8_16); + spec_m16 = spec_m16 - simm8_16; + resultflags( spec_m16); + build unlock; +} + +:SUB^lockx spec_m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; spec_m32 & reg_opcode=5 ...; simm8_32 +{ + build lockx; + build spec_m32; + subflags( spec_m32,simm8_32); + spec_m32 = spec_m32 - simm8_32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:SUB^lockx spec_m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; spec_m64 & reg_opcode=5 ...; simm8_64 +{ + build lockx; + build spec_m64; + subflags( spec_m64,simm8_64); + spec_m64 = spec_m64 - simm8_64; + resultflags( spec_m64); + build unlock; +} +@endif + +:SUB^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x28; m8 & Reg8 ... +{ + build lockx; + build m8; + subflags( m8,Reg8 ); + m8 = m8 - Reg8; + resultflags( m8); + build unlock; +} + +:SUB^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x29; m16 & Reg16 ... +{ + build lockx; + build m16; + subflags( m16,Reg16); + m16 = m16 - Reg16; + resultflags( m16); + build unlock; +} + +:SUB^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x29; m32 & Reg32 ... +{ + build lockx; + build m32; + subflags( m32,Reg32); + m32 = m32 - Reg32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:SUB^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x29; m64 & Reg64 ... +{ + build lockx; + build m64; + subflags( m64,Reg64); + m64 = m64 - Reg64; + resultflags( m64); + build unlock; +} +@endif + +:XADD^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x0F; byte=0xC0; m8 & Reg8 ... +{ + build lockx; + build m8; + addflags( m8,Reg8 ); + local tmp = m8 + Reg8; + Reg8 = m8; + m8 = tmp; + resultflags(tmp); + build unlock; +} + +:XADD^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x0F; byte=0xC1; m16 & Reg16 ... +{ + build lockx; + build m16; + addflags(m16,Reg16); + local tmp = m16 + Reg16; + Reg16 = m16; + m16 = tmp; + resultflags(tmp); + build unlock; +} + +:XADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x0F; byte=0xC1; m32 & Reg32 & check_Reg32_dest ... +{ + build lockx; + build m32; + addflags(m32,Reg32); + local tmp = m32 + Reg32; + Reg32 = m32; + build check_Reg32_dest; + m32 = tmp; + resultflags(tmp); + build unlock; +} + +@ifdef IA64 +:XADD^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x0F; byte=0xC1; m64 & Reg64 ... +{ + build lockx; + build m64; + addflags(m64,Reg64); + local tmp = m64 + Reg64; + Reg64 = m64; + m64 = tmp; + resultflags(tmp); + build unlock; +} +@endif + +# XCHG with memory operands always asserts a lock signal regardless of prefix presence +:XCHG^xacq_xrel_prefx^alwaysLock m8,Reg8 is vexMode=0 & xacq_xrel_prefx & alwaysLock & byte=0x86; m8 & Reg8 ... +{ + build xacq_xrel_prefx; + build alwaysLock; + build m8; + local tmp = m8; + m8 = Reg8; + Reg8 = tmp; + UNLOCK(); +} + +:XCHG^xacq_xrel_prefx^alwaysLock m16,Reg16 is vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=0 & byte=0x87; m16 & Reg16 ... +{ + build xacq_xrel_prefx; + build alwaysLock; + build m16; + local tmp = m16; + m16 = Reg16; + Reg16 = tmp; + UNLOCK(); +} + +:XCHG^xacq_xrel_prefx^alwaysLock m32,Reg32 is vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=1 & byte=0x87; m32 & Reg32 ... +{ + build xacq_xrel_prefx; + build alwaysLock; + build m32; + local tmp = m32; + m32 = Reg32; + Reg32 = tmp; + UNLOCK(); +} + +@ifdef IA64 +:XCHG^xacq_xrel_prefx^alwaysLock m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=2 & byte=0x87; m64 & Reg64 ... +{ + build xacq_xrel_prefx; + build alwaysLock; + build m64; + local tmp = m64; + m64 = Reg64; + Reg64 = tmp; + UNLOCK(); +} +@endif + +:XOR^lockx spec_m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); spec_m8 & reg_opcode=6 ...; imm8 +{ + build lockx; + build spec_m8; + logicalflags(); + spec_m8 = spec_m8 ^ imm8; + resultflags( spec_m8); + build unlock; +} + +:XOR^lockx spec_m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; spec_m16 & reg_opcode=6 ...; imm16 +{ + build lockx; + build spec_m16; + logicalflags(); + spec_m16 = spec_m16 ^ imm16; + resultflags( spec_m16); + build unlock; +} + +:XOR^lockx spec_m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; spec_m32 & reg_opcode=6 ...; imm32 +{ + build lockx; + build spec_m32; + logicalflags(); + spec_m32 = spec_m32 ^ imm32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:XOR^lockx spec_m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; spec_m64 & reg_opcode=6 ...; simm32 +{ + build lockx; + build spec_m64; + logicalflags(); + spec_m64 = spec_m64 ^ simm32; + resultflags( spec_m64); + build unlock; +} +@endif + +:XOR^lockx spec_m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; spec_m16 & reg_opcode=6 ...; usimm8_16 +{ + build lockx; + build spec_m16; + logicalflags(); + spec_m16 = spec_m16 ^ usimm8_16; + resultflags( spec_m16); + build unlock; +} + +:XOR^lockx spec_m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; spec_m32 & reg_opcode=6 ...; usimm8_32 +{ + build lockx; + build spec_m32; + logicalflags(); + spec_m32 = spec_m32 ^ usimm8_32; + resultflags( spec_m32); + build unlock; +} + +@ifdef IA64 +:XOR^lockx spec_m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; spec_m64 & reg_opcode=6 ...; usimm8_64 +{ + build lockx; + build spec_m64; + logicalflags(); + spec_m64 = spec_m64 ^ usimm8_64; + resultflags( spec_m64); + build unlock; +} +@endif + +:XOR^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x30; m8 & Reg8 ... +{ + build lockx; + build m8; + logicalflags(); + m8 = m8 ^ Reg8; + resultflags( m8); + build unlock; +} + +:XOR^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x31; m16 & Reg16 ... +{ + build lockx; + build m16; + logicalflags(); + m16 = m16 ^ Reg16; + resultflags( m16); + build unlock; +} + +:XOR^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x31; m32 & Reg32 ... +{ + build lockx; + build m32; + logicalflags(); + m32 = m32 ^ Reg32; + resultflags( m32); + build unlock; +} + +@ifdef IA64 +:XOR^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x31; m64 & Reg64 ... +{ + build lockx; + build m64; + logicalflags(); + m64 = m64 ^ Reg64; + resultflags( m64); + build unlock; +} +@endif diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/lzcnt.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/lzcnt.sinc new file mode 100644 index 00000000..6927814b --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/lzcnt.sinc @@ -0,0 +1,32 @@ +macro lzcntflags(input, output) { + ZF = (output == 0); + CF = (input == 0); + # OF, SF, PF, AF are undefined +} + +#### +#### LZCNT instructions +#### + + +:LZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg16 ... & rm16 { + + Reg16 = lzcount(rm16); + lzcntflags(rm16, Reg16); +} + +:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & check_Reg32_dest ... & rm32 { + + Reg32 = lzcount(rm32); + lzcntflags(rm32, Reg32); + build check_Reg32_dest; +} + +@ifdef IA64 +:LZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 { + + Reg64 = lzcount(rm64); + lzcntflags(rm64, Reg64); +} +@endif + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/macros.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/macros.sinc new file mode 100644 index 00000000..1a199e1a --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/macros.sinc @@ -0,0 +1,3 @@ +macro conditionalAssign(dest, cond, trueVal, falseVal) { + dest = zext(cond) * trueVal | zext(!cond) * falseVal; +} \ No newline at end of file diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/mpx.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/mpx.sinc new file mode 100644 index 00000000..db600d48 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/mpx.sinc @@ -0,0 +1,234 @@ +define pcodeop br_exception; + + +# BNDMK needs the base address register only +# - if no base register, needs 0 + +@ifdef IA64 +bndmk_addr64: [Rmr64] is mod=0 & Rmr64 { export Rmr64; } +bndmk_addr64: [Rmr64 + simm8_64] is mod=1 & Rmr64; simm8_64 { export Rmr64; } +bndmk_addr64: [simm32_64 + Rmr64] is mod=2 & Rmr64; simm32_64 { export Rmr64; } +bndmk_addr64: [Rmr64] is mod=1 & r_m!=4 & Rmr64; simm8=0 { export Rmr64; } +bndmk_addr64: [Rmr64] is mod=2 & r_m!=4 & Rmr64; simm32=0 { export Rmr64; } +#invalid bndmk_addr64: [riprel] is mod=0 & r_m=5; simm32 [ riprel=inst_next+simm32; ] { export *[const]:8 riprel; } +bndmk_addr64: [Base64 + Index64*ss] is mod=0 & r_m=4; Index64 & Base64 & ss { export Base64; } +bndmk_addr64: [Base64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & Base64 { export Base64; } +bndmk_addr64: [simm32_64 + Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; simm32_64 { tmp:8 = 0; export tmp; } +bndmk_addr64: [Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; imm32=0 { tmp:8 = 0; export tmp; } +bndmk_addr64: [simm32_64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & base64=5; simm32_64 { tmp:8 = 0; export tmp; } +bndmk_addr64: [Base64 + Index64*ss + simm8_64] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8_64 { export Base64; } +bndmk_addr64: [Base64 + Index64*ss] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8=0 { export Base64; } +bndmk_addr64: [Base64 + simm8_64] is mod=1 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm8_64 { export Base64; } +bndmk_addr64: [simm32_64 + Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; simm32_64 { export Base64; } +bndmk_addr64: [simm32_64 + Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm32_64 { export Base64; } +bndmk_addr64: [Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; imm32=0 { export Base64; } +bndmk_addr64: [Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; imm32=0 { export Base64; } +@endif + +bndmk_addr32: [Rmr32] is mod=0 & Rmr32 { export Rmr32; } +bndmk_addr32: [Rmr32 + simm8_32] is mod=1 & Rmr32; simm8_32 { export Rmr32; } +bndmk_addr32: [Rmr32] is mod=1 & r_m!=4 & Rmr32; simm8=0 { export Rmr32; } +bndmk_addr32: [imm32 + Rmr32] is mod=2 & Rmr32; imm32 { export Rmr32; } +bndmk_addr32: [Rmr32] is mod=2 & r_m!=4 & Rmr32; imm32=0 { export Rmr32; } +bndmk_addr32: [imm32] is mod=0 & r_m=5; imm32 { tmp:4 = 0; export tmp; } +bndmk_addr32: [Base + Index*ss] is mod=0 & r_m=4; Index & Base & ss { export Base; } +bndmk_addr32: [Base] is mod=0 & r_m=4; index=4 & Base { export Base; } +bndmk_addr32: [imm32 + Index*ss] is mod=0 & r_m=4; Index & base=5 & ss; imm32 { tmp:4 = 0; export tmp; } +bndmk_addr32: [imm32] is mod=0 & r_m=4; index=4 & base=5; imm32 { tmp:4 = 0; export tmp; } +bndmk_addr32: [Base + Index*ss + simm8_32] is mod=1 & r_m=4; Index & Base & ss; simm8_32 { export Base; } +bndmk_addr32: [Base + simm8_32] is mod=1 & r_m=4; index=4 & Base; simm8_32 { export Base; } +bndmk_addr32: [Base + Index*ss] is mod=1 & r_m=4; Index & Base & ss; simm8=0 { export Base; } +bndmk_addr32: [Base] is mod=1 & r_m=4; index=4 & Base; simm8=0 { export Base; } +bndmk_addr32: [imm32 + Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32 { export Base; } +bndmk_addr32: [imm32 + Base] is mod=2 & r_m=4; index=4 & Base; imm32 { export Base; } +bndmk_addr32: [Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32=0 { export Base; } +bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export Base; } + + + +@ifdef IA64 + +:BNDCL bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr64 { +# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Rmr64 < bnd1_lb) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCL bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem { +# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Mem < bnd1_lb) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCU bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr64 { +# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Rmr64 > ~bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCU bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem { +# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Mem > ~bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCN bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr64 { +# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Rmr64 > bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCN bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem { +# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(Mem > bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +#TODO: This probably cannot be fully modeled +:BNDLDX bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1A; bnd1 ... & Mem { +# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU ); +# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU ); + +# core implementation + bnd1 = *:16 Mem; +} + +:BNDMK bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr64 & Mem ) { +# BND.LB and BND.UB set from m64 + bnd1_lb = bndmk_addr64; + bnd1_ub = Mem; +} + +:BNDMOV bnd1, m128 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; bnd1 ... & m128 { + bnd1 = m128; +} + +:BNDMOV bnd1, bnd2 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 { + bnd1 = bnd2; +} + +:BNDMOV m128, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; bnd1 ... & m128 { + m128 = bnd1; +} + +:BNDMOV bnd2, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 { + bnd2 = bnd1; +} + +#TODO: This probably cannot be fully modeled +:BNDSTX Mem, bnd1 is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1B; bnd1 ... & Mem { +# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU ); +# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU ); + +# core implementation + *:16 Mem = bnd1; +} + +@endif + +:BNDCL bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr32 { +# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Rmr32) < bnd1_lb) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCL bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem { +# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Mem) < bnd1_lb) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCU bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr32 { +# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Rmr32) > ~bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCU bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem { +# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Mem) > ~bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCN bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr32 { +# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Rmr32) > bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +:BNDCN bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem { +# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION + if !(zext(Mem) > bnd1_ub) goto ; + BNDSTATUS = 0x01; + br_exception(); + +} + +#TODO: This probably cannot be fully modeled +:BNDLDX bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem { +# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU ); +# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU ); + +# core implementation + tmp:8 = *:8 Mem; + bnd1_lb = zext(tmp:4); + tmp2:4 = tmp(4); + bnd1_ub = zext(tmp2); +} + +:BNDMK bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr32 & Mem ) { +# BND.LB and BND.UB set from m32 + bnd1_lb = zext(bndmk_addr32); + bnd1_ub = zext(Mem); +} + +:BNDMOV bnd1, m64 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 { + tmp:8 = m64; + bnd1_lb = zext(tmp:4); + tmp2:4 = tmp(4); + bnd1_ub = zext(tmp2); +} + +:BNDMOV bnd1, bnd2 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 { + bnd1 = bnd2; +} + +:BNDMOV m64, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 { + m64 = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4); +} + +:BNDMOV bnd2, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 { + bnd2 = bnd1; +} + +#TODO: This probably cannot be fully modeled +:BNDSTX Mem, bnd1 is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem { +# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU ); +# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU ); + +# core implementation + *:8 Mem = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4); +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.lang b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.lang new file mode 100644 index 00000000..53252379 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.lang @@ -0,0 +1,150 @@ + + + + x86:LE:16:Real Mode + x86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.trans b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.trans new file mode 100644 index 00000000..5bd8a773 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86RealV1.trans @@ -0,0 +1,7 @@ + + + x86:LE:16:Real Mode + x86:LE:16:Real Mode + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.lang b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.lang new file mode 100644 index 00000000..ae7d23a5 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.lang @@ -0,0 +1,151 @@ + + + + x86:LE:32:default + x86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.trans b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.trans new file mode 100644 index 00000000..bc1ef4c6 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86V1.trans @@ -0,0 +1,8 @@ + + + x86:LE:32:default + x86:LE:32:default + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.lang b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.lang new file mode 100644 index 00000000..0404f968 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.lang @@ -0,0 +1,221 @@ + + + + x64:LE:64:default + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.trans b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.trans new file mode 100644 index 00000000..f50f8aa8 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86_64bit_v1.trans @@ -0,0 +1,8 @@ + + + x64:LE:64:default + x86:LE:64:default + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.lang b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.lang new file mode 100644 index 00000000..ac64bb67 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.lang @@ -0,0 +1,150 @@ + + + + x86:LE:32:System Management Mode + x86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.trans b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.trans new file mode 100644 index 00000000..42e664d4 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/old/x86smmV1.trans @@ -0,0 +1,7 @@ + + + x86:LE:32:System Management Mode + x86:LE:32:System Management Mode + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/pclmulqdq.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/pclmulqdq.sinc new file mode 100644 index 00000000..a1005ef6 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/pclmulqdq.sinc @@ -0,0 +1,173 @@ +# Due to limitations on variable length matching that preclude opcode matching afterwards, all memory addressing forms of PCLMULQDQ are decoded to PCLMULQDQ, not the macro names. +# Display is non-standard, but semantics, and de-compilation should be correct. + +macro pclmul(src1, src2, dest) { + local i:4 = 0:4; + local temp:16 = 0; + + + if (i > 63:4) goto ; + if ((src1 & (1 << i)) == 0) goto ; + temp = temp ^ (src2 << i); + + i = i+1; + goto ; + + dest = temp; +} + +:PCLMULLQLQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x00 +{ + local src1:16 = zext(XmmReg1[0,64]); + local src2:16 = zext(XmmReg2[0,64]); + pclmul(src1,src2,XmmReg1); +} + +:PCLMULHQLQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x01 +{ + local src1:16 = zext(XmmReg1[64,64]); + local src2:16 = zext(XmmReg2[0,64]); + pclmul(src1,src2,XmmReg1); +} + +:PCLMULLQHQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x10 +{ + local src1:16 = zext(XmmReg1[0,64]); + local src2:16 = zext(XmmReg2[64,64]); + pclmul(src1,src2,XmmReg1); +} + +:PCLMULHQHQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x11 +{ + local src1:16 = zext(XmmReg1[64,64]); + local src2:16 = zext(XmmReg2[64,64]); + pclmul(src1,src2,XmmReg1); +} + +:PCLMULQDQ XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; imm8 & imm8_4 & imm8_0 +{ + if (imm8_0:1) goto ; + src1:16 = zext(XmmReg1[0,64]); + goto ; + + + src1 = zext(XmmReg1[64,64]); + + + + if (imm8_4:1) goto ; + src2:16 = zext(XmmReg2[0,64]); + goto ; + + + src2 = zext(XmmReg2[64,64]); + + + + pclmul(src1,src2,XmmReg1); +} + +:PCLMULQDQ XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; XmmReg ... & m128; imm8 & imm8_4 & imm8_0 +{ + if (imm8_0:1) goto ; + src1:16 = zext(XmmReg[0,64]); + goto ; + + + src1 = zext(XmmReg[64,64]); + + + local m:16 = m128; + if (imm8_4:1) goto ; + src2:16 = zext(m[0,64]); + goto ; + + + src2 = zext(m[64,64]); + + + + pclmul(src1,src2,XmmReg); +} + +:VPCLMULLQLQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x00 +{ + local src1:16 = zext(vexVVVV_XmmReg[0,64]); + local src2:16 = zext(XmmReg2[0,64]); + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + +:VPCLMULHQLQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x01 +{ + local src1:16 = zext(vexVVVV_XmmReg[64,64]); + local src2:16 = zext(XmmReg2[0,64]); + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + +:VPCLMULLQHQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x10 +{ + local src1:16 = zext(vexVVVV_XmmReg[0,64]); + local src2:16 = zext(XmmReg2[64,64]); + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + +:VPCLMULHQHQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x11 +{ + local src1:16 = zext(vexVVVV_XmmReg[64,64]); + local src2:16 = zext(XmmReg2[64,64]); + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + +:VPCLMULQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; imm8 & imm8_4 & imm8_0 +{ + if (imm8_0:1) goto ; + src1:16 = zext(vexVVVV_XmmReg[0,64]); + goto ; + + + src1 = zext(vexVVVV_XmmReg[64,64]); + + + + if (imm8_4:1) goto ; + src2:16 = zext(XmmReg2[0,64]); + goto ; + + + src2 = zext(XmmReg2[64,64]); + + + + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + +:VPCLMULQDQ XmmReg1, vexVVVV_XmmReg, m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; (XmmReg1 & YmmReg1) ... & m128; imm8 & imm8_4 & imm8_0 +{ + if (imm8_0:1) goto ; + src1:16 = zext(vexVVVV_XmmReg[0,64]); + goto ; + + + src1 = zext(vexVVVV_XmmReg[64,64]); + + + + local m:16 = m128; + if (imm8_4:1) goto ; + src2:16 = zext(m[0,64]); + goto ; + + + src2 = zext(m[64,64]); + + + + pclmul(src1,src2,XmmReg1); + YmmReg1 = zext(XmmReg1); +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/rdrand.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/rdrand.sinc new file mode 100644 index 00000000..4037bb95 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/rdrand.sinc @@ -0,0 +1,51 @@ +define pcodeop rdrand; +define pcodeop rdrandIsValid; + +macro rdflags(){ + OF = 0; SF = 0; ZF = 0; AF = 0; PF = 0; +} + +:RDRAND Rmr16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; mod=3 & Rmr16 & reg_opcode=6 +{ + Rmr16 = rdrand(); + CF=rdrandIsValid(); + rdflags(); + +} +:RDRAND Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=6 +{ + Rmr32 = rdrand(); + CF=rdrandIsValid(); + rdflags(); +} +@ifdef IA64 +:RDRAND Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=6 +{ + Rmr64 = rdrand(); + CF=rdrandIsValid(); + rdflags(); +} +@endif + +define pcodeop rdseed; +define pcodeop rdseedIsValid; +:RDSEED Rmr16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; mod=3 & Rmr16 & reg_opcode=7 +{ + Rmr16 = rdseed(); + CF=rdseedIsValid(); + rdflags(); +} +:RDSEED Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=7 +{ + Rmr32 = rdseed(); + CF=rdseedIsValid(); + rdflags(); +} +@ifdef IA64 +:RDSEED Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=7 +{ + Rmr64 = rdseed(); + CF=rdseedIsValid(); + rdflags(); +} +@endif diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/sgx.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/sgx.sinc new file mode 100644 index 00000000..9c124e14 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/sgx.sinc @@ -0,0 +1,257 @@ +define pcodeop encls_ecreate; +define pcodeop encls_eadd; +define pcodeop encls_einit; +define pcodeop encls_einit_ZF; +define pcodeop encls_eremove; +define pcodeop encls_eremove_ZF; +define pcodeop encls_edbgrd; +define pcodeop encls_edbgrd_RBX; +define pcodeop encls_edbgwr; +define pcodeop encls_eextend; +define pcodeop encls_eldb; +define pcodeop encls_eldb_ZF; +define pcodeop encls_eldu; +define pcodeop encls_eldu_ZF; +define pcodeop encls_eblock; +define pcodeop encls_eblock_ZF; +define pcodeop encls_epa; +define pcodeop encls_ewb; +define pcodeop encls_ewb_ZF; +define pcodeop encls_ewb_CF; +define pcodeop encls_etrack; +define pcodeop encls_etrack_ZF; +define pcodeop encls_eaug; +define pcodeop encls_emodpr; +define pcodeop encls_emodpr_ZF; +define pcodeop encls_emodt; +define pcodeop encls_emodt_ZF; +define pcodeop encls_unknown; + +:ENCLS is vexMode=0 & byte=0x0f; byte=0x01; byte=0xcf { + + if ( EAX != 0x0 ) goto ; + encls_ecreate( RBX, RCX ); + goto ; + + + if ( EAX != 0x1 ) goto ; + encls_eadd( RBX, RCX ); + goto ; + + + if ( EAX != 0x2 ) goto ; + RAX = encls_einit( RBX, RCX, RDX ); + ZF = encls_einit_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x3 ) goto ; + RAX = encls_eremove( RCX ); + ZF = encls_eremove_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x4 ) goto ; + RAX = encls_edbgrd( RCX ); + RBX = encls_edbgrd_RBX( RCX ); + goto ; + + + if ( EAX != 0x5 ) goto ; + RAX = encls_edbgwr( RBX, RCX ); + goto ; + + + if ( EAX != 0x6 ) goto ; + encls_eextend( RBX, RCX ); + goto ; + + + if ( EAX != 0x7 ) goto ; + RAX = encls_eldb( RBX, RCX, RDX ); + ZF = encls_eldb_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x8 ) goto ; + RAX = encls_eldu( RBX, RCX, RDX ); + ZF = encls_eldu_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x9 ) goto ; + RAX = encls_eblock( RCX ); + ZF = encls_eblock_ZF( RCX ); + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0xA ) goto ; + encls_epa( RBX, RCX ); + goto ; + + + if ( EAX != 0xB ) goto ; + RAX = encls_ewb( RBX, RCX, RDX ); + ZF = encls_ewb_ZF( RBX, RCX, RDX ); + CF = encls_ewb_CF( RBX, RCX, RDX ); + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0xC ) goto ; + RAX = encls_etrack( RCX ); + ZF = encls_etrack_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0xD ) goto ; + encls_eaug( RBX, RCX, RDX ); + goto ; + + + if ( EAX != 0xE ) goto ; + RAX = encls_emodpr( RBX, RCX ); + ZF = encls_emodpr_ZF( RCX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0xF ) goto ; + RAX = encls_emodt( RBX, RCX ); + ZF = encls_emodt_ZF( RCX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + encls_unknown(); + + +} + + +define pcodeop enclu_ereport; +define pcodeop enclu_egetkey; +define pcodeop enclu_egetkey_ZF; +define pcodeop enclu_eenter_EAX; +define pcodeop enclu_eenter_RCX; +define pcodeop enclu_eenter_TF; +define pcodeop enclu_eresume; +define pcodeop enclu_eexit; +define pcodeop enclu_eexit_TF; +define pcodeop enclu_eaccept; +define pcodeop enclu_eaccept_ZF; +define pcodeop enclu_emodpe; +define pcodeop enclu_eacceptcopy; +define pcodeop enclu_eacceptcopy_ZF; +define pcodeop enclu_unknown; + +:ENCLU is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd7 { + + if ( EAX != 0x0 ) goto ; + enclu_ereport( RBX, RCX, RDX ); + goto ; + + + if ( EAX != 0x1 ) goto ; + RAX = enclu_egetkey( RBX, RCX ); + ZF = enclu_egetkey_ZF( RBX, RCX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x2 ) goto ; + tempBX:8 = RBX; + tempCX:8 = RCX; + + EAX = enclu_eenter_EAX( tempBX, tempCX ); + RCX = enclu_eenter_RCX( tempBX, tempCX ); + TF = enclu_eenter_TF( tempBX, tempCX ); + goto ; + + + if ( EAX != 0x3 ) goto ; + TF = enclu_eresume( RBX, RCX ); + goto ; + + + if ( EAX != 0x4 ) goto ; + RCX = enclu_eexit( RBX ); + TF = enclu_eexit_TF( RBX ); + goto ; + + + if ( EAX != 0x5 ) goto ; + RAX = enclu_eaccept( RBX, RCX ); + ZF = enclu_eaccept_ZF( RBX, RCX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + if ( EAX != 0x6 ) goto ; + enclu_emodpe( RBX, RCX ); + goto ; + + + if ( EAX != 0x7 ) goto ; + RAX = enclu_eacceptcopy( RBX, RCX, RDX ); + ZF = enclu_eacceptcopy_ZF( RBX, RCX, RDX ); + CF = 0; + PF = 0; + AF = 0; + OF = 0; + SF = 0; + goto ; + + + enclu_unknown(); + + +} diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/sha.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/sha.sinc new file mode 100644 index 00000000..91914175 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/sha.sinc @@ -0,0 +1,53 @@ +# INFO This file automatically generated by andre on Fri Mar 16 15:13:25 2018 +# INFO Direct edits to this file may be lost in future updates +# INFO Command line arguments: ['--sinc', '--cpuid-match', 'SHA'] + +# SHA1RNDS4 4-602 PAGE 1722 LINE 89511 +define pcodeop sha1rnds4_sha ; +:SHA1RNDS4 XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & byte=0x0F; byte=0x3A; byte=0xCC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8 +{ + XmmReg1 = sha1rnds4_sha( XmmReg1, XmmReg2_m128, imm8:1 ); +} + +# SHA1NEXTE 4-604 PAGE 1724 LINE 89602 +define pcodeop sha1nexte_sha ; +:SHA1NEXTE XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xC8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1 = sha1nexte_sha( XmmReg1, XmmReg2_m128 ); +} + +# SHA1MSG1 4-605 PAGE 1725 LINE 89654 +define pcodeop sha1msg1_sha ; +:SHA1MSG1 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xC9; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1 = sha1msg1_sha( XmmReg1, XmmReg2_m128 ); +} + +# SHA1MSG2 4-606 PAGE 1726 LINE 89708 +define pcodeop sha1msg2_sha ; +:SHA1MSG2 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1 = sha1msg2_sha( XmmReg1, XmmReg2_m128 ); +} + +# SHA256RNDS2 4-607 PAGE 1727 LINE 89765 +define pcodeop sha256rnds2_sha ; +:SHA256RNDS2 XmmReg1, XmmReg2_m128, XMM0 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCB; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 & XMM0 +{ + XmmReg1 = sha256rnds2_sha( XmmReg1, XmmReg2_m128, XMM0 ); +} + +# SHA256MSG1 4-609 PAGE 1729 LINE 89847 +define pcodeop sha256msg1_sha ; +:SHA256MSG1 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1 = sha256msg1_sha( XmmReg1, XmmReg2_m128 ); +} + +# SHA256MSG2 4-610 PAGE 1730 LINE 89900 +define pcodeop sha256msg2_sha ; +:SHA256MSG2 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCD; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 +{ + XmmReg1 = sha256msg2_sha( XmmReg1, XmmReg2_m128 ); +} + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/smx.sinc b/src/icicle/data/Ghidra/Processors/x86/data/languages/smx.sinc new file mode 100644 index 00000000..67f1c1e5 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/smx.sinc @@ -0,0 +1,67 @@ +define pcodeop getsec_capabilities; +define pcodeop getsec_enteraccs; +define pcodeop getsec_exitac; +define pcodeop getsec_senter; +define pcodeop getsec_sexit; +define pcodeop getsec_parameters_EAX; +define pcodeop getsec_parameters_EBX; +define pcodeop getsec_parameters_ECX; +define pcodeop getsec_smctrl; +define pcodeop getsec_wakeup; +define pcodeop getsec_unknown; + + +:GETSEC is vexMode=0 & byte=0x0f; byte=0x37 { + + if ( EAX != 0x0 ) goto ; + EAX = 0; + if ( EBX != 0x0 ) goto ; + EAX = getsec_capabilities( EBX ); + goto ; + + + if ( EAX != 0x2 ) goto ; + getsec_enteraccs( EBX, ECX ); + goto ; + + + if ( EAX != 0x3 ) goto ; +@ifdef IA64 + getsec_exitac( RBX, EDX ); +@else + getsec_exitac( EBX, EDX ); +@endif + goto ; + + + if ( EAX != 0x4 ) goto ; + getsec_senter( EBX, ECX, EDX); + goto ; + + + if ( EAX != 0x5 ) goto ; + getsec_sexit(); + goto ; + + + if ( EAX != 0x6 ) goto ; + EAX = getsec_parameters_EAX( EBX ); + ECX = getsec_parameters_ECX( EBX ); + EBX = getsec_parameters_EBX( EBX ); + goto ; + + + if ( EAX != 0x7 ) goto ; + getsec_smctrl(EBX); + goto ; + + + if ( EAX != 0x8 ) goto ; + getsec_wakeup(); + goto ; + + + getsec_unknown(); + + +} diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16-real.pspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16-real.pspec new file mode 100644 index 00000000..ba7ff912 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16-real.pspec @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.cspec new file mode 100644 index 00000000..f07cea0b --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.cspec @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.gdis b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.gdis new file mode 100644 index 00000000..2efbfd61 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.gdis @@ -0,0 +1,3 @@ + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.pspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.pspec new file mode 100644 index 00000000..ae2d69c7 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-16.pspec @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-gcc.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-gcc.cspec new file mode 100644 index 00000000..7b7ca230 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-gcc.cspec @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-win.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-win.cspec new file mode 100644 index 00000000..907f9814 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64-win.cspec @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.dwarf b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.dwarf new file mode 100644 index 00000000..c8218184 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.dwarf @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.pspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.pspec new file mode 100644 index 00000000..315344dc --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.pspec @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.slaspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.slaspec new file mode 100644 index 00000000..8b442ec1 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86-64.slaspec @@ -0,0 +1,6 @@ +@define IA64 "IA64" +@include "x86.slaspec" +with : lockprefx=0 { +@include "sgx.sinc" +@include "fma.sinc" +} diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.dwarf b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.dwarf new file mode 100644 index 00000000..154617ec --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.dwarf @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.ldefs b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.ldefs new file mode 100644 index 00000000..482ef9e3 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.ldefs @@ -0,0 +1,98 @@ + + + + + Intel/AMD 32-bit x86 + + + + + + + + + + + + + + + + + + + + Intel/AMD 32-bit x86 System Management Mode + + + + + Intel/AMD 16-bit x86 Real Mode + + + + + + + + + + + + Intel/AMD 16-bit x86 Protected Mode + + + + + + + Intel/AMD 64-bit x86 + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.opinion b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.opinion new file mode 100644 index 00000000..ef5283f7 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.opinion @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.pspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.pspec new file mode 100644 index 00000000..595d1e2d --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.pspec @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.slaspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.slaspec new file mode 100644 index 00000000..4c1962c0 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86.slaspec @@ -0,0 +1,19 @@ +@include "ia.sinc" +@include "lockable.sinc" +with : lockprefx=0 { +@include "avx.sinc" +@include "avx_manual.sinc" +@include "avx2.sinc" +@include "avx2_manual.sinc" +@include "adx.sinc" +@include "clwb.sinc" +@include "pclmulqdq.sinc" +@include "mpx.sinc" +@include "lzcnt.sinc" +@include "bmi1.sinc" +@include "bmi2.sinc" +@include "sha.sinc" +@include "smx.sinc" +@include "cet.sinc" +@include "rdrand.sinc" +} diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86borland.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86borland.cspec new file mode 100644 index 00000000..c17bca69 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86borland.cspec @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86delphi.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86delphi.cspec new file mode 100644 index 00000000..8f042482 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86delphi.cspec @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86gcc.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86gcc.cspec new file mode 100644 index 00000000..bcd049d2 --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86gcc.cspec @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icicle/data/Ghidra/Processors/x86/data/languages/x86win.cspec b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86win.cspec new file mode 100644 index 00000000..c07b7e4d --- /dev/null +++ b/src/icicle/data/Ghidra/Processors/x86/data/languages/x86win.cspec @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 102676b51ccdbb88cf5bf6677a6b835668021b8a Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 4 Apr 2025 16:16:40 +0200 Subject: [PATCH 3/6] Unify environment variables --- .github/workflows/build.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab0b53d5..2afb2310 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -301,15 +301,11 @@ jobs: with: submodules: recursive - - name: Setup Asan Environment Variables - if: ${{ contains(matrix.platform, 'Sanitizer') }} + - name: Setup Environment Variables run: | + echo "RUST_BACKTRACE=1" >> $GITHUB_ENV echo "ASAN_OPTIONS=detect_odr_violation=0" >> $GITHUB_ENV - - - name: Setup Icicle Environment Variables - if: ${{ matrix.emulator == 'Icicle' }} - run: | - echo "EMULATOR_ICICLE=1" >> $GITHUB_ENV + echo "EMULATOR_ICICLE=${{ matrix.emulator == 'Icicle' }}" >> $GITHUB_ENV - name: Download Test Configuration uses: actions/download-artifact@v4.2.1 From b69611742405b05f2c9a10e76fe5846b8b042365 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 4 Apr 2025 19:13:35 +0200 Subject: [PATCH 4/6] Add safety checks --- src/icicle/src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/icicle/src/lib.rs b/src/icicle/src/lib.rs index 0e6eab75..1df8d39b 100644 --- a/src/icicle/src/lib.rs +++ b/src/icicle/src/lib.rs @@ -104,6 +104,14 @@ pub fn icicle_write_memory( data: *const c_void, size: usize, ) -> i32 { + if size == 0 { + return 1; + } + + if data.is_null() { + return 0; + } + unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts(data as *const u8, size); @@ -127,6 +135,10 @@ pub fn icicle_save_registers(ptr: *mut c_void, accessor: DataFunction, accessor_ #[unsafe(no_mangle)] pub fn icicle_restore_registers(ptr: *mut c_void, data: *const c_void, size: usize) { + if size == 0 || data.is_null() { + return; + } + unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts(data as *const u8, size); @@ -136,6 +148,14 @@ pub fn icicle_restore_registers(ptr: *mut c_void, data: *const c_void, size: usi #[unsafe(no_mangle)] pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, size: usize) -> i32 { + if size == 0 { + return 1; + } + + if data.is_null() { + return 0; + } + unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size); @@ -192,6 +212,14 @@ pub fn icicle_read_register( data: *mut c_void, size: usize, ) -> usize { + if size == 0 { + return 1; + } + + if data.is_null() { + return 0; + } + unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size); @@ -206,6 +234,14 @@ pub fn icicle_write_register( data: *const c_void, size: usize, ) -> usize { + if size == 0 { + return 1; + } + + if data.is_null() { + return 0; + } + unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts(data as *const u8, size); From d191f8e66701e79ffc1e2b9d58cf76b6834eec7e Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 5 Apr 2025 08:55:08 +0200 Subject: [PATCH 5/6] Optimize MMIO handling --- src/emulator/memory_interface.hpp | 4 +-- src/icicle-emulator/icicle_x64_emulator.cpp | 29 ++++------------- src/icicle/src/lib.rs | 8 ++--- src/unicorn-emulator/unicorn_x64_emulator.cpp | 32 +++++++++++++++---- src/windows-emulator/kusd_mmio.cpp | 25 ++++++--------- src/windows-emulator/kusd_mmio.hpp | 2 +- src/windows-emulator/memory_manager.hpp | 4 +-- 7 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/emulator/memory_interface.hpp b/src/emulator/memory_interface.hpp index 3cdcc895..2f735e9a 100644 --- a/src/emulator/memory_interface.hpp +++ b/src/emulator/memory_interface.hpp @@ -4,8 +4,8 @@ #include "memory_permission.hpp" -using mmio_read_callback = std::function; -using mmio_write_callback = std::function; +using mmio_read_callback = std::function; +using mmio_write_callback = std::function; class memory_manager; diff --git a/src/icicle-emulator/icicle_x64_emulator.cpp b/src/icicle-emulator/icicle_x64_emulator.cpp index 31b62ce6..d6fddef1 100644 --- a/src/icicle-emulator/icicle_x64_emulator.cpp +++ b/src/icicle-emulator/icicle_x64_emulator.cpp @@ -12,8 +12,8 @@ extern "C" using violation_func = int32_t(void*, uint64_t address, uint8_t operation, int32_t unmapped); using data_accessor_func = void(void* user, const void* data, size_t length); - using icicle_mmio_read_func = void(void* user, uint64_t address, size_t length, void* data); - using icicle_mmio_write_func = void(void* user, uint64_t address, size_t length, const void* data); + using icicle_mmio_read_func = void(void* user, uint64_t address, void* data, size_t length); + using icicle_mmio_write_func = void(void* user, uint64_t address, const void* data, size_t length); icicle_emulator* icicle_create_emulator(); int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions); @@ -185,31 +185,14 @@ namespace icicle auto* ptr = wrapper.get(); this->storage_.push_back(std::move(wrapper)); - auto* read_wrapper = +[](void* user, const uint64_t addr, const size_t length, void* data) { - constexpr auto limit = sizeof(uint64_t); + auto* read_wrapper = +[](void* user, const uint64_t addr, void* data, const size_t length) { const auto* w = static_cast(user); - - // TODO: Change interface to get rid of loop - for (size_t offset = 0; offset < length; offset += limit) - { - const auto max_read = std::min(limit, length - offset); - const auto value = w->read_cb(addr + offset - w->base, max_read); - memcpy(static_cast(data) + offset, &value, max_read); - } + w->read_cb(addr - w->base, data, length); }; - auto* write_wrapper = +[](void* user, const uint64_t addr, const size_t length, const void* data) { - constexpr auto limit = sizeof(uint64_t); + auto* write_wrapper = +[](void* user, const uint64_t addr, const void* data, const size_t length) { const auto* w = static_cast(user); - - // TODO: Change interface to get rid of loop - for (size_t offset = 0; offset < length; offset += limit) - { - uint64_t value{}; - const auto max_read = std::min(limit, length - offset); - memcpy(&value, static_cast(data) + offset, max_read); - w->write_cb(addr + offset - w->base, max_read, value); - } + w->write_cb(addr + w->base, data, length); }; icicle_map_mmio(this->emu_, address, size, read_wrapper, ptr, write_wrapper, ptr); diff --git a/src/icicle/src/lib.rs b/src/icicle/src/lib.rs index 1df8d39b..dab13cfb 100644 --- a/src/icicle/src/lib.rs +++ b/src/icicle/src/lib.rs @@ -38,8 +38,8 @@ pub fn icicle_stop(ptr: *mut c_void) { type RawFunction = extern "C" fn(*mut c_void); type PtrFunction = extern "C" fn(*mut c_void, u64); type DataFunction = extern "C" fn(*mut c_void, *const c_void, usize); -type MmioReadFunction = extern "C" fn(*mut c_void, u64, usize, *mut c_void); -type MmioWriteFunction = extern "C" fn(*mut c_void, u64, usize, *const c_void); +type MmioReadFunction = extern "C" fn(*mut c_void, u64, *mut c_void, usize); +type MmioWriteFunction = extern "C" fn(*mut c_void, u64, *const c_void, usize); type ViolationFunction = extern "C" fn(*mut c_void, u64, u8, i32) -> i32; #[unsafe(no_mangle)] @@ -57,12 +57,12 @@ pub fn icicle_map_mmio( let read_wrapper = Box::new(move |addr: u64, data: &mut [u8]| { let raw_pointer: *mut u8 = data.as_mut_ptr(); - read_cb(read_data, addr, data.len(), raw_pointer as *mut c_void); + read_cb(read_data, addr, raw_pointer as *mut c_void, data.len()); }); let write_wrapper = Box::new(move |addr: u64, data: &[u8]| { let raw_pointer: *const u8 = data.as_ptr(); - write_cb(write_data, addr, data.len(), raw_pointer as *const c_void); + write_cb(write_data, addr, raw_pointer as *const c_void, data.len()); }); let res = emulator.map_mmio(address, length, read_wrapper, write_wrapper); diff --git a/src/unicorn-emulator/unicorn_x64_emulator.cpp b/src/unicorn-emulator/unicorn_x64_emulator.cpp index f26dddda..de01afcf 100644 --- a/src/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/unicorn-emulator/unicorn_x64_emulator.cpp @@ -243,6 +243,14 @@ namespace unicorn return block; } + void assert_64bit_limit(const size_t size) + { + if (size > sizeof(uint64_t)) + { + throw std::runtime_error("Exceeded uint64_t size limit"); + } + } + class unicorn_x64_emulator : public x64_emulator { public: @@ -370,13 +378,23 @@ namespace unicorn void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb) override { - mmio_callbacks cb{.read = mmio_callbacks::read_wrapper( - [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s) { - return c(addr, s); - }), - .write = mmio_callbacks::write_wrapper( - [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s, - const uint64_t value) { c(addr, s, value); })}; + auto read_wrapper = [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s) { + assert_64bit_limit(s); + uint64_t value{}; + c(addr, &value, s); + return value; + }; + + auto write_wrapper = [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s, + const uint64_t value) { + assert_64bit_limit(s); + c(addr, &value, s); + }; + + mmio_callbacks cb{ + .read = mmio_callbacks::read_wrapper(std::move(read_wrapper)), + .write = mmio_callbacks::write_wrapper(std::move(write_wrapper)), + }; uce(uc_mmio_map(*this, address, size, cb.read.get_c_function(), cb.read.get_user_data(), cb.write.get_c_function(), cb.write.get_user_data())); diff --git a/src/windows-emulator/kusd_mmio.cpp b/src/windows-emulator/kusd_mmio.cpp index 136ecbc7..856d7187 100644 --- a/src/windows-emulator/kusd_mmio.cpp +++ b/src/windows-emulator/kusd_mmio.cpp @@ -83,13 +83,13 @@ namespace namespace utils { - inline void serialize(buffer_serializer& buffer, const KUSER_SHARED_DATA64& kusd) + static void serialize(buffer_serializer& buffer, const KUSER_SHARED_DATA64& kusd) { static_assert(KUSD_SIZE == sizeof(kusd)); buffer.write(&kusd, KUSD_SIZE); } - inline void deserialize(buffer_deserializer& buffer, KUSER_SHARED_DATA64& kusd) + static void deserialize(buffer_deserializer& buffer, KUSER_SHARED_DATA64& kusd) { buffer.read(&kusd, KUSD_SIZE); } @@ -130,30 +130,21 @@ void kusd_mmio::deserialize(utils::buffer_deserializer& buffer) this->register_mmio(); } -uint64_t kusd_mmio::read(const uint64_t addr, const size_t size) +void kusd_mmio::read(const uint64_t addr, void* data, const size_t size) { - uint64_t result{}; - this->update(); if (addr >= KUSD_SIZE) { - return result; + return; } const auto end = addr + size; const auto valid_end = std::min(end, static_cast(KUSD_SIZE)); const auto real_size = valid_end - addr; - if (real_size > sizeof(result)) - { - return result; - } - const auto* kusd_buffer = reinterpret_cast(&this->kusd_); - memcpy(&result, kusd_buffer + addr, real_size); - - return result; + memcpy(data, kusd_buffer + addr, real_size); } uint64_t kusd_mmio::address() @@ -178,8 +169,10 @@ void kusd_mmio::register_mmio() this->memory_->allocate_mmio( KUSD_ADDRESS, KUSD_BUFFER_SIZE, - [this](const uint64_t addr, const size_t size) { return this->read(addr, size); }, - [](const uint64_t, const size_t, const uint64_t) { + [this](const uint64_t addr, void* data, const size_t size) { + this->read(addr, data, size); // + }, + [](const uint64_t, const void*, const size_t) { // Writing not supported! }); } diff --git a/src/windows-emulator/kusd_mmio.hpp b/src/windows-emulator/kusd_mmio.hpp index 24c4df53..bba54287 100644 --- a/src/windows-emulator/kusd_mmio.hpp +++ b/src/windows-emulator/kusd_mmio.hpp @@ -48,7 +48,7 @@ class kusd_mmio KUSER_SHARED_DATA64 kusd_{}; - uint64_t read(uint64_t addr, size_t size); + void read(uint64_t addr, void* data, size_t size); void update(); diff --git a/src/windows-emulator/memory_manager.hpp b/src/windows-emulator/memory_manager.hpp index 02e0aa07..92daab60 100644 --- a/src/windows-emulator/memory_manager.hpp +++ b/src/windows-emulator/memory_manager.hpp @@ -20,8 +20,8 @@ struct region_info : basic_memory_region bool is_committed{}; }; -using mmio_read_callback = std::function; -using mmio_write_callback = std::function; +using mmio_read_callback = std::function; +using mmio_write_callback = std::function; class memory_manager : public memory_interface { From dd7a80a9f058b675dc9b3cd8d270bab8dcaea835 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 5 Apr 2025 09:03:19 +0200 Subject: [PATCH 6/6] Disable icicle tests --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2afb2310..2e2726cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -270,7 +270,7 @@ jobs: - macOS x86_64 emulator: - Unicorn - - Icicle + #- Icicle emulation-root: - Windows 2025 - Windows 2022 @@ -354,7 +354,7 @@ jobs: #- arm64-v8a emulator: - Unicorn - - Icicle + #- Icicle emulation-root: - Windows 2025 - Windows 2022