[ABI] Improvements to avoid UB and warnings, clean build with MSAN

* Added more clang compilers on CI (CI)
  * Added memory sanitizer to build matrix (CI)
  * Use problem matcher in all builds (CI)
  * Fixed the use of some constructs in tests
  * Fixed warnings about unused functions in tests
  * Fixed warnings about unused variables caused by some build options
  * Fixed tests to be clean with MSAN (zeroing memory filled by JIT code)
  * Removed -Wclass-memaccess (gcc) from ignored warnings
  * Removed -Wconstant-logical-operand (clang) from ignored warnings
  * Removed -Wunnamed-type-template-args (clang) from ignored warnings
  * Reworked InstData and InstExData to not cause UB (ABI break)

Unfortunately the existing InstData and InstExData was not good for static
analysis and in general compilers emitted warnings regarding accessing
InstNode::_opArray. The reason was that InstExNode added one or two
more operands which extended InstData::_opArray, but there was no way to
tell the C++ compiler about this layout.

It has been changed to InstNode having no operands and InstNodeWithOperands
being templatized for the right number of operands. Nodes that need to
inherit InstNode would just inherit InstNodeWithOperands<N>. It works the
same way as before, just the class hierarchy changed a little.
This commit is contained in:
kobalicek
2023-12-26 18:48:24 +01:00
parent 7c10a14d34
commit 073f6e85e4
28 changed files with 458 additions and 397 deletions

View File

@@ -1,7 +1,8 @@
{
"diagnostics": {
"asan": { "definitions": ["ASMJIT_SANITIZE=address"] },
"ubsan": { "definitions": ["ASMJIT_SANITIZE=undefined"] }
"ubsan": { "definitions": ["ASMJIT_SANITIZE=undefined"] },
"msan": { "definitions": ["ASMJIT_SANITIZE=memory"] }
},
"valgrind_arguments": [

View File

@@ -31,90 +31,107 @@ jobs:
fail-fast: false
matrix:
include:
- { title: "linux-lib" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , problem_matcher: "cpp" }
- { title: "macos-lib" , os: "macos-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , problem_matcher: "cpp" }
- { title: "windows-lib" , os: "windows-latest", cc: "vs2022" , arch: "x64", build_type: "Debug" , problem_matcher: "cpp" }
- { title: "linux-lib" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", conf: "Debug" }
- { title: "macos-lib" , os: "macos-latest" , cc: "clang" , arch: "x64", conf: "Debug" }
- { title: "windows-lib" , os: "windows-latest", cc: "vs2022" , arch: "x64", conf: "Debug" }
- { title: "diag-asan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", diagnostics: "address" , defs: "ASMJIT_TEST=1" }
- { title: "diag-ubsan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", diagnostics: "undefined", defs: "ASMJIT_TEST=1" }
- { title: "diag-valgrind" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", diagnostics: "valgrind" , defs: "ASMJIT_TEST=1" }
- { title: "diag-scan-build" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , diagnostics: "scan-build" }
- { title: "diag-analyze" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Debug" , diagnostics: "analyze-build" }
- { title: "diag-asan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "asan", defs: "ASMJIT_TEST=1" }
- { title: "diag-msan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "msan", defs: "ASMJIT_TEST=1" }
- { title: "diag-ubsan" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "ubsan", defs: "ASMJIT_TEST=1" }
- { title: "diag-valgrind" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", diagnostics: "valgrind", defs: "ASMJIT_TEST=1" }
- { title: "no-deprecated" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" }
- { title: "no-intrinsics" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" }
- { title: "no-logging" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" }
- { title: "no-logging-text" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" }
- { title: "no-builder" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" }
- { title: "no-compiler" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" }
- { title: "no-jit" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" }
- { title: "no-introspection", os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTROSPECTION=1" }
- { title: "no-validation" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" }
- { title: "no-x86" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" }
- { title: "no-aarch64" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" }
- { title: "no-deprecated" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" }
- { title: "no-intrinsics" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" }
- { title: "no-logging" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" }
- { title: "no-logging-text" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" }
- { title: "no-builder" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" }
- { title: "no-compiler" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" }
- { title: "no-introspection", os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" }
- { title: "no-jit" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" }
- { title: "no-validation" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" }
- { title: "no-x86" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" }
- { title: "no-aarch64" , os: "ubuntu-latest" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-9" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-10" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-11" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-12" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "gcc-13" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-11", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-12", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-13", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-14", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-15", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-16", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "linux" , os: "ubuntu-22.04" , cc: "clang-17", arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "gcc-11" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "macos" , os: "macos-12" , cc: "clang" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", conf: "Release", defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", conf: "Debug" , defs: "ASMJIT_TEST=1" }
- { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "freebsd", osver: "13.2", cc: "clang", arch: "x86-64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { host: "macos-12" , os: "netbsd" , osver: "9.3" , cc: "clang", arch: "x86-64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { host: "macos-12" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "x86-64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { host: "ubuntu-latest" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "arm64" , build_type: "Release", defs: "ASMJIT_TEST=ON" }
- { host: "macos-12" , os: "freebsd", osver: "13.2", cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "netbsd" , osver: "9.3" , cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { host: "macos-12" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "x86-64", conf: "Release", defs: "ASMJIT_TEST=1" }
- { host: "ubuntu-latest" , os: "openbsd", osver: "7.3" , cc: "clang", arch: "arm64" , conf: "Release", defs: "ASMJIT_TEST=1" }
name: "${{matrix.title || format('{0}-{1}', matrix.os, matrix.osver)}} (${{matrix.cc}}, ${{matrix.arch}}, ${{matrix.build_type}})"
name: "${{matrix.title || format('{0}-{1}', matrix.os, matrix.osver)}} (${{matrix.cc}}, ${{matrix.arch}}, ${{matrix.conf}})"
runs-on: "${{matrix.host || matrix.os}}"
steps:
@@ -138,11 +155,13 @@ jobs:
if: ${{!matrix.host}}
run: python build-actions/action.py
--step=all
--compiler=${{matrix.cc}}
--architecture=${{matrix.arch}}
--source-dir=source
--config=source/.github/workflows/build-config.json
--build-type=${{matrix.build_type}}
--compiler=${{matrix.cc}}
--diagnostics=${{matrix.diagnostics}}
--architecture=${{matrix.arch}}
--problem-matcher=auto
--build-type=${{matrix.conf}}
--build-defs=${{matrix.defs}}
- name: "Build & Test in VM"
@@ -165,9 +184,11 @@ jobs:
sh ./build-actions/prepare-environment.sh
python3 build-actions/action.py \
--step=all \
--compiler=${{matrix.cc}} \
--architecture=${{matrix.arch}} \
--source-dir=source \
--config=source/.github/workflows/build-config.json \
--build-type=${{matrix.build_type}} \
--compiler=${{matrix.cc}} \
--diagnostics=${{matrix.diagnostics}} \
--architecture=${{matrix.arch}} \
--problem-matcher=auto \
--build-type=${{matrix.conf}} \
--build-defs=${{matrix.defs}}

View File

@@ -4114,7 +4114,6 @@ Case_BaseLdurStur:
if (inverted) {
imm8 = ~imm8 & 0xFFu;
inverted = 0;
}
cmode = B(3) | B(2) | B(1);
@@ -4147,7 +4146,6 @@ Case_BaseLdurStur:
case 3:
if (inverted) {
imm8 = ~imm8 & 0xFFu;
inverted = 0;
}
op = 1;

View File

@@ -45,20 +45,27 @@ public:
return reg;
}
template<typename RegT, typename Type>
ASMJIT_INLINE_NODEBUG RegT _newRegInternal(const Type& type, const char* s) {
#ifndef ASMJIT_NO_LOGGING
RegT reg(Globals::NoInit);
_newReg(&reg, type, s);
return reg;
#else
DebugUtils::unused(s);
return _newRegInternal<RegT>(type);
#endif
}
template<typename RegT, typename Type, typename... Args>
ASMJIT_INLINE_NODEBUG RegT _newRegInternal(const Type& type, const char* s, Args&&... args) {
#ifndef ASMJIT_NO_LOGGING
RegT reg(Globals::NoInit);
if (sizeof...(Args) == 0)
_newReg(&reg, type, s);
else
_newRegFmt(&reg, type, s, std::forward<Args>(args)...);
return reg;
#else
DebugUtils::unused(s, std::forward<Args>(args)...);
RegT reg(Globals::NoInit);
_newReg(&reg, type, nullptr);
return reg;
return _newRegInternal<RegT>(type);
#endif
}
//! \endcond

View File

@@ -169,7 +169,7 @@ Error EmitHelper::emitArgMove(
if (TypeUtils::isInt(dstTypeId)) {
if (TypeUtils::isInt(srcTypeId)) {
uint32_t x = dstSize == 8;
uint32_t x = uint32_t(dstSize == 8);
dst.setSignature(OperandSignature{x ? uint32_t(GpX::kSignature) : uint32_t(GpW::kSignature)});
_emitter->setInlineComment(comment);
@@ -186,7 +186,7 @@ Error EmitHelper::emitArgMove(
case TypeId::kInt16: instId = Inst::kIdLdrsh; break;
case TypeId::kUInt16: instId = Inst::kIdLdrh; break;
case TypeId::kInt32: instId = x ? Inst::kIdLdrsw : Inst::kIdLdr; break;
case TypeId::kUInt32: instId = Inst::kIdLdr; x = 0; break;
case TypeId::kUInt32: instId = Inst::kIdLdr; break;
case TypeId::kInt64: instId = Inst::kIdLdr; break;
case TypeId::kUInt64: instId = Inst::kIdLdr; break;
default:

View File

@@ -185,7 +185,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatCondCode(String& sb, CondCode c
}
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatShiftOp(String& sb, ShiftOp shiftOp) noexcept {
const char* str = "<Unknown>";
const char* str = nullptr;
switch (shiftOp) {
case ShiftOp::kLSL: str = "lsl"; break;
case ShiftOp::kLSR: str = "lsr"; break;
@@ -201,6 +201,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatShiftOp(String& sb, ShiftOp shi
case ShiftOp::kSXTH: str = "sxth"; break;
case ShiftOp::kSXTW: str = "sxtw"; break;
case ShiftOp::kSXTX: str = "sxtx"; break;
default: str = "<Unknown>"; break;
}
return sb.append(str);
}

View File

@@ -16,7 +16,7 @@
#define ASMJIT_LIBRARY_MAKE_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
//! AsmJit library version, see \ref ASMJIT_LIBRARY_MAKE_VERSION for a version format reference.
#define ASMJIT_LIBRARY_VERSION ASMJIT_LIBRARY_MAKE_VERSION(1, 11, 0)
#define ASMJIT_LIBRARY_VERSION ASMJIT_LIBRARY_MAKE_VERSION(1, 12, 0)
//! \def ASMJIT_ABI_NAMESPACE
//!
@@ -27,7 +27,7 @@
//! AsmJit default, which makes it possible to use multiple AsmJit libraries within a single project, totally
//! controlled by users. This is useful especially in cases in which some of such library comes from third party.
#if !defined(ASMJIT_ABI_NAMESPACE)
#define ASMJIT_ABI_NAMESPACE _abi_1_11
#define ASMJIT_ABI_NAMESPACE _abi_1_12
#endif // !ASMJIT_ABI_NAMESPACE
//! \}
@@ -221,45 +221,11 @@ namespace asmjit {
// C++ Compiler and Features Detection
// ===================================
#define ASMJIT_CXX_GNU 0
#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR))
// Intel Compiler [pretends to be GNU or MSC, so it must be checked first]:
// - https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
// - https://software.intel.com/en-us/articles/c14-features-supported-by-intel-c-compiler
// - https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler
#if defined(__INTEL_COMPILER)
// MSC Compiler:
// - https://msdn.microsoft.com/en-us/library/hh567368.aspx
//
// Version List:
// - 16.00.0 == VS2010
// - 17.00.0 == VS2012
// - 18.00.0 == VS2013
// - 19.00.0 == VS2015
// - 19.10.0 == VS2017
#elif defined(_MSC_VER) && defined(_MSC_FULL_VER)
// Clang Compiler [Pretends to be GNU, so it must be checked before]:
// - https://clang.llvm.org/cxx_status.html
#elif defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
// GNU Compiler:
// - https://gcc.gnu.org/projects/cxx-status.html
#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#undef ASMJIT_CXX_GNU
#define ASMJIT_CXX_GNU ASMJIT_CXX_MAKE_VER(__GNUC__, __GNUC_MINOR__)
#endif
// Compiler features detection macros.
#if defined(__clang__) && defined(__has_attribute)
#if defined(__GNUC__) && defined(__has_attribute)
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (__has_attribute(NAME))
#else
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK)))
#endif
#endif // !ASMJIT_CXX_HAS_ATTRIBUTE
// API Decorators & C++ Extensions
// ===============================
@@ -301,7 +267,7 @@ namespace asmjit {
//! is unwanted in most projects. MSVC automatically exports typeinfo and vtable if at least one symbol of the class
//! is exported. However, GCC has some strange behavior that even if one or more symbol is exported it doesn't export
//! typeinfo unless the class itself is decorated with "visibility(default)" (i.e. ASMJIT_API).
#if !defined(_WIN32) && defined(__GNUC__)
#if defined(__GNUC__) && !defined(_WIN32)
#define ASMJIT_VIRTAPI ASMJIT_API
#else
#define ASMJIT_VIRTAPI
@@ -477,66 +443,60 @@ namespace asmjit {
#if ASMJIT_CXX_HAS_ATTRIBUTE(no_sanitize, 0)
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize__("undefined")))
#elif ASMJIT_CXX_GNU >= ASMJIT_CXX_MAKE_VER(4, 9)
#elif defined(__GNUC__) && __GNUC__ >= 5
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF __attribute__((__no_sanitize_undefined__))
#else
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF
#endif
// Begin-Namespace & End-Namespace Macros
// Diagnostic Macros
// ======================================
#if defined _DOXYGEN
#define ASMJIT_BEGIN_NAMESPACE namespace asmjit {
#define ASMJIT_END_NAMESPACE }
#elif defined(__clang__)
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wconstant-logical-operand\"") \
_Pragma("clang diagnostic ignored \"-Wunnamed-type-template-args\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("clang diagnostic pop") \
}}
#elif defined(__GNUC__) && __GNUC__ == 4
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
#if !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(_DOXYGEN)
#if defined(__GNUC__) && __GNUC__ == 4
// There is a bug in GCC 4.X that has been fixed in GCC 5+, so just silence the warning.
#define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("GCC diagnostic pop") \
}}
#elif defined(__GNUC__) && __GNUC__ >= 8
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("GCC diagnostic pop") \
}}
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#define ASMJIT_BEGIN_NAMESPACE \
namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
#define ASMJIT_END_DIAGNOSTIC_SCOPE \
_Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
#define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
__pragma(warning(push)) \
__pragma(warning(disable: 4127)) /* conditional expression is const */ \
__pragma(warning(disable: 4201)) /* nameless struct/union */
#define ASMJIT_END_DIAGNOSTIC_SCOPE \
__pragma(warning(pop))
#endif
#endif
#if !defined(ASMJIT_BEGIN_DIAGNOSTIC_SCOPE) && !defined(ASMJIT_END_DIAGNOSTIC_SCOPE)
#define ASMJIT_BEGIN_DIAGNOSTIC_SCOPE
#define ASMJIT_END_DIAGNOSTIC_SCOPE
#endif
// Begin-Namespace & End-Namespace Macros
// ======================================
#if !defined(ASMJIT_NO_ABI_NAMESPACE) && !defined(_DOXYGEN)
#define ASMJIT_BEGIN_NAMESPACE \
ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
namespace asmjit { \
inline namespace ASMJIT_ABI_NAMESPACE {
#define ASMJIT_END_NAMESPACE \
}} \
ASMJIT_END_DIAGNOSTIC_SCOPE
#else
#define ASMJIT_BEGIN_NAMESPACE \
ASMJIT_BEGIN_DIAGNOSTIC_SCOPE \
namespace asmjit {
#define ASMJIT_END_NAMESPACE \
__pragma(warning(pop)) \
}}
#endif
#if !defined(ASMJIT_BEGIN_NAMESPACE) && !defined(ASMJIT_END_NAMESPACE)
#define ASMJIT_BEGIN_NAMESPACE namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE {
#define ASMJIT_END_NAMESPACE }}
#endif
#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) \
ASMJIT_BEGIN_NAMESPACE \
namespace NAMESPACE {
#define ASMJIT_END_SUB_NAMESPACE \
} \
ASMJIT_END_NAMESPACE
ASMJIT_END_DIAGNOSTIC_SCOPE
#endif
#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) ASMJIT_BEGIN_NAMESPACE namespace NAMESPACE {
#define ASMJIT_END_SUB_NAMESPACE } ASMJIT_END_NAMESPACE
// C++ Utilities
// =============
@@ -612,10 +572,4 @@ namespace asmjit {
}
#endif
// Cleanup Api-Config Specific Macros
// ==================================
#undef ASMJIT_CXX_GNU
#undef ASMJIT_CXX_MAKE_VER
#endif // ASMJIT_CORE_API_CONFIG_H_INCLUDED

View File

@@ -48,7 +48,7 @@ enum class NodeType : uint8_t {
// [BaseBuilder]
//! Node is \ref InstNode or \ref InstExNode.
//! Node is \ref InstNode.
kInst = 1,
//! Node is \ref SectionNode.
kSection = 2,
@@ -748,12 +748,15 @@ public:
//! \name Constants
//! \{
enum : uint32_t {
//! Count of embedded operands per `InstNode` that are always allocated as a part of the instruction. Minimum
//! embedded operands is 4, but in 32-bit more pointers are smaller and we can embed 5. The rest (up to 6 operands)
//! is always stored in `InstExNode`.
kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_))
};
//! The number of embedded operands for a default \ref InstNode instance that are always allocated as a part of
//! the instruction itself. Minimum embedded operands is 4, but in 32-bit more pointers are smaller and we can
//! embed 5. The rest (up to 6 operands) is considered extended.
//!
//! The number of operands InstNode holds is decided when \ref InstNode is created.
static constexpr uint32_t kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_));
//! Count of maximum number of operands \ref InstNode can hold.
static constexpr uint32_t kFullOpCapacity = Globals::kMaxOpCount;
//! \}
@@ -762,8 +765,6 @@ public:
//! Base instruction data.
BaseInst _baseInst;
//! First 4 or 5 operands (indexed from 0).
Operand_ _opArray[kBaseOpCapacity];
//! \}
@@ -851,38 +852,52 @@ public:
ASMJIT_INLINE_NODEBUG void setOpCount(uint32_t opCount) noexcept { _inst._opCount = uint8_t(opCount); }
//! Returns operands array.
ASMJIT_INLINE_NODEBUG Operand* operands() noexcept { return (Operand*)_opArray; }
ASMJIT_INLINE_NODEBUG Operand* operands() noexcept {
return reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(this) + sizeof(InstNode));
}
//! Returns operands array (const).
ASMJIT_INLINE_NODEBUG const Operand* operands() const noexcept { return (const Operand*)_opArray; }
ASMJIT_INLINE_NODEBUG const Operand* operands() const noexcept {
return reinterpret_cast<const Operand*>(reinterpret_cast<const uint8_t*>(this) + sizeof(InstNode));
}
//! Returns operand at the given `index`.
inline Operand& op(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
return _opArray[index].as<Operand>();
Operand* ops = operands();
return ops[index].as<Operand>();
}
//! Returns operand at the given `index` (const).
inline const Operand& op(uint32_t index) const noexcept {
ASMJIT_ASSERT(index < opCapacity());
return _opArray[index].as<Operand>();
const Operand* ops = operands();
return ops[index].as<Operand>();
}
//! Sets operand at the given `index` to `op`.
inline void setOp(uint32_t index, const Operand_& op) noexcept {
ASMJIT_ASSERT(index < opCapacity());
_opArray[index].copyFrom(op);
Operand* ops = operands();
ops[index].copyFrom(op);
}
//! Resets operand at the given `index` to none.
inline void resetOp(uint32_t index) noexcept {
ASMJIT_ASSERT(index < opCapacity());
_opArray[index].reset();
Operand* ops = operands();
ops[index].reset();
}
//! Resets operands at `[start, end)` range.
inline void resetOpRange(uint32_t start, uint32_t end) noexcept {
Operand* ops = operands();
for (uint32_t i = start; i < end; i++)
_opArray[i].reset();
ops[i].reset();
}
//! \}
@@ -891,8 +906,9 @@ public:
//! \{
inline bool hasOpType(OperandType opType) const noexcept {
const Operand* ops = operands();
for (uint32_t i = 0, count = opCount(); i < count; i++)
if (_opArray[i].opType() == opType)
if (ops[i].opType() == opType)
return true;
return false;
}
@@ -905,9 +921,10 @@ public:
inline uint32_t indexOfOpType(OperandType opType) const noexcept {
uint32_t i = 0;
uint32_t count = opCount();
const Operand* ops = operands();
while (i < count) {
if (_opArray[i].opType() == opType)
if (ops[i].opType() == opType)
break;
i++;
}
@@ -950,43 +967,31 @@ public:
//! \{
//! \cond INTERNAL
static ASMJIT_INLINE_NODEBUG uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
static ASMJIT_INLINE_NODEBUG constexpr uint32_t capacityOfOpCount(uint32_t opCount) noexcept {
return opCount <= kBaseOpCapacity ? kBaseOpCapacity : Globals::kMaxOpCount;
}
static ASMJIT_INLINE_NODEBUG size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept {
size_t base = sizeof(InstNode) - kBaseOpCapacity * sizeof(Operand);
return base + opCapacity * sizeof(Operand);
static ASMJIT_INLINE_NODEBUG constexpr size_t nodeSizeOfOpCapacity(uint32_t opCapacity) noexcept {
return sizeof(InstNode) + opCapacity * sizeof(Operand);
}
//! \endcond
//! \}
};
//! Instruction node with maximum number of operands.
//! Instruction node with embedded operands following \ref InstNode layout.
//!
//! This node is created automatically by Builder/Compiler in case that the required number of operands exceeds
//! the default capacity of `InstNode`.
class InstExNode : public InstNode {
//! \note This is used to make tools such as static analysis and compilers happy about the layout. There were two
//! instruction nodes in the past, having the second extend the operand array of the first, but that has caused
//! undefined behavior and made recent tools unhappy about that.
template<uint32_t kN>
class InstNodeWithOperands : public InstNode {
public:
ASMJIT_NONCOPYABLE(InstExNode)
Operand_ _operands[kN];
//! \name Members
//! \{
//! Continued `_opArray[]` to hold up to `kMaxOpCount` operands.
Operand_ _opArrayEx[Globals::kMaxOpCount - kBaseOpCapacity];
//! \}
//! \name Construction & Destruction
//! \{
//! Creates a new `InstExNode` instance.
ASMJIT_INLINE_NODEBUG InstExNode(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCapacity = Globals::kMaxOpCount) noexcept
: InstNode(cb, instId, options, opCapacity) {}
//! \}
//! Creates a new `InstNodeWithOperands` instance.
ASMJIT_INLINE_NODEBUG InstNodeWithOperands(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCount) noexcept
: InstNode(cb, instId, options, opCount, kN) {}
};
//! Section node.
@@ -1013,9 +1018,9 @@ public:
//! \{
//! Creates a new `SectionNode` instance.
ASMJIT_INLINE_NODEBUG SectionNode(BaseBuilder* cb, uint32_t secionId = 0) noexcept
ASMJIT_INLINE_NODEBUG SectionNode(BaseBuilder* cb, uint32_t sectionId = 0) noexcept
: BaseNode(cb, NodeType::kSection, NodeFlags::kHasNoEffect),
_id(secionId),
_id(sectionId),
_nextSection(nullptr) {}
//! \}

View File

@@ -325,7 +325,7 @@ public:
//! \note This node should be only used to represent jump where the jump target cannot be deduced by examining
//! instruction operands. For example if the jump target is register or memory location. This pattern is often
//! used to perform indirect jumps that use jump table, e.g. to implement `switch{}` statement.
class JumpNode : public InstNode {
class JumpNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(JumpNode)
@@ -340,7 +340,7 @@ public:
//! \{
inline JumpNode(BaseCompiler* ASMJIT_NONNULL(cc), InstId instId, InstOptions options, uint32_t opCount, JumpAnnotation* annotation) noexcept
: InstNode(cc, instId, options, opCount, kBaseOpCapacity),
: InstNodeWithOperands(cc, instId, options, opCount),
_annotation(annotation) {
setType(NodeType::kJump);
}
@@ -531,7 +531,7 @@ public:
};
//! Function return, used by \ref BaseCompiler.
class FuncRetNode : public InstNode {
class FuncRetNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(FuncRetNode)
@@ -539,7 +539,8 @@ public:
//! \{
//! Creates a new `FuncRetNode` instance.
inline FuncRetNode(BaseBuilder* ASMJIT_NONNULL(cb)) noexcept : InstNode(cb, BaseInst::kIdAbstract, InstOptions::kNone, 0) {
inline FuncRetNode(BaseBuilder* ASMJIT_NONNULL(cb)) noexcept
: InstNodeWithOperands(cb, BaseInst::kIdAbstract, InstOptions::kNone, 0) {
_any._nodeType = NodeType::kFuncRet;
}
@@ -547,12 +548,12 @@ public:
};
//! Function invocation, used by \ref BaseCompiler.
class InvokeNode : public InstNode {
class InvokeNode : public InstNodeWithOperands<InstNode::kBaseOpCapacity> {
public:
ASMJIT_NONCOPYABLE(InvokeNode)
//! Operand pack provides multiple operands that can be associated with a single return value of function
//! argument. Sometims this is necessary to express an argument or return value that requires multiple
//! argument. Sometimes this is necessary to express an argument or return value that requires multiple
//! registers, for example 64-bit value in 32-bit mode or passing / returning homogeneous data structures.
struct OperandPack {
//! Operands.
@@ -594,7 +595,7 @@ public:
//! Creates a new `InvokeNode` instance.
inline InvokeNode(BaseBuilder* ASMJIT_NONNULL(cb), InstId instId, InstOptions options) noexcept
: InstNode(cb, instId, options, kBaseOpCapacity),
: InstNodeWithOperands(cb, instId, options, 0),
_funcDetail(),
_args(nullptr) {
setType(NodeType::kInvoke);
@@ -619,9 +620,9 @@ public:
ASMJIT_INLINE_NODEBUG const FuncDetail& detail() const noexcept { return _funcDetail; }
//! Returns the target operand.
ASMJIT_INLINE_NODEBUG Operand& target() noexcept { return _opArray[0].as<Operand>(); }
ASMJIT_INLINE_NODEBUG Operand& target() noexcept { return op(0); }
//! \overload
ASMJIT_INLINE_NODEBUG const Operand& target() const noexcept { return _opArray[0].as<Operand>(); }
ASMJIT_INLINE_NODEBUG const Operand& target() const noexcept { return op(0); }
//! Returns the number of function return values.
ASMJIT_INLINE_NODEBUG bool hasRet() const noexcept { return _funcDetail.hasRet(); }

View File

@@ -876,59 +876,58 @@ public:
//! \{
//! Architecture.
Arch _arch;
Arch _arch {};
//! Sub-architecture.
SubArch _subArch;
SubArch _subArch {};
//! True if the CPU was detected, false if the detection failed or it's not available.
bool _wasDetected;
bool _wasDetected {};
//! Reserved for future use.
uint8_t _reserved;
uint8_t _reserved {};
//! CPU family ID.
uint32_t _familyId;
uint32_t _familyId {};
//! CPU model ID.
uint32_t _modelId;
uint32_t _modelId {};
//! CPU brand ID.
uint32_t _brandId;
uint32_t _brandId {};
//! CPU stepping.
uint32_t _stepping;
uint32_t _stepping {};
//! Processor type.
uint32_t _processorType;
uint32_t _processorType {};
//! Maximum number of addressable IDs for logical processors.
uint32_t _maxLogicalProcessors;
uint32_t _maxLogicalProcessors {};
//! Cache line size (in bytes).
uint32_t _cacheLineSize;
uint32_t _cacheLineSize {};
//! Number of hardware threads.
uint32_t _hwThreadCount;
uint32_t _hwThreadCount {};
//! CPU vendor string.
FixedString<16> _vendor;
FixedString<16> _vendor {};
//! CPU brand string.
FixedString<64> _brand;
FixedString<64> _brand {};
//! CPU features.
CpuFeatures _features;
CpuFeatures _features {};
//! \}
//! \name Construction & Destruction
//! \{
ASMJIT_INLINE_NODEBUG CpuInfo() noexcept { reset(); }
ASMJIT_INLINE_NODEBUG CpuInfo() noexcept {}
ASMJIT_INLINE_NODEBUG CpuInfo(const CpuInfo& other) noexcept = default;
ASMJIT_INLINE_NODEBUG explicit CpuInfo(Globals::NoInit_) noexcept
: _features(Globals::NoInit) {};
//! \}
//! \name CPU Information Detection
//! \{
//! Returns the host CPU information.
//!
//! \note The returned reference is global - it's setup only once and then shared.
ASMJIT_API static const CpuInfo& host() noexcept;
//! Initializes CpuInfo architecture and sub-architecture members to `arch` and `subArch`, respectively.
ASMJIT_INLINE_NODEBUG void initArch(Arch arch, SubArch subArch = SubArch::kUnknown) noexcept {
_arch = arch;
_subArch = subArch;
}
ASMJIT_INLINE_NODEBUG void reset() noexcept { memset(this, 0, sizeof(*this)); }
//! \}
//! \name Overloaded Operators
@@ -938,6 +937,19 @@ public:
//! \}
//! \name Init & Reset
//! \{
//! Initializes CpuInfo architecture and sub-architecture members to `arch` and `subArch`, respectively.
ASMJIT_INLINE_NODEBUG void initArch(Arch arch, SubArch subArch = SubArch::kUnknown) noexcept {
_arch = arch;
_subArch = subArch;
}
ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = CpuInfo{}; }
//! \}
//! \name Accessors
//! \{

View File

@@ -194,6 +194,7 @@ ASMJIT_DEFINE_ENUM_FLAGS(DiagnosticOptions)
class ASMJIT_VIRTAPI BaseEmitter {
public:
ASMJIT_BASE_CLASS(BaseEmitter)
ASMJIT_NONCOPYABLE(BaseEmitter)
//! \name Members
//! \{

View File

@@ -57,7 +57,7 @@ Error formatTypeId(String& sb, TypeId typeId) noexcept {
if (!TypeUtils::isValid(typeId))
return sb.append("unknown");
const char* typeName = "unknown";
const char* typeName = nullptr;
uint32_t typeSize = TypeUtils::sizeOf(typeId);
TypeId scalarType = TypeUtils::scalarOf(typeId);
@@ -514,7 +514,7 @@ Error formatNode(
ASMJIT_PROPAGATE(sb.append("[FuncRet]"));
for (uint32_t i = 0; i < 2; i++) {
const Operand_& op = retNode->_opArray[i];
const Operand_& op = retNode->op(i);
if (!op.isNone()) {
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
ASMJIT_PROPAGATE(formatOperand(sb, formatOptions.flags(), builder, builder->arch(), op));

View File

@@ -499,7 +499,8 @@ struct OpRWInfo {
_consecutiveLeadCount = 0;
_resetReserved();
uint64_t mask = Support::lsbMask<uint64_t>(regSize);
uint64_t mask = Support::lsbMask<uint64_t>(Support::min<uint32_t>(regSize, 64));
_readByteMask = Support::test(opFlags, OpRWFlags::kRead) ? mask : uint64_t(0);
_writeByteMask = Support::test(opFlags, OpRWFlags::kWrite) ? mask : uint64_t(0);
_extendByteMask = 0;

View File

@@ -37,12 +37,13 @@ static constexpr uint32_t kJitAllocatorMaxBlockSize = 1024 * 1024 * 64;
// ===========================
static inline uint32_t JitAllocator_defaultFillPattern() noexcept {
#if ASMJIT_ARCH_X86
// X86 and X86_64 - 4x 'int3' instruction.
if (ASMJIT_ARCH_X86)
return 0xCCCCCCCCu;
#else
// Unknown...
return 0u;
#endif
}
// JitAllocator - BitVectorRangeIterator

View File

@@ -331,25 +331,25 @@ struct OperandSignature {
ASMJIT_INLINE_NODEBUG constexpr uint32_t bits() const noexcept { return _bits; }
ASMJIT_INLINE_NODEBUG void setBits(uint32_t bits) noexcept { _bits = bits; }
template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
template<uint32_t kFieldMask>
ASMJIT_INLINE_NODEBUG constexpr bool hasField() const noexcept {
return (_bits & kFieldMask) != 0;
}
template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
template<uint32_t kFieldMask>
ASMJIT_INLINE_NODEBUG constexpr bool hasField(uint32_t value) const noexcept {
return (_bits & kFieldMask) != value << kFieldShift;
return (_bits & kFieldMask) != value << Support::ConstCTZ<kFieldMask>::value;
}
template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
template<uint32_t kFieldMask>
ASMJIT_INLINE_NODEBUG constexpr uint32_t getField() const noexcept {
return (_bits >> kFieldShift) & (kFieldMask >> kFieldShift);
return (_bits >> Support::ConstCTZ<kFieldMask>::value) & (kFieldMask >> Support::ConstCTZ<kFieldMask>::value);
}
template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
template<uint32_t kFieldMask>
ASMJIT_INLINE_NODEBUG void setField(uint32_t value) noexcept {
ASMJIT_ASSERT((value & ~(kFieldMask >> kFieldShift)) == 0);
_bits = (_bits & ~kFieldMask) | (value << kFieldShift);
ASMJIT_ASSERT(((value << Support::ConstCTZ<kFieldMask>::value) & ~kFieldMask) == 0);
_bits = (_bits & ~kFieldMask) | (value << Support::ConstCTZ<kFieldMask>::value);
}
ASMJIT_INLINE_NODEBUG constexpr OperandSignature subset(uint32_t mask) const noexcept { return OperandSignature{_bits & mask}; }
@@ -643,10 +643,10 @@ struct Operand_ {
//! \note This basically performs a binary comparison, if aby bit is
//! different the operands are not equal.
ASMJIT_INLINE_NODEBUG constexpr bool equals(const Operand_& other) const noexcept {
return (_signature == other._signature) &
(_baseId == other._baseId ) &
(_data[0] == other._data[0] ) &
(_data[1] == other._data[1] ) ;
return bool(unsigned(_signature == other._signature) &
unsigned(_baseId == other._baseId ) &
unsigned(_data[0] == other._data[0] ) &
unsigned(_data[1] == other._data[1] ));
}
//! Tests whether the operand is a register matching the given register `type`.
@@ -712,7 +712,7 @@ public:
//! Creates an operand initialized to raw `[u0, u1, u2, u3]` values.
ASMJIT_INLINE_NODEBUG constexpr Operand(Globals::Init_, const Signature& u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
: Operand_{ u0, u1, { u2, u3 }} {}
: Operand_{{u0._bits}, u1, {u2, u3}} {}
//! Creates an uninitialized operand (dangerous).
ASMJIT_INLINE_NODEBUG explicit Operand(Globals::NoInit_) noexcept {}

View File

@@ -476,12 +476,18 @@ Error BaseRAPass::buildCFGDominators() noexcept {
entryBlock->setIDom(entryBlock);
bool changed = true;
uint32_t nIters = 0;
#ifndef ASMJIT_NO_LOGGING
uint32_t numIters = 0;
#endif
while (changed) {
nIters++;
changed = false;
#ifndef ASMJIT_NO_LOGGING
numIters++;
#endif
uint32_t i = _pov.size();
while (i) {
RABlock* block = _pov[--i];
@@ -508,7 +514,7 @@ Error BaseRAPass::buildCFGDominators() noexcept {
}
}
ASMJIT_RA_LOG_FORMAT(" Done (%u iterations)\n", nIters);
ASMJIT_RA_LOG_FORMAT(" Done (%u iterations)\n", numIters);
return kErrorOk;
}
@@ -798,7 +804,6 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
uint32_t numAllBlocks = blockCount();
uint32_t numReachableBlocks = reachableBlockCount();
uint32_t numVisits = numReachableBlocks;
uint32_t numWorkRegs = workRegCount();
uint32_t numBitWords = ZoneBitVector::_wordsPerBits(numWorkRegs);
@@ -888,6 +893,10 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
// Calculate IN/OUT of Each Block
// ------------------------------
#ifndef ASMJIT_NO_LOGGING
uint32_t numVisits = numReachableBlocks;
#endif
{
ZoneStack<RABlock*> workList;
ZoneBitVector workBits;
@@ -918,7 +927,9 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
}
}
}
#ifndef ASMJIT_NO_LOGGING
numVisits++;
#endif
}
workList.reset();

View File

@@ -230,7 +230,7 @@ static ASMJIT_INLINE_NODEBUG constexpr T lsbMask(const CountT& n) noexcept {
: n ? T(shr(allOnes<T>(), bitSizeOf<T>() - size_t(n))) : T(0);
}
//! Generats a leading bit-mask that has `n` most significant (leading) bits set.
//! Generates a leading bit-mask that has `n` most significant (leading) bits set.
template<typename T, typename CountT>
static ASMJIT_INLINE_NODEBUG constexpr T msbMask(const CountT& n) noexcept {
typedef typename std::make_unsigned<T>::type U;
@@ -321,12 +321,12 @@ struct BitScanCalc<T, 0> {
};
template<typename T>
constexpr ASMJIT_INLINE_NODEBUG uint32_t clzFallback(const T& x) noexcept {
ASMJIT_INLINE_NODEBUG constexpr uint32_t clzFallback(const T& x) noexcept {
return BitScanCalc<T, bitSizeOf<T>() / 2u>::clz(BitScanData<T>{x, 1}).n;
}
template<typename T>
constexpr ASMJIT_INLINE_NODEBUG uint32_t ctzFallback(const T& x) noexcept {
ASMJIT_INLINE_NODEBUG constexpr uint32_t ctzFallback(const T& x) noexcept {
return BitScanCalc<T, bitSizeOf<T>() / 2u>::ctz(BitScanData<T>{x, 1}).n;
}
@@ -457,31 +457,30 @@ namespace Internal {
}
static ASMJIT_INLINE_NODEBUG uint32_t constPopcntImpl(uint64_t x) noexcept {
if (ASMJIT_ARCH_BITS >= 64) {
#if ASMJIT_ARCH_BITS >= 64
x = x - ((x >> 1) & 0x5555555555555555u);
x = (x & 0x3333333333333333u) + ((x >> 2) & 0x3333333333333333u);
return uint32_t((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fu) * 0x0101010101010101u) >> 56);
}
else {
#else
return constPopcntImpl(uint32_t(x >> 32)) +
constPopcntImpl(uint32_t(x & 0xFFFFFFFFu));
}
#endif
}
static ASMJIT_INLINE_NODEBUG uint32_t popcntImpl(uint32_t x) noexcept {
#if defined(__GNUC__)
#if defined(__GNUC__)
return uint32_t(__builtin_popcount(x));
#else
#else
return constPopcntImpl(asUInt(x));
#endif
#endif
}
static ASMJIT_INLINE_NODEBUG uint32_t popcntImpl(uint64_t x) noexcept {
#if defined(__GNUC__)
#if defined(__GNUC__)
return uint32_t(__builtin_popcountll(x));
#else
#else
return constPopcntImpl(asUInt(x));
#endif
#endif
}
}
//! \endcond
@@ -596,9 +595,9 @@ namespace Internal {
template<typename T> inline T subOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return subOverflowFallback(x, y, of); }
template<typename T> inline T mulOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return mulOverflowFallback(x, y, of); }
#if defined(__GNUC__) && !defined(ASMJIT_NO_INTRINSICS)
#if defined(__clang__) || __GNUC__ >= 5
#define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, RESULT_T, BUILTIN) \
#if defined(__GNUC__) && !defined(ASMJIT_NO_INTRINSICS)
#if defined(__clang__) || __GNUC__ >= 5
#define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, RESULT_T, BUILTIN) \
template<> \
inline T FUNC(const T& x, const T& y, FastUInt8* of) noexcept { \
RESULT_T result; \
@@ -617,13 +616,13 @@ namespace Internal {
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint32_t, unsigned int , __builtin_umul_overflow )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, int64_t , long long , __builtin_smulll_overflow)
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(mulOverflowImpl, uint64_t, unsigned long long, __builtin_umulll_overflow)
#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
#endif
#endif
#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
#endif
#endif
// There is a bug in MSVC that makes these specializations unusable, maybe in the future...
#if defined(_MSC_VER) && 0
#define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
#if defined(_MSC_VER) && 0
#define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
template<> \
inline T FUNC(T x, T y, FastUInt8* of) noexcept { \
ALT_T result; \
@@ -632,12 +631,12 @@ namespace Internal {
}
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , _addcarry_u32 )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint32_t, unsigned int , _subborrow_u32)
#if ARCH_BITS >= 64
#if ARCH_BITS >= 64
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint64_t, unsigned __int64 , _addcarry_u64 )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint64_t, unsigned __int64 , _subborrow_u64)
#endif
#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
#endif
#endif
#undef ASMJIT_ARITH_OVERFLOW_SPECIALIZE
#endif
} // {Internal}
//! \endcond

View File

@@ -194,8 +194,13 @@ public:
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
::memmove(static_cast<T*>(_data) + 1, _data, size_t(_size) * sizeof(T));
memcpy(_data, &item, sizeof(T));
memmove(static_cast<void*>(static_cast<T*>(_data) + 1),
static_cast<const void*>(_data),
size_t(_size) * sizeof(T));
memcpy(static_cast<void*>(_data),
static_cast<const void*>(&item),
sizeof(T));
_size++;
return kErrorOk;
@@ -209,10 +214,15 @@ public:
ASMJIT_PROPAGATE(grow(allocator, 1));
T* dst = static_cast<T*>(_data) + index;
::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
memcpy(dst, &item, sizeof(T));
_size++;
memmove(static_cast<void*>(dst + 1),
static_cast<const void*>(dst),
size_t(_size - index) * sizeof(T));
memcpy(static_cast<void*>(dst),
static_cast<const void*>(&item),
sizeof(T));
_size++;
return kErrorOk;
}
@@ -221,9 +231,11 @@ public:
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
_size++;
memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
static_cast<const void*>(&item),
sizeof(T));
_size++;
return kErrorOk;
}
@@ -234,7 +246,9 @@ public:
ASMJIT_PROPAGATE(grow(allocator, size));
if (size) {
memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
static_cast<const void*>(other._data),
size_t(size) * sizeof(T));
_size += size;
}
@@ -249,10 +263,15 @@ public:
ASMJIT_ASSERT(_size < _capacity);
T* data = static_cast<T*>(_data);
if (_size)
::memmove(data + 1, data, size_t(_size) * sizeof(T));
if (_size) {
memmove(static_cast<void*>(data + 1),
static_cast<const void*>(data),
size_t(_size) * sizeof(T));
}
memcpy(data, &item, sizeof(T));
memcpy(static_cast<void*>(data),
static_cast<const void*>(&item),
sizeof(T));
_size++;
}
@@ -263,7 +282,9 @@ public:
ASMJIT_FORCE_INLINE void appendUnsafe(const T& item) noexcept {
ASMJIT_ASSERT(_size < _capacity);
memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
static_cast<const void*>(&item),
sizeof(T));
_size++;
}
@@ -273,17 +294,26 @@ public:
ASMJIT_ASSERT(index <= _size);
T* dst = static_cast<T*>(_data) + index;
::memmove(dst + 1, dst, size_t(_size - index) * sizeof(T));
memcpy(dst, &item, sizeof(T));
memmove(static_cast<void*>(dst + 1),
static_cast<const void*>(dst),
size_t(_size - index) * sizeof(T));
memcpy(static_cast<void*>(dst),
static_cast<const void*>(&item),
sizeof(T));
_size++;
}
//! Concatenates all items of `other` at the end of the vector.
ASMJIT_FORCE_INLINE void concatUnsafe(const ZoneVector<T>& other) noexcept {
uint32_t size = other._size;
ASMJIT_ASSERT(_capacity - _size >= size);
if (size) {
memcpy(static_cast<T*>(_data) + _size, other._data, size_t(size) * sizeof(T));
memcpy(static_cast<void*>(static_cast<T*>(_data) + _size),
static_cast<const void*>(other._data),
size_t(size) * sizeof(T));
_size += size;
}
}
@@ -311,8 +341,11 @@ public:
T* data = static_cast<T*>(_data) + i;
size_t size = --_size - i;
if (size)
::memmove(data, data + 1, size_t(size) * sizeof(T));
if (size) {
memmove(static_cast<void*>(data),
static_cast<const void*>(data + 1),
size_t(size) * sizeof(T));
}
}
//! Pops the last element from the vector and returns it.

View File

@@ -560,7 +560,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
const Operand_* rmRel; // Memory operand or operand that holds Label|Imm.
uint32_t rmInfo; // Memory operand's info based on x86MemInfo.
uint32_t rbReg; // Memory base or modRM register.
uint32_t rbReg = 0; // Memory base or modRM register.
uint32_t rxReg; // Memory index register.
uint32_t opReg; // ModR/M opcode or register id.
@@ -653,7 +653,6 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, con
// This sequence seems to be the fastest.
opcode = InstDB::_mainOpcodeTable[instInfo->_mainOpcodeIndex];
opReg = opcode.extractModO();
rbReg = 0;
opcode |= instInfo->_mainOpcodeValue;
// Encoding Scope

View File

@@ -539,7 +539,6 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint3
ASMJIT_PROPAGATE(sb.appendUInt(index));
}
if (kImmCharEnd)
ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
@@ -576,7 +575,7 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint3
ASMJIT_PROPAGATE(sb.append(str));
}
if (n && kImmCharEnd)
if (n)
ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
@@ -592,10 +591,7 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint3
ASMJIT_PROPAGATE(sb.append(Support::findPackedString(text, value)));
}
if (kImmCharEnd)
ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
return sb.append(kImmCharEnd);
}
ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(

View File

@@ -1711,18 +1711,6 @@ Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand
// =========================
#if defined(ASMJIT_TEST)
template<typename... Args>
static Error queryRWInfoInline(InstRWInfo* out, Arch arch, BaseInst inst, Args&&... args) {
Operand_ opArray[] = { std::forward<Args>(args)... };
return InstInternal::queryRWInfo(arch, inst, opArray, sizeof...(args), out);
}
template<typename... Args>
static Error queryFeaturesInline(CpuFeatures* out, Arch arch, BaseInst inst, Args&&... args) {
Operand_ opArray[] = { std::forward<Args>(args)... };
return InstInternal::queryFeatures(arch, inst, opArray, sizeof...(args), out);
}
#ifndef ASMJIT_NO_TEXT
UNIT(x86_inst_api_text) {
// All known instructions should be matched.
@@ -1741,6 +1729,13 @@ UNIT(x86_inst_api_text) {
}
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_INTROSPECTION
template<typename... Args>
static Error queryFeaturesInline(CpuFeatures* out, Arch arch, BaseInst inst, Args&&... args) {
Operand_ opArray[] = { std::forward<Args>(args)... };
return InstInternal::queryFeatures(arch, inst, opArray, sizeof...(args), out);
}
UNIT(x86_inst_api_cpu_features) {
INFO("Verifying whether SSE2+ features are reported correctly for legacy instructions");
{
@@ -1815,6 +1810,14 @@ UNIT(x86_inst_api_cpu_features) {
EXPECT_TRUE(f.x86().hasAVX512_F());
}
}
#endif // !ASMJIT_NO_INTROSPECTION
#ifndef ASMJIT_NO_INTROSPECTION
template<typename... Args>
static Error queryRWInfoInline(InstRWInfo* out, Arch arch, BaseInst inst, Args&&... args) {
Operand_ opArray[] = { std::forward<Args>(args)... };
return InstInternal::queryRWInfo(arch, inst, opArray, sizeof...(args), out);
}
UNIT(x86_inst_api_rm_features) {
INFO("Verifying whether RM/feature is reported correctly for PEXTRW instruction");
@@ -1869,7 +1872,9 @@ UNIT(x86_inst_api_rm_features) {
EXPECT_EQ(rwi.rmFeature(), 0u);
}
}
#endif
#endif // !ASMJIT_NO_INTROSPECTION
#endif // ASMJIT_TEST
ASMJIT_END_SUB_NAMESPACE

View File

@@ -823,7 +823,7 @@ Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& a
stackPtr.setSize(4);
imm[0] = imm_;
uint32_t nMovs = 0;
uint32_t movCount = 0;
// One stack entry has the same size as the native register size. That means that if we want to move a 32-bit
// integer on the stack in 64-bit mode, we need to extend it to a 64-bit integer first. In 32-bit mode, pushing
@@ -839,7 +839,7 @@ Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& a
case TypeId::kFloat32:
MovU32:
imm[0].zeroExtend32Bits();
nMovs = 1;
movCount = 1;
break;
case TypeId::kInt64:
@@ -849,20 +849,20 @@ MovU32:
case TypeId::kMmx64:
if (_is64Bit && imm[0].isInt32()) {
stackPtr.setSize(8);
nMovs = 1;
movCount = 1;
break;
}
imm[1].setValue(imm[0].uint32Hi());
imm[0].zeroExtend32Bits();
nMovs = 2;
movCount = 2;
break;
default:
return DebugUtils::errored(kErrorInvalidAssignment);
}
for (uint32_t i = 0; i < nMovs; i++) {
for (uint32_t i = 0; i < movCount; i++) {
ASMJIT_PROPAGATE(cc()->mov(stackPtr, imm[i]));
stackPtr.addOffsetLo32(int32_t(stackPtr.size()));
}

View File

@@ -971,8 +971,8 @@ public:
typedef void (*Func)(int*, int*);
Func func = ptr_as_func<Func>(_func);
int resultX;
int resultY;
int resultX = 0;
int resultY = 0;
int expectX = 36;
int expectY = -36;
@@ -1026,8 +1026,8 @@ public:
Func func = ptr_as_func<Func>(_func);
uint32_t i;
uint32_t resultBuf[32];
uint32_t expectBuf[32];
uint32_t resultBuf[32] {};
uint32_t expectBuf[32] {};
for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++)
expectBuf[i] = i * 32;
@@ -1085,8 +1085,8 @@ public:
int v0 = 4;
int v1 = 4;
int resultHi;
int resultLo;
int resultHi = 0;
int resultLo = 0;
int expectHi = 0;
int expectLo = v0 * v1;
@@ -1227,7 +1227,7 @@ public:
typedef void (*Func)(int, int, char*);
Func func = ptr_as_func<Func>(_func);
char resultBuf[4];
char resultBuf[4] {};
char expectBuf[4] = { 1, 0, 0, 1 };
func(0, 0, &resultBuf[0]); // We are expecting 1 (0 == 0).
@@ -1280,7 +1280,7 @@ public:
int v0 = 0x000000FF;
int resultRet;
int resultRet = 0;
int expectRet = 0x0000FF00;
func(&resultRet, v0, 16, 8);
@@ -1347,10 +1347,9 @@ public:
uint32_t i;
uint32_t buf[kCount];
uint32_t resultRet;
uint32_t expectRet;
uint32_t resultRet = 0;
uint32_t expectRet = 0;
expectRet = 0;
for (i = 0; i < kCount; i++) {
buf[i] = 1;
}
@@ -1700,7 +1699,7 @@ public:
x86::Gp x = cc.newInt8("x");
x86::Gp y = cc.newInt32("y");
FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, char>(CallConvId::kHost));
FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int8_t>(CallConvId::kHost));
funcNode->setArg(0, x);
cc.movsx(y, x);
@@ -1710,10 +1709,10 @@ public:
}
virtual bool run(void* _func, String& result, String& expect) {
typedef int (*Func)(char);
typedef int (*Func)(int8_t);
Func func = ptr_as_func<Func>(_func);
int resultRet = func(-13);
int resultRet = func(int8_t(-13));
int expectRet = -13;
result.assignFormat("ret=%d", resultRet);
@@ -1853,7 +1852,7 @@ public:
typedef void (*Func)(float, float, float, float, float, float, float, float*);
Func func = ptr_as_func<Func>(_func);
float resultRet;
float resultRet = 0;
float expectRet = 1.0f + 2.0f + 3.0f + 4.0f + 5.0f + 6.0f + 7.0f;
func(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, &resultRet);
@@ -1904,7 +1903,7 @@ public:
typedef void (*Func)(double, double, double, double, double, double, double, double*);
Func func = ptr_as_func<Func>(_func);
double resultRet;
double resultRet = 0;
double expectRet = 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0;
func(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, &resultRet);
@@ -1954,7 +1953,7 @@ public:
uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
uint8_t rData[16];
uint8_t rData[16] {};
uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
__m128i aVec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(aData));
@@ -2714,7 +2713,7 @@ public:
uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
uint8_t rData[16];
uint8_t rData[16] {};
uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
func(rData, aData, bData);
@@ -2823,7 +2822,7 @@ public:
int16_t c[8] = { 1, 3, 9, 7, 5, 4, 2, 1 };
int16_t d[8] = { 2, 0,-6,-4,-2,-1, 1, 2 };
int16_t o[8];
int16_t o[8] {};
int oExp = 7 * 3;
func(a, b, c, d, o);
@@ -4066,8 +4065,8 @@ public:
static const uint32_t aData[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
static const uint32_t bData[8] = { 6, 3, 5, 9, 1, 8, 7, 2 };
uint32_t resultData[8];
uint32_t expectData[8];
uint32_t resultData[8] {};
uint32_t expectData[8] {};
for (i = 0; i < 8; i++)
expectData[i] = aData[i] * 8 + bData[i] + 1;

View File

@@ -98,10 +98,6 @@ static uint32_t testFunc(JitRuntime& rt, EmitterType emitterType) noexcept {
Error err = kErrorOk;
switch (emitterType) {
case EmitterType::kNone: {
break;
}
case EmitterType::kAssembler: {
printf("Using x86::Assembler:\n");
x86::Assembler a(&code);
@@ -138,6 +134,11 @@ static uint32_t testFunc(JitRuntime& rt, EmitterType emitterType) noexcept {
break;
}
#endif
default: {
printf("** FAILURE: No emitter to use **\n");
return 1;
}
}
// Add the code generated to the runtime.
@@ -150,9 +151,9 @@ static uint32_t testFunc(JitRuntime& rt, EmitterType emitterType) noexcept {
}
// Execute the generated function.
int inA[4] = { 4, 3, 2, 1 };
int inB[4] = { 1, 5, 2, 8 };
int out[4];
static const int inA[4] = { 4, 3, 2, 1 };
static const int inB[4] = { 1, 5, 2, 8 };
int out[4] {};
fn(out, inA, inB);
// Should print {5 8 4 9}.

View File

@@ -13,6 +13,9 @@
using namespace asmjit;
namespace {
#if !defined(ASMJIT_NO_X86)
static char accessLetter(bool r, bool w) noexcept {
return r && w ? 'X' : r ? 'R' : w ? 'W' : '_';
}
@@ -140,6 +143,7 @@ static void printInfoExtra(Arch arch, InstId instId, InstOptions options, const
Operand_ opArray[] = { std::forward<Args>(args)... };
printInfo(arch, inst, opArray, sizeof...(args));
}
#endif // !ASMJIT_NO_X86
static void testX86Arch() {
#if !defined(ASMJIT_NO_X86)
@@ -165,9 +169,11 @@ static void testX86Arch() {
printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kNone, k1, zmm0, zmm1, zmm2);
printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kX86_ZMask, k1, zmm0, zmm1, zmm2);
#endif
#endif // !ASMJIT_NO_X86
}
} // {anonymous}
int main() {
printf("AsmJit Instruction Info Test-Suite v%u.%u.%u\n",
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),

View File

@@ -109,7 +109,8 @@ static void dumpSizeOf(void) noexcept {
DUMP_TYPE(BaseBuilder);
DUMP_TYPE(BaseNode);
DUMP_TYPE(InstNode);
DUMP_TYPE(InstExNode);
DUMP_TYPE(InstNodeWithOperands<InstNode::kBaseOpCapacity>);
DUMP_TYPE(InstNodeWithOperands<InstNode::kFullOpCapacity>);
DUMP_TYPE(AlignNode);
DUMP_TYPE(LabelNode);
DUMP_TYPE(EmbedDataNode);

View File

@@ -8,8 +8,10 @@
#include <asmjit/core.h>
namespace {
ASMJIT_MAYBE_UNUSED
static const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
switch (arch) {
case asmjit::Arch::kX86 : return "X86";
case asmjit::Arch::kX64 : return "X64";
@@ -37,7 +39,7 @@ static const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
}
ASMJIT_MAYBE_UNUSED
static void printIndented(const char* str, size_t indent) noexcept {
void printIndented(const char* str, size_t indent) noexcept {
const char* start = str;
while (*str) {
if (*str == '\n') {
@@ -53,4 +55,6 @@ static void printIndented(const char* str, size_t indent) noexcept {
printf("%*s%.*s\n", int(indent), "", int(size), start);
}
} // {anonymous}
#endif // ASMJITUTILS_H_INCLUDED

View File

@@ -11,3 +11,7 @@ echo ""
echo "== [Configuring Build - Release_UBSAN] =="
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release_UBSAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DASMJIT_SANITIZE=undefined
echo ""
echo "== [Configuring Build - Release_MSAN] =="
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release_MSAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DASMJIT_SANITIZE=memory
echo ""