[ABI] Accumulated API/ABI changes

* Renamed all eq() methods to equals() (consistency) (ABI)
  * Reorganized some X86 instructions in X86 database
  * Properly detect RISC-V CPU at compile time (Environment)
  * Removed CallConvId::kNone in favor of defaulting to kCDecl (ABI)
  * CallConvId::kHost is now alias to CallConvId::kCDecl (ABI)
  * Added FloatABI to Environment to disginguish between softfloat
    and hardfloat
  * Added more AArch64 CPU features and their detection (ABI)
  * Because of CallConvId changes it's now possible to run
    compiler tests on 32-bit ARM (fixes a bug in test cases)
  * Added QEMU to CI build matrix to test different architectures
This commit is contained in:
kobalicek
2024-01-01 20:15:00 +01:00
parent a465fe71ab
commit 3772c447ca
31 changed files with 1828 additions and 1041 deletions

View File

@@ -31,108 +31,113 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { title: "linux-lib" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", conf: "Debug" } - { title: "linux-lib" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Debug" }
- { title: "macos-lib" , os: "macos-latest" , cc: "clang" , arch: "x64", conf: "Debug" } - { title: "macos-lib" , host: "macos-latest" , arch: "x64" , cc: "clang" , conf: "Debug" }
- { title: "windows-lib" , os: "windows-latest", cc: "vs2022" , arch: "x64", conf: "Debug" } - { title: "windows-lib" , host: "windows-latest", arch: "x64" , cc: "vs2022" , conf: "Debug" }
- { title: "diag-analyze" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Debug" , diagnostics: "analyze-build" } - { title: "diag-analyze" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Debug" , diagnostics: "analyze-build" }
- { title: "diag-asan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "asan", defs: "ASMJIT_TEST=1" } - { title: "diag-asan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", diagnostics: "asan", defs: "ASMJIT_TEST=1" }
- { title: "diag-msan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "msan", defs: "ASMJIT_TEST=1" } - { title: "diag-msan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", diagnostics: "msan", defs: "ASMJIT_TEST=1" }
- { title: "diag-ubsan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "ubsan", defs: "ASMJIT_TEST=1" } - { title: "diag-ubsan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", diagnostics: "ubsan", defs: "ASMJIT_TEST=1" }
- { title: "diag-valgrind" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "valgrind", defs: "ASMJIT_TEST=1" } - { title: "diag-valgrind" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", diagnostics: "valgrind", defs: "ASMJIT_TEST=1" }
- { title: "no-deprecated" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" } - { title: "no-deprecated" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" }
- { title: "no-intrinsics" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" } - { title: "no-intrinsics" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" }
- { title: "no-logging" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" } - { title: "no-logging" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" }
- { title: "no-logging-text" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" } - { title: "no-logging-text" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" }
- { title: "no-builder" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" } - { title: "no-builder" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" }
- { title: "no-compiler" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" } - { title: "no-compiler" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" }
- { title: "no-introspection", os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" } - { title: "no-introspection", host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" }
- { title: "no-jit" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" } - { title: "no-jit" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" }
- { title: "no-validation" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" } - { title: "no-validation" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" }
- { title: "no-x86" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" } - { title: "no-x86" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" }
- { title: "no-aarch64" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" } - { title: "no-aarch64" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "gcc-7" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "gcc-7" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "gcc-7" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "gcc-7" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "gcc-8" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "gcc-8" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "gcc-8" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "gcc-8" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "clang-10", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x86" , cc: "clang-10", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "clang-10", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-20.04" , arch: "x64" , cc: "clang-10", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-11", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-11", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-12", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-12", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-13", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-13", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "macos" , host: "macos-12" , arch: "x64" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "macos" , host: "macos-12" , arch: "x64" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "macos" , host: "macos-12" , arch: "x64" , cc: "clang" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "macos" , host: "macos-12" , arch: "x64" , cc: "clang" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2019" , arch: "x86" , cc: "vs2019" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2019" , arch: "x86" , cc: "vs2019" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2019" , arch: "x64" , cc: "vs2019" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2019" , arch: "x64" , cc: "vs2019" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "freebsd", osver: "13.2", cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "freebsd" , host: "macos-12" , arch: "x86-64" , cc: "clang" , conf: "Release", vm: "freebsd", vm_ver: "13.2", defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "netbsd" , osver: "9.3" , cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "netbsd" , host: "macos-12" , arch: "x86-64" , cc: "clang" , conf: "Release", vm: "netbsd" , vm_ver: "9.3" , defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "openbsd" , host: "macos-12" , arch: "x86-64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" }
- { host: "ubuntu-latest" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "arm64" , conf: "Release", defs: "ASMJIT_TEST=1" } - { title: "openbsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" }
name: "${{matrix.title || format('{0}-{1}', matrix.os, matrix.osver)}} (${{matrix.cc}}, ${{matrix.arch}}, ${{matrix.conf}})" - { title: "debian" , host: "ubuntu-latest" , arch: "arm/v7" , cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
runs-on: "${{matrix.host || matrix.os}}" - { title: "debian" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
- { title: "debian" , host: "ubuntu-latest" , arch: "riscv64", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
- { title: "debian" , host: "ubuntu-latest" , arch: "ppc64le", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
name: "${{matrix.title}}/${{matrix.arch}}, ${{matrix.cc}} ${{matrix.conf}}"
runs-on: "${{matrix.host}}"
steps: steps:
- name: "Checkout" - name: "Checkout"
@@ -151,8 +156,14 @@ jobs:
with: with:
python-version: "3.x" python-version: "3.x"
- name: "Build & Test" - name: QEMU
if: ${{!matrix.host}} if: ${{matrix.vm && !matrix.vm_ver}}
uses: docker/setup-qemu-action@v3
with:
platforms: linux/${{matrix.arch}}
- name: "Build & Test - Native"
if: ${{!matrix.vm}}
run: python build-actions/action.py run: python build-actions/action.py
--step=all --step=all
--source-dir=source --source-dir=source
@@ -164,13 +175,15 @@ jobs:
--build-type=${{matrix.conf}} --build-type=${{matrix.conf}}
--build-defs=${{matrix.defs}} --build-defs=${{matrix.defs}}
- name: "Build & Test in VM" - name: "Build & Test - Cross Platform Actions"
if: ${{matrix.host}} if: ${{matrix.vm && matrix.vm_ver}}
uses: cross-platform-actions/action@master uses: cross-platform-actions/action@master
with: with:
operating_system: ${{matrix.os}} operating_system: ${{matrix.vm}}
architecture: ${{matrix.arch}} architecture: ${{matrix.arch}}
version: ${{matrix.osver}} version: ${{matrix.vm_ver}}
sync_files: "runner-to-vm"
shutdown_vm: false
shell: bash shell: bash
run: | run: |
set -e set -e
@@ -182,13 +195,33 @@ jobs:
export CI_NETBSD_USE_PKGIN export CI_NETBSD_USE_PKGIN
sh ./build-actions/prepare-environment.sh sh ./build-actions/prepare-environment.sh
python3 build-actions/action.py \ python3 build-actions/action.py \
--step=all \ --step=all \
--source-dir=source \ --source-dir=source \
--config=source/.github/workflows/build-config.json \ --config=source/.github/workflows/build-config.json \
--compiler=${{matrix.cc}} \ --compiler=${{matrix.cc}} \
--diagnostics=${{matrix.diagnostics}} \ --diagnostics=${{matrix.diagnostics}} \
--architecture=${{matrix.arch}} \ --architecture=${{matrix.arch}} \
--problem-matcher=auto \ --problem-matcher=auto \
--build-type=${{matrix.conf}} \ --build-type=${{matrix.conf}} \
--build-defs=${{matrix.defs}} --build-defs=${{matrix.defs}}
- name: "Build & Test - Docker + QEMU"
if: ${{matrix.vm && !matrix.vm_ver}}
run: |
docker run \
--rm \
-v $(pwd):/${{github.workspace}} \
-w ${{github.workspace}}/build-actions \
--platform linux/${{matrix.arch}} \
${{matrix.vm}} \
bash action.sh \
--step=all \
--source-dir=../source \
--config=../source/.github/workflows/build-config.json \
--compiler=${{matrix.cc}} \
--diagnostics=${{matrix.diagnostics}} \
--architecture=${{matrix.arch}} \
--problem-matcher=auto \
--build-type=${{matrix.conf}} \
--build-defs=${{matrix.defs}}

View File

@@ -341,13 +341,13 @@
{"inst": "or x:ax, iw/uw" , "op": "66 0D iw" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true}, {"inst": "or x:ax, iw/uw" , "op": "66 0D iw" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true},
{"inst": "or X:eax, id/ud" , "op": "0D id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true}, {"inst": "or X:eax, id/ud" , "op": "0D id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true},
{"inst": "or X:rax, id" , "op": "REX.W 0D id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true}, {"inst": "or X:rax, id" , "op": "REX.W 0D id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0", "altForm": true},
{"inst": "[lock|xacqrel] or x:r8/m8, ib/ub" , "op": "M: 80 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or x:r8/m8, ib/ub" , "op": "M: 80 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or x:r16/m16, iw/uw" , "op": "M: 66 81 /1 iw" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or x:r16/m16, iw/uw" , "op": "M: 66 81 /1 iw" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or X:r32/m32, id/ud" , "op": "M: 81 /1 id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or X:r32/m32, id/ud" , "op": "M: 81 /1 id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or X:r64/m64, id" , "op": "M: REX.W 81 /1 id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or X:r64/m64, id" , "op": "M: REX.W 81 /1 id" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or x:r16/m16, ib" , "op": "M: 66 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or x:r16/m16, ib" , "op": "M: 66 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or X:r32/m32, ib" , "op": "M: 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or X:r32/m32, ib" , "op": "M: 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or X:r64/m64, ib" , "op": "M: REX.W 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or X:r64/m64, ib" , "op": "M: REX.W 83 /1 ib" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or x:~r8/m8, ~r8" , "op": "MR: 08 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or x:~r8/m8, ~r8" , "op": "MR: 08 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or x:~r16/m16, ~r16" , "op": "MR: 66 09 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or x:~r16/m16, ~r16" , "op": "MR: 66 09 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
{"inst": "[lock|xacqrel] or X:~r32/m32, ~r32" , "op": "MR: 09 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"}, {"inst": "[lock|xacqrel] or X:~r32/m32, ~r32" , "op": "MR: 09 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=W CF=0"},
@@ -624,200 +624,405 @@
{"inst": "[rep] outs R:dx, R:m32(ds:zsi)" , "op": "6F"} {"inst": "[rep] outs R:dx, R:m32(ds:zsi)" , "op": "6F"}
]}, ]},
{"category": "GP GP_EXT", "data": [ {"category": "GP GP_EXT", "ext": "I486", "data": [
{"inst": "aadd X:m32, r32" , "op": "MR: 0F 38 FC /r" , "ext": "RAO_INT"}, {"inst": "[lock|xacqrel] cmpxchg x:r8/m8, r8, <al>" , "op": "MR: 0F B0 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "aadd X:m64, r64" , "op": "MR: REX.W 0F 38 FC /r" , "ext": "RAO_INT"}, {"inst": "[lock|xacqrel] cmpxchg x:r16/m16, r16, <ax>" , "op": "MR: 66 0F B1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "aand X:m32, r32" , "op": "MR: 66 0F 38 FC /r" , "ext": "RAO_INT"}, {"inst": "[lock|xacqrel] cmpxchg X:r32/m32, r32, <eax>" , "op": "MR: 0F B1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "aand X:m64, r64" , "op": "MR: REX.W 66 0F 38 FC /r" , "ext": "RAO_INT"}, {"inst": "[lock|xacqrel] cmpxchg X:r64/m64, r64, <rax>" , "op": "MR: REX.W 0F B1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "adcx X:~r32, ~r32/m32" , "op": "RM: 66 0F 38 F6 /r" , "ext": "ADX" , "io": "CF=X"}, {"inst": "cpuid X:<eax>, W:<ebx>, X:<ecx>, W:<edx>" , "op": "0F A2" , "volatile": true},
{"inst": "adcx X:~r64, ~r64/m64" , "op": "RM: REX.W 66 0F 38 F6 /r" , "ext": "ADX" , "io": "CF=X"}, {"inst": "[lock|xacqrel] xadd x:r8/m8, x:r8" , "op": "MR: 0F C0 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "adox X:~r32, ~r32/m32" , "op": "RM: F3 0F 38 F6 /r" , "ext": "ADX" , "io": "OF=X"}, {"inst": "[lock|xacqrel] xadd x:r16/m16, x:r16" , "op": "MR: 66 0F C1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "adox X:~r64, ~r64/m64" , "op": "RM: REX.W F3 0F 38 F6 /r" , "ext": "ADX" , "io": "OF=X"}, {"inst": "[lock|xacqrel] xadd X:r32/m32, X:r32" , "op": "MR: 0F C1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "andn W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.0F38.W0 F2 /r" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=0"}, {"inst": "[lock|xacqrel] xadd X:r64/m64, X:r64" , "op": "MR: REX.W 0F C1 /r" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"}
{"inst": "andn W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.0F38.W1 F2 /r" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=0"},
{"inst": "aor X:m32, r32" , "op": "MR: F2 0F 38 FC /r" , "ext": "RAO_INT"},
{"inst": "aor X:m64, r64" , "op": "MR: REX.W F2 0F 38 FC /r" , "ext": "RAO_INT"},
{"inst": "axor X:m32, r32" , "op": "MR: F3 0F 38 FC /r" , "ext": "RAO_INT"},
{"inst": "axor X:m64, r64" , "op": "MR: REX.W F3 0F 38 FC /r" , "ext": "RAO_INT"},
{"inst": "bextr W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.0F38.W0 F7 /r" , "ext": "BMI" , "io": "OF=0 SF=U ZF=W AF=U PF=U CF=0"},
{"inst": "bextr W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.0F38.W1 F7 /r" , "ext": "BMI" , "io": "OF=0 SF=U ZF=W AF=U PF=U CF=0"},
{"inst": "blsi W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /3" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsi W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /3" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsmsk W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /2" , "ext": "BMI" , "io": "OF=0 SF=W ZF=0 AF=U PF=U CF=W"},
{"inst": "blsmsk W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /2" , "ext": "BMI" , "io": "OF=0 SF=W ZF=0 AF=U PF=U CF=W"},
{"inst": "blsr W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /1" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsr W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /1" , "ext": "BMI" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "bzhi W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.0F38.W0 F5 /r" , "ext": "BMI2" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "bzhi W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.0F38.W1 F5 /r" , "ext": "BMI2" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "cldemote R:mem" , "op": "0F 1C /0" , "ext": "CLDEMOTE"},
{"inst": "clflush R:mem" , "op": "0F AE /7" , "ext": "CLFLUSH"},
{"inst": "clflushopt R:mem" , "op": "66 0F AE /7" , "ext": "CLFLUSHOPT"},
{"inst": "clwb R:mem" , "op": "66 0F AE /6" , "ext": "CLWB"},
{"inst": "clzero R:<m512(ds:zax)>" , "op": "0F 01 FC" , "ext": "CLZERO"},
{"inst": "cmovo x:r16, r16/m16" , "op": "RM: 66 0F 40 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovo X:r32, r32/m32" , "op": "RM: 0F 40 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovo X:r64, r64/m64" , "op": "RM: REX.W 0F 40 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovno x:r16, r16/m16" , "op": "RM: 66 0F 41 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovno X:r32, r32/m32" , "op": "RM: 0F 41 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovno X:r64, r64/m64" , "op": "RM: REX.W 0F 41 /r" , "ext": "CMOV" , "io": "OF=R"},
{"inst": "cmovb|cmovnae|cmovc x:r16, r16/m16" , "op": "RM: 66 0F 42 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmovb|cmovnae|cmovc X:r32, r32/m32" , "op": "RM: 0F 42 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmovb|cmovnae|cmovc X:r64, r64/m64" , "op": "RM: REX.W 0F 42 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc x:r16, r16/m16" , "op": "RM: 66 0F 43 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc X:r32, r32/m32" , "op": "RM: 0F 43 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc X:r64, r64/m64" , "op": "RM: REX.W 0F 43 /r" , "ext": "CMOV" , "io": "CF=R"},
{"inst": "cmove|cmovz x:r16, r16/m16" , "op": "RM: 66 0F 44 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmove|cmovz X:r32, r32/m32" , "op": "RM: 0F 44 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmove|cmovz X:r64, r64/m64" , "op": "RM: REX.W 0F 44 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz x:r16, r16/m16" , "op": "RM: 66 0F 45 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz X:r32, r32/m32" , "op": "RM: 0F 45 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz X:r64, r64/m64" , "op": "RM: REX.W 0F 45 /r" , "ext": "CMOV" , "io": "ZF=R"},
{"inst": "cmovbe|cmovna x:r16, r16/m16" , "op": "RM: 66 0F 46 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmovbe|cmovna X:r32, r32/m32" , "op": "RM: 0F 46 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmovbe|cmovna X:r64, r64/m64" , "op": "RM: REX.W 0F 46 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe x:r16, r16/m16" , "op": "RM: 66 0F 47 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe X:r32, r32/m32" , "op": "RM: 0F 47 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe X:r64, r64/m64" , "op": "RM: REX.W 0F 47 /r" , "ext": "CMOV" , "io": "CF=R ZF=R"},
{"inst": "cmovs x:r16, r16/m16" , "op": "RM: 66 0F 48 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovs X:r32, r32/m32" , "op": "RM: 0F 48 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovs X:r64, r64/m64" , "op": "RM: REX.W 0F 48 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovns x:r16, r16/m16" , "op": "RM: 66 0F 49 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovns X:r32, r32/m32" , "op": "RM: 0F 49 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovns X:r64, r64/m64" , "op": "RM: REX.W 0F 49 /r" , "ext": "CMOV" , "io": "SF=R"},
{"inst": "cmovp|cmovpe x:r16, r16/m16" , "op": "RM: 66 0F 4A /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovp|cmovpe X:r32, r32/m32" , "op": "RM: 0F 4A /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovp|cmovpe X:r64, r64/m64" , "op": "RM: REX.W 0F 4A /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo x:r16, r16/m16" , "op": "RM: 66 0F 4B /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo X:r32, r32/m32" , "op": "RM: 0F 4B /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo X:r64, r64/m64" , "op": "RM: REX.W 0F 4B /r" , "ext": "CMOV" , "io": "PF=R"},
{"inst": "cmovl|cmovnge x:r16, r16/m16" , "op": "RM: 66 0F 4C /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovl|cmovnge X:r32, r32/m32" , "op": "RM: 0F 4C /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovl|cmovnge X:r64, r64/m64" , "op": "RM: REX.W 0F 4C /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl x:r16, r16/m16" , "op": "RM: 66 0F 4D /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl X:r32, r32/m32" , "op": "RM: 0F 4D /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl X:r64, r64/m64" , "op": "RM: REX.W 0F 4D /r" , "ext": "CMOV" , "io": "SF=R OF=R"},
{"inst": "cmovle|cmovng x:r16, r16/m16" , "op": "RM: 66 0F 4E /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovle|cmovng X:r32, r32/m32" , "op": "RM: 0F 4E /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovle|cmovng X:r64, r64/m64" , "op": "RM: REX.W 0F 4E /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle x:r16, r16/m16" , "op": "RM: 66 0F 4F /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle X:r32, r32/m32" , "op": "RM: 0F 4F /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle X:r64, r64/m64" , "op": "RM: REX.W 0F 4F /r" , "ext": "CMOV" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmpbexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E6 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E6 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E2 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E2 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EE /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EE /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EC /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EC /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E7 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E7 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E3 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E3 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EF /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EF /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 ED /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 ED /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnoxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E1 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnoxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E1 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnpxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EB /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnpxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EB /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnsxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E9 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnsxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E9 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnzxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E5 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnzxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E5 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpoxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E0 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpoxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E0 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmppxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EA /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmppxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EA /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpsxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E8 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpsxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E8 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "[lock|xacqrel] cmpxchg x:r8/m8, r8, <al>" , "op": "MR: 0F B0 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] cmpxchg x:r16/m16, r16, <ax>" , "op": "MR: 66 0F B1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] cmpxchg X:r32/m32, r32, <eax>" , "op": "MR: 0F B1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] cmpxchg X:r64/m64, r64, <rax>" , "op": "MR: REX.W 0F B1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] cmpxchg8b X:m64,X:<edx>,X:<eax>,<ecx>,<ebx>" , "op": "0F C7 /1" , "ext": "CMPXCHG8B" , "io": "ZF=W"},
{"inst": "[lock|xacqrel] cmpxchg16b X:m128,X:<rdx>,X:<rax>,<rcx>,<rbx>","op": "REX.W 0F C7 /1" , "ext": "CMPXCHG16B" , "io": "ZF=W"},
{"inst": "cmpzxadd X:m32, X:r32, R:r32" , "op": "VEX.128.66.0F38.W0 E4 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpzxadd X:m64, X:r64, R:r64" , "op": "VEX.128.66.0F38.W1 E4 /r" , "ext": "CMPCCXADD" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cpuid X:<eax>, W:<ebx>, X:<ecx>, W:<edx>" , "op": "0F A2" , "ext": "I486" , "volatile": true},
{"inst": "lahf w:<ah>" , "op": "9F" , "ext": "LAHFSAHF" , "io": "SF=R ZF=R AF=R PF=R CF=R"},
{"inst": "lfence" , "op": "0F AE E8" , "ext": "SSE2"},
{"inst": "lzcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F BD /r" , "ext": "LZCNT" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "lzcnt W:r32, r32/m32" , "op": "RM: F3 0F BD /r" , "ext": "LZCNT" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "lzcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F BD /r" , "ext": "LZCNT" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "mcommit" , "op": "F3 0F 01 FA" , "ext": "MCOMMIT" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "mfence" , "op": "0F AE F0" , "ext": "SSE2"},
{"inst": "movbe w:r16, m16" , "op": "RM: 66 0F 38 F0 /r" , "ext": "MOVBE"},
{"inst": "movbe W:r32, m32" , "op": "RM: 0F 38 F0 /r" , "ext": "MOVBE"},
{"inst": "movbe W:r64, m64" , "op": "RM: REX.W 0F 38 F0 /r" , "ext": "MOVBE"},
{"inst": "movbe W:m16, r16" , "op": "MR: 66 0F 38 F1 /r" , "ext": "MOVBE"},
{"inst": "movbe W:m32, r32" , "op": "MR: 0F 38 F1 /r" , "ext": "MOVBE"},
{"inst": "movbe W:m64, r64" , "op": "MR: REX.W 0F 38 F1 /r" , "ext": "MOVBE"},
{"inst": "movdiri W:m32, r32" , "op": "MR: 0F 38 F9 /r" , "ext": "MOVDIRI"},
{"inst": "movdiri W:m64, r64" , "op": "MR: REX.W 0F 38 F9 /r" , "ext": "MOVDIRI"},
{"inst": "movdir64b W:m512(es:r32), m512" , "op": "RM: 66 0F 38 F8 /r" , "ext": "MOVDIR64B"},
{"inst": "movdir64b W:m512(es:r64), m512" , "op": "RM: 66 0F 38 F8 /r" , "ext": "MOVDIR64B"},
{"inst": "movnti W:m32, r32" , "op": "MR: 0F C3 /r" , "ext": "SSE2"},
{"inst": "movnti W:m64, r64" , "op": "MR: REX.W 0F C3 /r" , "ext": "SSE2"},
{"inst": "mulx W:r32, W:r32, ~r32/m32, ~<edx>" , "op": "RVM: VEX.LZ.F2.0F38.W0 F6 /r" , "ext": "BMI2"},
{"inst": "mulx W:r64, W:r64, ~r64/m64, ~<rdx>" , "op": "RVM: VEX.LZ.F2.0F38.W1 F6 /r" , "ext": "BMI2"},
{"inst": "pdep W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.F2.0F38.W0 F5 /r" , "ext": "BMI2"},
{"inst": "pdep W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.F2.0F38.W1 F5 /r" , "ext": "BMI2"},
{"inst": "pext W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.F3.0F38.W0 F5 /r" , "ext": "BMI2"},
{"inst": "pext W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.F3.0F38.W1 F5 /r" , "ext": "BMI2"},
{"inst": "popcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F B8 /r" , "ext": "POPCNT" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"},
{"inst": "popcnt W:r32, r32/m32" , "op": "RM: F3 0F B8 /r" , "ext": "POPCNT" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"},
{"inst": "popcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F B8 /r" , "ext": "POPCNT" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"},
{"inst": "prefetch R:mem" , "op": "0F 0D /0" , "ext": "3DNOW"},
{"inst": "prefetchit0 R:mem" , "op": "0F 18 /7" , "ext": "PREFETCHI" , "arch": "X64"},
{"inst": "prefetchit1 R:mem" , "op": "0F 18 /6" , "ext": "PREFETCHI" , "arch": "X64"},
{"inst": "prefetchnta R:mem" , "op": "0F 18 /0" , "ext": "SSE"},
{"inst": "prefetcht0 R:mem" , "op": "0F 18 /1" , "ext": "SSE"},
{"inst": "prefetcht1 R:mem" , "op": "0F 18 /2" , "ext": "SSE"},
{"inst": "prefetcht2 R:mem" , "op": "0F 18 /3" , "ext": "SSE"},
{"inst": "prefetchw R:mem" , "op": "0F 0D /1" , "ext": "PREFETCHW" , "io": "OF=U SF=U ZF=U AF=U PF=U CF=U"},
{"inst": "prefetchwt1 R:mem" , "op": "0F 0D /2" , "ext": "PREFETCHWT1", "io": "OF=U SF=U ZF=U AF=U PF=U CF=U"},
{"inst": "ptwrite R:r32/m32" , "op": "F3 0F AE /4" , "ext": "PTWRITE"},
{"inst": "ptwrite R:r64/m64" , "op": "REX.W F3 0F AE /4" , "ext": "PTWRITE"},
{"inst": "rdpid W:r32" , "op": "R: F3 0F C7 /7" , "ext": "RDPID" , "arch": "X86"},
{"inst": "rdpid W:r64" , "op": "R: F3 0F C7 /7" , "ext": "RDPID" , "arch": "X64"},
{"inst": "rdpkru W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 EE" , "ext": "OSPKE"},
{"inst": "rdpru W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 FD" , "ext": "RDPRU"},
{"inst": "rdrand w:r16" , "op": "66 0F C7 /6" , "ext": "RDRAND" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdrand W:r32" , "op": "0F C7 /6" , "ext": "RDRAND" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdrand W:r64" , "op": "REX.W 0F C7 /6" , "ext": "RDRAND" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdseed w:r16" , "op": "66 0F C7 /7" , "ext": "RDSEED" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdseed W:r32" , "op": "0F C7 /7" , "ext": "RDSEED" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdseed W:r64" , "op": "REX.W 0F C7 /7" , "ext": "RDSEED" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdtsc W:<edx>, W:<eax>" , "op": "0F 31" , "ext": "RDTSC"},
{"inst": "rdtscp W:<edx>, W:<eax>, W:<ecx>" , "op": "0F 01 F9" , "ext": "RDTSCP"},
{"inst": "rorx W:r32, r32/m32, ib/ub" , "op": "RM: VEX.LZ.F2.0F3A.W0 F0 /r ib" , "ext": "BMI2"},
{"inst": "rorx W:r64, r64/m64, ib/ub" , "op": "RM: VEX.LZ.F2.0F3A.W1 F0 /r ib" , "ext": "BMI2"},
{"inst": "sahf R:<ah>" , "op": "9E" , "ext": "LAHFSAHF" , "io": "SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "sarx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.F3.0F38.W0 F7 /r" , "ext": "BMI2"},
{"inst": "sarx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.F3.0F38.W1 F7 /r" , "ext": "BMI2"},
{"inst": "serialize" , "op": "0F 01 E8" , "ext": "SERIALIZE"},
{"inst": "sfence" , "op": "0F AE F8" , "ext": "SSE"},
{"inst": "shlx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.66.0F38.W0 F7 /r" , "ext": "BMI2"},
{"inst": "shlx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.66.0F38.W1 F7 /r" , "ext": "BMI2"},
{"inst": "shrx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.F2.0F38.W0 F7 /r" , "ext": "BMI2"},
{"inst": "shrx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.F2.0F38.W1 F7 /r" , "ext": "BMI2"},
{"inst": "tzcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F BC /r" , "ext": "BMI" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "tzcnt W:r32, r32/m32" , "op": "RM: F3 0F BC /r" , "ext": "BMI" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "tzcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F BC /r" , "ext": "BMI" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "[lock|xacqrel] xadd x:r8/m8, x:r8" , "op": "MR: 0F C0 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] xadd x:r16/m16, x:r16" , "op": "MR: 66 0F C1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] xadd X:r32/m32, X:r32" , "op": "MR: 0F C1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "[lock|xacqrel] xadd X:r64/m64, X:r64" , "op": "MR: REX.W 0F C1 /r" , "ext": "I486" , "io": "OF=W SF=W ZF=W AF=W PF=W CF=W"}
]}, ]},
{"category": "GP GP_EXT CRYPTO_HASH", "data": [ {"category": "GP GP_EXT", "ext": "3DNOW", "volatile": true, "data": [
{"inst": "crc32 X:r32, r8/m8" , "op": "RM: F2 0F 38 F0 /r" , "ext": "SSE4_2"}, {"inst": "prefetch R:mem" , "op": "0F 0D /0"}
{"inst": "crc32 X:r32, r16/m16" , "op": "RM: 66 F2 0F 38 F1 /r" , "ext": "SSE4_2"}, ]},
{"inst": "crc32 X:r32, r32/m32" , "op": "RM: F2 0F 38 F1 /r" , "ext": "SSE4_2"},
{"inst": "crc32 X:r64, r8/m8" , "op": "RM: REX.W F2 0F 38 F0 /r" , "ext": "SSE4_2"}, {"category": "GP GP_EXT", "ext": "ADX", "data": [
{"inst": "crc32 X:r64, r64/m64" , "op": "RM: REX.W F2 0F 38 F1 /r" , "ext": "SSE4_2"} {"inst": "adcx X:~r32, ~r32/m32" , "op": "RM: 66 0F 38 F6 /r" , "io": "CF=X"},
{"inst": "adcx X:~r64, ~r64/m64" , "op": "RM: REX.W 66 0F 38 F6 /r" , "io": "CF=X"},
{"inst": "adox X:~r32, ~r32/m32" , "op": "RM: F3 0F 38 F6 /r" , "io": "OF=X"},
{"inst": "adox X:~r64, ~r64/m64" , "op": "RM: REX.W F3 0F 38 F6 /r" , "io": "OF=X"}
]},
{"category": "GP GP_EXT", "ext": "BMI", "data": [
{"inst": "andn W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.0F38.W0 F2 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=0"},
{"inst": "andn W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.0F38.W1 F2 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=0"},
{"inst": "bextr W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.0F38.W0 F7 /r" , "io": "OF=0 SF=U ZF=W AF=U PF=U CF=0"},
{"inst": "bextr W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.0F38.W1 F7 /r" , "io": "OF=0 SF=U ZF=W AF=U PF=U CF=0"},
{"inst": "blsi W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /3" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsi W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /3" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsmsk W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /2" , "io": "OF=0 SF=W ZF=0 AF=U PF=U CF=W"},
{"inst": "blsmsk W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /2" , "io": "OF=0 SF=W ZF=0 AF=U PF=U CF=W"},
{"inst": "blsr W:r32, r32/m32" , "op": "VM: VEX.LZ.0F38.W0 F3 /1" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "blsr W:r64, r64/m64" , "op": "VM: VEX.LZ.0F38.W1 F3 /1" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "tzcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F BC /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "tzcnt W:r32, r32/m32" , "op": "RM: F3 0F BC /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "tzcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F BC /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"}
]},
{"category": "GP GP_EXT", "ext": "BMI2", "data": [
{"inst": "bzhi W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.0F38.W0 F5 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "bzhi W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.0F38.W1 F5 /r" , "io": "OF=0 SF=W ZF=W AF=U PF=U CF=W"},
{"inst": "mulx W:r32, W:r32, ~r32/m32, ~<edx>" , "op": "RVM: VEX.LZ.F2.0F38.W0 F6 /r"},
{"inst": "mulx W:r64, W:r64, ~r64/m64, ~<rdx>" , "op": "RVM: VEX.LZ.F2.0F38.W1 F6 /r"},
{"inst": "pdep W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.F2.0F38.W0 F5 /r"},
{"inst": "pdep W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.F2.0F38.W1 F5 /r"},
{"inst": "pext W:r32, r32, r32/m32" , "op": "RVM: VEX.LZ.F3.0F38.W0 F5 /r"},
{"inst": "pext W:r64, r64, r64/m64" , "op": "RVM: VEX.LZ.F3.0F38.W1 F5 /r"},
{"inst": "rorx W:r32, r32/m32, ib/ub" , "op": "RM: VEX.LZ.F2.0F3A.W0 F0 /r ib"},
{"inst": "rorx W:r64, r64/m64, ib/ub" , "op": "RM: VEX.LZ.F2.0F3A.W1 F0 /r ib"},
{"inst": "sarx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.F3.0F38.W0 F7 /r"},
{"inst": "sarx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.F3.0F38.W1 F7 /r"},
{"inst": "shlx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.66.0F38.W0 F7 /r"},
{"inst": "shlx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.66.0F38.W1 F7 /r"},
{"inst": "shrx W:r32, r32/m32, r32" , "op": "RMV: VEX.LZ.F2.0F38.W0 F7 /r"},
{"inst": "shrx W:r64, r64/m64, r64" , "op": "RMV: VEX.LZ.F2.0F38.W1 F7 /r"}
]},
{"category": "GP GP_EXT", "ext": "CET_SS", "volatile": true, "data": [
{"inst": "incsspd r32" , "op": "F3 0F AE /5"},
{"inst": "incsspq r64" , "op": "REX.W F3 0F AE /5"},
{"inst": "rdsspd W:r32" , "op": "F3 0F 1E /1"},
{"inst": "rdsspq W:r64" , "op": "REX.W F3 0F 1E /1"},
{"inst": "rstorssp R:m64" , "op": "F3 0F 01 /5" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "saveprevssp" , "op": "F3 0F 01 EA" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "CLDEMOTE", "data": [
{"inst": "cldemote R:mem" , "op": "0F 1C /0"}
]},
{"category": "GP GP_EXT", "ext": "CLFLUSH", "data": [
{"inst": "clflush R:mem" , "op": "0F AE /7"}
]},
{"category": "GP GP_EXT", "ext": "CLFLUSHOPT", "data": [
{"inst": "clflushopt R:mem" , "op": "66 0F AE /7"}
]},
{"category": "GP GP_EXT", "ext": "CLWB", "data": [
{"inst": "clwb R:mem" , "op": "66 0F AE /6"}
]},
{"category": "GP GP_EXT", "ext": "CLZERO", "data": [
{"inst": "clzero R:<m512(ds:zax)>" , "op": "0F 01 FC"}
]},
{"category": "GP GP_EXT", "ext": "CMOV", "data": [
{"inst": "cmovo x:r16, r16/m16" , "op": "RM: 66 0F 40 /r" , "io": "OF=R"},
{"inst": "cmovo X:r32, r32/m32" , "op": "RM: 0F 40 /r" , "io": "OF=R"},
{"inst": "cmovo X:r64, r64/m64" , "op": "RM: REX.W 0F 40 /r" , "io": "OF=R"},
{"inst": "cmovno x:r16, r16/m16" , "op": "RM: 66 0F 41 /r" , "io": "OF=R"},
{"inst": "cmovno X:r32, r32/m32" , "op": "RM: 0F 41 /r" , "io": "OF=R"},
{"inst": "cmovno X:r64, r64/m64" , "op": "RM: REX.W 0F 41 /r" , "io": "OF=R"},
{"inst": "cmovb|cmovnae|cmovc x:r16, r16/m16" , "op": "RM: 66 0F 42 /r" , "io": "CF=R"},
{"inst": "cmovb|cmovnae|cmovc X:r32, r32/m32" , "op": "RM: 0F 42 /r" , "io": "CF=R"},
{"inst": "cmovb|cmovnae|cmovc X:r64, r64/m64" , "op": "RM: REX.W 0F 42 /r" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc x:r16, r16/m16" , "op": "RM: 66 0F 43 /r" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc X:r32, r32/m32" , "op": "RM: 0F 43 /r" , "io": "CF=R"},
{"inst": "cmovae|cmovnb|cmovnc X:r64, r64/m64" , "op": "RM: REX.W 0F 43 /r" , "io": "CF=R"},
{"inst": "cmove|cmovz x:r16, r16/m16" , "op": "RM: 66 0F 44 /r" , "io": "ZF=R"},
{"inst": "cmove|cmovz X:r32, r32/m32" , "op": "RM: 0F 44 /r" , "io": "ZF=R"},
{"inst": "cmove|cmovz X:r64, r64/m64" , "op": "RM: REX.W 0F 44 /r" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz x:r16, r16/m16" , "op": "RM: 66 0F 45 /r" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz X:r32, r32/m32" , "op": "RM: 0F 45 /r" , "io": "ZF=R"},
{"inst": "cmovne|cmovnz X:r64, r64/m64" , "op": "RM: REX.W 0F 45 /r" , "io": "ZF=R"},
{"inst": "cmovbe|cmovna x:r16, r16/m16" , "op": "RM: 66 0F 46 /r" , "io": "CF=R ZF=R"},
{"inst": "cmovbe|cmovna X:r32, r32/m32" , "op": "RM: 0F 46 /r" , "io": "CF=R ZF=R"},
{"inst": "cmovbe|cmovna X:r64, r64/m64" , "op": "RM: REX.W 0F 46 /r" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe x:r16, r16/m16" , "op": "RM: 66 0F 47 /r" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe X:r32, r32/m32" , "op": "RM: 0F 47 /r" , "io": "CF=R ZF=R"},
{"inst": "cmova|cmovnbe X:r64, r64/m64" , "op": "RM: REX.W 0F 47 /r" , "io": "CF=R ZF=R"},
{"inst": "cmovs x:r16, r16/m16" , "op": "RM: 66 0F 48 /r" , "io": "SF=R"},
{"inst": "cmovs X:r32, r32/m32" , "op": "RM: 0F 48 /r" , "io": "SF=R"},
{"inst": "cmovs X:r64, r64/m64" , "op": "RM: REX.W 0F 48 /r" , "io": "SF=R"},
{"inst": "cmovns x:r16, r16/m16" , "op": "RM: 66 0F 49 /r" , "io": "SF=R"},
{"inst": "cmovns X:r32, r32/m32" , "op": "RM: 0F 49 /r" , "io": "SF=R"},
{"inst": "cmovns X:r64, r64/m64" , "op": "RM: REX.W 0F 49 /r" , "io": "SF=R"},
{"inst": "cmovp|cmovpe x:r16, r16/m16" , "op": "RM: 66 0F 4A /r" , "io": "PF=R"},
{"inst": "cmovp|cmovpe X:r32, r32/m32" , "op": "RM: 0F 4A /r" , "io": "PF=R"},
{"inst": "cmovp|cmovpe X:r64, r64/m64" , "op": "RM: REX.W 0F 4A /r" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo x:r16, r16/m16" , "op": "RM: 66 0F 4B /r" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo X:r32, r32/m32" , "op": "RM: 0F 4B /r" , "io": "PF=R"},
{"inst": "cmovnp|cmovpo X:r64, r64/m64" , "op": "RM: REX.W 0F 4B /r" , "io": "PF=R"},
{"inst": "cmovl|cmovnge x:r16, r16/m16" , "op": "RM: 66 0F 4C /r" , "io": "SF=R OF=R"},
{"inst": "cmovl|cmovnge X:r32, r32/m32" , "op": "RM: 0F 4C /r" , "io": "SF=R OF=R"},
{"inst": "cmovl|cmovnge X:r64, r64/m64" , "op": "RM: REX.W 0F 4C /r" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl x:r16, r16/m16" , "op": "RM: 66 0F 4D /r" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl X:r32, r32/m32" , "op": "RM: 0F 4D /r" , "io": "SF=R OF=R"},
{"inst": "cmovge|cmovnl X:r64, r64/m64" , "op": "RM: REX.W 0F 4D /r" , "io": "SF=R OF=R"},
{"inst": "cmovle|cmovng x:r16, r16/m16" , "op": "RM: 66 0F 4E /r" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovle|cmovng X:r32, r32/m32" , "op": "RM: 0F 4E /r" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovle|cmovng X:r64, r64/m64" , "op": "RM: REX.W 0F 4E /r" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle x:r16, r16/m16" , "op": "RM: 66 0F 4F /r" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle X:r32, r32/m32" , "op": "RM: 0F 4F /r" , "io": "ZF=R SF=R OF=R"},
{"inst": "cmovg|cmovnle X:r64, r64/m64" , "op": "RM: REX.W 0F 4F /r" , "io": "ZF=R SF=R OF=R"}
]},
{"category": "GP GP_EXT", "ext": "CMPCCXADD", "data": [
{"inst": "cmpbexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E6 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E6 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E2 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpbxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E2 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EE /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EE /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EC /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmplxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EC /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E7 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E7 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E3 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnbxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E3 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlexadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EF /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlexadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EF /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 ED /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnlxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 ED /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnoxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E1 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnoxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E1 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnpxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EB /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnpxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EB /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnsxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E9 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnsxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E9 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnzxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E5 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpnzxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E5 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpoxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E0 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpoxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E0 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmppxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 EA /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmppxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 EA /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpsxadd X:m32, X:r32, R:r32" , "op": "MVR: VEX.128.66.0F38.W0 E8 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpsxadd X:m64, X:r64, R:r64" , "op": "MVR: VEX.128.66.0F38.W1 E8 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpzxadd X:m32, X:r32, R:r32" , "op": "VEX.128.66.0F38.W0 E4 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"},
{"inst": "cmpzxadd X:m64, X:r64, R:r64" , "op": "VEX.128.66.0F38.W1 E4 /r" , "io": "CF=W OF=W SF=W ZF=W AF=W PF=W"}
]},
{"category": "GP GP_EXT", "ext": "CMPXCHG8B", "data": [
{"inst": "[lock|xacqrel] cmpxchg8b X:m64,X:<edx>,X:<eax>,<ecx>,<ebx>" , "op": "0F C7 /1" , "io": "ZF=W"}
]},
{"category": "GP GP_EXT", "ext": "CMPXCHG16B", "data": [
{"inst": "[lock|xacqrel] cmpxchg16b X:m128,X:<rdx>,X:<rax>,<rcx>,<rbx>","op": "REX.W 0F C7 /1" , "io": "ZF=W"}
]},
{"category": "GP GP_EXT", "ext": "FSGSBASE", "arch": "X64", "volatile": true, "data": [
{"inst": "rdfsbase W:r32" , "op": "F3 0F AE /0"},
{"inst": "rdfsbase W:r64" , "op": "REX.W F3 0F AE /0"},
{"inst": "rdgsbase W:r32" , "op": "F3 0F AE /1"},
{"inst": "rdgsbase W:r64" , "op": "REX.W F3 0F AE /1"},
{"inst": "wrfsbase R:r32" , "op": "F3 0F AE /2"},
{"inst": "wrfsbase R:r64" , "op": "REX.W F3 0F AE /2"},
{"inst": "wrgsbase R:r32" , "op": "F3 0F AE /3"},
{"inst": "wrgsbase R:r64" , "op": "REX.W F3 0F AE /3"}
]},
{"category": "GP GP_EXT", "ext": "FXSR", "volatile": true, "data": [
{"inst": "fxrstor R:mem" , "op": "0F AE /1" , "io": "C0=W C1=W C2=W C3=W"},
{"inst": "fxrstor64 R:mem" , "op": "REX.W 0F AE /1" , "io": "C0=W C1=W C2=W C3=W"},
{"inst": "fxsave W:mem" , "op": "0F AE /0" , "io": "C0=R C1=R C2=R C3=R"},
{"inst": "fxsave64 W:mem" , "op": "REX.W 0F AE /0" , "io": "C0=R C1=R C2=R C3=R"}
]},
{"category": "GP GP_EXT", "ext": "LAHFSAHF", "data": [
{"inst": "lahf w:<ah>" , "op": "9F" , "io": "SF=R ZF=R AF=R PF=R CF=R"},
{"inst": "sahf R:<ah>" , "op": "9E" , "io": "SF=W ZF=W AF=W PF=W CF=W"}
]},
{"category": "GP GP_EXT", "ext": "LWP", "volatile": true, "data": [
{"inst": "llwpcb R:r32" , "op": "XOP.L0.P0.M09.W0 12 /0"},
{"inst": "llwpcb R:r64" , "op": "XOP.L0.P0.M09.W1 12 /0"},
{"inst": "lwpins R:r32, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W0 12 /0 id"},
{"inst": "lwpins R:r64, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W1 12 /0 id"},
{"inst": "lwpval R:r32, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W0 12 /1 id"},
{"inst": "lwpval R:r64, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W1 12 /1 id"},
{"inst": "slwpcb W:r32" , "op": "XOP.L0.P0.M09.W0 12 /1"},
{"inst": "slwpcb W:r64" , "op": "XOP.L0.P0.M09.W1 12 /1"}
]},
{"category": "GP GP_EXT", "ext": "LZCNT", "data": [
{"inst": "lzcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F BD /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "lzcnt W:r32, r32/m32" , "op": "RM: F3 0F BD /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"},
{"inst": "lzcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F BD /r" , "io": "OF=U SF=U ZF=W AF=U PF=U CF=W"}
]},
{"category": "GP GP_EXT", "ext": "MONITORX", "volatile": true, "data": [
{"inst": "monitorx R:<mem(ds:zax)>, R:<ecx>, R:<edx>" , "op": "0F 01 FA"},
{"inst": "mwaitx R:<eax>, R:<ecx>, R:<ebx>" , "op": "0F 01 FB"}
]},
{"category": "GP GP_EXT", "ext": "MCOMMIT", "data": [
{"inst": "mcommit" , "op": "F3 0F 01 FA" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "MOVBE", "data": [
{"inst": "movbe w:r16, m16" , "op": "RM: 66 0F 38 F0 /r"},
{"inst": "movbe W:r32, m32" , "op": "RM: 0F 38 F0 /r"},
{"inst": "movbe W:r64, m64" , "op": "RM: REX.W 0F 38 F0 /r"},
{"inst": "movbe W:m16, r16" , "op": "MR: 66 0F 38 F1 /r"},
{"inst": "movbe W:m32, r32" , "op": "MR: 0F 38 F1 /r"},
{"inst": "movbe W:m64, r64" , "op": "MR: REX.W 0F 38 F1 /r"}
]},
{"category": "GP GP_EXT", "ext": "MOVDIRI", "data": [
{"inst": "movdiri W:m32, r32" , "op": "MR: 0F 38 F9 /r"},
{"inst": "movdiri W:m64, r64" , "op": "MR: REX.W 0F 38 F9 /r"}
]},
{"category": "GP GP_EXT", "ext": "MOVDIR64B", "data": [
{"inst": "movdir64b W:m512(es:r32), m512" , "op": "RM: 66 0F 38 F8 /r"},
{"inst": "movdir64b W:m512(es:r64), m512" , "op": "RM: 66 0F 38 F8 /r"}
]},
{"category": "GP GP_EXT", "ext": "PCONFIG", "volatile": true, "data": [
{"inst": "pconfig" , "op": "0F 01 C5"}
]},
{"category": "GP GP_EXT", "ext": "POPCNT", "data": [
{"inst": "popcnt w:r16, r16/m16" , "op": "RM: 66 F3 0F B8 /r" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"},
{"inst": "popcnt W:r32, r32/m32" , "op": "RM: F3 0F B8 /r" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"},
{"inst": "popcnt W:r64, r64/m64" , "op": "RM: REX.W F3 0F B8 /r" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"}
]},
{"category": "GP GP_EXT", "ext": "OSPKE", "data": [
{"inst": "rdpkru W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 EE"}
]},
{"category": "GP GP_EXT", "ext": "PREFETCHI", "arch": "X64", "volatile": true, "data": [
{"inst": "prefetchit0 R:mem" , "op": "0F 18 /7"},
{"inst": "prefetchit1 R:mem" , "op": "0F 18 /6"}
]},
{"category": "GP GP_EXT", "ext": "PREFETCHW", "volatile": true, "data": [
{"inst": "prefetchw R:mem" , "op": "0F 0D /1" , "io": "OF=U SF=U ZF=U AF=U PF=U CF=U"}
]},
{"category": "GP GP_EXT", "ext": "PREFETCHWT1", "volatile": true, "data": [
{"inst": "prefetchwt1 R:mem" , "op": "0F 0D /2" , "io": "OF=U SF=U ZF=U AF=U PF=U CF=U"}
]},
{"category": "GP GP_EXT", "ext": "PTWRITE", "volatile": true, "data": [
{"inst": "ptwrite R:r32/m32" , "op": "F3 0F AE /4"},
{"inst": "ptwrite R:r64/m64" , "op": "REX.W F3 0F AE /4"}
]},
{"category": "GP GP_EXT", "ext": "RAO_INT", "volatile": true, "data": [
{"inst": "aadd X:m32, r32" , "op": "MR: 0F 38 FC /r"},
{"inst": "aadd X:m64, r64" , "op": "MR: REX.W 0F 38 FC /r"},
{"inst": "aand X:m32, r32" , "op": "MR: 66 0F 38 FC /r"},
{"inst": "aand X:m64, r64" , "op": "MR: REX.W 66 0F 38 FC /r"},
{"inst": "aor X:m32, r32" , "op": "MR: F2 0F 38 FC /r"},
{"inst": "aor X:m64, r64" , "op": "MR: REX.W F2 0F 38 FC /r"},
{"inst": "axor X:m32, r32" , "op": "MR: F3 0F 38 FC /r"},
{"inst": "axor X:m64, r64" , "op": "MR: REX.W F3 0F 38 FC /r"}
]},
{"category": "GP GP_EXT", "ext": "RDPID", "data": [
{"inst": "rdpid W:r32" , "op": "R: F3 0F C7 /7" , "arch": "X86"},
{"inst": "rdpid W:r64" , "op": "R: F3 0F C7 /7" , "arch": "X64"}
]},
{"category": "GP GP_EXT", "ext": "RDPRU", "data": [
{"inst": "rdpru W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 FD"}
]},
{"category": "GP GP_EXT", "ext": "RDRAND", "data": [
{"inst": "rdrand w:r16" , "op": "66 0F C7 /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdrand W:r32" , "op": "0F C7 /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdrand W:r64" , "op": "REX.W 0F C7 /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "RDSEED", "data": [
{"inst": "rdseed w:r16" , "op": "66 0F C7 /7" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdseed W:r32" , "op": "0F C7 /7" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "rdseed W:r64" , "op": "REX.W 0F C7 /7" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "RDTSC", "data": [
{"inst": "rdtsc W:<edx>, W:<eax>" , "op": "0F 31"}
]},
{"category": "GP GP_EXT", "ext": "RDTSCP", "data": [
{"inst": "rdtscp W:<edx>, W:<eax>, W:<ecx>" , "op": "0F 01 F9"}
]},
{"category": "GP GP_EXT", "ext": "RTM", "volatile": true, "data": [
{"inst": "xabort ib/ub" , "op": "C6 /7 ib"},
{"inst": "xbegin rel16" , "op": "66 C7 /7 cw"},
{"inst": "xbegin rel32" , "op": "C7 /7 cd"},
{"inst": "xend" , "op": "0F 01 D5"}
]},
{"category": "GP GP_EXT", "ext": "SERIALIZE", "volatile": true, "data": [
{"inst": "serialize" , "op": "0F 01 E8"}
]},
{"category": "GP GP_EXT", "ext": "SSE", "volatile": true, "data": [
{"inst": "prefetchnta R:mem" , "op": "0F 18 /0"},
{"inst": "prefetcht0 R:mem" , "op": "0F 18 /1"},
{"inst": "prefetcht1 R:mem" , "op": "0F 18 /2"},
{"inst": "prefetcht2 R:mem" , "op": "0F 18 /3"},
{"inst": "sfence" , "op": "0F AE F8"}
]},
{"category": "GP GP_EXT", "ext": "SSE2", "volatile": true, "data": [
{"inst": "lfence" , "op": "0F AE E8"},
{"inst": "mfence" , "op": "0F AE F0"},
{"inst": "movnti W:m32, r32" , "op": "MR: 0F C3 /r"},
{"inst": "movnti W:m64, r64" , "op": "MR: REX.W 0F C3 /r"}
]},
{"category": "GP GP_EXT CRYPTO_HASH", "ext": "SSE4_2", "data": [
{"inst": "crc32 X:r32, r8/m8" , "op": "RM: F2 0F 38 F0 /r"},
{"inst": "crc32 X:r32, r16/m16" , "op": "RM: 66 F2 0F 38 F1 /r"},
{"inst": "crc32 X:r32, r32/m32" , "op": "RM: F2 0F 38 F1 /r"},
{"inst": "crc32 X:r64, r8/m8" , "op": "RM: REX.W F2 0F 38 F0 /r"},
{"inst": "crc32 X:r64, r64/m64" , "op": "RM: REX.W F2 0F 38 F1 /r"}
]},
{"category": "GP GP_EXT", "ext": "TSE", "arch": "X64", "volatile": true, "data": [
{"inst": "pbndkb W:<rax>, R:<mem(ds:rbx)>, W:<mem(ds:rcx)>" , "op": "0F 01 C7" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"}
]},
{"category": "GP GP_EXT", "ext": "TSX", "volatile": true, "data": [
{"inst": "xtest" , "op": "0F 01 D6" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"}
]},
{"category": "GP GP_EXT", "ext": "TSXLDTRK", "volatile": true, "data": [
{"inst": "xresldtrk" , "op": "F2 0F 01 E9"},
{"inst": "xsusldtrk" , "op": "F2 0F 01 E8"}
]},
{"category": "GP GP_EXT", "ext": "UINTR", "arch": "X64", "volatile": true, "data": [
{"inst": "uiret" , "op": "F3 0F 01 EC"},
{"inst": "clui" , "op": "F3 0F 01 EE"},
{"inst": "stui" , "op": "F3 0F 01 EF"},
{"inst": "testui" , "op": "F3 0F 01 ED" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "senduipi R:r64" , "op": "R: F3 0F C7 /6"}
]},
{"category": "GP GP_EXT", "ext": "WAITPKG", "volatile": true, "data": [
{"inst": "tpause R:r32, <edx>, <eax>" , "op": "66 0F AE /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "umonitor R:mem(ds:r32)" , "op": "F3 0F AE /6" , "arch": "X86"},
{"inst": "umonitor R:mem(ds:r64)" , "op": "F3 0F AE /6" , "arch": "X64"},
{"inst": "umwait R:r32, <edx>, <eax>" , "op": "F2 0F AE /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "XSAVE", "volatile": true, "data": [
{"inst": "xgetbv W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 D0" , "io": "XCR=R"},
{"inst": "xrstor R:mem, <edx>, <eax>" , "op": "0F AE /5" , "io": "XCR=R"},
{"inst": "xrstor64 R:mem, <edx>, <eax>" , "op": "REX.W 0F AE /5" , "io": "XCR=R"},
{"inst": "xsave W:mem, <edx>, <eax>" , "op": "0F AE /4" , "io": "XCR=R"},
{"inst": "xsave64 W:mem, <edx>, <eax>" , "op": "REX.W 0F AE /4" , "io": "XCR=R"}
]},
{"category": "GP GP_EXT", "ext": "XSAVEC", "volatile": true, "data": [
{"inst": "xsavec W:mem, <edx>, <eax>" , "op": "0F C7 /4" , "io": "XCR=R"},
{"inst": "xsavec64 W:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /4" , "io": "XCR=R"}
]},
{"category": "GP GP_EXT", "ext": "XSAVEOPT", "volatile": true, "data": [
{"inst": "xsaveopt W:mem, <edx>, <eax>" , "op": "0F AE /6" , "io": "XCR=R"},
{"inst": "xsaveopt64 W:mem, <edx>, <eax>" , "op": "REX.W 0F AE /6" , "io": "XCR=R"}
]}, ]},
{"category": "GP", "volatile": true, "data": [ {"category": "GP", "volatile": true, "data": [
@@ -863,21 +1068,35 @@
{"inst": "xlatb" , "op": "D7"} {"inst": "xlatb" , "op": "D7"}
]}, ]},
{"category": "GP", "deprecated": true, "data": [ {"category": "GP", "deprecated": true, "arch": "X86", "data": [
{"inst": "aaa x:<ax>" , "op": "37" , "arch": "X86", "io": "OF=U SF=U ZF=U AF=W PF=U CF=W"}, {"inst": "aaa x:<ax>" , "op": "37" , "io": "OF=U SF=U ZF=U AF=W PF=U CF=W"},
{"inst": "aas x:<ax>" , "op": "3F" , "arch": "X86", "io": "OF=U SF=U ZF=U AF=W PF=U CF=W"}, {"inst": "aas x:<ax>" , "op": "3F" , "io": "OF=U SF=U ZF=U AF=W PF=U CF=W"},
{"inst": "aad x:<ax>, ib/ub" , "op": "D5 ib" , "arch": "X86", "io": "OF=U SF=W ZF=W AF=U PF=W CF=U"}, {"inst": "aad x:<ax>, ib/ub" , "op": "D5 ib" , "io": "OF=U SF=W ZF=W AF=U PF=W CF=U"},
{"inst": "aam x:<ax>, ib/ub" , "op": "D4 ib" , "arch": "X86", "io": "OF=U SF=W ZF=W AF=U PF=W CF=U"}, {"inst": "aam x:<ax>, ib/ub" , "op": "D4 ib" , "io": "OF=U SF=W ZF=W AF=U PF=W CF=U"},
{"inst": "arpl x:r16/m16, R:r16" , "op": "MR: 63 /r" , "arch": "X86", "io": "ZF=W"}, {"inst": "arpl x:r16/m16, R:r16" , "op": "MR: 63 /r" , "io": "ZF=W"},
{"inst": "bound R:r16, R:m32" , "op": "RM: 66 62 /r" , "arch": "X86"}, {"inst": "bound R:r16, R:m32" , "op": "RM: 66 62 /r"},
{"inst": "bound R:r32, R:m64" , "op": "RM: 62 /r" , "arch": "X86"}, {"inst": "bound R:r32, R:m64" , "op": "RM: 62 /r"},
{"inst": "daa x:<ax>" , "op": "27" , "arch": "X86", "io": "OF=U SF=W ZF=W AF=W PF=W CF=W"}, {"inst": "daa x:<ax>" , "op": "27" , "io": "OF=U SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "das x:<ax>" , "op": "2F" , "arch": "X86", "io": "OF=U SF=W ZF=W AF=W PF=W CF=W"}, {"inst": "das x:<ax>" , "op": "2F" , "io": "OF=U SF=W ZF=W AF=W PF=W CF=W"},
{"inst": "into" , "op": "CE" , "arch": "X86", "io": "OF=R"}, {"inst": "into" , "op": "CE" , "io": "OF=R"},
{"inst": "popa" , "op": "66 61" , "arch": "X86"}, {"inst": "popa" , "op": "66 61"},
{"inst": "popad" , "op": "61" , "arch": "X86"}, {"inst": "popad" , "op": "61"},
{"inst": "pusha" , "op": "66 60" , "arch": "X86"}, {"inst": "pusha" , "op": "66 60"},
{"inst": "pushad" , "op": "60" , "arch": "X86"} {"inst": "pushad" , "op": "60"}
]},
{"category": "GP GP_EXT", "ext": "MPX", "deprecated": true, "data": [
{"inst": "bndcl R:bnd, r32/m32" , "op": "RM: F3 0F 1A /r" , "arch": "X86"},
{"inst": "bndcl R:bnd, r64/m64" , "op": "RM: F3 0F 1A /r" , "arch": "X64"},
{"inst": "bndcn R:bnd, r32/m32" , "op": "RM: F2 0F 1B /r" , "arch": "X86"},
{"inst": "bndcn R:bnd, r64/m64" , "op": "RM: F2 0F 1B /r" , "arch": "X64"},
{"inst": "bndcu R:bnd, r32/m32" , "op": "RM: F2 0F 1A /r" , "arch": "X86"},
{"inst": "bndcu R:bnd, r64/m64" , "op": "RM: F2 0F 1A /r" , "arch": "X64"},
{"inst": "bndldx W:bnd, mib" , "op": "RM: 0F 1A /r"},
{"inst": "bndmk W:bnd, mem" , "op": "RM: F3 0F 1B /r"},
{"inst": "bndmov W:bnd, bnd/mem" , "op": "RM: 66 0F 1A /r"},
{"inst": "bndmov W:bnd/mem, bnd" , "op": "MR: 66 0F 1B /r"},
{"inst": "bndstx W:mib, bnd" , "op": "MR: 0F 1B /r"}
]}, ]},
{"category": "GP GP_EXT", "ext": "TBM", "deprecated": true, "data": [ {"category": "GP GP_EXT", "ext": "TBM", "deprecated": true, "data": [
@@ -901,141 +1120,84 @@
{"inst": "t1mskc W:r64, r64/m64" , "op": "VM: XOP.LZ.M09.W1 01 /7"} {"inst": "t1mskc W:r64, r64/m64" , "op": "VM: XOP.LZ.M09.W1 01 /7"}
]}, ]},
{"category": "GP GP_EXT", "ext": "MPX", "deprecated": true, "data": [
{"inst": "bndcl R:bnd, r32/m32" , "op": "RM: F3 0F 1A /r" , "arch": "X86"},
{"inst": "bndcl R:bnd, r64/m64" , "op": "RM: F3 0F 1A /r" , "arch": "X64"},
{"inst": "bndcn R:bnd, r32/m32" , "op": "RM: F2 0F 1B /r" , "arch": "X86"},
{"inst": "bndcn R:bnd, r64/m64" , "op": "RM: F2 0F 1B /r" , "arch": "X64"},
{"inst": "bndcu R:bnd, r32/m32" , "op": "RM: F2 0F 1A /r" , "arch": "X86"},
{"inst": "bndcu R:bnd, r64/m64" , "op": "RM: F2 0F 1A /r" , "arch": "X64"},
{"inst": "bndldx W:bnd, mib" , "op": "RM: 0F 1A /r"},
{"inst": "bndmk W:bnd, mem" , "op": "RM: F3 0F 1B /r"},
{"inst": "bndmov W:bnd, bnd/mem" , "op": "RM: 66 0F 1A /r"},
{"inst": "bndmov W:bnd/mem, bnd" , "op": "MR: 66 0F 1B /r"},
{"inst": "bndstx W:mib, bnd" , "op": "MR: 0F 1B /r"}
]},
{"category": "GP GP_EXT", "volatile": true, "data": [
{"inst": "fxrstor R:mem" , "op": "0F AE /1" , "ext": "FXSR" , "io": "C0=W C1=W C2=W C3=W"},
{"inst": "fxrstor64 R:mem" , "op": "REX.W 0F AE /1" , "ext": "FXSR" , "io": "C0=W C1=W C2=W C3=W"},
{"inst": "fxsave W:mem" , "op": "0F AE /0" , "ext": "FXSR" , "io": "C0=R C1=R C2=R C3=R"},
{"inst": "fxsave64 W:mem" , "op": "REX.W 0F AE /0" , "ext": "FXSR" , "io": "C0=R C1=R C2=R C3=R"},
{"inst": "xgetbv W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 01 D0" , "ext": "XSAVE" , "io": "XCR=R"},
{"inst": "xrstor R:mem, <edx>, <eax>" , "op": "0F AE /5" , "ext": "XSAVE" , "io": "XCR=R"},
{"inst": "xrstor64 R:mem, <edx>, <eax>" , "op": "REX.W 0F AE /5" , "ext": "XSAVE" , "io": "XCR=R"},
{"inst": "xsave W:mem, <edx>, <eax>" , "op": "0F AE /4" , "ext": "XSAVE" , "io": "XCR=R"},
{"inst": "xsave64 W:mem, <edx>, <eax>" , "op": "REX.W 0F AE /4" , "ext": "XSAVE" , "io": "XCR=R"},
{"inst": "xsavec W:mem, <edx>, <eax>" , "op": "0F C7 /4" , "ext": "XSAVEC" , "io": "XCR=R"},
{"inst": "xsavec64 W:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /4" , "ext": "XSAVEC" , "io": "XCR=R"},
{"inst": "xsaveopt W:mem, <edx>, <eax>" , "op": "0F AE /6" , "ext": "XSAVEOPT", "io": "XCR=R"},
{"inst": "xsaveopt64 W:mem, <edx>, <eax>" , "op": "REX.W 0F AE /6" , "ext": "XSAVEOPT", "io": "XCR=R"}
]},
{"category": "GP GP_EXT", "volatile": true, "data": [
{"inst": "incsspd r32" , "op": "F3 0F AE /5" , "ext": "CET_SS"},
{"inst": "incsspq r64" , "op": "REX.W F3 0F AE /5" , "ext": "CET_SS"},
{"inst": "monitorx R:<mem(ds:zax)>, R:<ecx>, R:<edx>" , "op": "0F 01 FA" , "ext": "MONITORX"},
{"inst": "mwaitx R:<eax>, R:<ecx>, R:<ebx>" , "op": "0F 01 FB" , "ext": "MONITORX"},
{"inst": "rdsspd W:r32" , "op": "F3 0F 1E /1" , "ext": "CET_SS"},
{"inst": "rdsspq W:r64" , "op": "REX.W F3 0F 1E /1" , "ext": "CET_SS"},
{"inst": "rstorssp R:m64" , "op": "F3 0F 01 /5" , "ext": "CET_SS" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "saveprevssp" , "op": "F3 0F 01 EA" , "ext": "CET_SS" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "tpause R:r32, <edx>, <eax>" , "op": "66 0F AE /6" , "ext": "WAITPKG" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "umonitor R:mem(ds:r32)" , "op": "F3 0F AE /6" , "ext": "WAITPKG" , "arch": "X86"},
{"inst": "umonitor R:mem(ds:r64)" , "op": "F3 0F AE /6" , "ext": "WAITPKG" , "arch": "X64"},
{"inst": "umwait R:r32, <edx>, <eax>" , "op": "F2 0F AE /6" , "ext": "WAITPKG" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"}
]},
{"category": "GP GP_EXT", "ext": "LWP", "volatile": true, "data": [
{"inst": "llwpcb R:r32" , "op": "XOP.L0.P0.M09.W0 12 /0"},
{"inst": "llwpcb R:r64" , "op": "XOP.L0.P0.M09.W1 12 /0"},
{"inst": "lwpins R:r32, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W0 12 /0 id"},
{"inst": "lwpins R:r64, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W1 12 /0 id"},
{"inst": "lwpval R:r32, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W0 12 /1 id"},
{"inst": "lwpval R:r64, R:r32/m32, id/ud" , "op": "VM: XOP.L0.P0.M0A.W1 12 /1 id"},
{"inst": "slwpcb W:r32" , "op": "XOP.L0.P0.M09.W0 12 /1"},
{"inst": "slwpcb W:r64" , "op": "XOP.L0.P0.M09.W1 12 /1"}
]},
{"category": "GP GP_EXT", "ext": "FSGSBASE", "arch": "X64", "volatile": true, "data": [
{"inst": "rdfsbase W:r32" , "op": "F3 0F AE /0"},
{"inst": "rdfsbase W:r64" , "op": "REX.W F3 0F AE /0"},
{"inst": "rdgsbase W:r32" , "op": "F3 0F AE /1"},
{"inst": "rdgsbase W:r64" , "op": "REX.W F3 0F AE /1"},
{"inst": "wrfsbase R:r32" , "op": "F3 0F AE /2"},
{"inst": "wrfsbase R:r64" , "op": "REX.W F3 0F AE /2"},
{"inst": "wrgsbase R:r32" , "op": "F3 0F AE /3"},
{"inst": "wrgsbase R:r64" , "op": "REX.W F3 0F AE /3"}
]},
{"category": "GP GP_EXT", "ext": "UINTR", "arch": "X64", "volatile": true, "data": [
{"inst": "uiret" , "op": "F3 0F 01 EC"},
{"inst": "clui" , "op": "F3 0F 01 EE"},
{"inst": "stui" , "op": "F3 0F 01 EF"},
{"inst": "testui" , "op": "F3 0F 01 ED" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "senduipi R:r64" , "op": "R: F3 0F C7 /6"}
]},
{"category": "GP GP_EXT", "ext": "PCONFIG", "volatile": true, "data": [
{"inst": "pconfig" , "op": "0F 01 C5"}
]},
{"category": "GP GP_EXT", "ext": "TSE", "arch": "X64", "volatile": true, "data": [
{"inst": "pbndkb" , "op": "0F 01 C7"}
]},
{"category": "GP GP_EXT", "volatile": true, "data": [
{"inst": "xabort ib/ub" , "op": "C6 /7 ib" , "ext": "RTM"},
{"inst": "xbegin rel16" , "op": "66 C7 /7 cw" , "ext": "RTM"},
{"inst": "xbegin rel32" , "op": "C7 /7 cd" , "ext": "RTM"},
{"inst": "xend" , "op": "0F 01 D5" , "ext": "RTM"},
{"inst": "xresldtrk" , "op": "F2 0F 01 E9" , "ext": "TSXLDTRK"},
{"inst": "xsusldtrk" , "op": "F2 0F 01 E8" , "ext": "TSXLDTRK"},
{"inst": "xtest" , "op": "0F 01 D6" , "ext": "TSX" , "io": "OF=0 SF=0 ZF=W AF=0 PF=0 CF=0"}
]},
{"category": "GP", "volatile": true, "privilege": "L0", "data": [ {"category": "GP", "volatile": true, "privilege": "L0", "data": [
{"inst": "clrssbsy R:m64" , "op": "F3 0F AE /6" , "ext": "CET_SS" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "clts" , "op": "0F 06"}, {"inst": "clts" , "op": "0F 06"},
{"inst": "endbr32" , "op": "F3 0F 1E FB" , "ext": "CET_IBT"},
{"inst": "endbr64" , "op": "F3 0F 1E FA" , "ext": "CET_IBT"},
{"inst": "getsec <eax>" , "op": "0F 37" , "ext": "SMX"},
{"inst": "hlt" , "op": "F4"}, {"inst": "hlt" , "op": "F4"},
{"inst": "hreset ib/ub, W:<eax>" , "op": "F3 0F 3A F0 /0 ib" , "ext": "HRESET"},
{"inst": "invd" , "op": "0F 08" , "ext": "I486" },
{"inst": "invlpg R:mem" , "op": "0F 01 /7" , "ext": "I486"},
{"inst": "invpcid R:r32, R:m128" , "op": "RM: 66 0F 38 82 /r" , "ext": "I486" , "arch": "X86"},
{"inst": "invpcid R:r64, R:m128" , "op": "RM: 66 0F 38 82 /r" , "ext": "I486" , "arch": "X64"},
{"inst": "lgdt R:mem" , "op": "0F 01 /2"}, {"inst": "lgdt R:mem" , "op": "0F 01 /2"},
{"inst": "lidt R:mem" , "op": "0F 01 /3"}, {"inst": "lidt R:mem" , "op": "0F 01 /3"},
{"inst": "lldt R:r16/m16" , "op": "0F 00 /2"}, {"inst": "lldt R:r16/m16" , "op": "0F 00 /2"},
{"inst": "lmsw R:r16/m16" , "op": "0F 01 /6"}, {"inst": "lmsw R:r16/m16" , "op": "0F 01 /6"},
{"inst": "ltr R:r16/m16" , "op": "0F 00 /3"}, {"inst": "ltr R:r16/m16" , "op": "0F 00 /3"},
{"inst": "monitor R:<mem(ds:zax)>, R:<ecx>, R:<edx>" , "op": "0F 01 C8" , "ext": "MONITOR"},
{"inst": "mwait R:<eax>, R:<ecx>" , "op": "0F 01 C9" , "ext": "MONITOR"},
{"inst": "rdpmc W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 33"}, {"inst": "rdpmc W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 33"},
{"inst": "rdmsr W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 32" , "ext": "MSR" , "io": "MSR=R"},
{"inst": "rdmsrlist R:<mem(ds:rsi)>, W:<mem(ds:rdi)>, X:<rcx>" , "op": "F2 0F 01 C6" , "ext": "MSRLIST" , "arch": "X64", "io": "MSR=R"},
{"inst": "setssbsy" , "op": "F3 0F 01 E8" , "ext": "CET_SS"},
{"inst": "swapgs" , "op": "0F 01 F8" , "arch": "X64"}, {"inst": "swapgs" , "op": "0F 01 F8" , "arch": "X64"},
{"inst": "sysexit" , "op": "0F 35"}, {"inst": "sysexit" , "op": "0F 35"},
{"inst": "sysexitq" , "op": "REX.W 0F 35"}, {"inst": "sysexitq" , "op": "REX.W 0F 35"},
{"inst": "sysret" , "op": "0F 07" , "arch": "X64"}, {"inst": "sysret" , "op": "0F 07" , "arch": "X64"},
{"inst": "sysretq" , "op": "REX.W 0F 07" , "arch": "X64"}, {"inst": "sysretq" , "op": "REX.W 0F 07" , "arch": "X64"}
{"inst": "wbinvd" , "op": "0F 09" , "ext": "I486"}, ]},
{"inst": "wbnoinvd" , "op": "F3 0F 09" , "ext": "WBNOINVD"},
{"inst": "wrmsrns R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 01 C6" , "ext": "WRMSRNS" , "io": "MSR=W"}, {"category": "GP", "ext": "I486", "volatile": true, "privilege": "L0", "data": [
{"inst": "wrmsr R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 30" , "ext": "MSR" , "io": "MSR=W"}, {"inst": "invd" , "op": "0F 08"},
{"inst": "wrmsrlist R:<mem(ds:rsi)>, R:<mem(ds:rdi)>, X:<rcx>" , "op": "F3 0F 01 C6" , "ext": "MSRLIST" , "arch": "X64", "io": "MSR=W"}, {"inst": "invlpg R:mem" , "op": "0F 01 /7"},
{"inst": "wrssd W:r32/m32, r32" , "op": "MR: 0F 38 F6 /r" , "ext": "CET_SS"}, {"inst": "invpcid R:r32, R:m128" , "op": "RM: 66 0F 38 82 /r" , "arch": "X86"},
{"inst": "wrssq W:r64/m64, r64" , "op": "MR: REX.W 0F 38 F6 /r" , "ext": "CET_SS"}, {"inst": "invpcid R:r64, R:m128" , "op": "RM: 66 0F 38 82 /r" , "arch": "X64"},
{"inst": "xrstors R:mem, <edx>, <eax>" , "op": "0F C7 /3" , "ext": "XSAVES" , "io": "XCR=R"}, {"inst": "wbinvd" , "op": "0F 09"}
{"inst": "xrstors64 R:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /3" , "ext": "XSAVES" , "io": "XCR=R"}, ]},
{"inst": "wrussd W:r32/m32, r32" , "op": "MR: 66 0F 38 F5 /r" , "ext": "CET_SS"},
{"inst": "wrussq W:r64/m64, r64" , "op": "MR: REX.W 66 0F 38 F5 /r" , "ext": "CET_SS"}, {"category": "GP GP_EXT", "ext": "CET_IBT", "volatile": true, "privilege": "L0", "data": [
{"inst": "xsaves W:mem, <edx>, <eax>" , "op": "0F C7 /5" , "ext": "XSAVES" , "io": "XCR=R"}, {"inst": "endbr32" , "op": "F3 0F 1E FB"},
{"inst": "xsaves64 W:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /5" , "ext": "XSAVES" , "io": "XCR=R"}, {"inst": "endbr64" , "op": "F3 0F 1E FA"}
{"inst": "xsetbv R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 01 D1" , "ext": "XSAVE" , "io": "XCR=W"} ]},
{"category": "GP GP_EXT", "ext": "CET_SS", "volatile": true, "privilege": "L0", "data": [
{"inst": "clrssbsy R:m64" , "op": "F3 0F AE /6" , "io": "OF=0 SF=0 ZF=0 AF=0 PF=0 CF=W"},
{"inst": "setssbsy" , "op": "F3 0F 01 E8"},
{"inst": "wrssd W:r32/m32, r32" , "op": "MR: 0F 38 F6 /r"},
{"inst": "wrssq W:r64/m64, r64" , "op": "MR: REX.W 0F 38 F6 /r"},
{"inst": "wrussd W:r32/m32, r32" , "op": "MR: 66 0F 38 F5 /r"},
{"inst": "wrussq W:r64/m64, r64" , "op": "MR: REX.W 66 0F 38 F5 /r"}
]},
{"category": "GP GP_EXT", "ext": "HRESET", "volatile": true, "privilege": "L0", "data": [
{"inst": "hreset ib/ub, W:<eax>" , "op": "F3 0F 3A F0 /0 ib"}
]},
{"category": "GP GP_EXT", "ext": "MONITOR", "volatile": true, "privilege": "L0", "data": [
{"inst": "monitor R:<mem(ds:zax)>, R:<ecx>, R:<edx>" , "op": "0F 01 C8"},
{"inst": "mwait R:<eax>, R:<ecx>" , "op": "0F 01 C9"}
]},
{"category": "GP GP_EXT", "ext": "MSR", "volatile": true, "privilege": "L0", "data": [
{"inst": "rdmsr W:<edx>, W:<eax>, R:<ecx>" , "op": "0F 32" , "io": "MSR=R"},
{"inst": "wrmsr R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 30" , "io": "MSR=W"}
]},
{"category": "GP GP_EXT", "ext": "MSRLIST", "arch": "X64", "volatile": true, "privilege": "L0", "data": [
{"inst": "rdmsrlist R:<mem(ds:rsi)>, W:<mem(ds:rdi)>, X:<rcx>" , "op": "F2 0F 01 C6" , "io": "MSR=R"},
{"inst": "wrmsrlist R:<mem(ds:rsi)>, R:<mem(ds:rdi)>, X:<rcx>" , "op": "F3 0F 01 C6" , "io": "MSR=W"}
]},
{"category": "GP GP_EXT", "ext": "SMX", "volatile": true, "privilege": "L0", "data": [
{"inst": "getsec <eax>" , "op": "0F 37"}
]},
{"category": "GP GP_EXT", "ext": "WBNOINVD", "volatile": true, "privilege": "L0", "data": [
{"inst": "wbnoinvd" , "op": "F3 0F 09"}
]},
{"category": "GP GP_EXT", "ext": "WRMSRNS", "volatile": true, "privilege": "L0", "data": [
{"inst": "wrmsrns R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 01 C6" , "io": "MSR=W"}
]},
{"category": "GP GP_EXT", "ext": "XSAVE", "volatile": true, "privilege": "L0", "data": [
{"inst": "xsetbv R:<edx>, R:<eax>, R:<ecx>" , "op": "0F 01 D1" , "io": "XCR=W"}
]},
{"category": "GP GP_EXT", "ext": "XSAVES", "volatile": true, "privilege": "L0", "data": [
{"inst": "xrstors R:mem, <edx>, <eax>" , "op": "0F C7 /3" , "io": "XCR=R"},
{"inst": "xrstors64 R:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /3" , "io": "XCR=R"},
{"inst": "xsaves W:mem, <edx>, <eax>" , "op": "0F C7 /5" , "io": "XCR=R"},
{"inst": "xsaves64 W:mem, <edx>, <eax>" , "op": "REX.W 0F C7 /5" , "io": "XCR=R"}
]}, ]},
{"category": "VIRTUALIZATION", "volatile": true, "data": [ {"category": "VIRTUALIZATION", "volatile": true, "data": [
@@ -1108,14 +1270,6 @@
{"inst": "fbstp W:m80bcd" , "op": "DF /6" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"}, {"inst": "fbstp W:m80bcd" , "op": "DF /6" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"},
{"inst": "fchs" , "op": "D9 E0" , "io": "C0=U C1=0 C2=U C3=U"}, {"inst": "fchs" , "op": "D9 E0" , "io": "C0=U C1=0 C2=U C3=U"},
{"inst": "fclex" , "op": "9B DB E2" , "io": "C0=U C1=U C2=U C3=U"}, {"inst": "fclex" , "op": "9B DB E2" , "io": "C0=U C1=U C2=U C3=U"},
{"inst": "fcmovb st(i)" , "op": "DA C0+i" , "io": "C0=U C1=W C2=U C3=U CF=R" , "ext": "CMOV"},
{"inst": "fcmovbe st(i)" , "op": "DA D0+i" , "io": "C0=U C1=W C2=U C3=U CF=R ZF=R", "ext": "CMOV"},
{"inst": "fcmove st(i)" , "op": "DA C8+i" , "io": "C0=U C1=W C2=U C3=U ZF=R" , "ext": "CMOV"},
{"inst": "fcmovnb st(i)" , "op": "DB C0+i" , "io": "C0=U C1=W C2=U C3=U CF=R" , "ext": "CMOV"},
{"inst": "fcmovnbe st(i)" , "op": "DB D0+i" , "io": "C0=U C1=W C2=U C3=U CF=R ZF=R", "ext": "CMOV"},
{"inst": "fcmovne st(i)" , "op": "DB C8+i" , "io": "C0=U C1=W C2=U C3=U ZF=R" , "ext": "CMOV"},
{"inst": "fcmovnu st(i)" , "op": "DB D8+i" , "io": "C0=U C1=W C2=U C3=U PF=R" , "ext": "CMOV"},
{"inst": "fcmovu st(i)" , "op": "DA D8+i" , "io": "C0=U C1=W C2=U C3=U PF=R" , "ext": "CMOV"},
{"inst": "fcom" , "op": "D8 D1" , "io": "C0=W C1=0 C2=W C3=W"}, {"inst": "fcom" , "op": "D8 D1" , "io": "C0=W C1=0 C2=W C3=W"},
{"inst": "fcom R:m32fp" , "op": "D8 /2" , "io": "C0=W C1=0 C2=W C3=W"}, {"inst": "fcom R:m32fp" , "op": "D8 /2" , "io": "C0=W C1=0 C2=W C3=W"},
{"inst": "fcom R:m64fp" , "op": "DC /2" , "io": "C0=W C1=0 C2=W C3=W"}, {"inst": "fcom R:m64fp" , "op": "DC /2" , "io": "C0=W C1=0 C2=W C3=W"},
@@ -1164,9 +1318,6 @@
{"inst": "fistp W:m16int" , "op": "DF /3" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"}, {"inst": "fistp W:m16int" , "op": "DF /3" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"},
{"inst": "fistp W:m32int" , "op": "DB /3" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"}, {"inst": "fistp W:m32int" , "op": "DB /3" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"},
{"inst": "fistp W:m64int" , "op": "DF /7" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"}, {"inst": "fistp W:m64int" , "op": "DF /7" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"},
{"inst": "fisttp W:m16int" , "op": "DF /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop", "ext": "SSE3"},
{"inst": "fisttp W:m32int" , "op": "DB /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop", "ext": "SSE3"},
{"inst": "fisttp W:m64int" , "op": "DD /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop", "ext": "SSE3"},
{"inst": "fisub R:m16int" , "op": "DE /4" , "io": "C0=U C1=W C2=U C3=U"}, {"inst": "fisub R:m16int" , "op": "DE /4" , "io": "C0=U C1=W C2=U C3=U"},
{"inst": "fisub R:m32int" , "op": "DA /4" , "io": "C0=U C1=W C2=U C3=U"}, {"inst": "fisub R:m32int" , "op": "DA /4" , "io": "C0=U C1=W C2=U C3=U"},
{"inst": "fisubr R:m16int" , "op": "DE /5" , "io": "C0=U C1=W C2=U C3=U"}, {"inst": "fisubr R:m16int" , "op": "DE /5" , "io": "C0=U C1=W C2=U C3=U"},
@@ -1249,6 +1400,23 @@
{"inst": "fyl2xp1" , "op": "D9 F9" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"} {"inst": "fyl2xp1" , "op": "D9 F9" , "io": "C0=U C1=W C2=U C3=U", "fpuStack": "pop"}
]}, ]},
{"category": "FPU", "ext": "FPU CMOV", "data": [
{"inst": "fcmovb st(i)" , "op": "DA C0+i" , "io": "C0=U C1=W C2=U C3=U CF=R" },
{"inst": "fcmovbe st(i)" , "op": "DA D0+i" , "io": "C0=U C1=W C2=U C3=U CF=R ZF=R"},
{"inst": "fcmove st(i)" , "op": "DA C8+i" , "io": "C0=U C1=W C2=U C3=U ZF=R" },
{"inst": "fcmovnb st(i)" , "op": "DB C0+i" , "io": "C0=U C1=W C2=U C3=U CF=R" },
{"inst": "fcmovnbe st(i)" , "op": "DB D0+i" , "io": "C0=U C1=W C2=U C3=U CF=R ZF=R"},
{"inst": "fcmovne st(i)" , "op": "DB C8+i" , "io": "C0=U C1=W C2=U C3=U ZF=R" },
{"inst": "fcmovnu st(i)" , "op": "DB D8+i" , "io": "C0=U C1=W C2=U C3=U PF=R" },
{"inst": "fcmovu st(i)" , "op": "DA D8+i" , "io": "C0=U C1=W C2=U C3=U PF=R" }
]},
{"category": "FPU", "ext": "FPU SSE3", "data": [
{"inst": "fisttp W:m16int" , "op": "DF /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop"},
{"inst": "fisttp W:m32int" , "op": "DB /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop"},
{"inst": "fisttp W:m64int" , "op": "DD /1" , "io": "C0=U C1=0 C2=U C3=U", "fpuStack": "pop"}
]},
{"category": "MMX STATE", "deprecated": true, "volatile": true, "data": [ {"category": "MMX STATE", "deprecated": true, "volatile": true, "data": [
{"inst": "emms" , "op": "0F 77" , "ext": "MMX"}, {"inst": "emms" , "op": "0F 77" , "ext": "MMX"},
{"inst": "femms" , "op": "0F 0E" , "ext": "3DNOW"} {"inst": "femms" , "op": "0F 0E" , "ext": "3DNOW"}
@@ -1707,10 +1875,6 @@
{"inst": "insertq X:xmm, xmm, ib/ub, ib/ub" , "op": "RM: F2 0F 78 /r ib ib"} {"inst": "insertq X:xmm, xmm, ib/ub, ib/ub" , "op": "RM: F2 0F 78 /r ib ib"}
]}, ]},
{"category": "SSE SIMD", "ext": "PCLMULQDQ", "data": [
{"inst": "pclmulqdq X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A 44 /r ib"}
]},
{"category": "SSE SIMD CRYPTO_HASH", "ext": "AESNI", "data": [ {"category": "SSE SIMD CRYPTO_HASH", "ext": "AESNI", "data": [
{"inst": "aesdec X:xmm, xmm/m128" , "op": "RM: 66 0F 38 DE /r"}, {"inst": "aesdec X:xmm, xmm/m128" , "op": "RM: 66 0F 38 DE /r"},
{"inst": "aesdeclast X:xmm, xmm/m128" , "op": "RM: 66 0F 38 DF /r"}, {"inst": "aesdeclast X:xmm, xmm/m128" , "op": "RM: 66 0F 38 DF /r"},
@@ -1720,6 +1884,16 @@
{"inst": "aeskeygenassist W:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A DF /r ib"} {"inst": "aeskeygenassist W:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A DF /r ib"}
]}, ]},
{"category": "SSE SIMD", "ext": "GFNI", "data": [
{"inst": "gf2p8affineinvqb X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A CF /r ib"},
{"inst": "gf2p8affineqb X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A CE /r ib"},
{"inst": "gf2p8mulb X:xmm, xmm/m128" , "op": "RM: 66 0F 38 CF /r"}
]},
{"category": "SSE SIMD", "ext": "PCLMULQDQ", "data": [
{"inst": "pclmulqdq X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A 44 /r ib"}
]},
{"category": "SSE SIMD CRYPTO_HASH", "ext": "SHA", "data": [ {"category": "SSE SIMD CRYPTO_HASH", "ext": "SHA", "data": [
{"inst": "sha1msg1 xmm, xmm/m128" , "op": "RM: 0F 38 C9 /r"}, {"inst": "sha1msg1 xmm, xmm/m128" , "op": "RM: 0F 38 C9 /r"},
{"inst": "sha1msg2 xmm, xmm/m128" , "op": "RM: 0F 38 CA /r"}, {"inst": "sha1msg2 xmm, xmm/m128" , "op": "RM: 0F 38 CA /r"},
@@ -1730,12 +1904,6 @@
{"inst": "sha256rnds2 xmm, xmm/m128, <xmm0>" , "op": "RM: 0F 38 CB /r"} {"inst": "sha256rnds2 xmm, xmm/m128, <xmm0>" , "op": "RM: 0F 38 CB /r"}
]}, ]},
{"category": "SSE SIMD", "ext": "GFNI", "data": [
{"inst": "gf2p8affineinvqb X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A CF /r ib"},
{"inst": "gf2p8affineqb X:xmm, xmm/m128, ib/ub" , "op": "RM: 66 0F 3A CE /r ib"},
{"inst": "gf2p8mulb X:xmm, xmm/m128" , "op": "RM: 66 0F 38 CF /r"}
]},
{"category": "AVX STATE", "ext": "AVX", "data": [ {"category": "AVX STATE", "ext": "AVX", "data": [
{"inst": "vldmxcsr R:m32" , "op": "VEX.LZ.0F.WIG AE /2", "io": "MXCSR=W"}, {"inst": "vldmxcsr R:m32" , "op": "VEX.LZ.0F.WIG AE /2", "io": "MXCSR=W"},
{"inst": "vstmxcsr W:m32" , "op": "VEX.LZ.0F.WIG AE /3", "io": "MXCSR=R"}, {"inst": "vstmxcsr W:m32" , "op": "VEX.LZ.0F.WIG AE /3", "io": "MXCSR=R"},

View File

@@ -31,26 +31,45 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"ARMv8a\0" "ARMv8a\0"
"THUMB\0" "THUMB\0"
"THUMBv2\0" "THUMBv2\0"
"ABLE\0"
"ADERR\0"
"AES\0" "AES\0"
"AFP\0" "AFP\0"
"AIE\0"
"AMU1\0"
"AMU1_1\0"
"ANERR\0"
"ASIMD\0" "ASIMD\0"
"BF16\0" "BF16\0"
"BRBE\0"
"BTI\0" "BTI\0"
"BWE\0"
"CCIDX\0" "CCIDX\0"
"CHK\0" "CHK\0"
"CLRBHB\0" "CLRBHB\0"
"CMOW\0"
"CONSTPACFIELD\0"
"CPA\0"
"CPA2\0"
"CPUID\0" "CPUID\0"
"CRC32\0" "CRC32\0"
"CSSC\0" "CSSC\0"
"CSV2\0"
"CSV2_3\0"
"CSV3\0"
"D128\0" "D128\0"
"DGH\0" "DGH\0"
"DIT\0" "DIT\0"
"DOTPROD\0" "DOTPROD\0"
"DPB\0" "DPB\0"
"DPB2\0" "DPB2\0"
"EBEP\0"
"EBF16\0" "EBF16\0"
"ECBHB\0"
"ECV\0" "ECV\0"
"EDHSR\0"
"EDSP\0" "EDSP\0"
"FAMINMAX\0"
"FCMA\0" "FCMA\0"
"FGT\0" "FGT\0"
"FGT2\0" "FGT2\0"
@@ -61,13 +80,25 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"FP\0" "FP\0"
"FP16\0" "FP16\0"
"FP16CONV\0" "FP16CONV\0"
"FP8\0"
"FP8DOT2\0"
"FP8DOT4\0"
"FP8FMA\0"
"FPMR\0"
"FRINTTS\0" "FRINTTS\0"
"GCS\0" "GCS\0"
"HACDBS\0"
"HAFDBS\0"
"HAFT\0"
"HDBSS\0"
"HBC\0" "HBC\0"
"HCX\0" "HCX\0"
"HPDS\0"
"HPDS2\0"
"I8MM\0" "I8MM\0"
"IDIVA\0" "IDIVA\0"
"IDIVT\0" "IDIVT\0"
"ITE\0"
"JSCVT\0" "JSCVT\0"
"LOR\0" "LOR\0"
"LRCPC\0" "LRCPC\0"
@@ -79,12 +110,24 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"LSE\0" "LSE\0"
"LSE128\0" "LSE128\0"
"LSE2\0" "LSE2\0"
"LUT\0"
"LVA\0"
"LVA3\0"
"MEC\0"
"MOPS\0" "MOPS\0"
"MPAM\0" "MPAM\0"
"MTE\0" "MTE\0"
"MTE2\0" "MTE2\0"
"MTE3\0" "MTE3\0"
"MTE4\0" "MTE4\0"
"MTE_ASYM_FAULT\0"
"MTE_ASYNC\0"
"MTE_CANONICAL_TAGS\0"
"MTE_NO_ADDRESS_TAGS\0"
"MTE_PERM_S1\0"
"MTE_STORE_ONLY\0"
"MTE_TAGGED_FAR\0"
"MTPMU\0"
"NMI\0" "NMI\0"
"NV\0" "NV\0"
"NV2\0" "NV2\0"
@@ -92,19 +135,28 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"PAN2\0" "PAN2\0"
"PAN3\0" "PAN3\0"
"PAUTH\0" "PAUTH\0"
"PFAR\0"
"PMU\0" "PMU\0"
"PMULL\0" "PMULL\0"
"PRFMSLC\0" "PRFMSLC\0"
"RAS\0" "RAS\0"
"RAS1_1\0" "RAS1_1\0"
"RAS2\0" "RAS2\0"
"RASSA2\0"
"RDM\0" "RDM\0"
"RME\0" "RME\0"
"RNG\0" "RNG\0"
"RNG_TRAP\0" "RNG_TRAP\0"
"RPRES\0" "RPRES\0"
"RPRFM\0" "RPRFM\0"
"S1PIE\0"
"S1POE\0"
"S2PIE\0"
"S2POE\0"
"SB\0" "SB\0"
"SCTLR2\0"
"SEBEP\0"
"SEL2\0"
"SHA1\0" "SHA1\0"
"SHA256\0" "SHA256\0"
"SHA3\0" "SHA3\0"
@@ -121,14 +173,32 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"SME_F16F32\0" "SME_F16F32\0"
"SME_F32F32\0" "SME_F32F32\0"
"SME_F64F64\0" "SME_F64F64\0"
"SME_F8F16\0"
"SME_F8F32\0"
"SME_FA64\0" "SME_FA64\0"
"SME_I16I32\0" "SME_I16I32\0"
"SME_I16I64\0" "SME_I16I64\0"
"SME_I8I32\0" "SME_I8I32\0"
"SME_LUTv2\0"
"SPE\0"
"SPE1_1\0"
"SPE1_2\0"
"SPE1_3\0"
"SPE1_4\0"
"SPE_ALTCLK\0"
"SPE_CRR\0"
"SPE_EFT\0"
"SPE_FDS\0"
"SPE_FPF\0"
"SPE_SME\0"
"SPECRES\0" "SPECRES\0"
"SPECRES2\0" "SPECRES2\0"
"SPMU\0"
"SSBS\0" "SSBS\0"
"SSBS2\0" "SSBS2\0"
"SSVE_FP8DOT2\0"
"SSVE_FP8DOT4\0"
"SSVE_FP8FMA\0"
"SVE\0" "SVE\0"
"SVE2\0" "SVE2\0"
"SVE2_1\0" "SVE2_1\0"
@@ -146,25 +216,35 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"SYSINSTR128\0" "SYSINSTR128\0"
"SYSREG128\0" "SYSREG128\0"
"THE\0" "THE\0"
"TLBIOS\0"
"TLBIRANGE\0"
"TLBIW\0"
"TME\0" "TME\0"
"TRF\0" "TRF\0"
"UAO\0" "UAO\0"
"VFP_D32\0" "VFP_D32\0"
"VHE\0" "VHE\0"
"VMID16\0"
"WFXT\0" "WFXT\0"
"XNX\0"
"XS\0" "XS\0"
"<Unknown>\0"; "<Unknown>\0";
static const uint16_t sFeatureIndex[] = { static const uint16_t sFeatureIndex[] = {
0, 5, 11, 17, 24, 30, 38, 42, 46, 52, 57, 61, 67, 71, 78, 84, 90, 95, 100, 0, 5, 11, 17, 24, 30, 38, 43, 49, 53, 57, 61, 66, 73, 79, 85, 90, 95, 99,
104, 108, 116, 120, 125, 131, 135, 140, 145, 149, 154, 158, 164, 171, 176, 103, 109, 113, 120, 125, 139, 143, 148, 154, 160, 165, 170, 177, 182, 187,
179, 184, 193, 201, 205, 209, 213, 218, 224, 230, 236, 240, 246, 253, 260, 191, 195, 203, 207, 212, 217, 223, 229, 233, 239, 244, 253, 258, 262, 267,
265, 278, 285, 289, 296, 301, 306, 311, 315, 320, 325, 330, 334, 337, 341, 271, 277, 284, 289, 292, 297, 306, 310, 318, 326, 333, 338, 346, 350, 357,
345, 350, 355, 361, 365, 371, 379, 383, 390, 395, 399, 403, 407, 416, 422, 364, 369, 375, 379, 383, 388, 394, 399, 405, 411, 415, 421, 425, 431, 438,
428, 431, 436, 443, 448, 455, 459, 463, 467, 472, 479, 490, 501, 513, 524, 445, 450, 463, 470, 474, 481, 486, 490, 494, 499, 503, 508, 513, 517, 522,
535, 546, 557, 566, 577, 588, 598, 606, 615, 620, 626, 630, 635, 642, 650, 527, 532, 547, 557, 576, 596, 608, 623, 638, 644, 648, 651, 655, 659, 664,
661, 670, 682, 692, 702, 712, 721, 734, 743, 751, 763, 773, 777, 781, 785, 669, 675, 680, 684, 690, 698, 702, 709, 714, 721, 725, 729, 733, 742, 748,
789, 797, 801, 806, 809 754, 760, 766, 772, 778, 781, 788, 794, 799, 804, 811, 816, 823, 827, 831,
835, 840, 847, 858, 869, 881, 892, 903, 914, 925, 935, 945, 954, 965, 976,
986, 996, 1000, 1007, 1014, 1021, 1028, 1039, 1047, 1055, 1063, 1071, 1079,
1087, 1096, 1101, 1106, 1112, 1125, 1138, 1150, 1154, 1159, 1166, 1174, 1185,
1194, 1206, 1216, 1226, 1236, 1245, 1258, 1267, 1275, 1287, 1297, 1301, 1308,
1318, 1324, 1328, 1332, 1336, 1344, 1348, 1355, 1360, 1364, 1367
}; };
// @EnumStringEnd@ // @EnumStringEnd@

View File

@@ -179,38 +179,47 @@ namespace asmjit {
//! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. By default //! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. By default
//! AsmJit builds only the host backend, which is auto-detected at compile-time, but this can be overridden. //! AsmJit builds only the host backend, which is auto-detected at compile-time, but this can be overridden.
//! //!
//! - \ref ASMJIT_NO_X86 - Disable X86/X64 backends. //! - \ref ASMJIT_NO_X86 - Disables both X86 and X86_64 backends.
//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architectures. //! - \ref ASMJIT_NO_AARCH64 - Disables AArch64 backend.
//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architecture backends, only keeps a native backend.
//!
//! ### AsmJit Compilation Options
//!
//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the
//! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
//! enumerations, and functions.
//!
//! - \ref ASMJIT_NO_SHM_OPEN - Disables functionality that uses `shm_open()`.
//!
//! - \ref ASMJIT_NO_ABI_NAMESPACE - Disables inline ABI namespace within `asmjit` namespace. This is only provided
//! for users that control all the dependencies (even transitive ones) and that make sure that no two AsmJit
//! versions are used at the same time. This option can be debugging a little simpler as there would not be ABI
//! tag after `asmjit::` namespace. Otherwise asmjit would look like `asmjit::_abi_1_13::`, for example.
//! //!
//! ### Features Selection //! ### Features Selection
//! //!
//! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and //! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and
//! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...` //! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...`
//! definitions. //! definitions.
//!
//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the
//! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
//! enumerations, and functions.
//!
//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality completely. This implies \ref
//! ASMJIT_NO_COMPILER as \ref asmjit_compiler cannot be used without \ref asmjit_builder.
//!
//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
//!
//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime. //! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
//! //!
//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
//!
//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string representation of AsmJit constants, should //! - \ref ASMJIT_NO_TEXT - Disables everything that contains string representation of AsmJit constants, should
//! be used together with \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the ability to query //! be used together with \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the ability to query
//! instruction names, register names, etc... //! instruction names, register names, etc...
//! //!
//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
//!
//! - \ref ASMJIT_NO_VALIDATION - Disables validation API. //! - \ref ASMJIT_NO_VALIDATION - Disables validation API.
//! //!
//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, must be used together with \ref //! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, must be used together with \ref
//! ASMJIT_NO_COMPILER as \ref asmjit_compiler requires introspection for its liveness analysis and register //! ASMJIT_NO_COMPILER as \ref asmjit_compiler requires introspection for its liveness analysis and register
//! allocation. //! allocation.
//! //!
//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality completely. This implies \ref
//! ASMJIT_NO_COMPILER as \ref asmjit_compiler cannot be used without \ref asmjit_builder.
//!
//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
//!
//! \note It's not recommended to disable features if you plan to build AsmJit as a shared library that will be //! \note It's not recommended to disable features if you plan to build AsmJit as a shared library that will be
//! used by multiple projects that you don't control how AsmJit was built (for example AsmJit in a Linux distribution). //! used by multiple projects that you don't control how AsmJit was built (for example AsmJit in a Linux distribution).
//! The possibility to disable certain features exists mainly for customized AsmJit builds. //! The possibility to disable certain features exists mainly for customized AsmJit builds.
@@ -239,6 +248,18 @@ namespace asmjit {
//! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED` //! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
//! it's not using anything, which was deprecated. //! it's not using anything, which was deprecated.
//! //!
//! ### Changes committed at 2024-01-01
//!
//! Core changes:
//!
//! - Renamed equality functions `eq()` to `equals()` - Only related to `String`, `ZoneVector`, and `CpuFeatures`.
//! Old function names were deprecated.
//!
//! - Removed `CallConvId::kNone` in favor of `CallConvId::kCDecl`, which is now the default calling convention.
//!
//! - Deprecated `CallConvId::kHost` in favor of `CallConvId::kCDecl` - host calling convention is now not part
//! of CallConvId, it can be calculated from CallConvId and Environment instead.
//!
//! ### Changes committed at 2023-12-27 //! ### Changes committed at 2023-12-27
//! //!
//! Core changes: //! Core changes:

View File

@@ -16,7 +16,7 @@
#define ASMJIT_LIBRARY_MAKE_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) #define ASMJIT_LIBRARY_MAKE_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
//! AsmJit library version, see \ref ASMJIT_LIBRARY_MAKE_VERSION for a version format reference. //! AsmJit library version, see \ref ASMJIT_LIBRARY_MAKE_VERSION for a version format reference.
#define ASMJIT_LIBRARY_VERSION ASMJIT_LIBRARY_MAKE_VERSION(1, 12, 0) #define ASMJIT_LIBRARY_VERSION ASMJIT_LIBRARY_MAKE_VERSION(1, 13, 0)
//! \def ASMJIT_ABI_NAMESPACE //! \def ASMJIT_ABI_NAMESPACE
//! //!
@@ -27,7 +27,7 @@
//! AsmJit default, which makes it possible to use multiple AsmJit libraries within a single project, totally //! AsmJit default, which makes it possible to use multiple AsmJit libraries within a single project, totally
//! controlled by users. This is useful especially in cases in which some of such library comes from third party. //! controlled by users. This is useful especially in cases in which some of such library comes from third party.
#if !defined(ASMJIT_ABI_NAMESPACE) #if !defined(ASMJIT_ABI_NAMESPACE)
#define ASMJIT_ABI_NAMESPACE _abi_1_12 #define ASMJIT_ABI_NAMESPACE _abi_1_13
#endif // !ASMJIT_ABI_NAMESPACE #endif // !ASMJIT_ABI_NAMESPACE
//! \} //! \}
@@ -164,6 +164,41 @@ namespace asmjit {
// Target Architecture Detection // Target Architecture Detection
// ============================= // =============================
//! \addtogroup asmjit_core
//! \{
//! \def ASMJIT_ARCH_X86
//!
//! Defined to either 0, 32, or 64 depending on whether the target CPU is X86 (32) or X86_64 (64).
//! \def ASMJIT_ARCH_ARM
//!
//! Defined to either 0, 32, or 64 depending on whether the target CPU is ARM (32) or AArch64 (64).
//! \def ASMJIT_ARCH_MIPS
//!
//! Defined to either 0, 32, or 64 depending on whether the target CPU is MIPS (32) or MISP64 (64).
//! \def ASMJIT_ARCH_RISCV
//!
//! Defined to either 0, 32, or 64 depending on whether the target CPU is RV32 (32) or RV64 (64).
//! \def ASMJIT_ARCH_BITS
//!
//! Defined to either 32 or 64 depending on the target.
//! \def ASMJIT_ARCH_LE
//!
//! Defined to 1 if the target architecture is little endian.
//! \def ASMJIT_ARCH_BE
//!
//! Defined to 1 if the target architecture is big endian.
//! \}
//! \cond NONE
#if defined(_M_X64) || defined(__x86_64__) #if defined(_M_X64) || defined(__x86_64__)
#define ASMJIT_ARCH_X86 64 #define ASMJIT_ARCH_X86 64
#elif defined(_M_IX86) || defined(__X86__) || defined(__i386__) #elif defined(_M_IX86) || defined(__X86__) || defined(__i386__)
@@ -188,7 +223,14 @@ namespace asmjit {
#define ASMJIT_ARCH_MIPS 0 #define ASMJIT_ARCH_MIPS 0
#endif #endif
#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS) // NOTE `__riscv` is the correct macro in this case as specified by "RISC-V Toolchain Conventions".
#if (defined(__riscv) || defined(__riscv__)) && defined(__riscv_xlen)
#define ASMJIT_ARCH_RISCV __riscv_xlen
#else
#define ASMJIT_ARCH_RISCV 0
#endif
#define ASMJIT_ARCH_BITS (ASMJIT_ARCH_X86 | ASMJIT_ARCH_ARM | ASMJIT_ARCH_MIPS | ASMJIT_ARCH_RISCV)
#if ASMJIT_ARCH_BITS == 0 #if ASMJIT_ARCH_BITS == 0
#undef ASMJIT_ARCH_BITS #undef ASMJIT_ARCH_BITS
#if defined (__LP64__) || defined(_LP64) #if defined (__LP64__) || defined(_LP64)
@@ -218,6 +260,7 @@ namespace asmjit {
#endif #endif
#endif #endif
//! \endcond
// C++ Compiler and Features Detection // C++ Compiler and Features Detection
// =================================== // ===================================
@@ -231,10 +274,69 @@ namespace asmjit {
// API Decorators & C++ Extensions // API Decorators & C++ Extensions
// =============================== // ===============================
//! \addtogroup asmjit_core
//! \{
//! \def ASMJIT_API //! \def ASMJIT_API
//! //!
//! A decorator that is used to decorate API that AsmJit exports when built as a shared library. //! A decorator that is used to decorate API that AsmJit exports when built as a shared library.
//! \def ASMJIT_VIRTAPI
//!
//! This is basically a workaround. When using MSVC and marking class as DLL export everything gets exported, which
//! is unwanted in most projects. MSVC automatically exports typeinfo and vtable if at least one symbol of the class
//! is exported. However, GCC has some strange behavior that even if one or more symbol is exported it doesn't export
//! typeinfo unless the class itself is decorated with "visibility(default)" (i.e. ASMJIT_API).
//! \def ASMJIT_FORCE_INLINE
//!
//! Decorator to force inlining of functions, uses either `__attribute__((__always_inline__))` or __forceinline,
//! depending on C++ compiler.
//! \def ASMJIT_INLINE_NODEBUG
//!
//! Like \ref ASMJIT_FORCE_INLINE, but uses additionally `__nodebug__` or `__artificial__` attribute to make the
//! debugging of some AsmJit functions easier, especially getters and one-line abstractions where usually you don't
//! want to step in.
//! \def ASMJIT_NOINLINE
//!
//! Decorator to avoid inlining of functions, uses either `__attribute__((__noinline__))` or `__declspec(noinline)`
//! depending on C++ compiler.
//! \def ASMJIT_NORETURN
//!
//! Decorator that marks functions that should never return. Typically used to implement assertion handlers that
//! terminate, so the function never returns.
//! \def ASMJIT_CDECL
//!
//! CDECL function attribute - either `__attribute__((__cdecl__))` or `__cdecl`.
//! \def ASMJIT_STDCALL
//!
//! STDCALL function attribute - either `__attribute__((__stdcall__))` or `__stdcall`.
//!
//! \note This expands to nothing on non-x86 targets as STDCALL is X86 specific.
//! \def ASMJIT_FASTCALL
//!
//! FASTCALL function attribute - either `__attribute__((__fastcall__))` or `__fastcall`.
//!
//! \note Expands to nothing on non-x86 targets as FASTCALL is X86 specific.
//! \def ASMJIT_REGPARM(N)
//!
//! Expands to `__attribute__((__regparm__(N)))` when compiled by GCC or clang, nothing otherwise.
//! \def ASMJIT_VECTORCALL
//!
//! VECTORCALL function attribute - either `__attribute__((__vectorcall__))` or `__vectorcall`.
//!
//! \note Expands to nothing on non-x86 targets as VECTORCALL is X86 specific.
//! \}
// API (Export / Import). // API (Export / Import).
#if !defined(ASMJIT_STATIC) #if !defined(ASMJIT_STATIC)
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__)) #if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
@@ -262,12 +364,6 @@ namespace asmjit {
#define ASMJIT_VARAPI extern ASMJIT_API #define ASMJIT_VARAPI extern ASMJIT_API
#endif #endif
//! \def ASMJIT_VIRTAPI
//!
//! This is basically a workaround. When using MSVC and marking class as DLL export everything gets exported, which
//! is unwanted in most projects. MSVC automatically exports typeinfo and vtable if at least one symbol of the class
//! is exported. However, GCC has some strange behavior that even if one or more symbol is exported it doesn't export
//! typeinfo unless the class itself is decorated with "visibility(default)" (i.e. ASMJIT_API).
#if defined(__GNUC__) && !defined(_WIN32) #if defined(__GNUC__) && !defined(_WIN32)
#define ASMJIT_VIRTAPI ASMJIT_API #define ASMJIT_VIRTAPI ASMJIT_API
#else #else

View File

@@ -74,6 +74,9 @@ enum class Arch : uint8_t {
ASMJIT_ARCH_X86 == 32 ? kX86 : ASMJIT_ARCH_X86 == 32 ? kX86 :
ASMJIT_ARCH_X86 == 64 ? kX64 : ASMJIT_ARCH_X86 == 64 ? kX64 :
ASMJIT_ARCH_RISCV == 32 ? kRISCV32 :
ASMJIT_ARCH_RISCV == 64 ? kRISCV64 :
ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kARM : ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kARM :
ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kARM_BE : ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kARM_BE :
ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kAArch64 : ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kAArch64 :

View File

@@ -25,6 +25,7 @@ ASMJIT_BEGIN_NAMESPACE
//! Check out architecture specific assemblers for more details and examples: //! Check out architecture specific assemblers for more details and examples:
//! //!
//! - \ref x86::Assembler - X86/X64 assembler implementation. //! - \ref x86::Assembler - X86/X64 assembler implementation.
//! - \ref a64::Assembler - AArch64 assembler implementation.
class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter { class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter {
public: public:
ASMJIT_NONCOPYABLE(BaseAssembler) ASMJIT_NONCOPYABLE(BaseAssembler)

View File

@@ -181,6 +181,7 @@ public:
//! Check out architecture specific builders for more details and examples: //! Check out architecture specific builders for more details and examples:
//! //!
//! - \ref x86::Builder - X86/X64 builder implementation. //! - \ref x86::Builder - X86/X64 builder implementation.
//! - \ref a64::Builder - AArch64 builder implementation.
class ASMJIT_VIRTAPI BaseBuilder : public BaseEmitter { class ASMJIT_VIRTAPI BaseBuilder : public BaseEmitter {
public: public:
ASMJIT_NONCOPYABLE(BaseBuilder) ASMJIT_NONCOPYABLE(BaseBuilder)
@@ -813,11 +814,17 @@ public:
//! \name Instruction Options //! \name Instruction Options
//! \{ //! \{
//! Returns instruction options, see \ref InstOptions for more details.
ASMJIT_INLINE_NODEBUG InstOptions options() const noexcept { return _baseInst.options(); } ASMJIT_INLINE_NODEBUG InstOptions options() const noexcept { return _baseInst.options(); }
//! Tests whether instruction has the given \option` set/enabled.
ASMJIT_INLINE_NODEBUG bool hasOption(InstOptions option) const noexcept { return _baseInst.hasOption(option); } ASMJIT_INLINE_NODEBUG bool hasOption(InstOptions option) const noexcept { return _baseInst.hasOption(option); }
//! Sets instruction `options` to the provided value, resetting all others.
ASMJIT_INLINE_NODEBUG void setOptions(InstOptions options) noexcept { _baseInst.setOptions(options); } ASMJIT_INLINE_NODEBUG void setOptions(InstOptions options) noexcept { _baseInst.setOptions(options); }
//! Adds instruction `options` to the instruction.
ASMJIT_INLINE_NODEBUG void addOptions(InstOptions options) noexcept { _baseInst.addOptions(options); } ASMJIT_INLINE_NODEBUG void addOptions(InstOptions options) noexcept { _baseInst.addOptions(options); }
//! Clears instruction `options` of the instruction (disables the given options).
ASMJIT_INLINE_NODEBUG void clearOptions(InstOptions options) noexcept { _baseInst.clearOptions(options); } ASMJIT_INLINE_NODEBUG void clearOptions(InstOptions options) noexcept { _baseInst.clearOptions(options); }
//! Resets instruction options to none - disabling all instruction options.
ASMJIT_INLINE_NODEBUG void resetOptions() noexcept { _baseInst.resetOptions(); } ASMJIT_INLINE_NODEBUG void resetOptions() noexcept { _baseInst.resetOptions(); }
//! \} //! \}
@@ -905,6 +912,7 @@ public:
//! \name Utilities //! \name Utilities
//! \{ //! \{
//! Tests whether the given operand type `opType` is used by the instruction.
inline bool hasOpType(OperandType opType) const noexcept { inline bool hasOpType(OperandType opType) const noexcept {
const Operand* ops = operands(); const Operand* ops = operands();
for (uint32_t i = 0, count = opCount(); i < count; i++) for (uint32_t i = 0, count = opCount(); i < count; i++)
@@ -913,11 +921,19 @@ public:
return false; return false;
} }
//! Tests whether the instruction uses at least one register operand.
inline bool hasRegOp() const noexcept { return hasOpType(OperandType::kReg); } inline bool hasRegOp() const noexcept { return hasOpType(OperandType::kReg); }
//! Tests whether the instruction uses at least one memory operand.
inline bool hasMemOp() const noexcept { return hasOpType(OperandType::kMem); } inline bool hasMemOp() const noexcept { return hasOpType(OperandType::kMem); }
//! Tests whether the instruction uses at least one immediate operand.
inline bool hasImmOp() const noexcept { return hasOpType(OperandType::kImm); } inline bool hasImmOp() const noexcept { return hasOpType(OperandType::kImm); }
//! Tests whether the instruction uses at least one label operand.
inline bool hasLabelOp() const noexcept { return hasOpType(OperandType::kLabel); } inline bool hasLabelOp() const noexcept { return hasOpType(OperandType::kLabel); }
//! Returns the index of the given operand type `opType`.
//!
//! \note If the operand type wa found, the value returned represents its index in \ref operands()
//! array, otherwise \ref Globals::kNotFound is returned to signalize that the operand was not found.
inline uint32_t indexOfOpType(OperandType opType) const noexcept { inline uint32_t indexOfOpType(OperandType opType) const noexcept {
uint32_t i = 0; uint32_t i = 0;
uint32_t count = opCount(); uint32_t count = opCount();
@@ -925,15 +941,18 @@ public:
while (i < count) { while (i < count) {
if (ops[i].opType() == opType) if (ops[i].opType() == opType)
break; return i;
i++; i++;
} }
return i; return Globals::kNotFound;
} }
//! A shortcut that calls `indexOfOpType(OperandType::kMem)`.
inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(OperandType::kMem); } inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(OperandType::kMem); }
//! A shortcut that calls `indexOfOpType(OperandType::kImm)`.
inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(OperandType::kImm); } inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(OperandType::kImm); }
//! A shortcut that calls `indexOfOpType(OperandType::kLabel)`.
inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(OperandType::kLabel); } inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(OperandType::kLabel); }
//! \} //! \}
@@ -942,20 +961,40 @@ public:
//! \{ //! \{
//! \cond INTERNAL //! \cond INTERNAL
//! Returns uint32_t[] view that represents BaseInst::RegOnly and instruction operands.
ASMJIT_INLINE_NODEBUG uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; } ASMJIT_INLINE_NODEBUG uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; }
//! \overload
ASMJIT_INLINE_NODEBUG const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; } ASMJIT_INLINE_NODEBUG const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; }
//! Maximum value of rewrite id - 6 operands each having 4 slots is 24, one RegOnly having 2 slots => 26.
static constexpr uint32_t kMaxRewriteId = 26 - 1;
//! Returns a rewrite index of the given pointer to `id`.
//!
//! This function returns a value that can be then passed to `\ref rewriteIdAtIndex() function. It can address
//! any id from any operand that is used by the instruction in addition to \ref BaseInst::regOnly field, which
//! can also be used by the register allocator.
inline uint32_t getRewriteIndex(const uint32_t* id) const noexcept { inline uint32_t getRewriteIndex(const uint32_t* id) const noexcept {
const uint32_t* array = _getRewriteArray(); const uint32_t* array = _getRewriteArray();
ASMJIT_ASSERT(array <= id); ASMJIT_ASSERT(array <= id);
size_t index = (size_t)(id - array); size_t index = (size_t)(id - array);
ASMJIT_ASSERT(index < 32); ASMJIT_ASSERT(index <= kMaxRewriteId);
return uint32_t(index); return uint32_t(index);
} }
//! Rewrites the given `index` to the provided identifier `id`.
//!
//! \note This is an internal function that is used by a \ref BaseCompiler implementation to rewrite virtual
//! registers to physical registers. The rewriter in this case sees all operands as array of uint32 values
//! and the given `index` describes a position in this array. For example a single \ref Operand would be
//! decomposed to 4 uint32_t values, where the first at index 0 would be operand signature, next would be
//! base id, etc... This is a comfortable way of patching operands without having to check for their types.
inline void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept { inline void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept {
ASMJIT_ASSERT(index <= kMaxRewriteId);
uint32_t* array = _getRewriteArray(); uint32_t* array = _getRewriteArray();
array[index] = id; array[index] = id;
} }
@@ -967,10 +1006,19 @@ public:
//! \{ //! \{
//! \cond INTERNAL //! \cond INTERNAL
//! Returns the capacity required for the given operands count `opCount`.
//!
//! There are only two capacities used - \ref kBaseOpCapacity and \ref kFullOpCapacity, so this function
//! is used to decide between these two. The general rule is that instructions that can be represented with
//! \ref kBaseOpCapacity would use this value, and all others would take \ref kFullOpCapacity.
static ASMJIT_INLINE_NODEBUG constexpr uint32_t capacityOfOpCount(uint32_t opCount) noexcept { static ASMJIT_INLINE_NODEBUG constexpr uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
return opCount <= kBaseOpCapacity ? kBaseOpCapacity : Globals::kMaxOpCount; return opCount <= kBaseOpCapacity ? kBaseOpCapacity : kFullOpCapacity;
} }
//! Calculates the size of \ref InstNode required to hold at most `opCapacity` operands.
//!
//! This function is used internally to allocate \ref InstNode.
static ASMJIT_INLINE_NODEBUG constexpr size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept { static ASMJIT_INLINE_NODEBUG constexpr size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept {
return sizeof(InstNode) + opCapacity * sizeof(Operand); return sizeof(InstNode) + opCapacity * sizeof(Operand);
} }

View File

@@ -47,6 +47,7 @@ class InvokeNode;
//! Check out architecture specific compilers for more details and examples: //! Check out architecture specific compilers for more details and examples:
//! //!
//! - \ref x86::Compiler - X86/X64 compiler implementation. //! - \ref x86::Compiler - X86/X64 compiler implementation.
//! - \ref a64::Compiler - AArch64 compiler implementation.
class ASMJIT_VIRTAPI BaseCompiler : public BaseBuilder { class ASMJIT_VIRTAPI BaseCompiler : public BaseBuilder {
public: public:
ASMJIT_NONCOPYABLE(BaseCompiler) ASMJIT_NONCOPYABLE(BaseCompiler)

View File

@@ -27,6 +27,9 @@ enum class ConstPoolScope : uint32_t {
}; };
//! Constant pool. //! Constant pool.
//!
//! Constant pool is designed to hold 1, 2, 4, 8, 16, 32, and 64 byte constants. It's not designed to hold constants
//! having arbitrary length like strings and arrays.
class ConstPool { class ConstPool {
public: public:
ASMJIT_NONCOPYABLE(ConstPool) ASMJIT_NONCOPYABLE(ConstPool)
@@ -199,9 +202,17 @@ public:
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
ASMJIT_API ConstPool(Zone* zone) noexcept; //! Creates a new constant pool that would use `zone` as a memory allocator.
ASMJIT_API explicit ConstPool(Zone* zone) noexcept;
//! Destroys this constant pool.
ASMJIT_API ~ConstPool() noexcept; ASMJIT_API ~ConstPool() noexcept;
//! \}
//! \name Reset
//! \{
//! Resets this constant pool and its allocator to `zone`.
ASMJIT_API void reset(Zone* zone) noexcept; ASMJIT_API void reset(Zone* zone) noexcept;
//! \} //! \}

View File

@@ -569,6 +569,7 @@ static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
// Other resources: // Other resources:
// https://en.wikipedia.org/wiki/AArch64 // https://en.wikipedia.org/wiki/AArch64
// https://en.wikipedia.org/wiki/Apple_silicon#List_of_Apple_processors // https://en.wikipedia.org/wiki/Apple_silicon#List_of_Apple_processors
// https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
// https://developer.arm.com/architectures/learn-the-architecture/understanding-the-armv8-x-extensions/single-page // https://developer.arm.com/architectures/learn-the-architecture/understanding-the-armv8-x-extensions/single-page
#if ASMJIT_ARCH_ARM #if ASMJIT_ARCH_ARM
@@ -662,8 +663,8 @@ static inline void populateBaseARMFeatures(CpuInfo& cpu) noexcept {
#endif #endif
} }
// CpuInfo - Detect - ARM - Madatory Features of ARM Architectures // CpuInfo - Detect - ARM - Mandatory Features of ARM Architectures
// =============================================================== // ================================================================
// Populates mandatory ARMv8.[v]A features. // Populates mandatory ARMv8.[v]A features.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
@@ -681,16 +682,15 @@ static ASMJIT_FAVOR_SIZE void populateARMv8AFeatures(CpuFeatures::ARM& features,
features.add(Ext::kHCX, Ext::kPAN3, Ext::kWFXT, Ext::kXS); features.add(Ext::kHCX, Ext::kPAN3, Ext::kWFXT, Ext::kXS);
ASMJIT_FALLTHROUGH; ASMJIT_FALLTHROUGH;
case 6: // ARMv8.6 case 6: // ARMv8.6
// Missing: AMUv1p1. features.add(Ext::kAMU1_1, Ext::kBF16, Ext::kECV, Ext::kFGT, Ext::kI8MM);
features.add(Ext::kBF16, Ext::kECV, Ext::kFGT, Ext::kI8MM);
ASMJIT_FALLTHROUGH; ASMJIT_FALLTHROUGH;
case 5: // ARMv8.5 case 5: // ARMv8.5
// Missing: CSV2_2. features.add(Ext::kBTI, Ext::kCSV2, Ext::kDPB2, Ext::kFLAGM2, Ext::kFRINTTS, Ext::kSB, Ext::kSPECRES, Ext::kSSBS);
features.add(Ext::kBTI, Ext::kDPB2, Ext::kFLAGM2, Ext::kFRINTTS, Ext::kSB, Ext::kSPECRES, Ext::kSSBS);
ASMJIT_FALLTHROUGH; ASMJIT_FALLTHROUGH;
case 4: // ARMv8.4 case 4: // ARMv8.4
// Missing: AMUv1, SEL2, TLBIOS, TLBIRANGE. features.add(Ext::kAMU1, Ext::kDIT, Ext::kDOTPROD, Ext::kFLAGM,
features.add(Ext::kDIT, Ext::kDOTPROD, Ext::kFLAGM, Ext::kLRCPC2, Ext::kLSE2, Ext::kMPAM, Ext::kNV, Ext::kTRF); Ext::kLRCPC2, Ext::kLSE2, Ext::kMPAM, Ext::kNV,
Ext::kSEL2, Ext::kTLBIOS, Ext::kTLBIRANGE, Ext::kTRF);
ASMJIT_FALLTHROUGH; ASMJIT_FALLTHROUGH;
case 3: // ARMv8.3 case 3: // ARMv8.3
features.add(Ext::kCCIDX, Ext::kFCMA, Ext::kJSCVT, Ext::kLRCPC, Ext::kPAUTH); features.add(Ext::kCCIDX, Ext::kFCMA, Ext::kJSCVT, Ext::kLRCPC, Ext::kPAUTH);
@@ -755,9 +755,25 @@ static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeatureNA(CpuFeatures::ARM& fea
if (f3 != Ext::kNone) features.addIf(val >= 3, f3); if (f3 != Ext::kNone) features.addIf(val >= 3, f3);
} }
// Merges a feature that contains 0b0000 when it doesn't exist and starts at 0b0001 when it does. // Merges a feature identified by a single bit at `offset`.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeatureExt(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature1B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, Ext::Id f1) noexcept {
features.addIf((regBits & (uint64_t(1) << offset)) != 0, f1);
}
// Merges a feature-list starting from 0b01 when it does (0b00 means feature not supported).
ASMJIT_MAYBE_UNUSED
static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature2B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, Ext::Id f1, Ext::Id f2, Ext::Id f3) noexcept {
uint32_t val = uint32_t((regBits >> offset) & 0x3u);
if (f1 != Ext::kNone) features.addIf(val >= 1, f1);
if (f2 != Ext::kNone) features.addIf(val >= 2, f2);
if (f3 != Ext::kNone) features.addIf(val == 3, f3);
}
// Merges a feature-list starting from 0b0001 when it does (0b0000 means feature not supported).
ASMJIT_MAYBE_UNUSED
static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature4B(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset,
Ext::Id f1, Ext::Id f1,
Ext::Id f2 = Ext::kNone, Ext::Id f2 = Ext::kNone,
Ext::Id f3 = Ext::kNone, Ext::Id f3 = Ext::kNone,
@@ -773,65 +789,70 @@ static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeatureExt(CpuFeatures::ARM& fe
if (f4 != Ext::kNone) features.addIf(val >= 4, f4); if (f4 != Ext::kNone) features.addIf(val >= 4, f4);
} }
#define MERGE_FEATURE_N_A(identifier, reg, offset, ...) mergeAArch64CPUIDFeatureNA(cpu.features().arm(), reg, offset, __VA_ARGS__) // Merges a feature that is identified by an exact bit-combination of 4 bits.
#define MERGE_FEATURE_EXT(identifier, reg, offset, ...) mergeAArch64CPUIDFeatureExt(cpu.features().arm(), reg, offset, __VA_ARGS__) ASMJIT_MAYBE_UNUSED
static ASMJIT_FORCE_INLINE void mergeAArch64CPUIDFeature4S(CpuFeatures::ARM& features, uint64_t regBits, uint32_t offset, uint32_t value, Ext::Id f1) noexcept {
features.addIf(uint32_t((regBits >> offset) & 0xFu) == value, f1);
}
#define MERGE_FEATURE_NA(identifier, reg, offset, ...) mergeAArch64CPUIDFeatureNA(cpu.features().arm(), reg, offset, __VA_ARGS__)
#define MERGE_FEATURE_1B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature1B(cpu.features().arm(), reg, offset, __VA_ARGS__)
#define MERGE_FEATURE_2B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature2B(cpu.features().arm(), reg, offset, __VA_ARGS__)
#define MERGE_FEATURE_4B(identifier, reg, offset, ...) mergeAArch64CPUIDFeature4B(cpu.features().arm(), reg, offset, __VA_ARGS__)
#define MERGE_FEATURE_4S(identifier, reg, offset, ...) mergeAArch64CPUIDFeature4S(cpu.features().arm(), reg, offset, __VA_ARGS__)
// Detects features based on the content of ID_AA64PFR0_EL1 and ID_AA64PFR1_EL1 registers. // Detects features based on the content of ID_AA64PFR0_EL1 and ID_AA64PFR1_EL1 registers.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(CpuInfo& cpu, uint64_t fpr0, uint64_t fpr1) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(CpuInfo& cpu, uint64_t fpr0, uint64_t fpr1) noexcept {
// ID_AA64PFR0_EL1 // ID_AA64PFR0_EL1
// =============== // ===============
// FP and AdvSIMD bits should match (i.e. if FP features FP16, ASIMD must feature it too). // FP and AdvSIMD bits should match (i.e. if FP features FP16, ASIMD must feature it too).
MERGE_FEATURE_N_A("FP bits [19:16]" , fpr0, 16, Ext::kFP, Ext::kFP16); MERGE_FEATURE_NA("FP bits [19:16]" , fpr0, 16, Ext::kFP, Ext::kFP16);
MERGE_FEATURE_N_A("AdvSIMD bits [23:20]" , fpr0, 20, Ext::kASIMD, Ext::kFP16); MERGE_FEATURE_NA("AdvSIMD bits [23:20]" , fpr0, 20, Ext::kASIMD, Ext::kFP16);
/* /*
MERGE_FEATURE_EXT("GIC bits [27:24]" , fpr0, 24, ...); MERGE_FEATURE_4B("GIC bits [27:24]" , fpr0, 24, ...);
*/
MERGE_FEATURE_EXT("RAS bits [31:28]" , fpr0, 28, Ext::kRAS, Ext::kRAS1_1, Ext::kRAS2);
MERGE_FEATURE_EXT("SVE bits [35:32]" , fpr0, 32, Ext::kSVE);
/*
MERGE_FEATURE_EXT("SEL2 bits [39:36]" , fpr0, 36, ...);
MERGE_FEATURE_EXT("MPAM bits [43:40]" , fpr0, 40, ...);
MERGE_FEATURE_EXT("AMU bits [47:44]" , fpr0, 44, ...);
*/
MERGE_FEATURE_EXT("DIT bits [51:48]" , fpr0, 48, Ext::kDIT);
MERGE_FEATURE_EXT("RME bits [55:52]" , fpr0, 52, Ext::kRME);
/*
MERGE_FEATURE_EXT("CSV2 bits [59:56]" , fpr0, 56, ...);
MERGE_FEATURE_EXT("CSV3 bits [63:60]" , fpr0, 60, ...);
*/ */
MERGE_FEATURE_4B("RAS bits [31:28]" , fpr0, 28, Ext::kRAS, Ext::kRAS1_1, Ext::kRAS2);
MERGE_FEATURE_4B("SVE bits [35:32]" , fpr0, 32, Ext::kSVE);
MERGE_FEATURE_4B("SEL2 bits [39:36]" , fpr0, 36, Ext::kSEL2);
MERGE_FEATURE_4B("MPAM bits [43:40]" , fpr0, 40, Ext::kMPAM);
MERGE_FEATURE_4B("AMU bits [47:44]" , fpr0, 44, Ext::kAMU1, Ext::kAMU1_1);
MERGE_FEATURE_4B("DIT bits [51:48]" , fpr0, 48, Ext::kDIT);
MERGE_FEATURE_4B("RME bits [55:52]" , fpr0, 52, Ext::kRME);
MERGE_FEATURE_4B("CSV2 bits [59:56]" , fpr0, 56, Ext::kCSV2, Ext::kCSV2, Ext::kCSV2, Ext::kCSV2_3);
MERGE_FEATURE_4B("CSV3 bits [63:60]" , fpr0, 60, Ext::kCSV3);
// ID_AA64PFR1_EL1 // ID_AA64PFR1_EL1
// =============== // ===============
MERGE_FEATURE_EXT("BT bits [3:0]" , fpr1, 0, Ext::kBTI); MERGE_FEATURE_4B("BT bits [3:0]" , fpr1, 0, Ext::kBTI);
MERGE_FEATURE_EXT("SSBS bits [7:4]" , fpr1, 4, Ext::kSSBS, Ext::kSSBS2); MERGE_FEATURE_4B("SSBS bits [7:4]" , fpr1, 4, Ext::kSSBS, Ext::kSSBS2);
MERGE_FEATURE_EXT("MTE bits [11:8]" , fpr1, 8, Ext::kMTE, Ext::kMTE2, Ext::kMTE3); MERGE_FEATURE_4B("MTE bits [11:8]" , fpr1, 8, Ext::kMTE, Ext::kMTE2, Ext::kMTE3);
/* /*
MERGE_FEATURE_EXT("RAS_frac bits [15:12]" , fpr1, 12, ...); MERGE_FEATURE_4B("RAS_frac bits [15:12]" , fpr1, 12, ...);
MERGE_FEATURE_EXT("MPAM_frac bits [19:16]" , fpr1, 16, ...); MERGE_FEATURE_4B("MPAM_frac bits [19:16]" , fpr1, 16, ...);
*/ */
MERGE_FEATURE_EXT("SME bits [27:24]" , fpr1, 24, Ext::kSME, Ext::kSME2); MERGE_FEATURE_4B("SME bits [27:24]" , fpr1, 24, Ext::kSME, Ext::kSME2);
MERGE_FEATURE_EXT("RNDR_trap bits [31:28]" , fpr1, 28, Ext::kRNG_TRAP); MERGE_FEATURE_4B("RNDR_trap bits [31:28]" , fpr1, 28, Ext::kRNG_TRAP);
/* /*
MERGE_FEATURE_EXT("CSV2_frac bits [35:32]" , fpr1, 32, ...); MERGE_FEATURE_4B("CSV2_frac bits [35:32]" , fpr1, 32, ...);
*/ */
MERGE_FEATURE_EXT("NMI bits [39:36]" , fpr1, 36, Ext::kNMI); MERGE_FEATURE_4B("NMI bits [39:36]" , fpr1, 36, Ext::kNMI);
/* /*
MERGE_FEATURE_EXT("MTE_frac bits [43:40]" , fpr1, 40, ...); MERGE_FEATURE_4B("MTE_frac bits [43:40]" , fpr1, 40, ...);
MERGE_FEATURE_EXT("GCS bits [47:44]" , fpr1, 44, ...);
*/ */
MERGE_FEATURE_EXT("THE bits [51:48]" , fpr1, 48, Ext::kTHE); MERGE_FEATURE_4B("GCS bits [47:44]" , fpr1, 44, Ext::kGCS);
MERGE_FEATURE_4B("THE bits [51:48]" , fpr1, 48, Ext::kTHE);
// MTEX extensions are only available when MTE3 is available. // MTEX extensions are only available when MTE3 is available.
if (cpu.features().arm().hasMTE3()) if (cpu.features().arm().hasMTE3())
MERGE_FEATURE_EXT("MTEX bits [55:52]" , fpr1, 52, Ext::kMTE4); MERGE_FEATURE_4B("MTEX bits [55:52]" , fpr1, 52, Ext::kMTE4);
/* /*
MERGE_FEATURE_EXT("DF2 bits [59:56]" , fpr1, 56, ...); MERGE_FEATURE_4B("DF2 bits [59:56]" , fpr1, 56, ...);
MERGE_FEATURE_EXT("PFAR bits [63:60]" , fpr1, 60, ...);
*/ */
MERGE_FEATURE_4B("PFAR bits [63:60]" , fpr1, 60, Ext::kPFAR);
// ID_AA64PFR0_EL1 + ID_AA64PFR1_EL1 // ID_AA64PFR0_EL1 + ID_AA64PFR1_EL1
// ================================= // =================================
@@ -852,176 +873,212 @@ static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64PFR0_AA64PFR1(Cp
// Detects features based on the content of ID_AA64ISAR0_EL1 and ID_AA64ISAR1_EL1 registers. // Detects features based on the content of ID_AA64ISAR0_EL1 and ID_AA64ISAR1_EL1 registers.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64ISAR0_AA64ISAR1(CpuInfo& cpu, uint64_t isar0, uint64_t isar1) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64ISAR0_AA64ISAR1(CpuInfo& cpu, uint64_t isar0, uint64_t isar1) noexcept {
// ID_AA64ISAR0_EL1 // ID_AA64ISAR0_EL1
// ================ // ================
MERGE_FEATURE_EXT("AES bits [7:4]" , isar0, 4, Ext::kAES, Ext::kPMULL); MERGE_FEATURE_4B("AES bits [7:4]" , isar0, 4, Ext::kAES, Ext::kPMULL);
MERGE_FEATURE_EXT("SHA1 bits [11:8]" , isar0, 8, Ext::kSHA1); MERGE_FEATURE_4B("SHA1 bits [11:8]" , isar0, 8, Ext::kSHA1);
MERGE_FEATURE_EXT("SHA2 bits [15:12]" , isar0, 12, Ext::kSHA256, Ext::kSHA512); MERGE_FEATURE_4B("SHA2 bits [15:12]" , isar0, 12, Ext::kSHA256, Ext::kSHA512);
MERGE_FEATURE_EXT("CRC32 bits [19:16]" , isar0, 16, Ext::kCRC32); MERGE_FEATURE_4B("CRC32 bits [19:16]" , isar0, 16, Ext::kCRC32);
MERGE_FEATURE_EXT("Atomic bits [23:20]" , isar0, 20, Ext::kNone, Ext::kLSE, Ext::kLSE128); MERGE_FEATURE_4B("Atomic bits [23:20]" , isar0, 20, Ext::kNone, Ext::kLSE, Ext::kLSE128);
MERGE_FEATURE_EXT("TME bits [27:24]" , isar0, 24, Ext::kTME); MERGE_FEATURE_4B("TME bits [27:24]" , isar0, 24, Ext::kTME);
MERGE_FEATURE_EXT("RDM bits [31:28]" , isar0, 28, Ext::kRDM); MERGE_FEATURE_4B("RDM bits [31:28]" , isar0, 28, Ext::kRDM);
MERGE_FEATURE_EXT("SHA3 bits [35:32]" , isar0, 32, Ext::kSHA3); MERGE_FEATURE_4B("SHA3 bits [35:32]" , isar0, 32, Ext::kSHA3);
MERGE_FEATURE_EXT("SM3 bits [39:36]" , isar0, 36, Ext::kSM3); MERGE_FEATURE_4B("SM3 bits [39:36]" , isar0, 36, Ext::kSM3);
MERGE_FEATURE_EXT("SM4 bits [43:40]" , isar0, 40, Ext::kSM4); MERGE_FEATURE_4B("SM4 bits [43:40]" , isar0, 40, Ext::kSM4);
MERGE_FEATURE_EXT("DP bits [47:44]" , isar0, 44, Ext::kDOTPROD); MERGE_FEATURE_4B("DP bits [47:44]" , isar0, 44, Ext::kDOTPROD);
MERGE_FEATURE_EXT("FHM bits [51:48]" , isar0, 48, Ext::kFHM); MERGE_FEATURE_4B("FHM bits [51:48]" , isar0, 48, Ext::kFHM);
MERGE_FEATURE_EXT("TS bits [55:52]" , isar0, 52, Ext::kFLAGM, Ext::kFLAGM2); MERGE_FEATURE_4B("TS bits [55:52]" , isar0, 52, Ext::kFLAGM, Ext::kFLAGM2);
/* /*
MERGE_FEATURE_EXT("TLB bits [59:56]" , isar0, 56, ...); MERGE_FEATURE_4B("TLB bits [59:56]" , isar0, 56, ...);
*/ */
MERGE_FEATURE_EXT("RNDR bits [63:60]" , isar0, 60, Ext::kFLAGM, Ext::kRNG); MERGE_FEATURE_4B("RNDR bits [63:60]" , isar0, 60, Ext::kFLAGM, Ext::kRNG);
// ID_AA64ISAR1_EL1 // ID_AA64ISAR1_EL1
// ================ // ================
MERGE_FEATURE_EXT("DPB bits [3:0]" , isar1, 0, Ext::kDPB, Ext::kDPB2); MERGE_FEATURE_4B("DPB bits [3:0]" , isar1, 0, Ext::kDPB, Ext::kDPB2);
/* /*
MERGE_FEATURE_EXT("APA bits [7:4]" , isar1, 4, ...); MERGE_FEATURE_4B("APA bits [7:4]" , isar1, 4, ...);
MERGE_FEATURE_EXT("API bits [11:8]" , isar1, 8, ...); MERGE_FEATURE_4B("API bits [11:8]" , isar1, 8, ...);
*/ */
MERGE_FEATURE_EXT("JSCVT bits [15:12]" , isar1, 12, Ext::kJSCVT); MERGE_FEATURE_4B("JSCVT bits [15:12]" , isar1, 12, Ext::kJSCVT);
MERGE_FEATURE_EXT("FCMA bits [19:16]" , isar1, 16, Ext::kFCMA); MERGE_FEATURE_4B("FCMA bits [19:16]" , isar1, 16, Ext::kFCMA);
MERGE_FEATURE_EXT("LRCPC bits [23:20]" , isar1, 20, Ext::kLRCPC, Ext::kLRCPC2, Ext::kLRCPC3); MERGE_FEATURE_4B("LRCPC bits [23:20]" , isar1, 20, Ext::kLRCPC, Ext::kLRCPC2, Ext::kLRCPC3);
/* /*
MERGE_FEATURE_EXT("GPA bits [27:24]" , isar1, 24, ...); MERGE_FEATURE_4B("GPA bits [27:24]" , isar1, 24, ...);
MERGE_FEATURE_EXT("GPI bits [31:28]" , isar1, 28, ...); MERGE_FEATURE_4B("GPI bits [31:28]" , isar1, 28, ...);
*/ */
MERGE_FEATURE_EXT("FRINTTS bits [35:32]" , isar1, 32, Ext::kFRINTTS); MERGE_FEATURE_4B("FRINTTS bits [35:32]" , isar1, 32, Ext::kFRINTTS);
MERGE_FEATURE_EXT("SB bits [39:36]" , isar1, 36, Ext::kSB); MERGE_FEATURE_4B("SB bits [39:36]" , isar1, 36, Ext::kSB);
MERGE_FEATURE_EXT("SPECRES bits [43:40]" , isar1, 40, Ext::kSPECRES, Ext::kSPECRES2); MERGE_FEATURE_4B("SPECRES bits [43:40]" , isar1, 40, Ext::kSPECRES, Ext::kSPECRES2);
MERGE_FEATURE_EXT("BF16 bits [47:44]" , isar1, 44, Ext::kBF16, Ext::kEBF16); MERGE_FEATURE_4B("BF16 bits [47:44]" , isar1, 44, Ext::kBF16, Ext::kEBF16);
MERGE_FEATURE_EXT("DGH bits [51:48]" , isar1, 48, Ext::kDGH); MERGE_FEATURE_4B("DGH bits [51:48]" , isar1, 48, Ext::kDGH);
MERGE_FEATURE_EXT("I8MM bits [55:52]" , isar1, 52, Ext::kI8MM); MERGE_FEATURE_4B("I8MM bits [55:52]" , isar1, 52, Ext::kI8MM);
MERGE_FEATURE_EXT("XS bits [59:56]" , isar1, 56, Ext::kXS); MERGE_FEATURE_4B("XS bits [59:56]" , isar1, 56, Ext::kXS);
MERGE_FEATURE_EXT("LS64 bits [63:60]" , isar1, 60, Ext::kLS64, Ext::kLS64_V, Ext::kLS64_ACCDATA); MERGE_FEATURE_4B("LS64 bits [63:60]" , isar1, 60, Ext::kLS64, Ext::kLS64_V, Ext::kLS64_ACCDATA);
} }
// Detects features based on the content of ID_AA64ISAR2_EL1 register. // Detects features based on the content of ID_AA64ISAR2_EL1 register.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64ISAR2(CpuInfo& cpu, uint64_t isar2) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64ISAR2(CpuInfo& cpu, uint64_t isar2) noexcept {
MERGE_FEATURE_EXT("WFxT bits [3:0]" , isar2, 0, Ext::kNone, Ext::kWFXT); MERGE_FEATURE_4B("WFxT bits [3:0]" , isar2, 0, Ext::kNone, Ext::kWFXT);
MERGE_FEATURE_EXT("RPRES bits [7:4]" , isar2, 4, Ext::kRPRES); MERGE_FEATURE_4B("RPRES bits [7:4]" , isar2, 4, Ext::kRPRES);
/* /*
MERGE_FEATURE_EXT("GPA3 bits [11:8]" , isar2, 8, ...); MERGE_FEATURE_4B("GPA3 bits [11:8]" , isar2, 8, ...);
MERGE_FEATURE_EXT("APA3 bits [15:12]" , isar2, 12, ...); MERGE_FEATURE_4B("APA3 bits [15:12]" , isar2, 12, ...);
*/ */
MERGE_FEATURE_EXT("MOPS bits [19:16]" , isar2, 16, Ext::kMOPS); MERGE_FEATURE_4B("MOPS bits [19:16]" , isar2, 16, Ext::kMOPS);
MERGE_FEATURE_EXT("BC bits [23:20]" , isar2, 20, Ext::kHBC); MERGE_FEATURE_4B("BC bits [23:20]" , isar2, 20, Ext::kHBC);
/* MERGE_FEATURE_4B("PAC_frac bits [27:24]" , isar2, 24, Ext::kCONSTPACFIELD);
MERGE_FEATURE_EXT("PAC_frac bits [27:24]" , isar2, 24, ...); MERGE_FEATURE_4B("CLRBHB bits [31:28]" , isar2, 28, Ext::kCLRBHB);
*/ MERGE_FEATURE_4B("SYSREG128 bits [35:32]" , isar2, 32, Ext::kSYSREG128);
MERGE_FEATURE_EXT("CLRBHB bits [31:28]" , isar2, 28, Ext::kCLRBHB); MERGE_FEATURE_4B("SYSINSTR128 bits [39:36]" , isar2, 36, Ext::kSYSINSTR128);
MERGE_FEATURE_EXT("SYSREG128 bits [35:32]" , isar2, 32, Ext::kSYSREG128); MERGE_FEATURE_4B("PRFMSLC bits [43:40]" , isar2, 40, Ext::kPRFMSLC);
MERGE_FEATURE_EXT("SYSINSTR128 bits [39:36]" , isar2, 36, Ext::kSYSINSTR128); MERGE_FEATURE_4B("RPRFM bits [51:48]" , isar2, 48, Ext::kRPRFM);
MERGE_FEATURE_EXT("PRFMSLC bits [43:40]" , isar2, 40, Ext::kPRFMSLC); MERGE_FEATURE_4B("CSSC bits [55:52]" , isar2, 52, Ext::kCSSC);
MERGE_FEATURE_EXT("RPRFM bits [51:48]" , isar2, 48, Ext::kRPRFM); MERGE_FEATURE_4B("LUT bits [59:56]" , isar2, 56, Ext::kLUT);
MERGE_FEATURE_EXT("CSSC bits [55:52]" , isar2, 52, Ext::kCSSC);
} }
// TODO: This register is not accessed at the moment.
#if 0
// Detects features based on the content of ID_AA64ISAR3_EL1register.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64MMFR0(CpuInfo& cpu, uint64_t mmfr0) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64ISAR3(CpuInfo& cpu, uint64_t isar3) noexcept {
// ID_AA64ISAR3_EL1
// ================
MERGE_FEATURE_4B("CPA bits [3:0]" , isar3, 0, Ext::kCPA, Ext::kCPA2);
MERGE_FEATURE_4B("FAMINMAX bits [7:4]" , isar3, 4, Ext::kFAMINMAX);
MERGE_FEATURE_4B("TLBIW bits [11:8]" , isar3, 8, Ext::kTLBIW);
}
#endif
ASMJIT_MAYBE_UNUSED
static inline void detectAArch64FeaturesViaCPUID_AA64MMFR0(CpuInfo& cpu, uint64_t mmfr0) noexcept {
// ID_AA64MMFR0_EL1 // ID_AA64MMFR0_EL1
// ================ // ================
/* /*
MERGE_FEATURE_EXT("PARange bits [3:0]" , mmfr0, 0, ...); MERGE_FEATURE_4B("PARange bits [3:0]" , mmfr0, 0, ...);
MERGE_FEATURE_EXT("ASIDBits bits [7:4]" , mmfr0, 4, ...); MERGE_FEATURE_4B("ASIDBits bits [7:4]" , mmfr0, 4, ...);
MERGE_FEATURE_EXT("BigEnd bits [11:8]" , mmfr0, 8, ...); MERGE_FEATURE_4B("BigEnd bits [11:8]" , mmfr0, 8, ...);
MERGE_FEATURE_EXT("SNSMem bits [15:12]" , mmfr0, 12, ...); MERGE_FEATURE_4B("SNSMem bits [15:12]" , mmfr0, 12, ...);
MERGE_FEATURE_EXT("BigEndEL0 bits [19:16]" , mmfr0, 16, ...); MERGE_FEATURE_4B("BigEndEL0 bits [19:16]" , mmfr0, 16, ...);
MERGE_FEATURE_EXT("TGran16 bits [23:20]" , mmfr0, 20, ...); MERGE_FEATURE_4B("TGran16 bits [23:20]" , mmfr0, 20, ...);
MERGE_FEATURE_EXT("TGran64 bits [27:24]" , mmfr0, 24, ...); MERGE_FEATURE_4B("TGran64 bits [27:24]" , mmfr0, 24, ...);
MERGE_FEATURE_EXT("TGran4 bits [31:28]" , mmfr0, 28, ...); MERGE_FEATURE_4B("TGran4 bits [31:28]" , mmfr0, 28, ...);
MERGE_FEATURE_EXT("TGran16_2 bits [35:32]" , mmfr0, 32, ...); MERGE_FEATURE_4B("TGran16_2 bits [35:32]" , mmfr0, 32, ...);
MERGE_FEATURE_EXT("TGran64_2 bits [39:36]" , mmfr0, 36, ...); MERGE_FEATURE_4B("TGran64_2 bits [39:36]" , mmfr0, 36, ...);
MERGE_FEATURE_EXT("TGran4_2 bits [43:40]" , mmfr0, 40, ...); MERGE_FEATURE_4B("TGran4_2 bits [43:40]" , mmfr0, 40, ...);
MERGE_FEATURE_EXT("ExS bits [47:44]" , mmfr0, 44, ...); MERGE_FEATURE_4B("ExS bits [47:44]" , mmfr0, 44, ...);
*/ */
MERGE_FEATURE_EXT("FGT bits [59:56]" , mmfr0, 56, Ext::kFGT, Ext::kFGT2); MERGE_FEATURE_4B("FGT bits [59:56]" , mmfr0, 56, Ext::kFGT, Ext::kFGT2);
MERGE_FEATURE_EXT("ECV bits [63:60]" , mmfr0, 60, Ext::kECV); MERGE_FEATURE_4B("ECV bits [63:60]" , mmfr0, 60, Ext::kECV);
} }
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64MMFR1(CpuInfo& cpu, uint64_t mmfr1) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64MMFR1(CpuInfo& cpu, uint64_t mmfr1) noexcept {
// ID_AA64MMFR1_EL1 // ID_AA64MMFR1_EL1
// ================ // ================
MERGE_FEATURE_4B("HAFDBS bits [3:0]" , mmfr1, 0, Ext::kHAFDBS, Ext::kNone, Ext::kHAFT, Ext::kHDBSS);
MERGE_FEATURE_4B("VMIDBits bits [7:4]" , mmfr1, 4, Ext::kVMID16);
MERGE_FEATURE_4B("VH bits [11:8]" , mmfr1, 8, Ext::kVHE);
MERGE_FEATURE_4B("HPDS bits [15:12]" , mmfr1, 12, Ext::kHPDS, Ext::kHPDS2);
MERGE_FEATURE_4B("LO bits [19:16]" , mmfr1, 16, Ext::kLOR);
MERGE_FEATURE_4B("PAN bits [23:20]" , mmfr1, 20, Ext::kPAN, Ext::kPAN2, Ext::kPAN3);
/* /*
MERGE_FEATURE_EXT("HAFDBS bits [3:0]" , mmfr1, 0, ...); MERGE_FEATURE_4B("SpecSEI bits [27:24]" , mmfr1, 24, ...);
MERGE_FEATURE_EXT("VMIDBits bits [7:4]" , mmfr1, 4, ...);
*/ */
MERGE_FEATURE_EXT("VH bits [11:8]" , mmfr1, 8, Ext::kVHE); MERGE_FEATURE_4B("XNX bits [31:28]" , mmfr1, 28, Ext::kXNX);
/* /*
MERGE_FEATURE_EXT("HPDS bits [15:12]" , mmfr1, 12, ...); MERGE_FEATURE_4B("TWED bits [35:32]" , mmfr1, 32, ...);
MERGE_FEATURE_4B("ETS bits [39:36]" , mmfr1, 36, ...);
*/ */
MERGE_FEATURE_EXT("LO bits [19:16]" , mmfr1, 16, Ext::kLOR); MERGE_FEATURE_4B("HCX bits [43:40]" , mmfr1, 40, Ext::kHCX);
MERGE_FEATURE_EXT("PAN bits [23:20]" , mmfr1, 20, Ext::kPAN, Ext::kPAN2, Ext::kPAN3); MERGE_FEATURE_4B("AFP bits [47:44]" , mmfr1, 44, Ext::kAFP);
/* /*
MERGE_FEATURE_EXT("SpecSEI bits [27:24]" , mmfr1, 24, ...); MERGE_FEATURE_4B("nTLBPA bits [51:48]" , mmfr1, 48, ...);
MERGE_FEATURE_EXT("XNX bits [31:28]" , mmfr1, 28, ...); MERGE_FEATURE_4B("TIDCP1 bits [55:52]" , mmfr1, 52, ...);
MERGE_FEATURE_EXT("TWED bits [35:32]" , mmfr1, 32, ...);
MERGE_FEATURE_EXT("ETS bits [39:36]" , mmfr1, 36, ...);
*/
MERGE_FEATURE_EXT("HCX bits [43:40]" , mmfr1, 40, Ext::kHCX);
MERGE_FEATURE_EXT("AFP bits [47:44]" , mmfr1, 44, Ext::kAFP);
/*
MERGE_FEATURE_EXT("nTLBPA bits [51:48]" , mmfr1, 48, ...);
MERGE_FEATURE_EXT("TIDCP1 bits [55:52]" , mmfr1, 52, ...);
MERGE_FEATURE_EXT("CMOW bits [59:56]" , mmfr1, 56, ...);
MERGE_FEATURE_EXT("ECBHB bits [63:60]" , mmfr1, 60, ...);
*/ */
MERGE_FEATURE_4B("CMOW bits [59:56]" , mmfr1, 56, Ext::kCMOW);
MERGE_FEATURE_4B("ECBHB bits [63:60]" , mmfr1, 60, Ext::kECBHB);
} }
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64MMFR2(CpuInfo& cpu, uint64_t mmfr2) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64MMFR2(CpuInfo& cpu, uint64_t mmfr2) noexcept {
// ID_AA64MMFR2_EL1 // ID_AA64MMFR2_EL1
// ================ // ================
/* /*
MERGE_FEATURE_EXT("CnP bits [3:0]" , mmfr2, 0, ...); MERGE_FEATURE_4B("CnP bits [3:0]" , mmfr2, 0, ...);
*/ */
MERGE_FEATURE_EXT("UAO bits [7:4]" , mmfr2, 4, Ext::kUAO); MERGE_FEATURE_4B("UAO bits [7:4]" , mmfr2, 4, Ext::kUAO);
/* /*
MERGE_FEATURE_EXT("LSM bits [11:8]" , mmfr2, 8, ...); MERGE_FEATURE_4B("LSM bits [11:8]" , mmfr2, 8, ...);
MERGE_FEATURE_EXT("IESB bits [15:12]" , mmfr2, 12, ...); MERGE_FEATURE_4B("IESB bits [15:12]" , mmfr2, 12, ...);
MERGE_FEATURE_EXT("VARange bits [19:16]" , mmfr2, 16, ...);
*/ */
MERGE_FEATURE_EXT("CCIDX bits [23:20]" , mmfr2, 20, Ext::kCCIDX); MERGE_FEATURE_4B("VARange bits [19:16]" , mmfr2, 16, Ext::kLVA, Ext::kLVA3);
MERGE_FEATURE_EXT("NV bits [27:24]" , mmfr2, 24, Ext::kNV, Ext::kNV2); MERGE_FEATURE_4B("CCIDX bits [23:20]" , mmfr2, 20, Ext::kCCIDX);
MERGE_FEATURE_4B("NV bits [27:24]" , mmfr2, 24, Ext::kNV, Ext::kNV2);
/* /*
MERGE_FEATURE_EXT("ST bits [31:28]" , mmfr2, 28, ...); MERGE_FEATURE_4B("ST bits [31:28]" , mmfr2, 28, ...);
*/ */
MERGE_FEATURE_EXT("AT bits [35:32]" , mmfr2, 32, Ext::kLSE2); MERGE_FEATURE_4B("AT bits [35:32]" , mmfr2, 32, Ext::kLSE2);
/* /*
MERGE_FEATURE_EXT("IDS bits [39:36]" , mmfr2, 36, ...); MERGE_FEATURE_4B("IDS bits [39:36]" , mmfr2, 36, ...);
MERGE_FEATURE_EXT("FWB bits [43:40]" , mmfr2, 40, ...); MERGE_FEATURE_4B("FWB bits [43:40]" , mmfr2, 40, ...);
MERGE_FEATURE_EXT("TTL bits [51:48]" , mmfr2, 48, ...); MERGE_FEATURE_4B("TTL bits [51:48]" , mmfr2, 48, ...);
MERGE_FEATURE_EXT("BBM bits [55:52]" , mmfr2, 52, ...); MERGE_FEATURE_4B("BBM bits [55:52]" , mmfr2, 52, ...);
MERGE_FEATURE_EXT("EVT bits [59:56]" , mmfr2, 56, ...); MERGE_FEATURE_4B("EVT bits [59:56]" , mmfr2, 56, ...);
MERGE_FEATURE_EXT("E0PD bits [63:60]" , mmfr2, 60, ...); MERGE_FEATURE_4B("E0PD bits [63:60]" , mmfr2, 60, ...);
*/ */
} }
// Detects features based on the content of ID_AA64ZFR0_EL1 register. // Detects features based on the content of ID_AA64ZFR0_EL1 register.
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID_AA64ZFR0(CpuInfo& cpu, uint64_t zfr0) noexcept { static inline void detectAArch64FeaturesViaCPUID_AA64ZFR0(CpuInfo& cpu, uint64_t zfr0) noexcept {
MERGE_FEATURE_EXT("SVEver bits [3:0]" , zfr0, 0, Ext::kSVE2, Ext::kSVE2_1); MERGE_FEATURE_4B("SVEver bits [3:0]" , zfr0, 0, Ext::kSVE2, Ext::kSVE2_1);
MERGE_FEATURE_EXT("AES bits [7:4]" , zfr0, 4, Ext::kSVE_AES, Ext::kSVE_PMULL128); MERGE_FEATURE_4B("AES bits [7:4]" , zfr0, 4, Ext::kSVE_AES, Ext::kSVE_PMULL128);
MERGE_FEATURE_EXT("BitPerm bits [19:16]" , zfr0, 16, Ext::kSVE_BITPERM); MERGE_FEATURE_4B("BitPerm bits [19:16]" , zfr0, 16, Ext::kSVE_BITPERM);
MERGE_FEATURE_EXT("BF16 bits [23:20]" , zfr0, 20, Ext::kSVE_BF16, Ext::kSVE_EBF16); MERGE_FEATURE_4B("BF16 bits [23:20]" , zfr0, 20, Ext::kSVE_BF16, Ext::kSVE_EBF16);
MERGE_FEATURE_EXT("B16B16 bits [27:24]" , zfr0, 24, Ext::kSVE_B16B16); MERGE_FEATURE_4B("B16B16 bits [27:24]" , zfr0, 24, Ext::kSVE_B16B16);
MERGE_FEATURE_EXT("SHA3 bits [35:32]" , zfr0, 32, Ext::kSVE_SHA3); MERGE_FEATURE_4B("SHA3 bits [35:32]" , zfr0, 32, Ext::kSVE_SHA3);
MERGE_FEATURE_EXT("SM4 bits [43:40]" , zfr0, 40, Ext::kSVE_SM4); MERGE_FEATURE_4B("SM4 bits [43:40]" , zfr0, 40, Ext::kSVE_SM4);
MERGE_FEATURE_EXT("I8MM bits [47:44]" , zfr0, 44, Ext::kSVE_I8MM); MERGE_FEATURE_4B("I8MM bits [47:44]" , zfr0, 44, Ext::kSVE_I8MM);
MERGE_FEATURE_EXT("F32MM bits [55:52]" , zfr0, 52, Ext::kSVE_F32MM); MERGE_FEATURE_4B("F32MM bits [55:52]" , zfr0, 52, Ext::kSVE_F32MM);
MERGE_FEATURE_EXT("F64MM bits [59:56]" , zfr0, 56, Ext::kSVE_F64MM); MERGE_FEATURE_4B("F64MM bits [59:56]" , zfr0, 56, Ext::kSVE_F64MM);
} }
#undef MERGE_FEATURE_EXT ASMJIT_MAYBE_UNUSED
#undef MERGE_FEATURE_N_A static inline void detectAArch64FeaturesViaCPUID_AA64SMFR0(CpuInfo& cpu, uint64_t smfr0) noexcept {
MERGE_FEATURE_1B("SF8DP2 bit [28]" , smfr0, 29, Ext::kSSVE_FP8DOT2);
MERGE_FEATURE_1B("SF8DP4 bit [29]" , smfr0, 29, Ext::kSSVE_FP8DOT4);
MERGE_FEATURE_1B("SF8FMA bit [30]" , smfr0, 30, Ext::kSSVE_FP8FMA);
MERGE_FEATURE_1B("F32F32 bit [32]" , smfr0, 32, Ext::kSME_F32F32);
MERGE_FEATURE_1B("BI32I32 bit [33]" , smfr0, 33, Ext::kSME_BI32I32);
MERGE_FEATURE_1B("B16F32 bit [34]" , smfr0, 34, Ext::kSME_B16F32);
MERGE_FEATURE_1B("F16F32 bit [35]" , smfr0, 35, Ext::kSME_F16F32);
MERGE_FEATURE_4S("I8I32 bits [39:36]" , smfr0, 36, 0xF, Ext::kSME_I8I32);
MERGE_FEATURE_1B("F8F32 bit [40]" , smfr0, 40, Ext::kSME_F8F32);
MERGE_FEATURE_1B("F8F16 bit [41]" , smfr0, 41, Ext::kSME_F8F16);
MERGE_FEATURE_1B("F16F16 bit [42]" , smfr0, 42, Ext::kSME_F16F16);
MERGE_FEATURE_1B("B16B16 bit [43]" , smfr0, 43, Ext::kSME_B16B16);
MERGE_FEATURE_4S("I16I32 bits [47:44]" , smfr0, 44, 0x5, Ext::kSME_I16I32);
MERGE_FEATURE_1B("F64F64 bit [48]" , smfr0, 48, Ext::kSME_F64F64);
MERGE_FEATURE_4S("I16I64 bits [55:52]" , smfr0, 52, 0xF, Ext::kSME_I16I64);
MERGE_FEATURE_4B("SMEver bits [59:56]" , smfr0, 56, Ext::kSME2, Ext::kSME2_1);
MERGE_FEATURE_1B("LUTv2 bit [60]" , smfr0, 60, Ext::kSME_LUTv2);
MERGE_FEATURE_1B("FA64 bit [63]" , smfr0, 63, Ext::kSME_FA64);
}
#undef MERGE_FEATURE_4S
#undef MERGE_FEATURE_4B
#undef MERGE_FEATURE_2B
#undef MERGE_FEATURE_1B
#undef MERGE_FEATURE_NA
// CpuInfo - Detect - ARM - CPU Vendor Features // CpuInfo - Detect - ARM - CPU Vendor Features
// ============================================ // ============================================
@@ -1084,11 +1141,10 @@ static ASMJIT_FAVOR_SIZE bool detectARMFeaturesViaAppleFamilyId(CpuInfo& cpu) no
// Apple A14/M1 (ARMv8.5-A). // Apple A14/M1 (ARMv8.5-A).
case uint32_t(Id::kFIRESTORM_ICESTORM): case uint32_t(Id::kFIRESTORM_ICESTORM):
// Missing: CSV2, CSV3.
populateARMv8AFeatures(features, 4); populateARMv8AFeatures(features, 4);
features.add(Ext::kAES, Ext::kDPB2, Ext::kECV, Ext::kFHM, Ext::kFLAGM2, Ext::kFP16, Ext::kFP16CONV, features.add(Ext::kAES, Ext::kCSV2, Ext::kCSV3, Ext::kDPB2, Ext::kECV, Ext::kFHM, Ext::kFLAGM2,
Ext::kFRINTTS, Ext::kPMU, Ext::kPMULL, Ext::kSB, Ext::kSHA1, Ext::kSHA256, Ext::kSHA3, Ext::kFP16, Ext::kFP16CONV, Ext::kFRINTTS, Ext::kPMU, Ext::kPMULL, Ext::kSB,
Ext::kSHA512, Ext::kSSBS); Ext::kSHA1, Ext::kSHA256, Ext::kSHA3, Ext::kSHA512, Ext::kSSBS);
return true; return true;
// Apple A15/M2. // Apple A15/M2.
@@ -1393,7 +1449,7 @@ ASMJIT_AARCH64_DEFINE_CPUID_READ_FN(aarch64ReadZFR0, S3_0_C0_C4_4) // ID_AA64ZFR
// dependent is zeroed, only the bits that are used for CPU feature identification would be present. // dependent is zeroed, only the bits that are used for CPU feature identification would be present.
// //
// References: // References:
// - https://docs.kernel.org/arm64/cpu-feature-registers.html // - https://docs.kernel.org/arch/arm64/cpu-feature-registers.html
ASMJIT_MAYBE_UNUSED ASMJIT_MAYBE_UNUSED
static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID(CpuInfo& cpu) noexcept { static ASMJIT_FAVOR_SIZE void detectAArch64FeaturesViaCPUID(CpuInfo& cpu) noexcept {
populateBaseARMFeatures(cpu); populateBaseARMFeatures(cpu);
@@ -1596,7 +1652,7 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
#else #else
// Reference: // Reference:
// - https://docs.kernel.org/arm64/elf_hwcaps.html // - https://docs.kernel.org/arch/arm64/elf_hwcaps.html
// - https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h // - https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
static const HWCapMapping hwCapMapping[] = { static const HWCapMapping hwCapMapping[] = {
{ uint8_t(Ext::kFP) , 0 }, // HWCAP_FP { uint8_t(Ext::kFP) , 0 }, // HWCAP_FP
@@ -1680,7 +1736,12 @@ static const HWCapMapping hwCap2Mapping[] = {
{ uint8_t(Ext::kSME_I16I32) , 39 }, // HWCAP2_SME_I16I32 { uint8_t(Ext::kSME_I16I32) , 39 }, // HWCAP2_SME_I16I32
{ uint8_t(Ext::kSME_BI32I32) , 40 }, // HWCAP2_SME_BI32I32 { uint8_t(Ext::kSME_BI32I32) , 40 }, // HWCAP2_SME_BI32I32
{ uint8_t(Ext::kSME_B16B16) , 41 }, // HWCAP2_SME_B16B16 { uint8_t(Ext::kSME_B16B16) , 41 }, // HWCAP2_SME_B16B16
{ uint8_t(Ext::kSME_F16F16) , 42 } // HWCAP2_SME_F16F16 { uint8_t(Ext::kSME_F16F16) , 42 }, // HWCAP2_SME_F16F16
{ uint8_t(Ext::kMOPS) , 43 }, // HWCAP2_MOPS
{ uint8_t(Ext::kHBC) , 44 }, // HWCAP2_HBC
{ uint8_t(Ext::kSVE_B16B16) , 45 }, // HWCAP2_SVE_B16B16
{ uint8_t(Ext::kLRCPC3) , 46 }, // HWCAP2_LRCPC3
{ uint8_t(Ext::kLSE128) , 47 }, // HWCAP2_LSE128
}; };
static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept { static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
@@ -1754,6 +1815,9 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
// Only read CPU_ID_AA64ZFR0 when either SVE or SME is available. // Only read CPU_ID_AA64ZFR0 when either SVE or SME is available.
if (cpu.features().arm().hasAny(Ext::kSVE, Ext::kSME)) { if (cpu.features().arm().hasAny(Ext::kSVE, Ext::kSME)) {
detectAArch64FeaturesViaCPUID_AA64ZFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64ZFR0)); detectAArch64FeaturesViaCPUID_AA64ZFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64ZFR0));
if (cpu.features().arm().hasSME())
detectAArch64FeaturesViaCPUID_AA64SMFR0(cpu, openbsdReadAArch64CPUID(ID::kAA64SMFR0));
} }
postProcessARMCpuInfo(cpu); postProcessARMCpuInfo(cpu);
@@ -1886,7 +1950,7 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
#else #else
#if ASMJIT_ARCH_ARM == 32 #if ASMJIT_ARCH_ARM == 32
#pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with ARM CPU)") #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch32 CPU)")
#else #else
#pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch64 CPU)") #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch64 CPU)")
#endif #endif
@@ -1921,8 +1985,6 @@ const CpuInfo& CpuInfo::host() noexcept {
x86::detectX86Cpu(cpuInfoLocal); x86::detectX86Cpu(cpuInfoLocal);
#elif ASMJIT_ARCH_ARM #elif ASMJIT_ARCH_ARM
arm::detectARMCpu(cpuInfoLocal); arm::detectARMCpu(cpuInfoLocal);
#else
#pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown CPU)")
#endif #endif
cpuInfoLocal._hwThreadCount = detectHWThreadCount(); cpuInfoLocal._hwThreadCount = detectHWThreadCount();

View File

@@ -55,8 +55,8 @@ public:
//! \name Overloaded Operators //! \name Overloaded Operators
//! \{ //! \{
ASMJIT_INLINE_NODEBUG bool operator==(const Data& other) noexcept { return eq(other); } ASMJIT_INLINE_NODEBUG bool operator==(const Data& other) const noexcept { return equals(other); }
ASMJIT_INLINE_NODEBUG bool operator!=(const Data& other) noexcept { return !eq(other); } ASMJIT_INLINE_NODEBUG bool operator!=(const Data& other) const noexcept { return !equals(other); }
//! \} //! \}
@@ -88,11 +88,16 @@ public:
return bool((_bits[idx] >> bit) & 0x1); return bool((_bits[idx] >> bit) & 0x1);
} }
//! \cond NONE
template<typename FeatureId> template<typename FeatureId>
ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId) const noexcept { ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId) const noexcept {
return has(featureId); return has(featureId);
} }
//! \endcond
//! Tests whether any feature given is present.
//!
//! \note This is a variadic function template that can be used with multiple features.
template<typename FeatureId, typename... Args> template<typename FeatureId, typename... Args>
ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId, Args&&... otherFeatureIds) const noexcept { ASMJIT_INLINE_NODEBUG bool hasAny(const FeatureId& featureId, Args&&... otherFeatureIds) const noexcept {
return bool(unsigned(has(featureId)) | unsigned(hasAny(std::forward<Args>(otherFeatureIds)...))); return bool(unsigned(has(featureId)) | unsigned(hasAny(std::forward<Args>(otherFeatureIds)...)));
@@ -111,6 +116,7 @@ public:
//! \name Manipulation //! \name Manipulation
//! \{ //! \{
//! Clears all features set.
ASMJIT_INLINE_NODEBUG void reset() noexcept { _bits.fill(0); } ASMJIT_INLINE_NODEBUG void reset() noexcept { _bits.fill(0); }
//! Adds the given CPU `featureId` to the list of features. //! Adds the given CPU `featureId` to the list of features.
@@ -164,7 +170,12 @@ public:
} }
//! Tests whether this CPU features data matches `other`. //! Tests whether this CPU features data matches `other`.
ASMJIT_INLINE_NODEBUG bool eq(const Data& other) const noexcept { return _bits == other._bits; } ASMJIT_INLINE_NODEBUG bool equals(const Data& other) const noexcept { return _bits == other._bits; }
#if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("Use CpuFeatures::Data::equals() instead")
ASMJIT_INLINE_NODEBUG bool eq(const Data& other) const noexcept { return equals(other); }
#endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}
@@ -333,6 +344,7 @@ public:
}; };
#define ASMJIT_X86_FEATURE(FEATURE) \ #define ASMJIT_X86_FEATURE(FEATURE) \
/*! Tests whether FEATURE is present. */ \
ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); } ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); }
ASMJIT_X86_FEATURE(MT) ASMJIT_X86_FEATURE(MT)
@@ -502,137 +514,213 @@ public:
kARMv6, //!< CPU is at least ARMv6 {A32}. kARMv6, //!< CPU is at least ARMv6 {A32}.
kARMv7, //!< CPU is at least ARMv7 {A32}. kARMv7, //!< CPU is at least ARMv7 {A32}.
kARMv8a, //!< CPU is at least ARMv8A. kARMv8a, //!< CPU is at least ARMv8A.
kTHUMB, //!< CPU has THUMB (16-bit THUMB encoding) {A32}. kTHUMB, //!< CPU has THUMB (16-bit THUMB encoding) {A32}.
kTHUMBv2, //!< CPU has THUMBv2 (32-bit THUMB encoding) {A32}. kTHUMBv2, //!< CPU has THUMBv2 (32-bit THUMB encoding) {A32}.
kAES, //!< CPU has AES (ASIMD AES instructions). kABLE, //!< CPU has ABLE (address breakpoint linking extension) {A64}.
kAFP, //!< CPU has AFP (alternate floating-point behavior) {A64}. kADERR, //!< CPU has ADERR (asynchronous device error exceptions) {A64}.
kASIMD, //!< CPU has ASIMD (NEON on ARM/THUMB). kAES, //!< CPU has AES (ASIMD AES instructions).
kBF16, //!< CPU has BF16 (BFloat16 instructions) {A64}. kAFP, //!< CPU has AFP (alternate floating-point behavior) {A64}.
kBTI, //!< CPU has BTI (branch target identification). kAIE, //!< CPU has AIE (memory attribute index enhancement) {A64}.
kCCIDX, //!< CPU has CCIDX (extend of the CCSIDR number of sets). kAMU1, //!< CPU has AMUv1 (activity monitors extension version 1) {A64}.
kCHK, //!< CPU has CHK (CHKFEAT instruction) {A64}. kAMU1_1, //!< CPU has AMUv1p1 (activity monitors extension version 1.1) {A64}.
kCLRBHB, //!< CPU has CLRBHB (clear BHB instruction). kANERR, //!< CPU has ANERR (asynchronous normal error exception) {A64}.
kCPUID, //!< CPU has CPUID (CPUID registers accessible in user-space). kASIMD, //!< CPU has ASIMD (NEON on ARM/THUMB).
kCRC32, //!< CPU has CRC32 (CRC32 instructions). kBF16, //!< CPU has BF16 (BFloat16 instructions) {A64}.
kCSSC, //!< CPU has CSSC (common short sequence compression) {A64}. kBRBE, //!< CPU has BRBE (branch record buffer extension) {A64}.
kD128, //!< CPU has D128 (128-bit translation tables, 56 bit PA) {A64}. kBTI, //!< CPU has BTI (branch target identification).
kDGH, //!< CPU has DGH (data gathering hint) {A64}. kBWE, //!< CPU has BWE (breakpoint mismatch and range extension) {A64}.
kDIT, //!< CPU has DIT (data independent timing of instructions). kCCIDX, //!< CPU has CCIDX (extend of the CCSIDR number of sets).
kDOTPROD, //!< CPU has DOTPROD (ASIMD Int8 dot product instructions). kCHK, //!< CPU has CHK (check feature status - CHKFEAT instruction) {A64}.
kDPB, //!< CPU has DPB (DC CVAP instruction) {A64}. kCLRBHB, //!< CPU has CLRBHB (clear BHB instruction).
kDPB2, //!< CPU has DPB2 (DC CVADP instruction) {A64}. kCMOW, //!< CPU has CMOW (control for cache maintenance permission) {A64}.
kEBF16, //!< CPU has EBF16 (extended BFloat16 mode) {A64}. kCONSTPACFIELD, //!< CPU has CONSTPACFIELD (PAC algorithm enhancement) {A64}.
kECV, //!< CPU has ECV (enhanced counter virtualization). kCPA, //!< CPU has CPA (instruction-only Checked Pointer Arithmetic) {A64}.
kEDSP, //!< CPU has EDSP (ARM/THUMB only). kCPA2, //!< CPU has CPA2 (checked Pointer Arithmetic) {A64}.
kFCMA, //!< CPU has FCMA (FCADD/FCMLA). kCPUID, //!< CPU has CPUID (CPUID registers accessible in user-space).
kFGT, //!< CPU has FGT (fine-grained traps). kCRC32, //!< CPU has CRC32 (CRC32 instructions).
kFGT2, //!< CPU has FGT2 (fine-grained traps 2). kCSSC, //!< CPU has CSSC (common short sequence compression) {A64}.
kFHM, //!< CPU has FHM (half-precision floating-point FMLAL instructions). kCSV2, //!< CPU has CSV2 (cache speculation variant 2 version 2.1) {A64}.
kFLAGM, //!< CPU has FLAGM (condition flag manipulation) {A64}. kCSV2_3, //!< CPU has CSV2_3 (cache speculation variant 2 version 3) {A64}.
kFLAGM2, //!< CPU has FLAGM2 (condition flag manipulation version v2) {A64}. kCSV3, //!< CPU has CSV3 (cache speculation Variant 3) {A64}.
kFMAC, //!< CPU has FMAC (ARM/THUMB only). kD128, //!< CPU has D128 (128-bit translation tables, 56 bit PA) {A64}.
kFP, //!< CPU has FP (floating-point) (on 32-bit ARM this means VFPv3). kDGH, //!< CPU has DGH (data gathering hint) {A64}.
kFP16, //!< CPU has FP16 (half-precision floating-point data processing). kDIT, //!< CPU has DIT (data independent timing of instructions).
kFP16CONV, //!< CPU has FP16CONV (half-precision float conversion). kDOTPROD, //!< CPU has DOTPROD (ASIMD Int8 dot product instructions).
kFRINTTS, //!< CPU has FRINTTS (FRINT[32|64][X|Z] instructions) {A64}. kDPB, //!< CPU has DPB (DC CVAP instruction) {A64}.
kGCS, //!< CPU has GCS (guarded control stack extension) {A64}. kDPB2, //!< CPU has DPB2 (DC CVADP instruction) {A64}.
kHBC, //!< CPU has HBC (hinted conditional branches) {A64} kEBEP, //!< CPU has EBEP (exception-based event profiling) {A64}.
kHCX, //!< CPU has HCX (support for the HCRX_EL2 register) {A64}. kEBF16, //!< CPU has EBF16 (extended BFloat16 mode) {A64}.
kI8MM, //!< CPU has I8MM (int8 matrix multiplication) {A64}. kECBHB, //!< CPU has ECBHB (exploitative control using branch history information) {A64}.
kIDIVA, //!< CPU has IDIV (hardware SDIV and UDIV in ARM mode). kECV, //!< CPU has ECV (enhanced counter virtualization).
kIDIVT, //!< CPU has IDIV (hardware SDIV and UDIV in THUMB mode). kEDHSR, //!< CPU has EDHSR (support for EDHSR) {A64}.
kJSCVT, //!< CPU has JSCVT (JavaScript FJCVTS conversion instruction) {A64}. kEDSP, //!< CPU has EDSP (ARM/THUMB only).
kLOR, //!< CPU has LOR (limited ordering regions extension). kFAMINMAX, //!< CPU has FAMINMAX (floating-point maximum and minimum absolute value instructions) {A64}.
kLRCPC, //!< CPU has LRCPC (load-acquire RCpc instructions) {A64}. kFCMA, //!< CPU has FCMA (FCADD/FCMLA).
kLRCPC2, //!< CPU has LRCPC2 (load-acquire RCpc instructions v2) {A64}. kFGT, //!< CPU has FGT (fine-grained traps).
kLRCPC3, //!< CPU has LRCPC3 (load-Acquire RCpc instructions v3) {A64}. kFGT2, //!< CPU has FGT2 (fine-grained traps 2).
kLS64, //!< CPU has LS64 (64 byte loads/stores without return) {A64}. kFHM, //!< CPU has FHM (half-precision floating-point FMLAL instructions).
kLS64_ACCDATA, //!< CPU has LS64_ACCDATA (64-byte EL0 stores with return) {A64}. kFLAGM, //!< CPU has FLAGM (condition flag manipulation) {A64}.
kLS64_V, //!< CPU has LS64_V (64-byte stores with return) {A64}. kFLAGM2, //!< CPU has FLAGM2 (condition flag manipulation version v2) {A64}.
kLSE, //!< CPU has LSE (large system extensions) {A64}. kFMAC, //!< CPU has FMAC (ARM/THUMB only).
kLSE128, //!< CPU has LSE128 (128-bit atomics) {A64}. kFP, //!< CPU has FP (floating-point) (on 32-bit ARM this means VFPv3).
kLSE2, //!< CPU has LSE2 (large system extensions v2) {A64}. kFP16, //!< CPU has FP16 (half-precision floating-point data processing).
kMOPS, //!< CPU has MOPS (memcpy and memset acceleration instructions) {A64}. kFP16CONV, //!< CPU has FP16CONV (half-precision float conversion).
kMPAM, //!< CPU has MPAM (memory system partitioning and monitoring extension) {A64}. kFP8, //!< CPU has FP8 (FP8 convert instructions) {A64}.
kMTE, //!< CPU has MTE (instruction-only memory tagging extension) {A64}. kFP8DOT2, //!< CPU has FP8DOT2 (FP8 2-way dot product to half-precision instructions) {A64}.
kMTE2, //!< CPU has MTE2 (full memory tagging extension) {A64}. kFP8DOT4, //!< CPU has FP8DOT4 (FP8 4-way dot product to single-precision instructions) {A64}.
kMTE3, //!< CPU has MTE3 (MTE asymmetric fault handling) {A64}. kFP8FMA, //!< CPU has FP8FMA (FP8 multiply-accumulate to half-precision and single-precision instructions) {A64}.
kMTE4, //!< CPU has MTE4 (MTE v4) {A64}. kFPMR, //!< CPU has FPMR (floating-point Mode Register) {A64}.
kNMI, //!< CPU has NMI (non-maskable Interrupt) {A64}. kFRINTTS, //!< CPU has FRINTTS (FRINT[32|64][X|Z] instructions) {A64}.
kNV, //!< CPU has NV (nested virtualization enchancement) {A64}. kGCS, //!< CPU has GCS (guarded control stack extension) {A64}.
kNV2, //!< CPU has NV2 (enhanced support for nested virtualization) {A64}. kHACDBS, //!< CPU has HACDBS (hardware accelerator for cleaning Dirty state) {A64}.
kPAN, //!< CPU has PAN (privileged access-never extension) {A64}. kHAFDBS, //!< CPU has HAFDBS (hardware management of the access flag and dirty state) {A64}.
kPAN2, //!< CPU has PAN2 (PAN s1e1R and s1e1W variants) {A64}. kHAFT, //!< CPU has HAFT (hardware managed access flag for table descriptors) {A64}.
kPAN3, //!< CPU has PAN3 (support for SCTLR_ELx.EPAN) {A64}. kHDBSS, //!< CPU has HDBSS (hardware Dirty state tracking Structure) {A64}.
kPAUTH, //!< CPU has PAUTH (pointer authentication extension) {A64}. kHBC, //!< CPU has HBC (hinted conditional branches) {A64}.
kPMU, //!< CPU has PMU {A64}. kHCX, //!< CPU has HCX (support for the HCRX_EL2 register) {A64}.
kPMULL, //!< CPU has PMULL {A64}. kHPDS, //!< CPU has HPDS (hierarchical permission disables in translation tables ) {A64}.
kPRFMSLC, //!< CPU has PRFMSLC (PRFM instructions support the SLC target) {A64} kHPDS2, //!< CPU has HPDS2 (hierarchical permission disables) {A64}.
kRAS, //!< CPU has RAS (reliability, availability and serviceability extensions). kI8MM, //!< CPU has I8MM (int8 matrix multiplication) {A64}.
kRAS1_1, //!< CPU has RASv1p1 (RAS v1.1). kIDIVA, //!< CPU has IDIV (hardware SDIV and UDIV in ARM mode).
kRAS2, //!< CPU has RASv2 (RAS v2). kIDIVT, //!< CPU has IDIV (hardware SDIV and UDIV in THUMB mode).
kRDM, //!< CPU has RDM (rounding double multiply accumulate) {A64}. kITE, //!< CPU has ITE (instrumentation extension) {A64}.
kRME, //!< CPU has RME (memory encryption contexts extension) {A64}. kJSCVT, //!< CPU has JSCVT (JavaScript FJCVTS conversion instruction) {A64}.
kRNG, //!< CPU has RNG (random number generation). kLOR, //!< CPU has LOR (limited ordering regions extension).
kRNG_TRAP, //!< CPU has RNG_TRAP (random number trap to EL3 field) {A64}. kLRCPC, //!< CPU has LRCPC (load-acquire RCpc instructions) {A64}.
kRPRES, //!< CPU has RPRES (increased precision of reciprocal estimate and RSQRT estimate) {A64}. kLRCPC2, //!< CPU has LRCPC2 (load-acquire RCpc instructions v2) {A64}.
kRPRFM, //!! CPU has RPRFM (range prefetch hint instruction). kLRCPC3, //!< CPU has LRCPC3 (load-Acquire RCpc instructions v3) {A64}.
kSB, //!< CPU has SB (speculative barrier). kLS64, //!< CPU has LS64 (64 byte loads/stores without return) {A64}.
kSHA1, //!< CPU has SHA1 (ASIMD SHA1 instructions). kLS64_ACCDATA, //!< CPU has LS64_ACCDATA (64-byte EL0 stores with return) {A64}.
kSHA256, //!< CPU has SHA256 (ASIMD SHA256 instructions). kLS64_V, //!< CPU has LS64_V (64-byte stores with return) {A64}.
kSHA3, //!< CPU has SHA3 (ASIMD EOR3, RAX1, XAR, and BCAX instructions). kLSE, //!< CPU has LSE (large system extensions) {A64}.
kSHA512, //!< CPU has SHA512 (ASIMD SHA512 instructions). kLSE128, //!< CPU has LSE128 (128-bit atomics) {A64}.
kSM3, //!< CPU has SM3 (ASIMD SM3 instructions). kLSE2, //!< CPU has LSE2 (large system extensions v2) {A64}.
kSM4, //!< CPU has SM4 (ASIMD SM4 instructions). kLUT, //!< CPU has LUT (lookup table instructions with 2-bit and 4-bit indices) {A64}.
kSME, //!< CPU has SME (SME v1 - scalable matrix extension) {A64}. kLVA, //!< CPU has LVA (large VA support) {A64}.
kSME2, //!< CPU has SME2 (SME v2) {A64}. kLVA3, //!< CPU has LVA3 (56-bit VA) {A64}.
kSME2_1, //!< CPU has SME2p1 (SME v2.1) {A64}. kMEC, //!< CPU has MEC (memory encryption contexts) {A64}.
kSME_B16B16, //!< CPU has SME_B16B16 (SME non-widening BFloat16 to BFloat16 arithmetic) {A64}. kMOPS, //!< CPU has MOPS (memcpy and memset acceleration instructions) {A64}.
kSME_B16F32, //!< CPU has SME_B16F32 {A64}. kMPAM, //!< CPU has MPAM (memory system partitioning and monitoring extension) {A64}.
kSME_BI32I32, //!< CPU has SME_BI32I32 {A64}. kMTE, //!< CPU has MTE (instruction-only memory tagging extension) {A64}.
kSME_F16F16, //!< CPU has SME_F16F16 (SME2.1 non-widening half-precision FP16 to FP16 arithmetic) {A64}. kMTE2, //!< CPU has MTE2 (full memory tagging extension) {A64}.
kSME_F16F32, //!< CPU has SME_F16F32 {A64}. kMTE3, //!< CPU has MTE3 (MTE asymmetric fault handling) {A64}.
kSME_F32F32, //!< CPU has SME_F32F32 {A64}. kMTE4, //!< CPU has MTE4 (MTE v4) {A64}.
kSME_F64F64, //!< CPU has SME_F64F64 {A64}. kMTE_ASYM_FAULT, //!< CPU has MTE_ASYM_FAULT (memory tagging asymmetric faults) {A64}.
kSME_FA64, //!< CPU has SME_FA64 {A64}. kMTE_ASYNC, //!< CPU has MTE_ASYNC (memory tagging asynchronous faulting) {A64}.
kSME_I16I32, //!< CPU has SME_I16I32 {A64}. kMTE_CANONICAL_TAGS, //!< CPU has MTE_CANONICAL_TAGS (canonical tag checking for untagged memory) {A64}.
kSME_I16I64, //!< CPU has SME_I16I64 {A64}. kMTE_NO_ADDRESS_TAGS, //!< CPU has MTE_NO_ADDRESS_TAGS (memory tagging with address tagging disabled) {A64}.
kSME_I8I32, //!< CPU has SME_I8I32 {A64}. kMTE_PERM_S1, //!< CPU has MTE_PERM_S1 (allocation tag access permission) {A64}.
kSPECRES, //!< CPU has SPECRES (speculation restriction instructions). kMTE_STORE_ONLY, //!< CPU has MTE_STORE_ONLY (store-only tag checking) {A64}.
kSPECRES2, //!< CPU has SPECRES2 (clear other speculative predictions). kMTE_TAGGED_FAR, //!< CPU has MTE_TAGGED_FAR (FAR_ELx on a tag check fault) {A64}.
kSSBS, //!< CPU has SSBS (speculative store bypass safe instruction). kMTPMU, //!< CPU has MTPMU (multi-threaded PMU extensions) {A64}.
kSSBS2, //!< CPU has SSBS2 (MRS and MSR instructions for SSBS). kNMI, //!< CPU has NMI (non-maskable Interrupt) {A64}.
kSVE, //!< CPU has SVE (SVE v1 - scalable vector extension) {A64}. kNV, //!< CPU has NV (nested virtualization enchancement) {A64}.
kSVE2, //!< CPU has SVE2 (SVE v2) {A64}. kNV2, //!< CPU has NV2 (enhanced support for nested virtualization) {A64}.
kSVE2_1, //!< CPU has SVE2p1 (SVE v2.1) {A64}. kPAN, //!< CPU has PAN (privileged access-never extension) {A64}.
kSVE_AES, //!< CPU has SVE_AES (SVE AES instructions) {A64}. kPAN2, //!< CPU has PAN2 (PAN s1e1R and s1e1W variants) {A64}.
kSVE_B16B16, //!< CPU has SVE_B16B16 (SVE non-widening BFloat16 to BFloat16 arithmetic) {A64}. kPAN3, //!< CPU has PAN3 (support for SCTLR_ELx.EPAN) {A64}.
kSVE_BF16, //!< CPU has SVE_BF16 (SVE BF16 instructions) {A64}. kPAUTH, //!< CPU has PAUTH (pointer authentication extension) {A64}.
kSVE_BITPERM, //!< CPU has SVE_BITPERM (SVE bit permute) {A64}. kPFAR, //!< CPU has PFAR (physical fault address registers) {A64}.
kSVE_EBF16, //!< CPU has SVE_EBF16 (SVE extended BFloat16 mode) {A64}. kPMU, //!< CPU has PMU {A64}.
kSVE_F32MM, //!< CPU has SVE_F32MM (SVE single-precision floating-point matrix multiply instruction) {A64}. kPMULL, //!< CPU has PMULL (ASIMD PMULL instructions) {A64}.
kSVE_F64MM, //!< CPU has SVE_F64MM (SVE double-precision floating-point matrix multiply instruction) {A64}. kPRFMSLC, //!< CPU has PRFMSLC (PRFM instructions support the SLC target) {A64}.
kSVE_I8MM, //!< CPU has SVE_I8MM (SVE int8 matrix multiplication) {A64}. kRAS, //!< CPU has RAS (reliability, availability and serviceability extensions).
kSVE_PMULL128, //!< CPU has SVE_PMULL128 (SVE PMULL instructions) {A64}. kRAS1_1, //!< CPU has RASv1p1 (RAS v1.1).
kSVE_SHA3, //!< CPU has SVE_SHA3 (SVE SHA-3 instructions) {A64}. kRAS2, //!< CPU has RASv2 (RAS v2).
kSVE_SM4, //!< CPU has SVE_SM4 (SVE SM4 instructions {A64}. kRASSA2, //!< CPU has RASSAv2 (RAS v2 system architecture).
kSYSINSTR128, //!< CPU has SYSINSTR128 (128-bit system instructions) {A64}. kRDM, //!< CPU has RDM (rounding double multiply accumulate) {A64}.
kSYSREG128, //!< CPU has SYSREG128 (128-bit system registers) {A64}. kRME, //!< CPU has RME (memory encryption contexts extension) {A64}.
kTHE, //!< CPU has THE (translation hardening extension). kRNG, //!< CPU has RNG (random number generation).
kTME, //!< CPU has TME (transactional memory extensions). kRNG_TRAP, //!< CPU has RNG_TRAP (random number trap to EL3 field) {A64}.
kTRF, //!< CPU has TRF (trace extension). kRPRES, //!< CPU has RPRES (increased precision of reciprocal estimate and RSQRT estimate) {A64}.
kUAO, //!< CPU has UAO (AArch64 v8.2 UAO PState) {A64}. kRPRFM, //!< CPU has RPRFM (range prefetch hint instruction).
kVFP_D32, //!< CPU has VFP_D32 (32 VFP-D registers) (ARM/THUMB only). kS1PIE, //!< CPU has S1PIE (permission model enhancements) {A64}.
kVHE, //!< CPU has VHE (virtual host extension). kS1POE, //!< CPU has S1POE (permission model enhancements) {A64}.
kWFXT, //!< CPU has WFxT (WFE and WFI instructions with timeout) {A64}. kS2PIE, //!< CPU has S2PIE (permission model enhancements) {A64}.
kXS, //!< CPU has XS (XS attribute in TLBI and DSB instructions) {A64}. kS2POE, //!< CPU has S2POE (permission model enhancements) {A64}.
kSB, //!< CPU has SB (speculative barrier).
kSCTLR2, //!< CPU has SCTLR2 (extension to SCTLR_ELx) {A64}.
kSEBEP, //!< CPU has SEBEP (synchronous exception-based event profiling) {A64}.
kSEL2, //!< CPU has SEL2 (secure EL2) {A64}.
kSHA1, //!< CPU has SHA1 (ASIMD SHA1 instructions).
kSHA256, //!< CPU has SHA256 (ASIMD SHA256 instructions).
kSHA3, //!< CPU has SHA3 (ASIMD EOR3, RAX1, XAR, and BCAX instructions).
kSHA512, //!< CPU has SHA512 (ASIMD SHA512 instructions).
kSM3, //!< CPU has SM3 (ASIMD SM3 instructions).
kSM4, //!< CPU has SM4 (ASIMD SM4 instructions).
kSME, //!< CPU has SME (SME v1 - scalable matrix extension) {A64}.
kSME2, //!< CPU has SME2 (SME v2) {A64}.
kSME2_1, //!< CPU has SME2p1 (SME v2.1) {A64}.
kSME_B16B16, //!< CPU has SME_B16B16 (SME non-widening BFloat16 to BFloat16 arithmetic) {A64}.
kSME_B16F32, //!< CPU has SME_B16F32 (BFMOPA and BFMOPS instructions that accumulate BFloat16 outer products into single-precision tiles) {A64}.
kSME_BI32I32, //!< CPU has SME_BI32I32 (BMOPA and BMOPS instructions that accumulate 1-bit binary outer products into 32-bit integer tiles) {A64}.
kSME_F16F16, //!< CPU has SME_F16F16 (SME2.1 non-widening half-precision FP16 to FP16 arithmetic) {A64}.
kSME_F16F32, //!< CPU has SME_F16F32 {A64}.
kSME_F32F32, //!< CPU has SME_F32F32 {A64}.
kSME_F64F64, //!< CPU has SME_F64F64 {A64}.
kSME_F8F16, //!< CPU has SME_F8F16 (SME2 ZA-targeting FP8 multiply-accumulate, dot product, and outer product to half-precision instructions) {A64}.
kSME_F8F32, //!< CPU has SME_F8F32 (SME2 ZA-targeting FP8 multiply-accumulate, dot product, and outer product to single-precision instructions) {A64}.
kSME_FA64, //!< CPU has SME_FA64 {A64}.
kSME_I16I32, //!< CPU has SME_I16I32 {A64}.
kSME_I16I64, //!< CPU has SME_I16I64 {A64}.
kSME_I8I32, //!< CPU has SME_I8I32 {A64}.
kSME_LUTv2, //!< CPU has SME_LUTv2 (lookup table instructions with 4-bit indices and 8-bit elements) {A64}.
kSPE, //!< CPU has SPE (statistical profiling extension) {A64}.
kSPE1_1, //!< CPU has SPEv1p1 (statistical profiling extensions version 1.1) {A64}.
kSPE1_2, //!< CPU has SPEv1p2 (statistical profiling extensions version 1.2) {A64}.
kSPE1_3, //!< CPU has SPEv1p3 (statistical profiling extensions version 1.3) {A64}.
kSPE1_4, //!< CPU has SPEv1p4 (statistical profiling extensions version 1.4) {A64}.
kSPE_ALTCLK, //!< CPU has SPE_ALTCLK (statistical profiling alternate clock domain extension) {A64}.
kSPE_CRR, //!< CPU has SPE_CRR (statistical profiling call return branch records) {A64}.
kSPE_EFT, //!< CPU has SPE_EFT (statistical profiling extended filtering by type) {A64}.
kSPE_FDS, //!< CPU has SPE_FDS (statistical profiling data source filtering) {A64}.
kSPE_FPF, //!< CPU has SPE_FPF (statistical profiling floating-point flag extension) {A64}.
kSPE_SME, //!< CPU has SPE_SME (statistical profiling extensions for SME) {A64}.
kSPECRES, //!< CPU has SPECRES (speculation restriction instructions).
kSPECRES2, //!< CPU has SPECRES2 (clear other speculative predictions).
kSPMU, //!< CPU has SPMU (system performance monitors extension) {A64}.
kSSBS, //!< CPU has SSBS (speculative store bypass safe instruction).
kSSBS2, //!< CPU has SSBS2 (MRS and MSR instructions for SSBS).
kSSVE_FP8DOT2, //!< CPU has SSVE_FP8DOT2 (SVE2 FP8 2-way dot product to half-precision instructions in Streaming SVE mode) {A64}.
kSSVE_FP8DOT4, //!< CPU has SSVE_FP8DOT4 (SVE2 FP8 4-way dot product to single-precision instructions in Streaming SVE mode) {A64}.
kSSVE_FP8FMA, //!< CPU has SSVE_FP8FMA (SVE2 FP8 multiply-accumulate to half-precision and single-precision instructions in Streaming SVE mode) {A64}.
kSVE, //!< CPU has SVE (SVE v1 - scalable vector extension) {A64}.
kSVE2, //!< CPU has SVE2 (SVE v2) {A64}.
kSVE2_1, //!< CPU has SVE2p1 (SVE v2.1) {A64}.
kSVE_AES, //!< CPU has SVE_AES (SVE AES instructions) {A64}.
kSVE_B16B16, //!< CPU has SVE_B16B16 (SVE non-widening BFloat16 to BFloat16 arithmetic) {A64}.
kSVE_BF16, //!< CPU has SVE_BF16 (SVE BF16 instructions) {A64}.
kSVE_BITPERM, //!< CPU has SVE_BITPERM (SVE bit permute) {A64}.
kSVE_EBF16, //!< CPU has SVE_EBF16 (SVE extended BFloat16 mode) {A64}.
kSVE_F32MM, //!< CPU has SVE_F32MM (SVE single-precision floating-point matrix multiply instruction) {A64}.
kSVE_F64MM, //!< CPU has SVE_F64MM (SVE double-precision floating-point matrix multiply instruction) {A64}.
kSVE_I8MM, //!< CPU has SVE_I8MM (SVE int8 matrix multiplication) {A64}.
kSVE_PMULL128, //!< CPU has SVE_PMULL128 (SVE PMULL instructions) {A64}.
kSVE_SHA3, //!< CPU has SVE_SHA3 (SVE SHA-3 instructions) {A64}.
kSVE_SM4, //!< CPU has SVE_SM4 (SVE SM4 instructions {A64}.
kSYSINSTR128, //!< CPU has SYSINSTR128 (128-bit system instructions) {A64}.
kSYSREG128, //!< CPU has SYSREG128 (128-bit system registers) {A64}.
kTHE, //!< CPU has THE (translation hardening extension).
kTLBIOS, //!< CPU has TLBIOS (TLBI instructions in Outer Shareable domain) {A64}.
kTLBIRANGE, //!< CPU has TLBIRANGE (TLBI range instructions) {A64}.
kTLBIW, //!< CPU has TLBIW (TLBI VMALL for dirty state) {A64}.
kTME, //!< CPU has TME (transactional memory extensions).
kTRF, //!< CPU has TRF (self-hosted trace extensions).
kUAO, //!< CPU has UAO (AArch64 v8.2 UAO PState) {A64}.
kVFP_D32, //!< CPU has VFP_D32 (32 VFP-D registers) (ARM/THUMB only).
kVHE, //!< CPU has VHE (virtual host extension).
kVMID16, //!< CPU has VMID16 (16-bit VMID) {A64}.
kWFXT, //!< CPU has WFxT (WFE and WFI instructions with timeout) {A64}.
kXNX, //!< CPU has XNX (translation table stage 2 unprivileged execute-never) {A64}.
kXS, //!< CPU has XS (XS attribute in TLBI and DSB instructions) {A64}.
// @EnumValuesEnd@ // @EnumValuesEnd@
kMaxValue = kXS kMaxValue = kXS
}; };
#define ASMJIT_ARM_FEATURE(FEATURE) \ #define ASMJIT_ARM_FEATURE(FEATURE) \
/*! Tests whether FEATURE is present. */ \
ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); } ASMJIT_INLINE_NODEBUG bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); }
ASMJIT_ARM_FEATURE(THUMB) ASMJIT_ARM_FEATURE(THUMB)
@@ -642,26 +730,45 @@ public:
ASMJIT_ARM_FEATURE(ARMv7) ASMJIT_ARM_FEATURE(ARMv7)
ASMJIT_ARM_FEATURE(ARMv8a) ASMJIT_ARM_FEATURE(ARMv8a)
ASMJIT_ARM_FEATURE(ABLE)
ASMJIT_ARM_FEATURE(ADERR)
ASMJIT_ARM_FEATURE(AES) ASMJIT_ARM_FEATURE(AES)
ASMJIT_ARM_FEATURE(AFP) ASMJIT_ARM_FEATURE(AFP)
ASMJIT_ARM_FEATURE(AIE)
ASMJIT_ARM_FEATURE(AMU1)
ASMJIT_ARM_FEATURE(AMU1_1)
ASMJIT_ARM_FEATURE(ANERR)
ASMJIT_ARM_FEATURE(ASIMD) ASMJIT_ARM_FEATURE(ASIMD)
ASMJIT_ARM_FEATURE(BF16) ASMJIT_ARM_FEATURE(BF16)
ASMJIT_ARM_FEATURE(BRBE)
ASMJIT_ARM_FEATURE(BTI) ASMJIT_ARM_FEATURE(BTI)
ASMJIT_ARM_FEATURE(BWE)
ASMJIT_ARM_FEATURE(CCIDX) ASMJIT_ARM_FEATURE(CCIDX)
ASMJIT_ARM_FEATURE(CHK) ASMJIT_ARM_FEATURE(CHK)
ASMJIT_ARM_FEATURE(CLRBHB) ASMJIT_ARM_FEATURE(CLRBHB)
ASMJIT_ARM_FEATURE(CMOW)
ASMJIT_ARM_FEATURE(CONSTPACFIELD)
ASMJIT_ARM_FEATURE(CPA)
ASMJIT_ARM_FEATURE(CPA2)
ASMJIT_ARM_FEATURE(CPUID) ASMJIT_ARM_FEATURE(CPUID)
ASMJIT_ARM_FEATURE(CRC32) ASMJIT_ARM_FEATURE(CRC32)
ASMJIT_ARM_FEATURE(CSSC) ASMJIT_ARM_FEATURE(CSSC)
ASMJIT_ARM_FEATURE(CSV2)
ASMJIT_ARM_FEATURE(CSV2_3)
ASMJIT_ARM_FEATURE(CSV3)
ASMJIT_ARM_FEATURE(D128) ASMJIT_ARM_FEATURE(D128)
ASMJIT_ARM_FEATURE(DGH) ASMJIT_ARM_FEATURE(DGH)
ASMJIT_ARM_FEATURE(DIT) ASMJIT_ARM_FEATURE(DIT)
ASMJIT_ARM_FEATURE(DOTPROD) ASMJIT_ARM_FEATURE(DOTPROD)
ASMJIT_ARM_FEATURE(DPB) ASMJIT_ARM_FEATURE(DPB)
ASMJIT_ARM_FEATURE(DPB2) ASMJIT_ARM_FEATURE(DPB2)
ASMJIT_ARM_FEATURE(EBEP)
ASMJIT_ARM_FEATURE(EBF16) ASMJIT_ARM_FEATURE(EBF16)
ASMJIT_ARM_FEATURE(ECBHB)
ASMJIT_ARM_FEATURE(ECV) ASMJIT_ARM_FEATURE(ECV)
ASMJIT_ARM_FEATURE(EDHSR)
ASMJIT_ARM_FEATURE(EDSP) ASMJIT_ARM_FEATURE(EDSP)
ASMJIT_ARM_FEATURE(FAMINMAX)
ASMJIT_ARM_FEATURE(FCMA) ASMJIT_ARM_FEATURE(FCMA)
ASMJIT_ARM_FEATURE(FGT) ASMJIT_ARM_FEATURE(FGT)
ASMJIT_ARM_FEATURE(FGT2) ASMJIT_ARM_FEATURE(FGT2)
@@ -672,13 +779,25 @@ public:
ASMJIT_ARM_FEATURE(FP) ASMJIT_ARM_FEATURE(FP)
ASMJIT_ARM_FEATURE(FP16) ASMJIT_ARM_FEATURE(FP16)
ASMJIT_ARM_FEATURE(FP16CONV) ASMJIT_ARM_FEATURE(FP16CONV)
ASMJIT_ARM_FEATURE(FP8)
ASMJIT_ARM_FEATURE(FP8DOT2)
ASMJIT_ARM_FEATURE(FP8DOT4)
ASMJIT_ARM_FEATURE(FP8FMA)
ASMJIT_ARM_FEATURE(FPMR)
ASMJIT_ARM_FEATURE(FRINTTS) ASMJIT_ARM_FEATURE(FRINTTS)
ASMJIT_ARM_FEATURE(GCS) ASMJIT_ARM_FEATURE(GCS)
ASMJIT_ARM_FEATURE(HACDBS)
ASMJIT_ARM_FEATURE(HAFDBS)
ASMJIT_ARM_FEATURE(HAFT)
ASMJIT_ARM_FEATURE(HDBSS)
ASMJIT_ARM_FEATURE(HBC) ASMJIT_ARM_FEATURE(HBC)
ASMJIT_ARM_FEATURE(HCX) ASMJIT_ARM_FEATURE(HCX)
ASMJIT_ARM_FEATURE(HPDS)
ASMJIT_ARM_FEATURE(HPDS2)
ASMJIT_ARM_FEATURE(I8MM) ASMJIT_ARM_FEATURE(I8MM)
ASMJIT_ARM_FEATURE(IDIVA) ASMJIT_ARM_FEATURE(IDIVA)
ASMJIT_ARM_FEATURE(IDIVT) ASMJIT_ARM_FEATURE(IDIVT)
ASMJIT_ARM_FEATURE(ITE)
ASMJIT_ARM_FEATURE(JSCVT) ASMJIT_ARM_FEATURE(JSCVT)
ASMJIT_ARM_FEATURE(LOR) ASMJIT_ARM_FEATURE(LOR)
ASMJIT_ARM_FEATURE(LRCPC) ASMJIT_ARM_FEATURE(LRCPC)
@@ -690,12 +809,24 @@ public:
ASMJIT_ARM_FEATURE(LSE) ASMJIT_ARM_FEATURE(LSE)
ASMJIT_ARM_FEATURE(LSE128) ASMJIT_ARM_FEATURE(LSE128)
ASMJIT_ARM_FEATURE(LSE2) ASMJIT_ARM_FEATURE(LSE2)
ASMJIT_ARM_FEATURE(LUT)
ASMJIT_ARM_FEATURE(LVA)
ASMJIT_ARM_FEATURE(LVA3)
ASMJIT_ARM_FEATURE(MEC)
ASMJIT_ARM_FEATURE(MOPS) ASMJIT_ARM_FEATURE(MOPS)
ASMJIT_ARM_FEATURE(MPAM) ASMJIT_ARM_FEATURE(MPAM)
ASMJIT_ARM_FEATURE(MTE) ASMJIT_ARM_FEATURE(MTE)
ASMJIT_ARM_FEATURE(MTE2) ASMJIT_ARM_FEATURE(MTE2)
ASMJIT_ARM_FEATURE(MTE3) ASMJIT_ARM_FEATURE(MTE3)
ASMJIT_ARM_FEATURE(MTE4) ASMJIT_ARM_FEATURE(MTE4)
ASMJIT_ARM_FEATURE(MTE_ASYM_FAULT)
ASMJIT_ARM_FEATURE(MTE_ASYNC)
ASMJIT_ARM_FEATURE(MTE_CANONICAL_TAGS)
ASMJIT_ARM_FEATURE(MTE_NO_ADDRESS_TAGS)
ASMJIT_ARM_FEATURE(MTE_PERM_S1)
ASMJIT_ARM_FEATURE(MTE_STORE_ONLY)
ASMJIT_ARM_FEATURE(MTE_TAGGED_FAR)
ASMJIT_ARM_FEATURE(MTPMU)
ASMJIT_ARM_FEATURE(NMI) ASMJIT_ARM_FEATURE(NMI)
ASMJIT_ARM_FEATURE(NV) ASMJIT_ARM_FEATURE(NV)
ASMJIT_ARM_FEATURE(NV2) ASMJIT_ARM_FEATURE(NV2)
@@ -703,19 +834,28 @@ public:
ASMJIT_ARM_FEATURE(PAN2) ASMJIT_ARM_FEATURE(PAN2)
ASMJIT_ARM_FEATURE(PAN3) ASMJIT_ARM_FEATURE(PAN3)
ASMJIT_ARM_FEATURE(PAUTH) ASMJIT_ARM_FEATURE(PAUTH)
ASMJIT_ARM_FEATURE(PFAR)
ASMJIT_ARM_FEATURE(PMU) ASMJIT_ARM_FEATURE(PMU)
ASMJIT_ARM_FEATURE(PMULL) ASMJIT_ARM_FEATURE(PMULL)
ASMJIT_ARM_FEATURE(PRFMSLC) ASMJIT_ARM_FEATURE(PRFMSLC)
ASMJIT_ARM_FEATURE(RAS) ASMJIT_ARM_FEATURE(RAS)
ASMJIT_ARM_FEATURE(RAS1_1) ASMJIT_ARM_FEATURE(RAS1_1)
ASMJIT_ARM_FEATURE(RAS2) ASMJIT_ARM_FEATURE(RAS2)
ASMJIT_ARM_FEATURE(RASSA2)
ASMJIT_ARM_FEATURE(RDM) ASMJIT_ARM_FEATURE(RDM)
ASMJIT_ARM_FEATURE(RME) ASMJIT_ARM_FEATURE(RME)
ASMJIT_ARM_FEATURE(RNG) ASMJIT_ARM_FEATURE(RNG)
ASMJIT_ARM_FEATURE(RNG_TRAP) ASMJIT_ARM_FEATURE(RNG_TRAP)
ASMJIT_ARM_FEATURE(RPRES) ASMJIT_ARM_FEATURE(RPRES)
ASMJIT_ARM_FEATURE(RPRFM) ASMJIT_ARM_FEATURE(RPRFM)
ASMJIT_ARM_FEATURE(S1PIE)
ASMJIT_ARM_FEATURE(S1POE)
ASMJIT_ARM_FEATURE(S2PIE)
ASMJIT_ARM_FEATURE(S2POE)
ASMJIT_ARM_FEATURE(SB) ASMJIT_ARM_FEATURE(SB)
ASMJIT_ARM_FEATURE(SCTLR2)
ASMJIT_ARM_FEATURE(SEBEP)
ASMJIT_ARM_FEATURE(SEL2)
ASMJIT_ARM_FEATURE(SHA1) ASMJIT_ARM_FEATURE(SHA1)
ASMJIT_ARM_FEATURE(SHA256) ASMJIT_ARM_FEATURE(SHA256)
ASMJIT_ARM_FEATURE(SHA3) ASMJIT_ARM_FEATURE(SHA3)
@@ -732,14 +872,32 @@ public:
ASMJIT_ARM_FEATURE(SME_F16F32) ASMJIT_ARM_FEATURE(SME_F16F32)
ASMJIT_ARM_FEATURE(SME_F32F32) ASMJIT_ARM_FEATURE(SME_F32F32)
ASMJIT_ARM_FEATURE(SME_F64F64) ASMJIT_ARM_FEATURE(SME_F64F64)
ASMJIT_ARM_FEATURE(SME_F8F16)
ASMJIT_ARM_FEATURE(SME_F8F32)
ASMJIT_ARM_FEATURE(SME_FA64) ASMJIT_ARM_FEATURE(SME_FA64)
ASMJIT_ARM_FEATURE(SME_I16I32) ASMJIT_ARM_FEATURE(SME_I16I32)
ASMJIT_ARM_FEATURE(SME_I16I64) ASMJIT_ARM_FEATURE(SME_I16I64)
ASMJIT_ARM_FEATURE(SME_I8I32) ASMJIT_ARM_FEATURE(SME_I8I32)
ASMJIT_ARM_FEATURE(SME_LUTv2)
ASMJIT_ARM_FEATURE(SPE)
ASMJIT_ARM_FEATURE(SPE1_1)
ASMJIT_ARM_FEATURE(SPE1_2)
ASMJIT_ARM_FEATURE(SPE1_3)
ASMJIT_ARM_FEATURE(SPE1_4)
ASMJIT_ARM_FEATURE(SPE_ALTCLK)
ASMJIT_ARM_FEATURE(SPE_CRR)
ASMJIT_ARM_FEATURE(SPE_EFT)
ASMJIT_ARM_FEATURE(SPE_FDS)
ASMJIT_ARM_FEATURE(SPE_FPF)
ASMJIT_ARM_FEATURE(SPE_SME)
ASMJIT_ARM_FEATURE(SPECRES) ASMJIT_ARM_FEATURE(SPECRES)
ASMJIT_ARM_FEATURE(SPECRES2) ASMJIT_ARM_FEATURE(SPECRES2)
ASMJIT_ARM_FEATURE(SPMU)
ASMJIT_ARM_FEATURE(SSBS) ASMJIT_ARM_FEATURE(SSBS)
ASMJIT_ARM_FEATURE(SSBS2) ASMJIT_ARM_FEATURE(SSBS2)
ASMJIT_ARM_FEATURE(SSVE_FP8DOT2)
ASMJIT_ARM_FEATURE(SSVE_FP8DOT4)
ASMJIT_ARM_FEATURE(SSVE_FP8FMA)
ASMJIT_ARM_FEATURE(SVE) ASMJIT_ARM_FEATURE(SVE)
ASMJIT_ARM_FEATURE(SVE2) ASMJIT_ARM_FEATURE(SVE2)
ASMJIT_ARM_FEATURE(SVE2_1) ASMJIT_ARM_FEATURE(SVE2_1)
@@ -757,12 +915,17 @@ public:
ASMJIT_ARM_FEATURE(SYSINSTR128) ASMJIT_ARM_FEATURE(SYSINSTR128)
ASMJIT_ARM_FEATURE(SYSREG128) ASMJIT_ARM_FEATURE(SYSREG128)
ASMJIT_ARM_FEATURE(THE) ASMJIT_ARM_FEATURE(THE)
ASMJIT_ARM_FEATURE(TLBIOS)
ASMJIT_ARM_FEATURE(TLBIRANGE)
ASMJIT_ARM_FEATURE(TLBIW)
ASMJIT_ARM_FEATURE(TME) ASMJIT_ARM_FEATURE(TME)
ASMJIT_ARM_FEATURE(TRF) ASMJIT_ARM_FEATURE(TRF)
ASMJIT_ARM_FEATURE(UAO) ASMJIT_ARM_FEATURE(UAO)
ASMJIT_ARM_FEATURE(VFP_D32) ASMJIT_ARM_FEATURE(VFP_D32)
ASMJIT_ARM_FEATURE(VHE) ASMJIT_ARM_FEATURE(VHE)
ASMJIT_ARM_FEATURE(VMID16)
ASMJIT_ARM_FEATURE(WFXT) ASMJIT_ARM_FEATURE(WFXT)
ASMJIT_ARM_FEATURE(XNX)
ASMJIT_ARM_FEATURE(XS) ASMJIT_ARM_FEATURE(XS)
#undef ASMJIT_ARM_FEATURE #undef ASMJIT_ARM_FEATURE
@@ -794,8 +957,8 @@ public:
ASMJIT_INLINE_NODEBUG CpuFeatures& operator=(const CpuFeatures& other) noexcept = default; ASMJIT_INLINE_NODEBUG CpuFeatures& operator=(const CpuFeatures& other) noexcept = default;
ASMJIT_INLINE_NODEBUG bool operator==(const CpuFeatures& other) noexcept { return eq(other); } ASMJIT_INLINE_NODEBUG bool operator==(const CpuFeatures& other) const noexcept { return equals(other); }
ASMJIT_INLINE_NODEBUG bool operator!=(const CpuFeatures& other) noexcept { return !eq(other); } ASMJIT_INLINE_NODEBUG bool operator!=(const CpuFeatures& other) const noexcept { return !equals(other); }
//! \} //! \}
@@ -849,6 +1012,7 @@ public:
//! \name Manipulation //! \name Manipulation
//! \{ //! \{
//! Clears all features set.
ASMJIT_INLINE_NODEBUG void reset() noexcept { _data.reset(); } ASMJIT_INLINE_NODEBUG void reset() noexcept { _data.reset(); }
//! Adds the given CPU `featureId` to the list of features. //! Adds the given CPU `featureId` to the list of features.
@@ -864,7 +1028,12 @@ public:
ASMJIT_INLINE_NODEBUG void remove(Args&&... args) noexcept { return _data.remove(std::forward<Args>(args)...); } ASMJIT_INLINE_NODEBUG void remove(Args&&... args) noexcept { return _data.remove(std::forward<Args>(args)...); }
//! Tests whether this CPU features matches `other`. //! Tests whether this CPU features matches `other`.
ASMJIT_INLINE_NODEBUG bool eq(const CpuFeatures& other) const noexcept { return _data.eq(other._data); } ASMJIT_INLINE_NODEBUG bool equals(const CpuFeatures& other) const noexcept { return _data.equals(other._data); }
#if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("Use CpuFeatures::equals() instead")
ASMJIT_INLINE_NODEBUG bool eq(const CpuFeatures& other) const noexcept { return equals(other); }
#endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}
}; };
@@ -912,9 +1081,12 @@ public:
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
//! Creates a new CpuInfo instance.
ASMJIT_INLINE_NODEBUG CpuInfo() noexcept {} ASMJIT_INLINE_NODEBUG CpuInfo() noexcept {}
//! Creates a copy of `other` instance.
ASMJIT_INLINE_NODEBUG CpuInfo(const CpuInfo& other) noexcept = default; ASMJIT_INLINE_NODEBUG CpuInfo(const CpuInfo& other) noexcept = default;
//! Creates an unitialized `CpuInfo` instance.
ASMJIT_INLINE_NODEBUG explicit CpuInfo(Globals::NoInit_) noexcept ASMJIT_INLINE_NODEBUG explicit CpuInfo(Globals::NoInit_) noexcept
: _features(Globals::NoInit) {}; : _features(Globals::NoInit) {};
@@ -933,6 +1105,7 @@ public:
//! \name Overloaded Operators //! \name Overloaded Operators
//! \{ //! \{
//! Copy assignment.
ASMJIT_INLINE_NODEBUG CpuInfo& operator=(const CpuInfo& other) noexcept = default; ASMJIT_INLINE_NODEBUG CpuInfo& operator=(const CpuInfo& other) noexcept = default;
//! \} //! \}
@@ -946,6 +1119,7 @@ public:
_subArch = subArch; _subArch = subArch;
} }
//! Resets this \ref CpuInfo to a default constructed state.
ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = CpuInfo{}; } ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = CpuInfo{}; }
//! \} //! \}
@@ -1016,7 +1190,7 @@ public:
//! Returns a CPU vendor string. //! Returns a CPU vendor string.
ASMJIT_INLINE_NODEBUG const char* vendor() const noexcept { return _vendor.str; } ASMJIT_INLINE_NODEBUG const char* vendor() const noexcept { return _vendor.str; }
//! Tests whether the CPU vendor string is equal to `s`. //! Tests whether the CPU vendor string is equal to `s`.
ASMJIT_INLINE_NODEBUG bool isVendor(const char* s) const noexcept { return _vendor.eq(s); } ASMJIT_INLINE_NODEBUG bool isVendor(const char* s) const noexcept { return _vendor.equals(s); }
//! Returns a CPU brand string. //! Returns a CPU brand string.
ASMJIT_INLINE_NODEBUG const char* brand() const noexcept { return _brand.str; } ASMJIT_INLINE_NODEBUG const char* brand() const noexcept { return _brand.str; }

View File

@@ -116,7 +116,7 @@ enum class Platform : uint8_t {
//! Platform ABI (application binary interface). //! Platform ABI (application binary interface).
enum class PlatformABI : uint8_t { enum class PlatformABI : uint8_t {
//! Unknown or uninitialied environment. //! Unknown or uninitialized environment.
kUnknown = 0, kUnknown = 0,
//! Microsoft ABI. //! Microsoft ABI.
kMSVC, kMSVC,
@@ -147,6 +147,19 @@ enum class PlatformABI : uint8_t {
#endif #endif
}; };
//! Floating point ABI (ARM).
enum class FloatABI : uint8_t {
kHardFloat = 0,
kSoftFloat,
kHost =
#if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
kSoftFloat
#else
kHardFloat
#endif
};
//! Object format. //! Object format.
//! //!
//! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at //! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at
@@ -186,53 +199,56 @@ public:
//! \{ //! \{
//! Architecture. //! Architecture.
Arch _arch; Arch _arch = Arch::kUnknown;
//! Sub-architecture type. //! Sub-architecture type.
SubArch _subArch; SubArch _subArch = SubArch::kUnknown;
//! Vendor type. //! Vendor type.
Vendor _vendor; Vendor _vendor = Vendor::kUnknown;
//! Platform. //! Platform.
Platform _platform; Platform _platform = Platform::kUnknown;
//! Platform ABI. //! Platform ABI.
PlatformABI _platformABI; PlatformABI _platformABI = PlatformABI::kUnknown;
//! Object format. //! Object format.
ObjectFormat _objectFormat; ObjectFormat _objectFormat = ObjectFormat::kUnknown;
//! Floating point ABI.
FloatABI _floatABI = FloatABI::kHardFloat;
//! Reserved for future use, must be zero. //! Reserved for future use, must be zero.
uint8_t _reserved[2]; uint8_t _reserved = 0;
//! \} //! \}
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
ASMJIT_INLINE_NODEBUG Environment() noexcept : //! Creates a default initialized environment (all values either unknown or set to safe defaults).
_arch(Arch::kUnknown), ASMJIT_INLINE_NODEBUG constexpr Environment() noexcept = default;
_subArch(SubArch::kUnknown), //! Creates a copy of `other` instance.
_vendor(Vendor::kUnknown), ASMJIT_INLINE_NODEBUG constexpr Environment(const Environment& other) noexcept = default;
_platform(Platform::kUnknown),
_platformABI(PlatformABI::kUnknown),
_objectFormat(ObjectFormat::kUnknown),
_reserved { 0, 0 } {}
ASMJIT_INLINE_NODEBUG explicit Environment( //! Creates \ref Environment initialized to `arch`, `subArch`, `vendor`, `platform`, `platformABI`, `objectFormat`,
//! and `floatABI`.
ASMJIT_INLINE_NODEBUG constexpr explicit Environment(
Arch arch, Arch arch,
SubArch subArch = SubArch::kUnknown, SubArch subArch = SubArch::kUnknown,
Vendor vendor = Vendor::kUnknown, Vendor vendor = Vendor::kUnknown,
Platform platform = Platform::kUnknown, Platform platform = Platform::kUnknown,
PlatformABI abi = PlatformABI::kUnknown, PlatformABI platformABI = PlatformABI::kUnknown,
ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept { ObjectFormat objectFormat = ObjectFormat::kUnknown,
FloatABI floatABI = FloatABI::kHardFloat) noexcept
init(arch, subArch, vendor, platform, abi, objectFormat); : _arch(arch),
} _subArch(subArch),
_vendor(vendor),
ASMJIT_INLINE_NODEBUG Environment(const Environment& other) noexcept = default; _platform(platform),
_platformABI(platformABI),
_objectFormat(objectFormat),
_floatABI(floatABI) {}
//! Returns the host environment constructed from preprocessor macros defined by the compiler. //! Returns the host environment constructed from preprocessor macros defined by the compiler.
//! //!
//! The returned environment should precisely match the target host architecture, sub-architecture, platform, //! The returned environment should precisely match the target host architecture, sub-architecture, platform,
//! and ABI. //! and ABI.
static ASMJIT_INLINE_NODEBUG Environment host() noexcept { static ASMJIT_INLINE_NODEBUG Environment host() noexcept {
return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown); return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown, FloatABI::kHost);
} }
//! \} //! \}
@@ -271,20 +287,10 @@ public:
} }
//! Resets all members of the environment to zero / unknown. //! Resets all members of the environment to zero / unknown.
ASMJIT_INLINE_NODEBUG void reset() noexcept { ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = Environment{}; }
_arch = Arch::kUnknown;
_subArch = SubArch::kUnknown;
_vendor = Vendor::kUnknown;
_platform = Platform::kUnknown;
_platformABI = PlatformABI::kUnknown;
_objectFormat = ObjectFormat::kUnknown;
_reserved[0] = 0;
_reserved[1] = 0;
}
ASMJIT_INLINE_NODEBUG bool equals(const Environment& other) const noexcept { //! Tests whether this environment is equal to `other`.
return _packed() == other._packed(); ASMJIT_INLINE_NODEBUG bool equals(const Environment& other) const noexcept { return _packed() == other._packed(); }
}
//! Returns the architecture. //! Returns the architecture.
ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; } ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
@@ -298,14 +304,19 @@ public:
ASMJIT_INLINE_NODEBUG PlatformABI platformABI() const noexcept { return _platformABI; } ASMJIT_INLINE_NODEBUG PlatformABI platformABI() const noexcept { return _platformABI; }
//! Returns target's object format. //! Returns target's object format.
ASMJIT_INLINE_NODEBUG ObjectFormat objectFormat() const noexcept { return _objectFormat; } ASMJIT_INLINE_NODEBUG ObjectFormat objectFormat() const noexcept { return _objectFormat; }
//! Returns floating point ABI.
ASMJIT_INLINE_NODEBUG FloatABI floatABI() const noexcept { return _floatABI; }
//! Initializes \ref Environment to `arch`, `subArch`, `vendor`, `platform`, `platformABI`, `objectFormat`,
//! and `floatABI`.
inline void init( inline void init(
Arch arch, Arch arch,
SubArch subArch = SubArch::kUnknown, SubArch subArch = SubArch::kUnknown,
Vendor vendor = Vendor::kUnknown, Vendor vendor = Vendor::kUnknown,
Platform platform = Platform::kUnknown, Platform platform = Platform::kUnknown,
PlatformABI platformABI = PlatformABI::kUnknown, PlatformABI platformABI = PlatformABI::kUnknown,
ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept { ObjectFormat objectFormat = ObjectFormat::kUnknown,
FloatABI floatABI = FloatABI::kHardFloat) noexcept {
_arch = arch; _arch = arch;
_subArch = subArch; _subArch = subArch;
@@ -313,18 +324,27 @@ public:
_platform = platform; _platform = platform;
_platformABI = platformABI; _platformABI = platformABI;
_objectFormat = objectFormat; _objectFormat = objectFormat;
_reserved[0] = 0; _floatABI = floatABI;
_reserved[1] = 0; _reserved = 0;
} }
//! Tests whether this environment describes a 32-bit X86.
ASMJIT_INLINE_NODEBUG bool isArchX86() const noexcept { return _arch == Arch::kX86; } ASMJIT_INLINE_NODEBUG bool isArchX86() const noexcept { return _arch == Arch::kX86; }
//! Tests whether this environment describes a 64-bit X86.
ASMJIT_INLINE_NODEBUG bool isArchX64() const noexcept { return _arch == Arch::kX64; } ASMJIT_INLINE_NODEBUG bool isArchX64() const noexcept { return _arch == Arch::kX64; }
//! Tests whether this environment describes a 32-bit ARM.
ASMJIT_INLINE_NODEBUG bool isArchARM() const noexcept { return isArchARM(_arch); } ASMJIT_INLINE_NODEBUG bool isArchARM() const noexcept { return isArchARM(_arch); }
//! Tests whether this environment describes a 32-bit ARM in THUMB mode.
ASMJIT_INLINE_NODEBUG bool isArchThumb() const noexcept { return isArchThumb(_arch); } ASMJIT_INLINE_NODEBUG bool isArchThumb() const noexcept { return isArchThumb(_arch); }
//! Tests whether this environment describes a 64-bit X86.
ASMJIT_INLINE_NODEBUG bool isArchAArch64() const noexcept { return isArchAArch64(_arch); } ASMJIT_INLINE_NODEBUG bool isArchAArch64() const noexcept { return isArchAArch64(_arch); }
//! Tests whether this environment describes a 32-bit MIPS.
ASMJIT_INLINE_NODEBUG bool isArchMIPS32() const noexcept { return isArchMIPS32(_arch); } ASMJIT_INLINE_NODEBUG bool isArchMIPS32() const noexcept { return isArchMIPS32(_arch); }
//! Tests whether this environment describes a 64-bit MIPS.
ASMJIT_INLINE_NODEBUG bool isArchMIPS64() const noexcept { return isArchMIPS64(_arch); } ASMJIT_INLINE_NODEBUG bool isArchMIPS64() const noexcept { return isArchMIPS64(_arch); }
//! Tests whether this environment describes a 32-bit RISC-V.
ASMJIT_INLINE_NODEBUG bool isArchRISCV32() const noexcept { return _arch == Arch::kRISCV32; } ASMJIT_INLINE_NODEBUG bool isArchRISCV32() const noexcept { return _arch == Arch::kRISCV32; }
//! Tests whether this environment describes a 64-bit RISC-V.
ASMJIT_INLINE_NODEBUG bool isArchRISCV64() const noexcept { return _arch == Arch::kRISCV64; } ASMJIT_INLINE_NODEBUG bool isArchRISCV64() const noexcept { return _arch == Arch::kRISCV64; }
//! Tests whether the architecture is 32-bit. //! Tests whether the architecture is 32-bit.
@@ -352,13 +372,10 @@ public:
//! Tests whether the environment platform is Windows. //! Tests whether the environment platform is Windows.
ASMJIT_INLINE_NODEBUG bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; } ASMJIT_INLINE_NODEBUG bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; }
//! Tests whether the environment platform is Linux. //! Tests whether the environment platform is Linux.
ASMJIT_INLINE_NODEBUG bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; } ASMJIT_INLINE_NODEBUG bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; }
//! Tests whether the environment platform is Hurd. //! Tests whether the environment platform is Hurd.
ASMJIT_INLINE_NODEBUG bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; } ASMJIT_INLINE_NODEBUG bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; }
//! Tests whether the environment platform is Haiku. //! Tests whether the environment platform is Haiku.
ASMJIT_INLINE_NODEBUG bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; } ASMJIT_INLINE_NODEBUG bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; }
@@ -402,6 +419,9 @@ public:
//! Sets the object format to `objectFormat`. //! Sets the object format to `objectFormat`.
ASMJIT_INLINE_NODEBUG void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; } ASMJIT_INLINE_NODEBUG void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; }
//! Sets floating point ABI to `floatABI`.
ASMJIT_INLINE_NODEBUG void setFloatABI(FloatABI floatABI) noexcept { _floatABI = floatABI; }
//! \} //! \}
//! \name Static Utilities //! \name Static Utilities

View File

@@ -28,9 +28,6 @@ ASMJIT_BEGIN_NAMESPACE
//! - Target specific - calling conventions that are used by a particular architecture and ABI. For example //! - Target specific - calling conventions that are used by a particular architecture and ABI. For example
//! Windows 64-bit calling convention and AMD64 SystemV calling convention. //! Windows 64-bit calling convention and AMD64 SystemV calling convention.
enum class CallConvId : uint8_t { enum class CallConvId : uint8_t {
//! None or invalid (can't be used).
kNone = 0,
// Universal Calling Conventions // Universal Calling Conventions
// ----------------------------- // -----------------------------
@@ -38,48 +35,38 @@ enum class CallConvId : uint8_t {
//! //!
//! This is a universal calling convention, which is used to initialize specific calling conventions based on //! This is a universal calling convention, which is used to initialize specific calling conventions based on
//! architecture, platform, and its ABI. //! architecture, platform, and its ABI.
kCDecl = 1, kCDecl = 0,
//! `__stdcall` on targets that support this calling convention (X86). //! `__stdcall` on targets that support this calling convention (X86).
//! //!
//! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support //! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support
//! this calling convention it will be replaced by \ref CallConvId::kCDecl. //! this calling convention it will be replaced by \ref CallConvId::kCDecl.
kStdCall = 2, kStdCall = 1,
//! `__fastcall` on targets that support this calling convention (X86). //! `__fastcall` on targets that support this calling convention (X86).
//! //!
//! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support //! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support
//! this calling convention it will be replaced by \ref CallConvId::kCDecl. //! this calling convention it will be replaced by \ref CallConvId::kCDecl.
kFastCall = 3, kFastCall = 2,
//! `__vectorcall` on targets that support this calling convention (X86/X64). //! `__vectorcall` on targets that support this calling convention (X86/X64).
//! //!
//! \note This calling convention is only supported on 32-bit and 64-bit X86 architecture on Windows platform. //! \note This calling convention is only supported on 32-bit and 64-bit X86 architecture on Windows platform.
//! If used on environment that doesn't support this calling it will be replaced by \ref CallConvId::kCDecl. //! If used on environment that doesn't support this calling it will be replaced by \ref CallConvId::kCDecl.
kVectorCall = 4, kVectorCall = 3,
//! `__thiscall` on targets that support this calling convention (X86). //! `__thiscall` on targets that support this calling convention (X86).
//! //!
//! \note This calling convention is only supported on 32-bit X86 Windows platform. If used on environment that //! \note This calling convention is only supported on 32-bit X86 Windows platform. If used on environment that
//! doesn't support this calling convention it will be replaced by \ref CallConvId::kCDecl. //! doesn't support this calling convention it will be replaced by \ref CallConvId::kCDecl.
kThisCall = 5, kThisCall = 4,
//! `__attribute__((regparm(1)))` convention (GCC and Clang). //! `__attribute__((regparm(1)))` convention (GCC and Clang).
kRegParm1 = 6, kRegParm1 = 5,
//! `__attribute__((regparm(2)))` convention (GCC and Clang). //! `__attribute__((regparm(2)))` convention (GCC and Clang).
kRegParm2 = 7, kRegParm2 = 6,
//! `__attribute__((regparm(3)))` convention (GCC and Clang). //! `__attribute__((regparm(3)))` convention (GCC and Clang).
kRegParm3 = 8, kRegParm3 = 7,
//! Soft-float calling convention (ARM).
//!
//! Floating point arguments are passed via general purpose registers.
kSoftFloat = 9,
//! Hard-float calling convention (ARM).
//!
//! Floating point arguments are passed via SIMD registers.
kHardFloat = 10,
//! AsmJit specific calling convention designed for calling functions inside a multimedia code that don't use many //! AsmJit specific calling convention designed for calling functions inside a multimedia code that don't use many
//! registers internally, but are long enough to be called and not inlined. These functions are usually used to //! registers internally, but are long enough to be called and not inlined. These functions are usually used to
@@ -91,28 +78,32 @@ enum class CallConvId : uint8_t {
// ABI-Specific Calling Conventions // ABI-Specific Calling Conventions
// -------------------------------- // --------------------------------
//! Soft-float calling convention (AArch32).
//!
//! Floating point arguments are passed via general purpose registers.
kSoftFloat = 30,
//! Hard-float calling convention (AArch32).
//!
//! Floating point arguments are passed via SIMD registers.
kHardFloat = 31,
//! X64 System-V calling convention. //! X64 System-V calling convention.
kX64SystemV = 32, kX64SystemV = 32,
//! X64 Windows calling convention. //! X64 Windows calling convention.
kX64Windows = 33, kX64Windows = 33,
//! Maximum value of `CallConvId`. //! Maximum value of `CallConvId`.
kMaxValue = kX64Windows, kMaxValue = kX64Windows
// Host Calling Conventions // Deprecated Aliases
// ------------------------ // ------------------
//! Host calling convention detected at compile-time. #if !defined(ASMJIT_NO_DEPRECATED)
kHost = ,
#if defined(_DOXYGEN) kNone = kCDecl,
DETECTED_AT_COMPILE_TIME kHost = kCDecl
#elif ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__) #endif // !ASMJIT_NO_DEPRECATED
kSoftFloat
#elif ASMJIT_ARCH_ARM == 32 && !defined(__SOFTFP__)
kHardFloat
#else
kCDecl
#endif
}; };
//! Strategy used by calling conventions to assign registers to function arguments. //! Strategy used by calling conventions to assign registers to function arguments.
@@ -377,7 +368,7 @@ struct FuncSignature {
//! \{ //! \{
//! Calling convention id. //! Calling convention id.
CallConvId _ccId = CallConvId::kHost; CallConvId _ccId = CallConvId::kCDecl;
//! Count of arguments. //! Count of arguments.
uint8_t _argCount = 0; uint8_t _argCount = 0;
//! Index of a first VA or `kNoVarArgs`. //! Index of a first VA or `kNoVarArgs`.
@@ -394,7 +385,7 @@ struct FuncSignature {
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
//! Default constructed function signature, initialized to \ref CallConvId::kHost, having no return value and no arguments. //! Default constructed function signature, initialized to \ref CallConvId::kCDecl, having no return value and no arguments.
ASMJIT_FORCE_INLINE constexpr FuncSignature() = default; ASMJIT_FORCE_INLINE constexpr FuncSignature() = default;
//! Copy constructor, which is initialized to the same function signature as `other`. //! Copy constructor, which is initialized to the same function signature as `other`.
@@ -415,7 +406,7 @@ struct FuncSignature {
_args{std::forward<Args>(args)...} {} _args{std::forward<Args>(args)...} {}
template<typename... RetValueAndArgs> template<typename... RetValueAndArgs>
static ASMJIT_INLINE_NODEBUG constexpr FuncSignature build(CallConvId ccId = CallConvId::kHost, uint32_t vaIndex = kNoVarArgs) noexcept { static ASMJIT_INLINE_NODEBUG constexpr FuncSignature build(CallConvId ccId = CallConvId::kCDecl, uint32_t vaIndex = kNoVarArgs) noexcept {
return FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... ); return FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... );
} }
@@ -522,9 +513,10 @@ struct FuncSignature {
#if !defined(ASMJIT_NO_DEPRECATED) #if !defined(ASMJIT_NO_DEPRECATED)
template<typename... RetValueAndArgs> template<typename... RetValueAndArgs>
class ASMJIT_DEPRECATED("Use FuncSignature::build<RetValueAndArgs>() instead") FuncSignatureT : public FuncSignature { class FuncSignatureT : public FuncSignature {
public: public:
ASMJIT_INLINE_NODEBUG constexpr FuncSignatureT(CallConvId ccId = CallConvId::kHost, uint32_t vaIndex = kNoVarArgs) noexcept ASMJIT_DEPRECATED("Use FuncSignature::build<RetValueAndArgs>() instead")
ASMJIT_INLINE_NODEBUG constexpr FuncSignatureT(CallConvId ccId = CallConvId::kCDecl, uint32_t vaIndex = kNoVarArgs) noexcept
: FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... ) {} : FuncSignature(ccId, vaIndex, (TypeId(TypeUtils::TypeIdOfT<RetValueAndArgs>::kTypeId))... ) {}
}; };
@@ -573,15 +565,17 @@ struct FuncValue {
//! //!
//! \{ //! \{
//! Initializes the `typeId` of this `FuncValue`. //! Initializes this `FuncValue` only to the `typeId` provided - the rest of the values will be cleared.
ASMJIT_INLINE_NODEBUG void initTypeId(TypeId typeId) noexcept { ASMJIT_INLINE_NODEBUG void initTypeId(TypeId typeId) noexcept {
_data = uint32_t(typeId) << kTypeIdShift; _data = uint32_t(typeId) << kTypeIdShift;
} }
//! Initializes this `FuncValue` to a register of `regType`, `regId`, and assigns its `typeId` and `flags`.
ASMJIT_INLINE_NODEBUG void initReg(RegType regType, uint32_t regId, TypeId typeId, uint32_t flags = 0) noexcept { ASMJIT_INLINE_NODEBUG void initReg(RegType regType, uint32_t regId, TypeId typeId, uint32_t flags = 0) noexcept {
_data = (uint32_t(regType) << kRegTypeShift) | (regId << kRegIdShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsReg | flags; _data = (uint32_t(regType) << kRegTypeShift) | (regId << kRegIdShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsReg | flags;
} }
//! Initializes this `FuncValue` to a stack at the given `offset` and assigns its `typeId`.
ASMJIT_INLINE_NODEBUG void initStack(int32_t offset, TypeId typeId) noexcept { ASMJIT_INLINE_NODEBUG void initStack(int32_t offset, TypeId typeId) noexcept {
_data = (uint32_t(offset) << kStackOffsetShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsStack; _data = (uint32_t(offset) << kStackOffsetShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsStack;
} }
@@ -825,22 +819,35 @@ public:
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
//! Creates a default constructed \ref FuncDetail.
ASMJIT_INLINE_NODEBUG FuncDetail() noexcept {} ASMJIT_INLINE_NODEBUG FuncDetail() noexcept {}
//! Copy constructor.
//!
//! Function details are copyable.
ASMJIT_INLINE_NODEBUG FuncDetail(const FuncDetail& other) noexcept = default; ASMJIT_INLINE_NODEBUG FuncDetail(const FuncDetail& other) noexcept = default;
//! Initializes this `FuncDetail` to the given signature. //! Initializes this `FuncDetail` to the given signature.
ASMJIT_API Error init(const FuncSignature& signature, const Environment& environment) noexcept; ASMJIT_API Error init(const FuncSignature& signature, const Environment& environment) noexcept;
ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = FuncDetail{}; }
//! \} //! \}
//! \name Overloaded Operators //! \name Overloaded Operators
//! \{ //! \{
//! Assignment operator, copies `other` to this \ref FuncDetail.
ASMJIT_INLINE_NODEBUG FuncDetail& operator=(const FuncDetail& other) noexcept = default; ASMJIT_INLINE_NODEBUG FuncDetail& operator=(const FuncDetail& other) noexcept = default;
//! \} //! \}
//! \name Reset
//! \{
//! Resets the function detail to its default constructed state.
ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = FuncDetail{}; }
//! \}
//! \name Accessors //! \name Accessors
//! \{ //! \{
@@ -1298,11 +1305,16 @@ public:
addDirtyRegs(std::forward<Args>(args)...); addDirtyRegs(std::forward<Args>(args)...);
} }
//! A helper function to set all registers from all register groups dirty.
//!
//! \note This should not be used in general as it's the most pessimistic case. However, it can be used for testing
//! or in cases in which all registers are considered clobbered.
ASMJIT_INLINE_NODEBUG void setAllDirty() noexcept { ASMJIT_INLINE_NODEBUG void setAllDirty() noexcept {
for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_dirtyRegs); i++) for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_dirtyRegs); i++)
_dirtyRegs[i] = 0xFFFFFFFFu; _dirtyRegs[i] = 0xFFFFFFFFu;
} }
//! A helper function to set all registers from the given register `group` dirty.
inline void setAllDirty(RegGroup group) noexcept { inline void setAllDirty(RegGroup group) noexcept {
ASMJIT_ASSERT(group <= RegGroup::kMaxVirt); ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_dirtyRegs[group] = 0xFFFFFFFFu; _dirtyRegs[group] = 0xFFFFFFFFu;
@@ -1325,6 +1337,7 @@ public:
return _preservedRegs[group]; return _preservedRegs[group];
} }
//! Returns the size of a save-restore are for the required register `group`.
inline uint32_t saveRestoreRegSize(RegGroup group) const noexcept { inline uint32_t saveRestoreRegSize(RegGroup group) const noexcept {
ASMJIT_ASSERT(group <= RegGroup::kMaxVirt); ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _saveRestoreRegSize[group]; return _saveRestoreRegSize[group];
@@ -1392,10 +1405,14 @@ public:
//! \name Construction & Destruction //! \name Construction & Destruction
//! \{ //! \{
//! Creates either a default initialized `FuncArgsAssignment` or to assignment that links to `fd`, if non-null.
ASMJIT_INLINE_NODEBUG explicit FuncArgsAssignment(const FuncDetail* fd = nullptr) noexcept { reset(fd); } ASMJIT_INLINE_NODEBUG explicit FuncArgsAssignment(const FuncDetail* fd = nullptr) noexcept { reset(fd); }
//! Copy constructor.
ASMJIT_INLINE_NODEBUG FuncArgsAssignment(const FuncArgsAssignment& other) noexcept = default; ASMJIT_INLINE_NODEBUG FuncArgsAssignment(const FuncArgsAssignment& other) noexcept = default;
//! Resets this `FuncArgsAssignment` to either default constructed state or to assignment that links to `fd`,
//! if non-null.
inline void reset(const FuncDetail* fd = nullptr) noexcept { inline void reset(const FuncDetail* fd = nullptr) noexcept {
_funcDetail = fd; _funcDetail = fd;
_saRegId = uint8_t(BaseReg::kIdBad); _saRegId = uint8_t(BaseReg::kIdBad);
@@ -1408,6 +1425,7 @@ public:
//! \name Overloaded Operators //! \name Overloaded Operators
//! \{ //! \{
//! Copy assignment.
ASMJIT_INLINE_NODEBUG FuncArgsAssignment& operator=(const FuncArgsAssignment& other) noexcept = default; ASMJIT_INLINE_NODEBUG FuncArgsAssignment& operator=(const FuncArgsAssignment& other) noexcept = default;
//! \} //! \}
@@ -1415,7 +1433,9 @@ public:
//! \name Accessors //! \name Accessors
//! \{ //! \{
//! Returns the associated \ref FuncDetail of this `FuncArgsAssignment`.
ASMJIT_INLINE_NODEBUG const FuncDetail* funcDetail() const noexcept { return _funcDetail; } ASMJIT_INLINE_NODEBUG const FuncDetail* funcDetail() const noexcept { return _funcDetail; }
//! Associates \ref FuncDetails with this `FuncArgsAssignment`.
ASMJIT_INLINE_NODEBUG void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; } ASMJIT_INLINE_NODEBUG void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; }
ASMJIT_INLINE_NODEBUG bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; } ASMJIT_INLINE_NODEBUG bool hasSARegId() const noexcept { return _saRegId != BaseReg::kIdBad; }
@@ -1423,47 +1443,59 @@ public:
ASMJIT_INLINE_NODEBUG void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); } ASMJIT_INLINE_NODEBUG void setSARegId(uint32_t regId) { _saRegId = uint8_t(regId); }
ASMJIT_INLINE_NODEBUG void resetSARegId() { _saRegId = uint8_t(BaseReg::kIdBad); } ASMJIT_INLINE_NODEBUG void resetSARegId() { _saRegId = uint8_t(BaseReg::kIdBad); }
//! Returns assigned argument at `argIndex` and `valueIndex`.
//!
//! \note `argIndex` refers to he function argument and `valueIndex` refers to a value pack (in case multiple
//! values are passed as a single argument).
inline FuncValue& arg(size_t argIndex, size_t valueIndex) noexcept { inline FuncValue& arg(size_t argIndex, size_t valueIndex) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex]; return _argPacks[argIndex][valueIndex];
} }
//! \overload
inline const FuncValue& arg(size_t argIndex, size_t valueIndex) const noexcept { inline const FuncValue& arg(size_t argIndex, size_t valueIndex) const noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex]; return _argPacks[argIndex][valueIndex];
} }
//! Tests whether argument at `argIndex` and `valueIndex` has been assigned.
inline bool isAssigned(size_t argIndex, size_t valueIndex) const noexcept { inline bool isAssigned(size_t argIndex, size_t valueIndex) const noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
return _argPacks[argIndex][valueIndex].isAssigned(); return _argPacks[argIndex][valueIndex].isAssigned();
} }
//! Assigns register at `argIndex` and value index of 0 to `reg` and an optional `typeId`.
inline void assignReg(size_t argIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept { inline void assignReg(size_t argIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
ASMJIT_ASSERT(reg.isPhysReg()); ASMJIT_ASSERT(reg.isPhysReg());
_argPacks[argIndex][0].initReg(reg.type(), reg.id(), typeId); _argPacks[argIndex][0].initReg(reg.type(), reg.id(), typeId);
} }
//! Assigns register at `argIndex` and value index of 0 to `regType`, `regId`, and an optional `typeId`.
inline void assignReg(size_t argIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept { inline void assignReg(size_t argIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][0].initReg(regType, regId, typeId); _argPacks[argIndex][0].initReg(regType, regId, typeId);
} }
//! Assigns stack at `argIndex` and value index of 0 to `offset` and an optional `typeId`.
inline void assignStack(size_t argIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept { inline void assignStack(size_t argIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][0].initStack(offset, typeId); _argPacks[argIndex][0].initStack(offset, typeId);
} }
//! Assigns register at `argIndex` and `valueIndex` to `reg` and an optional `typeId`.
inline void assignRegInPack(size_t argIndex, size_t valueIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept { inline void assignRegInPack(size_t argIndex, size_t valueIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
ASMJIT_ASSERT(reg.isPhysReg()); ASMJIT_ASSERT(reg.isPhysReg());
_argPacks[argIndex][valueIndex].initReg(reg.type(), reg.id(), typeId); _argPacks[argIndex][valueIndex].initReg(reg.type(), reg.id(), typeId);
} }
//! Assigns register at `argIndex` and `valueIndex` to `regType`, `regId`, and an optional `typeId`.
inline void assignRegInPack(size_t argIndex, size_t valueIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept { inline void assignRegInPack(size_t argIndex, size_t valueIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][valueIndex].initReg(regType, regId, typeId); _argPacks[argIndex][valueIndex].initReg(regType, regId, typeId);
} }
//! Assigns stack at `argIndex` and `valueIndex` to `offset` and an optional `typeId`.
inline void assignStackInPack(size_t argIndex, size_t valueIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept { inline void assignStackInPack(size_t argIndex, size_t valueIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks)); ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][valueIndex].initStack(offset, typeId); _argPacks[argIndex][valueIndex].initStack(offset, typeId);
@@ -1482,6 +1514,9 @@ public:
_assignAllInternal(argIndex + 1, std::forward<Args>(args)...); _assignAllInternal(argIndex + 1, std::forward<Args>(args)...);
} }
//! Assigns all argument at once.
//!
//! \note This function can be only used if the arguments don't contain value packs (multiple values per argument).
template<typename... Args> template<typename... Args>
inline void assignAll(Args&&... args) noexcept { inline void assignAll(Args&&... args) noexcept {
_assignAllInternal(0, std::forward<Args>(args)...); _assignAllInternal(0, std::forward<Args>(args)...);
@@ -1506,4 +1541,3 @@ public:
ASMJIT_END_NAMESPACE ASMJIT_END_NAMESPACE
#endif // ASMJIT_CORE_FUNC_H_INCLUDED #endif // ASMJIT_CORE_FUNC_H_INCLUDED

View File

@@ -131,14 +131,18 @@ static constexpr uint32_t kNumVirtGroups = 4;
struct Init_ {}; struct Init_ {};
struct NoInit_ {}; struct NoInit_ {};
//! A decorator used to initialize.
static const constexpr Init_ Init {}; static const constexpr Init_ Init {};
//! A decorator used to not initialize.
static const constexpr NoInit_ NoInit {}; static const constexpr NoInit_ NoInit {};
} // {Globals} } // {Globals}
//! Casts a `void*` pointer `func` to a function pointer `Func`.
template<typename Func> template<typename Func>
static ASMJIT_INLINE_NODEBUG Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); } static ASMJIT_INLINE_NODEBUG Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
//! Casts a function pointer `func` to a void pointer `void*`.
template<typename Func> template<typename Func>
static ASMJIT_INLINE_NODEBUG void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); } static ASMJIT_INLINE_NODEBUG void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_impl<void*, Func>(func); }

View File

@@ -20,8 +20,10 @@ class CodeHolder;
//! \addtogroup asmjit_virtual_memory //! \addtogroup asmjit_virtual_memory
//! \{ //! \{
//! JIT execution runtime is a special `Target` that is designed to store and //! JIT execution runtime is a special `Target` that is designed to store and execute a generated code.
//! execute the generated code. //!
//! JIT runtime is the easiest way of using AsmJit as it abstracts allocation and deallocation of virtual memory
//! where executable code can be placed and from which it can be executed as well.
class ASMJIT_VIRTAPI JitRuntime : public Target { class ASMJIT_VIRTAPI JitRuntime : public Target {
public: public:
ASMJIT_NONCOPYABLE(JitRuntime) ASMJIT_NONCOPYABLE(JitRuntime)
@@ -37,6 +39,16 @@ public:
//! Destroys the `JitRuntime` instance. //! Destroys the `JitRuntime` instance.
ASMJIT_API ~JitRuntime() noexcept override; ASMJIT_API ~JitRuntime() noexcept override;
//! \}
//! \name Accessors
//! \{
//! Resets the \ref JitRuntime, freeing everything that was allocated by it.
//!
//! Depending on `resetPolicy` the currently held memory can be either freed entirely when ResetPolicy::kHard is used,
//! or the allocator can keep some of it for next allocations when ResetPolicy::kSoft is used, which is the default
//! behavior.
ASMJIT_INLINE_NODEBUG void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept { ASMJIT_INLINE_NODEBUG void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
_allocator.reset(resetPolicy); _allocator.reset(resetPolicy);
} }

View File

@@ -703,10 +703,10 @@ struct Operand_ {
} }
#if !defined(ASMJIT_NO_DEPRECATED) #if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() instead if, your target is X86/X86_64") ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() instead, if your target is X86/X86_64")
ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return x86RmSize() != 0u; } ASMJIT_INLINE_NODEBUG constexpr bool hasSize() const noexcept { return x86RmSize() != 0u; }
ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() instead if, your target is X86/X86_64") ASMJIT_DEPRECATED("hasSize() is no longer portable - use x86RmSize() instead, if your target is X86/X86_64")
ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return x86RmSize() == s; } ASMJIT_INLINE_NODEBUG constexpr bool hasSize(uint32_t s) const noexcept { return x86RmSize() == s; }
ASMJIT_DEPRECATED("size() is no longer portable - use x86RmSize() instead, if your target is X86/X86_64") ASMJIT_DEPRECATED("size() is no longer portable - use x86RmSize() instead, if your target is X86/X86_64")

View File

@@ -463,7 +463,7 @@ Error String::truncate(size_t newSize) noexcept {
return kErrorOk; return kErrorOk;
} }
bool String::eq(const char* other, size_t size) const noexcept { bool String::equals(const char* other, size_t size) const noexcept {
const char* aData = data(); const char* aData = data();
const char* bData = other; const char* bData = other;
@@ -499,8 +499,8 @@ UNIT(core_string) {
EXPECT_EQ(s.capacity(), String::kSSOCapacity); EXPECT_EQ(s.capacity(), String::kSSOCapacity);
EXPECT_EQ(s.data()[0], 'a'); EXPECT_EQ(s.data()[0], 'a');
EXPECT_EQ(s.data()[1], '\0'); EXPECT_EQ(s.data()[1], '\0');
EXPECT_TRUE(s.eq("a")); EXPECT_TRUE(s.equals("a"));
EXPECT_TRUE(s.eq("a", 1)); EXPECT_TRUE(s.equals("a", 1));
EXPECT_EQ(s.assignChars('b', 4), kErrorOk); EXPECT_EQ(s.assignChars('b', 4), kErrorOk);
EXPECT_EQ(s.size(), 4u); EXPECT_EQ(s.size(), 4u);
@@ -510,8 +510,8 @@ UNIT(core_string) {
EXPECT_EQ(s.data()[2], 'b'); EXPECT_EQ(s.data()[2], 'b');
EXPECT_EQ(s.data()[3], 'b'); EXPECT_EQ(s.data()[3], 'b');
EXPECT_EQ(s.data()[4], '\0'); EXPECT_EQ(s.data()[4], '\0');
EXPECT_TRUE(s.eq("bbbb")); EXPECT_TRUE(s.equals("bbbb"));
EXPECT_TRUE(s.eq("bbbb", 4)); EXPECT_TRUE(s.equals("bbbb", 4));
EXPECT_EQ(s.assign("abc"), kErrorOk); EXPECT_EQ(s.assign("abc"), kErrorOk);
EXPECT_EQ(s.size(), 3u); EXPECT_EQ(s.size(), 3u);
@@ -520,16 +520,16 @@ UNIT(core_string) {
EXPECT_EQ(s.data()[1], 'b'); EXPECT_EQ(s.data()[1], 'b');
EXPECT_EQ(s.data()[2], 'c'); EXPECT_EQ(s.data()[2], 'c');
EXPECT_EQ(s.data()[3], '\0'); EXPECT_EQ(s.data()[3], '\0');
EXPECT_TRUE(s.eq("abc")); EXPECT_TRUE(s.equals("abc"));
EXPECT_TRUE(s.eq("abc", 3)); EXPECT_TRUE(s.equals("abc", 3));
const char* large = "Large string that will not fit into SSO buffer"; const char* large = "Large string that will not fit into SSO buffer";
EXPECT_EQ(s.assign(large), kErrorOk); EXPECT_EQ(s.assign(large), kErrorOk);
EXPECT_TRUE(s.isLargeOrExternal()); EXPECT_TRUE(s.isLargeOrExternal());
EXPECT_EQ(s.size(), strlen(large)); EXPECT_EQ(s.size(), strlen(large));
EXPECT_GT(s.capacity(), String::kSSOCapacity); EXPECT_GT(s.capacity(), String::kSSOCapacity);
EXPECT_TRUE(s.eq(large)); EXPECT_TRUE(s.equals(large));
EXPECT_TRUE(s.eq(large, strlen(large))); EXPECT_TRUE(s.equals(large, strlen(large)));
const char* additional = " (additional content)"; const char* additional = " (additional content)";
EXPECT_TRUE(s.isLargeOrExternal()); EXPECT_TRUE(s.isLargeOrExternal());
@@ -543,10 +543,10 @@ UNIT(core_string) {
EXPECT_TRUE(s.isLargeOrExternal()); // Clear should never release the memory. EXPECT_TRUE(s.isLargeOrExternal()); // Clear should never release the memory.
EXPECT_EQ(s.appendUInt(1234), kErrorOk); EXPECT_EQ(s.appendUInt(1234), kErrorOk);
EXPECT_TRUE(s.eq("1234")); EXPECT_TRUE(s.equals("1234"));
EXPECT_EQ(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate), kErrorOk); EXPECT_EQ(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate), kErrorOk);
EXPECT_TRUE(s.eq("0xFFFF")); EXPECT_TRUE(s.equals("0xFFFF"));
StringTmp<64> sTmp; StringTmp<64> sTmp;
EXPECT_TRUE(sTmp.isLargeOrExternal()); EXPECT_TRUE(sTmp.isLargeOrExternal());

View File

@@ -53,9 +53,12 @@ union FixedString {
//! \name Utilities //! \name Utilities
//! \{ //! \{
inline bool eq(const char* other) const noexcept { inline bool equals(const char* other) const noexcept { return strcmp(str, other) == 0; }
return strcmp(str, other) == 0;
} #if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("Use FixedString::equals() instead")
inline bool eq(const char* other) const noexcept { return equals(other); }
#endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}
}; };
@@ -158,11 +161,11 @@ public:
return *this; return *this;
} }
ASMJIT_INLINE_NODEBUG bool operator==(const char* other) const noexcept { return eq(other); } ASMJIT_INLINE_NODEBUG bool operator==(const char* other) const noexcept { return equals(other); }
ASMJIT_INLINE_NODEBUG bool operator!=(const char* other) const noexcept { return !eq(other); } ASMJIT_INLINE_NODEBUG bool operator!=(const char* other) const noexcept { return !equals(other); }
ASMJIT_INLINE_NODEBUG bool operator==(const String& other) const noexcept { return eq(other); } ASMJIT_INLINE_NODEBUG bool operator==(const String& other) const noexcept { return equals(other); }
ASMJIT_INLINE_NODEBUG bool operator!=(const String& other) const noexcept { return !eq(other); } ASMJIT_INLINE_NODEBUG bool operator!=(const String& other) const noexcept { return !equals(other); }
//! \} //! \}
@@ -312,8 +315,16 @@ public:
//! Truncate the string length into `newSize`. //! Truncate the string length into `newSize`.
ASMJIT_API Error truncate(size_t newSize) noexcept; ASMJIT_API Error truncate(size_t newSize) noexcept;
ASMJIT_API bool eq(const char* other, size_t size = SIZE_MAX) const noexcept; ASMJIT_API bool equals(const char* other, size_t size = SIZE_MAX) const noexcept;
ASMJIT_INLINE_NODEBUG bool eq(const String& other) const noexcept { return eq(other.data(), other.size()); } ASMJIT_INLINE_NODEBUG bool equals(const String& other) const noexcept { return equals(other.data(), other.size()); }
#if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("Use String::equals() instead")
ASMJIT_INLINE_NODEBUG bool eq(const char* other, size_t size = SIZE_MAX) const noexcept { return equals(other, size); }
ASMJIT_DEPRECATED("Use String::equals() instead")
ASMJIT_INLINE_NODEBUG bool eq(const String& other) const noexcept { return equals(other.data(), other.size()); }
#endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}

View File

@@ -493,8 +493,8 @@ public:
//! \name Overloaded Operators //! \name Overloaded Operators
//! \{ //! \{
ASMJIT_INLINE_NODEBUG bool operator==(const ZoneBitVector& other) const noexcept { return eq(other); } ASMJIT_INLINE_NODEBUG bool operator==(const ZoneBitVector& other) const noexcept { return equals(other); }
ASMJIT_INLINE_NODEBUG bool operator!=(const ZoneBitVector& other) const noexcept { return !eq(other); } ASMJIT_INLINE_NODEBUG bool operator!=(const ZoneBitVector& other) const noexcept { return !equals(other); }
//! \} //! \}
@@ -661,7 +661,7 @@ public:
_data[idx] &= (BitWord(1) << bit) - 1u; _data[idx] &= (BitWord(1) << bit) - 1u;
} }
ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept { ASMJIT_FORCE_INLINE bool equals(const ZoneBitVector& other) const noexcept {
if (_size != other._size) if (_size != other._size)
return false; return false;
@@ -675,6 +675,11 @@ public:
return true; return true;
} }
#if !defined(ASMJIT_NO_DEPRECATED)
ASMJIT_DEPRECATED("Use ZoneVector::equals() instead")
ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept { return equals(other); }
#endif // !ASMJIT_NO_DEPRECATED
//! \} //! \}
//! \name Memory Management //! \name Memory Management

View File

@@ -365,7 +365,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! //!
//! // Create/initialize FuncDetail and FuncFrame. //! // Create/initialize FuncDetail and FuncFrame.
//! FuncDetail func; //! FuncDetail func;
//! func.init(FuncSignature::build<void, int*, const int*, const int*>(CallConvId::kHost)); //! func.init(FuncSignature::build<void, int*, const int*, const int*>());
//! //!
//! FuncFrame frame; //! FuncFrame frame;
//! frame.init(func); //! frame.init(func);

View File

@@ -61,7 +61,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! //!
//! // Create and initialize `FuncDetail`. //! // Create and initialize `FuncDetail`.
//! FuncDetail func; //! FuncDetail func;
//! func.init(FuncSignature::build<void, int*, const int*, const int*>(CallConvId::kHost)); //! func.init(FuncSignature::build<void, int*, const int*, const int*>());
//! //!
//! // Remember prolog insertion point. //! // Remember prolog insertion point.
//! BaseNode* prologInsertionPoint = cb.cursor(); //! BaseNode* prologInsertionPoint = cb.cursor();

View File

@@ -414,7 +414,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! using namespace asmjit; //! using namespace asmjit;
//! //!
//! static void exampleUseOfIndirectJump(x86::Compiler& cc) { //! static void exampleUseOfIndirectJump(x86::Compiler& cc) {
//! FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float, uint32_t>(CallConvId::kHost)); //! FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float, uint32_t>());
//! //!
//! // Function arguments //! // Function arguments
//! x86::Xmm a = cc.newXmmSs("a"); //! x86::Xmm a = cc.newXmmSs("a");

View File

@@ -98,8 +98,10 @@ int TestApp::run() {
stringLogger.setOptions(formatOptions); stringLogger.setOptions(formatOptions);
auto printStringLoggerContent = [&]() { auto printStringLoggerContent = [&]() {
if (!_verbose) if (!_verbose) {
printf("%s", stringLogger.data()); printf("%s", stringLogger.data());
fflush(stdout);
}
}; };
#else #else
auto printStringLoggerContent = [&]() {}; auto printStringLoggerContent = [&]() {};
@@ -202,6 +204,7 @@ int TestApp::run() {
if (pass != 0) { if (pass != 0) {
printf("[Test:%s] %s", asmjitArchAsString(test->arch()), test->name()); printf("[Test:%s] %s", asmjitArchAsString(test->arch()), test->name());
fflush(stdout);
#ifndef ASMJIT_NO_LOGGING #ifndef ASMJIT_NO_LOGGING
if (_verbose || _dumpAsm || _dumpHex) { if (_verbose || _dumpAsm || _dumpHex) {

View File

@@ -423,7 +423,7 @@ public:
cc.mov(fn, (uint64_t)calledFunc); cc.mov(fn, (uint64_t)calledFunc);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, fn, FuncSignature::build<uint32_t, uint32_t, uint32_t>(CallConvId::kHost)); cc.invoke(&invokeNode, fn, FuncSignature::build<uint32_t, uint32_t, uint32_t>());
invokeNode->setArg(0, x); invokeNode->setArg(0, x);
invokeNode->setArg(1, y); invokeNode->setArg(1, y);
invokeNode->setRet(0, r); invokeNode->setRet(0, r);
@@ -475,7 +475,7 @@ public:
cc.mov(fn, (uint64_t)calledFunc); cc.mov(fn, (uint64_t)calledFunc);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, fn, FuncSignature::build<double, double, double>(CallConvId::kHost)); cc.invoke(&invokeNode, fn, FuncSignature::build<double, double, double>());
invokeNode->setArg(0, x); invokeNode->setArg(0, x);
invokeNode->setArg(1, y); invokeNode->setArg(1, y);
invokeNode->setRet(0, r); invokeNode->setRet(0, r);
@@ -527,7 +527,7 @@ public:
cc.mov(fn, (uint64_t)calledFunc); cc.mov(fn, (uint64_t)calledFunc);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, fn, FuncSignature::build<double, double, double>(CallConvId::kHost)); cc.invoke(&invokeNode, fn, FuncSignature::build<double, double, double>());
invokeNode->setArg(0, y); invokeNode->setArg(0, y);
invokeNode->setArg(1, x); invokeNode->setArg(1, x);
invokeNode->setRet(0, r); invokeNode->setRet(0, r);

View File

@@ -67,7 +67,7 @@ public:
uint32_t i; uint32_t i;
uint32_t argCount = _argCount; uint32_t argCount = _argCount;
FuncSignature signature(CallConvId::kHost); FuncSignature signature(CallConvId::kCDecl);
signature.setRetT<int>(); signature.setRetT<int>();
for (i = 0; i < argCount; i++) for (i = 0; i < argCount; i++)
signature.addArgT<int>(); signature.addArgT<int>();
@@ -223,7 +223,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
cc.endFunc(); cc.endFunc();
} }
@@ -250,7 +250,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
cc.align(AlignMode::kCode, 0); cc.align(AlignMode::kCode, 0);
cc.align(AlignMode::kCode, 1); cc.align(AlignMode::kCode, 1);
cc.endFunc(); cc.endFunc();
@@ -279,7 +279,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* func = cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); FuncNode* func = cc.addFunc(FuncSignature::build<void>());
func->addAttributes(FuncAttributes::kIndirectBranchProtection); func->addAttributes(FuncAttributes::kIndirectBranchProtection);
cc.endFunc(); cc.endFunc();
} }
@@ -316,7 +316,7 @@ public:
x86::Gp dst = cc.newIntPtr("dst"); x86::Gp dst = cc.newIntPtr("dst");
x86::Gp val = cc.newInt32("val"); x86::Gp val = cc.newInt32("val");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, val); funcNode->setArg(1, val);
@@ -372,7 +372,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
Label L1 = cc.newLabel(); Label L1 = cc.newLabel();
Label L2 = cc.newLabel(); Label L2 = cc.newLabel();
@@ -413,7 +413,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
for (uint32_t i = 0; i < 1000; i++) { for (uint32_t i = 0; i < 1000; i++) {
Label L = cc.newLabel(); Label L = cc.newLabel();
cc.jmp(L); cc.jmp(L);
@@ -453,7 +453,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
Label L_1 = cc.newLabel(); Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel(); Label L_2 = cc.newLabel();
@@ -515,7 +515,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
Label L_1 = cc.newLabel(); Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel(); Label L_2 = cc.newLabel();
@@ -588,7 +588,7 @@ public:
Label L_Div = cc.newLabel(); Label L_Div = cc.newLabel();
Label L_End = cc.newLabel(); Label L_End = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float, uint32_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float, uint32_t>());
funcNode->setArg(0, a); funcNode->setArg(0, a);
funcNode->setArg(1, b); funcNode->setArg(1, b);
funcNode->setArg(2, op); funcNode->setArg(2, op);
@@ -689,7 +689,7 @@ public:
Label L_Case1 = cc.newLabel(); Label L_Case1 = cc.newLabel();
Label L_End = cc.newLabel(); Label L_End = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>());
funcNode->setArg(0, value); funcNode->setArg(0, value);
cc.bind(L_Begin); cc.bind(L_Begin);
@@ -759,7 +759,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
Label L_Target = cc.newLabel(); Label L_Target = cc.newLabel();
x86::Gp target = cc.newUIntPtr("target"); x86::Gp target = cc.newUIntPtr("target");
@@ -807,7 +807,7 @@ public:
x86::Gp result = cc.newUInt32("result"); x86::Gp result = cc.newUInt32("result");
x86::Gp condition = cc.newUInt32("condition"); x86::Gp condition = cc.newUInt32("condition");
FuncNode* func = cc.addFunc(FuncSignature::build<int, int>(CallConvId::kHost)); FuncNode* func = cc.addFunc(FuncSignature::build<int, int>());
func->setArg(0, condition); func->setArg(0, condition);
Label L_NonZero = cc.newLabel(); Label L_NonZero = cc.newLabel();
@@ -878,7 +878,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
x86::Gp v0 = cc.newInt32("v0"); x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1"); x86::Gp v1 = cc.newInt32("v1");
@@ -933,7 +933,7 @@ public:
x86::Gp a0 = cc.newIntPtr("a0"); x86::Gp a0 = cc.newIntPtr("a0");
x86::Gp a1 = cc.newIntPtr("a1"); x86::Gp a1 = cc.newIntPtr("a1");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int*>());
funcNode->setArg(0, a0); funcNode->setArg(0, a0);
funcNode->setArg(1, a1); funcNode->setArg(1, a1);
@@ -1001,7 +1001,7 @@ public:
x86::Gp a = cc.newIntPtr("a"); x86::Gp a = cc.newIntPtr("a");
x86::Gp v[32]; x86::Gp v[32];
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, uint32_t*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, uint32_t*>());
funcNode->setArg(0, a); funcNode->setArg(0, a);
for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i); for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i);
@@ -1066,7 +1066,7 @@ public:
x86::Gp vLo = cc.newInt32("vLo"); x86::Gp vLo = cc.newInt32("vLo");
x86::Gp src = cc.newInt32("src"); x86::Gp src = cc.newInt32("src");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int*, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int*, int, int>());
funcNode->setArg(0, dstHi); funcNode->setArg(0, dstHi);
funcNode->setArg(1, dstLo); funcNode->setArg(1, dstLo);
funcNode->setArg(2, vLo); funcNode->setArg(2, vLo);
@@ -1115,7 +1115,7 @@ public:
x86::Gp dst = cc.newIntPtr("dst"); x86::Gp dst = cc.newIntPtr("dst");
x86::Gp src = cc.newIntPtr("src"); x86::Gp src = cc.newIntPtr("src");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, const int*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, const int*>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, src); funcNode->setArg(1, src);
@@ -1168,7 +1168,7 @@ public:
x86::Gp b = cc.newInt32("b"); x86::Gp b = cc.newInt32("b");
x86::Gp dummy = cc.newInt32("dummy"); x86::Gp dummy = cc.newInt32("dummy");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
funcNode->setArg(0, a); funcNode->setArg(0, a);
funcNode->setArg(1, b); funcNode->setArg(1, b);
@@ -1212,7 +1212,7 @@ public:
x86::Gp src1 = cc.newInt32("src1"); x86::Gp src1 = cc.newInt32("src1");
x86::Gp dst0 = cc.newIntPtr("dst0"); x86::Gp dst0 = cc.newIntPtr("dst0");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int, int, char*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int, int, char*>());
funcNode->setArg(0, src0); funcNode->setArg(0, src0);
funcNode->setArg(1, src1); funcNode->setArg(1, src1);
funcNode->setArg(2, dst0); funcNode->setArg(2, dst0);
@@ -1262,7 +1262,7 @@ public:
x86::Gp vShlParam = cc.newInt32("vShlParam"); x86::Gp vShlParam = cc.newInt32("vShlParam");
x86::Gp vRorParam = cc.newInt32("vRorParam"); x86::Gp vRorParam = cc.newInt32("vRorParam");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, int*, int, int, int>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, var); funcNode->setArg(1, var);
funcNode->setArg(2, vShlParam); funcNode->setArg(2, vShlParam);
@@ -1310,7 +1310,7 @@ public:
x86::Gp rSum = cc.newUInt32("rSum"); x86::Gp rSum = cc.newUInt32("rSum");
x86::Gp x[kCount]; x86::Gp x[kCount];
FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t*>());
funcNode->setArg(0, rPtr); funcNode->setArg(0, rPtr);
for (uint32_t i = 0; i < kCount; i++) { for (uint32_t i = 0; i < kCount; i++) {
@@ -1391,7 +1391,7 @@ public:
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
x86::Gp v = cc.newUInt32("v"); x86::Gp v = cc.newUInt32("v");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t>());
funcNode->setArg(0, v); funcNode->setArg(0, v);
cc.mov(v.r8(), 0xFF); cc.mov(v.r8(), 0xFF);
@@ -1429,7 +1429,7 @@ public:
x86::Gp src = cc.newIntPtr("src"); x86::Gp src = cc.newIntPtr("src");
x86::Gp cnt = cc.newIntPtr("cnt"); x86::Gp cnt = cc.newIntPtr("cnt");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, void*, size_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, void*, size_t>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, src); funcNode->setArg(1, src);
funcNode->setArg(2, cnt); funcNode->setArg(2, cnt);
@@ -1471,7 +1471,7 @@ public:
Label L_1 = cc.newLabel(); Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel(); Label L_2 = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
funcNode->setArg(0, v1); funcNode->setArg(0, v1);
funcNode->setArg(1, v2); funcNode->setArg(1, v2);
@@ -1523,7 +1523,7 @@ public:
Label L_3 = cc.newLabel(); Label L_3 = cc.newLabel();
Label L_4 = cc.newLabel(); Label L_4 = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
funcNode->setArg(0, v1); funcNode->setArg(0, v1);
funcNode->setArg(1, v2); funcNode->setArg(1, v2);
@@ -1582,7 +1582,7 @@ public:
Label L_Loop = cc.newLabel(); Label L_Loop = cc.newLabel();
Label L_Exit = cc.newLabel(); Label L_Exit = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
funcNode->setArg(0, v1); funcNode->setArg(0, v1);
funcNode->setArg(1, v2); funcNode->setArg(1, v2);
@@ -1642,7 +1642,7 @@ public:
Label L_Loop2 = cc.newLabel(); Label L_Loop2 = cc.newLabel();
Label L_Exit = cc.newLabel(); Label L_Exit = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
funcNode->setArg(0, v1); funcNode->setArg(0, v1);
funcNode->setArg(1, v2); funcNode->setArg(1, v2);
@@ -1699,7 +1699,7 @@ public:
x86::Gp x = cc.newInt8("x"); x86::Gp x = cc.newInt8("x");
x86::Gp y = cc.newInt32("y"); x86::Gp y = cc.newInt32("y");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int8_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int8_t>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
cc.movsx(y, x); cc.movsx(y, x);
@@ -1736,7 +1736,7 @@ public:
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
x86::Gp x = cc.newInt32("x"); x86::Gp x = cc.newInt32("x");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
funcNode->setArg(2, x); funcNode->setArg(2, x);
cc.ret(x); cc.ret(x);
@@ -1769,7 +1769,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, void*, void*, void*, void*, void*, void*, void*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, void*, void*, void*, void*, void*, void*, void*>());
x86::Gp var[8]; x86::Gp var[8];
for (uint32_t i = 0; i < 8; i++) { for (uint32_t i = 0; i < 8; i++) {
@@ -1825,7 +1825,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, float, float, float, float, float, float, float, void*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, float, float, float, float, float, float, float, void*>());
x86::Gp p = cc.newIntPtr("p"); x86::Gp p = cc.newIntPtr("p");
x86::Xmm xv[7]; x86::Xmm xv[7];
@@ -1876,7 +1876,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, double, double, double, double, double, double, double, void*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, double, double, double, double, double, double, double, void*>());
x86::Gp p = cc.newIntPtr("p"); x86::Gp p = cc.newIntPtr("p");
x86::Xmm xv[7]; x86::Xmm xv[7];
@@ -1936,7 +1936,7 @@ public:
x86::Xmm a = cc.newXmm("aXmm"); x86::Xmm a = cc.newXmm("aXmm");
x86::Xmm b = cc.newXmm("bXmm"); x86::Xmm b = cc.newXmm("bXmm");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<x86::Xmm, x86::Xmm, x86::Xmm>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<x86::Xmm, x86::Xmm, x86::Xmm>());
funcNode->setArg(0, a); funcNode->setArg(0, a);
funcNode->setArg(1, b); funcNode->setArg(1, b);
@@ -1984,7 +1984,7 @@ public:
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
x86::Xmm x = cc.newXmmSs("x"); x86::Xmm x = cc.newXmmSs("x");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
cc.ret(x); cc.ret(x);
@@ -2020,7 +2020,7 @@ public:
x86::Xmm x = cc.newXmmSs("x"); x86::Xmm x = cc.newXmmSs("x");
x86::Xmm y = cc.newXmmSs("y"); x86::Xmm y = cc.newXmmSs("y");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
funcNode->setArg(1, y); funcNode->setArg(1, y);
@@ -2058,7 +2058,7 @@ public:
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
x86::Xmm x = cc.newXmmSd("x"); x86::Xmm x = cc.newXmmSd("x");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
cc.ret(x); cc.ret(x);
@@ -2094,7 +2094,7 @@ public:
x86::Xmm x = cc.newXmmSd("x"); x86::Xmm x = cc.newXmmSd("x");
x86::Xmm y = cc.newXmmSd("y"); x86::Xmm y = cc.newXmmSd("y");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
funcNode->setArg(1, y); funcNode->setArg(1, y);
@@ -2132,7 +2132,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
x86::Mem stack = cc.newStack(kSize, 1); x86::Mem stack = cc.newStack(kSize, 1);
stack.setSize(1); stack.setSize(1);
@@ -2206,7 +2206,7 @@ public:
Label L_Loop = cc.newLabel(); // Create base labels we use Label L_Loop = cc.newLabel(); // Create base labels we use
Label L_Exit = cc.newLabel(); // in our function. Label L_Exit = cc.newLabel(); // in our function.
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, uint32_t*, const uint32_t*, size_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, uint32_t*, const uint32_t*, size_t>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, src); funcNode->setArg(1, src);
funcNode->setArg(2, cnt); funcNode->setArg(2, cnt);
@@ -2283,7 +2283,7 @@ public:
x86::Gp a = cc.newInt32("a"); x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b"); x86::Gp b = cc.newInt32("b");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
funcNode->setArg(0, cond); funcNode->setArg(0, cond);
funcNode->setArg(1, a); funcNode->setArg(1, a);
funcNode->setArg(2, b); funcNode->setArg(2, b);
@@ -2422,7 +2422,7 @@ public:
x86::Gp v1 = cc.newInt32("v1"); x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2"); x86::Gp v2 = cc.newInt32("v2");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
funcNode->setArg(0, v0); funcNode->setArg(0, v0);
funcNode->setArg(1, v1); funcNode->setArg(1, v1);
funcNode->setArg(2, v2); funcNode->setArg(2, v2);
@@ -2434,7 +2434,7 @@ public:
// Call a function. // Call a function.
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<int, int, int, int>(CallConvId::kHost)); cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<int, int, int, int>());
invokeNode->setArg(0, v2); invokeNode->setArg(0, v2);
invokeNode->setArg(1, v1); invokeNode->setArg(1, v1);
invokeNode->setArg(2, v0); invokeNode->setArg(2, v0);
@@ -2474,7 +2474,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
const int kTokenSize = 32; const int kTokenSize = 32;
@@ -2494,19 +2494,19 @@ public:
cc.lea(p2, s2); cc.lea(p2, s2);
// Try to corrupt the stack if wrongly allocated. // Try to corrupt the stack if wrongly allocated.
cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignature::build<void*, void*, void*, size_t>(CallConvId::kCDecl)); cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignature::build<void*, void*, void*, size_t>());
invokeNode->setArg(0, p1); invokeNode->setArg(0, p1);
invokeNode->setArg(1, imm(token)); invokeNode->setArg(1, imm(token));
invokeNode->setArg(2, imm(kTokenSize)); invokeNode->setArg(2, imm(kTokenSize));
invokeNode->setRet(0, p1); invokeNode->setRet(0, p1);
cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignature::build<void*, void*, void*, size_t>(CallConvId::kCDecl)); cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignature::build<void*, void*, void*, size_t>());
invokeNode->setArg(0, p2); invokeNode->setArg(0, p2);
invokeNode->setArg(1, imm(token)); invokeNode->setArg(1, imm(token));
invokeNode->setArg(2, imm(kTokenSize)); invokeNode->setArg(2, imm(kTokenSize));
invokeNode->setRet(0, p2); invokeNode->setRet(0, p2);
cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignature::build<int, void*, void*, size_t>(CallConvId::kCDecl)); cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignature::build<int, void*, void*, size_t>());
invokeNode->setArg(0, p1); invokeNode->setArg(0, p1);
invokeNode->setArg(1, p2); invokeNode->setArg(1, p2);
invokeNode->setArg(2, imm(kTokenSize)); invokeNode->setArg(2, imm(kTokenSize));
@@ -2557,7 +2557,7 @@ public:
x86::Gp y = cc.newInt32("y"); x86::Gp y = cc.newInt32("y");
x86::Gp z = cc.newInt32("z"); x86::Gp z = cc.newInt32("z");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
funcNode->setArg(1, y); funcNode->setArg(1, y);
funcNode->setArg(2, z); funcNode->setArg(2, z);
@@ -2608,7 +2608,7 @@ public:
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
x86::Gp var = cc.newInt32("var"); x86::Gp var = cc.newInt32("var");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>());
funcNode->setArg(0, var); funcNode->setArg(0, var);
InvokeNode* invokeNode; InvokeNode* invokeNode;
@@ -2666,7 +2666,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, const void*, const void*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, const void*, const void*>());
x86::Gp resultPtr = cc.newIntPtr("resultPtr"); x86::Gp resultPtr = cc.newIntPtr("resultPtr");
x86::Gp aPtr = cc.newIntPtr("aPtr"); x86::Gp aPtr = cc.newIntPtr("aPtr");
@@ -2748,7 +2748,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncSignature f1Sig = FuncSignature::build<void, const void*, const void*, const void*, const void*, void*>(CallConvId::kCDecl); FuncSignature f1Sig = FuncSignature::build<void, const void*, const void*, const void*, const void*, void*>();
FuncSignature f2Sig = FuncSignature::build<x86::Xmm, x86::Xmm, x86::Xmm>(CallConvId::kLightCall2); FuncSignature f2Sig = FuncSignature::build<x86::Xmm, x86::Xmm, x86::Xmm>(CallConvId::kLightCall2);
FuncNode* f1Node = cc.newFunc(f1Sig); FuncNode* f1Node = cc.newFunc(f1Sig);
@@ -2850,7 +2850,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
// Prepare. // Prepare.
x86::Gp va = cc.newInt32("va"); x86::Gp va = cc.newInt32("va");
@@ -2879,7 +2879,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost)); FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>());
invokeNode->setArg(0, va); invokeNode->setArg(0, va);
invokeNode->setArg(1, vb); invokeNode->setArg(1, vb);
invokeNode->setArg(2, vc); invokeNode->setArg(2, vc);
@@ -2926,7 +2926,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
// Prepare. // Prepare.
x86::Gp a = cc.newInt32("a"); x86::Gp a = cc.newInt32("a");
@@ -2936,7 +2936,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost)); FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>());
invokeNode->setArg(0, a); invokeNode->setArg(0, a);
invokeNode->setArg(1, a); invokeNode->setArg(1, a);
invokeNode->setArg(2, a); invokeNode->setArg(2, a);
@@ -2979,7 +2979,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
// Prepare. // Prepare.
x86::Gp rv = cc.newInt32("rv"); x86::Gp rv = cc.newInt32("rv");
@@ -2988,7 +2988,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)X86Test_FuncCallManyArgs::calledFunc), imm((void*)X86Test_FuncCallManyArgs::calledFunc),
FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost)); FuncSignature::build<int, int, int, int, int, int, int, int, int, int, int>());
invokeNode->setArg(0, imm(0x03)); invokeNode->setArg(0, imm(0x03));
invokeNode->setArg(1, imm(0x12)); invokeNode->setArg(1, imm(0x12));
@@ -3045,7 +3045,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
// Prepare. // Prepare.
x86::Gp rv = cc.newInt32("rv"); x86::Gp rv = cc.newInt32("rv");
@@ -3054,7 +3054,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConvId::kHost)); FuncSignature::build<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>());
invokeNode->setArg(0, imm(0x01)); invokeNode->setArg(0, imm(0x01));
invokeNode->setArg(1, imm(0x02)); invokeNode->setArg(1, imm(0x02));
@@ -3106,7 +3106,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int&, int&, int&, int&>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int&, int&, int&, int&>());
// Prepare. // Prepare.
x86::Gp arg1 = cc.newInt32(); x86::Gp arg1 = cc.newInt32();
@@ -3124,7 +3124,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<int, int&, int&, int&, int&>(CallConvId::kHost)); FuncSignature::build<int, int&, int&, int&, int&>());
invokeNode->setArg(0, arg1); invokeNode->setArg(0, arg1);
invokeNode->setArg(1, arg2); invokeNode->setArg(1, arg2);
@@ -3168,7 +3168,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<float, float, float>());
x86::Xmm a = cc.newXmmSs("a"); x86::Xmm a = cc.newXmmSs("a");
x86::Xmm b = cc.newXmmSs("b"); x86::Xmm b = cc.newXmmSs("b");
@@ -3179,7 +3179,7 @@ public:
// Call function. // Call function.
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<float, float, float>(CallConvId::kHost)); cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<float, float, float>());
invokeNode->setArg(0, a); invokeNode->setArg(0, a);
invokeNode->setArg(1, b); invokeNode->setArg(1, b);
invokeNode->setRet(0, ret); invokeNode->setRet(0, ret);
@@ -3218,7 +3218,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double>());
x86::Xmm a = cc.newXmmSd("a"); x86::Xmm a = cc.newXmmSd("a");
x86::Xmm b = cc.newXmmSd("b"); x86::Xmm b = cc.newXmmSd("b");
@@ -3228,7 +3228,7 @@ public:
funcNode->setArg(1, b); funcNode->setArg(1, b);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<double, double, double>(CallConvId::kHost)); cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<double, double, double>());
invokeNode->setArg(0, a); invokeNode->setArg(0, a);
invokeNode->setArg(1, b); invokeNode->setArg(1, b);
invokeNode->setRet(0, ret); invokeNode->setRet(0, ret);
@@ -3270,7 +3270,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
x86::Gp result; x86::Gp result;
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
funcNode->setArg(0, x); funcNode->setArg(0, x);
funcNode->setArg(1, y); funcNode->setArg(1, y);
funcNode->setArg(2, op); funcNode->setArg(2, op);
@@ -3290,7 +3290,7 @@ public:
cc.bind(opAdd); cc.bind(opAdd);
result = cc.newInt32("result_1"); result = cc.newInt32("result_1");
cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignature::build<int, int, int>(CallConvId::kHost)); cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignature::build<int, int, int>());
invokeNode->setArg(0, x); invokeNode->setArg(0, x);
invokeNode->setArg(1, y); invokeNode->setArg(1, y);
invokeNode->setRet(0, result); invokeNode->setRet(0, result);
@@ -3299,7 +3299,7 @@ public:
cc.bind(opMul); cc.bind(opMul);
result = cc.newInt32("result_2"); result = cc.newInt32("result_2");
cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignature::build<int, int, int>(CallConvId::kHost)); cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignature::build<int, int, int>());
invokeNode->setArg(0, x); invokeNode->setArg(0, x);
invokeNode->setArg(1, y); invokeNode->setArg(1, y);
invokeNode->setRet(0, result); invokeNode->setRet(0, result);
@@ -3353,7 +3353,7 @@ public:
x86::Gp acc0 = cc.newInt32("acc0"); x86::Gp acc0 = cc.newInt32("acc0");
x86::Gp acc1 = cc.newInt32("acc1"); x86::Gp acc1 = cc.newInt32("acc1");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int*>());
funcNode->setArg(0, buf); funcNode->setArg(0, buf);
cc.mov(acc0, 0); cc.mov(acc0, 0);
@@ -3422,7 +3422,7 @@ public:
x86::Gp val = cc.newInt32("val"); x86::Gp val = cc.newInt32("val");
Label skip = cc.newLabel(); Label skip = cc.newLabel();
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int>());
funcNode->setArg(0, val); funcNode->setArg(0, val);
cc.cmp(val, 1); cc.cmp(val, 1);
@@ -3434,7 +3434,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, funcNode->label(), FuncSignature::build<int, int>(CallConvId::kHost)); cc.invoke(&invokeNode, funcNode->label(), FuncSignature::build<int, int>());
invokeNode->setArg(0, tmp); invokeNode->setArg(0, tmp);
invokeNode->setRet(0, tmp); invokeNode->setRet(0, tmp);
cc.mul(cc.newInt32(), val, tmp); cc.mul(cc.newInt32(), val, tmp);
@@ -3470,7 +3470,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int, int>());
x86::Gp a0 = cc.newInt32("a0"); x86::Gp a0 = cc.newInt32("a0");
x86::Gp a1 = cc.newInt32("a1"); x86::Gp a1 = cc.newInt32("a1");
@@ -3488,7 +3488,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<int, size_t, int, int, int, int>(CallConvId::kHost, 1)); FuncSignature::build<int, size_t, int, int, int, int>(CallConvId::kCDecl, 1));
invokeNode->setArg(0, imm(4)); invokeNode->setArg(0, imm(4));
invokeNode->setArg(1, a0); invokeNode->setArg(1, a0);
invokeNode->setArg(2, a1); invokeNode->setArg(2, a1);
@@ -3538,7 +3538,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double, double, double>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, double, double, double, double>());
x86::Xmm a0 = cc.newXmmSd("a0"); x86::Xmm a0 = cc.newXmmSd("a0");
x86::Xmm a1 = cc.newXmmSd("a1"); x86::Xmm a1 = cc.newXmmSd("a1");
@@ -3556,7 +3556,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)calledFunc), imm((void*)calledFunc),
FuncSignature::build<double, size_t, double, double, double, double>(CallConvId::kHost, 1)); FuncSignature::build<double, size_t, double, double, double, double>(CallConvId::kCDecl, 1));
invokeNode->setArg(0, imm(4)); invokeNode->setArg(0, imm(4));
invokeNode->setArg(1, a0); invokeNode->setArg(1, a0);
invokeNode->setArg(2, a1); invokeNode->setArg(2, a1);
@@ -3606,7 +3606,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint64_t, uint64_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint64_t, uint64_t>());
if (cc.is64Bit()) { if (cc.is64Bit()) {
x86::Gp reg = cc.newUInt64(); x86::Gp reg = cc.newUInt64();
@@ -3669,7 +3669,7 @@ public:
static void dummy(int, int) {} static void dummy(int, int) {}
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int>());
x86::Gp a = cc.newInt32("a"); x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b"); x86::Gp b = cc.newInt32("b");
@@ -3681,7 +3681,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)dummy), imm((void*)dummy),
FuncSignature::build<void, int, int>(CallConvId::kHost)); FuncSignature::build<void, int, int>());
invokeNode->setArg(0, a); invokeNode->setArg(0, a);
invokeNode->setArg(1, b); invokeNode->setArg(1, b);
@@ -3717,7 +3717,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, const double*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, const double*>());
x86::Gp p = cc.newIntPtr("p"); x86::Gp p = cc.newIntPtr("p");
x86::Xmm arg = cc.newXmmSd("arg"); x86::Xmm arg = cc.newXmmSd("arg");
@@ -3729,7 +3729,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)op), imm((void*)op),
FuncSignature::build<double, double>(CallConvId::kHost)); FuncSignature::build<double, double>());
invokeNode->setArg(0, arg); invokeNode->setArg(0, arg);
invokeNode->setRet(0, ret); invokeNode->setRet(0, ret);
@@ -3767,7 +3767,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, const double*>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<double, const double*>());
x86::Gp p = cc.newIntPtr("p"); x86::Gp p = cc.newIntPtr("p");
x86::Xmm arg = cc.newXmmSd("arg"); x86::Xmm arg = cc.newXmmSd("arg");
@@ -3779,7 +3779,7 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, cc.invoke(&invokeNode,
imm((void*)op), imm((void*)op),
FuncSignature::build<double, double>(CallConvId::kHost)); FuncSignature::build<double, double>());
invokeNode->setArg(0, arg); invokeNode->setArg(0, arg);
invokeNode->setRet(0, ret); invokeNode->setRet(0, ret);
@@ -3823,12 +3823,12 @@ public:
InvokeNode* invokeNode; InvokeNode* invokeNode;
FuncSignature funcSignature; FuncSignature funcSignature;
funcSignature.setCallConvId(CallConvId::kHost); funcSignature.setCallConvId(CallConvId::kCDecl);
funcSignature.setRet(TypeId::kFloat64); funcSignature.setRet(TypeId::kFloat64);
cc.addFunc(funcSignature); cc.addFunc(funcSignature);
FuncSignature invokeSignature; FuncSignature invokeSignature;
invokeSignature.setCallConvId(CallConvId::kHost); invokeSignature.setCallConvId(CallConvId::kCDecl);
invokeSignature.setRet(TypeId::kFloat64); invokeSignature.setRet(TypeId::kFloat64);
cc.invoke(&invokeNode, imm((void*)calledFunc), invokeSignature); cc.invoke(&invokeNode, imm((void*)calledFunc), invokeSignature);
@@ -3868,7 +3868,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
x86::Gp pFn = cc.newIntPtr("pFn"); x86::Gp pFn = cc.newIntPtr("pFn");
x86::Gp vars[16]; x86::Gp vars[16];
@@ -3887,7 +3887,7 @@ public:
} }
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, pFn, FuncSignature::build<void>(CallConvId::kHost)); cc.invoke(&invokeNode, pFn, FuncSignature::build<void>());
for (i = 1; i < regCount; i++) for (i = 1; i < regCount; i++)
if (vars[i].isValid()) if (vars[i].isValid())
@@ -3925,7 +3925,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<uint32_t, uint32_t>());
constexpr uint32_t kCount = 16; constexpr uint32_t kCount = 16;
@@ -3941,7 +3941,7 @@ public:
v[i] = cc.newUInt32("v%u", i); v[i] = cc.newUInt32("v%u", i);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<uint32_t, uint32_t>(CallConvId::kHost)); cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignature::build<uint32_t, uint32_t>());
invokeNode->setArg(0, argVal); invokeNode->setArg(0, argVal);
invokeNode->setRet(0, retVal); invokeNode->setRet(0, retVal);
@@ -3988,7 +3988,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* mainFunc = cc.addFunc(FuncSignature::build<void, void*, const void*, const void*>(CallConvId::kHost)); FuncNode* mainFunc = cc.addFunc(FuncSignature::build<void, void*, const void*, const void*>());
mainFunc->frame().setAvxEnabled(); mainFunc->frame().setAvxEnabled();
mainFunc->frame().setAvxCleanup(); mainFunc->frame().setAvxCleanup();
@@ -4103,7 +4103,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
x86::Gp v0 = cc.newInt32("v0"); x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1"); x86::Gp v1 = cc.newInt32("v1");
@@ -4145,7 +4145,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignature::build<int>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<int>());
x86::Gp v0 = cc.newInt32("v0"); x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1"); x86::Gp v1 = cc.newInt32("v1");
@@ -4186,7 +4186,7 @@ struct X86Test_MiscMultiRet : public X86TestCase {
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<int, int, int, int>());
x86::Gp op = cc.newInt32("op"); x86::Gp op = cc.newInt32("op");
x86::Gp a = cc.newInt32("a"); x86::Gp a = cc.newInt32("a");
@@ -4262,7 +4262,7 @@ struct X86Test_MiscMultiRet : public X86TestCase {
result.assignFormat("ret={%d %d %d %d}", r0, r1, r2, r3); result.assignFormat("ret={%d %d %d %d}", r0, r1, r2, r3);
expect.assignFormat("ret={%d %d %d %d}", e0, e1, e2, e3); expect.assignFormat("ret={%d %d %d %d}", e0, e1, e2, e3);
return result.eq(expect); return result == expect;
} }
}; };
@@ -4278,8 +4278,8 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
FuncNode* f1Node = cc.newFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* f1Node = cc.newFunc(FuncSignature::build<int, int, int>());
FuncNode* f2Node = cc.newFunc(FuncSignature::build<int, int, int>(CallConvId::kHost)); FuncNode* f2Node = cc.newFunc(FuncSignature::build<int, int, int>());
{ {
x86::Gp a = cc.newInt32("a"); x86::Gp a = cc.newInt32("a");
@@ -4290,7 +4290,7 @@ public:
f1Node->setArg(1, b); f1Node->setArg(1, b);
InvokeNode* invokeNode; InvokeNode* invokeNode;
cc.invoke(&invokeNode, f2Node->label(), FuncSignature::build<int, int, int>(CallConvId::kHost)); cc.invoke(&invokeNode, f2Node->label(), FuncSignature::build<int, int, int>());
invokeNode->setArg(0, a); invokeNode->setArg(0, a);
invokeNode->setArg(1, b); invokeNode->setArg(1, b);
invokeNode->setRet(0, a); invokeNode->setRet(0, a);
@@ -4324,7 +4324,7 @@ public:
result.assignFormat("ret=%d", resultRet); result.assignFormat("ret=%d", resultRet);
expect.assignFormat("ret=%d", expectRet); expect.assignFormat("ret=%d", expectRet);
return result.eq(expect); return result == expect;
} }
}; };

View File

@@ -34,7 +34,7 @@ static void makeRawFunc(x86::Emitter* emitter) noexcept {
// Create and initialize `FuncDetail` and `FuncFrame`. // Create and initialize `FuncDetail` and `FuncFrame`.
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, int*, const int*, const int*>(CallConvId::kHost), emitter->environment()); func.init(FuncSignature::build<void, int*, const int*, const int*>(), emitter->environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -70,7 +70,7 @@ static void makeCompiledFunc(x86::Compiler* cc) noexcept {
x86::Xmm vec0 = cc->newXmm("vec0"); x86::Xmm vec0 = cc->newXmm("vec0");
x86::Xmm vec1 = cc->newXmm("vec1"); x86::Xmm vec1 = cc->newXmm("vec1");
FuncNode* funcNode = cc->addFunc(FuncSignature::build<void, int*, const int*, const int*>(CallConvId::kHost)); FuncNode* funcNode = cc->addFunc(FuncSignature::build<void, int*, const int*, const int*>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, src_a); funcNode->setArg(1, src_a);
funcNode->setArg(2, src_b); funcNode->setArg(2, src_b);

View File

@@ -170,7 +170,7 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -202,7 +202,7 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -242,7 +242,7 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
Xmm v6 = cc.newXmm("v6"); Xmm v6 = cc.newXmm("v6");
Xmm v7 = cc.newXmm("v7"); Xmm v7 = cc.newXmm("v7");
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost)); FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*, const void*, size_t>());
funcNode->setArg(0, dst); funcNode->setArg(0, dst);
funcNode->setArg(1, src); funcNode->setArg(1, src);
funcNode->setArg(2, i); funcNode->setArg(2, i);

View File

@@ -582,7 +582,7 @@ static void generateGpSequence(BaseEmitter& emitter, bool emitPrologEpilog) {
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -608,7 +608,7 @@ static void generateGpSequence(BaseEmitter& emitter, bool emitPrologEpilog) {
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -633,7 +633,7 @@ static void generateGpSequence(BaseEmitter& emitter, bool emitPrologEpilog) {
a64::Gp c = cc.newIntPtr("c"); a64::Gp c = cc.newIntPtr("c");
a64::Gp d = cc.newIntPtr("d"); a64::Gp d = cc.newIntPtr("d");
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
generateGpSequenceInternal(cc, a, b, c, d); generateGpSequenceInternal(cc, a, b, c, d);
cc.endFunc(); cc.endFunc();
} }

View File

@@ -335,7 +335,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -361,7 +361,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -386,7 +386,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
Gp c = cc.newIntPtr("c"); Gp c = cc.newIntPtr("c");
Gp d = cc.newIntPtr("d"); Gp d = cc.newIntPtr("d");
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
generateGpSequenceInternal(cc, form, a, b, c, d); generateGpSequenceInternal(cc, form, a, b, c, d);
cc.endFunc(); cc.endFunc();
} }
@@ -927,7 +927,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -948,7 +948,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -974,7 +974,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
Xmm c = cc.newXmm("c"); Xmm c = cc.newXmm("c");
Xmm d = cc.newXmm("d"); Xmm d = cc.newXmm("d");
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
generateSseSequenceInternal(cc, form, gp, a, b, c, d); generateSseSequenceInternal(cc, form, gp, a, b, c, d);
cc.endFunc(); cc.endFunc();
} }
@@ -2134,7 +2134,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -2155,7 +2155,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -2181,7 +2181,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
Ymm c = cc.newYmm("c"); Ymm c = cc.newYmm("c");
Ymm d = cc.newYmm("d"); Ymm d = cc.newYmm("d");
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
generateAvxSequenceInternal(cc, form, gp, a, b, c, d); generateAvxSequenceInternal(cc, form, gp, a, b, c, d);
cc.endFunc(); cc.endFunc();
} }
@@ -4928,7 +4928,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -4949,7 +4949,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
if (emitPrologEpilog) { if (emitPrologEpilog) {
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment()); func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);
@@ -4979,7 +4979,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
KReg kB = cc.newKq("kB"); KReg kB = cc.newKq("kB");
KReg kC = cc.newKq("kC"); KReg kC = cc.newKq("kC");
cc.addFunc(FuncSignature::build<void>(CallConvId::kHost)); cc.addFunc(FuncSignature::build<void>());
generateAvx512SequenceInternal(cc, form, gp, kA, kB, kC, vecA, vecB, vecC, vecD); generateAvx512SequenceInternal(cc, form, gp, kA, kB, kC, vecA, vecB, vecC, vecD);
cc.endFunc(); cc.endFunc();
} }

View File

@@ -70,7 +70,7 @@ int main() {
Label data = a.newLabel(); Label data = a.newLabel();
FuncDetail func; FuncDetail func;
func.init(FuncSignature::build<size_t, size_t>(CallConvId::kHost), code.environment()); func.init(FuncSignature::build<size_t, size_t>(), code.environment());
FuncFrame frame; FuncFrame frame;
frame.init(func); frame.init(func);