RISCV support ISRV32/ISRV64 (#1401)

* Added RISCV dir to contain the RISCV architecture engine code. Adding the TableGen files generated from llvm-tblgen. Add Disassembler.h

* Started working on RISCVDisassembler.c - RISCV_init(), RISCVDisassembler_getInstruction, and RISCV_getInstruction

* Added all functions to RISCVDisassembler.c and needed modifications to RISCVGenDisassemblerTables.inc. Add and modified RISCVGenSubtargetInfo.inc. Start creation of RISCVInstPrinter.h

* Finished RISCVGenAsmWriter.inc. Finished RISCVGenRegisterInfo.inc. Minor fixes to RISCVDisassembler.c. Working on RISCVInstPrinter

* Finished RISCVInstPrinter, RISCVMapping, RISCVBaseInfo, RISCVGenInstrInfo.inc, RISCVModule.c. Working on riscv.h

* Backport it from: 0db412ce3b

* All RISCV files added. Compiled correctly and initial test for ADD, ADDI, AND works properly.

* Add refactored cs.c for RISCV

* Testing all I instructions in test_riscv.c

* Modify the orignal backport for RISCVGenRegisterInfo.inc, capstone.h and test_iter to work w/ the current code strcuture

* Fix issue with RISCVGenRegisterInfo.inc - RISCVRegDesc[] (Excess elements in struct initializer). Added RISCV tests to test_iter.c

* fixed bug related to incorrect initialization of memory after malloc

* fix compile bug

* Fix compile errors.

* move riscv.h to include/capstone

* fix indentation issues

* fix coding style issues

* Fix indentation issues

* fix coding style

* Move variable declaration to the top of the block

* Fix coding indentation

* Move some stuff into RISCVMappingInsn.inc

* Fix code sytle

* remove cs_mode support for RISCV

* update asmwriter-inc to LLVM upstream

* update the .inc files to riscv upstream

* update riscv disassembler function for suport 16bit instructions

* update printer & tablegen inc files which have fixed arguments mismatch

* update headers and mapping source

* add riscv architecture specific test code

* fix all RISCV tons of compiler errors

* pass final tests

* add riscv tablegen patchs

* merge with upstream/next

* fix cstool missing riscv file

* fix root Makefile

* add new TableGen patchs for riscv

* fix cmakefile.txt of missing one riscv file

* fix declaration conflict

* fix incompatible declaration type

* change riscvc from arch to mode

* fix test_riscv warnning

* fix code style and add riscv part of test_basic

* add RISCV64 mode

* add suite for riscv

* crack fuzz test

* fix getfeaturebits test add riscvc

* fix test missing const qualifier warnning

* fix testcase type mismatch

* fix return value missing

* change getfeaturebits test

* add test cs files

* using a winder type contain the decode string

* fix a copy typo

* remove useless mode for riscv

* change cs file blank type

* add repo for update_riscv & fix cstool missing riscv mode

* fix typo

* add riscv for cstool useage

* add TableGen patch for riscv asmwriter

* clean ctags file

* remove black comment line

* fix fuzz related something

* fix missing RISCV string of fuzz

* update readme, etc..

* add riscv *.s.cs file

* add riscv *.s.cs file & clear ctags

* clear useless array declarations at capstone_test

* update to 5e4069f

* update readme change name more formal

* change position of riscv after bpf and modify copyright more uniform

* clear useless ctags file

* change blank with tab in riscv.h

* add riscv python bindings

* add riscv in __init__.py

* fix riscv define value for python binding

* fix test_riscv.py typo

* add missing riscvc in __init__.py of python bindings

* fix alias-insn printer bug, remove useless newline

* change inst print delimter from tab to bankspace for travis

* add riscv tablegen patch

* fix inst output more consistency

* add TableGen patch which fix inst output formal

* crack the effective address output for detail and change register print function

* fix not detail crash bug

* change item declaration position at cs_riscv

* update riscv.py

* change function name more meaningfull

* update python binding makefile

* fix register enum sequence according to riscvgenreginfo.inc

* test function name

* add enum s0/fp in riscv.h & update riscv_const.py

* add register name enum
This commit is contained in:
z 2019-03-09 08:41:12 +08:00 committed by Nguyen Anh Quynh
parent be60fe4202
commit b8fcf27b22
68 changed files with 27520 additions and 154 deletions

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

@ -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_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_%:

View File

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

106
arch/RISCV/RISCVBaseInfo.h Normal file
View File

@ -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 <assert.h>
//#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

View File

@ -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 <porto703@gmail.com> &
Shawn Chang <citypw@gmail.com>, HardenedLinux@2018 */
#ifdef CAPSTONE_HAS_RISCV
#include <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.h>
#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<N>(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<N>(Imm) && "Invalid immediate");
addImplySP(Inst, Address, Decoder);
// Sign-extend the number in the bottom N bits of Imm
//Inst.addOperand(MCOperand::createImm(SignExtend64<N>(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<N>(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<N>(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

View File

@ -0,0 +1,18 @@
/* Capstone Disassembly Engine */
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> &
Shawn Chang <citypw@gmail.com>, 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,275 @@
// This is auto-gen data for Capstone engine (www.capstone-engine.org)
// By Nguyen Anh Quynh <aquynh@gmail.com>
{ 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" },

View File

@ -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 <aquynh@gmail.com>, 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

View File

@ -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 <aquynh@gmail.com>, 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

View File

@ -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 <aquynh@gmail.com>, 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

View File

@ -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 <stdio.h> // DEBUG
#include <stdlib.h>
#include <string.h>
#include <capstone/platform.h>
#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<MCInst *>(&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<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());
O << RISCVFPRndMode::roundingModeToString(FRMArg);
#endif
SStream_concat0(O, roundingModeToString(FRMArg));
}
#endif // CAPSTONE_HAS_RISCV

View File

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

359
arch/RISCV/RISCVMapping.c Normal file
View File

@ -0,0 +1,359 @@
#ifdef CAPSTONE_HAS_RISCV
#include <stdio.h> // debug
#include <string.h>
#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

22
arch/RISCV/RISCVMapping.h Normal file
View File

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

File diff suppressed because it is too large Load Diff

42
arch/RISCV/RISCVModule.c Normal file
View File

@ -0,0 +1,42 @@
/* Capstone Disassembly Engine */
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> &
Shawn Chang <citypw@gmail.com>, 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

12
arch/RISCV/RISCVModule.h Normal file
View File

@ -0,0 +1,12 @@
/* Capstone Disassembly Engine */
/* By Shawn Chang <citypw@gmail.com>, 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

View File

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

View File

@ -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': '',
},

View File

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

View File

@ -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
@ -196,7 +200,10 @@ 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_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 = ""

View File

@ -0,0 +1,49 @@
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
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]))

View File

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

View File

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

View File

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

67
bindings/python/test_riscv.py Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
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()

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,905 @@
From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
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<Record *> 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<typename InsnType>\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<typename InsnType>\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<Record*> &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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
From 5adfa13945a8eb1a104db57b29d27ceba0a2d948 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
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

View File

@ -0,0 +1,32 @@
From 9028d6a0ce67296be48a3dae07d954ebe26942e1 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
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

View File

@ -0,0 +1,24 @@
From 6830f128011a19e77e8c131cdfcf2f87fb78e316 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
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

View File

@ -0,0 +1,38 @@
From b1a7abb285aaa1436d563a30f65813513a512850 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
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

View File

@ -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.old \
| sort -u) \
<(grep RISCV_INS_ <arch/RISCV/RISCVGenInsnNameMaps.inc \
| sort -u) \
>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" }' \
<include/capstone/RISCV.h | sort -u) \
<(perl -ne 'if (/(RISCV_INS_.+),/) { print "\t$1,\n" }' \
<arch/RISCV/RISCVMappingInsn.inc | sort -u)
```
* `enum RISCV_insn_group`:
```
perl -ne 'if (/(\{.RISCV_GRP_.*?\}),/) { print "\t$1,\n"; }' < \
arch/RISCV/RISCVMappingInsn.inc | sort -u
```
* `arch/RISCV/RISCVDisassembler.c`
* `arch/RISCV/RISCVInstPrinter.c`
* `arch/RISCV/RISCVMCTargetDesc.c`
* `arch/RISCV/RISCVMCTargetDesc.h`
* `arch/RISCV/RISCVMapping.c`
* `enum group_name_maps`:
```
perl -ne 'if (/(RISCV_GRP_(.*?)),/) { print "\t{ $1, \"" . lc($2) . "\" },\n"; }' \
arch/RISCV/RISCVMappingInsn.inc | sort -u
```

41
cs.c
View File

@ -65,6 +65,7 @@
#include "arch/TMS320C64x/TMS320C64xModule.h"
#include "arch/X86/X86Module.h"
#include "arch/XCore/XCoreModule.h"
#include "arch/RISCV/RISCVModule.h"
#include "arch/MOS65XX/MOS65XXModule.h"
#include "arch/BPF/BPFModule.h"
@ -145,6 +146,11 @@ static cs_err (*cs_arch_init[MAX_ARCH])(cs_struct *) = {
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_RISCV
RISCV_global_init,
#else
NULL,
#endif
};
// support cs_option() for all archs
@ -224,6 +230,11 @@ static cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t valu
#else
NULL,
#endif
#ifdef CAPSTONE_HAS_RISCV
RISCV_option,
#else
NULL,
#endif
};
// bitmask for finding disallowed modes for an arch:
@ -312,6 +323,11 @@ static cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH] = {
#else
0,
#endif
#ifdef CAPSTONE_HAS_RISCV
~(CS_MODE_RISCV32 | CS_MODE_RISCV64 | CS_MODE_RISCVC),
#else
0,
#endif
};
// bitmask of enabled architectures
@ -361,6 +377,9 @@ static uint32_t all_arch = 0
#ifdef CAPSTONE_HAS_BPF
| (1 << CS_ARCH_BPF)
#endif
#ifdef CAPSTONE_HAS_RISCV
| (1 << CS_ARCH_RISCV)
#endif
;
@ -432,8 +451,8 @@ bool CAPSTONE_API cs_support(int query)
(1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_MOS65XX) | (1 << CS_ARCH_WASM) |
(1 << CS_ARCH_BPF));
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
(1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF));
if ((unsigned int)query < CS_ARCH_MAX)
return all_arch & (1 << query);
@ -708,6 +727,11 @@ static uint8_t skipdata_size(cs_struct *handle)
case CS_ARCH_BPF:
// both classic and extended BPF have alignment 8.
return 8;
case CS_ARCH_RISCV:
// special compress mode
if (handle->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;

View File

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

46
cstool/cstool_riscv.c Normal file
View File

@ -0,0 +1,46 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <capstone/capstone.h>
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");
}

View File

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

531
include/capstone/riscv.h Normal file
View File

@ -0,0 +1,531 @@
#ifndef CAPSTONE_RISCV_H
#define CAPSTONE_RISCV_H
/* Capstone Disassembly Engine */
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> &
Shawn Chang <citypw@gmail.com>, HardenedLinux@2018 */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_MSC_VER) || !defined(_KERNEL_MODE)
#include <stdint.h>
#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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,6 +6,108 @@
#include "capstone_test.h"
#include <unistd.h>
#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");

View File

@ -0,0 +1,47 @@
/* Capstone testing regression */
/* By Do Minh Tuan <tuanit96@gmail.com>, 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;
}

View File

@ -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'):

View File

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

View File

@ -95,6 +95,10 @@ int main(int argc, char** argv)
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

View File

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

View File

@ -15,3 +15,4 @@
../tests/test_x86 >> /tmp/$1
../tests/test_systemz >> /tmp/$1
../tests/test_xcore >> /tmp/$1
../tests/test_riscv >> /tmp/$1

View File

@ -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'):

View File

@ -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__':

View File

@ -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'):

View File

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

View File

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

View File

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

159
tests/test_riscv.c Normal file
View File

@ -0,0 +1,159 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include <capstone/capstone.h>
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;
}