mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-22 21:19:48 +00:00
SystemZ Auto-Sync refactor (#2462)
Some checks failed
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 cmake os:ubuntu-22.04]) (push) Failing after 0s
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:make diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 make os:ubuntu-22.04]) (push) Failing after 0s
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (ubuntu-latest) (push) Failing after 0s
RELEASE BUILD - PyPI 📦 Distribution / Make SDist (push) Failing after 0s
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:ON name:ubuntu-24.04 x64 ASAN os:ubuntu-24.04]) (push) Has been cancelled
Run Test / ${{ matrix.config.name }} (map[arch:x64 name:windows x64 MSVC 64bit os:windows-latest platform:windows python-arch:x64 python-version:3.9]) (push) Has been cancelled
Auto-Sync / check (push) Has been cancelled
Run clang-tidy / clang-tidy (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (macos-latest) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (windows-latest) (push) Has been cancelled
Python Package CI / build (macOS-14, 3.12) (push) Has been cancelled
Python Package CI / build (macOS-14, 3.8) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.12) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.8) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.12) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.8) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / publish (push) Has been cancelled
Some checks failed
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 cmake os:ubuntu-22.04]) (push) Failing after 0s
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:make diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 make os:ubuntu-22.04]) (push) Failing after 0s
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (ubuntu-latest) (push) Failing after 0s
RELEASE BUILD - PyPI 📦 Distribution / Make SDist (push) Failing after 0s
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:ON name:ubuntu-24.04 x64 ASAN os:ubuntu-24.04]) (push) Has been cancelled
Run Test / ${{ matrix.config.name }} (map[arch:x64 name:windows x64 MSVC 64bit os:windows-latest platform:windows python-arch:x64 python-version:3.9]) (push) Has been cancelled
Auto-Sync / check (push) Has been cancelled
Run clang-tidy / clang-tidy (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (macos-latest) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (windows-latest) (push) Has been cancelled
Python Package CI / build (macOS-14, 3.12) (push) Has been cancelled
Python Package CI / build (macOS-14, 3.8) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.12) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.8) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.12) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.8) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / publish (push) Has been cancelled
This commit is contained in:
parent
6a7fef60ea
commit
af1ed2fb3d
19
.github/workflows/CITest.yml
vendored
19
.github/workflows/CITest.yml
vendored
@ -92,25 +92,20 @@ jobs:
|
||||
# Work-around ASAN bug https://github.com/google/sanitizers/issues/1716
|
||||
sudo sysctl vm.mmap_rnd_bits=28
|
||||
|
||||
- name: "Compatibility header test"
|
||||
- name: unit tests
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
run: |
|
||||
ctest --test-dir build --output-on-failure -R unit_*
|
||||
|
||||
- name: "Integration tests"
|
||||
if: startsWith(matrix.config.build-system, 'cmake') && matrix.config.diet-build == 'OFF'
|
||||
run: |
|
||||
ctest --test-dir build --output-on-failure -R ASCompatibilityHeaderTest
|
||||
ctest --test-dir build --output-on-failure -R integration_*
|
||||
|
||||
- name: cstool - reaches disassembler engine
|
||||
run: |
|
||||
sh suite/run_invalid_cstool.sh
|
||||
|
||||
- name: cstest unit tests
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
run: |
|
||||
ctest --test-dir build --output-on-failure -R UnitCSTest
|
||||
|
||||
- name: cstest integration tests
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
run: |
|
||||
ctest --test-dir build --output-on-failure -R IntegrationCSTest
|
||||
|
||||
- name: cstest MC
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
run: |
|
||||
|
9
.github/workflows/auto-sync.yml
vendored
9
.github/workflows/auto-sync.yml
vendored
@ -78,6 +78,7 @@ jobs:
|
||||
./src/autosync/ASUpdater.py -d -a PPC -s IncGen
|
||||
./src/autosync/ASUpdater.py -d -a LoongArch -s IncGen
|
||||
./src/autosync/ASUpdater.py -d -a Mips -s IncGen
|
||||
./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen
|
||||
|
||||
- name: CppTranslator - Patch tests
|
||||
run: |
|
||||
@ -94,10 +95,4 @@ jobs:
|
||||
./src/autosync/ASUpdater.py --ci -d -a PPC -s Translate
|
||||
./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate
|
||||
./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate
|
||||
|
||||
- name: Differ - Test save file is up-to-date
|
||||
run: |
|
||||
./src/autosync/cpptranslator/Differ.py -a AArch64 --check_saved
|
||||
./src/autosync/cpptranslator/Differ.py -a ARM --check_saved
|
||||
./src/autosync/cpptranslator/Differ.py -a PPC --check_saved
|
||||
./src/autosync/cpptranslator/Differ.py -a LoongArch --check_saved
|
||||
./src/autosync/ASUpdater.py --ci -d -a SystemZ -s Translate
|
||||
|
@ -89,7 +89,7 @@ if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
|
||||
endif()
|
||||
|
||||
set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH)
|
||||
set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSTEMZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH)
|
||||
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch)
|
||||
|
||||
# If building for OSX it's best to allow CMake to handle building both architectures
|
||||
@ -200,6 +200,7 @@ set(HEADERS_COMMON
|
||||
include/capstone/x86.h
|
||||
include/capstone/sparc.h
|
||||
include/capstone/systemz.h
|
||||
include/capstone/systemz_compatibility.h
|
||||
include/capstone/xcore.h
|
||||
include/capstone/m68k.h
|
||||
include/capstone/tms320c64x.h
|
||||
@ -412,27 +413,34 @@ if(CAPSTONE_SPARC_SUPPORT)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CAPSTONE_SYSZ_SUPPORT)
|
||||
add_definitions(-DCAPSTONE_HAS_SYSZ)
|
||||
set(SOURCES_SYSZ
|
||||
if(CAPSTONE_SYSTEMZ_SUPPORT)
|
||||
add_definitions(-DCAPSTONE_HAS_SYSTEMZ)
|
||||
set(SOURCES_SYSTEMZ
|
||||
arch/SystemZ/SystemZDisassembler.c
|
||||
arch/SystemZ/SystemZDisassemblerExtension.c
|
||||
arch/SystemZ/SystemZInstPrinter.c
|
||||
arch/SystemZ/SystemZMapping.c
|
||||
arch/SystemZ/SystemZModule.c
|
||||
arch/SystemZ/SystemZMCTargetDesc.c
|
||||
)
|
||||
set(HEADERS_SYSZ
|
||||
arch/SystemZ/SystemZDisassembler.h
|
||||
set(HEADERS_SYSTEMZ
|
||||
arch/SystemZ/SystemZLinkage.h
|
||||
arch/SystemZ/SystemZDisassemblerExtension.h
|
||||
arch/SystemZ/SystemZInstPrinter.h
|
||||
arch/SystemZ/SystemZMCTargetDesc.h
|
||||
arch/SystemZ/SystemZMapping.h
|
||||
arch/SystemZ/SystemZModule.h
|
||||
arch/SystemZ/SystemZGenAsmWriter.inc
|
||||
arch/SystemZ/SystemZGenCSAliasMnemMap.inc
|
||||
arch/SystemZ/SystemZGenCSFeatureName.inc
|
||||
arch/SystemZ/SystemZGenCSMappingInsn.inc
|
||||
arch/SystemZ/SystemZGenCSMappingInsnName.inc
|
||||
arch/SystemZ/SystemZGenCSMappingInsnOp.inc
|
||||
arch/SystemZ/SystemZGenCSOpGroup.inc
|
||||
arch/SystemZ/SystemZGenDisassemblerTables.inc
|
||||
arch/SystemZ/SystemZGenInsnNameMaps.inc
|
||||
arch/SystemZ/SystemZGenInstrInfo.inc
|
||||
arch/SystemZ/SystemZGenRegisterInfo.inc
|
||||
arch/SystemZ/SystemZGenSubtargetInfo.inc
|
||||
arch/SystemZ/SystemZInstPrinter.h
|
||||
arch/SystemZ/SystemZMapping.h
|
||||
arch/SystemZ/SystemZMappingInsn.inc
|
||||
arch/SystemZ/SystemZMCTargetDesc.h
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -688,7 +696,7 @@ set(ALL_SOURCES
|
||||
${SOURCES_PPC}
|
||||
${SOURCES_X86}
|
||||
${SOURCES_SPARC}
|
||||
${SOURCES_SYSZ}
|
||||
${SOURCES_SYSTEMZ}
|
||||
${SOURCES_XCORE}
|
||||
${SOURCES_M68K}
|
||||
${SOURCES_TMS320C64X}
|
||||
@ -714,7 +722,7 @@ set(ALL_HEADERS
|
||||
${HEADERS_PPC}
|
||||
${HEADERS_X86}
|
||||
${HEADERS_SPARC}
|
||||
${HEADERS_SYSZ}
|
||||
${HEADERS_SYSTEMZ}
|
||||
${HEADERS_XCORE}
|
||||
${HEADERS_M68K}
|
||||
${HEADERS_TMS320C64X}
|
||||
@ -765,7 +773,7 @@ source_group("Source\\AARCH64" FILES ${SOURCES_AARCH64})
|
||||
source_group("Source\\Mips" FILES ${SOURCES_MIPS})
|
||||
source_group("Source\\PowerPC" FILES ${SOURCES_PPC})
|
||||
source_group("Source\\Sparc" FILES ${SOURCES_SPARC})
|
||||
source_group("Source\\SystemZ" FILES ${SOURCES_SYSZ})
|
||||
source_group("Source\\SystemZ" FILES ${SOURCES_SYSTEMZ})
|
||||
source_group("Source\\X86" FILES ${SOURCES_X86})
|
||||
source_group("Source\\XCore" FILES ${SOURCES_XCORE})
|
||||
source_group("Source\\M68K" FILES ${SOURCES_M68K})
|
||||
@ -789,7 +797,7 @@ source_group("Include\\AARCH64" FILES ${HEADERS_AARCH64})
|
||||
source_group("Include\\Mips" FILES ${HEADERS_MIPS})
|
||||
source_group("Include\\PowerPC" FILES ${HEADERS_PPC})
|
||||
source_group("Include\\Sparc" FILES ${HEADERS_SPARC})
|
||||
source_group("Include\\SystemZ" FILES ${HEADERS_SYSZ})
|
||||
source_group("Include\\SystemZ" FILES ${HEADERS_SYSTEMZ})
|
||||
source_group("Include\\X86" FILES ${HEADERS_X86})
|
||||
source_group("Include\\XCore" FILES ${HEADERS_XCORE})
|
||||
source_group("Include\\M68K" FILES ${HEADERS_M68K})
|
||||
@ -898,8 +906,4 @@ if(CAPSTONE_BUILD_CSTEST)
|
||||
add_subdirectory(${TESTS_INTEGRATION_DIR})
|
||||
set(TESTS_UNIT_DIR ${PROJECT_SOURCE_DIR}/tests/unit)
|
||||
add_subdirectory(${TESTS_UNIT_DIR})
|
||||
|
||||
# Unit tests for auto-sync
|
||||
set(AUTO_SYNC_C_TEST_DIR ${PROJECT_SOURCE_DIR}/suite/auto-sync/c_tests/)
|
||||
add_subdirectory(${AUTO_SYNC_C_TEST_DIR})
|
||||
endif()
|
||||
|
@ -28,7 +28,7 @@ Get CMake for free from http://www.cmake.org.
|
||||
- CAPSTONE_MOS65XX_SUPPORT: support MOS65XX. Run cmake with -DCAPSTONE_MOS65XX_SUPPORT=0 to remove MOS65XX.
|
||||
- CAPSTONE_PPC_SUPPORT: support PPC. Run cmake with -DCAPSTONE_PPC_SUPPORT=0 to remove PPC.
|
||||
- CAPSTONE_SPARC_SUPPORT: support Sparc. Run cmake with -DCAPSTONE_SPARC_SUPPORT=0 to remove Sparc.
|
||||
- CAPSTONE_SYSZ_SUPPORT: support SystemZ. Run cmake with -DCAPSTONE_SYSZ_SUPPORT=0 to remove SystemZ.
|
||||
- CAPSTONE_SYSTEMZ_SUPPORT: support SystemZ. Run cmake with -DCAPSTONE_SYSTEMZ_SUPPORT=0 to remove SystemZ.
|
||||
- CAPSTONE_XCORE_SUPPORT: support XCore. Run cmake with -DCAPSTONE_XCORE_SUPPORT=0 to remove XCore.
|
||||
- CAPSTONE_TRICORE_SUPPORT: support TriCore. Run cmake with -DCAPSTONE_TRICORE_SUPPORT=0 to remove TriCore.
|
||||
- CAPSTONE_X86_SUPPORT: support X86. Run cmake with -DCAPSTONE_X86_SUPPORT=0 to remove X86.
|
||||
|
19
MCAsmInfo.h
Normal file
19
MCAsmInfo.h
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright © 2024 Rot127 <unisono@quyllur.org>
|
||||
// SPDX-License-Identifier: BSD-3
|
||||
|
||||
/// The equivalent of the MCAsmInfo class in LLVM.
|
||||
/// We save only some flags of the original class here.
|
||||
|
||||
#ifndef CS_MCASMINFO_H
|
||||
#define CS_MCASMINFO_H
|
||||
|
||||
typedef enum {
|
||||
SYSTEMZASMDIALECT_AD_ATT = 0,
|
||||
SYSTEMZASMDIALECT_AD_HLASM = 1,
|
||||
} MCAsmInfoAssemblerDialect;
|
||||
|
||||
typedef struct {
|
||||
MCAsmInfoAssemblerDialect assemblerDialect;
|
||||
} MCAsmInfo;
|
||||
|
||||
#endif // CS_MCASMINFO_H
|
16
MCInst.c
16
MCInst.c
@ -16,7 +16,7 @@
|
||||
|
||||
#define MCINST_CACHE (ARR_SIZE(mcInst->Operands) - 1)
|
||||
|
||||
void MCInst_Init(MCInst *inst)
|
||||
void MCInst_Init(MCInst *inst, cs_arch arch)
|
||||
{
|
||||
// unnecessary to initialize in loop . its expensive and inst->size should be honored
|
||||
inst->Operands[0].Kind = kInvalid;
|
||||
@ -37,6 +37,15 @@ void MCInst_Init(MCInst *inst)
|
||||
inst->isAliasInstr = false;
|
||||
inst->fillDetailOps = false;
|
||||
memset(&inst->hppa_ext, 0, sizeof(inst->hppa_ext));
|
||||
|
||||
// Set default assembly dialect.
|
||||
switch (arch) {
|
||||
default:
|
||||
break;
|
||||
case CS_ARCH_SYSTEMZ:
|
||||
inst->MAI.assemblerDialect = SYSTEMZASMDIALECT_AD_HLASM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MCInst_clear(MCInst *inst)
|
||||
@ -150,6 +159,11 @@ int64_t MCOperand_getImm(const MCOperand *op)
|
||||
return op->ImmVal;
|
||||
}
|
||||
|
||||
int64_t MCOperand_getExpr(const MCOperand *op)
|
||||
{
|
||||
return op->ImmVal;
|
||||
}
|
||||
|
||||
void MCOperand_setImm(MCOperand *op, int64_t Val)
|
||||
{
|
||||
op->ImmVal = Val;
|
||||
|
6
MCInst.h
6
MCInst.h
@ -20,6 +20,7 @@
|
||||
#define CS_MCINST_H
|
||||
|
||||
#include "include/capstone/capstone.h"
|
||||
#include "MCAsmInfo.h"
|
||||
#include "MCInstrDesc.h"
|
||||
#include "MCRegisterInfo.h"
|
||||
|
||||
@ -73,6 +74,8 @@ int64_t MCOperand_getImm(const MCOperand *op);
|
||||
|
||||
void MCOperand_setImm(MCOperand *op, int64_t Val);
|
||||
|
||||
int64_t MCOperand_getExpr(const MCOperand *op);
|
||||
|
||||
double MCOperand_getFPImm(const MCOperand *op);
|
||||
|
||||
void MCOperand_setFPImm(MCOperand *op, double Val);
|
||||
@ -133,9 +136,10 @@ struct MCInst {
|
||||
bool isAliasInstr; // Flag if this MCInst is an alias.
|
||||
bool fillDetailOps; // If set, detail->operands gets filled.
|
||||
hppa_ext hppa_ext; ///< for HPPA operand. Contains info about modifiers and their effect on the instruction
|
||||
MCAsmInfo MAI; ///< The equivalent to MCAsmInfo in LLVM. It holds flags relevant for the asm style to print.
|
||||
};
|
||||
|
||||
void MCInst_Init(MCInst *inst);
|
||||
void MCInst_Init(MCInst *inst, cs_arch arch);
|
||||
|
||||
void MCInst_clear(MCInst *inst);
|
||||
|
||||
|
@ -340,6 +340,7 @@ DEFINE_get_detail_op(hppa, HPPA);
|
||||
DEFINE_get_detail_op(loongarch, LoongArch);
|
||||
DEFINE_get_detail_op(mips, Mips);
|
||||
DEFINE_get_detail_op(riscv, RISCV);
|
||||
DEFINE_get_detail_op(systemz, SystemZ);
|
||||
|
||||
/// Returns true if for this architecture the
|
||||
/// alias operands should be filled.
|
||||
@ -433,7 +434,7 @@ uint64_t enum_map_bin_search(const cs_enum_id_map *map, size_t map_len,
|
||||
} else if (id[i] > map[m].str[j]) {
|
||||
l = m + 1;
|
||||
}
|
||||
if (m == 0 || (l + r) / 2 >= map_len) {
|
||||
if ((m == 0 && id[i] < map[m].str[j]) || (l + r) / 2 >= map_len) {
|
||||
// Break before we go out of bounds.
|
||||
break;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ typedef struct insn_map {
|
||||
ppc_suppl_info ppc;
|
||||
loongarch_suppl_info loongarch;
|
||||
aarch64_suppl_info aarch64;
|
||||
systemz_suppl_info systemz;
|
||||
} suppl_info; // Supplementary information for each instruction.
|
||||
#endif
|
||||
} insn_map;
|
||||
@ -140,6 +141,7 @@ DECL_get_detail_op(hppa, HPPA);
|
||||
DECL_get_detail_op(loongarch, LoongArch);
|
||||
DECL_get_detail_op(mips, Mips);
|
||||
DECL_get_detail_op(riscv, RISCV);
|
||||
DECL_get_detail_op(systemz, SystemZ);
|
||||
|
||||
/// Increments the detail->arch.op_count by one.
|
||||
#define DEFINE_inc_detail_op_count(arch, ARCH) \
|
||||
@ -173,6 +175,8 @@ DEFINE_inc_detail_op_count(mips, Mips);
|
||||
DEFINE_dec_detail_op_count(mips, Mips);
|
||||
DEFINE_inc_detail_op_count(riscv, RISCV);
|
||||
DEFINE_dec_detail_op_count(riscv, RISCV);
|
||||
DEFINE_inc_detail_op_count(systemz, SystemZ);
|
||||
DEFINE_dec_detail_op_count(systemz, SystemZ);
|
||||
|
||||
/// Returns true if a memory operand is currently edited.
|
||||
static inline bool doing_mem(const MCInst *MI)
|
||||
@ -203,6 +207,7 @@ DEFINE_get_arch_detail(hppa, HPPA);
|
||||
DEFINE_get_arch_detail(loongarch, LoongArch);
|
||||
DEFINE_get_arch_detail(mips, Mips);
|
||||
DEFINE_get_arch_detail(riscv, RISCV);
|
||||
DEFINE_get_arch_detail(systemz, SystemZ);
|
||||
|
||||
static inline bool detail_is_set(const MCInst *MI)
|
||||
{
|
||||
|
167
SStream.c
167
SStream.c
@ -28,6 +28,19 @@ void SStream_Init(SStream *ss)
|
||||
ss->index = 0;
|
||||
ss->buffer[0] = '\0';
|
||||
ss->is_closed = false;
|
||||
ss->markup_stream = false;
|
||||
ss->prefixed_by_markup = false;
|
||||
}
|
||||
|
||||
/// Empty the stream @ss to given @file (stdin/stderr).
|
||||
/// @file can be NULL. Then the buffer content is not emitted.
|
||||
void SStream_Flush(SStream *ss, FILE *file)
|
||||
{
|
||||
assert(ss);
|
||||
if (file) {
|
||||
fprintf(file, "%s\n", ss->buffer);
|
||||
}
|
||||
SStream_Init(ss);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,9 +70,17 @@ void SStream_concat0(SStream *ss, const char *s)
|
||||
return;
|
||||
unsigned int len = (unsigned int) strlen(s);
|
||||
|
||||
SSTREAM_OVERFLOW_CHECK(ss, len);
|
||||
|
||||
memcpy(ss->buffer + ss->index, s, len);
|
||||
ss->index += len;
|
||||
ss->buffer[ss->index] = '\0';
|
||||
if (ss->markup_stream && ss->prefixed_by_markup) {
|
||||
SSTREAM_OVERFLOW_CHECK(ss, 1);
|
||||
ss->buffer[ss->index] = '>';
|
||||
ss->index += 1;
|
||||
ss->buffer[ss->index] = '\0';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -72,9 +93,17 @@ void SStream_concat1(SStream *ss, const char c)
|
||||
SSTREAM_RETURN_IF_CLOSED(ss);
|
||||
if (c == '\0')
|
||||
return;
|
||||
|
||||
SSTREAM_OVERFLOW_CHECK(ss, 1);
|
||||
|
||||
ss->buffer[ss->index] = c;
|
||||
ss->index++;
|
||||
ss->buffer[ss->index] = '\0';
|
||||
if (ss->markup_stream && ss->prefixed_by_markup) {
|
||||
SSTREAM_OVERFLOW_CHECK(ss, 1);
|
||||
ss->buffer[ss->index] = '>';
|
||||
ss->index++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -92,6 +121,11 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
|
||||
ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
|
||||
va_end(ap);
|
||||
ss->index += ret;
|
||||
if (ss->markup_stream && ss->prefixed_by_markup) {
|
||||
SSTREAM_OVERFLOW_CHECK(ss, 1);
|
||||
ss->buffer[ss->index] = '>';
|
||||
ss->index += 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -99,29 +133,15 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
|
||||
void printInt64Bang(SStream *O, int64_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val >= 0) {
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "#0x%"PRIx64, val);
|
||||
else
|
||||
SStream_concat(O, "#%"PRIu64, val);
|
||||
} else {
|
||||
if (val <- HEX_THRESHOLD) {
|
||||
if (val == LONG_MIN)
|
||||
SStream_concat(O, "#-0x%"PRIx64, (uint64_t)val);
|
||||
else
|
||||
SStream_concat(O, "#-0x%"PRIx64, (uint64_t)-val);
|
||||
} else
|
||||
SStream_concat(O, "#-%"PRIu64, -val);
|
||||
}
|
||||
SStream_concat1(O, '#');
|
||||
printInt64(O, val);
|
||||
}
|
||||
|
||||
void printUInt64Bang(SStream *O, uint64_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "#0x%"PRIx64, val);
|
||||
else
|
||||
SStream_concat(O, "#%"PRIu64, val);
|
||||
SStream_concat1(O, '#');
|
||||
printUInt64(O, val);
|
||||
}
|
||||
|
||||
// print number
|
||||
@ -134,9 +154,9 @@ void printInt64(SStream *O, int64_t val)
|
||||
else
|
||||
SStream_concat(O, "%"PRIu64, val);
|
||||
} else {
|
||||
if (val <- HEX_THRESHOLD) {
|
||||
if (val == LONG_MIN)
|
||||
SStream_concat(O, "-0x%"PRIx64, (uint64_t)val);
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT64_MIN)
|
||||
SStream_concat(O, "-0x%"PRIx64, (uint64_t) INT64_MAX + 1);
|
||||
else
|
||||
SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val);
|
||||
} else
|
||||
@ -158,31 +178,57 @@ void printInt32BangDec(SStream *O, int32_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val >= 0)
|
||||
SStream_concat(O, "#%u", val);
|
||||
SStream_concat(O, "#%" PRIu32, val);
|
||||
else {
|
||||
if (val == INT_MIN)
|
||||
SStream_concat(O, "#-%u", val);
|
||||
if (val == INT32_MIN)
|
||||
SStream_concat(O, "#-%" PRIu32, val);
|
||||
else
|
||||
SStream_concat(O, "#-%u", (uint32_t)-val);
|
||||
SStream_concat(O, "#-%" PRIu32, (uint32_t)-val);
|
||||
}
|
||||
}
|
||||
|
||||
void printInt32Bang(SStream *O, int32_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
SStream_concat1(O, '#');
|
||||
printInt32(O, val);
|
||||
}
|
||||
|
||||
void printInt8(SStream *O, int8_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val >= 0) {
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "#0x%x", val);
|
||||
SStream_concat(O, "0x%" PRIx8, val);
|
||||
else
|
||||
SStream_concat(O, "#%u", val);
|
||||
SStream_concat(O, "%" PRId8, val);
|
||||
} else {
|
||||
if (val <- HEX_THRESHOLD) {
|
||||
if (val == INT_MIN)
|
||||
SStream_concat(O, "#-0x%x", (uint32_t)val);
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT8_MIN)
|
||||
SStream_concat(O, "-0x%" PRIx8, (uint8_t) INT8_MAX + 1);
|
||||
else
|
||||
SStream_concat(O, "#-0x%x", (uint32_t)-val);
|
||||
SStream_concat(O, "-0x%" PRIx8, (int8_t)-val);
|
||||
} else
|
||||
SStream_concat(O, "#-%u", -val);
|
||||
SStream_concat(O, "-%" PRIu8, -val);
|
||||
}
|
||||
}
|
||||
|
||||
void printInt16(SStream *O, int16_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val >= 0) {
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%" PRIx16, val);
|
||||
else
|
||||
SStream_concat(O, "%" PRId16, val);
|
||||
} else {
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
if (val == INT16_MIN)
|
||||
SStream_concat(O, "-0x%" PRIx16, (uint16_t) INT16_MAX + 1);
|
||||
else
|
||||
SStream_concat(O, "-0x%" PRIx16, (int16_t)-val);
|
||||
} else
|
||||
SStream_concat(O, "-%" PRIu16, -val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,27 +237,23 @@ void printInt32(SStream *O, int32_t val)
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val >= 0) {
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%x", val);
|
||||
SStream_concat(O, "0x%" PRIx32, val);
|
||||
else
|
||||
SStream_concat(O, "%u", val);
|
||||
SStream_concat(O, "%" PRId32, val);
|
||||
} else {
|
||||
if (val <- HEX_THRESHOLD) {
|
||||
if (val == INT_MIN)
|
||||
SStream_concat(O, "-0x%x", (uint32_t)val);
|
||||
else
|
||||
SStream_concat(O, "-0x%x", (uint32_t)-val);
|
||||
} else
|
||||
SStream_concat(O, "-%u", -val);
|
||||
if (val < -HEX_THRESHOLD) {
|
||||
SStream_concat(O, "-0x%" PRIx32, (uint32_t)-val);
|
||||
} else {
|
||||
SStream_concat(O, "-%" PRIu32, (uint32_t)-val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printUInt32Bang(SStream *O, uint32_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
if (val > HEX_THRESHOLD)
|
||||
SStream_concat(O, "#0x%x", val);
|
||||
else
|
||||
SStream_concat(O, "#%u", val);
|
||||
SStream_concat1(O, '#');
|
||||
printUInt32(O, val);
|
||||
}
|
||||
|
||||
void printUInt32(SStream *O, uint32_t val)
|
||||
@ -234,3 +276,38 @@ void printFloatBang(SStream *O, float val)
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
SStream_concat(O, "#%e", val);
|
||||
}
|
||||
|
||||
void printExpr(SStream *O, uint64_t val)
|
||||
{
|
||||
SSTREAM_RETURN_IF_CLOSED(O);
|
||||
SStream_concat(O, "%"PRIu64, val);
|
||||
}
|
||||
|
||||
SStream *markup_OS(SStream *OS, SStreamMarkup style) {
|
||||
assert(OS);
|
||||
|
||||
if (OS->is_closed || !OS->markup_stream) {
|
||||
return OS;
|
||||
}
|
||||
OS->markup_stream = false; // Disable temporarily.
|
||||
switch (style) {
|
||||
default:
|
||||
SStream_concat0(OS, "<UNKNOWN:");
|
||||
return OS;
|
||||
case Markup_Immediate:
|
||||
SStream_concat0(OS, "<imm:");
|
||||
break;
|
||||
case Markup_Register:
|
||||
SStream_concat0(OS, "<reg:");
|
||||
break;
|
||||
case Markup_Target:
|
||||
SStream_concat0(OS, "<tar:");
|
||||
break;
|
||||
case Markup_Memory:
|
||||
SStream_concat0(OS, "<mem:");
|
||||
break;
|
||||
}
|
||||
OS->markup_stream = true;
|
||||
OS->prefixed_by_markup = true;
|
||||
return OS;
|
||||
}
|
||||
|
30
SStream.h
30
SStream.h
@ -5,13 +5,33 @@
|
||||
#define CS_SSTREAM_H_
|
||||
|
||||
#include "include/capstone/platform.h"
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
Markup_Immediate,
|
||||
Markup_Register,
|
||||
Markup_Target,
|
||||
Markup_Memory,
|
||||
} SStreamMarkup;
|
||||
|
||||
#define SSTREAM_BUF_LEN 512
|
||||
|
||||
typedef struct SStream {
|
||||
char buffer[512];
|
||||
char buffer[SSTREAM_BUF_LEN];
|
||||
int index;
|
||||
bool is_closed;
|
||||
bool markup_stream; ///< If true, markups to the stream are allowed.
|
||||
bool prefixed_by_markup; ///< Set after the stream wrote a markup for an operand.
|
||||
} SStream;
|
||||
|
||||
#define SSTREAM_OVERFLOW_CHECK(OS, len) \
|
||||
do { \
|
||||
if (OS->index + len + 1 > SSTREAM_BUF_LEN) { \
|
||||
fprintf(stderr, "Buffer overflow caught!\n"); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define SSTREAM_RETURN_IF_CLOSED(OS) \
|
||||
do { \
|
||||
if (OS->is_closed) \
|
||||
@ -20,6 +40,8 @@ do { \
|
||||
|
||||
void SStream_Init(SStream *ss);
|
||||
|
||||
void SStream_Flush(SStream *ss, FILE *file);
|
||||
|
||||
void SStream_Open(SStream *ss);
|
||||
|
||||
void SStream_Close(SStream *ss);
|
||||
@ -39,6 +61,8 @@ void printUInt64(SStream *O, uint64_t val);
|
||||
|
||||
void printInt32Bang(SStream *O, int32_t val);
|
||||
|
||||
void printInt8(SStream *O, int8_t val);
|
||||
void printInt16(SStream *O, int16_t val);
|
||||
void printInt32(SStream *O, int32_t val);
|
||||
|
||||
void printUInt32Bang(SStream *O, uint32_t val);
|
||||
@ -52,4 +76,8 @@ void printFloat(SStream *O, float val);
|
||||
|
||||
void printFloatBang(SStream *O, float val);
|
||||
|
||||
void printExpr(SStream *O, uint64_t val);
|
||||
|
||||
SStream *markup_OS(SStream *OS, SStreamMarkup style);
|
||||
|
||||
#endif
|
||||
|
@ -359,7 +359,7 @@ static void printInst(MCInst *MI, SStream *O, void *info)
|
||||
if (MCRegisterClass_contains(MRC, Reg)) {
|
||||
MCInst NewMI;
|
||||
|
||||
MCInst_Init(&NewMI);
|
||||
MCInst_Init(&NewMI, CS_ARCH_ARM);
|
||||
MCInst_setOpcode(&NewMI, Opcode);
|
||||
|
||||
if (isStore)
|
||||
|
@ -1,484 +1,408 @@
|
||||
//===------ SystemZDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
/* Automatically translated source file from LLVM. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Only small edits allowed. */
|
||||
/* For multiple similar edits, please create a Patch for the translator. */
|
||||
|
||||
/* Capstone's C++ file translator: */
|
||||
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
|
||||
|
||||
//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
|
||||
#include <stdio.h> // DEBUG
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <capstone/platform.h>
|
||||
|
||||
#include "../../MCInst.h"
|
||||
#include "../../MathExtras.h"
|
||||
#include "../../MCInstPrinter.h"
|
||||
#include "../../MCDisassembler.h"
|
||||
#include "../../MCFixedLenDisassembler.h"
|
||||
#include "../../cs_priv.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
#include "SystemZDisassembler.h"
|
||||
|
||||
#include "../../MCInst.h"
|
||||
#include "../../MCInstrDesc.h"
|
||||
#include "../../MCFixedLenDisassembler.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../MCDisassembler.h"
|
||||
#include "../../MathExtras.h"
|
||||
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
#include "SystemZDisassemblerExtension.h"
|
||||
|
||||
static uint64_t getFeatureBits(int mode)
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define CONCAT_(a, b) a##_##b
|
||||
|
||||
#define DEBUG_TYPE "systemz-disassembler"
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *Instr, uint16_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address,
|
||||
SStream *CStream);
|
||||
|
||||
/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
|
||||
/// immediate Value in the MCInst.
|
||||
///
|
||||
/// @param Value - The immediate Value, has had any PC adjustment made by
|
||||
/// the caller.
|
||||
/// @param isBranch - If the instruction is a branch instruction
|
||||
/// @param Address - The starting address of the instruction
|
||||
/// @param Offset - The byte offset to this immediate in the instruction
|
||||
/// @param Width - The byte width of this immediate in the instruction
|
||||
///
|
||||
/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
|
||||
/// called then that function is called to get any symbolic information for the
|
||||
/// immediate in the instruction using the Address, Offset and Width. If that
|
||||
/// returns non-zero then the symbolic information it returns is used to create
|
||||
/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
|
||||
/// returns zero and isBranch is true then a symbol look up for immediate Value
|
||||
/// is done and if a symbol is found an MCExpr is created with that, else
|
||||
/// an MCExpr with the immediate Value is created. This function returns true
|
||||
/// if it adds an operand to the MCInst and false otherwise.
|
||||
static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
|
||||
uint64_t Address, uint64_t Offset,
|
||||
uint64_t Width, MCInst *MI,
|
||||
const void *Decoder)
|
||||
{
|
||||
// support everything
|
||||
return (uint64_t)-1;
|
||||
// return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch,
|
||||
// Offset, Width, /*InstSize=*/0);
|
||||
return false;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, const unsigned *Regs)
|
||||
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
const unsigned *Regs, unsigned Size,
|
||||
bool IsAddr)
|
||||
{
|
||||
//assert(RegNo < 16 && "Invalid register");
|
||||
RegNo = Regs[RegNo];
|
||||
if (RegNo == 0)
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
MCOperand_CreateReg0(Inst, (unsigned)RegNo);
|
||||
CS_ASSERT((RegNo < Size && "Invalid register"));
|
||||
if (IsAddr && RegNo == 0) {
|
||||
RegNo = SystemZ_NoRegister;
|
||||
} else {
|
||||
RegNo = Regs[RegNo];
|
||||
if (RegNo == 0)
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
MCOperand_CreateReg0(Inst, (RegNo));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeADDR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs, 16, true);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs, 16, true);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs, 32, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs, 32, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs, 32, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs);
|
||||
return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs, 16, false);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm)
|
||||
{
|
||||
//assert(isUInt<N>(Imm) && "Invalid immediate");
|
||||
MCOperand_CreateImm0(Inst, Imm);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
#define DEFINE_decodeUImmOperand(N) \
|
||||
static DecodeStatus CONCAT(decodeUImmOperand, N)(MCInst * Inst, \
|
||||
uint64_t Imm) \
|
||||
{ \
|
||||
if (!isUIntN(N, Imm)) \
|
||||
return MCDisassembler_Fail; \
|
||||
MCOperand_CreateImm0(Inst, (Imm)); \
|
||||
return MCDisassembler_Success; \
|
||||
}
|
||||
DEFINE_decodeUImmOperand(1);
|
||||
DEFINE_decodeUImmOperand(2);
|
||||
DEFINE_decodeUImmOperand(3);
|
||||
DEFINE_decodeUImmOperand(4);
|
||||
DEFINE_decodeUImmOperand(8);
|
||||
DEFINE_decodeUImmOperand(12);
|
||||
DEFINE_decodeUImmOperand(16);
|
||||
DEFINE_decodeUImmOperand(32);
|
||||
|
||||
static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N)
|
||||
{
|
||||
//assert(isUInt<N>(Imm) && "Invalid immediate");
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
#define DEFINE_decodeSImmOperand(N) \
|
||||
static DecodeStatus CONCAT(decodeSImmOperand, N)(MCInst * Inst, \
|
||||
uint64_t Imm) \
|
||||
{ \
|
||||
if (!isUIntN(N, Imm)) \
|
||||
return MCDisassembler_Fail; \
|
||||
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
|
||||
return MCDisassembler_Success; \
|
||||
}
|
||||
DEFINE_decodeSImmOperand(8);
|
||||
DEFINE_decodeSImmOperand(16);
|
||||
DEFINE_decodeSImmOperand(20);
|
||||
DEFINE_decodeSImmOperand(32);
|
||||
|
||||
static DecodeStatus decodeU1ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 1)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 2)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 3)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 4)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 8)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 12)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 16)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeUImmOperand(Inst, Imm);
|
||||
return CONCAT(decodeUImmOperand, 32)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeSImmOperand(Inst, Imm, 8);
|
||||
return CONCAT(decodeSImmOperand, 8)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeSImmOperand(Inst, Imm, 16);
|
||||
return CONCAT(decodeSImmOperand, 16)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeS20ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return CONCAT(decodeSImmOperand, 20)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeSImmOperand(Inst, Imm, 32);
|
||||
return CONCAT(decodeSImmOperand, 32)(Inst, Imm);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address, unsigned N)
|
||||
{
|
||||
//assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address);
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
#define DEFINE_decodeLenOperand(N) \
|
||||
static DecodeStatus CONCAT(decodeLenOperand, \
|
||||
N)(MCInst * Inst, uint64_t Imm, \
|
||||
uint64_t Address, const void *Decoder) \
|
||||
{ \
|
||||
if (!isUIntN(N, Imm)) \
|
||||
return MCDisassembler_Fail; \
|
||||
MCOperand_CreateImm0(Inst, (Imm + 1)); \
|
||||
return MCDisassembler_Success; \
|
||||
}
|
||||
DEFINE_decodeLenOperand(8);
|
||||
DEFINE_decodeLenOperand(4);
|
||||
|
||||
#define DEFINE_decodePCDBLOperand(N) \
|
||||
static DecodeStatus CONCAT(decodePCDBLOperand, N)( \
|
||||
MCInst * Inst, uint64_t Imm, uint64_t Address, bool isBranch, \
|
||||
const void *Decoder) \
|
||||
{ \
|
||||
CS_ASSERT((isUIntN(N, Imm) && "Invalid PC-relative offset")); \
|
||||
uint64_t Value = SignExtend64((Imm), N) * 2 + Address; \
|
||||
\
|
||||
if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, \
|
||||
N / 8, Inst, Decoder)) \
|
||||
MCOperand_CreateImm0(Inst, (Value)); \
|
||||
\
|
||||
return MCDisassembler_Success; \
|
||||
}
|
||||
DEFINE_decodePCDBLOperand(12);
|
||||
DEFINE_decodePCDBLOperand(16);
|
||||
DEFINE_decodePCDBLOperand(24);
|
||||
DEFINE_decodePCDBLOperand(32);
|
||||
|
||||
static DecodeStatus decodePC12DBLBranchOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodePCDBLOperand(Inst, Imm, Address, 12);
|
||||
return CONCAT(decodePCDBLOperand, 12)(Inst, Imm, Address, true,
|
||||
Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodePCDBLOperand(Inst, Imm, Address, 16);
|
||||
return CONCAT(decodePCDBLOperand, 16)(Inst, Imm, Address, true,
|
||||
Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodePCDBLOperand(Inst, Imm, Address, 24);
|
||||
return CONCAT(decodePCDBLOperand, 24)(Inst, Imm, Address, true,
|
||||
Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
{
|
||||
return decodePCDBLOperand(Inst, Imm, Address, 32);
|
||||
return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, true,
|
||||
Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm,
|
||||
uint64_t Address,
|
||||
const void *Decoder)
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodePCDBLOperand(Inst, Imm, Address, 32);
|
||||
return CONCAT(decodePCDBLOperand, 32)(Inst, Imm, Address, false,
|
||||
Decoder);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr12Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Base = Field >> 12;
|
||||
uint64_t Disp = Field & 0xfff;
|
||||
//assert(Base < 16 && "Invalid BDAddr12");
|
||||
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, Disp);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr20Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Base = Field >> 20;
|
||||
uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
|
||||
//assert(Base < 16 && "Invalid BDAddr20");
|
||||
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDXAddr12Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Index = Field >> 16;
|
||||
uint64_t Base = (Field >> 12) & 0xf;
|
||||
uint64_t Disp = Field & 0xfff;
|
||||
|
||||
//assert(Index < 16 && "Invalid BDXAddr12");
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, Disp);
|
||||
MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDXAddr20Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Index = Field >> 24;
|
||||
uint64_t Base = (Field >> 20) & 0xf;
|
||||
uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
|
||||
|
||||
//assert(Index < 16 && "Invalid BDXAddr20");
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
|
||||
MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDLAddr12Len8Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Length = Field >> 16;
|
||||
uint64_t Base = (Field >> 12) & 0xf;
|
||||
uint64_t Disp = Field & 0xfff;
|
||||
//assert(Length < 256 && "Invalid BDLAddr12Len8");
|
||||
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, Disp);
|
||||
MCOperand_CreateImm0(Inst, Length + 1);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDRAddr12Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Length = Field >> 16;
|
||||
uint64_t Base = (Field >> 12) & 0xf;
|
||||
uint64_t Disp = Field & 0xfff;
|
||||
//assert(Length < 16 && "Invalid BDRAddr12");
|
||||
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, Disp);
|
||||
MCOperand_CreateReg0(Inst, Regs[Length]);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDVAddr12Operand(MCInst *Inst, uint64_t Field,
|
||||
const unsigned *Regs)
|
||||
{
|
||||
uint64_t Index = Field >> 16;
|
||||
uint64_t Base = (Field >> 12) & 0xf;
|
||||
uint64_t Disp = Field & 0xfff;
|
||||
//assert(Index < 32 && "Invalid BDVAddr12");
|
||||
|
||||
MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
|
||||
MCOperand_CreateImm0(Inst, Disp);
|
||||
MCOperand_CreateReg0(Inst, SystemZMC_VR128Regs[Index]);
|
||||
|
||||
return MCDisassembler_Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDRAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
|
||||
uint64_t Address, const void *Decoder)
|
||||
{
|
||||
return decodeBDVAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
|
||||
}
|
||||
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
#include "SystemZGenDisassemblerTables.inc"
|
||||
bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
|
||||
uint16_t *size, uint64_t address, void *info)
|
||||
|
||||
static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *Bytes,
|
||||
size_t BytesLen, uint64_t Address, SStream *CS)
|
||||
{
|
||||
uint64_t Inst;
|
||||
const uint8_t *Table;
|
||||
uint16_t I;
|
||||
// Get the first two bytes of the instruction.
|
||||
*Size = 0;
|
||||
if (BytesLen < 2)
|
||||
return MCDisassembler_Fail;
|
||||
|
||||
// The top 2 bits of the first byte specify the size.
|
||||
if (*code < 0x40) {
|
||||
*size = 2;
|
||||
const uint8_t *Table;
|
||||
uint64_t Inst = 0;
|
||||
if (Bytes[0] < 0x40) {
|
||||
*Size = 2;
|
||||
Table = DecoderTable16;
|
||||
} else if (*code < 0xc0) {
|
||||
*size = 4;
|
||||
Inst = readBytes16(MI, Bytes);
|
||||
} else if (Bytes[0] < 0xc0) {
|
||||
*Size = 4;
|
||||
Table = DecoderTable32;
|
||||
Inst = readBytes32(MI, Bytes);
|
||||
} else {
|
||||
*size = 6;
|
||||
*Size = 6;
|
||||
Table = DecoderTable48;
|
||||
Inst = readBytes48(MI, Bytes);
|
||||
}
|
||||
|
||||
if (code_len < *size)
|
||||
// short of input data
|
||||
return false;
|
||||
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
|
||||
// Read any remaining bytes.
|
||||
if (BytesLen < *Size) {
|
||||
*Size = BytesLen;
|
||||
return MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
// Construct the instruction.
|
||||
Inst = 0;
|
||||
for (I = 0; I < *size; ++I)
|
||||
Inst = (Inst << 8) | code[I];
|
||||
|
||||
return decodeInstruction(Table, MI, Inst, address, info, 0);
|
||||
return decodeInstruction_8(Table, MI, Inst, Address, NULL);
|
||||
}
|
||||
|
||||
#define GET_REGINFO_ENUM
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
void SystemZ_init(MCRegisterInfo *MRI)
|
||||
DecodeStatus SystemZ_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t BytesLen, MCInst *MI,
|
||||
uint16_t *Size, uint64_t Address,
|
||||
void *Info)
|
||||
{
|
||||
/*
|
||||
InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC,
|
||||
SystemZMCRegisterClasses, 12,
|
||||
SystemZRegUnitRoots,
|
||||
49,
|
||||
SystemZRegDiffLists,
|
||||
SystemZRegStrings,
|
||||
SystemZSubRegIdxLists,
|
||||
7,
|
||||
SystemZSubRegIdxRanges,
|
||||
SystemZRegEncodingTable);
|
||||
*/
|
||||
|
||||
MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 194,
|
||||
0, 0,
|
||||
SystemZMCRegisterClasses, 21,
|
||||
0, 0,
|
||||
SystemZRegDiffLists,
|
||||
0,
|
||||
SystemZSubRegIdxLists, 7,
|
||||
0);
|
||||
return getInstruction(MI, Size, Bytes, BytesLen, MI->address, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,17 +0,0 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifndef CS_SYSZDISASSEMBLER_H
|
||||
#define CS_SYSZDISASSEMBLER_H
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../MCInst.h"
|
||||
|
||||
void SystemZ_init(MCRegisterInfo *MRI);
|
||||
|
||||
bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
MCInst *instr, uint16_t *size, uint64_t address, void *info);
|
||||
|
||||
#endif
|
||||
|
116
arch/SystemZ/SystemZDisassemblerExtension.c
Normal file
116
arch/SystemZ/SystemZDisassemblerExtension.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Rot127 <unisono@quyllur.org>, 2022-2023 */
|
||||
|
||||
#include <capstone/systemz.h>
|
||||
#include "SystemZDisassemblerExtension.h"
|
||||
#include "../../utils.h"
|
||||
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
|
||||
static int systemz_arch9_features[] = {
|
||||
SystemZ_FeatureDistinctOps,
|
||||
SystemZ_FeatureFastSerialization,
|
||||
SystemZ_FeatureFPExtension,
|
||||
SystemZ_FeatureHighWord,
|
||||
SystemZ_FeatureInterlockedAccess1,
|
||||
SystemZ_FeatureLoadStoreOnCond,
|
||||
SystemZ_FeaturePopulationCount,
|
||||
SystemZ_FeatureMessageSecurityAssist3,
|
||||
SystemZ_FeatureMessageSecurityAssist4,
|
||||
SystemZ_FeatureResetReferenceBitsMultiple
|
||||
};
|
||||
|
||||
static int systemz_arch10_features[] = {
|
||||
SystemZ_FeatureExecutionHint,
|
||||
SystemZ_FeatureLoadAndTrap,
|
||||
SystemZ_FeatureMiscellaneousExtensions,
|
||||
SystemZ_FeatureProcessorAssist,
|
||||
SystemZ_FeatureTransactionalExecution,
|
||||
SystemZ_FeatureDFPZonedConversion,
|
||||
SystemZ_FeatureEnhancedDAT2
|
||||
};
|
||||
|
||||
static int systemz_arch11_features[] = {
|
||||
SystemZ_FeatureLoadAndZeroRightmostByte,
|
||||
SystemZ_FeatureLoadStoreOnCond2,
|
||||
SystemZ_FeatureMessageSecurityAssist5,
|
||||
SystemZ_FeatureDFPPackedConversion,
|
||||
SystemZ_FeatureVector
|
||||
};
|
||||
|
||||
static int systemz_arch12_features[] = {
|
||||
SystemZ_FeatureMiscellaneousExtensions2,
|
||||
SystemZ_FeatureGuardedStorage,
|
||||
SystemZ_FeatureMessageSecurityAssist7,
|
||||
SystemZ_FeatureMessageSecurityAssist8,
|
||||
SystemZ_FeatureVectorEnhancements1,
|
||||
SystemZ_FeatureVectorPackedDecimal,
|
||||
SystemZ_FeatureInsertReferenceBitsMultiple
|
||||
};
|
||||
|
||||
static int systemz_arch13_features[] = {
|
||||
SystemZ_FeatureMiscellaneousExtensions3,
|
||||
SystemZ_FeatureMessageSecurityAssist9,
|
||||
SystemZ_FeatureVectorEnhancements2,
|
||||
SystemZ_FeatureVectorPackedDecimalEnhancement,
|
||||
SystemZ_FeatureEnhancedSort,
|
||||
SystemZ_FeatureDeflateConversion
|
||||
};
|
||||
|
||||
static int systemz_arch14_features[] = {
|
||||
SystemZ_FeatureVectorPackedDecimalEnhancement2,
|
||||
SystemZ_FeatureNNPAssist,
|
||||
SystemZ_FeatureBEAREnhancement,
|
||||
SystemZ_FeatureResetDATProtection,
|
||||
SystemZ_FeatureProcessorActivityInstrumentation
|
||||
};
|
||||
|
||||
bool SystemZ_getFeatureBits(unsigned int mode, unsigned int feature) {
|
||||
switch (mode & ~CS_MODE_BIG_ENDIAN) {
|
||||
case CS_MODE_SYSTEMZ_ARCH14:
|
||||
case CS_MODE_SYSTEMZ_Z16:
|
||||
if (arr_exist_int(systemz_arch14_features, ARR_SIZE(systemz_arch14_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_ARCH13:
|
||||
case CS_MODE_SYSTEMZ_Z15:
|
||||
if (arr_exist_int(systemz_arch13_features, ARR_SIZE(systemz_arch13_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_ARCH12:
|
||||
case CS_MODE_SYSTEMZ_Z14:
|
||||
if (arr_exist_int(systemz_arch12_features, ARR_SIZE(systemz_arch12_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_ARCH11:
|
||||
case CS_MODE_SYSTEMZ_Z13:
|
||||
if (arr_exist_int(systemz_arch11_features, ARR_SIZE(systemz_arch11_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_ARCH10:
|
||||
case CS_MODE_SYSTEMZ_ZEC12:
|
||||
if (arr_exist_int(systemz_arch10_features, ARR_SIZE(systemz_arch10_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_ARCH9:
|
||||
case CS_MODE_SYSTEMZ_Z196:
|
||||
if (arr_exist_int(systemz_arch9_features, ARR_SIZE(systemz_arch9_features), feature)) {
|
||||
return true;
|
||||
}
|
||||
// fallthrough
|
||||
case CS_MODE_SYSTEMZ_GENERIC:
|
||||
case CS_MODE_SYSTEMZ_ARCH8:
|
||||
case CS_MODE_SYSTEMZ_Z10:
|
||||
// There are no features defined for Arch8
|
||||
return false;
|
||||
default:
|
||||
// Default case is the "allow all features", which is normal Capstone behavior
|
||||
// until https://github.com/capstone-engine/capstone/issues/1992 is implemented.
|
||||
return true;
|
||||
}
|
||||
}
|
11
arch/SystemZ/SystemZDisassemblerExtension.h
Normal file
11
arch/SystemZ/SystemZDisassemblerExtension.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Rot127 <unisono@quyllur.org>, 2022-2023 */
|
||||
|
||||
#ifndef CS_SYSTEMZ_DISASSEMBLER_EXTENSION_H
|
||||
#define CS_SYSTEMZ_DISASSEMBLER_EXTENSION_H
|
||||
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
bool SystemZ_getFeatureBits(unsigned int mode, unsigned int feature);
|
||||
|
||||
#endif // CS_SYSTEMZ_DISASSEMBLER_EXTENSION_H
|
File diff suppressed because it is too large
Load Diff
55
arch/SystemZ/SystemZGenCSAliasMnemMap.inc
Normal file
55
arch/SystemZ/SystemZGenCSAliasMnemMap.inc
Normal file
@ -0,0 +1,55 @@
|
||||
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2024 */
|
||||
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Do not edit. */
|
||||
|
||||
/* Capstone's LLVM TableGen Backends: */
|
||||
/* https://github.com/capstone-engine/llvm-capstone */
|
||||
|
||||
{ SYSTEMZ_INS_ALIAS_VISTRB, "vistrb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VISTR, "vistr" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFEEB, "vfeeb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFEE, "vfee" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEB, "vfaeb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEBS, "vfaebs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAE, "vfae" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRSB, "vstrsb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRS, "vstrs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCB, "vstrcb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCBS, "vstrcbs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRC, "vstrc" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEH, "vfaeh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEHS, "vfaehs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEF, "vfaef" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEFS, "vfaefs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZB, "vfaezb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZBS, "vfaezbs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZH, "vfaezh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZHS, "vfaezhs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZF, "vfaezf" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFAEZFS, "vfaezfs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFEEH, "vfeeh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFEEF, "vfeef" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFENE, "vfene" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFENEB, "vfeneb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFENEH, "vfeneh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VFENEF, "vfenef" },
|
||||
{ SYSTEMZ_INS_ALIAS_VISTRH, "vistrh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VISTRF, "vistrf" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCH, "vstrch" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCHS, "vstrchs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCF, "vstrcf" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCFS, "vstrcfs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZB, "vstrczb" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZBS, "vstrczbs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZH, "vstrczh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZHS, "vstrczhs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZF, "vstrczf" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRCZFS, "vstrczfs" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRSH, "vstrsh" },
|
||||
{ SYSTEMZ_INS_ALIAS_VSTRSF, "vstrsf" },
|
55
arch/SystemZ/SystemZGenCSFeatureName.inc
Normal file
55
arch/SystemZ/SystemZGenCSFeatureName.inc
Normal file
@ -0,0 +1,55 @@
|
||||
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2024 */
|
||||
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Do not edit. */
|
||||
|
||||
/* Capstone's LLVM TableGen Backends: */
|
||||
/* https://github.com/capstone-engine/llvm-capstone */
|
||||
|
||||
{ SYSTEMZ_FEATURE_FEATURESOFTFLOAT, "FeatureSoftFloat" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREBACKCHAIN, "FeatureBackChain" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREDISTINCTOPS, "FeatureDistinctOps" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREFASTSERIALIZATION, "FeatureFastSerialization" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREFPEXTENSION, "FeatureFPExtension" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREHIGHWORD, "FeatureHighWord" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREINTERLOCKEDACCESS1, "FeatureInterlockedAccess1" },
|
||||
{ SYSTEMZ_FEATURE_FEATURELOADSTOREONCOND, "FeatureLoadStoreOnCond" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREPOPULATIONCOUNT, "FeaturePopulationCount" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST3, "FeatureMessageSecurityAssist3" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST4, "FeatureMessageSecurityAssist4" },
|
||||
{ SYSTEMZ_FEATURE_FEATURERESETREFERENCEBITSMULTIPLE, "FeatureResetReferenceBitsMultiple" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREEXECUTIONHINT, "FeatureExecutionHint" },
|
||||
{ SYSTEMZ_FEATURE_FEATURELOADANDTRAP, "FeatureLoadAndTrap" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMISCELLANEOUSEXTENSIONS, "FeatureMiscellaneousExtensions" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREPROCESSORASSIST, "FeatureProcessorAssist" },
|
||||
{ SYSTEMZ_FEATURE_FEATURETRANSACTIONALEXECUTION, "FeatureTransactionalExecution" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREDFPZONEDCONVERSION, "FeatureDFPZonedConversion" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREENHANCEDDAT2, "FeatureEnhancedDAT2" },
|
||||
{ SYSTEMZ_FEATURE_FEATURELOADANDZERORIGHTMOSTBYTE, "FeatureLoadAndZeroRightmostByte" },
|
||||
{ SYSTEMZ_FEATURE_FEATURELOADSTOREONCOND2, "FeatureLoadStoreOnCond2" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST5, "FeatureMessageSecurityAssist5" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREDFPPACKEDCONVERSION, "FeatureDFPPackedConversion" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTOR, "FeatureVector" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMISCELLANEOUSEXTENSIONS2, "FeatureMiscellaneousExtensions2" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREGUARDEDSTORAGE, "FeatureGuardedStorage" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST7, "FeatureMessageSecurityAssist7" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST8, "FeatureMessageSecurityAssist8" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTORENHANCEMENTS1, "FeatureVectorEnhancements1" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTORPACKEDDECIMAL, "FeatureVectorPackedDecimal" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREINSERTREFERENCEBITSMULTIPLE, "FeatureInsertReferenceBitsMultiple" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMISCELLANEOUSEXTENSIONS3, "FeatureMiscellaneousExtensions3" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREMESSAGESECURITYASSIST9, "FeatureMessageSecurityAssist9" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTORENHANCEMENTS2, "FeatureVectorEnhancements2" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTORPACKEDDECIMALENHANCEMENT, "FeatureVectorPackedDecimalEnhancement" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREENHANCEDSORT, "FeatureEnhancedSort" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREDEFLATECONVERSION, "FeatureDeflateConversion" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREVECTORPACKEDDECIMALENHANCEMENT2, "FeatureVectorPackedDecimalEnhancement2" },
|
||||
{ SYSTEMZ_FEATURE_FEATURENNPASSIST, "FeatureNNPAssist" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREBEARENHANCEMENT, "FeatureBEAREnhancement" },
|
||||
{ SYSTEMZ_FEATURE_FEATURERESETDATPROTECTION, "FeatureResetDATProtection" },
|
||||
{ SYSTEMZ_FEATURE_FEATUREPROCESSORACTIVITYINSTRUMENTATION, "FeatureProcessorActivityInstrumentation" },
|
24272
arch/SystemZ/SystemZGenCSMappingInsn.inc
Normal file
24272
arch/SystemZ/SystemZGenCSMappingInsn.inc
Normal file
File diff suppressed because it is too large
Load Diff
2513
arch/SystemZ/SystemZGenCSMappingInsnName.inc
Normal file
2513
arch/SystemZ/SystemZGenCSMappingInsnName.inc
Normal file
File diff suppressed because it is too large
Load Diff
20132
arch/SystemZ/SystemZGenCSMappingInsnOp.inc
Normal file
20132
arch/SystemZ/SystemZGenCSMappingInsnOp.inc
Normal file
File diff suppressed because it is too large
Load Diff
34
arch/SystemZ/SystemZGenCSOpGroup.inc
Normal file
34
arch/SystemZ/SystemZGenCSOpGroup.inc
Normal file
@ -0,0 +1,34 @@
|
||||
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2024 */
|
||||
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Do not edit. */
|
||||
|
||||
/* Capstone's LLVM TableGen Backends: */
|
||||
/* https://github.com/capstone-engine/llvm-capstone */
|
||||
|
||||
SystemZ_OP_GROUP_Operand = 0,
|
||||
SystemZ_OP_GROUP_BDXAddrOperand = 1,
|
||||
SystemZ_OP_GROUP_S32ImmOperand = 2,
|
||||
SystemZ_OP_GROUP_S16ImmOperand = 3,
|
||||
SystemZ_OP_GROUP_BDAddrOperand = 4,
|
||||
SystemZ_OP_GROUP_U32ImmOperand = 5,
|
||||
SystemZ_OP_GROUP_U16ImmOperand = 6,
|
||||
SystemZ_OP_GROUP_S8ImmOperand = 7,
|
||||
SystemZ_OP_GROUP_Cond4Operand = 8,
|
||||
SystemZ_OP_GROUP_U8ImmOperand = 9,
|
||||
SystemZ_OP_GROUP_PCRelOperand = 10,
|
||||
SystemZ_OP_GROUP_U4ImmOperand = 11,
|
||||
SystemZ_OP_GROUP_BDLAddrOperand = 12,
|
||||
SystemZ_OP_GROUP_PCRelTLSOperand = 13,
|
||||
SystemZ_OP_GROUP_U48ImmOperand = 14,
|
||||
SystemZ_OP_GROUP_BDRAddrOperand = 15,
|
||||
SystemZ_OP_GROUP_U12ImmOperand = 16,
|
||||
SystemZ_OP_GROUP_BDVAddrOperand = 17,
|
||||
SystemZ_OP_GROUP_U2ImmOperand = 18,
|
||||
SystemZ_OP_GROUP_U1ImmOperand = 19,
|
||||
SystemZ_OP_GROUP_U3ImmOperand = 20,
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,65 @@
|
||||
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* Subtarget Enumeration Source Fragment *|
|
||||
|* *|
|
||||
|* Automatically generated file, do not edit! *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2024 */
|
||||
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
|
||||
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Do not edit. */
|
||||
|
||||
/* Capstone's LLVM TableGen Backends: */
|
||||
/* https://github.com/capstone-engine/llvm-capstone */
|
||||
|
||||
#ifdef GET_SUBTARGETINFO_ENUM
|
||||
#undef GET_SUBTARGETINFO_ENUM
|
||||
|
||||
enum {
|
||||
SystemZ_FeatureDFPPackedConversion = 1ULL << 0,
|
||||
SystemZ_FeatureDFPZonedConversion = 1ULL << 1,
|
||||
SystemZ_FeatureDistinctOps = 1ULL << 2,
|
||||
SystemZ_FeatureEnhancedDAT2 = 1ULL << 3,
|
||||
SystemZ_FeatureExecutionHint = 1ULL << 4,
|
||||
SystemZ_FeatureFPExtension = 1ULL << 5,
|
||||
SystemZ_FeatureFastSerialization = 1ULL << 6,
|
||||
SystemZ_FeatureGuardedStorage = 1ULL << 7,
|
||||
SystemZ_FeatureHighWord = 1ULL << 8,
|
||||
SystemZ_FeatureInsertReferenceBitsMultiple = 1ULL << 9,
|
||||
SystemZ_FeatureInterlockedAccess1 = 1ULL << 10,
|
||||
SystemZ_FeatureLoadAndTrap = 1ULL << 11,
|
||||
SystemZ_FeatureLoadAndZeroRightmostByte = 1ULL << 12,
|
||||
SystemZ_FeatureLoadStoreOnCond = 1ULL << 13,
|
||||
SystemZ_FeatureLoadStoreOnCond2 = 1ULL << 14,
|
||||
SystemZ_FeatureMessageSecurityAssist3 = 1ULL << 15,
|
||||
SystemZ_FeatureMessageSecurityAssist4 = 1ULL << 16,
|
||||
SystemZ_FeatureMessageSecurityAssist5 = 1ULL << 17,
|
||||
SystemZ_FeatureMessageSecurityAssist7 = 1ULL << 18,
|
||||
SystemZ_FeatureMessageSecurityAssist8 = 1ULL << 19,
|
||||
SystemZ_FeatureMiscellaneousExtensions = 1ULL << 20,
|
||||
SystemZ_FeatureMiscellaneousExtensions2 = 1ULL << 21,
|
||||
SystemZ_FeaturePopulationCount = 1ULL << 22,
|
||||
SystemZ_FeatureProcessorAssist = 1ULL << 23,
|
||||
SystemZ_FeatureResetReferenceBitsMultiple = 1ULL << 24,
|
||||
SystemZ_FeatureTransactionalExecution = 1ULL << 25,
|
||||
SystemZ_FeatureVector = 1ULL << 26,
|
||||
SystemZ_FeatureVectorEnhancements1 = 1ULL << 27,
|
||||
SystemZ_FeatureVectorPackedDecimal = 1ULL << 28,
|
||||
SystemZ_FeatureBEAREnhancement = 0,
|
||||
SystemZ_FeatureBackChain = 1,
|
||||
SystemZ_FeatureDFPPackedConversion = 2,
|
||||
SystemZ_FeatureDFPZonedConversion = 3,
|
||||
SystemZ_FeatureDeflateConversion = 4,
|
||||
SystemZ_FeatureDistinctOps = 5,
|
||||
SystemZ_FeatureEnhancedDAT2 = 6,
|
||||
SystemZ_FeatureEnhancedSort = 7,
|
||||
SystemZ_FeatureExecutionHint = 8,
|
||||
SystemZ_FeatureFPExtension = 9,
|
||||
SystemZ_FeatureFastSerialization = 10,
|
||||
SystemZ_FeatureGuardedStorage = 11,
|
||||
SystemZ_FeatureHighWord = 12,
|
||||
SystemZ_FeatureInsertReferenceBitsMultiple = 13,
|
||||
SystemZ_FeatureInterlockedAccess1 = 14,
|
||||
SystemZ_FeatureLoadAndTrap = 15,
|
||||
SystemZ_FeatureLoadAndZeroRightmostByte = 16,
|
||||
SystemZ_FeatureLoadStoreOnCond = 17,
|
||||
SystemZ_FeatureLoadStoreOnCond2 = 18,
|
||||
SystemZ_FeatureMessageSecurityAssist3 = 19,
|
||||
SystemZ_FeatureMessageSecurityAssist4 = 20,
|
||||
SystemZ_FeatureMessageSecurityAssist5 = 21,
|
||||
SystemZ_FeatureMessageSecurityAssist7 = 22,
|
||||
SystemZ_FeatureMessageSecurityAssist8 = 23,
|
||||
SystemZ_FeatureMessageSecurityAssist9 = 24,
|
||||
SystemZ_FeatureMiscellaneousExtensions = 25,
|
||||
SystemZ_FeatureMiscellaneousExtensions2 = 26,
|
||||
SystemZ_FeatureMiscellaneousExtensions3 = 27,
|
||||
SystemZ_FeatureNNPAssist = 28,
|
||||
SystemZ_FeaturePopulationCount = 29,
|
||||
SystemZ_FeatureProcessorActivityInstrumentation = 30,
|
||||
SystemZ_FeatureProcessorAssist = 31,
|
||||
SystemZ_FeatureResetDATProtection = 32,
|
||||
SystemZ_FeatureResetReferenceBitsMultiple = 33,
|
||||
SystemZ_FeatureSoftFloat = 34,
|
||||
SystemZ_FeatureTransactionalExecution = 35,
|
||||
SystemZ_FeatureVector = 36,
|
||||
SystemZ_FeatureVectorEnhancements1 = 37,
|
||||
SystemZ_FeatureVectorEnhancements2 = 38,
|
||||
SystemZ_FeatureVectorPackedDecimal = 39,
|
||||
SystemZ_FeatureVectorPackedDecimalEnhancement = 40,
|
||||
SystemZ_FeatureVectorPackedDecimalEnhancement2 = 41,
|
||||
SystemZ_NumSubtargetFeatures = 42
|
||||
};
|
||||
|
||||
#endif // GET_SUBTARGETINFO_ENUM
|
||||
|
||||
|
||||
|
||||
|
@ -1,433 +1,384 @@
|
||||
//===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax --------===//
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
/* Automatically translated source file from LLVM. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Only small edits allowed. */
|
||||
/* For multiple similar edits, please create a Patch for the translator. */
|
||||
|
||||
/* Capstone's C++ file translator: */
|
||||
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
|
||||
|
||||
//===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class prints an SystemZ MCInst to a .s file.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <capstone/platform.h>
|
||||
|
||||
#include "SystemZInstPrinter.h"
|
||||
#include "../../MCInst.h"
|
||||
#include "../../utils.h"
|
||||
#include "../../SStream.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../MathExtras.h"
|
||||
#include "../../MCAsmInfo.h"
|
||||
|
||||
#include "SystemZMapping.h"
|
||||
#include "SystemZInstPrinter.h"
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define CONCAT_(a, b) a##_##b
|
||||
|
||||
void SystemZ_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
||||
static void printAddress(const MCAsmInfo *MAI, MCRegister Base,
|
||||
const MCOperand *DispMO, MCRegister Index, SStream *O);
|
||||
static void printMCOperandMAI(const MCOperand *MO, const MCAsmInfo *MAI,
|
||||
SStream *O);
|
||||
static void printRegName(const MCInst *MI, SStream *O, MCRegister Reg);
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O);
|
||||
static void printOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU1ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU2ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU3ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
static void printPCRelOperand(MCInst *MI, uint64_t Address, int OpNum, SStream *O);
|
||||
static void printPCRelTLSOperand(MCInst *MI, uint64_t Address, int OpNum, SStream *O);
|
||||
// This forms part of the instruction name rather than the operand list.
|
||||
// Print the mnemonic for a condition-code mask ("ne", "lh", etc.)
|
||||
static void printCond4Operand(MCInst *MI, int OpNum, SStream *O);
|
||||
|
||||
#include "SystemZGenAsmWriter.inc"
|
||||
|
||||
#define DECLARE_printUImmOperand(N) \
|
||||
static void CONCAT(printUImmOperand, N)(MCInst * MI, int OpNum, SStream *O);
|
||||
DECLARE_printUImmOperand(1);
|
||||
DECLARE_printUImmOperand(2);
|
||||
DECLARE_printUImmOperand(3);
|
||||
DECLARE_printUImmOperand(4);
|
||||
DECLARE_printUImmOperand(8);
|
||||
DECLARE_printUImmOperand(12);
|
||||
DECLARE_printUImmOperand(16);
|
||||
DECLARE_printUImmOperand(32);
|
||||
DECLARE_printUImmOperand(48);
|
||||
|
||||
#define DECLARE_printSImmOperand(N) \
|
||||
static void CONCAT(printSImmOperand, N)(MCInst * MI, int OpNum, SStream *O);
|
||||
DECLARE_printSImmOperand(8);
|
||||
DECLARE_printSImmOperand(16);
|
||||
DECLARE_printSImmOperand(32);
|
||||
|
||||
static void printAddress(const MCAsmInfo *MAI, MCRegister Base,
|
||||
const MCOperand *DispMO, MCRegister Index, SStream *O)
|
||||
{
|
||||
/*
|
||||
if (((cs_struct *)ud)->detail != CS_OPT_ON)
|
||||
return;
|
||||
*/
|
||||
}
|
||||
|
||||
static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O)
|
||||
{
|
||||
printInt64(O, Disp);
|
||||
|
||||
if (Base) {
|
||||
printMCOperandMAI(DispMO, MAI, O);
|
||||
if (Base || Index) {
|
||||
SStream_concat0(O, "(");
|
||||
if (Index)
|
||||
SStream_concat(O, "%%%s, ", getRegisterName(Index));
|
||||
SStream_concat(O, "%%%s)", getRegisterName(Base));
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
} else if (!Index) {
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Disp;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
} else {
|
||||
SStream_concat(O, "(%%%s)", getRegisterName(Index));
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
if (Index) {
|
||||
printFormattedRegName(MAI, Index, O);
|
||||
SStream_concat0(O, ",");
|
||||
}
|
||||
if (Base)
|
||||
printFormattedRegName(MAI, Base, O);
|
||||
else
|
||||
SStream_concat0(O, "0");
|
||||
|
||||
SStream_concat0(O, ")");
|
||||
}
|
||||
}
|
||||
|
||||
static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
|
||||
static void printMCOperandMAI(const MCOperand *MO, const MCAsmInfo *MAI,
|
||||
SStream *O) {
|
||||
if (MCOperand_isReg(MO)) {
|
||||
if (!MCOperand_getReg(MO))
|
||||
SStream_concat1(O, '0');
|
||||
else
|
||||
printFormattedRegName(MAI, MCOperand_getReg(MO), O);
|
||||
}
|
||||
else if (MCOperand_isImm(MO))
|
||||
printInt64(markup_OS(O, Markup_Immediate), MCOperand_getImm(MO));
|
||||
else if (MCOperand_isExpr(MO))
|
||||
printExpr(O, MCOperand_getExpr(MO));
|
||||
else
|
||||
CS_ASSERT(0 && "Invalid operand");
|
||||
}
|
||||
|
||||
static void printMCOperand(const MCInst *MI, const MCOperand *MO, SStream *O)
|
||||
{
|
||||
if (MCOperand_isReg(MO)) {
|
||||
unsigned reg;
|
||||
if (!MCOperand_getReg(MO))
|
||||
SStream_concat0(O, "0");
|
||||
|
||||
reg = MCOperand_getReg(MO);
|
||||
SStream_concat(O, "%%%s", getRegisterName(reg));
|
||||
reg = SystemZ_map_register(reg);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_REG;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = reg;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
} else if (MCOperand_isImm(MO)) {
|
||||
int64_t Imm = MCOperand_getImm(MO);
|
||||
|
||||
printInt64(O, Imm);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Imm;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
printFormattedRegName(&MI->MAI, MCOperand_getReg(MO), O);
|
||||
} else if (MCOperand_isImm(MO))
|
||||
printInt64(markup_OS(O, Markup_Immediate),
|
||||
MCOperand_getImm(MO));
|
||||
else if (MCOperand_isExpr(MO))
|
||||
printExpr(O, MCOperand_getExpr(MO)); \
|
||||
else
|
||||
assert(0 && "Invalid operand");
|
||||
}
|
||||
|
||||
void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, SStream *O)
|
||||
{
|
||||
const char *RegName = getRegisterName(Reg);
|
||||
if (MAI->assemblerDialect == SYSTEMZASMDIALECT_AD_ATT) {
|
||||
// Skip register prefix so that only register number is left
|
||||
CS_ASSERT((isalpha(RegName[0]) && isdigit(RegName[1])));
|
||||
SStream_concat0(markup_OS(O, Markup_Register), (RegName + 1));
|
||||
} else
|
||||
SStream_concat1(markup_OS(O, Markup_Register), '%');
|
||||
SStream_concat0(markup_OS(O, Markup_Register), RegName);
|
||||
}
|
||||
|
||||
static void printRegName(const MCInst *MI, SStream *O, MCRegister Reg)
|
||||
{
|
||||
printFormattedRegName(&MI->MAI, Reg, O);
|
||||
}
|
||||
|
||||
static void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
|
||||
{
|
||||
printInstruction(MI, Address, O);
|
||||
}
|
||||
|
||||
#define DEFINE_printUImmOperand(N) \
|
||||
void CONCAT(printUImmOperand, N)(MCInst * MI, int OpNum, SStream *O) \
|
||||
{ \
|
||||
MCOperand *MO = MCInst_getOperand(MI, (OpNum)); \
|
||||
if (MCOperand_isExpr(MO)) { \
|
||||
printExpr(O, MCOperand_getExpr(MO)); \
|
||||
return; \
|
||||
} \
|
||||
uint64_t Value = (uint64_t)(MCOperand_getImm(MO)); \
|
||||
CS_ASSERT((isUIntN(N, Value) && "Invalid uimm argument")); \
|
||||
printUInt64(markup_OS(O, Markup_Immediate), Value); \
|
||||
}
|
||||
DEFINE_printUImmOperand(1);
|
||||
DEFINE_printUImmOperand(2);
|
||||
DEFINE_printUImmOperand(3);
|
||||
DEFINE_printUImmOperand(4);
|
||||
DEFINE_printUImmOperand(8);
|
||||
DEFINE_printUImmOperand(12);
|
||||
DEFINE_printUImmOperand(16);
|
||||
DEFINE_printUImmOperand(32);
|
||||
DEFINE_printUImmOperand(48);
|
||||
|
||||
#define DEFINE_printSImmOperand(N) \
|
||||
void CONCAT(printSImmOperand, N)(MCInst * MI, int OpNum, SStream *O) \
|
||||
{ \
|
||||
MCOperand *MO = MCInst_getOperand(MI, (OpNum)); \
|
||||
if (MCOperand_isExpr(MO)) { \
|
||||
printExpr(O, MCOperand_getExpr(MO)); \
|
||||
return; \
|
||||
} \
|
||||
int64_t Value = \
|
||||
MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
|
||||
CS_ASSERT( \
|
||||
(CONCAT(isInt, N)(Value) && "Invalid simm argument")); \
|
||||
if (N == 8) \
|
||||
printInt8(markup_OS(O, Markup_Immediate), Value); \
|
||||
else if (N == 16) \
|
||||
printInt16(markup_OS(O, Markup_Immediate), Value); \
|
||||
else if (N == 32) \
|
||||
printInt32(markup_OS(O, Markup_Immediate), Value); \
|
||||
else \
|
||||
CS_ASSERT(0 && "Unreachable"); \
|
||||
}
|
||||
DEFINE_printSImmOperand(8);
|
||||
DEFINE_printSImmOperand(16);
|
||||
DEFINE_printSImmOperand(32);
|
||||
|
||||
static void printU1ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<1>(Value) && "Invalid u1imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U1ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 1)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU2ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<2>(Value) && "Invalid u2imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U2ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 2)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU3ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<3>(Value) && "Invalid u4imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U3ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 3)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<4>(Value) && "Invalid u4imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
}
|
||||
|
||||
static void printU6ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<6>(Value) && "Invalid u6imm argument");
|
||||
|
||||
printUInt32(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U4ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 4)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int8_t Value = (int8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isInt<8>(Value) && "Invalid s8imm argument");
|
||||
|
||||
if (Value >= 0) {
|
||||
if (Value > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%x", Value);
|
||||
else
|
||||
SStream_concat(O, "%u", Value);
|
||||
} else {
|
||||
if (Value < -HEX_THRESHOLD)
|
||||
SStream_concat(O, "-0x%x", -Value);
|
||||
else
|
||||
SStream_concat(O, "-%u", -Value);
|
||||
}
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_S8ImmOperand, OpNum);
|
||||
CONCAT(printSImmOperand, 8)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
uint8_t Value = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<8>(Value) && "Invalid u8imm argument");
|
||||
|
||||
if (Value > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%x", Value);
|
||||
else
|
||||
SStream_concat(O, "%u", Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U8ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 8)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<12>(Value) && "Invalid u12imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U12ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 12)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int16_t Value = (int16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isInt<16>(Value) && "Invalid s16imm argument");
|
||||
|
||||
if (Value >= 0) {
|
||||
if (Value > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%x", Value);
|
||||
else
|
||||
SStream_concat(O, "%u", Value);
|
||||
} else {
|
||||
if (Value < -HEX_THRESHOLD)
|
||||
SStream_concat(O, "-0x%x", -Value);
|
||||
else
|
||||
SStream_concat(O, "-%u", -Value);
|
||||
}
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_S16ImmOperand, OpNum);
|
||||
CONCAT(printSImmOperand, 16)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
uint16_t Value = (uint16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<16>(Value) && "Invalid u16imm argument");
|
||||
|
||||
if (Value > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%x", Value);
|
||||
else
|
||||
SStream_concat(O, "%u", Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U16ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 16)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int32_t Value = (int32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isInt<32>(Value) && "Invalid s32imm argument");
|
||||
|
||||
printInt32(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_S32ImmOperand, OpNum);
|
||||
CONCAT(printSImmOperand, 32)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<32>(Value) && "Invalid u32imm argument");
|
||||
|
||||
printUInt32(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U32ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 32)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(isUInt<48>(Value) && "Invalid u48imm argument");
|
||||
printInt64(O, Value);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_U48ImmOperand, OpNum);
|
||||
CONCAT(printUImmOperand, 48)(MI, OpNum, O);
|
||||
}
|
||||
|
||||
static void printPCRelOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
static void printPCRelOperand(MCInst *MI, uint64_t Address, int OpNum, SStream *O)
|
||||
{
|
||||
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
||||
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_PCRelOperand, OpNum);
|
||||
MCOperand *MO = MCInst_getOperand(MI, (OpNum));
|
||||
if (MCOperand_isImm(MO)) {
|
||||
int64_t imm = (int64_t)MCOperand_getImm(MO);
|
||||
|
||||
printInt64(O, imm);
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = imm;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
}
|
||||
}
|
||||
printInt64(O, MCOperand_getImm(MO));
|
||||
} else
|
||||
printExpr(O, MCOperand_getExpr(MO));
|
||||
}
|
||||
|
||||
static void printPCRelTLSOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
static void printPCRelTLSOperand(MCInst *MI, uint64_t Address, int OpNum, SStream *O)
|
||||
{
|
||||
// Output the PC-relative operand.
|
||||
printPCRelOperand(MI, OpNum, O);
|
||||
printPCRelOperand(MI, MI->address, OpNum, O);
|
||||
|
||||
// Output the TLS marker if present.
|
||||
if ((unsigned)OpNum + 1 < MCInst_getNumOperands(MI)) {
|
||||
// Expressions not supported
|
||||
}
|
||||
}
|
||||
|
||||
static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
_printOperand(MI, MCInst_getOperand(MI, OpNum), O);
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_Operand, OpNum);
|
||||
printMCOperand(MI, MCInst_getOperand(MI, (OpNum)), O);
|
||||
}
|
||||
|
||||
static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
|
||||
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), 0, O);
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_BDAddrOperand, OpNum);
|
||||
printAddress(&MI->MAI, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))),
|
||||
MCInst_getOperand(MI, (OpNum + 1)), 0, O);
|
||||
}
|
||||
|
||||
static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
|
||||
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
|
||||
MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_BDXAddrOperand, OpNum);
|
||||
printAddress(&MI->MAI, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))),
|
||||
MCInst_getOperand(MI, (OpNum + 1)),
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2))), O);
|
||||
}
|
||||
|
||||
static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
|
||||
uint64_t Length = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 2));
|
||||
|
||||
if (Disp > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%"PRIx64, Disp);
|
||||
else
|
||||
SStream_concat(O, "%"PRIu64, Disp);
|
||||
|
||||
if (Length > HEX_THRESHOLD)
|
||||
SStream_concat(O, "(0x%"PRIx64, Length);
|
||||
else
|
||||
SStream_concat(O, "(%"PRIu64, Length);
|
||||
|
||||
if (Base)
|
||||
SStream_concat(O, ", %%%s", getRegisterName(Base));
|
||||
SStream_concat0(O, ")");
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = Length;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_BDLAddrOperand, OpNum);
|
||||
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
|
||||
MCOperand *DispMO = MCInst_getOperand(MI, (OpNum + 1));
|
||||
uint64_t Length = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 2)));
|
||||
printMCOperandMAI(DispMO, &MI->MAI, O);
|
||||
SStream_concat1(O, '(');
|
||||
printUInt64(O, Length);
|
||||
if (Base) {
|
||||
SStream_concat0(O, ",");
|
||||
printRegName(MI, O, Base);
|
||||
}
|
||||
SStream_concat0(O, ")");
|
||||
}
|
||||
|
||||
static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
|
||||
uint64_t Length = MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2));
|
||||
|
||||
if (Disp > HEX_THRESHOLD)
|
||||
SStream_concat(O, "0x%"PRIx64, Disp);
|
||||
else
|
||||
SStream_concat(O, "%"PRIu64, Disp);
|
||||
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_BDRAddrOperand, OpNum);
|
||||
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
|
||||
MCOperand *DispMO = MCInst_getOperand(MI, (OpNum + 1));
|
||||
unsigned Length = MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2)));
|
||||
printMCOperandMAI(DispMO, &MI->MAI, O);
|
||||
SStream_concat0(O, "(");
|
||||
SStream_concat(O, "%%%s", getRegisterName(Length));
|
||||
|
||||
if (Base)
|
||||
SStream_concat(O, ", %%%s", getRegisterName(Base));
|
||||
SStream_concat0(O, ")");
|
||||
|
||||
if (MI->csh->detail_opt) {
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = (uint8_t)SystemZ_map_register(Length);
|
||||
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
|
||||
MI->flat_insn->detail->sysz.op_count++;
|
||||
printRegName(MI, O, Length);
|
||||
if (Base) {
|
||||
SStream_concat0(O, ",");
|
||||
printRegName(MI, O, Base);
|
||||
}
|
||||
SStream_concat0(O, ")");
|
||||
}
|
||||
|
||||
static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
|
||||
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
|
||||
MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_BDVAddrOperand, OpNum);
|
||||
printAddress(&MI->MAI, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))),
|
||||
MCInst_getOperand(MI, (OpNum + 1)),
|
||||
MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2))), O);
|
||||
}
|
||||
|
||||
static void printCond4Operand(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
static const char *const CondNames[] = {
|
||||
"o", "h", "nle", "l", "nhe", "lh", "ne",
|
||||
"e", "nlh", "he", "nl", "le", "nh", "no"
|
||||
};
|
||||
|
||||
uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
// assert(Imm > 0 && Imm < 15 && "Invalid condition");
|
||||
add_cs_detail(MI, SystemZ_OP_GROUP_Cond4Operand, OpNum);
|
||||
static const char *const CondNames[] = { "o", "h", "nle", "l",
|
||||
"nhe", "lh", "ne", "e",
|
||||
"nlh", "he", "nl", "le",
|
||||
"nh", "no" };
|
||||
uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
|
||||
CS_ASSERT((Imm > 0 && Imm < 15 && "Invalid condition"));
|
||||
SStream_concat0(O, CondNames[Imm - 1]);
|
||||
|
||||
if (MI->csh->detail_opt)
|
||||
MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm;
|
||||
}
|
||||
|
||||
#define PRINT_ALIAS_INSTR
|
||||
#include "SystemZGenAsmWriter.inc"
|
||||
|
||||
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
const char *SystemZ_LLVM_getRegisterName(unsigned RegNo)
|
||||
{
|
||||
printInstruction(MI, O, Info);
|
||||
return getRegisterName(RegNo);
|
||||
}
|
||||
|
||||
#endif
|
||||
void SystemZ_LLVM_printInstruction(MCInst *MI, const char *Annotation, SStream *O)
|
||||
{
|
||||
printInst(MI, MI->address, Annotation, O);
|
||||
}
|
||||
|
@ -1,15 +1,51 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
/* Automatically translated source file from LLVM. */
|
||||
|
||||
#ifndef CS_SYSZINSTPRINTER_H
|
||||
#define CS_SYSZINSTPRINTER_H
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
#include "../../MCInst.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../SStream.h"
|
||||
/* Only small edits allowed. */
|
||||
/* For multiple similar edits, please create a Patch for the translator. */
|
||||
|
||||
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info);
|
||||
/* Capstone's C++ file translator: */
|
||||
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
|
||||
|
||||
void SystemZ_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci);
|
||||
//==- SystemZInstPrinter.h - Convert SystemZ MCInst to assembly --*- C++ -*-==//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class prints a SystemZ MCInst to a .s file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#endif
|
||||
#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H
|
||||
#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <capstone/platform.h>
|
||||
|
||||
#include "../../MCInstPrinter.h"
|
||||
#include "../../cs_priv.h"
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define CONCAT_(a, b) a##_##b
|
||||
|
||||
//
|
||||
// All function declarations are moved for now to the C file to make them static.
|
||||
//
|
||||
void printOperandAsmInfo(const MCOperand *MO, const MCAsmInfo *MAI, SStream *O);
|
||||
void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, SStream *O);
|
||||
|
||||
// Print various types of operand.
|
||||
;
|
||||
|
||||
// end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H
|
||||
|
22
arch/SystemZ/SystemZLinkage.h
Normal file
22
arch/SystemZ/SystemZLinkage.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
|
||||
#ifndef CS_SYSTEMZ_LINKAGE_H
|
||||
#define CS_SYSTEMZ_LINKAGE_H
|
||||
|
||||
// Function definitions to call static LLVM functions.
|
||||
|
||||
#include "../../MCDisassembler.h"
|
||||
#include "../../MCInst.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "../../SStream.h"
|
||||
#include "capstone/capstone.h"
|
||||
|
||||
DecodeStatus SystemZ_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||
size_t ByteLen, MCInst *MI, uint16_t *Size,
|
||||
uint64_t Address, void *Info);
|
||||
const char *SystemZ_LLVM_getRegisterName(unsigned RegNo);
|
||||
void SystemZ_LLVM_printInstruction(MCInst *MI, const char *Annot,
|
||||
SStream *O);
|
||||
|
||||
#endif // CS_SYSTEMZ_LINKAGE_H
|
@ -1,195 +1,157 @@
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
/* Automatically translated source file from LLVM. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Only small edits allowed. */
|
||||
/* For multiple similar edits, please create a Patch for the translator. */
|
||||
|
||||
/* Capstone's C++ file translator: */
|
||||
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
|
||||
|
||||
//===-- SystemZMCTargetDesc.cpp - SystemZ target descriptions -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <capstone/platform.h>
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "../../MCInst.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
#include "SystemZInstPrinter.h"
|
||||
|
||||
#define GET_INSTRINFO_MC_DESC
|
||||
#define ENABLE_INSTR_PREDICATE_VERIFIER
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_MC_DESC
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define CONCAT_(a, b) a##_##b
|
||||
|
||||
const unsigned SystemZMC_GR32Regs[16] = {
|
||||
SystemZ_R0L, SystemZ_R1L, SystemZ_R2L, SystemZ_R3L,
|
||||
SystemZ_R4L, SystemZ_R5L, SystemZ_R6L, SystemZ_R7L,
|
||||
SystemZ_R8L, SystemZ_R9L, SystemZ_R10L, SystemZ_R11L,
|
||||
SystemZ_R0L, SystemZ_R1L, SystemZ_R2L, SystemZ_R3L,
|
||||
SystemZ_R4L, SystemZ_R5L, SystemZ_R6L, SystemZ_R7L,
|
||||
SystemZ_R8L, SystemZ_R9L, SystemZ_R10L, SystemZ_R11L,
|
||||
SystemZ_R12L, SystemZ_R13L, SystemZ_R14L, SystemZ_R15L
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_GRH32Regs[16] = {
|
||||
SystemZ_R0H, SystemZ_R1H, SystemZ_R2H, SystemZ_R3H,
|
||||
SystemZ_R4H, SystemZ_R5H, SystemZ_R6H, SystemZ_R7H,
|
||||
SystemZ_R8H, SystemZ_R9H, SystemZ_R10H, SystemZ_R11H,
|
||||
SystemZ_R0H, SystemZ_R1H, SystemZ_R2H, SystemZ_R3H,
|
||||
SystemZ_R4H, SystemZ_R5H, SystemZ_R6H, SystemZ_R7H,
|
||||
SystemZ_R8H, SystemZ_R9H, SystemZ_R10H, SystemZ_R11H,
|
||||
SystemZ_R12H, SystemZ_R13H, SystemZ_R14H, SystemZ_R15H
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_GR64Regs[16] = {
|
||||
SystemZ_R0D, SystemZ_R1D, SystemZ_R2D, SystemZ_R3D,
|
||||
SystemZ_R4D, SystemZ_R5D, SystemZ_R6D, SystemZ_R7D,
|
||||
SystemZ_R8D, SystemZ_R9D, SystemZ_R10D, SystemZ_R11D,
|
||||
SystemZ_R0D, SystemZ_R1D, SystemZ_R2D, SystemZ_R3D,
|
||||
SystemZ_R4D, SystemZ_R5D, SystemZ_R6D, SystemZ_R7D,
|
||||
SystemZ_R8D, SystemZ_R9D, SystemZ_R10D, SystemZ_R11D,
|
||||
SystemZ_R12D, SystemZ_R13D, SystemZ_R14D, SystemZ_R15D
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_GR128Regs[16] = {
|
||||
SystemZ_R0Q, 0, SystemZ_R2Q, 0,
|
||||
SystemZ_R4Q, 0, SystemZ_R6Q, 0,
|
||||
SystemZ_R8Q, 0, SystemZ_R10Q, 0,
|
||||
SystemZ_R12Q, 0, SystemZ_R14Q, 0
|
||||
};
|
||||
const unsigned SystemZMC_GR128Regs[16] = { SystemZ_R0Q, 0, SystemZ_R2Q, 0,
|
||||
SystemZ_R4Q, 0, SystemZ_R6Q, 0,
|
||||
SystemZ_R8Q, 0, SystemZ_R10Q, 0,
|
||||
SystemZ_R12Q, 0, SystemZ_R14Q, 0 };
|
||||
|
||||
const unsigned SystemZMC_FP32Regs[16] = {
|
||||
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S,
|
||||
SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S,
|
||||
SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S,
|
||||
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S,
|
||||
SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S,
|
||||
SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S,
|
||||
SystemZ_F12S, SystemZ_F13S, SystemZ_F14S, SystemZ_F15S
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_FP64Regs[16] = {
|
||||
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D,
|
||||
SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D,
|
||||
SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D,
|
||||
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D,
|
||||
SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D,
|
||||
SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D,
|
||||
SystemZ_F12D, SystemZ_F13D, SystemZ_F14D, SystemZ_F15D
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_FP128Regs[16] = {
|
||||
SystemZ_F0Q, SystemZ_F1Q, 0, 0,
|
||||
SystemZ_F4Q, SystemZ_F5Q, 0, 0,
|
||||
SystemZ_F8Q, SystemZ_F9Q, 0, 0,
|
||||
SystemZ_F12Q, SystemZ_F13Q, 0, 0
|
||||
};
|
||||
const unsigned SystemZMC_FP128Regs[16] = { SystemZ_F0Q, SystemZ_F1Q, 0, 0,
|
||||
SystemZ_F4Q, SystemZ_F5Q, 0, 0,
|
||||
SystemZ_F8Q, SystemZ_F9Q, 0, 0,
|
||||
SystemZ_F12Q, SystemZ_F13Q, 0, 0 };
|
||||
|
||||
const unsigned SystemZMC_VR32Regs[32] = {
|
||||
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S,
|
||||
SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S,
|
||||
SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S,
|
||||
SystemZ_F12S, SystemZ_F13S, SystemZ_F14S, SystemZ_F15S,
|
||||
SystemZ_F16S, SystemZ_F17S, SystemZ_F18S, SystemZ_F19S,
|
||||
SystemZ_F20S, SystemZ_F21S, SystemZ_F22S, SystemZ_F23S,
|
||||
SystemZ_F24S, SystemZ_F25S, SystemZ_F26S, SystemZ_F27S,
|
||||
SystemZ_F28S, SystemZ_F29S, SystemZ_F30S, SystemZ_F31S
|
||||
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S, SystemZ_F4S,
|
||||
SystemZ_F5S, SystemZ_F6S, SystemZ_F7S, SystemZ_F8S, SystemZ_F9S,
|
||||
SystemZ_F10S, SystemZ_F11S, SystemZ_F12S, SystemZ_F13S, SystemZ_F14S,
|
||||
SystemZ_F15S, SystemZ_F16S, SystemZ_F17S, SystemZ_F18S, SystemZ_F19S,
|
||||
SystemZ_F20S, SystemZ_F21S, SystemZ_F22S, SystemZ_F23S, SystemZ_F24S,
|
||||
SystemZ_F25S, SystemZ_F26S, SystemZ_F27S, SystemZ_F28S, SystemZ_F29S,
|
||||
SystemZ_F30S, SystemZ_F31S
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_VR64Regs[32] = {
|
||||
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D,
|
||||
SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D,
|
||||
SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D,
|
||||
SystemZ_F12D, SystemZ_F13D, SystemZ_F14D, SystemZ_F15D,
|
||||
SystemZ_F16D, SystemZ_F17D, SystemZ_F18D, SystemZ_F19D,
|
||||
SystemZ_F20D, SystemZ_F21D, SystemZ_F22D, SystemZ_F23D,
|
||||
SystemZ_F24D, SystemZ_F25D, SystemZ_F26D, SystemZ_F27D,
|
||||
SystemZ_F28D, SystemZ_F29D, SystemZ_F30D, SystemZ_F31D
|
||||
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D, SystemZ_F4D,
|
||||
SystemZ_F5D, SystemZ_F6D, SystemZ_F7D, SystemZ_F8D, SystemZ_F9D,
|
||||
SystemZ_F10D, SystemZ_F11D, SystemZ_F12D, SystemZ_F13D, SystemZ_F14D,
|
||||
SystemZ_F15D, SystemZ_F16D, SystemZ_F17D, SystemZ_F18D, SystemZ_F19D,
|
||||
SystemZ_F20D, SystemZ_F21D, SystemZ_F22D, SystemZ_F23D, SystemZ_F24D,
|
||||
SystemZ_F25D, SystemZ_F26D, SystemZ_F27D, SystemZ_F28D, SystemZ_F29D,
|
||||
SystemZ_F30D, SystemZ_F31D
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_VR128Regs[32] = {
|
||||
SystemZ_V0, SystemZ_V1, SystemZ_V2, SystemZ_V3,
|
||||
SystemZ_V4, SystemZ_V5, SystemZ_V6, SystemZ_V7,
|
||||
SystemZ_V8, SystemZ_V9, SystemZ_V10, SystemZ_V11,
|
||||
SystemZ_V12, SystemZ_V13, SystemZ_V14, SystemZ_V15,
|
||||
SystemZ_V16, SystemZ_V17, SystemZ_V18, SystemZ_V19,
|
||||
SystemZ_V20, SystemZ_V21, SystemZ_V22, SystemZ_V23,
|
||||
SystemZ_V24, SystemZ_V25, SystemZ_V26, SystemZ_V27,
|
||||
SystemZ_V28, SystemZ_V29, SystemZ_V30, SystemZ_V31
|
||||
SystemZ_V0, SystemZ_V1, SystemZ_V2, SystemZ_V3, SystemZ_V4,
|
||||
SystemZ_V5, SystemZ_V6, SystemZ_V7, SystemZ_V8, SystemZ_V9,
|
||||
SystemZ_V10, SystemZ_V11, SystemZ_V12, SystemZ_V13, SystemZ_V14,
|
||||
SystemZ_V15, SystemZ_V16, SystemZ_V17, SystemZ_V18, SystemZ_V19,
|
||||
SystemZ_V20, SystemZ_V21, SystemZ_V22, SystemZ_V23, SystemZ_V24,
|
||||
SystemZ_V25, SystemZ_V26, SystemZ_V27, SystemZ_V28, SystemZ_V29,
|
||||
SystemZ_V30, SystemZ_V31
|
||||
};
|
||||
|
||||
const unsigned SystemZMC_AR32Regs[16] = {
|
||||
SystemZ_A0, SystemZ_A1, SystemZ_A2, SystemZ_A3,
|
||||
SystemZ_A4, SystemZ_A5, SystemZ_A6, SystemZ_A7,
|
||||
SystemZ_A8, SystemZ_A9, SystemZ_A10, SystemZ_A11,
|
||||
SystemZ_A12, SystemZ_A13, SystemZ_A14, SystemZ_A15
|
||||
};
|
||||
const unsigned SystemZMC_AR32Regs[16] = { SystemZ_A0, SystemZ_A1, SystemZ_A2,
|
||||
SystemZ_A3, SystemZ_A4, SystemZ_A5,
|
||||
SystemZ_A6, SystemZ_A7, SystemZ_A8,
|
||||
SystemZ_A9, SystemZ_A10, SystemZ_A11,
|
||||
SystemZ_A12, SystemZ_A13, SystemZ_A14,
|
||||
SystemZ_A15 };
|
||||
|
||||
const unsigned SystemZMC_CR64Regs[16] = {
|
||||
SystemZ_C0, SystemZ_C1, SystemZ_C2, SystemZ_C3,
|
||||
SystemZ_C4, SystemZ_C5, SystemZ_C6, SystemZ_C7,
|
||||
SystemZ_C8, SystemZ_C9, SystemZ_C10, SystemZ_C11,
|
||||
SystemZ_C12, SystemZ_C13, SystemZ_C14, SystemZ_C15
|
||||
};
|
||||
|
||||
/* All register classes that have 0-15. */
|
||||
#define DEF_REG16(N) \
|
||||
[SystemZ_R ## N ## L] = N, \
|
||||
[SystemZ_R ## N ## H] = N, \
|
||||
[SystemZ_R ## N ## D] = N, \
|
||||
[SystemZ_F ## N ## S] = N, \
|
||||
[SystemZ_F ## N ## D] = N, \
|
||||
[SystemZ_V ## N] = N, \
|
||||
[SystemZ_A ## N] = N, \
|
||||
[SystemZ_C ## N] = N
|
||||
|
||||
/* All register classes that (also) have 16-31. */
|
||||
#define DEF_REG32(N) \
|
||||
[SystemZ_F ## N ## S] = N, \
|
||||
[SystemZ_F ## N ## D] = N, \
|
||||
[SystemZ_V ## N] = N
|
||||
|
||||
static const uint8_t Map[SystemZ_NUM_TARGET_REGS] = {
|
||||
DEF_REG16(0),
|
||||
DEF_REG16(1),
|
||||
DEF_REG16(2),
|
||||
DEF_REG16(3),
|
||||
DEF_REG16(4),
|
||||
DEF_REG16(5),
|
||||
DEF_REG16(6),
|
||||
DEF_REG16(8),
|
||||
DEF_REG16(9),
|
||||
DEF_REG16(10),
|
||||
DEF_REG16(11),
|
||||
DEF_REG16(12),
|
||||
DEF_REG16(13),
|
||||
DEF_REG16(14),
|
||||
DEF_REG16(15),
|
||||
|
||||
DEF_REG32(16),
|
||||
DEF_REG32(17),
|
||||
DEF_REG32(18),
|
||||
DEF_REG32(19),
|
||||
DEF_REG32(20),
|
||||
DEF_REG32(21),
|
||||
DEF_REG32(22),
|
||||
DEF_REG32(23),
|
||||
DEF_REG32(24),
|
||||
DEF_REG32(25),
|
||||
DEF_REG32(26),
|
||||
DEF_REG32(27),
|
||||
DEF_REG32(28),
|
||||
DEF_REG32(29),
|
||||
DEF_REG32(30),
|
||||
DEF_REG32(31),
|
||||
|
||||
/* The float Q registers are non-sequential. */
|
||||
[SystemZ_F0Q] = 0,
|
||||
[SystemZ_F1Q] = 1,
|
||||
[SystemZ_F4Q] = 4,
|
||||
[SystemZ_F5Q] = 5,
|
||||
[SystemZ_F8Q] = 8,
|
||||
[SystemZ_F9Q] = 9,
|
||||
[SystemZ_F12Q] = 12,
|
||||
[SystemZ_F13Q] = 13,
|
||||
|
||||
/* The integer Q registers are all even. */
|
||||
[SystemZ_R0Q] = 0,
|
||||
[SystemZ_R2Q] = 2,
|
||||
[SystemZ_R4Q] = 4,
|
||||
[SystemZ_R6Q] = 6,
|
||||
[SystemZ_R8Q] = 8,
|
||||
[SystemZ_R10Q] = 10,
|
||||
[SystemZ_R12Q] = 12,
|
||||
[SystemZ_R14Q] = 14,
|
||||
};
|
||||
const unsigned SystemZMC_CR64Regs[16] = { SystemZ_C0, SystemZ_C1, SystemZ_C2,
|
||||
SystemZ_C3, SystemZ_C4, SystemZ_C5,
|
||||
SystemZ_C6, SystemZ_C7, SystemZ_C8,
|
||||
SystemZ_C9, SystemZ_C10, SystemZ_C11,
|
||||
SystemZ_C12, SystemZ_C13, SystemZ_C14,
|
||||
SystemZ_C15 };
|
||||
|
||||
unsigned SystemZMC_getFirstReg(unsigned Reg)
|
||||
{
|
||||
// assert(Reg < SystemZ_NUM_TARGET_REGS);
|
||||
static unsigned Map[NUM_TARGET_REGS];
|
||||
static bool Initialized = false;
|
||||
if (!Initialized) {
|
||||
for (unsigned I = 0; I < 16; ++I) {
|
||||
Map[SystemZMC_GR32Regs[I]] = I;
|
||||
Map[SystemZMC_GRH32Regs[I]] = I;
|
||||
Map[SystemZMC_GR64Regs[I]] = I;
|
||||
Map[SystemZMC_GR128Regs[I]] = I;
|
||||
Map[SystemZMC_FP128Regs[I]] = I;
|
||||
Map[SystemZMC_AR32Regs[I]] = I;
|
||||
}
|
||||
for (unsigned I = 0; I < 32; ++I) {
|
||||
Map[SystemZMC_VR32Regs[I]] = I;
|
||||
Map[SystemZMC_VR64Regs[I]] = I;
|
||||
Map[SystemZMC_VR128Regs[I]] = I;
|
||||
}
|
||||
}
|
||||
CS_ASSERT((Reg < SystemZ_NUM_TARGET_REGS));
|
||||
return Map[Reg];
|
||||
}
|
||||
|
||||
#endif
|
||||
// end namespace
|
||||
|
@ -1,17 +1,39 @@
|
||||
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|
||||
/* Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
/* Automatically translated source file from LLVM. */
|
||||
|
||||
/* LLVM-commit: <commit> */
|
||||
/* LLVM-tag: <tag> */
|
||||
|
||||
/* Only small edits allowed. */
|
||||
/* For multiple similar edits, please create a Patch for the translator. */
|
||||
|
||||
/* Capstone's C++ file translator: */
|
||||
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
|
||||
|
||||
//===-- SystemZMCTargetDesc.h - SystemZ target descriptions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZMCTARGETDESC_H
|
||||
#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZMCTARGETDESC_H
|
||||
|
||||
#ifndef CS_SYSTEMZMCTARGETDESC_H
|
||||
#define CS_SYSTEMZMCTARGETDESC_H
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <capstone/platform.h>
|
||||
|
||||
#include "../../MCInstPrinter.h"
|
||||
#include "../../cs_priv.h"
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define CONCAT_(a, b) a##_##b
|
||||
|
||||
// CS namespace begin: SystemZMC
|
||||
|
||||
// Maps of asm register numbers to LLVM register numbers, with 0 indicating
|
||||
// an invalid register. In principle we could use 32-bit and 64-bit register
|
||||
@ -20,32 +42,72 @@
|
||||
// as %r0-%r15. It seems better to provide the same interface for
|
||||
// all classes though.
|
||||
extern const unsigned SystemZMC_GR32Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_GRH32Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_GR64Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_GR128Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_FP32Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_FP64Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_FP128Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_VR32Regs[32];
|
||||
|
||||
extern const unsigned SystemZMC_VR64Regs[32];
|
||||
|
||||
extern const unsigned SystemZMC_VR128Regs[32];
|
||||
|
||||
extern const unsigned SystemZMC_AR32Regs[16];
|
||||
|
||||
extern const unsigned SystemZMC_CR64Regs[16];
|
||||
|
||||
// Return the 0-based number of the first architectural register that
|
||||
// contains the given LLVM register. E.g. R1D -> 1.
|
||||
unsigned SystemZMC_getFirstReg(unsigned Reg);
|
||||
|
||||
// Return the given register as a GR64.
|
||||
inline unsigned SystemZMC_getRegAsGR64(unsigned Reg)
|
||||
{
|
||||
return SystemZMC_GR64Regs[SystemZMC_getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a low GR32.
|
||||
inline unsigned SystemZMC_getRegAsGR32(unsigned Reg)
|
||||
{
|
||||
return SystemZMC_GR32Regs[SystemZMC_getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a high GR32.
|
||||
inline unsigned SystemZMC_getRegAsGRH32(unsigned Reg)
|
||||
{
|
||||
return SystemZMC_GRH32Regs[SystemZMC_getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a VR128.
|
||||
inline unsigned SystemZMC_getRegAsVR128(unsigned Reg)
|
||||
{
|
||||
return SystemZMC_VR128Regs[SystemZMC_getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// CS namespace end: SystemZMC
|
||||
|
||||
// end namespace SystemZMC
|
||||
|
||||
// Defines symbolic names for SystemZ registers.
|
||||
// This defines a mapping from register name to register number.
|
||||
//#define GET_REGINFO_ENUM
|
||||
//#include "SystemZGenRegisterInfo.inc"
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
// Defines symbolic names for the SystemZ instructions.
|
||||
//#define GET_INSTRINFO_ENUM
|
||||
//#include "SystemZGenInstrInfo.inc"
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#define GET_INSTRINFO_MC_HELPER_DECLS
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
//#define GET_SUBTARGETINFO_ENUM
|
||||
//#include "SystemZGenSubtargetInfo.inc"
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
#endif
|
||||
|
@ -1,224 +1,130 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
/* By Rot127 <unisono@quyllur.org> 2022-2023 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
#ifdef CAPSTONE_HAS_SYSTEMZ
|
||||
|
||||
#include <stdio.h> // debug
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Mapping.h"
|
||||
#include "../../utils.h"
|
||||
#include "../../cs_simple_types.h"
|
||||
#include <capstone/cs_operand.h>
|
||||
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
#include "SystemZMapping.h"
|
||||
#include "SystemZLinkage.h"
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map reg_name_maps[] = {
|
||||
{ SYSZ_REG_INVALID, NULL },
|
||||
|
||||
{ SYSZ_REG_0, "0" },
|
||||
{ SYSZ_REG_1, "1" },
|
||||
{ SYSZ_REG_2, "2" },
|
||||
{ SYSZ_REG_3, "3" },
|
||||
{ SYSZ_REG_4, "4" },
|
||||
{ SYSZ_REG_5, "5" },
|
||||
{ SYSZ_REG_6, "6" },
|
||||
{ SYSZ_REG_7, "7" },
|
||||
{ SYSZ_REG_8, "8" },
|
||||
{ SYSZ_REG_9, "9" },
|
||||
{ SYSZ_REG_10, "10" },
|
||||
{ SYSZ_REG_11, "11" },
|
||||
{ SYSZ_REG_12, "12" },
|
||||
{ SYSZ_REG_13, "13" },
|
||||
{ SYSZ_REG_14, "14" },
|
||||
{ SYSZ_REG_15, "15" },
|
||||
{ SYSZ_REG_CC, "cc"},
|
||||
{ SYSZ_REG_F0, "f0" },
|
||||
{ SYSZ_REG_F1, "f1" },
|
||||
{ SYSZ_REG_F2, "f2" },
|
||||
{ SYSZ_REG_F3, "f3" },
|
||||
{ SYSZ_REG_F4, "f4" },
|
||||
{ SYSZ_REG_F5, "f5" },
|
||||
{ SYSZ_REG_F6, "f6" },
|
||||
{ SYSZ_REG_F7, "f7" },
|
||||
{ SYSZ_REG_F8, "f8" },
|
||||
{ SYSZ_REG_F9, "f9" },
|
||||
{ SYSZ_REG_F10, "f10" },
|
||||
{ SYSZ_REG_F11, "f11" },
|
||||
{ SYSZ_REG_F12, "f12" },
|
||||
{ SYSZ_REG_F13, "f13" },
|
||||
{ SYSZ_REG_F14, "f14" },
|
||||
{ SYSZ_REG_F15, "f15" },
|
||||
{ SYSZ_REG_R0L, "r0l" },
|
||||
{ SYSZ_REG_A0, "a0" },
|
||||
{ SYSZ_REG_A1, "a1" },
|
||||
{ SYSZ_REG_A2, "a2" },
|
||||
{ SYSZ_REG_A3, "a3" },
|
||||
{ SYSZ_REG_A4, "a4" },
|
||||
{ SYSZ_REG_A5, "a5" },
|
||||
{ SYSZ_REG_A6, "a6" },
|
||||
{ SYSZ_REG_A7, "a7" },
|
||||
{ SYSZ_REG_A8, "a8" },
|
||||
{ SYSZ_REG_A9, "a9" },
|
||||
{ SYSZ_REG_A10, "a10" },
|
||||
{ SYSZ_REG_A11, "a11" },
|
||||
{ SYSZ_REG_A12, "a12" },
|
||||
{ SYSZ_REG_A13, "a13" },
|
||||
{ SYSZ_REG_A14, "a14" },
|
||||
{ SYSZ_REG_A15, "a15" },
|
||||
{ SYSZ_REG_C0, "c0" },
|
||||
{ SYSZ_REG_C1, "c1" },
|
||||
{ SYSZ_REG_C2, "c2" },
|
||||
{ SYSZ_REG_C3, "c3" },
|
||||
{ SYSZ_REG_C4, "c4" },
|
||||
{ SYSZ_REG_C5, "c5" },
|
||||
{ SYSZ_REG_C6, "c6" },
|
||||
{ SYSZ_REG_C7, "c7" },
|
||||
{ SYSZ_REG_C8, "c8" },
|
||||
{ SYSZ_REG_C9, "c9" },
|
||||
{ SYSZ_REG_C10, "c10" },
|
||||
{ SYSZ_REG_C11, "c11" },
|
||||
{ SYSZ_REG_C12, "c12" },
|
||||
{ SYSZ_REG_C13, "c13" },
|
||||
{ SYSZ_REG_C14, "c14" },
|
||||
{ SYSZ_REG_C15, "c15" },
|
||||
{ SYSZ_REG_V0, "v0" },
|
||||
{ SYSZ_REG_V1, "v1" },
|
||||
{ SYSZ_REG_V2, "v2" },
|
||||
{ SYSZ_REG_V3, "v3" },
|
||||
{ SYSZ_REG_V4, "v4" },
|
||||
{ SYSZ_REG_V5, "v5" },
|
||||
{ SYSZ_REG_V6, "v6" },
|
||||
{ SYSZ_REG_V7, "v7" },
|
||||
{ SYSZ_REG_V8, "v8" },
|
||||
{ SYSZ_REG_V9, "v9" },
|
||||
{ SYSZ_REG_V10, "v10" },
|
||||
{ SYSZ_REG_V11, "v11" },
|
||||
{ SYSZ_REG_V12, "v12" },
|
||||
{ SYSZ_REG_V13, "v13" },
|
||||
{ SYSZ_REG_V14, "v14" },
|
||||
{ SYSZ_REG_V15, "v15" },
|
||||
{ SYSZ_REG_V16, "v16" },
|
||||
{ SYSZ_REG_V17, "v17" },
|
||||
{ SYSZ_REG_V18, "v18" },
|
||||
{ SYSZ_REG_V19, "v19" },
|
||||
{ SYSZ_REG_V20, "v20" },
|
||||
{ SYSZ_REG_V21, "v21" },
|
||||
{ SYSZ_REG_V22, "v22" },
|
||||
{ SYSZ_REG_V23, "v23" },
|
||||
{ SYSZ_REG_V24, "v24" },
|
||||
{ SYSZ_REG_V25, "v25" },
|
||||
{ SYSZ_REG_V26, "v26" },
|
||||
{ SYSZ_REG_V27, "v27" },
|
||||
{ SYSZ_REG_V28, "v28" },
|
||||
{ SYSZ_REG_V29, "v29" },
|
||||
{ SYSZ_REG_V30, "v30" },
|
||||
{ SYSZ_REG_V31, "v31" },
|
||||
{ SYSZ_REG_F16, "f16" },
|
||||
{ SYSZ_REG_F17, "f17" },
|
||||
{ SYSZ_REG_F18, "f18" },
|
||||
{ SYSZ_REG_F19, "f19" },
|
||||
{ SYSZ_REG_F20, "f20" },
|
||||
{ SYSZ_REG_F21, "f21" },
|
||||
{ SYSZ_REG_F22, "f22" },
|
||||
{ SYSZ_REG_F23, "f23" },
|
||||
{ SYSZ_REG_F24, "f24" },
|
||||
{ SYSZ_REG_F25, "f25" },
|
||||
{ SYSZ_REG_F26, "f26" },
|
||||
{ SYSZ_REG_F27, "f27" },
|
||||
{ SYSZ_REG_F28, "f28" },
|
||||
{ SYSZ_REG_F29, "f29" },
|
||||
{ SYSZ_REG_F30, "f30" },
|
||||
{ SYSZ_REG_F31, "f31" },
|
||||
{ SYSZ_REG_F0Q, "f0q" },
|
||||
{ SYSZ_REG_F4Q, "f4q" },
|
||||
static const char *const insn_name_maps[] = {
|
||||
#include "SystemZGenCSMappingInsnName.inc"
|
||||
};
|
||||
|
||||
static const name_map insn_alias_mnem_map[] = {
|
||||
#include "SystemZGenCSAliasMnemMap.inc"
|
||||
{ SYSTEMZ_INS_ALIAS_END, NULL },
|
||||
};
|
||||
|
||||
static const map_insn_ops insn_operands[] = {
|
||||
#include "SystemZGenCSMappingInsnOp.inc"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
const insn_map systemz_insns[] = {
|
||||
#include "SystemZGenCSMappingInsn.inc"
|
||||
};
|
||||
|
||||
void SystemZ_set_instr_map_data(MCInst *MI, const uint8_t *Bytes, size_t BytesLen)
|
||||
{
|
||||
map_cs_id(MI, systemz_insns, ARR_SIZE(systemz_insns));
|
||||
map_implicit_reads(MI, systemz_insns);
|
||||
map_implicit_writes(MI, systemz_insns);
|
||||
map_groups(MI, systemz_insns);
|
||||
const systemz_suppl_info *suppl_info =
|
||||
map_get_suppl_info(MI, systemz_insns);
|
||||
if (suppl_info) {
|
||||
SystemZ_get_detail(MI)->format = suppl_info->form;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemZ_init_mri(MCRegisterInfo *MRI)
|
||||
{
|
||||
MCRegisterInfo_InitMCRegisterInfo(
|
||||
MRI, SystemZRegDesc, AARCH64_REG_ENDING, 0, 0,
|
||||
SystemZMCRegisterClasses, ARR_SIZE(SystemZMCRegisterClasses), 0,
|
||||
0, SystemZRegDiffLists, 0, SystemZSubRegIdxLists,
|
||||
ARR_SIZE(SystemZSubRegIdxLists), 0);
|
||||
}
|
||||
|
||||
const char *SystemZ_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
if (reg >= ARR_SIZE(reg_name_maps))
|
||||
return NULL;
|
||||
return SystemZ_LLVM_getRegisterName(reg);
|
||||
}
|
||||
|
||||
return reg_name_maps[reg].name;
|
||||
#else
|
||||
return NULL;
|
||||
void SystemZ_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
|
||||
{
|
||||
MI->MRI = (MCRegisterInfo *)info;
|
||||
MI->fillDetailOps = detail_is_set(MI);
|
||||
SystemZ_LLVM_printInstruction(MI, "", O);
|
||||
#ifndef CAPSTONE_DIET
|
||||
map_set_alias_id(MI, O, insn_alias_mnem_map,
|
||||
ARR_SIZE(insn_alias_mnem_map));
|
||||
#endif
|
||||
}
|
||||
|
||||
static const insn_map insns[] = {
|
||||
// dummy item
|
||||
{
|
||||
0, 0,
|
||||
#ifndef CAPSTONE_DIET
|
||||
{ 0 }, { 0 }, { 0 }, 0, 0
|
||||
#endif
|
||||
},
|
||||
void SystemZ_init_cs_detail(MCInst *MI) {
|
||||
if (!detail_is_set(MI)) {
|
||||
return;
|
||||
}
|
||||
memset(get_detail(MI), 0, sizeof(cs_detail));
|
||||
if (detail_is_set(MI)) {
|
||||
SystemZ_get_detail(MI)->cc = SYSTEMZ_CC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
#include "SystemZMappingInsn.inc"
|
||||
};
|
||||
bool SystemZ_getInstruction(csh handle, const uint8_t *bytes, size_t bytes_len,
|
||||
MCInst *MI, uint16_t *size, uint64_t address,
|
||||
void *info)
|
||||
{
|
||||
SystemZ_init_cs_detail(MI);
|
||||
MI->MRI = (MCRegisterInfo *)info;
|
||||
DecodeStatus result = SystemZ_LLVM_getInstruction(
|
||||
handle, bytes, bytes_len, MI, size, address, info);
|
||||
SystemZ_set_instr_map_data(MI, bytes, bytes_len);
|
||||
return result != MCDisassembler_Fail;
|
||||
}
|
||||
|
||||
// given internal insn id, return public instruction info
|
||||
void SystemZ_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||||
{
|
||||
unsigned short i;
|
||||
|
||||
i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
||||
if (i != 0) {
|
||||
insn->id = insns[i].mapid;
|
||||
|
||||
if (h->detail_opt) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
|
||||
insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use);
|
||||
|
||||
memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
|
||||
insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod);
|
||||
|
||||
memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
|
||||
insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups);
|
||||
|
||||
if (insns[i].branch || insns[i].indirect_branch) {
|
||||
// this insn also belongs to JUMP group. add JUMP group
|
||||
insn->detail->groups[insn->detail->groups_count] = SYSZ_GRP_JUMP;
|
||||
insn->detail->groups_count++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// We do this after Instruction disassembly.
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map insn_name_maps[] = {
|
||||
{ SYSZ_INS_INVALID, NULL },
|
||||
|
||||
#include "SystemZGenInsnNameMaps.inc"
|
||||
};
|
||||
|
||||
// special alias insn
|
||||
static const name_map alias_insn_names[] = {
|
||||
{ 0, NULL }
|
||||
};
|
||||
#endif
|
||||
|
||||
const char *SystemZ_insn_name(csh handle, unsigned int id)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
unsigned int i;
|
||||
if (id < SYSTEMZ_INS_ALIAS_END && id > SYSTEMZ_INS_ALIAS_BEGIN) {
|
||||
if (id - SYSTEMZ_INS_ALIAS_BEGIN >=
|
||||
ARR_SIZE(insn_alias_mnem_map))
|
||||
return NULL;
|
||||
|
||||
if (id >= SYSZ_INS_ENDING)
|
||||
return insn_alias_mnem_map[id - SYSTEMZ_INS_ALIAS_BEGIN - 1]
|
||||
.name;
|
||||
}
|
||||
if (id >= SYSTEMZ_INS_ENDING)
|
||||
return NULL;
|
||||
|
||||
// handle special alias first
|
||||
for (i = 0; i < ARR_SIZE(alias_insn_names); i++) {
|
||||
if (alias_insn_names[i].id == id)
|
||||
return alias_insn_names[i].name;
|
||||
}
|
||||
if (id < ARR_SIZE(insn_name_maps))
|
||||
return insn_name_maps[id];
|
||||
|
||||
return insn_name_maps[id].name;
|
||||
// not found
|
||||
return NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
@ -227,38 +133,16 @@ const char *SystemZ_insn_name(csh handle, unsigned int id)
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const name_map group_name_maps[] = {
|
||||
// generic groups
|
||||
{ SYSZ_GRP_INVALID, NULL },
|
||||
{ SYSZ_GRP_JUMP, "jump" },
|
||||
{ SYSTEMZ_GRP_INVALID, NULL },
|
||||
{ SYSTEMZ_GRP_JUMP, "jump" },
|
||||
{ SYSTEMZ_GRP_CALL, "call" },
|
||||
{ SYSTEMZ_GRP_RET, "return" },
|
||||
{ SYSTEMZ_GRP_INT, "int" },
|
||||
{ SYSTEMZ_GRP_IRET, "iret" },
|
||||
{ SYSTEMZ_GRP_PRIVILEGE, "privilege" },
|
||||
{ SYSTEMZ_GRP_BRANCH_RELATIVE, "branch_relative" },
|
||||
|
||||
// architecture-specific groups
|
||||
{ SYSZ_GRP_DFPPACKEDCONVERSION, "dfppackedconversion" },
|
||||
{ SYSZ_GRP_DFPZONEDCONVERSION, "dfpzonedconversion" },
|
||||
{ SYSZ_GRP_DISTINCTOPS, "distinctops" },
|
||||
{ SYSZ_GRP_ENHANCEDDAT2, "enhanceddat2" },
|
||||
{ SYSZ_GRP_EXECUTIONHINT, "executionhint" },
|
||||
{ SYSZ_GRP_FPEXTENSION, "fpextension" },
|
||||
{ SYSZ_GRP_GUARDEDSTORAGE, "guardedstorage" },
|
||||
{ SYSZ_GRP_HIGHWORD, "highword" },
|
||||
{ SYSZ_GRP_INSERTREFERENCEBITSMULTIPLE, "insertreferencebitsmultiple" },
|
||||
{ SYSZ_GRP_INTERLOCKEDACCESS1, "interlockedaccess1" },
|
||||
{ SYSZ_GRP_LOADANDTRAP, "loadandtrap" },
|
||||
{ SYSZ_GRP_LOADANDZERORIGHTMOSTBYTE, "loadandzerorightmostbyte" },
|
||||
{ SYSZ_GRP_LOADSTOREONCOND, "loadstoreoncond" },
|
||||
{ SYSZ_GRP_LOADSTOREONCOND2, "loadstoreoncond2" },
|
||||
{ SYSZ_GRP_MESSAGESECURITYASSIST3, "messagesecurityassist3" },
|
||||
{ SYSZ_GRP_MESSAGESECURITYASSIST4, "messagesecurityassist4" },
|
||||
{ SYSZ_GRP_MESSAGESECURITYASSIST5, "messagesecurityassist5" },
|
||||
{ SYSZ_GRP_MESSAGESECURITYASSIST7, "messagesecurityassist7" },
|
||||
{ SYSZ_GRP_MESSAGESECURITYASSIST8, "messagesecurityassist8" },
|
||||
{ SYSZ_GRP_MISCELLANEOUSEXTENSIONS, "miscellaneousextensions" },
|
||||
{ SYSZ_GRP_MISCELLANEOUSEXTENSIONS2, "miscellaneousextensions2" },
|
||||
{ SYSZ_GRP_POPULATIONCOUNT, "populationcount" },
|
||||
{ SYSZ_GRP_PROCESSORASSIST, "processorassist" },
|
||||
{ SYSZ_GRP_RESETREFERENCEBITSMULTIPLE, "resetreferencebitsmultiple" },
|
||||
{ SYSZ_GRP_TRANSACTIONALEXECUTION, "transactionalexecution" },
|
||||
{ SYSZ_GRP_VECTOR, "vector" },
|
||||
{ SYSZ_GRP_VECTORENHANCEMENTS1, "vectorenhancements1" },
|
||||
{ SYSZ_GRP_VECTORPACKEDDECIMAL, "vectorpackeddecimal" },
|
||||
#include "SystemZGenCSFeatureName.inc"
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -271,210 +155,212 @@ const char *SystemZ_group_name(csh handle, unsigned int id)
|
||||
#endif
|
||||
}
|
||||
|
||||
// map internal raw register to 'public' register
|
||||
sysz_reg SystemZ_map_register(unsigned int r)
|
||||
void SystemZ_add_cs_detail(MCInst *MI, int /* aarch64_op_group */ op_group,
|
||||
va_list args)
|
||||
{
|
||||
static const unsigned int map[] = { 0,
|
||||
/* SystemZ_CC = 1 */ SYSZ_REG_CC,
|
||||
/* SystemZ_A0 = 2 */ SYSZ_REG_A0,
|
||||
/* SystemZ_A1 = 3 */ SYSZ_REG_A1,
|
||||
/* SystemZ_A2 = 4 */ SYSZ_REG_A2,
|
||||
/* SystemZ_A3 = 5 */ SYSZ_REG_A3,
|
||||
/* SystemZ_A4 = 6 */ SYSZ_REG_A4,
|
||||
/* SystemZ_A5 = 7 */ SYSZ_REG_A5,
|
||||
/* SystemZ_A6 = 8 */ SYSZ_REG_A6,
|
||||
/* SystemZ_A7 = 9 */ SYSZ_REG_A7,
|
||||
/* SystemZ_A8 = 10 */ SYSZ_REG_A8,
|
||||
/* SystemZ_A9 = 11 */ SYSZ_REG_A9,
|
||||
/* SystemZ_A10 = 12 */ SYSZ_REG_A10,
|
||||
/* SystemZ_A11 = 13 */ SYSZ_REG_A11,
|
||||
/* SystemZ_A12 = 14 */ SYSZ_REG_A12,
|
||||
/* SystemZ_A13 = 15 */ SYSZ_REG_A13,
|
||||
/* SystemZ_A14 = 16 */ SYSZ_REG_A14,
|
||||
/* SystemZ_A15 = 17 */ SYSZ_REG_A15,
|
||||
/* SystemZ_C0 = 18 */ SYSZ_REG_C0,
|
||||
/* SystemZ_C1 = 19 */ SYSZ_REG_C1,
|
||||
/* SystemZ_C2 = 20 */ SYSZ_REG_C2,
|
||||
/* SystemZ_C3 = 21 */ SYSZ_REG_C3,
|
||||
/* SystemZ_C4 = 22 */ SYSZ_REG_C4,
|
||||
/* SystemZ_C5 = 23 */ SYSZ_REG_C5,
|
||||
/* SystemZ_C6 = 24 */ SYSZ_REG_C6,
|
||||
/* SystemZ_C7 = 25 */ SYSZ_REG_C7,
|
||||
/* SystemZ_C8 = 26 */ SYSZ_REG_C8,
|
||||
/* SystemZ_C9 = 27 */ SYSZ_REG_C9,
|
||||
/* SystemZ_C10 = 28 */ SYSZ_REG_C10,
|
||||
/* SystemZ_C11 = 29 */ SYSZ_REG_C11,
|
||||
/* SystemZ_C12 = 30 */ SYSZ_REG_C12,
|
||||
/* SystemZ_C13 = 31 */ SYSZ_REG_C13,
|
||||
/* SystemZ_C14 = 32 */ SYSZ_REG_C14,
|
||||
/* SystemZ_C15 = 33 */ SYSZ_REG_C15,
|
||||
/* SystemZ_V0 = 34 */ SYSZ_REG_V0,
|
||||
/* SystemZ_V1 = 35 */ SYSZ_REG_V1,
|
||||
/* SystemZ_V2 = 36 */ SYSZ_REG_V2,
|
||||
/* SystemZ_V3 = 37 */ SYSZ_REG_V3,
|
||||
/* SystemZ_V4 = 38 */ SYSZ_REG_V4,
|
||||
/* SystemZ_V5 = 39 */ SYSZ_REG_V5,
|
||||
/* SystemZ_V6 = 40 */ SYSZ_REG_V6,
|
||||
/* SystemZ_V7 = 41 */ SYSZ_REG_V7,
|
||||
/* SystemZ_V8 = 42 */ SYSZ_REG_V8,
|
||||
/* SystemZ_V9 = 43 */ SYSZ_REG_V9,
|
||||
/* SystemZ_V10 = 44 */ SYSZ_REG_V10,
|
||||
/* SystemZ_V11 = 45 */ SYSZ_REG_V11,
|
||||
/* SystemZ_V12 = 46 */ SYSZ_REG_V12,
|
||||
/* SystemZ_V13 = 47 */ SYSZ_REG_V13,
|
||||
/* SystemZ_V14 = 48 */ SYSZ_REG_V14,
|
||||
/* SystemZ_V15 = 49 */ SYSZ_REG_V15,
|
||||
/* SystemZ_V16 = 50 */ SYSZ_REG_V16,
|
||||
/* SystemZ_V17 = 51 */ SYSZ_REG_V17,
|
||||
/* SystemZ_V18 = 52 */ SYSZ_REG_V18,
|
||||
/* SystemZ_V19 = 53 */ SYSZ_REG_V19,
|
||||
/* SystemZ_V20 = 54 */ SYSZ_REG_V20,
|
||||
/* SystemZ_V21 = 55 */ SYSZ_REG_V21,
|
||||
/* SystemZ_V22 = 56 */ SYSZ_REG_V22,
|
||||
/* SystemZ_V23 = 57 */ SYSZ_REG_V23,
|
||||
/* SystemZ_V24 = 58 */ SYSZ_REG_V24,
|
||||
/* SystemZ_V25 = 59 */ SYSZ_REG_V25,
|
||||
/* SystemZ_V26 = 60 */ SYSZ_REG_V26,
|
||||
/* SystemZ_V27 = 61 */ SYSZ_REG_V27,
|
||||
/* SystemZ_V28 = 62 */ SYSZ_REG_V28,
|
||||
/* SystemZ_V29 = 63 */ SYSZ_REG_V29,
|
||||
/* SystemZ_V30 = 64 */ SYSZ_REG_V30,
|
||||
/* SystemZ_V31 = 65 */ SYSZ_REG_V31,
|
||||
/* SystemZ_F0D = 66 */ SYSZ_REG_F0,
|
||||
/* SystemZ_F1D = 67 */ SYSZ_REG_F1,
|
||||
/* SystemZ_F2D = 68 */ SYSZ_REG_F2,
|
||||
/* SystemZ_F3D = 69 */ SYSZ_REG_F3,
|
||||
/* SystemZ_F4D = 70 */ SYSZ_REG_F4,
|
||||
/* SystemZ_F5D = 71 */ SYSZ_REG_F5,
|
||||
/* SystemZ_F6D = 72 */ SYSZ_REG_F6,
|
||||
/* SystemZ_F7D = 73 */ SYSZ_REG_F7,
|
||||
/* SystemZ_F8D = 74 */ SYSZ_REG_F8,
|
||||
/* SystemZ_F9D = 75 */ SYSZ_REG_F9,
|
||||
/* SystemZ_F10D = 76 */ SYSZ_REG_F10,
|
||||
/* SystemZ_F11D = 77 */ SYSZ_REG_F11,
|
||||
/* SystemZ_F12D = 78 */ SYSZ_REG_F12,
|
||||
/* SystemZ_F13D = 79 */ SYSZ_REG_F13,
|
||||
/* SystemZ_F14D = 80 */ SYSZ_REG_F14,
|
||||
/* SystemZ_F15D = 81 */ SYSZ_REG_F15,
|
||||
/* SystemZ_F16D = 82 */ SYSZ_REG_F16,
|
||||
/* SystemZ_F17D = 83 */ SYSZ_REG_F17,
|
||||
/* SystemZ_F18D = 84 */ SYSZ_REG_F18,
|
||||
/* SystemZ_F19D = 85 */ SYSZ_REG_F19,
|
||||
/* SystemZ_F20D = 86 */ SYSZ_REG_F20,
|
||||
/* SystemZ_F21D = 87 */ SYSZ_REG_F21,
|
||||
/* SystemZ_F22D = 88 */ SYSZ_REG_F22,
|
||||
/* SystemZ_F23D = 89 */ SYSZ_REG_F23,
|
||||
/* SystemZ_F24D = 90 */ SYSZ_REG_F24,
|
||||
/* SystemZ_F25D = 91 */ SYSZ_REG_F25,
|
||||
/* SystemZ_F26D = 92 */ SYSZ_REG_F26,
|
||||
/* SystemZ_F27D = 93 */ SYSZ_REG_F27,
|
||||
/* SystemZ_F28D = 94 */ SYSZ_REG_F28,
|
||||
/* SystemZ_F29D = 95 */ SYSZ_REG_F29,
|
||||
/* SystemZ_F30D = 96 */ SYSZ_REG_F30,
|
||||
/* SystemZ_F31D = 97 */ SYSZ_REG_F31,
|
||||
/* SystemZ_F0Q = 98 */ SYSZ_REG_F0,
|
||||
/* SystemZ_F1Q = 99 */ SYSZ_REG_F1,
|
||||
/* SystemZ_F4Q = 100 */ SYSZ_REG_F4,
|
||||
/* SystemZ_F5Q = 101 */ SYSZ_REG_F5,
|
||||
/* SystemZ_F8Q = 102 */ SYSZ_REG_F8,
|
||||
/* SystemZ_F9Q = 103 */ SYSZ_REG_F9,
|
||||
/* SystemZ_F12Q = 104 */ SYSZ_REG_F12,
|
||||
/* SystemZ_F13Q = 105 */ SYSZ_REG_F13,
|
||||
/* SystemZ_F0S = 106 */ SYSZ_REG_F0,
|
||||
/* SystemZ_F1S = 107 */ SYSZ_REG_F1,
|
||||
/* SystemZ_F2S = 108 */ SYSZ_REG_F2,
|
||||
/* SystemZ_F3S = 109 */ SYSZ_REG_F3,
|
||||
/* SystemZ_F4S = 110 */ SYSZ_REG_F4,
|
||||
/* SystemZ_F5S = 111 */ SYSZ_REG_F5,
|
||||
/* SystemZ_F6S = 112 */ SYSZ_REG_F6,
|
||||
/* SystemZ_F7S = 113 */ SYSZ_REG_F7,
|
||||
/* SystemZ_F8S = 114 */ SYSZ_REG_F8,
|
||||
/* SystemZ_F9S = 115 */ SYSZ_REG_F9,
|
||||
/* SystemZ_F10S = 116 */ SYSZ_REG_F10,
|
||||
/* SystemZ_F11S = 117 */ SYSZ_REG_F11,
|
||||
/* SystemZ_F12S = 118 */ SYSZ_REG_F12,
|
||||
/* SystemZ_F13S = 119 */ SYSZ_REG_F13,
|
||||
/* SystemZ_F14S = 120 */ SYSZ_REG_F14,
|
||||
/* SystemZ_F15S = 121 */ SYSZ_REG_F15,
|
||||
/* SystemZ_F16S = 122 */ SYSZ_REG_F16,
|
||||
/* SystemZ_F17S = 123 */ SYSZ_REG_F17,
|
||||
/* SystemZ_F18S = 124 */ SYSZ_REG_F18,
|
||||
/* SystemZ_F19S = 125 */ SYSZ_REG_F19,
|
||||
/* SystemZ_F20S = 126 */ SYSZ_REG_F20,
|
||||
/* SystemZ_F21S = 127 */ SYSZ_REG_F21,
|
||||
/* SystemZ_F22S = 128 */ SYSZ_REG_F22,
|
||||
/* SystemZ_F23S = 129 */ SYSZ_REG_F23,
|
||||
/* SystemZ_F24S = 130 */ SYSZ_REG_F24,
|
||||
/* SystemZ_F25S = 131 */ SYSZ_REG_F25,
|
||||
/* SystemZ_F26S = 132 */ SYSZ_REG_F26,
|
||||
/* SystemZ_F27S = 133 */ SYSZ_REG_F27,
|
||||
/* SystemZ_F28S = 134 */ SYSZ_REG_F28,
|
||||
/* SystemZ_F29S = 135 */ SYSZ_REG_F29,
|
||||
/* SystemZ_F30S = 136 */ SYSZ_REG_F30,
|
||||
/* SystemZ_F31S = 137 */ SYSZ_REG_F31,
|
||||
/* SystemZ_R0D = 138 */ SYSZ_REG_0,
|
||||
/* SystemZ_R1D = 139 */ SYSZ_REG_1,
|
||||
/* SystemZ_R2D = 140 */ SYSZ_REG_2,
|
||||
/* SystemZ_R3D = 141 */ SYSZ_REG_3,
|
||||
/* SystemZ_R4D = 142 */ SYSZ_REG_4,
|
||||
/* SystemZ_R5D = 143 */ SYSZ_REG_5,
|
||||
/* SystemZ_R6D = 144 */ SYSZ_REG_6,
|
||||
/* SystemZ_R7D = 145 */ SYSZ_REG_7,
|
||||
/* SystemZ_R8D = 146 */ SYSZ_REG_8,
|
||||
/* SystemZ_R9D = 147 */ SYSZ_REG_9,
|
||||
/* SystemZ_R10D = 148 */ SYSZ_REG_10,
|
||||
/* SystemZ_R11D = 149 */ SYSZ_REG_11,
|
||||
/* SystemZ_R12D = 150 */ SYSZ_REG_12,
|
||||
/* SystemZ_R13D = 151 */ SYSZ_REG_13,
|
||||
/* SystemZ_R14D = 152 */ SYSZ_REG_14,
|
||||
/* SystemZ_R15D = 153 */ SYSZ_REG_15,
|
||||
/* SystemZ_R0H = 154 */ SYSZ_REG_0,
|
||||
/* SystemZ_R1H = 155 */ SYSZ_REG_1,
|
||||
/* SystemZ_R2H = 156 */ SYSZ_REG_2,
|
||||
/* SystemZ_R3H = 157 */ SYSZ_REG_3,
|
||||
/* SystemZ_R4H = 158 */ SYSZ_REG_4,
|
||||
/* SystemZ_R5H = 159 */ SYSZ_REG_5,
|
||||
/* SystemZ_R6H = 160 */ SYSZ_REG_6,
|
||||
/* SystemZ_R7H = 161 */ SYSZ_REG_7,
|
||||
/* SystemZ_R8H = 162 */ SYSZ_REG_8,
|
||||
/* SystemZ_R9H = 163 */ SYSZ_REG_9,
|
||||
/* SystemZ_R10H = 164 */ SYSZ_REG_10,
|
||||
/* SystemZ_R11H = 165 */ SYSZ_REG_11,
|
||||
/* SystemZ_R12H = 166 */ SYSZ_REG_12,
|
||||
/* SystemZ_R13H = 167 */ SYSZ_REG_13,
|
||||
/* SystemZ_R14H = 168 */ SYSZ_REG_14,
|
||||
/* SystemZ_R15H = 169 */ SYSZ_REG_15,
|
||||
/* SystemZ_R0L = 170 */ SYSZ_REG_0,
|
||||
/* SystemZ_R1L = 171 */ SYSZ_REG_1,
|
||||
/* SystemZ_R2L = 172 */ SYSZ_REG_2,
|
||||
/* SystemZ_R3L = 173 */ SYSZ_REG_3,
|
||||
/* SystemZ_R4L = 174 */ SYSZ_REG_4,
|
||||
/* SystemZ_R5L = 175 */ SYSZ_REG_5,
|
||||
/* SystemZ_R6L = 176 */ SYSZ_REG_6,
|
||||
/* SystemZ_R7L = 177 */ SYSZ_REG_7,
|
||||
/* SystemZ_R8L = 178 */ SYSZ_REG_8,
|
||||
/* SystemZ_R9L = 179 */ SYSZ_REG_9,
|
||||
/* SystemZ_R10L = 180 */ SYSZ_REG_10,
|
||||
/* SystemZ_R11L = 181 */ SYSZ_REG_11,
|
||||
/* SystemZ_R12L = 182 */ SYSZ_REG_12,
|
||||
/* SystemZ_R13L = 183 */ SYSZ_REG_13,
|
||||
/* SystemZ_R14L = 184 */ SYSZ_REG_14,
|
||||
/* SystemZ_R15L = 185 */ SYSZ_REG_15,
|
||||
/* SystemZ_R0Q = 186 */ SYSZ_REG_0,
|
||||
/* SystemZ_R2Q = 187 */ SYSZ_REG_2,
|
||||
/* SystemZ_R4Q = 188 */ SYSZ_REG_4,
|
||||
/* SystemZ_R6Q = 189 */ SYSZ_REG_6,
|
||||
/* SystemZ_R8Q = 190 */ SYSZ_REG_8,
|
||||
/* SystemZ_R10Q = 191 */ SYSZ_REG_10,
|
||||
/* SystemZ_R12Q = 192 */ SYSZ_REG_12,
|
||||
/* SystemZ_R14Q = 193 */ SYSZ_REG_14,
|
||||
};
|
||||
#ifndef CAPSTONE_DIET
|
||||
if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
|
||||
return;
|
||||
|
||||
if (r < ARR_SIZE(map))
|
||||
return map[r];
|
||||
unsigned op_num = va_arg(args, unsigned);
|
||||
|
||||
// cannot find this register
|
||||
return 0;
|
||||
switch (op_group) {
|
||||
default:
|
||||
printf("Operand group %d not handled\n", op_group);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_Operand: {
|
||||
CS_ASSERT(!(op_type & CS_OP_MEM) && "Mem op passed to prinOperand");
|
||||
cs_op_type secondary_op_type = map_get_op_type(MI, op_num) &
|
||||
~(CS_OP_MEM | CS_OP_BOUND);
|
||||
if (secondary_op_type == CS_OP_IMM) {
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 0);
|
||||
} else if (secondary_op_type == CS_OP_REG) {
|
||||
SystemZ_set_detail_op_reg(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num));
|
||||
} else {
|
||||
assert(0 && "Op type not handled.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SystemZ_OP_GROUP_Cond4Operand: {
|
||||
systemz_cc cc = MCInst_getOpVal(MI, op_num);
|
||||
SystemZ_get_detail(MI)->cc = cc;
|
||||
break;
|
||||
}
|
||||
case SystemZ_OP_GROUP_BDAddrOperand:
|
||||
assert(map_get_op_type(MI, (op_num)) & CS_OP_MEM);
|
||||
assert(map_get_op_type(MI, (op_num + 1)) & CS_OP_MEM);
|
||||
assert(MCOperand_isReg(MCInst_getOperand(MI, (op_num))));
|
||||
assert(MCOperand_isImm(MCInst_getOperand(MI, (op_num + 1))));
|
||||
SystemZ_set_detail_op_mem(MI,
|
||||
op_num,
|
||||
MCInst_getOpVal(MI, (op_num)),
|
||||
MCInst_getOpVal(MI, (op_num + 1)),
|
||||
0,
|
||||
0,
|
||||
SYSTEMZ_AM_BD
|
||||
);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_BDVAddrOperand:
|
||||
case SystemZ_OP_GROUP_BDXAddrOperand: {
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 1)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 2)) & CS_OP_MEM);
|
||||
CS_ASSERT(MCOperand_isReg(MCInst_getOperand(MI, (op_num))));
|
||||
CS_ASSERT(MCOperand_isImm(MCInst_getOperand(MI, (op_num + 1))));
|
||||
CS_ASSERT(MCOperand_isReg(MCInst_getOperand(MI, (op_num + 2))));
|
||||
SystemZ_set_detail_op_mem(MI,
|
||||
op_num,
|
||||
MCInst_getOpVal(MI, (op_num)),
|
||||
MCInst_getOpVal(MI, (op_num + 1)),
|
||||
0,
|
||||
MCInst_getOpVal(MI, (op_num + 2)),
|
||||
(op_group == SystemZ_OP_GROUP_BDXAddrOperand ? SYSTEMZ_AM_BDX : SYSTEMZ_AM_BDV)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case SystemZ_OP_GROUP_BDLAddrOperand:
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 1)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 2)) & CS_OP_MEM);
|
||||
CS_ASSERT(MCOperand_isReg(MCInst_getOperand(MI, (op_num))));
|
||||
CS_ASSERT(MCOperand_isImm(MCInst_getOperand(MI, (op_num + 1))));
|
||||
CS_ASSERT(MCOperand_isImm(MCInst_getOperand(MI, (op_num + 2))));
|
||||
SystemZ_set_detail_op_mem(MI,
|
||||
op_num,
|
||||
MCInst_getOpVal(MI, (op_num)),
|
||||
MCInst_getOpVal(MI, (op_num + 1)),
|
||||
MCInst_getOpVal(MI, (op_num + 2)),
|
||||
0,
|
||||
SYSTEMZ_AM_BDL
|
||||
);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_BDRAddrOperand:
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 1)) & CS_OP_MEM);
|
||||
CS_ASSERT(map_get_op_type(MI, (op_num + 2)) & CS_OP_MEM);
|
||||
CS_ASSERT(MCOperand_isReg(MCInst_getOperand(MI, (op_num))));
|
||||
CS_ASSERT(MCOperand_isImm(MCInst_getOperand(MI, (op_num + 1))));
|
||||
CS_ASSERT(MCOperand_isReg(MCInst_getOperand(MI, (op_num + 2))));
|
||||
SystemZ_set_detail_op_mem(MI,
|
||||
op_num,
|
||||
MCInst_getOpVal(MI, (op_num)),
|
||||
MCInst_getOpVal(MI, (op_num + 1)),
|
||||
MCInst_getOpVal(MI, (op_num + 2)),
|
||||
0,
|
||||
SYSTEMZ_AM_BDL
|
||||
);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_PCRelOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 0);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U1ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 1);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U2ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 2);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U3ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 3);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U4ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 4);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U8ImmOperand:
|
||||
case SystemZ_OP_GROUP_S8ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 8);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U12ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 12);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U16ImmOperand:
|
||||
case SystemZ_OP_GROUP_S16ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 16);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U32ImmOperand:
|
||||
case SystemZ_OP_GROUP_S32ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 32);
|
||||
break;
|
||||
case SystemZ_OP_GROUP_U48ImmOperand:
|
||||
SystemZ_set_detail_op_imm(MI, op_num,
|
||||
MCInst_getOpVal(MI, op_num), 48);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
|
||||
void SystemZ_set_detail_op_imm(MCInst *MI, unsigned op_num, int64_t Imm, size_t width)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
CS_ASSERT((map_get_op_type(MI, op_num) & ~CS_OP_MEM) == CS_OP_IMM);
|
||||
|
||||
SystemZ_get_detail_op(MI, 0)->type = SYSTEMZ_OP_IMM;
|
||||
SystemZ_get_detail_op(MI, 0)->imm = Imm;
|
||||
SystemZ_get_detail_op(MI, 0)->access = map_get_op_access(MI, op_num);
|
||||
SystemZ_get_detail_op(MI, 0)->imm_width = width;
|
||||
SystemZ_inc_op_count(MI);
|
||||
}
|
||||
|
||||
void SystemZ_set_detail_op_reg(MCInst *MI, unsigned op_num, systemz_reg Reg)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
CS_ASSERT((map_get_op_type(MI, op_num) & ~CS_OP_MEM) == CS_OP_REG);
|
||||
|
||||
SystemZ_get_detail_op(MI, 0)->type = SYSTEMZ_OP_REG;
|
||||
SystemZ_get_detail_op(MI, 0)->reg = Reg;
|
||||
SystemZ_get_detail_op(MI, 0)->access = map_get_op_access(MI, op_num);
|
||||
SystemZ_inc_op_count(MI);
|
||||
}
|
||||
|
||||
void SystemZ_set_detail_op_mem(MCInst *MI, unsigned op_num, systemz_reg base, int64_t disp, uint64_t length, systemz_reg index, systemz_addr_mode am)
|
||||
{
|
||||
if (!detail_is_set(MI))
|
||||
return;
|
||||
SystemZ_get_detail_op(MI, 0)->type = SYSTEMZ_OP_MEM;
|
||||
SystemZ_get_detail_op(MI, 0)->access = map_get_op_access(MI, op_num);
|
||||
SystemZ_get_detail_op(MI, 0)->mem.am = am;
|
||||
switch(am) {
|
||||
default:
|
||||
CS_ASSERT(0 && "Address mode not handled\n");
|
||||
break;
|
||||
case SYSTEMZ_AM_BD:
|
||||
SystemZ_get_detail_op(MI, 0)->mem.base = base;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.disp = disp;
|
||||
break;
|
||||
case SYSTEMZ_AM_BDX:
|
||||
case SYSTEMZ_AM_BDV:
|
||||
SystemZ_get_detail_op(MI, 0)->mem.base = base;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.disp = disp;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.index = index;
|
||||
break;
|
||||
case SYSTEMZ_AM_BDL:
|
||||
SystemZ_get_detail_op(MI, 0)->mem.base = base;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.disp = disp;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.length = length;
|
||||
break;
|
||||
case SYSTEMZ_AM_BDR:
|
||||
SystemZ_get_detail_op(MI, 0)->mem.base = base;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.disp = disp;
|
||||
SystemZ_get_detail_op(MI, 0)->mem.length = length;
|
||||
break;
|
||||
}
|
||||
SystemZ_inc_op_count(MI);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,10 +1,16 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifndef CS_SYSZ_MAP_H
|
||||
#define CS_SYSZ_MAP_H
|
||||
#ifndef CS_SYSTEMZ_MAP_H
|
||||
#define CS_SYSTEMZ_MAP_H
|
||||
|
||||
#include "capstone/capstone.h"
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
#include "../../cs_priv.h"
|
||||
|
||||
typedef enum {
|
||||
#include "SystemZGenCSOpGroup.inc"
|
||||
} systemz_op_group;
|
||||
|
||||
// return name of register in friendly string
|
||||
const char *SystemZ_reg_name(csh handle, unsigned int reg);
|
||||
@ -16,8 +22,29 @@ const char *SystemZ_insn_name(csh handle, unsigned int id);
|
||||
|
||||
const char *SystemZ_group_name(csh handle, unsigned int id);
|
||||
|
||||
// map internal raw register to 'public' register
|
||||
sysz_reg SystemZ_map_register(unsigned int r);
|
||||
void SystemZ_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info);
|
||||
bool SystemZ_getInstruction(csh handle, const uint8_t *bytes, size_t bytes_len,
|
||||
MCInst *MI, uint16_t *size, uint64_t address,
|
||||
void *info);
|
||||
void SystemZ_init_mri(MCRegisterInfo *MRI);
|
||||
void SystemZ_init_cs_detail(MCInst *MI);
|
||||
|
||||
#endif
|
||||
void SystemZ_set_detail_op_reg(MCInst *MI, unsigned op_num, systemz_reg Reg);
|
||||
void SystemZ_set_detail_op_imm(MCInst *MI, unsigned op_num, int64_t Imm, size_t width);
|
||||
void SystemZ_set_detail_op_mem(MCInst *MI, unsigned op_num, systemz_reg base, int64_t disp, uint64_t length, systemz_reg index, systemz_addr_mode am);
|
||||
void SystemZ_add_cs_detail(MCInst *MI, int /* systemz_op_group */ op_group,
|
||||
va_list args);
|
||||
|
||||
static inline void add_cs_detail(MCInst *MI,
|
||||
int /* aarch64_op_group */ op_group, ...)
|
||||
{
|
||||
if (!MI->flat_insn->detail)
|
||||
return;
|
||||
va_list args;
|
||||
va_start(args, op_group);
|
||||
SystemZ_add_cs_detail(MI, op_group, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#endif // CS_SYSTEMZ_MAP_H
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,10 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
#ifdef CAPSTONE_HAS_SYSTEMZ
|
||||
|
||||
#include "../../utils.h"
|
||||
#include "../../MCRegisterInfo.h"
|
||||
#include "SystemZDisassembler.h"
|
||||
#include "SystemZInstPrinter.h"
|
||||
#include "SystemZMapping.h"
|
||||
#include "SystemZModule.h"
|
||||
|
||||
@ -15,12 +13,12 @@ cs_err SystemZ_global_init(cs_struct *ud)
|
||||
MCRegisterInfo *mri;
|
||||
mri = cs_mem_malloc(sizeof(*mri));
|
||||
|
||||
SystemZ_init(mri);
|
||||
ud->printer = SystemZ_printInst;
|
||||
SystemZ_init_mri(mri);
|
||||
ud->printer = SystemZ_printer;
|
||||
ud->printer_info = mri;
|
||||
ud->getinsn_info = mri;
|
||||
ud->disasm = SystemZ_getInstruction;
|
||||
ud->post_printer = SystemZ_post_printer;
|
||||
ud->post_printer = NULL;
|
||||
|
||||
ud->reg_name = SystemZ_reg_name;
|
||||
ud->insn_id = SystemZ_get_insn_id;
|
||||
@ -32,11 +30,11 @@ cs_err SystemZ_global_init(cs_struct *ud)
|
||||
|
||||
cs_err SystemZ_option(cs_struct *handle, cs_opt_type type, size_t value)
|
||||
{
|
||||
if (type == CS_OPT_SYNTAX)
|
||||
if (type == CS_OPT_SYNTAX) {
|
||||
handle->syntax = (int) value;
|
||||
|
||||
// Do not set mode because only CS_MODE_BIG_ENDIAN is valid; we cannot
|
||||
// test for CS_MODE_LITTLE_ENDIAN because it is 0
|
||||
} else if (type == CS_OPT_MODE) {
|
||||
handle->mode |= (cs_mode)value;
|
||||
}
|
||||
|
||||
return CS_ERR_OK;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ template = {
|
||||
'x86.h': 'X86',
|
||||
'ppc.h': 'Ppc',
|
||||
'sparc.h': 'Sparc',
|
||||
'systemz.h': 'Sysz',
|
||||
'systemz.h': 'Systemz',
|
||||
'xcore.h': 'Xcore',
|
||||
'tms320c64x.h': 'TMS320C64x',
|
||||
'm680x.h': 'M680x',
|
||||
@ -31,8 +31,10 @@ template = {
|
||||
'comment_close': '',
|
||||
},
|
||||
'python': {
|
||||
'header': "from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX\n"
|
||||
"# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.py]\n",
|
||||
'header': (
|
||||
"from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX\n"
|
||||
"# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.py]\n"
|
||||
),
|
||||
'footer': "",
|
||||
'line_format': '%s = %s\n',
|
||||
'out_file': './python/capstone/%s_const.py',
|
||||
@ -44,7 +46,7 @@ template = {
|
||||
'x86.h': 'x86',
|
||||
'ppc.h': 'ppc',
|
||||
'sparc.h': 'sparc',
|
||||
'systemz.h': 'sysz',
|
||||
'systemz.h': 'systemz',
|
||||
'xcore.h': 'xcore',
|
||||
'tms320c64x.h': 'tms320c64x',
|
||||
'm680x.h': 'm680x',
|
||||
@ -73,7 +75,7 @@ template = {
|
||||
'x86.h': 'x86',
|
||||
'ppc.h': 'ppc',
|
||||
'sparc.h': 'sparc',
|
||||
'systemz.h': 'sysz',
|
||||
'systemz.h': 'systemz',
|
||||
'xcore.h': 'xcore',
|
||||
'tms320c64x.h': 'tms320c64x',
|
||||
'm680x.h': 'm680x',
|
||||
@ -175,7 +177,7 @@ def gen(lang):
|
||||
|
||||
if line.startswith('#define '):
|
||||
line = line[8:] #cut off define
|
||||
xline = re.split('\s+', line, 1) #split to at most 2 express
|
||||
xline = re.split(r'\s+', line, 1) #split to at most 2 express
|
||||
if len(xline) != 2:
|
||||
continue
|
||||
if '(' in xline[0] or ')' in xline[0]: #does it look like a function
|
||||
@ -201,7 +203,7 @@ def gen(lang):
|
||||
# hacky: remove type cast (uint64_t)
|
||||
t = t.replace('(uint64_t)', '')
|
||||
t = re.sub(r'\((\d+)ULL << (\d+)\)', r'\1 << \2', t) # (1ULL<<1) to 1 << 1
|
||||
f = re.split('\s+', t)
|
||||
f = re.split(r'\s+', t)
|
||||
|
||||
if not has_special_arch_prefix(f[0]):
|
||||
continue
|
||||
|
@ -26,7 +26,7 @@ __all__ = [
|
||||
'CS_ARCH_X86',
|
||||
'CS_ARCH_PPC',
|
||||
'CS_ARCH_SPARC',
|
||||
'CS_ARCH_SYSZ',
|
||||
'CS_ARCH_SYSTEMZ',
|
||||
'CS_ARCH_XCORE',
|
||||
'CS_ARCH_M68K',
|
||||
'CS_ARCH_TMS320C64X',
|
||||
@ -130,6 +130,21 @@ __all__ = [
|
||||
'CS_MODE_HPPA_20W',
|
||||
'CS_MODE_LOONGARCH32',
|
||||
'CS_MODE_LOONGARCH64',
|
||||
'CS_MODE_SYSTEMZ_ARCH8',
|
||||
'CS_MODE_SYSTEMZ_ARCH9',
|
||||
'CS_MODE_SYSTEMZ_ARCH10',
|
||||
'CS_MODE_SYSTEMZ_ARCH11',
|
||||
'CS_MODE_SYSTEMZ_ARCH12',
|
||||
'CS_MODE_SYSTEMZ_ARCH13',
|
||||
'CS_MODE_SYSTEMZ_ARCH14',
|
||||
'CS_MODE_SYSTEMZ_Z10',
|
||||
'CS_MODE_SYSTEMZ_Z196',
|
||||
'CS_MODE_SYSTEMZ_ZEC12',
|
||||
'CS_MODE_SYSTEMZ_Z13',
|
||||
'CS_MODE_SYSTEMZ_Z14',
|
||||
'CS_MODE_SYSTEMZ_Z15',
|
||||
'CS_MODE_SYSTEMZ_Z16',
|
||||
'CS_MODE_SYSTEMZ_GENERIC',
|
||||
|
||||
'CS_OPT_SYNTAX',
|
||||
'CS_OPT_SYNTAX_DEFAULT',
|
||||
@ -214,6 +229,7 @@ __all__ = [
|
||||
'__version__',
|
||||
]
|
||||
|
||||
UINT8_MAX = 0xff
|
||||
UINT16_MAX = 0xffff
|
||||
|
||||
# Capstone C interface
|
||||
@ -232,11 +248,11 @@ __version__ = "%u.%u.%u" %(CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA)
|
||||
# architectures
|
||||
CS_ARCH_ARM = 0
|
||||
CS_ARCH_AARCH64 = 1
|
||||
CS_ARCH_MIPS = 2
|
||||
CS_ARCH_X86 = 3
|
||||
CS_ARCH_PPC = 4
|
||||
CS_ARCH_SPARC = 5
|
||||
CS_ARCH_SYSZ = 6
|
||||
CS_ARCH_SYSTEMZ = 2
|
||||
CS_ARCH_MIPS = 3
|
||||
CS_ARCH_X86 = 4
|
||||
CS_ARCH_PPC = 5
|
||||
CS_ARCH_SPARC = 6
|
||||
CS_ARCH_XCORE = 7
|
||||
CS_ARCH_M68K = 8
|
||||
CS_ARCH_TMS320C64X = 9
|
||||
@ -346,6 +362,21 @@ CS_MODE_HPPA_20 = 1 << 2 # HPPA 2.0
|
||||
CS_MODE_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3) # HPPA 2.0 wide
|
||||
CS_MODE_LOONGARCH32 = 1 << 0
|
||||
CS_MODE_LOONGARCH64 = 1 << 1
|
||||
CS_MODE_SYSTEMZ_ARCH8 = 1 << 1
|
||||
CS_MODE_SYSTEMZ_ARCH9 = 1 << 2
|
||||
CS_MODE_SYSTEMZ_ARCH10 = 1 << 3
|
||||
CS_MODE_SYSTEMZ_ARCH11 = 1 << 4
|
||||
CS_MODE_SYSTEMZ_ARCH12 = 1 << 5
|
||||
CS_MODE_SYSTEMZ_ARCH13 = 1 << 6
|
||||
CS_MODE_SYSTEMZ_ARCH14 = 1 << 7
|
||||
CS_MODE_SYSTEMZ_Z10 = 1 << 8
|
||||
CS_MODE_SYSTEMZ_Z196 = 1 << 9
|
||||
CS_MODE_SYSTEMZ_ZEC12 = 1 << 10
|
||||
CS_MODE_SYSTEMZ_Z13 = 1 << 11
|
||||
CS_MODE_SYSTEMZ_Z14 = 1 << 12
|
||||
CS_MODE_SYSTEMZ_Z15 = 1 << 13
|
||||
CS_MODE_SYSTEMZ_Z16 = 1 << 14
|
||||
CS_MODE_SYSTEMZ_GENERIC = 1 << 15
|
||||
|
||||
# Capstone option type
|
||||
CS_OPT_INVALID = 0 # No option specified
|
||||
@ -526,7 +557,7 @@ class _cs_arch(ctypes.Union):
|
||||
('x86', x86.CsX86),
|
||||
('ppc', ppc.CsPpc),
|
||||
('sparc', sparc.CsSparc),
|
||||
('sysz', systemz.CsSysz),
|
||||
('systemz', systemz.CsSystemZ),
|
||||
('xcore', xcore.CsXcore),
|
||||
('tms320c64x', tms320c64x.CsTMS320C64x),
|
||||
('m680x', m680x.CsM680x),
|
||||
@ -877,8 +908,8 @@ class CsInsn(object):
|
||||
ppc.get_arch_info(self._raw.detail.contents.arch.ppc)
|
||||
elif arch == CS_ARCH_SPARC:
|
||||
(self.cc, self.hint, self.operands) = sparc.get_arch_info(self._raw.detail.contents.arch.sparc)
|
||||
elif arch == CS_ARCH_SYSZ:
|
||||
(self.cc, self.operands) = systemz.get_arch_info(self._raw.detail.contents.arch.sysz)
|
||||
elif arch == CS_ARCH_SYSTEMZ:
|
||||
(self.cc, self.format, self.operands) = systemz.get_arch_info(self._raw.detail.contents.arch.systemz)
|
||||
elif arch == CS_ARCH_XCORE:
|
||||
(self.operands) = xcore.get_arch_info(self._raw.detail.contents.arch.xcore)
|
||||
elif arch == CS_ARCH_TMS320C64X:
|
||||
@ -1397,7 +1428,7 @@ def debug():
|
||||
archs = {
|
||||
"arm": CS_ARCH_ARM, "aarch64": CS_ARCH_AARCH64, "m68k": CS_ARCH_M68K,
|
||||
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC,
|
||||
"sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X,
|
||||
"systemz": CS_ARCH_SYSTEMZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X,
|
||||
"m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX,
|
||||
'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE,
|
||||
'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA,
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [aarch64_const.py]
|
||||
|
||||
AARCH64_SFT_INVALID = 0
|
||||
@ -2368,6 +2368,8 @@ AARCH64_SME_MATRIX_SLICE_OFF_RANGE = 4
|
||||
AARCH64_SME_OP_INVALID = 0
|
||||
AARCH64_SME_OP_TILE = 1
|
||||
AARCH64_SME_OP_TILE_VEC = 2
|
||||
AARCH64_SLICE_IMM_INVALID = UINT16_MAX
|
||||
AARCH64_SLICE_IMM_RANGE_INVALID = UINT8_MAX
|
||||
|
||||
AARCH64_INS_INVALID = 0
|
||||
AARCH64_INS_ABS = 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [alpha_const.py]
|
||||
|
||||
# Operand type for instruction's operands
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm_const.py]
|
||||
|
||||
ARMCC_EQ = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [bpf_const.py]
|
||||
|
||||
BPF_OP_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [evm_const.py]
|
||||
|
||||
EVM_INS_STOP = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [hppa_const.py]
|
||||
HPPA_MAX_OPS = 5
|
||||
HPPA_STR_MODIFIER_LEN = 8
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [loongarch_const.py]
|
||||
LOONGARCH_OP_INVALID = CS_OP_INVALID
|
||||
LOONGARCH_OP_REG = CS_OP_REG
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [m680x_const.py]
|
||||
M680X_OPERAND_COUNT = 9
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [m68k_const.py]
|
||||
M68K_OPERAND_COUNT = 4
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [mips_const.py]
|
||||
|
||||
MIPS_OP_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [mos65xx_const.py]
|
||||
|
||||
MOS65XX_REG_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [ppc_const.py]
|
||||
PPC_PRED_INVALID = 0xffff
|
||||
PPC_PRED_LT = (0<<5)|12
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [riscv_const.py]
|
||||
|
||||
# Operand type for instruction's operands
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sh_const.py]
|
||||
|
||||
SH_REG_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sparc_const.py]
|
||||
|
||||
SPARC_CC_INVALID = 0
|
||||
|
@ -2,28 +2,30 @@
|
||||
|
||||
import ctypes
|
||||
from . import copy_ctypes_list
|
||||
from .sysz_const import *
|
||||
|
||||
# define the API
|
||||
class SyszOpMem(ctypes.Structure):
|
||||
class SystemZOpMem(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('am', ctypes.c_int),
|
||||
('base', ctypes.c_uint8),
|
||||
('index', ctypes.c_uint8),
|
||||
('length', ctypes.c_uint64),
|
||||
('disp', ctypes.c_int64),
|
||||
)
|
||||
|
||||
class SyszOpValue(ctypes.Union):
|
||||
class SystemZOpValue(ctypes.Union):
|
||||
_fields_ = (
|
||||
('reg', ctypes.c_uint),
|
||||
('imm', ctypes.c_int64),
|
||||
('mem', SyszOpMem),
|
||||
('mem', SystemZOpMem),
|
||||
)
|
||||
|
||||
class SyszOp(ctypes.Structure):
|
||||
class SystemZOp(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('type', ctypes.c_uint),
|
||||
('value', SyszOpValue),
|
||||
('value', SystemZOpValue),
|
||||
('access', ctypes.c_int),
|
||||
('imm_width', ctypes.c_uint8),
|
||||
)
|
||||
|
||||
@property
|
||||
@ -39,13 +41,14 @@ class SyszOp(ctypes.Structure):
|
||||
return self.value.mem
|
||||
|
||||
|
||||
class CsSysz(ctypes.Structure):
|
||||
class CsSystemZ(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('cc', ctypes.c_uint),
|
||||
('format', ctypes.c_int),
|
||||
('op_count', ctypes.c_uint8),
|
||||
('operands', SyszOp * 6),
|
||||
('operands', SystemZOp * 6),
|
||||
)
|
||||
|
||||
def get_arch_info(a):
|
||||
return (a.cc, copy_ctypes_list(a.operands[:a.op_count]))
|
||||
return a.cc, a.format, copy_ctypes_list(a.operands[:a.op_count])
|
||||
|
||||
|
2903
bindings/python/capstone/systemz_const.py
Normal file
2903
bindings/python/capstone/systemz_const.py
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [tms320c64x_const.py]
|
||||
|
||||
TMS320C64X_OP_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [tricore_const.py]
|
||||
TRICORE_OP_INVALID = CS_OP_INVALID
|
||||
TRICORE_OP_REG = CS_OP_REG
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [wasm_const.py]
|
||||
|
||||
WASM_OP_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [x86_const.py]
|
||||
|
||||
X86_REG_INVALID = 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
|
||||
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX, UINT8_MAX
|
||||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [xcore_const.py]
|
||||
|
||||
XCORE_OP_INVALID = 0
|
||||
|
@ -13,7 +13,7 @@ from capstone import m68k_const
|
||||
from capstone import mips_const
|
||||
from capstone import ppc_const
|
||||
from capstone import sparc_const
|
||||
from capstone import sysz_const
|
||||
from capstone import systemz_const
|
||||
from capstone import x86_const
|
||||
from capstone import xcore_const
|
||||
from capstone import tms320c64x_const
|
||||
@ -52,7 +52,7 @@ def cs_const_getattr(identifier: str):
|
||||
attr = getattr(sparc_const, identifier, None)
|
||||
if attr is not None:
|
||||
return attr
|
||||
attr = getattr(sysz_const, identifier, None)
|
||||
attr = getattr(systemz_const, identifier, None)
|
||||
if attr is not None:
|
||||
return attr
|
||||
attr = getattr(x86_const, identifier, None)
|
||||
|
@ -69,7 +69,7 @@ from capstone.mos65xx_const import MOS65XX_OP_REG, MOS65XX_OP_MEM, MOS65XX_OP_IM
|
||||
from capstone.riscv_const import RISCV_OP_MEM, RISCV_OP_IMM, RISCV_OP_REG
|
||||
from capstone.sh_const import SH_OP_REG, SH_OP_MEM, SH_OP_IMM
|
||||
from capstone.sparc_const import SPARC_OP_REG, SPARC_OP_IMM, SPARC_OP_MEM
|
||||
from capstone.sysz_const import SYSZ_OP_REG, SYSZ_OP_IMM, SYSZ_OP_MEM
|
||||
from capstone.systemz_const import SYSTEMZ_OP_REG, SYSTEMZ_OP_IMM, SYSTEMZ_OP_MEM
|
||||
from capstone.tms320c64x_const import (
|
||||
TMS320C64X_OP_REG,
|
||||
TMS320C64X_OP_REGPAIR,
|
||||
@ -245,7 +245,7 @@ def compare_details(insn: CsInsn, expected: dict) -> bool:
|
||||
elif "xcore" in expected:
|
||||
return test_expected_xcore(actual, expected["xcore"])
|
||||
elif "systemz" in expected:
|
||||
return test_expected_sysz(actual, expected["systemz"])
|
||||
return test_expected_SystemZ(actual, expected["systemz"])
|
||||
elif "sparc" in expected:
|
||||
return test_expected_sparc(actual, expected["sparc"])
|
||||
elif "sh" in expected:
|
||||
@ -1349,25 +1349,35 @@ def test_expected_mips(actual: CsInsn, expected: dict) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def test_expected_sysz(actual: CsInsn, expected: dict) -> bool:
|
||||
def test_expected_SystemZ(actual: CsInsn, expected: dict) -> bool:
|
||||
if "operands" not in expected:
|
||||
return True
|
||||
elif not compare_uint32(
|
||||
len(actual.operands), len(expected.get("operands")), "operands_count"
|
||||
):
|
||||
return False
|
||||
elif not compare_enum(
|
||||
actual.format, expected.get("format"), "format"
|
||||
):
|
||||
return False
|
||||
|
||||
for aop, eop in zip(actual.operands, expected["operands"]):
|
||||
if not compare_enum(aop.type, eop.get("type"), "type"):
|
||||
return False
|
||||
if not compare_enum(aop.access, eop.get("access"), "access"):
|
||||
return False
|
||||
|
||||
if aop.type == SYSZ_OP_REG:
|
||||
if aop.type == SYSTEMZ_OP_REG:
|
||||
if not compare_reg(actual, aop.reg, eop.get("reg"), "reg"):
|
||||
return False
|
||||
elif aop.type == SYSZ_OP_IMM:
|
||||
elif aop.type == SYSTEMZ_OP_IMM:
|
||||
if not compare_int64(aop.imm, eop.get("imm"), "imm"):
|
||||
return False
|
||||
elif aop.type == SYSZ_OP_MEM:
|
||||
if not compare_int64(aop.imm_width, eop.get("imm_width"), "imm_width"):
|
||||
return False
|
||||
elif aop.type == SYSTEMZ_OP_MEM:
|
||||
if not compare_enum(aop.mem.am, eop.get("mem_am"), "mem_am"):
|
||||
return False
|
||||
if not compare_reg(actual, aop.mem.base, eop.get("mem_base"), "mem_base"):
|
||||
return False
|
||||
if not compare_reg(
|
||||
|
@ -56,7 +56,7 @@ all_tests = (
|
||||
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", CS_OPT_SYNTAX_NOREGNAME),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", None),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None),
|
||||
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None),
|
||||
(CS_ARCH_SYSTEMZ, 0, SYSZ_CODE, "SystemZ", None),
|
||||
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None),
|
||||
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None),
|
||||
(CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),
|
||||
|
@ -50,7 +50,7 @@ all_tests = (
|
||||
(CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", CS_OPT_SYNTAX_NOREGNAME),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", None),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None),
|
||||
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None),
|
||||
(CS_ARCH_SYSTEMZ, 0, SYSZ_CODE, "SystemZ", None),
|
||||
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None),
|
||||
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None),
|
||||
(CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),
|
||||
|
2
cmake.sh
2
cmake.sh
@ -31,7 +31,7 @@ case $1 in
|
||||
ARCH=SPARC
|
||||
;;
|
||||
SystemZ)
|
||||
ARCH=SYSZ
|
||||
ARCH=SYSTEMZ
|
||||
;;
|
||||
XCore)
|
||||
ARCH=XCORE
|
||||
|
@ -1,338 +0,0 @@
|
||||
From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 17:02:40 +0200
|
||||
Subject: [PATCH 1/7] capstone: generate *GenRegisterInfo.inc
|
||||
|
||||
---
|
||||
utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++++++++++++++++++++---
|
||||
1 file changed, 115 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
|
||||
index 49016cca799..6ebb7148b1b 100644
|
||||
--- a/utils/TableGen/RegisterInfoEmitter.cpp
|
||||
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
|
||||
@@ -99,6 +99,12 @@ private:
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
+#ifdef CAPSTONE
|
||||
+#define NAME_PREFIX Target.getName() << "_" <<
|
||||
+#else
|
||||
+#define NAME_PREFIX
|
||||
+#endif
|
||||
+
|
||||
// runEnums - Print out enum values for all of the registers.
|
||||
void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
CodeGenTarget &Target, CodeGenRegBank &Bank) {
|
||||
@@ -107,13 +113,22 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
// Register enums are stored as uint16_t in the tables. Make sure we'll fit.
|
||||
assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace");
|
||||
+#endif
|
||||
|
||||
emitSourceFileHeader("Target Register Enum Values", OS);
|
||||
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "/* Capstone Disassembly Engine */\n"
|
||||
+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
|
||||
+ "\n";
|
||||
+#endif
|
||||
+
|
||||
OS << "\n#ifdef GET_REGINFO_ENUM\n";
|
||||
OS << "#undef GET_REGINFO_ENUM\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace llvm {\n\n";
|
||||
|
||||
OS << "class MCRegisterClass;\n"
|
||||
@@ -122,16 +137,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
|
||||
if (!Namespace.empty())
|
||||
OS << "namespace " << Namespace << " {\n";
|
||||
- OS << "enum {\n NoRegister,\n";
|
||||
+#endif
|
||||
+
|
||||
+ OS << "enum {\n " << NAME_PREFIX "NoRegister,\n";
|
||||
|
||||
for (const auto &Reg : Registers)
|
||||
- OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
|
||||
+ OS << " " << NAME_PREFIX Reg.getName() << " = " << Reg.EnumValue << ",\n";
|
||||
assert(Registers.size() == Registers.back().EnumValue &&
|
||||
"Register enum value mismatch!");
|
||||
- OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
|
||||
+ OS << " " << NAME_PREFIX "NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
|
||||
OS << "};\n";
|
||||
+#ifndef CAPSTONE
|
||||
if (!Namespace.empty())
|
||||
OS << "} // end namespace " << Namespace << "\n";
|
||||
+#endif
|
||||
|
||||
const auto &RegisterClasses = Bank.getRegClasses();
|
||||
if (!RegisterClasses.empty()) {
|
||||
@@ -140,18 +159,29 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
assert(RegisterClasses.size() <= 0xffff &&
|
||||
"Too many register classes to fit in tables");
|
||||
|
||||
- OS << "\n// Register classes\n\n";
|
||||
+ OS << "\n// Register classes\n";
|
||||
+#ifndef CAPSTONE
|
||||
+ OS << "\n";
|
||||
if (!Namespace.empty())
|
||||
OS << "namespace " << Namespace << " {\n";
|
||||
+#endif
|
||||
OS << "enum {\n";
|
||||
for (const auto &RC : RegisterClasses)
|
||||
- OS << " " << RC.getName() << "RegClassID"
|
||||
+ OS << " " << NAME_PREFIX RC.getName() << "RegClassID"
|
||||
<< " = " << RC.EnumValue << ",\n";
|
||||
- OS << "\n };\n";
|
||||
+#ifdef CAPSTONE
|
||||
+ OS
|
||||
+#else
|
||||
+ OS << "\n "
|
||||
+#endif
|
||||
+ << "};\n";
|
||||
+#ifndef CAPSTONE
|
||||
if (!Namespace.empty())
|
||||
OS << "} // end namespace " << Namespace << "\n\n";
|
||||
+#endif
|
||||
}
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
const std::vector<Record*> &RegAltNameIndices = Target.getRegAltNameIndices();
|
||||
// If the only definition is the default NoRegAltName, we don't need to
|
||||
// emit anything.
|
||||
@@ -182,8 +212,11 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
if (!Namespace.empty())
|
||||
OS << "} // end namespace " << Namespace << "\n\n";
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "} // end namespace llvm\n\n";
|
||||
+#endif
|
||||
OS << "#endif // GET_REGINFO_ENUM\n\n";
|
||||
}
|
||||
|
||||
@@ -830,7 +863,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
const auto &Regs = RegBank.getRegisters();
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
auto &SubRegIndices = RegBank.getSubRegIndices();
|
||||
+#endif
|
||||
// The lists of sub-registers and super-registers go in the same array. That
|
||||
// allows us to share suffixes.
|
||||
typedef std::vector<const CodeGenRegister*> RegVec;
|
||||
@@ -922,25 +957,40 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
LaneMaskSeqs.layout();
|
||||
SubRegIdxSeqs.layout();
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace llvm {\n\n";
|
||||
+#endif
|
||||
|
||||
const std::string &TargetName = Target.getName();
|
||||
|
||||
// Emit the shared table of differential lists.
|
||||
- OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "static"
|
||||
+#else
|
||||
+ OS << "extern"
|
||||
+#endif
|
||||
+ << " const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
|
||||
DiffSeqs.emit(OS, printDiff16);
|
||||
OS << "};\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
// Emit the shared table of regunit lane mask sequences.
|
||||
OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
|
||||
LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()");
|
||||
OS << "};\n\n";
|
||||
+#endif
|
||||
|
||||
// Emit the table of sub-register indexes.
|
||||
- OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "static"
|
||||
+#else
|
||||
+ OS << "extern"
|
||||
+#endif
|
||||
+ << " const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
|
||||
SubRegIdxSeqs.emit(OS, printSubRegIndex);
|
||||
OS << "};\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
// Emit the table of sub-register index sizes.
|
||||
OS << "extern const MCRegisterInfo::SubRegCoveredBits "
|
||||
<< TargetName << "SubRegIdxRanges[] = {\n";
|
||||
@@ -950,14 +1000,22 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< Idx.getName() << "\n";
|
||||
}
|
||||
OS << "};\n\n";
|
||||
+#endif
|
||||
|
||||
// Emit the string table.
|
||||
RegStrings.layout();
|
||||
+#ifndef CAPSTONE
|
||||
OS << "extern const char " << TargetName << "RegStrings[] = {\n";
|
||||
RegStrings.emit(OS, printChar);
|
||||
OS << "};\n\n";
|
||||
+#endif
|
||||
|
||||
- OS << "extern const MCRegisterDesc " << TargetName
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "static"
|
||||
+#else
|
||||
+ OS << "extern"
|
||||
+#endif
|
||||
+ << " const MCRegisterDesc " << TargetName
|
||||
<< "RegDesc[] = { // Descriptors\n";
|
||||
OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n";
|
||||
|
||||
@@ -973,6 +1031,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
}
|
||||
OS << "};\n\n"; // End of register descriptors...
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
// Emit the table of register unit roots. Each regunit has one or two root
|
||||
// registers.
|
||||
OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n";
|
||||
@@ -986,11 +1045,14 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << " },\n";
|
||||
}
|
||||
OS << "};\n\n";
|
||||
+#endif
|
||||
|
||||
const auto &RegisterClasses = RegBank.getRegClasses();
|
||||
|
||||
// Loop over all of the register classes... emitting each one.
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace { // Register classes...\n";
|
||||
+#endif
|
||||
|
||||
SequenceToOffsetTable<std::string> RegClassStrings;
|
||||
|
||||
@@ -1005,15 +1067,28 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
// Emit the register list now.
|
||||
OS << " // " << Name << " Register Class...\n"
|
||||
- << " const MCPhysReg " << Name
|
||||
+ << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "static "
|
||||
+#endif
|
||||
+ << "const MCPhysReg " << Name
|
||||
<< "[] = {\n ";
|
||||
for (Record *Reg : Order) {
|
||||
- OS << getQualifiedName(Reg) << ", ";
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << NAME_PREFIX Reg->getName()
|
||||
+#else
|
||||
+ OS << getQualifiedName(Reg)
|
||||
+#endif
|
||||
+ << ", ";
|
||||
}
|
||||
OS << "\n };\n\n";
|
||||
|
||||
OS << " // " << Name << " Bit set.\n"
|
||||
- << " const uint8_t " << Name
|
||||
+ << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "static "
|
||||
+#endif
|
||||
+ << "const uint8_t " << Name
|
||||
<< "Bits[] = {\n ";
|
||||
BitVectorEmitter BVE;
|
||||
for (Record *Reg : Order) {
|
||||
@@ -1023,14 +1098,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << "\n };\n\n";
|
||||
|
||||
}
|
||||
+#ifndef CAPSTONE
|
||||
OS << "} // end anonymous namespace\n\n";
|
||||
+#endif
|
||||
|
||||
RegClassStrings.layout();
|
||||
+#ifndef CAPSTONE
|
||||
OS << "extern const char " << TargetName << "RegClassStrings[] = {\n";
|
||||
RegClassStrings.emit(OS, printChar);
|
||||
OS << "};\n\n";
|
||||
+#endif
|
||||
|
||||
- OS << "extern const MCRegisterClass " << TargetName
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "static"
|
||||
+#else
|
||||
+ OS << "extern"
|
||||
+#endif
|
||||
+ << " const MCRegisterClass " << TargetName
|
||||
<< "MCRegisterClasses[] = {\n";
|
||||
|
||||
for (const auto &RC : RegisterClasses) {
|
||||
@@ -1041,7 +1125,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
|
||||
<< RegClassStrings.get(RC.getName()) << ", "
|
||||
<< RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
|
||||
- << RC.getQualifiedName() + "RegClassID" << ", "
|
||||
+#ifdef CAPSTONE
|
||||
+ << NAME_PREFIX RC.getName()
|
||||
+#else
|
||||
+ << RC.getQualifiedName()
|
||||
+#endif
|
||||
+ << "RegClassID" << ", "
|
||||
<< RegSize/8 << ", "
|
||||
<< RC.CopyCost << ", "
|
||||
<< ( RC.Allocatable ? "true" : "false" ) << " },\n";
|
||||
@@ -1049,6 +1138,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
OS << "};\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
EmitRegMappingTables(OS, Regs, false);
|
||||
|
||||
// Emit Reg encoding table
|
||||
@@ -1067,7 +1157,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << " " << Value << ",\n";
|
||||
}
|
||||
OS << "};\n"; // End of HW encoding table
|
||||
+#endif
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
// MCRegisterInfo initialization routine.
|
||||
OS << "static inline void Init" << TargetName
|
||||
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
|
||||
@@ -1088,7 +1180,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "} // end namespace llvm\n\n";
|
||||
- OS << "#endif // GET_REGINFO_MC_DESC\n\n";
|
||||
+#endif
|
||||
+ OS << "#endif // GET_REGINFO_MC_DESC\n"
|
||||
+#ifndef CAPSTONE
|
||||
+ << "\n"
|
||||
+#endif
|
||||
+ ;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1568,10 +1665,13 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
void RegisterInfoEmitter::run(raw_ostream &OS) {
|
||||
CodeGenRegBank &RegBank = Target.getRegBank();
|
||||
+
|
||||
runEnums(OS, Target, RegBank);
|
||||
runMCDesc(OS, Target, RegBank);
|
||||
+#ifndef CAPSTONE
|
||||
runTargetHeader(OS, Target, RegBank);
|
||||
runTargetDesc(OS, Target, RegBank);
|
||||
+#endif
|
||||
|
||||
if (RegisterInfoDebug)
|
||||
debugDump(errs());
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,86 +0,0 @@
|
||||
From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 17:42:59 +0200
|
||||
Subject: [PATCH 2/7] capstone: generate *GenSubtargetInfo.inc
|
||||
|
||||
---
|
||||
utils/TableGen/SubtargetEmitter.cpp | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
|
||||
index c5da8d8142f..98ab3240472 100644
|
||||
--- a/utils/TableGen/SubtargetEmitter.cpp
|
||||
+++ b/utils/TableGen/SubtargetEmitter.cpp
|
||||
@@ -147,7 +147,9 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) {
|
||||
if (N > MAX_SUBTARGET_FEATURES)
|
||||
PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace " << Target << " {\n";
|
||||
+#endif
|
||||
|
||||
// Open enumeration.
|
||||
OS << "enum {\n";
|
||||
@@ -158,12 +160,22 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) {
|
||||
Record *Def = DefList[i];
|
||||
|
||||
// Get and emit name
|
||||
- OS << " " << Def->getName() << " = " << i << ",\n";
|
||||
+ OS << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << Target << "_"
|
||||
+#endif
|
||||
+ << Def->getName() << " = "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "1ULL << "
|
||||
+#endif
|
||||
+ << i << ",\n";
|
||||
}
|
||||
|
||||
// Close enumeration and namespace
|
||||
OS << "};\n";
|
||||
+#ifndef CAPSTONE
|
||||
OS << "} // end namespace " << Target << "\n";
|
||||
+#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1709,14 +1721,27 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
|
||||
void SubtargetEmitter::run(raw_ostream &OS) {
|
||||
emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
|
||||
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n"
|
||||
+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
|
||||
+ "\n";
|
||||
+#endif
|
||||
+
|
||||
OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
|
||||
OS << "#undef GET_SUBTARGETINFO_ENUM\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace llvm {\n";
|
||||
+#endif
|
||||
Enumeration(OS);
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "\n";
|
||||
+#else
|
||||
OS << "} // end namespace llvm\n\n";
|
||||
+#endif
|
||||
OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
|
||||
OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n";
|
||||
|
||||
@@ -1857,6 +1882,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
|
||||
OS << "} // end namespace llvm\n\n";
|
||||
|
||||
OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
|
||||
+#endif
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,130 +0,0 @@
|
||||
From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 17:59:43 +0200
|
||||
Subject: [PATCH 3/7] capstone: generate *GenInstrInfo.inc
|
||||
|
||||
---
|
||||
utils/TableGen/InstrInfoEmitter.cpp | 49 ++++++++++++++++++++++++++---
|
||||
1 file changed, 44 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
index 0aff1aa6f94..2f3a2729262 100644
|
||||
--- a/utils/TableGen/InstrInfoEmitter.cpp
|
||||
+++ b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
@@ -92,6 +92,7 @@ private:
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
static void PrintDefList(const std::vector<Record*> &Uses,
|
||||
unsigned Num, raw_ostream &OS) {
|
||||
OS << "static const MCPhysReg ImplicitList" << Num << "[] = { ";
|
||||
@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector<Record*> &Uses,
|
||||
OS << getQualifiedName(U) << ", ";
|
||||
OS << "0 };\n";
|
||||
}
|
||||
+#endif
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operand Info Emission.
|
||||
@@ -426,8 +428,17 @@ void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) {
|
||||
// run - Emit the main instruction description records for the target...
|
||||
void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);
|
||||
+
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "/* Capstone Disassembly Engine */\n"
|
||||
+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
|
||||
+ "\n"
|
||||
+ "\n";
|
||||
+#endif
|
||||
+
|
||||
emitEnums(OS);
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
|
||||
OS << "#undef GET_INSTRINFO_MC_DESC\n";
|
||||
|
||||
@@ -545,6 +556,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
|
||||
emitOperandTypesEnum(OS, Target);
|
||||
|
||||
emitMCIIHelperMethods(OS);
|
||||
+#endif
|
||||
}
|
||||
|
||||
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
@@ -659,7 +671,9 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
|
||||
OS << "#ifdef GET_INSTRINFO_ENUM\n";
|
||||
OS << "#undef GET_INSTRINFO_ENUM\n";
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace llvm {\n\n";
|
||||
+#endif
|
||||
|
||||
CodeGenTarget Target(Records);
|
||||
|
||||
@@ -669,17 +683,39 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
|
||||
if (Namespace.empty())
|
||||
PrintFatalError("No instructions defined!");
|
||||
|
||||
+#ifndef CAPSTONE
|
||||
OS << "namespace " << Namespace << " {\n";
|
||||
- OS << " enum {\n";
|
||||
+#endif
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "\n"
|
||||
+#else
|
||||
+ OS << " "
|
||||
+#endif
|
||||
+ << "enum {\n";
|
||||
unsigned Num = 0;
|
||||
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue())
|
||||
- OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
|
||||
- OS << " INSTRUCTION_LIST_END = " << Num << "\n";
|
||||
+ OS << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << Target.getName() << "_"
|
||||
+#endif
|
||||
+ << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
|
||||
+ OS << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << Target.getName() << "_"
|
||||
+#endif
|
||||
+ << "INSTRUCTION_LIST_END = " << Num << "\n";
|
||||
OS << " };\n\n";
|
||||
+#ifndef CAPSTONE
|
||||
OS << "} // end " << Namespace << " namespace\n";
|
||||
OS << "} // end llvm namespace\n";
|
||||
- OS << "#endif // GET_INSTRINFO_ENUM\n\n";
|
||||
-
|
||||
+#endif
|
||||
+ OS << "#endif // GET_INSTRINFO_ENUM\n"
|
||||
+#ifndef CAPSTONE
|
||||
+ << "\n"
|
||||
+#endif
|
||||
+ ;
|
||||
+
|
||||
+#ifndef CAPSTONE
|
||||
OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
|
||||
OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
|
||||
OS << "namespace llvm {\n\n";
|
||||
@@ -696,13 +732,16 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
|
||||
OS << "} // end llvm namespace\n";
|
||||
|
||||
OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
|
||||
+#endif
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
|
||||
InstrInfoEmitter(RK).run(OS);
|
||||
+#ifndef CAPSTONE
|
||||
EmitMapTable(RK, OS);
|
||||
+#endif
|
||||
}
|
||||
|
||||
} // end llvm namespace
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,472 +0,0 @@
|
||||
From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 18:20:17 +0200
|
||||
Subject: [PATCH 4/7] capstone: generate *GenDisassemblerTables.inc
|
||||
|
||||
---
|
||||
utils/TableGen/DisassemblerEmitter.cpp | 12 +-
|
||||
utils/TableGen/FixedLenDecoderEmitter.cpp | 248 ++++++++++++++++++++--
|
||||
2 files changed, 239 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
|
||||
index b99a0a973a2..2ac6d89645c 100644
|
||||
--- a/utils/TableGen/DisassemblerEmitter.cpp
|
||||
+++ b/utils/TableGen/DisassemblerEmitter.cpp
|
||||
@@ -106,6 +106,11 @@ extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS,
|
||||
void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
|
||||
CodeGenTarget Target(Records);
|
||||
emitSourceFileHeader(" * " + Target.getName().str() + " Disassembler", OS);
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "/* Capstone Disassembly Engine */\n"
|
||||
+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
|
||||
+ "\n";
|
||||
+#endif
|
||||
|
||||
// X86 uses a custom disassembler.
|
||||
if (Target.getName() == "X86") {
|
||||
@@ -150,7 +155,12 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
|
||||
}
|
||||
|
||||
EmitFixedLenDecoder(Records, OS, Target.getName(),
|
||||
- "if (", " == MCDisassembler::Fail)",
|
||||
+ "if (",
|
||||
+#ifdef CAPSTONE
|
||||
+ " == MCDisassembler_Fail)",
|
||||
+#else
|
||||
+ " == MCDisassembler::Fail)",
|
||||
+#endif
|
||||
"MCDisassembler::Success", "MCDisassembler::Fail", "");
|
||||
}
|
||||
|
||||
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
|
||||
index fcecc764d44..36845d960d8 100644
|
||||
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
|
||||
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
|
||||
@@ -730,7 +730,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
++I;
|
||||
unsigned Start = *I++;
|
||||
unsigned Len = *I++;
|
||||
- OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_ExtractField"
|
||||
+#else
|
||||
+ << "MCD::OPC_ExtractField"
|
||||
+#endif
|
||||
+ << ", " << Start << ", "
|
||||
<< Len << ", // Inst{";
|
||||
if (Len > 1)
|
||||
OS << (Start + Len - 1) << "-";
|
||||
@@ -739,7 +745,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
}
|
||||
case MCD::OPC_FilterValue: {
|
||||
++I;
|
||||
- OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_FilterValue"
|
||||
+#else
|
||||
+ << "MCD::OPC_FilterValue"
|
||||
+#endif
|
||||
+ << ", ";
|
||||
// The filter value is ULEB128 encoded.
|
||||
while (*I >= 128)
|
||||
OS << (unsigned)*I++ << ", ";
|
||||
@@ -759,7 +771,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
++I;
|
||||
unsigned Start = *I++;
|
||||
unsigned Len = *I++;
|
||||
- OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_CheckField"
|
||||
+#else
|
||||
+ << "MCD::OPC_CheckField"
|
||||
+#endif
|
||||
+ << ", " << Start << ", "
|
||||
<< Len << ", ";// << Val << ", " << NumToSkip << ",\n";
|
||||
// ULEB128 encoded field value.
|
||||
for (; *I >= 128; ++I)
|
||||
@@ -777,7 +795,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
}
|
||||
case MCD::OPC_CheckPredicate: {
|
||||
++I;
|
||||
- OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_CheckPredicate"
|
||||
+#else
|
||||
+ << "MCD::OPC_CheckPredicate"
|
||||
+#endif
|
||||
+ << ", ";
|
||||
for (; *I >= 128; ++I)
|
||||
OS << (unsigned)*I << ", ";
|
||||
OS << (unsigned)*I++ << ", ";
|
||||
@@ -803,7 +827,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
&& "ULEB128 value too large!");
|
||||
// Decode the Opcode value.
|
||||
unsigned Opc = decodeULEB128(Buffer);
|
||||
- OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "")
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_"
|
||||
+#else
|
||||
+ << "MCD::OPC_"
|
||||
+#endif
|
||||
+ << (IsTry ? "Try" : "")
|
||||
<< "Decode, ";
|
||||
for (p = Buffer; *p >= 128; ++p)
|
||||
OS << (unsigned)*p << ", ";
|
||||
@@ -837,7 +867,12 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
}
|
||||
case MCD::OPC_SoftFail: {
|
||||
++I;
|
||||
- OS.indent(Indentation) << "MCD::OPC_SoftFail";
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_SoftFail";
|
||||
+#else
|
||||
+ << "MCD::OPC_SoftFail";
|
||||
+#endif
|
||||
// Positive mask
|
||||
uint64_t Value = 0;
|
||||
unsigned Shift = 0;
|
||||
@@ -869,7 +904,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
}
|
||||
case MCD::OPC_Fail: {
|
||||
++I;
|
||||
- OS.indent(Indentation) << "MCD::OPC_Fail,\n";
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCD_OPC_Fail"
|
||||
+#else
|
||||
+ << "MCD::OPC_Fail"
|
||||
+#endif
|
||||
+ << ",\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -884,23 +925,46 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
|
||||
void FixedLenDecoderEmitter::
|
||||
emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
|
||||
unsigned Indentation) const {
|
||||
+#ifdef CAPSTONE
|
||||
+ OS.indent(Indentation) << "static bool getbool(uint64_t b)\n";
|
||||
+ OS.indent(Indentation) << "{\n";
|
||||
+ OS.indent(Indentation) << "\treturn b != 0;\n";
|
||||
+ OS.indent(Indentation) << "}\n\n";
|
||||
+#endif
|
||||
+
|
||||
// The predicate function is just a big switch statement based on the
|
||||
// input predicate index.
|
||||
OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "uint64_t Bits)\n{\n";
|
||||
+#else
|
||||
<< "const FeatureBitset& Bits) {\n";
|
||||
+#endif
|
||||
Indentation += 2;
|
||||
if (!Predicates.empty()) {
|
||||
OS.indent(Indentation) << "switch (Idx) {\n";
|
||||
- OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
||||
+ OS.indent(Indentation) << "default: "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "// "
|
||||
+#endif
|
||||
+ << "llvm_unreachable(\"Invalid index!\");\n";
|
||||
unsigned Index = 0;
|
||||
for (const auto &Predicate : Predicates) {
|
||||
OS.indent(Indentation) << "case " << Index++ << ":\n";
|
||||
- OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
|
||||
+ OS.indent(Indentation+2) << "return "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "getbool"
|
||||
+#endif
|
||||
+ << "(" << Predicate << ");\n";
|
||||
}
|
||||
OS.indent(Indentation) << "}\n";
|
||||
} else {
|
||||
// No case statement to emit
|
||||
- OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
|
||||
+ OS.indent(Indentation)
|
||||
+#ifdef CAPSTONE
|
||||
+ << "// "
|
||||
+#endif
|
||||
+ << "llvm_unreachable(\"Invalid index!\");\n";
|
||||
}
|
||||
Indentation -= 2;
|
||||
OS.indent(Indentation) << "}\n\n";
|
||||
@@ -911,23 +975,39 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
|
||||
unsigned Indentation) const {
|
||||
// The decoder function is just a big switch statement based on the
|
||||
// input decoder index.
|
||||
+#ifdef CAPSTONE
|
||||
+#define EDF_EOL " \\\n"
|
||||
+ OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n";
|
||||
+ OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n";
|
||||
+ OS.indent(Indentation) << " uint64_t Address, const void *Decoder) \\\n";
|
||||
+ OS.indent(Indentation) << "{ \\\n";
|
||||
+#else
|
||||
+#define EDF_EOL "\n"
|
||||
OS.indent(Indentation) << "template<typename InsnType>\n";
|
||||
OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
|
||||
<< " unsigned Idx, InsnType insn, MCInst &MI,\n";
|
||||
OS.indent(Indentation) << " uint64_t "
|
||||
<< "Address, const void *Decoder, bool &DecodeComplete) {\n";
|
||||
+#endif
|
||||
Indentation += 2;
|
||||
+#ifndef CAPSTONE
|
||||
OS.indent(Indentation) << "DecodeComplete = true;\n";
|
||||
- OS.indent(Indentation) << "InsnType tmp;\n";
|
||||
- OS.indent(Indentation) << "switch (Idx) {\n";
|
||||
- OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
||||
+#endif
|
||||
+ OS.indent(Indentation) << "InsnType tmp;" EDF_EOL;
|
||||
+ OS.indent(Indentation) << "switch (Idx) {" EDF_EOL;
|
||||
+ OS.indent(Indentation) << "default:"
|
||||
+#ifndef CAPSTONE
|
||||
+ << " llvm_unreachable(\"Invalid index!\");\n";
|
||||
+#else
|
||||
+ << " \\\n";
|
||||
+#endif
|
||||
unsigned Index = 0;
|
||||
for (const auto &Decoder : Decoders) {
|
||||
- OS.indent(Indentation) << "case " << Index++ << ":\n";
|
||||
+ OS.indent(Indentation) << "case " << Index++ << ":" EDF_EOL;
|
||||
OS << Decoder;
|
||||
- OS.indent(Indentation+2) << "return S;\n";
|
||||
+ OS.indent(Indentation+2) << "return S;" EDF_EOL;
|
||||
}
|
||||
- OS.indent(Indentation) << "}\n";
|
||||
+ OS.indent(Indentation) << "}" EDF_EOL;
|
||||
Indentation -= 2;
|
||||
OS.indent(Indentation) << "}\n\n";
|
||||
}
|
||||
@@ -1054,16 +1134,21 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
|
||||
const std::string &Decoder = OpInfo.Decoder;
|
||||
|
||||
if (OpInfo.numFields() != 1)
|
||||
- o.indent(Indentation) << "tmp = 0;\n";
|
||||
+ o.indent(Indentation) << "tmp = 0;" EDF_EOL;
|
||||
|
||||
for (const EncodingField &EF : OpInfo) {
|
||||
o.indent(Indentation) << "tmp ";
|
||||
if (OpInfo.numFields() != 1) o << '|';
|
||||
- o << "= fieldFromInstruction"
|
||||
+ o << "= "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "fieldname"
|
||||
+#else
|
||||
+ << "fieldFromInstruction"
|
||||
+#endif
|
||||
<< "(insn, " << EF.Base << ", " << EF.Width << ')';
|
||||
if (OpInfo.numFields() != 1 || EF.Offset != 0)
|
||||
o << " << " << EF.Offset;
|
||||
- o << ";\n";
|
||||
+ o << ";" EDF_EOL;
|
||||
}
|
||||
|
||||
if (Decoder != "") {
|
||||
@@ -1071,8 +1156,12 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
|
||||
o.indent(Indentation) << Emitter->GuardPrefix << Decoder
|
||||
<< "(MI, tmp, Address, Decoder)"
|
||||
<< Emitter->GuardPostfix
|
||||
+#ifdef CAPSTONE
|
||||
+ << " return MCDisassembler_Fail; \\\n";
|
||||
+#else
|
||||
<< " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
|
||||
<< "return MCDisassembler::Fail; }\n";
|
||||
+#endif
|
||||
} else {
|
||||
OpHasCompleteDecoder = true;
|
||||
o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
|
||||
@@ -1091,7 +1180,13 @@ void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
|
||||
<< "(MI, insn, Address, Decoder)"
|
||||
<< Emitter->GuardPostfix
|
||||
<< " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
|
||||
- << "return MCDisassembler::Fail; }\n";
|
||||
+ << "return "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCDisassembler_Fail"
|
||||
+#else
|
||||
+ << "MCDisassembler::Fail"
|
||||
+#endif
|
||||
+ << "; }\n";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1129,10 +1224,19 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
|
||||
static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
|
||||
const std::string &PredicateNamespace) {
|
||||
if (str[0] == '!')
|
||||
+#ifdef CAPSTONE
|
||||
+ o << "~(Bits & " << PredicateNamespace << "_"
|
||||
+ << str.slice(1,str.size()) << ")";
|
||||
+#else
|
||||
o << "!Bits[" << PredicateNamespace << "::"
|
||||
<< str.slice(1,str.size()) << "]";
|
||||
+#endif
|
||||
else
|
||||
+#ifdef CAPSTONE
|
||||
+ o << "(Bits & " << PredicateNamespace << "_" << str << ")";
|
||||
+#else
|
||||
o << "Bits[" << PredicateNamespace << "::" << str << "]";
|
||||
+#endif
|
||||
}
|
||||
|
||||
bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
|
||||
@@ -2047,6 +2151,17 @@ static bool populateInstruction(CodeGenTarget &Target,
|
||||
// fieldFromInstruction().
|
||||
static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
|
||||
OS << "// Helper function for extracting fields from encoded instructions.\n"
|
||||
+#ifdef CAPSTONE
|
||||
+ << "#define FieldFromInstruction(fname, InsnType) \\\n"
|
||||
+ << "static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \\\n"
|
||||
+ << "{ \\\n"
|
||||
+ << " InsnType fieldMask; \\\n"
|
||||
+ << " if (numBits == sizeof(InsnType)*8) \\\n"
|
||||
+ << " fieldMask = (InsnType)(-1LL); \\\n"
|
||||
+ << " else \\\n"
|
||||
+ << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \\\n"
|
||||
+ << " return (insn & fieldMask) >> startBit; \\\n"
|
||||
+#else
|
||||
<< "template<typename InsnType>\n"
|
||||
<< "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n"
|
||||
<< " unsigned numBits) {\n"
|
||||
@@ -2058,12 +2173,92 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
|
||||
<< " else\n"
|
||||
<< " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
|
||||
<< " return (insn & fieldMask) >> startBit;\n"
|
||||
+#endif
|
||||
<< "}\n\n";
|
||||
}
|
||||
|
||||
// emitDecodeInstruction - Emit the templated helper function
|
||||
// decodeInstruction().
|
||||
static void emitDecodeInstruction(formatted_raw_ostream &OS) {
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n"
|
||||
+ << "static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \\\n"
|
||||
+ << " InsnType insn, uint64_t Address, const MCRegisterInfo *MRI, int feature) \\\n"
|
||||
+ << "{ \\\n"
|
||||
+ << " uint64_t Bits = getFeatureBits(feature); \\\n"
|
||||
+ << " const uint8_t *Ptr = DecodeTable; \\\n"
|
||||
+ << " uint32_t CurFieldValue = 0, ExpectedValue; \\\n"
|
||||
+ << " DecodeStatus S = MCDisassembler_Success; \\\n"
|
||||
+ << " unsigned Start, Len, NumToSkip, PIdx, Opc, DecodeIdx; \\\n"
|
||||
+ << " InsnType Val, FieldValue, PositiveMask, NegativeMask; \\\n"
|
||||
+ << " bool Pred, Fail; \\\n"
|
||||
+ << " for (;;) { \\\n"
|
||||
+ << " switch (*Ptr) { \\\n"
|
||||
+ << " default: \\\n"
|
||||
+ << " return MCDisassembler_Fail; \\\n"
|
||||
+ << " case MCD_OPC_ExtractField: { \\\n"
|
||||
+ << " Start = *++Ptr; \\\n"
|
||||
+ << " Len = *++Ptr; \\\n"
|
||||
+ << " ++Ptr; \\\n"
|
||||
+ << " CurFieldValue = (uint32_t)fieldname(insn, Start, Len); \\\n"
|
||||
+ << " break; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_FilterValue: { \\\n"
|
||||
+ << " Val = (InsnType)decodeULEB128(++Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " NumToSkip = *Ptr++; \\\n"
|
||||
+ << " NumToSkip |= (*Ptr++) << 8; \\\n"
|
||||
+ << " if (Val != CurFieldValue) \\\n"
|
||||
+ << " Ptr += NumToSkip; \\\n"
|
||||
+ << " break; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_CheckField: { \\\n"
|
||||
+ << " Start = *++Ptr; \\\n"
|
||||
+ << " Len = *++Ptr; \\\n"
|
||||
+ << " FieldValue = fieldname(insn, Start, Len); \\\n"
|
||||
+ << " ExpectedValue = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " NumToSkip = *Ptr++; \\\n"
|
||||
+ << " NumToSkip |= (*Ptr++) << 8; \\\n"
|
||||
+ << " if (ExpectedValue != FieldValue) \\\n"
|
||||
+ << " Ptr += NumToSkip; \\\n"
|
||||
+ << " break; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_CheckPredicate: { \\\n"
|
||||
+ << " PIdx = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " NumToSkip = *Ptr++; \\\n"
|
||||
+ << " NumToSkip |= (*Ptr++) << 8; \\\n"
|
||||
+ << " Pred = checkDecoderPredicate(PIdx, Bits); \\\n"
|
||||
+ << " if (!Pred) \\\n"
|
||||
+ << " Ptr += NumToSkip; \\\n"
|
||||
+ << " (void)Pred; \\\n"
|
||||
+ << " break; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_Decode: { \\\n"
|
||||
+ << " Opc = (unsigned)decodeULEB128(++Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " DecodeIdx = (unsigned)decodeULEB128(Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " MCInst_setOpcode(MI, Opc); \\\n"
|
||||
+ << " return decoder(S, DecodeIdx, insn, MI, Address, MRI); \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_SoftFail: { \\\n"
|
||||
+ << " PositiveMask = (InsnType)decodeULEB128(++Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " NegativeMask = (InsnType)decodeULEB128(Ptr, &Len); \\\n"
|
||||
+ << " Ptr += Len; \\\n"
|
||||
+ << " Fail = (insn & PositiveMask) || (~insn & NegativeMask); \\\n"
|
||||
+ << " if (Fail) \\\n"
|
||||
+ << " S = MCDisassembler_SoftFail; \\\n"
|
||||
+ << " break; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " case MCD_OPC_Fail: { \\\n"
|
||||
+ << " return MCDisassembler_Fail; \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " } \\\n"
|
||||
+ << " } \\\n"
|
||||
+#else
|
||||
OS << "template<typename InsnType>\n"
|
||||
<< "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
|
||||
"MCInst &MI,\n"
|
||||
@@ -2240,12 +2435,18 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
|
||||
<< " }\n"
|
||||
<< " llvm_unreachable(\"bogosity detected in disassembler state "
|
||||
"machine!\");\n"
|
||||
+#endif
|
||||
<< "}\n\n";
|
||||
}
|
||||
|
||||
// Emits disassembler code for instruction decoding.
|
||||
void FixedLenDecoderEmitter::run(raw_ostream &o) {
|
||||
formatted_raw_ostream OS(o);
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "#include \"../../MCInst.h\"\n";
|
||||
+ OS << "#include \"../../LEB128.h\"\n";
|
||||
+ OS << "\n";
|
||||
+#else
|
||||
OS << "#include \"llvm/MC/MCInst.h\"\n";
|
||||
OS << "#include \"llvm/Support/Debug.h\"\n";
|
||||
OS << "#include \"llvm/Support/DataTypes.h\"\n";
|
||||
@@ -2254,6 +2455,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
|
||||
OS << "#include <assert.h>\n";
|
||||
OS << '\n';
|
||||
OS << "namespace llvm {\n\n";
|
||||
+#endif
|
||||
|
||||
emitFieldFromInstruction(OS);
|
||||
|
||||
@@ -2322,7 +2524,13 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
|
||||
// Emit the main entry point for the decoder, decodeInstruction().
|
||||
emitDecodeInstruction(OS);
|
||||
|
||||
+#ifdef CAPSTONE
|
||||
+ OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n";
|
||||
+ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n";
|
||||
+ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n";
|
||||
+#else
|
||||
OS << "\n} // End llvm namespace\n";
|
||||
+#endif
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,225 +0,0 @@
|
||||
From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 20:00:08 +0200
|
||||
Subject: [PATCH 5/7] capstone: generate *GenAsmWriter.inc
|
||||
|
||||
---
|
||||
utils/TableGen/AsmWriterEmitter.cpp | 89 +++++++++++++++++++++++++++--
|
||||
utils/TableGen/AsmWriterInst.cpp | 4 ++
|
||||
2 files changed, 87 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
|
||||
index 3c4c9c8e5c6..133800d217c 100644
|
||||
--- a/utils/TableGen/AsmWriterEmitter.cpp
|
||||
+++ b/utils/TableGen/AsmWriterEmitter.cpp
|
||||
@@ -272,16 +272,22 @@ static void UnescapeString(std::string &Str) {
|
||||
/// clearing the Instructions vector.
|
||||
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
Record *AsmWriter = Target.getAsmWriter();
|
||||
+#ifndef CAPSTONE
|
||||
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
|
||||
+#endif
|
||||
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
|
||||
|
||||
O <<
|
||||
"/// printInstruction - This method is automatically generated by tablegen\n"
|
||||
"/// from the instruction set description.\n"
|
||||
+#ifdef CAPSTONE
|
||||
+ "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n";
|
||||
+#else
|
||||
"void " << Target.getName() << ClassName
|
||||
<< "::printInstruction(const MCInst *MI, "
|
||||
<< (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
|
||||
<< "raw_ostream &O) {\n";
|
||||
+#endif
|
||||
|
||||
// Build an aggregate string, and build a table of offsets into it.
|
||||
SequenceToOffsetTable<std::string> StringTable;
|
||||
@@ -379,9 +385,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
}
|
||||
|
||||
// Emit the string table itself.
|
||||
+#ifdef CAPSTONE
|
||||
+ O << "#ifndef CAPSTONE_DIET\n";
|
||||
+#endif
|
||||
O << " static const char AsmStrs[] = {\n";
|
||||
StringTable.emit(O, printChar);
|
||||
- O << " };\n\n";
|
||||
+ O << " };\n"
|
||||
+#ifdef CAPSTONE
|
||||
+ << "#endif\n"
|
||||
+#endif
|
||||
+ << "\n";
|
||||
|
||||
// Emit the lookup tables in pieces to minimize wasted bytes.
|
||||
unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8;
|
||||
@@ -409,21 +422,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
// If the total bits is more than 32-bits we need to use a 64-bit type.
|
||||
if (BitsLeft < (OpcodeInfoBits - 32))
|
||||
BitsOS << "(uint64_t)";
|
||||
- BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n";
|
||||
+ BitsOS << "OpInfo" << Table << "["
|
||||
+#ifdef CAPSTONE
|
||||
+ << "MCInst_getOpcode(MI)"
|
||||
+#else
|
||||
+ << "MI->getOpcode()"
|
||||
+#endif
|
||||
+ << "] << " << Shift << ";\n";
|
||||
// Prepare the shift for the next iteration and increment the table count.
|
||||
Shift += TableSize;
|
||||
++Table;
|
||||
}
|
||||
|
||||
// Emit the initial tab character.
|
||||
+#ifndef CAPSTONE
|
||||
O << " O << \"\\t\";\n\n";
|
||||
+#endif
|
||||
|
||||
O << " // Emit the opcode for the instruction.\n";
|
||||
O << BitsString;
|
||||
|
||||
// Emit the starting string.
|
||||
- O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
|
||||
- << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
|
||||
+ O << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "// "
|
||||
+#endif
|
||||
+ << "assert(Bits != 0 && \"Cannot print this instruction.\");\n"
|
||||
+#ifdef CAPSTONE
|
||||
+ << "#ifndef CAPSTONE_DIET\n"
|
||||
+ << " SStream_concat0(O, "
|
||||
+#else
|
||||
+ << " O << "
|
||||
+#endif
|
||||
+ << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1"
|
||||
+#ifdef CAPSTONE
|
||||
+ << ");\n"
|
||||
+ << "#endif\n\n";
|
||||
+#else
|
||||
+ << ");\n\n";
|
||||
+#endif
|
||||
|
||||
// Output the table driven operand information.
|
||||
BitsLeft = OpcodeInfoBits-AsmStrBits;
|
||||
@@ -455,7 +492,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
O << " switch ((Bits >> "
|
||||
<< (OpcodeInfoBits-BitsLeft) << ") & "
|
||||
<< ((1 << NumBits)-1) << ") {\n"
|
||||
- << " default: llvm_unreachable(\"Invalid command number.\");\n";
|
||||
+ << " default: "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "// "
|
||||
+#endif
|
||||
+ << "llvm_unreachable(\"Invalid command number.\");\n";
|
||||
|
||||
// Print out all the cases.
|
||||
for (unsigned j = 0, e = Commands.size(); j != e; ++j) {
|
||||
@@ -536,6 +577,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
|
||||
}
|
||||
|
||||
StringTable.layout();
|
||||
+#ifdef CAPSTONE
|
||||
+ O << "#ifndef CAPSTONE_DIET\n";
|
||||
+#endif
|
||||
O << " static const char AsmStrs" << AltName << "[] = {\n";
|
||||
StringTable.emit(O, printChar);
|
||||
O << " };\n\n";
|
||||
@@ -552,8 +596,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
|
||||
}
|
||||
|
||||
void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
|
||||
+#ifndef CAPSTONE
|
||||
Record *AsmWriter = Target.getAsmWriter();
|
||||
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
|
||||
+#endif
|
||||
const auto &Registers = Target.getRegBank().getRegisters();
|
||||
const std::vector<Record*> &AltNameIndices = Target.getRegAltNameIndices();
|
||||
bool hasAltNames = AltNameIndices.size() > 1;
|
||||
@@ -563,12 +609,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
|
||||
"\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
|
||||
"/// from the register set description. This returns the assembler name\n"
|
||||
"/// for the specified register.\n"
|
||||
+#ifdef CAPSTONE
|
||||
+ "static const char *getRegisterName(unsigned RegNo)\n{\n";
|
||||
+#else
|
||||
"const char *" << Target.getName() << ClassName << "::";
|
||||
if (hasAltNames)
|
||||
O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
|
||||
else
|
||||
O << "getRegisterName(unsigned RegNo) {\n";
|
||||
- O << " assert(RegNo && RegNo < " << (Registers.size()+1)
|
||||
+#endif
|
||||
+ O << " "
|
||||
+#ifdef CAPSTONE
|
||||
+ << "// "
|
||||
+#endif
|
||||
+ << "assert(RegNo && RegNo < " << (Registers.size()+1)
|
||||
<< " && \"Invalid register number!\");\n"
|
||||
<< "\n";
|
||||
|
||||
@@ -595,10 +649,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
|
||||
}
|
||||
O << " }\n";
|
||||
} else {
|
||||
+#ifdef CAPSTONE
|
||||
+ O << " //int i;\n"
|
||||
+ << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n"
|
||||
+ << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n"
|
||||
+ << " //printf(\"*************************\\n\");\n"
|
||||
+#else
|
||||
O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
|
||||
<< " \"Invalid alt name index for register!\");\n"
|
||||
+#endif
|
||||
<< " return AsmStrs+RegAsmOffset[RegNo-1];\n";
|
||||
}
|
||||
+#ifdef CAPSTONE
|
||||
+ O << "#else\n"
|
||||
+ << " return NULL;\n"
|
||||
+ << "#endif\n";
|
||||
+#endif
|
||||
O << "}\n";
|
||||
}
|
||||
|
||||
@@ -1135,9 +1201,20 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
|
||||
}
|
||||
|
||||
void AsmWriterEmitter::run(raw_ostream &O) {
|
||||
+#ifdef CAPSTONE
|
||||
+ O << "/* Capstone Disassembly Engine */\n"
|
||||
+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
|
||||
+ "\n"
|
||||
+ "#include <stdio.h>\t// debug\n"
|
||||
+ "#include <capstone/platform.h>\n"
|
||||
+ "\n"
|
||||
+ "\n";
|
||||
+#endif
|
||||
EmitPrintInstruction(O);
|
||||
EmitGetRegisterName(O);
|
||||
+#ifndef CAPSTONE
|
||||
EmitPrintAliasInstruction(O);
|
||||
+#endif
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
|
||||
index 2c19e5d663d..6fa751e50df 100644
|
||||
--- a/utils/TableGen/AsmWriterInst.cpp
|
||||
+++ b/utils/TableGen/AsmWriterInst.cpp
|
||||
@@ -28,9 +28,13 @@ static bool isIdentChar(char C) {
|
||||
|
||||
std::string AsmWriterOperand::getCode(bool PassSubtarget) const {
|
||||
if (OperandType == isLiteralTextOperand) {
|
||||
+#ifdef CAPSTONE
|
||||
+ return "SStream_concat0(O, \"" + Str + "\");";
|
||||
+#else
|
||||
if (Str.size() == 1)
|
||||
return "O << '" + Str + "';";
|
||||
return "O << \"" + Str + "\";";
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (OperandType == isLiteralStatementOperand)
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,174 +0,0 @@
|
||||
From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 20:55:32 +0200
|
||||
Subject: [PATCH 6/7] capstone: generate *MappingInsn.inc
|
||||
|
||||
---
|
||||
lib/Target/SystemZ/CMakeLists.txt | 1 +
|
||||
utils/TableGen/InstrInfoEmitter.cpp | 95 +++++++++++++++++++++++++++++
|
||||
utils/TableGen/TableGen.cpp | 6 ++
|
||||
utils/TableGen/TableGenBackends.h | 1 +
|
||||
4 files changed, 103 insertions(+)
|
||||
|
||||
diff --git a/lib/Target/SystemZ/CMakeLists.txt b/lib/Target/SystemZ/CMakeLists.txt
|
||||
index f83b4242fb4..4b5d9c4a3b2 100644
|
||||
--- a/lib/Target/SystemZ/CMakeLists.txt
|
||||
+++ b/lib/Target/SystemZ/CMakeLists.txt
|
||||
@@ -6,6 +6,7 @@ tablegen(LLVM SystemZGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler)
|
||||
tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info)
|
||||
+tablegen(LLVM SystemZMappingInsn.inc -mapping-insn)
|
||||
tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM SystemZGenSubtargetInfo.inc -gen-subtarget)
|
||||
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
index 2f3a2729262..14ab1ea8a72 100644
|
||||
--- a/utils/TableGen/InstrInfoEmitter.cpp
|
||||
+++ b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
@@ -744,4 +744,99 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifdef CAPSTONE
|
||||
+std::string GetPublicName(const CodeGenInstruction *Inst) {
|
||||
+ std::string Name = Inst->TheDef->getName();
|
||||
+ // Apply backward compatibility fixups.
|
||||
+ // BRNLE -> BNLER.
|
||||
+ if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") {
|
||||
+ Name = "B" + Name.substr(5, Name.length() - 5) + "R";
|
||||
+ }
|
||||
+ // SSKEOpt -> SSKE.
|
||||
+ while (Name.length() >= 3 && Name.substr(Name.length() - 3, 3) == "Opt") {
|
||||
+ Name = Name.substr(0, Name.length() - 3);
|
||||
+ }
|
||||
+ // BRCLAsm -> BRCL.
|
||||
+ while (true) {
|
||||
+ size_t pos = Name.find("Asm");
|
||||
+ if (pos == std::string::npos) {
|
||||
+ break;
|
||||
+ }
|
||||
+ Name = Name.substr(0, pos) + Name.substr(pos + 3);
|
||||
+ }
|
||||
+ // CPSDRxx -> CPSDR.
|
||||
+ if (Name.length() >= 2) {
|
||||
+ std::string Suffix2 = Name.substr(Name.length() - 2, 2);
|
||||
+ if (Suffix2 == "dd" || Suffix2 == "ds" ||
|
||||
+ Suffix2 == "sd" || Suffix2 == "ss") {
|
||||
+ Name = Name.substr(0, Name.length() - 2);
|
||||
+ }
|
||||
+ }
|
||||
+ return "SYSZ_INS_" + Name;
|
||||
+}
|
||||
+
|
||||
+std::string GetRegisterName(Record *Reg) {
|
||||
+ std::string Name = Reg->getName();
|
||||
+ for (char& c : Name) {
|
||||
+ c = toupper(c);
|
||||
+ }
|
||||
+ // R0L, R0D -> R0.
|
||||
+ if (Name.length() >= 3 &&
|
||||
+ Name[Name.length() - 3] == 'R' &&
|
||||
+ (Name[Name.length() - 1] == 'L' ||
|
||||
+ Name[Name.length() - 1] == 'D')) {
|
||||
+ Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2];
|
||||
+ }
|
||||
+ return "SYSZ_REG_" + Name;
|
||||
+}
|
||||
+
|
||||
+std::string GetGroupName(Record *Pred) {
|
||||
+ std::string Name = Pred->getName();
|
||||
+ for (char& c : Name) {
|
||||
+ c = toupper(c);
|
||||
+ }
|
||||
+ if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") {
|
||||
+ Name = Name.substr(7);
|
||||
+ }
|
||||
+ return "SYSZ_GRP_" + Name;
|
||||
+}
|
||||
+
|
||||
+void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) {
|
||||
+ OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n"
|
||||
+ "// By Nguyen Anh Quynh <aquynh@gmail.com>\n"
|
||||
+ "\n";
|
||||
+ CodeGenTarget Target(RK);
|
||||
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
||||
+ if (Inst->TheDef->getValueAsBit("isPseudo") ||
|
||||
+ Inst->TheDef->getValueAsBit("isCodeGenOnly")) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ OS << "{\n"
|
||||
+ << "\t" << Target.getName() << "_" << Inst->TheDef->getName() << ", "
|
||||
+ << GetPublicName(Inst) << ",\n"
|
||||
+ << "#ifndef CAPSTONE_DIET\n"
|
||||
+ << "\t{ ";
|
||||
+ for (Record *Use : Inst->TheDef->getValueAsListOfDefs("Uses")) {
|
||||
+ OS << GetRegisterName(Use) << ", ";
|
||||
+ }
|
||||
+ OS << "0 }, { ";
|
||||
+ for (Record *Def : Inst->TheDef->getValueAsListOfDefs("Defs")) {
|
||||
+ OS << GetRegisterName(Def) << ", ";
|
||||
+ }
|
||||
+ OS << "0 }, { ";
|
||||
+ ListInit *Predicates = Inst->TheDef->getValueAsListInit("Predicates");
|
||||
+ for (unsigned i = 0; i < Predicates->size(); ++i) {
|
||||
+ OS << GetGroupName(Predicates->getElementAsRecord(i)) << ", ";
|
||||
+ }
|
||||
+ OS << "0 }, "
|
||||
+ << Inst->TheDef->getValueAsBit("isBranch")
|
||||
+ << ", "
|
||||
+ << Inst->TheDef->getValueAsBit("isIndirectBranch")
|
||||
+ << "\n"
|
||||
+ << "#endif\n"
|
||||
+ << "},\n";
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
} // end llvm namespace
|
||||
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
|
||||
index cf1404d8769..bbb4e860536 100644
|
||||
--- a/utils/TableGen/TableGen.cpp
|
||||
+++ b/utils/TableGen/TableGen.cpp
|
||||
@@ -27,6 +27,7 @@ enum ActionType {
|
||||
GenEmitter,
|
||||
GenRegisterInfo,
|
||||
GenInstrInfo,
|
||||
+ MappingInsn,
|
||||
GenInstrDocs,
|
||||
GenAsmWriter,
|
||||
GenAsmMatcher,
|
||||
@@ -65,6 +66,8 @@ namespace {
|
||||
"Generate registers and register classes info"),
|
||||
clEnumValN(GenInstrInfo, "gen-instr-info",
|
||||
"Generate instruction descriptions"),
|
||||
+ clEnumValN(MappingInsn, "mapping-insn",
|
||||
+ ""),
|
||||
clEnumValN(GenInstrDocs, "gen-instr-docs",
|
||||
"Generate instruction documentation"),
|
||||
clEnumValN(GenCallingConv, "gen-callingconv",
|
||||
@@ -135,6 +138,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
||||
case GenInstrInfo:
|
||||
EmitInstrInfo(Records, OS);
|
||||
break;
|
||||
+ case MappingInsn:
|
||||
+ EmitMappingInsn(Records, OS);
|
||||
+ break;
|
||||
case GenInstrDocs:
|
||||
EmitInstrDocs(Records, OS);
|
||||
break;
|
||||
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
|
||||
index 1329a6d833f..a41e46b1db0 100644
|
||||
--- a/utils/TableGen/TableGenBackends.h
|
||||
+++ b/utils/TableGen/TableGenBackends.h
|
||||
@@ -75,6 +75,7 @@ void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitFastISel(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS);
|
||||
+void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS);
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,110 +0,0 @@
|
||||
From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001
|
||||
From: mephi42 <mephi42@gmail.com>
|
||||
Date: Fri, 17 Aug 2018 11:07:39 +0200
|
||||
Subject: [PATCH 7/7] capstone: generate *GenInsnNameMaps.inc
|
||||
|
||||
---
|
||||
lib/Target/SystemZ/CMakeLists.txt | 1 +
|
||||
utils/TableGen/InstrInfoEmitter.cpp | 29 +++++++++++++++++++++++++++++
|
||||
utils/TableGen/TableGen.cpp | 6 ++++++
|
||||
utils/TableGen/TableGenBackends.h | 1 +
|
||||
4 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/lib/Target/SystemZ/CMakeLists.txt b/lib/Target/SystemZ/CMakeLists.txt
|
||||
index 4b5d9c4a3b2..2c64e0a94b8 100644
|
||||
--- a/lib/Target/SystemZ/CMakeLists.txt
|
||||
+++ b/lib/Target/SystemZ/CMakeLists.txt
|
||||
@@ -7,6 +7,7 @@ tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler)
|
||||
tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM SystemZMappingInsn.inc -mapping-insn)
|
||||
+tablegen(LLVM SystemZGenInsnNameMaps.inc -gen-insn-name-maps)
|
||||
tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM SystemZGenSubtargetInfo.inc -gen-subtarget)
|
||||
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
index 14ab1ea8a72..ccf8170ca62 100644
|
||||
--- a/utils/TableGen/InstrInfoEmitter.cpp
|
||||
+++ b/utils/TableGen/InstrInfoEmitter.cpp
|
||||
@@ -837,6 +837,35 @@ void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) {
|
||||
<< "},\n";
|
||||
}
|
||||
}
|
||||
+
|
||||
+std::string GetMnemonic(const CodeGenInstruction *Inst) {
|
||||
+ std::string Mnemonic = Inst->AsmString;
|
||||
+
|
||||
+ for (size_t i = 0; i < Mnemonic.length(); i++) {
|
||||
+ if (Mnemonic[i] == '\t') {
|
||||
+ return Mnemonic.substr(0, i);
|
||||
+ }
|
||||
+ }
|
||||
+ return Mnemonic;
|
||||
+}
|
||||
+
|
||||
+void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS) {
|
||||
+ OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n"
|
||||
+ "// By Nguyen Anh Quynh <aquynh@gmail.com>\n"
|
||||
+ "\n";
|
||||
+ CodeGenTarget Target(RK);
|
||||
+ std::map<std::string, std::string> M;
|
||||
+ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
||||
+ if (Inst->TheDef->getValueAsBit("isPseudo") ||
|
||||
+ Inst->TheDef->getValueAsBit("isCodeGenOnly")) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ M[GetPublicName(Inst)] = GetMnemonic(Inst);
|
||||
+ }
|
||||
+ for (auto &P : M) {
|
||||
+ OS << "\t{ " << P.first << ", \"" << P.second << "\" },\n";
|
||||
+ }
|
||||
+}
|
||||
#endif
|
||||
|
||||
} // end llvm namespace
|
||||
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
|
||||
index bbb4e860536..27c6603de5a 100644
|
||||
--- a/utils/TableGen/TableGen.cpp
|
||||
+++ b/utils/TableGen/TableGen.cpp
|
||||
@@ -28,6 +28,7 @@ enum ActionType {
|
||||
GenRegisterInfo,
|
||||
GenInstrInfo,
|
||||
MappingInsn,
|
||||
+ GenInsnNameMaps,
|
||||
GenInstrDocs,
|
||||
GenAsmWriter,
|
||||
GenAsmMatcher,
|
||||
@@ -68,6 +69,8 @@ namespace {
|
||||
"Generate instruction descriptions"),
|
||||
clEnumValN(MappingInsn, "mapping-insn",
|
||||
""),
|
||||
+ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps",
|
||||
+ ""),
|
||||
clEnumValN(GenInstrDocs, "gen-instr-docs",
|
||||
"Generate instruction documentation"),
|
||||
clEnumValN(GenCallingConv, "gen-callingconv",
|
||||
@@ -141,6 +144,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
||||
case MappingInsn:
|
||||
EmitMappingInsn(Records, OS);
|
||||
break;
|
||||
+ case GenInsnNameMaps:
|
||||
+ EmitInsnNameMaps(Records, OS);
|
||||
+ break;
|
||||
case GenInstrDocs:
|
||||
EmitInstrDocs(Records, OS);
|
||||
break;
|
||||
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
|
||||
index a41e46b1db0..5656e5be849 100644
|
||||
--- a/utils/TableGen/TableGenBackends.h
|
||||
+++ b/utils/TableGen/TableGenBackends.h
|
||||
@@ -76,6 +76,7 @@ void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitFastISel(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS);
|
||||
+void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS);
|
||||
--
|
||||
2.19.1
|
||||
|
@ -1,58 +0,0 @@
|
||||
# How to update SystemZ tables.
|
||||
|
||||
* Checkout LLVM. Patches are tested on commit `c13d5969^`, because
|
||||
`c13d5969` changed the decode table format.
|
||||
* Apply patches from the current directory.
|
||||
* Run tablegen.
|
||||
```
|
||||
cd $LLVM
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_CXX_FLAGS=-DCAPSTONE ..
|
||||
make SystemZCommonTableGen -j$(getconf _NPROCESSORS_ONLN)
|
||||
```
|
||||
* Copy `.inc` files.
|
||||
```
|
||||
cp arch/SystemZ/SystemZGenInsnNameMaps.inc \
|
||||
arch/SystemZ/SystemZGenInsnNameMaps.inc.old
|
||||
for inc in $(cd arch/SystemZ && ls *.inc); do
|
||||
cp $LLVM/build/lib/Target/SystemZ/$inc arch/SystemZ/
|
||||
done
|
||||
```
|
||||
* Fixup `SystemZGenInsnNameMaps.inc`.
|
||||
```
|
||||
comm -1 -3 \
|
||||
<(grep SYSZ_INS_ <arch/SystemZ/SystemZGenInsnNameMaps.inc.old \
|
||||
| sort -u) \
|
||||
<(grep SYSZ_INS_ <arch/SystemZ/SystemZGenInsnNameMaps.inc \
|
||||
| sort -u) \
|
||||
>arch/SystemZ/SystemZGenInsnNameMaps.inc.new
|
||||
cat arch/SystemZ/SystemZGenInsnNameMaps.inc.old \
|
||||
arch/SystemZ/SystemZGenInsnNameMaps.inc.new \
|
||||
>arch/SystemZ/SystemZGenInsnNameMaps.inc
|
||||
```
|
||||
* Add new groups, insns, registers and formats.
|
||||
* `include/capstone/systemz.h`
|
||||
* `enum sysz_insn`:
|
||||
```
|
||||
comm -1 -3 \
|
||||
<(perl -ne 'if (/(SYSZ_INS_.+),/) { print "\t$1,\n" }' \
|
||||
<include/capstone/systemz.h | sort -u) \
|
||||
<(perl -ne 'if (/(SYSZ_INS_.+),/) { print "\t$1,\n" }' \
|
||||
<arch/SystemZ/SystemZMappingInsn.inc | sort -u)
|
||||
```
|
||||
* `enum sysz_insn_group`:
|
||||
```
|
||||
perl -ne 'if (/(SYSZ_GRP_.*?),/) { print "\t$1,\n"; }' < \
|
||||
arch/SystemZ/SystemZMappingInsn.inc | sort -u
|
||||
```
|
||||
* `arch/SystemZ/SystemZDisassembler.c`
|
||||
* `arch/SystemZ/SystemZInstPrinter.c`
|
||||
* `arch/SystemZ/SystemZMCTargetDesc.c`
|
||||
* `arch/SystemZ/SystemZMCTargetDesc.h`
|
||||
* `arch/SystemZ/SystemZMapping.c`
|
||||
* `enum group_name_maps`:
|
||||
```
|
||||
perl -ne 'if (/(SYSZ_GRP_(.*?)),/) { print "\t{ $1, \"" . lc($2) . "\" },\n"; }' \
|
||||
arch/SystemZ/SystemZMappingInsn.inc | sort -u
|
||||
```
|
60
cs.c
60
cs.c
@ -147,11 +147,27 @@ typedef struct cs_arch_config {
|
||||
Sparc_option, \
|
||||
~(CS_MODE_BIG_ENDIAN | CS_MODE_V9), \
|
||||
}
|
||||
#define CS_ARCH_CONFIG_SYSZ \
|
||||
#define CS_ARCH_CONFIG_SYSTEMZ \
|
||||
{ \
|
||||
SystemZ_global_init, \
|
||||
SystemZ_option, \
|
||||
~(CS_MODE_BIG_ENDIAN), \
|
||||
~(CS_MODE_BIG_ENDIAN | \
|
||||
CS_MODE_SYSTEMZ_ARCH8 | \
|
||||
CS_MODE_SYSTEMZ_ARCH9 | \
|
||||
CS_MODE_SYSTEMZ_ARCH10 | \
|
||||
CS_MODE_SYSTEMZ_ARCH11 | \
|
||||
CS_MODE_SYSTEMZ_ARCH12 | \
|
||||
CS_MODE_SYSTEMZ_ARCH13 | \
|
||||
CS_MODE_SYSTEMZ_ARCH14 | \
|
||||
CS_MODE_SYSTEMZ_Z10 | \
|
||||
CS_MODE_SYSTEMZ_Z196 | \
|
||||
CS_MODE_SYSTEMZ_ZEC12 | \
|
||||
CS_MODE_SYSTEMZ_Z13 | \
|
||||
CS_MODE_SYSTEMZ_Z14 | \
|
||||
CS_MODE_SYSTEMZ_Z15 | \
|
||||
CS_MODE_SYSTEMZ_Z16 | \
|
||||
CS_MODE_SYSTEMZ_GENERIC \
|
||||
), \
|
||||
}
|
||||
#define CS_ARCH_CONFIG_XCORE \
|
||||
{ \
|
||||
@ -257,6 +273,11 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
|
||||
#else
|
||||
{ NULL, NULL, 0 },
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_SYSTEMZ
|
||||
CS_ARCH_CONFIG_SYSTEMZ,
|
||||
#else
|
||||
{ NULL, NULL, 0 },
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_MIPS
|
||||
CS_ARCH_CONFIG_MIPS,
|
||||
#else
|
||||
@ -277,11 +298,6 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
|
||||
#else
|
||||
{ NULL, NULL, 0 },
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
CS_ARCH_CONFIG_SYSZ,
|
||||
#else
|
||||
{ NULL, NULL, 0 },
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_XCORE
|
||||
CS_ARCH_CONFIG_XCORE,
|
||||
#else
|
||||
@ -379,8 +395,8 @@ static const uint32_t all_arch = 0
|
||||
#ifdef CAPSTONE_HAS_SPARC
|
||||
| (1 << CS_ARCH_SPARC)
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_SYSZ
|
||||
| (1 << CS_ARCH_SYSZ)
|
||||
#ifdef CAPSTONE_HAS_SYSTEMZ
|
||||
| (1 << CS_ARCH_SYSTEMZ)
|
||||
#endif
|
||||
#ifdef CAPSTONE_HAS_XCORE
|
||||
| (1 << CS_ARCH_XCORE)
|
||||
@ -540,10 +556,10 @@ void CAPSTONE_API cs_arch_register_sparc(void)
|
||||
}
|
||||
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_arch_register_sysz(void)
|
||||
void CAPSTONE_API cs_arch_register_systemz(void)
|
||||
{
|
||||
#if defined(CAPSTONE_USE_ARCH_REGISTRATION) && defined(CAPSTONE_HAS_SYSZ)
|
||||
CS_ARCH_REGISTER(SYSZ);
|
||||
#if defined(CAPSTONE_USE_ARCH_REGISTRATION) && defined(CAPSTONE_HAS_SYSTEMZ)
|
||||
CS_ARCH_REGISTER(SYSTEMZ);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -659,7 +675,7 @@ bool CAPSTONE_API cs_support(int query)
|
||||
((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) |
|
||||
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
|
||||
(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
|
||||
(1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
|
||||
(1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_XCORE) |
|
||||
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
|
||||
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
|
||||
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
|
||||
@ -962,7 +978,7 @@ static uint8_t skipdata_size(cs_struct *handle)
|
||||
case CS_ARCH_SPARC:
|
||||
// skip 4 bytes
|
||||
return 4;
|
||||
case CS_ARCH_SYSZ:
|
||||
case CS_ARCH_SYSTEMZ:
|
||||
// SystemZ instruction's length can be 2, 4 or 6 bytes,
|
||||
// so we just skip 2 bytes
|
||||
return 2;
|
||||
@ -1229,7 +1245,7 @@ size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64
|
||||
insn_cache = total;
|
||||
|
||||
while (size > 0) {
|
||||
MCInst_Init(&mci);
|
||||
MCInst_Init(&mci, handle->arch);
|
||||
mci.csh = handle;
|
||||
|
||||
// relative branches need to know the address & size of current insn
|
||||
@ -1442,7 +1458,7 @@ bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
|
||||
|
||||
handle->errnum = CS_ERR_OK;
|
||||
|
||||
MCInst_Init(&mci);
|
||||
MCInst_Init(&mci, handle->arch);
|
||||
mci.csh = handle;
|
||||
|
||||
// relative branches need to know the address & size of current insn
|
||||
@ -1700,9 +1716,9 @@ int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
|
||||
if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
|
||||
count++;
|
||||
break;
|
||||
case CS_ARCH_SYSZ:
|
||||
for (i = 0; i < insn->detail->sysz.op_count; i++)
|
||||
if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
|
||||
case CS_ARCH_SYSTEMZ:
|
||||
for (i = 0; i < insn->detail->systemz.op_count; i++)
|
||||
if (insn->detail->systemz.operands[i].type == (systemz_op_type)op_type)
|
||||
count++;
|
||||
break;
|
||||
case CS_ARCH_XCORE:
|
||||
@ -1852,9 +1868,9 @@ int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
case CS_ARCH_SYSZ:
|
||||
for (i = 0; i < insn->detail->sysz.op_count; i++) {
|
||||
if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
|
||||
case CS_ARCH_SYSTEMZ:
|
||||
for (i = 0; i < insn->detail->systemz.op_count; i++) {
|
||||
if (insn->detail->systemz.operands[i].type == (systemz_op_type)op_type)
|
||||
count++;
|
||||
if (count == post)
|
||||
return i;
|
||||
|
@ -146,8 +146,16 @@ static struct {
|
||||
{ "sparc", "Sparc, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN },
|
||||
{ "sparcv9", "Sparc v9, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 },
|
||||
|
||||
{ "systemz", "SystemZ, big endian", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
|
||||
{ "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch8", "(arch8/z10/generic)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch9", "(arch9/z196)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch10", "(arch10/zec12)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch11", "(arch11/z13)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch12", "(arch12/z14)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch13", "(arch13/z15)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN },
|
||||
{ "systemz_arch14", "(arch14/z16)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN },
|
||||
|
||||
{ "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
|
||||
|
||||
{ "xcore", "xcore, big endian", CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN },
|
||||
|
||||
@ -283,7 +291,7 @@ static const char *get_arch_name(cs_arch arch)
|
||||
case CS_ARCH_X86: return "x86";
|
||||
case CS_ARCH_PPC: return "PowerPC";
|
||||
case CS_ARCH_SPARC: return "Sparc";
|
||||
case CS_ARCH_SYSZ: return "SysZ";
|
||||
case CS_ARCH_SYSTEMZ: return "SystemZ";
|
||||
case CS_ARCH_XCORE: return "Xcore";
|
||||
case CS_ARCH_M68K: return "M68K";
|
||||
case CS_ARCH_TMS320C64X: return "TMS320C64X";
|
||||
@ -370,8 +378,8 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
|
||||
case CS_ARCH_SPARC:
|
||||
print_insn_detail_sparc(handle, ins);
|
||||
break;
|
||||
case CS_ARCH_SYSZ:
|
||||
print_insn_detail_sysz(handle, ins);
|
||||
case CS_ARCH_SYSTEMZ:
|
||||
print_insn_detail_systemz(handle, ins);
|
||||
break;
|
||||
case CS_ARCH_XCORE:
|
||||
print_insn_detail_xcore(handle, ins);
|
||||
@ -581,8 +589,8 @@ int main(int argc, char **argv)
|
||||
printf("sparc=1 ");
|
||||
}
|
||||
|
||||
if (cs_support(CS_ARCH_SYSZ)) {
|
||||
printf("sysz=1 ");
|
||||
if (cs_support(CS_ARCH_SYSTEMZ)) {
|
||||
printf("systemz=1 ");
|
||||
}
|
||||
|
||||
if (cs_support(CS_ARCH_XCORE)) {
|
||||
@ -767,7 +775,7 @@ int main(int argc, char **argv)
|
||||
for (; j < 16; j++) {
|
||||
printf(" ");
|
||||
}
|
||||
} else if (arch == CS_ARCH_SYSZ) {
|
||||
} else if (arch == CS_ARCH_SYSTEMZ) {
|
||||
for (; j < 6; j++) {
|
||||
printf(" ");
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ void print_insn_detail_aarch64(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_mips(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_ppc(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_sparc(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_sysz(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_systemz(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_xcore(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_m68k(csh handle, cs_insn *ins);
|
||||
void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);
|
||||
|
@ -6,50 +6,84 @@
|
||||
#include <capstone/capstone.h>
|
||||
#include "cstool.h"
|
||||
|
||||
void print_insn_detail_sysz(csh handle, cs_insn *ins)
|
||||
void print_insn_detail_systemz(csh handle, cs_insn *ins)
|
||||
{
|
||||
cs_sysz *sysz;
|
||||
cs_systemz *systemz;
|
||||
int i;
|
||||
|
||||
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
|
||||
if (ins->detail == NULL)
|
||||
return;
|
||||
|
||||
sysz = &(ins->detail->sysz);
|
||||
if (sysz->op_count)
|
||||
printf("\top_count: %u\n", sysz->op_count);
|
||||
systemz = &(ins->detail->systemz);
|
||||
if (systemz->op_count)
|
||||
printf("\top_count: %u\n", systemz->op_count);
|
||||
|
||||
for (i = 0; i < sysz->op_count; i++) {
|
||||
cs_sysz_op *op = &(sysz->operands[i]);
|
||||
for (i = 0; i < systemz->op_count; i++) {
|
||||
cs_systemz_op *op = &(systemz->operands[i]);
|
||||
switch((int)op->type) {
|
||||
default:
|
||||
break;
|
||||
case SYSZ_OP_REG:
|
||||
case SYSTEMZ_OP_REG:
|
||||
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
|
||||
break;
|
||||
case SYSZ_OP_ACREG:
|
||||
printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg);
|
||||
break;
|
||||
case SYSZ_OP_IMM:
|
||||
case SYSTEMZ_OP_IMM:
|
||||
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
|
||||
break;
|
||||
case SYSZ_OP_MEM:
|
||||
case SYSTEMZ_OP_MEM:
|
||||
printf("\t\toperands[%u].type: MEM\n", i);
|
||||
if (op->mem.base != SYSZ_REG_INVALID)
|
||||
if (op->mem.base != SYSTEMZ_REG_INVALID)
|
||||
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
|
||||
i, cs_reg_name(handle, op->mem.base));
|
||||
if (op->mem.index != SYSZ_REG_INVALID)
|
||||
if (op->mem.index != SYSTEMZ_REG_INVALID)
|
||||
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
|
||||
i, cs_reg_name(handle, op->mem.index));
|
||||
if (op->mem.length != 0)
|
||||
printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
|
||||
if (op->mem.disp != 0)
|
||||
printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
|
||||
|
||||
if (op->mem.length != 0) {
|
||||
if (op->mem.am == SYSTEMZ_AM_BDL) {
|
||||
printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
|
||||
} else {
|
||||
printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
|
||||
}
|
||||
}
|
||||
printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
|
||||
switch(op->mem.am) {
|
||||
default:
|
||||
printf("\t\t\toperands[%u].mem.am: UNHANDLED\n", i);
|
||||
break;
|
||||
case SYSTEMZ_AM_BD:
|
||||
printf("\t\t\toperands[%u].mem.am: SYSTEMZ_AM_BD\n", i);
|
||||
break;
|
||||
case SYSTEMZ_AM_BDX:
|
||||
printf("\t\t\toperands[%u].mem.am: SYSTEMZ_AM_BDX\n", i);
|
||||
break;
|
||||
case SYSTEMZ_AM_BDL:
|
||||
printf("\t\t\toperands[%u].mem.am: SYSTEMZ_AM_BDL\n", i);
|
||||
break;
|
||||
case SYSTEMZ_AM_BDR:
|
||||
printf("\t\t\toperands[%u].mem.am: SYSTEMZ_AM_BDR\n", i);
|
||||
break;
|
||||
case SYSTEMZ_AM_BDV:
|
||||
printf("\t\t\toperands[%u].mem.am: SYSTEMZ_AM_BDV\n", i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch(op->access) {
|
||||
default:
|
||||
break;
|
||||
case CS_AC_READ:
|
||||
printf("\t\toperands[%u].access: READ\n", i);
|
||||
break;
|
||||
case CS_AC_WRITE:
|
||||
printf("\t\toperands[%u].access: WRITE\n", i);
|
||||
break;
|
||||
case CS_AC_READ | CS_AC_WRITE:
|
||||
printf("\t\toperands[%u].access: READ | WRITE\n", i);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (sysz->cc != 0)
|
||||
printf("\tCode condition: %u\n", sysz->cc);
|
||||
if (systemz->cc != SYSTEMZ_CC_INVALID)
|
||||
printf("\tCode condition: %u\n", systemz->cc);
|
||||
}
|
||||
|
@ -34,6 +34,62 @@ The `auto-sync` updater, the additional updates of ARM, AArch64 and PPC, as well
|
||||
|
||||
With all that said, we hope you enjoy the new release!
|
||||
|
||||
## New features
|
||||
|
||||
**LoongArch**
|
||||
|
||||
- Architecture support was added (based on LLVM-18).
|
||||
|
||||
**HPPA**
|
||||
|
||||
- Architecture support was added.
|
||||
|
||||
**Alpha**
|
||||
|
||||
- Architecture support was added (based on LLVM-3)
|
||||
- System operands are provided with way more detail in separated operand.
|
||||
|
||||
**AArch64**
|
||||
|
||||
- Updated to LLVM-18
|
||||
- Adding new instructions of SME, SVE2 extensions. With it the `sme` and `pred` operands are added.
|
||||
- System operands are provided with way more detail in separated operand.
|
||||
|
||||
**PPC**
|
||||
|
||||
- Updated to LLVM-16
|
||||
- The instruction encoding formats are added for PPC. They are accessible via `cs_ppc->format`.
|
||||
They do follow loosely the ISA formats of instructions but not quite. Unfortunately,
|
||||
LLV doesn't group the instruction formats perfectly aligned with the ISA.
|
||||
Nonetheless, we hope this additional information is useful to you.
|
||||
- Branching information in `cs_ppc->bc` is way more detailed now.
|
||||
- The Paired Single extension was added.
|
||||
|
||||
**SystemZ**
|
||||
|
||||
- Updated to LLVM-18
|
||||
- Operands have now read/write access information
|
||||
- Memory operands have now the address mode specified
|
||||
- Immediate oprands have a new `imm_width` field. storing the bit width if known.
|
||||
- CPU features can be enabled or disabled by SystemZ architecture (arch8-arch14).
|
||||
|
||||
**Mips**
|
||||
|
||||
- Updated to LLVM-18
|
||||
- Support added for: `microMips32r3`, `microMips32r6`, `Mips16`, `Mips I ISA`, `Mips II ISA`, `Mips32 r2 ISA`, `Mips32 r3 ISA`, `Mips32 r5 ISA`, `Mips32 r6 ISA`, `Mips III ISA`, `Mips IV ISA`, `Mips V ISA`, `Mips64 r2 ISA`, `Mips64 r3 ISA`, `Mips64 r5 ISA`, `Mips64 r6 ISA`, `Octeon (cnMIPS)`, `Octeon+ (cnMIPS+)`, `NanoMips`
|
||||
- Support for different register naming style (`CS_OPT_SYNTAX_NO_DOLLAR`, `CS_OPT_SYNTAX_NOREGNAME`)
|
||||
|
||||
**RISCV**
|
||||
|
||||
- Operands have now read/write access information
|
||||
|
||||
**Code quality**
|
||||
|
||||
- ASAN: All tests are now run with the address sanitizer enabled. This includes checking for leaks.
|
||||
- Coverity code scanning workflow added.
|
||||
- Testing was re-written from scratch. Now allowing fine-grained testing of all details and is more convenient to use by contributors.
|
||||
|
||||
|
||||
## Breaking changes
|
||||
|
||||
**All `auto-sync` architectures**
|
||||
@ -49,6 +105,7 @@ With all that said, we hope you enjoy the new release!
|
||||
| Post-index | Post-index memory access has the disponent now set in the `MEMORY` operand! No longer as separated `reg`/`imm` operand. | The CS memory operand had a field which was there for disponents. Not having it set, for post-index operands was inconsistent. | Edit `ARM_set_detail_op_mem()` and add an immediate operand instead of setting the disponent. |
|
||||
| Sign `mem.disp` | `mem.disp` is now always positive and the `subtracted` flag indicates if it should be subtracted. | It was inconsistent before. | Change behavior in `ARM_set_detail_op_mem()` |
|
||||
| `ARM_CC` | `ARM_CC` → `ARMCC` and value change | They match the same LLVM enum. Better for LLVM compatibility and code generation. | Change it manually. |
|
||||
| `ARMCC_*` | `ARMCC_EQ == 0` but `ARMCC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. | Change by hand. |
|
||||
| System registers | System registers are no longer saved in `cs_arm->reg`, but are separated and have more detail. | System operands follow their own encoding logic. Hence, they should be separated in the details as well. | None |
|
||||
| System operands | System operands have now the encoding of LLVM (SYSm value mostly) | See note about system registers. | None |
|
||||
| Instruction enum | Multiple instructions which were only alias were removed from the instruction enum. | Alias are always disassembled as their real instructions and an additional field identifies which alias it is. | None |
|
||||
@ -68,7 +125,6 @@ With all that said, we hope you enjoy the new release!
|
||||
| `crx` | `ppc_ops_crx` was removed. | It was never used in the first place. | None. |
|
||||
| `(RA\|0)` | The `(RA\|0)` cases (see ISA for details) for which `0` is used, the `PPC_REG_ZERO` register is used. The register name of it is `0`. | Mimics LLVM behavior. | None. |
|
||||
|
||||
|
||||
**AArch64**
|
||||
|
||||
| Keyword | Change | Justification | Possible revert |
|
||||
@ -79,26 +135,44 @@ With all that said, we hope you enjoy the new release!
|
||||
| `writeback` | `writeback` member was moved to detail. | See ARM explanation. | See ARM. |
|
||||
| `arm64_vas` | `arm64_vas` renamed to `AArch64Layout_VectorLayout` | LLVM compatibility. | None. |
|
||||
| Register alias | Register alias (`x29 = fp` etc.) are not printed if LLVM doesn't do it. Old Capstone register alias can be enabled by `CS_OPT_SYNTAX_CS_REG_ALIAS`. | Mimic LLVM as close as possible. | Enable option. |
|
||||
| `AArch64CC_*` | `AArch64CC_EQ == 0` but `AArch64CC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. | Change by hand. |
|
||||
|
||||
**Note about AArch64**
|
||||
**Mips**
|
||||
|
||||
`ARM64` was everywhere renamed to `AArch64`. This is a necessity to ensure that the update scripts stay reasonably simple.
|
||||
Capstone was very inconsistent with the naming before (sometimes `AArch64` sometimes `ARM64`).
|
||||
Because Capstone uses a huge amount of LLVM code, we renamed everything to `AArch64`. This reduces complexity enormously because it follows the naming of LLVM.
|
||||
| Keyword | Change | Justification | Possible revert |
|
||||
|---------|--------|---------------|-----------------|
|
||||
| `CS_OPT_SYNTAX_NO_DOLLAR` | Adds options which removes the `$` (dollar sign) from the register name. | New Feature | Enable option. |
|
||||
| `CS_OPT_SYNTAX_NOREGNAME` | Implements the options to output raw register numbers (only the standard GPR are numeric). | Was not implemented | Enable option. |
|
||||
| `cs_mips_op.uimm` | Access for the unsigned immediate value of the IMM operand. | Was missing | None. |
|
||||
| `cs_mips_op.is_unsigned` | Defines if the IMM operand is signed (when false) or unsigned (when true). | Was missing | None. |
|
||||
| `cs_mips_op.is_reglist` | Defines if the REG operand is part of a list of registers. | Was missing | None. |
|
||||
| `cs_mips_op.access` | Defines how is this operand accessed, i.e. READ, WRITE or READ & WRITE. | Was missing | None. |
|
||||
|
||||
Because this would completely break maintaining Capstone `v6` and `pre-v6` in a project, we added two solutions:
|
||||
**SystemZ**
|
||||
|
||||
| Keyword | Change | Justification | Possible revert |
|
||||
|---------|--------|---------------|-----------------|
|
||||
| `SYSTEMZ_CC_*` | `SYSTEMZ_CC_O = 0` and `SYSTEMZ_CC_INVALID != 0` | They match the same LLVM values. Better for LLVM compatibility and code generation. | Change by hand. |
|
||||
|
||||
**Note about AArch64 and SystemZ**
|
||||
|
||||
`ARM64` was everywhere renamed to `AArch64`. And `SYSZ` to `SYSTEMZ`. This is a necessity to ensure that the update scripts stay reasonably simple.
|
||||
Capstone was very inconsistent with the naming before (sometimes `AArch64` sometimes `ARM64`. Sometimes `SYSZ` sometimes `SYSTEMZ`).
|
||||
Because Capstone uses a huge amount of LLVM code, we renamed everything to `AArch64` and `SystemZ`. This reduces complexity enormously because it follows the naming of LLVM.
|
||||
|
||||
Because this would completely break maintaining Capstone `v6` and `pre-v6` in a project, we added compatibility headers:
|
||||
|
||||
1. Make `arm64.h` a compatibility header which merely maps every member to the one in the `aarch64.h` header.
|
||||
2. Macros for meta-programming which select the right name.
|
||||
2. The `systemz.h` header includes the `SYSZ` to `SYSZTEMZ` mapping if `CAPSTONE_SYSTEMZ_COMPAT_HEADER` is defined.
|
||||
|
||||
We will continue to maintain both solutions.
|
||||
So if you need to support the previous version of Capstone as well, you can use either of the solutions.
|
||||
We will continue to maintain both headers.
|
||||
|
||||
_Compatibility header_
|
||||
|
||||
If you want to use the compatibility header and stick with the `ARM64` naming, you can define `CAPSTONE_AARCH64_COMPAT_HEADER` before including `capstone.h`.
|
||||
If you want to use the compatibility header and stick with the `ARM64`/`SYSZ` naming, you can define `CAPSTONE_AARCH64_COMPAT_HEADER` and `CAPSTONE_SYSTEMZ_COMPAT_HEADER` before including `capstone.h`.
|
||||
|
||||
```c
|
||||
#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
#define CAPSTONE_AARCH64_COMPAT_HEADER
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
@ -108,6 +182,7 @@ If you want to use the compatibility header and stick with the `ARM64` naming, y
|
||||
_Meta programming macros_
|
||||
|
||||
The following `sed` commands in a sh script should ease the replacement of `ARM64` with the macros a lot.
|
||||
These macros are also part of the latest `v4` and `v5` release.
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
@ -137,6 +212,8 @@ echo "Replace detail->arm64"
|
||||
sed -i -E "s/detail->arm64/detail->CS_aarch64()/g" $1
|
||||
```
|
||||
|
||||
_Example renaming with `sed`_
|
||||
|
||||
Simple renaming from `ARM64` to `AArch64`:
|
||||
|
||||
```sh
|
||||
@ -165,20 +242,35 @@ echo "Replace detail->arm64"
|
||||
sed -i "s|detail->arm64|detail->aarch64|g" $1
|
||||
```
|
||||
|
||||
Simple renaming from `SYSZ` to `SYSTEMZ`:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
echo "Replace enum names"
|
||||
|
||||
sed -i "s|CS_ARCH_SYSZ|CS_ARCH_SYSTEMZ|g" $1
|
||||
sed -i "s|SYSZ_INS_|SYSTEMZ_INS_|g" $1
|
||||
sed -i "s|SYSZ_REG_|SYSTEMZ_REG_|g" $1
|
||||
sed -i "s|SYSZ_OP_|SYSTEMZ_OP_|g" $1
|
||||
sed -i "s|SYSZ_CC_|SYSTEMZ_CC_|g" $1
|
||||
|
||||
echo "Replace type identifiers"
|
||||
|
||||
sed -i "s|sysz_reg|systemz_reg|g" $1
|
||||
sed -i "s|sysz_cc |systemz_cc |g" $1
|
||||
sed -i "s|cs_sysz|cs_systemz|g" $1
|
||||
sed -i "s|sysz_op_type|systemz_op_type|g" $1
|
||||
sed -i "s|sysz_op_type|systemz_op_type|g" $1
|
||||
sed -i "s|sysz_op_mem|systemz_op_mem|g" $1
|
||||
sed -i "s|sysz_op|systemz_op|g" $1
|
||||
|
||||
echo "Replace detail->sysz"
|
||||
|
||||
sed -i "s|detail->sysz|detail->systemz|g" $1
|
||||
```
|
||||
|
||||
Write it into `rename_arm64.sh` and run it on files with `sh rename_arm64.sh <src-file>`
|
||||
|
||||
|
||||
**Mips**
|
||||
|
||||
| Keyword | Change | Justification | Possible revert |
|
||||
|---------|--------|---------------|-----------------|
|
||||
| `CS_OPT_SYNTAX_NO_DOLLAR` | Adds options which removes the `$` (dollar sign) from the register name. | New Feature | Enable option. |
|
||||
| `CS_OPT_SYNTAX_NOREGNAME` | Implements the options to output raw register numbers (only the standard GPR are numeric). | Was not implemented | Enable option. |
|
||||
| `cs_mips_op.uimm` | Access for the unsigned immediate value of the IMM operand. | Was missing | None. |
|
||||
| `cs_mips_op.is_unsigned` | Defines if the IMM operand is signed (when false) or unsigned (when true). | Was missing | None. |
|
||||
| `cs_mips_op.is_reglist` | Defines if the REG operand is part of a list of registers. | Was missing | None. |
|
||||
| `cs_mips_op.access` | Defines how is this operand accessed, i.e. READ, WRITE or READ & WRITE. | Was missing | None. |
|
||||
|
||||
**Note about AArch64**
|
||||
|
||||
in `capstone.h` new mips ISA has been added which can be used by themselves.
|
||||
@ -340,4 +432,4 @@ $ cstool -s arm 0c100097000000008fa2000034213456
|
||||
4 00 00 00 00 andeq r0, r0, r0
|
||||
8 8f a2 00 00 andeq r10, r0, pc, lsl #5
|
||||
10 34 21 34 56 shasxpl r2, r4, r4
|
||||
```
|
||||
```
|
||||
|
@ -139,12 +139,16 @@ typedef enum cs_arch {
|
||||
CS_ARCH_ARM64 = 1, ///< ARM64
|
||||
#else
|
||||
CS_ARCH_AARCH64 = 1, ///< AArch64
|
||||
#endif
|
||||
#ifdef CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
CS_ARCH_SYSZ = 2, ///< SystemZ architecture
|
||||
#else
|
||||
CS_ARCH_SYSTEMZ = 2, ///< SystemZ architecture
|
||||
#endif
|
||||
CS_ARCH_MIPS, ///< Mips architecture
|
||||
CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64)
|
||||
CS_ARCH_PPC, ///< PowerPC architecture
|
||||
CS_ARCH_SPARC, ///< Sparc architecture
|
||||
CS_ARCH_SYSZ, ///< SystemZ architecture
|
||||
CS_ARCH_XCORE, ///< XCore architecture
|
||||
CS_ARCH_M68K, ///< 68K architecture
|
||||
CS_ARCH_TMS320C64X, ///< TMS320C64x architecture
|
||||
@ -263,6 +267,21 @@ typedef enum cs_mode {
|
||||
CS_MODE_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3), ///< HPPA 2.0 wide
|
||||
CS_MODE_LOONGARCH32 = 1 << 0, ///< LoongArch32
|
||||
CS_MODE_LOONGARCH64 = 1 << 1, ///< LoongArch64
|
||||
CS_MODE_SYSTEMZ_ARCH8 = 1 << 1, ///< Enables features of the ARCH8 processor
|
||||
CS_MODE_SYSTEMZ_ARCH9 = 1 << 2, ///< Enables features of the ARCH9 processor
|
||||
CS_MODE_SYSTEMZ_ARCH10 = 1 << 3, ///< Enables features of the ARCH10 processor
|
||||
CS_MODE_SYSTEMZ_ARCH11 = 1 << 4, ///< Enables features of the ARCH11 processor
|
||||
CS_MODE_SYSTEMZ_ARCH12 = 1 << 5, ///< Enables features of the ARCH12 processor
|
||||
CS_MODE_SYSTEMZ_ARCH13 = 1 << 6, ///< Enables features of the ARCH13 processor
|
||||
CS_MODE_SYSTEMZ_ARCH14 = 1 << 7, ///< Enables features of the ARCH14 processor
|
||||
CS_MODE_SYSTEMZ_Z10 = 1 << 8, ///< Enables features of the Z10 processor
|
||||
CS_MODE_SYSTEMZ_Z196 = 1 << 9, ///< Enables features of the Z196 processor
|
||||
CS_MODE_SYSTEMZ_ZEC12 = 1 << 10, ///< Enables features of the ZEC12 processor
|
||||
CS_MODE_SYSTEMZ_Z13 = 1 << 11, ///< Enables features of the Z13 processor
|
||||
CS_MODE_SYSTEMZ_Z14 = 1 << 12, ///< Enables features of the Z14 processor
|
||||
CS_MODE_SYSTEMZ_Z15 = 1 << 13, ///< Enables features of the Z15 processor
|
||||
CS_MODE_SYSTEMZ_Z16 = 1 << 14, ///< Enables features of the Z16 processor
|
||||
CS_MODE_SYSTEMZ_GENERIC = 1 << 15, ///< Enables features of the generic processor
|
||||
} cs_mode;
|
||||
|
||||
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
|
||||
@ -451,12 +470,17 @@ typedef struct cs_detail {
|
||||
#else
|
||||
cs_aarch64 aarch64; ///< AArch6464 architecture (aka ARM64)
|
||||
#endif
|
||||
|
||||
#ifdef CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
cs_sysz sysz; ///< SystemZ architecture
|
||||
#else
|
||||
cs_systemz systemz; ///< SystemZ architecture (aka SysZ)
|
||||
#endif
|
||||
cs_arm arm; ///< ARM architecture (including Thumb/Thumb2)
|
||||
cs_m68k m68k; ///< M68K architecture
|
||||
cs_mips mips; ///< MIPS architecture
|
||||
cs_ppc ppc; ///< PowerPC architecture
|
||||
cs_sparc sparc; ///< Sparc architecture
|
||||
cs_sysz sysz; ///< SystemZ architecture
|
||||
cs_xcore xcore; ///< XCore architecture
|
||||
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
|
||||
cs_m680x m680x; ///< M680X architecture
|
||||
@ -591,7 +615,10 @@ void CAPSTONE_API cs_arch_register_powerpc(void);
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_arch_register_sparc(void);
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_arch_register_sysz(void);
|
||||
void CAPSTONE_API cs_arch_register_systemz(void);
|
||||
#ifdef CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
#define cs_arch_register_sysz cs_arch_register_systemz
|
||||
#endif
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_arch_register_xcore(void);
|
||||
CAPSTONE_EXPORT
|
||||
|
File diff suppressed because it is too large
Load Diff
2966
include/capstone/systemz_compatibility.h
Normal file
2966
include/capstone/systemz_compatibility.h
Normal file
File diff suppressed because it is too large
Load Diff
2
suite/auto-sync/.gitignore
vendored
2
suite/auto-sync/.gitignore
vendored
@ -9,4 +9,4 @@ src/autosync/Tests/MCUpdaterTests/Disassembler/ARCH/Output
|
||||
src/autosync/lit_config/test_dir_*
|
||||
src/autosync/lit_config/.lit_test_times.txt
|
||||
src/autosync/Tests/MCUpdaterTests/test_output
|
||||
src/autosync/Tests/MCUpdaterTests/ARCH/Output
|
||||
src/autosync/Tests/MCUpdaterTests/**/Output
|
||||
|
@ -1,16 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
set(AUTO_SYNC_C_TEST_SRC_DIR ${AUTO_SYNC_C_TEST_DIR}/src)
|
||||
set(AUTO_SYNC_C_TEST_INC_DIR ${AUTO_SYNC_C_TEST_DIR}/include)
|
||||
|
||||
include_directories(${AUTO_SYNC_C_TEST_INC_DIR} ${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
file(GLOB AUTO_SYNC_C_SRC ${AUTO_SYNC_C_TEST_SRC_DIR}/*.c)
|
||||
add_executable(compat_header_build_test ${AUTO_SYNC_C_SRC})
|
||||
add_dependencies(compat_header_build_test capstone)
|
||||
target_link_libraries(compat_header_build_test PUBLIC capstone)
|
||||
|
||||
add_test(NAME ASCompatibilityHeaderTest
|
||||
COMMAND compat_header_build_test
|
||||
WORKING_DIRECTORY ${AUTO_SYNC_C_TEST_DIR}
|
||||
)
|
@ -22,3 +22,6 @@ requires-python = ">= 3.11"
|
||||
[tool.setuptools]
|
||||
packages = ["autosync", "autosync.cpptranslator", "autosync.cpptranslator.patches"]
|
||||
package-dir = {"" = "src"}
|
||||
|
||||
[project.scripts]
|
||||
ASUpdater = "autosync.ASUpdater:main"
|
||||
|
@ -10,17 +10,19 @@ import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
from enum import StrEnum
|
||||
from pathlib import Path
|
||||
|
||||
from autosync.cpptranslator.Configurator import Configurator
|
||||
from autosync.cpptranslator.CppTranslator import Translator
|
||||
from autosync.HeaderPatcher import CompatHeaderBuilder, HeaderPatcher
|
||||
from autosync.Helper import check_py_version, convert_loglevel, fail_exit, get_path
|
||||
from autosync.Helper import convert_loglevel, fail_exit, get_path
|
||||
|
||||
from autosync.IncGenerator import IncGenerator
|
||||
|
||||
from autosync.MCUpdater import MCUpdater
|
||||
from autosync.Targets import ARCH_LLVM_NAMING
|
||||
|
||||
|
||||
class USteps(StrEnum):
|
||||
@ -44,7 +46,7 @@ class ASUpdater:
|
||||
steps: list[USteps],
|
||||
inc_list: list,
|
||||
no_clean: bool,
|
||||
refactor: bool,
|
||||
copy_translated: bool,
|
||||
differ_no_auto_apply: bool,
|
||||
wait_for_user: bool = True,
|
||||
) -> None:
|
||||
@ -63,7 +65,7 @@ class ASUpdater:
|
||||
]
|
||||
else:
|
||||
self.steps = steps
|
||||
self.refactor = refactor
|
||||
self.copy_translated = copy_translated
|
||||
self.differ_no_auto_apply = differ_no_auto_apply
|
||||
self.arch_dir = get_path("{CS_ARCH_MODULE_DIR}").joinpath(self.arch)
|
||||
if not self.no_clean_build:
|
||||
@ -72,12 +74,16 @@ class ASUpdater:
|
||||
self.arch,
|
||||
self.inc_list,
|
||||
)
|
||||
with open(get_path("{MCUPDATER_CONFIG_FILE}")) as f:
|
||||
self.mcupdater_conf = json.loads(f.read())
|
||||
|
||||
self.mc_updater = MCUpdater(
|
||||
self.arch,
|
||||
get_path("{LLVM_MC_TEST_DIR}"),
|
||||
None,
|
||||
None,
|
||||
True if self.arch == "ARM" else False,
|
||||
self.arch in self.mcupdater_conf["unify_test_cases"],
|
||||
multi_mode=True,
|
||||
)
|
||||
|
||||
def clean_build_dir(self) -> None:
|
||||
@ -108,10 +114,10 @@ class ASUpdater:
|
||||
if self.arch == "AArch64":
|
||||
# Update the compatibility header
|
||||
builder = CompatHeaderBuilder(
|
||||
aarch64_h=main_header,
|
||||
arm64_h=get_path("{CS_INCLUDE_DIR}").joinpath(f"arm64.h"),
|
||||
v6=main_header,
|
||||
v5=get_path("{CS_INCLUDE_DIR}").joinpath(f"arm64.h"),
|
||||
)
|
||||
builder.generate_aarch64_compat_header()
|
||||
builder.generate_v5_compat_header()
|
||||
return patched
|
||||
|
||||
def copy_files(self, path: Path, dest: Path) -> None:
|
||||
@ -173,36 +179,44 @@ class ASUpdater:
|
||||
self.diff()
|
||||
if USteps.MC in self.steps:
|
||||
self.mc_updater.gen_all()
|
||||
if self.write:
|
||||
# Copy .inc files
|
||||
log.info(f"Copy .inc files to {self.arch_dir}")
|
||||
i = 0
|
||||
arch_header = get_path("{CS_INCLUDE_DIR}").joinpath(
|
||||
f"{self.arch.lower()}.h"
|
||||
)
|
||||
for file in get_path("{C_INC_OUT_DIR}").iterdir():
|
||||
if HeaderPatcher.file_in_main_header(arch_header, file.name):
|
||||
continue
|
||||
if not self.write:
|
||||
# Done
|
||||
exit(0)
|
||||
|
||||
# Copy .inc files
|
||||
log.info(f"Copy .inc files to {self.arch_dir}")
|
||||
i = 0
|
||||
arch_header = get_path("{CS_INCLUDE_DIR}").joinpath(f"{self.arch.lower()}.h")
|
||||
for file in get_path("{C_INC_OUT_DIR}").iterdir():
|
||||
if HeaderPatcher.file_in_main_header(arch_header, file.name):
|
||||
continue
|
||||
self.copy_files(file, self.arch_dir)
|
||||
i += 1
|
||||
log.info(f"Copied {i} files")
|
||||
|
||||
i = 0
|
||||
if self.copy_translated:
|
||||
# Diffed files
|
||||
log.info(f"Copy translated files to {self.arch_dir}")
|
||||
for file in get_path("{CPP_TRANSLATOR_TRANSLATION_OUT_DIR}").iterdir():
|
||||
self.copy_files(file, self.arch_dir)
|
||||
i += 1
|
||||
log.info(f"Copied {i} files")
|
||||
|
||||
i = 0
|
||||
else:
|
||||
# Diffed files
|
||||
log.info(f"Copy diffed files to {self.arch_dir}")
|
||||
for file in get_path("{CPP_TRANSLATOR_DIFF_OUT_DIR}").iterdir():
|
||||
self.copy_files(file, self.arch_dir)
|
||||
i += 1
|
||||
log.info(f"Copied {i} files")
|
||||
log.info(f"Copied {i} files")
|
||||
|
||||
# MC tests
|
||||
i = 0
|
||||
mc_dir = get_path("{MC_DIR}").joinpath(self.arch)
|
||||
log.info(f"Copy MC test files to {mc_dir}")
|
||||
for file in get_path("{MCUPDATER_OUT_DIR}").iterdir():
|
||||
self.copy_files(file, mc_dir)
|
||||
i += 1
|
||||
log.info(f"Copied {i} files")
|
||||
# MC tests
|
||||
i = 0
|
||||
mc_dir = get_path("{MC_DIR}").joinpath(self.arch)
|
||||
log.info(f"Copy MC test files to {mc_dir}")
|
||||
for file in get_path("{MCUPDATER_OUT_DIR}").iterdir():
|
||||
self.copy_files(file, mc_dir)
|
||||
i += 1
|
||||
log.info(f"Copied {i} files")
|
||||
|
||||
exit(0)
|
||||
|
||||
@ -216,7 +230,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"-a",
|
||||
dest="arch",
|
||||
help="Name of target architecture.",
|
||||
choices=["ARM", "PPC", "AArch64", "Alpha", "LoongArch", "Mips"],
|
||||
choices=ARCH_LLVM_NAMING,
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -278,9 +292,9 @@ def parse_args() -> argparse.Namespace:
|
||||
default=["All"],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--refactor",
|
||||
dest="refactor",
|
||||
help="Sets change update behavior to ease refactoring and new implementations.",
|
||||
"--copy-translated",
|
||||
dest="copy_translated",
|
||||
help="Copy the translated files and not the files produced by the Differ.",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -293,9 +307,7 @@ def parse_args() -> argparse.Namespace:
|
||||
return arguments
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
check_py_version()
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
log.basicConfig(
|
||||
level=convert_loglevel(args.verbosity),
|
||||
@ -310,8 +322,12 @@ if __name__ == "__main__":
|
||||
args.steps,
|
||||
args.inc_list,
|
||||
args.no_clean,
|
||||
args.refactor,
|
||||
args.copy_translated,
|
||||
args.no_auto_apply,
|
||||
args.wait_for_user,
|
||||
)
|
||||
Updater.update()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -18,10 +18,10 @@ def parse_args() -> argparse.Namespace:
|
||||
parser.add_argument("--header", dest="header", help="Path header file.", type=Path)
|
||||
parser.add_argument("--inc", dest="inc", help="Path inc file.", type=Path)
|
||||
parser.add_argument(
|
||||
"--aarch64", dest="aarch64", help="aarch64.h header file location", type=Path
|
||||
"--v6", dest="v6", help="aarch64.h/systemz.h header file location", type=Path
|
||||
)
|
||||
parser.add_argument(
|
||||
"--arm64", dest="arm64", help="arm64.h header file location", type=Path
|
||||
"--v5", dest="v5", help="arm64.h/systemz_v5.h header file location", type=Path
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", dest="compat", help="Generate compatibility header", action="store_true"
|
||||
@ -120,78 +120,98 @@ class HeaderPatcher:
|
||||
|
||||
|
||||
class CompatHeaderBuilder:
|
||||
def __init__(self, v6: Path, v5: Path, arch: str):
|
||||
self.v6 = v6
|
||||
self.v5 = v5
|
||||
match arch:
|
||||
case "aarch64":
|
||||
self.v6_lower = "aarch64"
|
||||
self.v6_upper = "AARCH64"
|
||||
self.v6_camel = "AArch64"
|
||||
self.v5_lower = "arm64"
|
||||
self.v5_upper = "ARM64"
|
||||
case "systemz":
|
||||
self.v6_lower = "systemz"
|
||||
self.v6_upper = "SYSTEMZ"
|
||||
self.v6_camel = "SystemZ"
|
||||
self.v5_lower = "sysz"
|
||||
self.v5_upper = "SYSZ"
|
||||
case _:
|
||||
raise ValueError(f"{arch} not handled")
|
||||
|
||||
def __init__(self, aarch64_h: Path, arm64_h: Path):
|
||||
self.aarch64_h = aarch64_h
|
||||
self.arm64_h = arm64_h
|
||||
|
||||
def replace_typedef_struct(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def replace_typedef_struct(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
typedef = ""
|
||||
for line in aarch64_lines:
|
||||
for line in v6_lines:
|
||||
if typedef:
|
||||
if not re.search(r"^}\s[\w_]+;", line):
|
||||
# Skip struct content
|
||||
continue
|
||||
type_name = re.findall(r"[\w_]+", line)[0]
|
||||
output.append(
|
||||
f"typedef {type_name} {re.sub('aarch64','arm64', type_name)};\n"
|
||||
f"typedef {type_name} {re.sub(self.v6_lower,self.v5_lower, type_name)};\n"
|
||||
)
|
||||
typedef = ""
|
||||
continue
|
||||
|
||||
if re.search(f"^typedef\s+(struct|union)", line):
|
||||
if re.search(rf"^typedef\s+(struct|union)", line):
|
||||
typedef = line
|
||||
continue
|
||||
output.append(line)
|
||||
return output
|
||||
|
||||
def replace_typedef_enum(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def replace_typedef_enum(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
typedef = ""
|
||||
for line in aarch64_lines:
|
||||
for line in v6_lines:
|
||||
if typedef:
|
||||
if not re.search(r"^}\s[\w_]+;", line):
|
||||
# Replace name
|
||||
if "AArch64" not in line and "AARCH64" not in line:
|
||||
if self.v6_camel not in line and self.v6_upper not in line:
|
||||
output.append(line)
|
||||
continue
|
||||
found = re.findall(r"(AArch64|AARCH64)([\w_]+)", line)
|
||||
found = re.findall(
|
||||
rf"({self.v6_camel}|{self.v6_upper})([\w_]+)", line
|
||||
)
|
||||
entry_name: str = "".join(found[0])
|
||||
arm64_name = entry_name.replace("AArch64", "ARM64").replace(
|
||||
"AARCH64", "ARM64"
|
||||
v5_name = entry_name.replace(self.v6_camel, self.v6_camel).replace(
|
||||
self.v6_upper, self.v5_upper
|
||||
)
|
||||
patched_line = re.sub(
|
||||
r"(AArch64|AARCH64).+", f"{arm64_name} = {entry_name},", line
|
||||
rf"({self.v6_camel}|{self.v6_upper}).+",
|
||||
f"{v5_name} = {entry_name},",
|
||||
line,
|
||||
)
|
||||
output.append(patched_line)
|
||||
continue
|
||||
# We still have LLVM and CS naming conventions mixed
|
||||
p = re.sub(r"aarch64", "arm64", line)
|
||||
p = re.sub(r"(AArch64|AARCH64)", "ARM64", p)
|
||||
p = re.sub(self.v6_lower, self.v5_lower, line)
|
||||
p = re.sub(rf"({self.v6_camel}|{self.v6_upper})", self.v5_upper, p)
|
||||
output.append(p)
|
||||
typedef = ""
|
||||
continue
|
||||
|
||||
if re.search(f"^typedef\s+enum", line):
|
||||
if re.search(rf"^typedef\s+enum", line):
|
||||
typedef = line
|
||||
output.append("typedef enum {\n")
|
||||
continue
|
||||
output.append(line)
|
||||
return output
|
||||
|
||||
def remove_comments(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def remove_comments(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
for line in aarch64_lines:
|
||||
for line in v6_lines:
|
||||
if re.search(r"^\s*//", line) and "// SPDX" not in line:
|
||||
continue
|
||||
output.append(line)
|
||||
return output
|
||||
|
||||
def replace_aarch64(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def replace_v6_prefix(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
in_typedef = False
|
||||
for line in aarch64_lines:
|
||||
for line in v6_lines:
|
||||
if "CAPSTONE_SYSTEMZ_COMPAT_HEADER" in line:
|
||||
output.append(line)
|
||||
if in_typedef:
|
||||
if re.search(r"^}\s[\w_]+;", line):
|
||||
in_typedef = False
|
||||
@ -202,46 +222,61 @@ class CompatHeaderBuilder:
|
||||
in_typedef = True
|
||||
output.append(line)
|
||||
continue
|
||||
output.append(re.sub(r"(AArch64|AARCH64)", "ARM64", line))
|
||||
output.append(
|
||||
re.sub(rf"({self.v6_camel}|{self.v6_upper})", self.v5_upper, line)
|
||||
)
|
||||
return output
|
||||
|
||||
def replace_include_guards(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def replace_include_guards(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
for line in aarch64_lines:
|
||||
skip = False
|
||||
for line in v6_lines:
|
||||
if "CAPSTONE_SYSTEMZ_COMPAT_HEADER" in line:
|
||||
# The compat heade is inlcuded in the v6 header.
|
||||
# Because v5 and v6 header share the same name.
|
||||
skip = True
|
||||
continue
|
||||
elif skip and "#endif" in line:
|
||||
skip = False
|
||||
continue
|
||||
elif skip:
|
||||
continue
|
||||
|
||||
if not re.search(r"^#(ifndef|define)", line):
|
||||
output.append(line)
|
||||
continue
|
||||
output.append(re.sub(r"AARCH64", "ARM64", line))
|
||||
output.append(re.sub(self.v6_upper, self.v5_upper, line))
|
||||
return output
|
||||
|
||||
def inject_aarch64_header(self, aarch64_lines: list[str]) -> list[str]:
|
||||
def inject_v6_header(self, v6_lines: list[str]) -> list[str]:
|
||||
output = list()
|
||||
header_inserted = False
|
||||
for line in aarch64_lines:
|
||||
for line in v6_lines:
|
||||
if re.search(r"^#include", line):
|
||||
if not header_inserted:
|
||||
output.append("#include <capstone/aarch64.h>\n")
|
||||
output.append(f"#include <capstone/{self.v6_lower}.h>\n")
|
||||
header_inserted = True
|
||||
output.append(line)
|
||||
return output
|
||||
|
||||
def generate_aarch64_compat_header(self) -> bool:
|
||||
def generate_v5_compat_header(self) -> bool:
|
||||
"""
|
||||
Translates the aarch64.h header into the arm64.h header and renames all aarch64 occurrences.
|
||||
It does simple regex matching and replacing.
|
||||
Same for systemz.h and SYSTEMZ -> SYSZ. But the output file is systemz_compatibility.h.
|
||||
"""
|
||||
log.info("Generate compatibility header")
|
||||
with open(self.aarch64_h) as f:
|
||||
aarch64 = f.readlines()
|
||||
with open(self.v6) as f:
|
||||
v6_lines = f.readlines()
|
||||
|
||||
patched = self.replace_typedef_struct(aarch64)
|
||||
patched = self.replace_typedef_struct(v6_lines)
|
||||
patched = self.replace_typedef_enum(patched)
|
||||
patched = self.remove_comments(patched)
|
||||
patched = self.replace_aarch64(patched)
|
||||
patched = self.replace_v6_prefix(patched)
|
||||
patched = self.replace_include_guards(patched)
|
||||
patched = self.inject_aarch64_header(patched)
|
||||
patched = self.inject_v6_header(patched)
|
||||
|
||||
with open(self.arm64_h, "w+") as f:
|
||||
with open(self.v5, "w+") as f:
|
||||
f.writelines(patched)
|
||||
|
||||
|
||||
@ -250,10 +285,8 @@ if __name__ == "__main__":
|
||||
if (not args.patch and not args.compat) or (args.patch and args.compat):
|
||||
print("You need to specify either -c or -p")
|
||||
exit(1)
|
||||
if args.compat and not (args.aarch64 and args.arm64):
|
||||
print(
|
||||
"Generating the arm64 compatibility header requires --arm64 and --aarch64"
|
||||
)
|
||||
if args.compat and not (args.v6 and args.v5):
|
||||
print("Generating the v5 compatibility header requires --v5 and --v6")
|
||||
exit(1)
|
||||
if args.patch and not (args.inc and args.header):
|
||||
print("Patching headers requires --inc and --header")
|
||||
@ -264,5 +297,12 @@ if __name__ == "__main__":
|
||||
patcher.patch_header()
|
||||
exit(0)
|
||||
|
||||
builder = CompatHeaderBuilder(args.aarch64, args.arm64)
|
||||
builder.generate_aarch64_compat_header()
|
||||
if "aarch64" in args.v6.name:
|
||||
arch = "aarch64"
|
||||
elif "systemz" in args.v6.name:
|
||||
arch = "systemz"
|
||||
else:
|
||||
raise ValueError(f"Does not know the arch for header file: {args.v6.name}")
|
||||
|
||||
builder = CompatHeaderBuilder(args.v6, args.v5, arch)
|
||||
builder.generate_v5_compat_header()
|
||||
|
@ -168,9 +168,3 @@ def fail_exit(msg: str) -> None:
|
||||
"""Logs a fatal message and exits with error code 1."""
|
||||
log.fatal(msg)
|
||||
exit(1)
|
||||
|
||||
|
||||
def check_py_version() -> None:
|
||||
if not sys.hexversion >= 0x030B00F0:
|
||||
log.fatal("Python >= v3.11 required.")
|
||||
exit(1)
|
||||
|
@ -4,6 +4,7 @@
|
||||
# SPDX-License-Identifier: BSD-3
|
||||
|
||||
import logging as log
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@ -12,58 +13,6 @@ from pathlib import Path
|
||||
|
||||
from autosync.Helper import fail_exit, get_path
|
||||
|
||||
inc_tables = [
|
||||
{
|
||||
"name": "Disassembler",
|
||||
"tblgen_arg": "--gen-disassembler",
|
||||
"inc_name": "DisassemblerTables",
|
||||
"only_arch": [],
|
||||
"lang": ["CCS", "C++"],
|
||||
},
|
||||
{
|
||||
"name": "AsmWriter",
|
||||
"tblgen_arg": "--gen-asm-writer",
|
||||
"inc_name": "AsmWriter",
|
||||
"only_arch": [],
|
||||
"lang": ["CCS", "C++"],
|
||||
},
|
||||
{
|
||||
"name": "RegisterInfo",
|
||||
"tblgen_arg": "--gen-register-info",
|
||||
"inc_name": "RegisterInfo",
|
||||
"only_arch": [],
|
||||
"lang": ["CCS"],
|
||||
},
|
||||
{
|
||||
"name": "InstrInfo",
|
||||
"tblgen_arg": "--gen-instr-info",
|
||||
"inc_name": "InstrInfo",
|
||||
"only_arch": [],
|
||||
"lang": ["CCS"],
|
||||
},
|
||||
{
|
||||
"name": "SubtargetInfo",
|
||||
"tblgen_arg": "--gen-subtarget",
|
||||
"inc_name": "SubtargetInfo",
|
||||
"only_arch": [],
|
||||
"lang": ["CCS"],
|
||||
},
|
||||
{
|
||||
"name": "Mapping",
|
||||
"tblgen_arg": "--gen-asm-matcher",
|
||||
"inc_name": None,
|
||||
"only_arch": [],
|
||||
"lang": ["CCS"],
|
||||
},
|
||||
{
|
||||
"name": "SystemOperand",
|
||||
"tblgen_arg": "--gen-searchable-tables",
|
||||
"inc_name": None,
|
||||
"only_arch": ["AArch64", "ARM"],
|
||||
"lang": ["CCS"],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class IncGenerator:
|
||||
def __init__(self, arch: str, inc_list: list) -> None:
|
||||
@ -79,6 +28,8 @@ class IncGenerator:
|
||||
self.llvm_tblgen: Path = get_path("{LLVM_TBLGEN_BIN}")
|
||||
self.output_dir_c_inc = get_path("{C_INC_OUT_DIR}")
|
||||
self.output_dir_cpp_inc = get_path("{CPP_INC_OUT_DIR}")
|
||||
with open(get_path("{INC_GEN_CONF_FILE}")) as f:
|
||||
self.conf = json.loads(f.read())
|
||||
self.check_paths()
|
||||
|
||||
def check_paths(self) -> None:
|
||||
@ -133,7 +84,7 @@ class IncGenerator:
|
||||
shutil.move(sys_ops_table_file, new_sys_ops_file)
|
||||
|
||||
def gen_incs(self) -> None:
|
||||
for table in inc_tables:
|
||||
for table in self.conf["inc_tables"]:
|
||||
if "All" not in self.inc_list and table["name"] not in self.inc_list:
|
||||
log.debug(f"Skip {table['name']} generation")
|
||||
continue
|
||||
|
@ -20,13 +20,15 @@ class LLVM_MC_Command:
|
||||
self.cmd: str = ""
|
||||
self.opts: str = ""
|
||||
self.file: Path | None = None
|
||||
self.mattr: str = mattr
|
||||
self.additional_mattr: str = mattr
|
||||
|
||||
self.cmd, self.opts, self.file = self.parse_llvm_mc_line(cmd_line)
|
||||
if not (self.cmd and self.opts and self.file):
|
||||
log.warning(f"Could not parse llvm-mc command: {cmd_line}")
|
||||
elif not "--show-encoding" in self.cmd:
|
||||
self.cmd = re.sub("llvm-mc", "llvm-mc --show-encoding", self.cmd)
|
||||
elif not "--disassemble" in self.cmd:
|
||||
self.cmd = re.sub("llvm-mc", "llvm-mc --disassemble", self.cmd)
|
||||
|
||||
def parse_llvm_mc_line(self, line: str) -> tuple[str, str, Path]:
|
||||
test_file_base_dir = str(get_path("{LLVM_LIT_TEST_DIR}").absolute())
|
||||
@ -42,20 +44,26 @@ class LLVM_MC_Command:
|
||||
opts = ",".join([m.group(2) for m in arch]) if arch else ""
|
||||
if mattr:
|
||||
opts += "" if not opts else ","
|
||||
opts += ",".join([m.group(2).strip("+") for m in mattr])
|
||||
processed_attr = list()
|
||||
for m in mattr:
|
||||
attribute = m.group(2).strip("+")
|
||||
processed_attr.append(attribute)
|
||||
opts += ",".join(processed_attr)
|
||||
return cmd, opts, Path(test_file)
|
||||
|
||||
def exec(self) -> sp.CompletedProcess:
|
||||
with open(self.file, "b+r") as f:
|
||||
content = f.read()
|
||||
if self.mattr:
|
||||
if self.additional_mattr:
|
||||
# If mattr exists, patch it into the cmd
|
||||
if "mattr" in self.cmd:
|
||||
self.cmd = re.sub(
|
||||
r"mattr[=\s]+", f"mattr={self.mattr} -mattr=", self.cmd
|
||||
r"mattr[=\s]+", f"mattr={self.additional_mattr} -mattr=", self.cmd
|
||||
)
|
||||
else:
|
||||
self.cmd = re.sub(r"llvm-mc", f"llvm-mc -mattr={self.mattr}", self.cmd)
|
||||
self.cmd = re.sub(
|
||||
r"llvm-mc", f"llvm-mc -mattr={self.additional_mattr}", self.cmd
|
||||
)
|
||||
|
||||
log.debug(f"Run: {self.cmd}")
|
||||
result = sp.run(self.cmd.split(" "), input=content, capture_output=True)
|
||||
@ -78,11 +86,7 @@ class MCTest:
|
||||
|
||||
def __init__(self, arch: str, opts: list[str], encoding: str, asm_text: str):
|
||||
self.arch = arch
|
||||
if arch.lower() in ["arm", "powerpc", "ppc", "aarch64"]:
|
||||
# Arch and PPC require this option for MC tests.
|
||||
self.opts = ["CS_OPT_NO_BRANCH_OFFSET"] + opts
|
||||
else:
|
||||
self.opts = opts
|
||||
self.opts = opts
|
||||
self.encoding: list[str] = [encoding]
|
||||
self.asm_text: list[str] = [asm_text]
|
||||
|
||||
@ -263,7 +267,7 @@ class MCUpdater:
|
||||
else ""
|
||||
)
|
||||
# A list of options which are always added.
|
||||
self.mandatory_options: str = (
|
||||
self.mandatory_options: list[str] = (
|
||||
self.conf["mandatory_options"][self.arch]
|
||||
if self.arch in self.conf["mandatory_options"]
|
||||
else list()
|
||||
@ -274,13 +278,15 @@ class MCUpdater:
|
||||
else list()
|
||||
)
|
||||
self.remove_options = [x.lower() for x in self.remove_options]
|
||||
self.replace_option_map: str = (
|
||||
self.replace_option_map: dict = (
|
||||
self.conf["replace_option_map"][self.arch]
|
||||
if self.arch in self.conf["replace_option_map"]
|
||||
else {}
|
||||
)
|
||||
self.replace_option_map = {
|
||||
k.lower(): v for k, v in self.replace_option_map.items()
|
||||
k.lower(): v
|
||||
for k, v in self.replace_option_map.items()
|
||||
if k.lower not in self.remove_options
|
||||
}
|
||||
self.multi_mode = multi_mode
|
||||
|
||||
@ -297,12 +303,14 @@ class MCUpdater:
|
||||
)
|
||||
|
||||
def write_to_build_dir(self):
|
||||
no_tests_file = 0
|
||||
file_cnt = 0
|
||||
test_cnt = 0
|
||||
overwritten = 0
|
||||
files_written = set()
|
||||
for test in sorted(self.test_files):
|
||||
if not test.has_tests():
|
||||
no_tests_file += 1
|
||||
continue
|
||||
file_cnt += 1
|
||||
test_cnt += test.num_test_cases()
|
||||
@ -332,7 +340,7 @@ class MCUpdater:
|
||||
f"The following file exists already: {filename}\n"
|
||||
"This is not allowed in multi-mode."
|
||||
)
|
||||
else:
|
||||
elif not self.multi_mode and filename.exists():
|
||||
log.debug(f"Overwrite: {filename}")
|
||||
overwritten += 1
|
||||
with open(filename, write_mode) as f:
|
||||
@ -340,7 +348,10 @@ class MCUpdater:
|
||||
log.debug(f"Write {filename}")
|
||||
files_written.add(filename)
|
||||
log.info(
|
||||
f"Processed {file_cnt} files with {test_cnt} test cases. Generated {len(files_written)} files"
|
||||
f"Got {len(self.test_files)} test files.\n"
|
||||
f"\t\tProcessed {file_cnt} files with {test_cnt} test cases.\n"
|
||||
f"\t\tIgnored {no_tests_file} without tests.\n"
|
||||
f"\t\tGenerated {len(files_written)} files"
|
||||
)
|
||||
if overwritten > 0:
|
||||
log.warning(
|
||||
@ -544,4 +555,5 @@ if __name__ == "__main__":
|
||||
args.excluded_files,
|
||||
args.included_files,
|
||||
args.unified_tests,
|
||||
True,
|
||||
).gen_all()
|
||||
|
@ -1,4 +1,27 @@
|
||||
# Copyright © 2024 Rot127 <unisono@quyllur.org>
|
||||
# SPDX-License-Identifier: BSD-3
|
||||
|
||||
TARGETS_LLVM_NAMING = ["ARM", "PowerPC", "Alpha", "AArch64", "LoongArch"]
|
||||
# Names of the target architectures as they are listed under llvm/lib/Target/
|
||||
TARGETS_LLVM_NAMING = [
|
||||
"ARM",
|
||||
"PowerPC",
|
||||
"Alpha",
|
||||
"AArch64",
|
||||
"LoongArch",
|
||||
"SystemZ",
|
||||
"Mips",
|
||||
]
|
||||
|
||||
# Names of the target architecture as they are used in code and pretty much everywhere else.
|
||||
ARCH_LLVM_NAMING = ["ARM", "PPC", "Alpha", "AArch64", "LoongArch", "SystemZ", "Mips"]
|
||||
|
||||
# Maps the target full name to the name used in code (and pretty much everywhere else).
|
||||
TARGET_TO_IN_CODE_NAME = {
|
||||
"ARM": "ARM",
|
||||
"PowerPC": "PPC",
|
||||
"Alpha": "Alpha",
|
||||
"AArch64": "AArch64",
|
||||
"LoongArch": "LoongArch",
|
||||
"SystemZ": "SystemZ",
|
||||
"Mips": "Mips",
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
# For z13 and above.
|
||||
# RUN: llvm-mc -triple s390x-linux-gnu -mcpu=z13 -show-encoding %s \
|
||||
# RUN: | FileCheck %s
|
||||
# RUN: llvm-mc -triple s390x-linux-gnu -mcpu=arch11 -show-encoding %s \
|
||||
# RUN: | FileCheck %s
|
||||
|
||||
#CHECK: cdpt %f0, 0(1), 0 # encoding: [0xed,0x00,0x00,0x00,0x00,0xae]
|
||||
#CHECK: cdpt %f15, 0(1), 0 # encoding: [0xed,0x00,0x00,0x00,0xf0,0xae]
|
||||
#CHECK: cdpt %f0, 0(1), 15 # encoding: [0xed,0x00,0x00,0x00,0x0f,0xae]
|
||||
#CHECK: cdpt %f0, 0(1,%r1), 0 # encoding: [0xed,0x00,0x10,0x00,0x00,0xae]
|
||||
|
||||
|
||||
cdpt %f0, 0(1), 0
|
||||
cdpt %f15, 0(1), 0
|
||||
cdpt %f0, 0(1), 15
|
||||
cdpt %f0, 0(1,%r1), 0
|
@ -0,0 +1,80 @@
|
||||
test_cases:
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0x00, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_Z13" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1), 0"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0xf0, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_Z13" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f15, 0(1), 0"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0x0f, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_Z13" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1), 15"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x10, 0x00, 0x00, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_Z13" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1,%r1), 0"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0x00, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_ARCH11" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1), 0"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0xf0, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_ARCH11" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f15, 0(1), 0"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x00, 0x00, 0x0f, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_ARCH11" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1), 15"
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0xed, 0x00, 0x10, 0x00, 0x00, 0xae ]
|
||||
arch: "CS_ARCH_SYSTEMZ"
|
||||
options: [ "CS_MODE_BIG_ENDIAN", "s390x-linux-gnu", "CS_MODE_SYSTEMZ_ARCH11" ]
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "cdpt %f0, 0(1,%r1), 0"
|
@ -15,10 +15,6 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
get_path("{HEADER_PATCHER_TEST_INC_FILE}"),
|
||||
write_file=False,
|
||||
)
|
||||
cls.compat_gen = CompatHeaderBuilder(
|
||||
get_path("{HEADER_GEN_TEST_AARCH64_FILE}"),
|
||||
get_path("{HEADER_GEN_TEST_ARM64_OUT_FILE}"),
|
||||
)
|
||||
|
||||
def test_header_patching(self):
|
||||
self.hpatcher.patch_header()
|
||||
@ -50,9 +46,26 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
),
|
||||
)
|
||||
|
||||
def test_compat_header_gen(self):
|
||||
self.compat_gen.generate_aarch64_compat_header()
|
||||
def test_compat_header_gen_arm64(self):
|
||||
self.compat_gen = CompatHeaderBuilder(
|
||||
get_path("{HEADER_GEN_TEST_AARCH64_FILE}"),
|
||||
get_path("{HEADER_GEN_TEST_ARM64_OUT_FILE}"),
|
||||
"aarch64",
|
||||
)
|
||||
self.compat_gen.generate_v5_compat_header()
|
||||
with open(get_path("{HEADER_GEN_TEST_ARM64_FILE}")) as f:
|
||||
correct = f.read()
|
||||
with open(get_path("{HEADER_GEN_TEST_ARM64_OUT_FILE}")) as f:
|
||||
self.assertEqual(f.read(), correct)
|
||||
|
||||
def test_compat_header_gen_arm64(self):
|
||||
self.compat_gen = CompatHeaderBuilder(
|
||||
get_path("{HEADER_GEN_TEST_SYSTEMZ_FILE}"),
|
||||
get_path("{HEADER_GEN_TEST_SYSZ_OUT_FILE}"),
|
||||
"systemz",
|
||||
)
|
||||
self.compat_gen.generate_v5_compat_header()
|
||||
with open(get_path("{HEADER_GEN_TEST_SYSZ_FILE}")) as f:
|
||||
correct = f.read()
|
||||
with open(get_path("{HEADER_GEN_TEST_SYSZ_OUT_FILE}")) as f:
|
||||
self.assertEqual(f.read(), correct)
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from threading import Lock
|
||||
from autosync.Helper import get_path, test_only_overwrite_path_var
|
||||
from autosync.MCUpdater import MCUpdater
|
||||
|
||||
@ -20,22 +22,34 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
format="%(levelname)-5s - %(message)s",
|
||||
force=True,
|
||||
)
|
||||
cls.mutex = Lock()
|
||||
|
||||
@staticmethod
|
||||
def del_path(file: Path):
|
||||
if not file.exists():
|
||||
return
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
if file.is_dir():
|
||||
shutil.rmtree(file)
|
||||
else:
|
||||
os.remove(file)
|
||||
|
||||
def test_test_case_gen(self):
|
||||
"""
|
||||
To enforce sequential execution of the tests, we execute them in here.
|
||||
And don't make them a separated test.
|
||||
"""
|
||||
self.assertTrue(self.unified_test_cases(), "Failed: unified_test_cases")
|
||||
self.assertTrue(self.separated_test_cases(), "Failed: separated_test_cases")
|
||||
self.assertTrue(
|
||||
self.multi_mode_unified_test_cases(),
|
||||
"Failed: multi_mode_unified_test_cases",
|
||||
)
|
||||
self.assertTrue(
|
||||
self.multi_mode_separated_test_cases(),
|
||||
"Failed: multi_mode_separated_test_cases",
|
||||
)
|
||||
with self.mutex:
|
||||
self.assertTrue(self.unified_test_cases(), "Failed: unified_test_cases")
|
||||
self.assertTrue(self.separated_test_cases(), "Failed: separated_test_cases")
|
||||
self.assertTrue(
|
||||
self.multi_mode_unified_test_cases(),
|
||||
"Failed: multi_mode_unified_test_cases",
|
||||
)
|
||||
self.assertTrue(
|
||||
self.multi_mode_separated_test_cases(),
|
||||
"Failed: multi_mode_separated_test_cases",
|
||||
)
|
||||
|
||||
def unified_test_cases(self):
|
||||
out_dir = Path(
|
||||
@ -44,8 +58,7 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
os.remove(file)
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
@ -63,8 +76,7 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
os.remove(file)
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
@ -82,8 +94,7 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
os.remove(file)
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
@ -108,8 +119,7 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
os.remove(file)
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
@ -128,28 +138,57 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_no_symbol_tests(self):
|
||||
out_dir = Path(get_path("{MCUPDATER_TEST_OUT_DIR}").joinpath("no_symbol"))
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
logging.debug(f"Delete old file: {file}")
|
||||
os.remove(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
)
|
||||
self.updater = MCUpdater(
|
||||
"ARCH",
|
||||
get_path("{MCUPDATER_TEST_DIR}"),
|
||||
[],
|
||||
[],
|
||||
False,
|
||||
)
|
||||
self.updater.gen_all()
|
||||
self.assertFalse(
|
||||
out_dir.joinpath("test_no_symbol.s.txt.yaml").exists(),
|
||||
"File should not exist",
|
||||
)
|
||||
with self.mutex:
|
||||
out_dir = Path(get_path("{MCUPDATER_TEST_OUT_DIR}").joinpath("no_symbol"))
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
)
|
||||
self.updater = MCUpdater(
|
||||
"ARCH",
|
||||
get_path("{MCUPDATER_TEST_DIR}"),
|
||||
[],
|
||||
[],
|
||||
False,
|
||||
)
|
||||
self.updater.gen_all()
|
||||
self.assertFalse(
|
||||
out_dir.joinpath("test_no_symbol.s.txt.yaml").exists(),
|
||||
"File should not exist",
|
||||
)
|
||||
|
||||
def test_systemz_mapping(self):
|
||||
with self.mutex:
|
||||
out_dir = Path(
|
||||
get_path("{MCUPDATER_TEST_OUT_DIR}").joinpath("mode_mapping/")
|
||||
)
|
||||
if not out_dir.exists():
|
||||
out_dir.mkdir(parents=True)
|
||||
for file in out_dir.iterdir():
|
||||
self.del_path(file)
|
||||
test_only_overwrite_path_var(
|
||||
"{MCUPDATER_OUT_DIR}",
|
||||
out_dir,
|
||||
)
|
||||
self.updater = MCUpdater(
|
||||
"SystemZ",
|
||||
get_path("{MCUPDATER_TEST_DIR}"),
|
||||
[],
|
||||
[],
|
||||
False,
|
||||
)
|
||||
self.updater.gen_all()
|
||||
self.assertTrue(
|
||||
self.compare_files(
|
||||
out_dir,
|
||||
["test_systemz_mapping.txt.yaml"],
|
||||
),
|
||||
"File mismatch",
|
||||
)
|
||||
|
||||
def compare_files(self, out_dir: Path, filenames: list[str]) -> bool:
|
||||
if not out_dir.is_dir():
|
||||
@ -159,11 +198,13 @@ class TestHeaderPatcher(unittest.TestCase):
|
||||
parent_name = out_dir.parent.name
|
||||
expected_dir = (
|
||||
get_path("{MCUPDATER_TEST_DIR_EXPECTED}")
|
||||
.joinpath(parent_name)
|
||||
.joinpath(out_dir.name)
|
||||
# Dirty for now. Sorry.
|
||||
.joinpath(parent_name if parent_name != "test_output" else "").joinpath(
|
||||
out_dir.name
|
||||
)
|
||||
)
|
||||
if not expected_dir.exists() or not expected_dir.is_dir():
|
||||
logging.error(f"{expected_dir} is not a directory.")
|
||||
logging.error(f"Expected: {expected_dir} is not a directory.")
|
||||
return False
|
||||
for file in filenames:
|
||||
efile = expected_dir.joinpath(file)
|
||||
|
142
suite/auto-sync/src/autosync/Tests/test_systemz_header.h
Normal file
142
suite/auto-sync/src/autosync/Tests/test_systemz_header.h
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
/// Enums corresponding to SystemZ condition codes
|
||||
typedef enum systemz_cc {
|
||||
SYSTEMZ_CC_O,
|
||||
SYSTEMZ_CC_H,
|
||||
|
||||
SYSTEMZ_CC_NH,
|
||||
SYSTEMZ_CC_NO,
|
||||
SYSTEMZ_CC_INVALID,
|
||||
} systemz_cc;
|
||||
|
||||
/// Group of SystemZ instructions
|
||||
typedef enum systemz_insn_group {
|
||||
SYSTEMZ_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SYSTEMZ_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
SYSTEMZ_GRP_CALL, ///< CS_GRP_CALL
|
||||
SYSTEMZ_GRP_RET, ///< CS_GRP_RET
|
||||
SYSTEMZ_GRP_INT, ///< CS_GRP_INT
|
||||
SYSTEMZ_GRP_IRET, ///< CS_GRP_IRET
|
||||
SYSTEMZ_GRP_PRIVILEGE, ///< CS_GRP_PRIVILEGE
|
||||
SYSTEMZ_GRP_BRANCH_RELATIVE, ///< CS_GRP_BRANCH_RELATIVE
|
||||
// generated content <SystemZGenCSFeatureEnum.inc> begin
|
||||
// clang-format off
|
||||
|
||||
SYSTEMZ_FEATURE_FEATURESOFTFLOAT = 128,
|
||||
SYSTEMZ_FEATURE_FEATUREBACKCHAIN,
|
||||
SYSTEMZ_FEATURE_FEATUREDISTINCTOPS,
|
||||
SYSTEMZ_FEATURE_FEATUREFASTSERIALIZATION,
|
||||
SYSTEMZ_FEATURE_FEATURERESETDATPROTECTION,
|
||||
SYSTEMZ_FEATURE_FEATUREPROCESSORACTIVITYINSTRUMENTATION,
|
||||
|
||||
// clang-format on
|
||||
// generated content <SystemZGenCSFeatureEnum.inc> end
|
||||
|
||||
SYSTEMZ_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} systemz_insn_group;
|
||||
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum systemz_op_type {
|
||||
SYSTEMZ_OP_INVALID = CS_OP_INVALID, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SYSTEMZ_OP_REG = CS_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SYSTEMZ_OP_IMM = CS_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SYSTEMZ_OP_MEM = CS_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} systemz_op_type;
|
||||
|
||||
/// SystemZ registers
|
||||
typedef enum systemz_reg {
|
||||
// generated content <SystemZGenCSRegEnum.inc> begin
|
||||
// clang-format off
|
||||
|
||||
SYSTEMZ_REG_INVALID = 0,
|
||||
SYSTEMZ_REG_CC = 1,
|
||||
SYSTEMZ_REG_FPC = 2,
|
||||
SYSTEMZ_REG_R12Q = 193,
|
||||
SYSTEMZ_REG_R14Q = 194,
|
||||
SYSTEMZ_REG_ENDING, // 195
|
||||
|
||||
// clang-format on
|
||||
// generated content <SystemZGenCSRegEnum.inc> end
|
||||
|
||||
// alias registers
|
||||
// None
|
||||
} systemz_reg;
|
||||
|
||||
typedef struct {
|
||||
systemz_insn_form form;
|
||||
} systemz_suppl_info;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SYSTEMZ_OP_MEM operand type above
|
||||
typedef struct systemz_op_mem {
|
||||
systemz_addr_mode am; ///< Address mode. Indicates which field below are set.
|
||||
uint8_t /* systemz_reg */ base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `systemz_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t /* systemz_reg */ index; ///< Index register, same conditions apply here
|
||||
uint64_t length; ///< Length component. Can be a register or immediate.
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} systemz_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_systemz_op {
|
||||
systemz_op_type type; ///< operand type
|
||||
union {
|
||||
systemz_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
systemz_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
cs_ac_type access; ///< R/W access of the operand.
|
||||
uint8_t imm_width; ///< Bit width of the immediate. 0 if not specified.
|
||||
} cs_systemz_op;
|
||||
|
||||
#define MAX_SYSTEMZ_OPS 6
|
||||
|
||||
// Instruction structure
|
||||
typedef struct cs_systemz {
|
||||
systemz_cc cc; ///< Code condition
|
||||
systemz_insn_form format; ///< The instruction format.
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_systemz_op operands[MAX_SYSTEMZ_OPS]; ///< operands for this instruction.
|
||||
} cs_systemz;
|
||||
|
||||
/// SystemZ instruction
|
||||
typedef enum systemz_insn {
|
||||
// generated content <SystemZGenCSInsnEnum.inc> begin
|
||||
// clang-format off
|
||||
|
||||
SYSTEMZ_INS_INVALID,
|
||||
SYSTEMZ_INS_A,
|
||||
SYSTEMZ_INS_ZAP,
|
||||
|
||||
// clang-format on
|
||||
// generated content <SystemZGenCSInsnEnum.inc> end
|
||||
|
||||
SYSTEMZ_INS_ENDING,
|
||||
|
||||
SYSTEMZ_INS_ALIAS_BEGIN,
|
||||
// generated content <SystemZGenCSAliasEnum.inc> begin
|
||||
// clang-format off
|
||||
|
||||
SYSTEMZ_INS_ALIAS_VISTRB, // Real instr.: SYSTEMZ_VISTRB
|
||||
SYSTEMZ_INS_ALIAS_VSTRCZFS, // Real instr.: SYSTEMZ_VSTRCZFS
|
||||
SYSTEMZ_INS_ALIAS_VSTRSH, // Real instr.: SYSTEMZ_VSTRSH
|
||||
SYSTEMZ_INS_ALIAS_VSTRSF, // Real instr.: SYSTEMZ_VSTRSF
|
||||
|
||||
// clang-format on
|
||||
// generated content <SystemZGenCSAliasEnum.inc> end
|
||||
|
||||
// Hard-coded alias come here
|
||||
|
||||
SYSTEMZ_INS_ALIAS_END,
|
||||
} systemz_insn;
|
||||
|
||||
#ifdef CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
#include "systemz_compatibility.h"
|
||||
#endif
|
83
suite/auto-sync/src/autosync/Tests/test_sysz_header.h
Normal file
83
suite/auto-sync/src/autosync/Tests/test_sysz_header.h
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
typedef enum {
|
||||
SYSZ_CC_O = SYSTEMZ_CC_O,
|
||||
SYSZ_CC_H = SYSTEMZ_CC_H,
|
||||
|
||||
SYSZ_CC_NH = SYSTEMZ_CC_NH,
|
||||
SYSZ_CC_NO = SYSTEMZ_CC_NO,
|
||||
SYSZ_CC_INVALID = SYSTEMZ_CC_INVALID,
|
||||
} sysz_cc;
|
||||
|
||||
typedef enum {
|
||||
SYSZ_GRP_INVALID = SYSTEMZ_GRP_INVALID,
|
||||
|
||||
SYSZ_GRP_JUMP = SYSTEMZ_GRP_JUMP,
|
||||
SYSZ_GRP_CALL = SYSTEMZ_GRP_CALL,
|
||||
SYSZ_GRP_RET = SYSTEMZ_GRP_RET,
|
||||
SYSZ_GRP_INT = SYSTEMZ_GRP_INT,
|
||||
SYSZ_GRP_IRET = SYSTEMZ_GRP_IRET,
|
||||
SYSZ_GRP_PRIVILEGE = SYSTEMZ_GRP_PRIVILEGE,
|
||||
SYSZ_GRP_BRANCH_RELATIVE = SYSTEMZ_GRP_BRANCH_RELATIVE,
|
||||
|
||||
SYSZ_FEATURE_FEATURESOFTFLOAT = SYSTEMZ_FEATURE_FEATURESOFTFLOAT,
|
||||
SYSZ_FEATURE_FEATUREBACKCHAIN = SYSTEMZ_FEATURE_FEATUREBACKCHAIN,
|
||||
SYSZ_FEATURE_FEATUREDISTINCTOPS = SYSTEMZ_FEATURE_FEATUREDISTINCTOPS,
|
||||
SYSZ_FEATURE_FEATUREFASTSERIALIZATION = SYSTEMZ_FEATURE_FEATUREFASTSERIALIZATION,
|
||||
SYSZ_FEATURE_FEATURERESETDATPROTECTION = SYSTEMZ_FEATURE_FEATURERESETDATPROTECTION,
|
||||
SYSZ_FEATURE_FEATUREPROCESSORACTIVITYINSTRUMENTATION = SYSTEMZ_FEATURE_FEATUREPROCESSORACTIVITYINSTRUMENTATION,
|
||||
|
||||
|
||||
SYSZ_GRP_ENDING = SYSTEMZ_GRP_ENDING,
|
||||
} sysz_insn_group;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SYSZ_OP_INVALID = SYSTEMZ_OP_INVALID,
|
||||
SYSZ_OP_REG = SYSTEMZ_OP_REG,
|
||||
SYSZ_OP_IMM = SYSTEMZ_OP_IMM,
|
||||
SYSZ_OP_MEM = SYSTEMZ_OP_MEM,
|
||||
} sysz_op_type;
|
||||
|
||||
typedef enum {
|
||||
|
||||
SYSZ_REG_INVALID = SYSTEMZ_REG_INVALID,
|
||||
SYSZ_REG_CC = SYSTEMZ_REG_CC,
|
||||
SYSZ_REG_FPC = SYSTEMZ_REG_FPC,
|
||||
SYSZ_REG_R12Q = SYSTEMZ_REG_R12Q,
|
||||
SYSZ_REG_R14Q = SYSTEMZ_REG_R14Q,
|
||||
SYSZ_REG_ENDING = SYSTEMZ_REG_ENDING,
|
||||
|
||||
|
||||
} sysz_reg;
|
||||
|
||||
typedef systemz_suppl_info sysz_suppl_info;
|
||||
|
||||
typedef systemz_op_mem sysz_op_mem;
|
||||
|
||||
typedef cs_systemz_op cs_sysz_op;
|
||||
|
||||
#define MAX_SYSZ_OPS 6
|
||||
|
||||
typedef cs_systemz cs_sysz;
|
||||
|
||||
typedef enum {
|
||||
|
||||
SYSZ_INS_INVALID = SYSTEMZ_INS_INVALID,
|
||||
SYSZ_INS_A = SYSTEMZ_INS_A,
|
||||
SYSZ_INS_ZAP = SYSTEMZ_INS_ZAP,
|
||||
|
||||
|
||||
SYSZ_INS_ENDING = SYSTEMZ_INS_ENDING,
|
||||
|
||||
SYSZ_INS_ALIAS_BEGIN = SYSTEMZ_INS_ALIAS_BEGIN,
|
||||
|
||||
SYSZ_INS_ALIAS_VISTRB = SYSTEMZ_INS_ALIAS_VISTRB,
|
||||
SYSZ_INS_ALIAS_VSTRCZFS = SYSTEMZ_INS_ALIAS_VSTRCZFS,
|
||||
SYSZ_INS_ALIAS_VSTRSH = SYSTEMZ_INS_ALIAS_VSTRSH,
|
||||
SYSZ_INS_ALIAS_VSTRSF = SYSTEMZ_INS_ALIAS_VSTRSF,
|
||||
|
||||
|
||||
|
||||
SYSZ_INS_ALIAS_END = SYSTEMZ_INS_ALIAS_END,
|
||||
} sysz_insn;
|
||||
|
@ -6,6 +6,7 @@
|
||||
import argparse
|
||||
import logging as log
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import termcolor
|
||||
@ -87,6 +88,7 @@ from autosync.Helper import (
|
||||
print_prominent_warning,
|
||||
run_clang_format,
|
||||
)
|
||||
from autosync.cpptranslator.patches.isUInt import IsUInt
|
||||
|
||||
|
||||
class Translator:
|
||||
@ -136,6 +138,7 @@ class Translator:
|
||||
CreateOperand0.__name__: 0, # ◁───┐ `CreateOperand0` removes most calls to MI.addOperand().
|
||||
AddOperand.__name__: 1, # ────────┘ The ones left are fixed with the `AddOperand` patch.
|
||||
CreateOperand1.__name__: 0,
|
||||
IsUInt.__name__: 0,
|
||||
GetOpcode.__name__: 0,
|
||||
SetOpcode.__name__: 0,
|
||||
GetOperand.__name__: 0,
|
||||
@ -248,6 +251,8 @@ class Translator:
|
||||
patch = CreateOperand0(p)
|
||||
case CreateOperand1.__name__:
|
||||
patch = CreateOperand1(p)
|
||||
case IsUInt.__name__:
|
||||
patch = IsUInt(p)
|
||||
case GetOpcode.__name__:
|
||||
patch = GetOpcode(p)
|
||||
case SetOpcode.__name__:
|
||||
@ -391,6 +396,17 @@ class Translator:
|
||||
file_constraints = apply_only_to[patch_name]
|
||||
if self.current_src_path_in.name in file_constraints["files"]:
|
||||
return True
|
||||
elif (
|
||||
re.search("InstPrinter.cpp", self.current_src_path_in.name)
|
||||
and patch_name == AddCSDetail.__name__
|
||||
):
|
||||
print_prominent_warning(
|
||||
(
|
||||
f"The AddCSDetail patch is not applied to {self.current_src_path_in.name}. "
|
||||
"Have you forgotten to add it to arch_config.json?"
|
||||
),
|
||||
False,
|
||||
)
|
||||
return False
|
||||
|
||||
def translate(self) -> None:
|
||||
|
@ -16,6 +16,7 @@ from shutil import copy2
|
||||
|
||||
from tree_sitter import Language, Node, Parser, Tree
|
||||
|
||||
from autosync.Targets import ARCH_LLVM_NAMING
|
||||
from autosync.cpptranslator.Configurator import Configurator
|
||||
from autosync.Helper import (
|
||||
bold,
|
||||
@ -925,7 +926,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"-a",
|
||||
dest="arch",
|
||||
help="Name of target architecture (ignored with -t option)",
|
||||
choices=["ARM", "PPC", "AArch64", "Alpha", "LoongArch", "Mips"],
|
||||
choices=ARCH_LLVM_NAMING,
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user