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

This commit is contained in:
Rot127 2024-09-14 08:57:54 +00:00 committed by GitHub
parent 6a7fef60ea
commit af1ed2fb3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
150 changed files with 180933 additions and 68802 deletions

View File

@ -92,25 +92,20 @@ jobs:
# Work-around ASAN bug https://github.com/google/sanitizers/issues/1716 # Work-around ASAN bug https://github.com/google/sanitizers/issues/1716
sudo sysctl vm.mmap_rnd_bits=28 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' if: startsWith(matrix.config.build-system, 'cmake') && matrix.config.diet-build == 'OFF'
run: | run: |
ctest --test-dir build --output-on-failure -R ASCompatibilityHeaderTest ctest --test-dir build --output-on-failure -R integration_*
- name: cstool - reaches disassembler engine - name: cstool - reaches disassembler engine
run: | run: |
sh suite/run_invalid_cstool.sh 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 - name: cstest MC
if: startsWith(matrix.config.build-system, 'cmake') if: startsWith(matrix.config.build-system, 'cmake')
run: | run: |

View File

@ -78,6 +78,7 @@ jobs:
./src/autosync/ASUpdater.py -d -a PPC -s IncGen ./src/autosync/ASUpdater.py -d -a PPC -s IncGen
./src/autosync/ASUpdater.py -d -a LoongArch -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 Mips -s IncGen
./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen
- name: CppTranslator - Patch tests - name: CppTranslator - Patch tests
run: | run: |
@ -94,10 +95,4 @@ jobs:
./src/autosync/ASUpdater.py --ci -d -a PPC -s Translate ./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 LoongArch -s Translate
./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate ./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate
./src/autosync/ASUpdater.py --ci -d -a SystemZ -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

View File

@ -89,7 +89,7 @@ if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
endif() 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) 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 # 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/x86.h
include/capstone/sparc.h include/capstone/sparc.h
include/capstone/systemz.h include/capstone/systemz.h
include/capstone/systemz_compatibility.h
include/capstone/xcore.h include/capstone/xcore.h
include/capstone/m68k.h include/capstone/m68k.h
include/capstone/tms320c64x.h include/capstone/tms320c64x.h
@ -412,27 +413,34 @@ if(CAPSTONE_SPARC_SUPPORT)
) )
endif() endif()
if(CAPSTONE_SYSZ_SUPPORT) if(CAPSTONE_SYSTEMZ_SUPPORT)
add_definitions(-DCAPSTONE_HAS_SYSZ) add_definitions(-DCAPSTONE_HAS_SYSTEMZ)
set(SOURCES_SYSZ set(SOURCES_SYSTEMZ
arch/SystemZ/SystemZDisassembler.c arch/SystemZ/SystemZDisassembler.c
arch/SystemZ/SystemZDisassemblerExtension.c
arch/SystemZ/SystemZInstPrinter.c arch/SystemZ/SystemZInstPrinter.c
arch/SystemZ/SystemZMapping.c arch/SystemZ/SystemZMapping.c
arch/SystemZ/SystemZModule.c arch/SystemZ/SystemZModule.c
arch/SystemZ/SystemZMCTargetDesc.c arch/SystemZ/SystemZMCTargetDesc.c
) )
set(HEADERS_SYSZ set(HEADERS_SYSTEMZ
arch/SystemZ/SystemZDisassembler.h 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/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/SystemZGenDisassemblerTables.inc
arch/SystemZ/SystemZGenInsnNameMaps.inc
arch/SystemZ/SystemZGenInstrInfo.inc arch/SystemZ/SystemZGenInstrInfo.inc
arch/SystemZ/SystemZGenRegisterInfo.inc arch/SystemZ/SystemZGenRegisterInfo.inc
arch/SystemZ/SystemZGenSubtargetInfo.inc arch/SystemZ/SystemZGenSubtargetInfo.inc
arch/SystemZ/SystemZInstPrinter.h
arch/SystemZ/SystemZMapping.h
arch/SystemZ/SystemZMappingInsn.inc
arch/SystemZ/SystemZMCTargetDesc.h
) )
endif() endif()
@ -688,7 +696,7 @@ set(ALL_SOURCES
${SOURCES_PPC} ${SOURCES_PPC}
${SOURCES_X86} ${SOURCES_X86}
${SOURCES_SPARC} ${SOURCES_SPARC}
${SOURCES_SYSZ} ${SOURCES_SYSTEMZ}
${SOURCES_XCORE} ${SOURCES_XCORE}
${SOURCES_M68K} ${SOURCES_M68K}
${SOURCES_TMS320C64X} ${SOURCES_TMS320C64X}
@ -714,7 +722,7 @@ set(ALL_HEADERS
${HEADERS_PPC} ${HEADERS_PPC}
${HEADERS_X86} ${HEADERS_X86}
${HEADERS_SPARC} ${HEADERS_SPARC}
${HEADERS_SYSZ} ${HEADERS_SYSTEMZ}
${HEADERS_XCORE} ${HEADERS_XCORE}
${HEADERS_M68K} ${HEADERS_M68K}
${HEADERS_TMS320C64X} ${HEADERS_TMS320C64X}
@ -765,7 +773,7 @@ source_group("Source\\AARCH64" FILES ${SOURCES_AARCH64})
source_group("Source\\Mips" FILES ${SOURCES_MIPS}) source_group("Source\\Mips" FILES ${SOURCES_MIPS})
source_group("Source\\PowerPC" FILES ${SOURCES_PPC}) source_group("Source\\PowerPC" FILES ${SOURCES_PPC})
source_group("Source\\Sparc" FILES ${SOURCES_SPARC}) 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\\X86" FILES ${SOURCES_X86})
source_group("Source\\XCore" FILES ${SOURCES_XCORE}) source_group("Source\\XCore" FILES ${SOURCES_XCORE})
source_group("Source\\M68K" FILES ${SOURCES_M68K}) 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\\Mips" FILES ${HEADERS_MIPS})
source_group("Include\\PowerPC" FILES ${HEADERS_PPC}) source_group("Include\\PowerPC" FILES ${HEADERS_PPC})
source_group("Include\\Sparc" FILES ${HEADERS_SPARC}) 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\\X86" FILES ${HEADERS_X86})
source_group("Include\\XCore" FILES ${HEADERS_XCORE}) source_group("Include\\XCore" FILES ${HEADERS_XCORE})
source_group("Include\\M68K" FILES ${HEADERS_M68K}) source_group("Include\\M68K" FILES ${HEADERS_M68K})
@ -898,8 +906,4 @@ if(CAPSTONE_BUILD_CSTEST)
add_subdirectory(${TESTS_INTEGRATION_DIR}) add_subdirectory(${TESTS_INTEGRATION_DIR})
set(TESTS_UNIT_DIR ${PROJECT_SOURCE_DIR}/tests/unit) set(TESTS_UNIT_DIR ${PROJECT_SOURCE_DIR}/tests/unit)
add_subdirectory(${TESTS_UNIT_DIR}) 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() endif()

View File

@ -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_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_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_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_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_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. - CAPSTONE_X86_SUPPORT: support X86. Run cmake with -DCAPSTONE_X86_SUPPORT=0 to remove X86.

19
MCAsmInfo.h Normal file
View 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

View File

@ -16,7 +16,7 @@
#define MCINST_CACHE (ARR_SIZE(mcInst->Operands) - 1) #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 // unnecessary to initialize in loop . its expensive and inst->size should be honored
inst->Operands[0].Kind = kInvalid; inst->Operands[0].Kind = kInvalid;
@ -37,6 +37,15 @@ void MCInst_Init(MCInst *inst)
inst->isAliasInstr = false; inst->isAliasInstr = false;
inst->fillDetailOps = false; inst->fillDetailOps = false;
memset(&inst->hppa_ext, 0, sizeof(inst->hppa_ext)); 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) void MCInst_clear(MCInst *inst)
@ -150,6 +159,11 @@ int64_t MCOperand_getImm(const MCOperand *op)
return op->ImmVal; return op->ImmVal;
} }
int64_t MCOperand_getExpr(const MCOperand *op)
{
return op->ImmVal;
}
void MCOperand_setImm(MCOperand *op, int64_t Val) void MCOperand_setImm(MCOperand *op, int64_t Val)
{ {
op->ImmVal = Val; op->ImmVal = Val;

View File

@ -20,6 +20,7 @@
#define CS_MCINST_H #define CS_MCINST_H
#include "include/capstone/capstone.h" #include "include/capstone/capstone.h"
#include "MCAsmInfo.h"
#include "MCInstrDesc.h" #include "MCInstrDesc.h"
#include "MCRegisterInfo.h" #include "MCRegisterInfo.h"
@ -73,6 +74,8 @@ int64_t MCOperand_getImm(const MCOperand *op);
void MCOperand_setImm(MCOperand *op, int64_t Val); void MCOperand_setImm(MCOperand *op, int64_t Val);
int64_t MCOperand_getExpr(const MCOperand *op);
double MCOperand_getFPImm(const MCOperand *op); double MCOperand_getFPImm(const MCOperand *op);
void MCOperand_setFPImm(MCOperand *op, double Val); void MCOperand_setFPImm(MCOperand *op, double Val);
@ -133,9 +136,10 @@ struct MCInst {
bool isAliasInstr; // Flag if this MCInst is an alias. bool isAliasInstr; // Flag if this MCInst is an alias.
bool fillDetailOps; // If set, detail->operands gets filled. 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 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); void MCInst_clear(MCInst *inst);

View File

@ -340,6 +340,7 @@ DEFINE_get_detail_op(hppa, HPPA);
DEFINE_get_detail_op(loongarch, LoongArch); DEFINE_get_detail_op(loongarch, LoongArch);
DEFINE_get_detail_op(mips, Mips); DEFINE_get_detail_op(mips, Mips);
DEFINE_get_detail_op(riscv, RISCV); DEFINE_get_detail_op(riscv, RISCV);
DEFINE_get_detail_op(systemz, SystemZ);
/// Returns true if for this architecture the /// Returns true if for this architecture the
/// alias operands should be filled. /// 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]) { } else if (id[i] > map[m].str[j]) {
l = m + 1; 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 before we go out of bounds.
break; break;
} }

View File

@ -32,6 +32,7 @@ typedef struct insn_map {
ppc_suppl_info ppc; ppc_suppl_info ppc;
loongarch_suppl_info loongarch; loongarch_suppl_info loongarch;
aarch64_suppl_info aarch64; aarch64_suppl_info aarch64;
systemz_suppl_info systemz;
} suppl_info; // Supplementary information for each instruction. } suppl_info; // Supplementary information for each instruction.
#endif #endif
} insn_map; } insn_map;
@ -140,6 +141,7 @@ DECL_get_detail_op(hppa, HPPA);
DECL_get_detail_op(loongarch, LoongArch); DECL_get_detail_op(loongarch, LoongArch);
DECL_get_detail_op(mips, Mips); DECL_get_detail_op(mips, Mips);
DECL_get_detail_op(riscv, RISCV); DECL_get_detail_op(riscv, RISCV);
DECL_get_detail_op(systemz, SystemZ);
/// Increments the detail->arch.op_count by one. /// Increments the detail->arch.op_count by one.
#define DEFINE_inc_detail_op_count(arch, ARCH) \ #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_dec_detail_op_count(mips, Mips);
DEFINE_inc_detail_op_count(riscv, RISCV); DEFINE_inc_detail_op_count(riscv, RISCV);
DEFINE_dec_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. /// Returns true if a memory operand is currently edited.
static inline bool doing_mem(const MCInst *MI) 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(loongarch, LoongArch);
DEFINE_get_arch_detail(mips, Mips); DEFINE_get_arch_detail(mips, Mips);
DEFINE_get_arch_detail(riscv, RISCV); DEFINE_get_arch_detail(riscv, RISCV);
DEFINE_get_arch_detail(systemz, SystemZ);
static inline bool detail_is_set(const MCInst *MI) static inline bool detail_is_set(const MCInst *MI)
{ {

167
SStream.c
View File

@ -28,6 +28,19 @@ void SStream_Init(SStream *ss)
ss->index = 0; ss->index = 0;
ss->buffer[0] = '\0'; ss->buffer[0] = '\0';
ss->is_closed = false; 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; return;
unsigned int len = (unsigned int) strlen(s); unsigned int len = (unsigned int) strlen(s);
SSTREAM_OVERFLOW_CHECK(ss, len);
memcpy(ss->buffer + ss->index, s, len); memcpy(ss->buffer + ss->index, s, len);
ss->index += len; ss->index += len;
ss->buffer[ss->index] = '\0'; 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 #endif
} }
@ -72,9 +93,17 @@ void SStream_concat1(SStream *ss, const char c)
SSTREAM_RETURN_IF_CLOSED(ss); SSTREAM_RETURN_IF_CLOSED(ss);
if (c == '\0') if (c == '\0')
return; return;
SSTREAM_OVERFLOW_CHECK(ss, 1);
ss->buffer[ss->index] = c; ss->buffer[ss->index] = c;
ss->index++; ss->index++;
ss->buffer[ss->index] = '\0'; 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 #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); ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
va_end(ap); va_end(ap);
ss->index += ret; ss->index += ret;
if (ss->markup_stream && ss->prefixed_by_markup) {
SSTREAM_OVERFLOW_CHECK(ss, 1);
ss->buffer[ss->index] = '>';
ss->index += 1;
}
#endif #endif
} }
@ -99,29 +133,15 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
void printInt64Bang(SStream *O, int64_t val) void printInt64Bang(SStream *O, int64_t val)
{ {
SSTREAM_RETURN_IF_CLOSED(O); SSTREAM_RETURN_IF_CLOSED(O);
if (val >= 0) { SStream_concat1(O, '#');
if (val > HEX_THRESHOLD) printInt64(O, val);
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);
}
} }
void printUInt64Bang(SStream *O, uint64_t val) void printUInt64Bang(SStream *O, uint64_t val)
{ {
SSTREAM_RETURN_IF_CLOSED(O); SSTREAM_RETURN_IF_CLOSED(O);
if (val > HEX_THRESHOLD) SStream_concat1(O, '#');
SStream_concat(O, "#0x%"PRIx64, val); printUInt64(O, val);
else
SStream_concat(O, "#%"PRIu64, val);
} }
// print number // print number
@ -134,9 +154,9 @@ void printInt64(SStream *O, int64_t val)
else else
SStream_concat(O, "%"PRIu64, val); SStream_concat(O, "%"PRIu64, val);
} else { } else {
if (val <- HEX_THRESHOLD) { if (val < -HEX_THRESHOLD) {
if (val == LONG_MIN) if (val == INT64_MIN)
SStream_concat(O, "-0x%"PRIx64, (uint64_t)val); SStream_concat(O, "-0x%"PRIx64, (uint64_t) INT64_MAX + 1);
else else
SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val); SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val);
} else } else
@ -158,31 +178,57 @@ void printInt32BangDec(SStream *O, int32_t val)
{ {
SSTREAM_RETURN_IF_CLOSED(O); SSTREAM_RETURN_IF_CLOSED(O);
if (val >= 0) if (val >= 0)
SStream_concat(O, "#%u", val); SStream_concat(O, "#%" PRIu32, val);
else { else {
if (val == INT_MIN) if (val == INT32_MIN)
SStream_concat(O, "#-%u", val); SStream_concat(O, "#-%" PRIu32, val);
else else
SStream_concat(O, "#-%u", (uint32_t)-val); SStream_concat(O, "#-%" PRIu32, (uint32_t)-val);
} }
} }
void printInt32Bang(SStream *O, int32_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); SSTREAM_RETURN_IF_CLOSED(O);
if (val >= 0) { if (val >= 0) {
if (val > HEX_THRESHOLD) if (val > HEX_THRESHOLD)
SStream_concat(O, "#0x%x", val); SStream_concat(O, "0x%" PRIx8, val);
else else
SStream_concat(O, "#%u", val); SStream_concat(O, "%" PRId8, val);
} else { } else {
if (val <- HEX_THRESHOLD) { if (val < -HEX_THRESHOLD) {
if (val == INT_MIN) if (val == INT8_MIN)
SStream_concat(O, "#-0x%x", (uint32_t)val); SStream_concat(O, "-0x%" PRIx8, (uint8_t) INT8_MAX + 1);
else else
SStream_concat(O, "#-0x%x", (uint32_t)-val); SStream_concat(O, "-0x%" PRIx8, (int8_t)-val);
} else } 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); SSTREAM_RETURN_IF_CLOSED(O);
if (val >= 0) { if (val >= 0) {
if (val > HEX_THRESHOLD) if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%x", val); SStream_concat(O, "0x%" PRIx32, val);
else else
SStream_concat(O, "%u", val); SStream_concat(O, "%" PRId32, val);
} else { } else {
if (val <- HEX_THRESHOLD) { if (val < -HEX_THRESHOLD) {
if (val == INT_MIN) SStream_concat(O, "-0x%" PRIx32, (uint32_t)-val);
SStream_concat(O, "-0x%x", (uint32_t)val); } else {
else SStream_concat(O, "-%" PRIu32, (uint32_t)-val);
SStream_concat(O, "-0x%x", (uint32_t)-val); }
} else
SStream_concat(O, "-%u", -val);
} }
} }
void printUInt32Bang(SStream *O, uint32_t val) void printUInt32Bang(SStream *O, uint32_t val)
{ {
SSTREAM_RETURN_IF_CLOSED(O); SSTREAM_RETURN_IF_CLOSED(O);
if (val > HEX_THRESHOLD) SStream_concat1(O, '#');
SStream_concat(O, "#0x%x", val); printUInt32(O, val);
else
SStream_concat(O, "#%u", val);
} }
void printUInt32(SStream *O, uint32_t val) void printUInt32(SStream *O, uint32_t val)
@ -234,3 +276,38 @@ void printFloatBang(SStream *O, float val)
SSTREAM_RETURN_IF_CLOSED(O); SSTREAM_RETURN_IF_CLOSED(O);
SStream_concat(O, "#%e", val); 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;
}

View File

@ -5,13 +5,33 @@
#define CS_SSTREAM_H_ #define CS_SSTREAM_H_
#include "include/capstone/platform.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 { typedef struct SStream {
char buffer[512]; char buffer[SSTREAM_BUF_LEN];
int index; int index;
bool is_closed; 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; } 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) \ #define SSTREAM_RETURN_IF_CLOSED(OS) \
do { \ do { \
if (OS->is_closed) \ if (OS->is_closed) \
@ -20,6 +40,8 @@ do { \
void SStream_Init(SStream *ss); void SStream_Init(SStream *ss);
void SStream_Flush(SStream *ss, FILE *file);
void SStream_Open(SStream *ss); void SStream_Open(SStream *ss);
void SStream_Close(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 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 printInt32(SStream *O, int32_t val);
void printUInt32Bang(SStream *O, uint32_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 printFloatBang(SStream *O, float val);
void printExpr(SStream *O, uint64_t val);
SStream *markup_OS(SStream *OS, SStreamMarkup style);
#endif #endif

View File

@ -359,7 +359,7 @@ static void printInst(MCInst *MI, SStream *O, void *info)
if (MCRegisterClass_contains(MRC, Reg)) { if (MCRegisterClass_contains(MRC, Reg)) {
MCInst NewMI; MCInst NewMI;
MCInst_Init(&NewMI); MCInst_Init(&NewMI, CS_ARCH_ARM);
MCInst_setOpcode(&NewMI, Opcode); MCInst_setOpcode(&NewMI, Opcode);
if (isStore) if (isStore)

View File

@ -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 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is distributed under the University of Illinois Open Source // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */ #include <stdio.h>
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
#ifdef CAPSTONE_HAS_SYSZ
#include <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.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 "../../cs_priv.h"
#include "../../utils.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 "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 Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch,
return (uint64_t)-1; // 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"); CS_ASSERT((RegNo < Size && "Invalid register"));
RegNo = Regs[RegNo]; if (IsAddr && RegNo == 0) {
if (RegNo == 0) RegNo = SystemZ_NoRegister;
return MCDisassembler_Fail; } else {
RegNo = Regs[RegNo];
MCOperand_CreateReg0(Inst, (unsigned)RegNo); if (RegNo == 0)
return MCDisassembler_Fail;
}
MCOperand_CreateReg0(Inst, (RegNo));
return MCDisassembler_Success; return MCDisassembler_Success;
} }
static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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) #define DEFINE_decodeUImmOperand(N) \
{ static DecodeStatus CONCAT(decodeUImmOperand, N)(MCInst * Inst, \
//assert(isUInt<N>(Imm) && "Invalid immediate"); uint64_t Imm) \
MCOperand_CreateImm0(Inst, Imm); { \
return MCDisassembler_Success; 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) #define DEFINE_decodeSImmOperand(N) \
{ static DecodeStatus CONCAT(decodeSImmOperand, N)(MCInst * Inst, \
//assert(isUInt<N>(Imm) && "Invalid immediate"); uint64_t Imm) \
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N)); { \
return MCDisassembler_Success; 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, 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, 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, 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, static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, const void *Decoder) uint64_t Address, const void *Decoder)
{ {
return decodeUImmOperand(Inst, Imm); return CONCAT(decodeUImmOperand, 4)(Inst, Imm);
}
static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, const void *Decoder)
{
return decodeUImmOperand(Inst, Imm);
} }
static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t 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, 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, 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, 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, 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, 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, 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, #define DEFINE_decodeLenOperand(N) \
uint64_t Address, unsigned N) static DecodeStatus CONCAT(decodeLenOperand, \
{ N)(MCInst * Inst, uint64_t Imm, \
//assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); uint64_t Address, const void *Decoder) \
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address); { \
return MCDisassembler_Success; 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, static DecodeStatus decodePC12DBLBranchOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, uint64_t Address,
const void *Decoder) 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, static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, uint64_t Address,
const void *Decoder) 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, static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, uint64_t Address,
const void *Decoder) 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, static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, uint64_t Address,
const void *Decoder) 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, static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm,
uint64_t Address, uint64_t Address, const void *Decoder)
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" #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; // Get the first two bytes of the instruction.
const uint8_t *Table; *Size = 0;
uint16_t I; if (BytesLen < 2)
return MCDisassembler_Fail;
// The top 2 bits of the first byte specify the size. // The top 2 bits of the first byte specify the size.
if (*code < 0x40) { const uint8_t *Table;
*size = 2; uint64_t Inst = 0;
if (Bytes[0] < 0x40) {
*Size = 2;
Table = DecoderTable16; Table = DecoderTable16;
} else if (*code < 0xc0) { Inst = readBytes16(MI, Bytes);
*size = 4; } else if (Bytes[0] < 0xc0) {
*Size = 4;
Table = DecoderTable32; Table = DecoderTable32;
Inst = readBytes32(MI, Bytes);
} else { } else {
*size = 6; *Size = 6;
Table = DecoderTable48; Table = DecoderTable48;
Inst = readBytes48(MI, Bytes);
} }
if (code_len < *size) // Read any remaining bytes.
// short of input data if (BytesLen < *Size) {
return false; *Size = BytesLen;
return MCDisassembler_Fail;
if (MI->flat_insn->detail) {
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
} }
// Construct the instruction. return decodeInstruction_8(Table, MI, Inst, Address, NULL);
Inst = 0;
for (I = 0; I < *size; ++I)
Inst = (Inst << 8) | code[I];
return decodeInstruction(Table, MI, Inst, address, info, 0);
} }
#define GET_REGINFO_ENUM DecodeStatus SystemZ_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
#define GET_REGINFO_MC_DESC size_t BytesLen, MCInst *MI,
#include "SystemZGenRegisterInfo.inc" uint16_t *Size, uint64_t Address,
void SystemZ_init(MCRegisterInfo *MRI) void *Info)
{ {
/* return getInstruction(MI, Size, Bytes, BytesLen, MI->address, NULL);
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);
} }
#endif

View File

@ -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

View 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;
}
}

View 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

View 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" },

View 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" },

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

View 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

View File

@ -1,49 +1,65 @@
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ /* Capstone Disassembly Engine, https://www.capstone-engine.org */
|* *| /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
|* Subtarget Enumeration Source Fragment *| /* Rot127 <unisono@quyllur.org> 2022-2024 */
|* *| /* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
/* Capstone Disassembly Engine, http://www.capstone-engine.org */ /* LLVM-commit: <commit> */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ /* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
#ifdef GET_SUBTARGETINFO_ENUM #ifdef GET_SUBTARGETINFO_ENUM
#undef GET_SUBTARGETINFO_ENUM #undef GET_SUBTARGETINFO_ENUM
enum { enum {
SystemZ_FeatureDFPPackedConversion = 1ULL << 0, SystemZ_FeatureBEAREnhancement = 0,
SystemZ_FeatureDFPZonedConversion = 1ULL << 1, SystemZ_FeatureBackChain = 1,
SystemZ_FeatureDistinctOps = 1ULL << 2, SystemZ_FeatureDFPPackedConversion = 2,
SystemZ_FeatureEnhancedDAT2 = 1ULL << 3, SystemZ_FeatureDFPZonedConversion = 3,
SystemZ_FeatureExecutionHint = 1ULL << 4, SystemZ_FeatureDeflateConversion = 4,
SystemZ_FeatureFPExtension = 1ULL << 5, SystemZ_FeatureDistinctOps = 5,
SystemZ_FeatureFastSerialization = 1ULL << 6, SystemZ_FeatureEnhancedDAT2 = 6,
SystemZ_FeatureGuardedStorage = 1ULL << 7, SystemZ_FeatureEnhancedSort = 7,
SystemZ_FeatureHighWord = 1ULL << 8, SystemZ_FeatureExecutionHint = 8,
SystemZ_FeatureInsertReferenceBitsMultiple = 1ULL << 9, SystemZ_FeatureFPExtension = 9,
SystemZ_FeatureInterlockedAccess1 = 1ULL << 10, SystemZ_FeatureFastSerialization = 10,
SystemZ_FeatureLoadAndTrap = 1ULL << 11, SystemZ_FeatureGuardedStorage = 11,
SystemZ_FeatureLoadAndZeroRightmostByte = 1ULL << 12, SystemZ_FeatureHighWord = 12,
SystemZ_FeatureLoadStoreOnCond = 1ULL << 13, SystemZ_FeatureInsertReferenceBitsMultiple = 13,
SystemZ_FeatureLoadStoreOnCond2 = 1ULL << 14, SystemZ_FeatureInterlockedAccess1 = 14,
SystemZ_FeatureMessageSecurityAssist3 = 1ULL << 15, SystemZ_FeatureLoadAndTrap = 15,
SystemZ_FeatureMessageSecurityAssist4 = 1ULL << 16, SystemZ_FeatureLoadAndZeroRightmostByte = 16,
SystemZ_FeatureMessageSecurityAssist5 = 1ULL << 17, SystemZ_FeatureLoadStoreOnCond = 17,
SystemZ_FeatureMessageSecurityAssist7 = 1ULL << 18, SystemZ_FeatureLoadStoreOnCond2 = 18,
SystemZ_FeatureMessageSecurityAssist8 = 1ULL << 19, SystemZ_FeatureMessageSecurityAssist3 = 19,
SystemZ_FeatureMiscellaneousExtensions = 1ULL << 20, SystemZ_FeatureMessageSecurityAssist4 = 20,
SystemZ_FeatureMiscellaneousExtensions2 = 1ULL << 21, SystemZ_FeatureMessageSecurityAssist5 = 21,
SystemZ_FeaturePopulationCount = 1ULL << 22, SystemZ_FeatureMessageSecurityAssist7 = 22,
SystemZ_FeatureProcessorAssist = 1ULL << 23, SystemZ_FeatureMessageSecurityAssist8 = 23,
SystemZ_FeatureResetReferenceBitsMultiple = 1ULL << 24, SystemZ_FeatureMessageSecurityAssist9 = 24,
SystemZ_FeatureTransactionalExecution = 1ULL << 25, SystemZ_FeatureMiscellaneousExtensions = 25,
SystemZ_FeatureVector = 1ULL << 26, SystemZ_FeatureMiscellaneousExtensions2 = 26,
SystemZ_FeatureVectorEnhancements1 = 1ULL << 27, SystemZ_FeatureMiscellaneousExtensions3 = 27,
SystemZ_FeatureVectorPackedDecimal = 1ULL << 28, 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 #endif // GET_SUBTARGETINFO_ENUM

View File

@ -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 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is distributed under the University of Illinois Open Source // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an SystemZ MCInst to a .s file.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */ #include <stdint.h>
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
#ifdef CAPSTONE_HAS_SYSZ
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <capstone/platform.h> #include <capstone/platform.h>
#include "SystemZInstPrinter.h" #include "../../MCAsmInfo.h"
#include "../../MCInst.h"
#include "../../utils.h"
#include "../../SStream.h"
#include "../../MCRegisterInfo.h"
#include "../../MathExtras.h"
#include "SystemZMapping.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)
{ {
/* printMCOperandMAI(DispMO, MAI, O);
if (((cs_struct *)ud)->detail != CS_OPT_ON) if (Base || Index) {
return;
*/
}
static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O)
{
printInt64(O, Disp);
if (Base) {
SStream_concat0(O, "("); SStream_concat0(O, "(");
if (Index)
SStream_concat(O, "%%%s, ", getRegisterName(Index));
SStream_concat(O, "%%%s)", getRegisterName(Base));
if (MI->csh->detail_opt) { if (Index) {
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM; printFormattedRegName(MAI, Index, O);
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base); SStream_concat0(O, ",");
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 (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)) { if (MCOperand_isReg(MO)) {
unsigned reg; if (!MCOperand_getReg(MO))
SStream_concat0(O, "0");
reg = MCOperand_getReg(MO); else
SStream_concat(O, "%%%s", getRegisterName(reg)); printFormattedRegName(&MI->MAI, MCOperand_getReg(MO), O);
reg = SystemZ_map_register(reg); } else if (MCOperand_isImm(MO))
printInt64(markup_OS(O, Markup_Immediate),
if (MI->csh->detail_opt) { MCOperand_getImm(MO));
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_REG; else if (MCOperand_isExpr(MO))
MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = reg; printExpr(O, MCOperand_getExpr(MO)); \
MI->flat_insn->detail->sysz.op_count++; else
} assert(0 && "Invalid operand");
} 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++;
}
}
} }
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) static void printU1ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U1ImmOperand, OpNum);
// assert(isUInt<1>(Value) && "Invalid u1imm argument"); CONCAT(printUImmOperand, 1)(MI, OpNum, O);
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 printU2ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU2ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U2ImmOperand, OpNum);
// assert(isUInt<2>(Value) && "Invalid u2imm argument"); CONCAT(printUImmOperand, 2)(MI, OpNum, O);
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 printU3ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU3ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U3ImmOperand, OpNum);
// assert(isUInt<3>(Value) && "Invalid u4imm argument"); CONCAT(printUImmOperand, 3)(MI, OpNum, O);
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 printU4ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U4ImmOperand, OpNum);
// assert(isUInt<4>(Value) && "Invalid u4imm argument"); CONCAT(printUImmOperand, 4)(MI, OpNum, O);
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++;
}
} }
static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int8_t Value = (int8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_S8ImmOperand, OpNum);
// assert(isInt<8>(Value) && "Invalid s8imm argument"); CONCAT(printSImmOperand, 8)(MI, OpNum, O);
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++;
}
} }
static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
uint8_t Value = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U8ImmOperand, OpNum);
// assert(isUInt<8>(Value) && "Invalid u8imm argument"); CONCAT(printUImmOperand, 8)(MI, OpNum, O);
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++;
}
} }
static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U12ImmOperand, OpNum);
// assert(isUInt<12>(Value) && "Invalid u12imm argument"); CONCAT(printUImmOperand, 12)(MI, OpNum, O);
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 printS16ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int16_t Value = (int16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_S16ImmOperand, OpNum);
// assert(isInt<16>(Value) && "Invalid s16imm argument"); CONCAT(printSImmOperand, 16)(MI, OpNum, O);
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++;
}
} }
static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
uint16_t Value = (uint16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U16ImmOperand, OpNum);
// assert(isUInt<16>(Value) && "Invalid u16imm argument"); CONCAT(printUImmOperand, 16)(MI, OpNum, O);
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++;
}
} }
static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int32_t Value = (int32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_S32ImmOperand, OpNum);
// assert(isInt<32>(Value) && "Invalid s32imm argument"); CONCAT(printSImmOperand, 32)(MI, OpNum, O);
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++;
}
} }
static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U32ImmOperand, OpNum);
// assert(isUInt<32>(Value) && "Invalid u32imm argument"); CONCAT(printUImmOperand, 32)(MI, OpNum, O);
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++;
}
} }
static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O) static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O)
{ {
int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_U48ImmOperand, OpNum);
// assert(isUInt<48>(Value) && "Invalid u48imm argument"); CONCAT(printUImmOperand, 48)(MI, OpNum, O);
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 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)) { if (MCOperand_isImm(MO)) {
int64_t imm = (int64_t)MCOperand_getImm(MO); printInt64(O, MCOperand_getImm(MO));
} else
printInt64(O, imm); printExpr(O, MCOperand_getExpr(MO));
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++;
}
}
} }
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. // 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) 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) static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O)
{ {
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)), add_cs_detail(MI, SystemZ_OP_GROUP_BDAddrOperand, OpNum);
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), 0, O); 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) static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O)
{ {
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)), add_cs_detail(MI, SystemZ_OP_GROUP_BDXAddrOperand, OpNum);
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), printAddress(&MI->MAI, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))),
MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O); MCInst_getOperand(MI, (OpNum + 1)),
MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2))), O);
} }
static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O) static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O)
{ {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_BDLAddrOperand, OpNum);
uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)); unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
uint64_t Length = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 2)); MCOperand *DispMO = MCInst_getOperand(MI, (OpNum + 1));
uint64_t Length = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 2)));
if (Disp > HEX_THRESHOLD) printMCOperandMAI(DispMO, &MI->MAI, O);
SStream_concat(O, "0x%"PRIx64, Disp); SStream_concat1(O, '(');
else printUInt64(O, Length);
SStream_concat(O, "%"PRIu64, Disp); if (Base) {
SStream_concat0(O, ",");
if (Length > HEX_THRESHOLD) printRegName(MI, O, Base);
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++;
} }
SStream_concat0(O, ")");
} }
static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O) static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O)
{ {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum)); add_cs_detail(MI, SystemZ_OP_GROUP_BDRAddrOperand, OpNum);
uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)); unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
uint64_t Length = MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)); MCOperand *DispMO = MCInst_getOperand(MI, (OpNum + 1));
unsigned Length = MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2)));
if (Disp > HEX_THRESHOLD) printMCOperandMAI(DispMO, &MI->MAI, O);
SStream_concat(O, "0x%"PRIx64, Disp);
else
SStream_concat(O, "%"PRIu64, Disp);
SStream_concat0(O, "("); SStream_concat0(O, "(");
SStream_concat(O, "%%%s", getRegisterName(Length)); printRegName(MI, O, Length);
if (Base) {
if (Base) SStream_concat0(O, ",");
SStream_concat(O, ", %%%s", getRegisterName(Base)); printRegName(MI, O, 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++;
} }
SStream_concat0(O, ")");
} }
static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O) static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O)
{ {
printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)), add_cs_detail(MI, SystemZ_OP_GROUP_BDVAddrOperand, OpNum);
MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), printAddress(&MI->MAI, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))),
MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O); MCInst_getOperand(MI, (OpNum + 1)),
MCOperand_getReg(MCInst_getOperand(MI, (OpNum + 2))), O);
} }
static void printCond4Operand(MCInst *MI, int OpNum, SStream *O) static void printCond4Operand(MCInst *MI, int OpNum, SStream *O)
{ {
static const char *const CondNames[] = { add_cs_detail(MI, SystemZ_OP_GROUP_Cond4Operand, OpNum);
"o", "h", "nle", "l", "nhe", "lh", "ne", static const char *const CondNames[] = { "o", "h", "nle", "l",
"e", "nlh", "he", "nl", "le", "nh", "no" "nhe", "lh", "ne", "e",
}; "nlh", "he", "nl", "le",
"nh", "no" };
uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
// assert(Imm > 0 && Imm < 15 && "Invalid condition"); CS_ASSERT((Imm > 0 && Imm < 15 && "Invalid condition"));
SStream_concat0(O, CondNames[Imm - 1]); SStream_concat0(O, CondNames[Imm - 1]);
if (MI->csh->detail_opt)
MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm;
} }
#define PRINT_ALIAS_INSTR const char *SystemZ_LLVM_getRegisterName(unsigned RegNo)
#include "SystemZGenAsmWriter.inc"
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
{ {
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);
}

View File

@ -1,15 +1,51 @@
/* Capstone Disassembly Engine */ /* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ /* 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 /* LLVM-commit: <commit> */
#define CS_SYSZINSTPRINTER_H /* LLVM-tag: <tag> */
#include "../../MCInst.h" /* Only small edits allowed. */
#include "../../MCRegisterInfo.h" /* For multiple similar edits, please create a Patch for the translator. */
#include "../../SStream.h"
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

View 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

View File

@ -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 -------------===// //===-- SystemZMCTargetDesc.cpp - SystemZ target descriptions -------------===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is distributed under the University of Illinois Open Source // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */ #include <stdio.h>
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ #include <string.h>
#include <stdlib.h>
#ifdef CAPSTONE_HAS_SYSZ
#include <capstone/platform.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" #include "SystemZGenRegisterInfo.inc"
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
const unsigned SystemZMC_GR32Regs[16] = { const unsigned SystemZMC_GR32Regs[16] = {
SystemZ_R0L, SystemZ_R1L, SystemZ_R2L, SystemZ_R3L, SystemZ_R0L, SystemZ_R1L, SystemZ_R2L, SystemZ_R3L,
SystemZ_R4L, SystemZ_R5L, SystemZ_R6L, SystemZ_R7L, SystemZ_R4L, SystemZ_R5L, SystemZ_R6L, SystemZ_R7L,
SystemZ_R8L, SystemZ_R9L, SystemZ_R10L, SystemZ_R11L, SystemZ_R8L, SystemZ_R9L, SystemZ_R10L, SystemZ_R11L,
SystemZ_R12L, SystemZ_R13L, SystemZ_R14L, SystemZ_R15L SystemZ_R12L, SystemZ_R13L, SystemZ_R14L, SystemZ_R15L
}; };
const unsigned SystemZMC_GRH32Regs[16] = { const unsigned SystemZMC_GRH32Regs[16] = {
SystemZ_R0H, SystemZ_R1H, SystemZ_R2H, SystemZ_R3H, SystemZ_R0H, SystemZ_R1H, SystemZ_R2H, SystemZ_R3H,
SystemZ_R4H, SystemZ_R5H, SystemZ_R6H, SystemZ_R7H, SystemZ_R4H, SystemZ_R5H, SystemZ_R6H, SystemZ_R7H,
SystemZ_R8H, SystemZ_R9H, SystemZ_R10H, SystemZ_R11H, SystemZ_R8H, SystemZ_R9H, SystemZ_R10H, SystemZ_R11H,
SystemZ_R12H, SystemZ_R13H, SystemZ_R14H, SystemZ_R15H SystemZ_R12H, SystemZ_R13H, SystemZ_R14H, SystemZ_R15H
}; };
const unsigned SystemZMC_GR64Regs[16] = { const unsigned SystemZMC_GR64Regs[16] = {
SystemZ_R0D, SystemZ_R1D, SystemZ_R2D, SystemZ_R3D, SystemZ_R0D, SystemZ_R1D, SystemZ_R2D, SystemZ_R3D,
SystemZ_R4D, SystemZ_R5D, SystemZ_R6D, SystemZ_R7D, SystemZ_R4D, SystemZ_R5D, SystemZ_R6D, SystemZ_R7D,
SystemZ_R8D, SystemZ_R9D, SystemZ_R10D, SystemZ_R11D, SystemZ_R8D, SystemZ_R9D, SystemZ_R10D, SystemZ_R11D,
SystemZ_R12D, SystemZ_R13D, SystemZ_R14D, SystemZ_R15D SystemZ_R12D, SystemZ_R13D, SystemZ_R14D, SystemZ_R15D
}; };
const unsigned SystemZMC_GR128Regs[16] = { const unsigned SystemZMC_GR128Regs[16] = { SystemZ_R0Q, 0, SystemZ_R2Q, 0,
SystemZ_R0Q, 0, SystemZ_R2Q, 0, SystemZ_R4Q, 0, SystemZ_R6Q, 0,
SystemZ_R4Q, 0, SystemZ_R6Q, 0, SystemZ_R8Q, 0, SystemZ_R10Q, 0,
SystemZ_R8Q, 0, SystemZ_R10Q, 0, SystemZ_R12Q, 0, SystemZ_R14Q, 0 };
SystemZ_R12Q, 0, SystemZ_R14Q, 0
};
const unsigned SystemZMC_FP32Regs[16] = { const unsigned SystemZMC_FP32Regs[16] = {
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S, SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S,
SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S, SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S,
SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S, SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S,
SystemZ_F12S, SystemZ_F13S, SystemZ_F14S, SystemZ_F15S SystemZ_F12S, SystemZ_F13S, SystemZ_F14S, SystemZ_F15S
}; };
const unsigned SystemZMC_FP64Regs[16] = { const unsigned SystemZMC_FP64Regs[16] = {
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D, SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D,
SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D, SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D,
SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D, SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D,
SystemZ_F12D, SystemZ_F13D, SystemZ_F14D, SystemZ_F15D SystemZ_F12D, SystemZ_F13D, SystemZ_F14D, SystemZ_F15D
}; };
const unsigned SystemZMC_FP128Regs[16] = { const unsigned SystemZMC_FP128Regs[16] = { SystemZ_F0Q, SystemZ_F1Q, 0, 0,
SystemZ_F0Q, SystemZ_F1Q, 0, 0, SystemZ_F4Q, SystemZ_F5Q, 0, 0,
SystemZ_F4Q, SystemZ_F5Q, 0, 0, SystemZ_F8Q, SystemZ_F9Q, 0, 0,
SystemZ_F8Q, SystemZ_F9Q, 0, 0, SystemZ_F12Q, SystemZ_F13Q, 0, 0 };
SystemZ_F12Q, SystemZ_F13Q, 0, 0
};
const unsigned SystemZMC_VR32Regs[32] = { const unsigned SystemZMC_VR32Regs[32] = {
SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S, SystemZ_F0S, SystemZ_F1S, SystemZ_F2S, SystemZ_F3S, SystemZ_F4S,
SystemZ_F4S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S, SystemZ_F5S, SystemZ_F6S, SystemZ_F7S, SystemZ_F8S, SystemZ_F9S,
SystemZ_F8S, SystemZ_F9S, SystemZ_F10S, SystemZ_F11S, SystemZ_F10S, SystemZ_F11S, SystemZ_F12S, SystemZ_F13S, SystemZ_F14S,
SystemZ_F12S, SystemZ_F13S, SystemZ_F14S, SystemZ_F15S, SystemZ_F15S, SystemZ_F16S, SystemZ_F17S, SystemZ_F18S, SystemZ_F19S,
SystemZ_F16S, SystemZ_F17S, SystemZ_F18S, SystemZ_F19S, SystemZ_F20S, SystemZ_F21S, SystemZ_F22S, SystemZ_F23S, SystemZ_F24S,
SystemZ_F20S, SystemZ_F21S, SystemZ_F22S, SystemZ_F23S, SystemZ_F25S, SystemZ_F26S, SystemZ_F27S, SystemZ_F28S, SystemZ_F29S,
SystemZ_F24S, SystemZ_F25S, SystemZ_F26S, SystemZ_F27S, SystemZ_F30S, SystemZ_F31S
SystemZ_F28S, SystemZ_F29S, SystemZ_F30S, SystemZ_F31S
}; };
const unsigned SystemZMC_VR64Regs[32] = { const unsigned SystemZMC_VR64Regs[32] = {
SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D, SystemZ_F0D, SystemZ_F1D, SystemZ_F2D, SystemZ_F3D, SystemZ_F4D,
SystemZ_F4D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D, SystemZ_F5D, SystemZ_F6D, SystemZ_F7D, SystemZ_F8D, SystemZ_F9D,
SystemZ_F8D, SystemZ_F9D, SystemZ_F10D, SystemZ_F11D, SystemZ_F10D, SystemZ_F11D, SystemZ_F12D, SystemZ_F13D, SystemZ_F14D,
SystemZ_F12D, SystemZ_F13D, SystemZ_F14D, SystemZ_F15D, SystemZ_F15D, SystemZ_F16D, SystemZ_F17D, SystemZ_F18D, SystemZ_F19D,
SystemZ_F16D, SystemZ_F17D, SystemZ_F18D, SystemZ_F19D, SystemZ_F20D, SystemZ_F21D, SystemZ_F22D, SystemZ_F23D, SystemZ_F24D,
SystemZ_F20D, SystemZ_F21D, SystemZ_F22D, SystemZ_F23D, SystemZ_F25D, SystemZ_F26D, SystemZ_F27D, SystemZ_F28D, SystemZ_F29D,
SystemZ_F24D, SystemZ_F25D, SystemZ_F26D, SystemZ_F27D, SystemZ_F30D, SystemZ_F31D
SystemZ_F28D, SystemZ_F29D, SystemZ_F30D, SystemZ_F31D
}; };
const unsigned SystemZMC_VR128Regs[32] = { const unsigned SystemZMC_VR128Regs[32] = {
SystemZ_V0, SystemZ_V1, SystemZ_V2, SystemZ_V3, SystemZ_V0, SystemZ_V1, SystemZ_V2, SystemZ_V3, SystemZ_V4,
SystemZ_V4, SystemZ_V5, SystemZ_V6, SystemZ_V7, SystemZ_V5, SystemZ_V6, SystemZ_V7, SystemZ_V8, SystemZ_V9,
SystemZ_V8, SystemZ_V9, SystemZ_V10, SystemZ_V11, SystemZ_V10, SystemZ_V11, SystemZ_V12, SystemZ_V13, SystemZ_V14,
SystemZ_V12, SystemZ_V13, SystemZ_V14, SystemZ_V15, SystemZ_V15, SystemZ_V16, SystemZ_V17, SystemZ_V18, SystemZ_V19,
SystemZ_V16, SystemZ_V17, SystemZ_V18, SystemZ_V19, SystemZ_V20, SystemZ_V21, SystemZ_V22, SystemZ_V23, SystemZ_V24,
SystemZ_V20, SystemZ_V21, SystemZ_V22, SystemZ_V23, SystemZ_V25, SystemZ_V26, SystemZ_V27, SystemZ_V28, SystemZ_V29,
SystemZ_V24, SystemZ_V25, SystemZ_V26, SystemZ_V27, SystemZ_V30, SystemZ_V31
SystemZ_V28, SystemZ_V29, SystemZ_V30, SystemZ_V31
}; };
const unsigned SystemZMC_AR32Regs[16] = { const unsigned SystemZMC_AR32Regs[16] = { SystemZ_A0, SystemZ_A1, SystemZ_A2,
SystemZ_A0, SystemZ_A1, SystemZ_A2, SystemZ_A3, SystemZ_A3, SystemZ_A4, SystemZ_A5,
SystemZ_A4, SystemZ_A5, SystemZ_A6, SystemZ_A7, SystemZ_A6, SystemZ_A7, SystemZ_A8,
SystemZ_A8, SystemZ_A9, SystemZ_A10, SystemZ_A11, SystemZ_A9, SystemZ_A10, SystemZ_A11,
SystemZ_A12, SystemZ_A13, SystemZ_A14, SystemZ_A15 SystemZ_A12, SystemZ_A13, SystemZ_A14,
}; SystemZ_A15 };
const unsigned SystemZMC_CR64Regs[16] = { const unsigned SystemZMC_CR64Regs[16] = { SystemZ_C0, SystemZ_C1, SystemZ_C2,
SystemZ_C0, SystemZ_C1, SystemZ_C2, SystemZ_C3, SystemZ_C3, SystemZ_C4, SystemZ_C5,
SystemZ_C4, SystemZ_C5, SystemZ_C6, SystemZ_C7, SystemZ_C6, SystemZ_C7, SystemZ_C8,
SystemZ_C8, SystemZ_C9, SystemZ_C10, SystemZ_C11, SystemZ_C9, SystemZ_C10, SystemZ_C11,
SystemZ_C12, SystemZ_C13, SystemZ_C14, SystemZ_C15 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,
};
unsigned SystemZMC_getFirstReg(unsigned Reg) 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]; return Map[Reg];
} }
#endif // end namespace

View File

@ -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++ -*-===// //===-- SystemZMCTargetDesc.h - SystemZ target descriptions -----*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// // See https://llvm.org/LICENSE.txt for license information.
// This file is distributed under the University of Illinois Open Source // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/* Capstone Disassembly Engine */ #ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZMCTARGETDESC_H
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ #define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZMCTARGETDESC_H
#ifndef CS_SYSTEMZMCTARGETDESC_H #include <stdio.h>
#define CS_SYSTEMZMCTARGETDESC_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 // 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 // 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 // as %r0-%r15. It seems better to provide the same interface for
// all classes though. // all classes though.
extern const unsigned SystemZMC_GR32Regs[16]; extern const unsigned SystemZMC_GR32Regs[16];
extern const unsigned SystemZMC_GRH32Regs[16]; extern const unsigned SystemZMC_GRH32Regs[16];
extern const unsigned SystemZMC_GR64Regs[16]; extern const unsigned SystemZMC_GR64Regs[16];
extern const unsigned SystemZMC_GR128Regs[16]; extern const unsigned SystemZMC_GR128Regs[16];
extern const unsigned SystemZMC_FP32Regs[16]; extern const unsigned SystemZMC_FP32Regs[16];
extern const unsigned SystemZMC_FP64Regs[16]; extern const unsigned SystemZMC_FP64Regs[16];
extern const unsigned SystemZMC_FP128Regs[16]; extern const unsigned SystemZMC_FP128Regs[16];
extern const unsigned SystemZMC_VR32Regs[32]; extern const unsigned SystemZMC_VR32Regs[32];
extern const unsigned SystemZMC_VR64Regs[32]; extern const unsigned SystemZMC_VR64Regs[32];
extern const unsigned SystemZMC_VR128Regs[32]; extern const unsigned SystemZMC_VR128Regs[32];
extern const unsigned SystemZMC_AR32Regs[16]; extern const unsigned SystemZMC_AR32Regs[16];
extern const unsigned SystemZMC_CR64Regs[16]; extern const unsigned SystemZMC_CR64Regs[16];
// Return the 0-based number of the first architectural register that // Return the 0-based number of the first architectural register that
// contains the given LLVM register. E.g. R1D -> 1. // contains the given LLVM register. E.g. R1D -> 1.
unsigned SystemZMC_getFirstReg(unsigned Reg); 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. // Defines symbolic names for SystemZ registers.
// This defines a mapping from register name to register number. // This defines a mapping from register name to register number.
//#define GET_REGINFO_ENUM #define GET_REGINFO_ENUM
//#include "SystemZGenRegisterInfo.inc" #include "SystemZGenRegisterInfo.inc"
// Defines symbolic names for the SystemZ instructions. // Defines symbolic names for the SystemZ instructions.
//#define GET_INSTRINFO_ENUM #define GET_INSTRINFO_ENUM
//#include "SystemZGenInstrInfo.inc" #define GET_INSTRINFO_MC_HELPER_DECLS
#include "SystemZGenInstrInfo.inc"
//#define GET_SUBTARGETINFO_ENUM #define GET_SUBTARGETINFO_ENUM
//#include "SystemZGenSubtargetInfo.inc" #include "SystemZGenSubtargetInfo.inc"
#endif #endif

View File

@ -1,224 +1,130 @@
/* Capstone Disassembly Engine */ /* 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 <stdio.h> // debug
#include <string.h> #include <string.h>
#include "../../Mapping.h" #include "../../Mapping.h"
#include "../../utils.h" #include "../../utils.h"
#include "../../cs_simple_types.h"
#include <capstone/cs_operand.h>
#include "SystemZMCTargetDesc.h"
#include "SystemZMapping.h" #include "SystemZMapping.h"
#include "SystemZLinkage.h"
#define GET_INSTRINFO_ENUM
#include "SystemZGenInstrInfo.inc"
#ifndef CAPSTONE_DIET #ifndef CAPSTONE_DIET
static const name_map reg_name_maps[] = {
{ SYSZ_REG_INVALID, NULL },
{ SYSZ_REG_0, "0" }, static const char *const insn_name_maps[] = {
{ SYSZ_REG_1, "1" }, #include "SystemZGenCSMappingInsnName.inc"
{ 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 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 #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) const char *SystemZ_reg_name(csh handle, unsigned int reg)
{ {
#ifndef CAPSTONE_DIET return SystemZ_LLVM_getRegisterName(reg);
if (reg >= ARR_SIZE(reg_name_maps)) }
return NULL;
return reg_name_maps[reg].name; void SystemZ_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
#else {
return NULL; 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 #endif
} }
static const insn_map insns[] = { void SystemZ_init_cs_detail(MCInst *MI) {
// dummy item if (!detail_is_set(MI)) {
{ return;
0, 0, }
#ifndef CAPSTONE_DIET memset(get_detail(MI), 0, sizeof(cs_detail));
{ 0 }, { 0 }, { 0 }, 0, 0 if (detail_is_set(MI)) {
#endif 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 // given internal insn id, return public instruction info
void SystemZ_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) void SystemZ_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{ {
unsigned short i; // We do this after Instruction disassembly.
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
}
}
} }
#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) const char *SystemZ_insn_name(csh handle, unsigned int id)
{ {
#ifndef CAPSTONE_DIET #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; return NULL;
// handle special alias first if (id < ARR_SIZE(insn_name_maps))
for (i = 0; i < ARR_SIZE(alias_insn_names); i++) { return insn_name_maps[id];
if (alias_insn_names[i].id == id)
return alias_insn_names[i].name;
}
return insn_name_maps[id].name; // not found
return NULL;
#else #else
return NULL; return NULL;
#endif #endif
@ -227,38 +133,16 @@ const char *SystemZ_insn_name(csh handle, unsigned int id)
#ifndef CAPSTONE_DIET #ifndef CAPSTONE_DIET
static const name_map group_name_maps[] = { static const name_map group_name_maps[] = {
// generic groups // generic groups
{ SYSZ_GRP_INVALID, NULL }, { SYSTEMZ_GRP_INVALID, NULL },
{ SYSZ_GRP_JUMP, "jump" }, { 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 #include "SystemZGenCSFeatureName.inc"
{ 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" },
}; };
#endif #endif
@ -271,210 +155,212 @@ const char *SystemZ_group_name(csh handle, unsigned int id)
#endif #endif
} }
// map internal raw register to 'public' register void SystemZ_add_cs_detail(MCInst *MI, int /* aarch64_op_group */ op_group,
sysz_reg SystemZ_map_register(unsigned int r) va_list args)
{ {
static const unsigned int map[] = { 0, #ifndef CAPSTONE_DIET
/* SystemZ_CC = 1 */ SYSZ_REG_CC, if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
/* SystemZ_A0 = 2 */ SYSZ_REG_A0, return;
/* 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,
};
if (r < ARR_SIZE(map)) unsigned op_num = va_arg(args, unsigned);
return map[r];
// cannot find this register switch (op_group) {
return 0; 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
#endif

View File

@ -1,10 +1,16 @@
/* Capstone Disassembly Engine */ /* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
#ifndef CS_SYSZ_MAP_H #ifndef CS_SYSTEMZ_MAP_H
#define CS_SYSZ_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 // return name of register in friendly string
const char *SystemZ_reg_name(csh handle, unsigned int reg); 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); const char *SystemZ_group_name(csh handle, unsigned int id);
// map internal raw register to 'public' register void SystemZ_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info);
sysz_reg SystemZ_map_register(unsigned int r); 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

View File

@ -1,12 +1,10 @@
/* Capstone Disassembly Engine */ /* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
#ifdef CAPSTONE_HAS_SYSZ #ifdef CAPSTONE_HAS_SYSTEMZ
#include "../../utils.h" #include "../../utils.h"
#include "../../MCRegisterInfo.h" #include "../../MCRegisterInfo.h"
#include "SystemZDisassembler.h"
#include "SystemZInstPrinter.h"
#include "SystemZMapping.h" #include "SystemZMapping.h"
#include "SystemZModule.h" #include "SystemZModule.h"
@ -15,12 +13,12 @@ cs_err SystemZ_global_init(cs_struct *ud)
MCRegisterInfo *mri; MCRegisterInfo *mri;
mri = cs_mem_malloc(sizeof(*mri)); mri = cs_mem_malloc(sizeof(*mri));
SystemZ_init(mri); SystemZ_init_mri(mri);
ud->printer = SystemZ_printInst; ud->printer = SystemZ_printer;
ud->printer_info = mri; ud->printer_info = mri;
ud->getinsn_info = mri; ud->getinsn_info = mri;
ud->disasm = SystemZ_getInstruction; ud->disasm = SystemZ_getInstruction;
ud->post_printer = SystemZ_post_printer; ud->post_printer = NULL;
ud->reg_name = SystemZ_reg_name; ud->reg_name = SystemZ_reg_name;
ud->insn_id = SystemZ_get_insn_id; 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) 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; handle->syntax = (int) value;
} else if (type == CS_OPT_MODE) {
// Do not set mode because only CS_MODE_BIG_ENDIAN is valid; we cannot handle->mode |= (cs_mode)value;
// test for CS_MODE_LITTLE_ENDIAN because it is 0 }
return CS_ERR_OK; return CS_ERR_OK;
} }

View File

@ -21,7 +21,7 @@ template = {
'x86.h': 'X86', 'x86.h': 'X86',
'ppc.h': 'Ppc', 'ppc.h': 'Ppc',
'sparc.h': 'Sparc', 'sparc.h': 'Sparc',
'systemz.h': 'Sysz', 'systemz.h': 'Systemz',
'xcore.h': 'Xcore', 'xcore.h': 'Xcore',
'tms320c64x.h': 'TMS320C64x', 'tms320c64x.h': 'TMS320C64x',
'm680x.h': 'M680x', 'm680x.h': 'M680x',
@ -31,8 +31,10 @@ template = {
'comment_close': '', 'comment_close': '',
}, },
'python': { '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" 'header': (
"# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.py]\n", "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': "", 'footer': "",
'line_format': '%s = %s\n', 'line_format': '%s = %s\n',
'out_file': './python/capstone/%s_const.py', 'out_file': './python/capstone/%s_const.py',
@ -44,7 +46,7 @@ template = {
'x86.h': 'x86', 'x86.h': 'x86',
'ppc.h': 'ppc', 'ppc.h': 'ppc',
'sparc.h': 'sparc', 'sparc.h': 'sparc',
'systemz.h': 'sysz', 'systemz.h': 'systemz',
'xcore.h': 'xcore', 'xcore.h': 'xcore',
'tms320c64x.h': 'tms320c64x', 'tms320c64x.h': 'tms320c64x',
'm680x.h': 'm680x', 'm680x.h': 'm680x',
@ -73,7 +75,7 @@ template = {
'x86.h': 'x86', 'x86.h': 'x86',
'ppc.h': 'ppc', 'ppc.h': 'ppc',
'sparc.h': 'sparc', 'sparc.h': 'sparc',
'systemz.h': 'sysz', 'systemz.h': 'systemz',
'xcore.h': 'xcore', 'xcore.h': 'xcore',
'tms320c64x.h': 'tms320c64x', 'tms320c64x.h': 'tms320c64x',
'm680x.h': 'm680x', 'm680x.h': 'm680x',
@ -175,7 +177,7 @@ def gen(lang):
if line.startswith('#define '): if line.startswith('#define '):
line = line[8:] #cut off 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: if len(xline) != 2:
continue continue
if '(' in xline[0] or ')' in xline[0]: #does it look like a function 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) # hacky: remove type cast (uint64_t)
t = t.replace('(uint64_t)', '') t = t.replace('(uint64_t)', '')
t = re.sub(r'\((\d+)ULL << (\d+)\)', r'\1 << \2', t) # (1ULL<<1) to 1 << 1 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]): if not has_special_arch_prefix(f[0]):
continue continue

View File

@ -26,7 +26,7 @@ __all__ = [
'CS_ARCH_X86', 'CS_ARCH_X86',
'CS_ARCH_PPC', 'CS_ARCH_PPC',
'CS_ARCH_SPARC', 'CS_ARCH_SPARC',
'CS_ARCH_SYSZ', 'CS_ARCH_SYSTEMZ',
'CS_ARCH_XCORE', 'CS_ARCH_XCORE',
'CS_ARCH_M68K', 'CS_ARCH_M68K',
'CS_ARCH_TMS320C64X', 'CS_ARCH_TMS320C64X',
@ -130,6 +130,21 @@ __all__ = [
'CS_MODE_HPPA_20W', 'CS_MODE_HPPA_20W',
'CS_MODE_LOONGARCH32', 'CS_MODE_LOONGARCH32',
'CS_MODE_LOONGARCH64', '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',
'CS_OPT_SYNTAX_DEFAULT', 'CS_OPT_SYNTAX_DEFAULT',
@ -214,6 +229,7 @@ __all__ = [
'__version__', '__version__',
] ]
UINT8_MAX = 0xff
UINT16_MAX = 0xffff UINT16_MAX = 0xffff
# Capstone C interface # Capstone C interface
@ -232,11 +248,11 @@ __version__ = "%u.%u.%u" %(CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA)
# architectures # architectures
CS_ARCH_ARM = 0 CS_ARCH_ARM = 0
CS_ARCH_AARCH64 = 1 CS_ARCH_AARCH64 = 1
CS_ARCH_MIPS = 2 CS_ARCH_SYSTEMZ = 2
CS_ARCH_X86 = 3 CS_ARCH_MIPS = 3
CS_ARCH_PPC = 4 CS_ARCH_X86 = 4
CS_ARCH_SPARC = 5 CS_ARCH_PPC = 5
CS_ARCH_SYSZ = 6 CS_ARCH_SPARC = 6
CS_ARCH_XCORE = 7 CS_ARCH_XCORE = 7
CS_ARCH_M68K = 8 CS_ARCH_M68K = 8
CS_ARCH_TMS320C64X = 9 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_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3) # HPPA 2.0 wide
CS_MODE_LOONGARCH32 = 1 << 0 CS_MODE_LOONGARCH32 = 1 << 0
CS_MODE_LOONGARCH64 = 1 << 1 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 # Capstone option type
CS_OPT_INVALID = 0 # No option specified CS_OPT_INVALID = 0 # No option specified
@ -526,7 +557,7 @@ class _cs_arch(ctypes.Union):
('x86', x86.CsX86), ('x86', x86.CsX86),
('ppc', ppc.CsPpc), ('ppc', ppc.CsPpc),
('sparc', sparc.CsSparc), ('sparc', sparc.CsSparc),
('sysz', systemz.CsSysz), ('systemz', systemz.CsSystemZ),
('xcore', xcore.CsXcore), ('xcore', xcore.CsXcore),
('tms320c64x', tms320c64x.CsTMS320C64x), ('tms320c64x', tms320c64x.CsTMS320C64x),
('m680x', m680x.CsM680x), ('m680x', m680x.CsM680x),
@ -877,8 +908,8 @@ class CsInsn(object):
ppc.get_arch_info(self._raw.detail.contents.arch.ppc) ppc.get_arch_info(self._raw.detail.contents.arch.ppc)
elif arch == CS_ARCH_SPARC: elif arch == CS_ARCH_SPARC:
(self.cc, self.hint, self.operands) = sparc.get_arch_info(self._raw.detail.contents.arch.sparc) (self.cc, self.hint, self.operands) = sparc.get_arch_info(self._raw.detail.contents.arch.sparc)
elif arch == CS_ARCH_SYSZ: elif arch == CS_ARCH_SYSTEMZ:
(self.cc, self.operands) = systemz.get_arch_info(self._raw.detail.contents.arch.sysz) (self.cc, self.format, self.operands) = systemz.get_arch_info(self._raw.detail.contents.arch.systemz)
elif arch == CS_ARCH_XCORE: elif arch == CS_ARCH_XCORE:
(self.operands) = xcore.get_arch_info(self._raw.detail.contents.arch.xcore) (self.operands) = xcore.get_arch_info(self._raw.detail.contents.arch.xcore)
elif arch == CS_ARCH_TMS320C64X: elif arch == CS_ARCH_TMS320C64X:
@ -1397,7 +1428,7 @@ def debug():
archs = { archs = {
"arm": CS_ARCH_ARM, "aarch64": CS_ARCH_AARCH64, "m68k": CS_ARCH_M68K, "arm": CS_ARCH_ARM, "aarch64": CS_ARCH_AARCH64, "m68k": CS_ARCH_M68K,
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, "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, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX,
'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE,
'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA, 'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA,

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [aarch64_const.py]
AARCH64_SFT_INVALID = 0 AARCH64_SFT_INVALID = 0
@ -2368,6 +2368,8 @@ AARCH64_SME_MATRIX_SLICE_OFF_RANGE = 4
AARCH64_SME_OP_INVALID = 0 AARCH64_SME_OP_INVALID = 0
AARCH64_SME_OP_TILE = 1 AARCH64_SME_OP_TILE = 1
AARCH64_SME_OP_TILE_VEC = 2 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_INVALID = 0
AARCH64_INS_ABS = 1 AARCH64_INS_ABS = 1

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [alpha_const.py]
# Operand type for instruction's operands # Operand type for instruction's operands

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm_const.py]
ARMCC_EQ = 0 ARMCC_EQ = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [bpf_const.py]
BPF_OP_INVALID = 0 BPF_OP_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [evm_const.py]
EVM_INS_STOP = 0 EVM_INS_STOP = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [hppa_const.py]
HPPA_MAX_OPS = 5 HPPA_MAX_OPS = 5
HPPA_STR_MODIFIER_LEN = 8 HPPA_STR_MODIFIER_LEN = 8

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [loongarch_const.py]
LOONGARCH_OP_INVALID = CS_OP_INVALID LOONGARCH_OP_INVALID = CS_OP_INVALID
LOONGARCH_OP_REG = CS_OP_REG LOONGARCH_OP_REG = CS_OP_REG

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [m680x_const.py]
M680X_OPERAND_COUNT = 9 M680X_OPERAND_COUNT = 9

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [m68k_const.py]
M68K_OPERAND_COUNT = 4 M68K_OPERAND_COUNT = 4

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [mips_const.py]
MIPS_OP_INVALID = 0 MIPS_OP_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [mos65xx_const.py]
MOS65XX_REG_INVALID = 0 MOS65XX_REG_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [ppc_const.py]
PPC_PRED_INVALID = 0xffff PPC_PRED_INVALID = 0xffff
PPC_PRED_LT = (0<<5)|12 PPC_PRED_LT = (0<<5)|12

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [riscv_const.py]
# Operand type for instruction's operands # Operand type for instruction's operands

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sh_const.py]
SH_REG_INVALID = 0 SH_REG_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sparc_const.py]
SPARC_CC_INVALID = 0 SPARC_CC_INVALID = 0

View File

@ -2,28 +2,30 @@
import ctypes import ctypes
from . import copy_ctypes_list from . import copy_ctypes_list
from .sysz_const import *
# define the API # define the API
class SyszOpMem(ctypes.Structure): class SystemZOpMem(ctypes.Structure):
_fields_ = ( _fields_ = (
('am', ctypes.c_int),
('base', ctypes.c_uint8), ('base', ctypes.c_uint8),
('index', ctypes.c_uint8), ('index', ctypes.c_uint8),
('length', ctypes.c_uint64), ('length', ctypes.c_uint64),
('disp', ctypes.c_int64), ('disp', ctypes.c_int64),
) )
class SyszOpValue(ctypes.Union): class SystemZOpValue(ctypes.Union):
_fields_ = ( _fields_ = (
('reg', ctypes.c_uint), ('reg', ctypes.c_uint),
('imm', ctypes.c_int64), ('imm', ctypes.c_int64),
('mem', SyszOpMem), ('mem', SystemZOpMem),
) )
class SyszOp(ctypes.Structure): class SystemZOp(ctypes.Structure):
_fields_ = ( _fields_ = (
('type', ctypes.c_uint), ('type', ctypes.c_uint),
('value', SyszOpValue), ('value', SystemZOpValue),
('access', ctypes.c_int),
('imm_width', ctypes.c_uint8),
) )
@property @property
@ -39,13 +41,14 @@ class SyszOp(ctypes.Structure):
return self.value.mem return self.value.mem
class CsSysz(ctypes.Structure): class CsSystemZ(ctypes.Structure):
_fields_ = ( _fields_ = (
('cc', ctypes.c_uint), ('cc', ctypes.c_uint),
('format', ctypes.c_int),
('op_count', ctypes.c_uint8), ('op_count', ctypes.c_uint8),
('operands', SyszOp * 6), ('operands', SystemZOp * 6),
) )
def get_arch_info(a): 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])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [tms320c64x_const.py]
TMS320C64X_OP_INVALID = 0 TMS320C64X_OP_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [tricore_const.py]
TRICORE_OP_INVALID = CS_OP_INVALID TRICORE_OP_INVALID = CS_OP_INVALID
TRICORE_OP_REG = CS_OP_REG TRICORE_OP_REG = CS_OP_REG

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [wasm_const.py]
WASM_OP_INVALID = 0 WASM_OP_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [x86_const.py]
X86_REG_INVALID = 0 X86_REG_INVALID = 0

View File

@ -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] # For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [xcore_const.py]
XCORE_OP_INVALID = 0 XCORE_OP_INVALID = 0

View File

@ -13,7 +13,7 @@ from capstone import m68k_const
from capstone import mips_const from capstone import mips_const
from capstone import ppc_const from capstone import ppc_const
from capstone import sparc_const from capstone import sparc_const
from capstone import sysz_const from capstone import systemz_const
from capstone import x86_const from capstone import x86_const
from capstone import xcore_const from capstone import xcore_const
from capstone import tms320c64x_const from capstone import tms320c64x_const
@ -52,7 +52,7 @@ def cs_const_getattr(identifier: str):
attr = getattr(sparc_const, identifier, None) attr = getattr(sparc_const, identifier, None)
if attr is not None: if attr is not None:
return attr return attr
attr = getattr(sysz_const, identifier, None) attr = getattr(systemz_const, identifier, None)
if attr is not None: if attr is not None:
return attr return attr
attr = getattr(x86_const, identifier, None) attr = getattr(x86_const, identifier, None)

View File

@ -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.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.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.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 ( from capstone.tms320c64x_const import (
TMS320C64X_OP_REG, TMS320C64X_OP_REG,
TMS320C64X_OP_REGPAIR, TMS320C64X_OP_REGPAIR,
@ -245,7 +245,7 @@ def compare_details(insn: CsInsn, expected: dict) -> bool:
elif "xcore" in expected: elif "xcore" in expected:
return test_expected_xcore(actual, expected["xcore"]) return test_expected_xcore(actual, expected["xcore"])
elif "systemz" in expected: elif "systemz" in expected:
return test_expected_sysz(actual, expected["systemz"]) return test_expected_SystemZ(actual, expected["systemz"])
elif "sparc" in expected: elif "sparc" in expected:
return test_expected_sparc(actual, expected["sparc"]) return test_expected_sparc(actual, expected["sparc"])
elif "sh" in expected: elif "sh" in expected:
@ -1349,25 +1349,35 @@ def test_expected_mips(actual: CsInsn, expected: dict) -> bool:
return True 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: if "operands" not in expected:
return True return True
elif not compare_uint32( elif not compare_uint32(
len(actual.operands), len(expected.get("operands")), "operands_count" len(actual.operands), len(expected.get("operands")), "operands_count"
): ):
return False return False
elif not compare_enum(
actual.format, expected.get("format"), "format"
):
return False
for aop, eop in zip(actual.operands, expected["operands"]): for aop, eop in zip(actual.operands, expected["operands"]):
if not compare_enum(aop.type, eop.get("type"), "type"): if not compare_enum(aop.type, eop.get("type"), "type"):
return False 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"): if not compare_reg(actual, aop.reg, eop.get("reg"), "reg"):
return False return False
elif aop.type == SYSZ_OP_IMM: elif aop.type == SYSTEMZ_OP_IMM:
if not compare_int64(aop.imm, eop.get("imm"), "imm"): if not compare_int64(aop.imm, eop.get("imm"), "imm"):
return False 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"): if not compare_reg(actual, aop.mem.base, eop.get("mem_base"), "mem_base"):
return False return False
if not compare_reg( if not compare_reg(

View File

@ -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_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, SPARC_CODE, "Sparc", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", 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_XCORE, 0, XCORE_CODE, "XCore", None),
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", 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), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),

View File

@ -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_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, SPARC_CODE, "Sparc", None),
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", 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_XCORE, 0, XCORE_CODE, "XCore", None),
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", 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), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None),

View File

@ -31,7 +31,7 @@ case $1 in
ARCH=SPARC ARCH=SPARC
;; ;;
SystemZ) SystemZ)
ARCH=SYSZ ARCH=SYSTEMZ
;; ;;
XCore) XCore)
ARCH=XCORE ARCH=XCORE

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -147,11 +147,27 @@ typedef struct cs_arch_config {
Sparc_option, \ Sparc_option, \
~(CS_MODE_BIG_ENDIAN | CS_MODE_V9), \ ~(CS_MODE_BIG_ENDIAN | CS_MODE_V9), \
} }
#define CS_ARCH_CONFIG_SYSZ \ #define CS_ARCH_CONFIG_SYSTEMZ \
{ \ { \
SystemZ_global_init, \ SystemZ_global_init, \
SystemZ_option, \ 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 \ #define CS_ARCH_CONFIG_XCORE \
{ \ { \
@ -257,6 +273,11 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
#else #else
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
#endif #endif
#ifdef CAPSTONE_HAS_SYSTEMZ
CS_ARCH_CONFIG_SYSTEMZ,
#else
{ NULL, NULL, 0 },
#endif
#ifdef CAPSTONE_HAS_MIPS #ifdef CAPSTONE_HAS_MIPS
CS_ARCH_CONFIG_MIPS, CS_ARCH_CONFIG_MIPS,
#else #else
@ -277,11 +298,6 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
#else #else
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
#endif #endif
#ifdef CAPSTONE_HAS_SYSZ
CS_ARCH_CONFIG_SYSZ,
#else
{ NULL, NULL, 0 },
#endif
#ifdef CAPSTONE_HAS_XCORE #ifdef CAPSTONE_HAS_XCORE
CS_ARCH_CONFIG_XCORE, CS_ARCH_CONFIG_XCORE,
#else #else
@ -379,8 +395,8 @@ static const uint32_t all_arch = 0
#ifdef CAPSTONE_HAS_SPARC #ifdef CAPSTONE_HAS_SPARC
| (1 << CS_ARCH_SPARC) | (1 << CS_ARCH_SPARC)
#endif #endif
#ifdef CAPSTONE_HAS_SYSZ #ifdef CAPSTONE_HAS_SYSTEMZ
| (1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_SYSTEMZ)
#endif #endif
#ifdef CAPSTONE_HAS_XCORE #ifdef CAPSTONE_HAS_XCORE
| (1 << CS_ARCH_XCORE) | (1 << CS_ARCH_XCORE)
@ -540,10 +556,10 @@ void CAPSTONE_API cs_arch_register_sparc(void)
} }
CAPSTONE_EXPORT 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) #if defined(CAPSTONE_USE_ARCH_REGISTRATION) && defined(CAPSTONE_HAS_SYSTEMZ)
CS_ARCH_REGISTER(SYSZ); CS_ARCH_REGISTER(SYSTEMZ);
#endif #endif
} }
@ -659,7 +675,7 @@ bool CAPSTONE_API cs_support(int query)
((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) | ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) |
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) | (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) | (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_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) | (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) | (1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
@ -962,7 +978,7 @@ static uint8_t skipdata_size(cs_struct *handle)
case CS_ARCH_SPARC: case CS_ARCH_SPARC:
// skip 4 bytes // skip 4 bytes
return 4; return 4;
case CS_ARCH_SYSZ: case CS_ARCH_SYSTEMZ:
// SystemZ instruction's length can be 2, 4 or 6 bytes, // SystemZ instruction's length can be 2, 4 or 6 bytes,
// so we just skip 2 bytes // so we just skip 2 bytes
return 2; 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; insn_cache = total;
while (size > 0) { while (size > 0) {
MCInst_Init(&mci); MCInst_Init(&mci, handle->arch);
mci.csh = handle; mci.csh = handle;
// relative branches need to know the address & size of current insn // 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; handle->errnum = CS_ERR_OK;
MCInst_Init(&mci); MCInst_Init(&mci, handle->arch);
mci.csh = handle; mci.csh = handle;
// relative branches need to know the address & size of current insn // 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) if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
count++; count++;
break; break;
case CS_ARCH_SYSZ: case CS_ARCH_SYSTEMZ:
for (i = 0; i < insn->detail->sysz.op_count; i++) for (i = 0; i < insn->detail->systemz.op_count; i++)
if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type) if (insn->detail->systemz.operands[i].type == (systemz_op_type)op_type)
count++; count++;
break; break;
case CS_ARCH_XCORE: 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; return i;
} }
break; break;
case CS_ARCH_SYSZ: case CS_ARCH_SYSTEMZ:
for (i = 0; i < insn->detail->sysz.op_count; i++) { for (i = 0; i < insn->detail->systemz.op_count; i++) {
if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type) if (insn->detail->systemz.operands[i].type == (systemz_op_type)op_type)
count++; count++;
if (count == post) if (count == post)
return i; return i;

View File

@ -146,8 +146,16 @@ static struct {
{ "sparc", "Sparc, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN }, { "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 }, { "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 }, { "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
{ "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSZ, 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 }, { "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_X86: return "x86";
case CS_ARCH_PPC: return "PowerPC"; case CS_ARCH_PPC: return "PowerPC";
case CS_ARCH_SPARC: return "Sparc"; 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_XCORE: return "Xcore";
case CS_ARCH_M68K: return "M68K"; case CS_ARCH_M68K: return "M68K";
case CS_ARCH_TMS320C64X: return "TMS320C64X"; 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: case CS_ARCH_SPARC:
print_insn_detail_sparc(handle, ins); print_insn_detail_sparc(handle, ins);
break; break;
case CS_ARCH_SYSZ: case CS_ARCH_SYSTEMZ:
print_insn_detail_sysz(handle, ins); print_insn_detail_systemz(handle, ins);
break; break;
case CS_ARCH_XCORE: case CS_ARCH_XCORE:
print_insn_detail_xcore(handle, ins); print_insn_detail_xcore(handle, ins);
@ -581,8 +589,8 @@ int main(int argc, char **argv)
printf("sparc=1 "); printf("sparc=1 ");
} }
if (cs_support(CS_ARCH_SYSZ)) { if (cs_support(CS_ARCH_SYSTEMZ)) {
printf("sysz=1 "); printf("systemz=1 ");
} }
if (cs_support(CS_ARCH_XCORE)) { if (cs_support(CS_ARCH_XCORE)) {
@ -767,7 +775,7 @@ int main(int argc, char **argv)
for (; j < 16; j++) { for (; j < 16; j++) {
printf(" "); printf(" ");
} }
} else if (arch == CS_ARCH_SYSZ) { } else if (arch == CS_ARCH_SYSTEMZ) {
for (; j < 6; j++) { for (; j < 6; j++) {
printf(" "); printf(" ");
} }

View File

@ -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_mips(csh handle, cs_insn *ins);
void print_insn_detail_ppc(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_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_xcore(csh handle, cs_insn *ins);
void print_insn_detail_m68k(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); void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);

View File

@ -6,50 +6,84 @@
#include <capstone/capstone.h> #include <capstone/capstone.h>
#include "cstool.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; int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL) if (ins->detail == NULL)
return; return;
sysz = &(ins->detail->sysz); systemz = &(ins->detail->systemz);
if (sysz->op_count) if (systemz->op_count)
printf("\top_count: %u\n", sysz->op_count); printf("\top_count: %u\n", systemz->op_count);
for (i = 0; i < sysz->op_count; i++) { for (i = 0; i < systemz->op_count; i++) {
cs_sysz_op *op = &(sysz->operands[i]); cs_systemz_op *op = &(systemz->operands[i]);
switch((int)op->type) { switch((int)op->type) {
default: default:
break; break;
case SYSZ_OP_REG: case SYSTEMZ_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break; break;
case SYSZ_OP_ACREG: case SYSTEMZ_OP_IMM:
printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg);
break;
case SYSZ_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break; break;
case SYSZ_OP_MEM: case SYSTEMZ_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i); 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", printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base)); 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", printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index)); i, cs_reg_name(handle, op->mem.index));
if (op->mem.length != 0) if (op->mem.length != 0) {
printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length); if (op->mem.am == SYSTEMZ_AM_BDL) {
if (op->mem.disp != 0) 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); } 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; 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) if (systemz->cc != SYSTEMZ_CC_INVALID)
printf("\tCode condition: %u\n", sysz->cc); printf("\tCode condition: %u\n", systemz->cc);
} }

View File

@ -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! 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 ## Breaking changes
**All `auto-sync` architectures** **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. | | 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()` | | 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. | | `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 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 | | 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 | | 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. | | `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. | | `(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** **AArch64**
| Keyword | Change | Justification | Possible revert | | 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. | | `writeback` | `writeback` member was moved to detail. | See ARM explanation. | See ARM. |
| `arm64_vas` | `arm64_vas` renamed to `AArch64Layout_VectorLayout` | LLVM compatibility. | None. | | `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. | | 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. | Keyword | Change | Justification | Possible revert |
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. | `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. 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. We will continue to maintain both headers.
So if you need to support the previous version of Capstone as well, you can use either of the solutions.
_Compatibility header_ _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 ```c
#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
#define CAPSTONE_AARCH64_COMPAT_HEADER #define CAPSTONE_AARCH64_COMPAT_HEADER
#include <capstone/capstone.h> #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_ _Meta programming macros_
The following `sed` commands in a sh script should ease the replacement of `ARM64` with the macros a lot. 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 ```sh
#!/bin/sh #!/bin/sh
@ -137,6 +212,8 @@ echo "Replace detail->arm64"
sed -i -E "s/detail->arm64/detail->CS_aarch64()/g" $1 sed -i -E "s/detail->arm64/detail->CS_aarch64()/g" $1
``` ```
_Example renaming with `sed`_
Simple renaming from `ARM64` to `AArch64`: Simple renaming from `ARM64` to `AArch64`:
```sh ```sh
@ -165,20 +242,35 @@ echo "Replace detail->arm64"
sed -i "s|detail->arm64|detail->aarch64|g" $1 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>` 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** **Note about AArch64**
in `capstone.h` new mips ISA has been added which can be used by themselves. 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 4 00 00 00 00 andeq r0, r0, r0
8 8f a2 00 00 andeq r10, r0, pc, lsl #5 8 8f a2 00 00 andeq r10, r0, pc, lsl #5
10 34 21 34 56 shasxpl r2, r4, r4 10 34 21 34 56 shasxpl r2, r4, r4
``` ```

View File

@ -139,12 +139,16 @@ typedef enum cs_arch {
CS_ARCH_ARM64 = 1, ///< ARM64 CS_ARCH_ARM64 = 1, ///< ARM64
#else #else
CS_ARCH_AARCH64 = 1, ///< AArch64 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 #endif
CS_ARCH_MIPS, ///< Mips architecture CS_ARCH_MIPS, ///< Mips architecture
CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64) CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64)
CS_ARCH_PPC, ///< PowerPC architecture CS_ARCH_PPC, ///< PowerPC architecture
CS_ARCH_SPARC, ///< Sparc architecture CS_ARCH_SPARC, ///< Sparc architecture
CS_ARCH_SYSZ, ///< SystemZ architecture
CS_ARCH_XCORE, ///< XCore architecture CS_ARCH_XCORE, ///< XCore architecture
CS_ARCH_M68K, ///< 68K architecture CS_ARCH_M68K, ///< 68K architecture
CS_ARCH_TMS320C64X, ///< TMS320C64x 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_HPPA_20W = CS_MODE_HPPA_20 | (1 << 3), ///< HPPA 2.0 wide
CS_MODE_LOONGARCH32 = 1 << 0, ///< LoongArch32 CS_MODE_LOONGARCH32 = 1 << 0, ///< LoongArch32
CS_MODE_LOONGARCH64 = 1 << 1, ///< LoongArch64 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; } cs_mode;
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
@ -451,12 +470,17 @@ typedef struct cs_detail {
#else #else
cs_aarch64 aarch64; ///< AArch6464 architecture (aka ARM64) cs_aarch64 aarch64; ///< AArch6464 architecture (aka ARM64)
#endif #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_arm arm; ///< ARM architecture (including Thumb/Thumb2)
cs_m68k m68k; ///< M68K architecture cs_m68k m68k; ///< M68K architecture
cs_mips mips; ///< MIPS architecture cs_mips mips; ///< MIPS architecture
cs_ppc ppc; ///< PowerPC architecture cs_ppc ppc; ///< PowerPC architecture
cs_sparc sparc; ///< Sparc architecture cs_sparc sparc; ///< Sparc architecture
cs_sysz sysz; ///< SystemZ architecture
cs_xcore xcore; ///< XCore architecture cs_xcore xcore; ///< XCore architecture
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
cs_m680x m680x; ///< M680X architecture cs_m680x m680x; ///< M680X architecture
@ -591,7 +615,10 @@ void CAPSTONE_API cs_arch_register_powerpc(void);
CAPSTONE_EXPORT CAPSTONE_EXPORT
void CAPSTONE_API cs_arch_register_sparc(void); void CAPSTONE_API cs_arch_register_sparc(void);
CAPSTONE_EXPORT 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 CAPSTONE_EXPORT
void CAPSTONE_API cs_arch_register_xcore(void); void CAPSTONE_API cs_arch_register_xcore(void);
CAPSTONE_EXPORT CAPSTONE_EXPORT

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,4 +9,4 @@ src/autosync/Tests/MCUpdaterTests/Disassembler/ARCH/Output
src/autosync/lit_config/test_dir_* src/autosync/lit_config/test_dir_*
src/autosync/lit_config/.lit_test_times.txt src/autosync/lit_config/.lit_test_times.txt
src/autosync/Tests/MCUpdaterTests/test_output src/autosync/Tests/MCUpdaterTests/test_output
src/autosync/Tests/MCUpdaterTests/ARCH/Output src/autosync/Tests/MCUpdaterTests/**/Output

View File

@ -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}
)

View File

@ -22,3 +22,6 @@ requires-python = ">= 3.11"
[tool.setuptools] [tool.setuptools]
packages = ["autosync", "autosync.cpptranslator", "autosync.cpptranslator.patches"] packages = ["autosync", "autosync.cpptranslator", "autosync.cpptranslator.patches"]
package-dir = {"" = "src"} package-dir = {"" = "src"}
[project.scripts]
ASUpdater = "autosync.ASUpdater:main"

View File

@ -10,17 +10,19 @@ import os
import shutil import shutil
import subprocess import subprocess
import sys import sys
import json
from enum import StrEnum from enum import StrEnum
from pathlib import Path from pathlib import Path
from autosync.cpptranslator.Configurator import Configurator from autosync.cpptranslator.Configurator import Configurator
from autosync.cpptranslator.CppTranslator import Translator from autosync.cpptranslator.CppTranslator import Translator
from autosync.HeaderPatcher import CompatHeaderBuilder, HeaderPatcher 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.IncGenerator import IncGenerator
from autosync.MCUpdater import MCUpdater from autosync.MCUpdater import MCUpdater
from autosync.Targets import ARCH_LLVM_NAMING
class USteps(StrEnum): class USteps(StrEnum):
@ -44,7 +46,7 @@ class ASUpdater:
steps: list[USteps], steps: list[USteps],
inc_list: list, inc_list: list,
no_clean: bool, no_clean: bool,
refactor: bool, copy_translated: bool,
differ_no_auto_apply: bool, differ_no_auto_apply: bool,
wait_for_user: bool = True, wait_for_user: bool = True,
) -> None: ) -> None:
@ -63,7 +65,7 @@ class ASUpdater:
] ]
else: else:
self.steps = steps self.steps = steps
self.refactor = refactor self.copy_translated = copy_translated
self.differ_no_auto_apply = differ_no_auto_apply self.differ_no_auto_apply = differ_no_auto_apply
self.arch_dir = get_path("{CS_ARCH_MODULE_DIR}").joinpath(self.arch) self.arch_dir = get_path("{CS_ARCH_MODULE_DIR}").joinpath(self.arch)
if not self.no_clean_build: if not self.no_clean_build:
@ -72,12 +74,16 @@ class ASUpdater:
self.arch, self.arch,
self.inc_list, self.inc_list,
) )
with open(get_path("{MCUPDATER_CONFIG_FILE}")) as f:
self.mcupdater_conf = json.loads(f.read())
self.mc_updater = MCUpdater( self.mc_updater = MCUpdater(
self.arch, self.arch,
get_path("{LLVM_MC_TEST_DIR}"), get_path("{LLVM_MC_TEST_DIR}"),
None, None,
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: def clean_build_dir(self) -> None:
@ -108,10 +114,10 @@ class ASUpdater:
if self.arch == "AArch64": if self.arch == "AArch64":
# Update the compatibility header # Update the compatibility header
builder = CompatHeaderBuilder( builder = CompatHeaderBuilder(
aarch64_h=main_header, v6=main_header,
arm64_h=get_path("{CS_INCLUDE_DIR}").joinpath(f"arm64.h"), v5=get_path("{CS_INCLUDE_DIR}").joinpath(f"arm64.h"),
) )
builder.generate_aarch64_compat_header() builder.generate_v5_compat_header()
return patched return patched
def copy_files(self, path: Path, dest: Path) -> None: def copy_files(self, path: Path, dest: Path) -> None:
@ -173,36 +179,44 @@ class ASUpdater:
self.diff() self.diff()
if USteps.MC in self.steps: if USteps.MC in self.steps:
self.mc_updater.gen_all() self.mc_updater.gen_all()
if self.write: if not self.write:
# Copy .inc files # Done
log.info(f"Copy .inc files to {self.arch_dir}") exit(0)
i = 0
arch_header = get_path("{CS_INCLUDE_DIR}").joinpath( # Copy .inc files
f"{self.arch.lower()}.h" log.info(f"Copy .inc files to {self.arch_dir}")
) i = 0
for file in get_path("{C_INC_OUT_DIR}").iterdir(): arch_header = get_path("{CS_INCLUDE_DIR}").joinpath(f"{self.arch.lower()}.h")
if HeaderPatcher.file_in_main_header(arch_header, file.name): for file in get_path("{C_INC_OUT_DIR}").iterdir():
continue 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) self.copy_files(file, self.arch_dir)
i += 1 i += 1
log.info(f"Copied {i} files") else:
i = 0
# Diffed files # Diffed files
log.info(f"Copy diffed files to {self.arch_dir}") log.info(f"Copy diffed files to {self.arch_dir}")
for file in get_path("{CPP_TRANSLATOR_DIFF_OUT_DIR}").iterdir(): for file in get_path("{CPP_TRANSLATOR_DIFF_OUT_DIR}").iterdir():
self.copy_files(file, self.arch_dir) self.copy_files(file, self.arch_dir)
i += 1 i += 1
log.info(f"Copied {i} files") log.info(f"Copied {i} files")
# MC tests # MC tests
i = 0 i = 0
mc_dir = get_path("{MC_DIR}").joinpath(self.arch) mc_dir = get_path("{MC_DIR}").joinpath(self.arch)
log.info(f"Copy MC test files to {mc_dir}") log.info(f"Copy MC test files to {mc_dir}")
for file in get_path("{MCUPDATER_OUT_DIR}").iterdir(): for file in get_path("{MCUPDATER_OUT_DIR}").iterdir():
self.copy_files(file, mc_dir) self.copy_files(file, mc_dir)
i += 1 i += 1
log.info(f"Copied {i} files") log.info(f"Copied {i} files")
exit(0) exit(0)
@ -216,7 +230,7 @@ def parse_args() -> argparse.Namespace:
"-a", "-a",
dest="arch", dest="arch",
help="Name of target architecture.", help="Name of target architecture.",
choices=["ARM", "PPC", "AArch64", "Alpha", "LoongArch", "Mips"], choices=ARCH_LLVM_NAMING,
required=True, required=True,
) )
parser.add_argument( parser.add_argument(
@ -278,9 +292,9 @@ def parse_args() -> argparse.Namespace:
default=["All"], default=["All"],
) )
parser.add_argument( parser.add_argument(
"--refactor", "--copy-translated",
dest="refactor", dest="copy_translated",
help="Sets change update behavior to ease refactoring and new implementations.", help="Copy the translated files and not the files produced by the Differ.",
action="store_true", action="store_true",
) )
parser.add_argument( parser.add_argument(
@ -293,9 +307,7 @@ def parse_args() -> argparse.Namespace:
return arguments return arguments
if __name__ == "__main__": def main():
check_py_version()
args = parse_args() args = parse_args()
log.basicConfig( log.basicConfig(
level=convert_loglevel(args.verbosity), level=convert_loglevel(args.verbosity),
@ -310,8 +322,12 @@ if __name__ == "__main__":
args.steps, args.steps,
args.inc_list, args.inc_list,
args.no_clean, args.no_clean,
args.refactor, args.copy_translated,
args.no_auto_apply, args.no_auto_apply,
args.wait_for_user, args.wait_for_user,
) )
Updater.update() Updater.update()
if __name__ == "__main__":
main()

View File

@ -18,10 +18,10 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--header", dest="header", help="Path header file.", type=Path) 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("--inc", dest="inc", help="Path inc file.", type=Path)
parser.add_argument( 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( 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( parser.add_argument(
"-c", dest="compat", help="Generate compatibility header", action="store_true" "-c", dest="compat", help="Generate compatibility header", action="store_true"
@ -120,78 +120,98 @@ class HeaderPatcher:
class CompatHeaderBuilder: 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): def replace_typedef_struct(self, v6_lines: list[str]) -> list[str]:
self.aarch64_h = aarch64_h
self.arm64_h = arm64_h
def replace_typedef_struct(self, aarch64_lines: list[str]) -> list[str]:
output = list() output = list()
typedef = "" typedef = ""
for line in aarch64_lines: for line in v6_lines:
if typedef: if typedef:
if not re.search(r"^}\s[\w_]+;", line): if not re.search(r"^}\s[\w_]+;", line):
# Skip struct content # Skip struct content
continue continue
type_name = re.findall(r"[\w_]+", line)[0] type_name = re.findall(r"[\w_]+", line)[0]
output.append( 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 = "" typedef = ""
continue continue
if re.search(f"^typedef\s+(struct|union)", line): if re.search(rf"^typedef\s+(struct|union)", line):
typedef = line typedef = line
continue continue
output.append(line) output.append(line)
return output 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() output = list()
typedef = "" typedef = ""
for line in aarch64_lines: for line in v6_lines:
if typedef: if typedef:
if not re.search(r"^}\s[\w_]+;", line): if not re.search(r"^}\s[\w_]+;", line):
# Replace name # 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) output.append(line)
continue 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]) entry_name: str = "".join(found[0])
arm64_name = entry_name.replace("AArch64", "ARM64").replace( v5_name = entry_name.replace(self.v6_camel, self.v6_camel).replace(
"AARCH64", "ARM64" self.v6_upper, self.v5_upper
) )
patched_line = re.sub( 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) output.append(patched_line)
continue continue
# We still have LLVM and CS naming conventions mixed # We still have LLVM and CS naming conventions mixed
p = re.sub(r"aarch64", "arm64", line) p = re.sub(self.v6_lower, self.v5_lower, line)
p = re.sub(r"(AArch64|AARCH64)", "ARM64", p) p = re.sub(rf"({self.v6_camel}|{self.v6_upper})", self.v5_upper, p)
output.append(p) output.append(p)
typedef = "" typedef = ""
continue continue
if re.search(f"^typedef\s+enum", line): if re.search(rf"^typedef\s+enum", line):
typedef = line typedef = line
output.append("typedef enum {\n") output.append("typedef enum {\n")
continue continue
output.append(line) output.append(line)
return output return output
def remove_comments(self, aarch64_lines: list[str]) -> list[str]: def remove_comments(self, v6_lines: list[str]) -> list[str]:
output = list() output = list()
for line in aarch64_lines: for line in v6_lines:
if re.search(r"^\s*//", line) and "// SPDX" not in line: if re.search(r"^\s*//", line) and "// SPDX" not in line:
continue continue
output.append(line) output.append(line)
return output 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() output = list()
in_typedef = False 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 in_typedef:
if re.search(r"^}\s[\w_]+;", line): if re.search(r"^}\s[\w_]+;", line):
in_typedef = False in_typedef = False
@ -202,46 +222,61 @@ class CompatHeaderBuilder:
in_typedef = True in_typedef = True
output.append(line) output.append(line)
continue 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 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() 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): if not re.search(r"^#(ifndef|define)", line):
output.append(line) output.append(line)
continue continue
output.append(re.sub(r"AARCH64", "ARM64", line)) output.append(re.sub(self.v6_upper, self.v5_upper, line))
return output 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() output = list()
header_inserted = False header_inserted = False
for line in aarch64_lines: for line in v6_lines:
if re.search(r"^#include", line): if re.search(r"^#include", line):
if not header_inserted: if not header_inserted:
output.append("#include <capstone/aarch64.h>\n") output.append(f"#include <capstone/{self.v6_lower}.h>\n")
header_inserted = True header_inserted = True
output.append(line) output.append(line)
return output 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. Translates the aarch64.h header into the arm64.h header and renames all aarch64 occurrences.
It does simple regex matching and replacing. 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") log.info("Generate compatibility header")
with open(self.aarch64_h) as f: with open(self.v6) as f:
aarch64 = f.readlines() 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.replace_typedef_enum(patched)
patched = self.remove_comments(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.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) f.writelines(patched)
@ -250,10 +285,8 @@ if __name__ == "__main__":
if (not args.patch and not args.compat) or (args.patch and args.compat): if (not args.patch and not args.compat) or (args.patch and args.compat):
print("You need to specify either -c or -p") print("You need to specify either -c or -p")
exit(1) exit(1)
if args.compat and not (args.aarch64 and args.arm64): if args.compat and not (args.v6 and args.v5):
print( print("Generating the v5 compatibility header requires --v5 and --v6")
"Generating the arm64 compatibility header requires --arm64 and --aarch64"
)
exit(1) exit(1)
if args.patch and not (args.inc and args.header): if args.patch and not (args.inc and args.header):
print("Patching headers requires --inc and --header") print("Patching headers requires --inc and --header")
@ -264,5 +297,12 @@ if __name__ == "__main__":
patcher.patch_header() patcher.patch_header()
exit(0) exit(0)
builder = CompatHeaderBuilder(args.aarch64, args.arm64) if "aarch64" in args.v6.name:
builder.generate_aarch64_compat_header() 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()

View File

@ -168,9 +168,3 @@ def fail_exit(msg: str) -> None:
"""Logs a fatal message and exits with error code 1.""" """Logs a fatal message and exits with error code 1."""
log.fatal(msg) log.fatal(msg)
exit(1) exit(1)
def check_py_version() -> None:
if not sys.hexversion >= 0x030B00F0:
log.fatal("Python >= v3.11 required.")
exit(1)

View File

@ -4,6 +4,7 @@
# SPDX-License-Identifier: BSD-3 # SPDX-License-Identifier: BSD-3
import logging as log import logging as log
import json
import os import os
import re import re
import shutil import shutil
@ -12,58 +13,6 @@ from pathlib import Path
from autosync.Helper import fail_exit, get_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: class IncGenerator:
def __init__(self, arch: str, inc_list: list) -> None: 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.llvm_tblgen: Path = get_path("{LLVM_TBLGEN_BIN}")
self.output_dir_c_inc = get_path("{C_INC_OUT_DIR}") self.output_dir_c_inc = get_path("{C_INC_OUT_DIR}")
self.output_dir_cpp_inc = get_path("{CPP_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() self.check_paths()
def check_paths(self) -> None: def check_paths(self) -> None:
@ -133,7 +84,7 @@ class IncGenerator:
shutil.move(sys_ops_table_file, new_sys_ops_file) shutil.move(sys_ops_table_file, new_sys_ops_file)
def gen_incs(self) -> None: 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: if "All" not in self.inc_list and table["name"] not in self.inc_list:
log.debug(f"Skip {table['name']} generation") log.debug(f"Skip {table['name']} generation")
continue continue

View File

@ -20,13 +20,15 @@ class LLVM_MC_Command:
self.cmd: str = "" self.cmd: str = ""
self.opts: str = "" self.opts: str = ""
self.file: Path | None = None 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) self.cmd, self.opts, self.file = self.parse_llvm_mc_line(cmd_line)
if not (self.cmd and self.opts and self.file): if not (self.cmd and self.opts and self.file):
log.warning(f"Could not parse llvm-mc command: {cmd_line}") log.warning(f"Could not parse llvm-mc command: {cmd_line}")
elif not "--show-encoding" in self.cmd: elif not "--show-encoding" in self.cmd:
self.cmd = re.sub("llvm-mc", "llvm-mc --show-encoding", 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]: def parse_llvm_mc_line(self, line: str) -> tuple[str, str, Path]:
test_file_base_dir = str(get_path("{LLVM_LIT_TEST_DIR}").absolute()) 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 "" opts = ",".join([m.group(2) for m in arch]) if arch else ""
if mattr: if mattr:
opts += "" if not opts else "," 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) return cmd, opts, Path(test_file)
def exec(self) -> sp.CompletedProcess: def exec(self) -> sp.CompletedProcess:
with open(self.file, "b+r") as f: with open(self.file, "b+r") as f:
content = f.read() content = f.read()
if self.mattr: if self.additional_mattr:
# If mattr exists, patch it into the cmd # If mattr exists, patch it into the cmd
if "mattr" in self.cmd: if "mattr" in self.cmd:
self.cmd = re.sub( 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: 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}") log.debug(f"Run: {self.cmd}")
result = sp.run(self.cmd.split(" "), input=content, capture_output=True) 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): def __init__(self, arch: str, opts: list[str], encoding: str, asm_text: str):
self.arch = arch self.arch = arch
if arch.lower() in ["arm", "powerpc", "ppc", "aarch64"]: self.opts = opts
# Arch and PPC require this option for MC tests.
self.opts = ["CS_OPT_NO_BRANCH_OFFSET"] + opts
else:
self.opts = opts
self.encoding: list[str] = [encoding] self.encoding: list[str] = [encoding]
self.asm_text: list[str] = [asm_text] self.asm_text: list[str] = [asm_text]
@ -263,7 +267,7 @@ class MCUpdater:
else "" else ""
) )
# A list of options which are always added. # A list of options which are always added.
self.mandatory_options: str = ( self.mandatory_options: list[str] = (
self.conf["mandatory_options"][self.arch] self.conf["mandatory_options"][self.arch]
if self.arch in self.conf["mandatory_options"] if self.arch in self.conf["mandatory_options"]
else list() else list()
@ -274,13 +278,15 @@ class MCUpdater:
else list() else list()
) )
self.remove_options = [x.lower() for x in self.remove_options] 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] self.conf["replace_option_map"][self.arch]
if self.arch in self.conf["replace_option_map"] if self.arch in self.conf["replace_option_map"]
else {} else {}
) )
self.replace_option_map = { 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 self.multi_mode = multi_mode
@ -297,12 +303,14 @@ class MCUpdater:
) )
def write_to_build_dir(self): def write_to_build_dir(self):
no_tests_file = 0
file_cnt = 0 file_cnt = 0
test_cnt = 0 test_cnt = 0
overwritten = 0 overwritten = 0
files_written = set() files_written = set()
for test in sorted(self.test_files): for test in sorted(self.test_files):
if not test.has_tests(): if not test.has_tests():
no_tests_file += 1
continue continue
file_cnt += 1 file_cnt += 1
test_cnt += test.num_test_cases() test_cnt += test.num_test_cases()
@ -332,7 +340,7 @@ class MCUpdater:
f"The following file exists already: {filename}\n" f"The following file exists already: {filename}\n"
"This is not allowed in multi-mode." "This is not allowed in multi-mode."
) )
else: elif not self.multi_mode and filename.exists():
log.debug(f"Overwrite: {filename}") log.debug(f"Overwrite: {filename}")
overwritten += 1 overwritten += 1
with open(filename, write_mode) as f: with open(filename, write_mode) as f:
@ -340,7 +348,10 @@ class MCUpdater:
log.debug(f"Write {filename}") log.debug(f"Write {filename}")
files_written.add(filename) files_written.add(filename)
log.info( 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: if overwritten > 0:
log.warning( log.warning(
@ -544,4 +555,5 @@ if __name__ == "__main__":
args.excluded_files, args.excluded_files,
args.included_files, args.included_files,
args.unified_tests, args.unified_tests,
True,
).gen_all() ).gen_all()

View File

@ -1,4 +1,27 @@
# Copyright © 2024 Rot127 <unisono@quyllur.org> # Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3 # 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",
}

View File

@ -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

View File

@ -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"

View File

@ -15,10 +15,6 @@ class TestHeaderPatcher(unittest.TestCase):
get_path("{HEADER_PATCHER_TEST_INC_FILE}"), get_path("{HEADER_PATCHER_TEST_INC_FILE}"),
write_file=False, 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): def test_header_patching(self):
self.hpatcher.patch_header() self.hpatcher.patch_header()
@ -50,9 +46,26 @@ class TestHeaderPatcher(unittest.TestCase):
), ),
) )
def test_compat_header_gen(self): def test_compat_header_gen_arm64(self):
self.compat_gen.generate_aarch64_compat_header() 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: with open(get_path("{HEADER_GEN_TEST_ARM64_FILE}")) as f:
correct = f.read() correct = f.read()
with open(get_path("{HEADER_GEN_TEST_ARM64_OUT_FILE}")) as f: with open(get_path("{HEADER_GEN_TEST_ARM64_OUT_FILE}")) as f:
self.assertEqual(f.read(), correct) 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)

View File

@ -3,10 +3,12 @@
import logging import logging
import os import os
import shutil
import sys import sys
import unittest import unittest
from pathlib import Path from pathlib import Path
from threading import Lock
from autosync.Helper import get_path, test_only_overwrite_path_var from autosync.Helper import get_path, test_only_overwrite_path_var
from autosync.MCUpdater import MCUpdater from autosync.MCUpdater import MCUpdater
@ -20,22 +22,34 @@ class TestHeaderPatcher(unittest.TestCase):
format="%(levelname)-5s - %(message)s", format="%(levelname)-5s - %(message)s",
force=True, 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): def test_test_case_gen(self):
""" """
To enforce sequential execution of the tests, we execute them in here. To enforce sequential execution of the tests, we execute them in here.
And don't make them a separated test. And don't make them a separated test.
""" """
self.assertTrue(self.unified_test_cases(), "Failed: unified_test_cases") with self.mutex:
self.assertTrue(self.separated_test_cases(), "Failed: separated_test_cases") self.assertTrue(self.unified_test_cases(), "Failed: unified_test_cases")
self.assertTrue( self.assertTrue(self.separated_test_cases(), "Failed: separated_test_cases")
self.multi_mode_unified_test_cases(), self.assertTrue(
"Failed: multi_mode_unified_test_cases", self.multi_mode_unified_test_cases(),
) "Failed: multi_mode_unified_test_cases",
self.assertTrue( )
self.multi_mode_separated_test_cases(), self.assertTrue(
"Failed: multi_mode_separated_test_cases", self.multi_mode_separated_test_cases(),
) "Failed: multi_mode_separated_test_cases",
)
def unified_test_cases(self): def unified_test_cases(self):
out_dir = Path( out_dir = Path(
@ -44,8 +58,7 @@ class TestHeaderPatcher(unittest.TestCase):
if not out_dir.exists(): if not out_dir.exists():
out_dir.mkdir(parents=True) out_dir.mkdir(parents=True)
for file in out_dir.iterdir(): for file in out_dir.iterdir():
logging.debug(f"Delete old file: {file}") self.del_path(file)
os.remove(file)
test_only_overwrite_path_var( test_only_overwrite_path_var(
"{MCUPDATER_OUT_DIR}", "{MCUPDATER_OUT_DIR}",
out_dir, out_dir,
@ -63,8 +76,7 @@ class TestHeaderPatcher(unittest.TestCase):
if not out_dir.exists(): if not out_dir.exists():
out_dir.mkdir(parents=True) out_dir.mkdir(parents=True)
for file in out_dir.iterdir(): for file in out_dir.iterdir():
logging.debug(f"Delete old file: {file}") self.del_path(file)
os.remove(file)
test_only_overwrite_path_var( test_only_overwrite_path_var(
"{MCUPDATER_OUT_DIR}", "{MCUPDATER_OUT_DIR}",
out_dir, out_dir,
@ -82,8 +94,7 @@ class TestHeaderPatcher(unittest.TestCase):
if not out_dir.exists(): if not out_dir.exists():
out_dir.mkdir(parents=True) out_dir.mkdir(parents=True)
for file in out_dir.iterdir(): for file in out_dir.iterdir():
logging.debug(f"Delete old file: {file}") self.del_path(file)
os.remove(file)
test_only_overwrite_path_var( test_only_overwrite_path_var(
"{MCUPDATER_OUT_DIR}", "{MCUPDATER_OUT_DIR}",
out_dir, out_dir,
@ -108,8 +119,7 @@ class TestHeaderPatcher(unittest.TestCase):
if not out_dir.exists(): if not out_dir.exists():
out_dir.mkdir(parents=True) out_dir.mkdir(parents=True)
for file in out_dir.iterdir(): for file in out_dir.iterdir():
logging.debug(f"Delete old file: {file}") self.del_path(file)
os.remove(file)
test_only_overwrite_path_var( test_only_overwrite_path_var(
"{MCUPDATER_OUT_DIR}", "{MCUPDATER_OUT_DIR}",
out_dir, out_dir,
@ -128,28 +138,57 @@ class TestHeaderPatcher(unittest.TestCase):
) )
def test_no_symbol_tests(self): def test_no_symbol_tests(self):
out_dir = Path(get_path("{MCUPDATER_TEST_OUT_DIR}").joinpath("no_symbol")) with self.mutex:
if not out_dir.exists(): out_dir = Path(get_path("{MCUPDATER_TEST_OUT_DIR}").joinpath("no_symbol"))
out_dir.mkdir(parents=True) if not out_dir.exists():
for file in out_dir.iterdir(): out_dir.mkdir(parents=True)
logging.debug(f"Delete old file: {file}") for file in out_dir.iterdir():
os.remove(file) self.del_path(file)
test_only_overwrite_path_var( test_only_overwrite_path_var(
"{MCUPDATER_OUT_DIR}", "{MCUPDATER_OUT_DIR}",
out_dir, out_dir,
) )
self.updater = MCUpdater( self.updater = MCUpdater(
"ARCH", "ARCH",
get_path("{MCUPDATER_TEST_DIR}"), get_path("{MCUPDATER_TEST_DIR}"),
[], [],
[], [],
False, False,
) )
self.updater.gen_all() self.updater.gen_all()
self.assertFalse( self.assertFalse(
out_dir.joinpath("test_no_symbol.s.txt.yaml").exists(), out_dir.joinpath("test_no_symbol.s.txt.yaml").exists(),
"File should not exist", "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: def compare_files(self, out_dir: Path, filenames: list[str]) -> bool:
if not out_dir.is_dir(): if not out_dir.is_dir():
@ -159,11 +198,13 @@ class TestHeaderPatcher(unittest.TestCase):
parent_name = out_dir.parent.name parent_name = out_dir.parent.name
expected_dir = ( expected_dir = (
get_path("{MCUPDATER_TEST_DIR_EXPECTED}") get_path("{MCUPDATER_TEST_DIR_EXPECTED}")
.joinpath(parent_name) # Dirty for now. Sorry.
.joinpath(out_dir.name) .joinpath(parent_name if parent_name != "test_output" else "").joinpath(
out_dir.name
)
) )
if not expected_dir.exists() or not expected_dir.is_dir(): 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 return False
for file in filenames: for file in filenames:
efile = expected_dir.joinpath(file) efile = expected_dir.joinpath(file)

View 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

View 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;

View File

@ -6,6 +6,7 @@
import argparse import argparse
import logging as log import logging as log
import sys import sys
import re
from pathlib import Path from pathlib import Path
import termcolor import termcolor
@ -87,6 +88,7 @@ from autosync.Helper import (
print_prominent_warning, print_prominent_warning,
run_clang_format, run_clang_format,
) )
from autosync.cpptranslator.patches.isUInt import IsUInt
class Translator: class Translator:
@ -136,6 +138,7 @@ class Translator:
CreateOperand0.__name__: 0, # ◁───┐ `CreateOperand0` removes most calls to MI.addOperand(). CreateOperand0.__name__: 0, # ◁───┐ `CreateOperand0` removes most calls to MI.addOperand().
AddOperand.__name__: 1, # ────────┘ The ones left are fixed with the `AddOperand` patch. AddOperand.__name__: 1, # ────────┘ The ones left are fixed with the `AddOperand` patch.
CreateOperand1.__name__: 0, CreateOperand1.__name__: 0,
IsUInt.__name__: 0,
GetOpcode.__name__: 0, GetOpcode.__name__: 0,
SetOpcode.__name__: 0, SetOpcode.__name__: 0,
GetOperand.__name__: 0, GetOperand.__name__: 0,
@ -248,6 +251,8 @@ class Translator:
patch = CreateOperand0(p) patch = CreateOperand0(p)
case CreateOperand1.__name__: case CreateOperand1.__name__:
patch = CreateOperand1(p) patch = CreateOperand1(p)
case IsUInt.__name__:
patch = IsUInt(p)
case GetOpcode.__name__: case GetOpcode.__name__:
patch = GetOpcode(p) patch = GetOpcode(p)
case SetOpcode.__name__: case SetOpcode.__name__:
@ -391,6 +396,17 @@ class Translator:
file_constraints = apply_only_to[patch_name] file_constraints = apply_only_to[patch_name]
if self.current_src_path_in.name in file_constraints["files"]: if self.current_src_path_in.name in file_constraints["files"]:
return True 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 return False
def translate(self) -> None: def translate(self) -> None:

View File

@ -16,6 +16,7 @@ from shutil import copy2
from tree_sitter import Language, Node, Parser, Tree from tree_sitter import Language, Node, Parser, Tree
from autosync.Targets import ARCH_LLVM_NAMING
from autosync.cpptranslator.Configurator import Configurator from autosync.cpptranslator.Configurator import Configurator
from autosync.Helper import ( from autosync.Helper import (
bold, bold,
@ -925,7 +926,7 @@ def parse_args() -> argparse.Namespace:
"-a", "-a",
dest="arch", dest="arch",
help="Name of target architecture (ignored with -t option)", help="Name of target architecture (ignored with -t option)",
choices=["ARM", "PPC", "AArch64", "Alpha", "LoongArch", "Mips"], choices=ARCH_LLVM_NAMING,
required=True, required=True,
) )
parser.add_argument( parser.add_argument(

Some files were not shown because too many files have changed in this diff Show More