mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-16 20:17:05 +03:00
[abi] Added support for 32-bit ARM (WIP)
This commit is contained in:
@@ -70,6 +70,7 @@ option(ASMJIT_NO_CUSTOM_FLAGS "Disable extra compilation flags added by AsmJit
|
|||||||
option(ASMJIT_NO_ABI_NAMESPACE "Disable the use of inline ABI namespace {asmjit::v...}" OFF)
|
option(ASMJIT_NO_ABI_NAMESPACE "Disable the use of inline ABI namespace {asmjit::v...}" OFF)
|
||||||
option(ASMJIT_NO_SHM_OPEN "Disable the use of shm_open() (some platforms have better options)" OFF)
|
option(ASMJIT_NO_SHM_OPEN "Disable the use of shm_open() (some platforms have better options)" OFF)
|
||||||
option(ASMJIT_NO_X86 "Disable X86/X64 backend" OFF)
|
option(ASMJIT_NO_X86 "Disable X86/X64 backend" OFF)
|
||||||
|
option(ASMJIT_NO_AARCH32 "Disable AArch32 backend" OFF)
|
||||||
option(ASMJIT_NO_AARCH64 "Disable AArch64 backend" OFF)
|
option(ASMJIT_NO_AARCH64 "Disable AArch64 backend" OFF)
|
||||||
option(ASMJIT_NO_FOREIGN "Disable all foreign backends (enables only a backend that matches the target)" OFF)
|
option(ASMJIT_NO_FOREIGN "Disable all foreign backends (enables only a backend that matches the target)" OFF)
|
||||||
option(ASMJIT_NO_JIT "Disable VirtMem, JitAllocator, and JitRuntime at build time" OFF)
|
option(ASMJIT_NO_JIT "Disable VirtMem, JitAllocator, and JitRuntime at build time" OFF)
|
||||||
@@ -219,12 +220,29 @@ set(ASMJIT_SRC
|
|||||||
asmjit/support/support.h
|
asmjit/support/support.h
|
||||||
asmjit/support/support_p.h
|
asmjit/support/support_p.h
|
||||||
|
|
||||||
|
asmjit/a32.h
|
||||||
asmjit/a64.h
|
asmjit/a64.h
|
||||||
asmjit/arm.h
|
asmjit/arm.h
|
||||||
asmjit/arm/armformatter.cpp
|
asmjit/arm/armformatter.cpp
|
||||||
asmjit/arm/armformatter_p.h
|
asmjit/arm/armformatter_p.h
|
||||||
asmjit/arm/armglobals.h
|
asmjit/arm/armglobals.h
|
||||||
asmjit/arm/armutils.h
|
asmjit/arm/armutils.h
|
||||||
|
asmjit/arm/a32archtraits_p.h
|
||||||
|
asmjit/arm/a32assembler.cpp
|
||||||
|
asmjit/arm/a32assembler.h
|
||||||
|
asmjit/arm/a32builder.cpp
|
||||||
|
asmjit/arm/a32builder.h
|
||||||
|
asmjit/arm/a32emithelper.cpp
|
||||||
|
asmjit/arm/a32emithelper_p.h
|
||||||
|
asmjit/arm/a32emitter.h
|
||||||
|
asmjit/arm/a32formatter.cpp
|
||||||
|
asmjit/arm/a32formatter_p.h
|
||||||
|
asmjit/arm/a32globals.h
|
||||||
|
asmjit/arm/a32instapi.cpp
|
||||||
|
asmjit/arm/a32instapi_p.h
|
||||||
|
asmjit/arm/a32instdb.cpp
|
||||||
|
asmjit/arm/a32instdb_p.h
|
||||||
|
asmjit/arm/a32operand.h
|
||||||
asmjit/arm/a64archtraits_p.h
|
asmjit/arm/a64archtraits_p.h
|
||||||
asmjit/arm/a64assembler.cpp
|
asmjit/arm/a64assembler.cpp
|
||||||
asmjit/arm/a64assembler.h
|
asmjit/arm/a64assembler.h
|
||||||
@@ -504,6 +522,7 @@ if (ASMJIT_NO_SHM_OPEN)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(build_option ASMJIT_NO_X86
|
foreach(build_option ASMJIT_NO_X86
|
||||||
|
ASMJIT_NO_AARCH32
|
||||||
ASMJIT_NO_AARCH64
|
ASMJIT_NO_AARCH64
|
||||||
ASMJIT_NO_FOREIGN
|
ASMJIT_NO_FOREIGN
|
||||||
ASMJIT_NO_ABI_NAMESPACE
|
ASMJIT_NO_ABI_NAMESPACE
|
||||||
@@ -613,6 +632,7 @@ else()
|
|||||||
asmjit_add_target(asmjit_test_assembler TEST
|
asmjit_add_target(asmjit_test_assembler TEST
|
||||||
SOURCES asmjit-testing/tests/asmjit_test_assembler.cpp
|
SOURCES asmjit-testing/tests/asmjit_test_assembler.cpp
|
||||||
asmjit-testing/tests/asmjit_test_assembler.h
|
asmjit-testing/tests/asmjit_test_assembler.h
|
||||||
|
asmjit-testing/tests/asmjit_test_assembler_a32.cpp
|
||||||
asmjit-testing/tests/asmjit_test_assembler_a64.cpp
|
asmjit-testing/tests/asmjit_test_assembler_a64.cpp
|
||||||
asmjit-testing/tests/asmjit_test_assembler_x64.cpp
|
asmjit-testing/tests/asmjit_test_assembler_x64.cpp
|
||||||
asmjit-testing/tests/asmjit_test_assembler_x86.cpp
|
asmjit-testing/tests/asmjit_test_assembler_x86.cpp
|
||||||
@@ -689,6 +709,7 @@ else()
|
|||||||
|
|
||||||
asmjit_add_target(asmjit_bench_codegen EXECUTABLE
|
asmjit_add_target(asmjit_bench_codegen EXECUTABLE
|
||||||
SOURCES asmjit-testing/bench/asmjit_bench_codegen.cpp
|
SOURCES asmjit-testing/bench/asmjit_bench_codegen.cpp
|
||||||
|
asmjit-testing/bench/asmjit_bench_codegen_a32.cpp
|
||||||
asmjit-testing/bench/asmjit_bench_codegen_a64.cpp
|
asmjit-testing/bench/asmjit_bench_codegen_a64.cpp
|
||||||
asmjit-testing/bench/asmjit_bench_codegen_x86.cpp
|
asmjit-testing/bench/asmjit_bench_codegen_x86.cpp
|
||||||
SOURCES asmjit-testing/bench/asmjit_bench_codegen.h
|
SOURCES asmjit-testing/bench/asmjit_bench_codegen.h
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ static void print_app_info() noexcept {
|
|||||||
void benchmark_x86_emitters(uint32_t num_iterations, bool test_x86, bool test_x64) noexcept;
|
void benchmark_x86_emitters(uint32_t num_iterations, bool test_x86, bool test_x64) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
void benchmark_aarch32_emitters(uint32_t num_iterations);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
void benchmark_aarch64_emitters(uint32_t num_iterations);
|
void benchmark_aarch64_emitters(uint32_t num_iterations);
|
||||||
#endif
|
#endif
|
||||||
@@ -49,6 +53,9 @@ int main(int argc, char* argv[]) {
|
|||||||
printf(" --arch=x86 32-bit X86 architecture (X86)\n");
|
printf(" --arch=x86 32-bit X86 architecture (X86)\n");
|
||||||
printf(" --arch=x64 64-bit X86 architecture (X86_64)\n");
|
printf(" --arch=x64 64-bit X86 architecture (X86_64)\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
printf(" --arch=aarch32 32-bit ARM architecture (AArch32)\n");
|
||||||
|
#endif
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
printf(" --arch=aarch64 64-bit ARM architecture (AArch64)\n");
|
printf(" --arch=aarch64 64-bit ARM architecture (AArch64)\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -71,6 +78,14 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
bool test_aarch32 = strcmp(arch, "all") == 0 || strcmp(arch, "aarch32") == 0;
|
||||||
|
|
||||||
|
if (test_aarch32) {
|
||||||
|
benchmark_aarch32_emitters(num_iterations);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
bool test_aarch64 = strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0;
|
bool test_aarch64 = strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0;
|
||||||
|
|
||||||
|
|||||||
23
asmjit-testing/bench/asmjit_bench_codegen_a32.cpp
Normal file
23
asmjit-testing/bench/asmjit_bench_codegen_a32.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See <asmjit/core.h> or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core.h>
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#include <asmjit/a32.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <asmjit-testing/bench/asmjit_bench_codegen.h>
|
||||||
|
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
void benchmark_aarch32_emitters(uint32_t num_iterations) {
|
||||||
|
Support::maybe_unused(num_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32
|
||||||
@@ -20,6 +20,10 @@ bool test_x86_assembler(const TestSettings& settings) noexcept;
|
|||||||
bool test_x64_assembler(const TestSettings& settings) noexcept;
|
bool test_x64_assembler(const TestSettings& settings) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
bool test_aarch32_assembler(const TestSettings& settings) noexcept;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
bool test_aarch64_assembler(const TestSettings& settings) noexcept;
|
bool test_aarch64_assembler(const TestSettings& settings) noexcept;
|
||||||
#endif
|
#endif
|
||||||
@@ -47,6 +51,9 @@ static void print_app_usage(const TestSettings& settings) noexcept {
|
|||||||
printf(" --arch=x86 32-bit X86 architecture (X86)\n");
|
printf(" --arch=x86 32-bit X86 architecture (X86)\n");
|
||||||
printf(" --arch=x64 64-bit X86 architecture (X86_64)\n");
|
printf(" --arch=x64 64-bit X86 architecture (X86_64)\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
printf(" --arch=aarch32 32-bit ARM architecture (AArch32)\n");
|
||||||
|
#endif
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
printf(" --arch=aarch64 64-bit ARM architecture (AArch64)\n");
|
printf(" --arch=aarch64 64-bit ARM architecture (AArch64)\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -68,34 +75,52 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* arch = cmd_line.value_of("--arch", "all");
|
const char* arch = cmd_line.value_of("--arch", "all");
|
||||||
|
|
||||||
bool x86_failed = false;
|
bool x86_failed = false;
|
||||||
bool x64_failed = false;
|
bool x64_failed = false;
|
||||||
|
bool aarch32_failed = false;
|
||||||
bool aarch64_failed = false;
|
bool aarch64_failed = false;
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_X86)
|
#if !defined(ASMJIT_NO_X86)
|
||||||
if ((strcmp(arch, "all") == 0 || strcmp(arch, "x86") == 0))
|
if ((strcmp(arch, "all") == 0 || strcmp(arch, "x86") == 0)) {
|
||||||
x86_failed = !test_x86_assembler(settings);
|
x86_failed = !test_x86_assembler(settings);
|
||||||
|
}
|
||||||
|
|
||||||
if ((strcmp(arch, "all") == 0 || strcmp(arch, "x64") == 0))
|
if ((strcmp(arch, "all") == 0 || strcmp(arch, "x64") == 0)) {
|
||||||
x64_failed = !test_x64_assembler(settings);
|
x64_failed = !test_x64_assembler(settings);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if ((strcmp(arch, "all") == 0 || strcmp(arch, "aarch32") == 0)) {
|
||||||
|
aarch32_failed = !test_aarch32_assembler(settings);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
if ((strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0))
|
if ((strcmp(arch, "all") == 0 || strcmp(arch, "aarch64") == 0)) {
|
||||||
aarch64_failed = !test_aarch64_assembler(settings);
|
aarch64_failed = !test_aarch64_assembler(settings);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool failed = x86_failed || x64_failed || aarch64_failed;
|
bool failed = x86_failed || x64_failed || aarch32_failed || aarch64_failed;
|
||||||
|
|
||||||
if (failed) {
|
if (failed) {
|
||||||
if (x86_failed)
|
if (x86_failed) {
|
||||||
printf("** X86 test suite failed **\n");
|
printf("** X86 test suite failed **\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (x64_failed)
|
if (x64_failed) {
|
||||||
printf("** X64 test suite failed **\n");
|
printf("** X64 test suite failed **\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (aarch64_failed)
|
if (aarch32_failed) {
|
||||||
|
printf("** AArch32 test suite failed **\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aarch64_failed) {
|
||||||
printf("** AArch64 test suite failed **\n");
|
printf("** AArch64 test suite failed **\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("** FAILURE **\n");
|
printf("** FAILURE **\n");
|
||||||
}
|
}
|
||||||
|
|||||||
2881
asmjit-testing/tests/asmjit_test_assembler_a32.cpp
Normal file
2881
asmjit-testing/tests/asmjit_test_assembler_a32.cpp
Normal file
File diff suppressed because it is too large
Load Diff
638
asmjit-testing/tests/asmjit_test_perf_a32.cpp
Normal file
638
asmjit-testing/tests/asmjit_test_perf_a32.cpp
Normal file
@@ -0,0 +1,638 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core.h>
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#include <asmjit/a32.h>
|
||||||
|
|
||||||
|
#include <asmjit-testing/commons/asmjit_test_perf.h.
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
// Generates a long sequence of GP instructions.
|
||||||
|
template<typename Emitter>
|
||||||
|
static void generateGpSequenceInternal(
|
||||||
|
Emitter& cc,
|
||||||
|
const a32::Gp& a, const a32::Gp& b, const a32::Gp& c, const a32::Gp& d) {
|
||||||
|
|
||||||
|
using namespace asmjit::a32;
|
||||||
|
|
||||||
|
cc.mov(a, 0);
|
||||||
|
cc.mov(b, 1);
|
||||||
|
cc.mov(c, 2);
|
||||||
|
cc.mov(d, 3);
|
||||||
|
|
||||||
|
cc.adc(a, b, c, lsl(d));
|
||||||
|
cc.adc(a, b, c, lsr(d));
|
||||||
|
cc.adc(a, b, c, asr(d));
|
||||||
|
cc.adc(a, b, c, ror(d));
|
||||||
|
cc.adc(a, b, c, lsl(8));
|
||||||
|
cc.adc(a, b, c, lsr(8));
|
||||||
|
cc.adc(a, b, c, asr(8));
|
||||||
|
cc.adc(a, b, c, ror(8));
|
||||||
|
cc.adc(a, b, 0xFF);
|
||||||
|
cc.adc(a, b, 0xFF00);
|
||||||
|
cc.adc(a, b, 0xFF000000);
|
||||||
|
cc.adc(a, b, 0xF000000F);
|
||||||
|
cc.adcs(a, b, c, lsl(d));
|
||||||
|
cc.adcs(a, b, c, lsr(d));
|
||||||
|
cc.adcs(a, b, c, asr(d));
|
||||||
|
cc.adcs(a, b, c, ror(d));
|
||||||
|
cc.adcs(a, b, c, lsl(8));
|
||||||
|
cc.adcs(a, b, c, lsr(8));
|
||||||
|
cc.adcs(a, b, c, asr(8));
|
||||||
|
cc.adcs(a, b, c, ror(8));
|
||||||
|
cc.adcs(a, b, 0xFF);
|
||||||
|
cc.adcs(a, b, 0xFF00);
|
||||||
|
cc.adcs(a, b, 0xFF000000);
|
||||||
|
cc.adcs(a, b, 0xF000000F);
|
||||||
|
cc.add(a, b, c, lsl(d));
|
||||||
|
cc.add(a, b, c, lsr(d));
|
||||||
|
cc.add(a, b, c, asr(d));
|
||||||
|
cc.add(a, b, c, ror(d));
|
||||||
|
cc.add(a, b, c, lsl(8));
|
||||||
|
cc.add(a, b, c, lsr(8));
|
||||||
|
cc.add(a, b, c, asr(8));
|
||||||
|
cc.add(a, b, c, ror(8));
|
||||||
|
cc.add(a, b, 0xFF);
|
||||||
|
cc.add(a, b, 0xFF00);
|
||||||
|
cc.add(a, b, 0xFF000000);
|
||||||
|
cc.add(a, b, 0xF000000F);
|
||||||
|
cc.adds(a, b, c, lsl(d));
|
||||||
|
cc.adds(a, b, c, lsr(d));
|
||||||
|
cc.adds(a, b, c, asr(d));
|
||||||
|
cc.adds(a, b, c, ror(d));
|
||||||
|
cc.adds(a, b, c, lsl(8));
|
||||||
|
cc.adds(a, b, c, lsr(8));
|
||||||
|
cc.adds(a, b, c, asr(8));
|
||||||
|
cc.adds(a, b, c, ror(8));
|
||||||
|
cc.adds(a, b, 0xFF);
|
||||||
|
cc.adds(a, b, 0xFF00);
|
||||||
|
cc.adds(a, b, 0xFF000000);
|
||||||
|
cc.adds(a, b, 0xF000000F);
|
||||||
|
cc.and_(a, b, c, lsl(d));
|
||||||
|
cc.and_(a, b, c, lsr(d));
|
||||||
|
cc.and_(a, b, c, asr(d));
|
||||||
|
cc.and_(a, b, c, ror(d));
|
||||||
|
cc.and_(a, b, c, lsl(8));
|
||||||
|
cc.and_(a, b, c, lsr(8));
|
||||||
|
cc.and_(a, b, c, asr(8));
|
||||||
|
cc.and_(a, b, c, ror(8));
|
||||||
|
cc.and_(a, b, 0xFF);
|
||||||
|
cc.and_(a, b, 0xFF00);
|
||||||
|
cc.and_(a, b, 0xFF000000);
|
||||||
|
cc.and_(a, b, 0xF000000F);
|
||||||
|
cc.ands(a, b, c, lsl(d));
|
||||||
|
cc.ands(a, b, c, lsr(d));
|
||||||
|
cc.ands(a, b, c, asr(d));
|
||||||
|
cc.ands(a, b, c, ror(d));
|
||||||
|
cc.ands(a, b, c, lsl(8));
|
||||||
|
cc.ands(a, b, c, lsr(8));
|
||||||
|
cc.ands(a, b, c, asr(8));
|
||||||
|
cc.ands(a, b, c, ror(8));
|
||||||
|
cc.ands(a, b, 0xFF);
|
||||||
|
cc.ands(a, b, 0xFF00);
|
||||||
|
cc.ands(a, b, 0xFF000000);
|
||||||
|
cc.ands(a, b, 0xF000000F);
|
||||||
|
cc.asr(a, b, c);
|
||||||
|
cc.asr(a, b, 3);
|
||||||
|
cc.asrs(a, b, c);
|
||||||
|
cc.asrs(a, b, 3);
|
||||||
|
cc.bfc(a, 3, 5);
|
||||||
|
cc.bfi(a, b, 3, 5);
|
||||||
|
cc.bic(a, b, c, lsl(d));
|
||||||
|
cc.bic(a, b, c, lsr(d));
|
||||||
|
cc.bic(a, b, c, asr(d));
|
||||||
|
cc.bic(a, b, c, ror(d));
|
||||||
|
cc.bic(a, b, c, lsl(8));
|
||||||
|
cc.bic(a, b, c, lsr(8));
|
||||||
|
cc.bic(a, b, c, asr(8));
|
||||||
|
cc.bic(a, b, c, ror(8));
|
||||||
|
cc.bic(a, b, 0xFF);
|
||||||
|
cc.bic(a, b, 0xFF00);
|
||||||
|
cc.bic(a, b, 0xFF000000);
|
||||||
|
cc.bic(a, b, 0xF000000F);
|
||||||
|
cc.bics(a, b, c, lsl(d));
|
||||||
|
cc.bics(a, b, c, lsr(d));
|
||||||
|
cc.bics(a, b, c, asr(d));
|
||||||
|
cc.bics(a, b, c, ror(d));
|
||||||
|
cc.bics(a, b, c, lsl(8));
|
||||||
|
cc.bics(a, b, c, lsr(8));
|
||||||
|
cc.bics(a, b, c, asr(8));
|
||||||
|
cc.bics(a, b, c, ror(8));
|
||||||
|
cc.bics(a, b, 0xFF);
|
||||||
|
cc.bics(a, b, 0xFF00);
|
||||||
|
cc.bics(a, b, 0xFF000000);
|
||||||
|
cc.bics(a, b, 0xF000000F);
|
||||||
|
cc.clz(a, b);
|
||||||
|
cc.cmn(a, b, lsl(c));
|
||||||
|
cc.cmn(a, b, lsr(c));
|
||||||
|
cc.cmn(a, b, asr(c));
|
||||||
|
cc.cmn(a, b, ror(c));
|
||||||
|
cc.cmn(a, b, lsl(8));
|
||||||
|
cc.cmn(a, b, lsr(8));
|
||||||
|
cc.cmn(a, b, asr(8));
|
||||||
|
cc.cmn(a, b, ror(8));
|
||||||
|
cc.cmn(a, 0xFF);
|
||||||
|
cc.cmn(a, 0xFF00);
|
||||||
|
cc.cmn(a, 0xFF000000);
|
||||||
|
cc.cmn(a, 0xF000000F);
|
||||||
|
cc.cmp(a, b, lsl(c));
|
||||||
|
cc.cmp(a, b, lsr(c));
|
||||||
|
cc.cmp(a, b, asr(c));
|
||||||
|
cc.cmp(a, b, ror(c));
|
||||||
|
cc.cmp(a, b, lsl(8));
|
||||||
|
cc.cmp(a, b, lsr(8));
|
||||||
|
cc.cmp(a, b, asr(8));
|
||||||
|
cc.cmp(a, b, ror(8));
|
||||||
|
cc.cmp(a, 0xFF);
|
||||||
|
cc.cmp(a, 0xFF00);
|
||||||
|
cc.cmp(a, 0xFF000000);
|
||||||
|
cc.cmp(a, 0xF000000F);
|
||||||
|
cc.crc32b(a, b, c);
|
||||||
|
cc.crc32cb(a, b, c);
|
||||||
|
cc.crc32ch(a, b, c);
|
||||||
|
cc.crc32cw(a, b, c);
|
||||||
|
cc.crc32h(a, b, c);
|
||||||
|
cc.crc32w(a, b, c);
|
||||||
|
cc.eor(a, b, c, lsl(d));
|
||||||
|
cc.eor(a, b, c, lsr(d));
|
||||||
|
cc.eor(a, b, c, asr(d));
|
||||||
|
cc.eor(a, b, c, ror(d));
|
||||||
|
cc.eor(a, b, c, lsl(8));
|
||||||
|
cc.eor(a, b, c, lsr(8));
|
||||||
|
cc.eor(a, b, c, asr(8));
|
||||||
|
cc.eor(a, b, c, ror(8));
|
||||||
|
cc.eor(a, b, 0xFF);
|
||||||
|
cc.eor(a, b, 0xFF00);
|
||||||
|
cc.eor(a, b, 0xFF000000);
|
||||||
|
cc.eor(a, b, 0xF000000F);
|
||||||
|
cc.eors(a, b, c, lsl(d));
|
||||||
|
cc.eors(a, b, c, lsr(d));
|
||||||
|
cc.eors(a, b, c, asr(d));
|
||||||
|
cc.eors(a, b, c, ror(d));
|
||||||
|
cc.eors(a, b, c, lsl(8));
|
||||||
|
cc.eors(a, b, c, lsr(8));
|
||||||
|
cc.eors(a, b, c, asr(8));
|
||||||
|
cc.eors(a, b, c, ror(8));
|
||||||
|
cc.eors(a, b, 0xFF);
|
||||||
|
cc.eors(a, b, 0xFF00);
|
||||||
|
cc.eors(a, b, 0xFF000000);
|
||||||
|
cc.eors(a, b, 0xF000000F);
|
||||||
|
cc.ldr(a, ptr(b, c));
|
||||||
|
cc.ldr(a, ptr_pre(b, c));
|
||||||
|
cc.ldr(a, ptr_post(b, c));
|
||||||
|
cc.ldr(a, ptr(b, 4));
|
||||||
|
cc.ldr(a, ptr_pre(b, 4));
|
||||||
|
cc.ldr(a, ptr_post(b, 4));
|
||||||
|
cc.ldrb(a, ptr(b, c));
|
||||||
|
cc.ldrb(a, ptr_pre(b, c));
|
||||||
|
cc.ldrb(a, ptr_post(b, c));
|
||||||
|
cc.ldrb(a, ptr(b, 4));
|
||||||
|
cc.ldrb(a, ptr_pre(b, 4));
|
||||||
|
cc.ldrb(a, ptr_post(b, 4));
|
||||||
|
cc.ldrbt(a, ptr_post(b, c));
|
||||||
|
cc.ldrbt(a, ptr_post(b, 4));
|
||||||
|
cc.ldrh(a, ptr(b, c));
|
||||||
|
cc.ldrh(a, ptr_pre(b, c));
|
||||||
|
cc.ldrh(a, ptr_post(b, c));
|
||||||
|
cc.ldrh(a, ptr(b, 4));
|
||||||
|
cc.ldrh(a, ptr_pre(b, 4));
|
||||||
|
cc.ldrh(a, ptr_post(b, 4));
|
||||||
|
cc.ldrht(a, ptr_post(b, c));
|
||||||
|
cc.ldrht(a, ptr_post(b, 4));
|
||||||
|
cc.ldrsb(a, ptr(b, c));
|
||||||
|
cc.ldrsb(a, ptr_pre(b, c));
|
||||||
|
cc.ldrsb(a, ptr_post(b, c));
|
||||||
|
cc.ldrsb(a, ptr(b, 4));
|
||||||
|
cc.ldrsb(a, ptr_pre(b, 4));
|
||||||
|
cc.ldrsb(a, ptr_post(b, 4));
|
||||||
|
cc.ldrsbt(a, ptr_post(b, c));
|
||||||
|
cc.ldrsbt(a, ptr_post(b, 4));
|
||||||
|
cc.ldrsh(a, ptr(b, c));
|
||||||
|
cc.ldrsh(a, ptr_pre(b, c));
|
||||||
|
cc.ldrsh(a, ptr_post(b, c));
|
||||||
|
cc.ldrsh(a, ptr(b, 4));
|
||||||
|
cc.ldrsh(a, ptr_pre(b, 4));
|
||||||
|
cc.ldrsh(a, ptr_post(b, 4));
|
||||||
|
cc.ldrsht(a, ptr_post(b, 4));
|
||||||
|
cc.ldrsht(a, ptr_post(b, c));
|
||||||
|
cc.ldrt(a, ptr_post(b, c));
|
||||||
|
cc.ldrt(a, ptr_post(b, 4));
|
||||||
|
cc.lsl(a, b, 3);
|
||||||
|
cc.lsl(a, b, c);
|
||||||
|
cc.lsls(a, b, 3);
|
||||||
|
cc.lsls(a, b, c);
|
||||||
|
cc.lsr(a, b, 3);
|
||||||
|
cc.lsr(a, b, c);
|
||||||
|
cc.lsrs(a, b, 3);
|
||||||
|
cc.lsrs(a, b, c);
|
||||||
|
cc.mla(a, b, c, d);
|
||||||
|
cc.mlas(a, b, c, d);
|
||||||
|
cc.mls(a, b, c, d);
|
||||||
|
cc.mov(a, b, lsl(c));
|
||||||
|
cc.mov(a, b, lsr(c));
|
||||||
|
cc.mov(a, b, asr(c));
|
||||||
|
cc.mov(a, b, ror(c));
|
||||||
|
cc.mov(a, b, lsl(8));
|
||||||
|
cc.mov(a, b, lsr(8));
|
||||||
|
cc.mov(a, b, asr(8));
|
||||||
|
cc.mov(a, b, ror(8));
|
||||||
|
cc.mov(a, 0xFF);
|
||||||
|
cc.mov(a, 0xFF00);
|
||||||
|
cc.mov(a, 0xFF000000);
|
||||||
|
cc.mov(a, 0xF000000F);
|
||||||
|
cc.movs(a, b, lsl(c));
|
||||||
|
cc.movs(a, b, lsr(c));
|
||||||
|
cc.movs(a, b, asr(c));
|
||||||
|
cc.movs(a, b, ror(c));
|
||||||
|
cc.movs(a, b, lsl(8));
|
||||||
|
cc.movs(a, b, lsr(8));
|
||||||
|
cc.movs(a, b, asr(8));
|
||||||
|
cc.movs(a, b, ror(8));
|
||||||
|
cc.movs(a, 0xFF);
|
||||||
|
cc.movs(a, 0xFF00);
|
||||||
|
cc.movs(a, 0xFF000000);
|
||||||
|
cc.movs(a, 0xF000000F);
|
||||||
|
cc.movt(a, 1);
|
||||||
|
cc.movw(a, 1);
|
||||||
|
cc.mul(a, b, c);
|
||||||
|
cc.muls(a, b, c);
|
||||||
|
cc.mvn(a, b, lsl(c));
|
||||||
|
cc.mvn(a, b, lsr(c));
|
||||||
|
cc.mvn(a, b, asr(c));
|
||||||
|
cc.mvn(a, b, ror(c));
|
||||||
|
cc.mvn(a, b, lsl(8));
|
||||||
|
cc.mvn(a, b, lsr(8));
|
||||||
|
cc.mvn(a, b, asr(8));
|
||||||
|
cc.mvn(a, b, ror(8));
|
||||||
|
cc.mvn(a, 0xFF);
|
||||||
|
cc.mvn(a, 0xFF00);
|
||||||
|
cc.mvn(a, 0xFF000000);
|
||||||
|
cc.mvn(a, 0xF000000F);
|
||||||
|
cc.mvns(a, b, lsl(c));
|
||||||
|
cc.mvns(a, b, lsr(c));
|
||||||
|
cc.mvns(a, b, asr(c));
|
||||||
|
cc.mvns(a, b, ror(c));
|
||||||
|
cc.mvns(a, b, lsl(8));
|
||||||
|
cc.mvns(a, b, lsr(8));
|
||||||
|
cc.mvns(a, b, asr(8));
|
||||||
|
cc.mvns(a, b, ror(8));
|
||||||
|
cc.mvns(a, 0xFF);
|
||||||
|
cc.mvns(a, 0xFF00);
|
||||||
|
cc.mvns(a, 0xFF000000);
|
||||||
|
cc.mvns(a, 0xF000000F);
|
||||||
|
cc.orr(a, b, c, lsl(d));
|
||||||
|
cc.orr(a, b, c, lsr(d));
|
||||||
|
cc.orr(a, b, c, asr(d));
|
||||||
|
cc.orr(a, b, c, ror(d));
|
||||||
|
cc.orr(a, b, c, lsl(8));
|
||||||
|
cc.orr(a, b, c, lsr(8));
|
||||||
|
cc.orr(a, b, c, asr(8));
|
||||||
|
cc.orr(a, b, c, ror(8));
|
||||||
|
cc.orr(a, b, 0xFF);
|
||||||
|
cc.orr(a, b, 0xFF00);
|
||||||
|
cc.orr(a, b, 0xFF000000);
|
||||||
|
cc.orr(a, b, 0xF000000F);
|
||||||
|
cc.orrs(a, b, c, lsl(d));
|
||||||
|
cc.orrs(a, b, c, lsr(d));
|
||||||
|
cc.orrs(a, b, c, asr(d));
|
||||||
|
cc.orrs(a, b, c, ror(d));
|
||||||
|
cc.orrs(a, b, c, lsl(8));
|
||||||
|
cc.orrs(a, b, c, lsr(8));
|
||||||
|
cc.orrs(a, b, c, asr(8));
|
||||||
|
cc.orrs(a, b, c, ror(8));
|
||||||
|
cc.orrs(a, b, 0xFF);
|
||||||
|
cc.orrs(a, b, 0xFF00);
|
||||||
|
cc.orrs(a, b, 0xFF000000);
|
||||||
|
cc.orrs(a, b, 0xF000000F);
|
||||||
|
cc.pkhbt(a, b, c, lsl(8));
|
||||||
|
cc.pkhtb(a, b, c, asr(8));
|
||||||
|
cc.qadd(a, b, c);
|
||||||
|
cc.qadd16(a, b, c);
|
||||||
|
cc.qadd8(a, b, c);
|
||||||
|
cc.qasx(a, b, c);
|
||||||
|
cc.qdadd(a, b, c);
|
||||||
|
cc.qdsub(a, b, c);
|
||||||
|
cc.qsax(a, b, c);
|
||||||
|
cc.qsub(a, b, c);
|
||||||
|
cc.qsub16(a, b, c);
|
||||||
|
cc.qsub8(a, b, c);
|
||||||
|
cc.rbit(a, b);
|
||||||
|
cc.rev(a, b);
|
||||||
|
cc.rev16(a, b);
|
||||||
|
cc.revsh(a, b);
|
||||||
|
cc.ror(a, b, 3);
|
||||||
|
cc.ror(a, b, c);
|
||||||
|
cc.rors(a, b, 3);
|
||||||
|
cc.rors(a, b, c);
|
||||||
|
cc.rrx(a, b);
|
||||||
|
cc.rrxs(a, b);
|
||||||
|
cc.rsb(a, b, c, lsl(d));
|
||||||
|
cc.rsb(a, b, c, lsr(d));
|
||||||
|
cc.rsb(a, b, c, asr(d));
|
||||||
|
cc.rsb(a, b, c, ror(d));
|
||||||
|
cc.rsb(a, b, c, lsl(8));
|
||||||
|
cc.rsb(a, b, c, lsr(8));
|
||||||
|
cc.rsb(a, b, c, asr(8));
|
||||||
|
cc.rsb(a, b, c, ror(8));
|
||||||
|
cc.rsb(a, b, 0xFF);
|
||||||
|
cc.rsb(a, b, 0xFF00);
|
||||||
|
cc.rsb(a, b, 0xFF000000);
|
||||||
|
cc.rsb(a, b, 0xF000000F);
|
||||||
|
cc.rsbs(a, b, c, lsl(d));
|
||||||
|
cc.rsbs(a, b, c, lsr(d));
|
||||||
|
cc.rsbs(a, b, c, asr(d));
|
||||||
|
cc.rsbs(a, b, c, ror(d));
|
||||||
|
cc.rsbs(a, b, c, lsl(8));
|
||||||
|
cc.rsbs(a, b, c, lsr(8));
|
||||||
|
cc.rsbs(a, b, c, asr(8));
|
||||||
|
cc.rsbs(a, b, c, ror(8));
|
||||||
|
cc.rsbs(a, b, 0xFF);
|
||||||
|
cc.rsbs(a, b, 0xFF00);
|
||||||
|
cc.rsbs(a, b, 0xFF000000);
|
||||||
|
cc.rsbs(a, b, 0xF000000F);
|
||||||
|
cc.rsc(a, b, c, lsl(d));
|
||||||
|
cc.rsc(a, b, c, lsr(d));
|
||||||
|
cc.rsc(a, b, c, asr(d));
|
||||||
|
cc.rsc(a, b, c, ror(d));
|
||||||
|
cc.rsc(a, b, c, lsl(8));
|
||||||
|
cc.rsc(a, b, c, lsr(8));
|
||||||
|
cc.rsc(a, b, c, asr(8));
|
||||||
|
cc.rsc(a, b, c, ror(8));
|
||||||
|
cc.rsc(a, b, 0xFF);
|
||||||
|
cc.rsc(a, b, 0xFF00);
|
||||||
|
cc.rsc(a, b, 0xFF000000);
|
||||||
|
cc.rsc(a, b, 0xF000000F);
|
||||||
|
cc.rscs(a, b, c, lsl(d));
|
||||||
|
cc.rscs(a, b, c, lsr(d));
|
||||||
|
cc.rscs(a, b, c, asr(d));
|
||||||
|
cc.rscs(a, b, c, ror(d));
|
||||||
|
cc.rscs(a, b, c, lsl(8));
|
||||||
|
cc.rscs(a, b, c, lsr(8));
|
||||||
|
cc.rscs(a, b, c, asr(8));
|
||||||
|
cc.rscs(a, b, c, ror(8));
|
||||||
|
cc.rscs(a, b, 0xFF);
|
||||||
|
cc.rscs(a, b, 0xFF00);
|
||||||
|
cc.rscs(a, b, 0xFF000000);
|
||||||
|
cc.rscs(a, b, 0xF000000F);
|
||||||
|
cc.sadd16(a, b, c);
|
||||||
|
cc.sadd8(a, b, c);
|
||||||
|
cc.sasx(a, b, c);
|
||||||
|
cc.sbc(a, b, c, lsl(d));
|
||||||
|
cc.sbc(a, b, c, lsr(d));
|
||||||
|
cc.sbc(a, b, c, asr(d));
|
||||||
|
cc.sbc(a, b, c, ror(d));
|
||||||
|
cc.sbc(a, b, c, lsl(8));
|
||||||
|
cc.sbc(a, b, c, lsr(8));
|
||||||
|
cc.sbc(a, b, c, asr(8));
|
||||||
|
cc.sbc(a, b, c, ror(8));
|
||||||
|
cc.sbc(a, b, 0xFF);
|
||||||
|
cc.sbc(a, b, 0xFF00);
|
||||||
|
cc.sbc(a, b, 0xFF000000);
|
||||||
|
cc.sbc(a, b, 0xF000000F);
|
||||||
|
cc.sbcs(a, b, c, lsl(d));
|
||||||
|
cc.sbcs(a, b, c, lsr(d));
|
||||||
|
cc.sbcs(a, b, c, asr(d));
|
||||||
|
cc.sbcs(a, b, c, ror(d));
|
||||||
|
cc.sbcs(a, b, c, lsl(8));
|
||||||
|
cc.sbcs(a, b, c, lsr(8));
|
||||||
|
cc.sbcs(a, b, c, asr(8));
|
||||||
|
cc.sbcs(a, b, c, ror(8));
|
||||||
|
cc.sbcs(a, b, 0xFF);
|
||||||
|
cc.sbcs(a, b, 0xFF00);
|
||||||
|
cc.sbcs(a, b, 0xFF000000);
|
||||||
|
cc.sbcs(a, b, 0xF000000F);
|
||||||
|
cc.sbfx(a, b, 3, 5);
|
||||||
|
cc.sdiv(a, b, c);
|
||||||
|
cc.sel(a, b, c);
|
||||||
|
cc.shadd16(a, b, c);
|
||||||
|
cc.shadd8(a, b, c);
|
||||||
|
cc.shasx(a, b, c);
|
||||||
|
cc.shsax(a, b, c);
|
||||||
|
cc.shsub16(a, b, c);
|
||||||
|
cc.shsub8(a, b, c);
|
||||||
|
cc.smlabb(a, b, c, d);
|
||||||
|
cc.smlabt(a, b, c, d);
|
||||||
|
cc.smlad(a, b, c, d);
|
||||||
|
cc.smladx(a, b, c, d);
|
||||||
|
cc.smlal(a, b, c, d);
|
||||||
|
cc.smlalbb(a, b, c, d);
|
||||||
|
cc.smlalbt(a, b, c, d);
|
||||||
|
cc.smlald(a, b, c, d);
|
||||||
|
cc.smlaldx(a, b, c, d);
|
||||||
|
cc.smlals(a, b, c, d);
|
||||||
|
cc.smlaltb(a, b, c, d);
|
||||||
|
cc.smlaltt(a, b, c, d);
|
||||||
|
cc.smlatb(a, b, c, d);
|
||||||
|
cc.smlatt(a, b, c, d);
|
||||||
|
cc.smlawb(a, b, c, d);
|
||||||
|
cc.smlawt(a, b, c, d);
|
||||||
|
cc.smlsd(a, b, c, d);
|
||||||
|
cc.smlsdx(a, b, c, d);
|
||||||
|
cc.smlsld(a, b, c, d);
|
||||||
|
cc.smlsldx(a, b, c, d);
|
||||||
|
cc.smmla(a, b, c, d);
|
||||||
|
cc.smmlar(a, b, c, d);
|
||||||
|
cc.smmls(a, b, c, d);
|
||||||
|
cc.smmlsr(a, b, c, d);
|
||||||
|
cc.smmul(a, b, c);
|
||||||
|
cc.smmulr(a, b, c);
|
||||||
|
cc.smuad(a, b, c);
|
||||||
|
cc.smuadx(a, b, c);
|
||||||
|
cc.smulbb(a, b, c);
|
||||||
|
cc.smulbt(a, b, c);
|
||||||
|
cc.smull(a, b, c, d);
|
||||||
|
cc.smulls(a, b, c, d);
|
||||||
|
cc.smultb(a, b, c);
|
||||||
|
cc.smultt(a, b, c);
|
||||||
|
cc.smulwb(a, b, c);
|
||||||
|
cc.smulwt(a, b, c);
|
||||||
|
cc.smusd(a, b, c);
|
||||||
|
cc.smusdx(a, b, c);
|
||||||
|
cc.ssat(a, 8, c);
|
||||||
|
cc.ssat(a, 8, c, lsl(8));
|
||||||
|
cc.ssat(a, 8, c, asr(8));
|
||||||
|
cc.ssat16(a, 8, c);
|
||||||
|
cc.ssax(a, b, c);
|
||||||
|
cc.ssub16(a, b, c);
|
||||||
|
cc.ssub8(a, b, c);
|
||||||
|
cc.str(a, ptr(b, c));
|
||||||
|
cc.str(a, ptr_pre(b, c));
|
||||||
|
cc.str(a, ptr_post(b, c));
|
||||||
|
cc.str(a, ptr(b, 4));
|
||||||
|
cc.str(a, ptr_pre(b, 4));
|
||||||
|
cc.str(a, ptr_post(b, 4));
|
||||||
|
cc.strb(a, ptr(b, c));
|
||||||
|
cc.strb(a, ptr_pre(b, c));
|
||||||
|
cc.strb(a, ptr_post(b, c));
|
||||||
|
cc.strb(a, ptr(b, 4));
|
||||||
|
cc.strb(a, ptr_pre(b, 4));
|
||||||
|
cc.strb(a, ptr_post(b, 4));
|
||||||
|
cc.strbt(a, ptr_post(b, c));
|
||||||
|
cc.strbt(a, ptr_post(b, 4));
|
||||||
|
cc.strh(a, ptr(b, c));
|
||||||
|
cc.strh(a, ptr_pre(b, c));
|
||||||
|
cc.strh(a, ptr_post(b, c));
|
||||||
|
cc.strh(a, ptr(b, 4));
|
||||||
|
cc.strh(a, ptr_pre(b, 4));
|
||||||
|
cc.strh(a, ptr_post(b, 4));
|
||||||
|
cc.strht(a, ptr_post(b, c));
|
||||||
|
cc.strht(a, ptr_post(b, 4));
|
||||||
|
cc.strt(a, ptr_post(b, c));
|
||||||
|
cc.strt(a, ptr_post(b, 4));
|
||||||
|
cc.sub(a, b, c, lsl(d));
|
||||||
|
cc.sub(a, b, c, lsr(d));
|
||||||
|
cc.sub(a, b, c, asr(d));
|
||||||
|
cc.sub(a, b, c, ror(d));
|
||||||
|
cc.sub(a, b, c, lsl(8));
|
||||||
|
cc.sub(a, b, c, lsr(8));
|
||||||
|
cc.sub(a, b, c, asr(8));
|
||||||
|
cc.sub(a, b, c, ror(8));
|
||||||
|
cc.sub(a, b, 0xFF);
|
||||||
|
cc.sub(a, b, 0xFF00);
|
||||||
|
cc.sub(a, b, 0xFF000000);
|
||||||
|
cc.sub(a, b, 0xF000000F);
|
||||||
|
cc.subs(a, b, c, lsl(d));
|
||||||
|
cc.subs(a, b, c, lsr(d));
|
||||||
|
cc.subs(a, b, c, asr(d));
|
||||||
|
cc.subs(a, b, c, ror(d));
|
||||||
|
cc.subs(a, b, c, lsl(8));
|
||||||
|
cc.subs(a, b, c, lsr(8));
|
||||||
|
cc.subs(a, b, c, asr(8));
|
||||||
|
cc.subs(a, b, c, ror(8));
|
||||||
|
cc.subs(a, b, 0xFF);
|
||||||
|
cc.subs(a, b, 0xFF00);
|
||||||
|
cc.subs(a, b, 0xFF000000);
|
||||||
|
cc.subs(a, b, 0xF000000F);
|
||||||
|
cc.sxtab(a, b, c, ror(8));
|
||||||
|
cc.sxtab16(a, b, c, ror(8));
|
||||||
|
cc.sxtah(a, b, c, ror(8));
|
||||||
|
cc.sxtb(a, b, ror(8));
|
||||||
|
cc.sxtb16(a, b, ror(8));
|
||||||
|
cc.sxth(a, b, ror(8));
|
||||||
|
cc.teq(a, b, lsl(c));
|
||||||
|
cc.teq(a, b, lsr(c));
|
||||||
|
cc.teq(a, b, asr(c));
|
||||||
|
cc.teq(a, b, ror(c));
|
||||||
|
cc.teq(a, b, lsl(8));
|
||||||
|
cc.teq(a, b, lsr(8));
|
||||||
|
cc.teq(a, b, asr(8));
|
||||||
|
cc.teq(a, b, ror(8));
|
||||||
|
cc.teq(a, 0xFF);
|
||||||
|
cc.teq(a, 0xFF00);
|
||||||
|
cc.teq(a, 0xFF000000);
|
||||||
|
cc.teq(a, 0xF000000F);
|
||||||
|
cc.tst(a, b, lsl(c));
|
||||||
|
cc.tst(a, b, lsr(c));
|
||||||
|
cc.tst(a, b, asr(c));
|
||||||
|
cc.tst(a, b, ror(c));
|
||||||
|
cc.tst(a, b, lsl(8));
|
||||||
|
cc.tst(a, b, lsr(8));
|
||||||
|
cc.tst(a, b, asr(8));
|
||||||
|
cc.tst(a, b, ror(8));
|
||||||
|
cc.tst(a, 0xFF);
|
||||||
|
cc.tst(a, 0xFF00);
|
||||||
|
cc.tst(a, 0xFF000000);
|
||||||
|
cc.tst(a, 0xF000000F);
|
||||||
|
cc.uadd16(a, b, c);
|
||||||
|
cc.uadd8(a, b, c);
|
||||||
|
cc.uasx(a, b, c);
|
||||||
|
cc.ubfx(a, b, 3, 5);
|
||||||
|
cc.udiv(a, b, c);
|
||||||
|
cc.uhadd16(a, b, c);
|
||||||
|
cc.uhadd8(a, b, c);
|
||||||
|
cc.uhasx(a, b, c);
|
||||||
|
cc.uhsax(a, b, c);
|
||||||
|
cc.uhsub16(a, b, c);
|
||||||
|
cc.uhsub8(a, b, c);
|
||||||
|
cc.umaal(a, b, c, d);
|
||||||
|
cc.umlal(a, b, c, d);
|
||||||
|
cc.umlals(a, b, c, d);
|
||||||
|
cc.umull(a, b, c, d);
|
||||||
|
cc.umulls(a, b, c, d);
|
||||||
|
cc.uqadd16(a, b, c);
|
||||||
|
cc.uqadd8(a, b, c);
|
||||||
|
cc.uqasx(a, b, c);
|
||||||
|
cc.uqsax(a, b, c);
|
||||||
|
cc.uqsub16(a, b, c);
|
||||||
|
cc.uqsub8(a, b, c);
|
||||||
|
cc.usad8(a, b, c);
|
||||||
|
cc.usada8(a, b, c, d);
|
||||||
|
cc.usat(a, 8, c, lsl(8));
|
||||||
|
cc.usat(a, 8, c, asr(8));
|
||||||
|
cc.usat16(a, 8, c);
|
||||||
|
cc.usax(a, b, c);
|
||||||
|
cc.usub16(a, b, c);
|
||||||
|
cc.usub8(a, b, c);
|
||||||
|
cc.uxtab(a, b, c, ror(8));
|
||||||
|
cc.uxtab16(a, b, c, ror(8));
|
||||||
|
cc.uxtah(a, b, c, ror(8));
|
||||||
|
cc.uxtb(a, b, ror(8));
|
||||||
|
cc.uxtb16(a, b, ror(8));
|
||||||
|
cc.uxth(a, b, ror(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generateGpSequence(BaseEmitter& emitter, bool emitPrologEpilog) {
|
||||||
|
if (emitter.isAssembler()) {
|
||||||
|
a32::Assembler& cc = *emitter.as<a32::Assembler>();
|
||||||
|
|
||||||
|
a32::Gp a = a32::r0;
|
||||||
|
a32::Gp b = a32::r1;
|
||||||
|
a32::Gp c = a32::r2;
|
||||||
|
a32::Gp d = a32::r3;
|
||||||
|
|
||||||
|
if (emitPrologEpilog) {
|
||||||
|
FuncDetail func;
|
||||||
|
func.init(FuncSignature::build<void, void*, const void*, size_t>(), cc.environment());
|
||||||
|
|
||||||
|
FuncFrame frame;
|
||||||
|
frame.init(func);
|
||||||
|
frame.addDirtyRegs(a, b, c, d);
|
||||||
|
frame.finalize();
|
||||||
|
|
||||||
|
cc.emitProlog(frame);
|
||||||
|
generateGpSequenceInternal(cc, a, b, c, d);
|
||||||
|
cc.emitEpilog(frame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
generateGpSequenceInternal(cc, a, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename EmitterFn>
|
||||||
|
static void benchmarkA32Function(Arch arch, uint32_t numIterations, const char* description, const EmitterFn& emitterFn) noexcept {
|
||||||
|
CodeHolder code;
|
||||||
|
printf("%s:\n", description);
|
||||||
|
|
||||||
|
uint32_t instCount = 0;
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_BUILDER
|
||||||
|
instCount = asmjit_perf_utils::calculateInstructionCount<a32::Builder>(code, arch, [&](a32::Builder& emitter) {
|
||||||
|
emitterFn(emitter, false);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
asmjit_perf_utils::bench<a32::Assembler>(code, arch, numIterations, "[raw]", instCount, [&](a32::Assembler& emitter) {
|
||||||
|
emitterFn(emitter, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void benchmarkA32Emitters(uint32_t numIterations) {
|
||||||
|
static const char description[] = "GpSequence (Sequence of GP instructions)";
|
||||||
|
benchmarkA32Function(Arch::kARM, numIterations, description, [](BaseEmitter& emitter, bool emitPrologEpilog) {
|
||||||
|
generateGpSequence(emitter, emitPrologEpilog);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32
|
||||||
55
asmjit/a32.h
Normal file
55
asmjit/a32.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_A32_H_INCLUDED
|
||||||
|
#define ASMJIT_A32_H_INCLUDED
|
||||||
|
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//!
|
||||||
|
//! ### Emitters
|
||||||
|
//!
|
||||||
|
//! - \ref a32::Assembler - AArch32 assembler (must read, provides examples).
|
||||||
|
//! - \ref a32::Builder - AArch32 builder.
|
||||||
|
//! - \ref a32::Compiler - AArch32 compiler.
|
||||||
|
//! - \ref a32::Emitter - AArch32 emitter (abstract).
|
||||||
|
//!
|
||||||
|
//! ### Supported Instructions
|
||||||
|
//!
|
||||||
|
//! - Emitters:
|
||||||
|
//! - \ref a32::EmitterExplicitT - Provides all instructions that use explicit operands, provides also utility
|
||||||
|
//! functions. The member functions provided are part of all AArch32 emitters.
|
||||||
|
//!
|
||||||
|
//! - Instruction representation:
|
||||||
|
//! - \ref a32::Inst::Id - instruction identifiers.
|
||||||
|
//!
|
||||||
|
//! ### Register Operands
|
||||||
|
//!
|
||||||
|
//! - \ref arm::Reg - Base class of any AArch32/AArch64 register.
|
||||||
|
//! - \ref a32::Gp - 32-bit general purpose register (AArch32)
|
||||||
|
//! - \ref arm::Vec - Vector (SIMD) register:
|
||||||
|
//! - \ref arm::VecS - 32-bit SIMD register.
|
||||||
|
//! - \ref arm::VecD - 64-bit SIMD register.
|
||||||
|
//! - \ref arm::VecV - 128-bit SIMD register.
|
||||||
|
//!
|
||||||
|
//! ### Memory Operands
|
||||||
|
//!
|
||||||
|
//! - \ref arm::Mem - AArch32/AArch64 memory operand that provides support for all ARM addressing features
|
||||||
|
//! including base, index, pre/post increment, and ARM-specific shift addressing and index extending.
|
||||||
|
//!
|
||||||
|
//! ### Other
|
||||||
|
//!
|
||||||
|
//! - \ref arm::Shift - Shift operation and value.
|
||||||
|
//! - \ref arm::DataType - Data type that is part of an instruction in AArch32 mode.
|
||||||
|
//! - \ref a32::Utils - Utilities that can help during code generation for AArch32.
|
||||||
|
|
||||||
|
#include <asmjit/arm.h>
|
||||||
|
#include <asmjit/arm/a32assembler.h>
|
||||||
|
#include <asmjit/arm/a32builder.h>
|
||||||
|
#include <asmjit/arm/a32emitter.h>
|
||||||
|
#include <asmjit/arm/a32globals.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
#endif // ASMJIT_A32_H_INCLUDED
|
||||||
|
|
||||||
76
asmjit/arm/a32archtraits_p.h
Normal file
76
asmjit/arm/a32archtraits_p.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32ARCHTRAITS_P_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32ARCHTRAITS_P_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/archtraits.h>
|
||||||
|
#include <asmjit/core/misc_p.h>
|
||||||
|
#include <asmjit/core/type.h>
|
||||||
|
#include <asmjit/arm/a32globals.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \cond INTERNAL
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
static const constexpr ArchTraits a32_arch_traits = {
|
||||||
|
// SP/FP/LR/PC.
|
||||||
|
13, 11, 14, 15,
|
||||||
|
|
||||||
|
// Reserved.
|
||||||
|
{ 0u, 0u, 0u },
|
||||||
|
|
||||||
|
// HW stack alignment (AArch32 requires stack aligned to 4 bytes at HW level).
|
||||||
|
4,
|
||||||
|
|
||||||
|
// Min/max stack offset.
|
||||||
|
0, 0, // TODO: ARM32
|
||||||
|
|
||||||
|
// Supported register types.
|
||||||
|
0u | (1u << uint32_t(RegType::kGp32 ))
|
||||||
|
| (1u << uint32_t(RegType::kVec32 ))
|
||||||
|
| (1u << uint32_t(RegType::kVec64 ))
|
||||||
|
| (1u << uint32_t(RegType::kVec128)),
|
||||||
|
|
||||||
|
// Instruction hints [Gp, Vec, ExtraVirt2, ExtraVirt3].
|
||||||
|
{{
|
||||||
|
InstHints::kPushPop,
|
||||||
|
InstHints::kPushPop,
|
||||||
|
InstHints::kNoHints,
|
||||||
|
InstHints::kNoHints
|
||||||
|
}},
|
||||||
|
|
||||||
|
// TypeIdToRegType.
|
||||||
|
#define V(index) (index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt8) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt8) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt16) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt16) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt32) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt32) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kIntPtr) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUIntPtr) ? RegType::kGp32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat32) ? RegType::kVec32 : \
|
||||||
|
index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat64) ? RegType::kVec64 : RegType::kNone)
|
||||||
|
{{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
|
||||||
|
#undef V
|
||||||
|
|
||||||
|
// Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
|
||||||
|
{
|
||||||
|
ArchTypeNameId::kByte,
|
||||||
|
ArchTypeNameId::kHWord,
|
||||||
|
ArchTypeNameId::kWord,
|
||||||
|
ArchTypeNameId::kXWord
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32ARCHTRAITS_P_H_INCLUDED
|
||||||
11016
asmjit/arm/a32assembler.cpp
Normal file
11016
asmjit/arm/a32assembler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
69
asmjit/arm/a32assembler.h
Normal file
69
asmjit/arm/a32assembler.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32ASSEMBLER_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32ASSEMBLER_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/assembler.h>
|
||||||
|
#include <asmjit/arm/a32emitter.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! AArch32 assembler implementation.
|
||||||
|
class ASMJIT_VIRTAPI Assembler
|
||||||
|
: public BaseAssembler,
|
||||||
|
public EmitterExplicitT<Assembler> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef BaseAssembler Base;
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Assembler(CodeHolder* code = nullptr) noexcept;
|
||||||
|
ASMJIT_API ~Assembler() noexcept override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Accessors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Gets whether the current ARM mode is THUMB (alternative to 32-bit ARM encoding).
|
||||||
|
ASMJIT_INLINE_NODEBUG bool is_in_thumb_mode() const noexcept { return _environment.is_arch_thumb(); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Emit
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Error _emit(InstId inst_id, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Align
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Error align(AlignMode align_mode, uint32_t alignment) override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Error on_attach(CodeHolder& code) noexcept override;
|
||||||
|
ASMJIT_API Error on_detach(CodeHolder& code) noexcept override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32ASSEMBLER_H_INCLUDED
|
||||||
58
asmjit/arm/a32builder.cpp
Normal file
58
asmjit/arm/a32builder.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core/api-build_p.h>
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32) && !defined(ASMJIT_NO_BUILDER)
|
||||||
|
|
||||||
|
#include <asmjit/arm/a32assembler.h>
|
||||||
|
#include <asmjit/arm/a32builder.h>
|
||||||
|
#include <asmjit/arm/a32emithelper_p.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
// a32::Builder - Construction & Destruction
|
||||||
|
// =========================================
|
||||||
|
|
||||||
|
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
|
||||||
|
_arch_mask = uint64_t(1) << uint32_t(Arch::kARM ) |
|
||||||
|
uint64_t(1) << uint32_t(Arch::kARM_BE ) |
|
||||||
|
uint64_t(1) << uint32_t(Arch::kThumb ) |
|
||||||
|
uint64_t(1) << uint32_t(Arch::kThumb_BE) ;
|
||||||
|
if (code)
|
||||||
|
code->attach(this);
|
||||||
|
}
|
||||||
|
Builder::~Builder() noexcept {}
|
||||||
|
|
||||||
|
// a32::Builder - Events
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
Error Builder::on_attach(CodeHolder& code) noexcept {
|
||||||
|
ASMJIT_PROPAGATE(Base::on_attach(code));
|
||||||
|
|
||||||
|
_instruction_alignment = _environment.is_arch_thumb() ? uint8_t(2) : uint8_t(4);
|
||||||
|
_instruction_alignment = uint8_t(4);
|
||||||
|
update_emitter_funcs(this);
|
||||||
|
|
||||||
|
return Error::kOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Builder::on_detach(CodeHolder& code) noexcept {
|
||||||
|
return Base::on_detach(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// a32::Builder - Finalize
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
Error Builder::finalize() {
|
||||||
|
ASMJIT_PROPAGATE(run_passes());
|
||||||
|
Assembler a(_code);
|
||||||
|
a.add_encoding_options(encoding_options());
|
||||||
|
a.add_diagnostic_options(diagnostic_options());
|
||||||
|
return serialize_to(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32 && !ASMJIT_NO_BUILDER
|
||||||
57
asmjit/arm/a32builder.h
Normal file
57
asmjit/arm/a32builder.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32BUILDER_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32BUILDER_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/api-config.h>
|
||||||
|
#ifndef ASMJIT_NO_BUILDER
|
||||||
|
|
||||||
|
#include <asmjit/core/builder.h>
|
||||||
|
#include <asmjit/arm/a32emitter.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! AArch32 builder implementation.
|
||||||
|
class ASMJIT_VIRTAPI Builder
|
||||||
|
: public BaseBuilder,
|
||||||
|
public EmitterExplicitT<Builder> {
|
||||||
|
public:
|
||||||
|
ASMJIT_NONCOPYABLE(Builder)
|
||||||
|
typedef BaseBuilder Base;
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API explicit Builder(CodeHolder* code = nullptr) noexcept;
|
||||||
|
ASMJIT_API ~Builder() noexcept override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Events
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Error on_attach(CodeHolder& code) noexcept override;
|
||||||
|
ASMJIT_API Error on_detach(CodeHolder& code) noexcept override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Finalize
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_API Error finalize() override;
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_BUILDER
|
||||||
|
#endif // ASMJIT_ARM_A32BUILDER_H_INCLUDED
|
||||||
395
asmjit/arm/a32emithelper.cpp
Normal file
395
asmjit/arm/a32emithelper.cpp
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core/api-build_p.h>
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
|
||||||
|
#include <asmjit/core/formatter.h>
|
||||||
|
#include <asmjit/core/funcargscontext_p.h>
|
||||||
|
#include <asmjit/core/string.h>
|
||||||
|
#include <asmjit/core/type.h>
|
||||||
|
#include <asmjit/support/support.h>
|
||||||
|
#include <asmjit/arm/a32emithelper_p.h>
|
||||||
|
#include <asmjit/arm/a32formatter_p.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
// a32::EmitHelper - Emit Operations
|
||||||
|
// =================================
|
||||||
|
|
||||||
|
ASMJIT_FAVOR_SIZE Error EmitHelper::emit_reg_move(
|
||||||
|
const Operand_& dst_,
|
||||||
|
const Operand_& src_, TypeId type_id, const char* comment) {
|
||||||
|
|
||||||
|
Emitter* emitter = _emitter->as<Emitter>();
|
||||||
|
|
||||||
|
// Invalid or abstract TypeIds are not allowed.
|
||||||
|
ASMJIT_ASSERT(TypeUtils::is_valid(type_id) && !TypeUtils::is_abstract(type_id));
|
||||||
|
|
||||||
|
emitter->set_inline_comment(comment);
|
||||||
|
|
||||||
|
if (dst_.is_reg() && src_.is_mem()) {
|
||||||
|
Reg dst(dst_.as<Reg>());
|
||||||
|
Mem src(src_.as<Mem>());
|
||||||
|
|
||||||
|
switch (type_id) {
|
||||||
|
case TypeId::kInt8:
|
||||||
|
case TypeId::kUInt8:
|
||||||
|
return emitter->ldrb(dst.as<Gp>(), src);
|
||||||
|
|
||||||
|
case TypeId::kInt16:
|
||||||
|
case TypeId::kUInt16:
|
||||||
|
return emitter->ldrh(dst.as<Gp>(), src);
|
||||||
|
|
||||||
|
case TypeId::kInt32:
|
||||||
|
case TypeId::kUInt32:
|
||||||
|
return emitter->ldr(dst.as<Gp>(), src);
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (TypeUtils::is_float32(type_id) || TypeUtils::is_vec32(type_id))
|
||||||
|
return emitter->vldr_32(dst.as<Vec>().s(), src);
|
||||||
|
|
||||||
|
if (TypeUtils::is_float64(type_id) || TypeUtils::is_vec64(type_id))
|
||||||
|
return emitter->vldr_64(dst.as<Vec>().d(), src);
|
||||||
|
|
||||||
|
// TODO: AArch32.
|
||||||
|
// if (TypeUtils::is_vec128(type_id))
|
||||||
|
// return emitter->vldr(dst.as<Vec>().q(), src);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_.is_mem() && src_.is_reg()) {
|
||||||
|
Mem dst(dst_.as<Mem>());
|
||||||
|
Reg src(src_.as<Reg>());
|
||||||
|
|
||||||
|
switch (type_id) {
|
||||||
|
case TypeId::kInt8:
|
||||||
|
case TypeId::kUInt8:
|
||||||
|
return emitter->strb(src.as<Gp>(), dst);
|
||||||
|
|
||||||
|
case TypeId::kInt16:
|
||||||
|
case TypeId::kUInt16:
|
||||||
|
return emitter->strh(src.as<Gp>(), dst);
|
||||||
|
|
||||||
|
case TypeId::kInt32:
|
||||||
|
case TypeId::kUInt32:
|
||||||
|
return emitter->str(src.as<Gp>(), dst);
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (TypeUtils::is_float32(type_id) || TypeUtils::is_vec32(type_id))
|
||||||
|
return emitter->vstr_32(src.as<Vec>().s(), dst);
|
||||||
|
|
||||||
|
if (TypeUtils::is_float64(type_id) || TypeUtils::is_vec64(type_id))
|
||||||
|
return emitter->vstr_64(src.as<Vec>().d(), dst);
|
||||||
|
|
||||||
|
// TODO: AArch32
|
||||||
|
// if (TypeUtils::isVec128(type_id))
|
||||||
|
// return emitter->vstr(src.as<Vec>().q(), dst);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_.is_reg() && src_.is_reg()) {
|
||||||
|
Reg dst(dst_.as<Reg>());
|
||||||
|
Reg src(src_.as<Reg>());
|
||||||
|
|
||||||
|
switch (type_id) {
|
||||||
|
case TypeId::kInt8:
|
||||||
|
case TypeId::kUInt8:
|
||||||
|
case TypeId::kInt16:
|
||||||
|
case TypeId::kUInt16:
|
||||||
|
case TypeId::kInt32:
|
||||||
|
case TypeId::kUInt32:
|
||||||
|
return emitter->mov(src.as<Gp>(), dst.as<Gp>());
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (TypeUtils::is_float32(type_id) || TypeUtils::is_vec32(type_id))
|
||||||
|
return emitter->vmov(dst.as<Vec>().s(), src.as<Vec>().s());
|
||||||
|
|
||||||
|
if (TypeUtils::is_float64(type_id) || TypeUtils::is_vec64(type_id))
|
||||||
|
return emitter->vmov(dst.as<Vec>().d(), src.as<Vec>().d());
|
||||||
|
|
||||||
|
if (TypeUtils::is_vec128(type_id))
|
||||||
|
return emitter->vmov(dst.as<Vec>().q(), src.as<Vec>().q());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter->set_inline_comment(nullptr);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error EmitHelper::emit_reg_swap(
|
||||||
|
const Reg& a,
|
||||||
|
const Reg& b, const char* comment) {
|
||||||
|
|
||||||
|
Support::maybe_unused(a, b, comment);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error EmitHelper::emit_arg_move(
|
||||||
|
const Reg& dst_, TypeId dst_type_id,
|
||||||
|
const Operand_& src_, TypeId src_type_id, const char* comment) {
|
||||||
|
|
||||||
|
// TODO: AArch32 - EmitArgMove is unfinished.
|
||||||
|
Support::maybe_unused(dst_, dst_type_id, src_, src_type_id, comment);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// a32::EmitHelper - Emit Prolog & Epilog
|
||||||
|
// ======================================
|
||||||
|
|
||||||
|
struct LoadStoreInstructions {
|
||||||
|
InstId singleInstId;
|
||||||
|
InstId pairInstId;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct PrologEpilogInfo {
|
||||||
|
struct RegPair {
|
||||||
|
uint8_t ids[2];
|
||||||
|
uint16_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GroupData {
|
||||||
|
RegPair pairs[16];
|
||||||
|
uint32_t pairCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
Support::Array<GroupData, 2> groups;
|
||||||
|
uint32_t sizeTotal;
|
||||||
|
|
||||||
|
Error init(const FuncFrame& frame) noexcept {
|
||||||
|
uint32_t offset = 0;
|
||||||
|
|
||||||
|
for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
|
||||||
|
GroupData& data = groups[group];
|
||||||
|
|
||||||
|
uint32_t n = 0;
|
||||||
|
uint32_t pairCount = 0;
|
||||||
|
RegPair* pairs = data.pairs;
|
||||||
|
|
||||||
|
uint32_t slotSize = frame.saveRestoreRegSize(group);
|
||||||
|
uint32_t savedRegs = frame.savedRegs(group);
|
||||||
|
|
||||||
|
if (group == RegGroup::kGp && frame.hasPreservedFP()) {
|
||||||
|
// Must be at the beginning of the push/pop sequence.
|
||||||
|
ASMJIT_ASSERT(pairCount == 0);
|
||||||
|
|
||||||
|
pairs[0].offset = uint16_t(offset);
|
||||||
|
pairs[0].ids[0] = Gp::kIdFp;
|
||||||
|
pairs[0].ids[1] = Gp::kIdLr;
|
||||||
|
offset += slotSize * 2;
|
||||||
|
pairCount++;
|
||||||
|
|
||||||
|
savedRegs &= ~Support::bitMask(Gp::kIdFp, Gp::kIdLr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Support::BitWordIterator<uint32_t> it(savedRegs);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
pairs[pairCount].ids[n] = uint8_t(it.next());
|
||||||
|
|
||||||
|
if (++n == 2) {
|
||||||
|
pairs[pairCount].offset = uint16_t(offset);
|
||||||
|
offset += slotSize * 2;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
pairCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
pairs[pairCount].ids[1] = uint8_t(BaseReg::kIdBad);
|
||||||
|
pairs[pairCount].offset = uint16_t(offset);
|
||||||
|
offset += slotSize * 2;
|
||||||
|
pairCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.pairCount = pairCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
sizeTotal = offset;
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
|
||||||
|
Emitter* emitter = _emitter->as<Emitter>();
|
||||||
|
|
||||||
|
PrologEpilogInfo pei;
|
||||||
|
ASMJIT_PROPAGATE(pei.init(frame));
|
||||||
|
|
||||||
|
static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
|
||||||
|
static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
|
||||||
|
{ Inst::kIdStr , Inst::kIdStp },
|
||||||
|
{ Inst::kIdStr_v, Inst::kIdStp_v }
|
||||||
|
}};
|
||||||
|
|
||||||
|
uint32_t adjustInitialOffset = pei.sizeTotal;
|
||||||
|
|
||||||
|
for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
|
||||||
|
const PrologEpilogInfo::GroupData& data = pei.groups[group];
|
||||||
|
uint32_t pairCount = data.pairCount;
|
||||||
|
|
||||||
|
Reg regs[2] = { groupRegs[group], groupRegs[group] };
|
||||||
|
Mem mem = ptr(sp);
|
||||||
|
|
||||||
|
const LoadStoreInstructions& insts = groupInsts[group];
|
||||||
|
for (uint32_t i = 0; i < pairCount; i++) {
|
||||||
|
const PrologEpilogInfo::RegPair& pair = data.pairs[i];
|
||||||
|
|
||||||
|
regs[0].setId(pair.ids[0]);
|
||||||
|
regs[1].setId(pair.ids[1]);
|
||||||
|
mem.setOffsetLo32(pair.offset);
|
||||||
|
|
||||||
|
if (pair.offset == 0 && adjustInitialOffset) {
|
||||||
|
mem.setOffset(-int(adjustInitialOffset));
|
||||||
|
mem.makePreIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pair.ids[1] == BaseReg::kIdBad)
|
||||||
|
ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
|
||||||
|
else
|
||||||
|
ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
|
||||||
|
|
||||||
|
mem.resetToFixedOffset();
|
||||||
|
|
||||||
|
if (i == 0 && frame.hasPreservedFP()) {
|
||||||
|
ASMJIT_PROPAGATE(emitter->mov(x29, sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.hasStackAdjustment()) {
|
||||||
|
uint32_t adj = frame.stackAdjustment();
|
||||||
|
if (adj <= 0xFFFu) {
|
||||||
|
ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj));
|
||||||
|
}
|
||||||
|
else if (adj <= 0xFFFFFFu) {
|
||||||
|
// TODO: [ARM] Prolog - we must touch the pages otherwise it's undefined.
|
||||||
|
ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0x000FFFu));
|
||||||
|
ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0xFFF000u));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: [ARM] Emit epilog.
|
||||||
|
ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
|
||||||
|
Emitter* emitter = _emitter->as<Emitter>();
|
||||||
|
|
||||||
|
PrologEpilogInfo pei;
|
||||||
|
ASMJIT_PROPAGATE(pei.init(frame));
|
||||||
|
|
||||||
|
static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
|
||||||
|
static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
|
||||||
|
{ Inst::kIdLdr , Inst::kIdLdp },
|
||||||
|
{ Inst::kIdLdr_v, Inst::kIdLdp_v }
|
||||||
|
}};
|
||||||
|
|
||||||
|
uint32_t adjustInitialOffset = pei.sizeTotal;
|
||||||
|
|
||||||
|
if (frame.hasStackAdjustment()) {
|
||||||
|
uint32_t adj = frame.stackAdjustment();
|
||||||
|
if (adj <= 0xFFFu) {
|
||||||
|
ASMJIT_PROPAGATE(emitter->add(sp, sp, adj));
|
||||||
|
}
|
||||||
|
else if (adj <= 0xFFFFFFu) {
|
||||||
|
ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0x000FFFu));
|
||||||
|
ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0xFFF000u));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int g = 1; g >= 0; g--) {
|
||||||
|
RegGroup group = RegGroup(g);
|
||||||
|
const PrologEpilogInfo::GroupData& data = pei.groups[group];
|
||||||
|
uint32_t pairCount = data.pairCount;
|
||||||
|
|
||||||
|
Reg regs[2] = { groupRegs[group], groupRegs[group] };
|
||||||
|
Mem mem = ptr(sp);
|
||||||
|
|
||||||
|
const LoadStoreInstructions& insts = groupInsts[group];
|
||||||
|
|
||||||
|
for (int i = int(pairCount) - 1; i >= 0; i--) {
|
||||||
|
const PrologEpilogInfo::RegPair& pair = data.pairs[i];
|
||||||
|
|
||||||
|
regs[0].setId(pair.ids[0]);
|
||||||
|
regs[1].setId(pair.ids[1]);
|
||||||
|
mem.setOffsetLo32(pair.offset);
|
||||||
|
|
||||||
|
if (pair.offset == 0 && adjustInitialOffset) {
|
||||||
|
mem.setOffset(int(adjustInitialOffset));
|
||||||
|
mem.makePostIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pair.ids[1] == BaseReg::kIdBad)
|
||||||
|
ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
|
||||||
|
else
|
||||||
|
ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
|
||||||
|
|
||||||
|
mem.resetToFixedOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_PROPAGATE(emitter->ret(x30));
|
||||||
|
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Error ASMJIT_CDECL Emitter_emit_prolog(BaseEmitter* emitter, const FuncFrame& frame) {
|
||||||
|
// EmitHelper emitHelper(emitter);
|
||||||
|
// return emitHelper.emitProlog(frame);
|
||||||
|
Support::maybe_unused(emitter, frame);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error ASMJIT_CDECL Emitter_emit_epilog(BaseEmitter* emitter, const FuncFrame& frame) {
|
||||||
|
// EmitHelper emitHelper(emitter);
|
||||||
|
// return emitHelper.emitEpilog(frame);
|
||||||
|
Support::maybe_unused(emitter, frame);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error ASMJIT_CDECL Emitter_emit_args_assignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
|
||||||
|
// EmitHelper emitHelper(emitter);
|
||||||
|
// return emitHelper.emitArgsAssignment(frame, args);
|
||||||
|
Support::maybe_unused(emitter, frame, args);
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assignEmitterFuncs(BaseEmitter* emitter) {
|
||||||
|
emitter->_funcs.emit_prolog = Emitter_emit_prolog;
|
||||||
|
emitter->_funcs.emit_epilog = Emitter_emit_epilog;
|
||||||
|
emitter->_funcs.emit_args_assignment = Emitter_emit_args_assignment;
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_LOGGING
|
||||||
|
emitter->_funcs.format_instruction = FormatterInternal::format_instruction;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_VALIDATION
|
||||||
|
// TODO: AArch32.
|
||||||
|
// emitter->_funcs.validate = InstInternal::validate;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32
|
||||||
53
asmjit/arm/a32emithelper_p.h
Normal file
53
asmjit/arm/a32emithelper_p.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32EMITHELPER_P_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32EMITHELPER_P_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/api-config.h>
|
||||||
|
|
||||||
|
#include <asmjit/core/emithelper_p.h>
|
||||||
|
#include <asmjit/core/func.h>
|
||||||
|
#include <asmjit/arm/a32emitter.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \cond INTERNAL
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
class EmitHelper : public BaseEmitHelper {
|
||||||
|
public:
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit EmitHelper(BaseEmitter* emitter = nullptr) noexcept
|
||||||
|
: BaseEmitHelper(emitter) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG ~EmitHelper() noexcept override = default;
|
||||||
|
|
||||||
|
Error emit_reg_move(
|
||||||
|
const Operand_& dst_,
|
||||||
|
const Operand_& src_, TypeId type_id, const char* comment = nullptr) override;
|
||||||
|
|
||||||
|
Error emit_reg_swap(
|
||||||
|
const Reg& a,
|
||||||
|
const Reg& b, const char* comment = nullptr) override;
|
||||||
|
|
||||||
|
Error emit_arg_move(
|
||||||
|
const Reg& dst_, TypeId dst_type_id,
|
||||||
|
const Operand_& src_, TypeId src_type_id, const char* comment = nullptr) override;
|
||||||
|
|
||||||
|
Error emit_prolog(const FuncFrame& frame);
|
||||||
|
Error emit_epilog(const FuncFrame& frame);
|
||||||
|
};
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
static inline void update_emitter_funcs(BaseEmitter* emitter) noexcept { Support::maybe_unused(emitter); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32EMITHELPER_P_H_INCLUDED
|
||||||
1603
asmjit/arm/a32emitter.h
Normal file
1603
asmjit/arm/a32emitter.h
Normal file
File diff suppressed because it is too large
Load Diff
68
asmjit/arm/a32formatter.cpp
Normal file
68
asmjit/arm/a32formatter.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core/api-build_p.h>
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32) && !defined(ASMJIT_NO_LOGGING)
|
||||||
|
|
||||||
|
#include <asmjit/core/misc_p.h>
|
||||||
|
#include <asmjit/support/support.h>
|
||||||
|
#include <asmjit/arm/a32formatter_p.h>
|
||||||
|
#include <asmjit/arm/a32instapi_p.h>
|
||||||
|
#include <asmjit/arm/a32instdb_p.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_COMPILER
|
||||||
|
#include <asmjit/core/compiler.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
// a32::FormatterInternal - Format Instruction
|
||||||
|
// ===========================================
|
||||||
|
|
||||||
|
ASMJIT_FAVOR_SIZE Error FormatterInternal::format_instruction(
|
||||||
|
String& sb,
|
||||||
|
FormatFlags format_flags,
|
||||||
|
const BaseEmitter* emitter,
|
||||||
|
Arch arch,
|
||||||
|
const BaseInst& inst, Span<const Operand_> operands) noexcept {
|
||||||
|
|
||||||
|
Support::maybe_unused(arch);
|
||||||
|
|
||||||
|
// Format instruction options and instruction mnemonic.
|
||||||
|
InstId inst_id = inst.real_id();
|
||||||
|
if (inst_id < Inst::_kIdCount) {
|
||||||
|
InstStringifyOptions stringifyOptions =
|
||||||
|
Support::test(format_flags, FormatFlags::kShowAliases)
|
||||||
|
? InstStringifyOptions::kAliases
|
||||||
|
: InstStringifyOptions::kNone;
|
||||||
|
ASMJIT_PROPAGATE(InstInternal::inst_id_to_string(inst_id, stringifyOptions, sb));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ASMJIT_PROPAGATE(sb.append_format("[InstId=#%u]", unsigned(inst_id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CondCode cc = inst.arm_cond_code();
|
||||||
|
if (cc != CondCode::kAL) {
|
||||||
|
ASMJIT_PROPAGATE(sb.append('.'));
|
||||||
|
ASMJIT_PROPAGATE(format_cond_code(sb, cc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format instruction operands.
|
||||||
|
for (size_t i = 0; i < operands.size(); i++) {
|
||||||
|
const Operand_& op = operands[i];
|
||||||
|
if (op.is_none())
|
||||||
|
break;
|
||||||
|
|
||||||
|
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
|
||||||
|
ASMJIT_PROPAGATE(format_operand(sb, format_flags, emitter, arch, op));
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32 && !ASMJIT_NO_LOGGING
|
||||||
42
asmjit/arm/a32formatter_p.h
Normal file
42
asmjit/arm/a32formatter_p.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32FORMATTER_P_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32FORMATTER_P_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/api-config.h>
|
||||||
|
#ifndef ASMJIT_NO_LOGGING
|
||||||
|
|
||||||
|
#include <asmjit/core/formatter.h>
|
||||||
|
#include <asmjit/core/string.h>
|
||||||
|
#include <asmjit/arm/armformatter_p.h>
|
||||||
|
#include <asmjit/arm/a32globals.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \cond INTERNAL
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
namespace FormatterInternal {
|
||||||
|
|
||||||
|
using namespace arm::FormatterInternal;
|
||||||
|
|
||||||
|
Error ASMJIT_CDECL format_instruction(
|
||||||
|
String& sb,
|
||||||
|
FormatFlags format_flags,
|
||||||
|
const BaseEmitter* emitter,
|
||||||
|
Arch arch,
|
||||||
|
const BaseInst& inst, Span<const Operand_> operands) noexcept;
|
||||||
|
|
||||||
|
} // {FormatterInternal}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_LOGGING
|
||||||
|
#endif // ASMJIT_ARM_A32FORMATTER_P_H_INCLUDED
|
||||||
531
asmjit/arm/a32globals.h
Normal file
531
asmjit/arm/a32globals.h
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32GLOBALS_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32GLOBALS_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/arm/armglobals.h>
|
||||||
|
|
||||||
|
//! \namespace asmjit::a32
|
||||||
|
//! \ingroup asmjit_a32
|
||||||
|
//!
|
||||||
|
//! AArch32 backend.
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! ARM32/THUMB instruction.
|
||||||
|
//!
|
||||||
|
//! \note Only used to hold ARM-specific enumerations and static functions.
|
||||||
|
struct Inst {
|
||||||
|
//! Instruction id.
|
||||||
|
enum Id : uint32_t {
|
||||||
|
// ${a32::InstId:Begin}
|
||||||
|
// ------------------- Automatically generated, do not edit -------------------
|
||||||
|
kIdNone = 0, //!< Instruction '<none>'.
|
||||||
|
kIdAdc, //!< Instruction 'adc'.
|
||||||
|
kIdAdcs, //!< Instruction 'adcs'.
|
||||||
|
kIdAdd, //!< Instruction 'add'.
|
||||||
|
kIdAdds, //!< Instruction 'adds'.
|
||||||
|
kIdAdr, //!< Instruction 'adr'.
|
||||||
|
kIdAesd, //!< Instruction 'aesd' {AES}.
|
||||||
|
kIdAese, //!< Instruction 'aese' {AES}.
|
||||||
|
kIdAesimc, //!< Instruction 'aesimc' {AES}.
|
||||||
|
kIdAesmc, //!< Instruction 'aesmc' {AES}.
|
||||||
|
kIdAnd, //!< Instruction 'and'.
|
||||||
|
kIdAnds, //!< Instruction 'ands'.
|
||||||
|
kIdAsr, //!< Instruction 'asr'.
|
||||||
|
kIdAsrs, //!< Instruction 'asrs'.
|
||||||
|
kIdB, //!< Instruction 'b'.
|
||||||
|
kIdBfc, //!< Instruction 'bfc'.
|
||||||
|
kIdBfi, //!< Instruction 'bfi'.
|
||||||
|
kIdBic, //!< Instruction 'bic'.
|
||||||
|
kIdBics, //!< Instruction 'bics'.
|
||||||
|
kIdBkpt, //!< Instruction 'bkpt'.
|
||||||
|
kIdBl, //!< Instruction 'bl'.
|
||||||
|
kIdBlx, //!< Instruction 'blx'.
|
||||||
|
kIdBx, //!< Instruction 'bx'.
|
||||||
|
kIdBxj, //!< Instruction 'bxj'.
|
||||||
|
kIdCbnz, //!< Instruction 'cbnz' (THUMB).
|
||||||
|
kIdCbz, //!< Instruction 'cbz' (THUMB).
|
||||||
|
kIdClrbhb, //!< Instruction 'clrbhb' {CLRBHB}.
|
||||||
|
kIdClrex, //!< Instruction 'clrex'.
|
||||||
|
kIdClz, //!< Instruction 'clz'.
|
||||||
|
kIdCmn, //!< Instruction 'cmn'.
|
||||||
|
kIdCmp, //!< Instruction 'cmp'.
|
||||||
|
kIdCps, //!< Instruction 'cps' (ARM).
|
||||||
|
kIdCpsid, //!< Instruction 'cpsid' (ARM).
|
||||||
|
kIdCpsie, //!< Instruction 'cpsie' (ARM).
|
||||||
|
kIdCrc32b, //!< Instruction 'crc32b' {CRC32}.
|
||||||
|
kIdCrc32cb, //!< Instruction 'crc32cb' {CRC32}.
|
||||||
|
kIdCrc32ch, //!< Instruction 'crc32ch' {CRC32}.
|
||||||
|
kIdCrc32cw, //!< Instruction 'crc32cw' {CRC32}.
|
||||||
|
kIdCrc32h, //!< Instruction 'crc32h' {CRC32}.
|
||||||
|
kIdCrc32w, //!< Instruction 'crc32w' {CRC32}.
|
||||||
|
kIdCsdb, //!< Instruction 'csdb'.
|
||||||
|
kIdDbg, //!< Instruction 'dbg' {ARMv8-}.
|
||||||
|
kIdDcps1, //!< Instruction 'dcps1' (THUMB).
|
||||||
|
kIdDcps2, //!< Instruction 'dcps2' (THUMB).
|
||||||
|
kIdDcps3, //!< Instruction 'dcps3' (THUMB).
|
||||||
|
kIdDmb, //!< Instruction 'dmb'.
|
||||||
|
kIdDsb, //!< Instruction 'dsb'.
|
||||||
|
kIdEor, //!< Instruction 'eor'.
|
||||||
|
kIdEors, //!< Instruction 'eors'.
|
||||||
|
kIdEret, //!< Instruction 'eret' (ARM).
|
||||||
|
kIdEsb, //!< Instruction 'esb' {RAS}.
|
||||||
|
kIdHlt, //!< Instruction 'hlt'.
|
||||||
|
kIdHvc, //!< Instruction 'hvc' (ARM).
|
||||||
|
kIdIsb, //!< Instruction 'isb'.
|
||||||
|
kIdIt, //!< Instruction 'it' (THUMB).
|
||||||
|
kIdIte, //!< Instruction 'ite' (THUMB).
|
||||||
|
kIdItee, //!< Instruction 'itee' (THUMB).
|
||||||
|
kIdIteee, //!< Instruction 'iteee' (THUMB).
|
||||||
|
kIdIteet, //!< Instruction 'iteet' (THUMB).
|
||||||
|
kIdItet, //!< Instruction 'itet' (THUMB).
|
||||||
|
kIdItete, //!< Instruction 'itete' (THUMB).
|
||||||
|
kIdItett, //!< Instruction 'itett' (THUMB).
|
||||||
|
kIdItt, //!< Instruction 'itt' (THUMB).
|
||||||
|
kIdItte, //!< Instruction 'itte' (THUMB).
|
||||||
|
kIdIttee, //!< Instruction 'ittee' (THUMB).
|
||||||
|
kIdIttet, //!< Instruction 'ittet' (THUMB).
|
||||||
|
kIdIttt, //!< Instruction 'ittt' (THUMB).
|
||||||
|
kIdIttte, //!< Instruction 'ittte' (THUMB).
|
||||||
|
kIdItttt, //!< Instruction 'itttt' (THUMB).
|
||||||
|
kIdLda, //!< Instruction 'lda'.
|
||||||
|
kIdLdab, //!< Instruction 'ldab'.
|
||||||
|
kIdLdaex, //!< Instruction 'ldaex'.
|
||||||
|
kIdLdaexb, //!< Instruction 'ldaexb'.
|
||||||
|
kIdLdaexd, //!< Instruction 'ldaexd'.
|
||||||
|
kIdLdaexh, //!< Instruction 'ldaexh'.
|
||||||
|
kIdLdah, //!< Instruction 'ldah'.
|
||||||
|
kIdLdmda, //!< Instruction 'ldmda' (ARM).
|
||||||
|
kIdLdmdb, //!< Instruction 'ldmdb'.
|
||||||
|
kIdLdmia, //!< Instruction 'ldmia'.
|
||||||
|
kIdLdmib, //!< Instruction 'ldmib' (ARM).
|
||||||
|
kIdLdr, //!< Instruction 'ldr'.
|
||||||
|
kIdLdrb, //!< Instruction 'ldrb'.
|
||||||
|
kIdLdrbt, //!< Instruction 'ldrbt'.
|
||||||
|
kIdLdrd, //!< Instruction 'ldrd'.
|
||||||
|
kIdLdrex, //!< Instruction 'ldrex'.
|
||||||
|
kIdLdrexb, //!< Instruction 'ldrexb'.
|
||||||
|
kIdLdrexd, //!< Instruction 'ldrexd'.
|
||||||
|
kIdLdrexh, //!< Instruction 'ldrexh'.
|
||||||
|
kIdLdrh, //!< Instruction 'ldrh'.
|
||||||
|
kIdLdrht, //!< Instruction 'ldrht'.
|
||||||
|
kIdLdrsb, //!< Instruction 'ldrsb'.
|
||||||
|
kIdLdrsbt, //!< Instruction 'ldrsbt'.
|
||||||
|
kIdLdrsh, //!< Instruction 'ldrsh'.
|
||||||
|
kIdLdrsht, //!< Instruction 'ldrsht'.
|
||||||
|
kIdLdrt, //!< Instruction 'ldrt'.
|
||||||
|
kIdLsl, //!< Instruction 'lsl'.
|
||||||
|
kIdLsls, //!< Instruction 'lsls'.
|
||||||
|
kIdLsr, //!< Instruction 'lsr'.
|
||||||
|
kIdLsrs, //!< Instruction 'lsrs'.
|
||||||
|
kIdMcr, //!< Instruction 'mcr' {ARMv6T2+}.
|
||||||
|
kIdMcr2, //!< Instruction 'mcr2' {ARMv6T2+}.
|
||||||
|
kIdMcrr, //!< Instruction 'mcrr' {ARMv6T2+}.
|
||||||
|
kIdMcrr2, //!< Instruction 'mcrr2' {ARMv6T2+}.
|
||||||
|
kIdMla, //!< Instruction 'mla'.
|
||||||
|
kIdMlas, //!< Instruction 'mlas' (ARM).
|
||||||
|
kIdMls, //!< Instruction 'mls'.
|
||||||
|
kIdMov, //!< Instruction 'mov'.
|
||||||
|
kIdMovs, //!< Instruction 'movs'.
|
||||||
|
kIdMovt, //!< Instruction 'movt'.
|
||||||
|
kIdMovw, //!< Instruction 'movw'.
|
||||||
|
kIdMrc, //!< Instruction 'mrc'.
|
||||||
|
kIdMrc2, //!< Instruction 'mrc2'.
|
||||||
|
kIdMrrc, //!< Instruction 'mrrc'.
|
||||||
|
kIdMrrc2, //!< Instruction 'mrrc2'.
|
||||||
|
kIdMrs, //!< Instruction 'mrs'.
|
||||||
|
kIdMsr, //!< Instruction 'msr'.
|
||||||
|
kIdMul, //!< Instruction 'mul'.
|
||||||
|
kIdMuls, //!< Instruction 'muls'.
|
||||||
|
kIdMvn, //!< Instruction 'mvn'.
|
||||||
|
kIdMvns, //!< Instruction 'mvns'.
|
||||||
|
kIdNop, //!< Instruction 'nop'.
|
||||||
|
kIdOrn, //!< Instruction 'orn' (THUMB).
|
||||||
|
kIdOrns, //!< Instruction 'orns' (THUMB).
|
||||||
|
kIdOrr, //!< Instruction 'orr'.
|
||||||
|
kIdOrrs, //!< Instruction 'orrs'.
|
||||||
|
kIdPkhbt, //!< Instruction 'pkhbt'.
|
||||||
|
kIdPkhtb, //!< Instruction 'pkhtb'.
|
||||||
|
kIdPld, //!< Instruction 'pld'.
|
||||||
|
kIdPldw, //!< Instruction 'pldw' {MP}.
|
||||||
|
kIdPli, //!< Instruction 'pli'.
|
||||||
|
kIdPop, //!< Instruction 'pop'.
|
||||||
|
kIdPssbb, //!< Instruction 'pssbb'.
|
||||||
|
kIdPush, //!< Instruction 'push'.
|
||||||
|
kIdQadd, //!< Instruction 'qadd'.
|
||||||
|
kIdQadd16, //!< Instruction 'qadd16'.
|
||||||
|
kIdQadd8, //!< Instruction 'qadd8'.
|
||||||
|
kIdQasx, //!< Instruction 'qasx'.
|
||||||
|
kIdQdadd, //!< Instruction 'qdadd'.
|
||||||
|
kIdQdsub, //!< Instruction 'qdsub'.
|
||||||
|
kIdQsax, //!< Instruction 'qsax'.
|
||||||
|
kIdQsub, //!< Instruction 'qsub'.
|
||||||
|
kIdQsub16, //!< Instruction 'qsub16'.
|
||||||
|
kIdQsub8, //!< Instruction 'qsub8'.
|
||||||
|
kIdRbit, //!< Instruction 'rbit'.
|
||||||
|
kIdRev, //!< Instruction 'rev'.
|
||||||
|
kIdRev16, //!< Instruction 'rev16'.
|
||||||
|
kIdRevsh, //!< Instruction 'revsh'.
|
||||||
|
kIdRfeda, //!< Instruction 'rfeda' (ARM).
|
||||||
|
kIdRfedb, //!< Instruction 'rfedb' (ARM).
|
||||||
|
kIdRfeia, //!< Instruction 'rfeia' (ARM).
|
||||||
|
kIdRfeib, //!< Instruction 'rfeib' (ARM).
|
||||||
|
kIdRor, //!< Instruction 'ror'.
|
||||||
|
kIdRors, //!< Instruction 'rors'.
|
||||||
|
kIdRrx, //!< Instruction 'rrx'.
|
||||||
|
kIdRrxs, //!< Instruction 'rrxs'.
|
||||||
|
kIdRsb, //!< Instruction 'rsb'.
|
||||||
|
kIdRsbs, //!< Instruction 'rsbs'.
|
||||||
|
kIdRsc, //!< Instruction 'rsc' (ARM).
|
||||||
|
kIdRscs, //!< Instruction 'rscs' (ARM).
|
||||||
|
kIdSadd16, //!< Instruction 'sadd16'.
|
||||||
|
kIdSadd8, //!< Instruction 'sadd8'.
|
||||||
|
kIdSasx, //!< Instruction 'sasx'.
|
||||||
|
kIdSb, //!< Instruction 'sb' {SB}.
|
||||||
|
kIdSbc, //!< Instruction 'sbc'.
|
||||||
|
kIdSbcs, //!< Instruction 'sbcs'.
|
||||||
|
kIdSbfx, //!< Instruction 'sbfx'.
|
||||||
|
kIdSdiv, //!< Instruction 'sdiv' {IDIVA & IDIVT}.
|
||||||
|
kIdSel, //!< Instruction 'sel'.
|
||||||
|
kIdSetend, //!< Instruction 'setend' {ARMv8-}.
|
||||||
|
kIdSetpan, //!< Instruction 'setpan' {PAN}.
|
||||||
|
kIdSev, //!< Instruction 'sev'.
|
||||||
|
kIdSevl, //!< Instruction 'sevl'.
|
||||||
|
kIdSha1c, //!< Instruction 'sha1c' {SHA1}.
|
||||||
|
kIdSha1h, //!< Instruction 'sha1h' {SHA1}.
|
||||||
|
kIdSha1m, //!< Instruction 'sha1m' {SHA1}.
|
||||||
|
kIdSha1p, //!< Instruction 'sha1p' {SHA1}.
|
||||||
|
kIdSha1su0, //!< Instruction 'sha1su0' {SHA1}.
|
||||||
|
kIdSha1su1, //!< Instruction 'sha1su1' {SHA1}.
|
||||||
|
kIdSha256h, //!< Instruction 'sha256h' {SHA256}.
|
||||||
|
kIdSha256h2, //!< Instruction 'sha256h2' {SHA256}.
|
||||||
|
kIdSha256su0, //!< Instruction 'sha256su0' {SHA256}.
|
||||||
|
kIdSha256su1, //!< Instruction 'sha256su1' {SHA256}.
|
||||||
|
kIdShadd16, //!< Instruction 'shadd16'.
|
||||||
|
kIdShadd8, //!< Instruction 'shadd8'.
|
||||||
|
kIdShasx, //!< Instruction 'shasx'.
|
||||||
|
kIdShsax, //!< Instruction 'shsax'.
|
||||||
|
kIdShsub16, //!< Instruction 'shsub16'.
|
||||||
|
kIdShsub8, //!< Instruction 'shsub8'.
|
||||||
|
kIdSmc, //!< Instruction 'smc' {SECURITY}.
|
||||||
|
kIdSmlabb, //!< Instruction 'smlabb'.
|
||||||
|
kIdSmlabt, //!< Instruction 'smlabt'.
|
||||||
|
kIdSmlad, //!< Instruction 'smlad'.
|
||||||
|
kIdSmladx, //!< Instruction 'smladx'.
|
||||||
|
kIdSmlal, //!< Instruction 'smlal'.
|
||||||
|
kIdSmlalbb, //!< Instruction 'smlalbb'.
|
||||||
|
kIdSmlalbt, //!< Instruction 'smlalbt'.
|
||||||
|
kIdSmlald, //!< Instruction 'smlald'.
|
||||||
|
kIdSmlaldx, //!< Instruction 'smlaldx'.
|
||||||
|
kIdSmlals, //!< Instruction 'smlals' (ARM).
|
||||||
|
kIdSmlaltb, //!< Instruction 'smlaltb'.
|
||||||
|
kIdSmlaltt, //!< Instruction 'smlaltt'.
|
||||||
|
kIdSmlatb, //!< Instruction 'smlatb'.
|
||||||
|
kIdSmlatt, //!< Instruction 'smlatt'.
|
||||||
|
kIdSmlawb, //!< Instruction 'smlawb'.
|
||||||
|
kIdSmlawt, //!< Instruction 'smlawt'.
|
||||||
|
kIdSmlsd, //!< Instruction 'smlsd'.
|
||||||
|
kIdSmlsdx, //!< Instruction 'smlsdx'.
|
||||||
|
kIdSmlsld, //!< Instruction 'smlsld'.
|
||||||
|
kIdSmlsldx, //!< Instruction 'smlsldx'.
|
||||||
|
kIdSmmla, //!< Instruction 'smmla'.
|
||||||
|
kIdSmmlar, //!< Instruction 'smmlar'.
|
||||||
|
kIdSmmls, //!< Instruction 'smmls'.
|
||||||
|
kIdSmmlsr, //!< Instruction 'smmlsr'.
|
||||||
|
kIdSmmul, //!< Instruction 'smmul'.
|
||||||
|
kIdSmmulr, //!< Instruction 'smmulr'.
|
||||||
|
kIdSmuad, //!< Instruction 'smuad'.
|
||||||
|
kIdSmuadx, //!< Instruction 'smuadx'.
|
||||||
|
kIdSmulbb, //!< Instruction 'smulbb'.
|
||||||
|
kIdSmulbt, //!< Instruction 'smulbt'.
|
||||||
|
kIdSmull, //!< Instruction 'smull'.
|
||||||
|
kIdSmulls, //!< Instruction 'smulls' (ARM).
|
||||||
|
kIdSmultb, //!< Instruction 'smultb'.
|
||||||
|
kIdSmultt, //!< Instruction 'smultt'.
|
||||||
|
kIdSmulwb, //!< Instruction 'smulwb'.
|
||||||
|
kIdSmulwt, //!< Instruction 'smulwt'.
|
||||||
|
kIdSmusd, //!< Instruction 'smusd'.
|
||||||
|
kIdSmusdx, //!< Instruction 'smusdx'.
|
||||||
|
kIdSrsda, //!< Instruction 'srsda' (ARM).
|
||||||
|
kIdSrsdb, //!< Instruction 'srsdb' (ARM).
|
||||||
|
kIdSrsia, //!< Instruction 'srsia' (ARM).
|
||||||
|
kIdSrsib, //!< Instruction 'srsib' (ARM).
|
||||||
|
kIdSsat, //!< Instruction 'ssat'.
|
||||||
|
kIdSsat16, //!< Instruction 'ssat16'.
|
||||||
|
kIdSsax, //!< Instruction 'ssax'.
|
||||||
|
kIdSsbb, //!< Instruction 'ssbb'.
|
||||||
|
kIdSsub16, //!< Instruction 'ssub16'.
|
||||||
|
kIdSsub8, //!< Instruction 'ssub8'.
|
||||||
|
kIdStl, //!< Instruction 'stl'.
|
||||||
|
kIdStlb, //!< Instruction 'stlb'.
|
||||||
|
kIdStlex, //!< Instruction 'stlex'.
|
||||||
|
kIdStlexb, //!< Instruction 'stlexb'.
|
||||||
|
kIdStlexd, //!< Instruction 'stlexd'.
|
||||||
|
kIdStlexh, //!< Instruction 'stlexh'.
|
||||||
|
kIdStlh, //!< Instruction 'stlh'.
|
||||||
|
kIdStmda, //!< Instruction 'stmda' (ARM).
|
||||||
|
kIdStmdb, //!< Instruction 'stmdb'.
|
||||||
|
kIdStmia, //!< Instruction 'stmia'.
|
||||||
|
kIdStmib, //!< Instruction 'stmib' (ARM).
|
||||||
|
kIdStr, //!< Instruction 'str'.
|
||||||
|
kIdStrb, //!< Instruction 'strb'.
|
||||||
|
kIdStrbt, //!< Instruction 'strbt'.
|
||||||
|
kIdStrd, //!< Instruction 'strd'.
|
||||||
|
kIdStrex, //!< Instruction 'strex'.
|
||||||
|
kIdStrexb, //!< Instruction 'strexb'.
|
||||||
|
kIdStrexd, //!< Instruction 'strexd'.
|
||||||
|
kIdStrexh, //!< Instruction 'strexh'.
|
||||||
|
kIdStrh, //!< Instruction 'strh'.
|
||||||
|
kIdStrht, //!< Instruction 'strht'.
|
||||||
|
kIdStrt, //!< Instruction 'strt'.
|
||||||
|
kIdSub, //!< Instruction 'sub'.
|
||||||
|
kIdSubs, //!< Instruction 'subs'.
|
||||||
|
kIdSvc, //!< Instruction 'svc'.
|
||||||
|
kIdSxtab, //!< Instruction 'sxtab'.
|
||||||
|
kIdSxtab16, //!< Instruction 'sxtab16'.
|
||||||
|
kIdSxtah, //!< Instruction 'sxtah'.
|
||||||
|
kIdSxtb, //!< Instruction 'sxtb'.
|
||||||
|
kIdSxtb16, //!< Instruction 'sxtb16'.
|
||||||
|
kIdSxth, //!< Instruction 'sxth'.
|
||||||
|
kIdTbb, //!< Instruction 'tbb' (THUMB).
|
||||||
|
kIdTbh, //!< Instruction 'tbh' (THUMB).
|
||||||
|
kIdTeq, //!< Instruction 'teq'.
|
||||||
|
kIdTst, //!< Instruction 'tst'.
|
||||||
|
kIdUadd16, //!< Instruction 'uadd16'.
|
||||||
|
kIdUadd8, //!< Instruction 'uadd8'.
|
||||||
|
kIdUasx, //!< Instruction 'uasx'.
|
||||||
|
kIdUbfx, //!< Instruction 'ubfx'.
|
||||||
|
kIdUdf, //!< Instruction 'udf' (ARM).
|
||||||
|
kIdUdiv, //!< Instruction 'udiv' {IDIVA & IDIVT}.
|
||||||
|
kIdUhadd16, //!< Instruction 'uhadd16'.
|
||||||
|
kIdUhadd8, //!< Instruction 'uhadd8'.
|
||||||
|
kIdUhasx, //!< Instruction 'uhasx'.
|
||||||
|
kIdUhsax, //!< Instruction 'uhsax'.
|
||||||
|
kIdUhsub16, //!< Instruction 'uhsub16'.
|
||||||
|
kIdUhsub8, //!< Instruction 'uhsub8'.
|
||||||
|
kIdUmaal, //!< Instruction 'umaal'.
|
||||||
|
kIdUmlal, //!< Instruction 'umlal'.
|
||||||
|
kIdUmlals, //!< Instruction 'umlals' (ARM).
|
||||||
|
kIdUmull, //!< Instruction 'umull'.
|
||||||
|
kIdUmulls, //!< Instruction 'umulls' (ARM).
|
||||||
|
kIdUqadd16, //!< Instruction 'uqadd16'.
|
||||||
|
kIdUqadd8, //!< Instruction 'uqadd8'.
|
||||||
|
kIdUqasx, //!< Instruction 'uqasx'.
|
||||||
|
kIdUqsax, //!< Instruction 'uqsax'.
|
||||||
|
kIdUqsub16, //!< Instruction 'uqsub16'.
|
||||||
|
kIdUqsub8, //!< Instruction 'uqsub8'.
|
||||||
|
kIdUsad8, //!< Instruction 'usad8'.
|
||||||
|
kIdUsada8, //!< Instruction 'usada8'.
|
||||||
|
kIdUsat, //!< Instruction 'usat'.
|
||||||
|
kIdUsat16, //!< Instruction 'usat16'.
|
||||||
|
kIdUsax, //!< Instruction 'usax'.
|
||||||
|
kIdUsub16, //!< Instruction 'usub16'.
|
||||||
|
kIdUsub8, //!< Instruction 'usub8'.
|
||||||
|
kIdUxtab, //!< Instruction 'uxtab'.
|
||||||
|
kIdUxtab16, //!< Instruction 'uxtab16'.
|
||||||
|
kIdUxtah, //!< Instruction 'uxtah'.
|
||||||
|
kIdUxtb, //!< Instruction 'uxtb'.
|
||||||
|
kIdUxtb16, //!< Instruction 'uxtb16'.
|
||||||
|
kIdUxth, //!< Instruction 'uxth'.
|
||||||
|
kIdVaba, //!< Instruction 'vaba' {ASIMD}.
|
||||||
|
kIdVabal, //!< Instruction 'vabal' {ASIMD}.
|
||||||
|
kIdVabd, //!< Instruction 'vabd' {ASIMD ~FP16}.
|
||||||
|
kIdVabdl, //!< Instruction 'vabdl' {ASIMD}.
|
||||||
|
kIdVabs, //!< Instruction 'vabs' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVacge, //!< Instruction 'vacge' {ASIMD ~FP16}.
|
||||||
|
kIdVacgt, //!< Instruction 'vacgt' {ASIMD ~FP16}.
|
||||||
|
kIdVacle, //!< Instruction 'vacle' {ASIMD ~FP16}.
|
||||||
|
kIdVaclt, //!< Instruction 'vaclt' {ASIMD ~FP16}.
|
||||||
|
kIdVadd, //!< Instruction 'vadd' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVaddhn, //!< Instruction 'vaddhn' {ASIMD}.
|
||||||
|
kIdVaddl, //!< Instruction 'vaddl' {ASIMD}.
|
||||||
|
kIdVaddw, //!< Instruction 'vaddw' {ASIMD}.
|
||||||
|
kIdVand, //!< Instruction 'vand' {ASIMD}.
|
||||||
|
kIdVbic, //!< Instruction 'vbic' {ASIMD}.
|
||||||
|
kIdVbif, //!< Instruction 'vbif' {ASIMD}.
|
||||||
|
kIdVbit, //!< Instruction 'vbit' {ASIMD}.
|
||||||
|
kIdVbsl, //!< Instruction 'vbsl' {ASIMD}.
|
||||||
|
kIdVcadd, //!< Instruction 'vcadd' {FCMA ~FP16}.
|
||||||
|
kIdVceq, //!< Instruction 'vceq' {ASIMD ~FP16}.
|
||||||
|
kIdVcge, //!< Instruction 'vcge' {ASIMD ~FP16}.
|
||||||
|
kIdVcgt, //!< Instruction 'vcgt' {ASIMD ~FP16}.
|
||||||
|
kIdVcle, //!< Instruction 'vcle' {ASIMD ~FP16}.
|
||||||
|
kIdVcls, //!< Instruction 'vcls' {ASIMD}.
|
||||||
|
kIdVclt, //!< Instruction 'vclt' {ASIMD ~FP16}.
|
||||||
|
kIdVclz, //!< Instruction 'vclz' {ASIMD}.
|
||||||
|
kIdVcmla, //!< Instruction 'vcmla' {FCMA ~FP16}.
|
||||||
|
kIdVcmp, //!< Instruction 'vcmp' {FP ~FP16}.
|
||||||
|
kIdVcmpe, //!< Instruction 'vcmpe' {FP ~FP16}.
|
||||||
|
kIdVcnt, //!< Instruction 'vcnt' {ASIMD}.
|
||||||
|
kIdVcvt, //!< Instruction 'vcvt' {ASIMD & FP & FP16CONV}.
|
||||||
|
kIdVcvta, //!< Instruction 'vcvta' {ASIMD & FP16CONV}.
|
||||||
|
kIdVcvtb, //!< Instruction 'vcvtb' {BF16 & FP16CONV}.
|
||||||
|
kIdVcvtm, //!< Instruction 'vcvtm' {ASIMD & FP16CONV}.
|
||||||
|
kIdVcvtn, //!< Instruction 'vcvtn' {ASIMD & FP16CONV}.
|
||||||
|
kIdVcvtp, //!< Instruction 'vcvtp' {ASIMD & FP16CONV}.
|
||||||
|
kIdVcvtr, //!< Instruction 'vcvtr' {FP & FP16CONV}.
|
||||||
|
kIdVcvtt, //!< Instruction 'vcvtt' {BF16 & FP16CONV}.
|
||||||
|
kIdVdiv, //!< Instruction 'vdiv' {FP ~FP16}.
|
||||||
|
kIdVdot, //!< Instruction 'vdot' {BF16}.
|
||||||
|
kIdVdup, //!< Instruction 'vdup' {ASIMD}.
|
||||||
|
kIdVeor, //!< Instruction 'veor' {ASIMD}.
|
||||||
|
kIdVext, //!< Instruction 'vext' {ASIMD}.
|
||||||
|
kIdVfma, //!< Instruction 'vfma' {ASIMD & VFPv4 ~FP16}.
|
||||||
|
kIdVfmab, //!< Instruction 'vfmab' {BF16}.
|
||||||
|
kIdVfmal, //!< Instruction 'vfmal' {FHM}.
|
||||||
|
kIdVfmat, //!< Instruction 'vfmat' {BF16}.
|
||||||
|
kIdVfms, //!< Instruction 'vfms' {ASIMD & VFPv4 ~FP16}.
|
||||||
|
kIdVfmsl, //!< Instruction 'vfmsl' {FHM}.
|
||||||
|
kIdVfnma, //!< Instruction 'vfnma' {VFPv4 ~FP16}.
|
||||||
|
kIdVfnms, //!< Instruction 'vfnms' {VFPv4 ~FP16}.
|
||||||
|
kIdVhadd, //!< Instruction 'vhadd' {ASIMD}.
|
||||||
|
kIdVhsub, //!< Instruction 'vhsub' {ASIMD}.
|
||||||
|
kIdVins, //!< Instruction 'vins' {ASIMD ~FP16}.
|
||||||
|
kIdVjcvt, //!< Instruction 'vjcvt' {JSCVT}.
|
||||||
|
kIdVld1, //!< Instruction 'vld1' {ASIMD}.
|
||||||
|
kIdVld1r, //!< Instruction 'vld1r' {ASIMD}.
|
||||||
|
kIdVld2, //!< Instruction 'vld2' {ASIMD}.
|
||||||
|
kIdVld2r, //!< Instruction 'vld2r' {ASIMD}.
|
||||||
|
kIdVld3, //!< Instruction 'vld3' {ASIMD}.
|
||||||
|
kIdVld3r, //!< Instruction 'vld3r' {ASIMD}.
|
||||||
|
kIdVld4, //!< Instruction 'vld4' {ASIMD}.
|
||||||
|
kIdVld4r, //!< Instruction 'vld4r' {ASIMD}.
|
||||||
|
kIdVldmdb, //!< Instruction 'vldmdb' {ASIMD}.
|
||||||
|
kIdVldmia, //!< Instruction 'vldmia' {ASIMD}.
|
||||||
|
kIdVldr, //!< Instruction 'vldr' {FP ~FP16}.
|
||||||
|
kIdVmax, //!< Instruction 'vmax' {ASIMD ~FP16}.
|
||||||
|
kIdVmaxnm, //!< Instruction 'vmaxnm' {ASIMD ~FP16}.
|
||||||
|
kIdVmin, //!< Instruction 'vmin' {ASIMD ~FP16}.
|
||||||
|
kIdVminnm, //!< Instruction 'vminnm' {ASIMD ~FP16}.
|
||||||
|
kIdVmla, //!< Instruction 'vmla' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVmlal, //!< Instruction 'vmlal' {ASIMD}.
|
||||||
|
kIdVmls, //!< Instruction 'vmls' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVmlsl, //!< Instruction 'vmlsl' {ASIMD}.
|
||||||
|
kIdVmmla, //!< Instruction 'vmmla' {BF16}.
|
||||||
|
kIdVmov, //!< Instruction 'vmov' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVmovl, //!< Instruction 'vmovl' {ASIMD}.
|
||||||
|
kIdVmovn, //!< Instruction 'vmovn' {ASIMD}.
|
||||||
|
kIdVmovx, //!< Instruction 'vmovx' {FP ~FP16}.
|
||||||
|
kIdVmul, //!< Instruction 'vmul' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVmull, //!< Instruction 'vmull' {ASIMD}.
|
||||||
|
kIdVmvn, //!< Instruction 'vmvn' {ASIMD}.
|
||||||
|
kIdVneg, //!< Instruction 'vneg' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVnmla, //!< Instruction 'vnmla' {FP ~FP16}.
|
||||||
|
kIdVnmls, //!< Instruction 'vnmls' {FP ~FP16}.
|
||||||
|
kIdVnmul, //!< Instruction 'vnmul' {FP ~FP16}.
|
||||||
|
kIdVorn, //!< Instruction 'vorn' {ASIMD}.
|
||||||
|
kIdVorr, //!< Instruction 'vorr' {ASIMD}.
|
||||||
|
kIdVpadal, //!< Instruction 'vpadal' {ASIMD}.
|
||||||
|
kIdVpadd, //!< Instruction 'vpadd' {ASIMD ~FP16}.
|
||||||
|
kIdVpaddl, //!< Instruction 'vpaddl' {ASIMD}.
|
||||||
|
kIdVpmax, //!< Instruction 'vpmax' {ASIMD ~FP16}.
|
||||||
|
kIdVpmin, //!< Instruction 'vpmin' {ASIMD ~FP16}.
|
||||||
|
kIdVpop, //!< Instruction 'vpop' {ASIMD}.
|
||||||
|
kIdVpush, //!< Instruction 'vpush' {ASIMD}.
|
||||||
|
kIdVqabs, //!< Instruction 'vqabs' {ASIMD}.
|
||||||
|
kIdVqadd, //!< Instruction 'vqadd' {ASIMD}.
|
||||||
|
kIdVqdmlal, //!< Instruction 'vqdmlal' {ASIMD}.
|
||||||
|
kIdVqdmlsl, //!< Instruction 'vqdmlsl' {ASIMD}.
|
||||||
|
kIdVqdmulh, //!< Instruction 'vqdmulh' {ASIMD}.
|
||||||
|
kIdVqdmull, //!< Instruction 'vqdmull' {ASIMD}.
|
||||||
|
kIdVqmovn, //!< Instruction 'vqmovn' {ASIMD}.
|
||||||
|
kIdVqmovun, //!< Instruction 'vqmovun' {ASIMD}.
|
||||||
|
kIdVqneg, //!< Instruction 'vqneg' {ASIMD}.
|
||||||
|
kIdVqrdmlah, //!< Instruction 'vqrdmlah' {RDM}.
|
||||||
|
kIdVqrdmlsh, //!< Instruction 'vqrdmlsh' {RDM}.
|
||||||
|
kIdVqrdmulh, //!< Instruction 'vqrdmulh' {ASIMD}.
|
||||||
|
kIdVqrshl, //!< Instruction 'vqrshl' {ASIMD}.
|
||||||
|
kIdVqrshrn, //!< Instruction 'vqrshrn' {ASIMD}.
|
||||||
|
kIdVqrshrun, //!< Instruction 'vqrshrun' {ASIMD}.
|
||||||
|
kIdVqshl, //!< Instruction 'vqshl' {ASIMD}.
|
||||||
|
kIdVqshlu, //!< Instruction 'vqshlu' {ASIMD}.
|
||||||
|
kIdVqshrn, //!< Instruction 'vqshrn' {ASIMD}.
|
||||||
|
kIdVqshrun, //!< Instruction 'vqshrun' {ASIMD}.
|
||||||
|
kIdVqsub, //!< Instruction 'vqsub' {ASIMD}.
|
||||||
|
kIdVraddhn, //!< Instruction 'vraddhn' {ASIMD}.
|
||||||
|
kIdVrecpe, //!< Instruction 'vrecpe' {ASIMD ~FP16}.
|
||||||
|
kIdVrecps, //!< Instruction 'vrecps' {ASIMD ~FP16}.
|
||||||
|
kIdVrev16, //!< Instruction 'vrev16' {ASIMD}.
|
||||||
|
kIdVrev32, //!< Instruction 'vrev32' {ASIMD}.
|
||||||
|
kIdVrev64, //!< Instruction 'vrev64' {ASIMD}.
|
||||||
|
kIdVrhadd, //!< Instruction 'vrhadd' {ASIMD}.
|
||||||
|
kIdVrinta, //!< Instruction 'vrinta' {ASIMD ~FP16}.
|
||||||
|
kIdVrintm, //!< Instruction 'vrintm' {ASIMD ~FP16}.
|
||||||
|
kIdVrintn, //!< Instruction 'vrintn' {ASIMD ~FP16}.
|
||||||
|
kIdVrintp, //!< Instruction 'vrintp' {ASIMD ~FP16}.
|
||||||
|
kIdVrintr, //!< Instruction 'vrintr' {ASIMD ~FP16}.
|
||||||
|
kIdVrintx, //!< Instruction 'vrintx' {ASIMD ~FP16}.
|
||||||
|
kIdVrintz, //!< Instruction 'vrintz' {ASIMD ~FP16}.
|
||||||
|
kIdVrshl, //!< Instruction 'vrshl' {ASIMD}.
|
||||||
|
kIdVrshr, //!< Instruction 'vrshr' {ASIMD}.
|
||||||
|
kIdVrshrn, //!< Instruction 'vrshrn' {ASIMD}.
|
||||||
|
kIdVrsqrte, //!< Instruction 'vrsqrte' {ASIMD ~FP16}.
|
||||||
|
kIdVrsqrts, //!< Instruction 'vrsqrts' {ASIMD ~FP16}.
|
||||||
|
kIdVrsra, //!< Instruction 'vrsra' {ASIMD}.
|
||||||
|
kIdVrsubhn, //!< Instruction 'vrsubhn' {ASIMD}.
|
||||||
|
kIdVsdot, //!< Instruction 'vsdot' {DOTPROD}.
|
||||||
|
kIdVseleq, //!< Instruction 'vseleq' {ASIMD ~FP16}.
|
||||||
|
kIdVselge, //!< Instruction 'vselge' {ASIMD ~FP16}.
|
||||||
|
kIdVselgt, //!< Instruction 'vselgt' {ASIMD ~FP16}.
|
||||||
|
kIdVselvs, //!< Instruction 'vselvs' {ASIMD ~FP16}.
|
||||||
|
kIdVshl, //!< Instruction 'vshl' {ASIMD}.
|
||||||
|
kIdVshll, //!< Instruction 'vshll' {ASIMD}.
|
||||||
|
kIdVshr, //!< Instruction 'vshr' {ASIMD}.
|
||||||
|
kIdVshrn, //!< Instruction 'vshrn' {ASIMD}.
|
||||||
|
kIdVsli, //!< Instruction 'vsli' {ASIMD}.
|
||||||
|
kIdVsmmla, //!< Instruction 'vsmmla' {I8MM}.
|
||||||
|
kIdVsqrt, //!< Instruction 'vsqrt' {FP ~FP16}.
|
||||||
|
kIdVsra, //!< Instruction 'vsra' {ASIMD}.
|
||||||
|
kIdVsri, //!< Instruction 'vsri' {ASIMD}.
|
||||||
|
kIdVst1, //!< Instruction 'vst1' {ASIMD}.
|
||||||
|
kIdVst2, //!< Instruction 'vst2' {ASIMD}.
|
||||||
|
kIdVst3, //!< Instruction 'vst3' {ASIMD}.
|
||||||
|
kIdVst4, //!< Instruction 'vst4' {ASIMD}.
|
||||||
|
kIdVstmdb, //!< Instruction 'vstmdb' {ASIMD}.
|
||||||
|
kIdVstmia, //!< Instruction 'vstmia' {ASIMD}.
|
||||||
|
kIdVstr, //!< Instruction 'vstr' {FP ~FP16}.
|
||||||
|
kIdVsub, //!< Instruction 'vsub' {ASIMD & FP ~FP16}.
|
||||||
|
kIdVsubhn, //!< Instruction 'vsubhn' {ASIMD}.
|
||||||
|
kIdVsubl, //!< Instruction 'vsubl' {ASIMD}.
|
||||||
|
kIdVsubw, //!< Instruction 'vsubw' {ASIMD}.
|
||||||
|
kIdVsudot, //!< Instruction 'vsudot' {I8MM}.
|
||||||
|
kIdVswp, //!< Instruction 'vswp' {ASIMD}.
|
||||||
|
kIdVtbl, //!< Instruction 'vtbl' {ASIMD}.
|
||||||
|
kIdVtbx, //!< Instruction 'vtbx' {ASIMD}.
|
||||||
|
kIdVtrn, //!< Instruction 'vtrn' {ASIMD}.
|
||||||
|
kIdVtst, //!< Instruction 'vtst' {ASIMD}.
|
||||||
|
kIdVudot, //!< Instruction 'vudot' {DOTPROD}.
|
||||||
|
kIdVummla, //!< Instruction 'vummla' {I8MM}.
|
||||||
|
kIdVusdot, //!< Instruction 'vusdot' {I8MM}.
|
||||||
|
kIdVusmmla, //!< Instruction 'vusmmla' {I8MM}.
|
||||||
|
kIdVuzp, //!< Instruction 'vuzp' {ASIMD}.
|
||||||
|
kIdVzip, //!< Instruction 'vzip' {ASIMD}.
|
||||||
|
kIdWfe, //!< Instruction 'wfe'.
|
||||||
|
kIdWfi, //!< Instruction 'wfi'.
|
||||||
|
kIdYield, //!< Instruction 'yield'.
|
||||||
|
_kIdCount
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ${a32::InstId:End}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Tests whether the `inst_id` is defined (counts also Inst::kIdNone, which must be zero).
|
||||||
|
//!
|
||||||
|
//! \note This function required identifier to be without modifiers. If the given instruction id contains modifiers
|
||||||
|
//! it would return false as modifiers overflow `_kIdCount`.
|
||||||
|
static constexpr inline bool is_defined_id(InstId inst_id) noexcept {
|
||||||
|
return inst_id < _kIdCount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32GLOBALS_H_INCLUDED
|
||||||
223
asmjit/arm/a32instapi.cpp
Normal file
223
asmjit/arm/a32instapi.cpp
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core/api-build_p.h>
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
|
||||||
|
#include <asmjit/support/support_p.h>
|
||||||
|
#include <asmjit/arm/a32instapi_p.h>
|
||||||
|
#include <asmjit/arm/a32instdb_p.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
namespace InstInternal {
|
||||||
|
|
||||||
|
// a32::InstAPI - Text
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_TEXT
|
||||||
|
Error inst_id_to_string(InstId inst_id, InstStringifyOptions options, String& output) noexcept {
|
||||||
|
uint32_t real_id = inst_id & uint32_t(InstIdParts::kRealId);
|
||||||
|
if (ASMJIT_UNLIKELY(!Inst::is_defined_id(real_id)))
|
||||||
|
return make_error(Error::kInvalidInstruction);
|
||||||
|
|
||||||
|
return InstNameUtils::decode(InstDB::_inst_name_index_table[real_id], options, InstDB::_inst_name_string_table, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstId string_to_inst_id(const char* s, size_t len) noexcept {
|
||||||
|
return InstNameUtils::find_instruction(s, len, InstDB::_inst_name_index_table, InstDB::_inst_name_string_table, InstDB::inst_name_index);
|
||||||
|
}
|
||||||
|
#endif // !ASMJIT_NO_TEXT
|
||||||
|
|
||||||
|
// a32::InstAPI - Validation
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_VALIDATION
|
||||||
|
Error validate(const BaseInst& inst, const Operand_* operands, size_t op_count, ValidationFlags validation_flags) noexcept {
|
||||||
|
// TODO: AArch32 tooling.
|
||||||
|
Support::maybe_unused(inst, operands, op_count, validation_flags);
|
||||||
|
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
#endif // !ASMJIT_NO_VALIDATION
|
||||||
|
|
||||||
|
// a32::InstAPI - Introspection
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_INTROSPECTION
|
||||||
|
|
||||||
|
struct InstRWInfoRecord {
|
||||||
|
//! RWX information for each operand.
|
||||||
|
uint8_t rwx[Globals::kMaxOpCount];
|
||||||
|
//! Index to InstRWFlagsRecord table.
|
||||||
|
uint8_t rw_flags_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InstRWFlagsRecord {
|
||||||
|
//! Read flags.
|
||||||
|
CpuRWFlags r;
|
||||||
|
//! Written flags.
|
||||||
|
CpuRWFlags w;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ${a32::RWInfo:Begin}
|
||||||
|
// ------------------- Automatically generated, do not edit -------------------
|
||||||
|
static const constexpr InstRWInfoRecord inst_rw_info_data[] = {
|
||||||
|
#define R uint8_t(OpRWFlags::kRead)
|
||||||
|
#define W uint8_t(OpRWFlags::kWrite)
|
||||||
|
#define X uint8_t(OpRWFlags::kRW)
|
||||||
|
|
||||||
|
{{ R, R, R, R, R, R }, 0}, // #0 [ref=105x]
|
||||||
|
{{ W, R, R, R, R, R }, 1}, // #1 [ref=3x]
|
||||||
|
{{ W, R, R, R, R, R }, 2}, // #2 [ref=1x]
|
||||||
|
{{ W, R, R, R, R, R }, 0}, // #3 [ref=243x]
|
||||||
|
{{ W, R, R, R, R, R }, 3}, // #4 [ref=5x]
|
||||||
|
{{ X, R, R, R, R, R }, 0}, // #5 [ref=32x]
|
||||||
|
{{ W, R, R, R, R, R }, 4}, // #6 [ref=11x]
|
||||||
|
{{ R, R, R, R, R, R }, 3}, // #7 [ref=2x]
|
||||||
|
{{ W, W, R, R, R, R }, 0}, // #8 [ref=6x]
|
||||||
|
{{ W, R, R, R, R, R }, 5}, // #9 [ref=2x]
|
||||||
|
{{ R, R, W, R, R, R }, 0}, // #10 [ref=2x]
|
||||||
|
{{ R, R, W, W, R, R }, 0}, // #11 [ref=2x]
|
||||||
|
{{ W, R, R, R, R, R }, 6}, // #12 [ref=20x]
|
||||||
|
{{ W, R, R, R, R, R }, 7}, // #13 [ref=12x]
|
||||||
|
{{ W, R, R, R, R, R }, 8}, // #14 [ref=1x]
|
||||||
|
{{ X, X, R, R, R, R }, 0}, // #15 [ref=13x]
|
||||||
|
{{ X, X, R, R, R, R }, 5}, // #16 [ref=2x]
|
||||||
|
{{ X, X, R, R, R, R }, 6}, // #17 [ref=2x]
|
||||||
|
{{ W, W, R, R, R, R }, 5}, // #18 [ref=2x]
|
||||||
|
{{ R, R, R, R, R, R }, 4}, // #19 [ref=2x]
|
||||||
|
{{ W, W, W, R, R, R }, 0}, // #20 [ref=2x]
|
||||||
|
{{ W, W, W, W, R, R }, 0} // #21 [ref=2x]
|
||||||
|
|
||||||
|
#undef R
|
||||||
|
#undef W
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
|
static const constexpr InstRWFlagsRecord instRWFlagsData[] = {
|
||||||
|
{ CpuRWFlags::kNone, CpuRWFlags::kNone }, // #0 [ref=407x]
|
||||||
|
{ CpuRWFlags::kARM_C, CpuRWFlags::kNone }, // #1 [ref=3x]
|
||||||
|
{ CpuRWFlags::kARM_C, CpuRWFlags::kARM_C | CpuRWFlags::kARM_N | CpuRWFlags::kARM_V | CpuRWFlags::kARM_Z }, // #2 [ref=1x]
|
||||||
|
{ CpuRWFlags::kNone, CpuRWFlags::kARM_C | CpuRWFlags::kARM_N | CpuRWFlags::kARM_V | CpuRWFlags::kARM_Z }, // #3 [ref=7x]
|
||||||
|
{ CpuRWFlags::kNone, CpuRWFlags::kARM_C | CpuRWFlags::kARM_N | CpuRWFlags::kARM_Z }, // #4 [ref=13x]
|
||||||
|
{ CpuRWFlags::kNone, CpuRWFlags::kARM_N | CpuRWFlags::kARM_Z }, // #5 [ref=6x]
|
||||||
|
{ CpuRWFlags::kARM_Q, CpuRWFlags::kARM_Q }, // #6 [ref=22x]
|
||||||
|
{ CpuRWFlags::kNone, CpuRWFlags::kARM_GE }, // #7 [ref=12x]
|
||||||
|
{ CpuRWFlags::kARM_GE, CpuRWFlags::kNone } // #8 [ref=1x]
|
||||||
|
};
|
||||||
|
|
||||||
|
static const constexpr uint8_t instRWInfoIndex[] {
|
||||||
|
0, 1, 2, 3, 4, 3, 5, 5, 3, 3, 3, 6, 3, 6, 0, 3, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 7, 0, 0, 0, 3, 3, 3, 3, 3, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 8, 3, 3, 0, 0, 0, 0,
|
||||||
|
3, 3, 3, 8, 3, 3, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 6, 0, 0, 0, 0, 3, 9, 3, 0xFFu, 0xFFu, 5, 3, 10, 10, 11, 11, 3, 0,
|
||||||
|
3, 9, 3, 6, 0, 3, 6, 3, 6, 3, 3, 0, 0, 0, 0xFFu, 0, 0, 12, 3, 3, 3, 12, 12, 3, 12, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 6,
|
||||||
|
1, 6, 3, 4, 3, 4, 13, 13, 13, 0, 1, 4, 3, 3, 14, 0, 0, 0, 0, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 0, 12, 12,
|
||||||
|
12, 12, 15, 15, 15, 15, 15, 16, 15, 15, 12, 12, 12, 12, 12, 12, 17, 17, 3, 3, 3, 3, 3, 3, 12, 12, 3, 3, 8, 18, 3, 3, 3,
|
||||||
|
3, 3, 3, 0, 0, 0, 0, 12, 12, 13, 0, 13, 13, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 3, 4, 0,
|
||||||
|
3, 3, 3, 3, 3, 3, 0, 0, 19, 19, 13, 13, 13, 3, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 16, 8, 18, 3, 3, 3, 3, 3, 3, 3, 3, 12,
|
||||||
|
12, 13, 13, 13, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0xFFu, 0xFFu, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
5, 0, 0, 3, 0xFFu, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 5, 3, 5, 5, 5, 5, 3, 3, 3, 3, 0xFFu, 0xFFu, 0xFFu, 8, 20,
|
||||||
|
20, 21, 21, 0, 0, 3, 3, 3, 3, 3, 5, 5, 5, 5, 3, 0xFFu, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, 0xFFu, 0xFFu, 5, 3, 3, 3, 3, 0, 0,
|
||||||
|
3, 3, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 5, 5, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 15, 3, 3, 15, 3, 3, 3, 3, 3, 15, 15, 0,
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ${a32::RWInfo:End}
|
||||||
|
|
||||||
|
Error query_rw_info(const BaseInst& inst, const Operand_* operands, size_t op_count, InstRWInfo* out) noexcept {
|
||||||
|
uint32_t inst_id = inst.inst_id();
|
||||||
|
uint32_t real_id = inst_id & uint32_t(InstIdParts::kRealId);
|
||||||
|
|
||||||
|
if (ASMJIT_UNLIKELY(!Inst::is_defined_id(real_id)))
|
||||||
|
return make_error(Error::kInvalidInstruction);
|
||||||
|
|
||||||
|
out->_inst_flags = InstRWFlags::kNone;
|
||||||
|
out->_op_count = uint8_t(op_count);
|
||||||
|
out->_rm_feature = 0;
|
||||||
|
out->_extra_reg.reset();
|
||||||
|
|
||||||
|
out->_read_flags = CpuRWFlags::kNone;
|
||||||
|
out->_write_flags = CpuRWFlags::kNone;
|
||||||
|
|
||||||
|
size_t index = instRWInfoIndex[real_id];
|
||||||
|
if (index < 0xFFu) {
|
||||||
|
const InstRWInfoRecord& rwInfo = inst_rw_info_data[index];
|
||||||
|
size_t rw_flags_index = rwInfo.rw_flags_index;
|
||||||
|
|
||||||
|
out->_read_flags = instRWFlagsData[rw_flags_index].r;
|
||||||
|
out->_write_flags = instRWFlagsData[rw_flags_index].w;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < op_count; i++) {
|
||||||
|
uint32_t access = rwInfo.rwx[i];
|
||||||
|
|
||||||
|
OpRWInfo& rwOp = out->_operands[i];
|
||||||
|
const Operand_& srcOp = operands[i];
|
||||||
|
|
||||||
|
if (!srcOp.is_reg_or_reg_list_or_mem()) {
|
||||||
|
rwOp.reset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rwOp._op_flags = OpRWFlags(access);
|
||||||
|
rwOp._phys_id = Reg::kIdBad;
|
||||||
|
rwOp._rm_size = 0;
|
||||||
|
rwOp._reset_reserved();
|
||||||
|
|
||||||
|
uint64_t r_byte_mask = rwOp.is_read() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
|
||||||
|
uint64_t w_byte_mask = rwOp.is_write() ? 0xFFFFFFFFFFFFFFFFu : 0x0000000000000000u;
|
||||||
|
|
||||||
|
rwOp._read_byte_mask = r_byte_mask;
|
||||||
|
rwOp._write_byte_mask = w_byte_mask;
|
||||||
|
rwOp._extend_byte_mask = 0;
|
||||||
|
rwOp._consecutive_lead_count = 0;
|
||||||
|
|
||||||
|
if (srcOp.is_mem()) {
|
||||||
|
const Mem& mem_op = srcOp.as<Mem>();
|
||||||
|
|
||||||
|
if (mem_op.has_base()) {
|
||||||
|
rwOp.add_op_flags(OpRWFlags::kMemBaseRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem_op.has_index()) {
|
||||||
|
rwOp.add_op_flags(mem_op.is_pre_or_post() ? OpRWFlags::kMemIndexRW : OpRWFlags::kMemIndexRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (srcOp.as<Vec>().has_element_index()) {
|
||||||
|
// Only part of the vector is accessed if element index [] is used.
|
||||||
|
uint32_t elementSize = data_type_size(inst.arm_dt());
|
||||||
|
uint32_t element_index = srcOp.as<Vec>().element_index();
|
||||||
|
|
||||||
|
// NOTE: DataType must be present otherwise it's impossible to calculate the access flags.
|
||||||
|
if (!elementSize)
|
||||||
|
return make_error(Error::kInvalidInstruction);
|
||||||
|
|
||||||
|
uint64_t accessMask = uint64_t(Support::lsb_mask<uint32_t>(elementSize)) << (element_index * elementSize);
|
||||||
|
rwOp._read_byte_mask &= accessMask;
|
||||||
|
rwOp._write_byte_mask &= accessMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO: [ARM] Not finished introspection.
|
||||||
|
return make_error(Error::kInvalidState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error query_features(const BaseInst& inst, const Operand_* operands, size_t op_count, CpuFeatures* out) noexcept {
|
||||||
|
// TODO: AArch32 tooling.
|
||||||
|
Support::maybe_unused(inst, operands, op_count, out);
|
||||||
|
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
#endif // !ASMJIT_NO_INTROSPECTION
|
||||||
|
|
||||||
|
} // {InstInternal}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32
|
||||||
42
asmjit/arm/a32instapi_p.h
Normal file
42
asmjit/arm/a32instapi_p.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32INSTAPI_H_P_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32INSTAPI_H_P_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/codeholder.h>
|
||||||
|
#include <asmjit/arm/a32instdb_p.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \cond INTERNAL
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
namespace InstInternal {
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_TEXT
|
||||||
|
Error ASMJIT_CDECL inst_id_to_string(InstId inst_id, InstStringifyOptions options, String& output) noexcept;
|
||||||
|
InstId ASMJIT_CDECL string_to_inst_id(const char* s, size_t len) noexcept;
|
||||||
|
#endif // !ASMJIT_NO_TEXT
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_VALIDATION
|
||||||
|
Error ASMJIT_CDECL validate(const BaseInst& inst, const Operand_* operands, size_t op_count, ValidationFlags validation_flags) noexcept;
|
||||||
|
#endif // !ASMJIT_NO_VALIDATION
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_INTROSPECTION
|
||||||
|
Error ASMJIT_CDECL query_rw_info(const BaseInst& inst, const Operand_* operands, size_t op_count, InstRWInfo* out) noexcept;
|
||||||
|
Error ASMJIT_CDECL query_features(const BaseInst& inst, const Operand_* operands, size_t op_count, CpuFeatures* out) noexcept;
|
||||||
|
#endif // !ASMJIT_NO_INTROSPECTION
|
||||||
|
|
||||||
|
} // {InstInternal}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32INSTAPI_H_P_INCLUDED
|
||||||
|
|
||||||
547
asmjit/arm/a32instdb.cpp
Normal file
547
asmjit/arm/a32instdb.cpp
Normal file
@@ -0,0 +1,547 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#include <asmjit/core/api-build_p.h>
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
|
||||||
|
#include <asmjit/arm/a32instdb_p.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
// a32::InstDB - Id <-> Name
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_TEXT
|
||||||
|
// ${a32::NameData:Begin}
|
||||||
|
// ------------------- Automatically generated, do not edit -------------------
|
||||||
|
const InstNameIndex InstDB::inst_name_index = {{
|
||||||
|
{ Inst::kIdAdc , Inst::kIdAsrs + 1 },
|
||||||
|
{ Inst::kIdB , Inst::kIdBxj + 1 },
|
||||||
|
{ Inst::kIdCbnz , Inst::kIdCsdb + 1 },
|
||||||
|
{ Inst::kIdDbg , Inst::kIdDsb + 1 },
|
||||||
|
{ Inst::kIdEor , Inst::kIdEsb + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 },
|
||||||
|
{ Inst::kIdHlt , Inst::kIdHvc + 1 },
|
||||||
|
{ Inst::kIdIsb , Inst::kIdItttt + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 },
|
||||||
|
{ Inst::kIdLda , Inst::kIdLsrs + 1 },
|
||||||
|
{ Inst::kIdMcr , Inst::kIdMvns + 1 },
|
||||||
|
{ Inst::kIdNop , Inst::kIdNop + 1 },
|
||||||
|
{ Inst::kIdOrn , Inst::kIdOrrs + 1 },
|
||||||
|
{ Inst::kIdPkhbt , Inst::kIdPush + 1 },
|
||||||
|
{ Inst::kIdQadd , Inst::kIdQsub8 + 1 },
|
||||||
|
{ Inst::kIdRbit , Inst::kIdRscs + 1 },
|
||||||
|
{ Inst::kIdSadd16 , Inst::kIdSxth + 1 },
|
||||||
|
{ Inst::kIdTbb , Inst::kIdTst + 1 },
|
||||||
|
{ Inst::kIdUadd16 , Inst::kIdUxth + 1 },
|
||||||
|
{ Inst::kIdVaba , Inst::kIdVzip + 1 },
|
||||||
|
{ Inst::kIdWfe , Inst::kIdWfi + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 },
|
||||||
|
{ Inst::kIdYield , Inst::kIdYield + 1 },
|
||||||
|
{ Inst::kIdNone , Inst::kIdNone + 1 }
|
||||||
|
}, uint16_t(9)};
|
||||||
|
|
||||||
|
const char InstDB::_inst_name_string_table[] =
|
||||||
|
"sha256su01h2vqrdmlaulhvqrshruncrc32cbwsha1sha1sushadd1shsub1smlalbtdxtbttsmlslsx"
|
||||||
|
"tab1uhadd1uhsub1uqadd1uqsub1uxtab1vqdvqdmvqdmulvqmovvraddhvrsqrtevrsubhvusmsadd1"
|
||||||
|
"8ssat1ssub1sxtb1uadd1usadausat1usub1uxtb1vrev164";
|
||||||
|
|
||||||
|
|
||||||
|
const uint32_t InstDB::_inst_name_index_table[] = {
|
||||||
|
0x80000000, // Small ''.
|
||||||
|
0x80000C81, // Small 'adc'.
|
||||||
|
0x80098C81, // Small 'adcs'.
|
||||||
|
0x80001081, // Small 'add'.
|
||||||
|
0x80099081, // Small 'adds'.
|
||||||
|
0x80004881, // Small 'adr'.
|
||||||
|
0x80024CA1, // Small 'aesd'.
|
||||||
|
0x8002CCA1, // Small 'aese'.
|
||||||
|
0x86D4CCA1, // Small 'aesimc'.
|
||||||
|
0x8036CCA1, // Small 'aesmc'.
|
||||||
|
0x800011C1, // Small 'and'.
|
||||||
|
0x800991C1, // Small 'ands'.
|
||||||
|
0x80004A61, // Small 'asr'.
|
||||||
|
0x8009CA61, // Small 'asrs'.
|
||||||
|
0x80000002, // Small 'b'.
|
||||||
|
0x80000CC2, // Small 'bfc'.
|
||||||
|
0x800024C2, // Small 'bfi'.
|
||||||
|
0x80000D22, // Small 'bic'.
|
||||||
|
0x80098D22, // Small 'bics'.
|
||||||
|
0x800A4162, // Small 'bkpt'.
|
||||||
|
0x80000182, // Small 'bl'.
|
||||||
|
0x80006182, // Small 'blx'.
|
||||||
|
0x80000302, // Small 'bx'.
|
||||||
|
0x80002B02, // Small 'bxj'.
|
||||||
|
0x800D3843, // Small 'cbnz'.
|
||||||
|
0x80006843, // Small 'cbz'.
|
||||||
|
0x84814983, // Small 'clrbhb'.
|
||||||
|
0x8182C983, // Small 'clrex'.
|
||||||
|
0x80006983, // Small 'clz'.
|
||||||
|
0x800039A3, // Small 'cmn'.
|
||||||
|
0x800041A3, // Small 'cmp'.
|
||||||
|
0x80004E03, // Small 'cps'.
|
||||||
|
0x8044CE03, // Small 'cpsid'.
|
||||||
|
0x8054CE03, // Small 'cpsie'.
|
||||||
|
0x85DF0E43, // Small 'crc32b'.
|
||||||
|
0x0000701E, // Large 'crc32cb'.
|
||||||
|
0x1001601E, // Large 'crc32c|h'.
|
||||||
|
0x1025601E, // Large 'crc32c|w'.
|
||||||
|
0x91DF0E43, // Small 'crc32h'.
|
||||||
|
0xAFDF0E43, // Small 'crc32w'.
|
||||||
|
0x80011263, // Small 'csdb'.
|
||||||
|
0x80001C44, // Small 'dbg'.
|
||||||
|
0x81C9C064, // Small 'dcps1'.
|
||||||
|
0x81D9C064, // Small 'dcps2'.
|
||||||
|
0x81E9C064, // Small 'dcps3'.
|
||||||
|
0x800009A4, // Small 'dmb'.
|
||||||
|
0x80000A64, // Small 'dsb'.
|
||||||
|
0x800049E5, // Small 'eor'.
|
||||||
|
0x8009C9E5, // Small 'eors'.
|
||||||
|
0x800A1645, // Small 'eret'.
|
||||||
|
0x80000A65, // Small 'esb'.
|
||||||
|
0x80005188, // Small 'hlt'.
|
||||||
|
0x80000EC8, // Small 'hvc'.
|
||||||
|
0x80000A69, // Small 'isb'.
|
||||||
|
0x80000289, // Small 'it'.
|
||||||
|
0x80001689, // Small 'ite'.
|
||||||
|
0x80029689, // Small 'itee'.
|
||||||
|
0x80529689, // Small 'iteee'.
|
||||||
|
0x81429689, // Small 'iteet'.
|
||||||
|
0x800A1689, // Small 'itet'.
|
||||||
|
0x805A1689, // Small 'itete'.
|
||||||
|
0x814A1689, // Small 'itett'.
|
||||||
|
0x80005289, // Small 'itt'.
|
||||||
|
0x8002D289, // Small 'itte'.
|
||||||
|
0x8052D289, // Small 'ittee'.
|
||||||
|
0x8142D289, // Small 'ittet'.
|
||||||
|
0x800A5289, // Small 'ittt'.
|
||||||
|
0x805A5289, // Small 'ittte'.
|
||||||
|
0x814A5289, // Small 'itttt'.
|
||||||
|
0x8000048C, // Small 'lda'.
|
||||||
|
0x8001048C, // Small 'ldab'.
|
||||||
|
0x8182848C, // Small 'ldaex'.
|
||||||
|
0x8582848C, // Small 'ldaexb'.
|
||||||
|
0x8982848C, // Small 'ldaexd'.
|
||||||
|
0x9182848C, // Small 'ldaexh'.
|
||||||
|
0x8004048C, // Small 'ldah'.
|
||||||
|
0x8012348C, // Small 'ldmda'.
|
||||||
|
0x8022348C, // Small 'ldmdb'.
|
||||||
|
0x8014B48C, // Small 'ldmia'.
|
||||||
|
0x8024B48C, // Small 'ldmib'.
|
||||||
|
0x8000488C, // Small 'ldr'.
|
||||||
|
0x8001488C, // Small 'ldrb'.
|
||||||
|
0x8141488C, // Small 'ldrbt'.
|
||||||
|
0x8002488C, // Small 'ldrd'.
|
||||||
|
0x8182C88C, // Small 'ldrex'.
|
||||||
|
0x8582C88C, // Small 'ldrexb'.
|
||||||
|
0x8982C88C, // Small 'ldrexd'.
|
||||||
|
0x9182C88C, // Small 'ldrexh'.
|
||||||
|
0x8004488C, // Small 'ldrh'.
|
||||||
|
0x8144488C, // Small 'ldrht'.
|
||||||
|
0x8029C88C, // Small 'ldrsb'.
|
||||||
|
0xA829C88C, // Small 'ldrsbt'.
|
||||||
|
0x8089C88C, // Small 'ldrsh'.
|
||||||
|
0xA889C88C, // Small 'ldrsht'.
|
||||||
|
0x800A488C, // Small 'ldrt'.
|
||||||
|
0x8000326C, // Small 'lsl'.
|
||||||
|
0x8009B26C, // Small 'lsls'.
|
||||||
|
0x80004A6C, // Small 'lsr'.
|
||||||
|
0x8009CA6C, // Small 'lsrs'.
|
||||||
|
0x8000486D, // Small 'mcr'.
|
||||||
|
0x800EC86D, // Small 'mcr2'.
|
||||||
|
0x8009486D, // Small 'mcrr'.
|
||||||
|
0x81D9486D, // Small 'mcrr2'.
|
||||||
|
0x8000058D, // Small 'mla'.
|
||||||
|
0x8009858D, // Small 'mlas'.
|
||||||
|
0x80004D8D, // Small 'mls'.
|
||||||
|
0x800059ED, // Small 'mov'.
|
||||||
|
0x8009D9ED, // Small 'movs'.
|
||||||
|
0x800A59ED, // Small 'movt'.
|
||||||
|
0x800BD9ED, // Small 'movw'.
|
||||||
|
0x80000E4D, // Small 'mrc'.
|
||||||
|
0x800E8E4D, // Small 'mrc2'.
|
||||||
|
0x8001CA4D, // Small 'mrrc'.
|
||||||
|
0x81D1CA4D, // Small 'mrrc2'.
|
||||||
|
0x80004E4D, // Small 'mrs'.
|
||||||
|
0x80004A6D, // Small 'msr'.
|
||||||
|
0x800032AD, // Small 'mul'.
|
||||||
|
0x8009B2AD, // Small 'muls'.
|
||||||
|
0x80003ACD, // Small 'mvn'.
|
||||||
|
0x8009BACD, // Small 'mvns'.
|
||||||
|
0x800041EE, // Small 'nop'.
|
||||||
|
0x80003A4F, // Small 'orn'.
|
||||||
|
0x8009BA4F, // Small 'orns'.
|
||||||
|
0x80004A4F, // Small 'orr'.
|
||||||
|
0x8009CA4F, // Small 'orrs'.
|
||||||
|
0x81412170, // Small 'pkhbt'.
|
||||||
|
0x802A2170, // Small 'pkhtb'.
|
||||||
|
0x80001190, // Small 'pld'.
|
||||||
|
0x800B9190, // Small 'pldw'.
|
||||||
|
0x80002590, // Small 'pli'.
|
||||||
|
0x800041F0, // Small 'pop'.
|
||||||
|
0x80214E70, // Small 'pssbb'.
|
||||||
|
0x80044EB0, // Small 'push'.
|
||||||
|
0x80021031, // Small 'qadd'.
|
||||||
|
0x10055061, // Large 'qadd1|6'.
|
||||||
|
0x10A04061, // Large 'qadd|8'.
|
||||||
|
0x800C4C31, // Small 'qasx'.
|
||||||
|
0x80420491, // Small 'qdadd'.
|
||||||
|
0x802ACC91, // Small 'qdsub'.
|
||||||
|
0x800C0671, // Small 'qsax'.
|
||||||
|
0x80015671, // Small 'qsub'.
|
||||||
|
0x10055067, // Large 'qsub1|6'.
|
||||||
|
0x10A04067, // Large 'qsub|8'.
|
||||||
|
0x800A2452, // Small 'rbit'.
|
||||||
|
0x800058B2, // Small 'rev'.
|
||||||
|
0x000050CA, // Large 'rev16'.
|
||||||
|
0x8089D8B2, // Small 'revsh'.
|
||||||
|
0x801214D2, // Small 'rfeda'.
|
||||||
|
0x802214D2, // Small 'rfedb'.
|
||||||
|
0x801494D2, // Small 'rfeia'.
|
||||||
|
0x802494D2, // Small 'rfeib'.
|
||||||
|
0x800049F2, // Small 'ror'.
|
||||||
|
0x8009C9F2, // Small 'rors'.
|
||||||
|
0x80006252, // Small 'rrx'.
|
||||||
|
0x8009E252, // Small 'rrxs'.
|
||||||
|
0x80000A72, // Small 'rsb'.
|
||||||
|
0x80098A72, // Small 'rsbs'.
|
||||||
|
0x80000E72, // Small 'rsc'.
|
||||||
|
0x80098E72, // Small 'rscs'.
|
||||||
|
0x1005509B, // Large 'sadd1|6'.
|
||||||
|
0x10A0409B, // Large 'sadd|8'.
|
||||||
|
0x800C4C33, // Small 'sasx'.
|
||||||
|
0x80000053, // Small 'sb'.
|
||||||
|
0x80000C53, // Small 'sbc'.
|
||||||
|
0x80098C53, // Small 'sbcs'.
|
||||||
|
0x800C1853, // Small 'sbfx'.
|
||||||
|
0x800B2493, // Small 'sdiv'.
|
||||||
|
0x800030B3, // Small 'sel'.
|
||||||
|
0x88E2D0B3, // Small 'setend'.
|
||||||
|
0x9C1850B3, // Small 'setpan'.
|
||||||
|
0x800058B3, // Small 'sev'.
|
||||||
|
0x800658B3, // Small 'sevl'.
|
||||||
|
0x803E0513, // Small 'sha1c'.
|
||||||
|
0x808E0513, // Small 'sha1h'.
|
||||||
|
0x80DE0513, // Small 'sha1m'.
|
||||||
|
0x810E0513, // Small 'sha1p'.
|
||||||
|
0x30064026, // Large 'sha1|su0'.
|
||||||
|
0x1009602A, // Large 'sha1su|1'.
|
||||||
|
0x10016000, // Large 'sha256|h'.
|
||||||
|
0x200A6000, // Large 'sha256|h2'.
|
||||||
|
0x00009000, // Large 'sha256su0'.
|
||||||
|
0x10098000, // Large 'sha256su|1'.
|
||||||
|
0x10056030, // Large 'shadd1|6'.
|
||||||
|
0x10A05030, // Large 'shadd|8'.
|
||||||
|
0x81898513, // Small 'shasx'.
|
||||||
|
0x8180CD13, // Small 'shsax'.
|
||||||
|
0x10056036, // Large 'shsub1|6'.
|
||||||
|
0x10A05036, // Large 'shsub|8'.
|
||||||
|
0x80000DB3, // Small 'smc'.
|
||||||
|
0x8420B1B3, // Small 'smlabb'.
|
||||||
|
0xA820B1B3, // Small 'smlabt'.
|
||||||
|
0x8040B1B3, // Small 'smlad'.
|
||||||
|
0xB040B1B3, // Small 'smladx'.
|
||||||
|
0x80C0B1B3, // Small 'smlal'.
|
||||||
|
0x1024603C, // Large 'smlalb|b'.
|
||||||
|
0x1042603C, // Large 'smlalb|t'.
|
||||||
|
0x88C0B1B3, // Small 'smlald'.
|
||||||
|
0x2043503C, // Large 'smlal|dx'.
|
||||||
|
0xA6C0B1B3, // Small 'smlals'.
|
||||||
|
0x2045503C, // Large 'smlal|tb'.
|
||||||
|
0x2047503C, // Large 'smlal|tt'.
|
||||||
|
0x8540B1B3, // Small 'smlatb'.
|
||||||
|
0xA940B1B3, // Small 'smlatt'.
|
||||||
|
0x8570B1B3, // Small 'smlawb'.
|
||||||
|
0xA970B1B3, // Small 'smlawt'.
|
||||||
|
0x8049B1B3, // Small 'smlsd'.
|
||||||
|
0xB049B1B3, // Small 'smlsdx'.
|
||||||
|
0x88C9B1B3, // Small 'smlsld'.
|
||||||
|
0x20435049, // Large 'smlsl|dx'.
|
||||||
|
0x801635B3, // Small 'smmla'.
|
||||||
|
0xA41635B3, // Small 'smmlar'.
|
||||||
|
0x813635B3, // Small 'smmls'.
|
||||||
|
0xA53635B3, // Small 'smmlsr'.
|
||||||
|
0x80CAB5B3, // Small 'smmul'.
|
||||||
|
0xA4CAB5B3, // Small 'smmulr'.
|
||||||
|
0x8040D5B3, // Small 'smuad'.
|
||||||
|
0xB040D5B3, // Small 'smuadx'.
|
||||||
|
0x842655B3, // Small 'smulbb'.
|
||||||
|
0xA82655B3, // Small 'smulbt'.
|
||||||
|
0x80C655B3, // Small 'smull'.
|
||||||
|
0xA6C655B3, // Small 'smulls'.
|
||||||
|
0x854655B3, // Small 'smultb'.
|
||||||
|
0xA94655B3, // Small 'smultt'.
|
||||||
|
0x857655B3, // Small 'smulwb'.
|
||||||
|
0xA97655B3, // Small 'smulwt'.
|
||||||
|
0x8049D5B3, // Small 'smusd'.
|
||||||
|
0xB049D5B3, // Small 'smusdx'.
|
||||||
|
0x80124E53, // Small 'srsda'.
|
||||||
|
0x80224E53, // Small 'srsdb'.
|
||||||
|
0x8014CE53, // Small 'srsia'.
|
||||||
|
0x8024CE53, // Small 'srsib'.
|
||||||
|
0x800A0673, // Small 'ssat'.
|
||||||
|
0x100550A1, // Large 'ssat1|6'.
|
||||||
|
0x800C0673, // Small 'ssax'.
|
||||||
|
0x80010A73, // Small 'ssbb'.
|
||||||
|
0x100550A6, // Large 'ssub1|6'.
|
||||||
|
0x10A040A6, // Large 'ssub|8'.
|
||||||
|
0x80003293, // Small 'stl'.
|
||||||
|
0x80013293, // Small 'stlb'.
|
||||||
|
0x8182B293, // Small 'stlex'.
|
||||||
|
0x8582B293, // Small 'stlexb'.
|
||||||
|
0x8982B293, // Small 'stlexd'.
|
||||||
|
0x9182B293, // Small 'stlexh'.
|
||||||
|
0x80043293, // Small 'stlh'.
|
||||||
|
0x80123693, // Small 'stmda'.
|
||||||
|
0x80223693, // Small 'stmdb'.
|
||||||
|
0x8014B693, // Small 'stmia'.
|
||||||
|
0x8024B693, // Small 'stmib'.
|
||||||
|
0x80004A93, // Small 'str'.
|
||||||
|
0x80014A93, // Small 'strb'.
|
||||||
|
0x81414A93, // Small 'strbt'.
|
||||||
|
0x80024A93, // Small 'strd'.
|
||||||
|
0x8182CA93, // Small 'strex'.
|
||||||
|
0x8582CA93, // Small 'strexb'.
|
||||||
|
0x8982CA93, // Small 'strexd'.
|
||||||
|
0x9182CA93, // Small 'strexh'.
|
||||||
|
0x80044A93, // Small 'strh'.
|
||||||
|
0x81444A93, // Small 'strht'.
|
||||||
|
0x800A4A93, // Small 'strt'.
|
||||||
|
0x80000AB3, // Small 'sub'.
|
||||||
|
0x80098AB3, // Small 'subs'.
|
||||||
|
0x80000ED3, // Small 'svc'.
|
||||||
|
0x8020D313, // Small 'sxtab'.
|
||||||
|
0x1005604E, // Large 'sxtab1|6'.
|
||||||
|
0x8080D313, // Small 'sxtah'.
|
||||||
|
0x80015313, // Small 'sxtb'.
|
||||||
|
0x100550AB, // Large 'sxtb1|6'.
|
||||||
|
0x80045313, // Small 'sxth'.
|
||||||
|
0x80000854, // Small 'tbb'.
|
||||||
|
0x80002054, // Small 'tbh'.
|
||||||
|
0x800044B4, // Small 'teq'.
|
||||||
|
0x80005274, // Small 'tst'.
|
||||||
|
0x100550B0, // Large 'uadd1|6'.
|
||||||
|
0x10A040B0, // Large 'uadd|8'.
|
||||||
|
0x800C4C35, // Small 'uasx'.
|
||||||
|
0x800C1855, // Small 'ubfx'.
|
||||||
|
0x80001895, // Small 'udf'.
|
||||||
|
0x800B2495, // Small 'udiv'.
|
||||||
|
0x10056054, // Large 'uhadd1|6'.
|
||||||
|
0x10A05054, // Large 'uhadd|8'.
|
||||||
|
0x81898515, // Small 'uhasx'.
|
||||||
|
0x8180CD15, // Small 'uhsax'.
|
||||||
|
0x1005605A, // Large 'uhsub1|6'.
|
||||||
|
0x10A0505A, // Large 'uhsub|8'.
|
||||||
|
0x80C085B5, // Small 'umaal'.
|
||||||
|
0x80C0B1B5, // Small 'umlal'.
|
||||||
|
0xA6C0B1B5, // Small 'umlals'.
|
||||||
|
0x80C655B5, // Small 'umull'.
|
||||||
|
0xA6C655B5, // Small 'umulls'.
|
||||||
|
0x10056060, // Large 'uqadd1|6'.
|
||||||
|
0x10A05060, // Large 'uqadd|8'.
|
||||||
|
0x81898635, // Small 'uqasx'.
|
||||||
|
0x8180CE35, // Small 'uqsax'.
|
||||||
|
0x10056066, // Large 'uqsub1|6'.
|
||||||
|
0x10A05066, // Large 'uqsub|8'.
|
||||||
|
0x10A040B5, // Large 'usad|8'.
|
||||||
|
0x10A050B5, // Large 'usada|8'.
|
||||||
|
0x800A0675, // Small 'usat'.
|
||||||
|
0x100550BA, // Large 'usat1|6'.
|
||||||
|
0x800C0675, // Small 'usax'.
|
||||||
|
0x100550BF, // Large 'usub1|6'.
|
||||||
|
0x10A040BF, // Large 'usub|8'.
|
||||||
|
0x8020D315, // Small 'uxtab'.
|
||||||
|
0x1005606C, // Large 'uxtab1|6'.
|
||||||
|
0x8080D315, // Small 'uxtah'.
|
||||||
|
0x80015315, // Small 'uxtb'.
|
||||||
|
0x100550C4, // Large 'uxtb1|6'.
|
||||||
|
0x80045315, // Small 'uxth'.
|
||||||
|
0x80008836, // Small 'vaba'.
|
||||||
|
0x80C08836, // Small 'vabal'.
|
||||||
|
0x80020836, // Small 'vabd'.
|
||||||
|
0x80C20836, // Small 'vabdl'.
|
||||||
|
0x80098836, // Small 'vabs'.
|
||||||
|
0x80538C36, // Small 'vacge'.
|
||||||
|
0x81438C36, // Small 'vacgt'.
|
||||||
|
0x80560C36, // Small 'vacle'.
|
||||||
|
0x81460C36, // Small 'vaclt'.
|
||||||
|
0x80021036, // Small 'vadd'.
|
||||||
|
0x9C821036, // Small 'vaddhn'.
|
||||||
|
0x80C21036, // Small 'vaddl'.
|
||||||
|
0x81721036, // Small 'vaddw'.
|
||||||
|
0x80023836, // Small 'vand'.
|
||||||
|
0x8001A456, // Small 'vbic'.
|
||||||
|
0x80032456, // Small 'vbif'.
|
||||||
|
0x800A2456, // Small 'vbit'.
|
||||||
|
0x80064C56, // Small 'vbsl'.
|
||||||
|
0x80420476, // Small 'vcadd'.
|
||||||
|
0x80089476, // Small 'vceq'.
|
||||||
|
0x80029C76, // Small 'vcge'.
|
||||||
|
0x800A1C76, // Small 'vcgt'.
|
||||||
|
0x8002B076, // Small 'vcle'.
|
||||||
|
0x8009B076, // Small 'vcls'.
|
||||||
|
0x800A3076, // Small 'vclt'.
|
||||||
|
0x800D3076, // Small 'vclz'.
|
||||||
|
0x80163476, // Small 'vcmla'.
|
||||||
|
0x80083476, // Small 'vcmp'.
|
||||||
|
0x80583476, // Small 'vcmpe'.
|
||||||
|
0x800A3876, // Small 'vcnt'.
|
||||||
|
0x800A5876, // Small 'vcvt'.
|
||||||
|
0x801A5876, // Small 'vcvta'.
|
||||||
|
0x802A5876, // Small 'vcvtb'.
|
||||||
|
0x80DA5876, // Small 'vcvtm'.
|
||||||
|
0x80EA5876, // Small 'vcvtn'.
|
||||||
|
0x810A5876, // Small 'vcvtp'.
|
||||||
|
0x812A5876, // Small 'vcvtr'.
|
||||||
|
0x814A5876, // Small 'vcvtt'.
|
||||||
|
0x800B2496, // Small 'vdiv'.
|
||||||
|
0x800A3C96, // Small 'vdot'.
|
||||||
|
0x80085496, // Small 'vdup'.
|
||||||
|
0x80093CB6, // Small 'veor'.
|
||||||
|
0x800A60B6, // Small 'vext'.
|
||||||
|
0x8000B4D6, // Small 'vfma'.
|
||||||
|
0x8020B4D6, // Small 'vfmab'.
|
||||||
|
0x80C0B4D6, // Small 'vfmal'.
|
||||||
|
0x8140B4D6, // Small 'vfmat'.
|
||||||
|
0x8009B4D6, // Small 'vfms'.
|
||||||
|
0x80C9B4D6, // Small 'vfmsl'.
|
||||||
|
0x8016B8D6, // Small 'vfnma'.
|
||||||
|
0x8136B8D6, // Small 'vfnms'.
|
||||||
|
0x80420516, // Small 'vhadd'.
|
||||||
|
0x802ACD16, // Small 'vhsub'.
|
||||||
|
0x8009B936, // Small 'vins'.
|
||||||
|
0x814B0D56, // Small 'vjcvt'.
|
||||||
|
0x800E1196, // Small 'vld1'.
|
||||||
|
0x812E1196, // Small 'vld1r'.
|
||||||
|
0x800E9196, // Small 'vld2'.
|
||||||
|
0x812E9196, // Small 'vld2r'.
|
||||||
|
0x800F1196, // Small 'vld3'.
|
||||||
|
0x812F1196, // Small 'vld3r'.
|
||||||
|
0x800F9196, // Small 'vld4'.
|
||||||
|
0x812F9196, // Small 'vld4r'.
|
||||||
|
0x84469196, // Small 'vldmdb'.
|
||||||
|
0x82969196, // Small 'vldmia'.
|
||||||
|
0x80091196, // Small 'vldr'.
|
||||||
|
0x800C05B6, // Small 'vmax'.
|
||||||
|
0x9AEC05B6, // Small 'vmaxnm'.
|
||||||
|
0x800725B6, // Small 'vmin'.
|
||||||
|
0x9AE725B6, // Small 'vminnm'.
|
||||||
|
0x8000B1B6, // Small 'vmla'.
|
||||||
|
0x80C0B1B6, // Small 'vmlal'.
|
||||||
|
0x8009B1B6, // Small 'vmls'.
|
||||||
|
0x80C9B1B6, // Small 'vmlsl'.
|
||||||
|
0x801635B6, // Small 'vmmla'.
|
||||||
|
0x800B3DB6, // Small 'vmov'.
|
||||||
|
0x80CB3DB6, // Small 'vmovl'.
|
||||||
|
0x80EB3DB6, // Small 'vmovn'.
|
||||||
|
0x818B3DB6, // Small 'vmovx'.
|
||||||
|
0x800655B6, // Small 'vmul'.
|
||||||
|
0x80C655B6, // Small 'vmull'.
|
||||||
|
0x800759B6, // Small 'vmvn'.
|
||||||
|
0x800395D6, // Small 'vneg'.
|
||||||
|
0x801635D6, // Small 'vnmla'.
|
||||||
|
0x813635D6, // Small 'vnmls'.
|
||||||
|
0x80CAB5D6, // Small 'vnmul'.
|
||||||
|
0x800749F6, // Small 'vorn'.
|
||||||
|
0x800949F6, // Small 'vorr'.
|
||||||
|
0x98120616, // Small 'vpadal'.
|
||||||
|
0x80420616, // Small 'vpadd'.
|
||||||
|
0x98420616, // Small 'vpaddl'.
|
||||||
|
0x8180B616, // Small 'vpmax'.
|
||||||
|
0x80E4B616, // Small 'vpmin'.
|
||||||
|
0x80083E16, // Small 'vpop'.
|
||||||
|
0x8089D616, // Small 'vpush'.
|
||||||
|
0x81310636, // Small 'vqabs'.
|
||||||
|
0x80420636, // Small 'vqadd'.
|
||||||
|
0x403D3072, // Large 'vqd|mlal'.
|
||||||
|
0x404A3072, // Large 'vqd|mlsl'.
|
||||||
|
0x30134075, // Large 'vqdm|ulh'.
|
||||||
|
0x10116079, // Large 'vqdmul|l'.
|
||||||
|
0x9D67B636, // Small 'vqmovn'.
|
||||||
|
0x201C507F, // Large 'vqmov|un'.
|
||||||
|
0x8072BA36, // Small 'vqneg'.
|
||||||
|
0x1001700C, // Large 'vqrdmla|h'.
|
||||||
|
0x2000600C, // Large 'vqrdml|sh'.
|
||||||
|
0x3013500C, // Large 'vqrdm|ulh'.
|
||||||
|
0x9889CA36, // Small 'vqrshl'.
|
||||||
|
0x101D6016, // Large 'vqrshr|n'.
|
||||||
|
0x00008016, // Large 'vqrshrun'.
|
||||||
|
0x80C44E36, // Small 'vqshl'.
|
||||||
|
0xAAC44E36, // Small 'vqshlu'.
|
||||||
|
0x9D244E36, // Small 'vqshrn'.
|
||||||
|
0x5019200C, // Large 'vq|shrun'.
|
||||||
|
0x802ACE36, // Small 'vqsub'.
|
||||||
|
0x101D6084, // Large 'vraddh|n'.
|
||||||
|
0x8B019656, // Small 'vrecpe'.
|
||||||
|
0xA7019656, // Small 'vrecps'.
|
||||||
|
0x100550C9, // Large 'vrev1|6'.
|
||||||
|
0xBBEB1656, // Small 'vrev32'.
|
||||||
|
0x20CE40C9, // Large 'vrev|64'.
|
||||||
|
0x8840A256, // Small 'vrhadd'.
|
||||||
|
0x83472656, // Small 'vrinta'.
|
||||||
|
0x9B472656, // Small 'vrintm'.
|
||||||
|
0x9D472656, // Small 'vrintn'.
|
||||||
|
0xA1472656, // Small 'vrintp'.
|
||||||
|
0xA5472656, // Small 'vrintr'.
|
||||||
|
0xB1472656, // Small 'vrintx'.
|
||||||
|
0xB5472656, // Small 'vrintz'.
|
||||||
|
0x80C44E56, // Small 'vrshl'.
|
||||||
|
0x81244E56, // Small 'vrshr'.
|
||||||
|
0x9D244E56, // Small 'vrshrn'.
|
||||||
|
0x0000708A, // Large 'vrsqrte'.
|
||||||
|
0x1000608A, // Large 'vrsqrt|s'.
|
||||||
|
0x80194E56, // Small 'vrsra'.
|
||||||
|
0x101D6091, // Large 'vrsubh|n'.
|
||||||
|
0x81479276, // Small 'vsdot'.
|
||||||
|
0xA2561676, // Small 'vseleq'.
|
||||||
|
0x8A761676, // Small 'vselge'.
|
||||||
|
0xA8761676, // Small 'vselgt'.
|
||||||
|
0xA7661676, // Small 'vselvs'.
|
||||||
|
0x80062276, // Small 'vshl'.
|
||||||
|
0x80C62276, // Small 'vshll'.
|
||||||
|
0x80092276, // Small 'vshr'.
|
||||||
|
0x80E92276, // Small 'vshrn'.
|
||||||
|
0x8004B276, // Small 'vsli'.
|
||||||
|
0x82C6B676, // Small 'vsmmla'.
|
||||||
|
0x81494676, // Small 'vsqrt'.
|
||||||
|
0x8000CA76, // Small 'vsra'.
|
||||||
|
0x8004CA76, // Small 'vsri'.
|
||||||
|
0x800E5276, // Small 'vst1'.
|
||||||
|
0x800ED276, // Small 'vst2'.
|
||||||
|
0x800F5276, // Small 'vst3'.
|
||||||
|
0x800FD276, // Small 'vst4'.
|
||||||
|
0x8446D276, // Small 'vstmdb'.
|
||||||
|
0x8296D276, // Small 'vstmia'.
|
||||||
|
0x80095276, // Small 'vstr'.
|
||||||
|
0x80015676, // Small 'vsub'.
|
||||||
|
0x9C815676, // Small 'vsubhn'.
|
||||||
|
0x80C15676, // Small 'vsubl'.
|
||||||
|
0x81715676, // Small 'vsubw'.
|
||||||
|
0xA8F25676, // Small 'vsudot'.
|
||||||
|
0x80085E76, // Small 'vswp'.
|
||||||
|
0x80060A96, // Small 'vtbl'.
|
||||||
|
0x800C0A96, // Small 'vtbx'.
|
||||||
|
0x80074A96, // Small 'vtrn'.
|
||||||
|
0x800A4E96, // Small 'vtst'.
|
||||||
|
0x814792B6, // Small 'vudot'.
|
||||||
|
0x82C6B6B6, // Small 'vummla'.
|
||||||
|
0xA8F24EB6, // Small 'vusdot'.
|
||||||
|
0x30104097, // Large 'vusm|mla'.
|
||||||
|
0x80086AB6, // Small 'vuzp'.
|
||||||
|
0x80082756, // Small 'vzip'.
|
||||||
|
0x800014D7, // Small 'wfe'.
|
||||||
|
0x800024D7, // Small 'wfi'.
|
||||||
|
0x80461539 // Small 'yield'.
|
||||||
|
};
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ${a32::NameData:End}
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_TEXT
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // !ASMJIT_NO_AARCH32
|
||||||
0
asmjit/arm/a32instdb.h
Normal file
0
asmjit/arm/a32instdb.h
Normal file
38
asmjit/arm/a32instdb_p.h
Normal file
38
asmjit/arm/a32instdb_p.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32INSTDB_H_P_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32INSTDB_H_P_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/codeholder.h>
|
||||||
|
#include <asmjit/core/instdb_p.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \cond INTERNAL
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
namespace InstDB {
|
||||||
|
|
||||||
|
// a32::InstDB - Tables
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_TEXT
|
||||||
|
extern const InstNameIndex inst_name_index;
|
||||||
|
extern const char _inst_name_string_table[];
|
||||||
|
extern const uint32_t _inst_name_index_table[];
|
||||||
|
#endif // !ASMJIT_NO_TEXT
|
||||||
|
|
||||||
|
} // {InstDB}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32INSTDB_H_P_INCLUDED
|
||||||
|
|
||||||
803
asmjit/arm/a32operand.h
Normal file
803
asmjit/arm/a32operand.h
Normal file
@@ -0,0 +1,803 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
#ifndef ASMJIT_ARM_A32OPERAND_H_INCLUDED
|
||||||
|
#define ASMJIT_ARM_A32OPERAND_H_INCLUDED
|
||||||
|
|
||||||
|
#include <asmjit/core/operand.h>
|
||||||
|
#include <asmjit/arm/a32globals.h>
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
|
||||||
|
//! \addtogroup asmjit_a32
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! General purpose register (AArch32).
|
||||||
|
class Gp : public UniGp {
|
||||||
|
public:
|
||||||
|
ASMJIT_DEFINE_ABSTRACT_REG(Gp, UniGp)
|
||||||
|
|
||||||
|
//! \name Constants
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Special register id.
|
||||||
|
enum Id : uint32_t {
|
||||||
|
//! Frame pointer register id.
|
||||||
|
kIdFP = 11u,
|
||||||
|
//! Stack register id.
|
||||||
|
kIdSP = 13u,
|
||||||
|
//! Link register id.
|
||||||
|
kIdLR = 14u,
|
||||||
|
//! Program counter register id.
|
||||||
|
kIdPC = 15u
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Static Constructors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates a new 32-bit low general purpose register (R) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp make_r32(uint32_t reg_id) noexcept { return Gp(signature_of_t<RegType::kGp32>(), reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 32-bit low general purpose register (R) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp make_r(uint32_t reg_id) noexcept { return make_r32(reg_id); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Gp Register Accessors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Test whether this register is FP register.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_fp() const noexcept { return id() == kIdFP; }
|
||||||
|
|
||||||
|
//! Test whether this register is SP register.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_sp() const noexcept { return id() == kIdSP; }
|
||||||
|
|
||||||
|
//! Test whether this register is LR register.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_lr() const noexcept { return id() == kIdLR; }
|
||||||
|
|
||||||
|
//! Test whether this register is PC register.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_pc() const noexcept { return id() == kIdPC; }
|
||||||
|
|
||||||
|
//! Returns whether the register contains a shift operation predicate
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool hast_shift_op() const noexcept { return predicate() != 0u; }
|
||||||
|
|
||||||
|
//! Returns shift operation predicate.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR ShiftOp shift_op() const noexcept { return ShiftOp(predicate()); }
|
||||||
|
|
||||||
|
//! Sets a shift operation predicate to `op`.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_shift_op(ShiftOp op) noexcept { set_predicate(uint32_t(op)); }
|
||||||
|
|
||||||
|
//! Resets a shift operation predicate.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void reset_shift_op() noexcept { return reset_predicate(); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Clone
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Clones the register with assigned shift operation predicate `op`.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Gp shifted(ShiftOp op) const noexcept {
|
||||||
|
Gp r(*this);
|
||||||
|
r.set_shift_op(op);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Vector register (AArch32).
|
||||||
|
class Vec : public UniVec {
|
||||||
|
public:
|
||||||
|
ASMJIT_DEFINE_ABSTRACT_REG(Vec, UniVec)
|
||||||
|
|
||||||
|
//! \cond
|
||||||
|
|
||||||
|
// Register has element index (1 bit).
|
||||||
|
// |........|........|X.......|........|
|
||||||
|
static inline constexpr uint32_t kSignatureRegElementFlagShift = 15;
|
||||||
|
static inline constexpr uint32_t kSignatureRegElementFlagMask = 0x01 << kSignatureRegElementFlagShift;
|
||||||
|
|
||||||
|
// Register element index (4 bits).
|
||||||
|
// |........|....XXXX|........|........|
|
||||||
|
static inline constexpr uint32_t kSignatureRegElementIndexShift = 16;
|
||||||
|
static inline constexpr uint32_t kSignatureRegElementIndexMask = 0x0F << kSignatureRegElementIndexShift;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR OperandSignature _make_element_access_signature(uint32_t element_index) noexcept {
|
||||||
|
return OperandSignature{
|
||||||
|
uint32_t(RegTraits<RegType::kVec128>::kSignature) |
|
||||||
|
uint32_t(kSignatureRegElementFlagMask) |
|
||||||
|
(uint32_t(element_index << kSignatureRegElementIndexShift))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
//! \name Static Constructors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates a new 32-bit vector register (S) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_v32(uint32_t reg_id) noexcept { return Vec(signature_of_t<RegType::kVec32>(), reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 64-bit vector register (D) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_v64(uint32_t reg_id) noexcept { return Vec(signature_of_t<RegType::kVec64>(), reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 128-bit vector register (Q) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_v128(uint32_t reg_id) noexcept { return Vec(signature_of_t<RegType::kVec128>(), reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 32-bit vector register (S) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_s(uint32_t reg_id) noexcept { return make_v32(reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 64-bit vector register (D) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_d(uint32_t reg_id) noexcept { return make_v64(reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 128-bit vector register (Q) having the given register id `reg_id`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_q(uint32_t reg_id) noexcept { return make_v128(reg_id); }
|
||||||
|
|
||||||
|
//! Creates a new 128-bit vector of type specified by `element_type` and `element_index`.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec make_v128_with_element_index(uint32_t element_index, uint32_t reg_id) noexcept {
|
||||||
|
return Vec(_make_element_access_signature(element_index), reg_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Vector Register Accessors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 32-bit S register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec v32() const noexcept { return make_v32(id()); }
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 64-bit D register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec v64() const noexcept { return make_v64(id()); }
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 128-bit Q register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec v128() const noexcept { return make_v128(id()); }
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 32-bit S register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec s() const noexcept { return make_v32(id()); }
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 64-bit D register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec d() const noexcept { return make_v64(id()); }
|
||||||
|
|
||||||
|
//! Clones and casts the register to a 128-bit Q register (element type & index is not cloned).
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec q() const noexcept { return make_v128(id()); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Element Index Accessors
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Returns whether the register has element index (it's an element index access).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool has_element_index() const noexcept {
|
||||||
|
return _signature.has_field<kSignatureRegElementFlagMask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns element index of the register.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR uint32_t element_index() const noexcept {
|
||||||
|
return _signature.get_field<kSignatureRegElementIndexMask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Sets element index of the register to `element_type`.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_element_index(uint32_t element_index) noexcept {
|
||||||
|
_signature |= kSignatureRegElementFlagMask;
|
||||||
|
_signature.set_field<kSignatureRegElementIndexMask>(element_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Resets element index of the register.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void reset_element_index() noexcept {
|
||||||
|
_signature &= ~(kSignatureRegElementFlagMask | kSignatureRegElementIndexMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Clones a vector register with element access enabled at the given `element_index`.
|
||||||
|
[[nodiscard]]
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Vec at(uint32_t element_index) const noexcept {
|
||||||
|
return Vec((signature() & ~kSignatureRegElementIndexMask) | (element_index << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Register-list of 32-bit GP registers.
|
||||||
|
class GpList : public RegListT<Gp> {
|
||||||
|
public:
|
||||||
|
//! \name Constants
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
static inline constexpr uint32_t kSignature =
|
||||||
|
Signature::from_op_type(OperandType::kRegList).bits() | (RegTraits<RegType::kGp32>::kSignature & ~Signature::kOpTypeMask);
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates a dummy register-list operand.
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr GpList() noexcept
|
||||||
|
: RegListT<Gp>(Signature{kSignature}, RegMask(0)) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand which is the same as `other` .
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr GpList(const GpList& other) noexcept
|
||||||
|
: RegListT<Gp>(other) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to the given `regMask`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit constexpr GpList(RegMask regMask) noexcept
|
||||||
|
: RegListT<Gp>(Signature{kSignature}, regMask) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to `regs`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit GpList(std::initializer_list<Gp> regs) noexcept
|
||||||
|
: RegListT(Signature{kSignature}, regs) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit GpList(Globals::NoInit_) noexcept
|
||||||
|
: RegListT<Gp>(Globals::NoInit) {}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Overloaded Operators
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList& operator=(const GpList& other) noexcept = default;
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList& operator|=(const GpList& other) noexcept { add_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList& operator&=(const GpList& other) noexcept { and_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList& operator^=(const GpList& other) noexcept { xor_list(other); return *this; }
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList operator|(const GpList& other) const noexcept { return GpList(list() | other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList operator&(const GpList& other) const noexcept { return GpList(list() & other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG GpList operator^(const GpList& other) const noexcept { return GpList(list() ^ other.list()); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Register-list of 32-bit (vector) S registers.
|
||||||
|
class VecSList : public RegListT<Vec> {
|
||||||
|
public:
|
||||||
|
//! \name Constants
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
static inline constexpr uint32_t kSignature =
|
||||||
|
Signature::from_op_type(OperandType::kRegList).bits() | (RegTraits<RegType::kVec32>::kSignature & ~Signature::kOpTypeMask);
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates a dummy register-list operand.
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr VecSList() noexcept
|
||||||
|
: RegListT<Vec>(Signature{kSignature}, RegMask(0)) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand which is the same as `other` .
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr VecSList(const VecSList& other) noexcept
|
||||||
|
: RegListT<Vec>(other) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to the given `regMask`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit constexpr VecSList(RegMask regMask) noexcept
|
||||||
|
: RegListT<Vec>(Signature{kSignature}, regMask) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to `regs`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit VecSList(std::initializer_list<Vec> regs) noexcept
|
||||||
|
: RegListT(Signature{kSignature}, regs) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit VecSList(Globals::NoInit_) noexcept
|
||||||
|
: RegListT<Vec>(Globals::NoInit) {}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Overloaded Operators
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList& operator=(const VecSList& other) noexcept = default;
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList& operator|=(const VecSList& other) noexcept { add_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList& operator&=(const VecSList& other) noexcept { and_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList& operator^=(const VecSList& other) noexcept { xor_list(other); return *this; }
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList operator|(const VecSList& other) const noexcept { return VecSList(list() | other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList operator&(const VecSList& other) const noexcept { return VecSList(list() & other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecSList operator^(const VecSList& other) const noexcept { return VecSList(list() ^ other.list()); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Register-list of 32-bit (vector) D registers.
|
||||||
|
class VecDList : public RegListT<Vec> {
|
||||||
|
public:
|
||||||
|
//! \name Constants
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
static inline constexpr uint32_t kSignature =
|
||||||
|
Signature::from_op_type(OperandType::kRegList).bits() | (RegTraits<RegType::kVec64>::kSignature & ~Signature::kOpTypeMask);
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates a dummy register-list operand.
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr VecDList() noexcept
|
||||||
|
: RegListT<Vec>(Signature{kSignature}, RegMask(0)) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand which is the same as `other` .
|
||||||
|
ASMJIT_INLINE_NODEBUG constexpr VecDList(const VecDList& other) noexcept
|
||||||
|
: RegListT<Vec>(other) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to the given `regMask`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit constexpr VecDList(RegMask regMask) noexcept
|
||||||
|
: RegListT<Vec>(Signature{kSignature}, regMask) {}
|
||||||
|
|
||||||
|
//! Creates a register-list operand initialized to `regs`.
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit VecDList(std::initializer_list<Vec> regs) noexcept
|
||||||
|
: RegListT(Signature{kSignature}, regs) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit VecDList(Globals::NoInit_) noexcept
|
||||||
|
: RegListT<Vec>(Globals::NoInit) {}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Overloaded Operators
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList& operator=(const VecDList& other) noexcept = default;
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList& operator|=(const VecDList& other) noexcept { add_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList& operator&=(const VecDList& other) noexcept { and_list(other); return *this; }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList& operator^=(const VecDList& other) noexcept { xor_list(other); return *this; }
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList operator|(const VecDList& other) const noexcept { return VecDList(list() | other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList operator&(const VecDList& other) const noexcept { return VecDList(list() & other.list()); }
|
||||||
|
ASMJIT_INLINE_NODEBUG VecDList operator^(const VecDList& other) const noexcept { return VecDList(list() ^ other.list()); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Memory operand (AArch32).
|
||||||
|
class Mem : public BaseMem {
|
||||||
|
public:
|
||||||
|
//! \cond INTERNAL
|
||||||
|
|
||||||
|
// Index shift value (5 bits).
|
||||||
|
// |........|.....XXX|XX......|........|
|
||||||
|
static inline constexpr uint32_t kSignatureMemShiftValueShift = 14;
|
||||||
|
static inline constexpr uint32_t kSignatureMemShiftValueMask = 0x1Fu << kSignatureMemShiftValueShift;
|
||||||
|
|
||||||
|
// Index shift operation (4 bits).
|
||||||
|
// |........|XXXX....|........|........|
|
||||||
|
static inline constexpr uint32_t kSignatureMemShiftOpShift = 20;
|
||||||
|
static inline constexpr uint32_t kSignatureMemShiftOpMask = 0x0Fu << kSignatureMemShiftOpShift;
|
||||||
|
|
||||||
|
// Offset mode type (2 bits).
|
||||||
|
// |......XX|........|........|........|
|
||||||
|
static inline constexpr uint32_t kSignatureMemOffsetModeShift = 24;
|
||||||
|
static inline constexpr uint32_t kSignatureMemOffsetModeMask = 0x03u << kSignatureMemOffsetModeShift;
|
||||||
|
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
//! \name Construction & Destruction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Construct a default `Mem` operand, that points to [0].
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem() noexcept
|
||||||
|
: BaseMem() {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem(const Mem& other) noexcept
|
||||||
|
: BaseMem(other) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit Mem(Globals::NoInit_) noexcept
|
||||||
|
: BaseMem(Globals::NoInit) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem(const Signature& signature, uint32_t base_id, uint32_t index_id, int32_t offset) noexcept
|
||||||
|
: BaseMem(signature, base_id, index_id, offset) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR explicit Mem(const Label& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
|
||||||
|
: BaseMem(Signature::from_op_type(OperandType::kMem) |
|
||||||
|
Signature::from_mem_base_type(RegType::kLabelTag) |
|
||||||
|
signature, base.id(), 0, off) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR explicit Mem(const Reg& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
|
||||||
|
: BaseMem(Signature::from_op_type(OperandType::kMem) |
|
||||||
|
Signature::from_mem_base_type(base.reg_type()) |
|
||||||
|
signature, base.id(), 0, off) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem(const Reg& base, const Reg& index, Signature signature = Signature{0}) noexcept
|
||||||
|
: BaseMem(Signature::from_op_type(OperandType::kMem) |
|
||||||
|
Signature::from_mem_base_type(base.reg_type()) |
|
||||||
|
Signature::from_mem_index_type(index.reg_type()) |
|
||||||
|
signature, base.id(), index.id(), 0) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem(const Reg& base, const Reg& index, const Shift& shift, Signature signature = Signature{0}) noexcept
|
||||||
|
: BaseMem(Signature::from_op_type(OperandType::kMem) |
|
||||||
|
Signature::from_mem_base_type(base.reg_type()) |
|
||||||
|
Signature::from_mem_index_type(index.reg_type()) |
|
||||||
|
Signature::from_value<kSignatureMemShiftOpMask>(uint32_t(shift.op())) |
|
||||||
|
Signature::from_value<kSignatureMemShiftValueMask>(shift.value()) |
|
||||||
|
signature, base.id(), index.id(), 0) {}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR explicit Mem(uint64_t base, Signature signature = Signature{0}) noexcept
|
||||||
|
: BaseMem(Signature::from_op_type(OperandType::kMem) |
|
||||||
|
signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Overloaded Operators
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem& operator=(const Mem& other) noexcept {
|
||||||
|
copy_from(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Clone
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Clones the memory operand.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem clone() const noexcept { return Mem(*this); }
|
||||||
|
|
||||||
|
//! Gets new memory operand adjusted by `off`.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem clone_adjusted(int64_t off) const noexcept {
|
||||||
|
Mem result(*this);
|
||||||
|
result.add_offset(off);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Clones the memory operand and makes it pre-index.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem pre() const noexcept {
|
||||||
|
Mem result(*this);
|
||||||
|
result.set_offset_mode(OffsetMode::kPreIndex);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Clones the memory operand, applies a given offset `off` and makes it pre-index.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem pre(int64_t off) const noexcept {
|
||||||
|
Mem result(*this);
|
||||||
|
result.set_offset_mode(OffsetMode::kPreIndex);
|
||||||
|
result.add_offset(off);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Clones the memory operand and makes it post-index.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem post() const noexcept {
|
||||||
|
Mem result(*this);
|
||||||
|
result.set_offset_mode(OffsetMode::kPostIndex);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Clones the memory operand, applies a given offset `off` and makes it post-index.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR Mem post(int64_t off) const noexcept {
|
||||||
|
Mem result(*this);
|
||||||
|
result.set_offset_mode(OffsetMode::kPostIndex);
|
||||||
|
result.add_offset(off);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Base & Index
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Converts memory `base_type` and `base_id` to `arm::Reg` instance.
|
||||||
|
//!
|
||||||
|
//! The memory must have a valid base register otherwise the result will be wrong.
|
||||||
|
ASMJIT_INLINE_NODEBUG Reg base_reg() const noexcept { return Reg::from_type_and_id(base_type(), base_id()); }
|
||||||
|
|
||||||
|
//! Converts memory `index_type` and `index_id` to `arm::Reg` instance.
|
||||||
|
//!
|
||||||
|
//! The memory must have a valid index register otherwise the result will be wrong.
|
||||||
|
ASMJIT_INLINE_NODEBUG Reg index_reg() const noexcept { return Reg::from_type_and_id(index_type(), index_id()); }
|
||||||
|
|
||||||
|
using BaseMem::set_index;
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_index(const Reg& index, uint32_t shift) noexcept {
|
||||||
|
set_index(index);
|
||||||
|
set_shift(shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_index(const Reg& index, Shift shift) noexcept {
|
||||||
|
set_index(index);
|
||||||
|
set_shift(shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name ARM Specific Features
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Gets offset mode.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR OffsetMode offset_mode() const noexcept { return OffsetMode(_signature.get_field<kSignatureMemOffsetModeMask>()); }
|
||||||
|
//! Sets offset mode to `mode`.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_offset_mode(OffsetMode mode) noexcept { _signature.set_field<kSignatureMemOffsetModeMask>(uint32_t(mode)); }
|
||||||
|
//! Resets offset mode to default (fixed offset, without write-back).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void reset_offset_mode() noexcept { _signature.set_field<kSignatureMemOffsetModeMask>(uint32_t(OffsetMode::kFixed)); }
|
||||||
|
|
||||||
|
//! Tests whether the current memory offset mode is fixed (see \ref arm::OffsetMode::kFixed).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_fixed_offset() const noexcept { return offset_mode() == OffsetMode::kFixed; }
|
||||||
|
//! Tests whether the current memory offset mode is either pre-index or post-index (write-back is used).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_pre_or_post() const noexcept { return offset_mode() != OffsetMode::kFixed; }
|
||||||
|
//! Tests whether the current memory offset mode is pre-index (write-back is used).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_pre_index() const noexcept { return offset_mode() == OffsetMode::kPreIndex; }
|
||||||
|
//! Tests whether the current memory offset mode is post-index (write-back is used).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool is_post_index() const noexcept { return offset_mode() == OffsetMode::kPostIndex; }
|
||||||
|
|
||||||
|
//! Sets offset mode of this memory operand to pre-index (write-back is used).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void make_pre_index() noexcept { set_offset_mode(OffsetMode::kPreIndex); }
|
||||||
|
//! Sets offset mode of this memory operand to post-index (write-back is used).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void make_post_index() noexcept { set_offset_mode(OffsetMode::kPostIndex); }
|
||||||
|
|
||||||
|
//! Gets shift operation that is used by index register.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR ShiftOp shift_op() const noexcept { return ShiftOp(_signature.get_field<kSignatureMemShiftOpMask>()); }
|
||||||
|
//! Sets shift operation that is used by index register.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_shift_op(ShiftOp sop) noexcept { _signature.set_field<kSignatureMemShiftOpMask>(uint32_t(sop)); }
|
||||||
|
//! Resets shift operation that is used by index register to LSL (default value).
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void reset_shift_op() noexcept { _signature.set_field<kSignatureMemShiftOpMask>(uint32_t(ShiftOp::kLSL)); }
|
||||||
|
|
||||||
|
//! Gets whether the memory operand has shift (aka scale) constant.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR bool has_shift() const noexcept { return _signature.has_field<kSignatureMemShiftValueMask>(); }
|
||||||
|
//! Gets the memory operand's shift (aka scale) constant.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR uint32_t shift() const noexcept { return _signature.get_field<kSignatureMemShiftValueMask>(); }
|
||||||
|
//! Sets the memory operand's shift (aka scale) constant.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_shift(uint32_t shift) noexcept { _signature.set_field<kSignatureMemShiftValueMask>(shift); }
|
||||||
|
|
||||||
|
//! Sets the memory operand's shift and shift operation.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void set_shift(Shift shift) noexcept {
|
||||||
|
_signature.set_field<kSignatureMemShiftOpMask>(uint32_t(shift.op()));
|
||||||
|
_signature.set_field<kSignatureMemShiftValueMask>(shift.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Resets the memory operand's shift (aka scale) constant to zero.
|
||||||
|
ASMJIT_INLINE_CONSTEXPR void reset_shift() noexcept { _signature.set_field<kSignatureMemShiftValueMask>(0); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _DOXYGEN
|
||||||
|
namespace regs {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Creates a 32-bit R register operand.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp r(uint32_t id) noexcept { return Gp::make_r32(id); }
|
||||||
|
|
||||||
|
//! Creates a 32-bit S register operand.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec s(uint32_t id) noexcept { return Vec::make_v32(id); }
|
||||||
|
|
||||||
|
//! Creates a 64-bit D register operand.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec d(uint32_t id) noexcept { return Vec::make_v64(id); }
|
||||||
|
|
||||||
|
//! Creates a 128-bit V register operand.
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Vec q(uint32_t id) noexcept { return Vec::make_v128(id); }
|
||||||
|
|
||||||
|
static constexpr Gp r0 = Gp::make_r32(0);
|
||||||
|
static constexpr Gp r1 = Gp::make_r32(1);
|
||||||
|
static constexpr Gp r2 = Gp::make_r32(2);
|
||||||
|
static constexpr Gp r3 = Gp::make_r32(3);
|
||||||
|
static constexpr Gp r4 = Gp::make_r32(4);
|
||||||
|
static constexpr Gp r5 = Gp::make_r32(5);
|
||||||
|
static constexpr Gp r6 = Gp::make_r32(6);
|
||||||
|
static constexpr Gp r7 = Gp::make_r32(7);
|
||||||
|
static constexpr Gp r8 = Gp::make_r32(8);
|
||||||
|
static constexpr Gp r9 = Gp::make_r32(9);
|
||||||
|
static constexpr Gp r10 = Gp::make_r32(10);
|
||||||
|
static constexpr Gp r11 = Gp::make_r32(11);
|
||||||
|
static constexpr Gp r12 = Gp::make_r32(12);
|
||||||
|
static constexpr Gp r13 = Gp::make_r32(13);
|
||||||
|
static constexpr Gp r14 = Gp::make_r32(14);
|
||||||
|
static constexpr Gp r15 = Gp::make_r32(15);
|
||||||
|
|
||||||
|
static constexpr Gp fp = Gp::make_r32(Gp::kIdFP);
|
||||||
|
static constexpr Gp sp = Gp::make_r32(Gp::kIdSP);
|
||||||
|
static constexpr Gp lr = Gp::make_r32(Gp::kIdLR);
|
||||||
|
static constexpr Gp pc = Gp::make_r32(Gp::kIdPC);
|
||||||
|
|
||||||
|
static constexpr Vec s0 = Vec::make_v32(0);
|
||||||
|
static constexpr Vec s1 = Vec::make_v32(1);
|
||||||
|
static constexpr Vec s2 = Vec::make_v32(2);
|
||||||
|
static constexpr Vec s3 = Vec::make_v32(3);
|
||||||
|
static constexpr Vec s4 = Vec::make_v32(4);
|
||||||
|
static constexpr Vec s5 = Vec::make_v32(5);
|
||||||
|
static constexpr Vec s6 = Vec::make_v32(6);
|
||||||
|
static constexpr Vec s7 = Vec::make_v32(7);
|
||||||
|
static constexpr Vec s8 = Vec::make_v32(8);
|
||||||
|
static constexpr Vec s9 = Vec::make_v32(9);
|
||||||
|
static constexpr Vec s10 = Vec::make_v32(10);
|
||||||
|
static constexpr Vec s11 = Vec::make_v32(11);
|
||||||
|
static constexpr Vec s12 = Vec::make_v32(12);
|
||||||
|
static constexpr Vec s13 = Vec::make_v32(13);
|
||||||
|
static constexpr Vec s14 = Vec::make_v32(14);
|
||||||
|
static constexpr Vec s15 = Vec::make_v32(15);
|
||||||
|
static constexpr Vec s16 = Vec::make_v32(16);
|
||||||
|
static constexpr Vec s17 = Vec::make_v32(17);
|
||||||
|
static constexpr Vec s18 = Vec::make_v32(18);
|
||||||
|
static constexpr Vec s19 = Vec::make_v32(19);
|
||||||
|
static constexpr Vec s20 = Vec::make_v32(20);
|
||||||
|
static constexpr Vec s21 = Vec::make_v32(21);
|
||||||
|
static constexpr Vec s22 = Vec::make_v32(22);
|
||||||
|
static constexpr Vec s23 = Vec::make_v32(23);
|
||||||
|
static constexpr Vec s24 = Vec::make_v32(24);
|
||||||
|
static constexpr Vec s25 = Vec::make_v32(25);
|
||||||
|
static constexpr Vec s26 = Vec::make_v32(26);
|
||||||
|
static constexpr Vec s27 = Vec::make_v32(27);
|
||||||
|
static constexpr Vec s28 = Vec::make_v32(28);
|
||||||
|
static constexpr Vec s29 = Vec::make_v32(29);
|
||||||
|
static constexpr Vec s30 = Vec::make_v32(30);
|
||||||
|
static constexpr Vec s31 = Vec::make_v32(31);
|
||||||
|
|
||||||
|
static constexpr Vec d0 = Vec::make_v64(0);
|
||||||
|
static constexpr Vec d1 = Vec::make_v64(1);
|
||||||
|
static constexpr Vec d2 = Vec::make_v64(2);
|
||||||
|
static constexpr Vec d3 = Vec::make_v64(3);
|
||||||
|
static constexpr Vec d4 = Vec::make_v64(4);
|
||||||
|
static constexpr Vec d5 = Vec::make_v64(5);
|
||||||
|
static constexpr Vec d6 = Vec::make_v64(6);
|
||||||
|
static constexpr Vec d7 = Vec::make_v64(7);
|
||||||
|
static constexpr Vec d8 = Vec::make_v64(8);
|
||||||
|
static constexpr Vec d9 = Vec::make_v64(9);
|
||||||
|
static constexpr Vec d10 = Vec::make_v64(10);
|
||||||
|
static constexpr Vec d11 = Vec::make_v64(11);
|
||||||
|
static constexpr Vec d12 = Vec::make_v64(12);
|
||||||
|
static constexpr Vec d13 = Vec::make_v64(13);
|
||||||
|
static constexpr Vec d14 = Vec::make_v64(14);
|
||||||
|
static constexpr Vec d15 = Vec::make_v64(15);
|
||||||
|
static constexpr Vec d16 = Vec::make_v64(16);
|
||||||
|
static constexpr Vec d17 = Vec::make_v64(17);
|
||||||
|
static constexpr Vec d18 = Vec::make_v64(18);
|
||||||
|
static constexpr Vec d19 = Vec::make_v64(19);
|
||||||
|
static constexpr Vec d20 = Vec::make_v64(20);
|
||||||
|
static constexpr Vec d21 = Vec::make_v64(21);
|
||||||
|
static constexpr Vec d22 = Vec::make_v64(22);
|
||||||
|
static constexpr Vec d23 = Vec::make_v64(23);
|
||||||
|
static constexpr Vec d24 = Vec::make_v64(24);
|
||||||
|
static constexpr Vec d25 = Vec::make_v64(25);
|
||||||
|
static constexpr Vec d26 = Vec::make_v64(26);
|
||||||
|
static constexpr Vec d27 = Vec::make_v64(27);
|
||||||
|
static constexpr Vec d28 = Vec::make_v64(28);
|
||||||
|
static constexpr Vec d29 = Vec::make_v64(29);
|
||||||
|
static constexpr Vec d30 = Vec::make_v64(30);
|
||||||
|
static constexpr Vec d31 = Vec::make_v64(31);
|
||||||
|
|
||||||
|
static constexpr Vec q0 = Vec::make_v128(0);
|
||||||
|
static constexpr Vec q1 = Vec::make_v128(1);
|
||||||
|
static constexpr Vec q2 = Vec::make_v128(2);
|
||||||
|
static constexpr Vec q3 = Vec::make_v128(3);
|
||||||
|
static constexpr Vec q4 = Vec::make_v128(4);
|
||||||
|
static constexpr Vec q5 = Vec::make_v128(5);
|
||||||
|
static constexpr Vec q6 = Vec::make_v128(6);
|
||||||
|
static constexpr Vec q7 = Vec::make_v128(7);
|
||||||
|
static constexpr Vec q8 = Vec::make_v128(8);
|
||||||
|
static constexpr Vec q9 = Vec::make_v128(9);
|
||||||
|
static constexpr Vec q10 = Vec::make_v128(10);
|
||||||
|
static constexpr Vec q11 = Vec::make_v128(11);
|
||||||
|
static constexpr Vec q12 = Vec::make_v128(12);
|
||||||
|
static constexpr Vec q13 = Vec::make_v128(13);
|
||||||
|
static constexpr Vec q14 = Vec::make_v128(14);
|
||||||
|
static constexpr Vec q15 = Vec::make_v128(15);
|
||||||
|
|
||||||
|
#ifndef _DOXYGEN
|
||||||
|
} // {regs}
|
||||||
|
|
||||||
|
// Make `a32::regs` accessible through `a32` namespace as well.
|
||||||
|
using namespace regs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! \name Shift Operation Construction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Constructs a `LSL #value` shift (logical shift left).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp lsl(const Gp& gp) noexcept { return gp.shifted(ShiftOp::kLSL); }
|
||||||
|
|
||||||
|
//! Constructs a `LSR #value` shift (logical shift right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp lsr(const Gp& gp) noexcept { return gp.shifted(ShiftOp::kLSR); }
|
||||||
|
|
||||||
|
//! Constructs a `ASR #value` shift (arithmetic shift right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp asr(const Gp& gp) noexcept { return gp.shifted(ShiftOp::kASR); }
|
||||||
|
|
||||||
|
//! Constructs a `ROR #value` shift (rotate right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Gp ror(const Gp& gp) noexcept { return gp.shifted(ShiftOp::kROR); }
|
||||||
|
|
||||||
|
//! Constructs a `LSL #value` shift (logical shift left).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Shift lsl(uint32_t value) noexcept { return Shift(ShiftOp::kLSL, value); }
|
||||||
|
|
||||||
|
//! Constructs a `LSR #value` shift (logical shift right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Shift lsr(uint32_t value) noexcept { return Shift(ShiftOp::kLSR, value); }
|
||||||
|
|
||||||
|
//! Constructs a `ASR #value` shift (arithmetic shift right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Shift asr(uint32_t value) noexcept { return Shift(ShiftOp::kASR, value); }
|
||||||
|
|
||||||
|
//! Constructs a `ROR #value` shift (rotate right).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Shift ror(uint32_t value) noexcept { return Shift(ShiftOp::kROR, value); }
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
//! \name Memory Operand Construction
|
||||||
|
//! \{
|
||||||
|
|
||||||
|
//! Creates `[base, offset]` memory operand (offset mode) (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr(const Gp& base, int32_t offset = 0) noexcept {
|
||||||
|
return Mem(base, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base, offset]!` memory operand (pre-index mode) (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr_pre(const Gp& base, int32_t offset = 0) noexcept {
|
||||||
|
return Mem(base, offset, OperandSignature::from_value<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPreIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base], offset` memory operand (post-index mode) (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr_post(const Gp& base, int32_t offset = 0) noexcept {
|
||||||
|
return Mem(base, offset, OperandSignature::from_value<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPostIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base, index]` memory operand (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr(const Gp& base, const Gp& index) noexcept {
|
||||||
|
return Mem(base, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base, index]!` memory operand (pre-index mode) (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr_pre(const Gp& base, const Gp& index) noexcept {
|
||||||
|
return Mem(base, index, OperandSignature::from_value<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPreIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base], index` memory operand (post-index mode) (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr_post(const Gp& base, const Gp& index) noexcept {
|
||||||
|
return Mem(base, index, OperandSignature::from_value<Mem::kSignatureMemOffsetModeMask>(OffsetMode::kPostIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base, index, SHIFT_OP #shift]` memory operand (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr(const Gp& base, const Gp& index, const Shift& shift) noexcept {
|
||||||
|
return Mem(base, index, shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Creates `[base, offset]` memory operand (AArch32).
|
||||||
|
[[nodiscard]]
|
||||||
|
static ASMJIT_INLINE_CONSTEXPR Mem ptr(const Label& base, int32_t offset = 0) noexcept {
|
||||||
|
return Mem(base, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \}
|
||||||
|
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ASMJIT_ARM_A32OPERAND_H_INCLUDED
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <asmjit/core/misc_p.h>
|
#include <asmjit/core/misc_p.h>
|
||||||
#include <asmjit/support/support.h>
|
#include <asmjit/support/support.h>
|
||||||
#include <asmjit/arm/armformatter_p.h>
|
#include <asmjit/arm/armformatter_p.h>
|
||||||
|
#include <asmjit/arm/a32operand.h>
|
||||||
#include <asmjit/arm/a64operand.h>
|
#include <asmjit/arm/a64operand.h>
|
||||||
#include <asmjit/arm/a64instapi_p.h>
|
#include <asmjit/arm/a64instapi_p.h>
|
||||||
#include <asmjit/arm/a64instdb_p.h>
|
#include <asmjit/arm/a64instdb_p.h>
|
||||||
@@ -395,6 +396,15 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::format_register(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
letter = 'r';
|
letter = 'r';
|
||||||
|
|
||||||
|
if (reg_id == a32::Gp::kIdSP)
|
||||||
|
return sb.append("sp", 2);
|
||||||
|
|
||||||
|
if (reg_id == a32::Gp::kIdLR)
|
||||||
|
return sb.append("lr", 2);
|
||||||
|
|
||||||
|
if (reg_id == a32::Gp::kIdPC)
|
||||||
|
return sb.append("pc", 2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,12 @@
|
|||||||
#define ASMJIT_NO_X86
|
#define ASMJIT_NO_X86
|
||||||
#undef ASMJIT_NO_X86
|
#undef ASMJIT_NO_X86
|
||||||
|
|
||||||
|
//! \def ASMJIT_NO_AARCH32
|
||||||
|
//!
|
||||||
|
//! Disables AArch32 backend.
|
||||||
|
#define ASMJIT_NO_AARCH32
|
||||||
|
#undef ASMJIT_NO_AARCH32
|
||||||
|
|
||||||
//! \def ASMJIT_NO_AARCH64
|
//! \def ASMJIT_NO_AARCH64
|
||||||
//!
|
//!
|
||||||
//! Disables AArch64 backend.
|
//! Disables AArch64 backend.
|
||||||
@@ -304,6 +310,10 @@
|
|||||||
#define ASMJIT_NO_X86
|
#define ASMJIT_NO_X86
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ASMJIT_ARCH_ARM != 32 && !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#define ASMJIT_NO_AARCH32
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ASMJIT_ARCH_ARM != 64 && !defined(ASMJIT_NO_AARCH64)
|
#if ASMJIT_ARCH_ARM != 64 && !defined(ASMJIT_NO_AARCH64)
|
||||||
#define ASMJIT_NO_AARCH64
|
#define ASMJIT_NO_AARCH64
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -261,6 +261,10 @@ static ASMJIT_INLINE_NODEBUG uint32_t data_type_size(DataType dt) noexcept {
|
|||||||
|
|
||||||
ASMJIT_END_SUB_NAMESPACE
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
|
ASMJIT_BEGIN_SUB_NAMESPACE(a32)
|
||||||
|
using namespace arm;
|
||||||
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|
||||||
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
|
ASMJIT_BEGIN_SUB_NAMESPACE(a64)
|
||||||
using namespace arm;
|
using namespace arm;
|
||||||
ASMJIT_END_SUB_NAMESPACE
|
ASMJIT_END_SUB_NAMESPACE
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
#include <asmjit/x86/x86archtraits_p.h>
|
#include <asmjit/x86/x86archtraits_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#include <asmjit/arm/a32archtraits_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
#include <asmjit/arm/a64archtraits_p.h>
|
#include <asmjit/arm/a64archtraits_p.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -74,7 +78,11 @@ ASMJIT_VARAPI const ArchTraits _arch_traits[uint32_t(Arch::kMaxValue) + 1] = {
|
|||||||
no_arch_traits,
|
no_arch_traits,
|
||||||
|
|
||||||
// ARM architecture
|
// ARM architecture
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
a32::a32_arch_traits,
|
||||||
|
#else
|
||||||
no_arch_traits,
|
no_arch_traits,
|
||||||
|
#endif
|
||||||
|
|
||||||
// AArch64 architecture.
|
// AArch64 architecture.
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
@@ -84,7 +92,11 @@ ASMJIT_VARAPI const ArchTraits _arch_traits[uint32_t(Arch::kMaxValue) + 1] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ARM/Thumb architecture.
|
// ARM/Thumb architecture.
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
a32::a32_arch_traits,
|
||||||
|
#else
|
||||||
no_arch_traits,
|
no_arch_traits,
|
||||||
|
#endif
|
||||||
|
|
||||||
// Reserved.
|
// Reserved.
|
||||||
no_arch_traits,
|
no_arch_traits,
|
||||||
|
|||||||
@@ -20,6 +20,10 @@
|
|||||||
#include <asmjit/x86/x86formatter_p.h>
|
#include <asmjit/x86/x86formatter_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#include <asmjit/arm/a32formatter_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
#include <asmjit/arm/a64formatter_p.h>
|
#include <asmjit/arm/a64formatter_p.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -126,7 +130,7 @@ Error format_feature(String& sb, Arch arch, uint32_t feature_id) noexcept {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH32) && !defined(ASMJIT_NO_AARCH64)
|
||||||
if (Environment::is_family_arm(arch)) {
|
if (Environment::is_family_arm(arch)) {
|
||||||
return arm::FormatterInternal::format_feature(sb, feature_id);
|
return arm::FormatterInternal::format_feature(sb, feature_id);
|
||||||
}
|
}
|
||||||
@@ -184,7 +188,7 @@ Error format_register(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH32) || !defined(ASMJIT_NO_AARCH64)
|
||||||
if (Environment::is_family_arm(arch)) {
|
if (Environment::is_family_arm(arch)) {
|
||||||
return arm::FormatterInternal::format_register(sb, format_flags, emitter, arch, reg_type, reg_id);
|
return arm::FormatterInternal::format_register(sb, format_flags, emitter, arch, reg_type, reg_id);
|
||||||
}
|
}
|
||||||
@@ -206,7 +210,7 @@ Error format_operand(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH32) || !defined(ASMJIT_NO_AARCH64)
|
||||||
if (Environment::is_family_arm(arch)) {
|
if (Environment::is_family_arm(arch)) {
|
||||||
return arm::FormatterInternal::format_operand(sb, format_flags, emitter, arch, op);
|
return arm::FormatterInternal::format_operand(sb, format_flags, emitter, arch, op);
|
||||||
}
|
}
|
||||||
@@ -318,6 +322,11 @@ Error format_instruction(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::FormatterInternal::format_instruction(sb, format_flags, emitter, arch, inst, operands);
|
||||||
|
#endif
|
||||||
|
|
||||||
return make_error(Error::kInvalidArch);
|
return make_error(Error::kInvalidArch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
#include <asmjit/x86/x86instapi_p.h>
|
#include <asmjit/x86/x86instapi_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
#include <asmjit/arm/a32instapi_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ASMJIT_NO_AARCH64)
|
#if !defined(ASMJIT_NO_AARCH64)
|
||||||
#include <asmjit/arm/a64instapi_p.h>
|
#include <asmjit/arm/a64instapi_p.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -34,6 +38,11 @@ Error InstAPI::inst_id_to_string(Arch arch, InstId inst_id, InstStringifyOptions
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::InstInternal::inst_id_to_string(inst_id, options, output);
|
||||||
|
#endif
|
||||||
|
|
||||||
return make_error(Error::kInvalidArch);
|
return make_error(Error::kInvalidArch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +59,11 @@ InstId InstAPI::string_to_inst_id(Arch arch, const char* s, size_t len) noexcept
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::InstInternal::string_to_inst_id(s, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif // !ASMJIT_NO_TEXT
|
#endif // !ASMJIT_NO_TEXT
|
||||||
@@ -76,6 +90,10 @@ Error InstAPI::validate(Arch arch, const BaseInst& inst, const Operand_* operand
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::InstInternal::validate(inst, operands, op_count, validation_flags);
|
||||||
|
#endif
|
||||||
return make_error(Error::kInvalidArch);
|
return make_error(Error::kInvalidArch);
|
||||||
}
|
}
|
||||||
#endif // !ASMJIT_NO_INTROSPECTION
|
#endif // !ASMJIT_NO_INTROSPECTION
|
||||||
@@ -101,6 +119,11 @@ Error InstAPI::query_rw_info(Arch arch, const BaseInst& inst, const Operand_* op
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::InstInternal::query_rw_info(inst, operands, op_count, out);
|
||||||
|
#endif
|
||||||
|
|
||||||
return make_error(Error::kInvalidArch);
|
return make_error(Error::kInvalidArch);
|
||||||
}
|
}
|
||||||
#endif // !ASMJIT_NO_INTROSPECTION
|
#endif // !ASMJIT_NO_INTROSPECTION
|
||||||
@@ -122,6 +145,11 @@ Error InstAPI::query_features(Arch arch, const BaseInst& inst, const Operand_* o
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(ASMJIT_NO_AARCH32)
|
||||||
|
if (Environment::is_family_aarch32(arch))
|
||||||
|
return a32::InstInternal::query_features(inst, operands, op_count, out);
|
||||||
|
#endif
|
||||||
return make_error(Error::kInvalidArch);
|
return make_error(Error::kInvalidArch);
|
||||||
}
|
}
|
||||||
#endif // !ASMJIT_NO_INTROSPECTION
|
#endif // !ASMJIT_NO_INTROSPECTION
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
|
|||||||
|
|
||||||
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
|
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
|
||||||
_arch_mask = (uint64_t(1) << uint32_t(Arch::kX86)) |
|
_arch_mask = (uint64_t(1) << uint32_t(Arch::kX86)) |
|
||||||
(uint64_t(1) << uint32_t(Arch::kX64)) ;
|
(uint64_t(1) << uint32_t(Arch::kX64)) ;
|
||||||
init_emitter_funcs(this);
|
init_emitter_funcs(this);
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
|
|||||||
|
|
||||||
Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
|
Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
|
||||||
_arch_mask = (uint64_t(1) << uint32_t(Arch::kX86)) |
|
_arch_mask = (uint64_t(1) << uint32_t(Arch::kX86)) |
|
||||||
(uint64_t(1) << uint32_t(Arch::kX64)) ;
|
(uint64_t(1) << uint32_t(Arch::kX64)) ;
|
||||||
init_emitter_funcs(this);
|
init_emitter_funcs(this);
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
|
|||||||
1622
tools/tablegen-a32.js
Normal file
1622
tools/tablegen-a32.js
Normal file
File diff suppressed because it is too large
Load Diff
3
tools/tablegen-a32.sh
Executable file
3
tools/tablegen-a32.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
node ./tablegen-a32.js
|
||||||
417
tools/testgen-a32.js
Normal file
417
tools/testgen-a32.js
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
// This file is part of AsmJit project <https://asmjit.com>
|
||||||
|
//
|
||||||
|
// See asmjit.h or LICENSE.md for license and copyright information
|
||||||
|
// SPDX-License-Identifier: Zlib
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const core = require("./tablegen.js");
|
||||||
|
const isa = new core.asmdb.aarch32.ISA();
|
||||||
|
|
||||||
|
const LLVM_MC = "/home/petr/workspace/3rdparty/llvm-project-build/bin/llvm-mc";
|
||||||
|
|
||||||
|
function lsbFromMul(mul) {
|
||||||
|
for (let i = 0; i < 32; i++)
|
||||||
|
if ((mul & (1 << i)) != 0)
|
||||||
|
return i;
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
class TestsGenerator {
|
||||||
|
constructor(isa) {
|
||||||
|
this.isa = isa;
|
||||||
|
}
|
||||||
|
|
||||||
|
generate() {
|
||||||
|
const child_process = require("child_process");
|
||||||
|
const tests = {
|
||||||
|
"gp": [],
|
||||||
|
"vec": []
|
||||||
|
};
|
||||||
|
|
||||||
|
function flatten(inputArray) {
|
||||||
|
const outputArray = [inputArray];
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
while (i < outputArray.length) {
|
||||||
|
let didFlatten = false;
|
||||||
|
const items = outputArray[i];
|
||||||
|
|
||||||
|
for (let j = 0; j < items.length; j++) {
|
||||||
|
if (Array.isArray(items[j])) {
|
||||||
|
const flattenedItems = [];
|
||||||
|
for (let k = 0; k < items[j].length; k++) {
|
||||||
|
const copy = items.slice();
|
||||||
|
copy[j] = items[j][k];
|
||||||
|
flattenedItems.push(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputArray.splice(i, 1, ...flattenedItems);
|
||||||
|
didFlatten = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i += Number(!didFlatten);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeShiftOp(sop, op) {
|
||||||
|
if (sop === "sop")
|
||||||
|
return ["lsl " + op, "lsr " + op, "asr " + op, "ror " + op];
|
||||||
|
else if (sop === "lsl_or_asr")
|
||||||
|
return ["lsl " + op, "asr " + op];
|
||||||
|
else
|
||||||
|
return sop + " " + op;
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodingFromText(s) {
|
||||||
|
let m = s.match(/@\s*encoding\:\s*\[0x([\w]{2}),0x([\w]{2}),0x([\w]{2}),0x([\w]{2})\]/);
|
||||||
|
if (m)
|
||||||
|
return ('"' + m[1] + m[2] + m[3] + m[4] + '"').toUpperCase();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function codeFromInstruction(s) {
|
||||||
|
s = s.trim();
|
||||||
|
var sIdx = s.indexOf(" ");
|
||||||
|
var name = s.substr(0, sIdx !== -1 ? sIdx : s.length).replace(/\./g, "_");
|
||||||
|
var operands = s.substr(name.length).trim();
|
||||||
|
|
||||||
|
var sops = operands.replace(/(v\d+)\.(\d+)?([a-z]+)\[(\d+)\]/g, "$1.$3$2($4)")
|
||||||
|
.replace(/([d|s|q]\d+)\[(\d+)\]/g, "$1.at($2)")
|
||||||
|
.replace(/\[(\w+),\s*[#]?([-]?\w+)\]!/g, "ptr_pre($1, $2)")
|
||||||
|
.replace(/\[(\w+)\],\s*[#]?([-]?\w+)/g, "ptr_post($1, $2)")
|
||||||
|
.replace(/\[(\w+),\s*[#]?([-]?\w+)\]/g, "ptr($1, $2)")
|
||||||
|
.replace(/\[(\w+)\]/g, "ptr($1)")
|
||||||
|
.replace(/\beq\b/g, "Cond::kEQ")
|
||||||
|
.replace(/#((?:0x)?[-]?[\dA-Fa-f]+)\b/g, "$1")
|
||||||
|
.replace(/(lsl|lsr|asr|ror)\s+([r]?\d+)/g, "$1($2)")
|
||||||
|
.replace(/[{}]/g, "");
|
||||||
|
|
||||||
|
if (name === "and")
|
||||||
|
name = "and_";
|
||||||
|
|
||||||
|
return name + "(" + sops + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let inst of isa.instructions) {
|
||||||
|
if (inst.encoding !== "A32")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let category = "gp";
|
||||||
|
let elements = [""];
|
||||||
|
|
||||||
|
const dt1Array = inst.dt.length ? inst.dt : ["any"];
|
||||||
|
const dt2Array = inst.dt2.length ? inst.dt2 : ["any"];
|
||||||
|
const dataTypes = [];
|
||||||
|
|
||||||
|
for (let dt2 of dt2Array) {
|
||||||
|
for (let dt1 of dt1Array) {
|
||||||
|
if (dt2 !== "any")
|
||||||
|
dataTypes.push(`.${dt1}.${dt2}`);
|
||||||
|
else if (dt1 !== "any")
|
||||||
|
dataTypes.push(`.${dt1}`);
|
||||||
|
else
|
||||||
|
dataTypes.push(``);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let dataType of dataTypes) {
|
||||||
|
let instruction = inst.name + dataType;
|
||||||
|
let ops = [];
|
||||||
|
let proceed = true;
|
||||||
|
|
||||||
|
for (let i = 0; i < inst.operands.length; i++) {
|
||||||
|
const operand = inst.operands[i];
|
||||||
|
let regId = i + 1;
|
||||||
|
|
||||||
|
if (/^(ldaexd|ldrd|ldrexd|strd)$/.test(inst.name)) {
|
||||||
|
regId--;
|
||||||
|
}
|
||||||
|
else if (/^(stlexd|strexd)$/.test(inst.name)) {
|
||||||
|
if (i == 0)
|
||||||
|
regId = 7;
|
||||||
|
else
|
||||||
|
regId = i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (operand.type) {
|
||||||
|
case "reg": {
|
||||||
|
if (operand.regType === "r" && operand.shiftOp) {
|
||||||
|
ops.push(makeShiftOp(operand.shiftOp, `r${i + 1}`));
|
||||||
|
}
|
||||||
|
else if (operand.regType === "r") {
|
||||||
|
ops.push(`r${regId}`);
|
||||||
|
}
|
||||||
|
else if (operand.regType === "s") {
|
||||||
|
ops.push(`s${regId}`);
|
||||||
|
category = "vec";
|
||||||
|
}
|
||||||
|
else if (operand.regType === "d") {
|
||||||
|
ops.push(`d${regId}`);
|
||||||
|
category = "vec";
|
||||||
|
}
|
||||||
|
else if (operand.regType === "v") {
|
||||||
|
ops.push(`q${regId}`);
|
||||||
|
category = "vec";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
proceed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operand.element) {
|
||||||
|
ops[ops.length - 1] += "[@element@]";
|
||||||
|
switch (dataType) {
|
||||||
|
case ".8":
|
||||||
|
case ".s8":
|
||||||
|
case ".u8":
|
||||||
|
elements = [0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
|
break;
|
||||||
|
case ".16":
|
||||||
|
case ".s16":
|
||||||
|
case ".u16":
|
||||||
|
case ".f16":
|
||||||
|
if (inst.name === "vcmla" || inst.name === "vfmsl" || inst.name === "vfmal")
|
||||||
|
elements = [0, 1];
|
||||||
|
else
|
||||||
|
elements = [0, 1, 2, 3];
|
||||||
|
break;
|
||||||
|
case ".32":
|
||||||
|
case ".s32":
|
||||||
|
case ".u32":
|
||||||
|
case ".f32":
|
||||||
|
if (inst.name === "vcmla")
|
||||||
|
elements = [0];
|
||||||
|
else
|
||||||
|
elements = [0, 1];
|
||||||
|
break;
|
||||||
|
case ".64":
|
||||||
|
case ".s64":
|
||||||
|
case ".u64":
|
||||||
|
case ".f64":
|
||||||
|
elements = [0, 1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ".bf16":
|
||||||
|
if (inst.name === "vdot")
|
||||||
|
elements = [0, 1];
|
||||||
|
else
|
||||||
|
elements = [0, 1, 2, 3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "imm": {
|
||||||
|
if (inst.name === "vcadd")
|
||||||
|
ops.push(["#90", "#270"]);
|
||||||
|
else if (inst.name === "vcmla")
|
||||||
|
ops.push(["#0", "#90", "#180", "#270"]);
|
||||||
|
else if (operand.shiftOp)
|
||||||
|
ops.push(makeShiftOp(operand.shiftOp, "#8"));
|
||||||
|
else if (operand.imm === "zero")
|
||||||
|
ops.push("#0");
|
||||||
|
else if (operand.imm === "immA")
|
||||||
|
ops.push(["#0xFF", "0xFF00", "0xFF000000", "0xF000000F"]);
|
||||||
|
else if (operand.imm === "immZ")
|
||||||
|
ops.push("#1");
|
||||||
|
else if (operand.imm === "immV" && instruction.endsWith("16"))
|
||||||
|
ops.push(["#0x1F", "#0x80", "#0xFF", "0x1F00", "0xFF00"]);
|
||||||
|
else if (operand.imm === "immV" && instruction.endsWith("32"))
|
||||||
|
ops.push(["#0x1F", "#0x80", "#0xFF", "0x1F00", "0xFF00", "0x1F0000", "0xFF0000", "0xFF000000", "0xFFFF0000", "0x0000FFFF", "0xFFFFFF00", "0x00FFFFFF", "0xC0F00000"]);
|
||||||
|
else if (operand.imm === "immV" && instruction.endsWith("64"))
|
||||||
|
ops.push(["#00FFFF0000000000", "#0xFF00FF0000000000", "#0x00000000FFFFFFFF"]);
|
||||||
|
else if (operand.imm === "lsb")
|
||||||
|
ops.push("#3");
|
||||||
|
else if (operand.imm === "width")
|
||||||
|
ops.push("#5");
|
||||||
|
else if (operand.imm === "sat")
|
||||||
|
ops.push("#8");
|
||||||
|
else if (operand.imm === "imm")
|
||||||
|
ops.push("#0");
|
||||||
|
else if (operand.imm === "n")
|
||||||
|
ops.push("#3");
|
||||||
|
else
|
||||||
|
proceed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "mem": {
|
||||||
|
const combinations = [];
|
||||||
|
var off = "4";
|
||||||
|
|
||||||
|
if (operand.offset && operand.offset.exp) {
|
||||||
|
const e = operand.offset.exp;
|
||||||
|
if (e.op === "==") {
|
||||||
|
off = e.right.toString();
|
||||||
|
if (off.indexOf("sz") !== -1 && dataType) {
|
||||||
|
const sz = dataType.match(/(\d+)/);
|
||||||
|
off = eval(off.replace("sz", parseInt(lsbFromMul(sz[1] / 8))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operand.memModes.offset) {
|
||||||
|
if (operand.index)
|
||||||
|
combinations.push(`[r${regId}, r${regId + 1}]`);
|
||||||
|
else if (operand.offset)
|
||||||
|
combinations.push(`[r${regId}, #${off}]`);
|
||||||
|
else
|
||||||
|
combinations.push(`[r${regId}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operand.memModes.preIndex) {
|
||||||
|
if (operand.index)
|
||||||
|
combinations.push(`[r${regId}, r${regId + 1}]!`);
|
||||||
|
else if (operand.offset)
|
||||||
|
combinations.push(`[r${regId}, #${off}]!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operand.memModes.postIndex) {
|
||||||
|
if (operand.index)
|
||||||
|
combinations.push(`[r${regId}], r${regId + 1}`);
|
||||||
|
else if (operand.offset)
|
||||||
|
combinations.push(`[r${regId}], #${off}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
ops.push(combinations);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
proceed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proceed) {
|
||||||
|
console.log(`IGNORING: ${inst.name}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const opsArray = flatten(ops);
|
||||||
|
|
||||||
|
const args = [
|
||||||
|
"--arch=arm",
|
||||||
|
"-mattr=+v8.5a",
|
||||||
|
"-mattr=+aes",
|
||||||
|
"-mattr=+bf16",
|
||||||
|
"-mattr=+crc",
|
||||||
|
"-mattr=+crypto",
|
||||||
|
"-mattr=+hwdiv-arm",
|
||||||
|
"-mattr=+fp16fml",
|
||||||
|
"-mattr=+fullfp16",
|
||||||
|
"-mattr=+i8mm",
|
||||||
|
"-mattr=+mp",
|
||||||
|
"-mattr=+trustzone",
|
||||||
|
"-mattr=+virtualization",
|
||||||
|
"-show-encoding",
|
||||||
|
"-output-asm-variant=0"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let element of elements) {
|
||||||
|
for (let opsRow of opsArray) {
|
||||||
|
let line = instruction;
|
||||||
|
opsRow = opsRow.map(function(s) { return s.replace("@element@", element) });
|
||||||
|
|
||||||
|
let o = opsRow.slice();
|
||||||
|
switch (inst.name) {
|
||||||
|
case "pop":
|
||||||
|
case "push": {
|
||||||
|
o[0] = "{" + o[0];
|
||||||
|
o[o.length - 1] += "}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "vcls": {
|
||||||
|
line = line.replace(".u", ".s");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "vtbx":
|
||||||
|
case "vtbl": {
|
||||||
|
o[1] = "{" + o[1];
|
||||||
|
o[o.length - 2] += "}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "rfe":
|
||||||
|
case "rfeda":
|
||||||
|
case "rfedb":
|
||||||
|
case "rfeib": {
|
||||||
|
o[0] = o[0].replace(/[\[\]]/g, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "vld1r":
|
||||||
|
case "vld2r":
|
||||||
|
case "vld3r":
|
||||||
|
case "vld4r": {
|
||||||
|
line = line.replace("vld1r", "vld1")
|
||||||
|
.replace("vld2r", "vld2")
|
||||||
|
.replace("vld3r", "vld3")
|
||||||
|
.replace("vld4r", "vld4");
|
||||||
|
for (let i = 0; i < o.length - 1; i++)
|
||||||
|
o[i] += "[]";
|
||||||
|
// fallthrough;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "vld1":
|
||||||
|
case "vld2":
|
||||||
|
case "vld3":
|
||||||
|
case "vld4":
|
||||||
|
case "vst1":
|
||||||
|
case "vst2":
|
||||||
|
case "vst3":
|
||||||
|
case "vst4": {
|
||||||
|
o[o.length - 1] = o[o.length - 1].replace(/,\s*#\d+$/g, "!");
|
||||||
|
o[0] = "{" + o[0];
|
||||||
|
o[o.length - 2] += "}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const out = child_process.execFileSync(LLVM_MC, args, {
|
||||||
|
input: line + " " + o.join(", "),
|
||||||
|
encoding: "utf-8"
|
||||||
|
});
|
||||||
|
|
||||||
|
const encoding = encodingFromText(out);
|
||||||
|
const code = codeFromInstruction(instruction + " " + opsRow.join(", "));
|
||||||
|
|
||||||
|
tests[category].push(`TEST_INSTRUCTION(${encoding}, ${code});`);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
console.log(`FATAL: ${line} ${opsRow.join(", ")}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("static void ASMJIT_NOINLINE testA32AssemblerGp(AssemblerTester<a32::Assembler>& tester) noexcept {");
|
||||||
|
console.log(" using namespace a32;");
|
||||||
|
console.log("");
|
||||||
|
for (let test of tests.gp) {
|
||||||
|
console.log(" " + test);
|
||||||
|
}
|
||||||
|
console.log("}");
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("static void ASMJIT_NOINLINE testA32AssemblerVec(AssemblerTester<a32::Assembler>& tester) noexcept {");
|
||||||
|
console.log(" using namespace a32;");
|
||||||
|
console.log("");
|
||||||
|
for (let test of tests.vec)
|
||||||
|
console.log(" " + test);
|
||||||
|
console.log("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new TestsGenerator(isa).generate();
|
||||||
Reference in New Issue
Block a user