diff --git a/.gitignore b/.gitignore index 6cb022340..c6c407298 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,7 @@ tests/test_evm tests/test_wasm tests/test_mos65xx tests/test_bpf +tests/test_riscv # regress binaries suite/regress/invalid_read_in_print_operand diff --git a/CMakeLists.txt b/CMakeLists.txt index 25a2f8d25..1114f048f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ option(CAPSTONE_BUILD_TESTS "Build tests" ON) option(CAPSTONE_BUILD_CSTOOL "Build cstool" ON) option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON) -set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF) -set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF) +set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM RISCV MOS65XX WASM BPF) +set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM RISCV MOS65XX WASM BPF) list(LENGTH SUPPORTED_ARCHITECTURES count) math(EXPR count "${count}-1") @@ -111,6 +111,7 @@ set(HEADERS_COMMON include/capstone/sparc.h include/capstone/systemz.h include/capstone/xcore.h + include/capstone/riscv.h include/capstone/m68k.h include/capstone/tms320c64x.h include/capstone/m680x.h @@ -443,6 +444,31 @@ if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_EVM_SUPPORT) set(TEST_SOURCES ${TEST_SOURCES} test_evm.c) endif () +if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_RISCV_SUPPORT) + add_definitions(-DCAPSTONE_HAS_RISCV) + set(SOURCES_RISCV + arch/RISCV/RISCVDisassembler.c + arch/RISCV/RISCVInstPrinter.c + arch/RISCV/RISCVMapping.c + arch/RISCV/RISCVModule.c + ) + set(HEADERS_RISCV + arch/RISCV/RISCVBaseInfo.h + arch/RISCV/RISCVDisassembler.h + arch/RISCV/RISCVGenAsmWriter.inc + arch/RISCV/RISCVGenDisassemblerTables.inc + arch/RISCV/RISCVGenInsnNameMaps.inc + arch/RISCV/RISCVGenInstrInfo.inc + arch/RISCV/RISCVGenRegisterInfo.inc + arch/RISCV/RISCVGenSubtargetInfo.inc + arch/RISCV/RISCVInstPrinter.h + arch/RISCV/RISCVMapping.h + arch/RISCV/RISCVModule.h + arch/RISCV/RISCVMappingInsn.inc + ) + set(TEST_SOURCES ${TEST_SOURCES} test_riscv.c) +endif () + if (NOT CAPSTONE_X86_ONLY AND CAPSTONE_WASM_SUPPORT) add_definitions(-DCAPSTONE_HAS_WASM) set(SOURCES_WASM @@ -506,6 +532,7 @@ set(ALL_SOURCES ${SOURCES_TMS320C64X} ${SOURCES_M680X} ${SOURCES_EVM} + ${SOURCES_RISCV} ${SOURCES_WASM} ${SOURCES_MOS65XX} ${SOURCES_BPF} @@ -526,6 +553,7 @@ set(ALL_HEADERS ${HEADERS_TMS320C64X} ${HEADERS_M680X} ${HEADERS_EVM} + ${HEADERS_RISCV} ${HEADERS_WASM} ${HEADERS_MOS65XX} ${HEADERS_BPF} @@ -609,10 +637,10 @@ source_group("Source\\M68K" FILES ${SOURCES_M68K}) source_group("Source\\TMS320C64x" FILES ${SOURCES_TMS320C64X}) source_group("Source\\M680X" FILES ${SOURCES_M680X}) source_group("Source\\EVM" FILES ${SOURCES_EVM}) +source_group("Source\\RISCV" FILES ${SOURCES_RISCV}) source_group("Source\\WASM" FILES ${SOURCES_WASM}) source_group("Source\\MOS65XX" FILES ${SOURCES_MOS65XX}) source_group("Source\\BPF" FILES ${SOURCES_BPF}) - source_group("Include\\Common" FILES ${HEADERS_COMMON}) source_group("Include\\Engine" FILES ${HEADERS_ENGINE}) source_group("Include\\ARM" FILES ${HEADERS_ARM}) @@ -627,6 +655,7 @@ source_group("Include\\M68K" FILES ${HEADERS_M68K}) source_group("Include\\TMS320C64x" FILES ${HEADERS_TMS320C64X}) source_group("Include\\M680X" FILES ${HEADERS_MC680X}) source_group("Include\\EVM" FILES ${HEADERS_EVM}) +source_group("Include\\RISCV" FILES ${HEADERS_RISCV}) source_group("Include\\WASM" FILES ${HEADERS_WASM}) source_group("Include\\MOS65XX" FILES ${HEADERS_MOS65XX}) source_group("Include\\BPF" FILES ${HEADERS_BPF}) diff --git a/CREDITS.TXT b/CREDITS.TXT index f0e8efc2e..be3d5f8ea 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -82,3 +82,4 @@ Sebastian Macke: MOS65XX architecture Ilya Leoshkevich: SystemZ architecture improvements. Do Minh Tuan: Regression testing tool (cstest) david942j: BPF (both classic and extended) architecture. +fanfuqiang & citypw & porto703 : RISCV architecture. diff --git a/MCFixedLenDisassembler.h b/MCFixedLenDisassembler.h index 9e13efe78..20f2dc97c 100644 --- a/MCFixedLenDisassembler.h +++ b/MCFixedLenDisassembler.h @@ -23,8 +23,8 @@ enum DecoderOps { // uleb128 Val, uint16_t NumToSkip) MCD_OPC_CheckPredicate, // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip) MCD_OPC_Decode, // OPC_Decode(uleb128 Opcode, uleb128 DIdx) - MCD_OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx, - // uint16_t NumToSkip) + MCD_OPC_TryDecode, // OPC_TryDecode(uleb128 Opcode, uleb128 DIdx, + // uint16_t NumToSkip) MCD_OPC_SoftFail, // OPC_SoftFail(uleb128 PMask, uleb128 NMask) MCD_OPC_Fail // OPC_Fail() }; diff --git a/Makefile b/Makefile index 84771ec42..ff240cf78 100644 --- a/Makefile +++ b/Makefile @@ -245,6 +245,16 @@ ifneq (,$(findstring evm,$(CAPSTONE_ARCHS))) LIBOBJ_EVM += $(LIBSRC_EVM:%.c=$(OBJDIR)/%.o) endif +DEP_RISCV = +DEP_RISCV += $(wildcard arch/RISCV/RISCV*.inc) + +LIBOBJ_RISCV = +ifneq (,$(findstring riscv,$(CAPSTONE_ARCHS))) + CFLAGS += -DCAPSTONE_HAS_RISCV + LIBSRC_RISCV += $(wildcard arch/RISCV/RISCV*.c) + LIBOBJ_RISCV += $(LIBSRC_RISCV:%.c=$(OBJDIR)/%.o) +endif + DEP_WASM = DEP_WASM += $(wildcard arch/WASM/WASM*.inc) @@ -280,7 +290,7 @@ endif LIBOBJ = LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o -LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) +LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF) LIBOBJ += $(OBJDIR)/MCInst.o @@ -410,6 +420,7 @@ $(LIBOBJ_XCORE): $(DEP_XCORE) $(LIBOBJ_TMS320C64X): $(DEP_TMS320C64X) $(LIBOBJ_M680X): $(DEP_M680X) $(LIBOBJ_EVM): $(DEP_EVM) +$(LIBOBJ_RISCV): $(DEP_RISCV) $(LIBOBJ_WASM): $(DEP_WASM) $(LIBOBJ_MOS65XX): $(DEP_MOS65XX) $(LIBOBJ_BPF): $(DEP_BPF) @@ -486,13 +497,12 @@ dist: git archive --format=tar.gz --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).tgz git archive --format=zip --prefix=capstone-$(DIST_VERSION)/ $(TAG) > capstone-$(DIST_VERSION).zip - -TESTS = test_basic test_detail test_arm test_arm64 test_m68k test_mips test_ppc test_sparc -TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_mos65xx test_wasm test_bpf +TESTS = test_basic test_detail test_arm test_arm64 test_m68k test_mips test_ppc test_sparc +TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_riscv test_mos65xx test_wasm test_bpf TESTS += test_basic.static test_detail.static test_arm.static test_arm64.static TESTS += test_m68k.static test_mips.static test_ppc.static test_sparc.static TESTS += test_systemz.static test_x86.static test_xcore.static test_m680x.static -TESTS += test_skipdata test_skipdata.static test_iter.static test_evm.static +TESTS += test_skipdata test_skipdata.static test_iter.static test_evm.static test_riscv.static TESTS += test_mos65xx.static test_wasm.static test_bpf.static check: $(TESTS) fuzztest fuzzallcorp test_%: diff --git a/README.md b/README.md index d18955233..b7fa58cd3 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,9 @@ disasm engine for binary analysis and reversing in the security community. Created by Nguyen Anh Quynh, then developed and maintained by a small community, Capstone offers some unparalleled features: -- Support multiple hardware architectures: ARM, ARM64 (ARMv8), BPF, Ethereum VM, Webassembly, M68K, - Mips, MOS65XX, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore and X86 (including X86_64). +- Support multiple hardware architectures: ARM, ARM64 (ARMv8), BPF, Ethereum VM, Webassembly, + M68K, Mips, MOS65XX, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore, RISC-V(rv32G/rv64G) + and X86 (including X86_64). - Having clean/simple/lightweight/intuitive architecture-neutral API. diff --git a/arch/RISCV/RISCVBaseInfo.h b/arch/RISCV/RISCVBaseInfo.h new file mode 100644 index 000000000..35ace5588 --- /dev/null +++ b/arch/RISCV/RISCVBaseInfo.h @@ -0,0 +1,106 @@ +//===-- RISCVBaseInfo.h - Top level definitions for RISCV MC ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone enum definitions for the RISCV target +// useful for the compiler back-end and the MC libraries. +// +//===----------------------------------------------------------------------===// +#ifndef CS_RISCVBASEINFO_H +#define CS_RISCVBASEINFO_H +#include + +//#include "RISCVMCTargetDesc.h" + +// RISCVII - This namespace holds all of the target specific flags that +// instruction info tracks. All definitions must match RISCVInstrFormats.td. +enum { + IRISCVII_InstFormatPseudo = 0, + IRISCVII_InstFormatR = 1, + IRISCVII_InstFormatR4 = 2, + IRISCVII_InstFormatI = 3, + IRISCVII_InstFormatS = 4, + IRISCVII_InstFormatB = 5, + IRISCVII_InstFormatU = 6, + IRISCVII_InstFormatJ = 7, + IRISCVII_InstFormatCR = 8, + IRISCVII_InstFormatCI = 9, + IRISCVII_InstFormatCSS = 10, + IRISCVII_InstFormatCIW = 11, + IRISCVII_InstFormatCL = 12, + IRISCVII_InstFormatCS = 13, + IRISCVII_InstFormatCA = 14, + IRISCVII_InstFormatCB = 15, + IRISCVII_InstFormatCJ = 16, + IRISCVII_InstFormatOther = 17, + + IRISCVII_InstFormatMask = 31 +}; + +enum { + RISCVII_MO_None, + RISCVII_MO_LO, + RISCVII_MO_HI, + RISCVII_MO_PCREL_HI, +}; + +// Describes the predecessor/successor bits used in the FENCE instruction. +enum FenceField { + RISCVFenceField_I = 8, + RISCVFenceField_O = 4, + RISCVFenceField_R = 2, + RISCVFenceField_W = 1 +}; + +// Describes the supported floating point rounding mode encodings. +enum RoundingMode { + RISCVFPRndMode_RNE = 0, + RISCVFPRndMode_RTZ = 1, + RISCVFPRndMode_RDN = 2, + RISCVFPRndMode_RUP = 3, + RISCVFPRndMode_RMM = 4, + RISCVFPRndMode_DYN = 7, + RISCVFPRndMode_Invalid +}; + +inline static const char *roundingModeToString(enum RoundingMode RndMode) +{ + switch (RndMode) { + default: + assert(0 && "Unknown floating point rounding mode"); + case RISCVFPRndMode_RNE: + return "rne"; + case RISCVFPRndMode_RTZ: + return "rtz"; + case RISCVFPRndMode_RDN: + return "rdn"; + case RISCVFPRndMode_RUP: + return "rup"; + case RISCVFPRndMode_RMM: + return "rmm"; + case RISCVFPRndMode_DYN: + return "dyn"; + } +} + +inline static bool RISCVFPRndMode_isValidRoundingMode(unsigned Mode) +{ + switch (Mode) { + default: + return false; + case RISCVFPRndMode_RNE: + case RISCVFPRndMode_RTZ: + case RISCVFPRndMode_RDN: + case RISCVFPRndMode_RUP: + case RISCVFPRndMode_RMM: + case RISCVFPRndMode_DYN: + return true; + } +} + +#endif diff --git a/arch/RISCV/RISCVDisassembler.c b/arch/RISCV/RISCVDisassembler.c new file mode 100644 index 000000000..4330a4a99 --- /dev/null +++ b/arch/RISCV/RISCVDisassembler.c @@ -0,0 +1,434 @@ +//===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +/* Capstone Disassembly Engine */ +/* RISC-V Backend By Rodrigo Cortes Porto & + Shawn Chang , HardenedLinux@2018 */ + +#ifdef CAPSTONE_HAS_RISCV + +#include // DEBUG +#include +#include + +#include "../../cs_priv.h" +#include "../../utils.h" + +#include "../../MCInst.h" +#include "../../MCInstrDesc.h" +#include "../../MCFixedLenDisassembler.h" +#include "../../MCRegisterInfo.h" +#include "../../MCDisassembler.h" +#include "../../MathExtras.h" +#include "RISCVBaseInfo.h" +#include "RISCVDisassembler.h" + + +/* Need the feature infos define in + RISCVGenSubtargetInfo.inc. */ +#define GET_SUBTARGETINFO_ENUM +#include "RISCVGenSubtargetInfo.inc" + +/* When we specify the RISCV64 mode, It means It is RV64IMAFD. + Similar, RISCV32 means RV32IMAFD. +*/ +static uint64_t getFeatureBits(int mode) +{ + if (mode == CS_MODE_RISCV32) + // return b11110 + return RISCV_FeatureStdExtM | RISCV_FeatureStdExtA | + RISCV_FeatureStdExtF | RISCV_FeatureStdExtD ; + else + + // CS_MODE_RISCV64, return b11111 + return RISCV_Feature64Bit | RISCV_FeatureStdExtM | + RISCV_FeatureStdExtA | RISCV_FeatureStdExtF | + RISCV_FeatureStdExtD ; +} + +#define GET_REGINFO_ENUM +#define GET_REGINFO_MC_DESC +#include "RISCVGenRegisterInfo.inc" +#define GET_INSTRINFO_ENUM +#include "RISCVGenInstrInfo.inc" + +static const unsigned GPRDecoderTable[] = { + RISCV_X0, RISCV_X1, RISCV_X2, RISCV_X3, + RISCV_X4, RISCV_X5, RISCV_X6, RISCV_X7, + RISCV_X8, RISCV_X9, RISCV_X10, RISCV_X11, + RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, + RISCV_X16, RISCV_X17, RISCV_X18, RISCV_X19, + RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23, + RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27, + RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31 +}; + +static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > sizeof(GPRDecoderTable)) + return MCDisassembler_Fail; + + // We must define our own mapping from RegNo to register identifier. + // Accessing index RegNo in the register class will work in the case that + // registers were added in ascending order, but not in general. + Reg = GPRDecoderTable[RegNo]; + //Inst.addOperand(MCOperand::createReg(Reg)); + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +static const unsigned FPR32DecoderTable[] = { + RISCV_F0_32, RISCV_F1_32, RISCV_F2_32, RISCV_F3_32, + RISCV_F4_32, RISCV_F5_32, RISCV_F6_32, RISCV_F7_32, + RISCV_F8_32, RISCV_F9_32, RISCV_F10_32, RISCV_F11_32, + RISCV_F12_32, RISCV_F13_32, RISCV_F14_32, RISCV_F15_32, + RISCV_F16_32, RISCV_F17_32, RISCV_F18_32, RISCV_F19_32, + RISCV_F20_32, RISCV_F21_32, RISCV_F22_32, RISCV_F23_32, + RISCV_F24_32, RISCV_F25_32, RISCV_F26_32, RISCV_F27_32, + RISCV_F28_32, RISCV_F29_32, RISCV_F30_32, RISCV_F31_32 +}; + +static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > sizeof(FPR32DecoderTable)) + return MCDisassembler_Fail; + + // We must define our own mapping from RegNo to register identifier. + // Accessing index RegNo in the register class will work in the case that + // registers were added in ascending order, but not in general. + Reg = FPR32DecoderTable[RegNo]; + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +static DecodeStatus DecodeFPR32CRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > 8) + return MCDisassembler_Fail; + Reg = FPR32DecoderTable[RegNo + 8]; + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +static const unsigned FPR64DecoderTable[] = { + RISCV_F0_64, RISCV_F1_64, RISCV_F2_64, RISCV_F3_64, + RISCV_F4_64, RISCV_F5_64, RISCV_F6_64, RISCV_F7_64, + RISCV_F8_64, RISCV_F9_64, RISCV_F10_64, RISCV_F11_64, + RISCV_F12_64, RISCV_F13_64, RISCV_F14_64, RISCV_F15_64, + RISCV_F16_64, RISCV_F17_64, RISCV_F18_64, RISCV_F19_64, + RISCV_F20_64, RISCV_F21_64, RISCV_F22_64, RISCV_F23_64, + RISCV_F24_64, RISCV_F25_64, RISCV_F26_64, RISCV_F27_64, + RISCV_F28_64, RISCV_F29_64, RISCV_F30_64, RISCV_F31_64 +}; + +static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > sizeof(FPR64DecoderTable)) + return MCDisassembler_Fail; + + // We must define our own mapping from RegNo to register identifier. + // Accessing index RegNo in the register class will work in the case that + // registers were added in ascending order, but not in general. + Reg = FPR64DecoderTable[RegNo]; + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +static DecodeStatus DecodeFPR64CRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > 8) + return MCDisassembler_Fail; + Reg = FPR64DecoderTable[RegNo + 8]; + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) +{ + if (RegNo == 0) + return MCDisassembler_Fail; + return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) +{ + if (RegNo == 2) + return MCDisassembler_Fail; + return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) +{ + unsigned Reg = 0; + + if (RegNo > 8) + return MCDisassembler_Fail; + + Reg = GPRDecoderTable[RegNo + 8]; + MCOperand_CreateReg0(Inst, Reg); + return MCDisassembler_Success; +} + +// Add implied SP operand for instructions *SP compressed instructions. The SP +// operand isn't explicitly encoded in the instruction. +static void addImplySP(MCInst *Inst, int64_t Address, const void *Decoder) +{ + if (MCInst_getOpcode(Inst) == RISCV_C_LWSP || + MCInst_getOpcode(Inst) == RISCV_C_SWSP || + MCInst_getOpcode(Inst) == RISCV_C_LDSP || + MCInst_getOpcode(Inst) == RISCV_C_SDSP || + MCInst_getOpcode(Inst) == RISCV_C_FLWSP || + MCInst_getOpcode(Inst) == RISCV_C_FSWSP || + MCInst_getOpcode(Inst) == RISCV_C_FLDSP || + MCInst_getOpcode(Inst) == RISCV_C_FSDSP || + MCInst_getOpcode(Inst) == RISCV_C_ADDI4SPN) { + DecodeGPRRegisterClass(Inst, 2, Address, Decoder); + } + + if (MCInst_getOpcode(Inst) == RISCV_C_ADDI16SP) { + DecodeGPRRegisterClass(Inst, 2, Address, Decoder); + DecodeGPRRegisterClass(Inst, 2, Address, Decoder); + } +} + +static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm, + int64_t Address, const void *Decoder, + unsigned N) +{ + //assert(isUInt(Imm) && "Invalid immediate"); + addImplySP(Inst, Address, Decoder); + //Inst.addOperand(MCOperand::createImm(Imm)); + MCOperand_CreateImm0(Inst, Imm); + return MCDisassembler_Success; +} + +static DecodeStatus decodeUImmNonZeroOperand(MCInst *Inst, uint64_t Imm, + int64_t Address, + const void *Decoder, + unsigned N) +{ + if (Imm == 0) + return MCDisassembler_Fail; + return decodeUImmOperand(Inst, Imm, Address, Decoder, N); +} + +static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, + int64_t Address, const void *Decoder, + unsigned N) +{ + //assert(isUInt(Imm) && "Invalid immediate"); + addImplySP(Inst, Address, Decoder); + // Sign-extend the number in the bottom N bits of Imm + //Inst.addOperand(MCOperand::createImm(SignExtend64(Imm))); + MCOperand_CreateImm0(Inst, SignExtend64(Imm, N)); + return MCDisassembler_Success; +} + +static DecodeStatus decodeSImmNonZeroOperand(MCInst *Inst, uint64_t Imm, + int64_t Address, + const void *Decoder, + unsigned N) +{ + if (Imm == 0) + return MCDisassembler_Fail; + return decodeSImmOperand(Inst, Imm, Address, Decoder, N); +} + +static DecodeStatus decodeSImmOperandAndLsl1(MCInst *Inst, uint64_t Imm, + int64_t Address, + const void *Decoder, + unsigned N) +{ + //assert(isUInt(Imm) && "Invalid immediate"); + // Sign-extend the number in the bottom N bits of Imm after accounting for + // the fact that the N bit immediate is stored in N-1 bits (the LSB is + // always zero) + //Inst.addOperand(MCOperand::createImm(SignExtend64(Imm << 1))); + MCOperand_CreateImm0(Inst, SignExtend64(Imm << 1, N)); + return MCDisassembler_Success; +} + +static DecodeStatus decodeCLUIImmOperand(MCInst *Inst, uint64_t Imm, + int64_t Address, + const void *Decoder) +{ + //assert(isUInt<6>(Imm) && "Invalid immediate"); + if (Imm > 31) { + Imm = (SignExtend64(Imm, 6) & 0xfffff); + } + //Inst.addOperand(MCOperand::createImm(Imm)); + MCOperand_CreateImm0(Inst, Imm); + return MCDisassembler_Success; +} + +static DecodeStatus decodeFRMArg(MCInst *Inst, uint64_t Imm, + int64_t Address, + const void *Decoder) +{ + //assert(isUInt<3>(Imm) && "Invalid immediate"); + if (!RISCVFPRndMode_isValidRoundingMode(Imm)) + return MCDisassembler_Fail; + + //Inst.addOperand(MCOperand::createImm(Imm)); + MCOperand_CreateImm0(Inst, Imm); + return MCDisassembler_Success; +} + + +#include "RISCVGenDisassemblerTables.inc" + +static void init_MI_insn_detail(MCInst *MI) +{ + if (MI->flat_insn->detail) { + memset(MI->flat_insn->detail, 0, sizeof(cs_detail)); + } + + return; +} + +// mark the load/store instructions through the opcode. +static void markLSInsn(MCInst *MI, uint32_t in) +{ + /* + I ld 0000011 = 0x03 + st 0100011 = 0x23 + F/D ld 0000111 = 0x07 + st 0100111 = 0x27 + */ +#define MASK_LS_INSN 0x0000007f + uint32_t opcode = in & MASK_LS_INSN; + if (0 == (opcode ^ 0x03) || 0 == (opcode ^ 0x07) || + 0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27)) + MI->flat_insn->detail->riscv.need_effective_addr = true; +#undef MASK_LS_INSN + return; +} + +static DecodeStatus RISCVDisassembler_getInstruction(int mode, MCInst *MI, + const uint8_t *code, size_t code_len, + uint16_t *Size, uint64_t Address, + MCRegisterInfo *MRI) +{ + // TODO: This will need modification when supporting instruction set + // extensions with instructions > 32-bits (up to 176 bits wide). + uint32_t Inst = 0; + DecodeStatus Result; + + // It's a 32 bit instruction if bit 0 and 1 are 1. + if ((code[0] & 0x3) == 0x3) { + if (code_len < 4) { + *Size = 0; + return MCDisassembler_Fail; + } + + *Size = 4; + // Get the four bytes of the instruction. + //Encoded as little endian 32 bits. + Inst = code[0] | (code[1] << 8) | (code[2] << 16) | ((uint32_t)code[3] << 24); + init_MI_insn_detail(MI); + // Now we need mark what instruction need fix effective address output. + if (MI->csh->detail) + markLSInsn(MI, Inst); + Result = decodeInstruction(DecoderTable32, MI, Inst, Address, MRI, mode); + } else { + if (code_len < 2) { + *Size = 0; + return MCDisassembler_Fail; + } + + // If not b4bit. + if (! (getFeatureBits(mode) & ((uint64_t)RISCV_Feature64Bit))) { + // Trying RISCV32Only_16 table (16-bit Instruction) + Inst = code[0] | (code[1] << 8); + init_MI_insn_detail(MI); + Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Inst, Address, + MRI, mode); + if (Result != MCDisassembler_Fail) { + *Size = 2; + return Result; + } + } + + // Trying RISCV_C table (16-bit Instruction) + Inst = code[0] | (code[1] << 8); + init_MI_insn_detail(MI); + // Calling the auto-generated decoder function. + Result = decodeInstruction(DecoderTable16, MI, Inst, Address, MRI, mode); + *Size = 2; + } + + return Result; +} + +bool RISCV_getInstruction(csh ud, const uint8_t *code, size_t code_len, + MCInst *instr, uint16_t *size, uint64_t address, + void *info) +{ + cs_struct *handle = (cs_struct *)(uintptr_t)ud; + + return MCDisassembler_Success == + RISCVDisassembler_getInstruction(handle->mode, instr, + code, code_len, + size, address, + (MCRegisterInfo *)info); + +} + +void RISCV_init(MCRegisterInfo * MRI) +{ + /* + InitMCRegisterInfo(RISCVRegDesc, 97, RA, PC, + RISCVMCRegisterClasses, 11, + RISCVRegUnitRoots, + 64, + RISCVRegDiffLists, + RISCVLaneMaskLists, + RISCVRegStrings, + RISCVRegClassStrings, + RISCVSubRegIdxLists, + 2, + RISCVSubRegIdxRanges, + RISCVRegEncodingTable); + */ + + MCRegisterInfo_InitMCRegisterInfo(MRI, RISCVRegDesc, 97, 0, 0, + RISCVMCRegisterClasses, 11, + 0, + 0, + RISCVRegDiffLists, + 0, + RISCVSubRegIdxLists, + 2, + 0); +} + +#endif diff --git a/arch/RISCV/RISCVDisassembler.h b/arch/RISCV/RISCVDisassembler.h new file mode 100644 index 000000000..1cb70ea7c --- /dev/null +++ b/arch/RISCV/RISCVDisassembler.h @@ -0,0 +1,18 @@ +/* Capstone Disassembly Engine */ +/* RISC-V Backend By Rodrigo Cortes Porto & + Shawn Chang , HardenedLinux@2018 */ + +#ifndef CS_RISCVDISASSEMBLER_H +#define CS_RISCVDISASSEMBLER_H + +#include "../../include/capstone/capstone.h" +#include "../../MCRegisterInfo.h" +#include "../../MCInst.h" + +void RISCV_init(MCRegisterInfo *MRI); + +bool RISCV_getInstruction(csh ud, const uint8_t *code, size_t code_len, + MCInst *instr, uint16_t *size, uint64_t address, + void *info); + +#endif diff --git a/arch/RISCV/RISCVGenAsmWriter.inc b/arch/RISCV/RISCVGenAsmWriter.inc new file mode 100644 index 000000000..b9781f843 --- /dev/null +++ b/arch/RISCV/RISCVGenAsmWriter.inc @@ -0,0 +1,2638 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Assembly Writer Source Fragment *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2015 */ + +#include // debug +#include +#include + + +/// printInstruction - This method is automatically generated by tablegen +/// from the instruction set description. +static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI) +{ +#ifndef CAPSTONE_DIET + static const char AsmStrs[] = { + /* 0 */ 'l', 'l', 'a', 9, 0, + /* 5 */ 's', 'f', 'e', 'n', 'c', 'e', '.', 'v', 'm', 'a', 9, 0, + /* 17 */ 's', 'r', 'a', 9, 0, + /* 22 */ 'l', 'b', 9, 0, + /* 26 */ 's', 'b', 9, 0, + /* 30 */ 'c', '.', 's', 'u', 'b', 9, 0, + /* 37 */ 'a', 'u', 'i', 'p', 'c', 9, 0, + /* 44 */ 'c', 's', 'r', 'r', 'c', 9, 0, + /* 51 */ 'f', 's', 'u', 'b', '.', 'd', 9, 0, + /* 59 */ 'f', 'm', 's', 'u', 'b', '.', 'd', 9, 0, + /* 68 */ 'f', 'n', 'm', 's', 'u', 'b', '.', 'd', 9, 0, + /* 78 */ 's', 'c', '.', 'd', 9, 0, + /* 84 */ 'f', 'a', 'd', 'd', '.', 'd', 9, 0, + /* 92 */ 'f', 'm', 'a', 'd', 'd', '.', 'd', 9, 0, + /* 101 */ 'f', 'n', 'm', 'a', 'd', 'd', '.', 'd', 9, 0, + /* 111 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'd', 9, 0, + /* 121 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'd', 9, 0, + /* 131 */ 'f', 'l', 'e', '.', 'd', 9, 0, + /* 138 */ 'f', 's', 'g', 'n', 'j', '.', 'd', 9, 0, + /* 147 */ 'f', 'c', 'v', 't', '.', 'l', '.', 'd', 9, 0, + /* 157 */ 'f', 'm', 'u', 'l', '.', 'd', 9, 0, + /* 165 */ 'f', 'm', 'i', 'n', '.', 'd', 9, 0, + /* 173 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'd', 9, 0, + /* 183 */ 'f', 's', 'g', 'n', 'j', 'n', '.', 'd', 9, 0, + /* 193 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'd', 9, 0, + /* 204 */ 'f', 'e', 'q', '.', 'd', 9, 0, + /* 211 */ 'l', 'r', '.', 'd', 9, 0, + /* 217 */ 'a', 'm', 'o', 'o', 'r', '.', 'd', 9, 0, + /* 226 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'd', 9, 0, + /* 236 */ 'f', 'c', 'v', 't', '.', 's', '.', 'd', 9, 0, + /* 246 */ 'f', 'c', 'l', 'a', 's', 's', '.', 'd', 9, 0, + /* 256 */ 'f', 'l', 't', '.', 'd', 9, 0, + /* 263 */ 'f', 's', 'q', 'r', 't', '.', 'd', 9, 0, + /* 272 */ 'f', 'c', 'v', 't', '.', 'l', 'u', '.', 'd', 9, 0, + /* 283 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'd', 9, 0, + /* 294 */ 'f', 'c', 'v', 't', '.', 'w', 'u', '.', 'd', 9, 0, + /* 305 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'd', 9, 0, + /* 316 */ 'f', 'd', 'i', 'v', '.', 'd', 9, 0, + /* 324 */ 'f', 'c', 'v', 't', '.', 'w', '.', 'd', 9, 0, + /* 334 */ 'f', 'm', 'v', '.', 'x', '.', 'd', 9, 0, + /* 343 */ 'f', 'm', 'a', 'x', '.', 'd', 9, 0, + /* 351 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'd', 9, 0, + /* 361 */ 'f', 's', 'g', 'n', 'j', 'x', '.', 'd', 9, 0, + /* 371 */ 'c', '.', 'a', 'd', 'd', 9, 0, + /* 378 */ 'c', '.', 'l', 'd', 9, 0, + /* 384 */ 'c', '.', 'f', 'l', 'd', 9, 0, + /* 391 */ 'c', '.', 'a', 'n', 'd', 9, 0, + /* 398 */ 'c', '.', 's', 'd', 9, 0, + /* 404 */ 'c', '.', 'f', 's', 'd', 9, 0, + /* 411 */ 'f', 'e', 'n', 'c', 'e', 9, 0, + /* 418 */ 'b', 'g', 'e', 9, 0, + /* 423 */ 'b', 'n', 'e', 9, 0, + /* 428 */ 'm', 'u', 'l', 'h', 9, 0, + /* 434 */ 's', 'h', 9, 0, + /* 438 */ 'f', 'e', 'n', 'c', 'e', '.', 'i', 9, 0, + /* 447 */ 'c', '.', 's', 'r', 'a', 'i', 9, 0, + /* 455 */ 'c', 's', 'r', 'r', 'c', 'i', 9, 0, + /* 463 */ 'c', '.', 'a', 'd', 'd', 'i', 9, 0, + /* 471 */ 'c', '.', 'a', 'n', 'd', 'i', 9, 0, + /* 479 */ 'w', 'f', 'i', 9, 0, + /* 484 */ 'c', '.', 'l', 'i', 9, 0, + /* 490 */ 'c', '.', 's', 'l', 'l', 'i', 9, 0, + /* 498 */ 'c', '.', 's', 'r', 'l', 'i', 9, 0, + /* 506 */ 'x', 'o', 'r', 'i', 9, 0, + /* 512 */ 'c', 's', 'r', 'r', 's', 'i', 9, 0, + /* 520 */ 's', 'l', 't', 'i', 9, 0, + /* 526 */ 'c', '.', 'l', 'u', 'i', 9, 0, + /* 533 */ 'c', 's', 'r', 'r', 'w', 'i', 9, 0, + /* 541 */ 'c', '.', 'j', 9, 0, + /* 546 */ 'c', '.', 'e', 'b', 'r', 'e', 'a', 'k', 9, 0, + /* 556 */ 'f', 'c', 'v', 't', '.', 'd', '.', 'l', 9, 0, + /* 566 */ 'f', 'c', 'v', 't', '.', 's', '.', 'l', 9, 0, + /* 576 */ 'c', '.', 'j', 'a', 'l', 9, 0, + /* 583 */ 't', 'a', 'i', 'l', 9, 0, + /* 589 */ 'e', 'c', 'a', 'l', 'l', 9, 0, + /* 596 */ 's', 'l', 'l', 9, 0, + /* 601 */ 's', 'c', '.', 'd', '.', 'r', 'l', 9, 0, + /* 610 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'd', '.', 'r', 'l', 9, 0, + /* 623 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'd', '.', 'r', 'l', 9, 0, + /* 636 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'd', '.', 'r', 'l', 9, 0, + /* 649 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'd', '.', 'r', 'l', 9, 0, + /* 663 */ 'l', 'r', '.', 'd', '.', 'r', 'l', 9, 0, + /* 672 */ 'a', 'm', 'o', 'o', 'r', '.', 'd', '.', 'r', 'l', 9, 0, + /* 684 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'd', '.', 'r', 'l', 9, 0, + /* 697 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'd', '.', 'r', 'l', 9, 0, + /* 711 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'd', '.', 'r', 'l', 9, 0, + /* 725 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'd', '.', 'r', 'l', 9, 0, + /* 738 */ 's', 'c', '.', 'w', '.', 'r', 'l', 9, 0, + /* 747 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'w', '.', 'r', 'l', 9, 0, + /* 760 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'w', '.', 'r', 'l', 9, 0, + /* 773 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'w', '.', 'r', 'l', 9, 0, + /* 786 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'w', '.', 'r', 'l', 9, 0, + /* 800 */ 'l', 'r', '.', 'w', '.', 'r', 'l', 9, 0, + /* 809 */ 'a', 'm', 'o', 'o', 'r', '.', 'w', '.', 'r', 'l', 9, 0, + /* 821 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'w', '.', 'r', 'l', 9, 0, + /* 834 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'w', '.', 'r', 'l', 9, 0, + /* 848 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'w', '.', 'r', 'l', 9, 0, + /* 862 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'w', '.', 'r', 'l', 9, 0, + /* 875 */ 's', 'c', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 886 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 901 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 916 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 931 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 947 */ 'l', 'r', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 958 */ 'a', 'm', 'o', 'o', 'r', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 972 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 987 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1003 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1019 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'd', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1034 */ 's', 'c', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1045 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1060 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1075 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1090 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1106 */ 'l', 'r', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1117 */ 'a', 'm', 'o', 'o', 'r', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1131 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1146 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1162 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1178 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'w', '.', 'a', 'q', 'r', 'l', 9, 0, + /* 1193 */ 's', 'r', 'l', 9, 0, + /* 1198 */ 'm', 'u', 'l', 9, 0, + /* 1203 */ 'r', 'e', 'm', 9, 0, + /* 1208 */ 'c', '.', 'a', 'd', 'd', 'i', '4', 's', 'p', 'n', 9, 0, + /* 1220 */ 'f', 'e', 'n', 'c', 'e', '.', 't', 's', 'o', 9, 0, + /* 1231 */ 'c', '.', 'u', 'n', 'i', 'm', 'p', 9, 0, + /* 1240 */ 'c', '.', 'n', 'o', 'p', 9, 0, + /* 1247 */ 'c', '.', 'a', 'd', 'd', 'i', '1', '6', 's', 'p', 9, 0, + /* 1259 */ 'c', '.', 'l', 'd', 's', 'p', 9, 0, + /* 1267 */ 'c', '.', 'f', 'l', 'd', 's', 'p', 9, 0, + /* 1276 */ 'c', '.', 's', 'd', 's', 'p', 9, 0, + /* 1284 */ 'c', '.', 'f', 's', 'd', 's', 'p', 9, 0, + /* 1293 */ 'c', '.', 'l', 'w', 's', 'p', 9, 0, + /* 1301 */ 'c', '.', 'f', 'l', 'w', 's', 'p', 9, 0, + /* 1310 */ 'c', '.', 's', 'w', 's', 'p', 9, 0, + /* 1318 */ 'c', '.', 'f', 's', 'w', 's', 'p', 9, 0, + /* 1327 */ 's', 'c', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1336 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1349 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1362 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1375 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1389 */ 'l', 'r', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1398 */ 'a', 'm', 'o', 'o', 'r', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1410 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1423 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1437 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1451 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'd', '.', 'a', 'q', 9, 0, + /* 1464 */ 's', 'c', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1473 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1486 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1499 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1512 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1526 */ 'l', 'r', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1535 */ 'a', 'm', 'o', 'o', 'r', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1547 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1560 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1574 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1588 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'w', '.', 'a', 'q', 9, 0, + /* 1601 */ 'b', 'e', 'q', 9, 0, + /* 1606 */ 'c', '.', 'j', 'r', 9, 0, + /* 1612 */ 'c', '.', 'j', 'a', 'l', 'r', 9, 0, + /* 1620 */ 'c', '.', 'o', 'r', 9, 0, + /* 1626 */ 'c', '.', 'x', 'o', 'r', 9, 0, + /* 1633 */ 'f', 's', 'u', 'b', '.', 's', 9, 0, + /* 1641 */ 'f', 'm', 's', 'u', 'b', '.', 's', 9, 0, + /* 1650 */ 'f', 'n', 'm', 's', 'u', 'b', '.', 's', 9, 0, + /* 1660 */ 'f', 'c', 'v', 't', '.', 'd', '.', 's', 9, 0, + /* 1670 */ 'f', 'a', 'd', 'd', '.', 's', 9, 0, + /* 1678 */ 'f', 'm', 'a', 'd', 'd', '.', 's', 9, 0, + /* 1687 */ 'f', 'n', 'm', 'a', 'd', 'd', '.', 's', 9, 0, + /* 1697 */ 'f', 'l', 'e', '.', 's', 9, 0, + /* 1704 */ 'f', 's', 'g', 'n', 'j', '.', 's', 9, 0, + /* 1713 */ 'f', 'c', 'v', 't', '.', 'l', '.', 's', 9, 0, + /* 1723 */ 'f', 'm', 'u', 'l', '.', 's', 9, 0, + /* 1731 */ 'f', 'm', 'i', 'n', '.', 's', 9, 0, + /* 1739 */ 'f', 's', 'g', 'n', 'j', 'n', '.', 's', 9, 0, + /* 1749 */ 'f', 'e', 'q', '.', 's', 9, 0, + /* 1756 */ 'f', 'c', 'l', 'a', 's', 's', '.', 's', 9, 0, + /* 1766 */ 'f', 'l', 't', '.', 's', 9, 0, + /* 1773 */ 'f', 's', 'q', 'r', 't', '.', 's', 9, 0, + /* 1782 */ 'f', 'c', 'v', 't', '.', 'l', 'u', '.', 's', 9, 0, + /* 1793 */ 'f', 'c', 'v', 't', '.', 'w', 'u', '.', 's', 9, 0, + /* 1804 */ 'f', 'd', 'i', 'v', '.', 's', 9, 0, + /* 1812 */ 'f', 'c', 'v', 't', '.', 'w', '.', 's', 9, 0, + /* 1822 */ 'f', 'm', 'a', 'x', '.', 's', 9, 0, + /* 1830 */ 'f', 's', 'g', 'n', 'j', 'x', '.', 's', 9, 0, + /* 1840 */ 'c', 's', 'r', 'r', 's', 9, 0, + /* 1847 */ 'm', 'r', 'e', 't', 9, 0, + /* 1853 */ 's', 'r', 'e', 't', 9, 0, + /* 1859 */ 'u', 'r', 'e', 't', 9, 0, + /* 1865 */ 'b', 'l', 't', 9, 0, + /* 1870 */ 's', 'l', 't', 9, 0, + /* 1875 */ 'l', 'b', 'u', 9, 0, + /* 1880 */ 'b', 'g', 'e', 'u', 9, 0, + /* 1886 */ 'm', 'u', 'l', 'h', 'u', 9, 0, + /* 1893 */ 's', 'l', 't', 'i', 'u', 9, 0, + /* 1900 */ 'f', 'c', 'v', 't', '.', 'd', '.', 'l', 'u', 9, 0, + /* 1911 */ 'f', 'c', 'v', 't', '.', 's', '.', 'l', 'u', 9, 0, + /* 1922 */ 'r', 'e', 'm', 'u', 9, 0, + /* 1928 */ 'm', 'u', 'l', 'h', 's', 'u', 9, 0, + /* 1936 */ 'b', 'l', 't', 'u', 9, 0, + /* 1942 */ 's', 'l', 't', 'u', 9, 0, + /* 1948 */ 'd', 'i', 'v', 'u', 9, 0, + /* 1954 */ 'f', 'c', 'v', 't', '.', 'd', '.', 'w', 'u', 9, 0, + /* 1965 */ 'f', 'c', 'v', 't', '.', 's', '.', 'w', 'u', 9, 0, + /* 1976 */ 'l', 'w', 'u', 9, 0, + /* 1981 */ 'd', 'i', 'v', 9, 0, + /* 1986 */ 'c', '.', 'm', 'v', 9, 0, + /* 1992 */ 's', 'c', '.', 'w', 9, 0, + /* 1998 */ 'f', 'c', 'v', 't', '.', 'd', '.', 'w', 9, 0, + /* 2008 */ 'a', 'm', 'o', 'a', 'd', 'd', '.', 'w', 9, 0, + /* 2018 */ 'a', 'm', 'o', 'a', 'n', 'd', '.', 'w', 9, 0, + /* 2028 */ 'a', 'm', 'o', 'm', 'i', 'n', '.', 'w', 9, 0, + /* 2038 */ 'a', 'm', 'o', 's', 'w', 'a', 'p', '.', 'w', 9, 0, + /* 2049 */ 'l', 'r', '.', 'w', 9, 0, + /* 2055 */ 'a', 'm', 'o', 'o', 'r', '.', 'w', 9, 0, + /* 2064 */ 'a', 'm', 'o', 'x', 'o', 'r', '.', 'w', 9, 0, + /* 2074 */ 'f', 'c', 'v', 't', '.', 's', '.', 'w', 9, 0, + /* 2084 */ 'a', 'm', 'o', 'm', 'i', 'n', 'u', '.', 'w', 9, 0, + /* 2095 */ 'a', 'm', 'o', 'm', 'a', 'x', 'u', '.', 'w', 9, 0, + /* 2106 */ 'f', 'm', 'v', '.', 'x', '.', 'w', 9, 0, + /* 2115 */ 'a', 'm', 'o', 'm', 'a', 'x', '.', 'w', 9, 0, + /* 2125 */ 's', 'r', 'a', 'w', 9, 0, + /* 2131 */ 'c', '.', 's', 'u', 'b', 'w', 9, 0, + /* 2139 */ 'c', '.', 'a', 'd', 'd', 'w', 9, 0, + /* 2147 */ 's', 'r', 'a', 'i', 'w', 9, 0, + /* 2154 */ 'c', '.', 'a', 'd', 'd', 'i', 'w', 9, 0, + /* 2163 */ 's', 'l', 'l', 'i', 'w', 9, 0, + /* 2170 */ 's', 'r', 'l', 'i', 'w', 9, 0, + /* 2177 */ 'c', '.', 'l', 'w', 9, 0, + /* 2183 */ 'c', '.', 'f', 'l', 'w', 9, 0, + /* 2190 */ 's', 'l', 'l', 'w', 9, 0, + /* 2196 */ 's', 'r', 'l', 'w', 9, 0, + /* 2202 */ 'm', 'u', 'l', 'w', 9, 0, + /* 2208 */ 'r', 'e', 'm', 'w', 9, 0, + /* 2214 */ 'c', 's', 'r', 'r', 'w', 9, 0, + /* 2221 */ 'c', '.', 's', 'w', 9, 0, + /* 2227 */ 'c', '.', 'f', 's', 'w', 9, 0, + /* 2234 */ 'r', 'e', 'm', 'u', 'w', 9, 0, + /* 2241 */ 'd', 'i', 'v', 'u', 'w', 9, 0, + /* 2248 */ 'd', 'i', 'v', 'w', 9, 0, + /* 2254 */ 'f', 'm', 'v', '.', 'd', '.', 'x', 9, 0, + /* 2263 */ 'f', 'm', 'v', '.', 'w', '.', 'x', 9, 0, + /* 2272 */ 'c', '.', 'b', 'n', 'e', 'z', 9, 0, + /* 2280 */ 'c', '.', 'b', 'e', 'q', 'z', 9, 0, + /* 2288 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'F', 'u', 'n', 'c', 't', 'i', 'o', 'n', 32, 'P', 'a', 't', 'c', 'h', 'a', 'b', 'l', 'e', 32, 'R', 'E', 'T', '.', 0, + /* 2319 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'T', 'y', 'p', 'e', 'd', 32, 'E', 'v', 'e', 'n', 't', 32, 'L', 'o', 'g', '.', 0, + /* 2343 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'C', 'u', 's', 't', 'o', 'm', 32, 'E', 'v', 'e', 'n', 't', 32, 'L', 'o', 'g', '.', 0, + /* 2368 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'F', 'u', 'n', 'c', 't', 'i', 'o', 'n', 32, 'E', 'n', 't', 'e', 'r', '.', 0, + /* 2391 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'T', 'a', 'i', 'l', 32, 'C', 'a', 'l', 'l', 32, 'E', 'x', 'i', 't', '.', 0, + /* 2414 */ '#', 32, 'X', 'R', 'a', 'y', 32, 'F', 'u', 'n', 'c', 't', 'i', 'o', 'n', 32, 'E', 'x', 'i', 't', '.', 0, + /* 2436 */ 'L', 'I', 'F', 'E', 'T', 'I', 'M', 'E', '_', 'E', 'N', 'D', 0, + /* 2449 */ 'B', 'U', 'N', 'D', 'L', 'E', 0, + /* 2456 */ 'D', 'B', 'G', '_', 'V', 'A', 'L', 'U', 'E', 0, + /* 2466 */ 'D', 'B', 'G', '_', 'L', 'A', 'B', 'E', 'L', 0, + /* 2476 */ 'L', 'I', 'F', 'E', 'T', 'I', 'M', 'E', '_', 'S', 'T', 'A', 'R', 'T', 0, + /* 2491 */ '#', 32, 'F', 'E', 'n', 't', 'r', 'y', 32, 'c', 'a', 'l', 'l', 0, + }; +#endif + + static const uint16_t OpInfo0[] = { + 0U, // PHI + 0U, // INLINEASM + 0U, // INLINEASM_BR + 0U, // CFI_INSTRUCTION + 0U, // EH_LABEL + 0U, // GC_LABEL + 0U, // ANNOTATION_LABEL + 0U, // KILL + 0U, // EXTRACT_SUBREG + 0U, // INSERT_SUBREG + 0U, // IMPLICIT_DEF + 0U, // SUBREG_TO_REG + 0U, // COPY_TO_REGCLASS + 2457U, // DBG_VALUE + 2467U, // DBG_LABEL + 0U, // REG_SEQUENCE + 0U, // COPY + 2450U, // BUNDLE + 2477U, // LIFETIME_START + 2437U, // LIFETIME_END + 0U, // STACKMAP + 2492U, // FENTRY_CALL + 0U, // PATCHPOINT + 0U, // LOAD_STACK_GUARD + 0U, // STATEPOINT + 0U, // LOCAL_ESCAPE + 0U, // FAULTING_OP + 0U, // PATCHABLE_OP + 2369U, // PATCHABLE_FUNCTION_ENTER + 2289U, // PATCHABLE_RET + 2415U, // PATCHABLE_FUNCTION_EXIT + 2392U, // PATCHABLE_TAIL_CALL + 2344U, // PATCHABLE_EVENT_CALL + 2320U, // PATCHABLE_TYPED_EVENT_CALL + 0U, // ICALL_BRANCH_FUNNEL + 0U, // G_ADD + 0U, // G_SUB + 0U, // G_MUL + 0U, // G_SDIV + 0U, // G_UDIV + 0U, // G_SREM + 0U, // G_UREM + 0U, // G_AND + 0U, // G_OR + 0U, // G_XOR + 0U, // G_IMPLICIT_DEF + 0U, // G_PHI + 0U, // G_FRAME_INDEX + 0U, // G_GLOBAL_VALUE + 0U, // G_EXTRACT + 0U, // G_UNMERGE_VALUES + 0U, // G_INSERT + 0U, // G_MERGE_VALUES + 0U, // G_BUILD_VECTOR + 0U, // G_BUILD_VECTOR_TRUNC + 0U, // G_CONCAT_VECTORS + 0U, // G_PTRTOINT + 0U, // G_INTTOPTR + 0U, // G_BITCAST + 0U, // G_INTRINSIC_TRUNC + 0U, // G_INTRINSIC_ROUND + 0U, // G_LOAD + 0U, // G_SEXTLOAD + 0U, // G_ZEXTLOAD + 0U, // G_STORE + 0U, // G_ATOMIC_CMPXCHG_WITH_SUCCESS + 0U, // G_ATOMIC_CMPXCHG + 0U, // G_ATOMICRMW_XCHG + 0U, // G_ATOMICRMW_ADD + 0U, // G_ATOMICRMW_SUB + 0U, // G_ATOMICRMW_AND + 0U, // G_ATOMICRMW_NAND + 0U, // G_ATOMICRMW_OR + 0U, // G_ATOMICRMW_XOR + 0U, // G_ATOMICRMW_MAX + 0U, // G_ATOMICRMW_MIN + 0U, // G_ATOMICRMW_UMAX + 0U, // G_ATOMICRMW_UMIN + 0U, // G_BRCOND + 0U, // G_BRINDIRECT + 0U, // G_INTRINSIC + 0U, // G_INTRINSIC_W_SIDE_EFFECTS + 0U, // G_ANYEXT + 0U, // G_TRUNC + 0U, // G_CONSTANT + 0U, // G_FCONSTANT + 0U, // G_VASTART + 0U, // G_VAARG + 0U, // G_SEXT + 0U, // G_ZEXT + 0U, // G_SHL + 0U, // G_LSHR + 0U, // G_ASHR + 0U, // G_ICMP + 0U, // G_FCMP + 0U, // G_SELECT + 0U, // G_UADDO + 0U, // G_UADDE + 0U, // G_USUBO + 0U, // G_USUBE + 0U, // G_SADDO + 0U, // G_SADDE + 0U, // G_SSUBO + 0U, // G_SSUBE + 0U, // G_UMULO + 0U, // G_SMULO + 0U, // G_UMULH + 0U, // G_SMULH + 0U, // G_FADD + 0U, // G_FSUB + 0U, // G_FMUL + 0U, // G_FMA + 0U, // G_FDIV + 0U, // G_FREM + 0U, // G_FPOW + 0U, // G_FEXP + 0U, // G_FEXP2 + 0U, // G_FLOG + 0U, // G_FLOG2 + 0U, // G_FLOG10 + 0U, // G_FNEG + 0U, // G_FPEXT + 0U, // G_FPTRUNC + 0U, // G_FPTOSI + 0U, // G_FPTOUI + 0U, // G_SITOFP + 0U, // G_UITOFP + 0U, // G_FABS + 0U, // G_FCANONICALIZE + 0U, // G_GEP + 0U, // G_PTR_MASK + 0U, // G_BR + 0U, // G_INSERT_VECTOR_ELT + 0U, // G_EXTRACT_VECTOR_ELT + 0U, // G_SHUFFLE_VECTOR + 0U, // G_CTTZ + 0U, // G_CTTZ_ZERO_UNDEF + 0U, // G_CTLZ + 0U, // G_CTLZ_ZERO_UNDEF + 0U, // G_CTPOP + 0U, // G_BSWAP + 0U, // G_FCEIL + 0U, // G_FCOS + 0U, // G_FSIN + 0U, // G_FSQRT + 0U, // G_FFLOOR + 0U, // G_ADDRSPACE_CAST + 0U, // G_BLOCK_ADDR + 4U, // ADJCALLSTACKDOWN + 4U, // ADJCALLSTACKUP + 4U, // BuildPairF64Pseudo + 4U, // PseudoAtomicLoadNand32 + 4U, // PseudoAtomicLoadNand64 + 4U, // PseudoBR + 4U, // PseudoBRIND + 4687U, // PseudoCALL + 4U, // PseudoCALLIndirect + 4U, // PseudoCmpXchg32 + 4U, // PseudoCmpXchg64 + 20482U, // PseudoLA + 20967U, // PseudoLI + 20481U, // PseudoLLA + 4U, // PseudoMaskedAtomicLoadAdd32 + 4U, // PseudoMaskedAtomicLoadMax32 + 4U, // PseudoMaskedAtomicLoadMin32 + 4U, // PseudoMaskedAtomicLoadNand32 + 4U, // PseudoMaskedAtomicLoadSub32 + 4U, // PseudoMaskedAtomicLoadUMax32 + 4U, // PseudoMaskedAtomicLoadUMin32 + 4U, // PseudoMaskedAtomicSwap32 + 4U, // PseudoMaskedCmpXchg32 + 4U, // PseudoRET + 4680U, // PseudoTAIL + 4U, // PseudoTAILIndirect + 4U, // Select_FPR32_Using_CC_GPR + 4U, // Select_FPR64_Using_CC_GPR + 4U, // Select_GPR_Using_CC_GPR + 4U, // SplitF64Pseudo + 20854U, // ADD + 20946U, // ADDI + 22637U, // ADDIW + 22622U, // ADDW + 20592U, // AMOADD_D + 21817U, // AMOADD_D_AQ + 21367U, // AMOADD_D_AQ_RL + 21091U, // AMOADD_D_RL + 22489U, // AMOADD_W + 21954U, // AMOADD_W_AQ + 21526U, // AMOADD_W_AQ_RL + 21228U, // AMOADD_W_RL + 20602U, // AMOAND_D + 21830U, // AMOAND_D_AQ + 21382U, // AMOAND_D_AQ_RL + 21104U, // AMOAND_D_RL + 22499U, // AMOAND_W + 21967U, // AMOAND_W_AQ + 21541U, // AMOAND_W_AQ_RL + 21241U, // AMOAND_W_RL + 20786U, // AMOMAXU_D + 21918U, // AMOMAXU_D_AQ + 21484U, // AMOMAXU_D_AQ_RL + 21192U, // AMOMAXU_D_RL + 22576U, // AMOMAXU_W + 22055U, // AMOMAXU_W_AQ + 21643U, // AMOMAXU_W_AQ_RL + 21329U, // AMOMAXU_W_RL + 20832U, // AMOMAX_D + 21932U, // AMOMAX_D_AQ + 21500U, // AMOMAX_D_AQ_RL + 21206U, // AMOMAX_D_RL + 22596U, // AMOMAX_W + 22069U, // AMOMAX_W_AQ + 21659U, // AMOMAX_W_AQ_RL + 21343U, // AMOMAX_W_RL + 20764U, // AMOMINU_D + 21904U, // AMOMINU_D_AQ + 21468U, // AMOMINU_D_AQ_RL + 21178U, // AMOMINU_D_RL + 22565U, // AMOMINU_W + 22041U, // AMOMINU_W_AQ + 21627U, // AMOMINU_W_AQ_RL + 21315U, // AMOMINU_W_RL + 20654U, // AMOMIN_D + 21843U, // AMOMIN_D_AQ + 21397U, // AMOMIN_D_AQ_RL + 21117U, // AMOMIN_D_RL + 22509U, // AMOMIN_W + 21980U, // AMOMIN_W_AQ + 21556U, // AMOMIN_W_AQ_RL + 21254U, // AMOMIN_W_RL + 20698U, // AMOOR_D + 21879U, // AMOOR_D_AQ + 21439U, // AMOOR_D_AQ_RL + 21153U, // AMOOR_D_RL + 22536U, // AMOOR_W + 22016U, // AMOOR_W_AQ + 21598U, // AMOOR_W_AQ_RL + 21290U, // AMOOR_W_RL + 20674U, // AMOSWAP_D + 21856U, // AMOSWAP_D_AQ + 21412U, // AMOSWAP_D_AQ_RL + 21130U, // AMOSWAP_D_RL + 22519U, // AMOSWAP_W + 21993U, // AMOSWAP_W_AQ + 21571U, // AMOSWAP_W_AQ_RL + 21267U, // AMOSWAP_W_RL + 20707U, // AMOXOR_D + 21891U, // AMOXOR_D_AQ + 21453U, // AMOXOR_D_AQ_RL + 21165U, // AMOXOR_D_RL + 22545U, // AMOXOR_W + 22028U, // AMOXOR_W_AQ + 21612U, // AMOXOR_W_AQ_RL + 21302U, // AMOXOR_W_RL + 20874U, // AND + 20954U, // ANDI + 20518U, // AUIPC + 22082U, // BEQ + 20899U, // BGE + 22361U, // BGEU + 22346U, // BLT + 22417U, // BLTU + 20904U, // BNE + 20525U, // CSRRC + 20936U, // CSRRCI + 22321U, // CSRRS + 20993U, // CSRRSI + 22695U, // CSRRW + 21014U, // CSRRWI + 8564U, // C_ADD + 8656U, // C_ADDI + 9440U, // C_ADDI16SP + 21689U, // C_ADDI4SPN + 10347U, // C_ADDIW + 10332U, // C_ADDW + 8584U, // C_AND + 8664U, // C_ANDI + 22761U, // C_BEQZ + 22753U, // C_BNEZ + 547U, // C_EBREAK + 20865U, // C_FLD + 21748U, // C_FLDSP + 22664U, // C_FLW + 21782U, // C_FLWSP + 20885U, // C_FSD + 21765U, // C_FSDSP + 22708U, // C_FSW + 21799U, // C_FSWSP + 4638U, // C_J + 4673U, // C_JAL + 5709U, // C_JALR + 5703U, // C_JR + 20859U, // C_LD + 21740U, // C_LDSP + 20965U, // C_LI + 21007U, // C_LUI + 22658U, // C_LW + 21774U, // C_LWSP + 22467U, // C_MV + 1241U, // C_NOP + 9813U, // C_OR + 20879U, // C_SD + 21757U, // C_SDSP + 8683U, // C_SLLI + 8640U, // C_SRAI + 8691U, // C_SRLI + 8223U, // C_SUB + 10324U, // C_SUBW + 22702U, // C_SW + 21791U, // C_SWSP + 1232U, // C_UNIMP + 9819U, // C_XOR + 22462U, // DIV + 22429U, // DIVU + 22722U, // DIVUW + 22729U, // DIVW + 549U, // EBREAK + 590U, // ECALL + 20565U, // FADD_D + 22151U, // FADD_S + 20727U, // FCLASS_D + 22237U, // FCLASS_S + 21037U, // FCVT_D_L + 22381U, // FCVT_D_LU + 22141U, // FCVT_D_S + 22479U, // FCVT_D_W + 22435U, // FCVT_D_WU + 20753U, // FCVT_LU_D + 22263U, // FCVT_LU_S + 20628U, // FCVT_L_D + 22194U, // FCVT_L_S + 20717U, // FCVT_S_D + 21047U, // FCVT_S_L + 22392U, // FCVT_S_LU + 22555U, // FCVT_S_W + 22446U, // FCVT_S_WU + 20775U, // FCVT_WU_D + 22274U, // FCVT_WU_S + 20805U, // FCVT_W_D + 22293U, // FCVT_W_S + 20797U, // FDIV_D + 22285U, // FDIV_S + 12700U, // FENCE + 439U, // FENCE_I + 1221U, // FENCE_TSO + 20685U, // FEQ_D + 22230U, // FEQ_S + 20867U, // FLD + 20612U, // FLE_D + 22178U, // FLE_S + 20737U, // FLT_D + 22247U, // FLT_S + 22666U, // FLW + 20573U, // FMADD_D + 22159U, // FMADD_S + 20824U, // FMAX_D + 22303U, // FMAX_S + 20646U, // FMIN_D + 22212U, // FMIN_S + 20540U, // FMSUB_D + 22122U, // FMSUB_S + 20638U, // FMUL_D + 22204U, // FMUL_S + 22735U, // FMV_D_X + 22744U, // FMV_W_X + 20815U, // FMV_X_D + 22587U, // FMV_X_W + 20582U, // FNMADD_D + 22168U, // FNMADD_S + 20549U, // FNMSUB_D + 22131U, // FNMSUB_S + 20887U, // FSD + 20664U, // FSGNJN_D + 22220U, // FSGNJN_S + 20842U, // FSGNJX_D + 22311U, // FSGNJX_S + 20619U, // FSGNJ_D + 22185U, // FSGNJ_S + 20744U, // FSQRT_D + 22254U, // FSQRT_S + 20532U, // FSUB_D + 22114U, // FSUB_S + 22710U, // FSW + 21059U, // JAL + 22095U, // JALR + 20503U, // LB + 22356U, // LBU + 20861U, // LD + 20911U, // LH + 22369U, // LHU + 37076U, // LR_D + 38254U, // LR_D_AQ + 37812U, // LR_D_AQ_RL + 37528U, // LR_D_RL + 38914U, // LR_W + 38391U, // LR_W_AQ + 37971U, // LR_W_AQ_RL + 37665U, // LR_W_RL + 21009U, // LUI + 22660U, // LW + 22457U, // LWU + 1848U, // MRET + 21679U, // MUL + 20909U, // MULH + 22409U, // MULHSU + 22367U, // MULHU + 22683U, // MULW + 22103U, // OR + 20988U, // ORI + 21684U, // REM + 22403U, // REMU + 22715U, // REMUW + 22689U, // REMW + 20507U, // SB + 20559U, // SC_D + 21808U, // SC_D_AQ + 21356U, // SC_D_AQ_RL + 21082U, // SC_D_RL + 22473U, // SC_W + 21945U, // SC_W_AQ + 21515U, // SC_W_AQ_RL + 21219U, // SC_W_RL + 20881U, // SD + 20486U, // SFENCE_VMA + 20915U, // SH + 21077U, // SLL + 20973U, // SLLI + 22644U, // SLLIW + 22671U, // SLLW + 22351U, // SLT + 21001U, // SLTI + 22374U, // SLTIU + 22423U, // SLTU + 20498U, // SRA + 20930U, // SRAI + 22628U, // SRAIW + 22606U, // SRAW + 1854U, // SRET + 21674U, // SRL + 20981U, // SRLI + 22651U, // SRLIW + 22677U, // SRLW + 20513U, // SUB + 22614U, // SUBW + 22704U, // SW + 1234U, // UNIMP + 1860U, // URET + 480U, // WFI + 22109U, // XOR + 20987U, // XORI + }; + + static const uint8_t OpInfo1[] = { + 0U, // PHI + 0U, // INLINEASM + 0U, // INLINEASM_BR + 0U, // CFI_INSTRUCTION + 0U, // EH_LABEL + 0U, // GC_LABEL + 0U, // ANNOTATION_LABEL + 0U, // KILL + 0U, // EXTRACT_SUBREG + 0U, // INSERT_SUBREG + 0U, // IMPLICIT_DEF + 0U, // SUBREG_TO_REG + 0U, // COPY_TO_REGCLASS + 0U, // DBG_VALUE + 0U, // DBG_LABEL + 0U, // REG_SEQUENCE + 0U, // COPY + 0U, // BUNDLE + 0U, // LIFETIME_START + 0U, // LIFETIME_END + 0U, // STACKMAP + 0U, // FENTRY_CALL + 0U, // PATCHPOINT + 0U, // LOAD_STACK_GUARD + 0U, // STATEPOINT + 0U, // LOCAL_ESCAPE + 0U, // FAULTING_OP + 0U, // PATCHABLE_OP + 0U, // PATCHABLE_FUNCTION_ENTER + 0U, // PATCHABLE_RET + 0U, // PATCHABLE_FUNCTION_EXIT + 0U, // PATCHABLE_TAIL_CALL + 0U, // PATCHABLE_EVENT_CALL + 0U, // PATCHABLE_TYPED_EVENT_CALL + 0U, // ICALL_BRANCH_FUNNEL + 0U, // G_ADD + 0U, // G_SUB + 0U, // G_MUL + 0U, // G_SDIV + 0U, // G_UDIV + 0U, // G_SREM + 0U, // G_UREM + 0U, // G_AND + 0U, // G_OR + 0U, // G_XOR + 0U, // G_IMPLICIT_DEF + 0U, // G_PHI + 0U, // G_FRAME_INDEX + 0U, // G_GLOBAL_VALUE + 0U, // G_EXTRACT + 0U, // G_UNMERGE_VALUES + 0U, // G_INSERT + 0U, // G_MERGE_VALUES + 0U, // G_BUILD_VECTOR + 0U, // G_BUILD_VECTOR_TRUNC + 0U, // G_CONCAT_VECTORS + 0U, // G_PTRTOINT + 0U, // G_INTTOPTR + 0U, // G_BITCAST + 0U, // G_INTRINSIC_TRUNC + 0U, // G_INTRINSIC_ROUND + 0U, // G_LOAD + 0U, // G_SEXTLOAD + 0U, // G_ZEXTLOAD + 0U, // G_STORE + 0U, // G_ATOMIC_CMPXCHG_WITH_SUCCESS + 0U, // G_ATOMIC_CMPXCHG + 0U, // G_ATOMICRMW_XCHG + 0U, // G_ATOMICRMW_ADD + 0U, // G_ATOMICRMW_SUB + 0U, // G_ATOMICRMW_AND + 0U, // G_ATOMICRMW_NAND + 0U, // G_ATOMICRMW_OR + 0U, // G_ATOMICRMW_XOR + 0U, // G_ATOMICRMW_MAX + 0U, // G_ATOMICRMW_MIN + 0U, // G_ATOMICRMW_UMAX + 0U, // G_ATOMICRMW_UMIN + 0U, // G_BRCOND + 0U, // G_BRINDIRECT + 0U, // G_INTRINSIC + 0U, // G_INTRINSIC_W_SIDE_EFFECTS + 0U, // G_ANYEXT + 0U, // G_TRUNC + 0U, // G_CONSTANT + 0U, // G_FCONSTANT + 0U, // G_VASTART + 0U, // G_VAARG + 0U, // G_SEXT + 0U, // G_ZEXT + 0U, // G_SHL + 0U, // G_LSHR + 0U, // G_ASHR + 0U, // G_ICMP + 0U, // G_FCMP + 0U, // G_SELECT + 0U, // G_UADDO + 0U, // G_UADDE + 0U, // G_USUBO + 0U, // G_USUBE + 0U, // G_SADDO + 0U, // G_SADDE + 0U, // G_SSUBO + 0U, // G_SSUBE + 0U, // G_UMULO + 0U, // G_SMULO + 0U, // G_UMULH + 0U, // G_SMULH + 0U, // G_FADD + 0U, // G_FSUB + 0U, // G_FMUL + 0U, // G_FMA + 0U, // G_FDIV + 0U, // G_FREM + 0U, // G_FPOW + 0U, // G_FEXP + 0U, // G_FEXP2 + 0U, // G_FLOG + 0U, // G_FLOG2 + 0U, // G_FLOG10 + 0U, // G_FNEG + 0U, // G_FPEXT + 0U, // G_FPTRUNC + 0U, // G_FPTOSI + 0U, // G_FPTOUI + 0U, // G_SITOFP + 0U, // G_UITOFP + 0U, // G_FABS + 0U, // G_FCANONICALIZE + 0U, // G_GEP + 0U, // G_PTR_MASK + 0U, // G_BR + 0U, // G_INSERT_VECTOR_ELT + 0U, // G_EXTRACT_VECTOR_ELT + 0U, // G_SHUFFLE_VECTOR + 0U, // G_CTTZ + 0U, // G_CTTZ_ZERO_UNDEF + 0U, // G_CTLZ + 0U, // G_CTLZ_ZERO_UNDEF + 0U, // G_CTPOP + 0U, // G_BSWAP + 0U, // G_FCEIL + 0U, // G_FCOS + 0U, // G_FSIN + 0U, // G_FSQRT + 0U, // G_FFLOOR + 0U, // G_ADDRSPACE_CAST + 0U, // G_BLOCK_ADDR + 0U, // ADJCALLSTACKDOWN + 0U, // ADJCALLSTACKUP + 0U, // BuildPairF64Pseudo + 0U, // PseudoAtomicLoadNand32 + 0U, // PseudoAtomicLoadNand64 + 0U, // PseudoBR + 0U, // PseudoBRIND + 0U, // PseudoCALL + 0U, // PseudoCALLIndirect + 0U, // PseudoCmpXchg32 + 0U, // PseudoCmpXchg64 + 0U, // PseudoLA + 0U, // PseudoLI + 0U, // PseudoLLA + 0U, // PseudoMaskedAtomicLoadAdd32 + 0U, // PseudoMaskedAtomicLoadMax32 + 0U, // PseudoMaskedAtomicLoadMin32 + 0U, // PseudoMaskedAtomicLoadNand32 + 0U, // PseudoMaskedAtomicLoadSub32 + 0U, // PseudoMaskedAtomicLoadUMax32 + 0U, // PseudoMaskedAtomicLoadUMin32 + 0U, // PseudoMaskedAtomicSwap32 + 0U, // PseudoMaskedCmpXchg32 + 0U, // PseudoRET + 0U, // PseudoTAIL + 0U, // PseudoTAILIndirect + 0U, // Select_FPR32_Using_CC_GPR + 0U, // Select_FPR64_Using_CC_GPR + 0U, // Select_GPR_Using_CC_GPR + 0U, // SplitF64Pseudo + 4U, // ADD + 4U, // ADDI + 4U, // ADDIW + 4U, // ADDW + 9U, // AMOADD_D + 9U, // AMOADD_D_AQ + 9U, // AMOADD_D_AQ_RL + 9U, // AMOADD_D_RL + 9U, // AMOADD_W + 9U, // AMOADD_W_AQ + 9U, // AMOADD_W_AQ_RL + 9U, // AMOADD_W_RL + 9U, // AMOAND_D + 9U, // AMOAND_D_AQ + 9U, // AMOAND_D_AQ_RL + 9U, // AMOAND_D_RL + 9U, // AMOAND_W + 9U, // AMOAND_W_AQ + 9U, // AMOAND_W_AQ_RL + 9U, // AMOAND_W_RL + 9U, // AMOMAXU_D + 9U, // AMOMAXU_D_AQ + 9U, // AMOMAXU_D_AQ_RL + 9U, // AMOMAXU_D_RL + 9U, // AMOMAXU_W + 9U, // AMOMAXU_W_AQ + 9U, // AMOMAXU_W_AQ_RL + 9U, // AMOMAXU_W_RL + 9U, // AMOMAX_D + 9U, // AMOMAX_D_AQ + 9U, // AMOMAX_D_AQ_RL + 9U, // AMOMAX_D_RL + 9U, // AMOMAX_W + 9U, // AMOMAX_W_AQ + 9U, // AMOMAX_W_AQ_RL + 9U, // AMOMAX_W_RL + 9U, // AMOMINU_D + 9U, // AMOMINU_D_AQ + 9U, // AMOMINU_D_AQ_RL + 9U, // AMOMINU_D_RL + 9U, // AMOMINU_W + 9U, // AMOMINU_W_AQ + 9U, // AMOMINU_W_AQ_RL + 9U, // AMOMINU_W_RL + 9U, // AMOMIN_D + 9U, // AMOMIN_D_AQ + 9U, // AMOMIN_D_AQ_RL + 9U, // AMOMIN_D_RL + 9U, // AMOMIN_W + 9U, // AMOMIN_W_AQ + 9U, // AMOMIN_W_AQ_RL + 9U, // AMOMIN_W_RL + 9U, // AMOOR_D + 9U, // AMOOR_D_AQ + 9U, // AMOOR_D_AQ_RL + 9U, // AMOOR_D_RL + 9U, // AMOOR_W + 9U, // AMOOR_W_AQ + 9U, // AMOOR_W_AQ_RL + 9U, // AMOOR_W_RL + 9U, // AMOSWAP_D + 9U, // AMOSWAP_D_AQ + 9U, // AMOSWAP_D_AQ_RL + 9U, // AMOSWAP_D_RL + 9U, // AMOSWAP_W + 9U, // AMOSWAP_W_AQ + 9U, // AMOSWAP_W_AQ_RL + 9U, // AMOSWAP_W_RL + 9U, // AMOXOR_D + 9U, // AMOXOR_D_AQ + 9U, // AMOXOR_D_AQ_RL + 9U, // AMOXOR_D_RL + 9U, // AMOXOR_W + 9U, // AMOXOR_W_AQ + 9U, // AMOXOR_W_AQ_RL + 9U, // AMOXOR_W_RL + 4U, // AND + 4U, // ANDI + 0U, // AUIPC + 4U, // BEQ + 4U, // BGE + 4U, // BGEU + 4U, // BLT + 4U, // BLTU + 4U, // BNE + 2U, // CSRRC + 2U, // CSRRCI + 2U, // CSRRS + 2U, // CSRRSI + 2U, // CSRRW + 2U, // CSRRWI + 0U, // C_ADD + 0U, // C_ADDI + 0U, // C_ADDI16SP + 4U, // C_ADDI4SPN + 0U, // C_ADDIW + 0U, // C_ADDW + 0U, // C_AND + 0U, // C_ANDI + 0U, // C_BEQZ + 0U, // C_BNEZ + 0U, // C_EBREAK + 13U, // C_FLD + 13U, // C_FLDSP + 13U, // C_FLW + 13U, // C_FLWSP + 13U, // C_FSD + 13U, // C_FSDSP + 13U, // C_FSW + 13U, // C_FSWSP + 0U, // C_J + 0U, // C_JAL + 0U, // C_JALR + 0U, // C_JR + 13U, // C_LD + 13U, // C_LDSP + 0U, // C_LI + 0U, // C_LUI + 13U, // C_LW + 13U, // C_LWSP + 0U, // C_MV + 0U, // C_NOP + 0U, // C_OR + 13U, // C_SD + 13U, // C_SDSP + 0U, // C_SLLI + 0U, // C_SRAI + 0U, // C_SRLI + 0U, // C_SUB + 0U, // C_SUBW + 13U, // C_SW + 13U, // C_SWSP + 0U, // C_UNIMP + 0U, // C_XOR + 4U, // DIV + 4U, // DIVU + 4U, // DIVUW + 4U, // DIVW + 0U, // EBREAK + 0U, // ECALL + 36U, // FADD_D + 36U, // FADD_S + 0U, // FCLASS_D + 0U, // FCLASS_S + 20U, // FCVT_D_L + 20U, // FCVT_D_LU + 0U, // FCVT_D_S + 0U, // FCVT_D_W + 0U, // FCVT_D_WU + 20U, // FCVT_LU_D + 20U, // FCVT_LU_S + 20U, // FCVT_L_D + 20U, // FCVT_L_S + 20U, // FCVT_S_D + 20U, // FCVT_S_L + 20U, // FCVT_S_LU + 20U, // FCVT_S_W + 20U, // FCVT_S_WU + 20U, // FCVT_WU_D + 20U, // FCVT_WU_S + 20U, // FCVT_W_D + 20U, // FCVT_W_S + 36U, // FDIV_D + 36U, // FDIV_S + 0U, // FENCE + 0U, // FENCE_I + 0U, // FENCE_TSO + 4U, // FEQ_D + 4U, // FEQ_S + 13U, // FLD + 4U, // FLE_D + 4U, // FLE_S + 4U, // FLT_D + 4U, // FLT_S + 13U, // FLW + 100U, // FMADD_D + 100U, // FMADD_S + 4U, // FMAX_D + 4U, // FMAX_S + 4U, // FMIN_D + 4U, // FMIN_S + 100U, // FMSUB_D + 100U, // FMSUB_S + 36U, // FMUL_D + 36U, // FMUL_S + 0U, // FMV_D_X + 0U, // FMV_W_X + 0U, // FMV_X_D + 0U, // FMV_X_W + 100U, // FNMADD_D + 100U, // FNMADD_S + 100U, // FNMSUB_D + 100U, // FNMSUB_S + 13U, // FSD + 4U, // FSGNJN_D + 4U, // FSGNJN_S + 4U, // FSGNJX_D + 4U, // FSGNJX_S + 4U, // FSGNJ_D + 4U, // FSGNJ_S + 20U, // FSQRT_D + 20U, // FSQRT_S + 36U, // FSUB_D + 36U, // FSUB_S + 13U, // FSW + 0U, // JAL + 4U, // JALR + 13U, // LB + 13U, // LBU + 13U, // LD + 13U, // LH + 13U, // LHU + 0U, // LR_D + 0U, // LR_D_AQ + 0U, // LR_D_AQ_RL + 0U, // LR_D_RL + 0U, // LR_W + 0U, // LR_W_AQ + 0U, // LR_W_AQ_RL + 0U, // LR_W_RL + 0U, // LUI + 13U, // LW + 13U, // LWU + 0U, // MRET + 4U, // MUL + 4U, // MULH + 4U, // MULHSU + 4U, // MULHU + 4U, // MULW + 4U, // OR + 4U, // ORI + 4U, // REM + 4U, // REMU + 4U, // REMUW + 4U, // REMW + 13U, // SB + 9U, // SC_D + 9U, // SC_D_AQ + 9U, // SC_D_AQ_RL + 9U, // SC_D_RL + 9U, // SC_W + 9U, // SC_W_AQ + 9U, // SC_W_AQ_RL + 9U, // SC_W_RL + 13U, // SD + 0U, // SFENCE_VMA + 13U, // SH + 4U, // SLL + 4U, // SLLI + 4U, // SLLIW + 4U, // SLLW + 4U, // SLT + 4U, // SLTI + 4U, // SLTIU + 4U, // SLTU + 4U, // SRA + 4U, // SRAI + 4U, // SRAIW + 4U, // SRAW + 0U, // SRET + 4U, // SRL + 4U, // SRLI + 4U, // SRLIW + 4U, // SRLW + 4U, // SUB + 4U, // SUBW + 13U, // SW + 0U, // UNIMP + 0U, // URET + 0U, // WFI + 4U, // XOR + 4U, // XORI + }; + + // Emit the opcode for the instruction. + uint32_t Bits = 0; + Bits |= OpInfo0[MCInst_getOpcode(MI)] << 0; + Bits |= OpInfo1[MCInst_getOpcode(MI)] << 16; + // assert(Bits != 0 && "Cannot print this instruction."); +#ifndef CAPSTONE_DIET + SStream_concat0(O, AsmStrs+(Bits & 4095)-1); +#endif + + + // Fragment 0 encoded into 2 bits for 4 unique commands. + switch ((Bits >> 12) & 3) { + default: assert(0 && "Invalid command number."); + case 0: + // DBG_VALUE, DBG_LABEL, BUNDLE, LIFETIME_START, LIFETIME_END, FENTRY_CAL... + return; + break; + case 1: + // PseudoCALL, PseudoLA, PseudoLI, PseudoLLA, PseudoTAIL, ADD, ADDI, ADDI... + printOperand(MI, 0, O); + break; + case 2: + // C_ADD, C_ADDI, C_ADDI16SP, C_ADDIW, C_ADDW, C_AND, C_ANDI, C_OR, C_SLL... + printOperand(MI, 1, O); + SStream_concat0(O, ", "); + printOperand(MI, 2, O); + return; + break; + case 3: + // FENCE + printFenceArg(MI, 0, O); + SStream_concat0(O, ", "); + printFenceArg(MI, 1, O); + return; + break; + } + + + // Fragment 1 encoded into 2 bits for 3 unique commands. + switch ((Bits >> 14) & 3) { + default: assert(0 && "Invalid command number."); + case 0: + // PseudoCALL, PseudoTAIL, C_J, C_JAL, C_JALR, C_JR + return; + break; + case 1: + // PseudoLA, PseudoLI, PseudoLLA, ADD, ADDI, ADDIW, ADDW, AMOADD_D, AMOAD... + SStream_concat0(O, ", "); + break; + case 2: + // LR_D, LR_D_AQ, LR_D_AQ_RL, LR_D_RL, LR_W, LR_W_AQ, LR_W_AQ_RL, LR_W_RL + SStream_concat0(O, ", ("); + printOperand(MI, 1, O); + SStream_concat0(O, ")"); + return; + break; + } + + + // Fragment 2 encoded into 2 bits for 3 unique commands. + switch ((Bits >> 16) & 3) { + default: assert(0 && "Invalid command number."); + case 0: + // PseudoLA, PseudoLI, PseudoLLA, ADD, ADDI, ADDIW, ADDW, AND, ANDI, AUIP... + printOperand(MI, 1, O); + break; + case 1: + // AMOADD_D, AMOADD_D_AQ, AMOADD_D_AQ_RL, AMOADD_D_RL, AMOADD_W, AMOADD_W... + printOperand(MI, 2, O); + break; + case 2: + // CSRRC, CSRRCI, CSRRS, CSRRSI, CSRRW, CSRRWI + printCSRSystemRegister(MI, 1, O); + SStream_concat0(O, ", "); + printOperand(MI, 2, O); + return; + break; + } + + + // Fragment 3 encoded into 2 bits for 4 unique commands. + switch ((Bits >> 18) & 3) { + default: assert(0 && "Invalid command number."); + case 0: + // PseudoLA, PseudoLI, PseudoLLA, AUIPC, C_BEQZ, C_BNEZ, C_LI, C_LUI, C_M... + return; + break; + case 1: + // ADD, ADDI, ADDIW, ADDW, AND, ANDI, BEQ, BGE, BGEU, BLT, BLTU, BNE, C_A... + SStream_concat0(O, ", "); + break; + case 2: + // AMOADD_D, AMOADD_D_AQ, AMOADD_D_AQ_RL, AMOADD_D_RL, AMOADD_W, AMOADD_W... + SStream_concat0(O, ", ("); + printOperand(MI, 1, O); + SStream_concat0(O, ")"); + return; + break; + case 3: + // C_FLD, C_FLDSP, C_FLW, C_FLWSP, C_FSD, C_FSDSP, C_FSW, C_FSWSP, C_LD, ... + SStream_concat0(O, "("); + printOperand(MI, 1, O); + SStream_concat0(O, ")"); + return; + break; + } + + + // Fragment 4 encoded into 1 bits for 2 unique commands. + if ((Bits >> 20) & 1) { + // FCVT_D_L, FCVT_D_LU, FCVT_LU_D, FCVT_LU_S, FCVT_L_D, FCVT_L_S, FCVT_S_... + printFRMArg(MI, 2, O); + return; + } else { + // ADD, ADDI, ADDIW, ADDW, AND, ANDI, BEQ, BGE, BGEU, BLT, BLTU, BNE, C_A... + printOperand(MI, 2, O); + } + + + // Fragment 5 encoded into 1 bits for 2 unique commands. + if ((Bits >> 21) & 1) { + // FADD_D, FADD_S, FDIV_D, FDIV_S, FMADD_D, FMADD_S, FMSUB_D, FMSUB_S, FM... + SStream_concat0(O, ", "); + } else { + // ADD, ADDI, ADDIW, ADDW, AND, ANDI, BEQ, BGE, BGEU, BLT, BLTU, BNE, C_A... + return; + } + + + // Fragment 6 encoded into 1 bits for 2 unique commands. + if ((Bits >> 22) & 1) { + // FMADD_D, FMADD_S, FMSUB_D, FMSUB_S, FNMADD_D, FNMADD_S, FNMSUB_D, FNMS... + printOperand(MI, 3, O); + SStream_concat0(O, ", "); + printFRMArg(MI, 4, O); + return; + } else { + // FADD_D, FADD_S, FDIV_D, FDIV_S, FMUL_D, FMUL_S, FSUB_D, FSUB_S + printFRMArg(MI, 3, O); + return; + } + +} + + +/// getRegisterName - This method is automatically generated by tblgen +/// from the register set description. This returns the assembler name +/// for the specified register. +static const char * +getRegisterName(unsigned RegNo, unsigned AltIdx) +{ + assert(RegNo && RegNo < 97 && "Invalid register number!"); + +#ifndef CAPSTONE_DIET + static const char AsmStrsABIRegAltName[] = { + /* 0 */ 'f', 's', '1', '0', 0, + /* 5 */ 'f', 't', '1', '0', 0, + /* 10 */ 'f', 'a', '0', 0, + /* 14 */ 'f', 's', '0', 0, + /* 18 */ 'f', 't', '0', 0, + /* 22 */ 'f', 's', '1', '1', 0, + /* 27 */ 'f', 't', '1', '1', 0, + /* 32 */ 'f', 'a', '1', 0, + /* 36 */ 'f', 's', '1', 0, + /* 40 */ 'f', 't', '1', 0, + /* 44 */ 'f', 'a', '2', 0, + /* 48 */ 'f', 's', '2', 0, + /* 52 */ 'f', 't', '2', 0, + /* 56 */ 'f', 'a', '3', 0, + /* 60 */ 'f', 's', '3', 0, + /* 64 */ 'f', 't', '3', 0, + /* 68 */ 'f', 'a', '4', 0, + /* 72 */ 'f', 's', '4', 0, + /* 76 */ 'f', 't', '4', 0, + /* 80 */ 'f', 'a', '5', 0, + /* 84 */ 'f', 's', '5', 0, + /* 88 */ 'f', 't', '5', 0, + /* 92 */ 'f', 'a', '6', 0, + /* 96 */ 'f', 's', '6', 0, + /* 100 */ 'f', 't', '6', 0, + /* 104 */ 'f', 'a', '7', 0, + /* 108 */ 'f', 's', '7', 0, + /* 112 */ 'f', 't', '7', 0, + /* 116 */ 'f', 's', '8', 0, + /* 120 */ 'f', 't', '8', 0, + /* 124 */ 'f', 's', '9', 0, + /* 128 */ 'f', 't', '9', 0, + /* 132 */ 'r', 'a', 0, + /* 135 */ 'z', 'e', 'r', 'o', 0, + /* 140 */ 'g', 'p', 0, + /* 143 */ 's', 'p', 0, + /* 146 */ 't', 'p', 0, + }; + + static const uint8_t RegAsmOffsetABIRegAltName[] = { + 135, 132, 143, 140, 146, 19, 41, 53, 15, 37, 11, 33, 45, 57, + 69, 81, 93, 105, 49, 61, 73, 85, 97, 109, 117, 125, 1, 23, + 65, 77, 89, 101, 18, 18, 40, 40, 52, 52, 64, 64, 76, 76, + 88, 88, 100, 100, 112, 112, 14, 14, 36, 36, 10, 10, 32, 32, + 44, 44, 56, 56, 68, 68, 80, 80, 92, 92, 104, 104, 48, 48, + 60, 60, 72, 72, 84, 84, 96, 96, 108, 108, 116, 116, 124, 124, + 0, 0, 22, 22, 120, 120, 128, 128, 5, 5, 27, 27, + }; + + static const char AsmStrsNoRegAltName[] = { + /* 0 */ 'f', '1', '0', 0, + /* 4 */ 'x', '1', '0', 0, + /* 8 */ 'f', '2', '0', 0, + /* 12 */ 'x', '2', '0', 0, + /* 16 */ 'f', '3', '0', 0, + /* 20 */ 'x', '3', '0', 0, + /* 24 */ 'f', '0', 0, + /* 27 */ 'x', '0', 0, + /* 30 */ 'f', '1', '1', 0, + /* 34 */ 'x', '1', '1', 0, + /* 38 */ 'f', '2', '1', 0, + /* 42 */ 'x', '2', '1', 0, + /* 46 */ 'f', '3', '1', 0, + /* 50 */ 'x', '3', '1', 0, + /* 54 */ 'f', '1', 0, + /* 57 */ 'x', '1', 0, + /* 60 */ 'f', '1', '2', 0, + /* 64 */ 'x', '1', '2', 0, + /* 68 */ 'f', '2', '2', 0, + /* 72 */ 'x', '2', '2', 0, + /* 76 */ 'f', '2', 0, + /* 79 */ 'x', '2', 0, + /* 82 */ 'f', '1', '3', 0, + /* 86 */ 'x', '1', '3', 0, + /* 90 */ 'f', '2', '3', 0, + /* 94 */ 'x', '2', '3', 0, + /* 98 */ 'f', '3', 0, + /* 101 */ 'x', '3', 0, + /* 104 */ 'f', '1', '4', 0, + /* 108 */ 'x', '1', '4', 0, + /* 112 */ 'f', '2', '4', 0, + /* 116 */ 'x', '2', '4', 0, + /* 120 */ 'f', '4', 0, + /* 123 */ 'x', '4', 0, + /* 126 */ 'f', '1', '5', 0, + /* 130 */ 'x', '1', '5', 0, + /* 134 */ 'f', '2', '5', 0, + /* 138 */ 'x', '2', '5', 0, + /* 142 */ 'f', '5', 0, + /* 145 */ 'x', '5', 0, + /* 148 */ 'f', '1', '6', 0, + /* 152 */ 'x', '1', '6', 0, + /* 156 */ 'f', '2', '6', 0, + /* 160 */ 'x', '2', '6', 0, + /* 164 */ 'f', '6', 0, + /* 167 */ 'x', '6', 0, + /* 170 */ 'f', '1', '7', 0, + /* 174 */ 'x', '1', '7', 0, + /* 178 */ 'f', '2', '7', 0, + /* 182 */ 'x', '2', '7', 0, + /* 186 */ 'f', '7', 0, + /* 189 */ 'x', '7', 0, + /* 192 */ 'f', '1', '8', 0, + /* 196 */ 'x', '1', '8', 0, + /* 200 */ 'f', '2', '8', 0, + /* 204 */ 'x', '2', '8', 0, + /* 208 */ 'f', '8', 0, + /* 211 */ 'x', '8', 0, + /* 214 */ 'f', '1', '9', 0, + /* 218 */ 'x', '1', '9', 0, + /* 222 */ 'f', '2', '9', 0, + /* 226 */ 'x', '2', '9', 0, + /* 230 */ 'f', '9', 0, + /* 233 */ 'x', '9', 0, + }; + + static const uint8_t RegAsmOffsetNoRegAltName[] = { + 27, 57, 79, 101, 123, 145, 167, 189, 211, 233, 4, 34, 64, 86, + 108, 130, 152, 174, 196, 218, 12, 42, 72, 94, 116, 138, 160, 182, + 204, 226, 20, 50, 24, 24, 54, 54, 76, 76, 98, 98, 120, 120, + 142, 142, 164, 164, 186, 186, 208, 208, 230, 230, 0, 0, 30, 30, + 60, 60, 82, 82, 104, 104, 126, 126, 148, 148, 170, 170, 192, 192, + 214, 214, 8, 8, 38, 38, 68, 68, 90, 90, 112, 112, 134, 134, + 156, 156, 178, 178, 200, 200, 222, 222, 16, 16, 46, 46, + }; + + switch(AltIdx) { + default: assert(0 && "Invalid register alt name index!"); + case RISCV_ABIRegAltName: + assert(*(AsmStrsABIRegAltName+RegAsmOffsetABIRegAltName[RegNo-1]) && + "Invalid alt name index for register!"); + return AsmStrsABIRegAltName+RegAsmOffsetABIRegAltName[RegNo-1]; + case RISCV_NoRegAltName: + assert(*(AsmStrsNoRegAltName+RegAsmOffsetNoRegAltName[RegNo-1]) && + "Invalid alt name index for register!"); + return AsmStrsNoRegAltName+RegAsmOffsetNoRegAltName[RegNo-1]; + } +#else + return NULL; +#endif +} + +#ifdef PRINT_ALIAS_INSTR +#undef PRINT_ALIAS_INSTR + +static bool RISCVInstPrinterValidateMCOperand(MCOperand *MCOp, + unsigned PredicateIndex); + +static bool printAliasInstr(MCInst *MI, SStream * OS, void *info) +{ + MCRegisterInfo *MRI = (MCRegisterInfo *) info; + const char *AsmString; + unsigned I = 0; + char *tmpString; + switch (MCInst_getOpcode(MI)) { + default: return false; + case RISCV_ADDI: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (ADDI X0, X0, 0) + AsmString = "nop"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (ADDI GPR:$rd, GPR:$rs, 0) + AsmString = "mv $\x01, $\x02"; + break; + } + return false; + case RISCV_ADDIW: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (ADDIW GPR:$rd, GPR:$rs, 0) + AsmString = "sext.w $\x01, $\x02"; + break; + } + return false; + case RISCV_BEQ: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BEQ GPR:$rs, X0, simm13_lsb0:$offset) + AsmString = "beqz $\x01, $\x03"; + break; + } + return false; + case RISCV_BGE: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BGE X0, GPR:$rs, simm13_lsb0:$offset) + AsmString = "blez $\x02, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BGE GPR:$rs, X0, simm13_lsb0:$offset) + AsmString = "bgez $\x01, $\x03"; + break; + } + return false; + case RISCV_BLT: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BLT GPR:$rs, X0, simm13_lsb0:$offset) + AsmString = "bltz $\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BLT X0, GPR:$rs, simm13_lsb0:$offset) + AsmString = "bgtz $\x02, $\x03"; + break; + } + return false; + case RISCV_BNE: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 2), 1)) { + // (BNE GPR:$rs, X0, simm13_lsb0:$offset) + AsmString = "bnez $\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRC: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRC X0, csr_sysreg:$csr, GPR:$rs) + AsmString = "csrc $\xFF\x02\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRCI: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0) { + // (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm) + AsmString = "csrci $\xFF\x02\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRS: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3, X0) + AsmString = "frcsr $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 2 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 2, X0) + AsmString = "frrm $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 1 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 1, X0) + AsmString = "frflags $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3074 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3074, X0) + AsmString = "rdinstret $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3072 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3072, X0) + AsmString = "rdcycle $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3073 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3073, X0) + AsmString = "rdtime $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3202 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3202, X0) + AsmString = "rdinstreth $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3200 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3200, X0) + AsmString = "rdcycleh $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3201 && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, 3201, X0) + AsmString = "rdtimeh $\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (CSRRS GPR:$rd, csr_sysreg:$csr, X0) + AsmString = "csrr $\x01, $\xFF\x02\x01"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRS X0, csr_sysreg:$csr, GPR:$rs) + AsmString = "csrs $\xFF\x02\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRSI: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0) { + // (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm) + AsmString = "csrsi $\xFF\x02\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRW: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW X0, 3, GPR:$rs) + AsmString = "fscsr $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 2 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW X0, 2, GPR:$rs) + AsmString = "fsrm $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 1 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW X0, 1, GPR:$rs) + AsmString = "fsflags $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW X0, csr_sysreg:$csr, GPR:$rs) + AsmString = "csrw $\xFF\x02\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW GPR:$rd, 3, GPR:$rs) + AsmString = "fscsr $\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 2 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW GPR:$rd, 2, GPR:$rs) + AsmString = "fsrm $\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 1 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (CSRRW GPR:$rd, 1, GPR:$rs) + AsmString = "fsflags $\x01, $\x03"; + break; + } + return false; + case RISCV_CSRRWI: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 2) { + // (CSRRWI X0, 2, uimm5:$imm) + AsmString = "fsrmi $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 1) { + // (CSRRWI X0, 1, uimm5:$imm) + AsmString = "fsflagsi $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0) { + // (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm) + AsmString = "csrwi $\xFF\x02\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 2) { + // (CSRRWI GPR:$rd, 2, uimm5:$imm) + AsmString = "fsrmi $\x01, $\x03"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 1) { + // (CSRRWI GPR:$rd, 1, uimm5:$imm) + AsmString = "fsflagsi $\x01, $\x03"; + break; + } + return false; + case RISCV_FADD_D: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FADD_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, { 1, 1, 1 }) + AsmString = "fadd.d $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FADD_S: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FADD_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, { 1, 1, 1 }) + AsmString = "fadd.s $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FCVT_D_L: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_D_L FPR64:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.d.l $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_D_LU: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_D_LU FPR64:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.d.lu $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_LU_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_LU_D GPR:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.lu.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_LU_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_LU_S GPR:$rd, FPR32:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.lu.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_L_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_L_D GPR:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.l.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_L_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_L_S GPR:$rd, FPR32:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.l.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_S_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_S_D FPR32:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.s.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_S_L: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_S_L FPR32:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.s.l $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_S_LU: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_S_LU FPR32:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.s.lu $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_S_W: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_S_W FPR32:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.s.w $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_S_WU: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_S_WU FPR32:$rd, GPR:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.s.wu $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_WU_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_WU_D GPR:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.wu.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_WU_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_WU_S GPR:$rd, FPR32:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.wu.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_W_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_W_D GPR:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.w.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FCVT_W_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FCVT_W_S GPR:$rd, FPR32:$rs1, { 1, 1, 1 }) + AsmString = "fcvt.w.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FDIV_D: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FDIV_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, { 1, 1, 1 }) + AsmString = "fdiv.d $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FDIV_S: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FDIV_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, { 1, 1, 1 }) + AsmString = "fdiv.s $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FENCE: + if (MCInst_getNumOperands(MI) == 2 && + MCOperand_isImm(MCInst_getOperand(MI, 0)) && + MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15 && + MCOperand_isImm(MCInst_getOperand(MI, 1)) && + MCOperand_getImm(MCInst_getOperand(MI, 1)) == 15) { + // (FENCE 15, 15) + AsmString = "fence"; + break; + } + return false; + case RISCV_FMADD_D: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FMADD_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, { 1, 1, 1 }) + AsmString = "fmadd.d $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FMADD_S: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FMADD_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, { 1, 1, 1 }) + AsmString = "fmadd.s $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FMSUB_D: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FMSUB_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, { 1, 1, 1 }) + AsmString = "fmsub.d $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FMSUB_S: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FMSUB_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, { 1, 1, 1 }) + AsmString = "fmsub.s $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FMUL_D: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FMUL_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, { 1, 1, 1 }) + AsmString = "fmul.d $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FMUL_S: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FMUL_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, { 1, 1, 1 }) + AsmString = "fmul.s $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FNMADD_D: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FNMADD_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, { 1, 1, 1 }) + AsmString = "fnmadd.d $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FNMADD_S: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FNMADD_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, { 1, 1, 1 }) + AsmString = "fnmadd.s $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FNMSUB_D: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FNMSUB_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, { 1, 1, 1 }) + AsmString = "fnmsub.d $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FNMSUB_S: + if (MCInst_getNumOperands(MI) == 5 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isReg(MCInst_getOperand(MI, 3)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 3))) && + MCOperand_isImm(MCInst_getOperand(MI, 4)) && + MCOperand_getImm(MCInst_getOperand(MI, 4)) == 7) { + // (FNMSUB_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, { 1, 1, 1 }) + AsmString = "fnmsub.s $\x01, $\x02, $\x03, $\x04"; + break; + } + return false; + case RISCV_FSGNJN_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJN_D FPR64:$rd, FPR64:$rs, FPR64:$rs) + AsmString = "fneg.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FSGNJN_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJN_S FPR32:$rd, FPR32:$rs, FPR32:$rs) + AsmString = "fneg.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FSGNJX_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJX_D FPR64:$rd, FPR64:$rs, FPR64:$rs) + AsmString = "fabs.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FSGNJX_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJX_S FPR32:$rd, FPR32:$rs, FPR32:$rs) + AsmString = "fabs.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FSGNJ_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJ_D FPR64:$rd, FPR64:$rs, FPR64:$rs) + AsmString = "fmv.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FSGNJ_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == MCOperand_getReg(MCInst_getOperand(MI, 1))) { + // (FSGNJ_S FPR32:$rd, FPR32:$rs, FPR32:$rs) + AsmString = "fmv.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FSQRT_D: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FSQRT_D FPR64:$rd, FPR64:$rs1, { 1, 1, 1 }) + AsmString = "fsqrt.d $\x01, $\x02"; + break; + } + return false; + case RISCV_FSQRT_S: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 7) { + // (FSQRT_S FPR32:$rd, FPR32:$rs1, { 1, 1, 1 }) + AsmString = "fsqrt.s $\x01, $\x02"; + break; + } + return false; + case RISCV_FSUB_D: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR64RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FSUB_D FPR64:$rd, FPR64:$rs1, FPR64:$rs2, { 1, 1, 1 }) + AsmString = "fsub.d $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_FSUB_S: + if (MCInst_getNumOperands(MI) == 4 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_FPR32RegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2))) && + MCOperand_isImm(MCInst_getOperand(MI, 3)) && + MCOperand_getImm(MCInst_getOperand(MI, 3)) == 7) { + // (FSUB_S FPR32:$rd, FPR32:$rs1, FPR32:$rs2, { 1, 1, 1 }) + AsmString = "fsub.s $\x01, $\x02, $\x03"; + break; + } + return false; + case RISCV_JAL: + if (MCInst_getNumOperands(MI) == 2 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 1), 2)) { + // (JAL X0, simm21_lsb0_jal:$offset) + AsmString = "j $\x02"; + break; + } + if (MCInst_getNumOperands(MI) == 2 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X1 && + RISCVInstPrinterValidateMCOperand(MCInst_getOperand(MI, 1), 2)) { + // (JAL X1, simm21_lsb0_jal:$offset) + AsmString = "jal $\x02"; + break; + } + return false; + case RISCV_JALR: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X1 && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (JALR X0, X1, 0) + AsmString = "ret"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (JALR X0, GPR:$rs, 0) + AsmString = "jr $\x02"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X1 && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 0) { + // (JALR X1, GPR:$rs, 0) + AsmString = "jalr $\x02"; + break; + } + return false; + case RISCV_SFENCE_VMA: + if (MCInst_getNumOperands(MI) == 2 && + MCOperand_getReg(MCInst_getOperand(MI, 0)) == RISCV_X0 && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0) { + // (SFENCE_VMA X0, X0) + AsmString = "sfence.vma"; + break; + } + if (MCInst_getNumOperands(MI) == 2 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0) { + // (SFENCE_VMA GPR:$rs, X0) + AsmString = "sfence.vma $\x01"; + break; + } + return false; + case RISCV_SLT: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_getReg(MCInst_getOperand(MI, 2)) == RISCV_X0) { + // (SLT GPR:$rd, GPR:$rs, X0) + AsmString = "sltz $\x01, $\x02"; + break; + } + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (SLT GPR:$rd, X0, GPR:$rs) + AsmString = "sgtz $\x01, $\x03"; + break; + } + return false; + case RISCV_SLTIU: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == 1) { + // (SLTIU GPR:$rd, GPR:$rs, 1) + AsmString = "seqz $\x01, $\x02"; + break; + } + return false; + case RISCV_SLTU: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (SLTU GPR:$rd, X0, GPR:$rs) + AsmString = "snez $\x01, $\x03"; + break; + } + return false; + case RISCV_SUB: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (SUB GPR:$rd, X0, GPR:$rs) + AsmString = "neg $\x01, $\x03"; + break; + } + return false; + case RISCV_SUBW: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_getReg(MCInst_getOperand(MI, 1)) == RISCV_X0 && + MCOperand_isReg(MCInst_getOperand(MI, 2)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 2)))) { + // (SUBW GPR:$rd, X0, GPR:$rs) + AsmString = "negw $\x01, $\x03"; + break; + } + return false; + case RISCV_XORI: + if (MCInst_getNumOperands(MI) == 3 && + MCOperand_isReg(MCInst_getOperand(MI, 0)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 0))) && + MCOperand_isReg(MCInst_getOperand(MI, 1)) && + MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, RISCV_GPRRegClassID), MCOperand_getReg(MCInst_getOperand(MI, 1))) && + MCOperand_isImm(MCInst_getOperand(MI, 2)) && + MCOperand_getImm(MCInst_getOperand(MI, 2)) == -1) { + // (XORI GPR:$rd, GPR:$rs, -1) + AsmString = "not $\x01, $\x02"; + break; + } + return false; + } + + tmpString = cs_strdup(AsmString); + while (AsmString[I] != ' ' && AsmString[I] != '\t' && + AsmString[I] != '$' && AsmString[I] != '\0') + ++I; + tmpString[I] = 0; + SStream_concat0(OS, tmpString); + if (AsmString[I] != '\0') { + if (AsmString[I] == ' ' || AsmString[I] == '\t') { + SStream_concat0(OS, " "); + ++I; + } + do { + if (AsmString[I] == '$') { + ++I; + if (AsmString[I] == (char)0xff) { + ++I; + int OpIdx = AsmString[I++] - 1; + int PrintMethodIdx = AsmString[I++] - 1; + printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS); + } else + printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS); + } else { + SStream_concat0(OS, &AsmString[I++]); + } + } while (AsmString[I] != '\0'); + } + + return true; +} + +static void printCustomAliasOperand( + MCInst *MI, unsigned OpIdx, + unsigned PrintMethodIdx, + SStream *OS) { + switch (PrintMethodIdx) { + default: + assert(0 && "Unknown PrintMethod kind"); + break; + case 0: + printCSRSystemRegister(MI, OpIdx, OS); + break; + } +} + +static bool RISCVInstPrinterValidateMCOperand(MCOperand *MCOp, + unsigned PredicateIndex) { + // TODO: need some constant untils operate the MCOperand, + // but current CAPSTONE does't have. + // So, We just return true + return true; + +#if 0 + switch (PredicateIndex) { + default: + llvm_unreachable("Unknown MCOperandPredicate kind"); + break; + case 1: { + + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return isShiftedInt<12, 1>(Imm); + return MCOp.isBareSymbolRef(); + + } + case 2: { + + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return isShiftedInt<20, 1>(Imm); + return MCOp.isBareSymbolRef(); + + } + } +#endif +} + +#endif // PRINT_ALIAS_INSTR diff --git a/arch/RISCV/RISCVGenDisassemblerTables.inc b/arch/RISCV/RISCVGenDisassemblerTables.inc new file mode 100644 index 000000000..21ff4ff08 --- /dev/null +++ b/arch/RISCV/RISCVGenDisassemblerTables.inc @@ -0,0 +1,1776 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* * RISCV Disassembler *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2015 */ + +#include "../../MCInst.h" +#include "../../LEB128.h" +#include + +// Helper functions for extracting fields from encoded instructions. +// InsnType must either be integral or an APInt-like object that must: +// * Have a static const max_size_in_bits equal to the number of bits in the +// encoding. +// * be default-constructible and copy-constructible +// * be constructible from a uint64_t +// * be constructible from an APInt (this can be private) +// * Support getBitsSet(loBit, hiBit) +// * be convertible to uint64_t +// * Support the ~, &, ==, !=, and |= operators with other objects of the same type +// * Support shift (<<, >>) with signed and unsigned integers on the RHS +// * Support put (<<) to raw_ostream& +#define FieldFromInstruction(fname, InsnType) \ +static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \ +{ \ + InsnType fieldMask; \ + if (numBits == sizeof(InsnType)*8) \ + fieldMask = (InsnType)(-1LL); \ + else \ + fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \ + return (insn & fieldMask) >> startBit; \ +} + +static const uint8_t DecoderTable16[] = { +/* 0 */ MCD_OPC_ExtractField, 13, 3, // Inst{15-13} ... +/* 3 */ MCD_OPC_FilterValue, 0, 77, 0, 0, // Skip to: 85 +/* 8 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 11 */ MCD_OPC_FilterValue, 0, 25, 0, 0, // Skip to: 41 +/* 16 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 32 +/* 21 */ MCD_OPC_CheckField, 2, 11, 0, 4, 0, 0, // Skip to: 32 +/* 28 */ MCD_OPC_Decode, 182, 2, 0, // Opcode: C_UNIMP +/* 32 */ MCD_OPC_CheckPredicate, 0, 116, 2, 0, // Skip to: 665 +/* 37 */ MCD_OPC_Decode, 144, 2, 1, // Opcode: C_ADDI4SPN +/* 41 */ MCD_OPC_FilterValue, 1, 25, 0, 0, // Skip to: 71 +/* 46 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 62 +/* 51 */ MCD_OPC_CheckField, 7, 6, 0, 4, 0, 0, // Skip to: 62 +/* 58 */ MCD_OPC_Decode, 171, 2, 0, // Opcode: C_NOP +/* 62 */ MCD_OPC_CheckPredicate, 0, 86, 2, 0, // Skip to: 665 +/* 67 */ MCD_OPC_Decode, 142, 2, 2, // Opcode: C_ADDI +/* 71 */ MCD_OPC_FilterValue, 2, 77, 2, 0, // Skip to: 665 +/* 76 */ MCD_OPC_CheckPredicate, 0, 72, 2, 0, // Skip to: 665 +/* 81 */ MCD_OPC_Decode, 175, 2, 3, // Opcode: C_SLLI +/* 85 */ MCD_OPC_FilterValue, 1, 45, 0, 0, // Skip to: 135 +/* 90 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 93 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 107 +/* 98 */ MCD_OPC_CheckPredicate, 1, 50, 2, 0, // Skip to: 665 +/* 103 */ MCD_OPC_Decode, 152, 2, 4, // Opcode: C_FLD +/* 107 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 121 +/* 112 */ MCD_OPC_CheckPredicate, 2, 36, 2, 0, // Skip to: 665 +/* 117 */ MCD_OPC_Decode, 145, 2, 2, // Opcode: C_ADDIW +/* 121 */ MCD_OPC_FilterValue, 2, 27, 2, 0, // Skip to: 665 +/* 126 */ MCD_OPC_CheckPredicate, 1, 22, 2, 0, // Skip to: 665 +/* 131 */ MCD_OPC_Decode, 153, 2, 5, // Opcode: C_FLDSP +/* 135 */ MCD_OPC_FilterValue, 2, 45, 0, 0, // Skip to: 185 +/* 140 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 143 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 157 +/* 148 */ MCD_OPC_CheckPredicate, 0, 0, 2, 0, // Skip to: 665 +/* 153 */ MCD_OPC_Decode, 168, 2, 6, // Opcode: C_LW +/* 157 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 171 +/* 162 */ MCD_OPC_CheckPredicate, 0, 242, 1, 0, // Skip to: 665 +/* 167 */ MCD_OPC_Decode, 166, 2, 7, // Opcode: C_LI +/* 171 */ MCD_OPC_FilterValue, 2, 233, 1, 0, // Skip to: 665 +/* 176 */ MCD_OPC_CheckPredicate, 0, 228, 1, 0, // Skip to: 665 +/* 181 */ MCD_OPC_Decode, 169, 2, 8, // Opcode: C_LWSP +/* 185 */ MCD_OPC_FilterValue, 3, 61, 0, 0, // Skip to: 251 +/* 190 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 193 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 207 +/* 198 */ MCD_OPC_CheckPredicate, 2, 206, 1, 0, // Skip to: 665 +/* 203 */ MCD_OPC_Decode, 164, 2, 9, // Opcode: C_LD +/* 207 */ MCD_OPC_FilterValue, 1, 25, 0, 0, // Skip to: 237 +/* 212 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 228 +/* 217 */ MCD_OPC_CheckField, 7, 5, 2, 4, 0, 0, // Skip to: 228 +/* 224 */ MCD_OPC_Decode, 143, 2, 10, // Opcode: C_ADDI16SP +/* 228 */ MCD_OPC_CheckPredicate, 0, 176, 1, 0, // Skip to: 665 +/* 233 */ MCD_OPC_Decode, 167, 2, 11, // Opcode: C_LUI +/* 237 */ MCD_OPC_FilterValue, 2, 167, 1, 0, // Skip to: 665 +/* 242 */ MCD_OPC_CheckPredicate, 2, 162, 1, 0, // Skip to: 665 +/* 247 */ MCD_OPC_Decode, 165, 2, 12, // Opcode: C_LDSP +/* 251 */ MCD_OPC_FilterValue, 4, 3, 1, 0, // Skip to: 515 +/* 256 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 259 */ MCD_OPC_FilterValue, 1, 167, 0, 0, // Skip to: 431 +/* 264 */ MCD_OPC_ExtractField, 10, 2, // Inst{11-10} ... +/* 267 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 281 +/* 272 */ MCD_OPC_CheckPredicate, 0, 132, 1, 0, // Skip to: 665 +/* 277 */ MCD_OPC_Decode, 177, 2, 13, // Opcode: C_SRLI +/* 281 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 295 +/* 286 */ MCD_OPC_CheckPredicate, 0, 118, 1, 0, // Skip to: 665 +/* 291 */ MCD_OPC_Decode, 176, 2, 13, // Opcode: C_SRAI +/* 295 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 309 +/* 300 */ MCD_OPC_CheckPredicate, 0, 104, 1, 0, // Skip to: 665 +/* 305 */ MCD_OPC_Decode, 148, 2, 14, // Opcode: C_ANDI +/* 309 */ MCD_OPC_FilterValue, 3, 95, 1, 0, // Skip to: 665 +/* 314 */ MCD_OPC_ExtractField, 5, 2, // Inst{6-5} ... +/* 317 */ MCD_OPC_FilterValue, 0, 31, 0, 0, // Skip to: 353 +/* 322 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ... +/* 325 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 339 +/* 330 */ MCD_OPC_CheckPredicate, 0, 74, 1, 0, // Skip to: 665 +/* 335 */ MCD_OPC_Decode, 178, 2, 15, // Opcode: C_SUB +/* 339 */ MCD_OPC_FilterValue, 1, 65, 1, 0, // Skip to: 665 +/* 344 */ MCD_OPC_CheckPredicate, 2, 60, 1, 0, // Skip to: 665 +/* 349 */ MCD_OPC_Decode, 179, 2, 15, // Opcode: C_SUBW +/* 353 */ MCD_OPC_FilterValue, 1, 31, 0, 0, // Skip to: 389 +/* 358 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ... +/* 361 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 375 +/* 366 */ MCD_OPC_CheckPredicate, 0, 38, 1, 0, // Skip to: 665 +/* 371 */ MCD_OPC_Decode, 183, 2, 15, // Opcode: C_XOR +/* 375 */ MCD_OPC_FilterValue, 1, 29, 1, 0, // Skip to: 665 +/* 380 */ MCD_OPC_CheckPredicate, 2, 24, 1, 0, // Skip to: 665 +/* 385 */ MCD_OPC_Decode, 146, 2, 15, // Opcode: C_ADDW +/* 389 */ MCD_OPC_FilterValue, 2, 16, 0, 0, // Skip to: 410 +/* 394 */ MCD_OPC_CheckPredicate, 0, 10, 1, 0, // Skip to: 665 +/* 399 */ MCD_OPC_CheckField, 12, 1, 0, 3, 1, 0, // Skip to: 665 +/* 406 */ MCD_OPC_Decode, 172, 2, 15, // Opcode: C_OR +/* 410 */ MCD_OPC_FilterValue, 3, 250, 0, 0, // Skip to: 665 +/* 415 */ MCD_OPC_CheckPredicate, 0, 245, 0, 0, // Skip to: 665 +/* 420 */ MCD_OPC_CheckField, 12, 1, 0, 238, 0, 0, // Skip to: 665 +/* 427 */ MCD_OPC_Decode, 147, 2, 15, // Opcode: C_AND +/* 431 */ MCD_OPC_FilterValue, 2, 229, 0, 0, // Skip to: 665 +/* 436 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ... +/* 439 */ MCD_OPC_FilterValue, 0, 25, 0, 0, // Skip to: 469 +/* 444 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 460 +/* 449 */ MCD_OPC_CheckField, 2, 5, 0, 4, 0, 0, // Skip to: 460 +/* 456 */ MCD_OPC_Decode, 163, 2, 16, // Opcode: C_JR +/* 460 */ MCD_OPC_CheckPredicate, 0, 200, 0, 0, // Skip to: 665 +/* 465 */ MCD_OPC_Decode, 170, 2, 17, // Opcode: C_MV +/* 469 */ MCD_OPC_FilterValue, 1, 191, 0, 0, // Skip to: 665 +/* 474 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 490 +/* 479 */ MCD_OPC_CheckField, 2, 10, 0, 4, 0, 0, // Skip to: 490 +/* 486 */ MCD_OPC_Decode, 151, 2, 0, // Opcode: C_EBREAK +/* 490 */ MCD_OPC_CheckPredicate, 0, 11, 0, 0, // Skip to: 506 +/* 495 */ MCD_OPC_CheckField, 2, 5, 0, 4, 0, 0, // Skip to: 506 +/* 502 */ MCD_OPC_Decode, 162, 2, 16, // Opcode: C_JALR +/* 506 */ MCD_OPC_CheckPredicate, 0, 154, 0, 0, // Skip to: 665 +/* 511 */ MCD_OPC_Decode, 141, 2, 18, // Opcode: C_ADD +/* 515 */ MCD_OPC_FilterValue, 5, 45, 0, 0, // Skip to: 565 +/* 520 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 523 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 537 +/* 528 */ MCD_OPC_CheckPredicate, 1, 132, 0, 0, // Skip to: 665 +/* 533 */ MCD_OPC_Decode, 156, 2, 4, // Opcode: C_FSD +/* 537 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 551 +/* 542 */ MCD_OPC_CheckPredicate, 0, 118, 0, 0, // Skip to: 665 +/* 547 */ MCD_OPC_Decode, 160, 2, 19, // Opcode: C_J +/* 551 */ MCD_OPC_FilterValue, 2, 109, 0, 0, // Skip to: 665 +/* 556 */ MCD_OPC_CheckPredicate, 1, 104, 0, 0, // Skip to: 665 +/* 561 */ MCD_OPC_Decode, 157, 2, 20, // Opcode: C_FSDSP +/* 565 */ MCD_OPC_FilterValue, 6, 45, 0, 0, // Skip to: 615 +/* 570 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 573 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 587 +/* 578 */ MCD_OPC_CheckPredicate, 0, 82, 0, 0, // Skip to: 665 +/* 583 */ MCD_OPC_Decode, 180, 2, 6, // Opcode: C_SW +/* 587 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 601 +/* 592 */ MCD_OPC_CheckPredicate, 0, 68, 0, 0, // Skip to: 665 +/* 597 */ MCD_OPC_Decode, 149, 2, 21, // Opcode: C_BEQZ +/* 601 */ MCD_OPC_FilterValue, 2, 59, 0, 0, // Skip to: 665 +/* 606 */ MCD_OPC_CheckPredicate, 0, 54, 0, 0, // Skip to: 665 +/* 611 */ MCD_OPC_Decode, 181, 2, 22, // Opcode: C_SWSP +/* 615 */ MCD_OPC_FilterValue, 7, 45, 0, 0, // Skip to: 665 +/* 620 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 623 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 637 +/* 628 */ MCD_OPC_CheckPredicate, 2, 32, 0, 0, // Skip to: 665 +/* 633 */ MCD_OPC_Decode, 173, 2, 9, // Opcode: C_SD +/* 637 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 651 +/* 642 */ MCD_OPC_CheckPredicate, 0, 18, 0, 0, // Skip to: 665 +/* 647 */ MCD_OPC_Decode, 150, 2, 21, // Opcode: C_BNEZ +/* 651 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 665 +/* 656 */ MCD_OPC_CheckPredicate, 2, 4, 0, 0, // Skip to: 665 +/* 661 */ MCD_OPC_Decode, 174, 2, 23, // Opcode: C_SDSP +/* 665 */ MCD_OPC_Fail, + 0 +}; + +static const uint8_t DecoderTable32[] = { +/* 0 */ MCD_OPC_ExtractField, 0, 7, // Inst{6-0} ... +/* 3 */ MCD_OPC_FilterValue, 3, 76, 0, 0, // Skip to: 84 +/* 8 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 11 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 20 +/* 16 */ MCD_OPC_Decode, 129, 3, 24, // Opcode: LB +/* 20 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 29 +/* 25 */ MCD_OPC_Decode, 132, 3, 24, // Opcode: LH +/* 29 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 38 +/* 34 */ MCD_OPC_Decode, 143, 3, 24, // Opcode: LW +/* 38 */ MCD_OPC_FilterValue, 3, 9, 0, 0, // Skip to: 52 +/* 43 */ MCD_OPC_CheckPredicate, 3, 55, 15, 0, // Skip to: 3943 +/* 48 */ MCD_OPC_Decode, 131, 3, 24, // Opcode: LD +/* 52 */ MCD_OPC_FilterValue, 4, 4, 0, 0, // Skip to: 61 +/* 57 */ MCD_OPC_Decode, 130, 3, 24, // Opcode: LBU +/* 61 */ MCD_OPC_FilterValue, 5, 4, 0, 0, // Skip to: 70 +/* 66 */ MCD_OPC_Decode, 133, 3, 24, // Opcode: LHU +/* 70 */ MCD_OPC_FilterValue, 6, 28, 15, 0, // Skip to: 3943 +/* 75 */ MCD_OPC_CheckPredicate, 3, 23, 15, 0, // Skip to: 3943 +/* 80 */ MCD_OPC_Decode, 144, 3, 24, // Opcode: LWU +/* 84 */ MCD_OPC_FilterValue, 7, 31, 0, 0, // Skip to: 120 +/* 89 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 92 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 106 +/* 97 */ MCD_OPC_CheckPredicate, 4, 1, 15, 0, // Skip to: 3943 +/* 102 */ MCD_OPC_Decode, 224, 2, 25, // Opcode: FLW +/* 106 */ MCD_OPC_FilterValue, 3, 248, 14, 0, // Skip to: 3943 +/* 111 */ MCD_OPC_CheckPredicate, 5, 243, 14, 0, // Skip to: 3943 +/* 116 */ MCD_OPC_Decode, 219, 2, 26, // Opcode: FLD +/* 120 */ MCD_OPC_FilterValue, 15, 52, 0, 0, // Skip to: 177 +/* 125 */ MCD_OPC_ExtractField, 7, 13, // Inst{19-7} ... +/* 128 */ MCD_OPC_FilterValue, 0, 28, 0, 0, // Skip to: 161 +/* 133 */ MCD_OPC_ExtractField, 28, 4, // Inst{31-28} ... +/* 136 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 145 +/* 141 */ MCD_OPC_Decode, 214, 2, 27, // Opcode: FENCE +/* 145 */ MCD_OPC_FilterValue, 8, 209, 14, 0, // Skip to: 3943 +/* 150 */ MCD_OPC_CheckField, 20, 8, 51, 202, 14, 0, // Skip to: 3943 +/* 157 */ MCD_OPC_Decode, 216, 2, 0, // Opcode: FENCE_TSO +/* 161 */ MCD_OPC_FilterValue, 32, 193, 14, 0, // Skip to: 3943 +/* 166 */ MCD_OPC_CheckField, 20, 12, 0, 186, 14, 0, // Skip to: 3943 +/* 173 */ MCD_OPC_Decode, 215, 2, 0, // Opcode: FENCE_I +/* 177 */ MCD_OPC_FilterValue, 19, 99, 0, 0, // Skip to: 281 +/* 182 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 185 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 194 +/* 190 */ MCD_OPC_Decode, 179, 1, 24, // Opcode: ADDI +/* 194 */ MCD_OPC_FilterValue, 1, 11, 0, 0, // Skip to: 210 +/* 199 */ MCD_OPC_CheckField, 26, 6, 0, 153, 14, 0, // Skip to: 3943 +/* 206 */ MCD_OPC_Decode, 170, 3, 28, // Opcode: SLLI +/* 210 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 219 +/* 215 */ MCD_OPC_Decode, 174, 3, 24, // Opcode: SLTI +/* 219 */ MCD_OPC_FilterValue, 3, 4, 0, 0, // Skip to: 228 +/* 224 */ MCD_OPC_Decode, 175, 3, 24, // Opcode: SLTIU +/* 228 */ MCD_OPC_FilterValue, 4, 4, 0, 0, // Skip to: 237 +/* 233 */ MCD_OPC_Decode, 193, 3, 24, // Opcode: XORI +/* 237 */ MCD_OPC_FilterValue, 5, 21, 0, 0, // Skip to: 263 +/* 242 */ MCD_OPC_ExtractField, 26, 6, // Inst{31-26} ... +/* 245 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 254 +/* 250 */ MCD_OPC_Decode, 183, 3, 28, // Opcode: SRLI +/* 254 */ MCD_OPC_FilterValue, 16, 100, 14, 0, // Skip to: 3943 +/* 259 */ MCD_OPC_Decode, 178, 3, 28, // Opcode: SRAI +/* 263 */ MCD_OPC_FilterValue, 6, 4, 0, 0, // Skip to: 272 +/* 268 */ MCD_OPC_Decode, 152, 3, 24, // Opcode: ORI +/* 272 */ MCD_OPC_FilterValue, 7, 82, 14, 0, // Skip to: 3943 +/* 277 */ MCD_OPC_Decode, 255, 1, 24, // Opcode: ANDI +/* 281 */ MCD_OPC_FilterValue, 23, 4, 0, 0, // Skip to: 290 +/* 286 */ MCD_OPC_Decode, 128, 2, 29, // Opcode: AUIPC +/* 290 */ MCD_OPC_FilterValue, 27, 74, 0, 0, // Skip to: 369 +/* 295 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 298 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 312 +/* 303 */ MCD_OPC_CheckPredicate, 3, 51, 14, 0, // Skip to: 3943 +/* 308 */ MCD_OPC_Decode, 180, 1, 24, // Opcode: ADDIW +/* 312 */ MCD_OPC_FilterValue, 1, 16, 0, 0, // Skip to: 333 +/* 317 */ MCD_OPC_CheckPredicate, 3, 37, 14, 0, // Skip to: 3943 +/* 322 */ MCD_OPC_CheckField, 25, 7, 0, 30, 14, 0, // Skip to: 3943 +/* 329 */ MCD_OPC_Decode, 171, 3, 30, // Opcode: SLLIW +/* 333 */ MCD_OPC_FilterValue, 5, 21, 14, 0, // Skip to: 3943 +/* 338 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 341 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 355 +/* 346 */ MCD_OPC_CheckPredicate, 3, 8, 14, 0, // Skip to: 3943 +/* 351 */ MCD_OPC_Decode, 184, 3, 30, // Opcode: SRLIW +/* 355 */ MCD_OPC_FilterValue, 32, 255, 13, 0, // Skip to: 3943 +/* 360 */ MCD_OPC_CheckPredicate, 3, 250, 13, 0, // Skip to: 3943 +/* 365 */ MCD_OPC_Decode, 179, 3, 30, // Opcode: SRAIW +/* 369 */ MCD_OPC_FilterValue, 35, 44, 0, 0, // Skip to: 418 +/* 374 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 377 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 386 +/* 382 */ MCD_OPC_Decode, 157, 3, 31, // Opcode: SB +/* 386 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 395 +/* 391 */ MCD_OPC_Decode, 168, 3, 31, // Opcode: SH +/* 395 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 404 +/* 400 */ MCD_OPC_Decode, 188, 3, 31, // Opcode: SW +/* 404 */ MCD_OPC_FilterValue, 3, 206, 13, 0, // Skip to: 3943 +/* 409 */ MCD_OPC_CheckPredicate, 3, 201, 13, 0, // Skip to: 3943 +/* 414 */ MCD_OPC_Decode, 166, 3, 31, // Opcode: SD +/* 418 */ MCD_OPC_FilterValue, 39, 31, 0, 0, // Skip to: 454 +/* 423 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 426 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 440 +/* 431 */ MCD_OPC_CheckPredicate, 4, 179, 13, 0, // Skip to: 3943 +/* 436 */ MCD_OPC_Decode, 254, 2, 32, // Opcode: FSW +/* 440 */ MCD_OPC_FilterValue, 3, 170, 13, 0, // Skip to: 3943 +/* 445 */ MCD_OPC_CheckPredicate, 5, 165, 13, 0, // Skip to: 3943 +/* 450 */ MCD_OPC_Decode, 243, 2, 33, // Opcode: FSD +/* 454 */ MCD_OPC_FilterValue, 47, 107, 6, 0, // Skip to: 2102 +/* 459 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 462 */ MCD_OPC_FilterValue, 0, 31, 0, 0, // Skip to: 498 +/* 467 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 470 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 484 +/* 475 */ MCD_OPC_CheckPredicate, 6, 135, 13, 0, // Skip to: 3943 +/* 480 */ MCD_OPC_Decode, 186, 1, 34, // Opcode: AMOADD_W +/* 484 */ MCD_OPC_FilterValue, 3, 126, 13, 0, // Skip to: 3943 +/* 489 */ MCD_OPC_CheckPredicate, 7, 121, 13, 0, // Skip to: 3943 +/* 494 */ MCD_OPC_Decode, 182, 1, 34, // Opcode: AMOADD_D +/* 498 */ MCD_OPC_FilterValue, 1, 31, 0, 0, // Skip to: 534 +/* 503 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 506 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 520 +/* 511 */ MCD_OPC_CheckPredicate, 6, 99, 13, 0, // Skip to: 3943 +/* 516 */ MCD_OPC_Decode, 189, 1, 34, // Opcode: AMOADD_W_RL +/* 520 */ MCD_OPC_FilterValue, 3, 90, 13, 0, // Skip to: 3943 +/* 525 */ MCD_OPC_CheckPredicate, 7, 85, 13, 0, // Skip to: 3943 +/* 530 */ MCD_OPC_Decode, 185, 1, 34, // Opcode: AMOADD_D_RL +/* 534 */ MCD_OPC_FilterValue, 2, 31, 0, 0, // Skip to: 570 +/* 539 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 542 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 556 +/* 547 */ MCD_OPC_CheckPredicate, 6, 63, 13, 0, // Skip to: 3943 +/* 552 */ MCD_OPC_Decode, 187, 1, 34, // Opcode: AMOADD_W_AQ +/* 556 */ MCD_OPC_FilterValue, 3, 54, 13, 0, // Skip to: 3943 +/* 561 */ MCD_OPC_CheckPredicate, 7, 49, 13, 0, // Skip to: 3943 +/* 566 */ MCD_OPC_Decode, 183, 1, 34, // Opcode: AMOADD_D_AQ +/* 570 */ MCD_OPC_FilterValue, 3, 31, 0, 0, // Skip to: 606 +/* 575 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 578 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 592 +/* 583 */ MCD_OPC_CheckPredicate, 6, 27, 13, 0, // Skip to: 3943 +/* 588 */ MCD_OPC_Decode, 188, 1, 34, // Opcode: AMOADD_W_AQ_RL +/* 592 */ MCD_OPC_FilterValue, 3, 18, 13, 0, // Skip to: 3943 +/* 597 */ MCD_OPC_CheckPredicate, 7, 13, 13, 0, // Skip to: 3943 +/* 602 */ MCD_OPC_Decode, 184, 1, 34, // Opcode: AMOADD_D_AQ_RL +/* 606 */ MCD_OPC_FilterValue, 4, 31, 0, 0, // Skip to: 642 +/* 611 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 614 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 628 +/* 619 */ MCD_OPC_CheckPredicate, 6, 247, 12, 0, // Skip to: 3943 +/* 624 */ MCD_OPC_Decode, 242, 1, 34, // Opcode: AMOSWAP_W +/* 628 */ MCD_OPC_FilterValue, 3, 238, 12, 0, // Skip to: 3943 +/* 633 */ MCD_OPC_CheckPredicate, 7, 233, 12, 0, // Skip to: 3943 +/* 638 */ MCD_OPC_Decode, 238, 1, 34, // Opcode: AMOSWAP_D +/* 642 */ MCD_OPC_FilterValue, 5, 31, 0, 0, // Skip to: 678 +/* 647 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 650 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 664 +/* 655 */ MCD_OPC_CheckPredicate, 6, 211, 12, 0, // Skip to: 3943 +/* 660 */ MCD_OPC_Decode, 245, 1, 34, // Opcode: AMOSWAP_W_RL +/* 664 */ MCD_OPC_FilterValue, 3, 202, 12, 0, // Skip to: 3943 +/* 669 */ MCD_OPC_CheckPredicate, 7, 197, 12, 0, // Skip to: 3943 +/* 674 */ MCD_OPC_Decode, 241, 1, 34, // Opcode: AMOSWAP_D_RL +/* 678 */ MCD_OPC_FilterValue, 6, 31, 0, 0, // Skip to: 714 +/* 683 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 686 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 700 +/* 691 */ MCD_OPC_CheckPredicate, 6, 175, 12, 0, // Skip to: 3943 +/* 696 */ MCD_OPC_Decode, 243, 1, 34, // Opcode: AMOSWAP_W_AQ +/* 700 */ MCD_OPC_FilterValue, 3, 166, 12, 0, // Skip to: 3943 +/* 705 */ MCD_OPC_CheckPredicate, 7, 161, 12, 0, // Skip to: 3943 +/* 710 */ MCD_OPC_Decode, 239, 1, 34, // Opcode: AMOSWAP_D_AQ +/* 714 */ MCD_OPC_FilterValue, 7, 31, 0, 0, // Skip to: 750 +/* 719 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 722 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 736 +/* 727 */ MCD_OPC_CheckPredicate, 6, 139, 12, 0, // Skip to: 3943 +/* 732 */ MCD_OPC_Decode, 244, 1, 34, // Opcode: AMOSWAP_W_AQ_RL +/* 736 */ MCD_OPC_FilterValue, 3, 130, 12, 0, // Skip to: 3943 +/* 741 */ MCD_OPC_CheckPredicate, 7, 125, 12, 0, // Skip to: 3943 +/* 746 */ MCD_OPC_Decode, 240, 1, 34, // Opcode: AMOSWAP_D_AQ_RL +/* 750 */ MCD_OPC_FilterValue, 8, 45, 0, 0, // Skip to: 800 +/* 755 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 758 */ MCD_OPC_FilterValue, 2, 16, 0, 0, // Skip to: 779 +/* 763 */ MCD_OPC_CheckPredicate, 6, 103, 12, 0, // Skip to: 3943 +/* 768 */ MCD_OPC_CheckField, 20, 5, 0, 96, 12, 0, // Skip to: 3943 +/* 775 */ MCD_OPC_Decode, 138, 3, 35, // Opcode: LR_W +/* 779 */ MCD_OPC_FilterValue, 3, 87, 12, 0, // Skip to: 3943 +/* 784 */ MCD_OPC_CheckPredicate, 7, 82, 12, 0, // Skip to: 3943 +/* 789 */ MCD_OPC_CheckField, 20, 5, 0, 75, 12, 0, // Skip to: 3943 +/* 796 */ MCD_OPC_Decode, 134, 3, 35, // Opcode: LR_D +/* 800 */ MCD_OPC_FilterValue, 9, 45, 0, 0, // Skip to: 850 +/* 805 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 808 */ MCD_OPC_FilterValue, 2, 16, 0, 0, // Skip to: 829 +/* 813 */ MCD_OPC_CheckPredicate, 6, 53, 12, 0, // Skip to: 3943 +/* 818 */ MCD_OPC_CheckField, 20, 5, 0, 46, 12, 0, // Skip to: 3943 +/* 825 */ MCD_OPC_Decode, 141, 3, 35, // Opcode: LR_W_RL +/* 829 */ MCD_OPC_FilterValue, 3, 37, 12, 0, // Skip to: 3943 +/* 834 */ MCD_OPC_CheckPredicate, 7, 32, 12, 0, // Skip to: 3943 +/* 839 */ MCD_OPC_CheckField, 20, 5, 0, 25, 12, 0, // Skip to: 3943 +/* 846 */ MCD_OPC_Decode, 137, 3, 35, // Opcode: LR_D_RL +/* 850 */ MCD_OPC_FilterValue, 10, 45, 0, 0, // Skip to: 900 +/* 855 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 858 */ MCD_OPC_FilterValue, 2, 16, 0, 0, // Skip to: 879 +/* 863 */ MCD_OPC_CheckPredicate, 6, 3, 12, 0, // Skip to: 3943 +/* 868 */ MCD_OPC_CheckField, 20, 5, 0, 252, 11, 0, // Skip to: 3943 +/* 875 */ MCD_OPC_Decode, 139, 3, 35, // Opcode: LR_W_AQ +/* 879 */ MCD_OPC_FilterValue, 3, 243, 11, 0, // Skip to: 3943 +/* 884 */ MCD_OPC_CheckPredicate, 7, 238, 11, 0, // Skip to: 3943 +/* 889 */ MCD_OPC_CheckField, 20, 5, 0, 231, 11, 0, // Skip to: 3943 +/* 896 */ MCD_OPC_Decode, 135, 3, 35, // Opcode: LR_D_AQ +/* 900 */ MCD_OPC_FilterValue, 11, 45, 0, 0, // Skip to: 950 +/* 905 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 908 */ MCD_OPC_FilterValue, 2, 16, 0, 0, // Skip to: 929 +/* 913 */ MCD_OPC_CheckPredicate, 6, 209, 11, 0, // Skip to: 3943 +/* 918 */ MCD_OPC_CheckField, 20, 5, 0, 202, 11, 0, // Skip to: 3943 +/* 925 */ MCD_OPC_Decode, 140, 3, 35, // Opcode: LR_W_AQ_RL +/* 929 */ MCD_OPC_FilterValue, 3, 193, 11, 0, // Skip to: 3943 +/* 934 */ MCD_OPC_CheckPredicate, 7, 188, 11, 0, // Skip to: 3943 +/* 939 */ MCD_OPC_CheckField, 20, 5, 0, 181, 11, 0, // Skip to: 3943 +/* 946 */ MCD_OPC_Decode, 136, 3, 35, // Opcode: LR_D_AQ_RL +/* 950 */ MCD_OPC_FilterValue, 12, 31, 0, 0, // Skip to: 986 +/* 955 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 958 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 972 +/* 963 */ MCD_OPC_CheckPredicate, 6, 159, 11, 0, // Skip to: 3943 +/* 968 */ MCD_OPC_Decode, 162, 3, 34, // Opcode: SC_W +/* 972 */ MCD_OPC_FilterValue, 3, 150, 11, 0, // Skip to: 3943 +/* 977 */ MCD_OPC_CheckPredicate, 7, 145, 11, 0, // Skip to: 3943 +/* 982 */ MCD_OPC_Decode, 158, 3, 34, // Opcode: SC_D +/* 986 */ MCD_OPC_FilterValue, 13, 31, 0, 0, // Skip to: 1022 +/* 991 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 994 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1008 +/* 999 */ MCD_OPC_CheckPredicate, 6, 123, 11, 0, // Skip to: 3943 +/* 1004 */ MCD_OPC_Decode, 165, 3, 34, // Opcode: SC_W_RL +/* 1008 */ MCD_OPC_FilterValue, 3, 114, 11, 0, // Skip to: 3943 +/* 1013 */ MCD_OPC_CheckPredicate, 7, 109, 11, 0, // Skip to: 3943 +/* 1018 */ MCD_OPC_Decode, 161, 3, 34, // Opcode: SC_D_RL +/* 1022 */ MCD_OPC_FilterValue, 14, 31, 0, 0, // Skip to: 1058 +/* 1027 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1030 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1044 +/* 1035 */ MCD_OPC_CheckPredicate, 6, 87, 11, 0, // Skip to: 3943 +/* 1040 */ MCD_OPC_Decode, 163, 3, 34, // Opcode: SC_W_AQ +/* 1044 */ MCD_OPC_FilterValue, 3, 78, 11, 0, // Skip to: 3943 +/* 1049 */ MCD_OPC_CheckPredicate, 7, 73, 11, 0, // Skip to: 3943 +/* 1054 */ MCD_OPC_Decode, 159, 3, 34, // Opcode: SC_D_AQ +/* 1058 */ MCD_OPC_FilterValue, 15, 31, 0, 0, // Skip to: 1094 +/* 1063 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1066 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1080 +/* 1071 */ MCD_OPC_CheckPredicate, 6, 51, 11, 0, // Skip to: 3943 +/* 1076 */ MCD_OPC_Decode, 164, 3, 34, // Opcode: SC_W_AQ_RL +/* 1080 */ MCD_OPC_FilterValue, 3, 42, 11, 0, // Skip to: 3943 +/* 1085 */ MCD_OPC_CheckPredicate, 7, 37, 11, 0, // Skip to: 3943 +/* 1090 */ MCD_OPC_Decode, 160, 3, 34, // Opcode: SC_D_AQ_RL +/* 1094 */ MCD_OPC_FilterValue, 16, 31, 0, 0, // Skip to: 1130 +/* 1099 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1102 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1116 +/* 1107 */ MCD_OPC_CheckPredicate, 6, 15, 11, 0, // Skip to: 3943 +/* 1112 */ MCD_OPC_Decode, 250, 1, 34, // Opcode: AMOXOR_W +/* 1116 */ MCD_OPC_FilterValue, 3, 6, 11, 0, // Skip to: 3943 +/* 1121 */ MCD_OPC_CheckPredicate, 7, 1, 11, 0, // Skip to: 3943 +/* 1126 */ MCD_OPC_Decode, 246, 1, 34, // Opcode: AMOXOR_D +/* 1130 */ MCD_OPC_FilterValue, 17, 31, 0, 0, // Skip to: 1166 +/* 1135 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1138 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1152 +/* 1143 */ MCD_OPC_CheckPredicate, 6, 235, 10, 0, // Skip to: 3943 +/* 1148 */ MCD_OPC_Decode, 253, 1, 34, // Opcode: AMOXOR_W_RL +/* 1152 */ MCD_OPC_FilterValue, 3, 226, 10, 0, // Skip to: 3943 +/* 1157 */ MCD_OPC_CheckPredicate, 7, 221, 10, 0, // Skip to: 3943 +/* 1162 */ MCD_OPC_Decode, 249, 1, 34, // Opcode: AMOXOR_D_RL +/* 1166 */ MCD_OPC_FilterValue, 18, 31, 0, 0, // Skip to: 1202 +/* 1171 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1174 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1188 +/* 1179 */ MCD_OPC_CheckPredicate, 6, 199, 10, 0, // Skip to: 3943 +/* 1184 */ MCD_OPC_Decode, 251, 1, 34, // Opcode: AMOXOR_W_AQ +/* 1188 */ MCD_OPC_FilterValue, 3, 190, 10, 0, // Skip to: 3943 +/* 1193 */ MCD_OPC_CheckPredicate, 7, 185, 10, 0, // Skip to: 3943 +/* 1198 */ MCD_OPC_Decode, 247, 1, 34, // Opcode: AMOXOR_D_AQ +/* 1202 */ MCD_OPC_FilterValue, 19, 31, 0, 0, // Skip to: 1238 +/* 1207 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1210 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1224 +/* 1215 */ MCD_OPC_CheckPredicate, 6, 163, 10, 0, // Skip to: 3943 +/* 1220 */ MCD_OPC_Decode, 252, 1, 34, // Opcode: AMOXOR_W_AQ_RL +/* 1224 */ MCD_OPC_FilterValue, 3, 154, 10, 0, // Skip to: 3943 +/* 1229 */ MCD_OPC_CheckPredicate, 7, 149, 10, 0, // Skip to: 3943 +/* 1234 */ MCD_OPC_Decode, 248, 1, 34, // Opcode: AMOXOR_D_AQ_RL +/* 1238 */ MCD_OPC_FilterValue, 32, 31, 0, 0, // Skip to: 1274 +/* 1243 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1246 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1260 +/* 1251 */ MCD_OPC_CheckPredicate, 6, 127, 10, 0, // Skip to: 3943 +/* 1256 */ MCD_OPC_Decode, 234, 1, 34, // Opcode: AMOOR_W +/* 1260 */ MCD_OPC_FilterValue, 3, 118, 10, 0, // Skip to: 3943 +/* 1265 */ MCD_OPC_CheckPredicate, 7, 113, 10, 0, // Skip to: 3943 +/* 1270 */ MCD_OPC_Decode, 230, 1, 34, // Opcode: AMOOR_D +/* 1274 */ MCD_OPC_FilterValue, 33, 31, 0, 0, // Skip to: 1310 +/* 1279 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1282 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1296 +/* 1287 */ MCD_OPC_CheckPredicate, 6, 91, 10, 0, // Skip to: 3943 +/* 1292 */ MCD_OPC_Decode, 237, 1, 34, // Opcode: AMOOR_W_RL +/* 1296 */ MCD_OPC_FilterValue, 3, 82, 10, 0, // Skip to: 3943 +/* 1301 */ MCD_OPC_CheckPredicate, 7, 77, 10, 0, // Skip to: 3943 +/* 1306 */ MCD_OPC_Decode, 233, 1, 34, // Opcode: AMOOR_D_RL +/* 1310 */ MCD_OPC_FilterValue, 34, 31, 0, 0, // Skip to: 1346 +/* 1315 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1318 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1332 +/* 1323 */ MCD_OPC_CheckPredicate, 6, 55, 10, 0, // Skip to: 3943 +/* 1328 */ MCD_OPC_Decode, 235, 1, 34, // Opcode: AMOOR_W_AQ +/* 1332 */ MCD_OPC_FilterValue, 3, 46, 10, 0, // Skip to: 3943 +/* 1337 */ MCD_OPC_CheckPredicate, 7, 41, 10, 0, // Skip to: 3943 +/* 1342 */ MCD_OPC_Decode, 231, 1, 34, // Opcode: AMOOR_D_AQ +/* 1346 */ MCD_OPC_FilterValue, 35, 31, 0, 0, // Skip to: 1382 +/* 1351 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1354 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1368 +/* 1359 */ MCD_OPC_CheckPredicate, 6, 19, 10, 0, // Skip to: 3943 +/* 1364 */ MCD_OPC_Decode, 236, 1, 34, // Opcode: AMOOR_W_AQ_RL +/* 1368 */ MCD_OPC_FilterValue, 3, 10, 10, 0, // Skip to: 3943 +/* 1373 */ MCD_OPC_CheckPredicate, 7, 5, 10, 0, // Skip to: 3943 +/* 1378 */ MCD_OPC_Decode, 232, 1, 34, // Opcode: AMOOR_D_AQ_RL +/* 1382 */ MCD_OPC_FilterValue, 48, 31, 0, 0, // Skip to: 1418 +/* 1387 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1390 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1404 +/* 1395 */ MCD_OPC_CheckPredicate, 6, 239, 9, 0, // Skip to: 3943 +/* 1400 */ MCD_OPC_Decode, 194, 1, 34, // Opcode: AMOAND_W +/* 1404 */ MCD_OPC_FilterValue, 3, 230, 9, 0, // Skip to: 3943 +/* 1409 */ MCD_OPC_CheckPredicate, 7, 225, 9, 0, // Skip to: 3943 +/* 1414 */ MCD_OPC_Decode, 190, 1, 34, // Opcode: AMOAND_D +/* 1418 */ MCD_OPC_FilterValue, 49, 31, 0, 0, // Skip to: 1454 +/* 1423 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1426 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1440 +/* 1431 */ MCD_OPC_CheckPredicate, 6, 203, 9, 0, // Skip to: 3943 +/* 1436 */ MCD_OPC_Decode, 197, 1, 34, // Opcode: AMOAND_W_RL +/* 1440 */ MCD_OPC_FilterValue, 3, 194, 9, 0, // Skip to: 3943 +/* 1445 */ MCD_OPC_CheckPredicate, 7, 189, 9, 0, // Skip to: 3943 +/* 1450 */ MCD_OPC_Decode, 193, 1, 34, // Opcode: AMOAND_D_RL +/* 1454 */ MCD_OPC_FilterValue, 50, 31, 0, 0, // Skip to: 1490 +/* 1459 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1462 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1476 +/* 1467 */ MCD_OPC_CheckPredicate, 6, 167, 9, 0, // Skip to: 3943 +/* 1472 */ MCD_OPC_Decode, 195, 1, 34, // Opcode: AMOAND_W_AQ +/* 1476 */ MCD_OPC_FilterValue, 3, 158, 9, 0, // Skip to: 3943 +/* 1481 */ MCD_OPC_CheckPredicate, 7, 153, 9, 0, // Skip to: 3943 +/* 1486 */ MCD_OPC_Decode, 191, 1, 34, // Opcode: AMOAND_D_AQ +/* 1490 */ MCD_OPC_FilterValue, 51, 31, 0, 0, // Skip to: 1526 +/* 1495 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1498 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1512 +/* 1503 */ MCD_OPC_CheckPredicate, 6, 131, 9, 0, // Skip to: 3943 +/* 1508 */ MCD_OPC_Decode, 196, 1, 34, // Opcode: AMOAND_W_AQ_RL +/* 1512 */ MCD_OPC_FilterValue, 3, 122, 9, 0, // Skip to: 3943 +/* 1517 */ MCD_OPC_CheckPredicate, 7, 117, 9, 0, // Skip to: 3943 +/* 1522 */ MCD_OPC_Decode, 192, 1, 34, // Opcode: AMOAND_D_AQ_RL +/* 1526 */ MCD_OPC_FilterValue, 64, 31, 0, 0, // Skip to: 1562 +/* 1531 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1534 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1548 +/* 1539 */ MCD_OPC_CheckPredicate, 6, 95, 9, 0, // Skip to: 3943 +/* 1544 */ MCD_OPC_Decode, 226, 1, 34, // Opcode: AMOMIN_W +/* 1548 */ MCD_OPC_FilterValue, 3, 86, 9, 0, // Skip to: 3943 +/* 1553 */ MCD_OPC_CheckPredicate, 7, 81, 9, 0, // Skip to: 3943 +/* 1558 */ MCD_OPC_Decode, 222, 1, 34, // Opcode: AMOMIN_D +/* 1562 */ MCD_OPC_FilterValue, 65, 31, 0, 0, // Skip to: 1598 +/* 1567 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1570 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1584 +/* 1575 */ MCD_OPC_CheckPredicate, 6, 59, 9, 0, // Skip to: 3943 +/* 1580 */ MCD_OPC_Decode, 229, 1, 34, // Opcode: AMOMIN_W_RL +/* 1584 */ MCD_OPC_FilterValue, 3, 50, 9, 0, // Skip to: 3943 +/* 1589 */ MCD_OPC_CheckPredicate, 7, 45, 9, 0, // Skip to: 3943 +/* 1594 */ MCD_OPC_Decode, 225, 1, 34, // Opcode: AMOMIN_D_RL +/* 1598 */ MCD_OPC_FilterValue, 66, 31, 0, 0, // Skip to: 1634 +/* 1603 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1606 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1620 +/* 1611 */ MCD_OPC_CheckPredicate, 6, 23, 9, 0, // Skip to: 3943 +/* 1616 */ MCD_OPC_Decode, 227, 1, 34, // Opcode: AMOMIN_W_AQ +/* 1620 */ MCD_OPC_FilterValue, 3, 14, 9, 0, // Skip to: 3943 +/* 1625 */ MCD_OPC_CheckPredicate, 7, 9, 9, 0, // Skip to: 3943 +/* 1630 */ MCD_OPC_Decode, 223, 1, 34, // Opcode: AMOMIN_D_AQ +/* 1634 */ MCD_OPC_FilterValue, 67, 31, 0, 0, // Skip to: 1670 +/* 1639 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1642 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1656 +/* 1647 */ MCD_OPC_CheckPredicate, 6, 243, 8, 0, // Skip to: 3943 +/* 1652 */ MCD_OPC_Decode, 228, 1, 34, // Opcode: AMOMIN_W_AQ_RL +/* 1656 */ MCD_OPC_FilterValue, 3, 234, 8, 0, // Skip to: 3943 +/* 1661 */ MCD_OPC_CheckPredicate, 7, 229, 8, 0, // Skip to: 3943 +/* 1666 */ MCD_OPC_Decode, 224, 1, 34, // Opcode: AMOMIN_D_AQ_RL +/* 1670 */ MCD_OPC_FilterValue, 80, 31, 0, 0, // Skip to: 1706 +/* 1675 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1678 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1692 +/* 1683 */ MCD_OPC_CheckPredicate, 6, 207, 8, 0, // Skip to: 3943 +/* 1688 */ MCD_OPC_Decode, 210, 1, 34, // Opcode: AMOMAX_W +/* 1692 */ MCD_OPC_FilterValue, 3, 198, 8, 0, // Skip to: 3943 +/* 1697 */ MCD_OPC_CheckPredicate, 7, 193, 8, 0, // Skip to: 3943 +/* 1702 */ MCD_OPC_Decode, 206, 1, 34, // Opcode: AMOMAX_D +/* 1706 */ MCD_OPC_FilterValue, 81, 31, 0, 0, // Skip to: 1742 +/* 1711 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1714 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1728 +/* 1719 */ MCD_OPC_CheckPredicate, 6, 171, 8, 0, // Skip to: 3943 +/* 1724 */ MCD_OPC_Decode, 213, 1, 34, // Opcode: AMOMAX_W_RL +/* 1728 */ MCD_OPC_FilterValue, 3, 162, 8, 0, // Skip to: 3943 +/* 1733 */ MCD_OPC_CheckPredicate, 7, 157, 8, 0, // Skip to: 3943 +/* 1738 */ MCD_OPC_Decode, 209, 1, 34, // Opcode: AMOMAX_D_RL +/* 1742 */ MCD_OPC_FilterValue, 82, 31, 0, 0, // Skip to: 1778 +/* 1747 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1750 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1764 +/* 1755 */ MCD_OPC_CheckPredicate, 6, 135, 8, 0, // Skip to: 3943 +/* 1760 */ MCD_OPC_Decode, 211, 1, 34, // Opcode: AMOMAX_W_AQ +/* 1764 */ MCD_OPC_FilterValue, 3, 126, 8, 0, // Skip to: 3943 +/* 1769 */ MCD_OPC_CheckPredicate, 7, 121, 8, 0, // Skip to: 3943 +/* 1774 */ MCD_OPC_Decode, 207, 1, 34, // Opcode: AMOMAX_D_AQ +/* 1778 */ MCD_OPC_FilterValue, 83, 31, 0, 0, // Skip to: 1814 +/* 1783 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1786 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1800 +/* 1791 */ MCD_OPC_CheckPredicate, 6, 99, 8, 0, // Skip to: 3943 +/* 1796 */ MCD_OPC_Decode, 212, 1, 34, // Opcode: AMOMAX_W_AQ_RL +/* 1800 */ MCD_OPC_FilterValue, 3, 90, 8, 0, // Skip to: 3943 +/* 1805 */ MCD_OPC_CheckPredicate, 7, 85, 8, 0, // Skip to: 3943 +/* 1810 */ MCD_OPC_Decode, 208, 1, 34, // Opcode: AMOMAX_D_AQ_RL +/* 1814 */ MCD_OPC_FilterValue, 96, 31, 0, 0, // Skip to: 1850 +/* 1819 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1822 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1836 +/* 1827 */ MCD_OPC_CheckPredicate, 6, 63, 8, 0, // Skip to: 3943 +/* 1832 */ MCD_OPC_Decode, 218, 1, 34, // Opcode: AMOMINU_W +/* 1836 */ MCD_OPC_FilterValue, 3, 54, 8, 0, // Skip to: 3943 +/* 1841 */ MCD_OPC_CheckPredicate, 7, 49, 8, 0, // Skip to: 3943 +/* 1846 */ MCD_OPC_Decode, 214, 1, 34, // Opcode: AMOMINU_D +/* 1850 */ MCD_OPC_FilterValue, 97, 31, 0, 0, // Skip to: 1886 +/* 1855 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1858 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1872 +/* 1863 */ MCD_OPC_CheckPredicate, 6, 27, 8, 0, // Skip to: 3943 +/* 1868 */ MCD_OPC_Decode, 221, 1, 34, // Opcode: AMOMINU_W_RL +/* 1872 */ MCD_OPC_FilterValue, 3, 18, 8, 0, // Skip to: 3943 +/* 1877 */ MCD_OPC_CheckPredicate, 7, 13, 8, 0, // Skip to: 3943 +/* 1882 */ MCD_OPC_Decode, 217, 1, 34, // Opcode: AMOMINU_D_RL +/* 1886 */ MCD_OPC_FilterValue, 98, 31, 0, 0, // Skip to: 1922 +/* 1891 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1894 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1908 +/* 1899 */ MCD_OPC_CheckPredicate, 6, 247, 7, 0, // Skip to: 3943 +/* 1904 */ MCD_OPC_Decode, 219, 1, 34, // Opcode: AMOMINU_W_AQ +/* 1908 */ MCD_OPC_FilterValue, 3, 238, 7, 0, // Skip to: 3943 +/* 1913 */ MCD_OPC_CheckPredicate, 7, 233, 7, 0, // Skip to: 3943 +/* 1918 */ MCD_OPC_Decode, 215, 1, 34, // Opcode: AMOMINU_D_AQ +/* 1922 */ MCD_OPC_FilterValue, 99, 31, 0, 0, // Skip to: 1958 +/* 1927 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1930 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1944 +/* 1935 */ MCD_OPC_CheckPredicate, 6, 211, 7, 0, // Skip to: 3943 +/* 1940 */ MCD_OPC_Decode, 220, 1, 34, // Opcode: AMOMINU_W_AQ_RL +/* 1944 */ MCD_OPC_FilterValue, 3, 202, 7, 0, // Skip to: 3943 +/* 1949 */ MCD_OPC_CheckPredicate, 7, 197, 7, 0, // Skip to: 3943 +/* 1954 */ MCD_OPC_Decode, 216, 1, 34, // Opcode: AMOMINU_D_AQ_RL +/* 1958 */ MCD_OPC_FilterValue, 112, 31, 0, 0, // Skip to: 1994 +/* 1963 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 1966 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 1980 +/* 1971 */ MCD_OPC_CheckPredicate, 6, 175, 7, 0, // Skip to: 3943 +/* 1976 */ MCD_OPC_Decode, 202, 1, 34, // Opcode: AMOMAXU_W +/* 1980 */ MCD_OPC_FilterValue, 3, 166, 7, 0, // Skip to: 3943 +/* 1985 */ MCD_OPC_CheckPredicate, 7, 161, 7, 0, // Skip to: 3943 +/* 1990 */ MCD_OPC_Decode, 198, 1, 34, // Opcode: AMOMAXU_D +/* 1994 */ MCD_OPC_FilterValue, 113, 31, 0, 0, // Skip to: 2030 +/* 1999 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2002 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 2016 +/* 2007 */ MCD_OPC_CheckPredicate, 6, 139, 7, 0, // Skip to: 3943 +/* 2012 */ MCD_OPC_Decode, 205, 1, 34, // Opcode: AMOMAXU_W_RL +/* 2016 */ MCD_OPC_FilterValue, 3, 130, 7, 0, // Skip to: 3943 +/* 2021 */ MCD_OPC_CheckPredicate, 7, 125, 7, 0, // Skip to: 3943 +/* 2026 */ MCD_OPC_Decode, 201, 1, 34, // Opcode: AMOMAXU_D_RL +/* 2030 */ MCD_OPC_FilterValue, 114, 31, 0, 0, // Skip to: 2066 +/* 2035 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2038 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 2052 +/* 2043 */ MCD_OPC_CheckPredicate, 6, 103, 7, 0, // Skip to: 3943 +/* 2048 */ MCD_OPC_Decode, 203, 1, 34, // Opcode: AMOMAXU_W_AQ +/* 2052 */ MCD_OPC_FilterValue, 3, 94, 7, 0, // Skip to: 3943 +/* 2057 */ MCD_OPC_CheckPredicate, 7, 89, 7, 0, // Skip to: 3943 +/* 2062 */ MCD_OPC_Decode, 199, 1, 34, // Opcode: AMOMAXU_D_AQ +/* 2066 */ MCD_OPC_FilterValue, 115, 80, 7, 0, // Skip to: 3943 +/* 2071 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2074 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 2088 +/* 2079 */ MCD_OPC_CheckPredicate, 6, 67, 7, 0, // Skip to: 3943 +/* 2084 */ MCD_OPC_Decode, 204, 1, 34, // Opcode: AMOMAXU_W_AQ_RL +/* 2088 */ MCD_OPC_FilterValue, 3, 58, 7, 0, // Skip to: 3943 +/* 2093 */ MCD_OPC_CheckPredicate, 7, 53, 7, 0, // Skip to: 3943 +/* 2098 */ MCD_OPC_Decode, 200, 1, 34, // Opcode: AMOMAXU_D_AQ_RL +/* 2102 */ MCD_OPC_FilterValue, 51, 13, 1, 0, // Skip to: 2376 +/* 2107 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2110 */ MCD_OPC_FilterValue, 0, 35, 0, 0, // Skip to: 2150 +/* 2115 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2118 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2127 +/* 2123 */ MCD_OPC_Decode, 178, 1, 34, // Opcode: ADD +/* 2127 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2141 +/* 2132 */ MCD_OPC_CheckPredicate, 8, 14, 7, 0, // Skip to: 3943 +/* 2137 */ MCD_OPC_Decode, 146, 3, 34, // Opcode: MUL +/* 2141 */ MCD_OPC_FilterValue, 32, 5, 7, 0, // Skip to: 3943 +/* 2146 */ MCD_OPC_Decode, 186, 3, 34, // Opcode: SUB +/* 2150 */ MCD_OPC_FilterValue, 1, 26, 0, 0, // Skip to: 2181 +/* 2155 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2158 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2167 +/* 2163 */ MCD_OPC_Decode, 169, 3, 34, // Opcode: SLL +/* 2167 */ MCD_OPC_FilterValue, 1, 235, 6, 0, // Skip to: 3943 +/* 2172 */ MCD_OPC_CheckPredicate, 8, 230, 6, 0, // Skip to: 3943 +/* 2177 */ MCD_OPC_Decode, 147, 3, 34, // Opcode: MULH +/* 2181 */ MCD_OPC_FilterValue, 2, 26, 0, 0, // Skip to: 2212 +/* 2186 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2189 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2198 +/* 2194 */ MCD_OPC_Decode, 173, 3, 34, // Opcode: SLT +/* 2198 */ MCD_OPC_FilterValue, 1, 204, 6, 0, // Skip to: 3943 +/* 2203 */ MCD_OPC_CheckPredicate, 8, 199, 6, 0, // Skip to: 3943 +/* 2208 */ MCD_OPC_Decode, 148, 3, 34, // Opcode: MULHSU +/* 2212 */ MCD_OPC_FilterValue, 3, 26, 0, 0, // Skip to: 2243 +/* 2217 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2220 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2229 +/* 2225 */ MCD_OPC_Decode, 176, 3, 34, // Opcode: SLTU +/* 2229 */ MCD_OPC_FilterValue, 1, 173, 6, 0, // Skip to: 3943 +/* 2234 */ MCD_OPC_CheckPredicate, 8, 168, 6, 0, // Skip to: 3943 +/* 2239 */ MCD_OPC_Decode, 149, 3, 34, // Opcode: MULHU +/* 2243 */ MCD_OPC_FilterValue, 4, 26, 0, 0, // Skip to: 2274 +/* 2248 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2251 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2260 +/* 2256 */ MCD_OPC_Decode, 192, 3, 34, // Opcode: XOR +/* 2260 */ MCD_OPC_FilterValue, 1, 142, 6, 0, // Skip to: 3943 +/* 2265 */ MCD_OPC_CheckPredicate, 8, 137, 6, 0, // Skip to: 3943 +/* 2270 */ MCD_OPC_Decode, 184, 2, 34, // Opcode: DIV +/* 2274 */ MCD_OPC_FilterValue, 5, 35, 0, 0, // Skip to: 2314 +/* 2279 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2282 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2291 +/* 2287 */ MCD_OPC_Decode, 182, 3, 34, // Opcode: SRL +/* 2291 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2305 +/* 2296 */ MCD_OPC_CheckPredicate, 8, 106, 6, 0, // Skip to: 3943 +/* 2301 */ MCD_OPC_Decode, 185, 2, 34, // Opcode: DIVU +/* 2305 */ MCD_OPC_FilterValue, 32, 97, 6, 0, // Skip to: 3943 +/* 2310 */ MCD_OPC_Decode, 177, 3, 34, // Opcode: SRA +/* 2314 */ MCD_OPC_FilterValue, 6, 26, 0, 0, // Skip to: 2345 +/* 2319 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2322 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2331 +/* 2327 */ MCD_OPC_Decode, 151, 3, 34, // Opcode: OR +/* 2331 */ MCD_OPC_FilterValue, 1, 71, 6, 0, // Skip to: 3943 +/* 2336 */ MCD_OPC_CheckPredicate, 8, 66, 6, 0, // Skip to: 3943 +/* 2341 */ MCD_OPC_Decode, 153, 3, 34, // Opcode: REM +/* 2345 */ MCD_OPC_FilterValue, 7, 57, 6, 0, // Skip to: 3943 +/* 2350 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2353 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 2362 +/* 2358 */ MCD_OPC_Decode, 254, 1, 34, // Opcode: AND +/* 2362 */ MCD_OPC_FilterValue, 1, 40, 6, 0, // Skip to: 3943 +/* 2367 */ MCD_OPC_CheckPredicate, 8, 35, 6, 0, // Skip to: 3943 +/* 2372 */ MCD_OPC_Decode, 154, 3, 34, // Opcode: REMU +/* 2376 */ MCD_OPC_FilterValue, 55, 4, 0, 0, // Skip to: 2385 +/* 2381 */ MCD_OPC_Decode, 142, 3, 29, // Opcode: LUI +/* 2385 */ MCD_OPC_FilterValue, 59, 187, 0, 0, // Skip to: 2577 +/* 2390 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2393 */ MCD_OPC_FilterValue, 0, 45, 0, 0, // Skip to: 2443 +/* 2398 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2401 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2415 +/* 2406 */ MCD_OPC_CheckPredicate, 3, 252, 5, 0, // Skip to: 3943 +/* 2411 */ MCD_OPC_Decode, 181, 1, 34, // Opcode: ADDW +/* 2415 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2429 +/* 2420 */ MCD_OPC_CheckPredicate, 9, 238, 5, 0, // Skip to: 3943 +/* 2425 */ MCD_OPC_Decode, 150, 3, 34, // Opcode: MULW +/* 2429 */ MCD_OPC_FilterValue, 32, 229, 5, 0, // Skip to: 3943 +/* 2434 */ MCD_OPC_CheckPredicate, 3, 224, 5, 0, // Skip to: 3943 +/* 2439 */ MCD_OPC_Decode, 187, 3, 34, // Opcode: SUBW +/* 2443 */ MCD_OPC_FilterValue, 1, 16, 0, 0, // Skip to: 2464 +/* 2448 */ MCD_OPC_CheckPredicate, 3, 210, 5, 0, // Skip to: 3943 +/* 2453 */ MCD_OPC_CheckField, 25, 7, 0, 203, 5, 0, // Skip to: 3943 +/* 2460 */ MCD_OPC_Decode, 172, 3, 34, // Opcode: SLLW +/* 2464 */ MCD_OPC_FilterValue, 4, 16, 0, 0, // Skip to: 2485 +/* 2469 */ MCD_OPC_CheckPredicate, 9, 189, 5, 0, // Skip to: 3943 +/* 2474 */ MCD_OPC_CheckField, 25, 7, 1, 182, 5, 0, // Skip to: 3943 +/* 2481 */ MCD_OPC_Decode, 187, 2, 34, // Opcode: DIVW +/* 2485 */ MCD_OPC_FilterValue, 5, 45, 0, 0, // Skip to: 2535 +/* 2490 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2493 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2507 +/* 2498 */ MCD_OPC_CheckPredicate, 3, 160, 5, 0, // Skip to: 3943 +/* 2503 */ MCD_OPC_Decode, 185, 3, 34, // Opcode: SRLW +/* 2507 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2521 +/* 2512 */ MCD_OPC_CheckPredicate, 9, 146, 5, 0, // Skip to: 3943 +/* 2517 */ MCD_OPC_Decode, 186, 2, 34, // Opcode: DIVUW +/* 2521 */ MCD_OPC_FilterValue, 32, 137, 5, 0, // Skip to: 3943 +/* 2526 */ MCD_OPC_CheckPredicate, 3, 132, 5, 0, // Skip to: 3943 +/* 2531 */ MCD_OPC_Decode, 180, 3, 34, // Opcode: SRAW +/* 2535 */ MCD_OPC_FilterValue, 6, 16, 0, 0, // Skip to: 2556 +/* 2540 */ MCD_OPC_CheckPredicate, 9, 118, 5, 0, // Skip to: 3943 +/* 2545 */ MCD_OPC_CheckField, 25, 7, 1, 111, 5, 0, // Skip to: 3943 +/* 2552 */ MCD_OPC_Decode, 156, 3, 34, // Opcode: REMW +/* 2556 */ MCD_OPC_FilterValue, 7, 102, 5, 0, // Skip to: 3943 +/* 2561 */ MCD_OPC_CheckPredicate, 9, 97, 5, 0, // Skip to: 3943 +/* 2566 */ MCD_OPC_CheckField, 25, 7, 1, 90, 5, 0, // Skip to: 3943 +/* 2573 */ MCD_OPC_Decode, 155, 3, 34, // Opcode: REMUW +/* 2577 */ MCD_OPC_FilterValue, 67, 31, 0, 0, // Skip to: 2613 +/* 2582 */ MCD_OPC_ExtractField, 25, 2, // Inst{26-25} ... +/* 2585 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2599 +/* 2590 */ MCD_OPC_CheckPredicate, 4, 68, 5, 0, // Skip to: 3943 +/* 2595 */ MCD_OPC_Decode, 226, 2, 36, // Opcode: FMADD_S +/* 2599 */ MCD_OPC_FilterValue, 1, 59, 5, 0, // Skip to: 3943 +/* 2604 */ MCD_OPC_CheckPredicate, 5, 54, 5, 0, // Skip to: 3943 +/* 2609 */ MCD_OPC_Decode, 225, 2, 37, // Opcode: FMADD_D +/* 2613 */ MCD_OPC_FilterValue, 71, 31, 0, 0, // Skip to: 2649 +/* 2618 */ MCD_OPC_ExtractField, 25, 2, // Inst{26-25} ... +/* 2621 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2635 +/* 2626 */ MCD_OPC_CheckPredicate, 4, 32, 5, 0, // Skip to: 3943 +/* 2631 */ MCD_OPC_Decode, 232, 2, 36, // Opcode: FMSUB_S +/* 2635 */ MCD_OPC_FilterValue, 1, 23, 5, 0, // Skip to: 3943 +/* 2640 */ MCD_OPC_CheckPredicate, 5, 18, 5, 0, // Skip to: 3943 +/* 2645 */ MCD_OPC_Decode, 231, 2, 37, // Opcode: FMSUB_D +/* 2649 */ MCD_OPC_FilterValue, 75, 31, 0, 0, // Skip to: 2685 +/* 2654 */ MCD_OPC_ExtractField, 25, 2, // Inst{26-25} ... +/* 2657 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2671 +/* 2662 */ MCD_OPC_CheckPredicate, 4, 252, 4, 0, // Skip to: 3943 +/* 2667 */ MCD_OPC_Decode, 242, 2, 36, // Opcode: FNMSUB_S +/* 2671 */ MCD_OPC_FilterValue, 1, 243, 4, 0, // Skip to: 3943 +/* 2676 */ MCD_OPC_CheckPredicate, 5, 238, 4, 0, // Skip to: 3943 +/* 2681 */ MCD_OPC_Decode, 241, 2, 37, // Opcode: FNMSUB_D +/* 2685 */ MCD_OPC_FilterValue, 79, 31, 0, 0, // Skip to: 2721 +/* 2690 */ MCD_OPC_ExtractField, 25, 2, // Inst{26-25} ... +/* 2693 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2707 +/* 2698 */ MCD_OPC_CheckPredicate, 4, 216, 4, 0, // Skip to: 3943 +/* 2703 */ MCD_OPC_Decode, 240, 2, 36, // Opcode: FNMADD_S +/* 2707 */ MCD_OPC_FilterValue, 1, 207, 4, 0, // Skip to: 3943 +/* 2712 */ MCD_OPC_CheckPredicate, 5, 202, 4, 0, // Skip to: 3943 +/* 2717 */ MCD_OPC_Decode, 239, 2, 37, // Opcode: FNMADD_D +/* 2721 */ MCD_OPC_FilterValue, 83, 136, 3, 0, // Skip to: 3630 +/* 2726 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 2729 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2743 +/* 2734 */ MCD_OPC_CheckPredicate, 4, 180, 4, 0, // Skip to: 3943 +/* 2739 */ MCD_OPC_Decode, 191, 2, 38, // Opcode: FADD_S +/* 2743 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2757 +/* 2748 */ MCD_OPC_CheckPredicate, 5, 166, 4, 0, // Skip to: 3943 +/* 2753 */ MCD_OPC_Decode, 190, 2, 39, // Opcode: FADD_D +/* 2757 */ MCD_OPC_FilterValue, 4, 9, 0, 0, // Skip to: 2771 +/* 2762 */ MCD_OPC_CheckPredicate, 4, 152, 4, 0, // Skip to: 3943 +/* 2767 */ MCD_OPC_Decode, 253, 2, 38, // Opcode: FSUB_S +/* 2771 */ MCD_OPC_FilterValue, 5, 9, 0, 0, // Skip to: 2785 +/* 2776 */ MCD_OPC_CheckPredicate, 5, 138, 4, 0, // Skip to: 3943 +/* 2781 */ MCD_OPC_Decode, 252, 2, 39, // Opcode: FSUB_D +/* 2785 */ MCD_OPC_FilterValue, 8, 9, 0, 0, // Skip to: 2799 +/* 2790 */ MCD_OPC_CheckPredicate, 4, 124, 4, 0, // Skip to: 3943 +/* 2795 */ MCD_OPC_Decode, 234, 2, 38, // Opcode: FMUL_S +/* 2799 */ MCD_OPC_FilterValue, 9, 9, 0, 0, // Skip to: 2813 +/* 2804 */ MCD_OPC_CheckPredicate, 5, 110, 4, 0, // Skip to: 3943 +/* 2809 */ MCD_OPC_Decode, 233, 2, 39, // Opcode: FMUL_D +/* 2813 */ MCD_OPC_FilterValue, 12, 9, 0, 0, // Skip to: 2827 +/* 2818 */ MCD_OPC_CheckPredicate, 4, 96, 4, 0, // Skip to: 3943 +/* 2823 */ MCD_OPC_Decode, 213, 2, 38, // Opcode: FDIV_S +/* 2827 */ MCD_OPC_FilterValue, 13, 9, 0, 0, // Skip to: 2841 +/* 2832 */ MCD_OPC_CheckPredicate, 5, 82, 4, 0, // Skip to: 3943 +/* 2837 */ MCD_OPC_Decode, 212, 2, 39, // Opcode: FDIV_D +/* 2841 */ MCD_OPC_FilterValue, 16, 45, 0, 0, // Skip to: 2891 +/* 2846 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2849 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2863 +/* 2854 */ MCD_OPC_CheckPredicate, 4, 60, 4, 0, // Skip to: 3943 +/* 2859 */ MCD_OPC_Decode, 249, 2, 40, // Opcode: FSGNJ_S +/* 2863 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2877 +/* 2868 */ MCD_OPC_CheckPredicate, 4, 46, 4, 0, // Skip to: 3943 +/* 2873 */ MCD_OPC_Decode, 245, 2, 40, // Opcode: FSGNJN_S +/* 2877 */ MCD_OPC_FilterValue, 2, 37, 4, 0, // Skip to: 3943 +/* 2882 */ MCD_OPC_CheckPredicate, 4, 32, 4, 0, // Skip to: 3943 +/* 2887 */ MCD_OPC_Decode, 247, 2, 40, // Opcode: FSGNJX_S +/* 2891 */ MCD_OPC_FilterValue, 17, 45, 0, 0, // Skip to: 2941 +/* 2896 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2899 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2913 +/* 2904 */ MCD_OPC_CheckPredicate, 5, 10, 4, 0, // Skip to: 3943 +/* 2909 */ MCD_OPC_Decode, 248, 2, 41, // Opcode: FSGNJ_D +/* 2913 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 2927 +/* 2918 */ MCD_OPC_CheckPredicate, 5, 252, 3, 0, // Skip to: 3943 +/* 2923 */ MCD_OPC_Decode, 244, 2, 41, // Opcode: FSGNJN_D +/* 2927 */ MCD_OPC_FilterValue, 2, 243, 3, 0, // Skip to: 3943 +/* 2932 */ MCD_OPC_CheckPredicate, 5, 238, 3, 0, // Skip to: 3943 +/* 2937 */ MCD_OPC_Decode, 246, 2, 41, // Opcode: FSGNJX_D +/* 2941 */ MCD_OPC_FilterValue, 20, 31, 0, 0, // Skip to: 2977 +/* 2946 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2949 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2963 +/* 2954 */ MCD_OPC_CheckPredicate, 4, 216, 3, 0, // Skip to: 3943 +/* 2959 */ MCD_OPC_Decode, 230, 2, 40, // Opcode: FMIN_S +/* 2963 */ MCD_OPC_FilterValue, 1, 207, 3, 0, // Skip to: 3943 +/* 2968 */ MCD_OPC_CheckPredicate, 4, 202, 3, 0, // Skip to: 3943 +/* 2973 */ MCD_OPC_Decode, 228, 2, 40, // Opcode: FMAX_S +/* 2977 */ MCD_OPC_FilterValue, 21, 31, 0, 0, // Skip to: 3013 +/* 2982 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 2985 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 2999 +/* 2990 */ MCD_OPC_CheckPredicate, 5, 180, 3, 0, // Skip to: 3943 +/* 2995 */ MCD_OPC_Decode, 229, 2, 41, // Opcode: FMIN_D +/* 2999 */ MCD_OPC_FilterValue, 1, 171, 3, 0, // Skip to: 3943 +/* 3004 */ MCD_OPC_CheckPredicate, 5, 166, 3, 0, // Skip to: 3943 +/* 3009 */ MCD_OPC_Decode, 227, 2, 41, // Opcode: FMAX_D +/* 3013 */ MCD_OPC_FilterValue, 32, 16, 0, 0, // Skip to: 3034 +/* 3018 */ MCD_OPC_CheckPredicate, 5, 152, 3, 0, // Skip to: 3943 +/* 3023 */ MCD_OPC_CheckField, 20, 5, 1, 145, 3, 0, // Skip to: 3943 +/* 3030 */ MCD_OPC_Decode, 203, 2, 42, // Opcode: FCVT_S_D +/* 3034 */ MCD_OPC_FilterValue, 33, 23, 0, 0, // Skip to: 3062 +/* 3039 */ MCD_OPC_CheckPredicate, 5, 131, 3, 0, // Skip to: 3943 +/* 3044 */ MCD_OPC_CheckField, 20, 5, 0, 124, 3, 0, // Skip to: 3943 +/* 3051 */ MCD_OPC_CheckField, 12, 3, 0, 117, 3, 0, // Skip to: 3943 +/* 3058 */ MCD_OPC_Decode, 196, 2, 43, // Opcode: FCVT_D_S +/* 3062 */ MCD_OPC_FilterValue, 44, 16, 0, 0, // Skip to: 3083 +/* 3067 */ MCD_OPC_CheckPredicate, 4, 103, 3, 0, // Skip to: 3943 +/* 3072 */ MCD_OPC_CheckField, 20, 5, 0, 96, 3, 0, // Skip to: 3943 +/* 3079 */ MCD_OPC_Decode, 251, 2, 44, // Opcode: FSQRT_S +/* 3083 */ MCD_OPC_FilterValue, 45, 16, 0, 0, // Skip to: 3104 +/* 3088 */ MCD_OPC_CheckPredicate, 5, 82, 3, 0, // Skip to: 3943 +/* 3093 */ MCD_OPC_CheckField, 20, 5, 0, 75, 3, 0, // Skip to: 3943 +/* 3100 */ MCD_OPC_Decode, 250, 2, 45, // Opcode: FSQRT_D +/* 3104 */ MCD_OPC_FilterValue, 80, 45, 0, 0, // Skip to: 3154 +/* 3109 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3112 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 3126 +/* 3117 */ MCD_OPC_CheckPredicate, 4, 53, 3, 0, // Skip to: 3943 +/* 3122 */ MCD_OPC_Decode, 221, 2, 46, // Opcode: FLE_S +/* 3126 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 3140 +/* 3131 */ MCD_OPC_CheckPredicate, 4, 39, 3, 0, // Skip to: 3943 +/* 3136 */ MCD_OPC_Decode, 223, 2, 46, // Opcode: FLT_S +/* 3140 */ MCD_OPC_FilterValue, 2, 30, 3, 0, // Skip to: 3943 +/* 3145 */ MCD_OPC_CheckPredicate, 4, 25, 3, 0, // Skip to: 3943 +/* 3150 */ MCD_OPC_Decode, 218, 2, 46, // Opcode: FEQ_S +/* 3154 */ MCD_OPC_FilterValue, 81, 45, 0, 0, // Skip to: 3204 +/* 3159 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3162 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 3176 +/* 3167 */ MCD_OPC_CheckPredicate, 5, 3, 3, 0, // Skip to: 3943 +/* 3172 */ MCD_OPC_Decode, 220, 2, 47, // Opcode: FLE_D +/* 3176 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 3190 +/* 3181 */ MCD_OPC_CheckPredicate, 5, 245, 2, 0, // Skip to: 3943 +/* 3186 */ MCD_OPC_Decode, 222, 2, 47, // Opcode: FLT_D +/* 3190 */ MCD_OPC_FilterValue, 2, 236, 2, 0, // Skip to: 3943 +/* 3195 */ MCD_OPC_CheckPredicate, 5, 231, 2, 0, // Skip to: 3943 +/* 3200 */ MCD_OPC_Decode, 217, 2, 47, // Opcode: FEQ_D +/* 3204 */ MCD_OPC_FilterValue, 96, 59, 0, 0, // Skip to: 3268 +/* 3209 */ MCD_OPC_ExtractField, 20, 5, // Inst{24-20} ... +/* 3212 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 3226 +/* 3217 */ MCD_OPC_CheckPredicate, 4, 209, 2, 0, // Skip to: 3943 +/* 3222 */ MCD_OPC_Decode, 211, 2, 48, // Opcode: FCVT_W_S +/* 3226 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 3240 +/* 3231 */ MCD_OPC_CheckPredicate, 4, 195, 2, 0, // Skip to: 3943 +/* 3236 */ MCD_OPC_Decode, 209, 2, 48, // Opcode: FCVT_WU_S +/* 3240 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 3254 +/* 3245 */ MCD_OPC_CheckPredicate, 10, 181, 2, 0, // Skip to: 3943 +/* 3250 */ MCD_OPC_Decode, 202, 2, 48, // Opcode: FCVT_L_S +/* 3254 */ MCD_OPC_FilterValue, 3, 172, 2, 0, // Skip to: 3943 +/* 3259 */ MCD_OPC_CheckPredicate, 10, 167, 2, 0, // Skip to: 3943 +/* 3264 */ MCD_OPC_Decode, 200, 2, 48, // Opcode: FCVT_LU_S +/* 3268 */ MCD_OPC_FilterValue, 97, 59, 0, 0, // Skip to: 3332 +/* 3273 */ MCD_OPC_ExtractField, 20, 5, // Inst{24-20} ... +/* 3276 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 3290 +/* 3281 */ MCD_OPC_CheckPredicate, 5, 145, 2, 0, // Skip to: 3943 +/* 3286 */ MCD_OPC_Decode, 210, 2, 49, // Opcode: FCVT_W_D +/* 3290 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 3304 +/* 3295 */ MCD_OPC_CheckPredicate, 5, 131, 2, 0, // Skip to: 3943 +/* 3300 */ MCD_OPC_Decode, 208, 2, 49, // Opcode: FCVT_WU_D +/* 3304 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 3318 +/* 3309 */ MCD_OPC_CheckPredicate, 11, 117, 2, 0, // Skip to: 3943 +/* 3314 */ MCD_OPC_Decode, 201, 2, 49, // Opcode: FCVT_L_D +/* 3318 */ MCD_OPC_FilterValue, 3, 108, 2, 0, // Skip to: 3943 +/* 3323 */ MCD_OPC_CheckPredicate, 11, 103, 2, 0, // Skip to: 3943 +/* 3328 */ MCD_OPC_Decode, 199, 2, 49, // Opcode: FCVT_LU_D +/* 3332 */ MCD_OPC_FilterValue, 104, 59, 0, 0, // Skip to: 3396 +/* 3337 */ MCD_OPC_ExtractField, 20, 5, // Inst{24-20} ... +/* 3340 */ MCD_OPC_FilterValue, 0, 9, 0, 0, // Skip to: 3354 +/* 3345 */ MCD_OPC_CheckPredicate, 4, 81, 2, 0, // Skip to: 3943 +/* 3350 */ MCD_OPC_Decode, 206, 2, 50, // Opcode: FCVT_S_W +/* 3354 */ MCD_OPC_FilterValue, 1, 9, 0, 0, // Skip to: 3368 +/* 3359 */ MCD_OPC_CheckPredicate, 4, 67, 2, 0, // Skip to: 3943 +/* 3364 */ MCD_OPC_Decode, 207, 2, 50, // Opcode: FCVT_S_WU +/* 3368 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 3382 +/* 3373 */ MCD_OPC_CheckPredicate, 10, 53, 2, 0, // Skip to: 3943 +/* 3378 */ MCD_OPC_Decode, 204, 2, 50, // Opcode: FCVT_S_L +/* 3382 */ MCD_OPC_FilterValue, 3, 44, 2, 0, // Skip to: 3943 +/* 3387 */ MCD_OPC_CheckPredicate, 10, 39, 2, 0, // Skip to: 3943 +/* 3392 */ MCD_OPC_Decode, 205, 2, 50, // Opcode: FCVT_S_LU +/* 3396 */ MCD_OPC_FilterValue, 105, 73, 0, 0, // Skip to: 3474 +/* 3401 */ MCD_OPC_ExtractField, 20, 5, // Inst{24-20} ... +/* 3404 */ MCD_OPC_FilterValue, 0, 16, 0, 0, // Skip to: 3425 +/* 3409 */ MCD_OPC_CheckPredicate, 5, 17, 2, 0, // Skip to: 3943 +/* 3414 */ MCD_OPC_CheckField, 12, 3, 0, 10, 2, 0, // Skip to: 3943 +/* 3421 */ MCD_OPC_Decode, 197, 2, 51, // Opcode: FCVT_D_W +/* 3425 */ MCD_OPC_FilterValue, 1, 16, 0, 0, // Skip to: 3446 +/* 3430 */ MCD_OPC_CheckPredicate, 5, 252, 1, 0, // Skip to: 3943 +/* 3435 */ MCD_OPC_CheckField, 12, 3, 0, 245, 1, 0, // Skip to: 3943 +/* 3442 */ MCD_OPC_Decode, 198, 2, 51, // Opcode: FCVT_D_WU +/* 3446 */ MCD_OPC_FilterValue, 2, 9, 0, 0, // Skip to: 3460 +/* 3451 */ MCD_OPC_CheckPredicate, 11, 231, 1, 0, // Skip to: 3943 +/* 3456 */ MCD_OPC_Decode, 194, 2, 52, // Opcode: FCVT_D_L +/* 3460 */ MCD_OPC_FilterValue, 3, 222, 1, 0, // Skip to: 3943 +/* 3465 */ MCD_OPC_CheckPredicate, 11, 217, 1, 0, // Skip to: 3943 +/* 3470 */ MCD_OPC_Decode, 195, 2, 52, // Opcode: FCVT_D_LU +/* 3474 */ MCD_OPC_FilterValue, 112, 45, 0, 0, // Skip to: 3524 +/* 3479 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3482 */ MCD_OPC_FilterValue, 0, 16, 0, 0, // Skip to: 3503 +/* 3487 */ MCD_OPC_CheckPredicate, 4, 195, 1, 0, // Skip to: 3943 +/* 3492 */ MCD_OPC_CheckField, 20, 5, 0, 188, 1, 0, // Skip to: 3943 +/* 3499 */ MCD_OPC_Decode, 238, 2, 53, // Opcode: FMV_X_W +/* 3503 */ MCD_OPC_FilterValue, 1, 179, 1, 0, // Skip to: 3943 +/* 3508 */ MCD_OPC_CheckPredicate, 4, 174, 1, 0, // Skip to: 3943 +/* 3513 */ MCD_OPC_CheckField, 20, 5, 0, 167, 1, 0, // Skip to: 3943 +/* 3520 */ MCD_OPC_Decode, 193, 2, 53, // Opcode: FCLASS_S +/* 3524 */ MCD_OPC_FilterValue, 113, 45, 0, 0, // Skip to: 3574 +/* 3529 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3532 */ MCD_OPC_FilterValue, 0, 16, 0, 0, // Skip to: 3553 +/* 3537 */ MCD_OPC_CheckPredicate, 11, 145, 1, 0, // Skip to: 3943 +/* 3542 */ MCD_OPC_CheckField, 20, 5, 0, 138, 1, 0, // Skip to: 3943 +/* 3549 */ MCD_OPC_Decode, 237, 2, 54, // Opcode: FMV_X_D +/* 3553 */ MCD_OPC_FilterValue, 1, 129, 1, 0, // Skip to: 3943 +/* 3558 */ MCD_OPC_CheckPredicate, 5, 124, 1, 0, // Skip to: 3943 +/* 3563 */ MCD_OPC_CheckField, 20, 5, 0, 117, 1, 0, // Skip to: 3943 +/* 3570 */ MCD_OPC_Decode, 192, 2, 54, // Opcode: FCLASS_D +/* 3574 */ MCD_OPC_FilterValue, 120, 23, 0, 0, // Skip to: 3602 +/* 3579 */ MCD_OPC_CheckPredicate, 4, 103, 1, 0, // Skip to: 3943 +/* 3584 */ MCD_OPC_CheckField, 20, 5, 0, 96, 1, 0, // Skip to: 3943 +/* 3591 */ MCD_OPC_CheckField, 12, 3, 0, 89, 1, 0, // Skip to: 3943 +/* 3598 */ MCD_OPC_Decode, 236, 2, 55, // Opcode: FMV_W_X +/* 3602 */ MCD_OPC_FilterValue, 121, 80, 1, 0, // Skip to: 3943 +/* 3607 */ MCD_OPC_CheckPredicate, 11, 75, 1, 0, // Skip to: 3943 +/* 3612 */ MCD_OPC_CheckField, 20, 5, 0, 68, 1, 0, // Skip to: 3943 +/* 3619 */ MCD_OPC_CheckField, 12, 3, 0, 61, 1, 0, // Skip to: 3943 +/* 3626 */ MCD_OPC_Decode, 235, 2, 51, // Opcode: FMV_D_X +/* 3630 */ MCD_OPC_FilterValue, 99, 57, 0, 0, // Skip to: 3692 +/* 3635 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3638 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 3647 +/* 3643 */ MCD_OPC_Decode, 129, 2, 56, // Opcode: BEQ +/* 3647 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 3656 +/* 3652 */ MCD_OPC_Decode, 134, 2, 56, // Opcode: BNE +/* 3656 */ MCD_OPC_FilterValue, 4, 4, 0, 0, // Skip to: 3665 +/* 3661 */ MCD_OPC_Decode, 132, 2, 56, // Opcode: BLT +/* 3665 */ MCD_OPC_FilterValue, 5, 4, 0, 0, // Skip to: 3674 +/* 3670 */ MCD_OPC_Decode, 130, 2, 56, // Opcode: BGE +/* 3674 */ MCD_OPC_FilterValue, 6, 4, 0, 0, // Skip to: 3683 +/* 3679 */ MCD_OPC_Decode, 133, 2, 56, // Opcode: BLTU +/* 3683 */ MCD_OPC_FilterValue, 7, 255, 0, 0, // Skip to: 3943 +/* 3688 */ MCD_OPC_Decode, 131, 2, 56, // Opcode: BGEU +/* 3692 */ MCD_OPC_FilterValue, 103, 11, 0, 0, // Skip to: 3708 +/* 3697 */ MCD_OPC_CheckField, 12, 3, 0, 239, 0, 0, // Skip to: 3943 +/* 3704 */ MCD_OPC_Decode, 128, 3, 24, // Opcode: JALR +/* 3708 */ MCD_OPC_FilterValue, 111, 4, 0, 0, // Skip to: 3717 +/* 3713 */ MCD_OPC_Decode, 255, 2, 57, // Opcode: JAL +/* 3717 */ MCD_OPC_FilterValue, 115, 221, 0, 0, // Skip to: 3943 +/* 3722 */ MCD_OPC_ExtractField, 12, 3, // Inst{14-12} ... +/* 3725 */ MCD_OPC_FilterValue, 0, 139, 0, 0, // Skip to: 3869 +/* 3730 */ MCD_OPC_ExtractField, 25, 7, // Inst{31-25} ... +/* 3733 */ MCD_OPC_FilterValue, 0, 51, 0, 0, // Skip to: 3789 +/* 3738 */ MCD_OPC_ExtractField, 15, 10, // Inst{24-15} ... +/* 3741 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 3757 +/* 3746 */ MCD_OPC_CheckField, 7, 5, 0, 190, 0, 0, // Skip to: 3943 +/* 3753 */ MCD_OPC_Decode, 189, 2, 0, // Opcode: ECALL +/* 3757 */ MCD_OPC_FilterValue, 32, 11, 0, 0, // Skip to: 3773 +/* 3762 */ MCD_OPC_CheckField, 7, 5, 0, 174, 0, 0, // Skip to: 3943 +/* 3769 */ MCD_OPC_Decode, 188, 2, 0, // Opcode: EBREAK +/* 3773 */ MCD_OPC_FilterValue, 64, 165, 0, 0, // Skip to: 3943 +/* 3778 */ MCD_OPC_CheckField, 7, 5, 0, 158, 0, 0, // Skip to: 3943 +/* 3785 */ MCD_OPC_Decode, 190, 3, 0, // Opcode: URET +/* 3789 */ MCD_OPC_FilterValue, 8, 36, 0, 0, // Skip to: 3830 +/* 3794 */ MCD_OPC_ExtractField, 15, 10, // Inst{24-15} ... +/* 3797 */ MCD_OPC_FilterValue, 64, 11, 0, 0, // Skip to: 3813 +/* 3802 */ MCD_OPC_CheckField, 7, 5, 0, 134, 0, 0, // Skip to: 3943 +/* 3809 */ MCD_OPC_Decode, 181, 3, 0, // Opcode: SRET +/* 3813 */ MCD_OPC_FilterValue, 160, 1, 124, 0, 0, // Skip to: 3943 +/* 3819 */ MCD_OPC_CheckField, 7, 5, 0, 117, 0, 0, // Skip to: 3943 +/* 3826 */ MCD_OPC_Decode, 191, 3, 0, // Opcode: WFI +/* 3830 */ MCD_OPC_FilterValue, 9, 11, 0, 0, // Skip to: 3846 +/* 3835 */ MCD_OPC_CheckField, 7, 5, 0, 101, 0, 0, // Skip to: 3943 +/* 3842 */ MCD_OPC_Decode, 167, 3, 58, // Opcode: SFENCE_VMA +/* 3846 */ MCD_OPC_FilterValue, 24, 92, 0, 0, // Skip to: 3943 +/* 3851 */ MCD_OPC_CheckField, 15, 10, 64, 85, 0, 0, // Skip to: 3943 +/* 3858 */ MCD_OPC_CheckField, 7, 5, 0, 78, 0, 0, // Skip to: 3943 +/* 3865 */ MCD_OPC_Decode, 145, 3, 0, // Opcode: MRET +/* 3869 */ MCD_OPC_FilterValue, 1, 24, 0, 0, // Skip to: 3898 +/* 3874 */ MCD_OPC_CheckField, 15, 17, 128, 128, 6, 11, 0, 0, // Skip to: 3894 +/* 3883 */ MCD_OPC_CheckField, 7, 5, 0, 4, 0, 0, // Skip to: 3894 +/* 3890 */ MCD_OPC_Decode, 189, 3, 0, // Opcode: UNIMP +/* 3894 */ MCD_OPC_Decode, 139, 2, 59, // Opcode: CSRRW +/* 3898 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 3907 +/* 3903 */ MCD_OPC_Decode, 137, 2, 59, // Opcode: CSRRS +/* 3907 */ MCD_OPC_FilterValue, 3, 4, 0, 0, // Skip to: 3916 +/* 3912 */ MCD_OPC_Decode, 135, 2, 59, // Opcode: CSRRC +/* 3916 */ MCD_OPC_FilterValue, 5, 4, 0, 0, // Skip to: 3925 +/* 3921 */ MCD_OPC_Decode, 140, 2, 60, // Opcode: CSRRWI +/* 3925 */ MCD_OPC_FilterValue, 6, 4, 0, 0, // Skip to: 3934 +/* 3930 */ MCD_OPC_Decode, 138, 2, 60, // Opcode: CSRRSI +/* 3934 */ MCD_OPC_FilterValue, 7, 4, 0, 0, // Skip to: 3943 +/* 3939 */ MCD_OPC_Decode, 136, 2, 60, // Opcode: CSRRCI +/* 3943 */ MCD_OPC_Fail, + 0 +}; + +static const uint8_t DecoderTableRISCV32Only_16[] = { +/* 0 */ MCD_OPC_ExtractField, 0, 2, // Inst{1-0} ... +/* 3 */ MCD_OPC_FilterValue, 0, 31, 0, 0, // Skip to: 39 +/* 8 */ MCD_OPC_ExtractField, 13, 3, // Inst{15-13} ... +/* 11 */ MCD_OPC_FilterValue, 3, 9, 0, 0, // Skip to: 25 +/* 16 */ MCD_OPC_CheckPredicate, 12, 75, 0, 0, // Skip to: 96 +/* 21 */ MCD_OPC_Decode, 154, 2, 61, // Opcode: C_FLW +/* 25 */ MCD_OPC_FilterValue, 7, 66, 0, 0, // Skip to: 96 +/* 30 */ MCD_OPC_CheckPredicate, 12, 61, 0, 0, // Skip to: 96 +/* 35 */ MCD_OPC_Decode, 158, 2, 61, // Opcode: C_FSW +/* 39 */ MCD_OPC_FilterValue, 1, 16, 0, 0, // Skip to: 60 +/* 44 */ MCD_OPC_CheckPredicate, 13, 47, 0, 0, // Skip to: 96 +/* 49 */ MCD_OPC_CheckField, 13, 3, 1, 40, 0, 0, // Skip to: 96 +/* 56 */ MCD_OPC_Decode, 161, 2, 19, // Opcode: C_JAL +/* 60 */ MCD_OPC_FilterValue, 2, 31, 0, 0, // Skip to: 96 +/* 65 */ MCD_OPC_ExtractField, 13, 3, // Inst{15-13} ... +/* 68 */ MCD_OPC_FilterValue, 3, 9, 0, 0, // Skip to: 82 +/* 73 */ MCD_OPC_CheckPredicate, 12, 18, 0, 0, // Skip to: 96 +/* 78 */ MCD_OPC_Decode, 155, 2, 62, // Opcode: C_FLWSP +/* 82 */ MCD_OPC_FilterValue, 7, 9, 0, 0, // Skip to: 96 +/* 87 */ MCD_OPC_CheckPredicate, 12, 4, 0, 0, // Skip to: 96 +/* 92 */ MCD_OPC_Decode, 159, 2, 63, // Opcode: C_FSWSP +/* 96 */ MCD_OPC_Fail, + 0 +}; + +static bool checkDecoderPredicate(unsigned Idx, uint64_t Bits) +{ + switch (Idx) { + default: assert(0 && "Invalid index!"); + case 0: + return (Bits & RISCV_FeatureStdExtC); + case 1: + return (Bits & RISCV_FeatureStdExtC) && (Bits & RISCV_FeatureStdExtD); + case 2: + return (Bits & RISCV_FeatureStdExtC) && (Bits & RISCV_Feature64Bit); + case 3: + return (Bits & RISCV_Feature64Bit); + case 4: + return (Bits & RISCV_FeatureStdExtF); + case 5: + return (Bits & RISCV_FeatureStdExtD); + case 6: + return (Bits & RISCV_FeatureStdExtA); + case 7: + return (Bits & RISCV_FeatureStdExtA) && (Bits & RISCV_Feature64Bit); + case 8: + return (Bits & RISCV_FeatureStdExtM); + case 9: + return (Bits & RISCV_FeatureStdExtM) && (Bits & RISCV_Feature64Bit); + case 10: + return (Bits & RISCV_FeatureStdExtF) && (Bits & RISCV_Feature64Bit); + case 11: + return (Bits & RISCV_FeatureStdExtD) && (Bits & RISCV_Feature64Bit); + case 12: + return (Bits & RISCV_FeatureStdExtC) && (Bits & RISCV_FeatureStdExtF) && !(Bits & RISCV_Feature64Bit); + case 13: + return (Bits & RISCV_FeatureStdExtC) && !(Bits & RISCV_Feature64Bit); + } +} + +#define DecodeToMCInst(fname, fieldname, InsnType) \ +static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \ + uint64_t Address, const void *Decoder,\ + bool *DecodeComplete) {\ + *DecodeComplete = true;\ + InsnType tmp; \ + switch (Idx) { \ + default: assert(0 && "Invalid index!");\ + case 0: \ + return S; \ + case 1: \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 5, 1) << 3; \ + tmp |= fieldname(insn, 6, 1) << 2; \ + tmp |= fieldname(insn, 7, 4) << 6; \ + tmp |= fieldname(insn, 11, 2) << 4; \ + if (decodeUImmNonZeroOperand(MI, tmp, Address, Decoder, 10) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 2: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 3: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 4: \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeFPR64CRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 5, 2) << 6; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 5: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 3) << 6; \ + tmp |= fieldname(insn, 5, 2) << 3; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 9) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 6: \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 5, 1) << 6; \ + tmp |= fieldname(insn, 6, 1) << 2; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 7) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 7: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 8: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 2) << 6; \ + tmp |= fieldname(insn, 4, 3) << 2; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 9: \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 5, 2) << 6; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 10: \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 1) << 5; \ + tmp |= fieldname(insn, 3, 2) << 7; \ + tmp |= fieldname(insn, 5, 1) << 6; \ + tmp |= fieldname(insn, 6, 1) << 4; \ + tmp |= fieldname(insn, 12, 1) << 9; \ + if (decodeSImmNonZeroOperand(MI, tmp, Address, Decoder, 10) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 11: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0X2RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeCLUIImmOperand(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 12: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 3) << 6; \ + tmp |= fieldname(insn, 5, 2) << 3; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 9) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 13: \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 14: \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 5) << 0; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 15: \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 16: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 17: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 18: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeGPRNoX0RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 19: \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 1) << 4; \ + tmp |= fieldname(insn, 3, 3) << 0; \ + tmp |= fieldname(insn, 6, 1) << 6; \ + tmp |= fieldname(insn, 7, 1) << 5; \ + tmp |= fieldname(insn, 8, 1) << 9; \ + tmp |= fieldname(insn, 9, 2) << 7; \ + tmp |= fieldname(insn, 11, 1) << 3; \ + tmp |= fieldname(insn, 12, 1) << 10; \ + if (decodeSImmOperandAndLsl1(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 20: \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 3) << 6; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 9) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 21: \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 1) << 4; \ + tmp |= fieldname(insn, 3, 2) << 0; \ + tmp |= fieldname(insn, 5, 2) << 5; \ + tmp |= fieldname(insn, 10, 2) << 2; \ + tmp |= fieldname(insn, 12, 1) << 7; \ + if (decodeSImmOperandAndLsl1(MI, tmp, Address, Decoder, 9) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 22: \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 2) << 6; \ + tmp |= fieldname(insn, 9, 4) << 2; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 23: \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 3) << 6; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 9) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 24: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 12); \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 25: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 12); \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 26: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 12); \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 27: \ + tmp = fieldname(insn, 24, 4); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 4) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 4); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 4) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 28: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 6); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 6) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 29: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 20); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 20) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 30: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 5) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 31: \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 5) << 0; \ + tmp |= fieldname(insn, 25, 7) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 32: \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 5) << 0; \ + tmp |= fieldname(insn, 25, 7) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 33: \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 5) << 0; \ + tmp |= fieldname(insn, 25, 7) << 5; \ + if (decodeSImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 34: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 35: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 36: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 27, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 37: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 27, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 38: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 39: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 40: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 41: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 42: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 43: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 44: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 45: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 46: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 47: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 48: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 49: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 50: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 51: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 52: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 12, 3); \ + if (decodeFRMArg(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 53: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 54: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeFPR64RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 55: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 56: \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 1) << 10; \ + tmp |= fieldname(insn, 8, 4) << 0; \ + tmp |= fieldname(insn, 25, 6) << 4; \ + tmp |= fieldname(insn, 31, 1) << 11; \ + if (decodeSImmOperandAndLsl1(MI, tmp, Address, Decoder, 13) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 57: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 12, 8) << 11; \ + tmp |= fieldname(insn, 20, 1) << 10; \ + tmp |= fieldname(insn, 21, 10) << 0; \ + tmp |= fieldname(insn, 31, 1) << 19; \ + if (decodeSImmOperandAndLsl1(MI, tmp, Address, Decoder, 21) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 58: \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 59: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 12); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 60: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeGPRRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 20, 12); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 12) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 15, 5); \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 5) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 61: \ + tmp = fieldname(insn, 2, 3); \ + if (DecodeFPR32CRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = fieldname(insn, 7, 3); \ + if (DecodeGPRCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 5, 1) << 6; \ + tmp |= fieldname(insn, 6, 1) << 2; \ + tmp |= fieldname(insn, 10, 3) << 3; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 7) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 62: \ + tmp = fieldname(insn, 7, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 2, 2) << 6; \ + tmp |= fieldname(insn, 4, 3) << 2; \ + tmp |= fieldname(insn, 12, 1) << 5; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + case 63: \ + tmp = fieldname(insn, 2, 5); \ + if (DecodeFPR32RegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + tmp = 0; \ + tmp |= fieldname(insn, 7, 2) << 6; \ + tmp |= fieldname(insn, 9, 4) << 2; \ + if (decodeUImmOperand(MI, tmp, Address, Decoder, 8) == MCDisassembler_Fail) return MCDisassembler_Fail; \ + return S; \ + } \ +} + +#define DecodeInstruction(fname, fieldname, decoder, InsnType) \ +static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI,\ + InsnType insn, uint64_t Address,\ + const void *DisAsm, int feature) {\ + uint64_t Bits = getFeatureBits(feature);\ +\ + const uint8_t *Ptr = DecodeTable;\ + uint32_t CurFieldValue = 0;\ + DecodeStatus S = MCDisassembler_Success;\ + while (true) {\ + switch (*Ptr) {\ + default:\ + return MCDisassembler_Fail;\ + case MCD_OPC_ExtractField: {\ + unsigned Start = *++Ptr;\ + unsigned Len = *++Ptr;\ + ++Ptr;\ + CurFieldValue = fieldname(insn, Start, Len);\ + break;\ + }\ + case MCD_OPC_FilterValue: {\ + unsigned Len;\ + InsnType Val = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + unsigned NumToSkip = *Ptr++;\ + NumToSkip |= (*Ptr++) << 8;\ + NumToSkip |= (*Ptr++) << 16;\ +\ + if (Val != CurFieldValue)\ + Ptr += NumToSkip;\ + break;\ + }\ + case MCD_OPC_CheckField: {\ + unsigned Start = *++Ptr;\ + unsigned Len = *++Ptr;\ + InsnType FieldValue = fieldname(insn, Start, Len);\ + uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + unsigned NumToSkip = *Ptr++;\ + NumToSkip |= (*Ptr++) << 8;\ + NumToSkip |= (*Ptr++) << 16;\ +\ + if (ExpectedValue != FieldValue)\ + Ptr += NumToSkip;\ + break;\ + }\ + case MCD_OPC_CheckPredicate: {\ + unsigned Len;\ + unsigned PIdx = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + unsigned NumToSkip = *Ptr++;\ + NumToSkip |= (*Ptr++) << 8;\ + NumToSkip |= (*Ptr++) << 16;\ + bool Pred;\ + if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\ + Ptr += NumToSkip;\ + (void)Pred;\ + break;\ + }\ + case MCD_OPC_Decode: {\ + unsigned Len;\ + unsigned Opc = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\ + Ptr += Len;\ +\ + MCInst_clear(MI);\ + MCInst_setOpcode(MI, Opc);\ + bool DecodeComplete;\ + S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, &DecodeComplete);\ + assert(DecodeComplete);\ +\ + return S;\ + }\ + case MCD_OPC_TryDecode: {\ + unsigned Len;\ + unsigned Opc = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\ + Ptr += Len;\ + unsigned NumToSkip = *Ptr++;\ + NumToSkip |= (*Ptr++) << 8;\ + NumToSkip |= (*Ptr++) << 16;\ +\ + MCInst TmpMI;\ + MCInst_setOpcode(&TmpMI, Opc);\ + bool DecodeComplete;\ + S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, &DecodeComplete);\ +\ + if (DecodeComplete) {\ + *MI = TmpMI;\ + return S;\ + } else {\ + assert(S == MCDisassembler_Fail);\ + Ptr += NumToSkip;\ + S = MCDisassembler_Success;\ + }\ + break;\ + }\ + case MCD_OPC_SoftFail: {\ + unsigned Len;\ + InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\ + Ptr += Len;\ + InsnType NegativeMask = decodeULEB128(Ptr, &Len);\ + Ptr += Len;\ + bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\ + if (Fail)\ + S = MCDisassembler_SoftFail;\ + break;\ + }\ + case MCD_OPC_Fail: {\ + return MCDisassembler_Fail;\ + }\ + }\ + }\ + assert(0 && "bogosity detected in disassembler state machine!");\ +} + +// For RISCV instruction is 32 bits. +FieldFromInstruction(fieldFromInstruction, uint32_t) +DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t) +DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t) diff --git a/arch/RISCV/RISCVGenInsnNameMaps.inc b/arch/RISCV/RISCVGenInsnNameMaps.inc new file mode 100644 index 000000000..17d42bf9c --- /dev/null +++ b/arch/RISCV/RISCVGenInsnNameMaps.inc @@ -0,0 +1,275 @@ +// This is auto-gen data for Capstone engine (www.capstone-engine.org) +// By Nguyen Anh Quynh + + { RISCV_INS_ADD, "add" }, + { RISCV_INS_ADDI, "addi" }, + { RISCV_INS_ADDIW, "addiw" }, + { RISCV_INS_ADDW, "addw" }, + { RISCV_INS_AMOADD_D, "amoadd.d" }, + { RISCV_INS_AMOADD_D_AQ, "amoadd.d.aq" }, + { RISCV_INS_AMOADD_D_AQ_RL, "amoadd.d.aqrl" }, + { RISCV_INS_AMOADD_D_RL, "amoadd.d.rl" }, + { RISCV_INS_AMOADD_W, "amoadd.w" }, + { RISCV_INS_AMOADD_W_AQ, "amoadd.w.aq" }, + { RISCV_INS_AMOADD_W_AQ_RL, "amoadd.w.aqrl" }, + { RISCV_INS_AMOADD_W_RL, "amoadd.w.rl" }, + { RISCV_INS_AMOAND_D, "amoand.d" }, + { RISCV_INS_AMOAND_D_AQ, "amoand.d.aq" }, + { RISCV_INS_AMOAND_D_AQ_RL, "amoand.d.aqrl" }, + { RISCV_INS_AMOAND_D_RL, "amoand.d.rl" }, + { RISCV_INS_AMOAND_W, "amoand.w" }, + { RISCV_INS_AMOAND_W_AQ, "amoand.w.aq" }, + { RISCV_INS_AMOAND_W_AQ_RL, "amoand.w.aqrl" }, + { RISCV_INS_AMOAND_W_RL, "amoand.w.rl" }, + { RISCV_INS_AMOMAXU_D, "amomaxu.d" }, + { RISCV_INS_AMOMAXU_D_AQ, "amomaxu.d.aq" }, + { RISCV_INS_AMOMAXU_D_AQ_RL, "amomaxu.d.aqrl" }, + { RISCV_INS_AMOMAXU_D_RL, "amomaxu.d.rl" }, + { RISCV_INS_AMOMAXU_W, "amomaxu.w" }, + { RISCV_INS_AMOMAXU_W_AQ, "amomaxu.w.aq" }, + { RISCV_INS_AMOMAXU_W_AQ_RL, "amomaxu.w.aqrl" }, + { RISCV_INS_AMOMAXU_W_RL, "amomaxu.w.rl" }, + { RISCV_INS_AMOMAX_D, "amomax.d" }, + { RISCV_INS_AMOMAX_D_AQ, "amomax.d.aq" }, + { RISCV_INS_AMOMAX_D_AQ_RL, "amomax.d.aqrl" }, + { RISCV_INS_AMOMAX_D_RL, "amomax.d.rl" }, + { RISCV_INS_AMOMAX_W, "amomax.w" }, + { RISCV_INS_AMOMAX_W_AQ, "amomax.w.aq" }, + { RISCV_INS_AMOMAX_W_AQ_RL, "amomax.w.aqrl" }, + { RISCV_INS_AMOMAX_W_RL, "amomax.w.rl" }, + { RISCV_INS_AMOMINU_D, "amominu.d" }, + { RISCV_INS_AMOMINU_D_AQ, "amominu.d.aq" }, + { RISCV_INS_AMOMINU_D_AQ_RL, "amominu.d.aqrl" }, + { RISCV_INS_AMOMINU_D_RL, "amominu.d.rl" }, + { RISCV_INS_AMOMINU_W, "amominu.w" }, + { RISCV_INS_AMOMINU_W_AQ, "amominu.w.aq" }, + { RISCV_INS_AMOMINU_W_AQ_RL, "amominu.w.aqrl" }, + { RISCV_INS_AMOMINU_W_RL, "amominu.w.rl" }, + { RISCV_INS_AMOMIN_D, "amomin.d" }, + { RISCV_INS_AMOMIN_D_AQ, "amomin.d.aq" }, + { RISCV_INS_AMOMIN_D_AQ_RL, "amomin.d.aqrl" }, + { RISCV_INS_AMOMIN_D_RL, "amomin.d.rl" }, + { RISCV_INS_AMOMIN_W, "amomin.w" }, + { RISCV_INS_AMOMIN_W_AQ, "amomin.w.aq" }, + { RISCV_INS_AMOMIN_W_AQ_RL, "amomin.w.aqrl" }, + { RISCV_INS_AMOMIN_W_RL, "amomin.w.rl" }, + { RISCV_INS_AMOOR_D, "amoor.d" }, + { RISCV_INS_AMOOR_D_AQ, "amoor.d.aq" }, + { RISCV_INS_AMOOR_D_AQ_RL, "amoor.d.aqrl" }, + { RISCV_INS_AMOOR_D_RL, "amoor.d.rl" }, + { RISCV_INS_AMOOR_W, "amoor.w" }, + { RISCV_INS_AMOOR_W_AQ, "amoor.w.aq" }, + { RISCV_INS_AMOOR_W_AQ_RL, "amoor.w.aqrl" }, + { RISCV_INS_AMOOR_W_RL, "amoor.w.rl" }, + { RISCV_INS_AMOSWAP_D, "amoswap.d" }, + { RISCV_INS_AMOSWAP_D_AQ, "amoswap.d.aq" }, + { RISCV_INS_AMOSWAP_D_AQ_RL, "amoswap.d.aqrl" }, + { RISCV_INS_AMOSWAP_D_RL, "amoswap.d.rl" }, + { RISCV_INS_AMOSWAP_W, "amoswap.w" }, + { RISCV_INS_AMOSWAP_W_AQ, "amoswap.w.aq" }, + { RISCV_INS_AMOSWAP_W_AQ_RL, "amoswap.w.aqrl" }, + { RISCV_INS_AMOSWAP_W_RL, "amoswap.w.rl" }, + { RISCV_INS_AMOXOR_D, "amoxor.d" }, + { RISCV_INS_AMOXOR_D_AQ, "amoxor.d.aq" }, + { RISCV_INS_AMOXOR_D_AQ_RL, "amoxor.d.aqrl" }, + { RISCV_INS_AMOXOR_D_RL, "amoxor.d.rl" }, + { RISCV_INS_AMOXOR_W, "amoxor.w" }, + { RISCV_INS_AMOXOR_W_AQ, "amoxor.w.aq" }, + { RISCV_INS_AMOXOR_W_AQ_RL, "amoxor.w.aqrl" }, + { RISCV_INS_AMOXOR_W_RL, "amoxor.w.rl" }, + { RISCV_INS_AND, "and" }, + { RISCV_INS_ANDI, "andi" }, + { RISCV_INS_AUIPC, "auipc" }, + { RISCV_INS_BEQ, "beq" }, + { RISCV_INS_BGE, "bge" }, + { RISCV_INS_BGEU, "bgeu" }, + { RISCV_INS_BLT, "blt" }, + { RISCV_INS_BLTU, "bltu" }, + { RISCV_INS_BNE, "bne" }, + { RISCV_INS_CSRRC, "csrrc" }, + { RISCV_INS_CSRRCI, "csrrci" }, + { RISCV_INS_CSRRS, "csrrs" }, + { RISCV_INS_CSRRSI, "csrrsi" }, + { RISCV_INS_CSRRW, "csrrw" }, + { RISCV_INS_CSRRWI, "csrrwi" }, + { RISCV_INS_C_ADD, "c.add" }, + { RISCV_INS_C_ADDI, "c.addi" }, + { RISCV_INS_C_ADDI16SP, "c.addi16sp" }, + { RISCV_INS_C_ADDI4SPN, "c.addi4spn" }, + { RISCV_INS_C_ADDIW, "c.addiw" }, + { RISCV_INS_C_ADDW, "c.addw" }, + { RISCV_INS_C_AND, "c.and" }, + { RISCV_INS_C_ANDI, "c.andi" }, + { RISCV_INS_C_BEQZ, "c.beqz" }, + { RISCV_INS_C_BNEZ, "c.bnez" }, + { RISCV_INS_C_EBREAK, "c.ebreak" }, + { RISCV_INS_C_FLD, "c.fld" }, + { RISCV_INS_C_FLDSP, "c.fldsp" }, + { RISCV_INS_C_FLW, "c.flw" }, + { RISCV_INS_C_FLWSP, "c.flwsp" }, + { RISCV_INS_C_FSD, "c.fsd" }, + { RISCV_INS_C_FSDSP, "c.fsdsp" }, + { RISCV_INS_C_FSW, "c.fsw" }, + { RISCV_INS_C_FSWSP, "c.fswsp" }, + { RISCV_INS_C_J, "c.j" }, + { RISCV_INS_C_JAL, "c.jal" }, + { RISCV_INS_C_JALR, "c.jalr" }, + { RISCV_INS_C_JR, "c.jr" }, + { RISCV_INS_C_LD, "c.ld" }, + { RISCV_INS_C_LDSP, "c.ldsp" }, + { RISCV_INS_C_LI, "c.li" }, + { RISCV_INS_C_LUI, "c.lui" }, + { RISCV_INS_C_LW, "c.lw" }, + { RISCV_INS_C_LWSP, "c.lwsp" }, + { RISCV_INS_C_MV, "c.mv" }, + { RISCV_INS_C_NOP, "c.nop" }, + { RISCV_INS_C_OR, "c.or" }, + { RISCV_INS_C_SD, "c.sd" }, + { RISCV_INS_C_SDSP, "c.sdsp" }, + { RISCV_INS_C_SLLI, "c.slli" }, + { RISCV_INS_C_SRAI, "c.srai" }, + { RISCV_INS_C_SRLI, "c.srli" }, + { RISCV_INS_C_SUB, "c.sub" }, + { RISCV_INS_C_SUBW, "c.subw" }, + { RISCV_INS_C_SW, "c.sw" }, + { RISCV_INS_C_SWSP, "c.swsp" }, + { RISCV_INS_C_UNIMP, "c.unimp" }, + { RISCV_INS_C_XOR, "c.xor" }, + { RISCV_INS_DIV, "div" }, + { RISCV_INS_DIVU, "divu" }, + { RISCV_INS_DIVUW, "divuw" }, + { RISCV_INS_DIVW, "divw" }, + { RISCV_INS_EBREAK, "ebreak" }, + { RISCV_INS_ECALL, "ecall" }, + { RISCV_INS_FADD_D, "fadd.d" }, + { RISCV_INS_FADD_S, "fadd.s" }, + { RISCV_INS_FCLASS_D, "fclass.d" }, + { RISCV_INS_FCLASS_S, "fclass.s" }, + { RISCV_INS_FCVT_D_L, "fcvt.d.l" }, + { RISCV_INS_FCVT_D_LU, "fcvt.d.lu" }, + { RISCV_INS_FCVT_D_S, "fcvt.d.s" }, + { RISCV_INS_FCVT_D_W, "fcvt.d.w" }, + { RISCV_INS_FCVT_D_WU, "fcvt.d.wu" }, + { RISCV_INS_FCVT_LU_D, "fcvt.lu.d" }, + { RISCV_INS_FCVT_LU_S, "fcvt.lu.s" }, + { RISCV_INS_FCVT_L_D, "fcvt.l.d" }, + { RISCV_INS_FCVT_L_S, "fcvt.l.s" }, + { RISCV_INS_FCVT_S_D, "fcvt.s.d" }, + { RISCV_INS_FCVT_S_L, "fcvt.s.l" }, + { RISCV_INS_FCVT_S_LU, "fcvt.s.lu" }, + { RISCV_INS_FCVT_S_W, "fcvt.s.w" }, + { RISCV_INS_FCVT_S_WU, "fcvt.s.wu" }, + { RISCV_INS_FCVT_WU_D, "fcvt.wu.d" }, + { RISCV_INS_FCVT_WU_S, "fcvt.wu.s" }, + { RISCV_INS_FCVT_W_D, "fcvt.w.d" }, + { RISCV_INS_FCVT_W_S, "fcvt.w.s" }, + { RISCV_INS_FDIV_D, "fdiv.d" }, + { RISCV_INS_FDIV_S, "fdiv.s" }, + { RISCV_INS_FENCE, "fence" }, + { RISCV_INS_FENCE_I, "fence.i" }, + { RISCV_INS_FENCE_TSO, "fence.tso" }, + { RISCV_INS_FEQ_D, "feq.d" }, + { RISCV_INS_FEQ_S, "feq.s" }, + { RISCV_INS_FLD, "fld" }, + { RISCV_INS_FLE_D, "fle.d" }, + { RISCV_INS_FLE_S, "fle.s" }, + { RISCV_INS_FLT_D, "flt.d" }, + { RISCV_INS_FLT_S, "flt.s" }, + { RISCV_INS_FLW, "flw" }, + { RISCV_INS_FMADD_D, "fmadd.d" }, + { RISCV_INS_FMADD_S, "fmadd.s" }, + { RISCV_INS_FMAX_D, "fmax.d" }, + { RISCV_INS_FMAX_S, "fmax.s" }, + { RISCV_INS_FMIN_D, "fmin.d" }, + { RISCV_INS_FMIN_S, "fmin.s" }, + { RISCV_INS_FMSUB_D, "fmsub.d" }, + { RISCV_INS_FMSUB_S, "fmsub.s" }, + { RISCV_INS_FMUL_D, "fmul.d" }, + { RISCV_INS_FMUL_S, "fmul.s" }, + { RISCV_INS_FMV_D_X, "fmv.d.x" }, + { RISCV_INS_FMV_W_X, "fmv.w.x" }, + { RISCV_INS_FMV_X_D, "fmv.x.d" }, + { RISCV_INS_FMV_X_W, "fmv.x.w" }, + { RISCV_INS_FNMADD_D, "fnmadd.d" }, + { RISCV_INS_FNMADD_S, "fnmadd.s" }, + { RISCV_INS_FNMSUB_D, "fnmsub.d" }, + { RISCV_INS_FNMSUB_S, "fnmsub.s" }, + { RISCV_INS_FSD, "fsd" }, + { RISCV_INS_FSGNJN_D, "fsgnjn.d" }, + { RISCV_INS_FSGNJN_S, "fsgnjn.s" }, + { RISCV_INS_FSGNJX_D, "fsgnjx.d" }, + { RISCV_INS_FSGNJX_S, "fsgnjx.s" }, + { RISCV_INS_FSGNJ_D, "fsgnj.d" }, + { RISCV_INS_FSGNJ_S, "fsgnj.s" }, + { RISCV_INS_FSQRT_D, "fsqrt.d" }, + { RISCV_INS_FSQRT_S, "fsqrt.s" }, + { RISCV_INS_FSUB_D, "fsub.d" }, + { RISCV_INS_FSUB_S, "fsub.s" }, + { RISCV_INS_FSW, "fsw" }, + { RISCV_INS_JAL, "jal" }, + { RISCV_INS_JALR, "jalr" }, + { RISCV_INS_LB, "lb" }, + { RISCV_INS_LBU, "lbu" }, + { RISCV_INS_LD, "ld" }, + { RISCV_INS_LH, "lh" }, + { RISCV_INS_LHU, "lhu" }, + { RISCV_INS_LR_D, "lr.d" }, + { RISCV_INS_LR_D_AQ, "lr.d.aq" }, + { RISCV_INS_LR_D_AQ_RL, "lr.d.aqrl" }, + { RISCV_INS_LR_D_RL, "lr.d.rl" }, + { RISCV_INS_LR_W, "lr.w" }, + { RISCV_INS_LR_W_AQ, "lr.w.aq" }, + { RISCV_INS_LR_W_AQ_RL, "lr.w.aqrl" }, + { RISCV_INS_LR_W_RL, "lr.w.rl" }, + { RISCV_INS_LUI, "lui" }, + { RISCV_INS_LW, "lw" }, + { RISCV_INS_LWU, "lwu" }, + { RISCV_INS_MRET, "mret" }, + { RISCV_INS_MUL, "mul" }, + { RISCV_INS_MULH, "mulh" }, + { RISCV_INS_MULHSU, "mulhsu" }, + { RISCV_INS_MULHU, "mulhu" }, + { RISCV_INS_MULW, "mulw" }, + { RISCV_INS_OR, "or" }, + { RISCV_INS_ORI, "ori" }, + { RISCV_INS_REM, "rem" }, + { RISCV_INS_REMU, "remu" }, + { RISCV_INS_REMUW, "remuw" }, + { RISCV_INS_REMW, "remw" }, + { RISCV_INS_SB, "sb" }, + { RISCV_INS_SC_D, "sc.d" }, + { RISCV_INS_SC_D_AQ, "sc.d.aq" }, + { RISCV_INS_SC_D_AQ_RL, "sc.d.aqrl" }, + { RISCV_INS_SC_D_RL, "sc.d.rl" }, + { RISCV_INS_SC_W, "sc.w" }, + { RISCV_INS_SC_W_AQ, "sc.w.aq" }, + { RISCV_INS_SC_W_AQ_RL, "sc.w.aqrl" }, + { RISCV_INS_SC_W_RL, "sc.w.rl" }, + { RISCV_INS_SD, "sd" }, + { RISCV_INS_SFENCE_VMA, "sfence.vma" }, + { RISCV_INS_SH, "sh" }, + { RISCV_INS_SLL, "sll" }, + { RISCV_INS_SLLI, "slli" }, + { RISCV_INS_SLLIW, "slliw" }, + { RISCV_INS_SLLW, "sllw" }, + { RISCV_INS_SLT, "slt" }, + { RISCV_INS_SLTI, "slti" }, + { RISCV_INS_SLTIU, "sltiu" }, + { RISCV_INS_SLTU, "sltu" }, + { RISCV_INS_SRA, "sra" }, + { RISCV_INS_SRAI, "srai" }, + { RISCV_INS_SRAIW, "sraiw" }, + { RISCV_INS_SRAW, "sraw" }, + { RISCV_INS_SRET, "sret" }, + { RISCV_INS_SRL, "srl" }, + { RISCV_INS_SRLI, "srli" }, + { RISCV_INS_SRLIW, "srliw" }, + { RISCV_INS_SRLW, "srlw" }, + { RISCV_INS_SUB, "sub" }, + { RISCV_INS_SUBW, "subw" }, + { RISCV_INS_SW, "sw" }, + { RISCV_INS_UNIMP, "unimp" }, + { RISCV_INS_URET, "uret" }, + { RISCV_INS_WFI, "wfi" }, + { RISCV_INS_XOR, "xor" }, + { RISCV_INS_XORI, "xori" }, diff --git a/arch/RISCV/RISCVGenInstrInfo.inc b/arch/RISCV/RISCVGenInstrInfo.inc new file mode 100644 index 000000000..069892e17 --- /dev/null +++ b/arch/RISCV/RISCVGenInstrInfo.inc @@ -0,0 +1,470 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Target Instruction Enum Values and Descriptors *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2015 */ + + +#ifdef GET_INSTRINFO_ENUM +#undef GET_INSTRINFO_ENUM + +enum { + RISCV_PHI = 0, + RISCV_INLINEASM = 1, + RISCV_INLINEASM_BR = 2, + RISCV_CFI_INSTRUCTION = 3, + RISCV_EH_LABEL = 4, + RISCV_GC_LABEL = 5, + RISCV_ANNOTATION_LABEL = 6, + RISCV_KILL = 7, + RISCV_EXTRACT_SUBREG = 8, + RISCV_INSERT_SUBREG = 9, + RISCV_IMPLICIT_DEF = 10, + RISCV_SUBREG_TO_REG = 11, + RISCV_COPY_TO_REGCLASS = 12, + RISCV_DBG_VALUE = 13, + RISCV_DBG_LABEL = 14, + RISCV_REG_SEQUENCE = 15, + RISCV_COPY = 16, + RISCV_BUNDLE = 17, + RISCV_LIFETIME_START = 18, + RISCV_LIFETIME_END = 19, + RISCV_STACKMAP = 20, + RISCV_FENTRY_CALL = 21, + RISCV_PATCHPOINT = 22, + RISCV_LOAD_STACK_GUARD = 23, + RISCV_STATEPOINT = 24, + RISCV_LOCAL_ESCAPE = 25, + RISCV_FAULTING_OP = 26, + RISCV_PATCHABLE_OP = 27, + RISCV_PATCHABLE_FUNCTION_ENTER = 28, + RISCV_PATCHABLE_RET = 29, + RISCV_PATCHABLE_FUNCTION_EXIT = 30, + RISCV_PATCHABLE_TAIL_CALL = 31, + RISCV_PATCHABLE_EVENT_CALL = 32, + RISCV_PATCHABLE_TYPED_EVENT_CALL = 33, + RISCV_ICALL_BRANCH_FUNNEL = 34, + RISCV_G_ADD = 35, + RISCV_G_SUB = 36, + RISCV_G_MUL = 37, + RISCV_G_SDIV = 38, + RISCV_G_UDIV = 39, + RISCV_G_SREM = 40, + RISCV_G_UREM = 41, + RISCV_G_AND = 42, + RISCV_G_OR = 43, + RISCV_G_XOR = 44, + RISCV_G_IMPLICIT_DEF = 45, + RISCV_G_PHI = 46, + RISCV_G_FRAME_INDEX = 47, + RISCV_G_GLOBAL_VALUE = 48, + RISCV_G_EXTRACT = 49, + RISCV_G_UNMERGE_VALUES = 50, + RISCV_G_INSERT = 51, + RISCV_G_MERGE_VALUES = 52, + RISCV_G_BUILD_VECTOR = 53, + RISCV_G_BUILD_VECTOR_TRUNC = 54, + RISCV_G_CONCAT_VECTORS = 55, + RISCV_G_PTRTOINT = 56, + RISCV_G_INTTOPTR = 57, + RISCV_G_BITCAST = 58, + RISCV_G_INTRINSIC_TRUNC = 59, + RISCV_G_INTRINSIC_ROUND = 60, + RISCV_G_LOAD = 61, + RISCV_G_SEXTLOAD = 62, + RISCV_G_ZEXTLOAD = 63, + RISCV_G_STORE = 64, + RISCV_G_ATOMIC_CMPXCHG_WITH_SUCCESS = 65, + RISCV_G_ATOMIC_CMPXCHG = 66, + RISCV_G_ATOMICRMW_XCHG = 67, + RISCV_G_ATOMICRMW_ADD = 68, + RISCV_G_ATOMICRMW_SUB = 69, + RISCV_G_ATOMICRMW_AND = 70, + RISCV_G_ATOMICRMW_NAND = 71, + RISCV_G_ATOMICRMW_OR = 72, + RISCV_G_ATOMICRMW_XOR = 73, + RISCV_G_ATOMICRMW_MAX = 74, + RISCV_G_ATOMICRMW_MIN = 75, + RISCV_G_ATOMICRMW_UMAX = 76, + RISCV_G_ATOMICRMW_UMIN = 77, + RISCV_G_BRCOND = 78, + RISCV_G_BRINDIRECT = 79, + RISCV_G_INTRINSIC = 80, + RISCV_G_INTRINSIC_W_SIDE_EFFECTS = 81, + RISCV_G_ANYEXT = 82, + RISCV_G_TRUNC = 83, + RISCV_G_CONSTANT = 84, + RISCV_G_FCONSTANT = 85, + RISCV_G_VASTART = 86, + RISCV_G_VAARG = 87, + RISCV_G_SEXT = 88, + RISCV_G_ZEXT = 89, + RISCV_G_SHL = 90, + RISCV_G_LSHR = 91, + RISCV_G_ASHR = 92, + RISCV_G_ICMP = 93, + RISCV_G_FCMP = 94, + RISCV_G_SELECT = 95, + RISCV_G_UADDO = 96, + RISCV_G_UADDE = 97, + RISCV_G_USUBO = 98, + RISCV_G_USUBE = 99, + RISCV_G_SADDO = 100, + RISCV_G_SADDE = 101, + RISCV_G_SSUBO = 102, + RISCV_G_SSUBE = 103, + RISCV_G_UMULO = 104, + RISCV_G_SMULO = 105, + RISCV_G_UMULH = 106, + RISCV_G_SMULH = 107, + RISCV_G_FADD = 108, + RISCV_G_FSUB = 109, + RISCV_G_FMUL = 110, + RISCV_G_FMA = 111, + RISCV_G_FDIV = 112, + RISCV_G_FREM = 113, + RISCV_G_FPOW = 114, + RISCV_G_FEXP = 115, + RISCV_G_FEXP2 = 116, + RISCV_G_FLOG = 117, + RISCV_G_FLOG2 = 118, + RISCV_G_FLOG10 = 119, + RISCV_G_FNEG = 120, + RISCV_G_FPEXT = 121, + RISCV_G_FPTRUNC = 122, + RISCV_G_FPTOSI = 123, + RISCV_G_FPTOUI = 124, + RISCV_G_SITOFP = 125, + RISCV_G_UITOFP = 126, + RISCV_G_FABS = 127, + RISCV_G_FCANONICALIZE = 128, + RISCV_G_GEP = 129, + RISCV_G_PTR_MASK = 130, + RISCV_G_BR = 131, + RISCV_G_INSERT_VECTOR_ELT = 132, + RISCV_G_EXTRACT_VECTOR_ELT = 133, + RISCV_G_SHUFFLE_VECTOR = 134, + RISCV_G_CTTZ = 135, + RISCV_G_CTTZ_ZERO_UNDEF = 136, + RISCV_G_CTLZ = 137, + RISCV_G_CTLZ_ZERO_UNDEF = 138, + RISCV_G_CTPOP = 139, + RISCV_G_BSWAP = 140, + RISCV_G_FCEIL = 141, + RISCV_G_FCOS = 142, + RISCV_G_FSIN = 143, + RISCV_G_FSQRT = 144, + RISCV_G_FFLOOR = 145, + RISCV_G_ADDRSPACE_CAST = 146, + RISCV_G_BLOCK_ADDR = 147, + RISCV_ADJCALLSTACKDOWN = 148, + RISCV_ADJCALLSTACKUP = 149, + RISCV_BuildPairF64Pseudo = 150, + RISCV_PseudoAtomicLoadNand32 = 151, + RISCV_PseudoAtomicLoadNand64 = 152, + RISCV_PseudoBR = 153, + RISCV_PseudoBRIND = 154, + RISCV_PseudoCALL = 155, + RISCV_PseudoCALLIndirect = 156, + RISCV_PseudoCmpXchg32 = 157, + RISCV_PseudoCmpXchg64 = 158, + RISCV_PseudoLA = 159, + RISCV_PseudoLI = 160, + RISCV_PseudoLLA = 161, + RISCV_PseudoMaskedAtomicLoadAdd32 = 162, + RISCV_PseudoMaskedAtomicLoadMax32 = 163, + RISCV_PseudoMaskedAtomicLoadMin32 = 164, + RISCV_PseudoMaskedAtomicLoadNand32 = 165, + RISCV_PseudoMaskedAtomicLoadSub32 = 166, + RISCV_PseudoMaskedAtomicLoadUMax32 = 167, + RISCV_PseudoMaskedAtomicLoadUMin32 = 168, + RISCV_PseudoMaskedAtomicSwap32 = 169, + RISCV_PseudoMaskedCmpXchg32 = 170, + RISCV_PseudoRET = 171, + RISCV_PseudoTAIL = 172, + RISCV_PseudoTAILIndirect = 173, + RISCV_Select_FPR32_Using_CC_GPR = 174, + RISCV_Select_FPR64_Using_CC_GPR = 175, + RISCV_Select_GPR_Using_CC_GPR = 176, + RISCV_SplitF64Pseudo = 177, + RISCV_ADD = 178, + RISCV_ADDI = 179, + RISCV_ADDIW = 180, + RISCV_ADDW = 181, + RISCV_AMOADD_D = 182, + RISCV_AMOADD_D_AQ = 183, + RISCV_AMOADD_D_AQ_RL = 184, + RISCV_AMOADD_D_RL = 185, + RISCV_AMOADD_W = 186, + RISCV_AMOADD_W_AQ = 187, + RISCV_AMOADD_W_AQ_RL = 188, + RISCV_AMOADD_W_RL = 189, + RISCV_AMOAND_D = 190, + RISCV_AMOAND_D_AQ = 191, + RISCV_AMOAND_D_AQ_RL = 192, + RISCV_AMOAND_D_RL = 193, + RISCV_AMOAND_W = 194, + RISCV_AMOAND_W_AQ = 195, + RISCV_AMOAND_W_AQ_RL = 196, + RISCV_AMOAND_W_RL = 197, + RISCV_AMOMAXU_D = 198, + RISCV_AMOMAXU_D_AQ = 199, + RISCV_AMOMAXU_D_AQ_RL = 200, + RISCV_AMOMAXU_D_RL = 201, + RISCV_AMOMAXU_W = 202, + RISCV_AMOMAXU_W_AQ = 203, + RISCV_AMOMAXU_W_AQ_RL = 204, + RISCV_AMOMAXU_W_RL = 205, + RISCV_AMOMAX_D = 206, + RISCV_AMOMAX_D_AQ = 207, + RISCV_AMOMAX_D_AQ_RL = 208, + RISCV_AMOMAX_D_RL = 209, + RISCV_AMOMAX_W = 210, + RISCV_AMOMAX_W_AQ = 211, + RISCV_AMOMAX_W_AQ_RL = 212, + RISCV_AMOMAX_W_RL = 213, + RISCV_AMOMINU_D = 214, + RISCV_AMOMINU_D_AQ = 215, + RISCV_AMOMINU_D_AQ_RL = 216, + RISCV_AMOMINU_D_RL = 217, + RISCV_AMOMINU_W = 218, + RISCV_AMOMINU_W_AQ = 219, + RISCV_AMOMINU_W_AQ_RL = 220, + RISCV_AMOMINU_W_RL = 221, + RISCV_AMOMIN_D = 222, + RISCV_AMOMIN_D_AQ = 223, + RISCV_AMOMIN_D_AQ_RL = 224, + RISCV_AMOMIN_D_RL = 225, + RISCV_AMOMIN_W = 226, + RISCV_AMOMIN_W_AQ = 227, + RISCV_AMOMIN_W_AQ_RL = 228, + RISCV_AMOMIN_W_RL = 229, + RISCV_AMOOR_D = 230, + RISCV_AMOOR_D_AQ = 231, + RISCV_AMOOR_D_AQ_RL = 232, + RISCV_AMOOR_D_RL = 233, + RISCV_AMOOR_W = 234, + RISCV_AMOOR_W_AQ = 235, + RISCV_AMOOR_W_AQ_RL = 236, + RISCV_AMOOR_W_RL = 237, + RISCV_AMOSWAP_D = 238, + RISCV_AMOSWAP_D_AQ = 239, + RISCV_AMOSWAP_D_AQ_RL = 240, + RISCV_AMOSWAP_D_RL = 241, + RISCV_AMOSWAP_W = 242, + RISCV_AMOSWAP_W_AQ = 243, + RISCV_AMOSWAP_W_AQ_RL = 244, + RISCV_AMOSWAP_W_RL = 245, + RISCV_AMOXOR_D = 246, + RISCV_AMOXOR_D_AQ = 247, + RISCV_AMOXOR_D_AQ_RL = 248, + RISCV_AMOXOR_D_RL = 249, + RISCV_AMOXOR_W = 250, + RISCV_AMOXOR_W_AQ = 251, + RISCV_AMOXOR_W_AQ_RL = 252, + RISCV_AMOXOR_W_RL = 253, + RISCV_AND = 254, + RISCV_ANDI = 255, + RISCV_AUIPC = 256, + RISCV_BEQ = 257, + RISCV_BGE = 258, + RISCV_BGEU = 259, + RISCV_BLT = 260, + RISCV_BLTU = 261, + RISCV_BNE = 262, + RISCV_CSRRC = 263, + RISCV_CSRRCI = 264, + RISCV_CSRRS = 265, + RISCV_CSRRSI = 266, + RISCV_CSRRW = 267, + RISCV_CSRRWI = 268, + RISCV_C_ADD = 269, + RISCV_C_ADDI = 270, + RISCV_C_ADDI16SP = 271, + RISCV_C_ADDI4SPN = 272, + RISCV_C_ADDIW = 273, + RISCV_C_ADDW = 274, + RISCV_C_AND = 275, + RISCV_C_ANDI = 276, + RISCV_C_BEQZ = 277, + RISCV_C_BNEZ = 278, + RISCV_C_EBREAK = 279, + RISCV_C_FLD = 280, + RISCV_C_FLDSP = 281, + RISCV_C_FLW = 282, + RISCV_C_FLWSP = 283, + RISCV_C_FSD = 284, + RISCV_C_FSDSP = 285, + RISCV_C_FSW = 286, + RISCV_C_FSWSP = 287, + RISCV_C_J = 288, + RISCV_C_JAL = 289, + RISCV_C_JALR = 290, + RISCV_C_JR = 291, + RISCV_C_LD = 292, + RISCV_C_LDSP = 293, + RISCV_C_LI = 294, + RISCV_C_LUI = 295, + RISCV_C_LW = 296, + RISCV_C_LWSP = 297, + RISCV_C_MV = 298, + RISCV_C_NOP = 299, + RISCV_C_OR = 300, + RISCV_C_SD = 301, + RISCV_C_SDSP = 302, + RISCV_C_SLLI = 303, + RISCV_C_SRAI = 304, + RISCV_C_SRLI = 305, + RISCV_C_SUB = 306, + RISCV_C_SUBW = 307, + RISCV_C_SW = 308, + RISCV_C_SWSP = 309, + RISCV_C_UNIMP = 310, + RISCV_C_XOR = 311, + RISCV_DIV = 312, + RISCV_DIVU = 313, + RISCV_DIVUW = 314, + RISCV_DIVW = 315, + RISCV_EBREAK = 316, + RISCV_ECALL = 317, + RISCV_FADD_D = 318, + RISCV_FADD_S = 319, + RISCV_FCLASS_D = 320, + RISCV_FCLASS_S = 321, + RISCV_FCVT_D_L = 322, + RISCV_FCVT_D_LU = 323, + RISCV_FCVT_D_S = 324, + RISCV_FCVT_D_W = 325, + RISCV_FCVT_D_WU = 326, + RISCV_FCVT_LU_D = 327, + RISCV_FCVT_LU_S = 328, + RISCV_FCVT_L_D = 329, + RISCV_FCVT_L_S = 330, + RISCV_FCVT_S_D = 331, + RISCV_FCVT_S_L = 332, + RISCV_FCVT_S_LU = 333, + RISCV_FCVT_S_W = 334, + RISCV_FCVT_S_WU = 335, + RISCV_FCVT_WU_D = 336, + RISCV_FCVT_WU_S = 337, + RISCV_FCVT_W_D = 338, + RISCV_FCVT_W_S = 339, + RISCV_FDIV_D = 340, + RISCV_FDIV_S = 341, + RISCV_FENCE = 342, + RISCV_FENCE_I = 343, + RISCV_FENCE_TSO = 344, + RISCV_FEQ_D = 345, + RISCV_FEQ_S = 346, + RISCV_FLD = 347, + RISCV_FLE_D = 348, + RISCV_FLE_S = 349, + RISCV_FLT_D = 350, + RISCV_FLT_S = 351, + RISCV_FLW = 352, + RISCV_FMADD_D = 353, + RISCV_FMADD_S = 354, + RISCV_FMAX_D = 355, + RISCV_FMAX_S = 356, + RISCV_FMIN_D = 357, + RISCV_FMIN_S = 358, + RISCV_FMSUB_D = 359, + RISCV_FMSUB_S = 360, + RISCV_FMUL_D = 361, + RISCV_FMUL_S = 362, + RISCV_FMV_D_X = 363, + RISCV_FMV_W_X = 364, + RISCV_FMV_X_D = 365, + RISCV_FMV_X_W = 366, + RISCV_FNMADD_D = 367, + RISCV_FNMADD_S = 368, + RISCV_FNMSUB_D = 369, + RISCV_FNMSUB_S = 370, + RISCV_FSD = 371, + RISCV_FSGNJN_D = 372, + RISCV_FSGNJN_S = 373, + RISCV_FSGNJX_D = 374, + RISCV_FSGNJX_S = 375, + RISCV_FSGNJ_D = 376, + RISCV_FSGNJ_S = 377, + RISCV_FSQRT_D = 378, + RISCV_FSQRT_S = 379, + RISCV_FSUB_D = 380, + RISCV_FSUB_S = 381, + RISCV_FSW = 382, + RISCV_JAL = 383, + RISCV_JALR = 384, + RISCV_LB = 385, + RISCV_LBU = 386, + RISCV_LD = 387, + RISCV_LH = 388, + RISCV_LHU = 389, + RISCV_LR_D = 390, + RISCV_LR_D_AQ = 391, + RISCV_LR_D_AQ_RL = 392, + RISCV_LR_D_RL = 393, + RISCV_LR_W = 394, + RISCV_LR_W_AQ = 395, + RISCV_LR_W_AQ_RL = 396, + RISCV_LR_W_RL = 397, + RISCV_LUI = 398, + RISCV_LW = 399, + RISCV_LWU = 400, + RISCV_MRET = 401, + RISCV_MUL = 402, + RISCV_MULH = 403, + RISCV_MULHSU = 404, + RISCV_MULHU = 405, + RISCV_MULW = 406, + RISCV_OR = 407, + RISCV_ORI = 408, + RISCV_REM = 409, + RISCV_REMU = 410, + RISCV_REMUW = 411, + RISCV_REMW = 412, + RISCV_SB = 413, + RISCV_SC_D = 414, + RISCV_SC_D_AQ = 415, + RISCV_SC_D_AQ_RL = 416, + RISCV_SC_D_RL = 417, + RISCV_SC_W = 418, + RISCV_SC_W_AQ = 419, + RISCV_SC_W_AQ_RL = 420, + RISCV_SC_W_RL = 421, + RISCV_SD = 422, + RISCV_SFENCE_VMA = 423, + RISCV_SH = 424, + RISCV_SLL = 425, + RISCV_SLLI = 426, + RISCV_SLLIW = 427, + RISCV_SLLW = 428, + RISCV_SLT = 429, + RISCV_SLTI = 430, + RISCV_SLTIU = 431, + RISCV_SLTU = 432, + RISCV_SRA = 433, + RISCV_SRAI = 434, + RISCV_SRAIW = 435, + RISCV_SRAW = 436, + RISCV_SRET = 437, + RISCV_SRL = 438, + RISCV_SRLI = 439, + RISCV_SRLIW = 440, + RISCV_SRLW = 441, + RISCV_SUB = 442, + RISCV_SUBW = 443, + RISCV_SW = 444, + RISCV_UNIMP = 445, + RISCV_URET = 446, + RISCV_WFI = 447, + RISCV_XOR = 448, + RISCV_XORI = 449, + RISCV_INSTRUCTION_LIST_END = 450 + }; + +#endif // GET_INSTRINFO_ENUM diff --git a/arch/RISCV/RISCVGenRegisterInfo.inc b/arch/RISCV/RISCVGenRegisterInfo.inc new file mode 100644 index 000000000..2b7446791 --- /dev/null +++ b/arch/RISCV/RISCVGenRegisterInfo.inc @@ -0,0 +1,426 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Target Register Enum Values *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2015 */ + + +#ifdef GET_REGINFO_ENUM +#undef GET_REGINFO_ENUM + +enum { + RISCV_NoRegister, + RISCV_X0 = 1, + RISCV_X1 = 2, + RISCV_X2 = 3, + RISCV_X3 = 4, + RISCV_X4 = 5, + RISCV_X5 = 6, + RISCV_X6 = 7, + RISCV_X7 = 8, + RISCV_X8 = 9, + RISCV_X9 = 10, + RISCV_X10 = 11, + RISCV_X11 = 12, + RISCV_X12 = 13, + RISCV_X13 = 14, + RISCV_X14 = 15, + RISCV_X15 = 16, + RISCV_X16 = 17, + RISCV_X17 = 18, + RISCV_X18 = 19, + RISCV_X19 = 20, + RISCV_X20 = 21, + RISCV_X21 = 22, + RISCV_X22 = 23, + RISCV_X23 = 24, + RISCV_X24 = 25, + RISCV_X25 = 26, + RISCV_X26 = 27, + RISCV_X27 = 28, + RISCV_X28 = 29, + RISCV_X29 = 30, + RISCV_X30 = 31, + RISCV_X31 = 32, + RISCV_F0_32 = 33, + RISCV_F0_64 = 34, + RISCV_F1_32 = 35, + RISCV_F1_64 = 36, + RISCV_F2_32 = 37, + RISCV_F2_64 = 38, + RISCV_F3_32 = 39, + RISCV_F3_64 = 40, + RISCV_F4_32 = 41, + RISCV_F4_64 = 42, + RISCV_F5_32 = 43, + RISCV_F5_64 = 44, + RISCV_F6_32 = 45, + RISCV_F6_64 = 46, + RISCV_F7_32 = 47, + RISCV_F7_64 = 48, + RISCV_F8_32 = 49, + RISCV_F8_64 = 50, + RISCV_F9_32 = 51, + RISCV_F9_64 = 52, + RISCV_F10_32 = 53, + RISCV_F10_64 = 54, + RISCV_F11_32 = 55, + RISCV_F11_64 = 56, + RISCV_F12_32 = 57, + RISCV_F12_64 = 58, + RISCV_F13_32 = 59, + RISCV_F13_64 = 60, + RISCV_F14_32 = 61, + RISCV_F14_64 = 62, + RISCV_F15_32 = 63, + RISCV_F15_64 = 64, + RISCV_F16_32 = 65, + RISCV_F16_64 = 66, + RISCV_F17_32 = 67, + RISCV_F17_64 = 68, + RISCV_F18_32 = 69, + RISCV_F18_64 = 70, + RISCV_F19_32 = 71, + RISCV_F19_64 = 72, + RISCV_F20_32 = 73, + RISCV_F20_64 = 74, + RISCV_F21_32 = 75, + RISCV_F21_64 = 76, + RISCV_F22_32 = 77, + RISCV_F22_64 = 78, + RISCV_F23_32 = 79, + RISCV_F23_64 = 80, + RISCV_F24_32 = 81, + RISCV_F24_64 = 82, + RISCV_F25_32 = 83, + RISCV_F25_64 = 84, + RISCV_F26_32 = 85, + RISCV_F26_64 = 86, + RISCV_F27_32 = 87, + RISCV_F27_64 = 88, + RISCV_F28_32 = 89, + RISCV_F28_64 = 90, + RISCV_F29_32 = 91, + RISCV_F29_64 = 92, + RISCV_F30_32 = 93, + RISCV_F30_64 = 94, + RISCV_F31_32 = 95, + RISCV_F31_64 = 96, + RISCV_NUM_TARGET_REGS // 97 +}; + +// Register classes +enum { + RISCV_FPR32RegClassID = 0, + RISCV_GPRRegClassID = 1, + RISCV_GPRNoX0RegClassID = 2, + RISCV_GPRNoX0X2RegClassID = 3, + RISCV_GPRTCRegClassID = 4, + RISCV_FPR32CRegClassID = 5, + RISCV_GPRCRegClassID = 6, + RISCV_GPRC_and_GPRTCRegClassID = 7, + RISCV_SPRegClassID = 8, + RISCV_FPR64RegClassID = 9, + RISCV_FPR64CRegClassID = 10, +}; + +// Register alternate name indices + +enum { + RISCV_ABIRegAltName, // 0 + RISCV_NoRegAltName, // 1 + RISCV_NUM_TARGET_REG_ALT_NAMES = 2 +}; + +// Subregister indices + +enum { + RISCV_NoSubRegister, + RISCV_sub_32, // 1 + RISCV_NUM_TARGET_SUBREGS +}; +#endif // GET_REGINFO_ENUM + +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* MC Register Information *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + + +#ifdef GET_REGINFO_MC_DESC +#undef GET_REGINFO_MC_DESC + +static const MCPhysReg RISCVRegDiffLists[] = { + /* 0 */ 1, 0, + /* 2 */ 32, 0, + /* 4 */ 33, 0, + /* 6 */ 34, 0, + /* 8 */ 35, 0, + /* 10 */ 36, 0, + /* 12 */ 37, 0, + /* 14 */ 38, 0, + /* 16 */ 39, 0, + /* 18 */ 40, 0, + /* 20 */ 41, 0, + /* 22 */ 42, 0, + /* 24 */ 43, 0, + /* 26 */ 44, 0, + /* 28 */ 45, 0, + /* 30 */ 46, 0, + /* 32 */ 47, 0, + /* 34 */ 48, 0, + /* 36 */ 49, 0, + /* 38 */ 50, 0, + /* 40 */ 51, 0, + /* 42 */ 52, 0, + /* 44 */ 53, 0, + /* 46 */ 54, 0, + /* 48 */ 55, 0, + /* 50 */ 56, 0, + /* 52 */ 57, 0, + /* 54 */ 58, 0, + /* 56 */ 59, 0, + /* 58 */ 60, 0, + /* 60 */ 61, 0, + /* 62 */ 62, 0, + /* 64 */ 63, 0, + /* 66 */ 65535, 0, +}; + +static const uint16_t RISCVSubRegIdxLists[] = { + /* 0 */ 1, 0, +}; + +static const MCRegisterDesc RISCVRegDesc[] = { // Descriptors + { 3, 0, 0, 0, 0, 0 }, + { 12, 1, 1, 1, 1057, 0 }, + { 27, 1, 1, 1, 1057, 0 }, + { 252, 1, 1, 1, 1057, 0 }, + { 263, 1, 1, 1, 1057, 0 }, + { 488, 1, 1, 1, 1057, 0 }, + { 499, 1, 1, 1, 1057, 0 }, + { 510, 1, 1, 1, 1057, 0 }, + { 521, 1, 1, 1, 1057, 0 }, + { 532, 1, 1, 1, 1057, 0 }, + { 543, 1, 1, 1, 1057, 0 }, + { 0, 1, 1, 1, 1057, 0 }, + { 15, 1, 1, 1, 1057, 0 }, + { 30, 1, 1, 1, 1057, 0 }, + { 255, 1, 1, 1, 1057, 0 }, + { 266, 1, 1, 1, 1057, 0 }, + { 491, 1, 1, 1, 1057, 0 }, + { 502, 1, 1, 1, 1057, 0 }, + { 513, 1, 1, 1, 1057, 0 }, + { 524, 1, 1, 1, 1057, 0 }, + { 535, 1, 1, 1, 1057, 0 }, + { 4, 1, 1, 1, 1057, 0 }, + { 19, 1, 1, 1, 1057, 0 }, + { 34, 1, 1, 1, 1057, 0 }, + { 259, 1, 1, 1, 1057, 0 }, + { 270, 1, 1, 1, 1057, 0 }, + { 495, 1, 1, 1, 1057, 0 }, + { 506, 1, 1, 1, 1057, 0 }, + { 517, 1, 1, 1, 1057, 0 }, + { 528, 1, 1, 1, 1057, 0 }, + { 539, 1, 1, 1, 1057, 0 }, + { 8, 1, 1, 1, 1057, 0 }, + { 23, 1, 1, 1, 1057, 0 }, + { 59, 1, 0, 1, 32, 0 }, + { 295, 66, 1, 0, 32, 2 }, + { 86, 1, 0, 1, 64, 0 }, + { 322, 66, 1, 0, 64, 2 }, + { 106, 1, 0, 1, 96, 0 }, + { 342, 66, 1, 0, 96, 2 }, + { 126, 1, 0, 1, 128, 0 }, + { 362, 66, 1, 0, 128, 2 }, + { 146, 1, 0, 1, 160, 0 }, + { 382, 66, 1, 0, 160, 2 }, + { 166, 1, 0, 1, 192, 0 }, + { 402, 66, 1, 0, 192, 2 }, + { 186, 1, 0, 1, 224, 0 }, + { 422, 66, 1, 0, 224, 2 }, + { 206, 1, 0, 1, 256, 0 }, + { 442, 66, 1, 0, 256, 2 }, + { 226, 1, 0, 1, 288, 0 }, + { 462, 66, 1, 0, 288, 2 }, + { 246, 1, 0, 1, 320, 0 }, + { 482, 66, 1, 0, 320, 2 }, + { 38, 1, 0, 1, 352, 0 }, + { 274, 66, 1, 0, 352, 2 }, + { 65, 1, 0, 1, 384, 0 }, + { 301, 66, 1, 0, 384, 2 }, + { 92, 1, 0, 1, 416, 0 }, + { 328, 66, 1, 0, 416, 2 }, + { 112, 1, 0, 1, 448, 0 }, + { 348, 66, 1, 0, 448, 2 }, + { 132, 1, 0, 1, 480, 0 }, + { 368, 66, 1, 0, 480, 2 }, + { 152, 1, 0, 1, 512, 0 }, + { 388, 66, 1, 0, 512, 2 }, + { 172, 1, 0, 1, 544, 0 }, + { 408, 66, 1, 0, 544, 2 }, + { 192, 1, 0, 1, 576, 0 }, + { 428, 66, 1, 0, 576, 2 }, + { 212, 1, 0, 1, 608, 0 }, + { 448, 66, 1, 0, 608, 2 }, + { 232, 1, 0, 1, 640, 0 }, + { 468, 66, 1, 0, 640, 2 }, + { 45, 1, 0, 1, 672, 0 }, + { 281, 66, 1, 0, 672, 2 }, + { 72, 1, 0, 1, 704, 0 }, + { 308, 66, 1, 0, 704, 2 }, + { 99, 1, 0, 1, 736, 0 }, + { 335, 66, 1, 0, 736, 2 }, + { 119, 1, 0, 1, 768, 0 }, + { 355, 66, 1, 0, 768, 2 }, + { 139, 1, 0, 1, 800, 0 }, + { 375, 66, 1, 0, 800, 2 }, + { 159, 1, 0, 1, 832, 0 }, + { 395, 66, 1, 0, 832, 2 }, + { 179, 1, 0, 1, 864, 0 }, + { 415, 66, 1, 0, 864, 2 }, + { 199, 1, 0, 1, 896, 0 }, + { 435, 66, 1, 0, 896, 2 }, + { 219, 1, 0, 1, 928, 0 }, + { 455, 66, 1, 0, 928, 2 }, + { 239, 1, 0, 1, 960, 0 }, + { 475, 66, 1, 0, 960, 2 }, + { 52, 1, 0, 1, 992, 0 }, + { 288, 66, 1, 0, 992, 2 }, + { 79, 1, 0, 1, 1024, 0 }, + { 315, 66, 1, 0, 1024, 2 }, +}; + + // FPR32 Register Class... + static const MCPhysReg FPR32[] = { + RISCV_F0_32, RISCV_F1_32, RISCV_F2_32, RISCV_F3_32, RISCV_F4_32, RISCV_F5_32, RISCV_F6_32, RISCV_F7_32, RISCV_F10_32, RISCV_F11_32, RISCV_F12_32, RISCV_F13_32, RISCV_F14_32, RISCV_F15_32, RISCV_F16_32, RISCV_F17_32, RISCV_F28_32, RISCV_F29_32, RISCV_F30_32, RISCV_F31_32, RISCV_F8_32, RISCV_F9_32, RISCV_F18_32, RISCV_F19_32, RISCV_F20_32, RISCV_F21_32, RISCV_F22_32, RISCV_F23_32, RISCV_F24_32, RISCV_F25_32, RISCV_F26_32, RISCV_F27_32, + }; + + // FPR32 Bit set. + static const uint8_t FPR32Bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + }; + + // GPR Register Class... + static const MCPhysReg GPR[] = { + RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X16, RISCV_X17, RISCV_X5, RISCV_X6, RISCV_X7, RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31, RISCV_X8, RISCV_X9, RISCV_X18, RISCV_X19, RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23, RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27, RISCV_X0, RISCV_X1, RISCV_X2, RISCV_X3, RISCV_X4, + }; + + // GPR Bit set. + static const uint8_t GPRBits[] = { + 0xfe, 0xff, 0xff, 0xff, 0x01, + }; + + // GPRNoX0 Register Class... + static const MCPhysReg GPRNoX0[] = { + RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X16, RISCV_X17, RISCV_X5, RISCV_X6, RISCV_X7, RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31, RISCV_X8, RISCV_X9, RISCV_X18, RISCV_X19, RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23, RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27, RISCV_X1, RISCV_X2, RISCV_X3, RISCV_X4, + }; + + // GPRNoX0 Bit set. + static const uint8_t GPRNoX0Bits[] = { + 0xfc, 0xff, 0xff, 0xff, 0x01, + }; + + // GPRNoX0X2 Register Class... + static const MCPhysReg GPRNoX0X2[] = { + RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X16, RISCV_X17, RISCV_X5, RISCV_X6, RISCV_X7, RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31, RISCV_X8, RISCV_X9, RISCV_X18, RISCV_X19, RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23, RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27, RISCV_X1, RISCV_X3, RISCV_X4, + }; + + // GPRNoX0X2 Bit set. + static const uint8_t GPRNoX0X2Bits[] = { + 0xf4, 0xff, 0xff, 0xff, 0x01, + }; + + // GPRTC Register Class... + static const MCPhysReg GPRTC[] = { + RISCV_X5, RISCV_X6, RISCV_X7, RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X16, RISCV_X17, RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31, + }; + + // GPRTC Bit set. + static const uint8_t GPRTCBits[] = { + 0xc0, 0xf9, 0x07, 0xe0, 0x01, + }; + + // FPR32C Register Class... + static const MCPhysReg FPR32C[] = { + RISCV_F10_32, RISCV_F11_32, RISCV_F12_32, RISCV_F13_32, RISCV_F14_32, RISCV_F15_32, RISCV_F8_32, RISCV_F9_32, + }; + + // FPR32C Bit set. + static const uint8_t FPR32CBits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, + }; + + // GPRC Register Class... + static const MCPhysReg GPRC[] = { + RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, RISCV_X8, RISCV_X9, + }; + + // GPRC Bit set. + static const uint8_t GPRCBits[] = { + 0x00, 0xfe, 0x01, + }; + + // GPRC_and_GPRTC Register Class... + static const MCPhysReg GPRC_and_GPRTC[] = { + RISCV_X10, RISCV_X11, RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15, + }; + + // GPRC_and_GPRTC Bit set. + static const uint8_t GPRC_and_GPRTCBits[] = { + 0x00, 0xf8, 0x01, + }; + + // SP Register Class... + static const MCPhysReg SP[] = { + RISCV_X2, + }; + + // SP Bit set. + static const uint8_t SPBits[] = { + 0x08, + }; + + // FPR64 Register Class... + static const MCPhysReg FPR64[] = { + RISCV_F0_64, RISCV_F1_64, RISCV_F2_64, RISCV_F3_64, RISCV_F4_64, RISCV_F5_64, RISCV_F6_64, RISCV_F7_64, RISCV_F10_64, RISCV_F11_64, RISCV_F12_64, RISCV_F13_64, RISCV_F14_64, RISCV_F15_64, RISCV_F16_64, RISCV_F17_64, RISCV_F28_64, RISCV_F29_64, RISCV_F30_64, RISCV_F31_64, RISCV_F8_64, RISCV_F9_64, RISCV_F18_64, RISCV_F19_64, RISCV_F20_64, RISCV_F21_64, RISCV_F22_64, RISCV_F23_64, RISCV_F24_64, RISCV_F25_64, RISCV_F26_64, RISCV_F27_64, + }; + + // FPR64 Bit set. + static const uint8_t FPR64Bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, + }; + + // FPR64C Register Class... + static const MCPhysReg FPR64C[] = { + RISCV_F10_64, RISCV_F11_64, RISCV_F12_64, RISCV_F13_64, RISCV_F14_64, RISCV_F15_64, RISCV_F8_64, RISCV_F9_64, + }; + + // FPR64C Bit set. + static const uint8_t FPR64CBits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, + }; + +static const MCRegisterClass RISCVMCRegisterClasses[] = { + { FPR32, FPR32Bits, sizeof(FPR32Bits) }, + { GPR, GPRBits, sizeof(GPRBits) }, + { GPRNoX0, GPRNoX0Bits, sizeof(GPRNoX0Bits) }, + { GPRNoX0X2, GPRNoX0X2Bits, sizeof(GPRNoX0X2Bits) }, + { GPRTC, GPRTCBits, sizeof(GPRTCBits) }, + { FPR32C, FPR32CBits, sizeof(FPR32CBits) }, + { GPRC, GPRCBits, sizeof(GPRCBits) }, + { GPRC_and_GPRTC, GPRC_and_GPRTCBits, sizeof(GPRC_and_GPRTCBits) }, + { SP, SPBits, sizeof(SPBits) }, + { FPR64, FPR64Bits, sizeof(FPR64Bits) }, + { FPR64C, FPR64CBits, sizeof(FPR64CBits) }, +}; + +#endif // GET_REGINFO_MC_DESC diff --git a/arch/RISCV/RISCVGenSubtargetInfo.inc b/arch/RISCV/RISCVGenSubtargetInfo.inc new file mode 100644 index 000000000..c857ce6c1 --- /dev/null +++ b/arch/RISCV/RISCVGenSubtargetInfo.inc @@ -0,0 +1,33 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Subtarget Enumeration Source Fragment *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + +/* Capstone Disassembly Engine, http://www.capstone-engine.org */ +/* By Nguyen Anh Quynh , 2013-2015 */ + + +#ifdef GET_SUBTARGETINFO_ENUM +#undef GET_SUBTARGETINFO_ENUM + +/* + Make sure: + CS_MODE_RISCV64 = 0b11111 + CS_MODE_RISCV32 = 0b11110 +*/ + +enum { + RISCV_Feature64Bit = 1ULL << 0, + RISCV_FeatureStdExtA = 1ULL << 1, + RISCV_FeatureStdExtC = 1ULL << 2, + RISCV_FeatureStdExtD = 1ULL << 3, + RISCV_FeatureStdExtF = 1ULL << 4, + RISCV_FeatureStdExtM = 1ULL << 5, + RISCV_FeatureRelax = 1ULL << 6, +}; + +#endif // GET_SUBTARGETINFO_ENUM + diff --git a/arch/RISCV/RISCVInstPrinter.c b/arch/RISCV/RISCVInstPrinter.c new file mode 100644 index 000000000..eba3298b8 --- /dev/null +++ b/arch/RISCV/RISCVInstPrinter.c @@ -0,0 +1,204 @@ +//===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm syntax ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an RISCV MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifdef CAPSTONE_HAS_RISCV + +#include // DEBUG +#include +#include +#include + +#include "RISCVInstPrinter.h" +#include "RISCVBaseInfo.h" +#include "../../MCInst.h" +#include "../../SStream.h" +#include "../../MCRegisterInfo.h" +#include "../../utils.h" +#include "RISCVMapping.h" + +//#include "RISCVDisassembler.h" + +#define GET_REGINFO_ENUM +#define GET_REGINFO_MC_DESC +#include "RISCVGenRegisterInfo.inc" +#define GET_INSTRINFO_ENUM +#include "RISCVGenInstrInfo.inc" + +// Autogenerated by tblgen. +static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI); +static bool printAliasInstr(MCInst *MI, SStream *OS, void *info); +static void printOperand(MCInst *MI, unsigned OpNo, SStream *O); +static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O); +static void printCSRSystemRegister(const MCInst*, unsigned, SStream *); +static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O); +static void printCustomAliasOperand( MCInst *, unsigned, unsigned, SStream *); +/// getRegisterName - This method is automatically generated by tblgen +/// from the register set description. This returns the assembler name +/// for the specified register. +static const char *getRegisterName(unsigned RegNo, unsigned AltIdx); + +// Include the auto-generated portion of the assembly writer. +#define PRINT_ALIAS_INSTR +#include "RISCVGenAsmWriter.inc" + + +static void fixDetailOfEffectiveAddr(MCInst *MI) +{ + unsigned reg = 0; + int64_t imm = 0; + + assert(3 == MI->flat_insn->detail->riscv.op_count); + assert(RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[0].type); + + if (RISCV_OP_IMM == MI->flat_insn->detail->riscv.operands[1].type) { + assert(RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[2].type); + imm = MI->flat_insn->detail->riscv.operands[1].imm; + reg = MI->flat_insn->detail->riscv.operands[2].reg; + } else if (RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[1].type) { + assert(RISCV_OP_IMM == MI->flat_insn->detail->riscv.operands[2].type); + reg = MI->flat_insn->detail->riscv.operands[1].reg; + imm = MI->flat_insn->detail->riscv.operands[2].imm; + } + + // set up effective address. + MI->flat_insn->detail->riscv.operands[1].type = RISCV_OP_MEM; + MI->flat_insn->detail->riscv.op_count--; + MI->flat_insn->detail->riscv.operands[1].mem.base = reg; + MI->flat_insn->detail->riscv.operands[1].mem.disp = imm; + + return; +} + + +//void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O, +// StringRef Annot, const MCSubtargetInfo &STI) +void RISCV_printInst(MCInst *MI, SStream *O, void *info) +{ + MCRegisterInfo *MRI = (MCRegisterInfo *) info; + //bool Res = false; + //MCInst *NewMI = MI; + // TODO: RISCV compressd instructions. + //MCInst UncompressedMI; + //if (!NoAliases) + //Res = uncompressInst(UncompressedMI, *MI, MRI, STI); + //if (Res) + //NewMI = const_cast(&UncompressedMI); + if (/*NoAliases ||*/ !printAliasInstr(MI, O, info)) + printInstruction(MI, O, MRI); + //printAnnotation(O, Annot); + // fix load/store type insttuction + if (MI->csh->detail && + MI->flat_insn->detail->riscv.need_effective_addr) + fixDetailOfEffectiveAddr(MI); + + return; +} + +static void printRegName(SStream *OS, unsigned RegNo) +{ + SStream_concat0(OS, getRegisterName(RegNo, RISCV_ABIRegAltName)); +} + +/** +void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier) +*/ +static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) +{ + unsigned reg; + int64_t Imm = 0; + + MCOperand *MO = MCInst_getOperand(MI, OpNo); + + if (MCOperand_isReg(MO)) { + reg = MCOperand_getReg(MO); + printRegName(O, reg); + if (MI->csh->detail) { + MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].type = RISCV_OP_REG; + MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].reg = reg; + MI->flat_insn->detail->riscv.op_count++; + } + } else { + assert(MCOperand_isImm(MO) && "Unknown operand kind in printOperand"); + Imm = MCOperand_getImm(MO); + if (Imm >= 0) { + if (Imm > HEX_THRESHOLD) + SStream_concat(O, "0x%" PRIx64, Imm); + else + SStream_concat(O, "%" PRIu64, Imm); + } else { + if (Imm < -HEX_THRESHOLD) + SStream_concat(O, "-0x%" PRIx64, -Imm); + else + SStream_concat(O, "-%" PRIu64, -Imm); + } + + if (MI->csh->detail) { + MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].type = RISCV_OP_IMM; + MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].imm = Imm; + MI->flat_insn->detail->riscv.op_count++; + } + } + + //assert(MO.isExpr() && "Unknown operand kind in printOperand"); + + return; +} + +static void printCSRSystemRegister(const MCInst *MI, unsigned OpNo, + //const MCSubtargetInfo &STI, + SStream *O) +{ + // TODO: Not yeat implementated. + return; + //assert (0 && "CSR system register hav't support."); +#if 0 + unsigned Imm = MI->getOperand(OpNo).getImm(); + auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); + if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits())) + O << SysReg->Name; + else + O << Imm; +#endif +} + +static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O) +{ + unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, OpNo)); + //assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); + + if ((FenceArg & RISCVFenceField_I) != 0) + SStream_concat0(O, "i"); + if ((FenceArg & RISCVFenceField_O) != 0) + SStream_concat0(O, "o"); + if ((FenceArg & RISCVFenceField_R) != 0) + SStream_concat0(O, "r"); + if ((FenceArg & RISCVFenceField_W) != 0) + SStream_concat0(O, "w"); + if (FenceArg == 0) + SStream_concat0(O, "unknown"); +} + +static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O) +{ + enum RoundingMode FRMArg = + (enum RoundingMode)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); +#if 0 + auto FRMArg = + static_cast(MI->getOperand(OpNo).getImm()); + O << RISCVFPRndMode::roundingModeToString(FRMArg); +#endif + SStream_concat0(O, roundingModeToString(FRMArg)); +} + +#endif // CAPSTONE_HAS_RISCV diff --git a/arch/RISCV/RISCVInstPrinter.h b/arch/RISCV/RISCVInstPrinter.h new file mode 100644 index 000000000..466c3f86d --- /dev/null +++ b/arch/RISCV/RISCVInstPrinter.h @@ -0,0 +1,24 @@ +//===-- RISCVInstPrinter.h - Convert RISCV MCInst to asm syntax ---*- C++ -*--// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints a RISCV MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef CS_RISCVINSTPRINTER_H +#define CS_RISCVINSTPRINTER_H + +#include "../../MCInst.h" +#include "../../SStream.h" + +void RISCV_printInst(MCInst * MI, SStream * O, void *info); + +void RISCV_post_printer(csh ud, cs_insn * insn, char *insn_asm, MCInst * mci); + +#endif diff --git a/arch/RISCV/RISCVMapping.c b/arch/RISCV/RISCVMapping.c new file mode 100644 index 000000000..da3b5c915 --- /dev/null +++ b/arch/RISCV/RISCVMapping.c @@ -0,0 +1,359 @@ + +#ifdef CAPSTONE_HAS_RISCV + +#include // debug +#include + +#include "../../utils.h" + +#include "RISCVMapping.h" +#include "RISCVInstPrinter.h" + +#define GET_INSTRINFO_ENUM +#include "RISCVGenInstrInfo.inc" + +#ifndef CAPSTONE_DIET +static const name_map reg_name_maps[] = { + {RISCV_REG_INVALID, NULL}, + + {RISCV_REG_X0, "zero"}, + {RISCV_REG_X1, "ra"}, + {RISCV_REG_X2, "sp"}, + {RISCV_REG_X3, "gp"}, + {RISCV_REG_X4, "tp"}, + {RISCV_REG_X5, "t0"}, + {RISCV_REG_X6, "t1"}, + {RISCV_REG_X7, "t2"}, + {RISCV_REG_X8, "s0"}, + {RISCV_REG_X9, "s1"}, + {RISCV_REG_X10, "a0"}, + {RISCV_REG_X11, "a1"}, + {RISCV_REG_X12, "a2"}, + {RISCV_REG_X13, "a3"}, + {RISCV_REG_X14, "a4"}, + {RISCV_REG_X15, "a5"}, + {RISCV_REG_X16, "a6"}, + {RISCV_REG_X17, "a7"}, + {RISCV_REG_X18, "s2"}, + {RISCV_REG_X19, "s3"}, + {RISCV_REG_X20, "s4"}, + {RISCV_REG_X21, "s5"}, + {RISCV_REG_X22, "s6"}, + {RISCV_REG_X23, "s7"}, + {RISCV_REG_X24, "s8"}, + {RISCV_REG_X25, "s9"}, + {RISCV_REG_X26, "s10"}, + {RISCV_REG_X27, "s11"}, + {RISCV_REG_X28, "t3"}, + {RISCV_REG_X29, "t4"}, + {RISCV_REG_X30, "t5"}, + {RISCV_REG_X31, "t6"}, + + {RISCV_REG_F0_32, "ft0"}, + {RISCV_REG_F0_64, "ft0"}, + {RISCV_REG_F1_32, "ft1"}, + {RISCV_REG_F1_64, "ft1"}, + {RISCV_REG_F2_32, "ft2"}, + {RISCV_REG_F2_64, "ft2"}, + {RISCV_REG_F3_32, "ft3"}, + {RISCV_REG_F3_64, "ft3"}, + {RISCV_REG_F4_32, "ft4"}, + {RISCV_REG_F4_64, "ft4"}, + {RISCV_REG_F5_32, "ft5"}, + {RISCV_REG_F5_64, "ft5"}, + {RISCV_REG_F6_32, "ft6"}, + {RISCV_REG_F6_64, "ft6"}, + {RISCV_REG_F7_32, "ft7"}, + {RISCV_REG_F7_64, "ft7"}, + {RISCV_REG_F8_32, "fs0"}, + {RISCV_REG_F8_64, "fs0"}, + {RISCV_REG_F9_32, "fs1"}, + {RISCV_REG_F9_64, "fs1"}, + {RISCV_REG_F10_32, "fa0"}, + {RISCV_REG_F10_64, "fa0"}, + {RISCV_REG_F11_32, "fa1"}, + {RISCV_REG_F11_64, "fa1"}, + {RISCV_REG_F12_32, "fa2"}, + {RISCV_REG_F12_64, "fa2"}, + {RISCV_REG_F13_32, "fa3"}, + {RISCV_REG_F13_64, "fa3"}, + {RISCV_REG_F14_32, "fa4"}, + {RISCV_REG_F14_64, "fa4"}, + {RISCV_REG_F15_32, "fa5"}, + {RISCV_REG_F15_64, "fa5"}, + {RISCV_REG_F16_32, "fa6"}, + {RISCV_REG_F16_64, "fa6"}, + {RISCV_REG_F17_32, "fa7"}, + {RISCV_REG_F17_64, "fa7"}, + {RISCV_REG_F18_32, "fs2"}, + {RISCV_REG_F18_64, "fs2"}, + {RISCV_REG_F19_32, "fs3"}, + {RISCV_REG_F19_64, "fs3"}, + {RISCV_REG_F20_32, "fs4"}, + {RISCV_REG_F20_64, "fs4"}, + {RISCV_REG_F21_32, "fs5"}, + {RISCV_REG_F21_64, "fs5"}, + {RISCV_REG_F22_32, "fs6"}, + {RISCV_REG_F22_64, "fs6"}, + {RISCV_REG_F23_32, "fs7"}, + {RISCV_REG_F23_64, "fs7"}, + {RISCV_REG_F24_32, "fs8"}, + {RISCV_REG_F24_64, "fs8"}, + {RISCV_REG_F25_32, "fs9"}, + {RISCV_REG_F25_64, "fs9"}, + {RISCV_REG_F26_32, "fs10"}, + {RISCV_REG_F26_64, "fs10"}, + {RISCV_REG_F27_32, "fs11"}, + {RISCV_REG_F27_64, "fs11"}, + {RISCV_REG_F28_32, "ft8"}, + {RISCV_REG_F28_64, "ft8"}, + {RISCV_REG_F29_32, "ft9"}, + {RISCV_REG_F29_64, "ft9"}, + {RISCV_REG_F30_32, "ft10"}, + {RISCV_REG_F30_64, "ft10"}, + {RISCV_REG_F31_32, "ft11"}, + {RISCV_REG_F31_64, "ft11"}, +}; +#endif + +const char *RISCV_reg_name(csh handle, unsigned int reg) +{ +#ifndef CAPSTONE_DIET + if (reg >= RISCV_REG_ENDING) + return NULL; + return reg_name_maps[reg].name; +#else + return NULL; +#endif +} + +static const insn_map insns[] = { + // dummy item + { + 0, 0, +#ifndef CAPSTONE_DIET + {0}, {0}, {0}, 0, 0 +#endif + }, + +#include "RISCVMappingInsn.inc" +}; + +// given internal insn id, return public instruction info +void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id) +{ + unsigned int i; + + i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); + if (i != 0) { + insn->id = insns[i].mapid; + + if (h->detail) { +#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] = RISCV_GRP_JUMP; + insn->detail->groups_count++; + } +#endif + } + } +} + +static const name_map insn_name_maps[] = { + {RISCV_INS_INVALID, NULL}, + +#include "RISCVGenInsnNameMaps.inc" +}; + +const char *RISCV_insn_name(csh handle, unsigned int id) +{ +#ifndef CAPSTONE_DIET + if (id >= RISCV_INS_ENDING) + return NULL; + + return insn_name_maps[id].name; +#else + return NULL; +#endif +} + +#ifndef CAPSTONE_DIET +static const name_map group_name_maps[] = { + {RISCV_GRP_INVALID, NULL}, + {RISCV_GRP_JUMP, "jump" }, + + // architecture specific + {RISCV_GRP_ISRV32, "isrv32"}, + {RISCV_GRP_ISRV64, "isrv64"}, + {RISCV_GRP_HASSTDEXTA, "hasStdExtA"}, + {RISCV_GRP_HASSTDEXTC, "hasStdExtC"}, + {RISCV_GRP_HASSTDEXTD, "hasStdExtD"}, + {RISCV_GRP_HASSTDEXTF, "hasStdExtF"}, + {RISCV_GRP_HASSTDEXTM, "hasStdExtM"}, + + /* + {RISCV_GRP_ISRVA, "isrva"}, + {RISCV_GRP_ISRVC, "isrvc"}, + {RISCV_GRP_ISRVD, "isrvd"}, + {RISCV_GRP_ISRVCD, "isrvcd"}, + {RISCV_GRP_ISRVF, "isrvf"}, + {RISCV_GRP_ISRV32C, "isrv32c"}, + {RISCV_GRP_ISRV32CF, "isrv32cf"}, + {RISCV_GRP_ISRVM, "isrvm"}, + {RISCV_GRP_ISRV64A, "isrv64a"}, + {RISCV_GRP_ISRV64C, "isrv64c"}, + {RISCV_GRP_ISRV64D, "isrv64d"}, + {RISCV_GRP_ISRV64F, "isrv64f"}, + {RISCV_GRP_ISRV64M, "isrv64m"} + */ + {RISCV_GRP_ENDING, NULL} +}; +#endif + +const char *RISCV_group_name(csh handle, unsigned int id) +{ +#ifndef CAPSTONE_DIET + // verify group id + if (id >= RISCV_GRP_ENDING || + (id > RISCV_GRP_JUMP && id < RISCV_GRP_ISRV32)) + return NULL; + return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); +#else + return NULL; +#endif +} + +// map instruction name to public instruction ID +riscv_reg RISCV_map_insn(const char *name) +{ + // handle special alias first + unsigned int i; + + // NOTE: skip first NULL name in insn_name_maps + i = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name); + + return (i != -1) ? i : RISCV_REG_INVALID; +} + +// map internal raw register to 'public' register +riscv_reg RISCV_map_register(unsigned int r) +{ + static const unsigned int map[] = { 0, + RISCV_REG_X0, + RISCV_REG_X1, + RISCV_REG_X2, + RISCV_REG_X3, + RISCV_REG_X4, + RISCV_REG_X5, + RISCV_REG_X6, + RISCV_REG_X7, + RISCV_REG_X8, + RISCV_REG_X9, + RISCV_REG_X10, + RISCV_REG_X11, + RISCV_REG_X12, + RISCV_REG_X13, + RISCV_REG_X14, + RISCV_REG_X15, + RISCV_REG_X16, + RISCV_REG_X17, + RISCV_REG_X18, + RISCV_REG_X19, + RISCV_REG_X20, + RISCV_REG_X21, + RISCV_REG_X22, + RISCV_REG_X23, + RISCV_REG_X24, + RISCV_REG_X25, + RISCV_REG_X26, + RISCV_REG_X27, + RISCV_REG_X28, + RISCV_REG_X29, + RISCV_REG_X30, + RISCV_REG_X31, + + RISCV_REG_F0_32, + RISCV_REG_F0_64, + RISCV_REG_F1_32, + RISCV_REG_F1_64, + RISCV_REG_F2_32, + RISCV_REG_F2_64, + RISCV_REG_F3_32, + RISCV_REG_F3_64, + RISCV_REG_F4_32, + RISCV_REG_F4_64, + RISCV_REG_F5_32, + RISCV_REG_F5_64, + RISCV_REG_F6_32, + RISCV_REG_F6_64, + RISCV_REG_F7_32, + RISCV_REG_F7_64, + RISCV_REG_F8_32, + RISCV_REG_F8_64, + RISCV_REG_F9_32, + RISCV_REG_F9_64, + RISCV_REG_F10_32, + RISCV_REG_F10_64, + RISCV_REG_F11_32, + RISCV_REG_F11_64, + RISCV_REG_F12_32, + RISCV_REG_F12_64, + RISCV_REG_F13_32, + RISCV_REG_F13_64, + RISCV_REG_F14_32, + RISCV_REG_F14_64, + RISCV_REG_F15_32, + RISCV_REG_F15_64, + RISCV_REG_F16_32, + RISCV_REG_F16_64, + RISCV_REG_F17_32, + RISCV_REG_F17_64, + RISCV_REG_F18_32, + RISCV_REG_F18_64, + RISCV_REG_F19_32, + RISCV_REG_F19_64, + RISCV_REG_F20_32, + RISCV_REG_F20_64, + RISCV_REG_F21_32, + RISCV_REG_F21_64, + RISCV_REG_F22_32, + RISCV_REG_F22_64, + RISCV_REG_F23_32, + RISCV_REG_F23_64, + RISCV_REG_F24_32, + RISCV_REG_F24_64, + RISCV_REG_F25_32, + RISCV_REG_F25_64, + RISCV_REG_F26_32, + RISCV_REG_F26_64, + RISCV_REG_F27_32, + RISCV_REG_F27_64, + RISCV_REG_F28_32, + RISCV_REG_F28_64, + RISCV_REG_F29_32, + RISCV_REG_F29_64, + RISCV_REG_F30_32, + RISCV_REG_F30_64, + RISCV_REG_F31_32, + RISCV_REG_F31_64, + }; + + if (r < ARR_SIZE(map)) + return map[r]; + + // cannot find this register + return 0; +} + +#endif diff --git a/arch/RISCV/RISCVMapping.h b/arch/RISCV/RISCVMapping.h new file mode 100644 index 000000000..c592e7fb5 --- /dev/null +++ b/arch/RISCV/RISCVMapping.h @@ -0,0 +1,22 @@ + +#ifndef CS_RISCV_MAP_H +#define CS_RISCV_MAP_H + +#include "../../include/capstone/capstone.h" + +// given internal insn id, return public instruction info +void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id); + +const char *RISCV_insn_name(csh handle, unsigned int id); + +const char *RISCV_group_name(csh handle, unsigned int id); + +const char *RISCV_reg_name(csh handle, unsigned int reg); + +// map instruction name to instruction ID +riscv_reg RISCV_map_insn(const char *name); + +// map internal raw register to 'public' register +riscv_reg RISCV_map_register(unsigned int r); + +#endif diff --git a/arch/RISCV/RISCVMappingInsn.inc b/arch/RISCV/RISCVMappingInsn.inc new file mode 100644 index 000000000..6789c0b79 --- /dev/null +++ b/arch/RISCV/RISCVMappingInsn.inc @@ -0,0 +1,1635 @@ +// This is auto-gen data for Capstone engine (www.capstone-engine.org) +// By Nguyen Anh Quynh + +{ + RISCV_ADD, RISCV_INS_ADD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_ADDI, RISCV_INS_ADDI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_ADDIW, RISCV_INS_ADDIW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_ADDW, RISCV_INS_ADDW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_D, RISCV_INS_AMOADD_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_D_AQ, RISCV_INS_AMOADD_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_D_AQ_RL, RISCV_INS_AMOADD_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_D_RL, RISCV_INS_AMOADD_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_W, RISCV_INS_AMOADD_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_W_AQ, RISCV_INS_AMOADD_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_W_AQ_RL, RISCV_INS_AMOADD_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOADD_W_RL, RISCV_INS_AMOADD_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_D, RISCV_INS_AMOAND_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_D_AQ, RISCV_INS_AMOAND_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_D_AQ_RL, RISCV_INS_AMOAND_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_D_RL, RISCV_INS_AMOAND_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_W, RISCV_INS_AMOAND_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_W_AQ, RISCV_INS_AMOAND_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_W_AQ_RL, RISCV_INS_AMOAND_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOAND_W_RL, RISCV_INS_AMOAND_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_D, RISCV_INS_AMOMAXU_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_D_AQ, RISCV_INS_AMOMAXU_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_D_AQ_RL, RISCV_INS_AMOMAXU_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_D_RL, RISCV_INS_AMOMAXU_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_W, RISCV_INS_AMOMAXU_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_W_AQ, RISCV_INS_AMOMAXU_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_W_AQ_RL, RISCV_INS_AMOMAXU_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAXU_W_RL, RISCV_INS_AMOMAXU_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_D, RISCV_INS_AMOMAX_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_D_AQ, RISCV_INS_AMOMAX_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_D_AQ_RL, RISCV_INS_AMOMAX_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_D_RL, RISCV_INS_AMOMAX_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_W, RISCV_INS_AMOMAX_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_W_AQ, RISCV_INS_AMOMAX_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_W_AQ_RL, RISCV_INS_AMOMAX_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMAX_W_RL, RISCV_INS_AMOMAX_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_D, RISCV_INS_AMOMINU_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_D_AQ, RISCV_INS_AMOMINU_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_D_AQ_RL, RISCV_INS_AMOMINU_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_D_RL, RISCV_INS_AMOMINU_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_W, RISCV_INS_AMOMINU_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_W_AQ, RISCV_INS_AMOMINU_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_W_AQ_RL, RISCV_INS_AMOMINU_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMINU_W_RL, RISCV_INS_AMOMINU_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_D, RISCV_INS_AMOMIN_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_D_AQ, RISCV_INS_AMOMIN_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_D_AQ_RL, RISCV_INS_AMOMIN_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_D_RL, RISCV_INS_AMOMIN_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_W, RISCV_INS_AMOMIN_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_W_AQ, RISCV_INS_AMOMIN_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_W_AQ_RL, RISCV_INS_AMOMIN_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOMIN_W_RL, RISCV_INS_AMOMIN_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_D, RISCV_INS_AMOOR_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_D_AQ, RISCV_INS_AMOOR_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_D_AQ_RL, RISCV_INS_AMOOR_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_D_RL, RISCV_INS_AMOOR_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_W, RISCV_INS_AMOOR_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_W_AQ, RISCV_INS_AMOOR_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_W_AQ_RL, RISCV_INS_AMOOR_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOOR_W_RL, RISCV_INS_AMOOR_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_D, RISCV_INS_AMOSWAP_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_D_AQ, RISCV_INS_AMOSWAP_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_D_AQ_RL, RISCV_INS_AMOSWAP_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_D_RL, RISCV_INS_AMOSWAP_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_W, RISCV_INS_AMOSWAP_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_W_AQ, RISCV_INS_AMOSWAP_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_W_AQ_RL, RISCV_INS_AMOSWAP_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOSWAP_W_RL, RISCV_INS_AMOSWAP_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_D, RISCV_INS_AMOXOR_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_D_AQ, RISCV_INS_AMOXOR_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_D_AQ_RL, RISCV_INS_AMOXOR_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_D_RL, RISCV_INS_AMOXOR_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_W, RISCV_INS_AMOXOR_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_W_AQ, RISCV_INS_AMOXOR_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_W_AQ_RL, RISCV_INS_AMOXOR_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AMOXOR_W_RL, RISCV_INS_AMOXOR_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_AND, RISCV_INS_AND, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_ANDI, RISCV_INS_ANDI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_AUIPC, RISCV_INS_AUIPC, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_BEQ, RISCV_INS_BEQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_BGE, RISCV_INS_BGE, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_BGEU, RISCV_INS_BGEU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_BLT, RISCV_INS_BLT, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_BLTU, RISCV_INS_BLTU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_BNE, RISCV_INS_BNE, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 1, 0 +#endif +}, +{ + RISCV_CSRRC, RISCV_INS_CSRRC, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_CSRRCI, RISCV_INS_CSRRCI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_CSRRS, RISCV_INS_CSRRS, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_CSRRSI, RISCV_INS_CSRRSI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_CSRRW, RISCV_INS_CSRRW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_CSRRWI, RISCV_INS_CSRRWI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADD, RISCV_INS_C_ADD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADDI, RISCV_INS_C_ADDI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADDI16SP, RISCV_INS_C_ADDI16SP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADDI4SPN, RISCV_INS_C_ADDI4SPN, +#ifndef CAPSTONE_DIET + { RISCV_REG_X2, 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADDIW, RISCV_INS_C_ADDIW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ADDW, RISCV_INS_C_ADDW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_AND, RISCV_INS_C_AND, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_ANDI, RISCV_INS_C_ANDI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_BEQZ, RISCV_INS_C_BEQZ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 1, 0 +#endif +}, +{ + RISCV_C_BNEZ, RISCV_INS_C_BNEZ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 1, 0 +#endif +}, +{ + RISCV_C_EBREAK, RISCV_INS_C_EBREAK, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FLD, RISCV_INS_C_FLD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FLDSP, RISCV_INS_C_FLDSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FLW, RISCV_INS_C_FLW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV32, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FLWSP, RISCV_INS_C_FLWSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV32, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FSD, RISCV_INS_C_FSD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FSDSP, RISCV_INS_C_FSDSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FSW, RISCV_INS_C_FSW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV32, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_FSWSP, RISCV_INS_C_FSWSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV32, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_J, RISCV_INS_C_J, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 1, 0 +#endif +}, +{ + RISCV_C_JAL, RISCV_INS_C_JAL, +#ifndef CAPSTONE_DIET + { 0 }, { RISCV_REG_X1, 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV32, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_JALR, RISCV_INS_C_JALR, +#ifndef CAPSTONE_DIET + { 0 }, { RISCV_REG_X1, 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_JR, RISCV_INS_C_JR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 1, 1 +#endif +}, +{ + RISCV_C_LD, RISCV_INS_C_LD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_LDSP, RISCV_INS_C_LDSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_LI, RISCV_INS_C_LI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_LUI, RISCV_INS_C_LUI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_LW, RISCV_INS_C_LW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_LWSP, RISCV_INS_C_LWSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_MV, RISCV_INS_C_MV, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_NOP, RISCV_INS_C_NOP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_OR, RISCV_INS_C_OR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SD, RISCV_INS_C_SD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SDSP, RISCV_INS_C_SDSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SLLI, RISCV_INS_C_SLLI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SRAI, RISCV_INS_C_SRAI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SRLI, RISCV_INS_C_SRLI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SUB, RISCV_INS_C_SUB, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SUBW, RISCV_INS_C_SUBW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SW, RISCV_INS_C_SW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_SWSP, RISCV_INS_C_SWSP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_UNIMP, RISCV_INS_C_UNIMP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_C_XOR, RISCV_INS_C_XOR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTC, 0 }, 0, 0 +#endif +}, +{ + RISCV_DIV, RISCV_INS_DIV, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_DIVU, RISCV_INS_DIVU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_DIVUW, RISCV_INS_DIVUW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_DIVW, RISCV_INS_DIVW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_EBREAK, RISCV_INS_EBREAK, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_ECALL, RISCV_INS_ECALL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_FADD_D, RISCV_INS_FADD_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FADD_S, RISCV_INS_FADD_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCLASS_D, RISCV_INS_FCLASS_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCLASS_S, RISCV_INS_FCLASS_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_D_L, RISCV_INS_FCVT_D_L, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_D_LU, RISCV_INS_FCVT_D_LU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_D_S, RISCV_INS_FCVT_D_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_D_W, RISCV_INS_FCVT_D_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_D_WU, RISCV_INS_FCVT_D_WU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_LU_D, RISCV_INS_FCVT_LU_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_LU_S, RISCV_INS_FCVT_LU_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_L_D, RISCV_INS_FCVT_L_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_L_S, RISCV_INS_FCVT_L_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_S_D, RISCV_INS_FCVT_S_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_S_L, RISCV_INS_FCVT_S_L, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_S_LU, RISCV_INS_FCVT_S_LU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_S_W, RISCV_INS_FCVT_S_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_S_WU, RISCV_INS_FCVT_S_WU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_WU_D, RISCV_INS_FCVT_WU_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_WU_S, RISCV_INS_FCVT_WU_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_W_D, RISCV_INS_FCVT_W_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FCVT_W_S, RISCV_INS_FCVT_W_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FDIV_D, RISCV_INS_FDIV_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FDIV_S, RISCV_INS_FDIV_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FENCE, RISCV_INS_FENCE, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_FENCE_I, RISCV_INS_FENCE_I, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_FENCE_TSO, RISCV_INS_FENCE_TSO, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_FEQ_D, RISCV_INS_FEQ_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FEQ_S, RISCV_INS_FEQ_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLD, RISCV_INS_FLD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLE_D, RISCV_INS_FLE_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLE_S, RISCV_INS_FLE_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLT_D, RISCV_INS_FLT_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLT_S, RISCV_INS_FLT_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FLW, RISCV_INS_FLW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMADD_D, RISCV_INS_FMADD_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMADD_S, RISCV_INS_FMADD_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMAX_D, RISCV_INS_FMAX_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMAX_S, RISCV_INS_FMAX_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMIN_D, RISCV_INS_FMIN_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMIN_S, RISCV_INS_FMIN_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMSUB_D, RISCV_INS_FMSUB_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMSUB_S, RISCV_INS_FMSUB_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMUL_D, RISCV_INS_FMUL_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMUL_S, RISCV_INS_FMUL_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMV_D_X, RISCV_INS_FMV_D_X, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMV_W_X, RISCV_INS_FMV_W_X, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMV_X_D, RISCV_INS_FMV_X_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_FMV_X_W, RISCV_INS_FMV_X_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FNMADD_D, RISCV_INS_FNMADD_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FNMADD_S, RISCV_INS_FNMADD_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FNMSUB_D, RISCV_INS_FNMSUB_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FNMSUB_S, RISCV_INS_FNMSUB_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSD, RISCV_INS_FSD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJN_D, RISCV_INS_FSGNJN_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJN_S, RISCV_INS_FSGNJN_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJX_D, RISCV_INS_FSGNJX_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJX_S, RISCV_INS_FSGNJX_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJ_D, RISCV_INS_FSGNJ_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSGNJ_S, RISCV_INS_FSGNJ_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSQRT_D, RISCV_INS_FSQRT_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSQRT_S, RISCV_INS_FSQRT_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSUB_D, RISCV_INS_FSUB_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTD, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSUB_S, RISCV_INS_FSUB_S, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_FSW, RISCV_INS_FSW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTF, 0 }, 0, 0 +#endif +}, +{ + RISCV_JAL, RISCV_INS_JAL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_JALR, RISCV_INS_JALR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LB, RISCV_INS_LB, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LBU, RISCV_INS_LBU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LD, RISCV_INS_LD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_LH, RISCV_INS_LH, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LHU, RISCV_INS_LHU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_D, RISCV_INS_LR_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_D_AQ, RISCV_INS_LR_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_D_AQ_RL, RISCV_INS_LR_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_D_RL, RISCV_INS_LR_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_W, RISCV_INS_LR_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_W_AQ, RISCV_INS_LR_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_W_AQ_RL, RISCV_INS_LR_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_LR_W_RL, RISCV_INS_LR_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_LUI, RISCV_INS_LUI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LW, RISCV_INS_LW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_LWU, RISCV_INS_LWU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_MRET, RISCV_INS_MRET, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_MUL, RISCV_INS_MUL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_MULH, RISCV_INS_MULH, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_MULHSU, RISCV_INS_MULHSU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_MULHU, RISCV_INS_MULHU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_MULW, RISCV_INS_MULW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_OR, RISCV_INS_OR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_ORI, RISCV_INS_ORI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_REM, RISCV_INS_REM, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_REMU, RISCV_INS_REMU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, 0 }, 0, 0 +#endif +}, +{ + RISCV_REMUW, RISCV_INS_REMUW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_REMW, RISCV_INS_REMW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SB, RISCV_INS_SB, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_D, RISCV_INS_SC_D, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_D_AQ, RISCV_INS_SC_D_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_D_AQ_RL, RISCV_INS_SC_D_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_D_RL, RISCV_INS_SC_D_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_W, RISCV_INS_SC_W, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_W_AQ, RISCV_INS_SC_W_AQ, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_W_AQ_RL, RISCV_INS_SC_W_AQ_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_SC_W_RL, RISCV_INS_SC_W_RL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_HASSTDEXTA, 0 }, 0, 0 +#endif +}, +{ + RISCV_SD, RISCV_INS_SD, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SFENCE_VMA, RISCV_INS_SFENCE_VMA, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SH, RISCV_INS_SH, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLL, RISCV_INS_SLL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLLI, RISCV_INS_SLLI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLLIW, RISCV_INS_SLLIW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SLLW, RISCV_INS_SLLW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SLT, RISCV_INS_SLT, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLTI, RISCV_INS_SLTI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLTIU, RISCV_INS_SLTIU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SLTU, RISCV_INS_SLTU, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRA, RISCV_INS_SRA, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRAI, RISCV_INS_SRAI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRAIW, RISCV_INS_SRAIW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SRAW, RISCV_INS_SRAW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SRET, RISCV_INS_SRET, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRL, RISCV_INS_SRL, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRLI, RISCV_INS_SRLI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SRLIW, RISCV_INS_SRLIW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SRLW, RISCV_INS_SRLW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SUB, RISCV_INS_SUB, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_SUBW, RISCV_INS_SUBW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { RISCV_GRP_ISRV64, 0 }, 0, 0 +#endif +}, +{ + RISCV_SW, RISCV_INS_SW, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_UNIMP, RISCV_INS_UNIMP, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_URET, RISCV_INS_URET, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_WFI, RISCV_INS_WFI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_XOR, RISCV_INS_XOR, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, +{ + RISCV_XORI, RISCV_INS_XORI, +#ifndef CAPSTONE_DIET + { 0 }, { 0 }, { 0 }, 0, 0 +#endif +}, diff --git a/arch/RISCV/RISCVModule.c b/arch/RISCV/RISCVModule.c new file mode 100644 index 000000000..cefd4b11a --- /dev/null +++ b/arch/RISCV/RISCVModule.c @@ -0,0 +1,42 @@ +/* Capstone Disassembly Engine */ +/* RISC-V Backend By Rodrigo Cortes Porto & + Shawn Chang , HardenedLinux@2018 */ + +#ifdef CAPSTONE_HAS_RISCV + +#include "../../utils.h" +#include "../../MCRegisterInfo.h" +#include "RISCVDisassembler.h" +#include "RISCVInstPrinter.h" +#include "RISCVMapping.h" +#include "RISCVModule.h" + +cs_err RISCV_global_init(cs_struct * ud) +{ + MCRegisterInfo *mri; + mri = cs_mem_malloc(sizeof(*mri)); + + RISCV_init(mri); + ud->printer = RISCV_printInst; + ud->printer_info = mri; + ud->getinsn_info = mri; + ud->disasm = RISCV_getInstruction; + ud->post_printer = NULL; + + ud->reg_name = RISCV_reg_name; + ud->insn_id = RISCV_get_insn_id; + ud->insn_name = RISCV_insn_name; + ud->group_name = RISCV_group_name; + + return CS_ERR_OK; +} + +cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value) +{ + if (type == CS_OPT_SYNTAX) + handle->syntax = (int)value; + + return CS_ERR_OK; +} + +#endif diff --git a/arch/RISCV/RISCVModule.h b/arch/RISCV/RISCVModule.h new file mode 100644 index 000000000..c250db554 --- /dev/null +++ b/arch/RISCV/RISCVModule.h @@ -0,0 +1,12 @@ +/* Capstone Disassembly Engine */ +/* By Shawn Chang , HardenedLinux@2018 */ + +#ifndef CS_RISCV_MODULE_H +#define CS_RISCV_MODULE_H + +#include "../../utils.h" + +cs_err RISCV_global_init(cs_struct * ud); +cs_err RISCV_option(cs_struct * handle, cs_opt_type type, size_t value); + +#endif diff --git a/bindings/Makefile b/bindings/Makefile index d22bb21f4..fe19b60bb 100644 --- a/bindings/Makefile +++ b/bindings/Makefile @@ -14,6 +14,7 @@ TEST_SYSZ = $(TMPDIR)/test_systemz TEST_X86 = $(TMPDIR)/test_x86 TEST_XCORE = $(TMPDIR)/test_xcore TEST_BPF = $(TMPDIR)/test_bpf +TEST_RISCV = $(TMPDIR)/test_riscv PYTHON2 = python @@ -44,6 +45,7 @@ expected: ../tests/test_x86 > $(TEST_X86)_e ../tests/test_xcore > $(TEST_XCORE)_e ../tests/test_bpf > $(TEST_BPF)_e + ../tests/test_riscv > $(TEST_RISCV)_e python: FORCE cd python && $(MAKE) @@ -59,6 +61,7 @@ python: FORCE $(PYTHON2) python/test_x86.py > $(TEST_X86)_o $(PYTHON2) python/test_xcore.py > $(TEST_XCORE)_o $(PYTHON2) python/test_bpf.py > $(TEST_BPF)_o + $(PYTHON2) python/test_riscv.py > $(TEST_RISCV)_o $(MAKE) test_diff java: FORCE diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 32baf9295..fda23642a 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -5,7 +5,7 @@ import sys, re INCL_DIR = '../include/capstone/' -include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ] +include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h' ] template = { 'java': { @@ -51,6 +51,7 @@ template = { 'wasm.h': 'wasm', 'mos65xx.h': 'mos65xx', 'bpf.h': 'bpf', + 'riscv.h': 'riscv', 'comment_open': '#', 'comment_close': '', }, diff --git a/bindings/python/Makefile b/bindings/python/Makefile index 7ae9abf47..4d325f9b8 100644 --- a/bindings/python/Makefile +++ b/bindings/python/Makefile @@ -70,7 +70,7 @@ clean: TESTS = test_basic.py test_detail.py test_arm.py test_arm64.py test_m68k.py test_mips.py TESTS += test_ppc.py test_sparc.py test_systemz.py test_x86.py test_xcore.py test_tms320c64x.py -TESTS += test_m680x.py test_skipdata.py test_mos65xx.py test_bpf.py +TESTS += test_m680x.py test_skipdata.py test_mos65xx.py test_bpf.py test_riscv.py TESTS += test_evm.py check: diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 9356f957d..ce814199e 100644 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -36,6 +36,7 @@ __all__ = [ 'CS_ARCH_M680X', 'CS_ARCH_EVM', 'CS_ARCH_BPF', + 'CS_ARCH_RISCV', 'CS_ARCH_MOS65XX', 'CS_ARCH_ALL', @@ -74,6 +75,8 @@ __all__ = [ 'CS_MODE_M680X_HCS08', 'CS_MODE_BPF_CLASSIC', 'CS_MODE_BPF_EXTENDED', + 'CS_MODE_RISCV32', + 'CS_MODE_RISCV64', 'CS_OPT_SYNTAX', 'CS_OPT_SYNTAX_DEFAULT', @@ -158,7 +161,8 @@ CS_ARCH_EVM = 11 CS_ARCH_MOS65XX = 12 CS_ARCH_WASM = 13 CS_ARCH_BPF = 14 -CS_ARCH_MAX = 15 +CS_ARCH_RISCV = 15 +CS_ARCH_MAX = 16 CS_ARCH_ALL = 0xFFFF # disasm mode @@ -195,8 +199,11 @@ CS_MODE_M680X_6809 = (1 << 7) # M680X M6809 mode CS_MODE_M680X_6811 = (1 << 8) # M680X M68HC11 mode CS_MODE_M680X_CPU12 = (1 << 9) # M680X CPU12 mode CS_MODE_M680X_HCS08 = (1 << 10) # M680X HCS08 mode -CS_MODE_BPF_CLASSIC = 0 # Classic BPF mode (default) -CS_MODE_BPF_EXTENDED = 1 << 0 # Extended BPF mode +CS_MODE_BPF_CLASSIC = 0 # Classic BPF mode (default) +CS_MODE_BPF_EXTENDED = (1 << 0) # Extended BPF mode +CS_MODE_RISCV32 = (1 << 0) # RISCV32 mode +CS_MODE_RISCV64 = (1 << 1) # RISCV64 mode +CS_MODE_RISCVC = (1 << 2) # RISCV compressed mode # Capstone option type CS_OPT_SYNTAX = 1 # Intel X86 asm syntax (CS_ARCH_X86 arch) @@ -336,7 +343,7 @@ def copy_ctypes_list(src): return [copy_ctypes(n) for n in src] # Weird import placement because these modules are needed by the below code but need the above functions -from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, bpf +from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, bpf, riscv class _cs_arch(ctypes.Union): _fields_ = ( @@ -354,6 +361,7 @@ class _cs_arch(ctypes.Union): ('evm', evm.CsEvm), ('mos65xx', mos65xx.CsMOS65xx), ('bpf', bpf.CsBPF), + ('riscv', riscv.CsRISCV), ) class _cs_detail(ctypes.Structure): @@ -672,6 +680,8 @@ class CsInsn(object): (self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(self._raw.detail.contents.arch.mos65xx) elif arch == CS_ARCH_BPF: (self.operands) = bpf.get_arch_info(self._raw.detail.contents.arch.bpf) + elif arch == CS_ARCH_RISCV: + (self.operands) = riscv.get_arch_info(self._raw.detail.contents.arch.riscv) def __getattr__(self, name): @@ -1131,7 +1141,7 @@ def debug(): "mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, "sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, - 'bpf': CS_ARCH_BPF, + 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, } all_archs = "" diff --git a/bindings/python/capstone/riscv.py b/bindings/python/capstone/riscv.py new file mode 100644 index 000000000..6e33a75f7 --- /dev/null +++ b/bindings/python/capstone/riscv.py @@ -0,0 +1,49 @@ +# Capstone Python bindings, by Nguyen Anh Quynnh + +import ctypes +from . import copy_ctypes_list +from .riscv_const import * + +# define the API +class RISCVOpMem(ctypes.Structure): + _fields_ = ( + ('base', ctypes.c_uint8), + ('disp', ctypes.c_int64), + ) + +class RISCVOpValue(ctypes.Union): + _fields_ = ( + ('reg', ctypes.c_uint), + ('imm', ctypes.c_int64), + ('mem', RISCVOpMem), + ) + +class RISCVOp(ctypes.Structure): + _fields_ = ( + ('type', ctypes.c_uint), + ('value', RISCVOpValue), + ) + + @property + def imm(self): + return self.value.imm + + @property + def reg(self): + return self.value.reg + + @property + def mem(self): + return self.value.mem + + +class CsRISCV(ctypes.Structure): + _fields_ = ( + ('need_effective_addr', ctypes.c_bool), + ('op_count', ctypes.c_uint8), + ('operands', RISCVOp * 8), + ) + +def get_arch_info(a): + return (copy_ctypes_list(a.operands[:a.op_count])) + diff --git a/bindings/python/capstone/riscv_const.py b/bindings/python/capstone/riscv_const.py new file mode 100644 index 000000000..811d965ba --- /dev/null +++ b/bindings/python/capstone/riscv_const.py @@ -0,0 +1,449 @@ +# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [riscv_const.py] + +# Operand type for instruction's operands + +RISCV_OP_INVALID = 0 +RISCV_OP_REG = 1 +RISCV_OP_IMM = 2 +RISCV_OP_MEM = 3 + +# RISCV registers + +RISCV_REG_INVALID = 0 + +# General purpose registers +RISCV_REG_X0 = 1 +RISCV_REG_ZERO = RISCV_REG_X0 +RISCV_REG_X1 = 2 +RISCV_REG_RA = RISCV_REG_X1 +RISCV_REG_X2 = 3 +RISCV_REG_SP = RISCV_REG_X2 +RISCV_REG_X3 = 4 +RISCV_REG_GP = RISCV_REG_X3 +RISCV_REG_X4 = 5 +RISCV_REG_TP = RISCV_REG_X4 +RISCV_REG_X5 = 6 +RISCV_REG_T0 = RISCV_REG_X5 +RISCV_REG_X6 = 7 +RISCV_REG_T1 = RISCV_REG_X6 +RISCV_REG_X7 = 8 +RISCV_REG_T2 = RISCV_REG_X7 +RISCV_REG_X8 = 9 +RISCV_REG_S0 = RISCV_REG_X8 +RISCV_REG_FP = RISCV_REG_X8 +RISCV_REG_X9 = 10 +RISCV_REG_S1 = RISCV_REG_X9 +RISCV_REG_X10 = 11 +RISCV_REG_A0 = RISCV_REG_X10 +RISCV_REG_X11 = 12 +RISCV_REG_A1 = RISCV_REG_X11 +RISCV_REG_X12 = 13 +RISCV_REG_A2 = RISCV_REG_X12 +RISCV_REG_X13 = 14 +RISCV_REG_A3 = RISCV_REG_X13 +RISCV_REG_X14 = 15 +RISCV_REG_A4 = RISCV_REG_X14 +RISCV_REG_X15 = 16 +RISCV_REG_A5 = RISCV_REG_X15 +RISCV_REG_X16 = 17 +RISCV_REG_A6 = RISCV_REG_X16 +RISCV_REG_X17 = 18 +RISCV_REG_A7 = RISCV_REG_X17 +RISCV_REG_X18 = 19 +RISCV_REG_S2 = RISCV_REG_X18 +RISCV_REG_X19 = 20 +RISCV_REG_S3 = RISCV_REG_X19 +RISCV_REG_X20 = 21 +RISCV_REG_S4 = RISCV_REG_X20 +RISCV_REG_X21 = 22 +RISCV_REG_S5 = RISCV_REG_X21 +RISCV_REG_X22 = 23 +RISCV_REG_S6 = RISCV_REG_X22 +RISCV_REG_X23 = 24 +RISCV_REG_S7 = RISCV_REG_X23 +RISCV_REG_X24 = 25 +RISCV_REG_S8 = RISCV_REG_X24 +RISCV_REG_X25 = 26 +RISCV_REG_S9 = RISCV_REG_X25 +RISCV_REG_X26 = 27 +RISCV_REG_S10 = RISCV_REG_X26 +RISCV_REG_X27 = 28 +RISCV_REG_S11 = RISCV_REG_X27 +RISCV_REG_X28 = 29 +RISCV_REG_T3 = RISCV_REG_X28 +RISCV_REG_X29 = 30 +RISCV_REG_T4 = RISCV_REG_X29 +RISCV_REG_X30 = 31 +RISCV_REG_T5 = RISCV_REG_X30 +RISCV_REG_X31 = 32 +RISCV_REG_T6 = RISCV_REG_X31 + +# Floating-point registers +RISCV_REG_F0_32 = 33 +RISCV_REG_F0_64 = 34 +RISCV_REG_F1_32 = 35 +RISCV_REG_F1_64 = 36 +RISCV_REG_F2_32 = 37 +RISCV_REG_F2_64 = 38 +RISCV_REG_F3_32 = 39 +RISCV_REG_F3_64 = 40 +RISCV_REG_F4_32 = 41 +RISCV_REG_F4_64 = 42 +RISCV_REG_F5_32 = 43 +RISCV_REG_F5_64 = 44 +RISCV_REG_F6_32 = 45 +RISCV_REG_F6_64 = 46 +RISCV_REG_F7_32 = 47 +RISCV_REG_F7_64 = 48 +RISCV_REG_F8_32 = 49 +RISCV_REG_F8_64 = 50 +RISCV_REG_F9_32 = 51 +RISCV_REG_F9_64 = 52 +RISCV_REG_F10_32 = 53 +RISCV_REG_F10_64 = 54 +RISCV_REG_F11_32 = 55 +RISCV_REG_F11_64 = 56 +RISCV_REG_F12_32 = 57 +RISCV_REG_F12_64 = 58 +RISCV_REG_F13_32 = 59 +RISCV_REG_F13_64 = 60 +RISCV_REG_F14_32 = 61 +RISCV_REG_F14_64 = 62 +RISCV_REG_F15_32 = 63 +RISCV_REG_F15_64 = 64 +RISCV_REG_F16_32 = 65 +RISCV_REG_F16_64 = 66 +RISCV_REG_F17_32 = 67 +RISCV_REG_F17_64 = 68 +RISCV_REG_F18_32 = 69 +RISCV_REG_F18_64 = 70 +RISCV_REG_F19_32 = 71 +RISCV_REG_F19_64 = 72 +RISCV_REG_F20_32 = 73 +RISCV_REG_F20_64 = 74 +RISCV_REG_F21_32 = 75 +RISCV_REG_F21_64 = 76 +RISCV_REG_F22_32 = 77 +RISCV_REG_F22_64 = 78 +RISCV_REG_F23_32 = 79 +RISCV_REG_F23_64 = 80 +RISCV_REG_F24_32 = 81 +RISCV_REG_F24_64 = 82 +RISCV_REG_F25_32 = 83 +RISCV_REG_F25_64 = 84 +RISCV_REG_F26_32 = 85 +RISCV_REG_F26_64 = 86 +RISCV_REG_F27_32 = 87 +RISCV_REG_F27_64 = 88 +RISCV_REG_F28_32 = 89 +RISCV_REG_F28_64 = 90 +RISCV_REG_F29_32 = 91 +RISCV_REG_F29_64 = 92 +RISCV_REG_F30_32 = 93 +RISCV_REG_F30_64 = 94 +RISCV_REG_F31_32 = 95 +RISCV_REG_F31_64 = 96 +RISCV_REG_ENDING = 97 + +# RISCV instruction + +RISCV_INS_INVALID = 0 +RISCV_INS_ADD = 1 +RISCV_INS_ADDI = 2 +RISCV_INS_ADDIW = 3 +RISCV_INS_ADDW = 4 +RISCV_INS_AMOADD_D = 5 +RISCV_INS_AMOADD_D_AQ = 6 +RISCV_INS_AMOADD_D_AQ_RL = 7 +RISCV_INS_AMOADD_D_RL = 8 +RISCV_INS_AMOADD_W = 9 +RISCV_INS_AMOADD_W_AQ = 10 +RISCV_INS_AMOADD_W_AQ_RL = 11 +RISCV_INS_AMOADD_W_RL = 12 +RISCV_INS_AMOAND_D = 13 +RISCV_INS_AMOAND_D_AQ = 14 +RISCV_INS_AMOAND_D_AQ_RL = 15 +RISCV_INS_AMOAND_D_RL = 16 +RISCV_INS_AMOAND_W = 17 +RISCV_INS_AMOAND_W_AQ = 18 +RISCV_INS_AMOAND_W_AQ_RL = 19 +RISCV_INS_AMOAND_W_RL = 20 +RISCV_INS_AMOMAXU_D = 21 +RISCV_INS_AMOMAXU_D_AQ = 22 +RISCV_INS_AMOMAXU_D_AQ_RL = 23 +RISCV_INS_AMOMAXU_D_RL = 24 +RISCV_INS_AMOMAXU_W = 25 +RISCV_INS_AMOMAXU_W_AQ = 26 +RISCV_INS_AMOMAXU_W_AQ_RL = 27 +RISCV_INS_AMOMAXU_W_RL = 28 +RISCV_INS_AMOMAX_D = 29 +RISCV_INS_AMOMAX_D_AQ = 30 +RISCV_INS_AMOMAX_D_AQ_RL = 31 +RISCV_INS_AMOMAX_D_RL = 32 +RISCV_INS_AMOMAX_W = 33 +RISCV_INS_AMOMAX_W_AQ = 34 +RISCV_INS_AMOMAX_W_AQ_RL = 35 +RISCV_INS_AMOMAX_W_RL = 36 +RISCV_INS_AMOMINU_D = 37 +RISCV_INS_AMOMINU_D_AQ = 38 +RISCV_INS_AMOMINU_D_AQ_RL = 39 +RISCV_INS_AMOMINU_D_RL = 40 +RISCV_INS_AMOMINU_W = 41 +RISCV_INS_AMOMINU_W_AQ = 42 +RISCV_INS_AMOMINU_W_AQ_RL = 43 +RISCV_INS_AMOMINU_W_RL = 44 +RISCV_INS_AMOMIN_D = 45 +RISCV_INS_AMOMIN_D_AQ = 46 +RISCV_INS_AMOMIN_D_AQ_RL = 47 +RISCV_INS_AMOMIN_D_RL = 48 +RISCV_INS_AMOMIN_W = 49 +RISCV_INS_AMOMIN_W_AQ = 50 +RISCV_INS_AMOMIN_W_AQ_RL = 51 +RISCV_INS_AMOMIN_W_RL = 52 +RISCV_INS_AMOOR_D = 53 +RISCV_INS_AMOOR_D_AQ = 54 +RISCV_INS_AMOOR_D_AQ_RL = 55 +RISCV_INS_AMOOR_D_RL = 56 +RISCV_INS_AMOOR_W = 57 +RISCV_INS_AMOOR_W_AQ = 58 +RISCV_INS_AMOOR_W_AQ_RL = 59 +RISCV_INS_AMOOR_W_RL = 60 +RISCV_INS_AMOSWAP_D = 61 +RISCV_INS_AMOSWAP_D_AQ = 62 +RISCV_INS_AMOSWAP_D_AQ_RL = 63 +RISCV_INS_AMOSWAP_D_RL = 64 +RISCV_INS_AMOSWAP_W = 65 +RISCV_INS_AMOSWAP_W_AQ = 66 +RISCV_INS_AMOSWAP_W_AQ_RL = 67 +RISCV_INS_AMOSWAP_W_RL = 68 +RISCV_INS_AMOXOR_D = 69 +RISCV_INS_AMOXOR_D_AQ = 70 +RISCV_INS_AMOXOR_D_AQ_RL = 71 +RISCV_INS_AMOXOR_D_RL = 72 +RISCV_INS_AMOXOR_W = 73 +RISCV_INS_AMOXOR_W_AQ = 74 +RISCV_INS_AMOXOR_W_AQ_RL = 75 +RISCV_INS_AMOXOR_W_RL = 76 +RISCV_INS_AND = 77 +RISCV_INS_ANDI = 78 +RISCV_INS_AUIPC = 79 +RISCV_INS_BEQ = 80 +RISCV_INS_BGE = 81 +RISCV_INS_BGEU = 82 +RISCV_INS_BLT = 83 +RISCV_INS_BLTU = 84 +RISCV_INS_BNE = 85 +RISCV_INS_CSRRC = 86 +RISCV_INS_CSRRCI = 87 +RISCV_INS_CSRRS = 88 +RISCV_INS_CSRRSI = 89 +RISCV_INS_CSRRW = 90 +RISCV_INS_CSRRWI = 91 +RISCV_INS_C_ADD = 92 +RISCV_INS_C_ADDI = 93 +RISCV_INS_C_ADDI16SP = 94 +RISCV_INS_C_ADDI4SPN = 95 +RISCV_INS_C_ADDIW = 96 +RISCV_INS_C_ADDW = 97 +RISCV_INS_C_AND = 98 +RISCV_INS_C_ANDI = 99 +RISCV_INS_C_BEQZ = 100 +RISCV_INS_C_BNEZ = 101 +RISCV_INS_C_EBREAK = 102 +RISCV_INS_C_FLD = 103 +RISCV_INS_C_FLDSP = 104 +RISCV_INS_C_FLW = 105 +RISCV_INS_C_FLWSP = 106 +RISCV_INS_C_FSD = 107 +RISCV_INS_C_FSDSP = 108 +RISCV_INS_C_FSW = 109 +RISCV_INS_C_FSWSP = 110 +RISCV_INS_C_J = 111 +RISCV_INS_C_JAL = 112 +RISCV_INS_C_JALR = 113 +RISCV_INS_C_JR = 114 +RISCV_INS_C_LD = 115 +RISCV_INS_C_LDSP = 116 +RISCV_INS_C_LI = 117 +RISCV_INS_C_LUI = 118 +RISCV_INS_C_LW = 119 +RISCV_INS_C_LWSP = 120 +RISCV_INS_C_MV = 121 +RISCV_INS_C_NOP = 122 +RISCV_INS_C_OR = 123 +RISCV_INS_C_SD = 124 +RISCV_INS_C_SDSP = 125 +RISCV_INS_C_SLLI = 126 +RISCV_INS_C_SRAI = 127 +RISCV_INS_C_SRLI = 128 +RISCV_INS_C_SUB = 129 +RISCV_INS_C_SUBW = 130 +RISCV_INS_C_SW = 131 +RISCV_INS_C_SWSP = 132 +RISCV_INS_C_UNIMP = 133 +RISCV_INS_C_XOR = 134 +RISCV_INS_DIV = 135 +RISCV_INS_DIVU = 136 +RISCV_INS_DIVUW = 137 +RISCV_INS_DIVW = 138 +RISCV_INS_EBREAK = 139 +RISCV_INS_ECALL = 140 +RISCV_INS_FADD_D = 141 +RISCV_INS_FADD_S = 142 +RISCV_INS_FCLASS_D = 143 +RISCV_INS_FCLASS_S = 144 +RISCV_INS_FCVT_D_L = 145 +RISCV_INS_FCVT_D_LU = 146 +RISCV_INS_FCVT_D_S = 147 +RISCV_INS_FCVT_D_W = 148 +RISCV_INS_FCVT_D_WU = 149 +RISCV_INS_FCVT_LU_D = 150 +RISCV_INS_FCVT_LU_S = 151 +RISCV_INS_FCVT_L_D = 152 +RISCV_INS_FCVT_L_S = 153 +RISCV_INS_FCVT_S_D = 154 +RISCV_INS_FCVT_S_L = 155 +RISCV_INS_FCVT_S_LU = 156 +RISCV_INS_FCVT_S_W = 157 +RISCV_INS_FCVT_S_WU = 158 +RISCV_INS_FCVT_WU_D = 159 +RISCV_INS_FCVT_WU_S = 160 +RISCV_INS_FCVT_W_D = 161 +RISCV_INS_FCVT_W_S = 162 +RISCV_INS_FDIV_D = 163 +RISCV_INS_FDIV_S = 164 +RISCV_INS_FENCE = 165 +RISCV_INS_FENCE_I = 166 +RISCV_INS_FENCE_TSO = 167 +RISCV_INS_FEQ_D = 168 +RISCV_INS_FEQ_S = 169 +RISCV_INS_FLD = 170 +RISCV_INS_FLE_D = 171 +RISCV_INS_FLE_S = 172 +RISCV_INS_FLT_D = 173 +RISCV_INS_FLT_S = 174 +RISCV_INS_FLW = 175 +RISCV_INS_FMADD_D = 176 +RISCV_INS_FMADD_S = 177 +RISCV_INS_FMAX_D = 178 +RISCV_INS_FMAX_S = 179 +RISCV_INS_FMIN_D = 180 +RISCV_INS_FMIN_S = 181 +RISCV_INS_FMSUB_D = 182 +RISCV_INS_FMSUB_S = 183 +RISCV_INS_FMUL_D = 184 +RISCV_INS_FMUL_S = 185 +RISCV_INS_FMV_D_X = 186 +RISCV_INS_FMV_W_X = 187 +RISCV_INS_FMV_X_D = 188 +RISCV_INS_FMV_X_W = 189 +RISCV_INS_FNMADD_D = 190 +RISCV_INS_FNMADD_S = 191 +RISCV_INS_FNMSUB_D = 192 +RISCV_INS_FNMSUB_S = 193 +RISCV_INS_FSD = 194 +RISCV_INS_FSGNJN_D = 195 +RISCV_INS_FSGNJN_S = 196 +RISCV_INS_FSGNJX_D = 197 +RISCV_INS_FSGNJX_S = 198 +RISCV_INS_FSGNJ_D = 199 +RISCV_INS_FSGNJ_S = 200 +RISCV_INS_FSQRT_D = 201 +RISCV_INS_FSQRT_S = 202 +RISCV_INS_FSUB_D = 203 +RISCV_INS_FSUB_S = 204 +RISCV_INS_FSW = 205 +RISCV_INS_JAL = 206 +RISCV_INS_JALR = 207 +RISCV_INS_LB = 208 +RISCV_INS_LBU = 209 +RISCV_INS_LD = 210 +RISCV_INS_LH = 211 +RISCV_INS_LHU = 212 +RISCV_INS_LR_D = 213 +RISCV_INS_LR_D_AQ = 214 +RISCV_INS_LR_D_AQ_RL = 215 +RISCV_INS_LR_D_RL = 216 +RISCV_INS_LR_W = 217 +RISCV_INS_LR_W_AQ = 218 +RISCV_INS_LR_W_AQ_RL = 219 +RISCV_INS_LR_W_RL = 220 +RISCV_INS_LUI = 221 +RISCV_INS_LW = 222 +RISCV_INS_LWU = 223 +RISCV_INS_MRET = 224 +RISCV_INS_MUL = 225 +RISCV_INS_MULH = 226 +RISCV_INS_MULHSU = 227 +RISCV_INS_MULHU = 228 +RISCV_INS_MULW = 229 +RISCV_INS_OR = 230 +RISCV_INS_ORI = 231 +RISCV_INS_REM = 232 +RISCV_INS_REMU = 233 +RISCV_INS_REMUW = 234 +RISCV_INS_REMW = 235 +RISCV_INS_SB = 236 +RISCV_INS_SC_D = 237 +RISCV_INS_SC_D_AQ = 238 +RISCV_INS_SC_D_AQ_RL = 239 +RISCV_INS_SC_D_RL = 240 +RISCV_INS_SC_W = 241 +RISCV_INS_SC_W_AQ = 242 +RISCV_INS_SC_W_AQ_RL = 243 +RISCV_INS_SC_W_RL = 244 +RISCV_INS_SD = 245 +RISCV_INS_SFENCE_VMA = 246 +RISCV_INS_SH = 247 +RISCV_INS_SLL = 248 +RISCV_INS_SLLI = 249 +RISCV_INS_SLLIW = 250 +RISCV_INS_SLLW = 251 +RISCV_INS_SLT = 252 +RISCV_INS_SLTI = 253 +RISCV_INS_SLTIU = 254 +RISCV_INS_SLTU = 255 +RISCV_INS_SRA = 256 +RISCV_INS_SRAI = 257 +RISCV_INS_SRAIW = 258 +RISCV_INS_SRAW = 259 +RISCV_INS_SRET = 260 +RISCV_INS_SRL = 261 +RISCV_INS_SRLI = 262 +RISCV_INS_SRLIW = 263 +RISCV_INS_SRLW = 264 +RISCV_INS_SUB = 265 +RISCV_INS_SUBW = 266 +RISCV_INS_SW = 267 +RISCV_INS_UNIMP = 268 +RISCV_INS_URET = 269 +RISCV_INS_WFI = 270 +RISCV_INS_XOR = 271 +RISCV_INS_XORI = 272 +RISCV_INS_ENDING = 273 + +# Group of RISCV instructions + +RISCV_GRP_INVALID = 0 +RISCV_GRP_JUMP = 1 +RISCV_GRP_ISRV32 = 128 +RISCV_GRP_ISRV64 = 129 +RISCV_GRP_HASSTDEXTA = 130 +RISCV_GRP_HASSTDEXTC = 131 +RISCV_GRP_HASSTDEXTD = 132 +RISCV_GRP_HASSTDEXTF = 133 +RISCV_GRP_HASSTDEXTM = 134 +RISCV_GRP_ISRVA = 135 +RISCV_GRP_ISRVC = 136 +RISCV_GRP_ISRVD = 137 +RISCV_GRP_ISRVCD = 138 +RISCV_GRP_ISRVF = 139 +RISCV_GRP_ISRV32C = 140 +RISCV_GRP_ISRV32CF = 141 +RISCV_GRP_ISRVM = 142 +RISCV_GRP_ISRV64A = 143 +RISCV_GRP_ISRV64C = 144 +RISCV_GRP_ISRV64D = 145 +RISCV_GRP_ISRV64F = 146 +RISCV_GRP_ISRV64M = 147 +RISCV_GRP_ENDING = 148 diff --git a/bindings/python/test_all.py b/bindings/python/test_all.py index 4ec912110..a01fc6598 100755 --- a/bindings/python/test_all.py +++ b/bindings/python/test_all.py @@ -2,7 +2,7 @@ import test_basic, test_arm, test_arm64, test_detail, test_lite, test_m68k, test_mips, \ test_ppc, test_x86, test_skipdata, test_sparc, test_systemz, test_tms320c64x, test_customized_mnem, \ - test_m680x, test_mos65xx + test_m680x, test_mos65xx, test_xcore, test_riscv test_basic.test_class() test_arm.test_class() @@ -20,3 +20,5 @@ test_tms320c64x.test_class() test_m680x.test_class() test_skipdata.test_class() test_customized_mnem.test() +test_xcore.test_class() +test_riscv.test_class() diff --git a/bindings/python/test_basic.py b/bindings/python/test_basic.py index b55187bd9..22007c565 100755 --- a/bindings/python/test_basic.py +++ b/bindings/python/test_basic.py @@ -34,6 +34,9 @@ XCORE_CODE = b"\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\ M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24" M680X_CODE = b"\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39" +RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" +RISCV_CODE64 = b"\x13\x04\xa8\x7a" + all_tests = ( (CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", None), @@ -62,6 +65,8 @@ all_tests = ( (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None), (CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x", None), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None), + (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32", None), + (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64", None), ) # ## Test cs_disasm_quick() diff --git a/bindings/python/test_riscv.py b/bindings/python/test_riscv.py new file mode 100755 index 000000000..21bd03cf2 --- /dev/null +++ b/bindings/python/test_riscv.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +# Capstone Python bindings, by Nguyen Anh Quynnh + +from __future__ import print_function +from capstone import * +from capstone.riscv import * +from xprint import to_x, to_hex + +RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" +RISCV_CODE64 = b"\x13\x04\xa8\x7a" + +all_tests = ( + (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32"), + (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64"), +) + + +def print_insn_detail(insn): + # print address, mnemonic and operands + print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + + # "data" instruction generated by SKIPDATA option has no detail + if insn.id == 0: + return + + if len(insn.operands) > 0: + print("\top_count: %u" % len(insn.operands)) + c = 0 + for i in insn.operands: + if i.type == RISCV_OP_REG: + print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg))) + if i.type == RISCV_OP_IMM: + print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm))) + if i.type == RISCV_OP_MEM: + print("\t\toperands[%u].type: MEM" % c) + if i.mem.base != 0: + print("\t\t\toperands[%u].mem.base: REG = %s" \ + % (c, insn.reg_name(i.mem.base))) + if i.mem.disp != 0: + print("\t\t\toperands[%u].mem.disp: 0x%s" \ + % (c, to_x(i.mem.disp))) + c += 1 + + +# ## Test class Cs +def test_class(): + + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" %comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") + + try: + md = Cs(arch, mode) + md.detail = True + for insn in md.disasm(code, 0x1000): + print_insn_detail(insn) + print () + print("0x%x:\n" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" %e) + + +if __name__ == '__main__': + test_class() diff --git a/config.mk b/config.mk index 052fc7816..c65103f44 100644 --- a/config.mk +++ b/config.mk @@ -4,7 +4,7 @@ ################################################################################ # Specify which archs you want to compile in. By default, we build all archs. -CAPSTONE_ARCHS ?= arm aarch64 m68k mips powerpc sparc systemz x86 xcore tms320c64x m680x evm mos65xx wasm bpf +CAPSTONE_ARCHS ?= arm aarch64 m68k mips powerpc sparc systemz x86 xcore tms320c64x m680x evm riscv mos65xx wasm bpf ################################################################################ diff --git a/contrib/riscv_update/0001-capstone-riscv-patchs.patch b/contrib/riscv_update/0001-capstone-riscv-patchs.patch new file mode 100644 index 000000000..eb3246814 --- /dev/null +++ b/contrib/riscv_update/0001-capstone-riscv-patchs.patch @@ -0,0 +1,3161 @@ +From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Sun, 17 Feb 2019 06:08:44 +0800 +Subject: [PATCH] capstone riscv patchs + +--- + ...apstone-generate-GenRegisterInfo.inc.patch | 338 +++++++++++++ + ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ++++ + ...3-capstone-generate-GenInstrInfo.inc.patch | 130 +++++ + ...e-generate-GenDisassemblerTables.inc.patch | 472 ++++++++++++++++++ + ...5-capstone-generate-GenAsmWriter.inc.patch | 225 +++++++++ + ...06-capstone-generate-MappingInsn.inc.patch | 174 +++++++ + ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ++++ + llvm/lib/Target/RISCV/CMakeLists.txt | 2 + + llvm/utils/TableGen/AsmWriterEmitter.cpp | 103 +++- + llvm/utils/TableGen/AsmWriterInst.cpp | 4 + + llvm/utils/TableGen/DisassemblerEmitter.cpp | 12 +- + .../utils/TableGen/FixedLenDecoderEmitter.cpp | 398 ++++++++++++++- + llvm/utils/TableGen/InstrInfoEmitter.cpp | 173 ++++++- + llvm/utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++- + llvm/utils/TableGen/SubtargetEmitter.cpp | 28 +- + llvm/utils/TableGen/TableGen.cpp | 12 + + llvm/utils/TableGen/TableGenBackends.h | 2 + + 17 files changed, 2349 insertions(+), 50 deletions(-) + create mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch + create mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch + create mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch + create mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch + create mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch + create mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch + create mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch + +diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +new file mode 100644 +index 000000000..b51aa515a +--- /dev/null ++++ b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +@@ -0,0 +1,338 @@ ++From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 , 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 &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 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 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 ++ +diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +new file mode 100644 +index 000000000..56ad28256 +--- /dev/null ++++ b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +@@ -0,0 +1,86 @@ ++From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 , 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 ++ +diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +new file mode 100644 +index 000000000..2baa59fc9 +--- /dev/null ++++ b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +@@ -0,0 +1,130 @@ ++From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 &Uses, ++ unsigned Num, raw_ostream &OS) { ++ OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; ++@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 ++ +diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +new file mode 100644 +index 000000000..0002b81b4 +--- /dev/null ++++ b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +@@ -0,0 +1,472 @@ ++From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 , 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\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\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\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 \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 ++ +diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +new file mode 100644 +index 000000000..cd1353eb7 +--- /dev/null ++++ b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +@@ -0,0 +1,225 @@ ++From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 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 &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 , 2013-2015 */\n" +++ "\n" +++ "#include \t// debug\n" +++ "#include \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 ++ +diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch +new file mode 100644 +index 000000000..7ee22d787 +--- /dev/null ++++ b/llvm/0006-capstone-generate-MappingInsn.inc.patch +@@ -0,0 +1,174 @@ ++From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 \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 ++ +diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +new file mode 100644 +index 000000000..019540d65 +--- /dev/null ++++ b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +@@ -0,0 +1,110 @@ ++From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 ++From: mephi42 ++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 \n" +++ "\n"; +++ CodeGenTarget Target(RK); +++ std::map 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 ++ +diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt +index 07c32cb31..1821f4b01 100644 +--- a/llvm/lib/Target/RISCV/CMakeLists.txt ++++ b/llvm/lib/Target/RISCV/CMakeLists.txt +@@ -6,6 +6,8 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) + tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) + tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) ++tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) ++tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) + tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) + tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) + tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index 24e16f9c4..c24dc6052 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -271,16 +271,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 StringTable; +@@ -378,9 +384,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; +@@ -408,21 +421,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; +@@ -454,7 +491,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 ++ << "assert(0);\n" ++#endif ++ << "llvm_unreachable(\"Invalid command number.\");\n"; + + // Print out all the cases. + for (unsigned j = 0, e = Commands.size(); j != e; ++j) { +@@ -535,6 +576,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"; +@@ -551,8 +595,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 &AltNameIndices = Target.getRegAltNameIndices(); + bool hasAltNames = AltNameIndices.size() > 1; +@@ -562,12 +608,22 @@ 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"; ++ "static const char *"; ++ if (hasAltNames) ++ O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx)\n{\n"; ++ else ++ O << "\ngetRegisterName(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 << " " ++ << "assert(RegNo && RegNo < " << (Registers.size()+1) + << " && \"Invalid register number!\");\n" + << "\n"; + +@@ -579,12 +635,21 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + + if (hasAltNames) { + O << " switch(AltIdx) {\n" ++#ifdef CAPSTONE ++ << " default: assert(0);\n"; ++#else + << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; ++#endif + for (const Record *R : AltNameIndices) { + StringRef AltName = R->getName(); + O << " case "; + if (!Namespace.empty()) +- O << Namespace << "::"; ++ O << Namespace ++#ifndef CAPSTONE ++ << "::"; ++#else ++ << "_"; ++#endif + O << AltName << ":\n" + << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName + << "[RegNo-1]) &&\n" +@@ -594,10 +659,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"; + } + +@@ -1139,9 +1216,21 @@ 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 , 2013-2015 */\n" ++ "\n" ++ "#include \t// debug\n" ++ "#include \n" ++ "#include \n" ++ "\n" ++ "\n"; ++#endif + EmitPrintInstruction(O); + EmitGetRegisterName(O); ++#ifndef CAPSTONE + EmitPrintAliasInstruction(O); ++#endif + } + + namespace llvm { +diff --git a/llvm/utils/TableGen/AsmWriterInst.cpp b/llvm/utils/TableGen/AsmWriterInst.cpp +index d065a4209..7266d1eda 100644 +--- a/llvm/utils/TableGen/AsmWriterInst.cpp ++++ b/llvm/utils/TableGen/AsmWriterInst.cpp +@@ -27,9 +27,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) +diff --git a/llvm/utils/TableGen/DisassemblerEmitter.cpp b/llvm/utils/TableGen/DisassemblerEmitter.cpp +index 9e75c7fba..1bc0cfa0d 100644 +--- a/llvm/utils/TableGen/DisassemblerEmitter.cpp ++++ b/llvm/utils/TableGen/DisassemblerEmitter.cpp +@@ -105,6 +105,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 , 2013-2015 */\n" ++ "\n"; ++#endif + + // X86 uses a custom disassembler. + if (Target.getName() == "X86") { +@@ -149,7 +154,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/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +index ea28e06cc..3db428dfa 100644 +--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +@@ -741,7 +741,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) << "-"; +@@ -750,7 +756,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++ << ", "; +@@ -773,7 +785,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) +@@ -794,7 +812,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++ << ", "; +@@ -823,7 +847,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 << ", "; +@@ -858,7 +888,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; +@@ -890,7 +925,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; + } + } +@@ -905,23 +946,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 ++ << "assert(0);\n" ++#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 ++ << "assert(0);\n" ++#endif ++ << "llvm_unreachable(\"Invalid index!\");\n"; + } + Indentation -= 2; + OS.indent(Indentation) << "}\n\n"; +@@ -932,23 +996,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\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 ++ << " assert(0);\\\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"; + } +@@ -1075,16 +1155,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 != "") { +@@ -1092,8 +1177,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"; +@@ -1112,7 +1201,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; + } + +@@ -1150,10 +1245,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, +@@ -2090,7 +2194,18 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { + << "// * Support shift (<<, >>) with signed and unsigned integers on the " + "RHS\n" + << "// * Support put (<<) to raw_ostream&\n" +- << "template\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\n" + << "#if defined(_MSC_VER) && !defined(__clang__)\n" + << "__declspec(noinline)\n" + << "#endif\n" +@@ -2127,12 +2242,239 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { + << " unsigned numBits) {\n" + << " return fieldFromInstruction(insn, startBit, numBits, " + "std::is_integral());\n" ++#endif + << "}\n\n"; + } + + // emitDecodeInstruction - Emit the templated helper function + // decodeInstruction(). + static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ ++#if 0 ++ 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" ++#endif ++ ++#ifdef CAPSTONE ++ OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " ++ ++ "MCInst *MI,\\\n" ++ << " InsnType insn, uint64_t " ++ "Address,\\\n" ++ << " const void *DisAsm,\\\n" ++ << " int feature) {\\\n" ++ << " uint64_t Bits = getFeatureBits(feature); \\\n" ++ //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" ++ << "\\\n" ++ << " const uint8_t *Ptr = DecodeTable;\\\n" ++ << " uint32_t CurFieldValue = 0;\\\n" ++ << " DecodeStatus S = MCDisassembler_Success;\\\n" ++ << " while (true) {\\\n" ++ << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n" ++ << " switch (*Ptr) {\\\n" ++ << " default:\\\n" ++ << " return MCDisassembler_Fail;\\\n" ++ << " case MCD_OPC_ExtractField: {\\\n" ++ << " unsigned Start = *++Ptr;\\\n" ++ << " unsigned Len = *++Ptr;\\\n" ++ << " ++Ptr;\\\n" ++ << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_FilterValue: {\\\n" ++ << " // Decode the field value.\\\n" ++ << " unsigned Len;\\\n" ++ << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++ << " // Perform the filter operation.\\\n" ++ << " if (Val != CurFieldValue)\\\n" ++ << " Ptr += NumToSkip;\\\n" ++ << "\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_CheckField: {\\\n" ++ << " unsigned Start = *++Ptr;\\\n" ++ << " unsigned Len = *++Ptr;\\\n" ++ << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" ++ << " // Decode the field value.\\\n" ++ << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++ << " // If the actual and expected values don't match, skip.\\\n" ++ << " if (ExpectedValue != FieldValue)\\\n" ++ << " Ptr += NumToSkip;\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_CheckPredicate: {\\\n" ++ << " unsigned Len;\\\n" ++ << " // Decode the Predicate Index value.\\\n" ++ << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << " // Check the predicate.\\\n" ++ << " bool Pred;\\\n" ++ << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" ++ << " Ptr += NumToSkip;\\\n" ++ << " (void)Pred;\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_Decode: {\\\n" ++ << " unsigned Len;\\\n" ++ << " // Decode the Opcode value.\\\n" ++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << "\\\n" ++ << " MCInst_clear(MI);\\\n" ++ << " MCInst_setOpcode(MI, Opc);\\\n" ++ << " bool DecodeComplete;\\\n" ++ << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " ++ "DecodeComplete);\\\n" ++ << " assert(DecodeComplete);\\\n" ++ << "\\\n" ++ << " return S;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_TryDecode: {\\\n" ++ << " unsigned Len;\\\n" ++ << " // Decode the Opcode value.\\\n" ++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++ << " // Perform the decode operation.\\\n" ++ << " MCInst TmpMI;\\\n" ++ << " MCInst_setOpcode(&TmpMI, Opc);\\\n" ++ << " bool DecodeComplete;\n" ++ << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " ++ "DecodeComplete);\\\n" ++ << " if (DecodeComplete) {\\\n" ++ << " // Decoding complete.\\\n" ++ << " MI = &TmpMI;\\\n" ++ << " return S;\\\n" ++ << " } else {\\\n" ++ << " assert(S == MCDisassembler_Fail);\\\n" ++ << " // If the decoding was incomplete, skip.\\\n" ++ << " Ptr += NumToSkip;\\\n" ++ << " // Reset decode status. This also drops a SoftFail status " ++ "that could be\\\n" ++ << " // set before the decode attempt.\\\n" ++ << " S = MCDisassembler_Success;\\\n" ++ << " }\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_SoftFail: {\\\n" ++ << " // Decode the mask values.\\\n" ++ << " unsigned Len;\\\n" ++ << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " bool 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" ++ << " assert(0);\\\n" ++ ++#else + OS << "template\n" + << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " + "MCInst &MI,\n" +@@ -2313,12 +2655,19 @@ 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 << "#include \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"; +@@ -2327,6 +2676,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { + OS << "#include \n"; + OS << '\n'; + OS << "namespace llvm {\n\n"; ++#endif + + emitFieldFromInstruction(OS); + +@@ -2401,7 +2751,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 { +diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp +index fd8775023..797f42a50 100644 +--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp ++++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp +@@ -92,6 +92,7 @@ private: + + } // end anonymous namespace + ++#ifndef CAPSTONE + static void PrintDefList(const std::vector &Uses, + unsigned Num, raw_ostream &OS) { + OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &Uses, + OS << getQualifiedName(U) << ", "; + OS << "0 };\n"; + } ++#endif + + //===----------------------------------------------------------------------===// + // Operand Info Emission. +@@ -434,8 +436,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 , 2013-2015 */\n" ++ "\n" ++ "\n"; ++#endif ++ + emitEnums(OS); + ++#ifndef CAPSTONE + OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; + OS << "#undef GET_INSTRINFO_MC_DESC\n"; + +@@ -563,6 +574,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { + emitOperandTypesEnum(OS, Target); + + emitMCIIHelperMethods(OS, TargetName); ++#endif + } + + void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, +@@ -680,7 +692,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); + +@@ -690,17 +704,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"; +@@ -717,13 +753,140 @@ 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 ++} ++ ++#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 \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"; ++ } ++} ++ ++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 \n" ++ "\n"; ++ CodeGenTarget Target(RK); ++ std::map 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/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +index 1b619072c..0df306680 100644 +--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +@@ -98,6 +98,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) { +@@ -106,13 +112,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 , 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" +@@ -121,16 +136,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()) { +@@ -139,18 +158,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 &RegAltNameIndices = Target.getRegAltNameIndices(); + // If the only definition is the default NoRegAltName, we don't need to + // emit anything. +@@ -181,8 +211,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"; + } + +@@ -869,7 +902,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 RegVec; +@@ -961,25 +996,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"; +@@ -989,14 +1039,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"; + +@@ -1012,6 +1070,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"; +@@ -1025,11 +1084,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 RegClassStrings; + +@@ -1044,15 +1106,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) { +@@ -1062,14 +1137,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) { +@@ -1077,13 +1161,20 @@ 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"; + } + + OS << "};\n\n"; + ++#ifndef CAPSTONE + EmitRegMappingTables(OS, Regs, false); + + // Emit Reg encoding table +@@ -1102,7 +1193,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, " +@@ -1123,7 +1216,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 +@@ -1605,8 +1703,10 @@ 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()); +diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp +index 792c957ea..3ddfd1371 100644 +--- a/llvm/utils/TableGen/SubtargetEmitter.cpp ++++ b/llvm/utils/TableGen/SubtargetEmitter.cpp +@@ -149,7 +149,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"; +@@ -160,12 +162,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 + } + + // +@@ -1786,14 +1798,27 @@ void SubtargetEmitter::EmitMCInstrAnalysisPredicateFunctions(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 , 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"; + +@@ -1942,6 +1967,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { + OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; + + EmitMCInstrAnalysisPredicateFunctions(OS); ++#endif + } + + namespace llvm { +diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp +index 38f81dc39..abe172be2 100644 +--- a/llvm/utils/TableGen/TableGen.cpp ++++ b/llvm/utils/TableGen/TableGen.cpp +@@ -27,6 +27,8 @@ enum ActionType { + GenEmitter, + GenRegisterInfo, + GenInstrInfo, ++ GenMappingInsn, ++ GenInsnNameMaps, + GenInstrDocs, + GenAsmWriter, + GenAsmMatcher, +@@ -68,6 +70,10 @@ namespace { + "Generate registers and register classes info"), + clEnumValN(GenInstrInfo, "gen-instr-info", + "Generate instruction descriptions"), ++ clEnumValN(GenMappingInsn, "gen-mapping-insn", ++ ""), ++ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", ++ ""), + clEnumValN(GenInstrDocs, "gen-instr-docs", + "Generate instruction documentation"), + clEnumValN(GenCallingConv, "gen-callingconv", +@@ -143,6 +149,12 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + case GenInstrInfo: + EmitInstrInfo(Records, OS); + break; ++ case GenMappingInsn: ++ EmitMappingInsn(Records, OS); ++ break; ++ case GenInsnNameMaps: ++ EmitInsnNameMaps(Records, OS); ++ break; + case GenInstrDocs: + EmitInstrDocs(Records, OS); + break; +diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h +index 135ec65c0..82f787dba 100644 +--- a/llvm/utils/TableGen/TableGenBackends.h ++++ b/llvm/utils/TableGen/TableGenBackends.h +@@ -74,6 +74,8 @@ 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 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.20.1 + diff --git a/contrib/riscv_update/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch b/contrib/riscv_update/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch new file mode 100644 index 000000000..a395c32a7 --- /dev/null +++ b/contrib/riscv_update/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch @@ -0,0 +1,905 @@ +From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 01:37:55 +0800 +Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE + +--- + llvm/lib/Target/RISCV/CMakeLists.txt | 2 +- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++-- + .../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------ + llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +- + llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +- + llvm/utils/TableGen/TableGen.cpp | 6 + + 6 files changed, 249 insertions(+), 90 deletions(-) + +diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt +index 1821f4b01..603aa3f54 100644 +--- a/llvm/lib/Target/RISCV/CMakeLists.txt ++++ b/llvm/lib/Target/RISCV/CMakeLists.txt +@@ -6,7 +6,7 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) + tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) + tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +-tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) ++tablegen(LLVM RISCVMappingInsn.inc -gen-mapping-insn) + tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) + tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) + tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index c24dc6052..ac82573fe 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) { + /// implementation. Destroys all instances of AsmWriterInst information, by + /// clearing the Instructions vector. + void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { ++#ifdef CAPSTONE ++ bool PassSubtarget = false; ++#else + Record *AsmWriter = Target.getAsmWriter(); +-#ifndef CAPSTONE + StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); +-#endif + bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); +- ++#endif + O << + "/// printInstruction - This method is automatically generated by tablegen\n" + "/// from the instruction set description.\n" +@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + } + + // Emit the initial tab character. +-#ifndef CAPSTONE ++#ifdef CAPSTONE ++ O << "#ifndef CAPSTONE_DIET\n" ++ << " SStream_concat0(O, \"\\t\");\n" ++ << "#endif\n\n"; ++#else + O << " O << \"\\t\";\n\n"; + #endif + +@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + << ((1 << NumBits)-1) << ") {\n" + << " default: " + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid command number.\");\n"; ++#else + << "llvm_unreachable(\"Invalid command number.\");\n"; +- ++#endif + // Print out all the cases. + for (unsigned j = 0, e = Commands.size(); j != e; ++j) { + O << " case " << j << ":\n"; +@@ -576,9 +581,7 @@ 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"; +@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + O << " " + << "assert(RegNo && RegNo < " << (Registers.size()+1) + << " && \"Invalid register number!\");\n" +- << "\n"; ++ << "\n" ++ << "#ifndef CAPSTONE_DIET\n"; + + if (hasAltNames) { + for (const Record *R : AltNameIndices) +@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + if (hasAltNames) { + O << " switch(AltIdx) {\n" + #ifdef CAPSTONE +- << " default: assert(0);\n"; ++ << " default: assert(0 && \"Invalid register alt name index!\");\n"; + #else + << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; + #endif +@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString); + ++#ifndef CAPSTONE // Silence the compiler waring. + StringRef Namespace = Target.getName(); ++#endif + std::vector ReqFeatures; + if (PassSubtarget) { + // We only consider ReqFeatures predicates if PassSubtarget +@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + NumMIOps += ResultInstOpnd.MINumOperands; + + std::string Cond; ++#ifdef CAPSTONE ++ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps); ++#else + Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps); ++#endif + IAP.addCond(Cond); + + bool CantHandle = false; +@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + } + break; + } +- ++#ifdef CAPSTONE ++ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")"; ++#else + std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")"; +- ++#endif + const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i]; + + switch (RO.Kind) { +@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + if (Rec->isSubClassOf("RegisterOperand")) + Rec = Rec->getValueAsDef("RegClass"); + if (Rec->isSubClassOf("RegisterClass")) { ++#ifdef CAPSTONE ++ IAP.addCond("MCOperand_isReg(" + Op + ")"); ++#else + IAP.addCond(Op + ".isReg()"); ++#endif + + if (!IAP.isOpMapped(ROName)) { + IAP.addOperand(ROName, MIOpNum, PrintMethodIdx); + Record *R = CGA.ResultOperands[i].getRecord(); + if (R->isSubClassOf("RegisterOperand")) + R = R->getValueAsDef("RegClass"); ++ ++#ifdef CAPSTONE ++ Cond = std::string("MCRegisterClass_contains(") + ++ "MCRegisterInfo_getRegClass(" + "MRI, " + ++ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" + ++ ", " + ++ "MCOperand_getReg(" + Op + "))"; ++#else + Cond = std::string("MRI.getRegClass(") + Target.getName().str() + + "::" + R->getName().str() + "RegClassID).contains(" + Op + + ".getReg())"; ++#endif ++ + } else { ++#ifdef CAPSTONE ++ Cond = std::string("MCOperand_getReg(") + Op + ") == " + ++ "MCOperand_getReg(MCInst_getOperand(MI, " + ++ utostr(IAP.getOpIndex(ROName)) + "))"; ++#else + Cond = Op + ".getReg() == MI->getOperand(" + + utostr(IAP.getOpIndex(ROName)) + ").getReg()"; ++#endif + } + } else { + // Assume all printable operands are desired for now. This can be +@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + break; // No conditions on this operand at all + } + Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op + ++ #ifdef CAPSTONE ++ ", " + utostr(Entry) + ")").str(); ++ #else + ", STI, " + utostr(Entry) + ")") + .str(); ++ #endif + } + // for all subcases of ResultOperand::K_Record: + IAP.addCond(Cond); +@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + case CodeGenInstAlias::ResultOperand::K_Imm: { + // Just because the alias has an immediate result, doesn't mean the + // MCInst will. An MCExpr could be present, for example. ++#ifdef CAPSTONE ++ IAP.addCond("MCOperand_isImm(" + Op + ")"); ++ Cond = "MCOperand_getImm(" + Op + ") == " + ++ itostr(CGA.ResultOperands[i].getImm()); ++#else + IAP.addCond(Op + ".isImm()"); +- + Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm()); ++#endif ++ + IAP.addCond(Cond); + break; + } +@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + break; + } + ++#ifdef CAPSTONE ++ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() + ++ "_" + CGA.ResultOperands[i].getRegister()->getName().str(); ++#else + Cond = Op + ".getReg() == " + Target.getName().str() + "::" + + CGA.ResultOperands[i].getRegister()->getName().str(); ++#endif ++ + IAP.addCond(Cond); + break; + } +@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (CantHandle) continue; + ++#ifndef CAPSTONE + for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) { + Record *R = *I; + StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); +@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + IAP.addCond(Cond); + } + } ++#endif + + IAPrinterMap[Aliases.first].push_back(std::move(IAP)); + } +@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + std::string Header; + raw_string_ostream HeaderO(Header); + ++#ifdef CAPSTONE ++ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)" ++ << "\n" ++ << "{\n" ++ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n"; ++#else + HeaderO << "bool " << Target.getName() << ClassName + << "::printAliasInstr(const MCInst" + << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") + << "raw_ostream &OS) {\n"; ++#endif + + std::string Cases; + raw_string_ostream CasesO(Cases); +@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (UniqueIAPs.empty()) continue; + ++#ifdef CAPSTONE ++ // TODO: tricky. ++ const char* tmpCase = Entry.first.c_str(); ++ assert (Entry.first.size() > 7); ++ CasesO.indent(2) << "case " ++ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7 ++ << ":\n"; ++#else + CasesO.indent(2) << "case " << Entry.first << ":\n"; ++#endif + + for (IAPrinter *IAP : UniqueIAPs) { + CasesO.indent(4); +@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (!MCOpPredicates.empty()) + O << "static bool " << Target.getName() << ClassName ++#ifdef CAPSTONE ++ << "ValidateMCOperand(MCOperand *MCOp,\n" ++#else + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" ++#endif + << " unsigned PredicateIndex);\n"; + + O << HeaderO.str(); + O.indent(2) << "const char *AsmString;\n"; ++#ifdef CAPSTONE ++ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n"; ++#else + O.indent(2) << "switch (MI->getOpcode()) {\n"; ++#endif + O.indent(2) << "default: return false;\n"; + O << CasesO.str(); + O.indent(2) << "}\n\n"; +@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + // Code that prints the alias, replacing the operands with the ones from the + // MCInst. + O << " unsigned I = 0;\n"; ++#ifdef CAPSTONE ++ O << " char *tmpString = cs_strdup(AsmString);\n"; ++#endif + O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n"; + O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n"; + O << " ++I;\n"; ++#ifdef CAPSTONE ++ O << " tmpString[I] = 0;\n"; ++ O << " SStream_concat0(OS, \"\\t\");\n"; ++ O << " SStream_concat0(OS, tmpString);\n"; ++ O << " SStream_concat0(OS, \"\\n\");\n"; ++#else + O << " OS << '\\t' << StringRef(AsmString, I);\n"; +- ++#endif + O << " if (AsmString[I] != '\\0') {\n"; + O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n"; ++#ifdef CAPSTONE ++ O << " SStream_concat0(OS, \"\\t\");\n"; ++#else + O << " OS << '\\t';\n"; ++#endif + O << " ++I;\n"; + O << " }\n"; + O << " do {\n"; +@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + O << " ++I;\n"; + O << " int OpIdx = AsmString[I++] - 1;\n"; + O << " int PrintMethodIdx = AsmString[I++] - 1;\n"; ++#ifdef CAPSTONE ++ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n"; ++#else + O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, "; + O << (PassSubtarget ? "STI, " : ""); + O << "OS);\n"; ++#endif + O << " } else\n"; ++ ++#ifdef CAPSTONE ++ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n"; ++#else + O << " printOperand(MI, unsigned(AsmString[I++]) - 1, "; + O << (PassSubtarget ? "STI, " : ""); + O << "OS);\n"; ++#endif + O << " } else {\n"; ++#ifdef CAPSTONE ++ O << " SStream_concat0(OS, &AsmString[I++]);\n"; ++#else + O << " OS << AsmString[I++];\n"; ++#endif + O << " }\n"; + O << " } while (AsmString[I] != '\\0');\n"; + O << " }\n\n"; +@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + ////////////////////////////// + // Write out the printCustomAliasOperand function + ////////////////////////////// +- ++#ifdef CAPSTONE ++ O << "static void " ++#else + O << "void " << Target.getName() << ClassName << "::" ++#endif + << "printCustomAliasOperand(\n" ++#ifdef CAPSTONE ++ << " MCInst *MI, unsigned OpIdx,\n" ++#else + << " const MCInst *MI, unsigned OpIdx,\n" ++#endif + << " unsigned PrintMethodIdx,\n" ++#ifdef CAPSTONE ++ << " SStream *OS) {\n"; ++#else + << (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "") + << " raw_ostream &OS) {\n"; ++#endif + if (PrintMethods.empty()) ++#ifdef CAPSTONE ++ O << " assert(0 && \"Unknown PrintMethod kind\");\n"; ++#else + O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n"; ++#endif + else { + O << " switch (PrintMethodIdx) {\n" + << " default:\n" ++#ifdef CAPSTONE ++ << " assert(0 && \"Unknown PrintMethod kind\");\n" ++#else + << " llvm_unreachable(\"Unknown PrintMethod kind\");\n" ++#endif + << " break;\n"; + + for (unsigned i = 0; i < PrintMethods.size(); ++i) { + O << " case " << i << ":\n" + << " " << PrintMethods[i] << "(MI, OpIdx, " ++#ifdef CAPSTONE ++ << "OS);\n" ++#else + << (PassSubtarget ? "STI, " : "") << "OS);\n" ++#endif + << " break;\n"; + } + O << " }\n"; +@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (!MCOpPredicates.empty()) { + O << "static bool " << Target.getName() << ClassName ++#ifdef CAPSTONE ++ << "ValidateMCOperand(MCOperand *MCOp,\n" ++#else + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" +- << " unsigned PredicateIndex) {\n" ++#endif ++ << " unsigned PredicateIndex) {\n" ++#ifdef CAPSTONE ++ << " // TODO: need some constant untils operate the MCOperand,\n" ++ << " // but current CAPSTONE does't have.\n" ++ << " // So, We just return true\n" ++ << " return true;\n\n" ++ << "#if 0\n" ++#endif + << " switch (PredicateIndex) {\n" + << " default:\n" + << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" +@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + llvm_unreachable("Unexpected MCOperandPredicate field!"); + } + O << " }\n" ++#ifdef CAPSTONE ++ << "#endif\n" ++#endif + << "}\n\n"; + } + +@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) { + #endif + EmitPrintInstruction(O); + EmitGetRegisterName(O); +-#ifndef CAPSTONE ++#ifdef CAPSTONE + EmitPrintAliasInstruction(O); + #endif + } +diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +index 3db428dfa..e1bfaa934 100644 +--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +@@ -946,13 +946,6 @@ 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, " +@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, + OS.indent(Indentation) << "switch (Idx) {\n"; + OS.indent(Indentation) << "default: " + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid index!\");\n"; ++#else + << "llvm_unreachable(\"Invalid index!\");\n"; ++#endif + unsigned Index = 0; + for (const auto &Predicate : Predicates) { + OS.indent(Indentation) << "case " << Index++ << ":\n"; + OS.indent(Indentation+2) << "return " +-#ifdef CAPSTONE +- << "getbool" +-#endif +- << "(" << Predicate << ");\n"; ++ << Predicate << ";\n"; + } + OS.indent(Indentation) << "}\n"; + } else { + // No case statement to emit + OS.indent(Indentation) + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid index!\");\n"; ++#else + << "llvm_unreachable(\"Invalid index!\");\n"; ++#endif + } + Indentation -= 2; + OS.indent(Indentation) << "}\n\n"; +@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, + // 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"; ++ 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) << " bool *DecodeComplete) {\\\n"; + #else + #define EDF_EOL "\n" + OS.indent(Indentation) << "template\n"; +@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, + << "Address, const void *Decoder, bool &DecodeComplete) {\n"; + #endif + Indentation += 2; +-#ifndef CAPSTONE ++#ifdef CAPSTONE ++ OS.indent(Indentation) << "*DecodeComplete = true;\\\n"; ++#else + OS.indent(Indentation) << "DecodeComplete = true;\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"; ++#ifdef CAPSTONE ++ << " assert(0 && \"Invalid index!\");\\\n"; + #else +- << " assert(0);\\\n"; ++ << " llvm_unreachable(\"Invalid index!\");\n"; + #endif + unsigned Index = 0; + for (const auto &Decoder : Decoders) { +@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, + + if (Decoder != "") { + OpHasCompleteDecoder = OpInfo.HasCompleteDecoder; ++#ifdef CAPSTONE ++ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0; ++ posOfLeftAngle = Decoder.find("<"); ++ posOfRightAngle = Decoder.find(">"); ++ std::string printDecoder = Decoder; ++ if (posOfLeftAngle != std::string::npos && ++ posOfRightAngle != std::string::npos) { ++ printDecoder = Decoder.substr(0, posOfLeftAngle); ++ o.indent(Indentation) << Emitter->GuardPrefix ++ << printDecoder ++ << "(MI, tmp, Address, Decoder, " ++ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1); ++ } else ++ o.indent(Indentation) << Emitter->GuardPrefix << Decoder ++ << "(MI, tmp, Address, Decoder"; ++ // trick. ++ o << ")" ++#else + o.indent(Indentation) << Emitter->GuardPrefix << Decoder + << "(MI, tmp, Address, Decoder)" ++#endif + << Emitter->GuardPostfix + #ifdef CAPSTONE + << " return MCDisassembler_Fail; \\\n"; +@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, + const std::string &PredicateNamespace) { + if (str[0] == '!') + #ifdef CAPSTONE +- o << "~(Bits & " << PredicateNamespace << "_" ++ o << "!(Bits & " << PredicateNamespace << "_" + << str.slice(1,str.size()) << ")"; + #else + o << "!Bits[" << PredicateNamespace << "::" +@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + #endif + + #ifdef CAPSTONE +- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +- ++ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" ++ << "static DecodeStatus fname(const uint8_t DecodeTable[], " + "MCInst *MI,\\\n" +- << " InsnType insn, uint64_t " ++ << " InsnType insn, uint64_t " + "Address,\\\n" +- << " const void *DisAsm,\\\n" +- << " int feature) {\\\n" +- << " uint64_t Bits = getFeatureBits(feature); \\\n" +- //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" ++ << " const void *DisAsm, int feature) {\\\n" ++ << " uint64_t Bits = getFeatureBits(feature);\\\n" + << "\\\n" + << " const uint8_t *Ptr = DecodeTable;\\\n" + << " uint32_t CurFieldValue = 0;\\\n" +@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " unsigned Start = *++Ptr;\\\n" + << " unsigned Len = *++Ptr;\\\n" + << " ++Ptr;\\\n" +- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" ++ << " CurFieldValue = fieldname(insn, Start, Len);\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_FilterValue: {\\\n" +- << " // Decode the field value.\\\n" + << " unsigned Len;\\\n" + << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" +- << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" +- << " // Perform the filter operation.\\\n" + << " if (Val != CurFieldValue)\\\n" + << " Ptr += NumToSkip;\\\n" +- << "\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_CheckField: {\\\n" + << " unsigned Start = *++Ptr;\\\n" + << " unsigned Len = *++Ptr;\\\n" +- << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +- << " // Decode the field value.\\\n" ++ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\n" + << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" +- << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" +- << " // If the actual and expected values don't match, skip.\\\n" + << " if (ExpectedValue != FieldValue)\\\n" + << " Ptr += NumToSkip;\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_CheckPredicate: {\\\n" + << " unsigned Len;\\\n" +- << " // Decode the Predicate Index value.\\\n" + << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" +- << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" +- << " // Check the predicate.\\\n" + << " bool Pred;\\\n" + << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" + << " Ptr += NumToSkip;\\\n" +@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " }\\\n" + << " case MCD_OPC_Decode: {\\\n" + << " unsigned Len;\\\n" +- << " // Decode the Opcode value.\\\n" + << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " MCInst_clear(MI);\\\n" + << " MCInst_setOpcode(MI, Opc);\\\n" + << " bool DecodeComplete;\\\n" +- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " +- "DecodeComplete);\\\n" ++ << " S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, " ++ "&DecodeComplete);\\\n" + << " assert(DecodeComplete);\\\n" + << "\\\n" + << " return S;\\\n" + << " }\\\n" + << " case MCD_OPC_TryDecode: {\\\n" + << " unsigned Len;\\\n" +- << " // Decode the Opcode value.\\\n" + << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" +- << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" +- << " // Perform the decode operation.\\\n" + << " MCInst TmpMI;\\\n" + << " MCInst_setOpcode(&TmpMI, Opc);\\\n" +- << " bool DecodeComplete;\n" +- << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +- "DecodeComplete);\\\n" ++ << " bool DecodeComplete;\\\n" ++ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " ++ "&DecodeComplete);\\\n" ++ << "\\\n" + << " if (DecodeComplete) {\\\n" +- << " // Decoding complete.\\\n" +- << " MI = &TmpMI;\\\n" ++ << " *MI = TmpMI;\\\n" + << " return S;\\\n" + << " } else {\\\n" + << " assert(S == MCDisassembler_Fail);\\\n" +- << " // If the decoding was incomplete, skip.\\\n" + << " Ptr += NumToSkip;\\\n" +- << " // Reset decode status. This also drops a SoftFail status " +- "that could be\\\n" +- << " // set before the decode attempt.\\\n" + << " S = MCDisassembler_Success;\\\n" + << " }\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_SoftFail: {\\\n" +- << " // Decode the mask values.\\\n" + << " unsigned Len;\\\n" + << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" +@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " }\\\n" + << " }\\\n" + << " }\\\n" +- << " assert(0);\\\n" +- ++ << " assert(0 && \"bogosity detected in disassembler state " ++ "machine!\");\\\n" + #else + OS << "template\n" + << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { + 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"; ++ OS << "// For RISCV instruction is 32 bits.\n"; ++ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n"; ++ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n"; ++ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n"; + #else + OS << "\n} // End llvm namespace\n"; + #endif +diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp +index 01605184f..e59dace24 100644 +--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp ++++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp +@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + #ifdef CAPSTONE + std::string GetPublicName(const CodeGenInstruction *Inst) { + std::string Name = Inst->TheDef->getName(); ++#if 0 + // Apply backward compatibility fixups. + // BRNLE -> BNLER. + if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { +@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { + break; + } + Name = Name.substr(0, pos) + Name.substr(pos + 3); +- } ++ }f 0 + // CPSDRxx -> CPSDR. + if (Name.length() >= 2) { + std::string Suffix2 = Name.substr(Name.length() - 2, 2); +@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { + Name = Name.substr(0, Name.length() - 2); + } + } +- return "SYSZ_INS_" + Name; ++#endif ++ return "RISCV_INS_" + Name; + } + + std::string GetRegisterName(Record *Reg) { +@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) { + for (char& c : Name) { + c = toupper(c); + } ++#if 0 + // R0L, R0D -> R0. + if (Name.length() >= 3 && + Name[Name.length() - 3] == 'R' && +@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) { + Name[Name.length() - 1] == 'D')) { + Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; + } +- return "SYSZ_REG_" + Name; ++#endif ++ return "RISCV_REG_" + Name; + } + + std::string GetGroupName(Record *Pred) { +@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) { + for (char& c : Name) { + c = toupper(c); + } ++#if 0 + if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { + Name = Name.substr(7); + } +- return "SYSZ_GRP_" + Name; ++#endif ++ return "RISCV_GRP_" + Name; + } + + void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { +diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +index 0df306680..cf9c352d7 100644 +--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + #endif + } + +-#ifndef CAPSTONE + const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); + // If the only definition is the default NoRegAltName, we don't need to + // emit anything. + if (RegAltNameIndices.size() > 1) { + OS << "\n// Register alternate name indices\n\n"; ++#ifdef CAPSTONE ++ OS << "enum {\n"; ++ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i) ++ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName() ++ << ",\t// " << i << "\n"; ++ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = " ++ << RegAltNameIndices.size() << "\n"; ++ OS << "};\n"; ++#else + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n"; +@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + OS << "};\n"; + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; ++#endif + } + + auto &SubRegIndices = Bank.getSubRegIndices(); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n\n"; ++#ifdef CAPSTONE ++ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n"; ++ unsigned i = 0; ++ for (const auto &Idx : SubRegIndices) ++ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n"; ++ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n"; ++#else + std::string Namespace = SubRegIndices.front().getNamespace(); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; +@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + OS << " NUM_TARGET_SUBREGS\n};\n"; + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; +- } + #endif ++ } + + #ifndef CAPSTONE + OS << "} // end namespace llvm\n\n"; +diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp +index 9e2a868be..7ec93c0e0 100644 +--- a/llvm/utils/TableGen/TableGen.cpp ++++ b/llvm/utils/TableGen/TableGen.cpp +@@ -27,8 +27,10 @@ enum ActionType { + GenEmitter, + GenRegisterInfo, + GenInstrInfo, ++#ifdef CAPSTONE + GenMappingInsn, + GenInsnNameMaps, ++#endif + GenInstrDocs, + GenAsmWriter, + GenAsmMatcher, +@@ -76,10 +78,12 @@ namespace { + "Generate registers and register classes info"), + clEnumValN(GenInstrInfo, "gen-instr-info", + "Generate instruction descriptions"), ++#ifdef CAPSTONE + clEnumValN(GenMappingInsn, "gen-mapping-insn", + ""), + clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", + ""), ++#endif + clEnumValN(GenInstrDocs, "gen-instr-docs", + "Generate instruction documentation"), + clEnumValN(GenCallingConv, "gen-callingconv", +@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + case GenInstrInfo: + EmitInstrInfo(Records, OS); + break; ++#ifdef CAPSTONE + case GenMappingInsn: + EmitMappingInsn(Records, OS); + break; + case GenInsnNameMaps: + EmitInsnNameMaps(Records, OS); + break; ++#endif + case GenInstrDocs: + EmitInstrDocs(Records, OS); + break; +-- +2.20.1 + diff --git a/contrib/riscv_update/0003-clear-old-patchs.patch b/contrib/riscv_update/0003-clear-old-patchs.patch new file mode 100644 index 000000000..720024662 --- /dev/null +++ b/contrib/riscv_update/0003-clear-old-patchs.patch @@ -0,0 +1,1602 @@ +From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 01:50:13 +0800 +Subject: [PATCH] clear old patchs + +--- + ...apstone-generate-GenRegisterInfo.inc.patch | 338 ------------- + ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ---- + ...3-capstone-generate-GenInstrInfo.inc.patch | 130 ----- + ...e-generate-GenDisassemblerTables.inc.patch | 472 ------------------ + ...5-capstone-generate-GenAsmWriter.inc.patch | 225 --------- + ...06-capstone-generate-MappingInsn.inc.patch | 174 ------- + ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ---- + 7 files changed, 1535 deletions(-) + delete mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch + delete mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch + delete mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch + delete mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch + delete mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch + delete mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch + delete mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch + +diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +deleted file mode 100644 +index b51aa515a..000000000 +--- a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++++ /dev/null +@@ -1,338 +0,0 @@ +-From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 , 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 &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 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 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 +- +diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +deleted file mode 100644 +index 56ad28256..000000000 +--- a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++++ /dev/null +@@ -1,86 +0,0 @@ +-From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 , 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 +- +diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +deleted file mode 100644 +index 2baa59fc9..000000000 +--- a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++++ /dev/null +@@ -1,130 +0,0 @@ +-From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 &Uses, +- unsigned Num, raw_ostream &OS) { +- OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +-@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 +- +diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +deleted file mode 100644 +index 0002b81b4..000000000 +--- a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++++ /dev/null +@@ -1,472 +0,0 @@ +-From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 , 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\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\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\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 \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 +- +diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +deleted file mode 100644 +index cd1353eb7..000000000 +--- a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++++ /dev/null +@@ -1,225 +0,0 @@ +-From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 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 &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 , 2013-2015 */\n" +-+ "\n" +-+ "#include \t// debug\n" +-+ "#include \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 +- +diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch +deleted file mode 100644 +index 7ee22d787..000000000 +--- a/llvm/0006-capstone-generate-MappingInsn.inc.patch ++++ /dev/null +@@ -1,174 +0,0 @@ +-From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 \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 +- +diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +deleted file mode 100644 +index 019540d65..000000000 +--- a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++++ /dev/null +@@ -1,110 +0,0 @@ +-From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 +-From: mephi42 +-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 \n" +-+ "\n"; +-+ CodeGenTarget Target(RK); +-+ std::map 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 +- +-- +2.20.1 + diff --git a/contrib/riscv_update/0004-fix-riscv-registerclass-array-of-genregisterinfo.patch b/contrib/riscv_update/0004-fix-riscv-registerclass-array-of-genregisterinfo.patch new file mode 100644 index 000000000..707062318 --- /dev/null +++ b/contrib/riscv_update/0004-fix-riscv-registerclass-array-of-genregisterinfo.patch @@ -0,0 +1,5743 @@ +From 66794c07a825d5149f72b5072d2de8ba95d5b284 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 21:17:27 +0800 +Subject: [PATCH] fix riscv registerclass array of genregisterinfo + +--- + llvm/0001-capstone-riscv-patchs.patch | 3161 +++++++++++++++++ + ...for-generate-RISCV-port-inc-for-CAPS.patch | 905 +++++ + llvm/0003-clear-old-patchs.patch | 1602 +++++++++ + .../utils/TableGen/FixedLenDecoderEmitter.cpp | 1 - + llvm/utils/TableGen/RegisterInfoEmitter.cpp | 8 +- + 5 files changed, 5672 insertions(+), 5 deletions(-) + create mode 100644 llvm/0001-capstone-riscv-patchs.patch + create mode 100644 llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch + create mode 100644 llvm/0003-clear-old-patchs.patch + +diff --git a/llvm/0001-capstone-riscv-patchs.patch b/llvm/0001-capstone-riscv-patchs.patch +new file mode 100644 +index 000000000..eb3246814 +--- /dev/null ++++ b/llvm/0001-capstone-riscv-patchs.patch +@@ -0,0 +1,3161 @@ ++From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001 ++From: fanfuqiang ++Date: Sun, 17 Feb 2019 06:08:44 +0800 ++Subject: [PATCH] capstone riscv patchs ++ ++--- ++ ...apstone-generate-GenRegisterInfo.inc.patch | 338 +++++++++++++ ++ ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ++++ ++ ...3-capstone-generate-GenInstrInfo.inc.patch | 130 +++++ ++ ...e-generate-GenDisassemblerTables.inc.patch | 472 ++++++++++++++++++ ++ ...5-capstone-generate-GenAsmWriter.inc.patch | 225 +++++++++ ++ ...06-capstone-generate-MappingInsn.inc.patch | 174 +++++++ ++ ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ++++ ++ llvm/lib/Target/RISCV/CMakeLists.txt | 2 + ++ llvm/utils/TableGen/AsmWriterEmitter.cpp | 103 +++- ++ llvm/utils/TableGen/AsmWriterInst.cpp | 4 + ++ llvm/utils/TableGen/DisassemblerEmitter.cpp | 12 +- ++ .../utils/TableGen/FixedLenDecoderEmitter.cpp | 398 ++++++++++++++- ++ llvm/utils/TableGen/InstrInfoEmitter.cpp | 173 ++++++- ++ llvm/utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++- ++ llvm/utils/TableGen/SubtargetEmitter.cpp | 28 +- ++ llvm/utils/TableGen/TableGen.cpp | 12 + ++ llvm/utils/TableGen/TableGenBackends.h | 2 + ++ 17 files changed, 2349 insertions(+), 50 deletions(-) ++ create mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++ create mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++ create mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++ create mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++ create mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++ create mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch ++ create mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++ ++diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++new file mode 100644 ++index 000000000..b51aa515a ++--- /dev/null +++++ b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++@@ -0,0 +1,338 @@ +++From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 , 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 &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 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 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 +++ ++diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++new file mode 100644 ++index 000000000..56ad28256 ++--- /dev/null +++++ b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++@@ -0,0 +1,86 @@ +++From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 , 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 +++ ++diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++new file mode 100644 ++index 000000000..2baa59fc9 ++--- /dev/null +++++ b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++@@ -0,0 +1,130 @@ +++From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 &Uses, +++ unsigned Num, raw_ostream &OS) { +++ OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +++@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 +++ ++diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++new file mode 100644 ++index 000000000..0002b81b4 ++--- /dev/null +++++ b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++@@ -0,0 +1,472 @@ +++From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 , 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\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\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\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 \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 +++ ++diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++new file mode 100644 ++index 000000000..cd1353eb7 ++--- /dev/null +++++ b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++@@ -0,0 +1,225 @@ +++From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 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 &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 , 2013-2015 */\n" ++++ "\n" ++++ "#include \t// debug\n" ++++ "#include \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 +++ ++diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch ++new file mode 100644 ++index 000000000..7ee22d787 ++--- /dev/null +++++ b/llvm/0006-capstone-generate-MappingInsn.inc.patch ++@@ -0,0 +1,174 @@ +++From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 \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 +++ ++diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++new file mode 100644 ++index 000000000..019540d65 ++--- /dev/null +++++ b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++@@ -0,0 +1,110 @@ +++From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 +++From: mephi42 +++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 \n" ++++ "\n"; ++++ CodeGenTarget Target(RK); ++++ std::map 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 +++ ++diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt ++index 07c32cb31..1821f4b01 100644 ++--- a/llvm/lib/Target/RISCV/CMakeLists.txt +++++ b/llvm/lib/Target/RISCV/CMakeLists.txt ++@@ -6,6 +6,8 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) ++ tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) ++ tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) ++ tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +++tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) +++tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) ++ tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) ++ tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) ++ tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) ++diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp ++index 24e16f9c4..c24dc6052 100644 ++--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp ++@@ -271,16 +271,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 StringTable; ++@@ -378,9 +384,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; ++@@ -408,21 +421,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; ++@@ -454,7 +491,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 +++ << "assert(0);\n" +++#endif +++ << "llvm_unreachable(\"Invalid command number.\");\n"; ++ ++ // Print out all the cases. ++ for (unsigned j = 0, e = Commands.size(); j != e; ++j) { ++@@ -535,6 +576,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"; ++@@ -551,8 +595,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 &AltNameIndices = Target.getRegAltNameIndices(); ++ bool hasAltNames = AltNameIndices.size() > 1; ++@@ -562,12 +608,22 @@ 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"; +++ "static const char *"; +++ if (hasAltNames) +++ O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx)\n{\n"; +++ else +++ O << "\ngetRegisterName(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 << " " +++ << "assert(RegNo && RegNo < " << (Registers.size()+1) ++ << " && \"Invalid register number!\");\n" ++ << "\n"; ++ ++@@ -579,12 +635,21 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { ++ ++ if (hasAltNames) { ++ O << " switch(AltIdx) {\n" +++#ifdef CAPSTONE +++ << " default: assert(0);\n"; +++#else ++ << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; +++#endif ++ for (const Record *R : AltNameIndices) { ++ StringRef AltName = R->getName(); ++ O << " case "; ++ if (!Namespace.empty()) ++- O << Namespace << "::"; +++ O << Namespace +++#ifndef CAPSTONE +++ << "::"; +++#else +++ << "_"; +++#endif ++ O << AltName << ":\n" ++ << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName ++ << "[RegNo-1]) &&\n" ++@@ -594,10 +659,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"; ++ } ++ ++@@ -1139,9 +1216,21 @@ 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 , 2013-2015 */\n" +++ "\n" +++ "#include \t// debug\n" +++ "#include \n" +++ "#include \n" +++ "\n" +++ "\n"; +++#endif ++ EmitPrintInstruction(O); ++ EmitGetRegisterName(O); +++#ifndef CAPSTONE ++ EmitPrintAliasInstruction(O); +++#endif ++ } ++ ++ namespace llvm { ++diff --git a/llvm/utils/TableGen/AsmWriterInst.cpp b/llvm/utils/TableGen/AsmWriterInst.cpp ++index d065a4209..7266d1eda 100644 ++--- a/llvm/utils/TableGen/AsmWriterInst.cpp +++++ b/llvm/utils/TableGen/AsmWriterInst.cpp ++@@ -27,9 +27,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) ++diff --git a/llvm/utils/TableGen/DisassemblerEmitter.cpp b/llvm/utils/TableGen/DisassemblerEmitter.cpp ++index 9e75c7fba..1bc0cfa0d 100644 ++--- a/llvm/utils/TableGen/DisassemblerEmitter.cpp +++++ b/llvm/utils/TableGen/DisassemblerEmitter.cpp ++@@ -105,6 +105,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 , 2013-2015 */\n" +++ "\n"; +++#endif ++ ++ // X86 uses a custom disassembler. ++ if (Target.getName() == "X86") { ++@@ -149,7 +154,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/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++index ea28e06cc..3db428dfa 100644 ++--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++@@ -741,7 +741,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) << "-"; ++@@ -750,7 +756,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++ << ", "; ++@@ -773,7 +785,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) ++@@ -794,7 +812,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++ << ", "; ++@@ -823,7 +847,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 << ", "; ++@@ -858,7 +888,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; ++@@ -890,7 +925,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; ++ } ++ } ++@@ -905,23 +946,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 +++ << "assert(0);\n" +++#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 +++ << "assert(0);\n" +++#endif +++ << "llvm_unreachable(\"Invalid index!\");\n"; ++ } ++ Indentation -= 2; ++ OS.indent(Indentation) << "}\n\n"; ++@@ -932,23 +996,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\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 +++ << " assert(0);\\\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"; ++ } ++@@ -1075,16 +1155,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 != "") { ++@@ -1092,8 +1177,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"; ++@@ -1112,7 +1201,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; ++ } ++ ++@@ -1150,10 +1245,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, ++@@ -2090,7 +2194,18 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { ++ << "// * Support shift (<<, >>) with signed and unsigned integers on the " ++ "RHS\n" ++ << "// * Support put (<<) to raw_ostream&\n" ++- << "template\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\n" ++ << "#if defined(_MSC_VER) && !defined(__clang__)\n" ++ << "__declspec(noinline)\n" ++ << "#endif\n" ++@@ -2127,12 +2242,239 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { ++ << " unsigned numBits) {\n" ++ << " return fieldFromInstruction(insn, startBit, numBits, " ++ "std::is_integral());\n" +++#endif ++ << "}\n\n"; ++ } ++ ++ // emitDecodeInstruction - Emit the templated helper function ++ // decodeInstruction(). ++ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +++ +++#if 0 +++ 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" +++#endif +++ +++#ifdef CAPSTONE +++ OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +++ +++ "MCInst *MI,\\\n" +++ << " InsnType insn, uint64_t " +++ "Address,\\\n" +++ << " const void *DisAsm,\\\n" +++ << " int feature) {\\\n" +++ << " uint64_t Bits = getFeatureBits(feature); \\\n" +++ //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" +++ << "\\\n" +++ << " const uint8_t *Ptr = DecodeTable;\\\n" +++ << " uint32_t CurFieldValue = 0;\\\n" +++ << " DecodeStatus S = MCDisassembler_Success;\\\n" +++ << " while (true) {\\\n" +++ << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n" +++ << " switch (*Ptr) {\\\n" +++ << " default:\\\n" +++ << " return MCDisassembler_Fail;\\\n" +++ << " case MCD_OPC_ExtractField: {\\\n" +++ << " unsigned Start = *++Ptr;\\\n" +++ << " unsigned Len = *++Ptr;\\\n" +++ << " ++Ptr;\\\n" +++ << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +++ << " break;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_FilterValue: {\\\n" +++ << " // Decode the field value.\\\n" +++ << " unsigned Len;\\\n" +++ << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " // NumToSkip is a plain 24-bit integer.\\\n" +++ << " unsigned NumToSkip = *Ptr++;\\\n" +++ << " NumToSkip |= (*Ptr++) << 8;\\\n" +++ << " NumToSkip |= (*Ptr++) << 16;\\\n" +++ << "\\\n" +++ << " // Perform the filter operation.\\\n" +++ << " if (Val != CurFieldValue)\\\n" +++ << " Ptr += NumToSkip;\\\n" +++ << "\\\n" +++ << " break;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_CheckField: {\\\n" +++ << " unsigned Start = *++Ptr;\\\n" +++ << " unsigned Len = *++Ptr;\\\n" +++ << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +++ << " // Decode the field value.\\\n" +++ << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " // NumToSkip is a plain 24-bit integer.\\\n" +++ << " unsigned NumToSkip = *Ptr++;\\\n" +++ << " NumToSkip |= (*Ptr++) << 8;\\\n" +++ << " NumToSkip |= (*Ptr++) << 16;\\\n" +++ << "\\\n" +++ << " // If the actual and expected values don't match, skip.\\\n" +++ << " if (ExpectedValue != FieldValue)\\\n" +++ << " Ptr += NumToSkip;\\\n" +++ << " break;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_CheckPredicate: {\\\n" +++ << " unsigned Len;\\\n" +++ << " // Decode the Predicate Index value.\\\n" +++ << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " // NumToSkip is a plain 24-bit integer.\\\n" +++ << " unsigned NumToSkip = *Ptr++;\\\n" +++ << " NumToSkip |= (*Ptr++) << 8;\\\n" +++ << " NumToSkip |= (*Ptr++) << 16;\\\n" +++ << " // Check the predicate.\\\n" +++ << " bool Pred;\\\n" +++ << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" +++ << " Ptr += NumToSkip;\\\n" +++ << " (void)Pred;\\\n" +++ << " break;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_Decode: {\\\n" +++ << " unsigned Len;\\\n" +++ << " // Decode the Opcode value.\\\n" +++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << "\\\n" +++ << " MCInst_clear(MI);\\\n" +++ << " MCInst_setOpcode(MI, Opc);\\\n" +++ << " bool DecodeComplete;\\\n" +++ << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " +++ "DecodeComplete);\\\n" +++ << " assert(DecodeComplete);\\\n" +++ << "\\\n" +++ << " return S;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_TryDecode: {\\\n" +++ << " unsigned Len;\\\n" +++ << " // Decode the Opcode value.\\\n" +++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " // NumToSkip is a plain 24-bit integer.\\\n" +++ << " unsigned NumToSkip = *Ptr++;\\\n" +++ << " NumToSkip |= (*Ptr++) << 8;\\\n" +++ << " NumToSkip |= (*Ptr++) << 16;\\\n" +++ << "\\\n" +++ << " // Perform the decode operation.\\\n" +++ << " MCInst TmpMI;\\\n" +++ << " MCInst_setOpcode(&TmpMI, Opc);\\\n" +++ << " bool DecodeComplete;\n" +++ << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +++ "DecodeComplete);\\\n" +++ << " if (DecodeComplete) {\\\n" +++ << " // Decoding complete.\\\n" +++ << " MI = &TmpMI;\\\n" +++ << " return S;\\\n" +++ << " } else {\\\n" +++ << " assert(S == MCDisassembler_Fail);\\\n" +++ << " // If the decoding was incomplete, skip.\\\n" +++ << " Ptr += NumToSkip;\\\n" +++ << " // Reset decode status. This also drops a SoftFail status " +++ "that could be\\\n" +++ << " // set before the decode attempt.\\\n" +++ << " S = MCDisassembler_Success;\\\n" +++ << " }\\\n" +++ << " break;\\\n" +++ << " }\\\n" +++ << " case MCD_OPC_SoftFail: {\\\n" +++ << " // Decode the mask values.\\\n" +++ << " unsigned Len;\\\n" +++ << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\\\n" +++ << " Ptr += Len;\\\n" +++ << " bool 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" +++ << " assert(0);\\\n" +++ +++#else ++ OS << "template\n" ++ << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " ++ "MCInst &MI,\n" ++@@ -2313,12 +2655,19 @@ 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 << "#include \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"; ++@@ -2327,6 +2676,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { ++ OS << "#include \n"; ++ OS << '\n'; ++ OS << "namespace llvm {\n\n"; +++#endif ++ ++ emitFieldFromInstruction(OS); ++ ++@@ -2401,7 +2751,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 { ++diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp ++index fd8775023..797f42a50 100644 ++--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp ++@@ -92,6 +92,7 @@ private: ++ ++ } // end anonymous namespace ++ +++#ifndef CAPSTONE ++ static void PrintDefList(const std::vector &Uses, ++ unsigned Num, raw_ostream &OS) { ++ OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; ++@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &Uses, ++ OS << getQualifiedName(U) << ", "; ++ OS << "0 };\n"; ++ } +++#endif ++ ++ //===----------------------------------------------------------------------===// ++ // Operand Info Emission. ++@@ -434,8 +436,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 , 2013-2015 */\n" +++ "\n" +++ "\n"; +++#endif +++ ++ emitEnums(OS); ++ +++#ifndef CAPSTONE ++ OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; ++ OS << "#undef GET_INSTRINFO_MC_DESC\n"; ++ ++@@ -563,6 +574,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { ++ emitOperandTypesEnum(OS, Target); ++ ++ emitMCIIHelperMethods(OS, TargetName); +++#endif ++ } ++ ++ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, ++@@ -680,7 +692,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); ++ ++@@ -690,17 +704,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"; ++@@ -717,13 +753,140 @@ 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 +++} +++ +++#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 \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"; +++ } +++} +++ +++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 \n" +++ "\n"; +++ CodeGenTarget Target(RK); +++ std::map 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/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++index 1b619072c..0df306680 100644 ++--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++@@ -98,6 +98,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) { ++@@ -106,13 +112,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 , 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" ++@@ -121,16 +136,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()) { ++@@ -139,18 +158,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 &RegAltNameIndices = Target.getRegAltNameIndices(); ++ // If the only definition is the default NoRegAltName, we don't need to ++ // emit anything. ++@@ -181,8 +211,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"; ++ } ++ ++@@ -869,7 +902,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 RegVec; ++@@ -961,25 +996,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"; ++@@ -989,14 +1039,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"; ++ ++@@ -1012,6 +1070,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"; ++@@ -1025,11 +1084,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 RegClassStrings; ++ ++@@ -1044,15 +1106,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) { ++@@ -1062,14 +1137,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) { ++@@ -1077,13 +1161,20 @@ 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"; ++ } ++ ++ OS << "};\n\n"; ++ +++#ifndef CAPSTONE ++ EmitRegMappingTables(OS, Regs, false); ++ ++ // Emit Reg encoding table ++@@ -1102,7 +1193,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, " ++@@ -1123,7 +1216,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 ++@@ -1605,8 +1703,10 @@ 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()); ++diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp ++index 792c957ea..3ddfd1371 100644 ++--- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++++ b/llvm/utils/TableGen/SubtargetEmitter.cpp ++@@ -149,7 +149,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"; ++@@ -160,12 +162,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 ++ } ++ ++ // ++@@ -1786,14 +1798,27 @@ void SubtargetEmitter::EmitMCInstrAnalysisPredicateFunctions(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 , 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"; ++ ++@@ -1942,6 +1967,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { ++ OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; ++ ++ EmitMCInstrAnalysisPredicateFunctions(OS); +++#endif ++ } ++ ++ namespace llvm { ++diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp ++index 38f81dc39..abe172be2 100644 ++--- a/llvm/utils/TableGen/TableGen.cpp +++++ b/llvm/utils/TableGen/TableGen.cpp ++@@ -27,6 +27,8 @@ enum ActionType { ++ GenEmitter, ++ GenRegisterInfo, ++ GenInstrInfo, +++ GenMappingInsn, +++ GenInsnNameMaps, ++ GenInstrDocs, ++ GenAsmWriter, ++ GenAsmMatcher, ++@@ -68,6 +70,10 @@ namespace { ++ "Generate registers and register classes info"), ++ clEnumValN(GenInstrInfo, "gen-instr-info", ++ "Generate instruction descriptions"), +++ clEnumValN(GenMappingInsn, "gen-mapping-insn", +++ ""), +++ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", +++ ""), ++ clEnumValN(GenInstrDocs, "gen-instr-docs", ++ "Generate instruction documentation"), ++ clEnumValN(GenCallingConv, "gen-callingconv", ++@@ -143,6 +149,12 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { ++ case GenInstrInfo: ++ EmitInstrInfo(Records, OS); ++ break; +++ case GenMappingInsn: +++ EmitMappingInsn(Records, OS); +++ break; +++ case GenInsnNameMaps: +++ EmitInsnNameMaps(Records, OS); +++ break; ++ case GenInstrDocs: ++ EmitInstrDocs(Records, OS); ++ break; ++diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h ++index 135ec65c0..82f787dba 100644 ++--- a/llvm/utils/TableGen/TableGenBackends.h +++++ b/llvm/utils/TableGen/TableGenBackends.h ++@@ -74,6 +74,8 @@ 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 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.20.1 ++ +diff --git a/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch +new file mode 100644 +index 000000000..a395c32a7 +--- /dev/null ++++ b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch +@@ -0,0 +1,905 @@ ++From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 ++From: fanfuqiang ++Date: Thu, 28 Feb 2019 01:37:55 +0800 ++Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE ++ ++--- ++ llvm/lib/Target/RISCV/CMakeLists.txt | 2 +- ++ llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++-- ++ .../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------ ++ llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +- ++ llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +- ++ llvm/utils/TableGen/TableGen.cpp | 6 + ++ 6 files changed, 249 insertions(+), 90 deletions(-) ++ ++diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt ++index 1821f4b01..603aa3f54 100644 ++--- a/llvm/lib/Target/RISCV/CMakeLists.txt +++++ b/llvm/lib/Target/RISCV/CMakeLists.txt ++@@ -6,7 +6,7 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) ++ tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) ++ tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) ++ tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) ++-tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) +++tablegen(LLVM RISCVMappingInsn.inc -gen-mapping-insn) ++ tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) ++ tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) ++ tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) ++diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp ++index c24dc6052..ac82573fe 100644 ++--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp ++@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) { ++ /// implementation. Destroys all instances of AsmWriterInst information, by ++ /// clearing the Instructions vector. ++ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { +++#ifdef CAPSTONE +++ bool PassSubtarget = false; +++#else ++ Record *AsmWriter = Target.getAsmWriter(); ++-#ifndef CAPSTONE ++ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); ++-#endif ++ bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); ++- +++#endif ++ O << ++ "/// printInstruction - This method is automatically generated by tablegen\n" ++ "/// from the instruction set description.\n" ++@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { ++ } ++ ++ // Emit the initial tab character. ++-#ifndef CAPSTONE +++#ifdef CAPSTONE +++ O << "#ifndef CAPSTONE_DIET\n" +++ << " SStream_concat0(O, \"\\t\");\n" +++ << "#endif\n\n"; +++#else ++ O << " O << \"\\t\";\n\n"; ++ #endif ++ ++@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { ++ << ((1 << NumBits)-1) << ") {\n" ++ << " default: " ++ #ifdef CAPSTONE ++- << "assert(0);\n" ++-#endif +++ << "assert(0 && \"Invalid command number.\");\n"; +++#else ++ << "llvm_unreachable(\"Invalid command number.\");\n"; ++- +++#endif ++ // Print out all the cases. ++ for (unsigned j = 0, e = Commands.size(); j != e; ++j) { ++ O << " case " << j << ":\n"; ++@@ -576,9 +581,7 @@ 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"; ++@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { ++ O << " " ++ << "assert(RegNo && RegNo < " << (Registers.size()+1) ++ << " && \"Invalid register number!\");\n" ++- << "\n"; +++ << "\n" +++ << "#ifndef CAPSTONE_DIET\n"; ++ ++ if (hasAltNames) { ++ for (const Record *R : AltNameIndices) ++@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { ++ if (hasAltNames) { ++ O << " switch(AltIdx) {\n" ++ #ifdef CAPSTONE ++- << " default: assert(0);\n"; +++ << " default: assert(0 && \"Invalid register alt name index!\");\n"; ++ #else ++ << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; ++ #endif ++@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ++ IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString); ++ +++#ifndef CAPSTONE // Silence the compiler waring. ++ StringRef Namespace = Target.getName(); +++#endif ++ std::vector ReqFeatures; ++ if (PassSubtarget) { ++ // We only consider ReqFeatures predicates if PassSubtarget ++@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ NumMIOps += ResultInstOpnd.MINumOperands; ++ ++ std::string Cond; +++#ifdef CAPSTONE +++ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps); +++#else ++ Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps); +++#endif ++ IAP.addCond(Cond); ++ ++ bool CantHandle = false; ++@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ } ++ break; ++ } ++- +++#ifdef CAPSTONE +++ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")"; +++#else ++ std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")"; ++- +++#endif ++ const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i]; ++ ++ switch (RO.Kind) { ++@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ if (Rec->isSubClassOf("RegisterOperand")) ++ Rec = Rec->getValueAsDef("RegClass"); ++ if (Rec->isSubClassOf("RegisterClass")) { +++#ifdef CAPSTONE +++ IAP.addCond("MCOperand_isReg(" + Op + ")"); +++#else ++ IAP.addCond(Op + ".isReg()"); +++#endif ++ ++ if (!IAP.isOpMapped(ROName)) { ++ IAP.addOperand(ROName, MIOpNum, PrintMethodIdx); ++ Record *R = CGA.ResultOperands[i].getRecord(); ++ if (R->isSubClassOf("RegisterOperand")) ++ R = R->getValueAsDef("RegClass"); +++ +++#ifdef CAPSTONE +++ Cond = std::string("MCRegisterClass_contains(") + +++ "MCRegisterInfo_getRegClass(" + "MRI, " + +++ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" + +++ ", " + +++ "MCOperand_getReg(" + Op + "))"; +++#else ++ Cond = std::string("MRI.getRegClass(") + Target.getName().str() + ++ "::" + R->getName().str() + "RegClassID).contains(" + Op + ++ ".getReg())"; +++#endif +++ ++ } else { +++#ifdef CAPSTONE +++ Cond = std::string("MCOperand_getReg(") + Op + ") == " + +++ "MCOperand_getReg(MCInst_getOperand(MI, " + +++ utostr(IAP.getOpIndex(ROName)) + "))"; +++#else ++ Cond = Op + ".getReg() == MI->getOperand(" + ++ utostr(IAP.getOpIndex(ROName)) + ").getReg()"; +++#endif ++ } ++ } else { ++ // Assume all printable operands are desired for now. This can be ++@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ break; // No conditions on this operand at all ++ } ++ Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op + +++ #ifdef CAPSTONE +++ ", " + utostr(Entry) + ")").str(); +++ #else ++ ", STI, " + utostr(Entry) + ")") ++ .str(); +++ #endif ++ } ++ // for all subcases of ResultOperand::K_Record: ++ IAP.addCond(Cond); ++@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ case CodeGenInstAlias::ResultOperand::K_Imm: { ++ // Just because the alias has an immediate result, doesn't mean the ++ // MCInst will. An MCExpr could be present, for example. +++#ifdef CAPSTONE +++ IAP.addCond("MCOperand_isImm(" + Op + ")"); +++ Cond = "MCOperand_getImm(" + Op + ") == " + +++ itostr(CGA.ResultOperands[i].getImm()); +++#else ++ IAP.addCond(Op + ".isImm()"); ++- ++ Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm()); +++#endif +++ ++ IAP.addCond(Cond); ++ break; ++ } ++@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ break; ++ } ++ +++#ifdef CAPSTONE +++ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() + +++ "_" + CGA.ResultOperands[i].getRegister()->getName().str(); +++#else ++ Cond = Op + ".getReg() == " + Target.getName().str() + "::" + ++ CGA.ResultOperands[i].getRegister()->getName().str(); +++#endif +++ ++ IAP.addCond(Cond); ++ break; ++ } ++@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ++ if (CantHandle) continue; ++ +++#ifndef CAPSTONE ++ for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) { ++ Record *R = *I; ++ StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); ++@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ IAP.addCond(Cond); ++ } ++ } +++#endif ++ ++ IAPrinterMap[Aliases.first].push_back(std::move(IAP)); ++ } ++@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ std::string Header; ++ raw_string_ostream HeaderO(Header); ++ +++#ifdef CAPSTONE +++ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)" +++ << "\n" +++ << "{\n" +++ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n"; +++#else ++ HeaderO << "bool " << Target.getName() << ClassName ++ << "::printAliasInstr(const MCInst" ++ << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") ++ << "raw_ostream &OS) {\n"; +++#endif ++ ++ std::string Cases; ++ raw_string_ostream CasesO(Cases); ++@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ++ if (UniqueIAPs.empty()) continue; ++ +++#ifdef CAPSTONE +++ // TODO: tricky. +++ const char* tmpCase = Entry.first.c_str(); +++ assert (Entry.first.size() > 7); +++ CasesO.indent(2) << "case " +++ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7 +++ << ":\n"; +++#else ++ CasesO.indent(2) << "case " << Entry.first << ":\n"; +++#endif ++ ++ for (IAPrinter *IAP : UniqueIAPs) { ++ CasesO.indent(4); ++@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ++ if (!MCOpPredicates.empty()) ++ O << "static bool " << Target.getName() << ClassName +++#ifdef CAPSTONE +++ << "ValidateMCOperand(MCOperand *MCOp,\n" +++#else ++ << "ValidateMCOperand(const MCOperand &MCOp,\n" ++ << " const MCSubtargetInfo &STI,\n" +++#endif ++ << " unsigned PredicateIndex);\n"; ++ ++ O << HeaderO.str(); ++ O.indent(2) << "const char *AsmString;\n"; +++#ifdef CAPSTONE +++ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n"; +++#else ++ O.indent(2) << "switch (MI->getOpcode()) {\n"; +++#endif ++ O.indent(2) << "default: return false;\n"; ++ O << CasesO.str(); ++ O.indent(2) << "}\n\n"; ++@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ // Code that prints the alias, replacing the operands with the ones from the ++ // MCInst. ++ O << " unsigned I = 0;\n"; +++#ifdef CAPSTONE +++ O << " char *tmpString = cs_strdup(AsmString);\n"; +++#endif ++ O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n"; ++ O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n"; ++ O << " ++I;\n"; +++#ifdef CAPSTONE +++ O << " tmpString[I] = 0;\n"; +++ O << " SStream_concat0(OS, \"\\t\");\n"; +++ O << " SStream_concat0(OS, tmpString);\n"; +++ O << " SStream_concat0(OS, \"\\n\");\n"; +++#else ++ O << " OS << '\\t' << StringRef(AsmString, I);\n"; ++- +++#endif ++ O << " if (AsmString[I] != '\\0') {\n"; ++ O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n"; +++#ifdef CAPSTONE +++ O << " SStream_concat0(OS, \"\\t\");\n"; +++#else ++ O << " OS << '\\t';\n"; +++#endif ++ O << " ++I;\n"; ++ O << " }\n"; ++ O << " do {\n"; ++@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ O << " ++I;\n"; ++ O << " int OpIdx = AsmString[I++] - 1;\n"; ++ O << " int PrintMethodIdx = AsmString[I++] - 1;\n"; +++#ifdef CAPSTONE +++ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n"; +++#else ++ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, "; ++ O << (PassSubtarget ? "STI, " : ""); ++ O << "OS);\n"; +++#endif ++ O << " } else\n"; +++ +++#ifdef CAPSTONE +++ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n"; +++#else ++ O << " printOperand(MI, unsigned(AsmString[I++]) - 1, "; ++ O << (PassSubtarget ? "STI, " : ""); ++ O << "OS);\n"; +++#endif ++ O << " } else {\n"; +++#ifdef CAPSTONE +++ O << " SStream_concat0(OS, &AsmString[I++]);\n"; +++#else ++ O << " OS << AsmString[I++];\n"; +++#endif ++ O << " }\n"; ++ O << " } while (AsmString[I] != '\\0');\n"; ++ O << " }\n\n"; ++@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ////////////////////////////// ++ // Write out the printCustomAliasOperand function ++ ////////////////////////////// ++- +++#ifdef CAPSTONE +++ O << "static void " +++#else ++ O << "void " << Target.getName() << ClassName << "::" +++#endif ++ << "printCustomAliasOperand(\n" +++#ifdef CAPSTONE +++ << " MCInst *MI, unsigned OpIdx,\n" +++#else ++ << " const MCInst *MI, unsigned OpIdx,\n" +++#endif ++ << " unsigned PrintMethodIdx,\n" +++#ifdef CAPSTONE +++ << " SStream *OS) {\n"; +++#else ++ << (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "") ++ << " raw_ostream &OS) {\n"; +++#endif ++ if (PrintMethods.empty()) +++#ifdef CAPSTONE +++ O << " assert(0 && \"Unknown PrintMethod kind\");\n"; +++#else ++ O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n"; +++#endif ++ else { ++ O << " switch (PrintMethodIdx) {\n" ++ << " default:\n" +++#ifdef CAPSTONE +++ << " assert(0 && \"Unknown PrintMethod kind\");\n" +++#else ++ << " llvm_unreachable(\"Unknown PrintMethod kind\");\n" +++#endif ++ << " break;\n"; ++ ++ for (unsigned i = 0; i < PrintMethods.size(); ++i) { ++ O << " case " << i << ":\n" ++ << " " << PrintMethods[i] << "(MI, OpIdx, " +++#ifdef CAPSTONE +++ << "OS);\n" +++#else ++ << (PassSubtarget ? "STI, " : "") << "OS);\n" +++#endif ++ << " break;\n"; ++ } ++ O << " }\n"; ++@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ ++ if (!MCOpPredicates.empty()) { ++ O << "static bool " << Target.getName() << ClassName +++#ifdef CAPSTONE +++ << "ValidateMCOperand(MCOperand *MCOp,\n" +++#else ++ << "ValidateMCOperand(const MCOperand &MCOp,\n" ++ << " const MCSubtargetInfo &STI,\n" ++- << " unsigned PredicateIndex) {\n" +++#endif +++ << " unsigned PredicateIndex) {\n" +++#ifdef CAPSTONE +++ << " // TODO: need some constant untils operate the MCOperand,\n" +++ << " // but current CAPSTONE does't have.\n" +++ << " // So, We just return true\n" +++ << " return true;\n\n" +++ << "#if 0\n" +++#endif ++ << " switch (PredicateIndex) {\n" ++ << " default:\n" ++ << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" ++@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { ++ llvm_unreachable("Unexpected MCOperandPredicate field!"); ++ } ++ O << " }\n" +++#ifdef CAPSTONE +++ << "#endif\n" +++#endif ++ << "}\n\n"; ++ } ++ ++@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) { ++ #endif ++ EmitPrintInstruction(O); ++ EmitGetRegisterName(O); ++-#ifndef CAPSTONE +++#ifdef CAPSTONE ++ EmitPrintAliasInstruction(O); ++ #endif ++ } ++diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++index 3db428dfa..e1bfaa934 100644 ++--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++@@ -946,13 +946,6 @@ 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, " ++@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, ++ OS.indent(Indentation) << "switch (Idx) {\n"; ++ OS.indent(Indentation) << "default: " ++ #ifdef CAPSTONE ++- << "assert(0);\n" ++-#endif +++ << "assert(0 && \"Invalid index!\");\n"; +++#else ++ << "llvm_unreachable(\"Invalid index!\");\n"; +++#endif ++ unsigned Index = 0; ++ for (const auto &Predicate : Predicates) { ++ OS.indent(Indentation) << "case " << Index++ << ":\n"; ++ OS.indent(Indentation+2) << "return " ++-#ifdef CAPSTONE ++- << "getbool" ++-#endif ++- << "(" << Predicate << ");\n"; +++ << Predicate << ";\n"; ++ } ++ OS.indent(Indentation) << "}\n"; ++ } else { ++ // No case statement to emit ++ OS.indent(Indentation) ++ #ifdef CAPSTONE ++- << "assert(0);\n" ++-#endif +++ << "assert(0 && \"Invalid index!\");\n"; +++#else ++ << "llvm_unreachable(\"Invalid index!\");\n"; +++#endif ++ } ++ Indentation -= 2; ++ OS.indent(Indentation) << "}\n\n"; ++@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, ++ // 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"; +++ 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) << " bool *DecodeComplete) {\\\n"; ++ #else ++ #define EDF_EOL "\n" ++ OS.indent(Indentation) << "template\n"; ++@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, ++ << "Address, const void *Decoder, bool &DecodeComplete) {\n"; ++ #endif ++ Indentation += 2; ++-#ifndef CAPSTONE +++#ifdef CAPSTONE +++ OS.indent(Indentation) << "*DecodeComplete = true;\\\n"; +++#else ++ OS.indent(Indentation) << "DecodeComplete = true;\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"; +++#ifdef CAPSTONE +++ << " assert(0 && \"Invalid index!\");\\\n"; ++ #else ++- << " assert(0);\\\n"; +++ << " llvm_unreachable(\"Invalid index!\");\n"; ++ #endif ++ unsigned Index = 0; ++ for (const auto &Decoder : Decoders) { ++@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, ++ ++ if (Decoder != "") { ++ OpHasCompleteDecoder = OpInfo.HasCompleteDecoder; +++#ifdef CAPSTONE +++ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0; +++ posOfLeftAngle = Decoder.find("<"); +++ posOfRightAngle = Decoder.find(">"); +++ std::string printDecoder = Decoder; +++ if (posOfLeftAngle != std::string::npos && +++ posOfRightAngle != std::string::npos) { +++ printDecoder = Decoder.substr(0, posOfLeftAngle); +++ o.indent(Indentation) << Emitter->GuardPrefix +++ << printDecoder +++ << "(MI, tmp, Address, Decoder, " +++ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1); +++ } else +++ o.indent(Indentation) << Emitter->GuardPrefix << Decoder +++ << "(MI, tmp, Address, Decoder"; +++ // trick. +++ o << ")" +++#else ++ o.indent(Indentation) << Emitter->GuardPrefix << Decoder ++ << "(MI, tmp, Address, Decoder)" +++#endif ++ << Emitter->GuardPostfix ++ #ifdef CAPSTONE ++ << " return MCDisassembler_Fail; \\\n"; ++@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, ++ const std::string &PredicateNamespace) { ++ if (str[0] == '!') ++ #ifdef CAPSTONE ++- o << "~(Bits & " << PredicateNamespace << "_" +++ o << "!(Bits & " << PredicateNamespace << "_" ++ << str.slice(1,str.size()) << ")"; ++ #else ++ o << "!Bits[" << PredicateNamespace << "::" ++@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ #endif ++ ++ #ifdef CAPSTONE ++- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " ++- +++ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" +++ << "static DecodeStatus fname(const uint8_t DecodeTable[], " ++ "MCInst *MI,\\\n" ++- << " InsnType insn, uint64_t " +++ << " InsnType insn, uint64_t " ++ "Address,\\\n" ++- << " const void *DisAsm,\\\n" ++- << " int feature) {\\\n" ++- << " uint64_t Bits = getFeatureBits(feature); \\\n" ++- //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" +++ << " const void *DisAsm, int feature) {\\\n" +++ << " uint64_t Bits = getFeatureBits(feature);\\\n" ++ << "\\\n" ++ << " const uint8_t *Ptr = DecodeTable;\\\n" ++ << " uint32_t CurFieldValue = 0;\\\n" ++@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ << " unsigned Start = *++Ptr;\\\n" ++ << " unsigned Len = *++Ptr;\\\n" ++ << " ++Ptr;\\\n" ++- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +++ << " CurFieldValue = fieldname(insn, Start, Len);\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_FilterValue: {\\\n" ++- << " // Decode the field value.\\\n" ++ << " unsigned Len;\\\n" ++ << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++- << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++- << " // Perform the filter operation.\\\n" ++ << " if (Val != CurFieldValue)\\\n" ++ << " Ptr += NumToSkip;\\\n" ++- << "\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_CheckField: {\\\n" ++ << " unsigned Start = *++Ptr;\\\n" ++ << " unsigned Len = *++Ptr;\\\n" ++- << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" ++- << " // Decode the field value.\\\n" +++ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\n" ++ << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++- << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++- << " // If the actual and expected values don't match, skip.\\\n" ++ << " if (ExpectedValue != FieldValue)\\\n" ++ << " Ptr += NumToSkip;\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_CheckPredicate: {\\\n" ++ << " unsigned Len;\\\n" ++- << " // Decode the Predicate Index value.\\\n" ++ << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++- << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++- << " // Check the predicate.\\\n" ++ << " bool Pred;\\\n" ++ << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" ++ << " Ptr += NumToSkip;\\\n" ++@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ << " }\\\n" ++ << " case MCD_OPC_Decode: {\\\n" ++ << " unsigned Len;\\\n" ++- << " // Decode the Opcode value.\\\n" ++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" ++@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ << " MCInst_clear(MI);\\\n" ++ << " MCInst_setOpcode(MI, Opc);\\\n" ++ << " bool DecodeComplete;\\\n" ++- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " ++- "DecodeComplete);\\\n" +++ << " S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, " +++ "&DecodeComplete);\\\n" ++ << " assert(DecodeComplete);\\\n" ++ << "\\\n" ++ << " return S;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_TryDecode: {\\\n" ++ << " unsigned Len;\\\n" ++- << " // Decode the Opcode value.\\\n" ++ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++- << " // NumToSkip is a plain 24-bit integer.\\\n" ++ << " unsigned NumToSkip = *Ptr++;\\\n" ++ << " NumToSkip |= (*Ptr++) << 8;\\\n" ++ << " NumToSkip |= (*Ptr++) << 16;\\\n" ++ << "\\\n" ++- << " // Perform the decode operation.\\\n" ++ << " MCInst TmpMI;\\\n" ++ << " MCInst_setOpcode(&TmpMI, Opc);\\\n" ++- << " bool DecodeComplete;\n" ++- << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " ++- "DecodeComplete);\\\n" +++ << " bool DecodeComplete;\\\n" +++ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +++ "&DecodeComplete);\\\n" +++ << "\\\n" ++ << " if (DecodeComplete) {\\\n" ++- << " // Decoding complete.\\\n" ++- << " MI = &TmpMI;\\\n" +++ << " *MI = TmpMI;\\\n" ++ << " return S;\\\n" ++ << " } else {\\\n" ++ << " assert(S == MCDisassembler_Fail);\\\n" ++- << " // If the decoding was incomplete, skip.\\\n" ++ << " Ptr += NumToSkip;\\\n" ++- << " // Reset decode status. This also drops a SoftFail status " ++- "that could be\\\n" ++- << " // set before the decode attempt.\\\n" ++ << " S = MCDisassembler_Success;\\\n" ++ << " }\\\n" ++ << " break;\\\n" ++ << " }\\\n" ++ << " case MCD_OPC_SoftFail: {\\\n" ++- << " // Decode the mask values.\\\n" ++ << " unsigned Len;\\\n" ++ << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" ++ << " Ptr += Len;\\\n" ++@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++ << " }\\\n" ++ << " }\\\n" ++ << " }\\\n" ++- << " assert(0);\\\n" ++- +++ << " assert(0 && \"bogosity detected in disassembler state " +++ "machine!\");\\\n" ++ #else ++ OS << "template\n" ++ << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " ++@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { ++ 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"; +++ OS << "// For RISCV instruction is 32 bits.\n"; +++ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n"; +++ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n"; +++ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n"; ++ #else ++ OS << "\n} // End llvm namespace\n"; ++ #endif ++diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp ++index 01605184f..e59dace24 100644 ++--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp ++@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { ++ #ifdef CAPSTONE ++ std::string GetPublicName(const CodeGenInstruction *Inst) { ++ std::string Name = Inst->TheDef->getName(); +++#if 0 ++ // Apply backward compatibility fixups. ++ // BRNLE -> BNLER. ++ if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { ++@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { ++ break; ++ } ++ Name = Name.substr(0, pos) + Name.substr(pos + 3); ++- } +++ }f 0 ++ // CPSDRxx -> CPSDR. ++ if (Name.length() >= 2) { ++ std::string Suffix2 = Name.substr(Name.length() - 2, 2); ++@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { ++ Name = Name.substr(0, Name.length() - 2); ++ } ++ } ++- return "SYSZ_INS_" + Name; +++#endif +++ return "RISCV_INS_" + Name; ++ } ++ ++ std::string GetRegisterName(Record *Reg) { ++@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) { ++ for (char& c : Name) { ++ c = toupper(c); ++ } +++#if 0 ++ // R0L, R0D -> R0. ++ if (Name.length() >= 3 && ++ Name[Name.length() - 3] == 'R' && ++@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) { ++ Name[Name.length() - 1] == 'D')) { ++ Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; ++ } ++- return "SYSZ_REG_" + Name; +++#endif +++ return "RISCV_REG_" + Name; ++ } ++ ++ std::string GetGroupName(Record *Pred) { ++@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) { ++ for (char& c : Name) { ++ c = toupper(c); ++ } +++#if 0 ++ if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { ++ Name = Name.substr(7); ++ } ++- return "SYSZ_GRP_" + Name; +++#endif +++ return "RISCV_GRP_" + Name; ++ } ++ ++ void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { ++diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++index 0df306680..cf9c352d7 100644 ++--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, ++ #endif ++ } ++ ++-#ifndef CAPSTONE ++ const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); ++ // If the only definition is the default NoRegAltName, we don't need to ++ // emit anything. ++ if (RegAltNameIndices.size() > 1) { ++ OS << "\n// Register alternate name indices\n\n"; +++#ifdef CAPSTONE +++ OS << "enum {\n"; +++ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i) +++ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName() +++ << ",\t// " << i << "\n"; +++ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = " +++ << RegAltNameIndices.size() << "\n"; +++ OS << "};\n"; +++#else ++ if (!Namespace.empty()) ++ OS << "namespace " << Namespace << " {\n"; ++ OS << "enum {\n"; ++@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, ++ OS << "};\n"; ++ if (!Namespace.empty()) ++ OS << "} // end namespace " << Namespace << "\n\n"; +++#endif ++ } ++ ++ auto &SubRegIndices = Bank.getSubRegIndices(); ++ if (!SubRegIndices.empty()) { ++ OS << "\n// Subregister indices\n\n"; +++#ifdef CAPSTONE +++ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n"; +++ unsigned i = 0; +++ for (const auto &Idx : SubRegIndices) +++ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n"; +++ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n"; +++#else ++ std::string Namespace = SubRegIndices.front().getNamespace(); ++ if (!Namespace.empty()) ++ OS << "namespace " << Namespace << " {\n"; ++@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, ++ OS << " NUM_TARGET_SUBREGS\n};\n"; ++ if (!Namespace.empty()) ++ OS << "} // end namespace " << Namespace << "\n\n"; ++- } ++ #endif +++ } ++ ++ #ifndef CAPSTONE ++ OS << "} // end namespace llvm\n\n"; ++diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp ++index 9e2a868be..7ec93c0e0 100644 ++--- a/llvm/utils/TableGen/TableGen.cpp +++++ b/llvm/utils/TableGen/TableGen.cpp ++@@ -27,8 +27,10 @@ enum ActionType { ++ GenEmitter, ++ GenRegisterInfo, ++ GenInstrInfo, +++#ifdef CAPSTONE ++ GenMappingInsn, ++ GenInsnNameMaps, +++#endif ++ GenInstrDocs, ++ GenAsmWriter, ++ GenAsmMatcher, ++@@ -76,10 +78,12 @@ namespace { ++ "Generate registers and register classes info"), ++ clEnumValN(GenInstrInfo, "gen-instr-info", ++ "Generate instruction descriptions"), +++#ifdef CAPSTONE ++ clEnumValN(GenMappingInsn, "gen-mapping-insn", ++ ""), ++ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", ++ ""), +++#endif ++ clEnumValN(GenInstrDocs, "gen-instr-docs", ++ "Generate instruction documentation"), ++ clEnumValN(GenCallingConv, "gen-callingconv", ++@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { ++ case GenInstrInfo: ++ EmitInstrInfo(Records, OS); ++ break; +++#ifdef CAPSTONE ++ case GenMappingInsn: ++ EmitMappingInsn(Records, OS); ++ break; ++ case GenInsnNameMaps: ++ EmitInsnNameMaps(Records, OS); ++ break; +++#endif ++ case GenInstrDocs: ++ EmitInstrDocs(Records, OS); ++ break; ++-- ++2.20.1 ++ +diff --git a/llvm/0003-clear-old-patchs.patch b/llvm/0003-clear-old-patchs.patch +new file mode 100644 +index 000000000..720024662 +--- /dev/null ++++ b/llvm/0003-clear-old-patchs.patch +@@ -0,0 +1,1602 @@ ++From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001 ++From: fanfuqiang ++Date: Thu, 28 Feb 2019 01:50:13 +0800 ++Subject: [PATCH] clear old patchs ++ ++--- ++ ...apstone-generate-GenRegisterInfo.inc.patch | 338 ------------- ++ ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ---- ++ ...3-capstone-generate-GenInstrInfo.inc.patch | 130 ----- ++ ...e-generate-GenDisassemblerTables.inc.patch | 472 ------------------ ++ ...5-capstone-generate-GenAsmWriter.inc.patch | 225 --------- ++ ...06-capstone-generate-MappingInsn.inc.patch | 174 ------- ++ ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ---- ++ 7 files changed, 1535 deletions(-) ++ delete mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++ delete mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++ delete mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++ delete mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++ delete mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++ delete mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch ++ delete mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++ ++diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++deleted file mode 100644 ++index b51aa515a..000000000 ++--- a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +++++ /dev/null ++@@ -1,338 +0,0 @@ ++-From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 , 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 &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 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 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 ++- ++diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++deleted file mode 100644 ++index 56ad28256..000000000 ++--- a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +++++ /dev/null ++@@ -1,86 +0,0 @@ ++-From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 , 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 ++- ++diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++deleted file mode 100644 ++index 2baa59fc9..000000000 ++--- a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +++++ /dev/null ++@@ -1,130 +0,0 @@ ++-From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 &Uses, ++- unsigned Num, raw_ostream &OS) { ++- OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; ++-@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 ++- ++diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++deleted file mode 100644 ++index 0002b81b4..000000000 ++--- a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +++++ /dev/null ++@@ -1,472 +0,0 @@ ++-From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 , 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\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\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\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 \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 ++- ++diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++deleted file mode 100644 ++index cd1353eb7..000000000 ++--- a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +++++ /dev/null ++@@ -1,225 +0,0 @@ ++-From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 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 &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 , 2013-2015 */\n" ++-+ "\n" ++-+ "#include \t// debug\n" ++-+ "#include \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 ++- ++diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch ++deleted file mode 100644 ++index 7ee22d787..000000000 ++--- a/llvm/0006-capstone-generate-MappingInsn.inc.patch +++++ /dev/null ++@@ -1,174 +0,0 @@ ++-From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 \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 ++- ++diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++deleted file mode 100644 ++index 019540d65..000000000 ++--- a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +++++ /dev/null ++@@ -1,110 +0,0 @@ ++-From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 ++-From: mephi42 ++-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 \n" ++-+ "\n"; ++-+ CodeGenTarget Target(RK); ++-+ std::map 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 ++- ++-- ++2.20.1 ++ +diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +index e1bfaa934..bf352f717 100644 +--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +@@ -2357,7 +2357,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " uint32_t CurFieldValue = 0;\\\n" + << " DecodeStatus S = MCDisassembler_Success;\\\n" + << " while (true) {\\\n" +- << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n" + << " switch (*Ptr) {\\\n" + << " default:\\\n" + << " return MCDisassembler_Fail;\\\n" +diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +index cf9c352d7..6064a20cd 100644 +--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +@@ -1175,17 +1175,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + for (const auto &RC : RegisterClasses) { + assert(isInt<8>(RC.CopyCost) && "Copy cost too large."); + OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, " +- << RegClassStrings.get(RC.getName()) << ", " +- << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " + #ifdef CAPSTONE +- << NAME_PREFIX RC.getName() ++ << "sizeof(" << RC.getName() << "Bits) },\n"; + #else ++ << RegClassStrings.get(RC.getName()) << ", " ++ << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " + << RC.getQualifiedName() +-#endif + << "RegClassID" << ", " + //<< RegSize/8 << ", " + << RC.CopyCost << ", " + << ( RC.Allocatable ? "true" : "false" ) << " },\n"; ++#endif + } + + OS << "};\n\n"; +-- +2.20.1 + diff --git a/contrib/riscv_update/0005-fix-riscv-registerclass-array-of-genregisterinfo.patch b/contrib/riscv_update/0005-fix-riscv-registerclass-array-of-genregisterinfo.patch new file mode 100644 index 000000000..ec0c9a1ea --- /dev/null +++ b/contrib/riscv_update/0005-fix-riscv-registerclass-array-of-genregisterinfo.patch @@ -0,0 +1,5703 @@ +From 9f8b248761db00ff85959d51258d963d1b8e5627 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 21:18:04 +0800 +Subject: [PATCH] fix riscv registerclass array of genregisterinfo + +--- + llvm/0001-capstone-riscv-patchs.patch | 3161 ----------------- + ...for-generate-RISCV-port-inc-for-CAPS.patch | 905 ----- + llvm/0003-clear-old-patchs.patch | 1602 --------- + 3 files changed, 5668 deletions(-) + delete mode 100644 llvm/0001-capstone-riscv-patchs.patch + delete mode 100644 llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch + delete mode 100644 llvm/0003-clear-old-patchs.patch + +diff --git a/llvm/0001-capstone-riscv-patchs.patch b/llvm/0001-capstone-riscv-patchs.patch +deleted file mode 100644 +index eb3246814..000000000 +--- a/llvm/0001-capstone-riscv-patchs.patch ++++ /dev/null +@@ -1,3161 +0,0 @@ +-From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001 +-From: fanfuqiang +-Date: Sun, 17 Feb 2019 06:08:44 +0800 +-Subject: [PATCH] capstone riscv patchs +- +---- +- ...apstone-generate-GenRegisterInfo.inc.patch | 338 +++++++++++++ +- ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ++++ +- ...3-capstone-generate-GenInstrInfo.inc.patch | 130 +++++ +- ...e-generate-GenDisassemblerTables.inc.patch | 472 ++++++++++++++++++ +- ...5-capstone-generate-GenAsmWriter.inc.patch | 225 +++++++++ +- ...06-capstone-generate-MappingInsn.inc.patch | 174 +++++++ +- ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ++++ +- llvm/lib/Target/RISCV/CMakeLists.txt | 2 + +- llvm/utils/TableGen/AsmWriterEmitter.cpp | 103 +++- +- llvm/utils/TableGen/AsmWriterInst.cpp | 4 + +- llvm/utils/TableGen/DisassemblerEmitter.cpp | 12 +- +- .../utils/TableGen/FixedLenDecoderEmitter.cpp | 398 ++++++++++++++- +- llvm/utils/TableGen/InstrInfoEmitter.cpp | 173 ++++++- +- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++- +- llvm/utils/TableGen/SubtargetEmitter.cpp | 28 +- +- llvm/utils/TableGen/TableGen.cpp | 12 + +- llvm/utils/TableGen/TableGenBackends.h | 2 + +- 17 files changed, 2349 insertions(+), 50 deletions(-) +- create mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +- create mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +- create mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch +- create mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +- create mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch +- create mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch +- create mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +- +-diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +-new file mode 100644 +-index 000000000..b51aa515a +---- /dev/null +-+++ b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +-@@ -0,0 +1,338 @@ +-+From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 , 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 &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 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 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 +-+ +-diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +-new file mode 100644 +-index 000000000..56ad28256 +---- /dev/null +-+++ b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +-@@ -0,0 +1,86 @@ +-+From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 , 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 +-+ +-diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +-new file mode 100644 +-index 000000000..2baa59fc9 +---- /dev/null +-+++ b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +-@@ -0,0 +1,130 @@ +-+From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 &Uses, +-+ unsigned Num, raw_ostream &OS) { +-+ OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +-+@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 +-+ +-diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +-new file mode 100644 +-index 000000000..0002b81b4 +---- /dev/null +-+++ b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +-@@ -0,0 +1,472 @@ +-+From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 , 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\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\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\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 \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 +-+ +-diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +-new file mode 100644 +-index 000000000..cd1353eb7 +---- /dev/null +-+++ b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +-@@ -0,0 +1,225 @@ +-+From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 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 &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 , 2013-2015 */\n" +-++ "\n" +-++ "#include \t// debug\n" +-++ "#include \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 +-+ +-diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch +-new file mode 100644 +-index 000000000..7ee22d787 +---- /dev/null +-+++ b/llvm/0006-capstone-generate-MappingInsn.inc.patch +-@@ -0,0 +1,174 @@ +-+From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 \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 +-+ +-diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +-new file mode 100644 +-index 000000000..019540d65 +---- /dev/null +-+++ b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +-@@ -0,0 +1,110 @@ +-+From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 +-+From: mephi42 +-+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 \n" +-++ "\n"; +-++ CodeGenTarget Target(RK); +-++ std::map 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 +-+ +-diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt +-index 07c32cb31..1821f4b01 100644 +---- a/llvm/lib/Target/RISCV/CMakeLists.txt +-+++ b/llvm/lib/Target/RISCV/CMakeLists.txt +-@@ -6,6 +6,8 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) +- tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) +- tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) +- tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +-+tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) +-+tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) +- tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) +- tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) +- tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) +-diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +-index 24e16f9c4..c24dc6052 100644 +---- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +-+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +-@@ -271,16 +271,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 StringTable; +-@@ -378,9 +384,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; +-@@ -408,21 +421,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; +-@@ -454,7 +491,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 +-+ << "assert(0);\n" +-+#endif +-+ << "llvm_unreachable(\"Invalid command number.\");\n"; +- +- // Print out all the cases. +- for (unsigned j = 0, e = Commands.size(); j != e; ++j) { +-@@ -535,6 +576,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"; +-@@ -551,8 +595,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 &AltNameIndices = Target.getRegAltNameIndices(); +- bool hasAltNames = AltNameIndices.size() > 1; +-@@ -562,12 +608,22 @@ 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"; +-+ "static const char *"; +-+ if (hasAltNames) +-+ O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx)\n{\n"; +-+ else +-+ O << "\ngetRegisterName(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 << " " +-+ << "assert(RegNo && RegNo < " << (Registers.size()+1) +- << " && \"Invalid register number!\");\n" +- << "\n"; +- +-@@ -579,12 +635,21 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { +- +- if (hasAltNames) { +- O << " switch(AltIdx) {\n" +-+#ifdef CAPSTONE +-+ << " default: assert(0);\n"; +-+#else +- << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; +-+#endif +- for (const Record *R : AltNameIndices) { +- StringRef AltName = R->getName(); +- O << " case "; +- if (!Namespace.empty()) +-- O << Namespace << "::"; +-+ O << Namespace +-+#ifndef CAPSTONE +-+ << "::"; +-+#else +-+ << "_"; +-+#endif +- O << AltName << ":\n" +- << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName +- << "[RegNo-1]) &&\n" +-@@ -594,10 +659,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"; +- } +- +-@@ -1139,9 +1216,21 @@ 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 , 2013-2015 */\n" +-+ "\n" +-+ "#include \t// debug\n" +-+ "#include \n" +-+ "#include \n" +-+ "\n" +-+ "\n"; +-+#endif +- EmitPrintInstruction(O); +- EmitGetRegisterName(O); +-+#ifndef CAPSTONE +- EmitPrintAliasInstruction(O); +-+#endif +- } +- +- namespace llvm { +-diff --git a/llvm/utils/TableGen/AsmWriterInst.cpp b/llvm/utils/TableGen/AsmWriterInst.cpp +-index d065a4209..7266d1eda 100644 +---- a/llvm/utils/TableGen/AsmWriterInst.cpp +-+++ b/llvm/utils/TableGen/AsmWriterInst.cpp +-@@ -27,9 +27,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) +-diff --git a/llvm/utils/TableGen/DisassemblerEmitter.cpp b/llvm/utils/TableGen/DisassemblerEmitter.cpp +-index 9e75c7fba..1bc0cfa0d 100644 +---- a/llvm/utils/TableGen/DisassemblerEmitter.cpp +-+++ b/llvm/utils/TableGen/DisassemblerEmitter.cpp +-@@ -105,6 +105,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 , 2013-2015 */\n" +-+ "\n"; +-+#endif +- +- // X86 uses a custom disassembler. +- if (Target.getName() == "X86") { +-@@ -149,7 +154,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/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-index ea28e06cc..3db428dfa 100644 +---- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-@@ -741,7 +741,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) << "-"; +-@@ -750,7 +756,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++ << ", "; +-@@ -773,7 +785,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) +-@@ -794,7 +812,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++ << ", "; +-@@ -823,7 +847,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 << ", "; +-@@ -858,7 +888,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; +-@@ -890,7 +925,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; +- } +- } +-@@ -905,23 +946,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 +-+ << "assert(0);\n" +-+#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 +-+ << "assert(0);\n" +-+#endif +-+ << "llvm_unreachable(\"Invalid index!\");\n"; +- } +- Indentation -= 2; +- OS.indent(Indentation) << "}\n\n"; +-@@ -932,23 +996,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\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 +-+ << " assert(0);\\\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"; +- } +-@@ -1075,16 +1155,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 != "") { +-@@ -1092,8 +1177,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"; +-@@ -1112,7 +1201,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; +- } +- +-@@ -1150,10 +1245,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, +-@@ -2090,7 +2194,18 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { +- << "// * Support shift (<<, >>) with signed and unsigned integers on the " +- "RHS\n" +- << "// * Support put (<<) to raw_ostream&\n" +-- << "template\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\n" +- << "#if defined(_MSC_VER) && !defined(__clang__)\n" +- << "__declspec(noinline)\n" +- << "#endif\n" +-@@ -2127,12 +2242,239 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { +- << " unsigned numBits) {\n" +- << " return fieldFromInstruction(insn, startBit, numBits, " +- "std::is_integral());\n" +-+#endif +- << "}\n\n"; +- } +- +- // emitDecodeInstruction - Emit the templated helper function +- // decodeInstruction(). +- static void emitDecodeInstruction(formatted_raw_ostream &OS) { +-+ +-+#if 0 +-+ 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" +-+#endif +-+ +-+#ifdef CAPSTONE +-+ OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +-+ +-+ "MCInst *MI,\\\n" +-+ << " InsnType insn, uint64_t " +-+ "Address,\\\n" +-+ << " const void *DisAsm,\\\n" +-+ << " int feature) {\\\n" +-+ << " uint64_t Bits = getFeatureBits(feature); \\\n" +-+ //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" +-+ << "\\\n" +-+ << " const uint8_t *Ptr = DecodeTable;\\\n" +-+ << " uint32_t CurFieldValue = 0;\\\n" +-+ << " DecodeStatus S = MCDisassembler_Success;\\\n" +-+ << " while (true) {\\\n" +-+ << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n" +-+ << " switch (*Ptr) {\\\n" +-+ << " default:\\\n" +-+ << " return MCDisassembler_Fail;\\\n" +-+ << " case MCD_OPC_ExtractField: {\\\n" +-+ << " unsigned Start = *++Ptr;\\\n" +-+ << " unsigned Len = *++Ptr;\\\n" +-+ << " ++Ptr;\\\n" +-+ << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +-+ << " break;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_FilterValue: {\\\n" +-+ << " // Decode the field value.\\\n" +-+ << " unsigned Len;\\\n" +-+ << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " // NumToSkip is a plain 24-bit integer.\\\n" +-+ << " unsigned NumToSkip = *Ptr++;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 8;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 16;\\\n" +-+ << "\\\n" +-+ << " // Perform the filter operation.\\\n" +-+ << " if (Val != CurFieldValue)\\\n" +-+ << " Ptr += NumToSkip;\\\n" +-+ << "\\\n" +-+ << " break;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_CheckField: {\\\n" +-+ << " unsigned Start = *++Ptr;\\\n" +-+ << " unsigned Len = *++Ptr;\\\n" +-+ << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +-+ << " // Decode the field value.\\\n" +-+ << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " // NumToSkip is a plain 24-bit integer.\\\n" +-+ << " unsigned NumToSkip = *Ptr++;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 8;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 16;\\\n" +-+ << "\\\n" +-+ << " // If the actual and expected values don't match, skip.\\\n" +-+ << " if (ExpectedValue != FieldValue)\\\n" +-+ << " Ptr += NumToSkip;\\\n" +-+ << " break;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_CheckPredicate: {\\\n" +-+ << " unsigned Len;\\\n" +-+ << " // Decode the Predicate Index value.\\\n" +-+ << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " // NumToSkip is a plain 24-bit integer.\\\n" +-+ << " unsigned NumToSkip = *Ptr++;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 8;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 16;\\\n" +-+ << " // Check the predicate.\\\n" +-+ << " bool Pred;\\\n" +-+ << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" +-+ << " Ptr += NumToSkip;\\\n" +-+ << " (void)Pred;\\\n" +-+ << " break;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_Decode: {\\\n" +-+ << " unsigned Len;\\\n" +-+ << " // Decode the Opcode value.\\\n" +-+ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << "\\\n" +-+ << " MCInst_clear(MI);\\\n" +-+ << " MCInst_setOpcode(MI, Opc);\\\n" +-+ << " bool DecodeComplete;\\\n" +-+ << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " +-+ "DecodeComplete);\\\n" +-+ << " assert(DecodeComplete);\\\n" +-+ << "\\\n" +-+ << " return S;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_TryDecode: {\\\n" +-+ << " unsigned Len;\\\n" +-+ << " // Decode the Opcode value.\\\n" +-+ << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " // NumToSkip is a plain 24-bit integer.\\\n" +-+ << " unsigned NumToSkip = *Ptr++;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 8;\\\n" +-+ << " NumToSkip |= (*Ptr++) << 16;\\\n" +-+ << "\\\n" +-+ << " // Perform the decode operation.\\\n" +-+ << " MCInst TmpMI;\\\n" +-+ << " MCInst_setOpcode(&TmpMI, Opc);\\\n" +-+ << " bool DecodeComplete;\n" +-+ << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +-+ "DecodeComplete);\\\n" +-+ << " if (DecodeComplete) {\\\n" +-+ << " // Decoding complete.\\\n" +-+ << " MI = &TmpMI;\\\n" +-+ << " return S;\\\n" +-+ << " } else {\\\n" +-+ << " assert(S == MCDisassembler_Fail);\\\n" +-+ << " // If the decoding was incomplete, skip.\\\n" +-+ << " Ptr += NumToSkip;\\\n" +-+ << " // Reset decode status. This also drops a SoftFail status " +-+ "that could be\\\n" +-+ << " // set before the decode attempt.\\\n" +-+ << " S = MCDisassembler_Success;\\\n" +-+ << " }\\\n" +-+ << " break;\\\n" +-+ << " }\\\n" +-+ << " case MCD_OPC_SoftFail: {\\\n" +-+ << " // Decode the mask values.\\\n" +-+ << " unsigned Len;\\\n" +-+ << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\\\n" +-+ << " Ptr += Len;\\\n" +-+ << " bool 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" +-+ << " assert(0);\\\n" +-+ +-+#else +- OS << "template\n" +- << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +- "MCInst &MI,\n" +-@@ -2313,12 +2655,19 @@ 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 << "#include \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"; +-@@ -2327,6 +2676,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { +- OS << "#include \n"; +- OS << '\n'; +- OS << "namespace llvm {\n\n"; +-+#endif +- +- emitFieldFromInstruction(OS); +- +-@@ -2401,7 +2751,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 { +-diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp +-index fd8775023..797f42a50 100644 +---- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +-+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp +-@@ -92,6 +92,7 @@ private: +- +- } // end anonymous namespace +- +-+#ifndef CAPSTONE +- static void PrintDefList(const std::vector &Uses, +- unsigned Num, raw_ostream &OS) { +- OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +-@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &Uses, +- OS << getQualifiedName(U) << ", "; +- OS << "0 };\n"; +- } +-+#endif +- +- //===----------------------------------------------------------------------===// +- // Operand Info Emission. +-@@ -434,8 +436,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 , 2013-2015 */\n" +-+ "\n" +-+ "\n"; +-+#endif +-+ +- emitEnums(OS); +- +-+#ifndef CAPSTONE +- OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; +- OS << "#undef GET_INSTRINFO_MC_DESC\n"; +- +-@@ -563,6 +574,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { +- emitOperandTypesEnum(OS, Target); +- +- emitMCIIHelperMethods(OS, TargetName); +-+#endif +- } +- +- void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, +-@@ -680,7 +692,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); +- +-@@ -690,17 +704,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"; +-@@ -717,13 +753,140 @@ 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 +-+} +-+ +-+#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 \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"; +-+ } +-+} +-+ +-+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 \n" +-+ "\n"; +-+ CodeGenTarget Target(RK); +-+ std::map 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/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-index 1b619072c..0df306680 100644 +---- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-@@ -98,6 +98,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) { +-@@ -106,13 +112,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 , 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" +-@@ -121,16 +136,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()) { +-@@ -139,18 +158,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 &RegAltNameIndices = Target.getRegAltNameIndices(); +- // If the only definition is the default NoRegAltName, we don't need to +- // emit anything. +-@@ -181,8 +211,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"; +- } +- +-@@ -869,7 +902,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 RegVec; +-@@ -961,25 +996,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"; +-@@ -989,14 +1039,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"; +- +-@@ -1012,6 +1070,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"; +-@@ -1025,11 +1084,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 RegClassStrings; +- +-@@ -1044,15 +1106,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) { +-@@ -1062,14 +1137,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) { +-@@ -1077,13 +1161,20 @@ 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"; +- } +- +- OS << "};\n\n"; +- +-+#ifndef CAPSTONE +- EmitRegMappingTables(OS, Regs, false); +- +- // Emit Reg encoding table +-@@ -1102,7 +1193,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, " +-@@ -1123,7 +1216,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 +-@@ -1605,8 +1703,10 @@ 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()); +-diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp +-index 792c957ea..3ddfd1371 100644 +---- a/llvm/utils/TableGen/SubtargetEmitter.cpp +-+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp +-@@ -149,7 +149,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"; +-@@ -160,12 +162,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 +- } +- +- // +-@@ -1786,14 +1798,27 @@ void SubtargetEmitter::EmitMCInstrAnalysisPredicateFunctions(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 , 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"; +- +-@@ -1942,6 +1967,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { +- OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; +- +- EmitMCInstrAnalysisPredicateFunctions(OS); +-+#endif +- } +- +- namespace llvm { +-diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp +-index 38f81dc39..abe172be2 100644 +---- a/llvm/utils/TableGen/TableGen.cpp +-+++ b/llvm/utils/TableGen/TableGen.cpp +-@@ -27,6 +27,8 @@ enum ActionType { +- GenEmitter, +- GenRegisterInfo, +- GenInstrInfo, +-+ GenMappingInsn, +-+ GenInsnNameMaps, +- GenInstrDocs, +- GenAsmWriter, +- GenAsmMatcher, +-@@ -68,6 +70,10 @@ namespace { +- "Generate registers and register classes info"), +- clEnumValN(GenInstrInfo, "gen-instr-info", +- "Generate instruction descriptions"), +-+ clEnumValN(GenMappingInsn, "gen-mapping-insn", +-+ ""), +-+ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", +-+ ""), +- clEnumValN(GenInstrDocs, "gen-instr-docs", +- "Generate instruction documentation"), +- clEnumValN(GenCallingConv, "gen-callingconv", +-@@ -143,6 +149,12 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { +- case GenInstrInfo: +- EmitInstrInfo(Records, OS); +- break; +-+ case GenMappingInsn: +-+ EmitMappingInsn(Records, OS); +-+ break; +-+ case GenInsnNameMaps: +-+ EmitInsnNameMaps(Records, OS); +-+ break; +- case GenInstrDocs: +- EmitInstrDocs(Records, OS); +- break; +-diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h +-index 135ec65c0..82f787dba 100644 +---- a/llvm/utils/TableGen/TableGenBackends.h +-+++ b/llvm/utils/TableGen/TableGenBackends.h +-@@ -74,6 +74,8 @@ 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 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.20.1 +- +diff --git a/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch +deleted file mode 100644 +index a395c32a7..000000000 +--- a/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch ++++ /dev/null +@@ -1,905 +0,0 @@ +-From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 +-From: fanfuqiang +-Date: Thu, 28 Feb 2019 01:37:55 +0800 +-Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE +- +---- +- llvm/lib/Target/RISCV/CMakeLists.txt | 2 +- +- llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++-- +- .../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------ +- llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +- +- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +- +- llvm/utils/TableGen/TableGen.cpp | 6 + +- 6 files changed, 249 insertions(+), 90 deletions(-) +- +-diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt +-index 1821f4b01..603aa3f54 100644 +---- a/llvm/lib/Target/RISCV/CMakeLists.txt +-+++ b/llvm/lib/Target/RISCV/CMakeLists.txt +-@@ -6,7 +6,7 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) +- tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) +- tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) +- tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +--tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) +-+tablegen(LLVM RISCVMappingInsn.inc -gen-mapping-insn) +- tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) +- tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) +- tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) +-diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +-index c24dc6052..ac82573fe 100644 +---- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +-+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +-@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) { +- /// implementation. Destroys all instances of AsmWriterInst information, by +- /// clearing the Instructions vector. +- void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { +-+#ifdef CAPSTONE +-+ bool PassSubtarget = false; +-+#else +- Record *AsmWriter = Target.getAsmWriter(); +--#ifndef CAPSTONE +- StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); +--#endif +- bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); +-- +-+#endif +- O << +- "/// printInstruction - This method is automatically generated by tablegen\n" +- "/// from the instruction set description.\n" +-@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { +- } +- +- // Emit the initial tab character. +--#ifndef CAPSTONE +-+#ifdef CAPSTONE +-+ O << "#ifndef CAPSTONE_DIET\n" +-+ << " SStream_concat0(O, \"\\t\");\n" +-+ << "#endif\n\n"; +-+#else +- O << " O << \"\\t\";\n\n"; +- #endif +- +-@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { +- << ((1 << NumBits)-1) << ") {\n" +- << " default: " +- #ifdef CAPSTONE +-- << "assert(0);\n" +--#endif +-+ << "assert(0 && \"Invalid command number.\");\n"; +-+#else +- << "llvm_unreachable(\"Invalid command number.\");\n"; +-- +-+#endif +- // Print out all the cases. +- for (unsigned j = 0, e = Commands.size(); j != e; ++j) { +- O << " case " << j << ":\n"; +-@@ -576,9 +581,7 @@ 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"; +-@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { +- O << " " +- << "assert(RegNo && RegNo < " << (Registers.size()+1) +- << " && \"Invalid register number!\");\n" +-- << "\n"; +-+ << "\n" +-+ << "#ifndef CAPSTONE_DIET\n"; +- +- if (hasAltNames) { +- for (const Record *R : AltNameIndices) +-@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { +- if (hasAltNames) { +- O << " switch(AltIdx) {\n" +- #ifdef CAPSTONE +-- << " default: assert(0);\n"; +-+ << " default: assert(0 && \"Invalid register alt name index!\");\n"; +- #else +- << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; +- #endif +-@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- +- IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString); +- +-+#ifndef CAPSTONE // Silence the compiler waring. +- StringRef Namespace = Target.getName(); +-+#endif +- std::vector ReqFeatures; +- if (PassSubtarget) { +- // We only consider ReqFeatures predicates if PassSubtarget +-@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- NumMIOps += ResultInstOpnd.MINumOperands; +- +- std::string Cond; +-+#ifdef CAPSTONE +-+ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps); +-+#else +- Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps); +-+#endif +- IAP.addCond(Cond); +- +- bool CantHandle = false; +-@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- } +- break; +- } +-- +-+#ifdef CAPSTONE +-+ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")"; +-+#else +- std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")"; +-- +-+#endif +- const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i]; +- +- switch (RO.Kind) { +-@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- if (Rec->isSubClassOf("RegisterOperand")) +- Rec = Rec->getValueAsDef("RegClass"); +- if (Rec->isSubClassOf("RegisterClass")) { +-+#ifdef CAPSTONE +-+ IAP.addCond("MCOperand_isReg(" + Op + ")"); +-+#else +- IAP.addCond(Op + ".isReg()"); +-+#endif +- +- if (!IAP.isOpMapped(ROName)) { +- IAP.addOperand(ROName, MIOpNum, PrintMethodIdx); +- Record *R = CGA.ResultOperands[i].getRecord(); +- if (R->isSubClassOf("RegisterOperand")) +- R = R->getValueAsDef("RegClass"); +-+ +-+#ifdef CAPSTONE +-+ Cond = std::string("MCRegisterClass_contains(") + +-+ "MCRegisterInfo_getRegClass(" + "MRI, " + +-+ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" + +-+ ", " + +-+ "MCOperand_getReg(" + Op + "))"; +-+#else +- Cond = std::string("MRI.getRegClass(") + Target.getName().str() + +- "::" + R->getName().str() + "RegClassID).contains(" + Op + +- ".getReg())"; +-+#endif +-+ +- } else { +-+#ifdef CAPSTONE +-+ Cond = std::string("MCOperand_getReg(") + Op + ") == " + +-+ "MCOperand_getReg(MCInst_getOperand(MI, " + +-+ utostr(IAP.getOpIndex(ROName)) + "))"; +-+#else +- Cond = Op + ".getReg() == MI->getOperand(" + +- utostr(IAP.getOpIndex(ROName)) + ").getReg()"; +-+#endif +- } +- } else { +- // Assume all printable operands are desired for now. This can be +-@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- break; // No conditions on this operand at all +- } +- Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op + +-+ #ifdef CAPSTONE +-+ ", " + utostr(Entry) + ")").str(); +-+ #else +- ", STI, " + utostr(Entry) + ")") +- .str(); +-+ #endif +- } +- // for all subcases of ResultOperand::K_Record: +- IAP.addCond(Cond); +-@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- case CodeGenInstAlias::ResultOperand::K_Imm: { +- // Just because the alias has an immediate result, doesn't mean the +- // MCInst will. An MCExpr could be present, for example. +-+#ifdef CAPSTONE +-+ IAP.addCond("MCOperand_isImm(" + Op + ")"); +-+ Cond = "MCOperand_getImm(" + Op + ") == " + +-+ itostr(CGA.ResultOperands[i].getImm()); +-+#else +- IAP.addCond(Op + ".isImm()"); +-- +- Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm()); +-+#endif +-+ +- IAP.addCond(Cond); +- break; +- } +-@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- break; +- } +- +-+#ifdef CAPSTONE +-+ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() + +-+ "_" + CGA.ResultOperands[i].getRegister()->getName().str(); +-+#else +- Cond = Op + ".getReg() == " + Target.getName().str() + "::" + +- CGA.ResultOperands[i].getRegister()->getName().str(); +-+#endif +-+ +- IAP.addCond(Cond); +- break; +- } +-@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- +- if (CantHandle) continue; +- +-+#ifndef CAPSTONE +- for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) { +- Record *R = *I; +- StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); +-@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- IAP.addCond(Cond); +- } +- } +-+#endif +- +- IAPrinterMap[Aliases.first].push_back(std::move(IAP)); +- } +-@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- std::string Header; +- raw_string_ostream HeaderO(Header); +- +-+#ifdef CAPSTONE +-+ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)" +-+ << "\n" +-+ << "{\n" +-+ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n"; +-+#else +- HeaderO << "bool " << Target.getName() << ClassName +- << "::printAliasInstr(const MCInst" +- << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") +- << "raw_ostream &OS) {\n"; +-+#endif +- +- std::string Cases; +- raw_string_ostream CasesO(Cases); +-@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- +- if (UniqueIAPs.empty()) continue; +- +-+#ifdef CAPSTONE +-+ // TODO: tricky. +-+ const char* tmpCase = Entry.first.c_str(); +-+ assert (Entry.first.size() > 7); +-+ CasesO.indent(2) << "case " +-+ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7 +-+ << ":\n"; +-+#else +- CasesO.indent(2) << "case " << Entry.first << ":\n"; +-+#endif +- +- for (IAPrinter *IAP : UniqueIAPs) { +- CasesO.indent(4); +-@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- +- if (!MCOpPredicates.empty()) +- O << "static bool " << Target.getName() << ClassName +-+#ifdef CAPSTONE +-+ << "ValidateMCOperand(MCOperand *MCOp,\n" +-+#else +- << "ValidateMCOperand(const MCOperand &MCOp,\n" +- << " const MCSubtargetInfo &STI,\n" +-+#endif +- << " unsigned PredicateIndex);\n"; +- +- O << HeaderO.str(); +- O.indent(2) << "const char *AsmString;\n"; +-+#ifdef CAPSTONE +-+ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n"; +-+#else +- O.indent(2) << "switch (MI->getOpcode()) {\n"; +-+#endif +- O.indent(2) << "default: return false;\n"; +- O << CasesO.str(); +- O.indent(2) << "}\n\n"; +-@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- // Code that prints the alias, replacing the operands with the ones from the +- // MCInst. +- O << " unsigned I = 0;\n"; +-+#ifdef CAPSTONE +-+ O << " char *tmpString = cs_strdup(AsmString);\n"; +-+#endif +- O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n"; +- O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n"; +- O << " ++I;\n"; +-+#ifdef CAPSTONE +-+ O << " tmpString[I] = 0;\n"; +-+ O << " SStream_concat0(OS, \"\\t\");\n"; +-+ O << " SStream_concat0(OS, tmpString);\n"; +-+ O << " SStream_concat0(OS, \"\\n\");\n"; +-+#else +- O << " OS << '\\t' << StringRef(AsmString, I);\n"; +-- +-+#endif +- O << " if (AsmString[I] != '\\0') {\n"; +- O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n"; +-+#ifdef CAPSTONE +-+ O << " SStream_concat0(OS, \"\\t\");\n"; +-+#else +- O << " OS << '\\t';\n"; +-+#endif +- O << " ++I;\n"; +- O << " }\n"; +- O << " do {\n"; +-@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- O << " ++I;\n"; +- O << " int OpIdx = AsmString[I++] - 1;\n"; +- O << " int PrintMethodIdx = AsmString[I++] - 1;\n"; +-+#ifdef CAPSTONE +-+ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n"; +-+#else +- O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, "; +- O << (PassSubtarget ? "STI, " : ""); +- O << "OS);\n"; +-+#endif +- O << " } else\n"; +-+ +-+#ifdef CAPSTONE +-+ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n"; +-+#else +- O << " printOperand(MI, unsigned(AsmString[I++]) - 1, "; +- O << (PassSubtarget ? "STI, " : ""); +- O << "OS);\n"; +-+#endif +- O << " } else {\n"; +-+#ifdef CAPSTONE +-+ O << " SStream_concat0(OS, &AsmString[I++]);\n"; +-+#else +- O << " OS << AsmString[I++];\n"; +-+#endif +- O << " }\n"; +- O << " } while (AsmString[I] != '\\0');\n"; +- O << " }\n\n"; +-@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- ////////////////////////////// +- // Write out the printCustomAliasOperand function +- ////////////////////////////// +-- +-+#ifdef CAPSTONE +-+ O << "static void " +-+#else +- O << "void " << Target.getName() << ClassName << "::" +-+#endif +- << "printCustomAliasOperand(\n" +-+#ifdef CAPSTONE +-+ << " MCInst *MI, unsigned OpIdx,\n" +-+#else +- << " const MCInst *MI, unsigned OpIdx,\n" +-+#endif +- << " unsigned PrintMethodIdx,\n" +-+#ifdef CAPSTONE +-+ << " SStream *OS) {\n"; +-+#else +- << (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "") +- << " raw_ostream &OS) {\n"; +-+#endif +- if (PrintMethods.empty()) +-+#ifdef CAPSTONE +-+ O << " assert(0 && \"Unknown PrintMethod kind\");\n"; +-+#else +- O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n"; +-+#endif +- else { +- O << " switch (PrintMethodIdx) {\n" +- << " default:\n" +-+#ifdef CAPSTONE +-+ << " assert(0 && \"Unknown PrintMethod kind\");\n" +-+#else +- << " llvm_unreachable(\"Unknown PrintMethod kind\");\n" +-+#endif +- << " break;\n"; +- +- for (unsigned i = 0; i < PrintMethods.size(); ++i) { +- O << " case " << i << ":\n" +- << " " << PrintMethods[i] << "(MI, OpIdx, " +-+#ifdef CAPSTONE +-+ << "OS);\n" +-+#else +- << (PassSubtarget ? "STI, " : "") << "OS);\n" +-+#endif +- << " break;\n"; +- } +- O << " }\n"; +-@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- +- if (!MCOpPredicates.empty()) { +- O << "static bool " << Target.getName() << ClassName +-+#ifdef CAPSTONE +-+ << "ValidateMCOperand(MCOperand *MCOp,\n" +-+#else +- << "ValidateMCOperand(const MCOperand &MCOp,\n" +- << " const MCSubtargetInfo &STI,\n" +-- << " unsigned PredicateIndex) {\n" +-+#endif +-+ << " unsigned PredicateIndex) {\n" +-+#ifdef CAPSTONE +-+ << " // TODO: need some constant untils operate the MCOperand,\n" +-+ << " // but current CAPSTONE does't have.\n" +-+ << " // So, We just return true\n" +-+ << " return true;\n\n" +-+ << "#if 0\n" +-+#endif +- << " switch (PredicateIndex) {\n" +- << " default:\n" +- << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" +-@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { +- llvm_unreachable("Unexpected MCOperandPredicate field!"); +- } +- O << " }\n" +-+#ifdef CAPSTONE +-+ << "#endif\n" +-+#endif +- << "}\n\n"; +- } +- +-@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) { +- #endif +- EmitPrintInstruction(O); +- EmitGetRegisterName(O); +--#ifndef CAPSTONE +-+#ifdef CAPSTONE +- EmitPrintAliasInstruction(O); +- #endif +- } +-diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-index 3db428dfa..e1bfaa934 100644 +---- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +-@@ -946,13 +946,6 @@ 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, " +-@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, +- OS.indent(Indentation) << "switch (Idx) {\n"; +- OS.indent(Indentation) << "default: " +- #ifdef CAPSTONE +-- << "assert(0);\n" +--#endif +-+ << "assert(0 && \"Invalid index!\");\n"; +-+#else +- << "llvm_unreachable(\"Invalid index!\");\n"; +-+#endif +- unsigned Index = 0; +- for (const auto &Predicate : Predicates) { +- OS.indent(Indentation) << "case " << Index++ << ":\n"; +- OS.indent(Indentation+2) << "return " +--#ifdef CAPSTONE +-- << "getbool" +--#endif +-- << "(" << Predicate << ");\n"; +-+ << Predicate << ";\n"; +- } +- OS.indent(Indentation) << "}\n"; +- } else { +- // No case statement to emit +- OS.indent(Indentation) +- #ifdef CAPSTONE +-- << "assert(0);\n" +--#endif +-+ << "assert(0 && \"Invalid index!\");\n"; +-+#else +- << "llvm_unreachable(\"Invalid index!\");\n"; +-+#endif +- } +- Indentation -= 2; +- OS.indent(Indentation) << "}\n\n"; +-@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, +- // 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"; +-+ 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) << " bool *DecodeComplete) {\\\n"; +- #else +- #define EDF_EOL "\n" +- OS.indent(Indentation) << "template\n"; +-@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, +- << "Address, const void *Decoder, bool &DecodeComplete) {\n"; +- #endif +- Indentation += 2; +--#ifndef CAPSTONE +-+#ifdef CAPSTONE +-+ OS.indent(Indentation) << "*DecodeComplete = true;\\\n"; +-+#else +- OS.indent(Indentation) << "DecodeComplete = true;\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"; +-+#ifdef CAPSTONE +-+ << " assert(0 && \"Invalid index!\");\\\n"; +- #else +-- << " assert(0);\\\n"; +-+ << " llvm_unreachable(\"Invalid index!\");\n"; +- #endif +- unsigned Index = 0; +- for (const auto &Decoder : Decoders) { +-@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, +- +- if (Decoder != "") { +- OpHasCompleteDecoder = OpInfo.HasCompleteDecoder; +-+#ifdef CAPSTONE +-+ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0; +-+ posOfLeftAngle = Decoder.find("<"); +-+ posOfRightAngle = Decoder.find(">"); +-+ std::string printDecoder = Decoder; +-+ if (posOfLeftAngle != std::string::npos && +-+ posOfRightAngle != std::string::npos) { +-+ printDecoder = Decoder.substr(0, posOfLeftAngle); +-+ o.indent(Indentation) << Emitter->GuardPrefix +-+ << printDecoder +-+ << "(MI, tmp, Address, Decoder, " +-+ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1); +-+ } else +-+ o.indent(Indentation) << Emitter->GuardPrefix << Decoder +-+ << "(MI, tmp, Address, Decoder"; +-+ // trick. +-+ o << ")" +-+#else +- o.indent(Indentation) << Emitter->GuardPrefix << Decoder +- << "(MI, tmp, Address, Decoder)" +-+#endif +- << Emitter->GuardPostfix +- #ifdef CAPSTONE +- << " return MCDisassembler_Fail; \\\n"; +-@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, +- const std::string &PredicateNamespace) { +- if (str[0] == '!') +- #ifdef CAPSTONE +-- o << "~(Bits & " << PredicateNamespace << "_" +-+ o << "!(Bits & " << PredicateNamespace << "_" +- << str.slice(1,str.size()) << ")"; +- #else +- o << "!Bits[" << PredicateNamespace << "::" +-@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +- #endif +- +- #ifdef CAPSTONE +-- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +-- +-+ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" +-+ << "static DecodeStatus fname(const uint8_t DecodeTable[], " +- "MCInst *MI,\\\n" +-- << " InsnType insn, uint64_t " +-+ << " InsnType insn, uint64_t " +- "Address,\\\n" +-- << " const void *DisAsm,\\\n" +-- << " int feature) {\\\n" +-- << " uint64_t Bits = getFeatureBits(feature); \\\n" +-- //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" +-+ << " const void *DisAsm, int feature) {\\\n" +-+ << " uint64_t Bits = getFeatureBits(feature);\\\n" +- << "\\\n" +- << " const uint8_t *Ptr = DecodeTable;\\\n" +- << " uint32_t CurFieldValue = 0;\\\n" +-@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +- << " unsigned Start = *++Ptr;\\\n" +- << " unsigned Len = *++Ptr;\\\n" +- << " ++Ptr;\\\n" +-- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +-+ << " CurFieldValue = fieldname(insn, Start, Len);\\\n" +- << " break;\\\n" +- << " }\\\n" +- << " case MCD_OPC_FilterValue: {\\\n" +-- << " // Decode the field value.\\\n" +- << " unsigned Len;\\\n" +- << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +-- << " // NumToSkip is a plain 24-bit integer.\\\n" +- << " unsigned NumToSkip = *Ptr++;\\\n" +- << " NumToSkip |= (*Ptr++) << 8;\\\n" +- << " NumToSkip |= (*Ptr++) << 16;\\\n" +- << "\\\n" +-- << " // Perform the filter operation.\\\n" +- << " if (Val != CurFieldValue)\\\n" +- << " Ptr += NumToSkip;\\\n" +-- << "\\\n" +- << " break;\\\n" +- << " }\\\n" +- << " case MCD_OPC_CheckField: {\\\n" +- << " unsigned Start = *++Ptr;\\\n" +- << " unsigned Len = *++Ptr;\\\n" +-- << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" +-- << " // Decode the field value.\\\n" +-+ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\n" +- << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +-- << " // NumToSkip is a plain 24-bit integer.\\\n" +- << " unsigned NumToSkip = *Ptr++;\\\n" +- << " NumToSkip |= (*Ptr++) << 8;\\\n" +- << " NumToSkip |= (*Ptr++) << 16;\\\n" +- << "\\\n" +-- << " // If the actual and expected values don't match, skip.\\\n" +- << " if (ExpectedValue != FieldValue)\\\n" +- << " Ptr += NumToSkip;\\\n" +- << " break;\\\n" +- << " }\\\n" +- << " case MCD_OPC_CheckPredicate: {\\\n" +- << " unsigned Len;\\\n" +-- << " // Decode the Predicate Index value.\\\n" +- << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +-- << " // NumToSkip is a plain 24-bit integer.\\\n" +- << " unsigned NumToSkip = *Ptr++;\\\n" +- << " NumToSkip |= (*Ptr++) << 8;\\\n" +- << " NumToSkip |= (*Ptr++) << 16;\\\n" +-- << " // Check the predicate.\\\n" +- << " bool Pred;\\\n" +- << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" +- << " Ptr += NumToSkip;\\\n" +-@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +- << " }\\\n" +- << " case MCD_OPC_Decode: {\\\n" +- << " unsigned Len;\\\n" +-- << " // Decode the Opcode value.\\\n" +- << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +- << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +-@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +- << " MCInst_clear(MI);\\\n" +- << " MCInst_setOpcode(MI, Opc);\\\n" +- << " bool DecodeComplete;\\\n" +-- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " +-- "DecodeComplete);\\\n" +-+ << " S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, " +-+ "&DecodeComplete);\\\n" +- << " assert(DecodeComplete);\\\n" +- << "\\\n" +- << " return S;\\\n" +- << " }\\\n" +- << " case MCD_OPC_TryDecode: {\\\n" +- << " unsigned Len;\\\n" +-- << " // Decode the Opcode value.\\\n" +- << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +- << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +-- << " // NumToSkip is a plain 24-bit integer.\\\n" +- << " unsigned NumToSkip = *Ptr++;\\\n" +- << " NumToSkip |= (*Ptr++) << 8;\\\n" +- << " NumToSkip |= (*Ptr++) << 16;\\\n" +- << "\\\n" +-- << " // Perform the decode operation.\\\n" +- << " MCInst TmpMI;\\\n" +- << " MCInst_setOpcode(&TmpMI, Opc);\\\n" +-- << " bool DecodeComplete;\n" +-- << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +-- "DecodeComplete);\\\n" +-+ << " bool DecodeComplete;\\\n" +-+ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " +-+ "&DecodeComplete);\\\n" +-+ << "\\\n" +- << " if (DecodeComplete) {\\\n" +-- << " // Decoding complete.\\\n" +-- << " MI = &TmpMI;\\\n" +-+ << " *MI = TmpMI;\\\n" +- << " return S;\\\n" +- << " } else {\\\n" +- << " assert(S == MCDisassembler_Fail);\\\n" +-- << " // If the decoding was incomplete, skip.\\\n" +- << " Ptr += NumToSkip;\\\n" +-- << " // Reset decode status. This also drops a SoftFail status " +-- "that could be\\\n" +-- << " // set before the decode attempt.\\\n" +- << " S = MCDisassembler_Success;\\\n" +- << " }\\\n" +- << " break;\\\n" +- << " }\\\n" +- << " case MCD_OPC_SoftFail: {\\\n" +-- << " // Decode the mask values.\\\n" +- << " unsigned Len;\\\n" +- << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" +- << " Ptr += Len;\\\n" +-@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { +- << " }\\\n" +- << " }\\\n" +- << " }\\\n" +-- << " assert(0);\\\n" +-- +-+ << " assert(0 && \"bogosity detected in disassembler state " +-+ "machine!\");\\\n" +- #else +- OS << "template\n" +- << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +-@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { +- 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"; +-+ OS << "// For RISCV instruction is 32 bits.\n"; +-+ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n"; +-+ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n"; +-+ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n"; +- #else +- OS << "\n} // End llvm namespace\n"; +- #endif +-diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp +-index 01605184f..e59dace24 100644 +---- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +-+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp +-@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { +- #ifdef CAPSTONE +- std::string GetPublicName(const CodeGenInstruction *Inst) { +- std::string Name = Inst->TheDef->getName(); +-+#if 0 +- // Apply backward compatibility fixups. +- // BRNLE -> BNLER. +- if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { +-@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { +- break; +- } +- Name = Name.substr(0, pos) + Name.substr(pos + 3); +-- } +-+ }f 0 +- // CPSDRxx -> CPSDR. +- if (Name.length() >= 2) { +- std::string Suffix2 = Name.substr(Name.length() - 2, 2); +-@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { +- Name = Name.substr(0, Name.length() - 2); +- } +- } +-- return "SYSZ_INS_" + Name; +-+#endif +-+ return "RISCV_INS_" + Name; +- } +- +- std::string GetRegisterName(Record *Reg) { +-@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) { +- for (char& c : Name) { +- c = toupper(c); +- } +-+#if 0 +- // R0L, R0D -> R0. +- if (Name.length() >= 3 && +- Name[Name.length() - 3] == 'R' && +-@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) { +- Name[Name.length() - 1] == 'D')) { +- Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; +- } +-- return "SYSZ_REG_" + Name; +-+#endif +-+ return "RISCV_REG_" + Name; +- } +- +- std::string GetGroupName(Record *Pred) { +-@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) { +- for (char& c : Name) { +- c = toupper(c); +- } +-+#if 0 +- if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { +- Name = Name.substr(7); +- } +-- return "SYSZ_GRP_" + Name; +-+#endif +-+ return "RISCV_GRP_" + Name; +- } +- +- void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { +-diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-index 0df306680..cf9c352d7 100644 +---- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +-@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, +- #endif +- } +- +--#ifndef CAPSTONE +- const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); +- // If the only definition is the default NoRegAltName, we don't need to +- // emit anything. +- if (RegAltNameIndices.size() > 1) { +- OS << "\n// Register alternate name indices\n\n"; +-+#ifdef CAPSTONE +-+ OS << "enum {\n"; +-+ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i) +-+ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName() +-+ << ",\t// " << i << "\n"; +-+ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = " +-+ << RegAltNameIndices.size() << "\n"; +-+ OS << "};\n"; +-+#else +- if (!Namespace.empty()) +- OS << "namespace " << Namespace << " {\n"; +- OS << "enum {\n"; +-@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, +- OS << "};\n"; +- if (!Namespace.empty()) +- OS << "} // end namespace " << Namespace << "\n\n"; +-+#endif +- } +- +- auto &SubRegIndices = Bank.getSubRegIndices(); +- if (!SubRegIndices.empty()) { +- OS << "\n// Subregister indices\n\n"; +-+#ifdef CAPSTONE +-+ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n"; +-+ unsigned i = 0; +-+ for (const auto &Idx : SubRegIndices) +-+ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n"; +-+ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n"; +-+#else +- std::string Namespace = SubRegIndices.front().getNamespace(); +- if (!Namespace.empty()) +- OS << "namespace " << Namespace << " {\n"; +-@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, +- OS << " NUM_TARGET_SUBREGS\n};\n"; +- if (!Namespace.empty()) +- OS << "} // end namespace " << Namespace << "\n\n"; +-- } +- #endif +-+ } +- +- #ifndef CAPSTONE +- OS << "} // end namespace llvm\n\n"; +-diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp +-index 9e2a868be..7ec93c0e0 100644 +---- a/llvm/utils/TableGen/TableGen.cpp +-+++ b/llvm/utils/TableGen/TableGen.cpp +-@@ -27,8 +27,10 @@ enum ActionType { +- GenEmitter, +- GenRegisterInfo, +- GenInstrInfo, +-+#ifdef CAPSTONE +- GenMappingInsn, +- GenInsnNameMaps, +-+#endif +- GenInstrDocs, +- GenAsmWriter, +- GenAsmMatcher, +-@@ -76,10 +78,12 @@ namespace { +- "Generate registers and register classes info"), +- clEnumValN(GenInstrInfo, "gen-instr-info", +- "Generate instruction descriptions"), +-+#ifdef CAPSTONE +- clEnumValN(GenMappingInsn, "gen-mapping-insn", +- ""), +- clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", +- ""), +-+#endif +- clEnumValN(GenInstrDocs, "gen-instr-docs", +- "Generate instruction documentation"), +- clEnumValN(GenCallingConv, "gen-callingconv", +-@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { +- case GenInstrInfo: +- EmitInstrInfo(Records, OS); +- break; +-+#ifdef CAPSTONE +- case GenMappingInsn: +- EmitMappingInsn(Records, OS); +- break; +- case GenInsnNameMaps: +- EmitInsnNameMaps(Records, OS); +- break; +-+#endif +- case GenInstrDocs: +- EmitInstrDocs(Records, OS); +- break; +--- +-2.20.1 +- +diff --git a/llvm/0003-clear-old-patchs.patch b/llvm/0003-clear-old-patchs.patch +deleted file mode 100644 +index 720024662..000000000 +--- a/llvm/0003-clear-old-patchs.patch ++++ /dev/null +@@ -1,1602 +0,0 @@ +-From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001 +-From: fanfuqiang +-Date: Thu, 28 Feb 2019 01:50:13 +0800 +-Subject: [PATCH] clear old patchs +- +---- +- ...apstone-generate-GenRegisterInfo.inc.patch | 338 ------------- +- ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ---- +- ...3-capstone-generate-GenInstrInfo.inc.patch | 130 ----- +- ...e-generate-GenDisassemblerTables.inc.patch | 472 ------------------ +- ...5-capstone-generate-GenAsmWriter.inc.patch | 225 --------- +- ...06-capstone-generate-MappingInsn.inc.patch | 174 ------- +- ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ---- +- 7 files changed, 1535 deletions(-) +- delete mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +- delete mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +- delete mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch +- delete mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +- delete mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch +- delete mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch +- delete mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +- +-diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +-deleted file mode 100644 +-index b51aa515a..000000000 +---- a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch +-+++ /dev/null +-@@ -1,338 +0,0 @@ +--From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 , 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 &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 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 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 +-- +-diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +-deleted file mode 100644 +-index 56ad28256..000000000 +---- a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch +-+++ /dev/null +-@@ -1,86 +0,0 @@ +--From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 , 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 +-- +-diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +-deleted file mode 100644 +-index 2baa59fc9..000000000 +---- a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch +-+++ /dev/null +-@@ -1,130 +0,0 @@ +--From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 &Uses, +-- unsigned Num, raw_ostream &OS) { +-- OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +--@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &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 , 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 +-- +-diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +-deleted file mode 100644 +-index 0002b81b4..000000000 +---- a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch +-+++ /dev/null +-@@ -1,472 +0,0 @@ +--From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 , 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\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\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\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 \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 +-- +-diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +-deleted file mode 100644 +-index cd1353eb7..000000000 +---- a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch +-+++ /dev/null +-@@ -1,225 +0,0 @@ +--From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 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 &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 , 2013-2015 */\n" +--+ "\n" +--+ "#include \t// debug\n" +--+ "#include \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 +-- +-diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch +-deleted file mode 100644 +-index 7ee22d787..000000000 +---- a/llvm/0006-capstone-generate-MappingInsn.inc.patch +-+++ /dev/null +-@@ -1,174 +0,0 @@ +--From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 \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 +-- +-diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +-deleted file mode 100644 +-index 019540d65..000000000 +---- a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch +-+++ /dev/null +-@@ -1,110 +0,0 @@ +--From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 +--From: mephi42 +--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 \n" +--+ "\n"; +--+ CodeGenTarget Target(RK); +--+ std::map 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 +-- +--- +-2.20.1 +- +-- +2.20.1 + diff --git a/contrib/riscv_update/0006-fix-output-TAB-for-riscv-capstone.patch b/contrib/riscv_update/0006-fix-output-TAB-for-riscv-capstone.patch new file mode 100644 index 000000000..d1614245a --- /dev/null +++ b/contrib/riscv_update/0006-fix-output-TAB-for-riscv-capstone.patch @@ -0,0 +1,32 @@ +From 5adfa13945a8eb1a104db57b29d27ceba0a2d948 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Sun, 3 Mar 2019 23:16:27 +0800 +Subject: [PATCH] fix output TAB for riscv capstone + +--- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index ac82573fe..21630f4ce 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -435,14 +435,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + } + + // Emit the initial tab character. +-#ifdef CAPSTONE +- O << "#ifndef CAPSTONE_DIET\n" +- << " SStream_concat0(O, \"\\t\");\n" +- << "#endif\n\n"; +-#else +- O << " O << \"\\t\";\n\n"; +-#endif +- ++ //O << " O << \"\\t\";\n\n"; + O << " // Emit the opcode for the instruction.\n"; + O << BitsString; + +-- +2.20.1 + diff --git a/contrib/riscv_update/0007-fix-riscv-alias-inst-output-useless-newline.patch b/contrib/riscv_update/0007-fix-riscv-alias-inst-output-useless-newline.patch new file mode 100644 index 000000000..19ccb188c --- /dev/null +++ b/contrib/riscv_update/0007-fix-riscv-alias-inst-output-useless-newline.patch @@ -0,0 +1,32 @@ +From 9028d6a0ce67296be48a3dae07d954ebe26942e1 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 7 Mar 2019 00:08:08 +0800 +Subject: [PATCH] fix riscv alias inst output useless newline + +--- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index 21630f4ce..9db5f7f54 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -1191,14 +1191,13 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + O << " tmpString[I] = 0;\n"; + O << " SStream_concat0(OS, \"\\t\");\n"; + O << " SStream_concat0(OS, tmpString);\n"; +- O << " SStream_concat0(OS, \"\\n\");\n"; + #else + O << " OS << '\\t' << StringRef(AsmString, I);\n"; + #endif + O << " if (AsmString[I] != '\\0') {\n"; + O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n"; + #ifdef CAPSTONE +- O << " SStream_concat0(OS, \"\\t\");\n"; ++ O << " SStream_concat0(OS, \" \");\n"; + #else + O << " OS << '\\t';\n"; + #endif +-- +2.20.1 + diff --git a/contrib/riscv_update/0008-fix-riscv-inst-output-more-formal.patch b/contrib/riscv_update/0008-fix-riscv-inst-output-more-formal.patch new file mode 100644 index 000000000..cdf14d9f3 --- /dev/null +++ b/contrib/riscv_update/0008-fix-riscv-inst-output-more-formal.patch @@ -0,0 +1,24 @@ +From 6830f128011a19e77e8c131cdfcf2f87fb78e316 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 7 Mar 2019 00:31:51 +0800 +Subject: [PATCH] fix riscv inst output more formal + +--- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index 9db5f7f54..fff9f7677 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -1189,7 +1189,6 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + O << " ++I;\n"; + #ifdef CAPSTONE + O << " tmpString[I] = 0;\n"; +- O << " SStream_concat0(OS, \"\\t\");\n"; + O << " SStream_concat0(OS, tmpString);\n"; + #else + O << " OS << '\\t' << StringRef(AsmString, I);\n"; +-- +2.20.1 + diff --git a/contrib/riscv_update/0009-fix-riscv-asmwriter-variable-declaration-place.patch b/contrib/riscv_update/0009-fix-riscv-asmwriter-variable-declaration-place.patch new file mode 100644 index 000000000..caf46707a --- /dev/null +++ b/contrib/riscv_update/0009-fix-riscv-asmwriter-variable-declaration-place.patch @@ -0,0 +1,38 @@ +From b1a7abb285aaa1436d563a30f65813513a512850 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Fri, 8 Mar 2019 11:09:54 +0800 +Subject: [PATCH] fix riscv asmwriter variable declaration place + +--- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index fff9f7677..90540000f 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -1170,6 +1170,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + O << HeaderO.str(); + O.indent(2) << "const char *AsmString;\n"; + #ifdef CAPSTONE ++ O << " unsigned I = 0;\n"; ++ O << " char *tmpString;\n"; + O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n"; + #else + O.indent(2) << "switch (MI->getOpcode()) {\n"; +@@ -1180,9 +1182,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + // Code that prints the alias, replacing the operands with the ones from the + // MCInst. ++#ifndef CAPSTONE + O << " unsigned I = 0;\n"; ++#endif + #ifdef CAPSTONE +- O << " char *tmpString = cs_strdup(AsmString);\n"; ++ O << " tmpString = cs_strdup(AsmString);\n"; + #endif + O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n"; + O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n"; +-- +2.20.1 + diff --git a/contrib/riscv_update/README.md b/contrib/riscv_update/README.md new file mode 100644 index 000000000..48e1a5b19 --- /dev/null +++ b/contrib/riscv_update/README.md @@ -0,0 +1,61 @@ +# How to update RISCV tables. + +* Checkout LLVM. Patches are tested on commit `b81d715c`. + ``` + git clone https://github.com/llvm/llvm-project.git + git checkout b81d715c + ``` +* Apply patches from the current directory. +* Run tablegen. + ``` + cd $LLVM + mkdir build + cd build + cmake -DCMAKE_CXX_FLAGS=-DCAPSTONE -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" .. + make RISCVCommonTableGen + ``` +* Copy `.inc` files. + ``` + cp arch/RISCV/RISCVGenInsnNameMaps.inc \ + arch/RISCV/RISCVGenInsnNameMaps.inc.old + for inc in $(cd arch/RISCV && ls *.inc); do + cp $LLVM/build/lib/Target/RISCV/$inc arch/RISCV/ + done + ``` +* Fixup `RISCVGenInsnNameMaps.inc`. + ``` + comm -1 -3 \ + <(grep RISCV_INS_ arch/RISCV/RISCVGenInsnNameMaps.inc.new + cat arch/RISCV/RISCVGenInsnNameMaps.inc.old \ + arch/RISCV/RISCVGenInsnNameMaps.inc.new \ + >arch/RISCV/RISCVGenInsnNameMaps.inc + ``` +* Add new groups, insns, registers and formats. + * `include/capstone/RISCV.h` + * `enum RISCV_insn`: + ``` + comm -1 -3 \ + <(perl -ne 'if (/(RISCV_INS_.+),/) { print "\t$1,\n" }' \ + mode & CS_MODE_RISCVC) + return 1; + return 4; } } @@ -1437,6 +1461,11 @@ int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type) if (insn->detail->bpf.operands[i].type == (bpf_op_type)op_type) count++; break; + case CS_ARCH_RISCV: + for (i = 0; i < insn->detail->riscv.op_count; i++) + if (insn->detail->riscv.operands[i].type == (riscv_op_type)op_type) + count++; + break; } return count; @@ -1596,6 +1625,14 @@ int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, return i; } break; + case CS_ARCH_RISCV: + for (i = 0; i < insn->detail->riscv.op_count; i++) { + if (insn->detail->riscv.operands[i].type == (riscv_op_type)op_type) + count++; + if (count == post) + return i; + } + break; } return -1; diff --git a/cstool/cstool.c b/cstool/cstool.c index 1b0cf798e..79a7574bf 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -72,6 +72,8 @@ static struct { { "bpfbe", CS_ARCH_BPF, CS_MODE_BIG_ENDIAN | CS_MODE_BPF_CLASSIC }, { "ebpf", CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED }, { "ebpfbe", CS_ARCH_BPF, CS_MODE_BIG_ENDIAN | CS_MODE_BPF_EXTENDED }, + { "riscv32", CS_ARCH_RISCV, CS_MODE_RISCV32 }, + { "riscv64", CS_ARCH_RISCV, CS_MODE_RISCV64 }, { NULL } }; @@ -87,6 +89,7 @@ void print_insn_detail_m68k(csh handle, cs_insn *ins); void print_insn_detail_tms320c64x(csh handle, cs_insn *ins); void print_insn_detail_m680x(csh handle, cs_insn *ins); void print_insn_detail_evm(csh handle, cs_insn *ins); +void print_insn_detail_riscv(csh handle, cs_insn *ins); void print_insn_detail_wasm(csh handle, cs_insn *ins); void print_insn_detail_mos65xx(csh handle, cs_insn *ins); void print_insn_detail_bpf(csh handle, cs_insn *ins); @@ -242,6 +245,11 @@ static void usage(char *prog) printf(" ebpfbe Extended BPF + big endian\n"); } + if (cs_support(CS_ARCH_RISCV)) { + printf(" riscv32 riscv32\n"); + printf(" riscv64 riscv64\n"); + } + printf("\nExtra options:\n"); printf(" -d show detailed information of the instructions\n"); printf(" -s decode in SKIPDATA mode\n"); @@ -297,6 +305,9 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins) case CS_ARCH_BPF: print_insn_detail_bpf(handle, ins); break; + case CS_ARCH_RISCV: + print_insn_detail_riscv(handle, ins); + break; default: break; } @@ -392,7 +403,7 @@ int main(int argc, char **argv) if (cs_support(CS_ARCH_EVM)) { printf("evm=1 "); } - + if (cs_support(CS_ARCH_WASM)) { printf("wasm=1 "); } @@ -405,6 +416,10 @@ int main(int argc, char **argv) printf("bpf=1 "); } + if (cs_support(CS_ARCH_RISCV)) { + printf("riscv=1 "); + } + if (cs_support(CS_SUPPORT_DIET)) { printf("diet=1 "); } diff --git a/cstool/cstool_riscv.c b/cstool/cstool_riscv.c new file mode 100644 index 000000000..2fd5b5be3 --- /dev/null +++ b/cstool/cstool_riscv.c @@ -0,0 +1,46 @@ +/* Capstone Disassembler Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#include +#include + +void print_insn_detail_riscv(csh handle, cs_insn *ins); + +void print_insn_detail_riscv(csh handle, cs_insn *ins) +{ + cs_riscv *riscv; + int i; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + riscv = &(ins->detail->riscv); + if (riscv->op_count) + printf("\top_count: %u\n", riscv->op_count); + + for (i = 0; i < riscv->op_count; i++) { + cs_riscv_op *op = &(riscv->operands[i]); + switch((int)op->type) { + default: + break; + case RISCV_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case RISCV_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%lx\n", i, (long)op->imm); + break; + case RISCV_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != RISCV_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%lx\n", i, (long)op->mem.disp); + + break; + } + } + + printf("\n"); +} diff --git a/include/capstone/capstone.h b/include/capstone/capstone.h index 3defb0e4f..16003127d 100644 --- a/include/capstone/capstone.h +++ b/include/capstone/capstone.h @@ -87,6 +87,7 @@ typedef enum cs_arch { CS_ARCH_MOS65XX, ///< MOS65XX architecture (including MOS6502) CS_ARCH_WASM, ///< WebAssembly architecture CS_ARCH_BPF, ///< Berkeley Packet Filter architecture (including eBPF) + CS_ARCH_RISCV, ///< RISCV architecture CS_ARCH_MAX, CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() } cs_arch; @@ -139,6 +140,9 @@ typedef enum cs_mode { CS_MODE_M680X_HCS08 = 1 << 10, ///< M680X Freescale/NXP HCS08 mode CS_MODE_BPF_CLASSIC = 0, ///< Classic BPF mode (default) CS_MODE_BPF_EXTENDED = 1 << 0, ///< Extended BPF mode + CS_MODE_RISCV32 = 1 << 0, ///< RISCV RV32G + CS_MODE_RISCV64 = 1 << 1, ///< RISCV RV64G + CS_MODE_RISCVC = 1 << 2, ///< RISCV compressed instructure mode } cs_mode; typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); @@ -262,6 +266,7 @@ typedef struct cs_opt_skipdata { /// X86: 1 bytes. /// XCore: 2 bytes. /// EVM: 1 bytes. + /// RISCV: 4 bytes. /// WASM: 1 bytes. /// MOS65XX: 1 bytes. /// BPF: 8 bytes. @@ -284,6 +289,7 @@ typedef struct cs_opt_skipdata { #include "tms320c64x.h" #include "m680x.h" #include "evm.h" +#include "riscv.h" #include "wasm.h" #include "mos65xx.h" #include "bpf.h" @@ -320,6 +326,7 @@ typedef struct cs_detail { cs_mos65xx mos65xx; ///< MOS65XX architecture (including MOS6502) cs_wasm wasm; ///< Web Assembly architecture cs_bpf bpf; ///< Berkeley Packet Filter architecture (including eBPF) + cs_riscv riscv; ///< RISCV architecture }; } cs_detail; diff --git a/include/capstone/riscv.h b/include/capstone/riscv.h new file mode 100644 index 000000000..0a5827051 --- /dev/null +++ b/include/capstone/riscv.h @@ -0,0 +1,531 @@ +#ifndef CAPSTONE_RISCV_H +#define CAPSTONE_RISCV_H + +/* Capstone Disassembly Engine */ +/* RISC-V Backend By Rodrigo Cortes Porto & + Shawn Chang , HardenedLinux@2018 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_MSC_VER) || !defined(_KERNEL_MODE) +#include +#endif + +#include "capstone/platform.h" + +// GCC MIPS toolchain has a default macro called "mips" which breaks +// compilation +//#undef riscv + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Operand type for instruction's operands +typedef enum riscv_op_type { + RISCV_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + RISCV_OP_REG, // = CS_OP_REG (Register operand). + RISCV_OP_IMM, // = CS_OP_IMM (Immediate operand). + RISCV_OP_MEM, // = CS_OP_MEM (Memory operand). +} riscv_op_type; + +// Instruction's operand referring to memory +// This is associated with RISCV_OP_MEM operand type above +typedef struct riscv_op_mem { + unsigned int base; // base register + int64_t disp; // displacement/offset value +} riscv_op_mem; + +// Instruction operand +typedef struct cs_riscv_op { + riscv_op_type type; // operand type + union { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + riscv_op_mem mem; // base/disp value for MEM operand + }; +} cs_riscv_op; + +// Instruction structure +typedef struct cs_riscv { + // Does this instruction need effective address or not. + bool need_effective_addr; + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_riscv_op operands[8]; // operands for this instruction. +} cs_riscv; + +//> RISCV registers +typedef enum riscv_reg { + RISCV_REG_INVALID = 0, + //> General purpose registers + RISCV_REG_X0, // "zero" + RISCV_REG_ZERO = RISCV_REG_X0, // "zero" + RISCV_REG_X1, // "ra" + RISCV_REG_RA = RISCV_REG_X1, // "ra" + RISCV_REG_X2, // "sp" + RISCV_REG_SP = RISCV_REG_X2, // "sp" + RISCV_REG_X3, // "gp" + RISCV_REG_GP = RISCV_REG_X3, // "gp" + RISCV_REG_X4, // "tp" + RISCV_REG_TP = RISCV_REG_X4, // "tp" + RISCV_REG_X5, // "t0" + RISCV_REG_T0 = RISCV_REG_X5, // "t0" + RISCV_REG_X6, // "t1" + RISCV_REG_T1 = RISCV_REG_X6, // "t1" + RISCV_REG_X7, // "t2" + RISCV_REG_T2 = RISCV_REG_X7, // "t2" + RISCV_REG_X8, // "s0/fp" + RISCV_REG_S0 = RISCV_REG_X8, // "s0" + RISCV_REG_FP = RISCV_REG_X8, // "fp" + RISCV_REG_X9, // "s1" + RISCV_REG_S1 = RISCV_REG_X9, // "s1" + RISCV_REG_X10, // "a0" + RISCV_REG_A0 = RISCV_REG_X10, // "a0" + RISCV_REG_X11, // "a1" + RISCV_REG_A1 = RISCV_REG_X11, // "a1" + RISCV_REG_X12, // "a2" + RISCV_REG_A2 = RISCV_REG_X12, // "a2" + RISCV_REG_X13, // "a3" + RISCV_REG_A3 = RISCV_REG_X13, // "a3" + RISCV_REG_X14, // "a4" + RISCV_REG_A4 = RISCV_REG_X14, // "a4" + RISCV_REG_X15, // "a5" + RISCV_REG_A5 = RISCV_REG_X15, // "a5" + RISCV_REG_X16, // "a6" + RISCV_REG_A6 = RISCV_REG_X16, // "a6" + RISCV_REG_X17, // "a7" + RISCV_REG_A7 = RISCV_REG_X17, // "a7" + RISCV_REG_X18, // "s2" + RISCV_REG_S2 = RISCV_REG_X18, // "s2" + RISCV_REG_X19, // "s3" + RISCV_REG_S3 = RISCV_REG_X19, // "s3" + RISCV_REG_X20, // "s4" + RISCV_REG_S4 = RISCV_REG_X20, // "s4" + RISCV_REG_X21, // "s5" + RISCV_REG_S5 = RISCV_REG_X21, // "s5" + RISCV_REG_X22, // "s6" + RISCV_REG_S6 = RISCV_REG_X22, // "s6" + RISCV_REG_X23, // "s7" + RISCV_REG_S7 = RISCV_REG_X23, // "s7" + RISCV_REG_X24, // "s8" + RISCV_REG_S8 = RISCV_REG_X24, // "s8" + RISCV_REG_X25, // "s9" + RISCV_REG_S9 = RISCV_REG_X25, // "s9" + RISCV_REG_X26, // "s10" + RISCV_REG_S10 = RISCV_REG_X26, // "s10" + RISCV_REG_X27, // "s11" + RISCV_REG_S11 = RISCV_REG_X27, // "s11" + RISCV_REG_X28, // "t3" + RISCV_REG_T3 = RISCV_REG_X28, // "t3" + RISCV_REG_X29, // "t4" + RISCV_REG_T4 = RISCV_REG_X29, // "t4" + RISCV_REG_X30, // "t5" + RISCV_REG_T5 = RISCV_REG_X30, // "t5" + RISCV_REG_X31, // "t6" + RISCV_REG_T6 = RISCV_REG_X31, // "t6" + + //> Floating-point registers + RISCV_REG_F0_32, // "ft0" + RISCV_REG_F0_64, // "ft0" + RISCV_REG_F1_32, // "ft1" + RISCV_REG_F1_64, // "ft1" + RISCV_REG_F2_32, // "ft2" + RISCV_REG_F2_64, // "ft2" + RISCV_REG_F3_32, // "ft3" + RISCV_REG_F3_64, // "ft3" + RISCV_REG_F4_32, // "ft4" + RISCV_REG_F4_64, // "ft4" + RISCV_REG_F5_32, // "ft5" + RISCV_REG_F5_64, // "ft5" + RISCV_REG_F6_32, // "ft6" + RISCV_REG_F6_64, // "ft6" + RISCV_REG_F7_32, // "ft7" + RISCV_REG_F7_64, // "ft7" + RISCV_REG_F8_32, // "fs0" + RISCV_REG_F8_64, // "fs0" + RISCV_REG_F9_32, // "fs1" + RISCV_REG_F9_64, // "fs1" + RISCV_REG_F10_32, // "fa0" + RISCV_REG_F10_64, // "fa0" + RISCV_REG_F11_32, // "fa1" + RISCV_REG_F11_64, // "fa1" + RISCV_REG_F12_32, // "fa2" + RISCV_REG_F12_64, // "fa2" + RISCV_REG_F13_32, // "fa3" + RISCV_REG_F13_64, // "fa3" + RISCV_REG_F14_32, // "fa4" + RISCV_REG_F14_64, // "fa4" + RISCV_REG_F15_32, // "fa5" + RISCV_REG_F15_64, // "fa5" + RISCV_REG_F16_32, // "fa6" + RISCV_REG_F16_64, // "fa6" + RISCV_REG_F17_32, // "fa7" + RISCV_REG_F17_64, // "fa7" + RISCV_REG_F18_32, // "fs2" + RISCV_REG_F18_64, // "fs2" + RISCV_REG_F19_32, // "fs3" + RISCV_REG_F19_64, // "fs3" + RISCV_REG_F20_32, // "fs4" + RISCV_REG_F20_64, // "fs4" + RISCV_REG_F21_32, // "fs5" + RISCV_REG_F21_64, // "fs5" + RISCV_REG_F22_32, // "fs6" + RISCV_REG_F22_64, // "fs6" + RISCV_REG_F23_32, // "fs7" + RISCV_REG_F23_64, // "fs7" + RISCV_REG_F24_32, // "fs8" + RISCV_REG_F24_64, // "fs8" + RISCV_REG_F25_32, // "fs9" + RISCV_REG_F25_64, // "fs9" + RISCV_REG_F26_32, // "fs10" + RISCV_REG_F26_64, // "fs10" + RISCV_REG_F27_32, // "fs11" + RISCV_REG_F27_64, // "fs11" + RISCV_REG_F28_32, // "ft8" + RISCV_REG_F28_64, // "ft8" + RISCV_REG_F29_32, // "ft9" + RISCV_REG_F29_64, // "ft9" + RISCV_REG_F30_32, // "ft10" + RISCV_REG_F30_64, // "ft10" + RISCV_REG_F31_32, // "ft11" + RISCV_REG_F31_64, // "ft11" + + RISCV_REG_ENDING, // <-- mark the end of the list or registers +} riscv_reg; + +//> RISCV instruction +typedef enum riscv_insn { + RISCV_INS_INVALID = 0, + + RISCV_INS_ADD, + RISCV_INS_ADDI, + RISCV_INS_ADDIW, + RISCV_INS_ADDW, + RISCV_INS_AMOADD_D, + RISCV_INS_AMOADD_D_AQ, + RISCV_INS_AMOADD_D_AQ_RL, + RISCV_INS_AMOADD_D_RL, + RISCV_INS_AMOADD_W, + RISCV_INS_AMOADD_W_AQ, + RISCV_INS_AMOADD_W_AQ_RL, + RISCV_INS_AMOADD_W_RL, + RISCV_INS_AMOAND_D, + RISCV_INS_AMOAND_D_AQ, + RISCV_INS_AMOAND_D_AQ_RL, + RISCV_INS_AMOAND_D_RL, + RISCV_INS_AMOAND_W, + RISCV_INS_AMOAND_W_AQ, + RISCV_INS_AMOAND_W_AQ_RL, + RISCV_INS_AMOAND_W_RL, + RISCV_INS_AMOMAXU_D, + RISCV_INS_AMOMAXU_D_AQ, + RISCV_INS_AMOMAXU_D_AQ_RL, + RISCV_INS_AMOMAXU_D_RL, + RISCV_INS_AMOMAXU_W, + RISCV_INS_AMOMAXU_W_AQ, + RISCV_INS_AMOMAXU_W_AQ_RL, + RISCV_INS_AMOMAXU_W_RL, + RISCV_INS_AMOMAX_D, + RISCV_INS_AMOMAX_D_AQ, + RISCV_INS_AMOMAX_D_AQ_RL, + RISCV_INS_AMOMAX_D_RL, + RISCV_INS_AMOMAX_W, + RISCV_INS_AMOMAX_W_AQ, + RISCV_INS_AMOMAX_W_AQ_RL, + RISCV_INS_AMOMAX_W_RL, + RISCV_INS_AMOMINU_D, + RISCV_INS_AMOMINU_D_AQ, + RISCV_INS_AMOMINU_D_AQ_RL, + RISCV_INS_AMOMINU_D_RL, + RISCV_INS_AMOMINU_W, + RISCV_INS_AMOMINU_W_AQ, + RISCV_INS_AMOMINU_W_AQ_RL, + RISCV_INS_AMOMINU_W_RL, + RISCV_INS_AMOMIN_D, + RISCV_INS_AMOMIN_D_AQ, + RISCV_INS_AMOMIN_D_AQ_RL, + RISCV_INS_AMOMIN_D_RL, + RISCV_INS_AMOMIN_W, + RISCV_INS_AMOMIN_W_AQ, + RISCV_INS_AMOMIN_W_AQ_RL, + RISCV_INS_AMOMIN_W_RL, + RISCV_INS_AMOOR_D, + RISCV_INS_AMOOR_D_AQ, + RISCV_INS_AMOOR_D_AQ_RL, + RISCV_INS_AMOOR_D_RL, + RISCV_INS_AMOOR_W, + RISCV_INS_AMOOR_W_AQ, + RISCV_INS_AMOOR_W_AQ_RL, + RISCV_INS_AMOOR_W_RL, + RISCV_INS_AMOSWAP_D, + RISCV_INS_AMOSWAP_D_AQ, + RISCV_INS_AMOSWAP_D_AQ_RL, + RISCV_INS_AMOSWAP_D_RL, + RISCV_INS_AMOSWAP_W, + RISCV_INS_AMOSWAP_W_AQ, + RISCV_INS_AMOSWAP_W_AQ_RL, + RISCV_INS_AMOSWAP_W_RL, + RISCV_INS_AMOXOR_D, + RISCV_INS_AMOXOR_D_AQ, + RISCV_INS_AMOXOR_D_AQ_RL, + RISCV_INS_AMOXOR_D_RL, + RISCV_INS_AMOXOR_W, + RISCV_INS_AMOXOR_W_AQ, + RISCV_INS_AMOXOR_W_AQ_RL, + RISCV_INS_AMOXOR_W_RL, + RISCV_INS_AND, + RISCV_INS_ANDI, + RISCV_INS_AUIPC, + RISCV_INS_BEQ, + RISCV_INS_BGE, + RISCV_INS_BGEU, + RISCV_INS_BLT, + RISCV_INS_BLTU, + RISCV_INS_BNE, + RISCV_INS_CSRRC, + RISCV_INS_CSRRCI, + RISCV_INS_CSRRS, + RISCV_INS_CSRRSI, + RISCV_INS_CSRRW, + RISCV_INS_CSRRWI, + RISCV_INS_C_ADD, + RISCV_INS_C_ADDI, + RISCV_INS_C_ADDI16SP, + RISCV_INS_C_ADDI4SPN, + RISCV_INS_C_ADDIW, + RISCV_INS_C_ADDW, + RISCV_INS_C_AND, + RISCV_INS_C_ANDI, + RISCV_INS_C_BEQZ, + RISCV_INS_C_BNEZ, + RISCV_INS_C_EBREAK, + RISCV_INS_C_FLD, + RISCV_INS_C_FLDSP, + RISCV_INS_C_FLW, + RISCV_INS_C_FLWSP, + RISCV_INS_C_FSD, + RISCV_INS_C_FSDSP, + RISCV_INS_C_FSW, + RISCV_INS_C_FSWSP, + RISCV_INS_C_J, + RISCV_INS_C_JAL, + RISCV_INS_C_JALR, + RISCV_INS_C_JR, + RISCV_INS_C_LD, + RISCV_INS_C_LDSP, + RISCV_INS_C_LI, + RISCV_INS_C_LUI, + RISCV_INS_C_LW, + RISCV_INS_C_LWSP, + RISCV_INS_C_MV, + RISCV_INS_C_NOP, + RISCV_INS_C_OR, + RISCV_INS_C_SD, + RISCV_INS_C_SDSP, + RISCV_INS_C_SLLI, + RISCV_INS_C_SRAI, + RISCV_INS_C_SRLI, + RISCV_INS_C_SUB, + RISCV_INS_C_SUBW, + RISCV_INS_C_SW, + RISCV_INS_C_SWSP, + RISCV_INS_C_UNIMP, + RISCV_INS_C_XOR, + RISCV_INS_DIV, + RISCV_INS_DIVU, + RISCV_INS_DIVUW, + RISCV_INS_DIVW, + RISCV_INS_EBREAK, + RISCV_INS_ECALL, + RISCV_INS_FADD_D, + RISCV_INS_FADD_S, + RISCV_INS_FCLASS_D, + RISCV_INS_FCLASS_S, + RISCV_INS_FCVT_D_L, + RISCV_INS_FCVT_D_LU, + RISCV_INS_FCVT_D_S, + RISCV_INS_FCVT_D_W, + RISCV_INS_FCVT_D_WU, + RISCV_INS_FCVT_LU_D, + RISCV_INS_FCVT_LU_S, + RISCV_INS_FCVT_L_D, + RISCV_INS_FCVT_L_S, + RISCV_INS_FCVT_S_D, + RISCV_INS_FCVT_S_L, + RISCV_INS_FCVT_S_LU, + RISCV_INS_FCVT_S_W, + RISCV_INS_FCVT_S_WU, + RISCV_INS_FCVT_WU_D, + RISCV_INS_FCVT_WU_S, + RISCV_INS_FCVT_W_D, + RISCV_INS_FCVT_W_S, + RISCV_INS_FDIV_D, + RISCV_INS_FDIV_S, + RISCV_INS_FENCE, + RISCV_INS_FENCE_I, + RISCV_INS_FENCE_TSO, + RISCV_INS_FEQ_D, + RISCV_INS_FEQ_S, + RISCV_INS_FLD, + RISCV_INS_FLE_D, + RISCV_INS_FLE_S, + RISCV_INS_FLT_D, + RISCV_INS_FLT_S, + RISCV_INS_FLW, + RISCV_INS_FMADD_D, + RISCV_INS_FMADD_S, + RISCV_INS_FMAX_D, + RISCV_INS_FMAX_S, + RISCV_INS_FMIN_D, + RISCV_INS_FMIN_S, + RISCV_INS_FMSUB_D, + RISCV_INS_FMSUB_S, + RISCV_INS_FMUL_D, + RISCV_INS_FMUL_S, + RISCV_INS_FMV_D_X, + RISCV_INS_FMV_W_X, + RISCV_INS_FMV_X_D, + RISCV_INS_FMV_X_W, + RISCV_INS_FNMADD_D, + RISCV_INS_FNMADD_S, + RISCV_INS_FNMSUB_D, + RISCV_INS_FNMSUB_S, + RISCV_INS_FSD, + RISCV_INS_FSGNJN_D, + RISCV_INS_FSGNJN_S, + RISCV_INS_FSGNJX_D, + RISCV_INS_FSGNJX_S, + RISCV_INS_FSGNJ_D, + RISCV_INS_FSGNJ_S, + RISCV_INS_FSQRT_D, + RISCV_INS_FSQRT_S, + RISCV_INS_FSUB_D, + RISCV_INS_FSUB_S, + RISCV_INS_FSW, + RISCV_INS_JAL, + RISCV_INS_JALR, + RISCV_INS_LB, + RISCV_INS_LBU, + RISCV_INS_LD, + RISCV_INS_LH, + RISCV_INS_LHU, + RISCV_INS_LR_D, + RISCV_INS_LR_D_AQ, + RISCV_INS_LR_D_AQ_RL, + RISCV_INS_LR_D_RL, + RISCV_INS_LR_W, + RISCV_INS_LR_W_AQ, + RISCV_INS_LR_W_AQ_RL, + RISCV_INS_LR_W_RL, + RISCV_INS_LUI, + RISCV_INS_LW, + RISCV_INS_LWU, + RISCV_INS_MRET, + RISCV_INS_MUL, + RISCV_INS_MULH, + RISCV_INS_MULHSU, + RISCV_INS_MULHU, + RISCV_INS_MULW, + RISCV_INS_OR, + RISCV_INS_ORI, + RISCV_INS_REM, + RISCV_INS_REMU, + RISCV_INS_REMUW, + RISCV_INS_REMW, + RISCV_INS_SB, + RISCV_INS_SC_D, + RISCV_INS_SC_D_AQ, + RISCV_INS_SC_D_AQ_RL, + RISCV_INS_SC_D_RL, + RISCV_INS_SC_W, + RISCV_INS_SC_W_AQ, + RISCV_INS_SC_W_AQ_RL, + RISCV_INS_SC_W_RL, + RISCV_INS_SD, + RISCV_INS_SFENCE_VMA, + RISCV_INS_SH, + RISCV_INS_SLL, + RISCV_INS_SLLI, + RISCV_INS_SLLIW, + RISCV_INS_SLLW, + RISCV_INS_SLT, + RISCV_INS_SLTI, + RISCV_INS_SLTIU, + RISCV_INS_SLTU, + RISCV_INS_SRA, + RISCV_INS_SRAI, + RISCV_INS_SRAIW, + RISCV_INS_SRAW, + RISCV_INS_SRET, + RISCV_INS_SRL, + RISCV_INS_SRLI, + RISCV_INS_SRLIW, + RISCV_INS_SRLW, + RISCV_INS_SUB, + RISCV_INS_SUBW, + RISCV_INS_SW, + RISCV_INS_UNIMP, + RISCV_INS_URET, + RISCV_INS_WFI, + RISCV_INS_XOR, + RISCV_INS_XORI, + + RISCV_INS_ENDING, +} riscv_insn; + +//> Group of RISCV instructions +typedef enum riscv_insn_group { +#if 0 + { RISCV_GRP_HASSTDEXTA, 0 }, + { RISCV_GRP_HASSTDEXTA, RISCV_GRP_ISRV64, 0 }, + { RISCV_GRP_HASSTDEXTC, 0 }, + { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTD, 0 }, + { RISCV_GRP_HASSTDEXTC, RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV32, 0 }, + { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV32, 0 }, + { RISCV_GRP_HASSTDEXTC, RISCV_GRP_ISRV64, 0 }, + { RISCV_GRP_HASSTDEXTD, 0 }, + { RISCV_GRP_HASSTDEXTD, RISCV_GRP_ISRV64, 0 }, + { RISCV_GRP_HASSTDEXTF, 0 }, + { RISCV_GRP_HASSTDEXTF, RISCV_GRP_ISRV64, 0 }, + { RISCV_GRP_HASSTDEXTM, 0 }, + { RISCV_GRP_HASSTDEXTM, RISCV_GRP_ISRV64, 0 }, + { RISCV_GRP_ISRV64, 0 }, +#endif + RISCV_GRP_INVALID = 0, // = CS_GRP_INVALID + RISCV_GRP_JUMP, + + RISCV_GRP_ISRV32 = 128, + RISCV_GRP_ISRV64, + RISCV_GRP_HASSTDEXTA, + RISCV_GRP_HASSTDEXTC, + RISCV_GRP_HASSTDEXTD, + RISCV_GRP_HASSTDEXTF, + RISCV_GRP_HASSTDEXTM, + /* + RISCV_GRP_ISRVA, + RISCV_GRP_ISRVC, + RISCV_GRP_ISRVD, + RISCV_GRP_ISRVCD, + RISCV_GRP_ISRVF, + RISCV_GRP_ISRV32C, + RISCV_GRP_ISRV32CF, + RISCV_GRP_ISRVM, + RISCV_GRP_ISRV64A, + RISCV_GRP_ISRV64C, + RISCV_GRP_ISRV64D, + RISCV_GRP_ISRV64F, + RISCV_GRP_ISRV64M, + */ + RISCV_GRP_ENDING, +} riscv_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/suite/MC/RISCV/insn-riscv32.s.cs b/suite/MC/RISCV/insn-riscv32.s.cs new file mode 100644 index 000000000..acac1c76c --- /dev/null +++ b/suite/MC/RISCV/insn-riscv32.s.cs @@ -0,0 +1,13 @@ +# CS_ARCH_RISCV, CS_MODE_RISCV32, None +0x37,0x34,0x00,0x00 = lui s0, 3 +0x97,0x82,0x00,0x00 = auipc t0, 8 +0x2f,0xae,0xaa,0x0a = amoswap.w.rl t3, a0, (s5) +0xe3,0x1f,0x31,0x5e = bne sp, gp, 0xdfe +0x73,0x00,0x00,0x00 = ecall +0x33,0x00,0x31,0x02 = mul zero, sp, gp +0x53,0x00,0x31,0x28 = fmin.s ft0, ft2, ft3 +0x53,0x10,0x31,0x2a = fmax.d ft0, ft2, ft3 +0x27,0xaa,0x6a,0x00 = fsw ft6, 0x14(s5) + +// issues +0xef,0xf0,0x1f,0xff = jal -0x10 diff --git a/suite/MC/RISCV/insn-riscv64.s.cs b/suite/MC/RISCV/insn-riscv64.s.cs new file mode 100644 index 000000000..dfcbb309d --- /dev/null +++ b/suite/MC/RISCV/insn-riscv64.s.cs @@ -0,0 +1,8 @@ +# CS_ARCH_RISCV, CS_MODE_RISCV64, None +0x13,0x04,0xa8,0x7a = addi s0, a6, 0x7aa +0x1b,0x8e,0xaa,0x2a = addiw t3, s5, 0x2aa +0x2f,0xbe,0xaa,0x0a = amoswap.d.rl t3, a0, (s5) +0x3b,0x00,0x31,0x02 = mulw zero, sp, gp +0x53,0xa0,0x31,0xd0 = fcvt.s.lu ft0, gp, rdn +0x53,0x81,0x01,0xf2 = fmv.d.x ft2, gp + diff --git a/suite/benchmark.py b/suite/benchmark.py index 62262a388..6b0d5b46f 100755 --- a/suite/benchmark.py +++ b/suite/benchmark.py @@ -37,6 +37,7 @@ all_tests = ( (CS_ARCH_SYSZ, 0, "SystemZ", 0), (CS_ARCH_XCORE, 0, "XCore", 0), (CS_ARCH_M68K, 0, "M68K", 0), + (CS_ARCH_RISCV, 0, "RISCV", 0), ) diff --git a/suite/capstone_get_setup.c b/suite/capstone_get_setup.c index ca279bfd2..08f96c6b4 100644 --- a/suite/capstone_get_setup.c +++ b/suite/capstone_get_setup.c @@ -19,71 +19,57 @@ int main() if (cs_support(CS_ARCH_X86)) { printf("x86=1 "); } - if (cs_support(CS_ARCH_ARM)) { printf("arm=1 "); } - if (cs_support(CS_ARCH_ARM64)) { printf("arm64=1 "); } - if (cs_support(CS_ARCH_MIPS)) { printf("mips=1 "); } - if (cs_support(CS_ARCH_PPC)) { printf("ppc=1 "); } - if (cs_support(CS_ARCH_SPARC)) { printf("sparc=1 "); } - if (cs_support(CS_ARCH_SYSZ)) { printf("sysz=1 "); } - if (cs_support(CS_ARCH_XCORE)) { printf("xcore=1 "); } - if (cs_support(CS_ARCH_M68K)) { printf("m68k=1 "); } - if (cs_support(CS_ARCH_TMS320C64X)) { printf("tms320c64x=1 "); } - if (cs_support(CS_ARCH_M680X)) { printf("m680x=1 "); } - if (cs_support(CS_ARCH_EVM)) { printf("evm=1 "); } - if (cs_support(CS_ARCH_WASM)) { printf("wasm=1 "); } - if (cs_support(CS_ARCH_MOS65XX)) { printf("mos65xx=1 "); } - if (cs_support(CS_ARCH_BPF)) { printf("bpf=1 "); } - + if (cs_support(CS_ARCH_RISCV)) { + printf("riscv=1 "); + } if (cs_support(CS_SUPPORT_DIET)) { printf("diet=1 "); } - if (cs_support(CS_SUPPORT_X86_REDUCE)) { printf("x86_reduce=1 "); } - printf("\n"); return 0; diff --git a/suite/cstest/include/capstone_test.h b/suite/cstest/include/capstone_test.h index ae0eedce3..5936678f0 100644 --- a/suite/cstest/include/capstone_test.h +++ b/suite/cstest/include/capstone_test.h @@ -51,9 +51,6 @@ typedef struct { unsigned int second_value; } double_dict; -extern single_dict arches[]; -extern single_dict modes[]; -extern double_dict options[]; extern char *(*function)(csh *, cs_mode, cs_insn*); int get_index(double_dict d[], unsigned size, const char *str); diff --git a/suite/cstest/include/factory.h b/suite/cstest/include/factory.h index 8ca635582..7df6c7838 100644 --- a/suite/cstest/include/factory.h +++ b/suite/cstest/include/factory.h @@ -18,6 +18,7 @@ char *get_detail_sparc(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_sysz(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_x86(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_xcore(csh *handle, cs_mode mode, cs_insn *ins); +char *get_detail_riscv(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_m68k(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_mos65xx(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_tms320c64x(csh *handle, cs_mode mode, cs_insn *ins); diff --git a/suite/cstest/src/capstone_test.c b/suite/cstest/src/capstone_test.c index 2dd08aca9..a534e49b3 100644 --- a/suite/cstest/src/capstone_test.c +++ b/suite/cstest/src/capstone_test.c @@ -4,101 +4,6 @@ #include "capstone_test.h" -single_dict arches[] = { - {"CS_ARCH_ARM", CS_ARCH_ARM}, - {"CS_ARCH_ARM64", CS_ARCH_ARM64}, - {"CS_ARCH_MIPS", CS_ARCH_MIPS}, - {"CS_ARCH_PPC", CS_ARCH_PPC}, - {"CS_ARCH_SPARC", CS_ARCH_SPARC}, - {"CS_ARCH_SYSZ", CS_ARCH_SYSZ}, - {"CS_ARCH_X86", CS_ARCH_X86}, - {"CS_ARCH_XCORE", CS_ARCH_XCORE}, - {"CS_ARCH_M68K", CS_ARCH_M68K}, - {"CS_ARCH_BPF", CS_ARCH_BPF}, -}; - -single_dict modes[] = { - {"CS_MODE_LITTLE_ENDIAN", CS_MODE_LITTLE_ENDIAN}, - {"CS_MODE_ARM", CS_MODE_ARM}, - {"CS_MODE_16", CS_MODE_16}, - {"CS_MODE_32", CS_MODE_32}, - {"CS_MODE_64", CS_MODE_64}, - {"CS_MODE_THUMB", CS_MODE_THUMB}, - {"CS_MODE_MCLASS", CS_MODE_MCLASS}, - {"CS_MODE_V8", CS_MODE_V8}, - {"CS_MODE_MICRO", CS_MODE_MICRO}, - {"CS_MODE_MIPS3", CS_MODE_MIPS3}, - {"CS_MODE_MIPS32R6", CS_MODE_MIPS32R6}, - {"CS_MODE_MIPS2", CS_MODE_MIPS2}, - {"CS_MODE_V9", CS_MODE_V9}, - {"CS_MODE_QPX", CS_MODE_QPX}, - {"CS_MODE_M68K_000", CS_MODE_M68K_000}, - {"CS_MODE_M68K_010", CS_MODE_M68K_010}, - {"CS_MODE_M68K_020", CS_MODE_M68K_020}, - {"CS_MODE_M68K_030", CS_MODE_M68K_030}, - {"CS_MODE_M68K_040", CS_MODE_M68K_040}, - {"CS_MODE_M68K_060", CS_MODE_M68K_060}, - {"CS_MODE_BIG_ENDIAN", CS_MODE_BIG_ENDIAN}, - {"CS_MODE_MIPS32", CS_MODE_MIPS32}, - {"CS_MODE_MIPS64", CS_MODE_MIPS64}, - {"CS_MODE_M680X_6301", CS_MODE_M680X_6301}, - {"CS_MODE_M680X_6309", CS_MODE_M680X_6309}, - {"CS_MODE_M680X_6800", CS_MODE_M680X_6800}, - {"CS_MODE_M680X_6801", CS_MODE_M680X_6801}, - {"CS_MODE_M680X_6805", CS_MODE_M680X_6805}, - {"CS_MODE_M680X_6808", CS_MODE_M680X_6808}, - {"CS_MODE_M680X_6809", CS_MODE_M680X_6809}, - {"CS_MODE_M680X_6811", CS_MODE_M680X_6811}, - {"CS_MODE_M680X_CPU12", CS_MODE_M680X_CPU12}, - {"CS_MODE_M680X_HCS08", CS_MODE_M680X_HCS08}, - {"CS_MODE_BPF_CLASSIC", CS_MODE_BPF_CLASSIC}, - {"CS_MODE_BPF_EXTENDED", CS_MODE_BPF_EXTENDED}, -}; - -double_dict options[] = { - {"CS_OPT_DETAIL", CS_OPT_DETAIL, CS_OPT_ON}, - {"CS_OPT_SKIPDATA", CS_OPT_SKIPDATA, CS_OPT_ON}, - {"CS_OPT_SYNTAX_DEFAULT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT}, - {"CS_OPT_SYNTAX_INTEL", CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL}, - {"CS_OPT_SYNTAX_ATT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT}, - {"CS_OPT_SYNTAX_NOREGNAME", CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME}, - {"CS_OPT_SYNTAX_MASM", CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM}, - {"CS_MODE_LITTLE_ENDIAN", CS_OPT_MODE, CS_MODE_LITTLE_ENDIAN}, - {"CS_MODE_ARM", CS_OPT_MODE, CS_MODE_ARM}, - {"CS_MODE_16", CS_OPT_MODE, CS_MODE_16}, - {"CS_MODE_32", CS_OPT_MODE, CS_MODE_32}, - {"CS_MODE_64", CS_OPT_MODE, CS_MODE_64}, - {"CS_MODE_THUMB", CS_OPT_MODE, CS_MODE_THUMB}, - {"CS_MODE_MCLASS", CS_OPT_MODE, CS_MODE_MCLASS}, - {"CS_MODE_V8", CS_OPT_MODE, CS_MODE_V8}, - {"CS_MODE_MICRO", CS_OPT_MODE, CS_MODE_MICRO}, - {"CS_MODE_MIPS3", CS_OPT_MODE, CS_MODE_MIPS3}, - {"CS_MODE_MIPS32R6", CS_OPT_MODE, CS_MODE_MIPS32R6}, - {"CS_MODE_MIPS2", CS_OPT_MODE, CS_MODE_MIPS2}, - {"CS_MODE_V9", CS_OPT_MODE, CS_MODE_V9}, - {"CS_MODE_QPX", CS_OPT_MODE, CS_MODE_QPX}, - {"CS_MODE_M68K_000", CS_OPT_MODE, CS_MODE_M68K_000}, - {"CS_MODE_M68K_010", CS_OPT_MODE, CS_MODE_M68K_010}, - {"CS_MODE_M68K_020", CS_OPT_MODE, CS_MODE_M68K_020}, - {"CS_MODE_M68K_030", CS_OPT_MODE, CS_MODE_M68K_030}, - {"CS_MODE_M68K_040", CS_OPT_MODE, CS_MODE_M68K_040}, - {"CS_MODE_M68K_060", CS_OPT_MODE, CS_MODE_M68K_060}, - {"CS_MODE_BIG_ENDIAN", CS_OPT_MODE, CS_MODE_BIG_ENDIAN}, - {"CS_MODE_MIPS32", CS_OPT_MODE, CS_MODE_MIPS32}, - {"CS_MODE_MIPS64", CS_OPT_MODE, CS_MODE_MIPS64}, - {"CS_MODE_M680X_6301", CS_OPT_MODE, CS_MODE_M680X_6301}, - {"CS_MODE_M680X_6309", CS_OPT_MODE, CS_MODE_M680X_6309}, - {"CS_MODE_M680X_6800", CS_OPT_MODE, CS_MODE_M680X_6800}, - {"CS_MODE_M680X_6801", CS_OPT_MODE, CS_MODE_M680X_6801}, - {"CS_MODE_M680X_6805", CS_OPT_MODE, CS_MODE_M680X_6805}, - {"CS_MODE_M680X_6808", CS_OPT_MODE, CS_MODE_M680X_6808}, - {"CS_MODE_M680X_6809", CS_OPT_MODE, CS_MODE_M680X_6809}, - {"CS_MODE_M680X_6811", CS_OPT_MODE, CS_MODE_M680X_6811}, - {"CS_MODE_M680X_CPU12", CS_OPT_MODE, CS_MODE_M680X_CPU12}, - {"CS_MODE_M680X_HCS08", CS_OPT_MODE, CS_MODE_M680X_HCS08}, - {"CS_OPT_UNSIGNED", CS_OPT_UNSIGNED, CS_OPT_ON}, -}; - char *(*function)(csh *, cs_mode, cs_insn*) = NULL; void test_single_MC(csh *handle, int mc_mode, char *line) @@ -273,6 +178,9 @@ int set_function(int arch) case CS_ARCH_BPF: function = get_detail_bpf; break; + case CS_ARCH_RISCV: + function = get_detail_riscv; + break; default: return -1; } diff --git a/suite/cstest/src/main.c b/suite/cstest/src/main.c index fc706d6af..55619e987 100644 --- a/suite/cstest/src/main.c +++ b/suite/cstest/src/main.c @@ -6,6 +6,108 @@ #include "capstone_test.h" #include +#define ARR_SIZE(a) (sizeof(a)/sizeof(a[0])) + +static single_dict arches[] = { + {"CS_ARCH_ARM", CS_ARCH_ARM}, + {"CS_ARCH_ARM64", CS_ARCH_ARM64}, + {"CS_ARCH_MIPS", CS_ARCH_MIPS}, + {"CS_ARCH_PPC", CS_ARCH_PPC}, + {"CS_ARCH_SPARC", CS_ARCH_SPARC}, + {"CS_ARCH_SYSZ", CS_ARCH_SYSZ}, + {"CS_ARCH_X86", CS_ARCH_X86}, + {"CS_ARCH_XCORE", CS_ARCH_XCORE}, + {"CS_ARCH_M68K", CS_ARCH_M68K}, + {"CS_ARCH_BPF", CS_ARCH_BPF}, + {"CS_ARCH_RISCV", CS_ARCH_RISCV}, +}; + + static single_dict modes[] = { + {"CS_MODE_LITTLE_ENDIAN", CS_MODE_LITTLE_ENDIAN}, + {"CS_MODE_ARM", CS_MODE_ARM}, + {"CS_MODE_16", CS_MODE_16}, + {"CS_MODE_32", CS_MODE_32}, + {"CS_MODE_64", CS_MODE_64}, + {"CS_MODE_THUMB", CS_MODE_THUMB}, + {"CS_MODE_MCLASS", CS_MODE_MCLASS}, + {"CS_MODE_V8", CS_MODE_V8}, + {"CS_MODE_MICRO", CS_MODE_MICRO}, + {"CS_MODE_MIPS3", CS_MODE_MIPS3}, + {"CS_MODE_MIPS32R6", CS_MODE_MIPS32R6}, + {"CS_MODE_MIPS2", CS_MODE_MIPS2}, + {"CS_MODE_V9", CS_MODE_V9}, + {"CS_MODE_QPX", CS_MODE_QPX}, + {"CS_MODE_M68K_000", CS_MODE_M68K_000}, + {"CS_MODE_M68K_010", CS_MODE_M68K_010}, + {"CS_MODE_M68K_020", CS_MODE_M68K_020}, + {"CS_MODE_M68K_030", CS_MODE_M68K_030}, + {"CS_MODE_M68K_040", CS_MODE_M68K_040}, + {"CS_MODE_M68K_060", CS_MODE_M68K_060}, + {"CS_MODE_BIG_ENDIAN", CS_MODE_BIG_ENDIAN}, + {"CS_MODE_MIPS32", CS_MODE_MIPS32}, + {"CS_MODE_MIPS64", CS_MODE_MIPS64}, + {"CS_MODE_M680X_6301", CS_MODE_M680X_6301}, + {"CS_MODE_M680X_6309", CS_MODE_M680X_6309}, + {"CS_MODE_M680X_6800", CS_MODE_M680X_6800}, + {"CS_MODE_M680X_6801", CS_MODE_M680X_6801}, + {"CS_MODE_M680X_6805", CS_MODE_M680X_6805}, + {"CS_MODE_M680X_6808", CS_MODE_M680X_6808}, + {"CS_MODE_M680X_6809", CS_MODE_M680X_6809}, + {"CS_MODE_M680X_6811", CS_MODE_M680X_6811}, + {"CS_MODE_M680X_CPU12", CS_MODE_M680X_CPU12}, + {"CS_MODE_M680X_HCS08", CS_MODE_M680X_HCS08}, + {"CS_MODE_BPF_CLASSIC", CS_MODE_BPF_CLASSIC}, + {"CS_MODE_BPF_EXTENDED", CS_MODE_BPF_EXTENDED}, + {"CS_MODE_RISCV32", CS_MODE_RISCV32}, + {"CS_MODE_RISCV64", CS_MODE_RISCV64}, +}; + + static double_dict options[] = { + {"CS_OPT_DETAIL", CS_OPT_DETAIL, CS_OPT_ON}, + {"CS_OPT_SKIPDATA", CS_OPT_SKIPDATA, CS_OPT_ON}, + {"CS_OPT_SYNTAX_DEFAULT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT}, + {"CS_OPT_SYNTAX_INTEL", CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL}, + {"CS_OPT_SYNTAX_ATT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT}, + {"CS_OPT_SYNTAX_NOREGNAME", CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME}, + {"CS_OPT_SYNTAX_MASM", CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM}, + {"CS_MODE_LITTLE_ENDIAN", CS_OPT_MODE, CS_MODE_LITTLE_ENDIAN}, + {"CS_MODE_ARM", CS_OPT_MODE, CS_MODE_ARM}, + {"CS_MODE_16", CS_OPT_MODE, CS_MODE_16}, + {"CS_MODE_32", CS_OPT_MODE, CS_MODE_32}, + {"CS_MODE_64", CS_OPT_MODE, CS_MODE_64}, + {"CS_MODE_THUMB", CS_OPT_MODE, CS_MODE_THUMB}, + {"CS_MODE_MCLASS", CS_OPT_MODE, CS_MODE_MCLASS}, + {"CS_MODE_V8", CS_OPT_MODE, CS_MODE_V8}, + {"CS_MODE_MICRO", CS_OPT_MODE, CS_MODE_MICRO}, + {"CS_MODE_MIPS3", CS_OPT_MODE, CS_MODE_MIPS3}, + {"CS_MODE_MIPS32R6", CS_OPT_MODE, CS_MODE_MIPS32R6}, + {"CS_MODE_MIPS2", CS_OPT_MODE, CS_MODE_MIPS2}, + {"CS_MODE_V9", CS_OPT_MODE, CS_MODE_V9}, + {"CS_MODE_QPX", CS_OPT_MODE, CS_MODE_QPX}, + {"CS_MODE_M68K_000", CS_OPT_MODE, CS_MODE_M68K_000}, + {"CS_MODE_M68K_010", CS_OPT_MODE, CS_MODE_M68K_010}, + {"CS_MODE_M68K_020", CS_OPT_MODE, CS_MODE_M68K_020}, + {"CS_MODE_M68K_030", CS_OPT_MODE, CS_MODE_M68K_030}, + {"CS_MODE_M68K_040", CS_OPT_MODE, CS_MODE_M68K_040}, + {"CS_MODE_M68K_060", CS_OPT_MODE, CS_MODE_M68K_060}, + {"CS_MODE_BIG_ENDIAN", CS_OPT_MODE, CS_MODE_BIG_ENDIAN}, + {"CS_MODE_MIPS32", CS_OPT_MODE, CS_MODE_MIPS32}, + {"CS_MODE_MIPS64", CS_OPT_MODE, CS_MODE_MIPS64}, + {"CS_MODE_M680X_6301", CS_OPT_MODE, CS_MODE_M680X_6301}, + {"CS_MODE_M680X_6309", CS_OPT_MODE, CS_MODE_M680X_6309}, + {"CS_MODE_M680X_6800", CS_OPT_MODE, CS_MODE_M680X_6800}, + {"CS_MODE_M680X_6801", CS_OPT_MODE, CS_MODE_M680X_6801}, + {"CS_MODE_M680X_6805", CS_OPT_MODE, CS_MODE_M680X_6805}, + {"CS_MODE_M680X_6808", CS_OPT_MODE, CS_MODE_M680X_6808}, + {"CS_MODE_M680X_6809", CS_OPT_MODE, CS_MODE_M680X_6809}, + {"CS_MODE_M680X_6811", CS_OPT_MODE, CS_MODE_M680X_6811}, + {"CS_MODE_M680X_CPU12", CS_OPT_MODE, CS_MODE_M680X_CPU12}, + {"CS_MODE_M680X_HCS08", CS_OPT_MODE, CS_MODE_M680X_HCS08}, + {"CS_MODE_RISCV32", CS_OPT_MODE, CS_MODE_RISCV32}, + {"CS_MODE_RISCV64", CS_OPT_MODE, CS_MODE_RISCV64}, + {"CS_OPT_UNSIGNED", CS_OPT_UNSIGNED, CS_OPT_ON}, +}; + static int counter; static char **list_lines; static int failed_setup; @@ -39,14 +141,14 @@ static int setup_MC(void **state) return -1; } - arch = get_value(arches, NUMARCH, list_params[0]); + arch = get_value(arches, ARR_SIZE(arches), list_params[0]); if (!strcmp(list_params[0], "CS_ARCH_ARM64")) mc_mode = 2; else mc_mode = 1; mode = 0; - for (i = 0; i < NUMMODE; ++i) { + for (i = 0; i < ARR_SIZE(modes); ++i) { if (strstr(list_params[1], modes[i].str)) { mode += modes[i].value; switch (modes[i].value) { @@ -78,7 +180,7 @@ static int setup_MC(void **state) return -1; } - for (i = 0; i < NUMOPTION; ++i) { + for (i = 0; i < ARR_SIZE(options); ++i) { if (strstr(list_params[2], options[i].str)) { if (cs_option(*handle, options[i].first_value, options[i].second_value) != CS_ERR_OK) { fprintf(stderr, "[ ERROR ] --- Option is not supported for this arch/mode\n"); @@ -148,7 +250,7 @@ static int setup_issue(void **state) else list_params = split(list_lines[counter] + 6, ", ", &size_params); - arch = get_value(arches, NUMARCH, list_params[0]); + arch = get_value(arches, ARR_SIZE(arches), list_params[0]); if (!strcmp(list_params[0], "CS_ARCH_ARM64")) mc_mode = 2; @@ -156,7 +258,7 @@ static int setup_issue(void **state) mc_mode = 1; mode = 0; - for (i = 0; i < NUMMODE; ++i) { + for (i = 0; i < ARR_SIZE(modes); ++i) { if (strstr(list_params[1], modes[i].str)) { mode += modes[i].value; switch (modes[i].value) { @@ -188,7 +290,7 @@ static int setup_issue(void **state) return -1; } - for (i = 0; i < NUMOPTION; ++i) { + for (i = 0; i < ARR_SIZE(options); ++i) { if (strstr(list_params[2], options[i].str)) { if (cs_option(*handle, options[i].first_value, options[i].second_value) != CS_ERR_OK) { fprintf(stderr, "[ ERROR ] --- Option is not supported for this arch/mode\n"); diff --git a/suite/cstest/src/riscv_detail.c b/suite/cstest/src/riscv_detail.c new file mode 100644 index 000000000..70cc770e2 --- /dev/null +++ b/suite/cstest/src/riscv_detail.c @@ -0,0 +1,47 @@ +/* Capstone testing regression */ +/* By Do Minh Tuan , 02-2019 */ + + +#include "factory.h" + +char *get_detail_riscv(csh *handle, cs_mode mode, cs_insn *ins) +{ + cs_riscv *riscv; + int i; + char *result; + + result = (char *)malloc(sizeof(char)); + result[0] = '\0'; + + if (ins->detail == NULL) + return result; + + riscv = &(ins->detail->riscv); + if (riscv->op_count) + add_str(&result, " ; op_count: %u", riscv->op_count); + + for (i = 0; i < riscv->op_count; i++) { + cs_riscv_op *op = &(riscv->operands[i]); + switch((int)op->type) { + default: + break; + case RISCV_OP_REG: + add_str(&result, " ; operands[%u].type: REG = %s", i, cs_reg_name(*handle, op->reg)); + break; + case RISCV_OP_IMM: + add_str(&result, " ; operands[%u].type: IMM = 0x%x", i, op->imm); + break; + case RISCV_OP_MEM: + add_str(&result, " ; operands[%u].type: MEM", i); + if (op->mem.base != RISCV_REG_INVALID) + add_str(&result, " ; operands[%u].mem.base: REG = %s", + i, cs_reg_name(*handle, op->mem.base)); + if (op->mem.disp != 0) + add_str(&result, " ; operands[%u].mem.disp: 0x%x", i, op->mem.disp); + break; + } + } + + return result; +} + diff --git a/suite/disasm_mc.py b/suite/disasm_mc.py index ff5875a9b..dd6c8cdbe 100755 --- a/suite/disasm_mc.py +++ b/suite/disasm_mc.py @@ -49,6 +49,7 @@ def test_file(fname): "CS_ARCH_X86": CS_ARCH_X86, "CS_ARCH_XCORE": CS_ARCH_XCORE, "CS_ARCH_M68K": CS_ARCH_M68K, + "CS_ARCH_RISCV": CS_ARCH_RISCV, } modes = { @@ -75,6 +76,8 @@ def test_file(fname): "CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN": CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN, + "CS_MODE_RISCV32": CS_MODE_RISCV32, + "CS_MODE_RISCV64": CS_MODE_RISCV64, } options = { @@ -102,6 +105,8 @@ def test_file(fname): ('CS_ARCH_SPARC', 'CS_MODE_BIG_ENDIAN'): ['-triple=sparc'], ('CS_ARCH_SPARC', 'CS_MODE_BIG_ENDIAN+CS_MODE_V9'): ['-triple=sparcv9'], ('CS_ARCH_SYSZ', '0'): ['-triple=s390x', '-mcpu=z196'], + ('CS_ARCH_RISCV', 'CS_MODE_RISCV32'): ['-triple=riscv32'], + ('CS_ARCH_RISCV', 'CS_MODE_RISCV64'): ['-triple=riscv64'], } #if not option in ('', 'None'): diff --git a/suite/fuzz.py b/suite/fuzz.py index 8e0f329a4..17a364749 100755 --- a/suite/fuzz.py +++ b/suite/fuzz.py @@ -43,6 +43,8 @@ all_tests = ( (CS_ARCH_SYSZ, 0, "SystemZ", 0), (CS_ARCH_XCORE, 0, "XCore", 0), (CS_ARCH_M68K, 0, "M68K", 0), + (CS_ARCH_RISCV, CS_MODE_RISCV32, "riscv32", 0), + (CS_ARCH_RISCV, CS_MODE_RISCV64, "riscv64", 0), ) diff --git a/suite/fuzz/drivermc.c b/suite/fuzz/drivermc.c index 70402076b..ff31ebdee 100644 --- a/suite/fuzz/drivermc.c +++ b/suite/fuzz/drivermc.c @@ -90,11 +90,15 @@ int main(int argc, char** argv) } else if (strcmp(arch, "CS_ARCH_M680X") == 0 && strcmp(mode, "CS_MODE_M680X_6809") == 0) { Data[0] = 24; } else if (strcmp(arch, "CS_ARCH_EVM") == 0 && strcmp(mode, "0") == 0) { - Data[0] = 25; - } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) { + Data[0] = 25; + } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) { Data[0] = 29; } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_EXTENDED") != NULL) { Data[0] = 30; + } else if (strcmp(arch, "CS_ARCH_RISCV") == 0 && strcmp(mode, "CS_MODE_RISCV32") == 0) { + Data[0] = 44; + } else if (strcmp(arch, "CS_ARCH_RISCV") == 0 && strcmp(mode, "CS_MODE_RISCV64") == 0) { + Data[0] = 45; } else { printf("Unknown mode\n"); //fail instead of continue diff --git a/suite/fuzz/fuzz_disasm.c b/suite/fuzz/fuzz_disasm.c index 33622906a..12077b9c9 100644 --- a/suite/fuzz/fuzz_disasm.c +++ b/suite/fuzz/fuzz_disasm.c @@ -332,6 +332,20 @@ static struct platform platforms[] = { "M680X_M6808", "hcs08" }, + { + //item 44 + CS_ARCH_RISCV, + CS_MODE_RISCV32, + "RISCV" + "riscv32" + }, + { + //item 45 + CS_ARCH_RISCV, + CS_MODE_RISCV64, + "RISCV" + "riscv64" + }, }; const char * cs_fuzz_arch(uint8_t arch) { diff --git a/suite/test_c.sh b/suite/test_c.sh index ccc88eb50..13f2a9cc8 100755 --- a/suite/test_c.sh +++ b/suite/test_c.sh @@ -15,3 +15,4 @@ ../tests/test_x86 >> /tmp/$1 ../tests/test_systemz >> /tmp/$1 ../tests/test_xcore >> /tmp/$1 +../tests/test_riscv >> /tmp/$1 diff --git a/suite/test_corpus.py b/suite/test_corpus.py index 083f78062..7a169a5b8 100755 --- a/suite/test_corpus.py +++ b/suite/test_corpus.py @@ -31,6 +31,7 @@ def test_file(fname): "CS_ARCH_SYSZ": CS_ARCH_SYSZ, "CS_ARCH_X86": CS_ARCH_X86, "CS_ARCH_XCORE": CS_ARCH_XCORE, + "CS_ARCH_RISCV": CS_ARCH_RISCV, } modes = { @@ -57,6 +58,8 @@ def test_file(fname): "CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN": CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN, + "CS_MODE_RISCV32": CS_MODE_RISCV32, + "CS_MODE_RISCV64": CS_MODE_RISCV64, } mc_modes = { @@ -91,6 +94,8 @@ def test_file(fname): ("CS_ARCH_BPF", "CS_MODE_LITTLE_ENDIAN+CS_MODE_BPF_EXTENDED"): 30, ("CS_ARCH_BPF", "CS_MODE_BIG_ENDIAN+CS_MODE_BPF_CLASSIC"): 31, ("CS_ARCH_BPF", "CS_MODE_BIG_ENDIAN+CS_MODE_BPF_EXTENDED"): 32, + ("CS_ARCH_RISCV", "CS_MODE_RISCV32"): 44, + ("CS_ARCH_RISCV", "CS_MODE_RISCV64"): 45, } #if not option in ('', 'None'): diff --git a/suite/test_group_name.py b/suite/test_group_name.py index 7a746f85e..f95e376e9 100755 --- a/suite/test_group_name.py +++ b/suite/test_group_name.py @@ -9,6 +9,7 @@ from capstone.sparc import * from capstone.systemz import * from capstone.x86 import * from capstone.xcore import * +from capstone.riscv import * import sys class GroupTest: @@ -224,6 +225,26 @@ xcore_dict = { XCORE_GRP_JUMP: "jump", } +riscv32_dict = { + RISCV_GRP_JUMP : "jump", + RISCV_GRP_ISRV32 : "isrv32", + RISCV_GRP_HASSTDEXTA : "hasstdexta", + RISCV_GRP_HASSTDEXTC : "hasstdextc", + RISCV_GRP_HASSTDEXTD : "hasstdextd", + RISCV_GRP_HASSTDEXTF : "hasstdextf", + RISCV_GRP_HASSTDEXTM : "hasstdextm", +} + +riscv64_dict = { + RISCV_GRP_JUMP : "jump", + RISCV_GRP_ISRV64 : "isrv64", + RISCV_GRP_HASSTDEXTA : "hasstdexta", + RISCV_GRP_HASSTDEXTC : "hasstdextc", + RISCV_GRP_HASSTDEXTD : "hasstdextd", + RISCV_GRP_HASSTDEXTF : "hasstdextf", + RISCV_GRP_HASSTDEXTM : "hasstdextm", +} + tests = [ GroupTest('arm', CS_ARCH_ARM, CS_MODE_THUMB, arm_dict), GroupTest('arm64', CS_ARCH_ARM64, CS_MODE_ARM, arm64_dict), @@ -234,6 +255,8 @@ tests = [ GroupTest('x86', CS_ARCH_X86, CS_MODE_32, x86_dict), GroupTest('xcore', CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, xcore_dict), GroupTest('m68k', CS_ARCH_M68K, CS_MODE_BIG_ENDIAN, xcore_dict), + GroupTest('riscv32', CS_ARCH_RISCV, CS_MODE_RISCV32, riscv32_dict), + GroupTest('riscv64', CS_ARCH_RISCV, CS_MODE_RISCV64, riscv64_dict), ] if __name__ == '__main__': diff --git a/suite/test_mc.py b/suite/test_mc.py index 7303b4566..b44c6b77b 100755 --- a/suite/test_mc.py +++ b/suite/test_mc.py @@ -91,6 +91,7 @@ def test_file(fname): "CS_ARCH_SYSZ": CS_ARCH_SYSZ, "CS_ARCH_X86": CS_ARCH_X86, "CS_ARCH_XCORE": CS_ARCH_XCORE + "CS_ARCH_RISCV": CS_ARCH_RISCV # "CS_ARCH_M68K": CS_ARCH_M68K, } @@ -118,6 +119,8 @@ def test_file(fname): "CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS32+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN": CS_MODE_MIPS64+CS_MODE_LITTLE_ENDIAN, "CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN": CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN, + "CS_MODE_RISCV32": CS_MODE_RISCV32, + "CS_MODE_RISCV64": CS_MODE_RISCV64, } options = { @@ -145,6 +148,8 @@ def test_file(fname): ('CS_ARCH_SPARC', 'CS_MODE_BIG_ENDIAN'): ['-triple=sparc'], ('CS_ARCH_SPARC', 'CS_MODE_BIG_ENDIAN+CS_MODE_V9'): ['-triple=sparcv9'], ('CS_ARCH_SYSZ', '0'): ['-triple=s390x', '-mcpu=z196'], + ('CS_ARCH_RISCV', 'CS_MODE_RISCV32'): ['-triple=riscv32'], + ('CS_ARCH_RISCV', 'CS_MODE_RISCV64'): ['-triple=riscv64'], } #if not option in ('', 'None'): diff --git a/tests/Makefile b/tests/Makefile index eda7e3d05..e514c273e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -113,6 +113,10 @@ ifneq (,$(findstring evm,$(CAPSTONE_ARCHS))) CFLAGS += -DCAPSTONE_HAS_EVM SOURCES += test_evm.c endif +ifneq (,$(findstring riscv,$(CAPSTONE_ARCHS))) +CFLAGS += -DCAPSTONE_HAS_RISCV +SOURCES += test_riscv.c +endif ifneq (,$(findstring wasm,$(CAPSTONE_ARCHS))) CFLAGS += -DCAPSTONE_HAS_WASM SOURCES += test_wasm.c diff --git a/tests/test_basic.c b/tests/test_basic.c index bbbd79b45..a7a6367ab 100644 --- a/tests/test_basic.c +++ b/tests/test_basic.c @@ -87,12 +87,16 @@ static void test() #ifdef CAPSTONE_HAS_WASM #define WASM_CODE "\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" #endif - #ifdef CAPSTONE_HAS_MOS65XX #define MOS65XX_CODE "\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42" #endif #define EBPF_CODE "\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" +#ifdef CAPSTONE_HAS_RISCV +#define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" +#define RISCV_CODE64 "\x13\x04\xa8\x7a" // aaa80413 +#endif + struct platform { cs_arch arch; cs_mode mode; @@ -348,6 +352,22 @@ static void test() sizeof(EBPF_CODE) - 1, "eBPF" }, +#endif +#ifdef CAPSTONE_HAS_RISCV + { + CS_ARCH_RISCV, + CS_MODE_RISCV32, + (unsigned char *)RISCV_CODE32, + sizeof(RISCV_CODE32) - 1, + "RISCV32" + }, + { + CS_ARCH_RISCV, + CS_MODE_RISCV64, + (unsigned char *)RISCV_CODE64, + sizeof(RISCV_CODE64) - 1, + "RISCV64" + }, #endif }; diff --git a/tests/test_iter.c b/tests/test_iter.c index e2dd19fd4..053fd01c0 100644 --- a/tests/test_iter.c +++ b/tests/test_iter.c @@ -84,6 +84,12 @@ static void test() #endif #define EBPF_CODE "\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" +#ifdef CAPSTONE_HAS_RISCV +#define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" +#define RISCV_CODE64 "\x13\x04\xa8\x7a" // aaa80413 +#endif + + struct platform platforms[] = { #ifdef CAPSTONE_HAS_X86 { @@ -241,6 +247,22 @@ static void test() sizeof(EBPF_CODE) - 1, "eBPF" }, +#endif +#ifdef CAPSTONE_HAS_RISCV + { + CS_ARCH_RISCV, + CS_MODE_RISCV32, + (unsigned char *)RISCV_CODE32, + sizeof(RISCV_CODE32) - 1, + "RISCV32" + }, + { + CS_ARCH_RISCV, + CS_MODE_RISCV64, + (unsigned char *)RISCV_CODE64, + sizeof(RISCV_CODE64) - 1, + "RISCV64" + }, #endif }; diff --git a/tests/test_riscv.c b/tests/test_riscv.c new file mode 100644 index 000000000..a36202219 --- /dev/null +++ b/tests/test_riscv.c @@ -0,0 +1,159 @@ + + +#include +#include + +#include +#include + +struct platform { + cs_arch arch; + cs_mode mode; + unsigned char *code; + size_t size; + const char *comment; +}; + +static csh handle; + +static void print_string_hex(const char *comment, unsigned char *str, size_t len) +{ + unsigned char *c; + + printf("%s", comment); + for (c = str; c < str + len; c++) { + printf("0x%02x ", *c & 0xff); + } + + printf("\n"); +} + +static void print_insn_detail(cs_insn *ins) +{ + int i; + int n; + cs_riscv *riscv; + cs_detail *detail; + + // detail can be NULL on "data" instruction if SKIPDATA option is turned ON + if (ins->detail == NULL) + return; + + riscv = &(ins->detail->riscv); + detail = ins->detail; + if (riscv->op_count) + printf("\top_count: %u\n", riscv->op_count); + + for (i = 0; i < riscv->op_count; i++) { + cs_riscv_op *op = &(riscv->operands[i]); + switch((int)op->type) { + default: + printf("\terror in opt_type: %u\n", (int)op->type); + break; + case RISCV_OP_REG: + printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg)); + break; + case RISCV_OP_IMM: + printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm); + break; + case RISCV_OP_MEM: + printf("\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != RISCV_REG_INVALID) + printf("\t\t\toperands[%u].mem.base: REG = %s\n", + i, cs_reg_name(handle, op->mem.base)); + if (op->mem.disp != 0) + printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp); + + break; + } + + } + + //print the groups this instruction belongs to + if (detail->groups_count > 0) { + printf("\tThis instruction belongs to groups: "); + for (n = 0; n < detail->groups_count; n++) { + printf("%s ", cs_group_name(handle, detail->groups[n])); + } + printf("\n"); + } + + printf("\n"); +} + +static void test() +{ + // \xb3\x00\x00\x00 for add ra, zero, zero + // \x93\x00\x21\x00 + // \xb3\x70\x31\x00 +#define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" +#define RISCV_CODE64 "\x13\x04\xa8\x7a" // aaa80413 + struct platform platforms[] = { + { + CS_ARCH_RISCV, + CS_MODE_RISCV32, + (unsigned char *)RISCV_CODE32, + sizeof(RISCV_CODE32) - 1, + "riscv32" + }, + { + CS_ARCH_RISCV, + CS_MODE_RISCV64, + (unsigned char *)RISCV_CODE64, + sizeof(RISCV_CODE64) - 1, + "riscv64" + } + }; + + uint64_t address = 0x1000; + cs_insn *insn; + int i; + size_t count; + + for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) { + cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle); + if (err) { + printf("Failed on cs_open() with error returned: %u\n", err); + continue; + } + + //To turn on or off the Print Details option + //cs_option(handle, CS_OPT_DETAIL, CS_OPT_OFF); + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + + count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn); + if (count) { + size_t j; + + printf("****************\n"); + printf("Platform: %s\n", platforms[i].comment); + print_string_hex("Code:", platforms[i].code, platforms[i].size); + printf("Disasm:\n"); + + for (j = 0; j < count; j++) { + printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + print_insn_detail(&insn[j]); + } + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); + + // free memory allocated by cs_disasm() + cs_free(insn, count); + } else { + printf("****************\n"); + printf("Platform: %s\n", platforms[i].comment); + print_string_hex("Code:", platforms[i].code, platforms[i].size); + printf("ERROR: Failed to disasm given code!\n"); + } + + printf("\n"); + + cs_close(&handle); + } +} + +int main() +{ + test(); + + return 0; +}