mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-28 07:21:02 +00:00
Restructure backends
This commit is contained in:
5
src/backends/CMakeLists.txt
Normal file
5
src/backends/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
add_subdirectory(unicorn-emulator)
|
||||
|
||||
if (MOMO_ENABLE_RUST_CODE)
|
||||
add_subdirectory(icicle-emulator)
|
||||
endif()
|
||||
20
src/backends/icicle-emulator/CMakeLists.txt
Normal file
20
src/backends/icicle-emulator/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
add_subdirectory(icicle-bridge)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
*.hpp
|
||||
*.rc
|
||||
)
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
if(MOMO_BUILD_AS_LIBRARY)
|
||||
add_library(icicle-emulator STATIC ${SRC_FILES})
|
||||
else()
|
||||
add_library(icicle-emulator SHARED ${SRC_FILES})
|
||||
endif()
|
||||
|
||||
target_include_directories(icicle-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
target_link_libraries(icicle-emulator PUBLIC emulator)
|
||||
target_link_libraries(icicle-emulator PRIVATE emulator-common icicle-bridge)
|
||||
2
src/backends/icicle-emulator/icicle-bridge/.gitignore
vendored
Normal file
2
src/backends/icicle-emulator/icicle-bridge/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Ghidra
|
||||
65
src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt
Normal file
65
src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
include(ExternalProject)
|
||||
|
||||
set(ICICLE_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/cargo-build)
|
||||
set(ICICLE_ARTIFACT_DIR ${ICICLE_BUILD_DIR}/$<IF:$<CONFIG:Debug>,debug,release>)
|
||||
|
||||
set(ICICLE_RUST_PROJECT_NAME "icicle")
|
||||
set(ICICLE_RUST_LIBNAME "lib${ICICLE_RUST_PROJECT_NAME}.a")
|
||||
|
||||
if(MSVC)
|
||||
set(ICICLE_RUST_LIBNAME "${ICICLE_RUST_PROJECT_NAME}.lib")
|
||||
endif()
|
||||
|
||||
set(CARGO_TRIPLE)
|
||||
set(CARGO_OPTIONS)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CARGO_TRIPLE "aarch64-apple-ios")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
|
||||
set(CARGO_TRIPLE "aarch64-linux-android")
|
||||
else()
|
||||
set(CARGO_TRIPLE "${CMAKE_ANDROID_ARCH_ABI}-linux-android")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CARGO_TRIPLE)
|
||||
set(CARGO_OPTIONS ${CARGO_OPTIONS} "--target=${CARGO_TRIPLE}")
|
||||
set(ICICLE_ARTIFACT_DIR ${ICICLE_BUILD_DIR}/${CARGO_TRIPLE}/$<IF:$<CONFIG:Debug>,debug,release>)
|
||||
endif()
|
||||
|
||||
|
||||
set(ICICLE_RUST_LIB ${ICICLE_ARTIFACT_DIR}/${ICICLE_RUST_LIBNAME})
|
||||
|
||||
ExternalProject_Add(
|
||||
icicle-rust-project
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
|
||||
BINARY_DIR ${CMAKE_CURRENT_LIST_DIR}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${ICICLE_BUILD_DIR}" cargo build ${CARGO_OPTIONS} --lib --profile $<IF:$<CONFIG:Debug>,dev,release>
|
||||
INSTALL_COMMAND ""
|
||||
USES_TERMINAL_CONFIGURE 1
|
||||
USES_TERMINAL_BUILD 1
|
||||
BUILD_ALWAYS 1
|
||||
BUILD_BYPRODUCTS ${ICICLE_RUST_LIB}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET icicle-rust-project POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_LIST_DIR}/data" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
|
||||
COMMENT "Copying Ghidra Processor Specification"
|
||||
)
|
||||
|
||||
add_library(icicle-bridge INTERFACE)
|
||||
add_dependencies(icicle-bridge icicle-rust-project)
|
||||
target_link_libraries(icicle-bridge INTERFACE ${ICICLE_RUST_LIB})
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(icicle-bridge INTERFACE
|
||||
ws2_32.lib
|
||||
Userenv.lib
|
||||
ntdll.lib
|
||||
Bcrypt.lib
|
||||
)
|
||||
endif()
|
||||
960
src/backends/icicle-emulator/icicle-bridge/Cargo.lock
generated
Normal file
960
src/backends/icicle-emulator/icicle-bridge/Cargo.lock
generated
Normal file
@@ -0,0 +1,960 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"cpp_demangle",
|
||||
"fallible-iterator",
|
||||
"gimli",
|
||||
"memmap2",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"smallvec",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpp_demangle"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27711210499725bafe52c320a988e27283e6cf477ee8edac57e8275bef8ea550"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-frontend",
|
||||
"cranelift-module",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "540b193ff98b825a1f250a75b3118911af918a734154c69d80bcfcf91e7e9522"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bitset"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7cb269598b9557ab942d687d3c1086d77c4b50dcf35813f3a65ba306fd42279"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46566d7c83a8bff4150748d66020f4c7224091952aa4b4df1ec4959c39d937a1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-bforest",
|
||||
"cranelift-bitset",
|
||||
"cranelift-codegen-meta",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-control",
|
||||
"cranelift-entity",
|
||||
"cranelift-isle",
|
||||
"gimli",
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"regalloc2",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2df8a86a34236cc75a8a6a271973da779c2aeb36c43b6e14da474cf931317082"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf75340b6a57b7c7c1b74f10d3d90883ee6d43a554be8131a4046c2ebcf5eb65"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e84495bc5d23d86aad8c86f8ade4af765b94882af60d60e271d3153942f1978"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963c17147b80df351965e57c04d20dbedc85bcaf44c3436780a59a3f1ff1b1c2"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "727f02acbc4b4cb2ba38a6637101d579db50190df1dd05168c68e762851a3dd5"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b00cc2e03c748f2531eea01c871f502b909d30295fdcad43aec7bf5c5b4667"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f74630af581f32b99c8f4e06ee45799383ecc0795e3ff8aa86b7584bb2d643fd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-control",
|
||||
"cranelift-entity",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"libc",
|
||||
"log",
|
||||
"region",
|
||||
"target-lexicon",
|
||||
"wasmtime-jit-icache-coherence",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6aaa16c4f18a15be310df221ea544f516acc42fc58ca96e09a3d08651744efa1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-control",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbeaf978dc7c1a2de8bbb9162510ed218eb156697bc45590b8fbdd69bb08e8de"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
dependencies = [
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"icicle-cpu",
|
||||
"icicle-vm",
|
||||
"pcode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-cpu"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
"bytemuck",
|
||||
"gimli",
|
||||
"half",
|
||||
"icicle-mem",
|
||||
"object",
|
||||
"pcode",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-jit"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"cranelift",
|
||||
"cranelift-codegen",
|
||||
"cranelift-jit",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"icicle-cpu",
|
||||
"memoffset",
|
||||
"pcode",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
"wasmtime-jit-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-linux"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bstr",
|
||||
"bytemuck",
|
||||
"icicle-cpu",
|
||||
"object",
|
||||
"pcode",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-mem"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-vm"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"icicle-cpu",
|
||||
"icicle-jit",
|
||||
"icicle-linux",
|
||||
"ihex",
|
||||
"object",
|
||||
"pcode",
|
||||
"ron",
|
||||
"serde",
|
||||
"serde-xml-rs",
|
||||
"sleigh-compile",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ihex"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "365a784774bb381e8c19edb91190a90d7f2625e057b55de2bc0f6b57bc779ff2"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"hashbrown 0.15.2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "pcode"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"slice-group-by",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "region"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"mach2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags 2.9.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f"
|
||||
dependencies = [
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-xml-rs"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-compile"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"pcode",
|
||||
"serde",
|
||||
"serde-xml-rs",
|
||||
"serde_derive",
|
||||
"sleigh-parse",
|
||||
"sleigh-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-parse"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-runtime"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
|
||||
dependencies = [
|
||||
"pcode",
|
||||
"sleigh-parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slice-group-by"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "1.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-debug"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f02a0118d471de665565ed200bc56673eaa10cc8e223dfe2cef5d50ed0d9d143"
|
||||
dependencies = [
|
||||
"object",
|
||||
"rustix",
|
||||
"wasmtime-versioned-export-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-icache-coherence"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da47fba49af72581bc0dc67c8faaf5ee550e6f106e285122a184a675193701a5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-versioned-export-macros"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db8efb877c9e5e67239d4553bb44dd2a34ae5cfb728f3cf2c5e64439c6ca6ee7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
12
src/backends/icicle-emulator/icicle-bridge/Cargo.toml
Normal file
12
src/backends/icicle-emulator/icicle-bridge/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "icicle"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
icicle-vm = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
icicle-cpu = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
pcode = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
@@ -0,0 +1,33 @@
|
||||
:ADCX Reg32, rm32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; rm32 & Reg32 ... & check_Reg32_dest ... {
|
||||
tmp:5 = zext(Reg32) + zext(rm32) + zext(CF);
|
||||
tmpCF:1 = tmp(4); # just the carry byte
|
||||
CF = tmpCF != 0;
|
||||
Reg32 = tmp:4;
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:ADCX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
||||
tmp:9 = zext(Reg64) + zext(rm64) + zext(CF);
|
||||
tmpCF:1 = tmp(8); # just the carry byte
|
||||
CF = tmpCF != 0;
|
||||
Reg64 = tmp:8;
|
||||
}
|
||||
@endif
|
||||
|
||||
:ADOX Reg32, rm32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; rm32 & Reg32 ... & check_Reg32_dest ... {
|
||||
tmp:5 = zext(Reg32) + zext(rm32) + zext(OF);
|
||||
tmpOF:1 = tmp(4); # just the carry byte
|
||||
OF = tmpOF != 0;
|
||||
Reg32 = tmp:4;
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:ADOX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
||||
tmp:9 = zext(Reg64) + zext(rm64) + zext(OF);
|
||||
tmpOF:1 = tmp(8); # just the carry byte
|
||||
OF = tmpOF != 0;
|
||||
Reg64 = tmp:8;
|
||||
}
|
||||
@endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,252 @@
|
||||
# VINSERTI128/VINSERTI32x4/VINSERTI64x2/VINSERTI32x8/VINSERTI64x4 5-314 PAGE 2138 LINE 109785
|
||||
define pcodeop vinserti128 ;
|
||||
:VINSERTI128 YmmReg1, vexVVVV_YmmReg, XmmReg2_m128, imm8 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x38; YmmReg1 ... & XmmReg2_m128; imm8 & imm8_0 {
|
||||
local tmp:16 = XmmReg2_m128;
|
||||
|
||||
# ignoring all but the least significant bit
|
||||
if (imm8_0:1 == 0) goto <case0>;
|
||||
if (imm8_0:1 == 1) goto <case1>;
|
||||
|
||||
<case0>
|
||||
YmmReg1[0,128] = tmp;
|
||||
YmmReg1[128,128] = vexVVVV_YmmReg[128,128];
|
||||
goto <done>;
|
||||
|
||||
<case1>
|
||||
YmmReg1[0,128] = vexVVVV_YmmReg[0,128];
|
||||
YmmReg1[128,128] = tmp;
|
||||
|
||||
<done>
|
||||
}
|
||||
|
||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106903
|
||||
define pcodeop vgatherdpd ;
|
||||
:VGATHERDPD XmmReg1, q_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x92; (XmmReg1 & YmmReg1) ... & q_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vgatherdpd(XmmReg1, q_vm32x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vgatherdpd(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
|
||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908
|
||||
@ifdef IA64
|
||||
define pcodeop vgatherqpd ;
|
||||
:VGATHERQPD XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vgatherqpd(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vgatherqpd(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106913
|
||||
:VGATHERDPD YmmReg1, q_vm32x, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x92; YmmReg1 ... & q_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vgatherdpd(YmmReg1, q_vm32x, vexVVVV_YmmReg);
|
||||
YmmReg1 = vgatherdpd(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
|
||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918
|
||||
@ifdef IA64
|
||||
:VGATHERQPD YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x93; YmmReg1 ... & q_vm64y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vgatherqpd(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
||||
YmmReg1 = vgatherqpd(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107130
|
||||
define pcodeop vgatherdps ;
|
||||
:VGATHERDPS XmmReg1, d_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x92; (XmmReg1 & YmmReg1) ... & d_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vgatherdps(XmmReg1, d_vm32x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vgatherdps(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
|
||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135
|
||||
@ifdef IA64
|
||||
define pcodeop vgatherqps ;
|
||||
:VGATHERQPS XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vgatherqps(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107140
|
||||
:VGATHERDPS YmmReg1, d_vm32y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x92; YmmReg1 ... & d_vm32y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vgatherdps(YmmReg1, d_vm32y, vexVVVV_YmmReg);
|
||||
YmmReg1 = vgatherdps(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
|
||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145
|
||||
@ifdef IA64
|
||||
:VGATHERQPS XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vgatherqps(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
||||
XmmReg1 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
# PCMPEQQ 4-250 PAGE 1370 LINE 71171
|
||||
:VPCMPEQQ YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_NDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_YmmReg; byte=0x29; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1[0,64] = zext(vexVVVV_YmmReg[0,64] == YmmReg2_m256[0,64]) * 0xffffffffffffffff:8;
|
||||
YmmReg1[64,64] = zext(vexVVVV_YmmReg[64,64] == YmmReg2_m256[64,64]) * 0xffffffffffffffff:8;
|
||||
YmmReg1[128,64] = zext(vexVVVV_YmmReg[128,64] == YmmReg2_m256[128,64]) * 0xffffffffffffffff:8;
|
||||
YmmReg1[192,64] = zext(vexVVVV_YmmReg[192,64] == YmmReg2_m256[192,64]) * 0xffffffffffffffff:8;
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107884
|
||||
define pcodeop vpgatherdd ;
|
||||
:VPGATHERDD XmmReg1, d_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x90; (XmmReg1 & YmmReg1) ... & d_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vpgatherdd(XmmReg1, d_vm32x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vpgatherdd(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
|
||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888
|
||||
@ifdef IA64
|
||||
define pcodeop vpgatherqd ;
|
||||
:VPGATHERQD XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107892
|
||||
:VPGATHERDD YmmReg1, d_vm32y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x90; YmmReg1 ... & d_vm32y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vpgatherdd(YmmReg1, d_vm32y, vexVVVV_YmmReg);
|
||||
YmmReg1 = vpgatherdd(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
|
||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896
|
||||
@ifdef IA64
|
||||
:VPGATHERQD XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
||||
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108234
|
||||
define pcodeop vpgatherdq ;
|
||||
:VPGATHERDQ XmmReg1, q_vm32x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x90; (XmmReg1 & YmmReg1) ... & q_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vpgatherdq(XmmReg1, q_vm32x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vpgatherdq(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
|
||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238
|
||||
@ifdef IA64
|
||||
define pcodeop vpgatherqq ;
|
||||
:VPGATHERQQ XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# XmmReg1 = vpgatherqq(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
||||
local tmp:16 = vpgatherqq(XmmReg1, vexVVVV_XmmReg);
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
vexVVVV_XmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108242
|
||||
:VPGATHERDQ YmmReg1, q_vm32x, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x90; YmmReg1 ... & q_vm32x {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vpgatherdq(YmmReg1, q_vm32x, vexVVVV_YmmReg);
|
||||
YmmReg1 = vpgatherdq(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
|
||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246
|
||||
@ifdef IA64
|
||||
:VPGATHERQQ YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x91; YmmReg1 ... & q_vm64y {
|
||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||
# YmmReg1 = vpgatherqq(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
||||
YmmReg1 = vpgatherqq(YmmReg1, vexVVVV_YmmReg);
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
vexVVVV_YmmReg = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
# PMOVMSKB 4-338 PAGE 1458 LINE 75655
|
||||
:VPMOVMSKB Reg32, YmmReg2 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD7; Reg32 & (mod=0x3 & YmmReg2) & check_Reg32_dest
|
||||
{
|
||||
local byte_mask:4 = 0:4;
|
||||
byte_mask[0,1] = YmmReg2[7,1];
|
||||
byte_mask[1,1] = YmmReg2[15,1];
|
||||
byte_mask[2,1] = YmmReg2[23,1];
|
||||
byte_mask[3,1] = YmmReg2[31,1];
|
||||
byte_mask[4,1] = YmmReg2[39,1];
|
||||
byte_mask[5,1] = YmmReg2[47,1];
|
||||
byte_mask[6,1] = YmmReg2[55,1];
|
||||
byte_mask[7,1] = YmmReg2[63,1];
|
||||
byte_mask[8,1] = YmmReg2[71,1];
|
||||
byte_mask[9,1] = YmmReg2[79,1];
|
||||
byte_mask[10,1] = YmmReg2[87,1];
|
||||
byte_mask[11,1] = YmmReg2[95,1];
|
||||
byte_mask[12,1] = YmmReg2[103,1];
|
||||
byte_mask[13,1] = YmmReg2[111,1];
|
||||
byte_mask[14,1] = YmmReg2[119,1];
|
||||
byte_mask[15,1] = YmmReg2[127,1];
|
||||
byte_mask[16,1] = YmmReg2[135,1];
|
||||
byte_mask[17,1] = YmmReg2[143,1];
|
||||
byte_mask[18,1] = YmmReg2[151,1];
|
||||
byte_mask[19,1] = YmmReg2[159,1];
|
||||
byte_mask[20,1] = YmmReg2[167,1];
|
||||
byte_mask[21,1] = YmmReg2[175,1];
|
||||
byte_mask[22,1] = YmmReg2[183,1];
|
||||
byte_mask[23,1] = YmmReg2[191,1];
|
||||
byte_mask[24,1] = YmmReg2[199,1];
|
||||
byte_mask[25,1] = YmmReg2[207,1];
|
||||
byte_mask[26,1] = YmmReg2[215,1];
|
||||
byte_mask[27,1] = YmmReg2[223,1];
|
||||
byte_mask[28,1] = YmmReg2[231,1];
|
||||
byte_mask[29,1] = YmmReg2[239,1];
|
||||
byte_mask[30,1] = YmmReg2[247,1];
|
||||
byte_mask[31,1] = YmmReg2[255,1];
|
||||
Reg32 = zext(byte_mask);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
# MOVAPD 4-45 PAGE 1165 LINE 60844
|
||||
:VMOVAPD XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x28; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
YmmReg1 = zext(XmmReg2_m128);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# MOVAPD 4-45 PAGE 1165 LINE 60846
|
||||
:VMOVAPD XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; mod=3 & XmmReg1 & (XmmReg2 & YmmReg2)
|
||||
{
|
||||
YmmReg2 = zext(XmmReg1);
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVAPD 4-45 PAGE 1165 LINE 60846
|
||||
:VMOVAPD m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; XmmReg1 ... & m128
|
||||
{
|
||||
m128 = XmmReg1;
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVAPD 4-45 PAGE 1165 LINE 60848
|
||||
:VMOVAPD YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x28; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = YmmReg2_m256;
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# MOVAPD 4-45 PAGE 1165 LINE 60850
|
||||
:VMOVAPD YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x29; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg2_m256 = YmmReg1;
|
||||
# TODO ZmmReg2 = zext(YmmReg2)
|
||||
}
|
||||
|
||||
# MOVAPS 4-49 PAGE 1169 LINE 61039
|
||||
:VMOVAPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x28; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
YmmReg1 = zext(XmmReg2_m128);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# MOVAPS 4-49 PAGE 1169 LINE 61041
|
||||
:VMOVAPS XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; mod=3 & XmmReg1 & (XmmReg2 & YmmReg2)
|
||||
{
|
||||
YmmReg2 = zext(XmmReg1);
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVAPS 4-49 PAGE 1169 LINE 61041
|
||||
:VMOVAPS m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; XmmReg1 ... & m128
|
||||
{
|
||||
m128 = XmmReg1;
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVAPS 4-49 PAGE 1169 LINE 61043
|
||||
:VMOVAPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x28; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = YmmReg2_m256;
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# MOVAPS 4-49 PAGE 1169 LINE 61045
|
||||
:VMOVAPS YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x29; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg2_m256 = YmmReg1;
|
||||
# TODO ZmmReg2 = zext(YmmReg2)
|
||||
}
|
||||
|
||||
# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61667
|
||||
# Note: we do not model the exception generated if VMOVDQA is used with a memory operand which is not 16-bye aligned
|
||||
:VMOVDQA XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
YmmReg1 = zext(XmmReg2_m128);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61669
|
||||
:VMOVDQA XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 & (mod = 3 & XmmReg2 & YmmReg2)
|
||||
{
|
||||
YmmReg2 = zext(XmmReg1);
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61669
|
||||
:VMOVDQA m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; XmmReg1 ... & m128
|
||||
{
|
||||
m128 = XmmReg1;
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61671
|
||||
:VMOVDQA YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x6F; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = YmmReg2_m256;
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# MOVDQA,VMOVDQA32/64 4-62 PAGE 1182 LINE 61673
|
||||
:VMOVDQA YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0x7F; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg2_m256 = YmmReg1;
|
||||
# TODO ZmmReg2 = zext(YmmReg2)
|
||||
}
|
||||
|
||||
# MOVSD 4-111 PAGE 1231 LINE 63970
|
||||
:VMOVSD XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x10; XmmReg1 & YmmReg1 & (mod=0x3 & XmmReg2)
|
||||
{
|
||||
local tmpa:8 = XmmReg2[0,64];
|
||||
local tmpb:8 = vexVVVV_XmmReg[64,64];
|
||||
YmmReg1 = 0;
|
||||
XmmReg1[0,64] = tmpa;
|
||||
XmmReg1[64,64] = tmpb;
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# MOVSD 4-111 PAGE 1231 LINE 63972
|
||||
:VMOVSD XmmReg1, m64 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & m64
|
||||
{
|
||||
YmmReg1[0,64] = m64;
|
||||
YmmReg1[64,64] = 0;
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# MOVSD 4-111 PAGE 1231 LINE 63974
|
||||
:VMOVSD XmmReg2, vexVVVV_XmmReg, XmmReg1 is $(VEX_NDS) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x11; XmmReg1 & (mod=0x3 & (XmmReg2 & YmmReg2))
|
||||
{
|
||||
local tmpa:8 = XmmReg1[0,64];
|
||||
local tmpb:8 = vexVVVV_XmmReg[64,64];
|
||||
YmmReg2 = 0;
|
||||
XmmReg2[0,64] = tmpa;
|
||||
XmmReg2[64,64] = tmpb;
|
||||
# TODO ZmmReg2 = zext(XmmReg2)
|
||||
}
|
||||
|
||||
# MOVSD 4-111 PAGE 1231 LINE 63976
|
||||
:VMOVSD m64, XmmReg1 is $(VEX_NONE) & $(VEX_LIG) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m64
|
||||
{
|
||||
m64 = XmmReg1[0,64];
|
||||
}
|
||||
|
||||
# MOVUPS 4-130 PAGE 1250 LINE 64872
|
||||
:VMOVUPS XmmReg1, XmmReg2_m128 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x10; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = XmmReg2_m128;
|
||||
YmmReg1[0,128] = tmp;
|
||||
YmmReg1[128,64] = 0;
|
||||
YmmReg1[192,64] = 0;
|
||||
}
|
||||
|
||||
# MOVUPS 4-130 PAGE 1250 LINE 64874
|
||||
# break this into two constructors to handle the zext for the register destination case
|
||||
:VMOVUPS XmmReg2, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 & (mod = 3 & XmmReg2 & YmmReg2)
|
||||
{
|
||||
XmmReg2 = XmmReg1;
|
||||
YmmReg2 = zext(XmmReg2);
|
||||
}
|
||||
|
||||
# MOVUPS 4-130 PAGE 1250 LINE 64874
|
||||
:VMOVUPS m128, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; XmmReg1 ... & m128
|
||||
{
|
||||
m128 = XmmReg1;
|
||||
}
|
||||
|
||||
# MOVUPS 4-130 PAGE 1250 LINE 64876
|
||||
:VMOVUPS YmmReg1, YmmReg2_m256 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x10; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = YmmReg2_m256;
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# MOVUPS 4-130 PAGE 1250 LINE 64878
|
||||
# TODO in general, what do we do with the zext of only the register case; needs investigation
|
||||
:VMOVUPS YmmReg2_m256, YmmReg1 is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x11; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg2_m256 = YmmReg1;
|
||||
}
|
||||
|
||||
# PCMPEQQ 4-250 PAGE 1370 LINE 71169
|
||||
:VPCMPEQQ XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x29; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1[0,64] = zext(vexVVVV_XmmReg[0,64] == XmmReg2_m128[0,64]) * 0xffffffffffffffff:8;
|
||||
XmmReg1[64,64] = zext(vexVVVV_XmmReg[64,64] == XmmReg2_m128[64,64]) * 0xffffffffffffffff:8;
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
|
||||
# PMOVMSKB 4-338 PAGE 1458 LINE 75651
|
||||
:VPMOVMSKB Reg32, XmmReg2 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_WIG); byte=0xD7; Reg32 & (mod=0x3 & XmmReg2) & check_Reg32_dest
|
||||
{
|
||||
local byte_mask:2 = 0:2;
|
||||
byte_mask[0,1] = XmmReg2[7,1];
|
||||
byte_mask[1,1] = XmmReg2[15,1];
|
||||
byte_mask[2,1] = XmmReg2[23,1];
|
||||
byte_mask[3,1] = XmmReg2[31,1];
|
||||
byte_mask[4,1] = XmmReg2[39,1];
|
||||
byte_mask[5,1] = XmmReg2[47,1];
|
||||
byte_mask[6,1] = XmmReg2[55,1];
|
||||
byte_mask[7,1] = XmmReg2[63,1];
|
||||
byte_mask[8,1] = XmmReg2[71,1];
|
||||
byte_mask[9,1] = XmmReg2[79,1];
|
||||
byte_mask[10,1] = XmmReg2[87,1];
|
||||
byte_mask[11,1] = XmmReg2[95,1];
|
||||
byte_mask[12,1] = XmmReg2[103,1];
|
||||
byte_mask[13,1] = XmmReg2[111,1];
|
||||
byte_mask[14,1] = XmmReg2[119,1];
|
||||
byte_mask[15,1] = XmmReg2[127,1];
|
||||
Reg32 = zext(byte_mask);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
# VZEROALL 5-563 PAGE 2387 LINE 122405
|
||||
:VZEROALL is $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77
|
||||
{
|
||||
YMM0[0,64] = 0:8; YMM0[64,64] = 0:8; YMM0[128,64] = 0:8; YMM0[192,64] = 0:8;
|
||||
YMM1[0,64] = 0:8; YMM1[64,64] = 0:8; YMM1[128,64] = 0:8; YMM1[192,64] = 0:8;
|
||||
YMM2[0,64] = 0:8; YMM2[64,64] = 0:8; YMM2[128,64] = 0:8; YMM2[192,64] = 0:8;
|
||||
YMM3[0,64] = 0:8; YMM3[64,64] = 0:8; YMM3[128,64] = 0:8; YMM3[192,64] = 0:8;
|
||||
YMM4[0,64] = 0:8; YMM4[64,64] = 0:8; YMM4[128,64] = 0:8; YMM4[192,64] = 0:8;
|
||||
YMM5[0,64] = 0:8; YMM5[64,64] = 0:8; YMM5[128,64] = 0:8; YMM5[192,64] = 0:8;
|
||||
YMM6[0,64] = 0:8; YMM6[64,64] = 0:8; YMM6[128,64] = 0:8; YMM6[192,64] = 0:8;
|
||||
YMM7[0,64] = 0:8; YMM7[64,64] = 0:8; YMM7[128,64] = 0:8; YMM7[192,64] = 0:8;
|
||||
#TODO: Zmm
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:VZEROALL is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L256) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77
|
||||
{
|
||||
YMM0[0,64] = 0:8; YMM0[64,64] = 0:8; YMM0[128,64] = 0:8; YMM0[192,64] = 0:8;
|
||||
YMM1[0,64] = 0:8; YMM1[64,64] = 0:8; YMM1[128,64] = 0:8; YMM1[192,64] = 0:8;
|
||||
YMM2[0,64] = 0:8; YMM2[64,64] = 0:8; YMM2[128,64] = 0:8; YMM2[192,64] = 0:8;
|
||||
YMM3[0,64] = 0:8; YMM3[64,64] = 0:8; YMM3[128,64] = 0:8; YMM3[192,64] = 0:8;
|
||||
YMM4[0,64] = 0:8; YMM4[64,64] = 0:8; YMM4[128,64] = 0:8; YMM4[192,64] = 0:8;
|
||||
YMM5[0,64] = 0:8; YMM5[64,64] = 0:8; YMM5[128,64] = 0:8; YMM5[192,64] = 0:8;
|
||||
YMM6[0,64] = 0:8; YMM6[64,64] = 0:8; YMM6[128,64] = 0:8; YMM6[192,64] = 0:8;
|
||||
YMM7[0,64] = 0:8; YMM7[64,64] = 0:8; YMM7[128,64] = 0:8; YMM7[192,64] = 0:8;
|
||||
YMM8[0,64] = 0:8; YMM8[64,64] = 0:8; YMM8[128,64] = 0:8; YMM8[192,64] = 0:8;
|
||||
YMM9[0,64] = 0:8; YMM9[64,64] = 0:8; YMM9[128,64] = 0:8; YMM9[192,64] = 0:8;
|
||||
YMM10[0,64] = 0:8; YMM10[64,64] = 0:8; YMM10[128,64] = 0:8; YMM10[192,64] = 0:8;
|
||||
YMM11[0,64] = 0:8; YMM11[64,64] = 0:8; YMM11[128,64] = 0:8; YMM11[192,64] = 0:8;
|
||||
YMM12[0,64] = 0:8; YMM12[64,64] = 0:8; YMM12[128,64] = 0:8; YMM12[192,64] = 0:8;
|
||||
YMM13[0,64] = 0:8; YMM13[64,64] = 0:8; YMM13[128,64] = 0:8; YMM13[192,64] = 0:8;
|
||||
YMM14[0,64] = 0:8; YMM14[64,64] = 0:8; YMM14[128,64] = 0:8; YMM14[192,64] = 0:8;
|
||||
YMM15[0,64] = 0:8; YMM15[64,64] = 0:8; YMM15[128,64] = 0:8; YMM15[192,64] = 0:8;
|
||||
#TODO: Zmm
|
||||
}
|
||||
@endif
|
||||
|
||||
# VZEROUPPER 5-565 PAGE 2389 LINE 122480
|
||||
:VZEROUPPER is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77
|
||||
{
|
||||
YMM0[128,64] = 0:8; YMM0[192,64] = 0:8;
|
||||
YMM1[128,64] = 0:8; YMM1[192,64] = 0:8;
|
||||
YMM2[128,64] = 0:8; YMM2[192,64] = 0:8;
|
||||
YMM3[128,64] = 0:8; YMM3[192,64] = 0:8;
|
||||
YMM4[128,64] = 0:8; YMM4[192,64] = 0:8;
|
||||
YMM5[128,64] = 0:8; YMM5[192,64] = 0:8;
|
||||
YMM6[128,64] = 0:8; YMM6[192,64] = 0:8;
|
||||
YMM7[128,64] = 0:8; YMM7[192,64] = 0:8;
|
||||
#TODO: Zmm
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:VZEROUPPER is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_NONE) & $(VEX_0F) & $(VEX_WIG); byte=0x77
|
||||
{
|
||||
YMM0[128,64] = 0:8; YMM0[192,64] = 0:8;
|
||||
YMM1[128,64] = 0:8; YMM1[192,64] = 0:8;
|
||||
YMM2[128,64] = 0:8; YMM2[192,64] = 0:8;
|
||||
YMM3[128,64] = 0:8; YMM3[192,64] = 0:8;
|
||||
YMM4[128,64] = 0:8; YMM4[192,64] = 0:8;
|
||||
YMM5[128,64] = 0:8; YMM5[192,64] = 0:8;
|
||||
YMM6[128,64] = 0:8; YMM6[192,64] = 0:8;
|
||||
YMM7[128,64] = 0:8; YMM7[192,64] = 0:8;
|
||||
YMM8[128,64] = 0:8; YMM8[192,64] = 0:8;
|
||||
YMM9[128,64] = 0:8; YMM9[192,64] = 0:8;
|
||||
YMM10[128,64] = 0:8; YMM10[192,64] = 0:8;
|
||||
YMM11[128,64] = 0:8; YMM11[192,64] = 0:8;
|
||||
YMM12[128,64] = 0:8; YMM12[192,64] = 0:8;
|
||||
YMM13[128,64] = 0:8; YMM13[192,64] = 0:8;
|
||||
YMM14[128,64] = 0:8; YMM14[192,64] = 0:8;
|
||||
YMM15[128,64] = 0:8; YMM15[192,64] = 0:8;
|
||||
#TODO: Zmm
|
||||
}
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
macro tzcntflags(input, output) {
|
||||
ZF = (output == 0);
|
||||
CF = (input == 0);
|
||||
# OF, SF, PF, AF are undefined
|
||||
}
|
||||
|
||||
|
||||
####
|
||||
#### BMI1 instructions
|
||||
####
|
||||
|
||||
# TODO remove ANDN from ia.sinc ?????
|
||||
:ANDN Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf2; Reg32 ... & check_Reg32_dest ... &rm32
|
||||
{
|
||||
Reg32 = ~(vexVVVV_r32) & rm32;
|
||||
resultflags(Reg32);
|
||||
OF = 0;
|
||||
CF = 0;
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
# TODO remove ANDN from ia.sinc ?????
|
||||
:ANDN Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf2; Reg64 ... & rm64
|
||||
{
|
||||
Reg64 = ~(vexVVVV_r64) & rm64;
|
||||
resultflags(Reg64);
|
||||
OF = 0;
|
||||
CF = 0;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:BEXTR Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
sourceTmp:1 = vexVVVV_r32[0,8];
|
||||
lengthTmp:1 = vexVVVV_r32[8,8];
|
||||
|
||||
Reg32 = (rm32 >> sourceTmp) & ((1 << lengthTmp) - 1);
|
||||
build check_Reg32_dest;
|
||||
|
||||
ZF = (Reg32 == 0);
|
||||
OF = 0;
|
||||
CF = 0;
|
||||
# AF, SF, and PF are undefined
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:BEXTR Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||
{
|
||||
sourceTmp:1 = vexVVVV_r64[0,8];
|
||||
lengthTmp:1 = vexVVVV_r64[8,8];
|
||||
|
||||
Reg64 = (rm64 >> sourceTmp) & ((1 << lengthTmp) - 1);
|
||||
|
||||
ZF = (Reg64 == 0);
|
||||
OF = 0;
|
||||
CF = 0;
|
||||
# AF, SF, and PF are undefined
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:BLSI vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=3 ... & check_vexVVVV_r32_dest ... & rm32
|
||||
{
|
||||
vexVVVV_r32 = -rm32 & rm32;
|
||||
build check_vexVVVV_r32_dest;
|
||||
|
||||
ZF = (vexVVVV_r32 == 0);
|
||||
SF = (vexVVVV_r32 s< 0);
|
||||
CF = (rm32 != 0);
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:BLSI vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=3 ... & rm64
|
||||
{
|
||||
vexVVVV_r64 = -rm64 & rm64;
|
||||
|
||||
ZF = (vexVVVV_r64 == 0);
|
||||
SF = (vexVVVV_r64 s< 0);
|
||||
CF = (rm64 != 0);
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:BLSMSK vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=2 ... & check_vexVVVV_r32_dest ... &rm32
|
||||
{
|
||||
CF = (rm32 == 0);
|
||||
vexVVVV_r32 = (rm32 - 1) ^ rm32;
|
||||
|
||||
SF = (vexVVVV_r32 s< 0);
|
||||
build check_vexVVVV_r32_dest;
|
||||
ZF = 0;
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:BLSMSK vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=2 ... & rm64
|
||||
{
|
||||
CF = (rm64 == 0);
|
||||
vexVVVV_r64 = (rm64 - 1) ^ rm64;
|
||||
|
||||
SF = (vexVVVV_r64 s< 0);
|
||||
ZF = 0;
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:BLSR vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=1 ... & check_vexVVVV_r32_dest ... &rm32
|
||||
{
|
||||
CF = (rm32 == 0);
|
||||
vexVVVV_r32 = (rm32 - 1) & rm32;
|
||||
build check_vexVVVV_r32_dest;
|
||||
|
||||
ZF = (vexVVVV_r32 == 0);
|
||||
SF = (vexVVVV_r32 s< 0);
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:BLSR vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=1 ... & rm64
|
||||
{
|
||||
CF = (rm64 == 0);
|
||||
vexVVVV_r64 = (rm64 - 1) & rm64;
|
||||
|
||||
ZF = (vexVVVV_r64 == 0);
|
||||
SF = (vexVVVV_r64 s< 0);
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
@endif
|
||||
|
||||
# not as documented in manual; requires PRE_66 prefix to get 16-bit operation
|
||||
:TZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg16 ... & rm16 {
|
||||
|
||||
countTmp:2 = 0;
|
||||
inputTmp:2 = rm16;
|
||||
|
||||
<loopbegin>
|
||||
if ((inputTmp & 1) != 0) goto <loopend>;
|
||||
|
||||
countTmp = countTmp + 1;
|
||||
inputTmp = (inputTmp >> 1) | 0x8000;
|
||||
goto <loopbegin>;
|
||||
|
||||
<loopend>
|
||||
tzcntflags(rm16, countTmp);
|
||||
Reg16 = countTmp;
|
||||
|
||||
}
|
||||
|
||||
:TZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg32 ... & check_Reg32_dest ... & rm32 {
|
||||
|
||||
countTmp:4 = 0;
|
||||
inputTmp:4 = rm32;
|
||||
|
||||
<loopbegin>
|
||||
if ((inputTmp & 1) != 0) goto <loopend>;
|
||||
|
||||
countTmp = countTmp + 1;
|
||||
inputTmp = (inputTmp >> 1) | 0x80000000;
|
||||
goto <loopbegin>;
|
||||
|
||||
<loopend>
|
||||
tzcntflags(rm32, countTmp);
|
||||
Reg32 = countTmp;
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:TZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBC; Reg64 ... & rm64 {
|
||||
|
||||
countTmp:8 = 0;
|
||||
inputTmp:8 = rm64;
|
||||
|
||||
<loopbegin>
|
||||
if ((inputTmp & 1) != 0) goto <loopend>;
|
||||
|
||||
countTmp = countTmp + 1;
|
||||
inputTmp = (inputTmp >> 1) | 0x8000000000000000;
|
||||
goto <loopbegin>;
|
||||
|
||||
<loopend>
|
||||
tzcntflags(rm64, countTmp);
|
||||
Reg64 = countTmp;
|
||||
}
|
||||
@endif
|
||||
@@ -0,0 +1,209 @@
|
||||
####
|
||||
#### BMI2 instructions
|
||||
####
|
||||
|
||||
|
||||
:BZHI Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
indexTmp:1 = vexVVVV_r32:1;
|
||||
|
||||
# saturate index amount to 32; operand size or higher does not clear any bits
|
||||
shift:1 = (indexTmp <= 32) * (32 - indexTmp);
|
||||
|
||||
# clear the upper bits
|
||||
Reg32 = (rm32 << shift) >> shift;
|
||||
build check_Reg32_dest;
|
||||
|
||||
ZF = (Reg32 == 0);
|
||||
SF = (Reg32 s< 0);
|
||||
CF = indexTmp > 31;
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:BZHI Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||
{
|
||||
indexTmp:1 = vexVVVV_r64:1;
|
||||
|
||||
# saturate index amount to 64; operand size or higher does not clear any bits
|
||||
shift:1 = (indexTmp <= 64) * (64 - indexTmp);
|
||||
|
||||
# clear the upper bits
|
||||
Reg64 = (rm64 << shift) >> shift;
|
||||
|
||||
ZF = (Reg64 == 0);
|
||||
SF = (Reg64 s< 0);
|
||||
CF = indexTmp > 63;
|
||||
OF = 0;
|
||||
# AF and PF are undefined
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:MULX Reg32, vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf6; Reg32 ... & check_Reg32_dest ... & check_vexVVVV_r32_dest ... & rm32
|
||||
{
|
||||
temp:8 = zext(EDX) * zext(rm32);
|
||||
|
||||
vexVVVV_r32 = temp:4;
|
||||
build check_vexVVVV_r32_dest;
|
||||
Reg32 = temp(4);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:MULX Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf6; Reg64 ... & rm64
|
||||
{
|
||||
temp:16 = zext(RDX) * zext(rm64);
|
||||
|
||||
vexVVVV_r64 = temp:8;
|
||||
Reg64 = temp(8);
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:PDEP Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
sourceTmp:4 = vexVVVV_r32;
|
||||
|
||||
indexTmp:4 = 1;
|
||||
resultTmp:4 = 0;
|
||||
|
||||
<loop>
|
||||
maskBit:4 = rm32 & indexTmp;
|
||||
|
||||
if (maskBit == 0) goto <nextMaskBit>;
|
||||
resultTmp = resultTmp | (maskBit * (sourceTmp & 1));
|
||||
sourceTmp = sourceTmp >> 1;
|
||||
|
||||
<nextMaskBit>
|
||||
indexTmp = indexTmp << 1;
|
||||
if (indexTmp != 0) goto <loop>;
|
||||
|
||||
Reg32 = resultTmp;
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:PDEP Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||
{
|
||||
sourceTmp:8 = vexVVVV_r64;
|
||||
|
||||
indexTmp:8 = 1;
|
||||
resultTmp:8 = 0;
|
||||
|
||||
<loop>
|
||||
maskBit:8 = rm64 & indexTmp;
|
||||
|
||||
if (maskBit == 0) goto <nextMaskBit>;
|
||||
resultTmp = resultTmp | (maskBit * (sourceTmp & 1));
|
||||
sourceTmp = sourceTmp >> 1;
|
||||
|
||||
<nextMaskBit>
|
||||
indexTmp = indexTmp << 1;
|
||||
if (indexTmp != 0) goto <loop>;
|
||||
|
||||
Reg64 = resultTmp;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:PEXT Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
indexTmp:4 = 0x80000000;
|
||||
resultTmp:4 = 0;
|
||||
|
||||
<loop>
|
||||
maskBit:4 = rm32 & indexTmp;
|
||||
|
||||
if (maskBit == 0) goto <nextMaskBit>;
|
||||
resultTmp = (resultTmp << 1) | zext((maskBit & vexVVVV_r32) != 0);
|
||||
|
||||
<nextMaskBit>
|
||||
indexTmp = indexTmp >> 1;
|
||||
if (indexTmp != 0) goto <loop>;
|
||||
|
||||
build check_Reg32_dest;
|
||||
Reg32 = resultTmp;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:PEXT Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||
{
|
||||
indexTmp:8 = 0x8000000000000000;
|
||||
resultTmp:8 = 0;
|
||||
|
||||
<loop>
|
||||
maskBit:8 = rm64 & indexTmp;
|
||||
|
||||
if (maskBit == 0) goto <nextMaskBit>;
|
||||
resultTmp = (resultTmp << 1) | zext((maskBit & vexVVVV_r64) != 0);
|
||||
|
||||
<nextMaskBit>
|
||||
indexTmp = indexTmp >> 1;
|
||||
if (indexTmp != 0) goto <loop>;
|
||||
|
||||
Reg64 = resultTmp;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:RORX Reg32, rm32, imm8 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W0); byte=0xf0; Reg32 ... & check_Reg32_dest ... & rm32; imm8
|
||||
{
|
||||
shiftTmp:1 = (imm8:1 & 0x1F);
|
||||
|
||||
Reg32 = (rm32 >> shiftTmp) | ( rm32 << (32 - shiftTmp));
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:RORX Reg64, rm64, imm8 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W1); byte=0xf0; Reg64 ... & rm64; imm8
|
||||
{
|
||||
shiftTmp:1 = (imm8:1 & 0x3F);
|
||||
|
||||
Reg64 = (rm64 >> shiftTmp) | ( rm64 << (64 - shiftTmp));
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:SARX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
Reg32 = rm32 s>> (vexVVVV_r32 & 0x0000001F);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:SARX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||
{
|
||||
Reg64 = rm64 s>> (vexVVVV_r64 & 0x000000000000003F);
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:SHLX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
Reg32 = rm32 << (vexVVVV_r32 & 0x0000001F);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:SHLX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||
{
|
||||
Reg64 = rm64 << (vexVVVV_r64 & 0x000000000000003F);
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
:SHRX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
|
||||
{
|
||||
Reg32 = rm32 >> (vexVVVV_r32 & 0x0000001F);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:SHRX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||
{
|
||||
Reg64 = rm64 >> (vexVVVV_r64 & 0x000000000000003F);
|
||||
}
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#
|
||||
# Instructions based on Intel Control-flow Enforcement Technology Preview
|
||||
#
|
||||
# Note: Shadow Stack semantics is not currently implemented correctly in these instructions
|
||||
# nor in the instructions affected by CET
|
||||
#
|
||||
|
||||
|
||||
define pcodeop ShadowStackPush8B;
|
||||
define pcodeop ShadowStackPush4B;
|
||||
|
||||
define pcodeop ShadowStackLoad8B;
|
||||
define pcodeop ShadowStackLoad4B;
|
||||
|
||||
:INCSSPD r32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0xae; reg_opcode=5 & r32 {
|
||||
SSP = SSP + zext(4 * r32:1);
|
||||
}
|
||||
@ifdef IA64
|
||||
:INCSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0xae; reg_opcode=5 & r64 {
|
||||
SSP = SSP + zext(8 * r64:1);
|
||||
}
|
||||
@endif
|
||||
|
||||
:RDSSPD r32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r32 {
|
||||
r32 = SSP:4;
|
||||
}
|
||||
@ifdef IA64
|
||||
:RDSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r64 {
|
||||
r64 = SSP;
|
||||
}
|
||||
@endif
|
||||
|
||||
:SAVEPREVSSP is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; byte=0xea {
|
||||
tmp:8 = SSP;
|
||||
SSP = SSP & ~0x7;
|
||||
ShadowStackPush8B(tmp);
|
||||
}
|
||||
|
||||
|
||||
:RSTORSSP m64 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; ( mod != 0b11 & reg_opcode=5 ) ... & m64 {
|
||||
tmp_SSP:8 = m64;
|
||||
SSP = tmp_SSP & ~0x01;
|
||||
}
|
||||
|
||||
define pcodeop writeToShadowStack;
|
||||
define pcodeop writeToUserShadowStack;
|
||||
|
||||
|
||||
:WRSSD rm32,Reg32 is vexMode=0 & byte=0x0f; byte=0x38; byte=0xf6; rm32 & Reg32 ... {
|
||||
writeToShadowStack(rm32, Reg32);
|
||||
}
|
||||
@ifdef IA64
|
||||
:WRSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf6; rm64 & Reg64 ... {
|
||||
writeToShadowStack(rm64, Reg64);
|
||||
}
|
||||
@endif
|
||||
|
||||
:WRUSSD rm32,Reg32 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0xf5; rm32 & Reg32 ... {
|
||||
writeToUserShadowStack(rm32, Reg32);
|
||||
}
|
||||
@ifdef IA64
|
||||
:WRUSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf5; rm64 & Reg64 ... {
|
||||
writeToUserShadowStack(rm64, Reg64);
|
||||
}
|
||||
@endif
|
||||
|
||||
define pcodeop markShadowStackBusy;
|
||||
define pcodeop clearShadowStackBusy;
|
||||
|
||||
:SETSSBSY is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x01; byte=0xe8 {
|
||||
SSP = markShadowStackBusy(IA32_PL0_SSP);
|
||||
}
|
||||
|
||||
:CLRSSBSY m64 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0xae; reg_opcode=6 ... & m64 {
|
||||
clearShadowStackBusy(m64);
|
||||
SSP=0;
|
||||
}
|
||||
|
||||
:ENDBR32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfb {}
|
||||
@ifdef IA64
|
||||
:ENDBR64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfa {}
|
||||
@endif
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
define pcodeop clwb;
|
||||
:CLWB m8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=6 ... {
|
||||
clwb(m8);
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
define pcodeop clflushopt;
|
||||
:CLFLUSHOPT m8 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=7 ... {
|
||||
clflushopt(m8);
|
||||
}
|
||||
@endif
|
||||
|
||||
# Note: PCOMMIT was deprecated prior to it ever being implemented in production processors.
|
||||
# I never found the encoding for it. Therefore, no constructor.
|
||||
@@ -0,0 +1,800 @@
|
||||
#
|
||||
# x86 FMA instructions
|
||||
#
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101211
|
||||
define pcodeop vfmadd132pd_fma ;
|
||||
:VFMADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x98; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101214
|
||||
define pcodeop vfmadd213pd_fma ;
|
||||
:VFMADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101217
|
||||
define pcodeop vfmadd231pd_fma ;
|
||||
:VFMADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101220
|
||||
:VFMADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x98; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101223
|
||||
:VFMADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA8; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSD 5-120 PAGE 1944 LINE 101226
|
||||
:VFMADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB8; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101572
|
||||
define pcodeop vfmadd132ps_fma ;
|
||||
:VFMADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x98; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101575
|
||||
define pcodeop vfmadd213ps_fma ;
|
||||
:VFMADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101578
|
||||
define pcodeop vfmadd231ps_fma ;
|
||||
:VFMADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101581
|
||||
:VFMADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x98; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101584
|
||||
:VFMADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA8; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFIXUPIMMSS 5-127 PAGE 1951 LINE 101587
|
||||
# WARNING: did not recognize VEX field 0 for "VFMADD231PS ymm1, ymm2, ymm3/m256"
|
||||
:VFMADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xB8; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101931
|
||||
define pcodeop vfmadd132sd_fma ;
|
||||
:VFMADD132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x99; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmadd132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101934
|
||||
define pcodeop vfmadd213sd_fma ;
|
||||
:VFMADD213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA9; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmadd213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132PS/VFMADD213PS/VFMADD231PS 5-134 PAGE 1958 LINE 101937
|
||||
define pcodeop vfmadd231sd_fma ;
|
||||
:VFMADD231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB9; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmadd231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102099
|
||||
define pcodeop vfmadd132ss_fma ;
|
||||
:VFMADD132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x99; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmadd132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102102
|
||||
define pcodeop vfmadd213ss_fma ;
|
||||
:VFMADD213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA9; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmadd213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-137 PAGE 1961 LINE 102105
|
||||
define pcodeop vfmadd231ss_fma ;
|
||||
:VFMADD231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB9; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmadd231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102272
|
||||
define pcodeop vfmaddsub132pd_fma ;
|
||||
:VFMADDSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x96; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102275
|
||||
define pcodeop vfmaddsub213pd_fma ;
|
||||
:VFMADDSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102278
|
||||
define pcodeop vfmaddsub231pd_fma ;
|
||||
:VFMADDSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102281
|
||||
:VFMADDSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x96; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102284
|
||||
:VFMADDSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA6; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD 5-140 PAGE 1964 LINE 102287
|
||||
:VFMADDSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB6; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102711
|
||||
define pcodeop vfmaddsub132ps_fma ;
|
||||
:VFMADDSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x96; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102714
|
||||
define pcodeop vfmaddsub213ps_fma ;
|
||||
:VFMADDSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102717
|
||||
define pcodeop vfmaddsub231ps_fma ;
|
||||
:VFMADDSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB6; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmaddsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102720
|
||||
:VFMADDSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x96; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102723
|
||||
:VFMADDSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA6; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMADD132SS/VFMADD213SS/VFMADD231SS 5-150 PAGE 1974 LINE 102726
|
||||
:VFMADDSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xB6; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmaddsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103141
|
||||
define pcodeop vfmsubadd132pd_fma ;
|
||||
:VFMSUBADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x97; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103144
|
||||
define pcodeop vfmsubadd213pd_fma ;
|
||||
:VFMSUBADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xA7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103147
|
||||
define pcodeop vfmsubadd231pd_fma ;
|
||||
:VFMSUBADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xB7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103150
|
||||
:VFMSUBADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x97; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103153
|
||||
:VFMSUBADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xA7; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD 5-159 PAGE 1983 LINE 103156
|
||||
:VFMSUBADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xB7; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103581
|
||||
define pcodeop vfmsubadd132ps_fma ;
|
||||
:VFMSUBADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x97; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103584
|
||||
define pcodeop vfmsubadd213ps_fma ;
|
||||
:VFMSUBADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xA7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103587
|
||||
define pcodeop vfmsubadd231ps_fma ;
|
||||
:VFMSUBADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xB7; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsubadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103590
|
||||
:VFMSUBADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x97; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103593
|
||||
:VFMSUBADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xA7; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUBADD132PS/VFMSUBADD213PS/VFMSUBADD231PS 5-169 PAGE 1993 LINE 103596
|
||||
:VFMSUBADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xB7; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsubadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104019
|
||||
define pcodeop vfmsub132pd_fma ;
|
||||
:VFMSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104022
|
||||
define pcodeop vfmsub213pd_fma ;
|
||||
:VFMSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104025
|
||||
define pcodeop vfmsub231pd_fma ;
|
||||
:VFMSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104028
|
||||
:VFMSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9A; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104031
|
||||
:VFMSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAA; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PD/VFMSUB213PD/VFMSUB231PD 5-179 PAGE 2003 LINE 104034
|
||||
:VFMSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBA; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104379
|
||||
define pcodeop vfmsub132ps_fma ;
|
||||
:VFMSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9A; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104382
|
||||
define pcodeop vfmsub213ps_fma ;
|
||||
:VFMSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104385
|
||||
define pcodeop vfmsub231ps_fma ;
|
||||
:VFMSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfmsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104388
|
||||
:VFMSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9A; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104391
|
||||
:VFMSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAA; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132PS/VFMSUB213PS/VFMSUB231PS 5-186 PAGE 2010 LINE 104394
|
||||
# WARNING: did not recognize VEX field 0 for "VFMSUB231PS ymm1, ymm2, ymm3/m256"
|
||||
:VFMSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBA; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfmsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104738
|
||||
define pcodeop vfmsub132sd_fma ;
|
||||
:VFMSUB132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9B; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmsub132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104741
|
||||
define pcodeop vfmsub213sd_fma ;
|
||||
:VFMSUB213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAB; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmsub213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SD/VFMSUB213SD/VFMSUB231SD 5-193 PAGE 2017 LINE 104744
|
||||
define pcodeop vfmsub231sd_fma ;
|
||||
:VFMSUB231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBB; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfmsub231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104913
|
||||
define pcodeop vfmsub132ss_fma ;
|
||||
:VFMSUB132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9B; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmsub132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104916
|
||||
define pcodeop vfmsub213ss_fma ;
|
||||
:VFMSUB213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAB; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmsub213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFMSUB132SS/VFMSUB213SS/VFMSUB231SS 5-196 PAGE 2020 LINE 104919
|
||||
define pcodeop vfmsub231ss_fma ;
|
||||
:VFMSUB231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBB; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfmsub231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105088
|
||||
define pcodeop vfnmadd132pd_fma ;
|
||||
:VFNMADD132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105091
|
||||
define pcodeop vfnmadd213pd_fma ;
|
||||
:VFNMADD213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105094
|
||||
define pcodeop vfnmadd231pd_fma ;
|
||||
:VFNMADD231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105097
|
||||
:VFNMADD132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9C; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105100
|
||||
:VFNMADD213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAC; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PD/VFNMADD213PD/VFNMADD231PD 5-199 PAGE 2023 LINE 105103
|
||||
:VFNMADD231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBC; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105447
|
||||
define pcodeop vfnmadd132ps_fma ;
|
||||
:VFNMADD132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9C; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105450
|
||||
define pcodeop vfnmadd213ps_fma ;
|
||||
:VFNMADD213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105453
|
||||
define pcodeop vfnmadd231ps_fma ;
|
||||
:VFNMADD231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmadd231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105456
|
||||
:VFNMADD132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9C; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105459
|
||||
:VFNMADD213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAC; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132PS/VFNMADD213PS/VFNMADD231PS 5-206 PAGE 2030 LINE 105462
|
||||
# WARNING: did not recognize VEX field 0 for "VFNMADD231PS ymm1, ymm2, ymm3/m256"
|
||||
:VFNMADD231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBC; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmadd231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105794
|
||||
define pcodeop vfnmadd132sd_fma ;
|
||||
:VFNMADD132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9D; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmadd132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105797
|
||||
define pcodeop vfnmadd213sd_fma ;
|
||||
:VFNMADD213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAD; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmadd213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SD/VFNMADD213SD/VFNMADD231SD 5-212 PAGE 2036 LINE 105800
|
||||
define pcodeop vfnmadd231sd_fma ;
|
||||
:VFNMADD231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBD; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmadd231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105966
|
||||
define pcodeop vfnmadd132ss_fma ;
|
||||
:VFNMADD132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9D; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmadd132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105969
|
||||
define pcodeop vfnmadd213ss_fma ;
|
||||
:VFNMADD213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAD; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmadd213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMADD132SS/VFNMADD213SS/VFNMADD231SS 5-215 PAGE 2039 LINE 105972
|
||||
define pcodeop vfnmadd231ss_fma ;
|
||||
:VFNMADD231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBD; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmadd231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106138
|
||||
define pcodeop vfnmsub132pd_fma ;
|
||||
:VFNMSUB132PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub132pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106141
|
||||
define pcodeop vfnmsub213pd_fma ;
|
||||
:VFNMSUB213PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub213pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106144
|
||||
define pcodeop vfnmsub231pd_fma ;
|
||||
:VFNMSUB231PD XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub231pd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106147
|
||||
:VFNMSUB132PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x9E; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub132pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106150
|
||||
:VFNMSUB213PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xAE; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub213pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PD/VFNMSUB213PD/VFNMSUB231PD 5-218 PAGE 2042 LINE 106153
|
||||
:VFNMSUB231PD YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0xBE; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub231pd_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106487
|
||||
define pcodeop vfnmsub132ps_fma ;
|
||||
:VFNMSUB132PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9E; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub132ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106490
|
||||
define pcodeop vfnmsub213ps_fma ;
|
||||
:VFNMSUB213PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub213ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106493
|
||||
define pcodeop vfnmsub231ps_fma ;
|
||||
:VFNMSUB231PS XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 is $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBE; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
local tmp:16 = vfnmsub231ps_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m128 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106496
|
||||
:VFNMSUB132PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0x9E; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub132ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106499
|
||||
:VFNMSUB213PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_YmmReg; byte=0xAE; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub213ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS 5-224 PAGE 2048 LINE 106502
|
||||
# WARNING: did not recognize VEX field 0 for "VFNMSUB231PS ymm1, ymm2, ymm3/m256"
|
||||
:VFNMSUB231PS YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 is $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & vexVVVV_YmmReg; byte=0xBE; YmmReg1 ... & YmmReg2_m256
|
||||
{
|
||||
YmmReg1 = vfnmsub231ps_fma( YmmReg1, vexVVVV_YmmReg, YmmReg2_m256 );
|
||||
# TODO ZmmReg1 = zext(YmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106832
|
||||
define pcodeop vfnmsub132sd_fma ;
|
||||
:VFNMSUB132SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x9F; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmsub132sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106835
|
||||
define pcodeop vfnmsub213sd_fma ;
|
||||
:VFNMSUB213SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xAF; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmsub213sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SD/VFNMSUB213SD/VFNMSUB231SD 5-230 PAGE 2054 LINE 106838
|
||||
define pcodeop vfnmsub231sd_fma ;
|
||||
:VFNMSUB231SD XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0xBF; (XmmReg1 & YmmReg1) ... & XmmReg2_m64
|
||||
{
|
||||
local tmp:16 = vfnmsub231sd_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m64 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107004
|
||||
define pcodeop vfnmsub132ss_fma ;
|
||||
:VFNMSUB132SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x9F; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmsub132ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107007
|
||||
define pcodeop vfnmsub213ss_fma ;
|
||||
:VFNMSUB213SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xAF; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmsub213ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
# VFNMSUB132SS/VFNMSUB213SS/VFNMSUB231SS 5-233 PAGE 2057 LINE 107010
|
||||
define pcodeop vfnmsub231ss_fma ;
|
||||
:VFNMSUB231SS XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 is $(VEX_LIG) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0xBF; (XmmReg1 & YmmReg1) ... & XmmReg2_m32
|
||||
{
|
||||
local tmp:16 = vfnmsub231ss_fma( XmmReg1, vexVVVV_XmmReg, XmmReg2_m32 );
|
||||
YmmReg1 = zext(tmp);
|
||||
# TODO ZmmReg1 = zext(XmmReg1)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
macro lzcntflags(input, output) {
|
||||
ZF = (output == 0);
|
||||
CF = (input == 0);
|
||||
# OF, SF, PF, AF are undefined
|
||||
}
|
||||
|
||||
####
|
||||
#### LZCNT instructions
|
||||
####
|
||||
|
||||
|
||||
:LZCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_66) & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg16 ... & rm16 {
|
||||
|
||||
Reg16 = lzcount(rm16);
|
||||
lzcntflags(rm16, Reg16);
|
||||
}
|
||||
|
||||
:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & check_Reg32_dest ... & rm32 {
|
||||
|
||||
Reg32 = lzcount(rm32);
|
||||
lzcntflags(rm32, Reg32);
|
||||
build check_Reg32_dest;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
:LZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 {
|
||||
|
||||
Reg64 = lzcount(rm64);
|
||||
lzcntflags(rm64, Reg64);
|
||||
}
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
macro conditionalAssign(dest, cond, trueVal, falseVal) {
|
||||
dest = zext(cond) * trueVal | zext(!cond) * falseVal;
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
define pcodeop br_exception;
|
||||
|
||||
|
||||
# BNDMK needs the base address register only
|
||||
# - if no base register, needs 0
|
||||
|
||||
@ifdef IA64
|
||||
bndmk_addr64: [Rmr64] is mod=0 & Rmr64 { export Rmr64; }
|
||||
bndmk_addr64: [Rmr64 + simm8_64] is mod=1 & Rmr64; simm8_64 { export Rmr64; }
|
||||
bndmk_addr64: [simm32_64 + Rmr64] is mod=2 & Rmr64; simm32_64 { export Rmr64; }
|
||||
bndmk_addr64: [Rmr64] is mod=1 & r_m!=4 & Rmr64; simm8=0 { export Rmr64; }
|
||||
bndmk_addr64: [Rmr64] is mod=2 & r_m!=4 & Rmr64; simm32=0 { export Rmr64; }
|
||||
#invalid bndmk_addr64: [riprel] is mod=0 & r_m=5; simm32 [ riprel=inst_next+simm32; ] { export *[const]:8 riprel; }
|
||||
bndmk_addr64: [Base64 + Index64*ss] is mod=0 & r_m=4; Index64 & Base64 & ss { export Base64; }
|
||||
bndmk_addr64: [Base64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & Base64 { export Base64; }
|
||||
bndmk_addr64: [simm32_64 + Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; simm32_64 { tmp:8 = 0; export tmp; }
|
||||
bndmk_addr64: [Index64*ss] is mod=0 & r_m=4; Index64 & base64=5 & ss; imm32=0 { tmp:8 = 0; export tmp; }
|
||||
bndmk_addr64: [simm32_64] is mod=0 & r_m=4; rexXprefix=0 & index64=4 & base64=5; simm32_64 { tmp:8 = 0; export tmp; }
|
||||
bndmk_addr64: [Base64 + Index64*ss + simm8_64] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8_64 { export Base64; }
|
||||
bndmk_addr64: [Base64 + Index64*ss] is mod=1 & r_m=4; Index64 & Base64 & ss; simm8=0 { export Base64; }
|
||||
bndmk_addr64: [Base64 + simm8_64] is mod=1 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm8_64 { export Base64; }
|
||||
bndmk_addr64: [simm32_64 + Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; simm32_64 { export Base64; }
|
||||
bndmk_addr64: [simm32_64 + Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm32_64 { export Base64; }
|
||||
bndmk_addr64: [Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; imm32=0 { export Base64; }
|
||||
bndmk_addr64: [Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; imm32=0 { export Base64; }
|
||||
@endif
|
||||
|
||||
bndmk_addr32: [Rmr32] is mod=0 & Rmr32 { export Rmr32; }
|
||||
bndmk_addr32: [Rmr32 + simm8_32] is mod=1 & Rmr32; simm8_32 { export Rmr32; }
|
||||
bndmk_addr32: [Rmr32] is mod=1 & r_m!=4 & Rmr32; simm8=0 { export Rmr32; }
|
||||
bndmk_addr32: [imm32 + Rmr32] is mod=2 & Rmr32; imm32 { export Rmr32; }
|
||||
bndmk_addr32: [Rmr32] is mod=2 & r_m!=4 & Rmr32; imm32=0 { export Rmr32; }
|
||||
bndmk_addr32: [imm32] is mod=0 & r_m=5; imm32 { tmp:4 = 0; export tmp; }
|
||||
bndmk_addr32: [Base + Index*ss] is mod=0 & r_m=4; Index & Base & ss { export Base; }
|
||||
bndmk_addr32: [Base] is mod=0 & r_m=4; index=4 & Base { export Base; }
|
||||
bndmk_addr32: [imm32 + Index*ss] is mod=0 & r_m=4; Index & base=5 & ss; imm32 { tmp:4 = 0; export tmp; }
|
||||
bndmk_addr32: [imm32] is mod=0 & r_m=4; index=4 & base=5; imm32 { tmp:4 = 0; export tmp; }
|
||||
bndmk_addr32: [Base + Index*ss + simm8_32] is mod=1 & r_m=4; Index & Base & ss; simm8_32 { export Base; }
|
||||
bndmk_addr32: [Base + simm8_32] is mod=1 & r_m=4; index=4 & Base; simm8_32 { export Base; }
|
||||
bndmk_addr32: [Base + Index*ss] is mod=1 & r_m=4; Index & Base & ss; simm8=0 { export Base; }
|
||||
bndmk_addr32: [Base] is mod=1 & r_m=4; index=4 & Base; simm8=0 { export Base; }
|
||||
bndmk_addr32: [imm32 + Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32 { export Base; }
|
||||
bndmk_addr32: [imm32 + Base] is mod=2 & r_m=4; index=4 & Base; imm32 { export Base; }
|
||||
bndmk_addr32: [Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32=0 { export Base; }
|
||||
bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export Base; }
|
||||
|
||||
|
||||
|
||||
@ifdef IA64
|
||||
|
||||
:BNDCL bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr64 {
|
||||
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Rmr64 < bnd1_lb) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCL bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
||||
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Mem < bnd1_lb) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCU bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
||||
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Rmr64 > ~bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCU bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
||||
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Mem > ~bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCN bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
||||
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Rmr64 > bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCN bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
||||
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(Mem > bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
#TODO: This probably cannot be fully modeled
|
||||
:BNDLDX bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1A; bnd1 ... & Mem {
|
||||
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
||||
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
||||
|
||||
# core implementation
|
||||
bnd1 = *:16 Mem;
|
||||
}
|
||||
|
||||
:BNDMK bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr64 & Mem ) {
|
||||
# BND.LB and BND.UB set from m64
|
||||
bnd1_lb = bndmk_addr64;
|
||||
bnd1_ub = Mem;
|
||||
}
|
||||
|
||||
:BNDMOV bnd1, m128 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; bnd1 ... & m128 {
|
||||
bnd1 = m128;
|
||||
}
|
||||
|
||||
:BNDMOV bnd1, bnd2 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
||||
bnd1 = bnd2;
|
||||
}
|
||||
|
||||
:BNDMOV m128, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; bnd1 ... & m128 {
|
||||
m128 = bnd1;
|
||||
}
|
||||
|
||||
:BNDMOV bnd2, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
||||
bnd2 = bnd1;
|
||||
}
|
||||
|
||||
#TODO: This probably cannot be fully modeled
|
||||
:BNDSTX Mem, bnd1 is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1B; bnd1 ... & Mem {
|
||||
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
||||
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
||||
|
||||
# core implementation
|
||||
*:16 Mem = bnd1;
|
||||
}
|
||||
|
||||
@endif
|
||||
|
||||
:BNDCL bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr32 {
|
||||
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Rmr32) < bnd1_lb) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCL bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
||||
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Mem) < bnd1_lb) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCU bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
||||
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Rmr32) > ~bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCU bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
||||
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Mem) > ~bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCN bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
||||
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Rmr32) > bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
:BNDCN bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
||||
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||
if !(zext(Mem) > bnd1_ub) goto <done>;
|
||||
BNDSTATUS = 0x01;
|
||||
br_exception();
|
||||
<done>
|
||||
}
|
||||
|
||||
#TODO: This probably cannot be fully modeled
|
||||
:BNDLDX bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
||||
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
||||
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
||||
|
||||
# core implementation
|
||||
tmp:8 = *:8 Mem;
|
||||
bnd1_lb = zext(tmp:4);
|
||||
tmp2:4 = tmp(4);
|
||||
bnd1_ub = zext(tmp2);
|
||||
}
|
||||
|
||||
:BNDMK bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr32 & Mem ) {
|
||||
# BND.LB and BND.UB set from m32
|
||||
bnd1_lb = zext(bndmk_addr32);
|
||||
bnd1_ub = zext(Mem);
|
||||
}
|
||||
|
||||
:BNDMOV bnd1, m64 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
||||
tmp:8 = m64;
|
||||
bnd1_lb = zext(tmp:4);
|
||||
tmp2:4 = tmp(4);
|
||||
bnd1_ub = zext(tmp2);
|
||||
}
|
||||
|
||||
:BNDMOV bnd1, bnd2 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
||||
bnd1 = bnd2;
|
||||
}
|
||||
|
||||
:BNDMOV m64, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
||||
m64 = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
||||
}
|
||||
|
||||
:BNDMOV bnd2, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
||||
bnd2 = bnd1;
|
||||
}
|
||||
|
||||
#TODO: This probably cannot be fully modeled
|
||||
:BNDSTX Mem, bnd1 is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
||||
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
||||
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
||||
|
||||
# core implementation
|
||||
*:8 Mem = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language version="1" endian="little">
|
||||
<description>
|
||||
<id>x86:LE:16:Real Mode</id>
|
||||
<processor>x86</processor>
|
||||
</description>
|
||||
<compiler name="default" id="default"/>
|
||||
<spaces>
|
||||
<segmented_space name="ram" default="yes" />
|
||||
<space name="register" type="register" size="4" />
|
||||
</spaces>
|
||||
<registers>
|
||||
<context_register name="contextreg" offset="0x2000" bitsize="32">
|
||||
<field name="lockprefx" range="8,8" />
|
||||
<field name="repprefx" range="7,7" />
|
||||
<field name="repneprefx" range="6,6" />
|
||||
<field name="sstype" range="5,5" />
|
||||
<field name="segover" range="2,4" />
|
||||
<field name="opsize" range="1,1" />
|
||||
<field name="addrsize" range="0,0" />
|
||||
</context_register>
|
||||
<register name="EAX" offset="0x0" bitsize="32" />
|
||||
<register name="ECX" offset="0x4" bitsize="32" />
|
||||
<register name="EDX" offset="0x8" bitsize="32" />
|
||||
<register name="EBX" offset="0xc" bitsize="32" />
|
||||
<register name="ESP" offset="0x10" bitsize="32" />
|
||||
<register name="EBP" offset="0x14" bitsize="32" />
|
||||
<register name="ESI" offset="0x18" bitsize="32" />
|
||||
<register name="EDI" offset="0x1c" bitsize="32" />
|
||||
<register name="AX" offset="0x0" bitsize="16" />
|
||||
<register name="CX" offset="0x4" bitsize="16" />
|
||||
<register name="DX" offset="0x8" bitsize="16" />
|
||||
<register name="BX" offset="0xc" bitsize="16" />
|
||||
<register name="SP" offset="0x10" bitsize="16" />
|
||||
<register name="BP" offset="0x14" bitsize="16" />
|
||||
<register name="SI" offset="0x18" bitsize="16" />
|
||||
<register name="DI" offset="0x1c" bitsize="16" />
|
||||
<register name="AL" offset="0x0" bitsize="8" />
|
||||
<register name="AH" offset="0x1" bitsize="8" />
|
||||
<register name="CL" offset="0x4" bitsize="8" />
|
||||
<register name="CH" offset="0x5" bitsize="8" />
|
||||
<register name="DL" offset="0x8" bitsize="8" />
|
||||
<register name="DH" offset="0x9" bitsize="8" />
|
||||
<register name="BL" offset="0xc" bitsize="8" />
|
||||
<register name="BH" offset="0xd" bitsize="8" />
|
||||
<register name="ES" offset="0x100" bitsize="16" />
|
||||
<register name="CS" offset="0x102" bitsize="16" />
|
||||
<register name="SS" offset="0x104" bitsize="16" />
|
||||
<register name="DS" offset="0x106" bitsize="16" />
|
||||
<register name="FS" offset="0x108" bitsize="16" />
|
||||
<register name="GS" offset="0x10a" bitsize="16" />
|
||||
<register name="FS_OFFSET" offset="0x110" bitsize="32" />
|
||||
<register name="CF" offset="0x200" bitsize="8" />
|
||||
<register name="F1" offset="0x201" bitsize="8" />
|
||||
<register name="PF" offset="0x202" bitsize="8" />
|
||||
<register name="F3" offset="0x203" bitsize="8" />
|
||||
<register name="AF" offset="0x204" bitsize="8" />
|
||||
<register name="F5" offset="0x205" bitsize="8" />
|
||||
<register name="ZF" offset="0x206" bitsize="8" />
|
||||
<register name="SF" offset="0x207" bitsize="8" />
|
||||
<register name="TF" offset="0x208" bitsize="8" />
|
||||
<register name="IF" offset="0x209" bitsize="8" />
|
||||
<register name="DF" offset="0x20a" bitsize="8" />
|
||||
<register name="OF" offset="0x20b" bitsize="8" />
|
||||
<register name="IOPL" offset="0x20c" bitsize="8" />
|
||||
<register name="NT" offset="0x20d" bitsize="8" />
|
||||
<register name="F15" offset="0x20e" bitsize="8" />
|
||||
<register name="RF" offset="0x20f" bitsize="8" />
|
||||
<register name="VM" offset="0x210" bitsize="8" />
|
||||
<register name="AC" offset="0x211" bitsize="8" />
|
||||
<register name="VIF" offset="0x212" bitsize="8" />
|
||||
<register name="VIP" offset="0x213" bitsize="8" />
|
||||
<register name="ID" offset="0x214" bitsize="8" />
|
||||
<register name="eflags" offset="0x280" bitsize="32" />
|
||||
<register name="EIP" offset="0x284" bitsize="32" />
|
||||
<register name="flags" offset="0x280" bitsize="16" />
|
||||
<register name="IP" offset="0x284" bitsize="16" />
|
||||
<register name="DR0" offset="0x300" bitsize="32" />
|
||||
<register name="DR1" offset="0x304" bitsize="32" />
|
||||
<register name="DR2" offset="0x308" bitsize="32" />
|
||||
<register name="DR3" offset="0x30c" bitsize="32" />
|
||||
<register name="DR4" offset="0x310" bitsize="32" />
|
||||
<register name="DR5" offset="0x314" bitsize="32" />
|
||||
<register name="DR6" offset="0x318" bitsize="32" />
|
||||
<register name="DR7" offset="0x31c" bitsize="32" />
|
||||
<register name="CR0" offset="0x320" bitsize="32" />
|
||||
<register name="CR2" offset="0x328" bitsize="32" />
|
||||
<register name="CR3" offset="0x32c" bitsize="32" />
|
||||
<register name="CR4" offset="0x330" bitsize="32" />
|
||||
<register name="TR0" offset="0x400" bitsize="32" />
|
||||
<register name="TR1" offset="0x404" bitsize="32" />
|
||||
<register name="TR2" offset="0x408" bitsize="32" />
|
||||
<register name="TR3" offset="0x40c" bitsize="32" />
|
||||
<register name="TR4" offset="0x410" bitsize="32" />
|
||||
<register name="TR5" offset="0x414" bitsize="32" />
|
||||
<register name="TR6" offset="0x418" bitsize="32" />
|
||||
<register name="TR7" offset="0x41c" bitsize="32" />
|
||||
<register name="ST0" offset="0x1000" bitsize="80" />
|
||||
<register name="ST1" offset="0x100a" bitsize="80" />
|
||||
<register name="ST2" offset="0x1014" bitsize="80" />
|
||||
<register name="ST3" offset="0x101e" bitsize="80" />
|
||||
<register name="ST4" offset="0x1028" bitsize="80" />
|
||||
<register name="ST5" offset="0x1032" bitsize="80" />
|
||||
<register name="ST6" offset="0x103c" bitsize="80" />
|
||||
<register name="ST7" offset="0x1046" bitsize="80" />
|
||||
<register name="FPUControlWord" offset="0x1090" bitsize="16" />
|
||||
<register name="FPUStatusWord" offset="0x1092" bitsize="16" />
|
||||
<register name="FPUTagWord" offset="0x1094" bitsize="16" />
|
||||
<register name="FPUDataPointer" offset="0x1096" bitsize="16" />
|
||||
<register name="FPUInstructionPointer" offset="0x1098" bitsize="16" />
|
||||
<register name="FPULastInstructionOpcode" offset="0x109a" bitsize="16" />
|
||||
<register name="MM0" offset="0x1100" bitsize="64" />
|
||||
<register name="MM1" offset="0x1108" bitsize="64" />
|
||||
<register name="MM2" offset="0x1110" bitsize="64" />
|
||||
<register name="MM3" offset="0x1118" bitsize="64" />
|
||||
<register name="MM4" offset="0x1120" bitsize="64" />
|
||||
<register name="MM5" offset="0x1128" bitsize="64" />
|
||||
<register name="MM6" offset="0x1130" bitsize="64" />
|
||||
<register name="MM7" offset="0x1138" bitsize="64" />
|
||||
<register name="XMM0" offset="0x1200" bitsize="128" />
|
||||
<register name="XMM1" offset="0x1210" bitsize="128" />
|
||||
<register name="XMM2" offset="0x1220" bitsize="128" />
|
||||
<register name="XMM3" offset="0x1230" bitsize="128" />
|
||||
<register name="XMM4" offset="0x1240" bitsize="128" />
|
||||
<register name="XMM5" offset="0x1250" bitsize="128" />
|
||||
<register name="XMM6" offset="0x1260" bitsize="128" />
|
||||
<register name="XMM7" offset="0x1270" bitsize="128" />
|
||||
<register name="XMM8" offset="0x1280" bitsize="128" />
|
||||
<register name="XMM9" offset="0x1290" bitsize="128" />
|
||||
<register name="XMM10" offset="0x12a0" bitsize="128" />
|
||||
<register name="XMM11" offset="0x12b0" bitsize="128" />
|
||||
<register name="XMM12" offset="0x12c0" bitsize="128" />
|
||||
<register name="XMM13" offset="0x12d0" bitsize="128" />
|
||||
<register name="XMM14" offset="0x12e0" bitsize="128" />
|
||||
<register name="XMM15" offset="0x12f0" bitsize="128" />
|
||||
<register name="IDTR" offset="0x2200" bitsize="48" />
|
||||
<register name="IDTR_Limit" offset="0x2200" bitsize="16" />
|
||||
<register name="IDTR_Address" offset="0x2202" bitsize="32" />
|
||||
<register name="GDTR" offset="0x2210" bitsize="48" />
|
||||
<register name="GDTR_Limit" offset="0x2210" bitsize="16" />
|
||||
<register name="GDTR_Address" offset="0x2212" bitsize="32" />
|
||||
<register name="LDTR" offset="0x2220" bitsize="48" />
|
||||
<register name="LDTR_Limit" offset="0x2220" bitsize="16" />
|
||||
<register name="LDTR_Address" offset="0x2222" bitsize="32" />
|
||||
<register name="TR" offset="0x2230" bitsize="48" />
|
||||
<register name="TR_Limit" offset="0x2230" bitsize="16" />
|
||||
<register name="TR_Address" offset="0x2232" bitsize="32" />
|
||||
</registers>
|
||||
</language>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language_translation>
|
||||
<from_language version="1">x86:LE:16:Real Mode</from_language>
|
||||
<to_language version="2">x86:LE:16:Real Mode</to_language>
|
||||
<map_compiler_spec from="default" to="default" />
|
||||
</language_translation>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language version="1" endian="little">
|
||||
<description>
|
||||
<id>x86:LE:32:default</id>
|
||||
<processor>x86</processor>
|
||||
</description>
|
||||
<compiler name="Visual Studio" id="windows"/>
|
||||
<compiler name="gcc" id="gcc"/>
|
||||
<spaces>
|
||||
<space name="ram" type="ram" size="4" default="yes" />
|
||||
<space name="register" type="register" size="4" />
|
||||
</spaces>
|
||||
<registers>
|
||||
<context_register name="contextreg" offset="0x2000" bitsize="32">
|
||||
<field name="lockprefx" range="8,8" />
|
||||
<field name="repprefx" range="7,7" />
|
||||
<field name="repneprefx" range="6,6" />
|
||||
<field name="sstype" range="5,5" />
|
||||
<field name="segover" range="2,4" />
|
||||
<field name="opsize" range="1,1" />
|
||||
<field name="addrsize" range="0,0" />
|
||||
</context_register>
|
||||
<register name="EAX" offset="0x0" bitsize="32" />
|
||||
<register name="ECX" offset="0x4" bitsize="32" />
|
||||
<register name="EDX" offset="0x8" bitsize="32" />
|
||||
<register name="EBX" offset="0xc" bitsize="32" />
|
||||
<register name="ESP" offset="0x10" bitsize="32" />
|
||||
<register name="EBP" offset="0x14" bitsize="32" />
|
||||
<register name="ESI" offset="0x18" bitsize="32" />
|
||||
<register name="EDI" offset="0x1c" bitsize="32" />
|
||||
<register name="AX" offset="0x0" bitsize="16" />
|
||||
<register name="CX" offset="0x4" bitsize="16" />
|
||||
<register name="DX" offset="0x8" bitsize="16" />
|
||||
<register name="BX" offset="0xc" bitsize="16" />
|
||||
<register name="SP" offset="0x10" bitsize="16" />
|
||||
<register name="BP" offset="0x14" bitsize="16" />
|
||||
<register name="SI" offset="0x18" bitsize="16" />
|
||||
<register name="DI" offset="0x1c" bitsize="16" />
|
||||
<register name="AL" offset="0x0" bitsize="8" />
|
||||
<register name="AH" offset="0x1" bitsize="8" />
|
||||
<register name="CL" offset="0x4" bitsize="8" />
|
||||
<register name="CH" offset="0x5" bitsize="8" />
|
||||
<register name="DL" offset="0x8" bitsize="8" />
|
||||
<register name="DH" offset="0x9" bitsize="8" />
|
||||
<register name="BL" offset="0xc" bitsize="8" />
|
||||
<register name="BH" offset="0xd" bitsize="8" />
|
||||
<register name="ES" offset="0x100" bitsize="16" />
|
||||
<register name="CS" offset="0x102" bitsize="16" />
|
||||
<register name="SS" offset="0x104" bitsize="16" />
|
||||
<register name="DS" offset="0x106" bitsize="16" />
|
||||
<register name="FS" offset="0x108" bitsize="16" />
|
||||
<register name="GS" offset="0x10a" bitsize="16" />
|
||||
<register name="FS_OFFSET" offset="0x110" bitsize="32" />
|
||||
<register name="CF" offset="0x200" bitsize="8" />
|
||||
<register name="F1" offset="0x201" bitsize="8" />
|
||||
<register name="PF" offset="0x202" bitsize="8" />
|
||||
<register name="F3" offset="0x203" bitsize="8" />
|
||||
<register name="AF" offset="0x204" bitsize="8" />
|
||||
<register name="F5" offset="0x205" bitsize="8" />
|
||||
<register name="ZF" offset="0x206" bitsize="8" />
|
||||
<register name="SF" offset="0x207" bitsize="8" />
|
||||
<register name="TF" offset="0x208" bitsize="8" />
|
||||
<register name="IF" offset="0x209" bitsize="8" />
|
||||
<register name="DF" offset="0x20a" bitsize="8" />
|
||||
<register name="OF" offset="0x20b" bitsize="8" />
|
||||
<register name="IOPL" offset="0x20c" bitsize="8" />
|
||||
<register name="NT" offset="0x20d" bitsize="8" />
|
||||
<register name="F15" offset="0x20e" bitsize="8" />
|
||||
<register name="RF" offset="0x20f" bitsize="8" />
|
||||
<register name="VM" offset="0x210" bitsize="8" />
|
||||
<register name="AC" offset="0x211" bitsize="8" />
|
||||
<register name="VIF" offset="0x212" bitsize="8" />
|
||||
<register name="VIP" offset="0x213" bitsize="8" />
|
||||
<register name="ID" offset="0x214" bitsize="8" />
|
||||
<register name="eflags" offset="0x280" bitsize="32" />
|
||||
<register name="EIP" offset="0x284" bitsize="32" />
|
||||
<register name="flags" offset="0x280" bitsize="16" />
|
||||
<register name="IP" offset="0x284" bitsize="16" />
|
||||
<register name="DR0" offset="0x300" bitsize="32" />
|
||||
<register name="DR1" offset="0x304" bitsize="32" />
|
||||
<register name="DR2" offset="0x308" bitsize="32" />
|
||||
<register name="DR3" offset="0x30c" bitsize="32" />
|
||||
<register name="DR4" offset="0x310" bitsize="32" />
|
||||
<register name="DR5" offset="0x314" bitsize="32" />
|
||||
<register name="DR6" offset="0x318" bitsize="32" />
|
||||
<register name="DR7" offset="0x31c" bitsize="32" />
|
||||
<register name="CR0" offset="0x320" bitsize="32" />
|
||||
<register name="CR2" offset="0x328" bitsize="32" />
|
||||
<register name="CR3" offset="0x32c" bitsize="32" />
|
||||
<register name="CR4" offset="0x330" bitsize="32" />
|
||||
<register name="TR0" offset="0x400" bitsize="32" />
|
||||
<register name="TR1" offset="0x404" bitsize="32" />
|
||||
<register name="TR2" offset="0x408" bitsize="32" />
|
||||
<register name="TR3" offset="0x40c" bitsize="32" />
|
||||
<register name="TR4" offset="0x410" bitsize="32" />
|
||||
<register name="TR5" offset="0x414" bitsize="32" />
|
||||
<register name="TR6" offset="0x418" bitsize="32" />
|
||||
<register name="TR7" offset="0x41c" bitsize="32" />
|
||||
<register name="ST0" offset="0x1000" bitsize="80" />
|
||||
<register name="ST1" offset="0x100a" bitsize="80" />
|
||||
<register name="ST2" offset="0x1014" bitsize="80" />
|
||||
<register name="ST3" offset="0x101e" bitsize="80" />
|
||||
<register name="ST4" offset="0x1028" bitsize="80" />
|
||||
<register name="ST5" offset="0x1032" bitsize="80" />
|
||||
<register name="ST6" offset="0x103c" bitsize="80" />
|
||||
<register name="ST7" offset="0x1046" bitsize="80" />
|
||||
<register name="FPUControlWord" offset="0x1090" bitsize="16" />
|
||||
<register name="FPUStatusWord" offset="0x1092" bitsize="16" />
|
||||
<register name="FPUTagWord" offset="0x1094" bitsize="16" />
|
||||
<register name="FPUDataPointer" offset="0x1096" bitsize="16" />
|
||||
<register name="FPUInstructionPointer" offset="0x1098" bitsize="16" />
|
||||
<register name="FPULastInstructionOpcode" offset="0x109a" bitsize="16" />
|
||||
<register name="MM0" offset="0x1100" bitsize="64" />
|
||||
<register name="MM1" offset="0x1108" bitsize="64" />
|
||||
<register name="MM2" offset="0x1110" bitsize="64" />
|
||||
<register name="MM3" offset="0x1118" bitsize="64" />
|
||||
<register name="MM4" offset="0x1120" bitsize="64" />
|
||||
<register name="MM5" offset="0x1128" bitsize="64" />
|
||||
<register name="MM6" offset="0x1130" bitsize="64" />
|
||||
<register name="MM7" offset="0x1138" bitsize="64" />
|
||||
<register name="XMM0" offset="0x1200" bitsize="128" />
|
||||
<register name="XMM1" offset="0x1210" bitsize="128" />
|
||||
<register name="XMM2" offset="0x1220" bitsize="128" />
|
||||
<register name="XMM3" offset="0x1230" bitsize="128" />
|
||||
<register name="XMM4" offset="0x1240" bitsize="128" />
|
||||
<register name="XMM5" offset="0x1250" bitsize="128" />
|
||||
<register name="XMM6" offset="0x1260" bitsize="128" />
|
||||
<register name="XMM7" offset="0x1270" bitsize="128" />
|
||||
<register name="XMM8" offset="0x1280" bitsize="128" />
|
||||
<register name="XMM9" offset="0x1290" bitsize="128" />
|
||||
<register name="XMM10" offset="0x12a0" bitsize="128" />
|
||||
<register name="XMM11" offset="0x12b0" bitsize="128" />
|
||||
<register name="XMM12" offset="0x12c0" bitsize="128" />
|
||||
<register name="XMM13" offset="0x12d0" bitsize="128" />
|
||||
<register name="XMM14" offset="0x12e0" bitsize="128" />
|
||||
<register name="XMM15" offset="0x12f0" bitsize="128" />
|
||||
<register name="IDTR" offset="0x2200" bitsize="48" />
|
||||
<register name="IDTR_Limit" offset="0x2200" bitsize="16" />
|
||||
<register name="IDTR_Address" offset="0x2202" bitsize="32" />
|
||||
<register name="GDTR" offset="0x2210" bitsize="48" />
|
||||
<register name="GDTR_Limit" offset="0x2210" bitsize="16" />
|
||||
<register name="GDTR_Address" offset="0x2212" bitsize="32" />
|
||||
<register name="LDTR" offset="0x2220" bitsize="48" />
|
||||
<register name="LDTR_Limit" offset="0x2220" bitsize="16" />
|
||||
<register name="LDTR_Address" offset="0x2222" bitsize="32" />
|
||||
<register name="TR" offset="0x2230" bitsize="48" />
|
||||
<register name="TR_Limit" offset="0x2230" bitsize="16" />
|
||||
<register name="TR_Address" offset="0x2232" bitsize="32" />
|
||||
</registers>
|
||||
</language>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language_translation>
|
||||
<from_language version="1">x86:LE:32:default</from_language>
|
||||
<to_language version="2">x86:LE:32:default</to_language>
|
||||
<map_compiler_spec from="windows" to="windows" />
|
||||
<map_compiler_spec from="gcc" to="gcc" />
|
||||
</language_translation>
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language version="1" endian="little">
|
||||
<description>
|
||||
<id>x64:LE:64:default</id>
|
||||
<processor>x64</processor>
|
||||
</description>
|
||||
<compiler name="Visual Studio" id="windows"/>
|
||||
<compiler name="gcc" id="gcc"/>
|
||||
<spaces>
|
||||
<space name="ram" type="ram" size="8" default="yes" />
|
||||
<space name="register" type="register" size="4" />
|
||||
</spaces>
|
||||
<registers>
|
||||
<context_register name="contextreg" offset="0x2000" bitsize="32">
|
||||
<field name="rexprefix" range="15,15" />
|
||||
<field name="rexBprefix" range="14,14" />
|
||||
<field name="rexXprefix" range="13,13" />
|
||||
<field name="rexRprefix" range="12,12" />
|
||||
<field name="rexWprefix" range="11,11" />
|
||||
<field name="lockprefx" range="10,10" />
|
||||
<field name="repprefx" range="9,9" />
|
||||
<field name="repneprefx" range="8,8" />
|
||||
<field name="sstype" range="7,7" />
|
||||
<field name="segover" range="4,6" />
|
||||
<field name="opsize" range="2,3" />
|
||||
<field name="addrsize" range="0,1" />
|
||||
<field name="bit64" range="0,0" />
|
||||
</context_register>
|
||||
<register name="RAX" offset="0x0" bitsize="64" />
|
||||
<register name="RCX" offset="0x8" bitsize="64" />
|
||||
<register name="RDX" offset="0x10" bitsize="64" />
|
||||
<register name="RBX" offset="0x18" bitsize="64" />
|
||||
<register name="RSP" offset="0x20" bitsize="64" />
|
||||
<register name="RBP" offset="0x28" bitsize="64" />
|
||||
<register name="RSI" offset="0x30" bitsize="64" />
|
||||
<register name="RDI" offset="0x38" bitsize="64" />
|
||||
<register name="EAX" offset="0x0" bitsize="32" />
|
||||
<register name="ECX" offset="0x8" bitsize="32" />
|
||||
<register name="EDX" offset="0x10" bitsize="32" />
|
||||
<register name="EBX" offset="0x18" bitsize="32" />
|
||||
<register name="ESP" offset="0x20" bitsize="32" />
|
||||
<register name="EBP" offset="0x28" bitsize="32" />
|
||||
<register name="ESI" offset="0x30" bitsize="32" />
|
||||
<register name="EDI" offset="0x38" bitsize="32" />
|
||||
<register name="AX" offset="0x0" bitsize="16" />
|
||||
<register name="CX" offset="0x8" bitsize="16" />
|
||||
<register name="DX" offset="0x10" bitsize="16" />
|
||||
<register name="BX" offset="0x18" bitsize="16" />
|
||||
<register name="SP" offset="0x20" bitsize="16" />
|
||||
<register name="BP" offset="0x28" bitsize="16" />
|
||||
<register name="SI" offset="0x30" bitsize="16" />
|
||||
<register name="DI" offset="0x38" bitsize="16" />
|
||||
<register name="AL" offset="0x0" bitsize="8" />
|
||||
<register name="AH" offset="0x1" bitsize="8" />
|
||||
<register name="CL" offset="0x8" bitsize="8" />
|
||||
<register name="CH" offset="0x9" bitsize="8" />
|
||||
<register name="DL" offset="0x10" bitsize="8" />
|
||||
<register name="DH" offset="0x11" bitsize="8" />
|
||||
<register name="BL" offset="0x18" bitsize="8" />
|
||||
<register name="BH" offset="0x19" bitsize="8" />
|
||||
<register name="SPL" offset="0x20" bitsize="8" />
|
||||
<register name="BPL" offset="0x28" bitsize="8" />
|
||||
<register name="SIL" offset="0x30" bitsize="8" />
|
||||
<register name="DIL" offset="0x38" bitsize="8" />
|
||||
<register name="R8" offset="0x80" bitsize="64" />
|
||||
<register name="R9" offset="0x88" bitsize="64" />
|
||||
<register name="R10" offset="0x90" bitsize="64" />
|
||||
<register name="R11" offset="0x98" bitsize="64" />
|
||||
<register name="R12" offset="0xa0" bitsize="64" />
|
||||
<register name="R13" offset="0xa8" bitsize="64" />
|
||||
<register name="R14" offset="0xb0" bitsize="64" />
|
||||
<register name="R15" offset="0xb8" bitsize="64" />
|
||||
<register name="R8D" offset="0x80" bitsize="32" />
|
||||
<register name="R9D" offset="0x88" bitsize="32" />
|
||||
<register name="R10D" offset="0x90" bitsize="32" />
|
||||
<register name="R11D" offset="0x98" bitsize="32" />
|
||||
<register name="R12D" offset="0xa0" bitsize="32" />
|
||||
<register name="R13D" offset="0xa8" bitsize="32" />
|
||||
<register name="R14D" offset="0xb0" bitsize="32" />
|
||||
<register name="R15D" offset="0xb8" bitsize="32" />
|
||||
<register name="R8W" offset="0x80" bitsize="16" />
|
||||
<register name="R9W" offset="0x88" bitsize="16" />
|
||||
<register name="R10W" offset="0x90" bitsize="16" />
|
||||
<register name="R11W" offset="0x98" bitsize="16" />
|
||||
<register name="R12W" offset="0xa0" bitsize="16" />
|
||||
<register name="R13W" offset="0xa8" bitsize="16" />
|
||||
<register name="R14W" offset="0xb0" bitsize="16" />
|
||||
<register name="R15W" offset="0xb8" bitsize="16" />
|
||||
<register name="R8B" offset="0x80" bitsize="8" />
|
||||
<register name="R9B" offset="0x88" bitsize="8" />
|
||||
<register name="R10B" offset="0x90" bitsize="8" />
|
||||
<register name="R11B" offset="0x98" bitsize="8" />
|
||||
<register name="R12B" offset="0xa0" bitsize="8" />
|
||||
<register name="R13B" offset="0xa8" bitsize="8" />
|
||||
<register name="R14B" offset="0xb0" bitsize="8" />
|
||||
<register name="R15B" offset="0xb8" bitsize="8" />
|
||||
<register name="ES" offset="0x100" bitsize="16" />
|
||||
<register name="CS" offset="0x102" bitsize="16" />
|
||||
<register name="SS" offset="0x104" bitsize="16" />
|
||||
<register name="DS" offset="0x106" bitsize="16" />
|
||||
<register name="FS" offset="0x108" bitsize="16" />
|
||||
<register name="GS" offset="0x10a" bitsize="16" />
|
||||
<register name="FS_OFFSET" offset="0x110" bitsize="32" />
|
||||
<register name="CF" offset="0x200" bitsize="8" />
|
||||
<register name="F1" offset="0x201" bitsize="8" />
|
||||
<register name="PF" offset="0x202" bitsize="8" />
|
||||
<register name="F3" offset="0x203" bitsize="8" />
|
||||
<register name="AF" offset="0x204" bitsize="8" />
|
||||
<register name="F5" offset="0x205" bitsize="8" />
|
||||
<register name="ZF" offset="0x206" bitsize="8" />
|
||||
<register name="SF" offset="0x207" bitsize="8" />
|
||||
<register name="TF" offset="0x208" bitsize="8" />
|
||||
<register name="IF" offset="0x209" bitsize="8" />
|
||||
<register name="DF" offset="0x20a" bitsize="8" />
|
||||
<register name="OF" offset="0x20b" bitsize="8" />
|
||||
<register name="IOPL" offset="0x20c" bitsize="8" />
|
||||
<register name="NT" offset="0x20d" bitsize="8" />
|
||||
<register name="F15" offset="0x20e" bitsize="8" />
|
||||
<register name="RF" offset="0x20f" bitsize="8" />
|
||||
<register name="VM" offset="0x210" bitsize="8" />
|
||||
<register name="AC" offset="0x211" bitsize="8" />
|
||||
<register name="VIF" offset="0x212" bitsize="8" />
|
||||
<register name="VIP" offset="0x213" bitsize="8" />
|
||||
<register name="ID" offset="0x214" bitsize="8" />
|
||||
<register name="rflags" offset="0x280" bitsize="64" />
|
||||
<register name="RIP" offset="0x288" bitsize="64" />
|
||||
<register name="eflags" offset="0x280" bitsize="32" />
|
||||
<register name="EIP" offset="0x288" bitsize="32" />
|
||||
<register name="flags" offset="0x280" bitsize="16" />
|
||||
<register name="IP" offset="0x288" bitsize="16" />
|
||||
<register name="DR0" offset="0x300" bitsize="64" />
|
||||
<register name="DR1" offset="0x308" bitsize="64" />
|
||||
<register name="DR2" offset="0x310" bitsize="64" />
|
||||
<register name="DR3" offset="0x318" bitsize="64" />
|
||||
<register name="DR4" offset="0x320" bitsize="64" />
|
||||
<register name="DR5" offset="0x328" bitsize="64" />
|
||||
<register name="DR6" offset="0x330" bitsize="64" />
|
||||
<register name="DR7" offset="0x338" bitsize="64" />
|
||||
<register name="DR8" offset="0x340" bitsize="64" />
|
||||
<register name="DR9" offset="0x348" bitsize="64" />
|
||||
<register name="DR10" offset="0x350" bitsize="64" />
|
||||
<register name="DR11" offset="0x358" bitsize="64" />
|
||||
<register name="DR12" offset="0x360" bitsize="64" />
|
||||
<register name="DR13" offset="0x368" bitsize="64" />
|
||||
<register name="DR14" offset="0x370" bitsize="64" />
|
||||
<register name="DR15" offset="0x378" bitsize="64" />
|
||||
<register name="CR0" offset="0x380" bitsize="64" />
|
||||
<register name="CR1" offset="0x388" bitsize="64" />
|
||||
<register name="CR2" offset="0x390" bitsize="64" />
|
||||
<register name="CR3" offset="0x398" bitsize="64" />
|
||||
<register name="CR4" offset="0x3a0" bitsize="64" />
|
||||
<register name="CR5" offset="0x3a8" bitsize="64" />
|
||||
<register name="CR6" offset="0x3b0" bitsize="64" />
|
||||
<register name="CR7" offset="0x3b8" bitsize="64" />
|
||||
<register name="CR8" offset="0x3c0" bitsize="64" />
|
||||
<register name="CR9" offset="0x3c8" bitsize="64" />
|
||||
<register name="CR10" offset="0x3d0" bitsize="64" />
|
||||
<register name="CR11" offset="0x3d8" bitsize="64" />
|
||||
<register name="CR12" offset="0x3e0" bitsize="64" />
|
||||
<register name="CR13" offset="0x3e8" bitsize="64" />
|
||||
<register name="CR14" offset="0x3f0" bitsize="64" />
|
||||
<register name="CR15" offset="0x3f8" bitsize="64" />
|
||||
<register name="ST0" offset="0x1000" bitsize="80" />
|
||||
<register name="ST1" offset="0x100a" bitsize="80" />
|
||||
<register name="ST2" offset="0x1014" bitsize="80" />
|
||||
<register name="ST3" offset="0x101e" bitsize="80" />
|
||||
<register name="ST4" offset="0x1028" bitsize="80" />
|
||||
<register name="ST5" offset="0x1032" bitsize="80" />
|
||||
<register name="ST6" offset="0x103c" bitsize="80" />
|
||||
<register name="ST7" offset="0x1046" bitsize="80" />
|
||||
<register name="C0" offset="0x1080" bitsize="8" />
|
||||
<register name="C1" offset="0x1081" bitsize="8" />
|
||||
<register name="C2" offset="0x1082" bitsize="8" />
|
||||
<register name="C3" offset="0x1083" bitsize="8" />
|
||||
<register name="FPUControlWord" offset="0x1090" bitsize="16" />
|
||||
<register name="FPUStatusWord" offset="0x1092" bitsize="16" />
|
||||
<register name="FPUTagWord" offset="0x1094" bitsize="16" />
|
||||
<register name="FPUDataPointer" offset="0x1096" bitsize="16" />
|
||||
<register name="FPUInstructionPointer" offset="0x1098" bitsize="16" />
|
||||
<register name="FPULastInstructionOpcode" offset="0x109a" bitsize="16" />
|
||||
<register name="MM0" offset="0x1100" bitsize="64" />
|
||||
<register name="MM1" offset="0x1108" bitsize="64" />
|
||||
<register name="MM2" offset="0x1110" bitsize="64" />
|
||||
<register name="MM3" offset="0x1118" bitsize="64" />
|
||||
<register name="MM4" offset="0x1120" bitsize="64" />
|
||||
<register name="MM5" offset="0x1128" bitsize="64" />
|
||||
<register name="MM6" offset="0x1130" bitsize="64" />
|
||||
<register name="MM7" offset="0x1138" bitsize="64" />
|
||||
<register name="XMM0" offset="0x1200" bitsize="128" />
|
||||
<register name="XMM1" offset="0x1210" bitsize="128" />
|
||||
<register name="XMM2" offset="0x1220" bitsize="128" />
|
||||
<register name="XMM3" offset="0x1230" bitsize="128" />
|
||||
<register name="XMM4" offset="0x1240" bitsize="128" />
|
||||
<register name="XMM5" offset="0x1250" bitsize="128" />
|
||||
<register name="XMM6" offset="0x1260" bitsize="128" />
|
||||
<register name="XMM7" offset="0x1270" bitsize="128" />
|
||||
<register name="XMM8" offset="0x1280" bitsize="128" />
|
||||
<register name="XMM9" offset="0x1290" bitsize="128" />
|
||||
<register name="XMM10" offset="0x12a0" bitsize="128" />
|
||||
<register name="XMM11" offset="0x12b0" bitsize="128" />
|
||||
<register name="XMM12" offset="0x12c0" bitsize="128" />
|
||||
<register name="XMM13" offset="0x12d0" bitsize="128" />
|
||||
<register name="XMM14" offset="0x12e0" bitsize="128" />
|
||||
<register name="XMM15" offset="0x12f0" bitsize="128" />
|
||||
<register name="IDTR_Limit" offset="0x2200" bitsize="32" />
|
||||
<register name="IDTR" offset="0x2200" bitsize="96" />
|
||||
<register name="IDTR_Address" offset="0x2204" bitsize="64" />
|
||||
<register name="GDTR_Limit" offset="0x2220" bitsize="32" />
|
||||
<register name="GDTR" offset="0x2220" bitsize="96" />
|
||||
<register name="GDTR_Address" offset="0x2224" bitsize="64" />
|
||||
<register name="LDTR_Limit" offset="0x2240" bitsize="32" />
|
||||
<register name="LDTR" offset="0x2240" bitsize="112" />
|
||||
<register name="LDTR_Address" offset="0x2244" bitsize="64" />
|
||||
<register name="LDTR_Attributes" offset="0x2248" bitsize="16" />
|
||||
<register name="TR_Limit" offset="0x2260" bitsize="32" />
|
||||
<register name="TR" offset="0x2260" bitsize="112" />
|
||||
<register name="TR_Address" offset="0x2264" bitsize="64" />
|
||||
<register name="TR_Attributes" offset="0x2268" bitsize="16" />
|
||||
</registers>
|
||||
</language>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language_translation>
|
||||
<from_language version="1">x64:LE:64:default</from_language>
|
||||
<to_language version="2">x86:LE:64:default</to_language>
|
||||
<map_compiler_spec from="windows" to="windows" />
|
||||
<map_compiler_spec from="gcc" to="gcc" />
|
||||
</language_translation>
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language version="1" endian="little">
|
||||
<description>
|
||||
<id>x86:LE:32:System Management Mode</id>
|
||||
<processor>x86</processor>
|
||||
</description>
|
||||
<compiler name="default" id="default"/>
|
||||
<spaces>
|
||||
<space name="ram" type="ram" size="4" default="yes" />
|
||||
<space name="register" type="register" size="4" />
|
||||
</spaces>
|
||||
<registers>
|
||||
<context_register name="contextreg" offset="0x2000" bitsize="32">
|
||||
<field name="lockprefx" range="8,8" />
|
||||
<field name="repprefx" range="7,7" />
|
||||
<field name="repneprefx" range="6,6" />
|
||||
<field name="sstype" range="5,5" />
|
||||
<field name="segover" range="2,4" />
|
||||
<field name="opsize" range="1,1" />
|
||||
<field name="addrsize" range="0,0" />
|
||||
</context_register>
|
||||
<register name="EAX" offset="0x0" bitsize="32" />
|
||||
<register name="ECX" offset="0x4" bitsize="32" />
|
||||
<register name="EDX" offset="0x8" bitsize="32" />
|
||||
<register name="EBX" offset="0xc" bitsize="32" />
|
||||
<register name="ESP" offset="0x10" bitsize="32" />
|
||||
<register name="EBP" offset="0x14" bitsize="32" />
|
||||
<register name="ESI" offset="0x18" bitsize="32" />
|
||||
<register name="EDI" offset="0x1c" bitsize="32" />
|
||||
<register name="AX" offset="0x0" bitsize="16" />
|
||||
<register name="CX" offset="0x4" bitsize="16" />
|
||||
<register name="DX" offset="0x8" bitsize="16" />
|
||||
<register name="BX" offset="0xc" bitsize="16" />
|
||||
<register name="SP" offset="0x10" bitsize="16" />
|
||||
<register name="BP" offset="0x14" bitsize="16" />
|
||||
<register name="SI" offset="0x18" bitsize="16" />
|
||||
<register name="DI" offset="0x1c" bitsize="16" />
|
||||
<register name="AL" offset="0x0" bitsize="8" />
|
||||
<register name="AH" offset="0x1" bitsize="8" />
|
||||
<register name="CL" offset="0x4" bitsize="8" />
|
||||
<register name="CH" offset="0x5" bitsize="8" />
|
||||
<register name="DL" offset="0x8" bitsize="8" />
|
||||
<register name="DH" offset="0x9" bitsize="8" />
|
||||
<register name="BL" offset="0xc" bitsize="8" />
|
||||
<register name="BH" offset="0xd" bitsize="8" />
|
||||
<register name="ES" offset="0x100" bitsize="16" />
|
||||
<register name="CS" offset="0x102" bitsize="16" />
|
||||
<register name="SS" offset="0x104" bitsize="16" />
|
||||
<register name="DS" offset="0x106" bitsize="16" />
|
||||
<register name="FS" offset="0x108" bitsize="16" />
|
||||
<register name="GS" offset="0x10a" bitsize="16" />
|
||||
<register name="FS_OFFSET" offset="0x110" bitsize="32" />
|
||||
<register name="CF" offset="0x200" bitsize="8" />
|
||||
<register name="F1" offset="0x201" bitsize="8" />
|
||||
<register name="PF" offset="0x202" bitsize="8" />
|
||||
<register name="F3" offset="0x203" bitsize="8" />
|
||||
<register name="AF" offset="0x204" bitsize="8" />
|
||||
<register name="F5" offset="0x205" bitsize="8" />
|
||||
<register name="ZF" offset="0x206" bitsize="8" />
|
||||
<register name="SF" offset="0x207" bitsize="8" />
|
||||
<register name="TF" offset="0x208" bitsize="8" />
|
||||
<register name="IF" offset="0x209" bitsize="8" />
|
||||
<register name="DF" offset="0x20a" bitsize="8" />
|
||||
<register name="OF" offset="0x20b" bitsize="8" />
|
||||
<register name="IOPL" offset="0x20c" bitsize="8" />
|
||||
<register name="NT" offset="0x20d" bitsize="8" />
|
||||
<register name="F15" offset="0x20e" bitsize="8" />
|
||||
<register name="RF" offset="0x20f" bitsize="8" />
|
||||
<register name="VM" offset="0x210" bitsize="8" />
|
||||
<register name="AC" offset="0x211" bitsize="8" />
|
||||
<register name="VIF" offset="0x212" bitsize="8" />
|
||||
<register name="VIP" offset="0x213" bitsize="8" />
|
||||
<register name="ID" offset="0x214" bitsize="8" />
|
||||
<register name="eflags" offset="0x280" bitsize="32" />
|
||||
<register name="EIP" offset="0x284" bitsize="32" />
|
||||
<register name="flags" offset="0x280" bitsize="16" />
|
||||
<register name="IP" offset="0x284" bitsize="16" />
|
||||
<register name="DR0" offset="0x300" bitsize="32" />
|
||||
<register name="DR1" offset="0x304" bitsize="32" />
|
||||
<register name="DR2" offset="0x308" bitsize="32" />
|
||||
<register name="DR3" offset="0x30c" bitsize="32" />
|
||||
<register name="DR4" offset="0x310" bitsize="32" />
|
||||
<register name="DR5" offset="0x314" bitsize="32" />
|
||||
<register name="DR6" offset="0x318" bitsize="32" />
|
||||
<register name="DR7" offset="0x31c" bitsize="32" />
|
||||
<register name="CR0" offset="0x320" bitsize="32" />
|
||||
<register name="CR2" offset="0x328" bitsize="32" />
|
||||
<register name="CR3" offset="0x32c" bitsize="32" />
|
||||
<register name="CR4" offset="0x330" bitsize="32" />
|
||||
<register name="TR0" offset="0x400" bitsize="32" />
|
||||
<register name="TR1" offset="0x404" bitsize="32" />
|
||||
<register name="TR2" offset="0x408" bitsize="32" />
|
||||
<register name="TR3" offset="0x40c" bitsize="32" />
|
||||
<register name="TR4" offset="0x410" bitsize="32" />
|
||||
<register name="TR5" offset="0x414" bitsize="32" />
|
||||
<register name="TR6" offset="0x418" bitsize="32" />
|
||||
<register name="TR7" offset="0x41c" bitsize="32" />
|
||||
<register name="ST0" offset="0x1000" bitsize="80" />
|
||||
<register name="ST1" offset="0x100a" bitsize="80" />
|
||||
<register name="ST2" offset="0x1014" bitsize="80" />
|
||||
<register name="ST3" offset="0x101e" bitsize="80" />
|
||||
<register name="ST4" offset="0x1028" bitsize="80" />
|
||||
<register name="ST5" offset="0x1032" bitsize="80" />
|
||||
<register name="ST6" offset="0x103c" bitsize="80" />
|
||||
<register name="ST7" offset="0x1046" bitsize="80" />
|
||||
<register name="FPUControlWord" offset="0x1090" bitsize="16" />
|
||||
<register name="FPUStatusWord" offset="0x1092" bitsize="16" />
|
||||
<register name="FPUTagWord" offset="0x1094" bitsize="16" />
|
||||
<register name="FPUDataPointer" offset="0x1096" bitsize="16" />
|
||||
<register name="FPUInstructionPointer" offset="0x1098" bitsize="16" />
|
||||
<register name="FPULastInstructionOpcode" offset="0x109a" bitsize="16" />
|
||||
<register name="MM0" offset="0x1100" bitsize="64" />
|
||||
<register name="MM1" offset="0x1108" bitsize="64" />
|
||||
<register name="MM2" offset="0x1110" bitsize="64" />
|
||||
<register name="MM3" offset="0x1118" bitsize="64" />
|
||||
<register name="MM4" offset="0x1120" bitsize="64" />
|
||||
<register name="MM5" offset="0x1128" bitsize="64" />
|
||||
<register name="MM6" offset="0x1130" bitsize="64" />
|
||||
<register name="MM7" offset="0x1138" bitsize="64" />
|
||||
<register name="XMM0" offset="0x1200" bitsize="128" />
|
||||
<register name="XMM1" offset="0x1210" bitsize="128" />
|
||||
<register name="XMM2" offset="0x1220" bitsize="128" />
|
||||
<register name="XMM3" offset="0x1230" bitsize="128" />
|
||||
<register name="XMM4" offset="0x1240" bitsize="128" />
|
||||
<register name="XMM5" offset="0x1250" bitsize="128" />
|
||||
<register name="XMM6" offset="0x1260" bitsize="128" />
|
||||
<register name="XMM7" offset="0x1270" bitsize="128" />
|
||||
<register name="XMM8" offset="0x1280" bitsize="128" />
|
||||
<register name="XMM9" offset="0x1290" bitsize="128" />
|
||||
<register name="XMM10" offset="0x12a0" bitsize="128" />
|
||||
<register name="XMM11" offset="0x12b0" bitsize="128" />
|
||||
<register name="XMM12" offset="0x12c0" bitsize="128" />
|
||||
<register name="XMM13" offset="0x12d0" bitsize="128" />
|
||||
<register name="XMM14" offset="0x12e0" bitsize="128" />
|
||||
<register name="XMM15" offset="0x12f0" bitsize="128" />
|
||||
<register name="IDTR" offset="0x2200" bitsize="48" />
|
||||
<register name="IDTR_Limit" offset="0x2200" bitsize="16" />
|
||||
<register name="IDTR_Address" offset="0x2202" bitsize="32" />
|
||||
<register name="GDTR" offset="0x2210" bitsize="48" />
|
||||
<register name="GDTR_Limit" offset="0x2210" bitsize="16" />
|
||||
<register name="GDTR_Address" offset="0x2212" bitsize="32" />
|
||||
<register name="LDTR" offset="0x2220" bitsize="48" />
|
||||
<register name="LDTR_Limit" offset="0x2220" bitsize="16" />
|
||||
<register name="LDTR_Address" offset="0x2222" bitsize="32" />
|
||||
<register name="TR" offset="0x2230" bitsize="48" />
|
||||
<register name="TR_Limit" offset="0x2230" bitsize="16" />
|
||||
<register name="TR_Address" offset="0x2232" bitsize="32" />
|
||||
</registers>
|
||||
</language>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language_translation>
|
||||
<from_language version="1">x86:LE:32:System Management Mode</from_language>
|
||||
<to_language version="2">x86:LE:32:System Management Mode</to_language>
|
||||
<map_compiler_spec from="default" to="default" />
|
||||
</language_translation>
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
# Due to limitations on variable length matching that preclude opcode matching afterwards, all memory addressing forms of PCLMULQDQ are decoded to PCLMULQDQ, not the macro names.
|
||||
# Display is non-standard, but semantics, and de-compilation should be correct.
|
||||
|
||||
macro pclmul(src1, src2, dest) {
|
||||
local i:4 = 0:4;
|
||||
local temp:16 = 0;
|
||||
|
||||
<start>
|
||||
if (i > 63:4) goto <end>;
|
||||
if ((src1 & (1 << i)) == 0) goto <skip>;
|
||||
temp = temp ^ (src2 << i);
|
||||
<skip>
|
||||
i = i+1;
|
||||
goto <start>;
|
||||
<end>
|
||||
dest = temp;
|
||||
}
|
||||
|
||||
:PCLMULLQLQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x00
|
||||
{
|
||||
local src1:16 = zext(XmmReg1[0,64]);
|
||||
local src2:16 = zext(XmmReg2[0,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
}
|
||||
|
||||
:PCLMULHQLQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x01
|
||||
{
|
||||
local src1:16 = zext(XmmReg1[64,64]);
|
||||
local src2:16 = zext(XmmReg2[0,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
}
|
||||
|
||||
:PCLMULLQHQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x10
|
||||
{
|
||||
local src1:16 = zext(XmmReg1[0,64]);
|
||||
local src2:16 = zext(XmmReg2[64,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
}
|
||||
|
||||
:PCLMULHQHQDQ XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; byte=0x11
|
||||
{
|
||||
local src1:16 = zext(XmmReg1[64,64]);
|
||||
local src2:16 = zext(XmmReg2[64,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
}
|
||||
|
||||
:PCLMULQDQ XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; xmmmod=3 & XmmReg1 & XmmReg2; imm8 & imm8_4 & imm8_0
|
||||
{
|
||||
if (imm8_0:1) goto <src1_b>;
|
||||
src1:16 = zext(XmmReg1[0,64]);
|
||||
goto <done1>;
|
||||
|
||||
<src1_b>
|
||||
src1 = zext(XmmReg1[64,64]);
|
||||
|
||||
<done1>
|
||||
|
||||
if (imm8_4:1) goto <src2_b>;
|
||||
src2:16 = zext(XmmReg2[0,64]);
|
||||
goto <done2>;
|
||||
|
||||
<src2_b>
|
||||
src2 = zext(XmmReg2[64,64]);
|
||||
|
||||
<done2>
|
||||
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
}
|
||||
|
||||
:PCLMULQDQ XmmReg, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0x3a; byte=0x44; XmmReg ... & m128; imm8 & imm8_4 & imm8_0
|
||||
{
|
||||
if (imm8_0:1) goto <src1_b>;
|
||||
src1:16 = zext(XmmReg[0,64]);
|
||||
goto <done1>;
|
||||
|
||||
<src1_b>
|
||||
src1 = zext(XmmReg[64,64]);
|
||||
|
||||
<done1>
|
||||
local m:16 = m128;
|
||||
if (imm8_4:1) goto <src2_b>;
|
||||
src2:16 = zext(m[0,64]);
|
||||
goto <done2>;
|
||||
|
||||
<src2_b>
|
||||
src2 = zext(m[64,64]);
|
||||
|
||||
<done2>
|
||||
|
||||
pclmul(src1,src2,XmmReg);
|
||||
}
|
||||
|
||||
:VPCLMULLQLQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x00
|
||||
{
|
||||
local src1:16 = zext(vexVVVV_XmmReg[0,64]);
|
||||
local src2:16 = zext(XmmReg2[0,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
:VPCLMULHQLQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x01
|
||||
{
|
||||
local src1:16 = zext(vexVVVV_XmmReg[64,64]);
|
||||
local src2:16 = zext(XmmReg2[0,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
:VPCLMULLQHQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x10
|
||||
{
|
||||
local src1:16 = zext(vexVVVV_XmmReg[0,64]);
|
||||
local src2:16 = zext(XmmReg2[64,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
:VPCLMULHQHQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; byte=0x11
|
||||
{
|
||||
local src1:16 = zext(vexVVVV_XmmReg[64,64]);
|
||||
local src2:16 = zext(XmmReg2[64,64]);
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
:VPCLMULQDQ XmmReg1, vexVVVV_XmmReg, XmmReg2, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; xmmmod=3 & (XmmReg1 & YmmReg1) & XmmReg2; imm8 & imm8_4 & imm8_0
|
||||
{
|
||||
if (imm8_0:1) goto <src1_b>;
|
||||
src1:16 = zext(vexVVVV_XmmReg[0,64]);
|
||||
goto <done1>;
|
||||
|
||||
<src1_b>
|
||||
src1 = zext(vexVVVV_XmmReg[64,64]);
|
||||
|
||||
<done1>
|
||||
|
||||
if (imm8_4:1) goto <src2_b>;
|
||||
src2:16 = zext(XmmReg2[0,64]);
|
||||
goto <done2>;
|
||||
|
||||
<src2_b>
|
||||
src2 = zext(XmmReg2[64,64]);
|
||||
|
||||
<done2>
|
||||
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
:VPCLMULQDQ XmmReg1, vexVVVV_XmmReg, m128, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_WIG) & vexVVVV_XmmReg; byte=0x44; (XmmReg1 & YmmReg1) ... & m128; imm8 & imm8_4 & imm8_0
|
||||
{
|
||||
if (imm8_0:1) goto <src1_b>;
|
||||
src1:16 = zext(vexVVVV_XmmReg[0,64]);
|
||||
goto <done1>;
|
||||
|
||||
<src1_b>
|
||||
src1 = zext(vexVVVV_XmmReg[64,64]);
|
||||
|
||||
<done1>
|
||||
|
||||
local m:16 = m128;
|
||||
if (imm8_4:1) goto <src2_b>;
|
||||
src2:16 = zext(m[0,64]);
|
||||
goto <done2>;
|
||||
|
||||
<src2_b>
|
||||
src2 = zext(m[64,64]);
|
||||
|
||||
<done2>
|
||||
|
||||
pclmul(src1,src2,XmmReg1);
|
||||
YmmReg1 = zext(XmmReg1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
define pcodeop rdrand;
|
||||
define pcodeop rdrandIsValid;
|
||||
|
||||
macro rdflags(){
|
||||
OF = 0; SF = 0; ZF = 0; AF = 0; PF = 0;
|
||||
}
|
||||
|
||||
:RDRAND Rmr16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; mod=3 & Rmr16 & reg_opcode=6
|
||||
{
|
||||
Rmr16 = rdrand();
|
||||
CF=rdrandIsValid();
|
||||
rdflags();
|
||||
|
||||
}
|
||||
:RDRAND Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=6
|
||||
{
|
||||
Rmr32 = rdrand();
|
||||
CF=rdrandIsValid();
|
||||
rdflags();
|
||||
}
|
||||
@ifdef IA64
|
||||
:RDRAND Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=6
|
||||
{
|
||||
Rmr64 = rdrand();
|
||||
CF=rdrandIsValid();
|
||||
rdflags();
|
||||
}
|
||||
@endif
|
||||
|
||||
define pcodeop rdseed;
|
||||
define pcodeop rdseedIsValid;
|
||||
:RDSEED Rmr16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; mod=3 & Rmr16 & reg_opcode=7
|
||||
{
|
||||
Rmr16 = rdseed();
|
||||
CF=rdseedIsValid();
|
||||
rdflags();
|
||||
}
|
||||
:RDSEED Rmr32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; mod=3 & Rmr32 & reg_opcode=7
|
||||
{
|
||||
Rmr32 = rdseed();
|
||||
CF=rdseedIsValid();
|
||||
rdflags();
|
||||
}
|
||||
@ifdef IA64
|
||||
:RDSEED Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; mod=3 & Rmr64 & reg_opcode=7
|
||||
{
|
||||
Rmr64 = rdseed();
|
||||
CF=rdseedIsValid();
|
||||
rdflags();
|
||||
}
|
||||
@endif
|
||||
@@ -0,0 +1,257 @@
|
||||
define pcodeop encls_ecreate;
|
||||
define pcodeop encls_eadd;
|
||||
define pcodeop encls_einit;
|
||||
define pcodeop encls_einit_ZF;
|
||||
define pcodeop encls_eremove;
|
||||
define pcodeop encls_eremove_ZF;
|
||||
define pcodeop encls_edbgrd;
|
||||
define pcodeop encls_edbgrd_RBX;
|
||||
define pcodeop encls_edbgwr;
|
||||
define pcodeop encls_eextend;
|
||||
define pcodeop encls_eldb;
|
||||
define pcodeop encls_eldb_ZF;
|
||||
define pcodeop encls_eldu;
|
||||
define pcodeop encls_eldu_ZF;
|
||||
define pcodeop encls_eblock;
|
||||
define pcodeop encls_eblock_ZF;
|
||||
define pcodeop encls_epa;
|
||||
define pcodeop encls_ewb;
|
||||
define pcodeop encls_ewb_ZF;
|
||||
define pcodeop encls_ewb_CF;
|
||||
define pcodeop encls_etrack;
|
||||
define pcodeop encls_etrack_ZF;
|
||||
define pcodeop encls_eaug;
|
||||
define pcodeop encls_emodpr;
|
||||
define pcodeop encls_emodpr_ZF;
|
||||
define pcodeop encls_emodt;
|
||||
define pcodeop encls_emodt_ZF;
|
||||
define pcodeop encls_unknown;
|
||||
|
||||
:ENCLS is vexMode=0 & byte=0x0f; byte=0x01; byte=0xcf {
|
||||
|
||||
if ( EAX != 0x0 ) goto <leaf_1>;
|
||||
encls_ecreate( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_1>
|
||||
if ( EAX != 0x1 ) goto <leaf_2>;
|
||||
encls_eadd( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_2>
|
||||
if ( EAX != 0x2 ) goto <leaf_3>;
|
||||
RAX = encls_einit( RBX, RCX, RDX );
|
||||
ZF = encls_einit_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_3>
|
||||
if ( EAX != 0x3 ) goto <leaf_4>;
|
||||
RAX = encls_eremove( RCX );
|
||||
ZF = encls_eremove_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_4>
|
||||
if ( EAX != 0x4 ) goto <leaf_5>;
|
||||
RAX = encls_edbgrd( RCX );
|
||||
RBX = encls_edbgrd_RBX( RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_5>
|
||||
if ( EAX != 0x5 ) goto <leaf_6>;
|
||||
RAX = encls_edbgwr( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_6>
|
||||
if ( EAX != 0x6 ) goto <leaf_7>;
|
||||
encls_eextend( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_7>
|
||||
if ( EAX != 0x7 ) goto <leaf_8>;
|
||||
RAX = encls_eldb( RBX, RCX, RDX );
|
||||
ZF = encls_eldb_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_8>
|
||||
if ( EAX != 0x8 ) goto <leaf_9>;
|
||||
RAX = encls_eldu( RBX, RCX, RDX );
|
||||
ZF = encls_eldu_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_9>
|
||||
if ( EAX != 0x9 ) goto <leaf_A>;
|
||||
RAX = encls_eblock( RCX );
|
||||
ZF = encls_eblock_ZF( RCX );
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_A>
|
||||
if ( EAX != 0xA ) goto <leaf_B>;
|
||||
encls_epa( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_B>
|
||||
if ( EAX != 0xB ) goto <leaf_C>;
|
||||
RAX = encls_ewb( RBX, RCX, RDX );
|
||||
ZF = encls_ewb_ZF( RBX, RCX, RDX );
|
||||
CF = encls_ewb_CF( RBX, RCX, RDX );
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_C>
|
||||
if ( EAX != 0xC ) goto <leaf_D>;
|
||||
RAX = encls_etrack( RCX );
|
||||
ZF = encls_etrack_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_D>
|
||||
if ( EAX != 0xD ) goto <leaf_E>;
|
||||
encls_eaug( RBX, RCX, RDX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_E>
|
||||
if ( EAX != 0xE ) goto <leaf_F>;
|
||||
RAX = encls_emodpr( RBX, RCX );
|
||||
ZF = encls_emodpr_ZF( RCX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_F>
|
||||
if ( EAX != 0xF ) goto <unknown>;
|
||||
RAX = encls_emodt( RBX, RCX );
|
||||
ZF = encls_emodt_ZF( RCX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<unknown>
|
||||
encls_unknown();
|
||||
|
||||
<done>
|
||||
}
|
||||
|
||||
|
||||
define pcodeop enclu_ereport;
|
||||
define pcodeop enclu_egetkey;
|
||||
define pcodeop enclu_egetkey_ZF;
|
||||
define pcodeop enclu_eenter_EAX;
|
||||
define pcodeop enclu_eenter_RCX;
|
||||
define pcodeop enclu_eenter_TF;
|
||||
define pcodeop enclu_eresume;
|
||||
define pcodeop enclu_eexit;
|
||||
define pcodeop enclu_eexit_TF;
|
||||
define pcodeop enclu_eaccept;
|
||||
define pcodeop enclu_eaccept_ZF;
|
||||
define pcodeop enclu_emodpe;
|
||||
define pcodeop enclu_eacceptcopy;
|
||||
define pcodeop enclu_eacceptcopy_ZF;
|
||||
define pcodeop enclu_unknown;
|
||||
|
||||
:ENCLU is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd7 {
|
||||
|
||||
if ( EAX != 0x0 ) goto <leaf_1>;
|
||||
enclu_ereport( RBX, RCX, RDX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_1>
|
||||
if ( EAX != 0x1 ) goto <leaf_2>;
|
||||
RAX = enclu_egetkey( RBX, RCX );
|
||||
ZF = enclu_egetkey_ZF( RBX, RCX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_2>
|
||||
if ( EAX != 0x2 ) goto <leaf_3>;
|
||||
tempBX:8 = RBX;
|
||||
tempCX:8 = RCX;
|
||||
|
||||
EAX = enclu_eenter_EAX( tempBX, tempCX );
|
||||
RCX = enclu_eenter_RCX( tempBX, tempCX );
|
||||
TF = enclu_eenter_TF( tempBX, tempCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_3>
|
||||
if ( EAX != 0x3 ) goto <leaf_4>;
|
||||
TF = enclu_eresume( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_4>
|
||||
if ( EAX != 0x4 ) goto <leaf_5>;
|
||||
RCX = enclu_eexit( RBX );
|
||||
TF = enclu_eexit_TF( RBX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_5>
|
||||
if ( EAX != 0x5 ) goto <leaf_6>;
|
||||
RAX = enclu_eaccept( RBX, RCX );
|
||||
ZF = enclu_eaccept_ZF( RBX, RCX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<leaf_6>
|
||||
if ( EAX != 0x6 ) goto <leaf_7>;
|
||||
enclu_emodpe( RBX, RCX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_7>
|
||||
if ( EAX != 0x7 ) goto <unknown>;
|
||||
RAX = enclu_eacceptcopy( RBX, RCX, RDX );
|
||||
ZF = enclu_eacceptcopy_ZF( RBX, RCX, RDX );
|
||||
CF = 0;
|
||||
PF = 0;
|
||||
AF = 0;
|
||||
OF = 0;
|
||||
SF = 0;
|
||||
goto <done>;
|
||||
|
||||
<unknown>
|
||||
enclu_unknown();
|
||||
|
||||
<done>
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# INFO This file automatically generated by andre on Fri Mar 16 15:13:25 2018
|
||||
# INFO Direct edits to this file may be lost in future updates
|
||||
# INFO Command line arguments: ['--sinc', '--cpuid-match', 'SHA']
|
||||
|
||||
# SHA1RNDS4 4-602 PAGE 1722 LINE 89511
|
||||
define pcodeop sha1rnds4_sha ;
|
||||
:SHA1RNDS4 XmmReg1, XmmReg2_m128, imm8 is vexMode=0 & byte=0x0F; byte=0x3A; byte=0xCC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128; imm8
|
||||
{
|
||||
XmmReg1 = sha1rnds4_sha( XmmReg1, XmmReg2_m128, imm8:1 );
|
||||
}
|
||||
|
||||
# SHA1NEXTE 4-604 PAGE 1724 LINE 89602
|
||||
define pcodeop sha1nexte_sha ;
|
||||
:SHA1NEXTE XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xC8; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1 = sha1nexte_sha( XmmReg1, XmmReg2_m128 );
|
||||
}
|
||||
|
||||
# SHA1MSG1 4-605 PAGE 1725 LINE 89654
|
||||
define pcodeop sha1msg1_sha ;
|
||||
:SHA1MSG1 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xC9; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1 = sha1msg1_sha( XmmReg1, XmmReg2_m128 );
|
||||
}
|
||||
|
||||
# SHA1MSG2 4-606 PAGE 1726 LINE 89708
|
||||
define pcodeop sha1msg2_sha ;
|
||||
:SHA1MSG2 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCA; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1 = sha1msg2_sha( XmmReg1, XmmReg2_m128 );
|
||||
}
|
||||
|
||||
# SHA256RNDS2 4-607 PAGE 1727 LINE 89765
|
||||
define pcodeop sha256rnds2_sha ;
|
||||
:SHA256RNDS2 XmmReg1, XmmReg2_m128, XMM0 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCB; (XmmReg1 & YmmReg1) ... & XmmReg2_m128 & XMM0
|
||||
{
|
||||
XmmReg1 = sha256rnds2_sha( XmmReg1, XmmReg2_m128, XMM0 );
|
||||
}
|
||||
|
||||
# SHA256MSG1 4-609 PAGE 1729 LINE 89847
|
||||
define pcodeop sha256msg1_sha ;
|
||||
:SHA256MSG1 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCC; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1 = sha256msg1_sha( XmmReg1, XmmReg2_m128 );
|
||||
}
|
||||
|
||||
# SHA256MSG2 4-610 PAGE 1730 LINE 89900
|
||||
define pcodeop sha256msg2_sha ;
|
||||
:SHA256MSG2 XmmReg1, XmmReg2_m128 is vexMode=0 & byte=0x0F; byte=0x38; byte=0xCD; (XmmReg1 & YmmReg1) ... & XmmReg2_m128
|
||||
{
|
||||
XmmReg1 = sha256msg2_sha( XmmReg1, XmmReg2_m128 );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
define pcodeop getsec_capabilities;
|
||||
define pcodeop getsec_enteraccs;
|
||||
define pcodeop getsec_exitac;
|
||||
define pcodeop getsec_senter;
|
||||
define pcodeop getsec_sexit;
|
||||
define pcodeop getsec_parameters_EAX;
|
||||
define pcodeop getsec_parameters_EBX;
|
||||
define pcodeop getsec_parameters_ECX;
|
||||
define pcodeop getsec_smctrl;
|
||||
define pcodeop getsec_wakeup;
|
||||
define pcodeop getsec_unknown;
|
||||
|
||||
|
||||
:GETSEC is vexMode=0 & byte=0x0f; byte=0x37 {
|
||||
|
||||
if ( EAX != 0x0 ) goto <leaf_1>;
|
||||
EAX = 0;
|
||||
if ( EBX != 0x0 ) goto <done>;
|
||||
EAX = getsec_capabilities( EBX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_1>
|
||||
if ( EAX != 0x2 ) goto <leaf_2>;
|
||||
getsec_enteraccs( EBX, ECX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_2>
|
||||
if ( EAX != 0x3 ) goto <leaf_3>;
|
||||
@ifdef IA64
|
||||
getsec_exitac( RBX, EDX );
|
||||
@else
|
||||
getsec_exitac( EBX, EDX );
|
||||
@endif
|
||||
goto <done>;
|
||||
|
||||
<leaf_3>
|
||||
if ( EAX != 0x4 ) goto <leaf_4>;
|
||||
getsec_senter( EBX, ECX, EDX);
|
||||
goto <done>;
|
||||
|
||||
<leaf_4>
|
||||
if ( EAX != 0x5 ) goto <leaf_5>;
|
||||
getsec_sexit();
|
||||
goto <done>;
|
||||
|
||||
<leaf_5>
|
||||
if ( EAX != 0x6 ) goto <leaf_6>;
|
||||
EAX = getsec_parameters_EAX( EBX );
|
||||
ECX = getsec_parameters_ECX( EBX );
|
||||
EBX = getsec_parameters_EBX( EBX );
|
||||
goto <done>;
|
||||
|
||||
<leaf_6>
|
||||
if ( EAX != 0x7 ) goto <leaf_7>;
|
||||
getsec_smctrl(EBX);
|
||||
goto <done>;
|
||||
|
||||
<leaf_7>
|
||||
if ( EAX != 0x8 ) goto <unknown>;
|
||||
getsec_wakeup();
|
||||
goto <done>;
|
||||
|
||||
<unknown>
|
||||
getsec_unknown();
|
||||
|
||||
<done>
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- Set up x86 16-bit in real mode -->
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||
</properties>
|
||||
<programcounter register="EIP"/>
|
||||
<segmented_address space="ram" type="real" />
|
||||
<segmentop space="ram" userop="segment" farpointer="yes">
|
||||
<pcode>
|
||||
<input name="base" size="2"/>
|
||||
<input name="inner" size="2"/>
|
||||
<output name="res" size="4"/>
|
||||
<body><![CDATA[
|
||||
res = (zext(base) << 4) + zext(inner);
|
||||
]]></body>
|
||||
</pcode>
|
||||
<constresolve>
|
||||
<register name="DS"/>
|
||||
</constresolve>
|
||||
</segmentop>
|
||||
<context_data>
|
||||
<context_set space="ram">
|
||||
<set name="addrsize" val="0"/>
|
||||
<set name="opsize" val="0"/>
|
||||
<set name="protectedMode" val="0"/>
|
||||
</context_set>
|
||||
<tracked_set space="ram">
|
||||
<set name="DF" val="0"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
</processor_spec>
|
||||
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" /> <!-- no maximum alignment -->
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="2" />
|
||||
<pointer_size value="2" /> <!-- near pointer, TODO: how do we define far 4-byte pointer? -->
|
||||
<wchar_size value="2" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="2" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="4" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="10" />
|
||||
<!-- alignment varies between MIcrosoft and Borland -->
|
||||
<!--
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="2" />
|
||||
<entry size="8" alignment="2" />
|
||||
</size_alignment_map>
|
||||
-->
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="SP" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall16near" extrapop="unknown" stackshift="2">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="2" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="DX" piece2="AX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="BP"/>
|
||||
<register name="SI"/>
|
||||
<register name="DI"/>
|
||||
<register name="DS"/>
|
||||
<register name="CS"/>
|
||||
<register name="ES"/>
|
||||
<register name="SS"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="__cdecl16near" extrapop="2" stackshift="2">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="2" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="DX" piece2="AX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="BP"/>
|
||||
<register name="SI"/>
|
||||
<register name="DI"/>
|
||||
<register name="DS"/>
|
||||
<register name="CS"/>
|
||||
<register name="ES"/>
|
||||
<register name="SS"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
<prototype name="__stdcall16far" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="DX" piece2="AX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="BP"/>
|
||||
<register name="SI"/>
|
||||
<register name="DI"/>
|
||||
<register name="DS"/>
|
||||
<register name="CS"/>
|
||||
<register name="ES"/>
|
||||
<register name="SS"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
<prototype name="__cdecl16far" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="BP"/>
|
||||
<register name="SI"/>
|
||||
<register name="DI"/>
|
||||
<register name="DS"/>
|
||||
<register name="CS"/>
|
||||
<register name="ES"/>
|
||||
<register name="SS"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
<prototype name="__regcall" extrapop="2" stackshift="2">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="BX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="CX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="DX"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="AX"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="DX" piece2="AX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="BP"/>
|
||||
<register name="CX"/>
|
||||
<register name="DX"/>
|
||||
<register name="SI"/>
|
||||
<register name="DI"/>
|
||||
<register name="DS"/>
|
||||
<register name="CS"/>
|
||||
<register name="ES"/>
|
||||
<register name="SS"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,3 @@
|
||||
<gdis>
|
||||
<global optstring="intel"/>
|
||||
</gdis>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- Set up x86 16-bit in protected mode -->
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||
</properties>
|
||||
<programcounter register="EIP"/>
|
||||
<segmented_address space="ram" type="protected"/>
|
||||
<segmentop space="ram" userop="segment" farpointer="yes">
|
||||
<pcode>
|
||||
<input name="base" size="2"/>
|
||||
<input name="inner" size="2"/>
|
||||
<output name="res" size="4"/>
|
||||
<body><![CDATA[
|
||||
res = (zext(base) << 16) + zext(inner);
|
||||
]]></body>
|
||||
</pcode>
|
||||
<constresolve>
|
||||
<register name="DS"/>
|
||||
</constresolve>
|
||||
</segmentop>
|
||||
<context_data>
|
||||
<context_set space="ram">
|
||||
<set name="addrsize" val="0"/>
|
||||
<set name="opsize" val="0"/>
|
||||
<set name="protectedMode" val="1"/>
|
||||
</context_set>
|
||||
<tracked_set space="ram">
|
||||
<set name="DF" val="0"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
</processor_spec>
|
||||
@@ -0,0 +1,324 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" />
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="4" />
|
||||
<pointer_size value="4" />
|
||||
<wchar_size value="4" /> <!-- matches go's 'rune' -->
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="4" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
|
||||
<context_data>
|
||||
</context_data>
|
||||
|
||||
<stackpointer register="ESP" space="ram"/>
|
||||
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="4"/>
|
||||
</returnaddress>
|
||||
|
||||
<default_proto>
|
||||
<prototype name="abi0" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<prototype name="duffzero" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDI"/>
|
||||
</pentry>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="EDI"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="duffcopy" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ESI"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="EDI"/>
|
||||
<register name="ESI"/>
|
||||
<register name="ECX"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="__cdeclf" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="10">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__thiscall" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm3" extrapop="4" stackshift="4"> <!-- Used particularly by linux kernel -->
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm2" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm1" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="syscall" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EBX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ESI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EBP"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="EBX"/>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="EBP"/>
|
||||
<register name="EDI"/>
|
||||
<register name="ESI"/>
|
||||
<register name="ESP"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="EAX"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,9 @@
|
||||
<golang>
|
||||
<register_info versions="all">
|
||||
<int_registers list=""/>
|
||||
<float_registers list=""/>
|
||||
<stack initialoffset="4" maxalign="4"/>
|
||||
<current_goroutine register=""/>
|
||||
<zero_register register=""/>
|
||||
</register_info>
|
||||
</golang>
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||
<property key="assemblyRating:x86:LE:64:compat32" value="GOLD"/>
|
||||
</properties>
|
||||
<programcounter register="RIP"/>
|
||||
<context_data>
|
||||
<context_set space="ram">
|
||||
<set name="addrsize" val="1"/>
|
||||
<set name="opsize" val="1"/>
|
||||
<set name="rexprefix" val="0"/>
|
||||
<set name="longMode" val="0"/>
|
||||
</context_set>
|
||||
<tracked_set space="ram">
|
||||
<set name="DF" val="0"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<register_data>
|
||||
<register name="DR0" group="DEBUG"/>
|
||||
<register name="DR1" group="DEBUG"/>
|
||||
<register name="DR2" group="DEBUG"/>
|
||||
<register name="DR3" group="DEBUG"/>
|
||||
<register name="DR4" group="DEBUG"/>
|
||||
<register name="DR5" group="DEBUG"/>
|
||||
<register name="DR6" group="DEBUG"/>
|
||||
<register name="DR7" group="DEBUG"/>
|
||||
<register name="DR8" group="DEBUG"/>
|
||||
<register name="DR9" group="DEBUG"/>
|
||||
<register name="DR10" group="DEBUG"/>
|
||||
<register name="DR11" group="DEBUG"/>
|
||||
<register name="DR12" group="DEBUG"/>
|
||||
<register name="DR13" group="DEBUG"/>
|
||||
<register name="DR14" group="DEBUG"/>
|
||||
<register name="DR15" group="DEBUG"/>
|
||||
<register name="CR0" group="CONTROL"/>
|
||||
<register name="CR1" group="CONTROL"/>
|
||||
<register name="CR2" group="CONTROL"/>
|
||||
<register name="CR3" group="CONTROL"/>
|
||||
<register name="CR4" group="CONTROL"/>
|
||||
<register name="CR5" group="CONTROL"/>
|
||||
<register name="CR6" group="CONTROL"/>
|
||||
<register name="CR7" group="CONTROL"/>
|
||||
<register name="CR8" group="CONTROL"/>
|
||||
<register name="CR9" group="CONTROL"/>
|
||||
<register name="CR10" group="CONTROL"/>
|
||||
<register name="CR11" group="CONTROL"/>
|
||||
<register name="CR12" group="CONTROL"/>
|
||||
<register name="CR13" group="CONTROL"/>
|
||||
<register name="CR14" group="CONTROL"/>
|
||||
<register name="CR15" group="CONTROL"/>
|
||||
<register name="C0" group="Cx"/>
|
||||
<register name="C1" group="Cx"/>
|
||||
<register name="C2" group="Cx"/>
|
||||
<register name="C3" group="Cx"/>
|
||||
<register name="ST0" group="ST"/>
|
||||
<register name="ST1" group="ST"/>
|
||||
<register name="ST2" group="ST"/>
|
||||
<register name="ST3" group="ST"/>
|
||||
<register name="ST4" group="ST"/>
|
||||
<register name="ST5" group="ST"/>
|
||||
<register name="ST6" group="ST"/>
|
||||
<register name="ST7" group="ST"/>
|
||||
<register name="FPUControlWord" group="FPU"/>
|
||||
<register name="FPUStatusWord" group="FPU"/>
|
||||
<register name="FPUTagWord" group="FPU"/>
|
||||
<register name="FPUDataPointer" group="FPU"/>
|
||||
<register name="FPUInstructionPointer" group="FPU"/>
|
||||
<register name="FPULastInstructionOpcode" group="FPU"/>
|
||||
<register name="MM0" group="MMX"/>
|
||||
<register name="MM1" group="MMX"/>
|
||||
<register name="MM2" group="MMX"/>
|
||||
<register name="MM3" group="MMX"/>
|
||||
<register name="MM4" group="MMX"/>
|
||||
<register name="MM5" group="MMX"/>
|
||||
<register name="MM6" group="MMX"/>
|
||||
<register name="MM7" group="MMX"/>
|
||||
<register name="YMM0" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM1" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM2" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM3" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM4" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM5" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM6" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM7" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM8" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM9" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM10" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM11" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM12" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM13" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM14" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM15" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM0" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM1" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM2" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM3" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM4" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM5" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM6" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM7" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM8" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM9" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM10" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM11" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM12" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM13" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM14" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM15" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="CF" group="FLAGS"/>
|
||||
<register name="F1" group="FLAGS"/>
|
||||
<register name="PF" group="FLAGS"/>
|
||||
<register name="F3" group="FLAGS"/>
|
||||
<register name="AF" group="FLAGS"/>
|
||||
<register name="F5" group="FLAGS"/>
|
||||
<register name="ZF" group="FLAGS"/>
|
||||
<register name="SF" group="FLAGS"/>
|
||||
<register name="TF" group="FLAGS"/>
|
||||
<register name="IF" group="FLAGS"/>
|
||||
<register name="DF" group="FLAGS"/>
|
||||
<register name="OF" group="FLAGS"/>
|
||||
<register name="IOPL" group="FLAGS"/>
|
||||
<register name="NT" group="FLAGS"/>
|
||||
<register name="F15" group="FLAGS"/>
|
||||
<register name="RF" group="FLAGS"/>
|
||||
<register name="VM" group="FLAGS"/>
|
||||
<register name="AC" group="FLAGS"/>
|
||||
<register name="VIF" group="FLAGS"/>
|
||||
<register name="VIP" group="FLAGS"/>
|
||||
<register name="ID" group="FLAGS"/>
|
||||
<register name="rflags" group="FLAGS"/>
|
||||
<register name="eflags" group="FLAGS"/>
|
||||
<register name="flags" group="FLAGS"/>
|
||||
<register name="bit64" hidden="true"/>
|
||||
<register name="segover" hidden="true"/>
|
||||
<register name="repneprefx" hidden="true"/>
|
||||
<register name="repprefx" hidden="true"/>
|
||||
<register name="rexWprefix" hidden="true"/>
|
||||
<register name="rexRprefix" hidden="true"/>
|
||||
<register name="rexXprefix" hidden="true"/>
|
||||
<register name="rexBprefix" hidden="true"/>
|
||||
<register name="xmmTmp1" hidden="true"/>
|
||||
<register name="xmmTmp1_Qa" hidden="true"/>
|
||||
<register name="xmmTmp1_Da" hidden="true"/>
|
||||
<register name="xmmTmp1_Db" hidden="true"/>
|
||||
<register name="xmmTmp1_Qb" hidden="true"/>
|
||||
<register name="xmmTmp1_Dc" hidden="true"/>
|
||||
<register name="xmmTmp1_Dd" hidden="true"/>
|
||||
<register name="xmmTmp2" hidden="true"/>
|
||||
<register name="xmmTmp2_Qa" hidden="true"/>
|
||||
<register name="xmmTmp2_Da" hidden="true"/>
|
||||
<register name="xmmTmp2_Db" hidden="true"/>
|
||||
<register name="xmmTmp2_Qb" hidden="true"/>
|
||||
<register name="xmmTmp2_Dc" hidden="true"/>
|
||||
<register name="xmmTmp2_Dd" hidden="true"/>
|
||||
<register name="rexprefix" hidden="true"/>
|
||||
</register_data>
|
||||
</processor_spec>
|
||||
@@ -0,0 +1,373 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="8" />
|
||||
<pointer_size value="8" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="8" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="10" /> <!-- aligned-length=16 -->
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
<entry size="16" alignment="16" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="RSP" space="ram"/>
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="8"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="8" stackshift="8">
|
||||
<!-- Derived from "System V Application Binary Interface AMD64 Architecture Processor Supplement" April 2016 -->
|
||||
<input>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM4_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM5_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM6_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM7_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="9" maxsize="16">
|
||||
<addr space="join" piece1="RDX" piece2="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="RDX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RBX"/>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="MSABI" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="40" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfffffffffff0bdc1" last="0xffffffffffffffff"/>
|
||||
<range space="stack" first="8" last="39"/>
|
||||
</localrange>
|
||||
</prototype>
|
||||
<prototype name="syscall" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RDX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RCX"/>
|
||||
<register name="R11"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
<prototype name="processEntry" extrapop="0" stackshift="0">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="RSP"/>
|
||||
</unaffected>
|
||||
<!-- Functions with this prototype don't have a return address. But, if we don't specify one, this prototype will
|
||||
use the default, which is to have the return address on the stack. That conflicts with how this prototype actually
|
||||
uses the stack, so we set a fake return address at a RBP, which is unspecified at process entry -->
|
||||
<returnaddress>
|
||||
<register name="RBP"/>
|
||||
</returnaddress>
|
||||
</prototype>
|
||||
|
||||
<callfixup name="x86_return_thunk">
|
||||
<target name="__x86_return_thunk"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
RIP = *:8 RSP;
|
||||
RSP = RSP + 8;
|
||||
return [RIP];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="fentry">
|
||||
<target name="__fentry__"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
temp:1 = 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="mcount">
|
||||
<target name="mcount"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
temp:1 = 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_rbp">
|
||||
<target name="__x86_indirect_thunk_rbp"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RBP];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_rax">
|
||||
<target name="__x86_indirect_thunk_rax"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RAX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_rbx">
|
||||
<target name="__x86_indirect_thunk_rbx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RBX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_rcx">
|
||||
<target name="__x86_indirect_thunk_rcx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RCX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_rdx">
|
||||
<target name="__x86_indirect_thunk_rdx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RDX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r8">
|
||||
<target name="__x86_indirect_thunk_r8"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R8];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r9">
|
||||
<target name="__x86_indirect_thunk_r9"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R9];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r10">
|
||||
<target name="__x86_indirect_thunk_r10"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R10];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r11">
|
||||
<target name="__x86_indirect_thunk_r11"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R11];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r12">
|
||||
<target name="__x86_indirect_thunk_r12"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R12];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r13">
|
||||
<target name="__x86_indirect_thunk_r13"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R13];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r14">
|
||||
<target name="__x86_indirect_thunk_r14"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R14];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="x86_indirect_thunk_r15">
|
||||
<target name="__x86_indirect_thunk_r15"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [R15];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,428 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" />
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="8" />
|
||||
<pointer_size value="8" />
|
||||
<wchar_size value="4" /> <!-- matches go's 'rune' -->
|
||||
<short_size value="2" />
|
||||
<integer_size value="8" />
|
||||
<long_size value="8" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="16" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
|
||||
<context_data>
|
||||
</context_data>
|
||||
|
||||
<stackpointer register="RSP" space="ram"/>
|
||||
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="8"/>
|
||||
</returnaddress>
|
||||
|
||||
<default_proto>
|
||||
<prototype name="abi-internal" extrapop="8" stackshift="8">
|
||||
<input>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM4_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM5_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM6_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM7_Qa"/>
|
||||
</pentry>
|
||||
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RBX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R11"/>
|
||||
</pentry>
|
||||
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="9" maxsize="16">
|
||||
<addr space="join" piece2="RAX" piece1="RBX"/>
|
||||
</pentry>
|
||||
<pentry minsize="17" maxsize="24">
|
||||
<addr space="join" piece3="RAX" piece2="RBX" piece1="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="25" maxsize="32">
|
||||
<addr space="join" piece4="RAX" piece3="RBX" piece2="RCX" piece1="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="33" maxsize="40">
|
||||
<addr space="join" piece5="RAX" piece4="RBX" piece3="RCX" piece2="RDI" piece1="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="41" maxsize="48">
|
||||
<addr space="join" piece6="RAX" piece5="RBX" piece4="RCX" piece3="RDI" piece2="RSI" piece1="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="49" maxsize="56">
|
||||
<addr space="join" piece7="RAX" piece6="RBX" piece5="RCX" piece4="RDI" piece3="RSI" piece2="R8" piece1="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="57" maxsize="64">
|
||||
<addr space="join" piece8="RAX" piece7="RBX" piece6="RCX" piece5="RDI" piece4="RSI" piece3="R8" piece2="R9" piece1="R10"/>
|
||||
</pentry>
|
||||
<pentry minsize="65" maxsize="72">
|
||||
<addr space="join" piece9="RAX" piece8="RBX" piece7="RCX" piece6="RDI" piece5="RSI" piece4="R8" piece3="R9" piece2="R10" piece1="R11"/>
|
||||
</pentry>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RCX"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R11"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R14"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<prototype name="abi0" extrapop="8" stackshift="8">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RCX"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R11"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R14"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="duffzero" extrapop="8" stackshift="8">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="RDI"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R14"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="duffcopy" extrapop="8" stackshift="8">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="9" maxsize="16">
|
||||
<addr space="join" piece2="RDI" piece1="RSI"/>
|
||||
</pentry>
|
||||
</output>
|
||||
|
||||
<killedbycall>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RAX"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RCX"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R11"/>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R14"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="__stdcall" extrapop="8" stackshift="8">
|
||||
<!-- Derived from "System V Application Binary Interface AMD64 Architecture Processor Supplement" April 2016 -->
|
||||
<input>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM4_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM5_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM6_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM7_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="8" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="9" maxsize="16">
|
||||
<addr space="join" piece1="RDX" piece2="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="RDX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<unaffected>
|
||||
<register name="RBX"/>
|
||||
<register name="RSP"/>
|
||||
<register name="RBP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<prototype name="MSABI" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="40" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfffffffffff0bdc1" last="0xffffffffffffffff"/>
|
||||
<range space="stack" first="8" last="39"/>
|
||||
</localrange>
|
||||
</prototype>
|
||||
|
||||
<prototype name="syscall" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RSI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R10"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RDX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R8"/>
|
||||
<register name="R9"/>
|
||||
<register name="R10"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RCX"/>
|
||||
<register name="R11"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,10 @@
|
||||
<golang>
|
||||
<!-- see https://github.com/golang/go/blob/master/src/internal/abi/abi_amd64.go -->
|
||||
<register_info versions="V1_17,V1_18,V1_19,V1_20"> <!-- "all", or comma list of: V1_2,V1_16,V1_17,V1_18 -->
|
||||
<int_registers list="RAX,RBX,RCX,RDI,RSI,R8,R9,R10,R11"/>
|
||||
<float_registers list="XMM0,XMM1,XMM2,XMM3,XMM4,XMM5,XMM6,XMM7,XMM8,XMM9,XMM10,XMM11,XMM12,XMM13,XMM14"/>
|
||||
<stack initialoffset="8" maxalign="8"/>
|
||||
<current_goroutine register="R14"/>
|
||||
<zero_register register="XMM15"/>
|
||||
</register_info>
|
||||
</golang>
|
||||
@@ -0,0 +1,225 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- see: -->
|
||||
<!-- https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions#register-usage -->
|
||||
<!-- https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention -->
|
||||
<!-- https://docs.microsoft.com/en-us/cpp/c-runtime-library/direction-flag -->
|
||||
<!-- https://docs.microsoft.com/en-us/cpp/cpp/vectorcall -->
|
||||
|
||||
<compiler_spec>
|
||||
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" />
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="8" />
|
||||
<pointer_size value="8" />
|
||||
<wchar_size value="2" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="8" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
<bitfield_packing>
|
||||
<use_MS_convention value="true"/>
|
||||
</bitfield_packing>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="RSP" space="ram"/>
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="8"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__fastcall" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="40" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
<register name="GS_OFFSET"/>
|
||||
<register name="XMM6"/>
|
||||
<register name="XMM7"/>
|
||||
<register name="XMM8"/>
|
||||
<register name="XMM9"/>
|
||||
<register name="XMM10"/>
|
||||
<register name="XMM11"/>
|
||||
<register name="XMM12"/>
|
||||
<register name="XMM13"/>
|
||||
<register name="XMM14"/>
|
||||
<register name="XMM15"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfffffffffff0bdc1" last="0xffffffffffffffff"/>
|
||||
<range space="stack" first="8" last="39"/>
|
||||
</localrange>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="__thiscall" extrapop="8" stackshift="8">
|
||||
<input pointermax="8" thisbeforeretpointer="true">
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RCX"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM1_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RDX"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM2_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R8"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<group>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM3_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="R9"/>
|
||||
</pentry>
|
||||
</group>
|
||||
<pentry minsize="1" maxsize="500" align="8">
|
||||
<addr offset="40" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="RAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="8"/>
|
||||
<register name="RBX"/>
|
||||
<register name="RBP"/>
|
||||
<register name="RDI"/>
|
||||
<register name="RSI"/>
|
||||
<register name="RSP"/>
|
||||
<register name="R12"/>
|
||||
<register name="R13"/>
|
||||
<register name="R14"/>
|
||||
<register name="R15"/>
|
||||
<register name="DF"/>
|
||||
<register name="GS_OFFSET"/>
|
||||
<register name="XMM6"/>
|
||||
<register name="XMM7"/>
|
||||
<register name="XMM8"/>
|
||||
<register name="XMM9"/>
|
||||
<register name="XMM10"/>
|
||||
<register name="XMM11"/>
|
||||
<register name="XMM12"/>
|
||||
<register name="XMM13"/>
|
||||
<register name="XMM14"/>
|
||||
<register name="XMM15"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="RAX"/>
|
||||
<register name="XMM0"/>
|
||||
</killedbycall>
|
||||
<localrange>
|
||||
<range space="stack" first="0xfffffffffff0bdc1" last="0xffffffffffffffff"/>
|
||||
<range space="stack" first="8" last="39"/>
|
||||
</localrange>
|
||||
</prototype>
|
||||
<modelalias name="__cdecl" parent="__fastcall"/>
|
||||
<modelalias name="__stdcall" parent="__fastcall"/>
|
||||
<callfixup name="alloca_probe">
|
||||
<target name="_alloca_probe"/>
|
||||
<target name="_alloca_probe2"/>
|
||||
<target name="__chkstk"/>
|
||||
<target name="__chkstk2"/>
|
||||
<target name="___chkstk_ms"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
RSP = RSP + 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
<callfixup name="guard_dispatch_icall">
|
||||
<target name="_guard_dispatch_icall"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [RAX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,34 @@
|
||||
<dwarf>
|
||||
<register_mappings>
|
||||
<register_mapping dwarf="0" ghidra="RAX"/>
|
||||
<register_mapping dwarf="1" ghidra="RDX"/>
|
||||
<register_mapping dwarf="2" ghidra="RCX"/>
|
||||
<register_mapping dwarf="3" ghidra="RBX"/>
|
||||
<register_mapping dwarf="4" ghidra="RSI"/>
|
||||
<register_mapping dwarf="5" ghidra="RDI"/>
|
||||
<register_mapping dwarf="6" ghidra="RBP"/>
|
||||
<register_mapping dwarf="7" ghidra="RSP" stackpointer="true"/>
|
||||
<register_mapping dwarf="8" ghidra="R8" auto_count="8"/> <!-- R8..R15 -->
|
||||
<register_mapping dwarf="16" ghidra="RIP"/>
|
||||
<register_mapping dwarf="17" ghidra="XMM0" auto_count="16"/> <!-- XMM0..XMM15 -->
|
||||
<register_mapping dwarf="33" ghidra="ST0" auto_count="8"/> <!-- ST0..ST7 -->
|
||||
<register_mapping dwarf="41" ghidra="MM0" auto_count="8"/> <!-- MM0..MM7 -->
|
||||
<register_mapping dwarf="49" ghidra="rflags"/>
|
||||
<register_mapping dwarf="50" ghidra="ES"/>
|
||||
<register_mapping dwarf="51" ghidra="CS"/>
|
||||
<register_mapping dwarf="52" ghidra="SS"/>
|
||||
<register_mapping dwarf="53" ghidra="DS"/>
|
||||
<register_mapping dwarf="54" ghidra="FS"/>
|
||||
<register_mapping dwarf="55" ghidra="GS"/>
|
||||
<!-- <register_mapping dwarf="58" ghidra="FSBASE"/> **not implemented** -->
|
||||
<!-- <register_mapping dwarf="59" ghidra="GSBASE"/> **not implemented** -->
|
||||
<register_mapping dwarf="62" ghidra="TR"/>
|
||||
<register_mapping dwarf="63" ghidra="LDTR"/>
|
||||
<register_mapping dwarf="64" ghidra="MXCSR"/>
|
||||
<!-- <register_mapping dwarf="65" ghidra="FCW"/> **not implemented** -->
|
||||
<!-- <register_mapping dwarf="66" ghidra="FSW"/> **not implemented** -->
|
||||
<!-- <register_mapping dwarf="68" ghidra="XMM16" auto_count="16"/> **not implemented yet** --> <!-- XMM16..XMM31 -->
|
||||
<!-- <register_mapping dwarf="118" ghidra="K0" auto_count="8"/> **not implemented yet** -->
|
||||
</register_mappings>
|
||||
<call_frame_cfa value="8"/>
|
||||
</dwarf>
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||
<property key="assemblyRating:x86:LE:64:default" value="GOLD"/>
|
||||
</properties>
|
||||
<programcounter register="RIP"/>
|
||||
<context_data>
|
||||
<context_set space="ram">
|
||||
<set name="addrsize" val="2"/>
|
||||
<set name="opsize" val="1"/>
|
||||
<set name="rexprefix" val="0"/>
|
||||
<set name="longMode" val="1"/>
|
||||
</context_set>
|
||||
<tracked_set space="ram">
|
||||
<set name="DF" val="0"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<register_data>
|
||||
<register name="DR0" group="DEBUG"/>
|
||||
<register name="DR1" group="DEBUG"/>
|
||||
<register name="DR2" group="DEBUG"/>
|
||||
<register name="DR3" group="DEBUG"/>
|
||||
<register name="DR4" group="DEBUG"/>
|
||||
<register name="DR5" group="DEBUG"/>
|
||||
<register name="DR6" group="DEBUG"/>
|
||||
<register name="DR7" group="DEBUG"/>
|
||||
<register name="DR8" group="DEBUG"/>
|
||||
<register name="DR9" group="DEBUG"/>
|
||||
<register name="DR10" group="DEBUG"/>
|
||||
<register name="DR11" group="DEBUG"/>
|
||||
<register name="DR12" group="DEBUG"/>
|
||||
<register name="DR13" group="DEBUG"/>
|
||||
<register name="DR14" group="DEBUG"/>
|
||||
<register name="DR15" group="DEBUG"/>
|
||||
<register name="CR0" group="CONTROL"/>
|
||||
<register name="CR1" group="CONTROL"/>
|
||||
<register name="CR2" group="CONTROL"/>
|
||||
<register name="CR3" group="CONTROL"/>
|
||||
<register name="CR4" group="CONTROL"/>
|
||||
<register name="CR5" group="CONTROL"/>
|
||||
<register name="CR6" group="CONTROL"/>
|
||||
<register name="CR7" group="CONTROL"/>
|
||||
<register name="CR8" group="CONTROL"/>
|
||||
<register name="CR9" group="CONTROL"/>
|
||||
<register name="CR10" group="CONTROL"/>
|
||||
<register name="CR11" group="CONTROL"/>
|
||||
<register name="CR12" group="CONTROL"/>
|
||||
<register name="CR13" group="CONTROL"/>
|
||||
<register name="CR14" group="CONTROL"/>
|
||||
<register name="CR15" group="CONTROL"/>
|
||||
<register name="C0" group="Cx"/>
|
||||
<register name="C1" group="Cx"/>
|
||||
<register name="C2" group="Cx"/>
|
||||
<register name="C3" group="Cx"/>
|
||||
<register name="ST0" group="ST"/>
|
||||
<register name="ST1" group="ST"/>
|
||||
<register name="ST2" group="ST"/>
|
||||
<register name="ST3" group="ST"/>
|
||||
<register name="ST4" group="ST"/>
|
||||
<register name="ST5" group="ST"/>
|
||||
<register name="ST6" group="ST"/>
|
||||
<register name="ST7" group="ST"/>
|
||||
<register name="FPUControlWord" group="FPU"/>
|
||||
<register name="FPUStatusWord" group="FPU"/>
|
||||
<register name="FPUTagWord" group="FPU"/>
|
||||
<register name="FPUDataPointer" group="FPU"/>
|
||||
<register name="FPUInstructionPointer" group="FPU"/>
|
||||
<register name="FPULastInstructionOpcode" group="FPU"/>
|
||||
<register name="MM0" group="MMX"/>
|
||||
<register name="MM1" group="MMX"/>
|
||||
<register name="MM2" group="MMX"/>
|
||||
<register name="MM3" group="MMX"/>
|
||||
<register name="MM4" group="MMX"/>
|
||||
<register name="MM5" group="MMX"/>
|
||||
<register name="MM6" group="MMX"/>
|
||||
<register name="MM7" group="MMX"/>
|
||||
<register name="YMM0" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM1" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM2" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM3" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM4" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM5" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM6" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM7" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM8" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM9" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM10" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM11" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM12" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM13" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM14" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM15" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM0" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM1" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM2" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM3" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM4" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM5" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM6" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM7" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM8" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM9" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM10" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM11" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM12" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM13" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM14" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM15" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="CF" group="FLAGS"/>
|
||||
<register name="F1" group="FLAGS"/>
|
||||
<register name="PF" group="FLAGS"/>
|
||||
<register name="F3" group="FLAGS"/>
|
||||
<register name="AF" group="FLAGS"/>
|
||||
<register name="F5" group="FLAGS"/>
|
||||
<register name="ZF" group="FLAGS"/>
|
||||
<register name="SF" group="FLAGS"/>
|
||||
<register name="TF" group="FLAGS"/>
|
||||
<register name="IF" group="FLAGS"/>
|
||||
<register name="DF" group="FLAGS"/>
|
||||
<register name="OF" group="FLAGS"/>
|
||||
<register name="IOPL" group="FLAGS"/>
|
||||
<register name="NT" group="FLAGS"/>
|
||||
<register name="F15" group="FLAGS"/>
|
||||
<register name="RF" group="FLAGS"/>
|
||||
<register name="VM" group="FLAGS"/>
|
||||
<register name="AC" group="FLAGS"/>
|
||||
<register name="VIF" group="FLAGS"/>
|
||||
<register name="VIP" group="FLAGS"/>
|
||||
<register name="ID" group="FLAGS"/>
|
||||
<register name="rflags" group="FLAGS"/>
|
||||
<register name="eflags" group="FLAGS"/>
|
||||
<register name="flags" group="FLAGS"/>
|
||||
<register name="bit64" hidden="true"/>
|
||||
<register name="segover" hidden="true"/>
|
||||
<register name="repneprefx" hidden="true"/>
|
||||
<register name="repprefx" hidden="true"/>
|
||||
<register name="rexWprefix" hidden="true"/>
|
||||
<register name="rexRprefix" hidden="true"/>
|
||||
<register name="rexXprefix" hidden="true"/>
|
||||
<register name="rexBprefix" hidden="true"/>
|
||||
<register name="xmmTmp1" hidden="true"/>
|
||||
<register name="xmmTmp1_Qa" hidden="true"/>
|
||||
<register name="xmmTmp1_Da" hidden="true"/>
|
||||
<register name="xmmTmp1_Db" hidden="true"/>
|
||||
<register name="xmmTmp1_Qb" hidden="true"/>
|
||||
<register name="xmmTmp1_Dc" hidden="true"/>
|
||||
<register name="xmmTmp1_Dd" hidden="true"/>
|
||||
<register name="xmmTmp2" hidden="true"/>
|
||||
<register name="xmmTmp2_Qa" hidden="true"/>
|
||||
<register name="xmmTmp2_Da" hidden="true"/>
|
||||
<register name="xmmTmp2_Db" hidden="true"/>
|
||||
<register name="xmmTmp2_Qb" hidden="true"/>
|
||||
<register name="xmmTmp2_Dc" hidden="true"/>
|
||||
<register name="xmmTmp2_Dd" hidden="true"/>
|
||||
<register name="rexprefix" hidden="true"/>
|
||||
</register_data>
|
||||
</processor_spec>
|
||||
@@ -0,0 +1,6 @@
|
||||
@define IA64 "IA64"
|
||||
@include "x86.slaspec"
|
||||
with : lockprefx=0 {
|
||||
@include "sgx.sinc"
|
||||
@include "fma.sinc"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<dwarf>
|
||||
<register_mappings>
|
||||
<register_mapping dwarf="0" ghidra="EAX"/>
|
||||
<register_mapping dwarf="1" ghidra="ECX"/>
|
||||
<register_mapping dwarf="2" ghidra="EDX"/>
|
||||
<register_mapping dwarf="3" ghidra="EBX"/>
|
||||
<register_mapping dwarf="4" ghidra="ESP" stackpointer="true"/>
|
||||
<register_mapping dwarf="5" ghidra="EBP"/>
|
||||
<register_mapping dwarf="6" ghidra="ESI"/>
|
||||
<register_mapping dwarf="7" ghidra="EDI"/>
|
||||
<register_mapping dwarf="8" ghidra="EIP"/>
|
||||
<register_mapping dwarf="9" ghidra="eflags"/>
|
||||
<!-- <register_mapping dwarf="10" ghidra="TRAPNO"/> **not implemented** -->
|
||||
<register_mapping dwarf="11" ghidra="ST0" auto_count="8"/> <!-- ST0..ST7 -->
|
||||
|
||||
<register_mapping dwarf="21" ghidra="XMM0" auto_count="8"/> <!-- XMM0..XMM7 -->
|
||||
<register_mapping dwarf="29" ghidra="MM0" auto_count="8"/> <!-- MM0..MM7 -->
|
||||
|
||||
<!-- <register_mapping dwarf="37" ghidra="FCW"/> **not implemented** -->
|
||||
<!-- <register_mapping dwarf="38" ghidra="FSW"/> **not implemented** -->
|
||||
<register_mapping dwarf="39" ghidra="MXCSR"/>
|
||||
|
||||
<register_mapping dwarf="40" ghidra="ES"/>
|
||||
<register_mapping dwarf="41" ghidra="CS"/>
|
||||
<register_mapping dwarf="42" ghidra="SS"/>
|
||||
<register_mapping dwarf="43" ghidra="DS"/>
|
||||
<register_mapping dwarf="44" ghidra="FS"/>
|
||||
<register_mapping dwarf="45" ghidra="GS"/>
|
||||
|
||||
<register_mapping dwarf="48" ghidra="TR"/>
|
||||
<register_mapping dwarf="49" ghidra="LDTR"/>
|
||||
</register_mappings>
|
||||
<call_frame_cfa value="4"/>
|
||||
</dwarf>
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<language_definitions>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="2.14"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:32:default">
|
||||
<description>Intel/AMD 32-bit x86</description>
|
||||
<compiler name="Visual Studio" spec="x86win.cspec" id="windows"/>
|
||||
<compiler name="clang" spec="x86win.cspec" id="clangwindows"/>
|
||||
<compiler name="gcc" spec="x86gcc.cspec" id="gcc"/>
|
||||
<compiler name="Borland C++" spec="x86borland.cspec" id="borlandcpp"/>
|
||||
<compiler name="Delphi" spec="x86delphi.cspec" id="borlanddelphi"/>
|
||||
<compiler name="golang" spec="x86-32-golang.cspec" id="golang"/>
|
||||
<external_name tool="gnu" name="i386:intel"/>
|
||||
<external_name tool="IDA-PRO" name="8086"/>
|
||||
<external_name tool="IDA-PRO" name="80486p"/>
|
||||
<external_name tool="IDA-PRO" name="80586p"/>
|
||||
<external_name tool="IDA-PRO" name="80686p"/>
|
||||
<external_name tool="IDA-PRO" name="k62"/>
|
||||
<external_name tool="IDA-PRO" name="p2"/>
|
||||
<external_name tool="IDA-PRO" name="p3"/>
|
||||
<external_name tool="IDA-PRO" name="athlon"/>
|
||||
<external_name tool="IDA-PRO" name="p4"/>
|
||||
<external_name tool="IDA-PRO" name="metapc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="x86.dwarf"/>
|
||||
<external_name tool="Golang.register.info.file" name="x86-32-golang.register.info"/>
|
||||
</language>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="32"
|
||||
variant="System Management Mode"
|
||||
version="2.14"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:32:System Management Mode">
|
||||
<description>Intel/AMD 32-bit x86 System Management Mode</description>
|
||||
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="x86.dwarf"/>
|
||||
</language>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="16"
|
||||
variant="Real Mode"
|
||||
version="2.14"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16-real.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:16:Real Mode">
|
||||
<description>Intel/AMD 16-bit x86 Real Mode</description>
|
||||
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
||||
<external_name tool="IDA-PRO" name="8086"/>
|
||||
<external_name tool="IDA-PRO" name="8086r"/>
|
||||
<external_name tool="IDA-PRO" name="80386r"/>
|
||||
<external_name tool="IDA-PRO" name="80486r"/>
|
||||
<external_name tool="IDA-PRO" name="80586r"/>
|
||||
<external_name tool="IDA-PRO" name="metapc"/>
|
||||
<external_name tool="gnu" name="i8086"/>
|
||||
<external_name tool="gdis.disassembler.options.file" name="x86-16.gdis"/>
|
||||
</language>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="16"
|
||||
variant="Protected Mode"
|
||||
version="2.14"
|
||||
slafile="x86.sla"
|
||||
processorspec="x86-16.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:16:Protected Mode">
|
||||
<description>Intel/AMD 16-bit x86 Protected Mode</description>
|
||||
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
||||
<external_name tool="IDA-PRO" name="8086p"/>
|
||||
<external_name tool="gnu" name="i8086"/>
|
||||
<external_name tool="gdis.disassembler.options.file" name="x86-16.gdis"/>
|
||||
</language>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="64"
|
||||
variant="default"
|
||||
version="2.14"
|
||||
slafile="x86-64.sla"
|
||||
processorspec="x86-64.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:64:default">
|
||||
<description>Intel/AMD 64-bit x86</description>
|
||||
<compiler name="Visual Studio" spec="x86-64-win.cspec" id="windows"/>
|
||||
<compiler name="clang" spec="x86-64-win.cspec" id="clangwindows"/>
|
||||
<compiler name="gcc" spec="x86-64-gcc.cspec" id="gcc"/>
|
||||
<compiler name="golang" spec="x86-64-golang.cspec" id="golang"/>
|
||||
<external_name tool="gnu" name="i386:x86-64:intel"/>
|
||||
<external_name tool="gnu" name="i386:x86-64"/>
|
||||
<external_name tool="IDA-PRO" name="metapc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="x86-64.dwarf"/>
|
||||
<external_name tool="Golang.register.info.file" name="x86-64-golang.register.info"/>
|
||||
</language>
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="64"
|
||||
variant="compat32"
|
||||
version="2.14"
|
||||
slafile="x86-64.sla"
|
||||
processorspec="x86-64-compat32.pspec"
|
||||
manualindexfile="../manuals/x86.idx"
|
||||
id="x86:LE:64:compat32">
|
||||
<description>Intel/AMD 64-bit x86 in 32-bit compatibility mode (long mode off)</description>
|
||||
<compiler name="Visual Studio" spec="x86win.cspec" id="windows"/>
|
||||
<compiler name="gcc" spec="x86gcc.cspec" id="gcc"/>
|
||||
<external_name tool="DWARF.register.mapping.file" name="x86.dwarf"/>
|
||||
</language>
|
||||
</language_definitions>
|
||||
@@ -0,0 +1,86 @@
|
||||
<opinions>
|
||||
<!-- NOTE: variant="default" is specified for 64-bit to give preference to the default variant -->
|
||||
<constraint loader="Portable Executable (PE)">
|
||||
<constraint compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="clangwindows">
|
||||
<constraint primary="332" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" secondary="clang" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="borlandcpp">
|
||||
<constraint primary="332" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="borlanddelphi">
|
||||
<constraint primary="332" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="golang">
|
||||
<constraint primary="332" secondary="golang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" secondary="golang" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
</constraint>
|
||||
<constraint loader="Debug Symbols (DBG)" compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="gcc">
|
||||
<constraint primary="3" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="62" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Module Definition (DEF)" compilerSpecID="windows">
|
||||
<constraint primary="0" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint loader="Program Mapfile (MAP)" compilerSpecID="windows">
|
||||
<constraint primary="0" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint loader="Old-style DOS Executable (MZ)" compilerSpecID="default">
|
||||
<constraint primary="23117" processor="x86" endian="little" size="16" variant="Real Mode"/>
|
||||
</constraint>
|
||||
<constraint loader="New Executable (NE)" compilerSpecID="default">
|
||||
<constraint primary="17742" processor="x86" endian="little" size="16" variant="Protected Mode"/>
|
||||
</constraint>
|
||||
<constraint loader="Mac OS X Mach-O" compilerSpecID="gcc">
|
||||
<constraint primary="7" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="16777223" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="DYLD Cache" compilerSpecID="gcc">
|
||||
<constraint primary="x86_64" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Common Object File Format (COFF)" compilerSpecID="gcc">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="MS Common Object File Format (COFF)" compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Assembler Output (AOUT)" compilerSpecID="gcc">
|
||||
<constraint primary="134" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint loader="Relocatable Object Module Format (OMF)">
|
||||
<constraint compilerSpecID="windows">
|
||||
<constraint primary="32bit" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="default">
|
||||
<constraint primary="16bit" processor="x86" endian="little" size="16" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="borlandcpp">
|
||||
<constraint primary="32bit" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="32bit" secondary="codegearcpp" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="borlanddelphi">
|
||||
<constraint primary="32bit" secondary="borlanddelphi" processor="x86" endian="little" size="32" />
|
||||
</constraint>
|
||||
</constraint>
|
||||
</opinions>
|
||||
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="useOperandReferenceAnalyzerSwitchTables" value="true"/>
|
||||
<property key="assemblyRating:x86:LE:32:default" value="GOLD"/>
|
||||
</properties>
|
||||
<programcounter register="EIP"/>
|
||||
<incidentalcopy>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
<register name="ST2"/>
|
||||
<register name="ST3"/>
|
||||
<register name="ST4"/>
|
||||
<register name="ST5"/>
|
||||
<register name="ST6"/>
|
||||
<register name="ST7"/>
|
||||
</incidentalcopy>
|
||||
<context_data>
|
||||
<context_set space="ram">
|
||||
<set name="addrsize" val="1"/>
|
||||
<set name="opsize" val="1"/>
|
||||
</context_set>
|
||||
<tracked_set space="ram">
|
||||
<set name="DF" val="0"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<register_data>
|
||||
<register name="DR0" group="DEBUG"/>
|
||||
<register name="DR1" group="DEBUG"/>
|
||||
<register name="DR2" group="DEBUG"/>
|
||||
<register name="DR3" group="DEBUG"/>
|
||||
<register name="DR4" group="DEBUG"/>
|
||||
<register name="DR5" group="DEBUG"/>
|
||||
<register name="DR6" group="DEBUG"/>
|
||||
<register name="DR7" group="DEBUG"/>
|
||||
<register name="CR0" group="CONTROL"/>
|
||||
<register name="CR2" group="CONTROL"/>
|
||||
<register name="CR3" group="CONTROL"/>
|
||||
<register name="CR4" group="CONTROL"/>
|
||||
<register name="ST0" group="ST"/>
|
||||
<register name="ST1" group="ST"/>
|
||||
<register name="ST2" group="ST"/>
|
||||
<register name="ST3" group="ST"/>
|
||||
<register name="ST4" group="ST"/>
|
||||
<register name="ST5" group="ST"/>
|
||||
<register name="ST6" group="ST"/>
|
||||
<register name="ST7" group="ST"/>
|
||||
<register name="FPUControlWord" group="FPU"/>
|
||||
<register name="FPUStatusWord" group="FPU"/>
|
||||
<register name="FPUTagWord" group="FPU"/>
|
||||
<register name="FPUInstructionPointer" group="FPU"/>
|
||||
<register name="FPULastInstructionOpcode" group="FPU"/>
|
||||
<register name="FPUDataPointer" group="FPU"/>
|
||||
<register name="MM0" group="MMX"/>
|
||||
<register name="MM1" group="MMX"/>
|
||||
<register name="MM2" group="MMX"/>
|
||||
<register name="MM3" group="MMX"/>
|
||||
<register name="MM4" group="MMX"/>
|
||||
<register name="MM5" group="MMX"/>
|
||||
<register name="MM6" group="MMX"/>
|
||||
<register name="MM7" group="MMX"/>
|
||||
<register name="YMM0" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM1" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM2" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM3" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM4" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM5" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM6" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM7" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM8" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM9" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM10" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM11" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM12" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM13" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM14" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="YMM15" group="AVX" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM0" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM1" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM2" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM3" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM4" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM5" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM6" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM7" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM8" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM9" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM10" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM11" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM12" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM13" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM14" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="XMM15" vector_lane_sizes="1,2,4,8"/>
|
||||
<register name="CF" group="FLAGS"/>
|
||||
<register name="F1" group="FLAGS"/>
|
||||
<register name="PF" group="FLAGS"/>
|
||||
<register name="F3" group="FLAGS"/>
|
||||
<register name="AF" group="FLAGS"/>
|
||||
<register name="F5" group="FLAGS"/>
|
||||
<register name="ZF" group="FLAGS"/>
|
||||
<register name="SF" group="FLAGS"/>
|
||||
<register name="TF" group="FLAGS"/>
|
||||
<register name="IF" group="FLAGS"/>
|
||||
<register name="DF" group="FLAGS"/>
|
||||
<register name="OF" group="FLAGS"/>
|
||||
<register name="IOPL" group="FLAGS"/>
|
||||
<register name="NT" group="FLAGS"/>
|
||||
<register name="F15" group="FLAGS"/>
|
||||
<register name="RF" group="FLAGS"/>
|
||||
<register name="VM" group="FLAGS"/>
|
||||
<register name="AC" group="FLAGS"/>
|
||||
<register name="VIF" group="FLAGS"/>
|
||||
<register name="VIP" group="FLAGS"/>
|
||||
<register name="ID" group="FLAGS"/>
|
||||
<register name="eflags" group="FLAGS"/>
|
||||
<register name="flags" group="FLAGS"/>
|
||||
<register name="repneprefx" hidden="true"/>
|
||||
<register name="segover" hidden="true"/>
|
||||
</register_data>
|
||||
</processor_spec>
|
||||
@@ -0,0 +1,19 @@
|
||||
@include "ia.sinc"
|
||||
@include "lockable.sinc"
|
||||
with : lockprefx=0 {
|
||||
@include "avx.sinc"
|
||||
@include "avx_manual.sinc"
|
||||
@include "avx2.sinc"
|
||||
@include "avx2_manual.sinc"
|
||||
@include "adx.sinc"
|
||||
@include "clwb.sinc"
|
||||
@include "pclmulqdq.sinc"
|
||||
@include "mpx.sinc"
|
||||
@include "lzcnt.sinc"
|
||||
@include "bmi1.sinc"
|
||||
@include "bmi2.sinc"
|
||||
@include "sha.sinc"
|
||||
@include "smx.sinc"
|
||||
@include "cet.sinc"
|
||||
@include "rdrand.sinc"
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" />
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="4" />
|
||||
<pointer_size value="4" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="10" /> <!-- aligned-length=12 -->
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="4" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="ESP" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__fastcall" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="__stdcall" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__cdecl" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__thiscall" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<resolveprototype name="__stdcall/__fastcall">
|
||||
<model name="__stdcall"/> <!-- The default case -->
|
||||
<model name="__fastcall"/>
|
||||
</resolveprototype>
|
||||
<eval_current_prototype name="__stdcall/__fastcall"/>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="ESP" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__register" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<!--there is also a "pascal" calling convention, which is the same as stdcall except that arguments are pushed left-to-right-->
|
||||
<prototype name="__stdcall" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__cdecl" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,463 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<machine_alignment value="2" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="4" />
|
||||
<pointer_size value="4" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="10" /> <!-- aligned-length=12 -->
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="4" />
|
||||
<entry size="16" alignment="16" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
<range space="OTHER"/>
|
||||
</global>
|
||||
<stackpointer register="ESP" space="ram"/>
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="4"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__cdecl" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="__cdeclf" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="10">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__thiscall" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm3" extrapop="4" stackshift="4"> <!-- Used particularly by linux kernel -->
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm2" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__regparm1" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="EAX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="syscall" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EBX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ESI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDI"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EBP"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="EBX"/>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="EBP"/>
|
||||
<register name="EDI"/>
|
||||
<register name="ESI"/>
|
||||
<register name="ESP"/>
|
||||
<register name="DF"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="EAX"/>
|
||||
</killedbycall>
|
||||
</prototype>
|
||||
<prototype name="processEntry" extrapop="0" stackshift="0">
|
||||
<input pointermax="4">
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="ESP"/>
|
||||
</unaffected>
|
||||
<!-- Functions with this prototype don't have a return address. But, if we don't specify one, this prototype will
|
||||
use the default, which is to have the return address on the stack. That conflicts with how this prototype actually
|
||||
uses the stack, so we set a fake return address at a EBP, which is unspecified at process entry -->
|
||||
<returnaddress>
|
||||
<register name="EBP"/>
|
||||
</returnaddress>
|
||||
</prototype>
|
||||
|
||||
|
||||
<resolveprototype name="__cdecl/__regparm">
|
||||
<model name="__cdecl"/> <!-- The default case -->
|
||||
<model name="__regparm3"/>
|
||||
<model name="__regparm2"/>
|
||||
<model name="__regparm1"/>
|
||||
</resolveprototype>
|
||||
<eval_current_prototype name="__cdecl/__regparm"/>
|
||||
|
||||
<callfixup name="get_pc_thunk_ax">
|
||||
<target name="__i686.get_pc_thunk.ax"/>
|
||||
<target name="__x86.get_pc_thunk.ax"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EAX = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="get_pc_thunk.bp">
|
||||
<target name="__i686.get_pc_thunk.bp"/>
|
||||
<target name="__x86.get_pc_thunk.bp"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EBP = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="get_pc_thunk_bx">
|
||||
<target name="__i686.get_pc_thunk.bx"/>
|
||||
<target name="__x86.get_pc_thunk.bx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EBX = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="get_pc_thunk_cx">
|
||||
<target name="__i686.get_pc_thunk.cx"/>
|
||||
<target name="__x86.get_pc_thunk.cx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ECX = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="get_pc_thunk_dx">
|
||||
<target name="__i686.get_pc_thunk.dx"/>
|
||||
<target name="__x86.get_pc_thunk.dx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EDX = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="get_pc_thunk_si">
|
||||
<target name="__i686.get_pc_thunk.si"/>
|
||||
<target name="__x86.get_pc_thunk.si"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ESI = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_return_thunk">
|
||||
<target name="__x86_return_thunk"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EIP = *:4 ESP;
|
||||
ESP = ESP + 4;
|
||||
return [EIP];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="fentry">
|
||||
<target name="__fentry__"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
temp:1 = 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="mcount">
|
||||
<target name="mcount"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
temp:1 = 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_indirect_thunk_ebp">
|
||||
<target name="__x86_indirect_thunk_ebp"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [EBP];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_indirect_thunk_eax">
|
||||
<target name="__x86_indirect_thunk_eax"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [EAX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_indirect_thunk_ebx">
|
||||
<target name="__x86_indirect_thunk_ebx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [EBX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_indirect_thunk_ecx">
|
||||
<target name="__x86_indirect_thunk_ecx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [ECX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="x86_indirect_thunk_edx">
|
||||
<target name="__x86_indirect_thunk_edx"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
call [EDX];
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
</compiler_spec>
|
||||
@@ -0,0 +1,388 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization>
|
||||
<absolute_max_alignment value="0" /> <!-- no maximum alignment -->
|
||||
<machine_alignment value="8" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="4" />
|
||||
<pointer_size value="4" />
|
||||
<wchar_size value="2" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="8" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
<bitfield_packing>
|
||||
<use_MS_convention value="true"/>
|
||||
</bitfield_packing>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="ESP" space="ram"/>
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="4"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
<register name="FS_OFFSET"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
<prototype name="__cdecl" extrapop="4" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
<register name="FS_OFFSET"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__fastcall" extrapop="unknown" stackshift="4">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EDX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
<register name="FS_OFFSET"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<prototype name="__thiscall" extrapop="unknown" stackshift="4">
|
||||
<input thisbeforeretpointer="true">
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="ECX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="4" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output killedbycall="true">
|
||||
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
|
||||
<register name="ST0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="EAX"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8">
|
||||
<addr space="join" piece1="EDX" piece2="EAX"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="ESP"/>
|
||||
<register name="EBP"/>
|
||||
<register name="ESI"/>
|
||||
<register name="EDI"/>
|
||||
<register name="EBX"/>
|
||||
<register name="DF"/>
|
||||
<register name="FS_OFFSET"/>
|
||||
</unaffected>
|
||||
<killedbycall>
|
||||
<register name="ECX"/>
|
||||
<register name="EDX"/>
|
||||
<register name="ST0"/>
|
||||
<register name="ST1"/>
|
||||
</killedbycall>
|
||||
<likelytrash>
|
||||
<register name="ECX"/>
|
||||
</likelytrash>
|
||||
</prototype>
|
||||
<resolveprototype name="__fastcall/__thiscall/__stdcall">
|
||||
<model name="__stdcall"/> <!-- The default case -->
|
||||
<model name="__fastcall"/>
|
||||
<model name="__thiscall"/>
|
||||
</resolveprototype>
|
||||
<eval_current_prototype name="__fastcall/__thiscall/__stdcall"/>
|
||||
|
||||
|
||||
|
||||
<!-- Injections for various compiler helper functions -->
|
||||
|
||||
<callfixup name="EH_prolog">
|
||||
<target name="__EH_prolog"/>
|
||||
<target name="_EH_prolog"/>
|
||||
<target name="thunk_EH_prolog"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ESP = ESP - 4;
|
||||
*:4 ESP = -1;
|
||||
ESP = ESP - 4;
|
||||
* ESP = EAX;
|
||||
EAX = * FS_OFFSET;
|
||||
ESP = ESP - 4;
|
||||
* ESP = EAX;
|
||||
* FS_OFFSET = ESP;
|
||||
tmp = ESP + 12;
|
||||
* tmp = EBP;
|
||||
EBP = tmp;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
|
||||
<callfixup name="EH_prolog3">
|
||||
<target name="_EH_prolog3"/>
|
||||
<target name="__EH_prolog3"/>
|
||||
<target name="EH_prolog3_GS"/>
|
||||
<target name="_EH_prolog3_GS"/>
|
||||
<target name="__EH_prolog3_GS"/>
|
||||
<target name="EH_prolog3_catch"/>
|
||||
<target name="_EH_prolog3_catch"/>
|
||||
<target name="__EH_prolog3_catch"/>
|
||||
<target name="EH_prolog3_catch_GS"/>
|
||||
<target name="_EH_prolog3_catch_GS"/>
|
||||
<target name="__EH_prolog3_catch_GS"/>
|
||||
<target name="EH_prolog3_catch"/>
|
||||
<target name="_EH_prolog3_catch"/>
|
||||
<target name="__EH_prolog3_catch"/>
|
||||
<target name="EH_prolog3_catch_GS"/>
|
||||
<target name="_EH_prolog3_catch_GS"/>
|
||||
<target name="__EH_prolog3_catch_GS"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EBP = ESP + 4;
|
||||
tmp = * EBP;
|
||||
ESP = ESP - tmp;
|
||||
ESP = ESP - 24;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="EH_epilog3">
|
||||
<target name="_EH_epilog3"/>
|
||||
<target name="__EH_epilog3"/>
|
||||
<target name="EH_epilog3_GS"/>
|
||||
<target name="_EH_epilog3_GS"/>
|
||||
<target name="__EH_epilog3_GS"/>
|
||||
<target name="EH_epilog3_catch"/>
|
||||
<target name="_EH_epilog3_catch"/>
|
||||
<target name="__EH_epilog3_catch"/>
|
||||
<target name="EH_epilog3_catch_GS"/>
|
||||
<target name="_EH_epilog3_catch_GS"/>
|
||||
<target name="FID_conflict:__EH_epilog3_GS"/>
|
||||
<target name="FID_conflict:__EH_epilog3_catch"/>
|
||||
<target name="FID_conflict:__EH_epilog3_catch_GS"/>
|
||||
<target name="SEH_epilog"/>
|
||||
<target name="_SEH_epilog"/>
|
||||
<target name="__SEH_epilog"/>
|
||||
<target name="SEH_epilog4"/>
|
||||
<target name="_SEH_epilog4"/>
|
||||
<target name="__SEH_epilog4"/>
|
||||
<target name="SEH_epilog4_GS"/>
|
||||
<target name="_SEH_epilog4_GS"/>
|
||||
<target name="__SEH_epilog4_GS"/>
|
||||
<target name="FID_conflict:__SEH_epilog4_GS"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ESP = EBP;
|
||||
EBP = * ESP;
|
||||
ESP = ESP + 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
|
||||
<!-- Not sure if these are ever used, and how they affect the stack
|
||||
<callfixup name="EH_prolog3_align">
|
||||
<target name="_EH_prolog3_align"/>
|
||||
<target name="__EH_prolog3_align"/>
|
||||
<target name="EH_prolog3_GS_align"/>
|
||||
<target name="_EH_prolog3_GS_align"/>
|
||||
<target name="__EH_prolog3_GS_align"/>
|
||||
<target name="EH_prolog3_catch_align"/>
|
||||
<target name="_EH_prolog3_catch_align"/>
|
||||
<target name="__EH_prolog3_catch_align"/>
|
||||
<target name="EH_prolog3_catch_GS_align"/>
|
||||
<target name="_EH_prolog3_catch_GS_align"/>
|
||||
<target name="__EH_prolog3_catch_GS_align"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
EBP = ESP + 4;
|
||||
tmp = * EBP;
|
||||
ESP = ESP - tmp;
|
||||
ESP = ESP - 24;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="EH_epilog3_align">
|
||||
<target name="_EH_epilog3_align"/>
|
||||
<target name="__EH_epilog3_align"/>
|
||||
<target name="EH_epilog3_GS_align"/>
|
||||
<target name="_EH_epilog3_GS_align"/>
|
||||
<target name="__EH_epilog3_GS_align"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ESP = EBP;
|
||||
EBP = * ESP;
|
||||
ESP = ESP - 4;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
-->
|
||||
|
||||
<callfixup name="alloca_probe">
|
||||
<target name="__alloca_probe"/>
|
||||
<target name="__alloca_probe_8"/>
|
||||
<target name="__alloca_probe_16"/>
|
||||
<target name="__chkstk"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
ESP = ESP + 4 - EAX;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="SEH_prolog">
|
||||
<target name="_SEH_prolog"/>
|
||||
<target name="__SEH_prolog"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
newframetmp = ESP + 8;
|
||||
localsizetmp:4 = * newframetmp;
|
||||
ESP = ESP - localsizetmp;
|
||||
ESP = ESP - 20;
|
||||
* newframetmp = EBP;
|
||||
EBP = newframetmp;
|
||||
*ESP = EDI;
|
||||
*(ESP+4) = ESI;
|
||||
*(ESP+8) = EBX;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="SEH_prolog4">
|
||||
<target name="_SEH_prolog4"/>
|
||||
<target name="__SEH_prolog4"/>
|
||||
<target name="SEH_prolog4_GS"/>
|
||||
<target name="_SEH_prolog4_GS"/>
|
||||
<target name="__SEH_prolog4_GS"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
newframetmp = ESP + 8;
|
||||
localsizetmp:4 = * newframetmp;
|
||||
ESP = ESP - localsizetmp;
|
||||
ESP = ESP - 24;
|
||||
* newframetmp = EBP;
|
||||
EBP = newframetmp;
|
||||
*(ESP+4) = EDI;
|
||||
*(ESP+8) = ESI;
|
||||
*(ESP+12) = EBX;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
|
||||
<callfixup name="__RTC_CheckEsp">
|
||||
<target name="__RTC_CheckEsp"/>
|
||||
<pcode>
|
||||
<body><![CDATA[
|
||||
temp:4 = 0;
|
||||
]]></body>
|
||||
</pcode>
|
||||
</callfixup>
|
||||
</compiler_spec>
|
||||
631
src/backends/icicle-emulator/icicle-bridge/src/icicle.rs
Normal file
631
src/backends/icicle-emulator/icicle-bridge/src/icicle.rs
Normal file
@@ -0,0 +1,631 @@
|
||||
use icicle_cpu::ExceptionCode;
|
||||
use icicle_cpu::ValueSource;
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use crate::registers;
|
||||
|
||||
fn create_x64_vm() -> icicle_vm::Vm {
|
||||
let mut cpu_config = icicle_vm::cpu::Config::from_target_triple("x86_64-none");
|
||||
cpu_config.enable_jit = false;
|
||||
cpu_config.enable_jit_mem = true;
|
||||
cpu_config.enable_shadow_stack = false;
|
||||
cpu_config.enable_recompilation = true;
|
||||
cpu_config.track_uninitialized = false;
|
||||
cpu_config.optimize_instructions = true;
|
||||
cpu_config.optimize_block = false;
|
||||
|
||||
return icicle_vm::build(&cpu_config).unwrap();
|
||||
}
|
||||
|
||||
const FOREIGN_READ: u8 = 1 << 0;
|
||||
const FOREIGN_WRITE: u8 = 1 << 1;
|
||||
const FOREIGN_EXEC: u8 = 1 << 2;
|
||||
|
||||
fn map_permissions(foreign_permissions: u8) -> u8 {
|
||||
let mut permissions: u8 = 0;
|
||||
|
||||
if (foreign_permissions & FOREIGN_READ) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::READ;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_WRITE) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::WRITE;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_EXEC) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::EXEC;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[allow(dead_code)]
|
||||
#[derive(PartialEq)]
|
||||
enum HookType {
|
||||
Syscall = 1,
|
||||
Read,
|
||||
Write,
|
||||
ExecuteGeneric,
|
||||
ExecuteSpecific,
|
||||
Violation,
|
||||
Interrupt,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
fn u8_to_hook_type_unsafe(value: u8) -> HookType {
|
||||
unsafe { std::mem::transmute(value) }
|
||||
}
|
||||
|
||||
fn split_hook_id(id: u32) -> (u32, HookType) {
|
||||
let hook_id = id & 0xFFFFFF;
|
||||
let hook_type = u8_to_hook_type_unsafe((id >> 24) as u8);
|
||||
|
||||
return (hook_id, hook_type);
|
||||
}
|
||||
|
||||
fn qualify_hook_id(hook_id: u32, hook_type: HookType) -> u32 {
|
||||
let hook_type: u32 = (hook_type as u8).into();
|
||||
let hook_type_mask: u32 = hook_type << 24;
|
||||
return (hook_id | hook_type_mask).into();
|
||||
}
|
||||
|
||||
pub struct HookContainer<Func: ?Sized> {
|
||||
hook_id: u32,
|
||||
hooks: HashMap<u32, Box<Func>>,
|
||||
}
|
||||
|
||||
impl<Func: ?Sized> HookContainer<Func> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
hook_id: 0,
|
||||
hooks: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_hook(&mut self, callback: Box<Func>) -> u32 {
|
||||
self.hook_id += 1;
|
||||
let id = self.hook_id;
|
||||
self.hooks.insert(id, callback);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
pub fn get_hooks(&self) -> &HashMap<u32, Box<Func>> {
|
||||
return &self.hooks;
|
||||
}
|
||||
|
||||
pub fn remove_hook(&mut self, id: u32) {
|
||||
self.hooks.remove(&id);
|
||||
}
|
||||
}
|
||||
|
||||
struct InstructionHookInjector {
|
||||
hook: pcode::HookId,
|
||||
}
|
||||
|
||||
impl icicle_vm::CodeInjector for InstructionHookInjector {
|
||||
fn inject(
|
||||
&mut self,
|
||||
_cpu: &mut icicle_vm::cpu::Cpu,
|
||||
group: &icicle_vm::cpu::BlockGroup,
|
||||
code: &mut icicle_vm::BlockTable,
|
||||
) {
|
||||
for id in group.range() {
|
||||
let block = &mut code.blocks[id];
|
||||
|
||||
let mut tmp_block = pcode::Block::new();
|
||||
tmp_block.next_tmp = block.pcode.next_tmp;
|
||||
|
||||
for stmt in block.pcode.instructions.drain(..) {
|
||||
tmp_block.push(stmt);
|
||||
if let pcode::Op::InstructionMarker = stmt.op {
|
||||
tmp_block.push(pcode::Op::Hook(self.hook));
|
||||
code.modified.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
std::mem::swap(&mut tmp_block.instructions, &mut block.pcode.instructions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ExecutionHooks {
|
||||
stop: Rc<RefCell<bool>>,
|
||||
generic_hooks: HookContainer<dyn Fn(u64)>,
|
||||
specific_hooks: HookContainer<dyn Fn(u64)>,
|
||||
address_mapping: HashMap<u64, Vec<u32>>,
|
||||
}
|
||||
|
||||
impl ExecutionHooks {
|
||||
pub fn new(stop_value: Rc<RefCell<bool>>) -> Self {
|
||||
Self {
|
||||
stop: stop_value,
|
||||
generic_hooks: HookContainer::new(),
|
||||
specific_hooks: HookContainer::new(),
|
||||
address_mapping: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn run_hooks(&self, address: u64) {
|
||||
for (_key, func) in self.generic_hooks.get_hooks() {
|
||||
func(address);
|
||||
}
|
||||
|
||||
let mapping = self.address_mapping.get(&address);
|
||||
if mapping.is_none(){
|
||||
return;
|
||||
}
|
||||
|
||||
for id in mapping.unwrap() {
|
||||
let func = self.specific_hooks.get_hooks().get(&id);
|
||||
if func.is_some() {
|
||||
func.unwrap()(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(&mut self,cpu: &mut icicle_cpu::Cpu, address: u64) {
|
||||
self.run_hooks(address);
|
||||
|
||||
if *self.stop.borrow() {
|
||||
cpu.exception.code = ExceptionCode::InstructionLimit as u32;
|
||||
cpu.exception.value = address;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_generic_hook(&mut self, callback: Box<dyn Fn(u64)>) -> u32 {
|
||||
self.generic_hooks.add_hook(callback)
|
||||
}
|
||||
|
||||
pub fn add_specific_hook(&mut self, address: u64, callback: Box<dyn Fn(u64)>) -> u32 {
|
||||
let id = self.specific_hooks.add_hook(callback);
|
||||
|
||||
let mapping = self.address_mapping.entry(address).or_insert_with(Vec::new);
|
||||
mapping.push(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
pub fn remove_generic_hook(&mut self, id: u32) {
|
||||
self.generic_hooks.remove_hook(id);
|
||||
}
|
||||
|
||||
pub fn remove_specific_hook(&mut self, id: u32) {
|
||||
self.address_mapping.retain(|_, vec| {
|
||||
vec.retain(|&x| x != id);
|
||||
!vec.is_empty()
|
||||
});
|
||||
|
||||
self.specific_hooks.remove_hook(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IcicleEmulator {
|
||||
executing_thread: std::thread::ThreadId,
|
||||
vm: icicle_vm::Vm,
|
||||
reg: registers::X64RegisterNodes,
|
||||
syscall_hooks: HookContainer<dyn Fn()>,
|
||||
interrupt_hooks: HookContainer<dyn Fn(i32)>,
|
||||
violation_hooks: HookContainer<dyn Fn(u64, u8, bool) -> bool>,
|
||||
execution_hooks: Rc<RefCell<ExecutionHooks>>,
|
||||
stop: Rc<RefCell<bool>>,
|
||||
}
|
||||
|
||||
struct MemoryHook {
|
||||
callback: Box<dyn Fn(u64, &[u8])>,
|
||||
}
|
||||
|
||||
impl icicle_cpu::mem::WriteHook for MemoryHook {
|
||||
fn write(&mut self, _mem: &mut icicle_cpu::Mmu, addr: u64, value: &[u8]) {
|
||||
(self.callback)(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
impl icicle_cpu::mem::ReadAfterHook for MemoryHook {
|
||||
fn read(&mut self, _mem: &mut icicle_cpu::Mmu, addr: u64, value: &[u8]) {
|
||||
(self.callback)(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MmioHandler {
|
||||
read_handler: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_handler: Box<dyn Fn(u64, &[u8])>,
|
||||
}
|
||||
|
||||
impl MmioHandler {
|
||||
pub fn new(
|
||||
read_function: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_function: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> Self {
|
||||
Self {
|
||||
read_handler: read_function,
|
||||
write_handler: write_function,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl icicle_cpu::mem::IoMemory for MmioHandler {
|
||||
fn read(&mut self, addr: u64, buf: &mut [u8]) -> icicle_cpu::mem::MemResult<()> {
|
||||
(self.read_handler)(addr, buf);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: u64, value: &[u8]) -> icicle_cpu::mem::MemResult<()> {
|
||||
(self.write_handler)(addr, value);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl IcicleEmulator {
|
||||
pub fn new() -> Self {
|
||||
let mut virtual_machine = create_x64_vm();
|
||||
let stop_value = Rc::new(RefCell::new(false));
|
||||
let exec_hooks = Rc::new(RefCell::new(ExecutionHooks::new(stop_value.clone())));
|
||||
|
||||
let exec_hooks_clone = Rc::clone(&exec_hooks);
|
||||
|
||||
let hook = icicle_cpu::InstHook::new(move |cpu: &mut icicle_cpu::Cpu, addr: u64| {
|
||||
exec_hooks_clone.borrow_mut().execute(cpu, addr);
|
||||
});
|
||||
|
||||
let hook = virtual_machine.cpu.add_hook(hook);
|
||||
virtual_machine.add_injector(InstructionHookInjector { hook });
|
||||
|
||||
Self {
|
||||
stop: stop_value,
|
||||
executing_thread: std::thread::current().id(),
|
||||
reg: registers::X64RegisterNodes::new(&virtual_machine.cpu.arch),
|
||||
vm: virtual_machine,
|
||||
syscall_hooks: HookContainer::new(),
|
||||
interrupt_hooks: HookContainer::new(),
|
||||
violation_hooks: HookContainer::new(),
|
||||
execution_hooks: exec_hooks,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mem(&mut self) -> &mut icicle_vm::cpu::Mmu {
|
||||
return &mut self.vm.cpu.mem;
|
||||
}
|
||||
|
||||
pub fn start(&mut self, count: u64) {
|
||||
self.executing_thread = std::thread::current().id();
|
||||
|
||||
self.vm.icount_limit = match count {
|
||||
0 => u64::MAX,
|
||||
_ => self.vm.cpu.icount.saturating_add(count),
|
||||
};
|
||||
|
||||
loop {
|
||||
self.vm.cpu.block_id = u64::MAX;
|
||||
self.vm.cpu.block_offset = 0;
|
||||
self.vm.cpu.pending_exception = None;
|
||||
self.vm.cpu.exception.clear();
|
||||
*self.stop.borrow_mut() = false;
|
||||
|
||||
let reason = self.vm.run();
|
||||
|
||||
match reason {
|
||||
icicle_vm::VmExit::InstructionLimit => break,
|
||||
icicle_vm::VmExit::UnhandledException((code, value)) => {
|
||||
let continue_execution = self.handle_exception(code, value);
|
||||
if !continue_execution {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_interrupt(&self, code: i32) -> bool {
|
||||
for (_key, func) in self.interrupt_hooks.get_hooks() {
|
||||
func(code);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn handle_exception(&mut self, code: ExceptionCode, value: u64) -> bool {
|
||||
let continue_execution = match code {
|
||||
ExceptionCode::Syscall => self.handle_syscall(),
|
||||
ExceptionCode::ReadPerm => self.handle_violation(value, FOREIGN_READ, false),
|
||||
ExceptionCode::WritePerm => self.handle_violation(value, FOREIGN_WRITE, false),
|
||||
ExceptionCode::ReadUnmapped => self.handle_violation(value, FOREIGN_READ, true),
|
||||
ExceptionCode::WriteUnmapped => self.handle_violation(value, FOREIGN_WRITE, true),
|
||||
ExceptionCode::InvalidInstruction => self.handle_interrupt(6),
|
||||
ExceptionCode::DivisionException => self.handle_interrupt(0),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
return continue_execution;
|
||||
}
|
||||
|
||||
fn handle_violation(&mut self, address: u64, permission: u8, unmapped: bool) -> bool {
|
||||
let hooks = &self.violation_hooks.get_hooks();
|
||||
if hooks.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut continue_execution = true;
|
||||
|
||||
for (_key, func) in self.violation_hooks.get_hooks() {
|
||||
continue_execution &= func(address, permission, unmapped);
|
||||
}
|
||||
|
||||
return continue_execution;
|
||||
}
|
||||
|
||||
fn handle_syscall(&mut self) -> bool {
|
||||
for (_key, func) in self.syscall_hooks.get_hooks() {
|
||||
func();
|
||||
}
|
||||
|
||||
self.vm.cpu.write_pc(self.vm.cpu.read_pc() + 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) {
|
||||
self.vm.icount_limit = 0;
|
||||
|
||||
if self.executing_thread == std::thread::current().id() {
|
||||
*self.stop.borrow_mut() = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_violation_hook(&mut self, callback: Box<dyn Fn(u64, u8, bool) -> bool>) -> u32 {
|
||||
let hook_id = self.violation_hooks.add_hook(callback);
|
||||
return qualify_hook_id(hook_id, HookType::Violation);
|
||||
}
|
||||
|
||||
pub fn add_execution_hook(&mut self, address:u64, callback: Box<dyn Fn(u64)>) -> u32 {
|
||||
let hook_id = self.execution_hooks.borrow_mut().add_specific_hook(address, callback);
|
||||
return qualify_hook_id(hook_id, HookType::ExecuteSpecific);
|
||||
}
|
||||
|
||||
pub fn add_generic_execution_hook(&mut self, callback: Box<dyn Fn(u64)>) -> u32 {
|
||||
let hook_id = self.execution_hooks.borrow_mut().add_generic_hook(callback);
|
||||
return qualify_hook_id(hook_id, HookType::ExecuteGeneric);
|
||||
}
|
||||
|
||||
pub fn add_syscall_hook(&mut self, callback: Box<dyn Fn()>) -> u32 {
|
||||
let hook_id = self.syscall_hooks.add_hook(callback);
|
||||
return qualify_hook_id(hook_id, HookType::Syscall);
|
||||
}
|
||||
|
||||
pub fn add_interrupt_hook(&mut self, callback: Box<dyn Fn(i32)>) -> u32 {
|
||||
let hook_id = self.interrupt_hooks.add_hook(callback);
|
||||
return qualify_hook_id(hook_id, HookType::Interrupt);
|
||||
}
|
||||
|
||||
pub fn add_read_hook(
|
||||
&mut self,
|
||||
start: u64,
|
||||
end: u64,
|
||||
callback: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> u32 {
|
||||
let id = self.get_mem().add_read_after_hook(start, end, Box::new(MemoryHook { callback }));
|
||||
if id.is_none() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return qualify_hook_id(id.unwrap(), HookType::Read);
|
||||
}
|
||||
|
||||
pub fn add_write_hook(
|
||||
&mut self,
|
||||
start: u64,
|
||||
end: u64,
|
||||
callback: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> u32 {
|
||||
let id = self.get_mem().add_write_hook(start, end, Box::new(MemoryHook { callback }));
|
||||
if id.is_none() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return qualify_hook_id(id.unwrap(), HookType::Write);
|
||||
}
|
||||
|
||||
pub fn remove_hook(&mut self, id: u32) {
|
||||
let (hook_id, hook_type) = split_hook_id(id);
|
||||
|
||||
match hook_type {
|
||||
HookType::Syscall => self.syscall_hooks.remove_hook(hook_id),
|
||||
HookType::Violation => self.violation_hooks.remove_hook(hook_id),
|
||||
HookType::Interrupt => self.interrupt_hooks.remove_hook(hook_id),
|
||||
HookType::ExecuteGeneric => self.execution_hooks.borrow_mut().remove_generic_hook(hook_id),
|
||||
HookType::ExecuteSpecific => self.execution_hooks.borrow_mut().remove_specific_hook(hook_id),
|
||||
HookType::Read => {self.get_mem().remove_read_after_hook(hook_id);()},
|
||||
HookType::Write => {self.get_mem().remove_write_hook(hook_id);()},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
|
||||
const MAPPING_PERMISSIONS: u8 = icicle_vm::cpu::mem::perm::MAP
|
||||
| icicle_vm::cpu::mem::perm::INIT
|
||||
| icicle_vm::cpu::mem::perm::IN_CODE_CACHE;
|
||||
|
||||
let native_permissions = map_permissions(permissions);
|
||||
|
||||
let mapping = icicle_vm::cpu::mem::Mapping {
|
||||
perm: native_permissions | MAPPING_PERMISSIONS,
|
||||
value: 0x0,
|
||||
};
|
||||
|
||||
let layout = icicle_vm::cpu::mem::AllocLayout {
|
||||
addr: Some(address),
|
||||
size: length,
|
||||
align: 0x1000,
|
||||
};
|
||||
|
||||
let res = self.get_mem().alloc_memory(layout, mapping);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn map_mmio(
|
||||
&mut self,
|
||||
address: u64,
|
||||
length: u64,
|
||||
read_function: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_function: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> bool {
|
||||
let mem = self.get_mem();
|
||||
|
||||
let handler = MmioHandler::new(read_function, write_function);
|
||||
let handler_id = mem.register_io_handler(handler);
|
||||
|
||||
let layout = icicle_vm::cpu::mem::AllocLayout {
|
||||
addr: Some(address),
|
||||
size: length,
|
||||
align: 0x1000,
|
||||
};
|
||||
|
||||
let res = mem.alloc_memory(layout, handler_id);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn unmap_memory(&mut self, address: u64, length: u64) -> bool {
|
||||
return self.get_mem().unmap_memory_len(address, length);
|
||||
}
|
||||
|
||||
pub fn protect_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
|
||||
let native_permissions = map_permissions(permissions);
|
||||
let res = self
|
||||
.get_mem()
|
||||
.update_perm(address, length, native_permissions);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn write_memory(&mut self, address: u64, data: &[u8]) -> bool {
|
||||
let res = self
|
||||
.get_mem()
|
||||
.write_bytes(address, data, icicle_vm::cpu::mem::perm::NONE);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn read_memory(&mut self, address: u64, data: &mut [u8]) -> bool {
|
||||
let res = self
|
||||
.get_mem()
|
||||
.read_bytes(address, data, icicle_vm::cpu::mem::perm::NONE);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn save_registers(&self) -> Vec<u8> {
|
||||
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
|
||||
unsafe {
|
||||
let data: [u8; REG_SIZE] = self.vm.cpu.regs.read_at(0);
|
||||
return data.to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore_registers(&mut self, data: &[u8]) {
|
||||
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
|
||||
|
||||
let mut buffer: [u8; REG_SIZE] = [0; REG_SIZE];
|
||||
let size = std::cmp::min(REG_SIZE, data.len());
|
||||
buffer.copy_from_slice(&data[..size]);
|
||||
|
||||
unsafe {
|
||||
self.vm.cpu.regs.write_at(0, buffer);
|
||||
};
|
||||
}
|
||||
|
||||
fn read_generic_register(&mut self, reg: registers::X64Register, buffer: &mut [u8]) -> usize {
|
||||
let reg_node = self.reg.get_node(reg);
|
||||
|
||||
let res = self.vm.cpu.read_dynamic(pcode::Value::Var(reg_node));
|
||||
let bytes: [u8; 32] = res.zxt();
|
||||
|
||||
let len = std::cmp::min(bytes.len(), buffer.len());
|
||||
buffer[..len].copy_from_slice(&bytes[..len]);
|
||||
|
||||
return reg_node.size.into();
|
||||
}
|
||||
|
||||
|
||||
fn read_flags<T>(&mut self, data: &mut [u8]) -> usize
|
||||
{
|
||||
const REAL_SIZE: usize = std::mem::size_of::<u64>();
|
||||
let limit: usize = std::mem::size_of::<T>();
|
||||
let size = std::cmp::min(REAL_SIZE, limit);
|
||||
|
||||
let flags: u64 = self.reg.get_flags(&mut self.vm.cpu);
|
||||
|
||||
let copy_size = std::cmp::min(data.len(), size);
|
||||
data[..copy_size].copy_from_slice(&flags.to_ne_bytes()[..copy_size]);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
pub fn read_register(&mut self, reg: registers::X64Register, data: &mut [u8]) -> usize {
|
||||
match reg {
|
||||
registers::X64Register::Rflags => self.read_flags::<u64>(data),
|
||||
registers::X64Register::Eflags => self.read_flags::<u32>(data),
|
||||
registers::X64Register::Flags => self.read_flags::<u16>(data),
|
||||
_ => self.read_generic_register(reg, data),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_flags<T>(&mut self, data: &[u8]) -> usize
|
||||
{
|
||||
const REAL_SIZE: usize = std::mem::size_of::<u64>();
|
||||
let limit: usize = std::mem::size_of::<T>();
|
||||
let size = std::cmp::min(REAL_SIZE, limit);
|
||||
let copy_size = std::cmp::min(data.len(), size);
|
||||
|
||||
let mut buffer = [0u8; REAL_SIZE];
|
||||
self.read_flags::<u64>(&mut buffer);
|
||||
|
||||
buffer[..copy_size].copy_from_slice(&data[..copy_size]);
|
||||
|
||||
let flags = u64::from_ne_bytes(buffer);
|
||||
self.reg.set_flags(&mut self.vm.cpu, flags);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
pub fn write_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize {
|
||||
match reg {
|
||||
registers::X64Register::Rflags => self.write_flags::<u64>(data),
|
||||
registers::X64Register::Eflags => self.write_flags::<u32>(data),
|
||||
registers::X64Register::Flags => self.write_flags::<u16>(data),
|
||||
_ => self.write_generic_register(reg, data),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_generic_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize {
|
||||
let reg_node = self.reg.get_node(reg);
|
||||
|
||||
let mut buffer = [0u8; 32];
|
||||
let len = std::cmp::min(data.len(), buffer.len());
|
||||
buffer[..len].copy_from_slice(&data[..len]);
|
||||
|
||||
//let value = icicle_cpu::regs::DynamicValue::new(buffer, reg_node.size.into());
|
||||
//self.vm.cpu.write_trunc(reg_node, value);
|
||||
|
||||
let cpu = &mut self.vm.cpu;
|
||||
|
||||
match reg_node.size {
|
||||
1 => cpu.write_var::<[u8; 1]>(reg_node, buffer[..1].try_into().unwrap()),
|
||||
2 => cpu.write_var::<[u8; 2]>(reg_node, buffer[..2].try_into().unwrap()),
|
||||
3 => cpu.write_var::<[u8; 3]>(reg_node, buffer[..3].try_into().unwrap()),
|
||||
4 => cpu.write_var::<[u8; 4]>(reg_node, buffer[..4].try_into().unwrap()),
|
||||
5 => cpu.write_var::<[u8; 5]>(reg_node, buffer[..5].try_into().unwrap()),
|
||||
6 => cpu.write_var::<[u8; 6]>(reg_node, buffer[..6].try_into().unwrap()),
|
||||
7 => cpu.write_var::<[u8; 7]>(reg_node, buffer[..7].try_into().unwrap()),
|
||||
8 => cpu.write_var::<[u8; 8]>(reg_node, buffer[..8].try_into().unwrap()),
|
||||
9 => cpu.write_var::<[u8; 9]>(reg_node, buffer[..9].try_into().unwrap()),
|
||||
10 => cpu.write_var::<[u8; 10]>(reg_node, buffer[..10].try_into().unwrap()),
|
||||
11 => cpu.write_var::<[u8; 11]>(reg_node, buffer[..11].try_into().unwrap()),
|
||||
12 => cpu.write_var::<[u8; 12]>(reg_node, buffer[..12].try_into().unwrap()),
|
||||
13 => cpu.write_var::<[u8; 13]>(reg_node, buffer[..13].try_into().unwrap()),
|
||||
14 => cpu.write_var::<[u8; 14]>(reg_node, buffer[..14].try_into().unwrap()),
|
||||
15 => cpu.write_var::<[u8; 15]>(reg_node, buffer[..15].try_into().unwrap()),
|
||||
16 => cpu.write_var::<[u8; 16]>(reg_node, buffer[..16].try_into().unwrap()),
|
||||
_ => panic!("invalid dynamic value size"),
|
||||
}
|
||||
|
||||
return reg_node.size.into();
|
||||
}
|
||||
}
|
||||
305
src/backends/icicle-emulator/icicle-bridge/src/lib.rs
Normal file
305
src/backends/icicle-emulator/icicle-bridge/src/lib.rs
Normal file
@@ -0,0 +1,305 @@
|
||||
mod icicle;
|
||||
mod registers;
|
||||
|
||||
use icicle::IcicleEmulator;
|
||||
use registers::X64Register;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
fn to_cbool(value: bool) -> i32 {
|
||||
if value {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_create_emulator() -> *mut c_void {
|
||||
let emulator = Box::new(IcicleEmulator::new());
|
||||
return Box::into_raw(emulator) as *mut c_void;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_start(ptr: *mut c_void, count: usize) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.start(count as u64);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_stop(ptr: *mut c_void) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.stop();
|
||||
}
|
||||
}
|
||||
|
||||
type RawFunction = extern "C" fn(*mut c_void);
|
||||
type PtrFunction = extern "C" fn(*mut c_void, u64);
|
||||
type DataFunction = extern "C" fn(*mut c_void, *const c_void, usize);
|
||||
type MmioReadFunction = extern "C" fn(*mut c_void, u64, *mut c_void, usize);
|
||||
type MmioWriteFunction = extern "C" fn(*mut c_void, u64, *const c_void, usize);
|
||||
type ViolationFunction = extern "C" fn(*mut c_void, u64, u8, i32) -> i32;
|
||||
type InterruptFunction = extern "C" fn(*mut c_void, i32);
|
||||
type MemoryAccessFunction = MmioWriteFunction;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_map_mmio(
|
||||
ptr: *mut c_void,
|
||||
address: u64,
|
||||
length: u64,
|
||||
read_cb: MmioReadFunction,
|
||||
read_data: *mut c_void,
|
||||
write_cb: MmioWriteFunction,
|
||||
write_data: *mut c_void,
|
||||
) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
|
||||
let read_wrapper = Box::new(move |addr: u64, data: &mut [u8]| {
|
||||
let raw_pointer: *mut u8 = data.as_mut_ptr();
|
||||
read_cb(read_data, addr, raw_pointer as *mut c_void, data.len());
|
||||
});
|
||||
|
||||
let write_wrapper = Box::new(move |addr: u64, data: &[u8]| {
|
||||
let raw_pointer: *const u8 = data.as_ptr();
|
||||
write_cb(write_data, addr, raw_pointer as *const c_void, data.len());
|
||||
});
|
||||
|
||||
let res = emulator.map_mmio(address, length, read_wrapper, write_wrapper);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_map_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.map_memory(address, length, permissions);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_unmap_memory(ptr: *mut c_void, address: u64, length: u64) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.unmap_memory(address, length);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_protect_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.protect_memory(address, length, permissions);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_write_memory(
|
||||
ptr: *mut c_void,
|
||||
address: u64,
|
||||
data: *const c_void,
|
||||
size: usize,
|
||||
) -> i32 {
|
||||
if size == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if data.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
let res = emulator.write_memory(address, u8_slice);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_save_registers(ptr: *mut c_void, accessor: DataFunction, accessor_data: *mut c_void) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let registers = emulator.save_registers();
|
||||
accessor(
|
||||
accessor_data,
|
||||
registers.as_ptr() as *const c_void,
|
||||
registers.len(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_restore_registers(ptr: *mut c_void, data: *const c_void, size: usize) {
|
||||
if size == 0 || data.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
emulator.restore_registers(u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, size: usize) -> i32 {
|
||||
if size == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if data.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size);
|
||||
let res = emulator.read_memory(address, u8_slice);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_interrupt_hook(ptr: *mut c_void, callback: InterruptFunction, data: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_interrupt_hook(Box::new(
|
||||
move |code: i32| callback(data, code),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_violation_hook(ptr: *mut c_void, callback: ViolationFunction, data: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_violation_hook(Box::new(
|
||||
move |address: u64, permission: u8, unmapped: bool| {
|
||||
let result = callback(data, address, permission, to_cbool(unmapped));
|
||||
if result == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_read_hook(ptr: *mut c_void, start: u64, end: u64, callback: MemoryAccessFunction, user: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_read_hook(start, end, Box::new(
|
||||
move |address: u64, data: &[u8]| {
|
||||
callback(user, address, data.as_ptr() as *const c_void, data.len());
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_write_hook(ptr: *mut c_void, start: u64, end: u64, callback: MemoryAccessFunction, user: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_write_hook(start, end, Box::new(
|
||||
move |address: u64, data: &[u8]| {
|
||||
callback(user, address, data.as_ptr() as *const c_void, data.len());
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_syscall_hook(ptr: *mut c_void, callback: RawFunction, data: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_syscall_hook(Box::new(move || callback(data)));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_generic_execution_hook(ptr: *mut c_void, callback: PtrFunction, data: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_generic_execution_hook(Box::new(move |ptr: u64| callback(data, ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_execution_hook(ptr: *mut c_void, address: u64, callback: PtrFunction, data: *mut c_void) -> u32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
return emulator.add_execution_hook(address, Box::new(move |ptr: u64| callback(data, ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_remove_hook(ptr: *mut c_void, id: u32) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.remove_hook(id);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_read_register(
|
||||
ptr: *mut c_void,
|
||||
reg: X64Register,
|
||||
data: *mut c_void,
|
||||
size: usize,
|
||||
) -> usize {
|
||||
if size == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if data.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size);
|
||||
return emulator.read_register(reg, u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_write_register(
|
||||
ptr: *mut c_void,
|
||||
reg: X64Register,
|
||||
data: *const c_void,
|
||||
size: usize,
|
||||
) -> usize {
|
||||
if size == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if data.is_null() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
return emulator.write_register(reg, u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_destroy_emulator(ptr: *mut c_void) {
|
||||
if ptr.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let _ = Box::from_raw(ptr as *mut IcicleEmulator);
|
||||
}
|
||||
}
|
||||
965
src/backends/icicle-emulator/icicle-bridge/src/registers.rs
Normal file
965
src/backends/icicle-emulator/icicle-bridge/src/registers.rs
Normal file
@@ -0,0 +1,965 @@
|
||||
#[repr(i32)]
|
||||
#[derive(PartialEq)]
|
||||
pub enum X64Register {
|
||||
Invalid = 0,
|
||||
Ah,
|
||||
Al,
|
||||
Ax,
|
||||
Bh,
|
||||
Bl,
|
||||
Bp,
|
||||
Bpl,
|
||||
Bx,
|
||||
Ch,
|
||||
Cl,
|
||||
Cs,
|
||||
Cx,
|
||||
Dh,
|
||||
Di,
|
||||
Dil,
|
||||
Dl,
|
||||
Ds,
|
||||
Dx,
|
||||
Eax,
|
||||
Ebp,
|
||||
Ebx,
|
||||
Ecx,
|
||||
Edi,
|
||||
Edx,
|
||||
Eflags,
|
||||
Eip,
|
||||
Es = 26 + 2,
|
||||
Esi,
|
||||
Esp,
|
||||
Fpsw,
|
||||
Fs,
|
||||
Gs,
|
||||
Ip,
|
||||
Rax,
|
||||
Rbp,
|
||||
Rbx,
|
||||
Rcx,
|
||||
Rdi,
|
||||
Rdx,
|
||||
Rip,
|
||||
Rsi = 41 + 2,
|
||||
Rsp,
|
||||
Si,
|
||||
Sil,
|
||||
Sp,
|
||||
Spl,
|
||||
Ss,
|
||||
Cr0,
|
||||
Cr1,
|
||||
Cr2,
|
||||
Cr3,
|
||||
Cr4,
|
||||
Cr8 = 54 + 4,
|
||||
Dr0 = 58 + 8,
|
||||
Dr1,
|
||||
Dr2,
|
||||
Dr3,
|
||||
Dr4,
|
||||
Dr5,
|
||||
Dr6,
|
||||
Dr7,
|
||||
Fp0 = 73 + 9,
|
||||
Fp1,
|
||||
Fp2,
|
||||
Fp3,
|
||||
Fp4,
|
||||
Fp5,
|
||||
Fp6,
|
||||
Fp7,
|
||||
K0,
|
||||
K1,
|
||||
K2,
|
||||
K3,
|
||||
K4,
|
||||
K5,
|
||||
K6,
|
||||
K7,
|
||||
Mm0,
|
||||
Mm1,
|
||||
Mm2,
|
||||
Mm3,
|
||||
Mm4,
|
||||
Mm5,
|
||||
Mm6,
|
||||
Mm7,
|
||||
R8,
|
||||
R9,
|
||||
R10,
|
||||
R11,
|
||||
R12,
|
||||
R13,
|
||||
R14,
|
||||
R15,
|
||||
St0,
|
||||
St1,
|
||||
St2,
|
||||
St3,
|
||||
St4,
|
||||
St5,
|
||||
St6,
|
||||
St7,
|
||||
Xmm0,
|
||||
Xmm1,
|
||||
Xmm2,
|
||||
Xmm3,
|
||||
Xmm4,
|
||||
Xmm5,
|
||||
Xmm6,
|
||||
Xmm7,
|
||||
Xmm8,
|
||||
Xmm9,
|
||||
Xmm10,
|
||||
Xmm11,
|
||||
Xmm12,
|
||||
Xmm13,
|
||||
Xmm14,
|
||||
Xmm15,
|
||||
Xmm16,
|
||||
Xmm17,
|
||||
Xmm18,
|
||||
Xmm19,
|
||||
Xmm20,
|
||||
Xmm21,
|
||||
Xmm22,
|
||||
Xmm23,
|
||||
Xmm24,
|
||||
Xmm25,
|
||||
Xmm26,
|
||||
Xmm27,
|
||||
Xmm28,
|
||||
Xmm29,
|
||||
Xmm30,
|
||||
Xmm31,
|
||||
Ymm0,
|
||||
Ymm1,
|
||||
Ymm2,
|
||||
Ymm3,
|
||||
Ymm4,
|
||||
Ymm5,
|
||||
Ymm6,
|
||||
Ymm7,
|
||||
Ymm8,
|
||||
Ymm9,
|
||||
Ymm10,
|
||||
Ymm11,
|
||||
Ymm12,
|
||||
Ymm13,
|
||||
Ymm14,
|
||||
Ymm15,
|
||||
Ymm16,
|
||||
Ymm17,
|
||||
Ymm18,
|
||||
Ymm19,
|
||||
Ymm20,
|
||||
Ymm21,
|
||||
Ymm22,
|
||||
Ymm23,
|
||||
Ymm24,
|
||||
Ymm25,
|
||||
Ymm26,
|
||||
Ymm27,
|
||||
Ymm28,
|
||||
Ymm29,
|
||||
Ymm30,
|
||||
Ymm31,
|
||||
Zmm0,
|
||||
Zmm1,
|
||||
Zmm2,
|
||||
Zmm3,
|
||||
Zmm4,
|
||||
Zmm5,
|
||||
Zmm6,
|
||||
Zmm7,
|
||||
Zmm8,
|
||||
Zmm9,
|
||||
Zmm10,
|
||||
Zmm11,
|
||||
Zmm12,
|
||||
Zmm13,
|
||||
Zmm14,
|
||||
Zmm15,
|
||||
Zmm16,
|
||||
Zmm17,
|
||||
Zmm18,
|
||||
Zmm19,
|
||||
Zmm20,
|
||||
Zmm21,
|
||||
Zmm22,
|
||||
Zmm23,
|
||||
Zmm24,
|
||||
Zmm25,
|
||||
Zmm26,
|
||||
Zmm27,
|
||||
Zmm28,
|
||||
Zmm29,
|
||||
Zmm30,
|
||||
Zmm31,
|
||||
R8b,
|
||||
R9b,
|
||||
R10b,
|
||||
R11b,
|
||||
R12b,
|
||||
R13b,
|
||||
R14b,
|
||||
R15b,
|
||||
R8d,
|
||||
R9d,
|
||||
R10d,
|
||||
R11d,
|
||||
R12d,
|
||||
R13d,
|
||||
R14d,
|
||||
R15d,
|
||||
R8w,
|
||||
R9w,
|
||||
R10w,
|
||||
R11w,
|
||||
R12w,
|
||||
R13w,
|
||||
R14w,
|
||||
R15w,
|
||||
Idtr,
|
||||
Gdtr,
|
||||
Ldtr,
|
||||
Tr,
|
||||
Fpcw,
|
||||
Fptag,
|
||||
Msr,
|
||||
Mxcsr,
|
||||
FsBase,
|
||||
GsBase,
|
||||
Flags,
|
||||
Rflags,
|
||||
Fip,
|
||||
Fcs,
|
||||
Fdp,
|
||||
Fds,
|
||||
Fop,
|
||||
End, // Must be last
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct X64RegisterNodes {
|
||||
rax: pcode::VarNode,
|
||||
rbx: pcode::VarNode,
|
||||
rcx: pcode::VarNode,
|
||||
rdx: pcode::VarNode,
|
||||
rsi: pcode::VarNode,
|
||||
rdi: pcode::VarNode,
|
||||
rbp: pcode::VarNode,
|
||||
rsp: pcode::VarNode,
|
||||
r8: pcode::VarNode,
|
||||
r9: pcode::VarNode,
|
||||
r10: pcode::VarNode,
|
||||
r11: pcode::VarNode,
|
||||
r12: pcode::VarNode,
|
||||
r13: pcode::VarNode,
|
||||
r14: pcode::VarNode,
|
||||
r15: pcode::VarNode,
|
||||
rip: pcode::VarNode,
|
||||
cs: pcode::VarNode,
|
||||
ds: pcode::VarNode,
|
||||
es: pcode::VarNode,
|
||||
fs: pcode::VarNode,
|
||||
gs: pcode::VarNode,
|
||||
ss: pcode::VarNode,
|
||||
ah: pcode::VarNode,
|
||||
al: pcode::VarNode,
|
||||
ax: pcode::VarNode,
|
||||
bh: pcode::VarNode,
|
||||
bl: pcode::VarNode,
|
||||
bpl: pcode::VarNode,
|
||||
ch: pcode::VarNode,
|
||||
cl: pcode::VarNode,
|
||||
cx: pcode::VarNode,
|
||||
dh: pcode::VarNode,
|
||||
dil: pcode::VarNode,
|
||||
dl: pcode::VarNode,
|
||||
dx: pcode::VarNode,
|
||||
eax: pcode::VarNode,
|
||||
ebp: pcode::VarNode,
|
||||
ebx: pcode::VarNode,
|
||||
ecx: pcode::VarNode,
|
||||
edi: pcode::VarNode,
|
||||
edx: pcode::VarNode,
|
||||
esi: pcode::VarNode,
|
||||
esp: pcode::VarNode,
|
||||
fpsw: pcode::VarNode,
|
||||
gdtr: pcode::VarNode,
|
||||
idtr: pcode::VarNode,
|
||||
ldtr: pcode::VarNode,
|
||||
tr: pcode::VarNode,
|
||||
cr0: pcode::VarNode,
|
||||
cr1: pcode::VarNode,
|
||||
cr2: pcode::VarNode,
|
||||
cr3: pcode::VarNode,
|
||||
cr4: pcode::VarNode,
|
||||
cr8: pcode::VarNode,
|
||||
dr0: pcode::VarNode,
|
||||
dr1: pcode::VarNode,
|
||||
dr2: pcode::VarNode,
|
||||
dr3: pcode::VarNode,
|
||||
dr4: pcode::VarNode,
|
||||
dr5: pcode::VarNode,
|
||||
dr6: pcode::VarNode,
|
||||
dr7: pcode::VarNode,
|
||||
fp0: pcode::VarNode,
|
||||
fp1: pcode::VarNode,
|
||||
fp2: pcode::VarNode,
|
||||
fp3: pcode::VarNode,
|
||||
fp4: pcode::VarNode,
|
||||
fp5: pcode::VarNode,
|
||||
fp6: pcode::VarNode,
|
||||
fp7: pcode::VarNode,
|
||||
/*k0: pcode::VarNode,
|
||||
k1: pcode::VarNode,
|
||||
k2: pcode::VarNode,
|
||||
k3: pcode::VarNode,
|
||||
k4: pcode::VarNode,
|
||||
k5: pcode::VarNode,
|
||||
k6: pcode::VarNode,
|
||||
k7: pcode::VarNode,*/
|
||||
mm0: pcode::VarNode,
|
||||
mm1: pcode::VarNode,
|
||||
mm2: pcode::VarNode,
|
||||
mm3: pcode::VarNode,
|
||||
mm4: pcode::VarNode,
|
||||
mm5: pcode::VarNode,
|
||||
mm6: pcode::VarNode,
|
||||
mm7: pcode::VarNode,
|
||||
st0: pcode::VarNode,
|
||||
st1: pcode::VarNode,
|
||||
st2: pcode::VarNode,
|
||||
st3: pcode::VarNode,
|
||||
st4: pcode::VarNode,
|
||||
st5: pcode::VarNode,
|
||||
st6: pcode::VarNode,
|
||||
st7: pcode::VarNode,
|
||||
xmm0: pcode::VarNode,
|
||||
xmm1: pcode::VarNode,
|
||||
xmm2: pcode::VarNode,
|
||||
xmm3: pcode::VarNode,
|
||||
xmm4: pcode::VarNode,
|
||||
xmm5: pcode::VarNode,
|
||||
xmm6: pcode::VarNode,
|
||||
xmm7: pcode::VarNode,
|
||||
xmm8: pcode::VarNode,
|
||||
xmm9: pcode::VarNode,
|
||||
xmm10: pcode::VarNode,
|
||||
xmm11: pcode::VarNode,
|
||||
xmm12: pcode::VarNode,
|
||||
xmm13: pcode::VarNode,
|
||||
xmm14: pcode::VarNode,
|
||||
xmm15: pcode::VarNode,
|
||||
/*xmm16: pcode::VarNode,
|
||||
xmm17: pcode::VarNode,
|
||||
xmm18: pcode::VarNode,
|
||||
xmm19: pcode::VarNode,
|
||||
xmm20: pcode::VarNode,
|
||||
xmm21: pcode::VarNode,
|
||||
xmm22: pcode::VarNode,
|
||||
xmm23: pcode::VarNode,
|
||||
xmm24: pcode::VarNode,
|
||||
xmm25: pcode::VarNode,
|
||||
xmm26: pcode::VarNode,
|
||||
xmm27: pcode::VarNode,
|
||||
xmm28: pcode::VarNode,
|
||||
xmm29: pcode::VarNode,
|
||||
xmm30: pcode::VarNode,
|
||||
xmm31: pcode::VarNode,*/
|
||||
ymm0: pcode::VarNode,
|
||||
ymm1: pcode::VarNode,
|
||||
ymm2: pcode::VarNode,
|
||||
ymm3: pcode::VarNode,
|
||||
ymm4: pcode::VarNode,
|
||||
ymm5: pcode::VarNode,
|
||||
ymm6: pcode::VarNode,
|
||||
ymm7: pcode::VarNode,
|
||||
ymm8: pcode::VarNode,
|
||||
ymm9: pcode::VarNode,
|
||||
ymm10: pcode::VarNode,
|
||||
ymm11: pcode::VarNode,
|
||||
ymm12: pcode::VarNode,
|
||||
ymm13: pcode::VarNode,
|
||||
ymm14: pcode::VarNode,
|
||||
ymm15: pcode::VarNode,
|
||||
/*ymm16: pcode::VarNode,
|
||||
ymm17: pcode::VarNode,
|
||||
ymm18: pcode::VarNode,
|
||||
ymm19: pcode::VarNode,
|
||||
ymm20: pcode::VarNode,
|
||||
ymm21: pcode::VarNode,
|
||||
ymm22: pcode::VarNode,
|
||||
ymm23: pcode::VarNode,
|
||||
ymm24: pcode::VarNode,
|
||||
ymm25: pcode::VarNode,
|
||||
ymm26: pcode::VarNode,
|
||||
ymm27: pcode::VarNode,
|
||||
ymm28: pcode::VarNode,
|
||||
ymm29: pcode::VarNode,
|
||||
ymm30: pcode::VarNode,
|
||||
ymm31: pcode::VarNode,*/
|
||||
/*zmm0: pcode::VarNode,
|
||||
zmm1: pcode::VarNode,
|
||||
zmm2: pcode::VarNode,
|
||||
zmm3: pcode::VarNode,
|
||||
zmm4: pcode::VarNode,
|
||||
zmm5: pcode::VarNode,
|
||||
zmm6: pcode::VarNode,
|
||||
zmm7: pcode::VarNode,
|
||||
zmm8: pcode::VarNode,
|
||||
zmm9: pcode::VarNode,
|
||||
zmm10: pcode::VarNode,
|
||||
zmm11: pcode::VarNode,
|
||||
zmm12: pcode::VarNode,
|
||||
zmm13: pcode::VarNode,
|
||||
zmm14: pcode::VarNode,
|
||||
zmm15: pcode::VarNode,
|
||||
zmm16: pcode::VarNode,
|
||||
zmm17: pcode::VarNode,
|
||||
zmm18: pcode::VarNode,
|
||||
zmm19: pcode::VarNode,
|
||||
zmm20: pcode::VarNode,
|
||||
zmm21: pcode::VarNode,
|
||||
zmm22: pcode::VarNode,
|
||||
zmm23: pcode::VarNode,
|
||||
zmm24: pcode::VarNode,
|
||||
zmm25: pcode::VarNode,
|
||||
zmm26: pcode::VarNode,
|
||||
zmm27: pcode::VarNode,
|
||||
zmm28: pcode::VarNode,
|
||||
zmm29: pcode::VarNode,
|
||||
zmm30: pcode::VarNode,
|
||||
zmm31: pcode::VarNode,*/
|
||||
r8b: pcode::VarNode,
|
||||
r9b: pcode::VarNode,
|
||||
r10b: pcode::VarNode,
|
||||
r11b: pcode::VarNode,
|
||||
r12b: pcode::VarNode,
|
||||
r13b: pcode::VarNode,
|
||||
r14b: pcode::VarNode,
|
||||
r15b: pcode::VarNode,
|
||||
r8d: pcode::VarNode,
|
||||
r9d: pcode::VarNode,
|
||||
r10d: pcode::VarNode,
|
||||
r11d: pcode::VarNode,
|
||||
r12d: pcode::VarNode,
|
||||
r13d: pcode::VarNode,
|
||||
r14d: pcode::VarNode,
|
||||
r15d: pcode::VarNode,
|
||||
r8w: pcode::VarNode,
|
||||
r9w: pcode::VarNode,
|
||||
r10w: pcode::VarNode,
|
||||
r11w: pcode::VarNode,
|
||||
r12w: pcode::VarNode,
|
||||
r13w: pcode::VarNode,
|
||||
r14w: pcode::VarNode,
|
||||
r15w: pcode::VarNode,
|
||||
fpcw: pcode::VarNode,
|
||||
fptag: pcode::VarNode,
|
||||
//msr: pcode::VarNode,
|
||||
mxcsr: pcode::VarNode,
|
||||
fs_base: pcode::VarNode,
|
||||
gs_base: pcode::VarNode,
|
||||
fip: pcode::VarNode,
|
||||
fcs: pcode::VarNode,
|
||||
fdp: pcode::VarNode,
|
||||
fds: pcode::VarNode,
|
||||
fop: pcode::VarNode,
|
||||
flags: Vec<pcode::VarNode>,
|
||||
}
|
||||
|
||||
impl X64RegisterNodes {
|
||||
pub fn new(arch: &icicle_cpu::Arch) -> Self {
|
||||
let r = |name: &str| arch.sleigh.get_reg(name).unwrap().var;
|
||||
let nodes = [
|
||||
"CF", "F1", "PF", "F3", "AF", "F5", "ZF", "SF", "TF", "IF", "DF", "OF", "IOPL", "NT",
|
||||
"F15", "RF", "VM", "AC", "VIF", "VIP", "ID",
|
||||
];
|
||||
|
||||
Self {
|
||||
rax: r("RAX"),
|
||||
rbx: r("RBX"),
|
||||
rcx: r("RCX"),
|
||||
rdx: r("RDX"),
|
||||
rsi: r("RSI"),
|
||||
rdi: r("RDI"),
|
||||
rbp: r("RBP"),
|
||||
rsp: r("RSP"),
|
||||
r8: r("R8"),
|
||||
r9: r("R9"),
|
||||
r10: r("R10"),
|
||||
r11: r("R11"),
|
||||
r12: r("R12"),
|
||||
r13: r("R13"),
|
||||
r14: r("R14"),
|
||||
r15: r("R15"),
|
||||
rip: r("RIP"),
|
||||
cs: r("CS"),
|
||||
ds: r("DS"),
|
||||
es: r("ES"),
|
||||
fs: r("FS"),
|
||||
gs: r("GS"),
|
||||
ss: r("SS"),
|
||||
ah: r("AH"),
|
||||
al: r("AL"),
|
||||
ax: r("AX"),
|
||||
bh: r("BH"),
|
||||
bl: r("BL"),
|
||||
bpl: r("BPL"),
|
||||
ch: r("CH"),
|
||||
cl: r("CL"),
|
||||
cx: r("CX"),
|
||||
dh: r("DH"),
|
||||
dil: r("DIL"),
|
||||
dl: r("DL"),
|
||||
dx: r("DX"),
|
||||
eax: r("EAX"),
|
||||
ebp: r("EBP"),
|
||||
ebx: r("EBX"),
|
||||
ecx: r("ECX"),
|
||||
edi: r("EDI"),
|
||||
edx: r("EDX"),
|
||||
esi: r("ESI"),
|
||||
esp: r("ESP"),
|
||||
fpsw: r("FPUStatusWord"),
|
||||
gdtr: r("GDTR"),
|
||||
idtr: r("IDTR"),
|
||||
ldtr: r("LDTR"),
|
||||
tr: r("TR"),
|
||||
cr0: r("CR0"),
|
||||
cr1: r("CR1"),
|
||||
cr2: r("CR2"),
|
||||
cr3: r("CR3"),
|
||||
cr4: r("CR4"),
|
||||
cr8: r("CR8"),
|
||||
dr0: r("DR0"),
|
||||
dr1: r("DR1"),
|
||||
dr2: r("DR2"),
|
||||
dr3: r("DR3"),
|
||||
dr4: r("DR4"),
|
||||
dr5: r("DR5"),
|
||||
dr6: r("DR6"),
|
||||
dr7: r("DR7"),
|
||||
fp0: r("ST0"), // ??
|
||||
fp1: r("ST1"),
|
||||
fp2: r("ST2"),
|
||||
fp3: r("ST3"),
|
||||
fp4: r("ST4"),
|
||||
fp5: r("ST5"),
|
||||
fp6: r("ST6"),
|
||||
fp7: r("ST7"),
|
||||
/*k0: r("K0"),
|
||||
k1: r("K1"),
|
||||
k2: r("K2"),
|
||||
k3: r("K3"),
|
||||
k4: r("K4"),
|
||||
k5: r("K5"),
|
||||
k6: r("K6"),
|
||||
k7: r("K7"),*/
|
||||
mm0: r("MM0"),
|
||||
mm1: r("MM1"),
|
||||
mm2: r("MM2"),
|
||||
mm3: r("MM3"),
|
||||
mm4: r("MM4"),
|
||||
mm5: r("MM5"),
|
||||
mm6: r("MM6"),
|
||||
mm7: r("MM7"),
|
||||
st0: r("ST0"),
|
||||
st1: r("ST1"),
|
||||
st2: r("ST2"),
|
||||
st3: r("ST3"),
|
||||
st4: r("ST4"),
|
||||
st5: r("ST5"),
|
||||
st6: r("ST6"),
|
||||
st7: r("ST7"),
|
||||
xmm0: r("XMM0"),
|
||||
xmm1: r("XMM1"),
|
||||
xmm2: r("XMM2"),
|
||||
xmm3: r("XMM3"),
|
||||
xmm4: r("XMM4"),
|
||||
xmm5: r("XMM5"),
|
||||
xmm6: r("XMM6"),
|
||||
xmm7: r("XMM7"),
|
||||
xmm8: r("XMM8"),
|
||||
xmm9: r("XMM9"),
|
||||
xmm10: r("XMM10"),
|
||||
xmm11: r("XMM11"),
|
||||
xmm12: r("XMM12"),
|
||||
xmm13: r("XMM13"),
|
||||
xmm14: r("XMM14"),
|
||||
xmm15: r("XMM15"),
|
||||
/*xmm16: r("XMM16"),
|
||||
xmm17: r("XMM17"),
|
||||
xmm18: r("XMM18"),
|
||||
xmm19: r("XMM19"),
|
||||
xmm20: r("XMM20"),
|
||||
xmm21: r("XMM21"),
|
||||
xmm22: r("XMM22"),
|
||||
xmm23: r("XMM23"),
|
||||
xmm24: r("XMM24"),
|
||||
xmm25: r("XMM25"),
|
||||
xmm26: r("XMM26"),
|
||||
xmm27: r("XMM27"),
|
||||
xmm28: r("XMM28"),
|
||||
xmm29: r("XMM29"),
|
||||
xmm30: r("XMM30"),
|
||||
xmm31: r("XMM31"),*/
|
||||
ymm0: r("YMM0"),
|
||||
ymm1: r("YMM1"),
|
||||
ymm2: r("YMM2"),
|
||||
ymm3: r("YMM3"),
|
||||
ymm4: r("YMM4"),
|
||||
ymm5: r("YMM5"),
|
||||
ymm6: r("YMM6"),
|
||||
ymm7: r("YMM7"),
|
||||
ymm8: r("YMM8"),
|
||||
ymm9: r("YMM9"),
|
||||
ymm10: r("YMM10"),
|
||||
ymm11: r("YMM11"),
|
||||
ymm12: r("YMM12"),
|
||||
ymm13: r("YMM13"),
|
||||
ymm14: r("YMM14"),
|
||||
ymm15: r("YMM15"),
|
||||
/*ymm16: r("YMM16"),
|
||||
ymm17: r("YMM17"),
|
||||
ymm18: r("YMM18"),
|
||||
ymm19: r("YMM19"),
|
||||
ymm20: r("YMM20"),
|
||||
ymm21: r("YMM21"),
|
||||
ymm22: r("YMM22"),
|
||||
ymm23: r("YMM23"),
|
||||
ymm24: r("YMM24"),
|
||||
ymm25: r("YMM25"),
|
||||
ymm26: r("YMM26"),
|
||||
ymm27: r("YMM27"),
|
||||
ymm28: r("YMM28"),
|
||||
ymm29: r("YMM29"),
|
||||
ymm30: r("YMM30"),
|
||||
ymm31: r("YMM31"),*/
|
||||
/*zmm0: r("ZMM0"),
|
||||
zmm1: r("ZMM1"),
|
||||
zmm2: r("ZMM2"),
|
||||
zmm3: r("ZMM3"),
|
||||
zmm4: r("ZMM4"),
|
||||
zmm5: r("ZMM5"),
|
||||
zmm6: r("ZMM6"),
|
||||
zmm7: r("ZMM7"),
|
||||
zmm8: r("ZMM8"),
|
||||
zmm9: r("ZMM9"),
|
||||
zmm10: r("ZMM10"),
|
||||
zmm11: r("ZMM11"),
|
||||
zmm12: r("ZMM12"),
|
||||
zmm13: r("ZMM13"),
|
||||
zmm14: r("ZMM14"),
|
||||
zmm15: r("ZMM15"),
|
||||
zmm16: r("ZMM16"),
|
||||
zmm17: r("ZMM17"),
|
||||
zmm18: r("ZMM18"),
|
||||
zmm19: r("ZMM19"),
|
||||
zmm20: r("ZMM20"),
|
||||
zmm21: r("ZMM21"),
|
||||
zmm22: r("ZMM22"),
|
||||
zmm23: r("ZMM23"),
|
||||
zmm24: r("ZMM24"),
|
||||
zmm25: r("ZMM25"),
|
||||
zmm26: r("ZMM26"),
|
||||
zmm27: r("ZMM27"),
|
||||
zmm28: r("ZMM28"),
|
||||
zmm29: r("ZMM29"),
|
||||
zmm30: r("ZMM30"),
|
||||
zmm31: r("ZMM31"),*/
|
||||
r8b: r("R8B"),
|
||||
r9b: r("R9B"),
|
||||
r10b: r("R10B"),
|
||||
r11b: r("R11B"),
|
||||
r12b: r("R12B"),
|
||||
r13b: r("R13B"),
|
||||
r14b: r("R14B"),
|
||||
r15b: r("R15B"),
|
||||
r8d: r("R8D"),
|
||||
r9d: r("R9D"),
|
||||
r10d: r("R10D"),
|
||||
r11d: r("R11D"),
|
||||
r12d: r("R12D"),
|
||||
r13d: r("R13D"),
|
||||
r14d: r("R14D"),
|
||||
r15d: r("R15D"),
|
||||
r8w: r("R8W"),
|
||||
r9w: r("R9W"),
|
||||
r10w: r("R10W"),
|
||||
r11w: r("R11W"),
|
||||
r12w: r("R12W"),
|
||||
r13w: r("R13W"),
|
||||
r14w: r("R14W"),
|
||||
r15w: r("R15W"),
|
||||
fpcw: r("FPUControlWord"),
|
||||
fptag: r("FPUTagWord"),
|
||||
mxcsr: r("MXCSR"),
|
||||
fip: r("FPUInstructionPointer"),
|
||||
fdp: r("FPUDataPointer"),
|
||||
fop: r("FPULastInstructionOpcode"),
|
||||
fds: r("DS"), // ?
|
||||
fcs: r("CS"), // ?
|
||||
//msr: r("MSR"),
|
||||
fs_base: r("FS_OFFSET"),
|
||||
gs_base: r("GS_OFFSET"),
|
||||
flags: nodes.map(|name: &str| r(name)).to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_flags(&self, cpu: &mut icicle_cpu::Cpu) -> u64 {
|
||||
let mut res: u64 = 0;
|
||||
|
||||
for (index, element) in self.flags.iter().enumerate() {
|
||||
let flag = cpu.read_reg(*element);
|
||||
res |= (flag & 1) << index;
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn set_flags(&self, cpu: &mut icicle_cpu::Cpu, value: u64) {
|
||||
for (index, element) in self.flags.iter().enumerate() {
|
||||
let flag = (value >> index) & 1;
|
||||
cpu.write_reg(*element, flag);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_node(&self, reg: X64Register) -> pcode::VarNode {
|
||||
match reg {
|
||||
X64Register::Rax => self.rax,
|
||||
X64Register::Rbx => self.rbx,
|
||||
X64Register::Rcx => self.rcx,
|
||||
X64Register::Rdx => self.rdx,
|
||||
X64Register::Rsi => self.rsi,
|
||||
X64Register::Rdi => self.rdi,
|
||||
X64Register::Rbp => self.rbp,
|
||||
X64Register::Rsp => self.rsp,
|
||||
X64Register::R8 => self.r8,
|
||||
X64Register::R9 => self.r9,
|
||||
X64Register::R10 => self.r10,
|
||||
X64Register::R11 => self.r11,
|
||||
X64Register::R12 => self.r12,
|
||||
X64Register::R13 => self.r13,
|
||||
X64Register::R14 => self.r14,
|
||||
X64Register::R15 => self.r15,
|
||||
X64Register::Rip => self.rip,
|
||||
X64Register::Cs => self.cs,
|
||||
X64Register::Ds => self.ds,
|
||||
X64Register::Es => self.es,
|
||||
X64Register::Fs => self.fs,
|
||||
X64Register::Gs => self.gs,
|
||||
X64Register::Ss => self.ss,
|
||||
X64Register::Ah => self.ah,
|
||||
X64Register::Al => self.al,
|
||||
X64Register::Ax => self.ax,
|
||||
X64Register::Bh => self.bh,
|
||||
X64Register::Bl => self.bl,
|
||||
X64Register::Bpl => self.bpl,
|
||||
X64Register::Ch => self.ch,
|
||||
X64Register::Cl => self.cl,
|
||||
X64Register::Cx => self.cx,
|
||||
X64Register::Dh => self.dh,
|
||||
X64Register::Dil => self.dil,
|
||||
X64Register::Dl => self.dl,
|
||||
X64Register::Dx => self.dx,
|
||||
X64Register::Eax => self.eax,
|
||||
X64Register::Ebp => self.ebp,
|
||||
X64Register::Ebx => self.ebx,
|
||||
X64Register::Ecx => self.ecx,
|
||||
X64Register::Edi => self.edi,
|
||||
X64Register::Edx => self.edx,
|
||||
X64Register::Esi => self.esi,
|
||||
X64Register::Esp => self.esp,
|
||||
X64Register::Fpsw => self.fpsw,
|
||||
X64Register::Gdtr => self.gdtr,
|
||||
X64Register::Idtr => self.idtr,
|
||||
X64Register::Ldtr => self.ldtr,
|
||||
X64Register::Tr => self.tr,
|
||||
X64Register::Cr0 => self.cr0,
|
||||
X64Register::Cr1 => self.cr1,
|
||||
X64Register::Cr2 => self.cr2,
|
||||
X64Register::Cr3 => self.cr3,
|
||||
X64Register::Cr4 => self.cr4,
|
||||
X64Register::Cr8 => self.cr8,
|
||||
X64Register::Dr0 => self.dr0,
|
||||
X64Register::Dr1 => self.dr1,
|
||||
X64Register::Dr2 => self.dr2,
|
||||
X64Register::Dr3 => self.dr3,
|
||||
X64Register::Dr4 => self.dr4,
|
||||
X64Register::Dr5 => self.dr5,
|
||||
X64Register::Dr6 => self.dr6,
|
||||
X64Register::Dr7 => self.dr7,
|
||||
X64Register::Fp0 => self.fp0,
|
||||
X64Register::Fp1 => self.fp1,
|
||||
X64Register::Fp2 => self.fp2,
|
||||
X64Register::Fp3 => self.fp3,
|
||||
X64Register::Fp4 => self.fp4,
|
||||
X64Register::Fp5 => self.fp5,
|
||||
X64Register::Fp6 => self.fp6,
|
||||
X64Register::Fp7 => self.fp7,
|
||||
/*X64Register::K0 => self.k0,
|
||||
X64Register::K1 => self.k1,
|
||||
X64Register::K2 => self.k2,
|
||||
X64Register::K3 => self.k3,
|
||||
X64Register::K4 => self.k4,
|
||||
X64Register::K5 => self.k5,
|
||||
X64Register::K6 => self.k6,
|
||||
X64Register::K7 => self.k7,*/
|
||||
X64Register::Mm0 => self.mm0,
|
||||
X64Register::Mm1 => self.mm1,
|
||||
X64Register::Mm2 => self.mm2,
|
||||
X64Register::Mm3 => self.mm3,
|
||||
X64Register::Mm4 => self.mm4,
|
||||
X64Register::Mm5 => self.mm5,
|
||||
X64Register::Mm6 => self.mm6,
|
||||
X64Register::Mm7 => self.mm7,
|
||||
X64Register::St0 => self.st0,
|
||||
X64Register::St1 => self.st1,
|
||||
X64Register::St2 => self.st2,
|
||||
X64Register::St3 => self.st3,
|
||||
X64Register::St4 => self.st4,
|
||||
X64Register::St5 => self.st5,
|
||||
X64Register::St6 => self.st6,
|
||||
X64Register::St7 => self.st7,
|
||||
X64Register::Xmm0 => self.xmm0,
|
||||
X64Register::Xmm1 => self.xmm1,
|
||||
X64Register::Xmm2 => self.xmm2,
|
||||
X64Register::Xmm3 => self.xmm3,
|
||||
X64Register::Xmm4 => self.xmm4,
|
||||
X64Register::Xmm5 => self.xmm5,
|
||||
X64Register::Xmm6 => self.xmm6,
|
||||
X64Register::Xmm7 => self.xmm7,
|
||||
X64Register::Xmm8 => self.xmm8,
|
||||
X64Register::Xmm9 => self.xmm9,
|
||||
X64Register::Xmm10 => self.xmm10,
|
||||
X64Register::Xmm11 => self.xmm11,
|
||||
X64Register::Xmm12 => self.xmm12,
|
||||
X64Register::Xmm13 => self.xmm13,
|
||||
X64Register::Xmm14 => self.xmm14,
|
||||
X64Register::Xmm15 => self.xmm15,
|
||||
/*X64Register::Xmm16 => self.xmm16,
|
||||
X64Register::Xmm17 => self.xmm17,
|
||||
X64Register::Xmm18 => self.xmm18,
|
||||
X64Register::Xmm19 => self.xmm19,
|
||||
X64Register::Xmm20 => self.xmm20,
|
||||
X64Register::Xmm21 => self.xmm21,
|
||||
X64Register::Xmm22 => self.xmm22,
|
||||
X64Register::Xmm23 => self.xmm23,
|
||||
X64Register::Xmm24 => self.xmm24,
|
||||
X64Register::Xmm25 => self.xmm25,
|
||||
X64Register::Xmm26 => self.xmm26,
|
||||
X64Register::Xmm27 => self.xmm27,
|
||||
X64Register::Xmm28 => self.xmm28,
|
||||
X64Register::Xmm29 => self.xmm29,
|
||||
X64Register::Xmm30 => self.xmm30,
|
||||
X64Register::Xmm31 => self.xmm31,*/
|
||||
X64Register::Ymm0 => self.ymm0,
|
||||
X64Register::Ymm1 => self.ymm1,
|
||||
X64Register::Ymm2 => self.ymm2,
|
||||
X64Register::Ymm3 => self.ymm3,
|
||||
X64Register::Ymm4 => self.ymm4,
|
||||
X64Register::Ymm5 => self.ymm5,
|
||||
X64Register::Ymm6 => self.ymm6,
|
||||
X64Register::Ymm7 => self.ymm7,
|
||||
X64Register::Ymm8 => self.ymm8,
|
||||
X64Register::Ymm9 => self.ymm9,
|
||||
X64Register::Ymm10 => self.ymm10,
|
||||
X64Register::Ymm11 => self.ymm11,
|
||||
X64Register::Ymm12 => self.ymm12,
|
||||
X64Register::Ymm13 => self.ymm13,
|
||||
X64Register::Ymm14 => self.ymm14,
|
||||
X64Register::Ymm15 => self.ymm15,
|
||||
/*X64Register::Ymm16 => self.ymm16,
|
||||
X64Register::Ymm17 => self.ymm17,
|
||||
X64Register::Ymm18 => self.ymm18,
|
||||
X64Register::Ymm19 => self.ymm19,
|
||||
X64Register::Ymm20 => self.ymm20,
|
||||
X64Register::Ymm21 => self.ymm21,
|
||||
X64Register::Ymm22 => self.ymm22,
|
||||
X64Register::Ymm23 => self.ymm23,
|
||||
X64Register::Ymm24 => self.ymm24,
|
||||
X64Register::Ymm25 => self.ymm25,
|
||||
X64Register::Ymm26 => self.ymm26,
|
||||
X64Register::Ymm27 => self.ymm27,
|
||||
X64Register::Ymm28 => self.ymm28,
|
||||
X64Register::Ymm29 => self.ymm29,
|
||||
X64Register::Ymm30 => self.ymm30,
|
||||
X64Register::Ymm31 => self.ymm31,*/
|
||||
/*X64Register::Zmm0 => self.zmm0,
|
||||
X64Register::Zmm1 => self.zmm1,
|
||||
X64Register::Zmm2 => self.zmm2,
|
||||
X64Register::Zmm3 => self.zmm3,
|
||||
X64Register::Zmm4 => self.zmm4,
|
||||
X64Register::Zmm5 => self.zmm5,
|
||||
X64Register::Zmm6 => self.zmm6,
|
||||
X64Register::Zmm7 => self.zmm7,
|
||||
X64Register::Zmm8 => self.zmm8,
|
||||
X64Register::Zmm9 => self.zmm9,
|
||||
X64Register::Zmm10 => self.zmm10,
|
||||
X64Register::Zmm11 => self.zmm11,
|
||||
X64Register::Zmm12 => self.zmm12,
|
||||
X64Register::Zmm13 => self.zmm13,
|
||||
X64Register::Zmm14 => self.zmm14,
|
||||
X64Register::Zmm15 => self.zmm15,
|
||||
X64Register::Zmm16 => self.zmm16,
|
||||
X64Register::Zmm17 => self.zmm17,
|
||||
X64Register::Zmm18 => self.zmm18,
|
||||
X64Register::Zmm19 => self.zmm19,
|
||||
X64Register::Zmm20 => self.zmm20,
|
||||
X64Register::Zmm21 => self.zmm21,
|
||||
X64Register::Zmm22 => self.zmm22,
|
||||
X64Register::Zmm23 => self.zmm23,
|
||||
X64Register::Zmm24 => self.zmm24,
|
||||
X64Register::Zmm25 => self.zmm25,
|
||||
X64Register::Zmm26 => self.zmm26,
|
||||
X64Register::Zmm27 => self.zmm27,
|
||||
X64Register::Zmm28 => self.zmm28,
|
||||
X64Register::Zmm29 => self.zmm29,
|
||||
X64Register::Zmm30 => self.zmm30,
|
||||
X64Register::Zmm31 => self.zmm31,*/
|
||||
X64Register::R8b => self.r8b,
|
||||
X64Register::R9b => self.r9b,
|
||||
X64Register::R10b => self.r10b,
|
||||
X64Register::R11b => self.r11b,
|
||||
X64Register::R12b => self.r12b,
|
||||
X64Register::R13b => self.r13b,
|
||||
X64Register::R14b => self.r14b,
|
||||
X64Register::R15b => self.r15b,
|
||||
X64Register::R8d => self.r8d,
|
||||
X64Register::R9d => self.r9d,
|
||||
X64Register::R10d => self.r10d,
|
||||
X64Register::R11d => self.r11d,
|
||||
X64Register::R12d => self.r12d,
|
||||
X64Register::R13d => self.r13d,
|
||||
X64Register::R14d => self.r14d,
|
||||
X64Register::R15d => self.r15d,
|
||||
X64Register::R8w => self.r8w,
|
||||
X64Register::R9w => self.r9w,
|
||||
X64Register::R10w => self.r10w,
|
||||
X64Register::R11w => self.r11w,
|
||||
X64Register::R12w => self.r12w,
|
||||
X64Register::R13w => self.r13w,
|
||||
X64Register::R14w => self.r14w,
|
||||
X64Register::R15w => self.r15w,
|
||||
X64Register::Fpcw => self.fpcw,
|
||||
X64Register::Fptag => self.fptag,
|
||||
//X64Register::Msr => self.msr,
|
||||
X64Register::Mxcsr => self.mxcsr,
|
||||
X64Register::FsBase => self.fs_base,
|
||||
X64Register::GsBase => self.gs_base,
|
||||
X64Register::Fip => self.fip,
|
||||
X64Register::Fcs => self.fcs,
|
||||
X64Register::Fdp => self.fdp,
|
||||
X64Register::Fds => self.fds,
|
||||
X64Register::Fop => self.fop,
|
||||
_ => panic!("Unsupported register"),
|
||||
}
|
||||
}
|
||||
}
|
||||
434
src/backends/icicle-emulator/icicle_x64_emulator.cpp
Normal file
434
src/backends/icicle-emulator/icicle_x64_emulator.cpp
Normal file
@@ -0,0 +1,434 @@
|
||||
#define ICICLE_EMULATOR_IMPL
|
||||
#include "icicle_x64_emulator.hpp"
|
||||
|
||||
#include <utils/object.hpp>
|
||||
|
||||
using icicle_emulator = struct icicle_emulator_;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
using icicle_mmio_read_func = void(void* user, uint64_t address, void* data, size_t length);
|
||||
using icicle_mmio_write_func = void(void* user, uint64_t address, const void* data, size_t length);
|
||||
|
||||
using raw_func = void(void*);
|
||||
using ptr_func = void(void*, uint64_t);
|
||||
using interrupt_func = void(void*, int32_t);
|
||||
using violation_func = int32_t(void*, uint64_t address, uint8_t operation, int32_t unmapped);
|
||||
using data_accessor_func = void(void* user, const void* data, size_t length);
|
||||
using memory_access_func = icicle_mmio_write_func;
|
||||
|
||||
icicle_emulator* icicle_create_emulator();
|
||||
int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
|
||||
int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
|
||||
int32_t icicle_map_mmio(icicle_emulator*, uint64_t address, uint64_t length, icicle_mmio_read_func* read_callback,
|
||||
void* read_data, icicle_mmio_write_func* write_callback, void* write_data);
|
||||
int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length);
|
||||
int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length);
|
||||
int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length);
|
||||
int32_t icicle_save_registers(icicle_emulator*, data_accessor_func* accessor, void* accessor_data);
|
||||
int32_t icicle_restore_registers(icicle_emulator*, const void* data, size_t length);
|
||||
uint32_t icicle_add_syscall_hook(icicle_emulator*, raw_func* callback, void* data);
|
||||
uint32_t icicle_add_interrupt_hook(icicle_emulator*, interrupt_func* callback, void* data);
|
||||
uint32_t icicle_add_execution_hook(icicle_emulator*, uint64_t address, ptr_func* callback, void* data);
|
||||
uint32_t icicle_add_generic_execution_hook(icicle_emulator*, ptr_func* callback, void* data);
|
||||
uint32_t icicle_add_violation_hook(icicle_emulator*, violation_func* callback, void* data);
|
||||
uint32_t icicle_add_read_hook(icicle_emulator*, uint64_t start, uint64_t end, memory_access_func* cb, void* data);
|
||||
uint32_t icicle_add_write_hook(icicle_emulator*, uint64_t start, uint64_t end, memory_access_func* cb, void* data);
|
||||
void icicle_remove_hook(icicle_emulator*, uint32_t id);
|
||||
size_t icicle_read_register(icicle_emulator*, int reg, void* data, size_t length);
|
||||
size_t icicle_write_register(icicle_emulator*, int reg, const void* data, size_t length);
|
||||
void icicle_start(icicle_emulator*, size_t count);
|
||||
void icicle_stop(icicle_emulator*);
|
||||
void icicle_destroy_emulator(icicle_emulator*);
|
||||
}
|
||||
|
||||
namespace icicle
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void ice(const bool result, const std::string_view error)
|
||||
{
|
||||
if (!result)
|
||||
{
|
||||
throw std::runtime_error(std::string(error));
|
||||
}
|
||||
}
|
||||
|
||||
emulator_hook* wrap_hook(const uint32_t id)
|
||||
{
|
||||
return reinterpret_cast<emulator_hook*>(static_cast<size_t>(id));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct function_object : utils::object
|
||||
{
|
||||
std::function<T> func{};
|
||||
|
||||
function_object(std::function<T> f = {})
|
||||
: func(std::move(f))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto operator()(Args&&... args) const
|
||||
{
|
||||
return this->func.operator()(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
~function_object() override = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<function_object<T>> make_function_object(std::function<T> func)
|
||||
{
|
||||
return std::make_unique<function_object<T>>(std::move(func));
|
||||
}
|
||||
}
|
||||
|
||||
class icicle_x64_emulator : public x64_emulator
|
||||
{
|
||||
public:
|
||||
icicle_x64_emulator()
|
||||
: emu_(icicle_create_emulator())
|
||||
{
|
||||
if (!this->emu_)
|
||||
{
|
||||
throw std::runtime_error("Failed to create icicle emulator instance");
|
||||
}
|
||||
}
|
||||
|
||||
~icicle_x64_emulator() override
|
||||
{
|
||||
if (this->emu_)
|
||||
{
|
||||
icicle_destroy_emulator(this->emu_);
|
||||
this->emu_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void start(const size_t count) override
|
||||
{
|
||||
icicle_start(this->emu_, count);
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
icicle_stop(this->emu_);
|
||||
}
|
||||
|
||||
void load_gdt(const pointer_type address, const uint32_t limit) override
|
||||
{
|
||||
struct gdtr
|
||||
{
|
||||
uint32_t padding{};
|
||||
uint32_t limit{};
|
||||
uint64_t address{};
|
||||
};
|
||||
|
||||
const gdtr entry{.limit = limit, .address = address};
|
||||
static_assert(sizeof(gdtr) - offsetof(gdtr, limit) == 12);
|
||||
|
||||
this->write_register(x64_register::gdtr, &entry.limit, 12);
|
||||
}
|
||||
|
||||
void set_segment_base(const x64_register base, const pointer_type value) override
|
||||
{
|
||||
switch (base)
|
||||
{
|
||||
case x64_register::fs:
|
||||
case x64_register::fs_base:
|
||||
this->reg(x64_register::fs_base, value);
|
||||
break;
|
||||
case x64_register::gs:
|
||||
case x64_register::gs_base:
|
||||
this->reg(x64_register::gs_base, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t write_raw_register(const int reg, const void* value, const size_t size) override
|
||||
{
|
||||
return icicle_write_register(this->emu_, reg, value, size);
|
||||
}
|
||||
|
||||
size_t read_raw_register(const int reg, void* value, const size_t size) override
|
||||
{
|
||||
return icicle_read_register(this->emu_, reg, value, size);
|
||||
}
|
||||
|
||||
void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb,
|
||||
mmio_write_callback write_cb) override
|
||||
{
|
||||
struct mmio_wrapper : utils::object
|
||||
{
|
||||
uint64_t base{};
|
||||
mmio_read_callback read_cb{};
|
||||
mmio_write_callback write_cb{};
|
||||
};
|
||||
|
||||
auto wrapper = std::make_unique<mmio_wrapper>();
|
||||
wrapper->base = address;
|
||||
wrapper->read_cb = std::move(read_cb);
|
||||
wrapper->write_cb = std::move(write_cb);
|
||||
|
||||
auto* ptr = wrapper.get();
|
||||
this->storage_.push_back(std::move(wrapper));
|
||||
|
||||
auto* read_wrapper = +[](void* user, const uint64_t addr, void* data, const size_t length) {
|
||||
const auto* w = static_cast<mmio_wrapper*>(user);
|
||||
w->read_cb(addr - w->base, data, length);
|
||||
};
|
||||
|
||||
auto* write_wrapper = +[](void* user, const uint64_t addr, const void* data, const size_t length) {
|
||||
const auto* w = static_cast<mmio_wrapper*>(user);
|
||||
w->write_cb(addr + w->base, data, length);
|
||||
};
|
||||
|
||||
icicle_map_mmio(this->emu_, address, size, read_wrapper, ptr, write_wrapper, ptr);
|
||||
}
|
||||
|
||||
void map_memory(const uint64_t address, const size_t size, memory_permission permissions) override
|
||||
{
|
||||
const auto res = icicle_map_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
|
||||
ice(res, "Failed to map memory");
|
||||
}
|
||||
|
||||
void unmap_memory(const uint64_t address, const size_t size) override
|
||||
{
|
||||
const auto res = icicle_unmap_memory(this->emu_, address, size);
|
||||
ice(res, "Failed to unmap memory");
|
||||
}
|
||||
|
||||
bool try_read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
return icicle_read_memory(this->emu_, address, data, size);
|
||||
}
|
||||
|
||||
void read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
const auto res = this->try_read_memory(address, data, size);
|
||||
ice(res, "Failed to read memory");
|
||||
}
|
||||
|
||||
void write_memory(const uint64_t address, const void* data, const size_t size) override
|
||||
{
|
||||
const auto res = icicle_write_memory(this->emu_, address, data, size);
|
||||
ice(res, "Failed to write memory");
|
||||
}
|
||||
|
||||
void apply_memory_protection(const uint64_t address, const size_t size, memory_permission permissions) override
|
||||
{
|
||||
const auto res = icicle_protect_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
|
||||
ice(res, "Failed to apply permissions");
|
||||
}
|
||||
|
||||
emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override
|
||||
{
|
||||
if (static_cast<x64_hookable_instructions>(instruction_type) != x64_hookable_instructions::syscall)
|
||||
{
|
||||
// TODO
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto obj = make_function_object(std::move(callback));
|
||||
auto* ptr = obj.get();
|
||||
|
||||
const auto invoker = +[](void* cb) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(cb);
|
||||
(void)func(); //
|
||||
};
|
||||
|
||||
const auto id = icicle_add_syscall_hook(this->emu_, invoker, ptr);
|
||||
this->hooks_[id] = std::move(obj);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_basic_block(basic_block_hook_callback callback) override
|
||||
{
|
||||
// TODO
|
||||
(void)callback;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_edge_generation(edge_generation_hook_callback callback) override
|
||||
{
|
||||
// TODO
|
||||
(void)callback;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_interrupt(interrupt_hook_callback callback) override
|
||||
{
|
||||
auto obj = make_function_object(std::move(callback));
|
||||
auto* ptr = obj.get();
|
||||
auto* wrapper = +[](void* user, const int32_t code) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
func(code);
|
||||
};
|
||||
|
||||
const auto id = icicle_add_interrupt_hook(this->emu_, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(obj);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_violation(memory_violation_hook_callback callback) override
|
||||
{
|
||||
auto obj = make_function_object(std::move(callback));
|
||||
auto* ptr = obj.get();
|
||||
auto* wrapper =
|
||||
+[](void* user, const uint64_t address, const uint8_t operation, const int32_t unmapped) -> int32_t {
|
||||
const auto violation_type = unmapped //
|
||||
? memory_violation_type::unmapped
|
||||
: memory_violation_type::protection;
|
||||
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
const auto res = func(address, 1, static_cast<memory_operation>(operation), violation_type);
|
||||
return res == memory_violation_continuation::resume ? 1 : 0;
|
||||
};
|
||||
|
||||
const auto id = icicle_add_violation_hook(this->emu_, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(obj);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_execution(const uint64_t address, memory_execution_hook_callback callback) override
|
||||
{
|
||||
auto object = make_function_object(std::move(callback));
|
||||
auto* ptr = object.get();
|
||||
auto* wrapper = +[](void* user, const uint64_t addr) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
(func)(addr);
|
||||
};
|
||||
|
||||
const auto id = icicle_add_execution_hook(this->emu_, address, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(object);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_execution(memory_execution_hook_callback callback) override
|
||||
{
|
||||
auto object = make_function_object(std::move(callback));
|
||||
auto* ptr = object.get();
|
||||
auto* wrapper = +[](void* user, const uint64_t addr) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
(func)(addr);
|
||||
};
|
||||
|
||||
const auto id = icicle_add_generic_execution_hook(this->emu_, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(object);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_read(const uint64_t address, const size_t size,
|
||||
memory_access_hook_callback callback) override
|
||||
{
|
||||
auto obj = make_function_object(std::move(callback));
|
||||
auto* ptr = obj.get();
|
||||
auto* wrapper = +[](void* user, const uint64_t address, const void* data, size_t length) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
func(address, data, length);
|
||||
};
|
||||
|
||||
const auto id = icicle_add_read_hook(this->emu_, address, address + size, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(obj);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_write(const uint64_t address, const size_t size,
|
||||
memory_access_hook_callback callback) override
|
||||
{
|
||||
auto obj = make_function_object(std::move(callback));
|
||||
auto* ptr = obj.get();
|
||||
auto* wrapper = +[](void* user, const uint64_t address, const void* data, size_t length) {
|
||||
const auto& func = *static_cast<decltype(ptr)>(user);
|
||||
func(address, data, length);
|
||||
};
|
||||
|
||||
const auto id = icicle_add_write_hook(this->emu_, address, address + size, wrapper, ptr);
|
||||
this->hooks_[id] = std::move(obj);
|
||||
|
||||
return wrap_hook(id);
|
||||
}
|
||||
|
||||
void delete_hook(emulator_hook* hook) override
|
||||
{
|
||||
const auto id = static_cast<uint32_t>(reinterpret_cast<size_t>(hook));
|
||||
const auto entry = this->hooks_.find(id);
|
||||
if (entry == this->hooks_.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
icicle_remove_hook(this->emu_, id);
|
||||
this->hooks_.erase(entry);
|
||||
}
|
||||
|
||||
void serialize_state(utils::buffer_serializer& buffer, const bool is_snapshot) const override
|
||||
{
|
||||
if (is_snapshot)
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
buffer.write_vector(this->save_registers());
|
||||
}
|
||||
|
||||
void deserialize_state(utils::buffer_deserializer& buffer, const bool is_snapshot) override
|
||||
{
|
||||
if (is_snapshot)
|
||||
{
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
const auto data = buffer.read_vector<std::byte>();
|
||||
this->restore_registers(data);
|
||||
}
|
||||
|
||||
std::vector<std::byte> save_registers() const override
|
||||
{
|
||||
std::vector<std::byte> data{};
|
||||
auto* accessor = +[](void* user, const void* data, const size_t length) {
|
||||
auto& vec = *static_cast<std::vector<std::byte>*>(user);
|
||||
vec.resize(length);
|
||||
memcpy(vec.data(), data, length);
|
||||
};
|
||||
|
||||
icicle_save_registers(this->emu_, accessor, &data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void restore_registers(const std::vector<std::byte>& register_data) override
|
||||
{
|
||||
icicle_restore_registers(this->emu_, register_data.data(), register_data.size());
|
||||
}
|
||||
|
||||
bool has_violation() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string get_name() const override
|
||||
{
|
||||
return "icicle-emu";
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<std::unique_ptr<utils::object>> storage_{};
|
||||
std::unordered_map<uint32_t, std::unique_ptr<utils::object>> hooks_{};
|
||||
icicle_emulator* emu_{};
|
||||
};
|
||||
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator()
|
||||
{
|
||||
return std::make_unique<icicle_x64_emulator>();
|
||||
}
|
||||
}
|
||||
19
src/backends/icicle-emulator/icicle_x64_emulator.hpp
Normal file
19
src/backends/icicle-emulator/icicle_x64_emulator.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <x64_emulator.hpp>
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#ifdef ICICLE_EMULATOR_IMPL
|
||||
#define ICICLE_EMULATOR_DLL_STORAGE EXPORT_SYMBOL
|
||||
#else
|
||||
#define ICICLE_EMULATOR_DLL_STORAGE IMPORT_SYMBOL
|
||||
#endif
|
||||
|
||||
namespace icicle
|
||||
{
|
||||
#if !MOMO_BUILD_AS_LIBRARY
|
||||
ICICLE_EMULATOR_DLL_STORAGE
|
||||
#endif
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator();
|
||||
}
|
||||
20
src/backends/unicorn-emulator/CMakeLists.txt
Normal file
20
src/backends/unicorn-emulator/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
*.hpp
|
||||
*.rc
|
||||
)
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
if(MOMO_BUILD_AS_LIBRARY)
|
||||
add_library(unicorn-emulator STATIC ${SRC_FILES})
|
||||
else()
|
||||
add_library(unicorn-emulator SHARED ${SRC_FILES})
|
||||
endif()
|
||||
|
||||
target_include_directories(unicorn-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
target_link_libraries(unicorn-emulator PUBLIC emulator)
|
||||
target_link_libraries(unicorn-emulator PRIVATE unicorn emulator-common)
|
||||
|
||||
momo_strip_target(unicorn-emulator)
|
||||
42
src/backends/unicorn-emulator/function_wrapper.hpp
Normal file
42
src/backends/unicorn-emulator/function_wrapper.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include <utils/object.hpp>
|
||||
|
||||
template <typename ReturnType, typename... Args>
|
||||
class function_wrapper : public utils::object
|
||||
{
|
||||
public:
|
||||
using user_data_pointer = void*;
|
||||
using c_function_type = ReturnType(Args..., user_data_pointer);
|
||||
using functor_type = std::function<ReturnType(Args...)>;
|
||||
|
||||
function_wrapper() = default;
|
||||
|
||||
function_wrapper(functor_type functor)
|
||||
: functor_(std::make_unique<functor_type>(std::move(functor)))
|
||||
{
|
||||
}
|
||||
|
||||
c_function_type* get_c_function() const
|
||||
{
|
||||
return +[](Args... args, user_data_pointer user_data) -> ReturnType {
|
||||
return (*static_cast<functor_type*>(user_data))(std::forward<Args>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
void* get_function() const
|
||||
{
|
||||
return reinterpret_cast<void*>(this->get_c_function());
|
||||
}
|
||||
|
||||
user_data_pointer get_user_data() const
|
||||
{
|
||||
return this->functor_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<functor_type> functor_{};
|
||||
};
|
||||
51
src/backends/unicorn-emulator/unicorn.hpp
Normal file
51
src/backends/unicorn-emulator/unicorn.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4505)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
#define NOMINMAX
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace unicorn
|
||||
{
|
||||
struct unicorn_error : std::runtime_error
|
||||
{
|
||||
unicorn_error(const uc_err error_code)
|
||||
: std::runtime_error(uc_strerror(error_code)),
|
||||
code(error_code)
|
||||
{
|
||||
}
|
||||
|
||||
uc_err code{};
|
||||
};
|
||||
|
||||
inline void throw_if_unicorn_error(const uc_err error_code)
|
||||
{
|
||||
if (error_code != UC_ERR_OK)
|
||||
{
|
||||
throw unicorn_error(error_code);
|
||||
}
|
||||
}
|
||||
|
||||
inline void uce(const uc_err error_code)
|
||||
{
|
||||
throw_if_unicorn_error(error_code);
|
||||
}
|
||||
}
|
||||
76
src/backends/unicorn-emulator/unicorn_hook.hpp
Normal file
76
src/backends/unicorn-emulator/unicorn_hook.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include "unicorn.hpp"
|
||||
|
||||
namespace unicorn
|
||||
{
|
||||
class unicorn_hook
|
||||
{
|
||||
public:
|
||||
unicorn_hook() = default;
|
||||
|
||||
unicorn_hook(uc_engine* uc)
|
||||
: unicorn_hook(uc, {})
|
||||
{
|
||||
}
|
||||
|
||||
unicorn_hook(uc_engine* uc, const uc_hook hook)
|
||||
: uc_(uc),
|
||||
hook_(hook)
|
||||
{
|
||||
}
|
||||
|
||||
~unicorn_hook()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
unicorn_hook(const unicorn_hook&) = delete;
|
||||
unicorn_hook& operator=(const unicorn_hook&) = delete;
|
||||
|
||||
unicorn_hook(unicorn_hook&& obj) noexcept
|
||||
{
|
||||
this->operator=(std::move(obj));
|
||||
}
|
||||
|
||||
uc_hook* make_reference()
|
||||
{
|
||||
if (!this->uc_)
|
||||
{
|
||||
throw std::runtime_error("Cannot make reference on default constructed hook");
|
||||
}
|
||||
|
||||
this->release();
|
||||
return &this->hook_;
|
||||
}
|
||||
|
||||
unicorn_hook& operator=(unicorn_hook&& obj) noexcept
|
||||
{
|
||||
if (this != &obj)
|
||||
{
|
||||
this->release();
|
||||
|
||||
this->uc_ = obj.uc_;
|
||||
this->hook_ = obj.hook_;
|
||||
|
||||
obj.hook_ = {};
|
||||
obj.uc_ = {};
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (this->hook_ && this->uc_)
|
||||
{
|
||||
uc_hook_del(this->uc_, this->hook_);
|
||||
this->hook_ = {};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uc_engine* uc_{};
|
||||
uc_hook hook_{};
|
||||
};
|
||||
}
|
||||
66
src/backends/unicorn-emulator/unicorn_memory_regions.hpp
Normal file
66
src/backends/unicorn-emulator/unicorn_memory_regions.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
|
||||
#include "unicorn.hpp"
|
||||
|
||||
namespace unicorn
|
||||
{
|
||||
class unicorn_memory_regions
|
||||
{
|
||||
public:
|
||||
unicorn_memory_regions(uc_engine* uc)
|
||||
{
|
||||
uce(uc_mem_regions(uc, &this->regions_, &this->count_));
|
||||
}
|
||||
|
||||
~unicorn_memory_regions()
|
||||
{
|
||||
this->release();
|
||||
}
|
||||
|
||||
unicorn_memory_regions(const unicorn_memory_regions&) = delete;
|
||||
unicorn_memory_regions& operator=(const unicorn_memory_regions&) = delete;
|
||||
|
||||
unicorn_memory_regions(unicorn_memory_regions&& obj) noexcept
|
||||
{
|
||||
this->operator=(std::move(obj));
|
||||
}
|
||||
|
||||
unicorn_memory_regions& operator=(unicorn_memory_regions&& obj) noexcept
|
||||
{
|
||||
if (this != &obj)
|
||||
{
|
||||
this->release();
|
||||
|
||||
this->count_ = obj.count_;
|
||||
this->regions_ = obj.regions_;
|
||||
|
||||
obj.count_ = {};
|
||||
obj.regions_ = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::span<uc_mem_region> get_span() const
|
||||
{
|
||||
return {this->regions_, this->count_};
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t count_{};
|
||||
uc_mem_region* regions_{};
|
||||
|
||||
void release()
|
||||
{
|
||||
if (this->regions_)
|
||||
{
|
||||
uc_free(regions_);
|
||||
}
|
||||
|
||||
this->count_ = {};
|
||||
this->regions_ = nullptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
699
src/backends/unicorn-emulator/unicorn_x64_emulator.cpp
Normal file
699
src/backends/unicorn-emulator/unicorn_x64_emulator.cpp
Normal file
@@ -0,0 +1,699 @@
|
||||
#define UNICORN_EMULATOR_IMPL
|
||||
#include "unicorn_x64_emulator.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "unicorn_memory_regions.hpp"
|
||||
#include "unicorn_hook.hpp"
|
||||
|
||||
#include "function_wrapper.hpp"
|
||||
#include <ranges>
|
||||
|
||||
namespace unicorn
|
||||
{
|
||||
namespace
|
||||
{
|
||||
static_assert(static_cast<uint32_t>(memory_permission::none) == UC_PROT_NONE);
|
||||
static_assert(static_cast<uint32_t>(memory_permission::read) == UC_PROT_READ);
|
||||
static_assert(static_cast<uint32_t>(memory_permission::exec) == UC_PROT_EXEC);
|
||||
static_assert(static_cast<uint32_t>(memory_permission::all) == UC_PROT_ALL);
|
||||
|
||||
static_assert(static_cast<uint32_t>(x64_register::end) == UC_X86_REG_ENDING);
|
||||
|
||||
uc_x86_insn map_hookable_instruction(const x64_hookable_instructions instruction)
|
||||
{
|
||||
switch (instruction)
|
||||
{
|
||||
case x64_hookable_instructions::syscall:
|
||||
return UC_X86_INS_SYSCALL;
|
||||
case x64_hookable_instructions::cpuid:
|
||||
return UC_X86_INS_CPUID;
|
||||
case x64_hookable_instructions::rdtsc:
|
||||
return UC_X86_INS_RDTSC;
|
||||
case x64_hookable_instructions::rdtscp:
|
||||
return UC_X86_INS_RDTSCP;
|
||||
default:
|
||||
throw std::runtime_error("Bad instruction for mapping");
|
||||
}
|
||||
}
|
||||
|
||||
memory_violation_type map_memory_violation_type(const uc_mem_type mem_type)
|
||||
{
|
||||
switch (mem_type)
|
||||
{
|
||||
case UC_MEM_READ_PROT:
|
||||
case UC_MEM_WRITE_PROT:
|
||||
case UC_MEM_FETCH_PROT:
|
||||
return memory_violation_type::protection;
|
||||
case UC_MEM_READ_UNMAPPED:
|
||||
case UC_MEM_WRITE_UNMAPPED:
|
||||
case UC_MEM_FETCH_UNMAPPED:
|
||||
return memory_violation_type::unmapped;
|
||||
default:
|
||||
throw std::runtime_error("Memory type does not constitute a violation");
|
||||
}
|
||||
}
|
||||
|
||||
memory_operation map_memory_operation(const uc_mem_type mem_type)
|
||||
{
|
||||
switch (mem_type)
|
||||
{
|
||||
case UC_MEM_READ:
|
||||
case UC_MEM_READ_PROT:
|
||||
case UC_MEM_READ_AFTER:
|
||||
case UC_MEM_READ_UNMAPPED:
|
||||
return memory_operation::read;
|
||||
case UC_MEM_WRITE:
|
||||
case UC_MEM_WRITE_PROT:
|
||||
case UC_MEM_WRITE_UNMAPPED:
|
||||
return memory_operation::write;
|
||||
case UC_MEM_FETCH:
|
||||
case UC_MEM_FETCH_PROT:
|
||||
case UC_MEM_FETCH_UNMAPPED:
|
||||
return memory_operation::exec;
|
||||
default:
|
||||
return memory_operation::none;
|
||||
}
|
||||
}
|
||||
|
||||
struct hook_object : utils::object
|
||||
{
|
||||
emulator_hook* as_opaque_hook()
|
||||
{
|
||||
return reinterpret_cast<emulator_hook*>(this);
|
||||
}
|
||||
};
|
||||
|
||||
class hook_container : public hook_object
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
requires(std::is_base_of_v<utils::object, T> && std::is_move_constructible_v<T>)
|
||||
void add(T data, unicorn_hook hook)
|
||||
{
|
||||
hook_entry entry{};
|
||||
|
||||
entry.data = std::make_unique<T>(std::move(data));
|
||||
entry.hook = std::move(hook);
|
||||
|
||||
this->hooks_.emplace_back(std::move(entry));
|
||||
}
|
||||
|
||||
private:
|
||||
struct hook_entry
|
||||
{
|
||||
std::unique_ptr<utils::object> data{};
|
||||
unicorn_hook hook{};
|
||||
};
|
||||
|
||||
std::vector<hook_entry> hooks_;
|
||||
};
|
||||
|
||||
struct mmio_callbacks
|
||||
{
|
||||
using read_wrapper = function_wrapper<uint64_t, uc_engine*, uint64_t, unsigned>;
|
||||
using write_wrapper = function_wrapper<void, uc_engine*, uint64_t, unsigned, uint64_t>;
|
||||
|
||||
read_wrapper read{};
|
||||
write_wrapper write{};
|
||||
};
|
||||
|
||||
class uc_context_serializer
|
||||
{
|
||||
public:
|
||||
uc_context_serializer(uc_engine* uc, const bool in_place)
|
||||
: uc_(uc)
|
||||
{
|
||||
if (in_place)
|
||||
{
|
||||
// Unicorn stores pointers in the struct. The serialization here is broken
|
||||
throw std::runtime_error("Memory saving not supported atm");
|
||||
}
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
uc_ctl_context_mode(uc, UC_CTL_CONTEXT_CPU | (in_place ? UC_CTL_CONTEXT_MEMORY : 0));
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
this->size_ = uc_context_size(uc);
|
||||
uce(uc_context_alloc(uc, &this->context_));
|
||||
}
|
||||
|
||||
~uc_context_serializer()
|
||||
{
|
||||
if (this->context_)
|
||||
{
|
||||
(void)uc_context_free(this->context_);
|
||||
}
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
uce(uc_context_save(this->uc_, this->context_));
|
||||
buffer.write(this->context_, this->size_);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer) const
|
||||
{
|
||||
buffer.read(this->context_, this->size_);
|
||||
uce(uc_context_restore(this->uc_, this->context_));
|
||||
}
|
||||
|
||||
uc_context_serializer(uc_context_serializer&&) = delete;
|
||||
uc_context_serializer(const uc_context_serializer&) = delete;
|
||||
uc_context_serializer& operator=(uc_context_serializer&&) = delete;
|
||||
uc_context_serializer& operator=(const uc_context_serializer&) = delete;
|
||||
|
||||
private:
|
||||
uc_engine* uc_{};
|
||||
uc_context* context_{};
|
||||
size_t size_{};
|
||||
};
|
||||
|
||||
basic_block map_block(const uc_tb& translation_block)
|
||||
{
|
||||
basic_block block{};
|
||||
|
||||
block.address = translation_block.pc;
|
||||
block.instruction_count = translation_block.icount;
|
||||
block.size = translation_block.size;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
void assert_64bit_limit(const size_t size)
|
||||
{
|
||||
if (size > sizeof(uint64_t))
|
||||
{
|
||||
throw std::runtime_error("Exceeded uint64_t size limit");
|
||||
}
|
||||
}
|
||||
|
||||
class unicorn_x64_emulator : public x64_emulator
|
||||
{
|
||||
public:
|
||||
unicorn_x64_emulator()
|
||||
{
|
||||
uce(uc_open(UC_ARCH_X86, UC_MODE_64, &this->uc_));
|
||||
uce(uc_ctl_set_cpu_model(this->uc_, UC_CPU_X86_EPYC_ROME));
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
uce(uc_ctl_set_tcg_buffer_size(this->uc_, 2 << 30 /* 2 gb */));
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
~unicorn_x64_emulator() override
|
||||
{
|
||||
this->hooks_.clear();
|
||||
uc_close(this->uc_);
|
||||
}
|
||||
|
||||
void start(const size_t count) override
|
||||
{
|
||||
this->has_violation_ = false;
|
||||
const auto start = this->read_instruction_pointer();
|
||||
constexpr auto end = std::numeric_limits<uint64_t>::max();
|
||||
const auto res = uc_emu_start(*this, start, end, 0, count);
|
||||
if (res == UC_ERR_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto is_violation = //
|
||||
res == UC_ERR_READ_UNMAPPED || //
|
||||
res == UC_ERR_WRITE_UNMAPPED || //
|
||||
res == UC_ERR_FETCH_UNMAPPED || //
|
||||
res == UC_ERR_READ_PROT || //
|
||||
res == UC_ERR_WRITE_PROT || //
|
||||
res == UC_ERR_FETCH_PROT;
|
||||
|
||||
if (!is_violation || !this->has_violation_)
|
||||
{
|
||||
uce(res);
|
||||
}
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
uce(uc_emu_stop(*this));
|
||||
}
|
||||
|
||||
void load_gdt(const pointer_type address, const uint32_t limit) override
|
||||
{
|
||||
const std::array<uint64_t, 4> gdtr = {0, address, limit, 0};
|
||||
this->write_register(x64_register::gdtr, gdtr.data(), gdtr.size() * sizeof(uint64_t));
|
||||
}
|
||||
|
||||
void set_segment_base(const x64_register base, const pointer_type value) override
|
||||
{
|
||||
constexpr auto IA32_FS_BASE_MSR = 0xC0000100;
|
||||
constexpr auto IA32_GS_BASE_MSR = 0xC0000101;
|
||||
|
||||
struct msr_value
|
||||
{
|
||||
uint32_t id;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
msr_value msr_val{
|
||||
.id = 0,
|
||||
.value = value,
|
||||
};
|
||||
|
||||
switch (base)
|
||||
{
|
||||
case x64_register::fs:
|
||||
case x64_register::fs_base:
|
||||
msr_val.id = IA32_FS_BASE_MSR;
|
||||
break;
|
||||
case x64_register::gs:
|
||||
case x64_register::gs_base:
|
||||
msr_val.id = IA32_GS_BASE_MSR;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
this->write_register(x64_register::msr, &msr_val, sizeof(msr_val));
|
||||
}
|
||||
|
||||
size_t write_raw_register(const int reg, const void* value, const size_t size) override
|
||||
{
|
||||
auto result_size = size;
|
||||
uce(uc_reg_write2(*this, reg, value, &result_size));
|
||||
|
||||
if (size < result_size)
|
||||
{
|
||||
throw std::runtime_error("Register size mismatch: " + std::to_string(size) +
|
||||
" != " + std::to_string(result_size));
|
||||
}
|
||||
|
||||
return result_size;
|
||||
}
|
||||
|
||||
size_t read_raw_register(const int reg, void* value, const size_t size) override
|
||||
{
|
||||
size_t result_size = size;
|
||||
memset(value, 0, size);
|
||||
uce(uc_reg_read2(*this, reg, value, &result_size));
|
||||
|
||||
if (size < result_size)
|
||||
{
|
||||
throw std::runtime_error("Register size mismatch: " + std::to_string(size) +
|
||||
" != " + std::to_string(result_size));
|
||||
}
|
||||
|
||||
return result_size;
|
||||
}
|
||||
|
||||
void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb,
|
||||
mmio_write_callback write_cb) override
|
||||
{
|
||||
auto read_wrapper = [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s) {
|
||||
assert_64bit_limit(s);
|
||||
uint64_t value{};
|
||||
c(addr, &value, s);
|
||||
return value;
|
||||
};
|
||||
|
||||
auto write_wrapper = [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s,
|
||||
const uint64_t value) {
|
||||
assert_64bit_limit(s);
|
||||
c(addr, &value, s);
|
||||
};
|
||||
|
||||
mmio_callbacks cb{
|
||||
.read = mmio_callbacks::read_wrapper(std::move(read_wrapper)),
|
||||
.write = mmio_callbacks::write_wrapper(std::move(write_wrapper)),
|
||||
};
|
||||
|
||||
uce(uc_mmio_map(*this, address, size, cb.read.get_c_function(), cb.read.get_user_data(),
|
||||
cb.write.get_c_function(), cb.write.get_user_data()));
|
||||
|
||||
this->mmio_[address] = std::move(cb);
|
||||
}
|
||||
|
||||
void map_memory(const uint64_t address, const size_t size, memory_permission permissions) override
|
||||
{
|
||||
uce(uc_mem_map(*this, address, size, static_cast<uint32_t>(permissions)));
|
||||
}
|
||||
|
||||
void unmap_memory(const uint64_t address, const size_t size) override
|
||||
{
|
||||
uce(uc_mem_unmap(*this, address, size));
|
||||
|
||||
const auto mmio_entry = this->mmio_.find(address);
|
||||
if (mmio_entry != this->mmio_.end())
|
||||
{
|
||||
this->mmio_.erase(mmio_entry);
|
||||
}
|
||||
}
|
||||
|
||||
bool try_read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
return uc_mem_read(*this, address, data, size) == UC_ERR_OK;
|
||||
}
|
||||
|
||||
void read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
uce(uc_mem_read(*this, address, data, size));
|
||||
}
|
||||
|
||||
void write_memory(const uint64_t address, const void* data, const size_t size) override
|
||||
{
|
||||
uce(uc_mem_write(*this, address, data, size));
|
||||
}
|
||||
|
||||
void apply_memory_protection(const uint64_t address, const size_t size,
|
||||
memory_permission permissions) override
|
||||
{
|
||||
uce(uc_mem_protect(*this, address, size, static_cast<uint32_t>(permissions)));
|
||||
}
|
||||
|
||||
emulator_hook* hook_instruction(const int instruction_type, instruction_hook_callback callback) override
|
||||
{
|
||||
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) {
|
||||
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0;
|
||||
});
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
auto container = std::make_unique<hook_container>();
|
||||
|
||||
const auto inst_type = static_cast<x64_hookable_instructions>(instruction_type);
|
||||
|
||||
if (inst_type == x64_hookable_instructions::invalid)
|
||||
{
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN_INVALID, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max()));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto uc_instruction = map_hookable_instruction(inst_type);
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max(),
|
||||
uc_instruction));
|
||||
}
|
||||
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
|
||||
auto* result = container->as_opaque_hook();
|
||||
|
||||
this->hooks_.push_back(std::move(container));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
emulator_hook* hook_basic_block(basic_block_hook_callback callback) override
|
||||
{
|
||||
function_wrapper<void, uc_engine*, uint64_t, size_t> wrapper(
|
||||
[c = std::move(callback)](uc_engine*, const uint64_t address, const size_t size) {
|
||||
basic_block block{};
|
||||
block.address = address;
|
||||
block.size = size;
|
||||
|
||||
c(block);
|
||||
});
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
auto container = std::make_unique<hook_container>();
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_BLOCK, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max()));
|
||||
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
|
||||
auto* result = container->as_opaque_hook();
|
||||
this->hooks_.push_back(std::move(container));
|
||||
return result;
|
||||
}
|
||||
|
||||
emulator_hook* hook_edge_generation(edge_generation_hook_callback callback) override
|
||||
{
|
||||
function_wrapper<void, uc_engine*, uc_tb*, uc_tb*> wrapper(
|
||||
[c = std::move(callback)](uc_engine*, const uc_tb* cur_tb, const uc_tb* prev_tb) {
|
||||
const auto current_block = map_block(*cur_tb);
|
||||
const auto previous_block = map_block(*prev_tb);
|
||||
|
||||
c(current_block, previous_block);
|
||||
});
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
auto container = std::make_unique<hook_container>();
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_EDGE_GENERATED, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max()));
|
||||
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
|
||||
auto* result = container->as_opaque_hook();
|
||||
this->hooks_.push_back(std::move(container));
|
||||
return result;
|
||||
}
|
||||
|
||||
emulator_hook* hook_interrupt(interrupt_hook_callback callback) override
|
||||
{
|
||||
function_wrapper<void, uc_engine*, int> wrapper(
|
||||
[c = std::move(callback)](uc_engine*, const int interrupt_type) { c(interrupt_type); });
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
auto container = std::make_unique<hook_container>();
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INTR, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max()));
|
||||
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
|
||||
auto* result = container->as_opaque_hook();
|
||||
this->hooks_.push_back(std::move(container));
|
||||
return result;
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_violation(memory_violation_hook_callback callback) override
|
||||
{
|
||||
function_wrapper<bool, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(
|
||||
[c = std::move(callback), this](uc_engine*, const uc_mem_type type, const uint64_t address,
|
||||
const int size, const int64_t) {
|
||||
const auto ip = this->read_instruction_pointer();
|
||||
|
||||
assert(size >= 0);
|
||||
const auto operation = map_memory_operation(type);
|
||||
const auto violation = map_memory_violation_type(type);
|
||||
|
||||
const auto resume = c(address, static_cast<uint64_t>(size), operation, violation) ==
|
||||
memory_violation_continuation::resume;
|
||||
|
||||
const auto has_ip_changed = ip != this->read_instruction_pointer();
|
||||
|
||||
if (!resume)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->has_violation_ = resume && has_ip_changed;
|
||||
|
||||
if (has_ip_changed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
auto container = std::make_unique<hook_container>();
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_INVALID, wrapper.get_function(),
|
||||
wrapper.get_user_data(), 0, std::numeric_limits<uint64_t>::max()));
|
||||
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
|
||||
auto* result = container->as_opaque_hook();
|
||||
this->hooks_.push_back(std::move(container));
|
||||
return result;
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_execution(const uint64_t address, const uint64_t size,
|
||||
memory_execution_hook_callback callback)
|
||||
{
|
||||
auto exec_wrapper = [c = std::move(callback)](uc_engine*, const uint64_t address,
|
||||
const uint32_t /*size*/) {
|
||||
c(address); //
|
||||
};
|
||||
|
||||
function_wrapper<void, uc_engine*, uint64_t, uint32_t> wrapper(std::move(exec_wrapper));
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_CODE, wrapper.get_function(),
|
||||
wrapper.get_user_data(), address, address + size));
|
||||
|
||||
auto* container = this->create_hook_container();
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
return container->as_opaque_hook();
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_execution(memory_execution_hook_callback callback) override
|
||||
{
|
||||
return this->hook_memory_execution(0, std::numeric_limits<uint64_t>::max(), std::move(callback));
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_execution(const uint64_t address,
|
||||
memory_execution_hook_callback callback) override
|
||||
{
|
||||
return this->hook_memory_execution(address, 1, std::move(callback));
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_read(const uint64_t address, const size_t size,
|
||||
memory_access_hook_callback callback) override
|
||||
{
|
||||
auto read_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type,
|
||||
const uint64_t address, const int size,
|
||||
const uint64_t value) {
|
||||
const auto operation = map_memory_operation(type);
|
||||
if (operation == memory_operation::read && size > 0)
|
||||
{
|
||||
c(address, &value, std::min(static_cast<size_t>(size), sizeof(value)));
|
||||
}
|
||||
};
|
||||
|
||||
function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(
|
||||
std::move(read_wrapper));
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_READ_AFTER, wrapper.get_function(),
|
||||
wrapper.get_user_data(), address, address + size));
|
||||
|
||||
auto* container = this->create_hook_container();
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
return container->as_opaque_hook();
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_write(const uint64_t address, const size_t size,
|
||||
memory_access_hook_callback callback) override
|
||||
{
|
||||
auto write_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type, const uint64_t addr,
|
||||
const int length, const uint64_t value) {
|
||||
const auto operation = map_memory_operation(type);
|
||||
if (operation == memory_operation::write && length > 0)
|
||||
{
|
||||
c(addr, &value, std::min(static_cast<size_t>(length), sizeof(value)));
|
||||
}
|
||||
};
|
||||
|
||||
function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(
|
||||
std::move(write_wrapper));
|
||||
|
||||
unicorn_hook hook{*this};
|
||||
|
||||
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_WRITE, wrapper.get_function(),
|
||||
wrapper.get_user_data(), address, address + size));
|
||||
|
||||
auto* container = this->create_hook_container();
|
||||
container->add(std::move(wrapper), std::move(hook));
|
||||
return container->as_opaque_hook();
|
||||
}
|
||||
|
||||
hook_container* create_hook_container()
|
||||
{
|
||||
auto container = std::make_unique<hook_container>();
|
||||
auto* ptr = container.get();
|
||||
this->hooks_.push_back(std::move(container));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void delete_hook(emulator_hook* hook) override
|
||||
{
|
||||
const auto entry =
|
||||
std::ranges::find_if(this->hooks_, [&](const std::unique_ptr<hook_object>& hook_ptr) {
|
||||
return hook_ptr->as_opaque_hook() == hook;
|
||||
});
|
||||
|
||||
if (entry != this->hooks_.end())
|
||||
{
|
||||
this->hooks_.erase(entry);
|
||||
}
|
||||
}
|
||||
|
||||
operator uc_engine*() const
|
||||
{
|
||||
return this->uc_;
|
||||
}
|
||||
|
||||
void serialize_state(utils::buffer_serializer& buffer, const bool is_snapshot) const override
|
||||
{
|
||||
if (this->has_snapshots_ && !is_snapshot)
|
||||
{
|
||||
// TODO: Investigate if this is really necessary
|
||||
throw std::runtime_error("Unable to serialize after snapshot was taken!");
|
||||
}
|
||||
|
||||
this->has_snapshots_ |= is_snapshot;
|
||||
|
||||
const uc_context_serializer serializer(this->uc_, is_snapshot);
|
||||
serializer.serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize_state(utils::buffer_deserializer& buffer, const bool is_snapshot) override
|
||||
{
|
||||
if (this->has_snapshots_ && !is_snapshot)
|
||||
{
|
||||
// TODO: Investigate if this is really necessary
|
||||
throw std::runtime_error("Unable to deserialize after snapshot was taken!");
|
||||
}
|
||||
|
||||
const uc_context_serializer serializer(this->uc_, is_snapshot);
|
||||
serializer.deserialize(buffer);
|
||||
}
|
||||
|
||||
std::vector<std::byte> save_registers() const override
|
||||
{
|
||||
utils::buffer_serializer buffer{};
|
||||
const uc_context_serializer serializer(this->uc_, false);
|
||||
serializer.serialize(buffer);
|
||||
return buffer.move_buffer();
|
||||
}
|
||||
|
||||
void restore_registers(const std::vector<std::byte>& register_data) override
|
||||
{
|
||||
utils::buffer_deserializer buffer{register_data};
|
||||
const uc_context_serializer serializer(this->uc_, false);
|
||||
serializer.deserialize(buffer);
|
||||
}
|
||||
|
||||
bool has_violation() const override
|
||||
{
|
||||
return this->has_violation_;
|
||||
}
|
||||
|
||||
std::string get_name() const override
|
||||
{
|
||||
return "Unicorn Engine";
|
||||
}
|
||||
|
||||
private:
|
||||
mutable bool has_snapshots_{false};
|
||||
uc_engine* uc_{};
|
||||
bool has_violation_{false};
|
||||
std::vector<std::unique_ptr<hook_object>> hooks_{};
|
||||
std::unordered_map<uint64_t, mmio_callbacks> mmio_{};
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator()
|
||||
{
|
||||
return std::make_unique<unicorn_x64_emulator>();
|
||||
}
|
||||
}
|
||||
19
src/backends/unicorn-emulator/unicorn_x64_emulator.hpp
Normal file
19
src/backends/unicorn-emulator/unicorn_x64_emulator.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <x64_emulator.hpp>
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#ifdef UNICORN_EMULATOR_IMPL
|
||||
#define UNICORN_EMULATOR_DLL_STORAGE EXPORT_SYMBOL
|
||||
#else
|
||||
#define UNICORN_EMULATOR_DLL_STORAGE IMPORT_SYMBOL
|
||||
#endif
|
||||
|
||||
namespace unicorn
|
||||
{
|
||||
#if !MOMO_BUILD_AS_LIBRARY
|
||||
UNICORN_EMULATOR_DLL_STORAGE
|
||||
#endif
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator();
|
||||
}
|
||||
Reference in New Issue
Block a user