Xtensa Support (#2380)

* Fix leaks

* Remove unnecessary new lines

* Add checks for actual buffer length before attempting reading it.

* Xtensa: add xtensa support

* Xtensa fixes

- fix MCExpr
- fix Xtensa_add_cs_detail
- add `add_cs_detail`
- add `MCExpr *MCOperand_getExpr(const MCOperand *MC)` `void printExpr(const MCExpr *E, SStream *O)`

autosync fix

- fix StreamOperation.py
- replace `report_fatal_error` with `CS_ASSERT`
- fix patch StreamOperation.py
- replace `assert` with `CS_ASSERT`
- fix AddCSDetail.py
- fix QualifiedIdentifier

* Xtensa fix

* Xtensa fix .py

* add Xtensa to the fuzzer

* Xtensa `LITBASE`: add a basic implementation

* Xtensa `LITBASE`: add a integration test

* Xtensa: fix cs_v6_release_guide.md

* Xtensa: fix `XTENSA_OP_GROUP_MEMOPERAND`

* Xtensa: fix

* Xtensa: fix Targets.py

* Use isUint and isInt all over Xtensa

* Add documentation about LITBASE functionality

* Fix typo

* Replace hard with Capstone assert

* Xtensa: fix arch_config.json

* Xtensa: fix

---------

Co-authored-by: Rot127 <unisono@quyllur.org>
This commit is contained in:
billow 2024-09-30 11:35:51 +08:00 committed by GitHub
parent 29d8773417
commit 21f7bc85f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
88 changed files with 9468 additions and 131 deletions

View File

@ -79,6 +79,7 @@ jobs:
./src/autosync/ASUpdater.py -d -a LoongArch -s IncGen ./src/autosync/ASUpdater.py -d -a LoongArch -s IncGen
./src/autosync/ASUpdater.py -d -a Mips -s IncGen ./src/autosync/ASUpdater.py -d -a Mips -s IncGen
./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen ./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen
./src/autosync/ASUpdater.py -d -a Xtensa -s IncGen
- name: CppTranslator - Patch tests - name: CppTranslator - Patch tests
run: | run: |
@ -96,3 +97,4 @@ jobs:
./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate ./src/autosync/ASUpdater.py --ci -d -a LoongArch -s Translate
./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate ./src/autosync/ASUpdater.py --ci -d -a Mips -s Translate
./src/autosync/ASUpdater.py --ci -d -a SystemZ -s Translate ./src/autosync/ASUpdater.py --ci -d -a SystemZ -s Translate
./src/autosync/ASUpdater.py --ci -d -a Xtensa -s Translate

View File

@ -5,6 +5,8 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build") message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif() endif()
set(BUILD_RPATH_USE_ORIGIN true)
# Detect whether capstone is compiled as top-level or a subdirectory # Detect whether capstone is compiled as top-level or a subdirectory
set(PROJECT_IS_TOP_LEVEL OFF) set(PROJECT_IS_TOP_LEVEL OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
@ -85,8 +87,8 @@ if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
endif() endif()
set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSTEMZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH) set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSTEMZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH XTENSA)
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch) set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch Xtensa)
# If building for OSX it's best to allow CMake to handle building both architectures # If building for OSX it's best to allow CMake to handle building both architectures
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN) if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
@ -211,6 +213,7 @@ set(HEADERS_COMMON
include/capstone/alpha.h include/capstone/alpha.h
include/capstone/hppa.h include/capstone/hppa.h
include/capstone/loongarch.h include/capstone/loongarch.h
include/capstone/xtensa.h
) )
## architecture support ## architecture support
@ -680,6 +683,22 @@ if (CAPSTONE_LOONGARCH_SUPPORT)
) )
endif () endif ()
if(CAPSTONE_XTENSA_SUPPORT)
add_definitions(-DCAPSTONE_HAS_XTENSA)
set(SOURCES_XTENSA
arch/Xtensa/XtensaDisassembler.c
arch/Xtensa/XtensaInstPrinter.c
arch/Xtensa/XtensaMapping.c
arch/Xtensa/XtensaModule.c
)
set(HEADERS_XTENSA
arch/Xtensa/XtensaDisassembler.h
arch/Xtensa/XtensaInstPrinter.h
arch/Xtensa/XtensaMapping.h
arch/Xtensa/XtensaModule.h
)
endif()
if (CAPSTONE_OSXKERNEL_SUPPORT) if (CAPSTONE_OSXKERNEL_SUPPORT)
add_definitions(-DCAPSTONE_HAS_OSXKERNEL) add_definitions(-DCAPSTONE_HAS_OSXKERNEL)
endif() endif()
@ -707,6 +726,7 @@ set(ALL_SOURCES
${SOURCES_ALPHA} ${SOURCES_ALPHA}
${SOURCES_HPPA} ${SOURCES_HPPA}
${SOURCES_LOONGARCH} ${SOURCES_LOONGARCH}
${SOURCES_XTENSA}
) )
set(ALL_HEADERS set(ALL_HEADERS
@ -733,6 +753,7 @@ set(ALL_HEADERS
${HEADERS_ALPHA} ${HEADERS_ALPHA}
${HEADERS_HPPA} ${HEADERS_HPPA}
${HEADERS_LOONGARCH} ${HEADERS_LOONGARCH}
${HEADERS_XTENSA}
) )
## properties ## properties
@ -785,6 +806,7 @@ source_group("Source\\TriCore" FILES ${SOURCES_TRICORE})
source_group("Source\\Alpha" FILES ${SOURCES_ALPHA}) source_group("Source\\Alpha" FILES ${SOURCES_ALPHA})
source_group("Source\\HPPA" FILES ${SOURCES_HPPA}) source_group("Source\\HPPA" FILES ${SOURCES_HPPA})
source_group("Source\\LoongArch" FILES ${SOURCES_LOONGARCH}) source_group("Source\\LoongArch" FILES ${SOURCES_LOONGARCH})
source_group("Source\\Xtensa" FILES ${SOURCES_XTENSA})
source_group("Include\\Common" FILES ${HEADERS_COMMON}) source_group("Include\\Common" FILES ${HEADERS_COMMON})
source_group("Include\\Engine" FILES ${HEADERS_ENGINE}) source_group("Include\\Engine" FILES ${HEADERS_ENGINE})
@ -809,6 +831,7 @@ source_group("Include\\TriCore" FILES ${HEADERS_TRICORE})
source_group("Include\\Alpha" FILES ${HEADERS_ALPHA}) source_group("Include\\Alpha" FILES ${HEADERS_ALPHA})
source_group("Include\\HPPA" FILES ${HEADERS_HPPA}) source_group("Include\\HPPA" FILES ${HEADERS_HPPA})
source_group("Include\\LoongArch" FILES ${HEADERS_LOONGARCH}) source_group("Include\\LoongArch" FILES ${HEADERS_LOONGARCH})
source_group("Include\\Xtensa" FILES ${HEADERS_XTENSA})
## installation ## installation
if(CAPSTONE_INSTALL) if(CAPSTONE_INSTALL)

View File

@ -87,6 +87,7 @@ david942j: BPF (both classic and extended) architecture.
fanfuqiang & citypw & porto703 : RISCV architecture. fanfuqiang & citypw & porto703 : RISCV architecture.
Josh "blacktop" Maine: Arm64 architecture improvements. Josh "blacktop" Maine: Arm64 architecture improvements.
Finn Wilkinson: AArch64 update to Armv9.2-a (SME + SVE2 support) Finn Wilkinson: AArch64 update to Armv9.2-a (SME + SVE2 support)
Billow & Sidneyp : TriCore architecture. Billow & Sidneyp: TriCore architecture.
Dmitry Sibirtsev: Alpha & HPPA architecture. Dmitry Sibirtsev: Alpha & HPPA architecture.
Jiajie Chen & Yanglin Xun: LoongArch architecture. Jiajie Chen & Yanglin Xun: LoongArch architecture.
Billow: Xtensa architecture.

View File

@ -27,7 +27,7 @@
typedef struct MCInst MCInst; typedef struct MCInst MCInst;
typedef struct cs_struct cs_struct; typedef struct cs_struct cs_struct;
typedef struct MCOperand MCOperand; typedef struct MCOperand MCOperand;
typedef unsigned MCRegister; typedef void MCExpr;
/// MCOperand - Instances of this class represent operands of the MCInst class. /// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union. /// This is a simple discriminated union.

View File

@ -20,11 +20,13 @@
#define CS_LLVM_MC_MCREGISTERINFO_H #define CS_LLVM_MC_MCREGISTERINFO_H
#include "capstone/platform.h" #include "capstone/platform.h"
#include "SStream.h"
/// An unsigned integer type large enough to represent all physical registers, /// An unsigned integer type large enough to represent all physical registers,
/// but not necessarily virtual registers. /// but not necessarily virtual registers.
typedef int16_t MCPhysReg; typedef int16_t MCPhysReg;
typedef const MCPhysReg* iterator; typedef const MCPhysReg* iterator;
typedef uint16_t MCRegister;
typedef struct MCRegisterClass2 { typedef struct MCRegisterClass2 {
iterator RegsBegin; iterator RegsBegin;

View File

@ -355,11 +355,21 @@ ifneq (,$(findstring loongarch,$(CAPSTONE_ARCHS)))
LIBOBJ_LOONGARCH += $(LIBSRC_LOONGARCH:%.c=$(OBJDIR)/%.o) LIBOBJ_LOONGARCH += $(LIBSRC_LOONGARCH:%.c=$(OBJDIR)/%.o)
endif endif
DEP_XTENSA =
DEP_XTENSA += $(wildcard arch/Xtensa/Xtensa*.inc)
LIBOBJ_XTENSA =
ifneq (,$(findstring xtensa,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_XTENSA
LIBSRC_XTENSA += $(wildcard arch/Xtensa/Xtensa*.c)
LIBOBJ_XTENSA += $(LIBSRC_XTENSA:%.c=$(OBJDIR)/%.o)
endif
LIBOBJ = LIBOBJ =
LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o $(OBJDIR)/MCInst.o $(OBJDIR)/MCInstPrinter.o $(OBJDIR)/Mapping.o LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o $(OBJDIR)/MCInst.o $(OBJDIR)/MCInstPrinter.o $(OBJDIR)/Mapping.o
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_AARCH64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_SH) LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_AARCH64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_SH)
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF) LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF)
LIBOBJ += $(LIBOBJ_TRICORE) $(LIBOBJ_ALPHA) $(LIBOBJ_HPPA) $(LIBOBJ_LOONGARCH) LIBOBJ += $(LIBOBJ_TRICORE) $(LIBOBJ_ALPHA) $(LIBOBJ_HPPA) $(LIBOBJ_LOONGARCH) $(LIBOBJ_XTENSA)
ifeq ($(PKG_EXTRA),) ifeq ($(PKG_EXTRA),)
@ -492,6 +502,7 @@ $(LIBOBJ_TRICORE): $(DEP_TRICORE)
$(LIBOBJ_ALPHA): $(DEP_ALPHA) $(LIBOBJ_ALPHA): $(DEP_ALPHA)
$(LIBOBJ_HPPA): $(DEP_HPPA) $(LIBOBJ_HPPA): $(DEP_HPPA)
$(LIBOBJ_LOONGARCH): $(DEP_LOONGARCH) $(LIBOBJ_LOONGARCH): $(DEP_LOONGARCH)
$(LIBOBJ_XTENSA): $(DEP_XTENSA)
ifeq ($(CAPSTONE_STATIC),yes) ifeq ($(CAPSTONE_STATIC),yes)
$(ARCHIVE): $(LIBOBJ) $(ARCHIVE): $(LIBOBJ)

View File

@ -347,6 +347,7 @@ DEFINE_get_detail_op(loongarch, LoongArch);
DEFINE_get_detail_op(mips, Mips); DEFINE_get_detail_op(mips, Mips);
DEFINE_get_detail_op(riscv, RISCV); DEFINE_get_detail_op(riscv, RISCV);
DEFINE_get_detail_op(systemz, SystemZ); DEFINE_get_detail_op(systemz, SystemZ);
DEFINE_get_detail_op(xtensa, Xtensa);
/// Returns true if for this architecture the /// Returns true if for this architecture the
/// alias operands should be filled. /// alias operands should be filled.

View File

@ -142,6 +142,7 @@ DECL_get_detail_op(loongarch, LoongArch);
DECL_get_detail_op(mips, Mips); DECL_get_detail_op(mips, Mips);
DECL_get_detail_op(riscv, RISCV); DECL_get_detail_op(riscv, RISCV);
DECL_get_detail_op(systemz, SystemZ); DECL_get_detail_op(systemz, SystemZ);
DECL_get_detail_op(xtensa, Xtensa);
/// Increments the detail->arch.op_count by one. /// Increments the detail->arch.op_count by one.
#define DEFINE_inc_detail_op_count(arch, ARCH) \ #define DEFINE_inc_detail_op_count(arch, ARCH) \
@ -177,6 +178,8 @@ DEFINE_inc_detail_op_count(riscv, RISCV);
DEFINE_dec_detail_op_count(riscv, RISCV); DEFINE_dec_detail_op_count(riscv, RISCV);
DEFINE_inc_detail_op_count(systemz, SystemZ); DEFINE_inc_detail_op_count(systemz, SystemZ);
DEFINE_dec_detail_op_count(systemz, SystemZ); DEFINE_dec_detail_op_count(systemz, SystemZ);
DEFINE_inc_detail_op_count(xtensa, Xtensa);
DEFINE_dec_detail_op_count(xtensa, Xtensa);
/// Returns true if a memory operand is currently edited. /// Returns true if a memory operand is currently edited.
static inline bool doing_mem(const MCInst *MI) static inline bool doing_mem(const MCInst *MI)
@ -208,6 +211,7 @@ DEFINE_get_arch_detail(loongarch, LoongArch);
DEFINE_get_arch_detail(mips, Mips); DEFINE_get_arch_detail(mips, Mips);
DEFINE_get_arch_detail(riscv, RISCV); DEFINE_get_arch_detail(riscv, RISCV);
DEFINE_get_arch_detail(systemz, SystemZ); DEFINE_get_arch_detail(systemz, SystemZ);
DEFINE_get_arch_detail(xtensa, Xtensa);
#define DEFINE_check_safe_inc(Arch, ARCH) \ #define DEFINE_check_safe_inc(Arch, ARCH) \
static inline void Arch##_check_safe_inc(const MCInst *MI) { \ static inline void Arch##_check_safe_inc(const MCInst *MI) { \

View File

@ -53,9 +53,9 @@ static inline bool isUIntN(unsigned N, uint64_t x) {
/// isIntN - Checks if an signed integer fits into the given (dynamic) /// isIntN - Checks if an signed integer fits into the given (dynamic)
/// bit width. /// bit width.
//static inline bool isIntN(unsigned N, int64_t x) { static inline bool isIntN(unsigned N, int64_t x) {
// return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
//} }
/// isMask_32 - This function returns true if the argument is a sequence of ones /// isMask_32 - This function returns true if the argument is a sequence of ones
/// starting at the least significant bit with the remainder zero (32 bit /// starting at the least significant bit with the remainder zero (32 bit

View File

@ -7,7 +7,8 @@ Capstone Engine
[![oss-fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/capstone.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:capstone) [![oss-fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/capstone.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:capstone)
> [!TIP] > [!TIP]
> Welcome to join our community group! &ensp; [<img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat-squeare&logo=telegram&logoColor=white" height="22" />](https://t.me/CapstoneEngine) > Welcome to join our community group!
> &ensp; [<img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat-squeare&logo=telegram&logoColor=white" height="22" />](https://t.me/CapstoneEngine)
Capstone is a disassembly framework with the target of becoming the ultimate Capstone is a disassembly framework with the target of becoming the ultimate
disasm engine for binary analysis and reversing in the security community. disasm engine for binary analysis and reversing in the security community.
@ -17,7 +18,7 @@ Capstone offers some unparalleled features:
- Support multiple hardware architectures: ARM, AArch64, Alpha, BPF, Ethereum VM, - Support multiple hardware architectures: ARM, AArch64, Alpha, BPF, Ethereum VM,
LoongArch, HP PA-RISC (HPPA), M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, LoongArch, HP PA-RISC (HPPA), M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH,
Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86 (16, 32, 64). Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86 (16, 32, 64), Xtensa.
- Having clean/simple/lightweight/intuitive architecture-neutral API. - Having clean/simple/lightweight/intuitive architecture-neutral API.

View File

@ -381,10 +381,16 @@ static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *By
Table = DecoderTable16; Table = DecoderTable16;
Inst = readBytes16(MI, Bytes); Inst = readBytes16(MI, Bytes);
} else if (Bytes[0] < 0xc0) { } else if (Bytes[0] < 0xc0) {
if (BytesLen < 4) {
return MCDisassembler_Fail;
}
*Size = 4; *Size = 4;
Table = DecoderTable32; Table = DecoderTable32;
Inst = readBytes32(MI, Bytes); Inst = readBytes32(MI, Bytes);
} else { } else {
if (BytesLen < 6) {
return MCDisassembler_Fail;
}
*Size = 6; *Size = 6;
Table = DecoderTable48; Table = DecoderTable48;
Inst = readBytes48(MI, Bytes); Inst = readBytes48(MI, Bytes);

View File

@ -0,0 +1,298 @@
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2023 */
/* Automatically translated source file from LLVM. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Only small edits allowed. */
/* For multiple similar edits, please create a Patch for the translator. */
/* Capstone's C++ file translator: */
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
//===-- XtensaDisassembler.cpp - Disassembler for Xtensa ------------------===//
//
// The LLVM Compiler Infrastructure
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the XtensaDisassembler class.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include "../../MathExtras.h"
#include "../../MCDisassembler.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../SStream.h"
#include "../../cs_priv.h"
#include "../../utils.h"
#include "priv.h"
#define GET_INSTRINFO_MC_DESC
#include "XtensaGenInstrInfo.inc"
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
#define DEBUG_TYPE "Xtensa-disassembler"
static const unsigned ARDecoderTable[] = {
Xtensa_A0, Xtensa_SP, Xtensa_A2, Xtensa_A3, Xtensa_A4, Xtensa_A5,
Xtensa_A6, Xtensa_A7, Xtensa_A8, Xtensa_A9, Xtensa_A10, Xtensa_A11,
Xtensa_A12, Xtensa_A13, Xtensa_A14, Xtensa_A15
};
static DecodeStatus DecodeARRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
if (RegNo >= ARR_SIZE(ARDecoderTable))
return MCDisassembler_Fail;
unsigned Reg = ARDecoderTable[RegNo];
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static const unsigned SRDecoderTable[] = { Xtensa_SAR, 3 };
static DecodeStatus DecodeSRRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
if (RegNo > 255)
return MCDisassembler_Fail;
for (unsigned i = 0; i + 1 < ARR_SIZE(SRDecoderTable); i += 2) {
if (SRDecoderTable[i + 1] == RegNo) {
unsigned Reg = SRDecoderTable[i];
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
}
return MCDisassembler_Fail;
}
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
uint64_t Address, uint64_t Offset,
uint64_t InstSize, MCInst *MI,
const void *Decoder)
{
// return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
// Offset, /*OpSize=*/0, InstSize);
return true;
}
static DecodeStatus decodeCallOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(18, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 2), 20)));
return MCDisassembler_Success;
}
static DecodeStatus decodeJumpOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(18, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 18)));
return MCDisassembler_Success;
}
static DecodeStatus decodeBranchOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
switch (MCInst_getOpcode(Inst)) {
case Xtensa_BEQZ:
case Xtensa_BGEZ:
case Xtensa_BLTZ:
case Xtensa_BNEZ:
CS_ASSERT(isUIntN(12, Imm) && "Invalid immediate");
if (!tryAddingSymbolicOperand(
SignExtend64((Imm), 12) + 4 + Address, true,
Address, 0, 3, Inst, Decoder))
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 12)));
break;
default:
CS_ASSERT(isUIntN(8, Imm) && "Invalid immediate");
if (!tryAddingSymbolicOperand(
SignExtend64((Imm), 8) + 4 + Address, true, Address,
0, 3, Inst, Decoder))
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 8)));
}
return MCDisassembler_Success;
}
static DecodeStatus decodeL32ROperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(16, Imm) && "Invalid immediate");
MCOperand_CreateImm0(
Inst,
(SignExtend64(((Imm << 2) + 0x40000 + (Address & 0x3)), 17)));
return MCDisassembler_Success;
}
static DecodeStatus decodeImm8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(8, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 8)));
return MCDisassembler_Success;
}
static DecodeStatus decodeImm8_sh8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(8, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 8), 16)));
return MCDisassembler_Success;
}
static DecodeStatus decodeImm12Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(12, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 12)));
return MCDisassembler_Success;
}
static DecodeStatus decodeUimm4Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(4, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeUimm5Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(5, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeImm1_16Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(4, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (Imm + 1));
return MCDisassembler_Success;
}
static DecodeStatus decodeShimm1_31Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(5, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (32 - Imm));
return MCDisassembler_Success;
}
static int64_t TableB4const[16] = { -1, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 16, 32, 64, 128, 256 };
static DecodeStatus decodeB4constOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(4, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (TableB4const[Imm]));
return MCDisassembler_Success;
}
static int64_t TableB4constu[16] = { 32768, 65536, 2, 3, 4, 5, 6, 7,
8, 10, 12, 16, 32, 64, 128, 256 };
static DecodeStatus decodeB4constuOperand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(4, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (TableB4constu[Imm]));
return MCDisassembler_Success;
}
static DecodeStatus decodeMem8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(12, Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 4) & 0xff));
return MCDisassembler_Success;
}
static DecodeStatus decodeMem16Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(12, Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 3) & 0x1fe));
return MCDisassembler_Success;
}
static DecodeStatus decodeMem32Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(12, Imm) && "Invalid immediate");
DecodeARRegisterClass(Inst, Imm & 0xf, Address, Decoder);
MCOperand_CreateImm0(Inst, ((Imm >> 2) & 0x3fc));
return MCDisassembler_Success;
}
/// Read three bytes from the ArrayRef and return 24 bit data
static DecodeStatus readInstruction24(MCInst *MI, uint64_t *SizeOut,
const uint8_t *Bytes,
const unsigned BytesSize, uint32_t *Insn)
{
// We want to read exactly 3 Bytes of data.
if (BytesSize < 3) {
*SizeOut = 0;
return MCDisassembler_Fail;
}
*Insn = readBytes24(MI, Bytes);
*SizeOut = 3;
return MCDisassembler_Success;
}
#include "XtensaGenDisassemblerTables.inc"
FieldFromInstruction(field_from_inst, uint32_t);
DecodeToMCInst(decode_to_MCInst, field_from_inst, uint32_t);
DecodeInstruction(decodeInstruction, field_from_inst, decode_to_MCInst,
uint32_t);
static DecodeStatus getInstruction(MCInst *MI, uint64_t *SizeOut,
const uint8_t *Bytes, unsigned BytesSize,
uint64_t Address)
{
uint32_t Insn;
DecodeStatus Result;
Result = readInstruction24(MI, SizeOut, Bytes, BytesSize, &Insn);
if (Result == MCDisassembler_Fail)
return MCDisassembler_Fail;
Result = decodeInstruction(DecoderTable24, MI, Insn, Address, NULL);
return Result;
}
DecodeStatus Xtensa_LLVM_getInstruction(MCInst *MI, uint16_t *size16,
const uint8_t *Bytes,
unsigned BytesSize, uint64_t Address)
{
uint64_t size64;
DecodeStatus status =
getInstruction(MI, &size64, Bytes, BytesSize, Address);
CS_ASSERT_RET_VAL(size64 < 0xffff, MCDisassembler_Fail);
*size16 = size64;
return status;
}

View File

@ -0,0 +1,13 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#ifndef XTENSA_DISASSEMBLER_H
#define XTENSA_DISASSEMBLER_H
#include "../../MCDisassembler.h"
DecodeStatus Xtensa_LLVM_getInstruction(MCInst *MI, uint16_t *Size,
const uint8_t *Bytes,
unsigned BytesSize, uint64_t Address);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
{ XTENSA_FEATURE_HASDENSITY, "HasDensity" },

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
"invalid", // XTENSA_INS_INVALID
"abs", // XTENSA_INS_ABS
"add", // XTENSA_INS_ADD
"addi", // XTENSA_INS_ADDI
"addmi", // XTENSA_INS_ADDMI
"addx2", // XTENSA_INS_ADDX2
"addx4", // XTENSA_INS_ADDX4
"addx8", // XTENSA_INS_ADDX8
"and", // XTENSA_INS_AND
"ball", // XTENSA_INS_BALL
"bany", // XTENSA_INS_BANY
"bbc", // XTENSA_INS_BBC
"bbci", // XTENSA_INS_BBCI
"bbs", // XTENSA_INS_BBS
"bbsi", // XTENSA_INS_BBSI
"beq", // XTENSA_INS_BEQ
"beqi", // XTENSA_INS_BEQI
"beqz", // XTENSA_INS_BEQZ
"bge", // XTENSA_INS_BGE
"bgei", // XTENSA_INS_BGEI
"bgeu", // XTENSA_INS_BGEU
"bgeui", // XTENSA_INS_BGEUI
"bgez", // XTENSA_INS_BGEZ
"blt", // XTENSA_INS_BLT
"blti", // XTENSA_INS_BLTI
"bltu", // XTENSA_INS_BLTU
"bltui", // XTENSA_INS_BLTUI
"bltz", // XTENSA_INS_BLTZ
"bnall", // XTENSA_INS_BNALL
"bne", // XTENSA_INS_BNE
"bnei", // XTENSA_INS_BNEI
"bnez", // XTENSA_INS_BNEZ
"bnone", // XTENSA_INS_BNONE
"call0", // XTENSA_INS_CALL0
"callx0", // XTENSA_INS_CALLX0
"dsync", // XTENSA_INS_DSYNC
"esync", // XTENSA_INS_ESYNC
"extui", // XTENSA_INS_EXTUI
"extw", // XTENSA_INS_EXTW
"isync", // XTENSA_INS_ISYNC
"j", // XTENSA_INS_J
"jx", // XTENSA_INS_JX
"l16si", // XTENSA_INS_L16SI
"l16ui", // XTENSA_INS_L16UI
"l32i", // XTENSA_INS_L32I
"l32r", // XTENSA_INS_L32R
"l8ui", // XTENSA_INS_L8UI
"memw", // XTENSA_INS_MEMW
"moveqz", // XTENSA_INS_MOVEQZ
"movgez", // XTENSA_INS_MOVGEZ
"movi", // XTENSA_INS_MOVI
"movltz", // XTENSA_INS_MOVLTZ
"movnez", // XTENSA_INS_MOVNEZ
"neg", // XTENSA_INS_NEG
"nop", // XTENSA_INS_NOP
"or", // XTENSA_INS_OR
"ret", // XTENSA_INS_RET
"rsr", // XTENSA_INS_RSR
"rsync", // XTENSA_INS_RSYNC
"s16i", // XTENSA_INS_S16I
"s32i", // XTENSA_INS_S32I
"s8i", // XTENSA_INS_S8I
"sll", // XTENSA_INS_SLL
"slli", // XTENSA_INS_SLLI
"sra", // XTENSA_INS_SRA
"srai", // XTENSA_INS_SRAI
"src", // XTENSA_INS_SRC
"srl", // XTENSA_INS_SRL
"srli", // XTENSA_INS_SRLI
"ssa8l", // XTENSA_INS_SSA8L
"ssai", // XTENSA_INS_SSAI
"ssl", // XTENSA_INS_SSL
"ssr", // XTENSA_INS_SSR
"sub", // XTENSA_INS_SUB
"subx2", // XTENSA_INS_SUBX2
"subx4", // XTENSA_INS_SUBX4
"subx8", // XTENSA_INS_SUBX8
"wsr", // XTENSA_INS_WSR
"xor", // XTENSA_INS_XOR
"xsr", // XTENSA_INS_XSR

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
XTENSA_OP_GROUP_OPERAND = 0,
XTENSA_OP_GROUP_IMM8_ASMOPERAND = 1,
XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND = 2,
XTENSA_OP_GROUP_BRANCHTARGET = 3,
XTENSA_OP_GROUP_UIMM5_ASMOPERAND = 4,
XTENSA_OP_GROUP_B4CONST_ASMOPERAND = 5,
XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND = 6,
XTENSA_OP_GROUP_CALLOPERAND = 7,
XTENSA_OP_GROUP_IMM1_16_ASMOPERAND = 8,
XTENSA_OP_GROUP_JUMPTARGET = 9,
XTENSA_OP_GROUP_MEMOPERAND = 10,
XTENSA_OP_GROUP_L32RTARGET = 11,
XTENSA_OP_GROUP_IMM12M_ASMOPERAND = 12,
XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND = 13,
XTENSA_OP_GROUP_UIMM4_ASMOPERAND = 14,

View File

@ -0,0 +1,633 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
#include "../../MCInst.h"
#include "../../LEB128.h"
// Helper function for extracting fields from encoded instructions.
#define FieldFromInstruction(fname, InsnType) \
static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \
{ \
InsnType fieldMask; \
if (numBits == sizeof(InsnType) * 8) \
fieldMask = (InsnType)(-1LL); \
else \
fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \
return (insn & fieldMask) >> startBit; \
}
static bool Check(DecodeStatus *Out, const DecodeStatus In) {
*Out = (DecodeStatus) (*Out & In);
return *Out != MCDisassembler_Fail;
}
static const uint8_t DecoderTable24[] = {
/* 0 */ MCD_OPC_ExtractField, 0, 4, // Inst{3-0} ...
/* 3 */ MCD_OPC_FilterValue, 0, 11, 3, 0, // Skip to: 787
/* 8 */ MCD_OPC_ExtractField, 17, 3, // Inst{19-17} ...
/* 11 */ MCD_OPC_FilterValue, 0, 146, 2, 0, // Skip to: 674
/* 16 */ MCD_OPC_ExtractField, 21, 3, // Inst{23-21} ...
/* 19 */ MCD_OPC_FilterValue, 0, 198, 0, 0, // Skip to: 222
/* 24 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 27 */ MCD_OPC_FilterValue, 0, 181, 0, 0, // Skip to: 213
/* 32 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 35 */ MCD_OPC_FilterValue, 0, 164, 0, 0, // Skip to: 204
/* 40 */ MCD_OPC_ExtractField, 4, 4, // Inst{7-4} ...
/* 43 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 59
/* 48 */ MCD_OPC_CheckField, 8, 8, 32, 144, 4, 0, // Skip to: 1223
/* 55 */ MCD_OPC_Decode, 181, 2, 0, // Opcode: ISYNC
/* 59 */ MCD_OPC_FilterValue, 1, 11, 0, 0, // Skip to: 75
/* 64 */ MCD_OPC_CheckField, 8, 8, 32, 128, 4, 0, // Skip to: 1223
/* 71 */ MCD_OPC_Decode, 200, 2, 0, // Opcode: RSYNC
/* 75 */ MCD_OPC_FilterValue, 2, 11, 0, 0, // Skip to: 91
/* 80 */ MCD_OPC_CheckField, 8, 8, 32, 112, 4, 0, // Skip to: 1223
/* 87 */ MCD_OPC_Decode, 178, 2, 0, // Opcode: ESYNC
/* 91 */ MCD_OPC_FilterValue, 3, 11, 0, 0, // Skip to: 107
/* 96 */ MCD_OPC_CheckField, 8, 8, 32, 96, 4, 0, // Skip to: 1223
/* 103 */ MCD_OPC_Decode, 177, 2, 0, // Opcode: DSYNC
/* 107 */ MCD_OPC_FilterValue, 8, 11, 0, 0, // Skip to: 123
/* 112 */ MCD_OPC_CheckField, 8, 8, 0, 80, 4, 0, // Skip to: 1223
/* 119 */ MCD_OPC_Decode, 198, 2, 0, // Opcode: RET
/* 123 */ MCD_OPC_FilterValue, 10, 11, 0, 0, // Skip to: 139
/* 128 */ MCD_OPC_CheckField, 12, 4, 0, 64, 4, 0, // Skip to: 1223
/* 135 */ MCD_OPC_Decode, 183, 2, 1, // Opcode: JX
/* 139 */ MCD_OPC_FilterValue, 12, 28, 0, 0, // Skip to: 172
/* 144 */ MCD_OPC_ExtractField, 12, 4, // Inst{15-12} ...
/* 147 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 156
/* 152 */ MCD_OPC_Decode, 176, 2, 1, // Opcode: CALLX0
/* 156 */ MCD_OPC_FilterValue, 2, 38, 4, 0, // Skip to: 1223
/* 161 */ MCD_OPC_CheckField, 8, 4, 0, 31, 4, 0, // Skip to: 1223
/* 168 */ MCD_OPC_Decode, 189, 2, 0, // Opcode: MEMW
/* 172 */ MCD_OPC_FilterValue, 13, 11, 0, 0, // Skip to: 188
/* 177 */ MCD_OPC_CheckField, 8, 8, 32, 15, 4, 0, // Skip to: 1223
/* 184 */ MCD_OPC_Decode, 180, 2, 0, // Opcode: EXTW
/* 188 */ MCD_OPC_FilterValue, 15, 6, 4, 0, // Skip to: 1223
/* 193 */ MCD_OPC_CheckField, 8, 8, 32, 255, 3, 0, // Skip to: 1223
/* 200 */ MCD_OPC_Decode, 196, 2, 0, // Opcode: NOP
/* 204 */ MCD_OPC_FilterValue, 1, 246, 3, 0, // Skip to: 1223
/* 209 */ MCD_OPC_Decode, 150, 2, 2, // Opcode: AND
/* 213 */ MCD_OPC_FilterValue, 1, 237, 3, 0, // Skip to: 1223
/* 218 */ MCD_OPC_Decode, 205, 2, 3, // Opcode: SLLI
/* 222 */ MCD_OPC_FilterValue, 1, 38, 0, 0, // Skip to: 265
/* 227 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 230 */ MCD_OPC_FilterValue, 0, 21, 0, 0, // Skip to: 256
/* 235 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 238 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 247
/* 243 */ MCD_OPC_Decode, 197, 2, 2, // Opcode: OR
/* 247 */ MCD_OPC_FilterValue, 1, 203, 3, 0, // Skip to: 1223
/* 252 */ MCD_OPC_Decode, 220, 2, 2, // Opcode: XOR
/* 256 */ MCD_OPC_FilterValue, 1, 194, 3, 0, // Skip to: 1223
/* 261 */ MCD_OPC_Decode, 207, 2, 4, // Opcode: SRAI
/* 265 */ MCD_OPC_FilterValue, 2, 119, 0, 0, // Skip to: 389
/* 270 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 273 */ MCD_OPC_FilterValue, 0, 95, 0, 0, // Skip to: 373
/* 278 */ MCD_OPC_ExtractField, 12, 4, // Inst{15-12} ...
/* 281 */ MCD_OPC_FilterValue, 0, 18, 0, 0, // Skip to: 304
/* 286 */ MCD_OPC_CheckField, 20, 1, 0, 162, 3, 0, // Skip to: 1223
/* 293 */ MCD_OPC_CheckField, 4, 4, 0, 155, 3, 0, // Skip to: 1223
/* 300 */ MCD_OPC_Decode, 214, 2, 1, // Opcode: SSR
/* 304 */ MCD_OPC_FilterValue, 1, 18, 0, 0, // Skip to: 327
/* 309 */ MCD_OPC_CheckField, 20, 1, 0, 139, 3, 0, // Skip to: 1223
/* 316 */ MCD_OPC_CheckField, 4, 4, 0, 132, 3, 0, // Skip to: 1223
/* 323 */ MCD_OPC_Decode, 213, 2, 1, // Opcode: SSL
/* 327 */ MCD_OPC_FilterValue, 2, 18, 0, 0, // Skip to: 350
/* 332 */ MCD_OPC_CheckField, 20, 1, 0, 116, 3, 0, // Skip to: 1223
/* 339 */ MCD_OPC_CheckField, 4, 4, 0, 109, 3, 0, // Skip to: 1223
/* 346 */ MCD_OPC_Decode, 211, 2, 1, // Opcode: SSA8L
/* 350 */ MCD_OPC_FilterValue, 4, 100, 3, 0, // Skip to: 1223
/* 355 */ MCD_OPC_CheckField, 20, 1, 0, 93, 3, 0, // Skip to: 1223
/* 362 */ MCD_OPC_CheckField, 5, 3, 0, 86, 3, 0, // Skip to: 1223
/* 369 */ MCD_OPC_Decode, 212, 2, 5, // Opcode: SSAI
/* 373 */ MCD_OPC_FilterValue, 1, 77, 3, 0, // Skip to: 1223
/* 378 */ MCD_OPC_CheckField, 20, 1, 0, 70, 3, 0, // Skip to: 1223
/* 385 */ MCD_OPC_Decode, 210, 2, 6, // Opcode: SRLI
/* 389 */ MCD_OPC_FilterValue, 3, 59, 0, 0, // Skip to: 453
/* 394 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 397 */ MCD_OPC_FilterValue, 0, 35, 0, 0, // Skip to: 437
/* 402 */ MCD_OPC_ExtractField, 8, 4, // Inst{11-8} ...
/* 405 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 421
/* 410 */ MCD_OPC_CheckField, 20, 1, 0, 38, 3, 0, // Skip to: 1223
/* 417 */ MCD_OPC_Decode, 195, 2, 7, // Opcode: NEG
/* 421 */ MCD_OPC_FilterValue, 1, 29, 3, 0, // Skip to: 1223
/* 426 */ MCD_OPC_CheckField, 20, 1, 0, 22, 3, 0, // Skip to: 1223
/* 433 */ MCD_OPC_Decode, 143, 2, 7, // Opcode: ABS
/* 437 */ MCD_OPC_FilterValue, 1, 13, 3, 0, // Skip to: 1223
/* 442 */ MCD_OPC_CheckField, 20, 1, 0, 6, 3, 0, // Skip to: 1223
/* 449 */ MCD_OPC_Decode, 221, 2, 8, // Opcode: XSR
/* 453 */ MCD_OPC_FilterValue, 4, 62, 0, 0, // Skip to: 520
/* 458 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 461 */ MCD_OPC_FilterValue, 0, 21, 0, 0, // Skip to: 487
/* 466 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 469 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 478
/* 474 */ MCD_OPC_Decode, 144, 2, 2, // Opcode: ADD
/* 478 */ MCD_OPC_FilterValue, 1, 228, 2, 0, // Skip to: 1223
/* 483 */ MCD_OPC_Decode, 147, 2, 2, // Opcode: ADDX2
/* 487 */ MCD_OPC_FilterValue, 1, 219, 2, 0, // Skip to: 1223
/* 492 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 495 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 504
/* 500 */ MCD_OPC_Decode, 208, 2, 2, // Opcode: SRC
/* 504 */ MCD_OPC_FilterValue, 1, 202, 2, 0, // Skip to: 1223
/* 509 */ MCD_OPC_CheckField, 8, 4, 0, 195, 2, 0, // Skip to: 1223
/* 516 */ MCD_OPC_Decode, 209, 2, 7, // Opcode: SRL
/* 520 */ MCD_OPC_FilterValue, 5, 69, 0, 0, // Skip to: 594
/* 525 */ MCD_OPC_ExtractField, 16, 1, // Inst{16} ...
/* 528 */ MCD_OPC_FilterValue, 0, 21, 0, 0, // Skip to: 554
/* 533 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 536 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 545
/* 541 */ MCD_OPC_Decode, 148, 2, 2, // Opcode: ADDX4
/* 545 */ MCD_OPC_FilterValue, 1, 161, 2, 0, // Skip to: 1223
/* 550 */ MCD_OPC_Decode, 149, 2, 2, // Opcode: ADDX8
/* 554 */ MCD_OPC_FilterValue, 1, 152, 2, 0, // Skip to: 1223
/* 559 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 562 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 578
/* 567 */ MCD_OPC_CheckField, 4, 4, 0, 137, 2, 0, // Skip to: 1223
/* 574 */ MCD_OPC_Decode, 204, 2, 9, // Opcode: SLL
/* 578 */ MCD_OPC_FilterValue, 1, 128, 2, 0, // Skip to: 1223
/* 583 */ MCD_OPC_CheckField, 8, 4, 0, 121, 2, 0, // Skip to: 1223
/* 590 */ MCD_OPC_Decode, 206, 2, 7, // Opcode: SRA
/* 594 */ MCD_OPC_FilterValue, 6, 35, 0, 0, // Skip to: 634
/* 599 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 602 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 618
/* 607 */ MCD_OPC_CheckField, 16, 1, 0, 97, 2, 0, // Skip to: 1223
/* 614 */ MCD_OPC_Decode, 215, 2, 2, // Opcode: SUB
/* 618 */ MCD_OPC_FilterValue, 1, 88, 2, 0, // Skip to: 1223
/* 623 */ MCD_OPC_CheckField, 16, 1, 0, 81, 2, 0, // Skip to: 1223
/* 630 */ MCD_OPC_Decode, 216, 2, 2, // Opcode: SUBX2
/* 634 */ MCD_OPC_FilterValue, 7, 72, 2, 0, // Skip to: 1223
/* 639 */ MCD_OPC_ExtractField, 20, 1, // Inst{20} ...
/* 642 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 658
/* 647 */ MCD_OPC_CheckField, 16, 1, 0, 57, 2, 0, // Skip to: 1223
/* 654 */ MCD_OPC_Decode, 217, 2, 2, // Opcode: SUBX4
/* 658 */ MCD_OPC_FilterValue, 1, 48, 2, 0, // Skip to: 1223
/* 663 */ MCD_OPC_CheckField, 16, 1, 0, 41, 2, 0, // Skip to: 1223
/* 670 */ MCD_OPC_Decode, 218, 2, 2, // Opcode: SUBX8
/* 674 */ MCD_OPC_FilterValue, 1, 99, 0, 0, // Skip to: 778
/* 679 */ MCD_OPC_ExtractField, 20, 4, // Inst{23-20} ...
/* 682 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 698
/* 687 */ MCD_OPC_CheckField, 16, 1, 1, 17, 2, 0, // Skip to: 1223
/* 694 */ MCD_OPC_Decode, 199, 2, 10, // Opcode: RSR
/* 698 */ MCD_OPC_FilterValue, 1, 11, 0, 0, // Skip to: 714
/* 703 */ MCD_OPC_CheckField, 16, 1, 1, 1, 2, 0, // Skip to: 1223
/* 710 */ MCD_OPC_Decode, 219, 2, 11, // Opcode: WSR
/* 714 */ MCD_OPC_FilterValue, 8, 11, 0, 0, // Skip to: 730
/* 719 */ MCD_OPC_CheckField, 16, 1, 1, 241, 1, 0, // Skip to: 1223
/* 726 */ MCD_OPC_Decode, 190, 2, 2, // Opcode: MOVEQZ
/* 730 */ MCD_OPC_FilterValue, 9, 11, 0, 0, // Skip to: 746
/* 735 */ MCD_OPC_CheckField, 16, 1, 1, 225, 1, 0, // Skip to: 1223
/* 742 */ MCD_OPC_Decode, 194, 2, 2, // Opcode: MOVNEZ
/* 746 */ MCD_OPC_FilterValue, 10, 11, 0, 0, // Skip to: 762
/* 751 */ MCD_OPC_CheckField, 16, 1, 1, 209, 1, 0, // Skip to: 1223
/* 758 */ MCD_OPC_Decode, 193, 2, 2, // Opcode: MOVLTZ
/* 762 */ MCD_OPC_FilterValue, 11, 200, 1, 0, // Skip to: 1223
/* 767 */ MCD_OPC_CheckField, 16, 1, 1, 193, 1, 0, // Skip to: 1223
/* 774 */ MCD_OPC_Decode, 191, 2, 2, // Opcode: MOVGEZ
/* 778 */ MCD_OPC_FilterValue, 2, 184, 1, 0, // Skip to: 1223
/* 783 */ MCD_OPC_Decode, 179, 2, 12, // Opcode: EXTUI
/* 787 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 796
/* 792 */ MCD_OPC_Decode, 187, 2, 13, // Opcode: L32R
/* 796 */ MCD_OPC_FilterValue, 2, 93, 0, 0, // Skip to: 894
/* 801 */ MCD_OPC_ExtractField, 12, 4, // Inst{15-12} ...
/* 804 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 813
/* 809 */ MCD_OPC_Decode, 188, 2, 14, // Opcode: L8UI
/* 813 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 822
/* 818 */ MCD_OPC_Decode, 185, 2, 15, // Opcode: L16UI
/* 822 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 831
/* 827 */ MCD_OPC_Decode, 186, 2, 16, // Opcode: L32I
/* 831 */ MCD_OPC_FilterValue, 4, 4, 0, 0, // Skip to: 840
/* 836 */ MCD_OPC_Decode, 203, 2, 14, // Opcode: S8I
/* 840 */ MCD_OPC_FilterValue, 5, 4, 0, 0, // Skip to: 849
/* 845 */ MCD_OPC_Decode, 201, 2, 15, // Opcode: S16I
/* 849 */ MCD_OPC_FilterValue, 6, 4, 0, 0, // Skip to: 858
/* 854 */ MCD_OPC_Decode, 202, 2, 16, // Opcode: S32I
/* 858 */ MCD_OPC_FilterValue, 9, 4, 0, 0, // Skip to: 867
/* 863 */ MCD_OPC_Decode, 184, 2, 15, // Opcode: L16SI
/* 867 */ MCD_OPC_FilterValue, 10, 4, 0, 0, // Skip to: 876
/* 872 */ MCD_OPC_Decode, 192, 2, 17, // Opcode: MOVI
/* 876 */ MCD_OPC_FilterValue, 12, 4, 0, 0, // Skip to: 885
/* 881 */ MCD_OPC_Decode, 145, 2, 18, // Opcode: ADDI
/* 885 */ MCD_OPC_FilterValue, 13, 77, 1, 0, // Skip to: 1223
/* 890 */ MCD_OPC_Decode, 146, 2, 19, // Opcode: ADDMI
/* 894 */ MCD_OPC_FilterValue, 5, 11, 0, 0, // Skip to: 910
/* 899 */ MCD_OPC_CheckField, 4, 2, 0, 61, 1, 0, // Skip to: 1223
/* 906 */ MCD_OPC_Decode, 175, 2, 20, // Opcode: CALL0
/* 910 */ MCD_OPC_FilterValue, 6, 126, 0, 0, // Skip to: 1041
/* 915 */ MCD_OPC_ExtractField, 4, 2, // Inst{5-4} ...
/* 918 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 927
/* 923 */ MCD_OPC_Decode, 182, 2, 21, // Opcode: J
/* 927 */ MCD_OPC_FilterValue, 1, 39, 0, 0, // Skip to: 971
/* 932 */ MCD_OPC_ExtractField, 6, 2, // Inst{7-6} ...
/* 935 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 944
/* 940 */ MCD_OPC_Decode, 159, 2, 22, // Opcode: BEQZ
/* 944 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 953
/* 949 */ MCD_OPC_Decode, 173, 2, 22, // Opcode: BNEZ
/* 953 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 962
/* 958 */ MCD_OPC_Decode, 169, 2, 22, // Opcode: BLTZ
/* 962 */ MCD_OPC_FilterValue, 3, 0, 1, 0, // Skip to: 1223
/* 967 */ MCD_OPC_Decode, 164, 2, 22, // Opcode: BGEZ
/* 971 */ MCD_OPC_FilterValue, 2, 39, 0, 0, // Skip to: 1015
/* 976 */ MCD_OPC_ExtractField, 6, 2, // Inst{7-6} ...
/* 979 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 988
/* 984 */ MCD_OPC_Decode, 158, 2, 23, // Opcode: BEQI
/* 988 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 997
/* 993 */ MCD_OPC_Decode, 172, 2, 23, // Opcode: BNEI
/* 997 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 1006
/* 1002 */ MCD_OPC_Decode, 166, 2, 23, // Opcode: BLTI
/* 1006 */ MCD_OPC_FilterValue, 3, 212, 0, 0, // Skip to: 1223
/* 1011 */ MCD_OPC_Decode, 161, 2, 23, // Opcode: BGEI
/* 1015 */ MCD_OPC_FilterValue, 3, 203, 0, 0, // Skip to: 1223
/* 1020 */ MCD_OPC_ExtractField, 6, 2, // Inst{7-6} ...
/* 1023 */ MCD_OPC_FilterValue, 2, 4, 0, 0, // Skip to: 1032
/* 1028 */ MCD_OPC_Decode, 168, 2, 24, // Opcode: BLTUI
/* 1032 */ MCD_OPC_FilterValue, 3, 186, 0, 0, // Skip to: 1223
/* 1037 */ MCD_OPC_Decode, 163, 2, 24, // Opcode: BGEUI
/* 1041 */ MCD_OPC_FilterValue, 7, 177, 0, 0, // Skip to: 1223
/* 1046 */ MCD_OPC_ExtractField, 13, 3, // Inst{15-13} ...
/* 1049 */ MCD_OPC_FilterValue, 0, 21, 0, 0, // Skip to: 1075
/* 1054 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1057 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1066
/* 1062 */ MCD_OPC_Decode, 174, 2, 25, // Opcode: BNONE
/* 1066 */ MCD_OPC_FilterValue, 1, 152, 0, 0, // Skip to: 1223
/* 1071 */ MCD_OPC_Decode, 157, 2, 25, // Opcode: BEQ
/* 1075 */ MCD_OPC_FilterValue, 1, 21, 0, 0, // Skip to: 1101
/* 1080 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1083 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1092
/* 1088 */ MCD_OPC_Decode, 165, 2, 25, // Opcode: BLT
/* 1092 */ MCD_OPC_FilterValue, 1, 126, 0, 0, // Skip to: 1223
/* 1097 */ MCD_OPC_Decode, 167, 2, 25, // Opcode: BLTU
/* 1101 */ MCD_OPC_FilterValue, 2, 21, 0, 0, // Skip to: 1127
/* 1106 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1109 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1118
/* 1114 */ MCD_OPC_Decode, 151, 2, 25, // Opcode: BALL
/* 1118 */ MCD_OPC_FilterValue, 1, 100, 0, 0, // Skip to: 1223
/* 1123 */ MCD_OPC_Decode, 153, 2, 25, // Opcode: BBC
/* 1127 */ MCD_OPC_FilterValue, 3, 4, 0, 0, // Skip to: 1136
/* 1132 */ MCD_OPC_Decode, 154, 2, 26, // Opcode: BBCI
/* 1136 */ MCD_OPC_FilterValue, 4, 21, 0, 0, // Skip to: 1162
/* 1141 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1144 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1153
/* 1149 */ MCD_OPC_Decode, 152, 2, 25, // Opcode: BANY
/* 1153 */ MCD_OPC_FilterValue, 1, 65, 0, 0, // Skip to: 1223
/* 1158 */ MCD_OPC_Decode, 171, 2, 25, // Opcode: BNE
/* 1162 */ MCD_OPC_FilterValue, 5, 21, 0, 0, // Skip to: 1188
/* 1167 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1170 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1179
/* 1175 */ MCD_OPC_Decode, 160, 2, 25, // Opcode: BGE
/* 1179 */ MCD_OPC_FilterValue, 1, 39, 0, 0, // Skip to: 1223
/* 1184 */ MCD_OPC_Decode, 162, 2, 25, // Opcode: BGEU
/* 1188 */ MCD_OPC_FilterValue, 6, 21, 0, 0, // Skip to: 1214
/* 1193 */ MCD_OPC_ExtractField, 12, 1, // Inst{12} ...
/* 1196 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 1205
/* 1201 */ MCD_OPC_Decode, 170, 2, 25, // Opcode: BNALL
/* 1205 */ MCD_OPC_FilterValue, 1, 13, 0, 0, // Skip to: 1223
/* 1210 */ MCD_OPC_Decode, 155, 2, 25, // Opcode: BBS
/* 1214 */ MCD_OPC_FilterValue, 7, 4, 0, 0, // Skip to: 1223
/* 1219 */ MCD_OPC_Decode, 156, 2, 26, // Opcode: BBSI
/* 1223 */ MCD_OPC_Fail,
0
};
static bool checkDecoderPredicate(MCInst *Inst, unsigned Idx) {
llvm_unreachable("Invalid index!");
return true;
}
#define DecodeToMCInst(fname, fieldname, InsnType) \
static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \
uint64_t Address, const void *Decoder, bool *DecodeComplete) \
{ \
*DecodeComplete = true; \
InsnType tmp; \
switch (Idx) { \
default: /* llvm_unreachable("Invalid index!"); */ \
case 0: \
return S; \
case 1: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 2: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 3: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 4, 4) << 0; \
tmp |= fieldname(insn, 20, 1) << 4; \
if (!Check(&S, decodeShimm1_31Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 4: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 0; \
tmp |= fieldname(insn, 20, 1) << 4; \
if (!Check(&S, decodeUimm5Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 5: \
tmp = 0x0; \
tmp |= fieldname(insn, 4, 1) << 4; \
tmp |= fieldname(insn, 8, 4) << 0; \
if (!Check(&S, decodeUimm5Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 6: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, decodeUimm4Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 7: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 8: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 8); \
if (!Check(&S, DecodeSRRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 8); \
if (!Check(&S, DecodeSRRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 9: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 10: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 8); \
if (!Check(&S, DecodeSRRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 11: \
tmp = fieldname(insn, 8, 8); \
if (!Check(&S, DecodeSRRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 12: \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 0; \
tmp |= fieldname(insn, 16, 1) << 4; \
if (!Check(&S, decodeUimm5Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 20, 4); \
if (!Check(&S, decodeImm1_16Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 13: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 16); \
if (!Check(&S, decodeL32ROperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 14: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 0; \
tmp |= fieldname(insn, 16, 8) << 4; \
if (!Check(&S, decodeMem8Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 15: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 0; \
tmp |= fieldname(insn, 16, 8) << 4; \
if (!Check(&S, decodeMem16Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 16: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 0; \
tmp |= fieldname(insn, 16, 8) << 4; \
if (!Check(&S, decodeMem32Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 17: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 8, 4) << 8; \
tmp |= fieldname(insn, 16, 8) << 0; \
if (!Check(&S, decodeImm12Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 18: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8); \
if (!Check(&S, decodeImm8Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 19: \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8) << 8; \
if (!Check(&S, decodeImm8_sh8Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 20: \
tmp = fieldname(insn, 6, 18); \
if (!Check(&S, decodeCallOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 21: \
tmp = fieldname(insn, 6, 18); \
if (!Check(&S, decodeJumpOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 22: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 12, 12); \
if (!Check(&S, decodeBranchOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 23: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, decodeB4constOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8); \
if (!Check(&S, decodeBranchOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 24: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 12, 4); \
if (!Check(&S, decodeB4constuOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8); \
if (!Check(&S, decodeBranchOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 25: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 4, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8); \
if (!Check(&S, decodeBranchOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
case 26: \
tmp = fieldname(insn, 8, 4); \
if (!Check(&S, DecodeARRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = 0x0; \
tmp |= fieldname(insn, 4, 4) << 0; \
tmp |= fieldname(insn, 12, 1) << 4; \
if (!Check(&S, decodeUimm5Operand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
tmp = fieldname(insn, 16, 8); \
if (!Check(&S, decodeBranchOperand(MI, tmp, Address, Decoder))) { return MCDisassembler_Fail; } \
return S; \
} \
}
#define DecodeInstruction(fname, fieldname, decoder, InsnType) \
static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \
InsnType insn, uint64_t Address, const void *Decoder) { \
const uint8_t *Ptr = DecodeTable; \
uint64_t CurFieldValue = 0; \
DecodeStatus S = MCDisassembler_Success; \
while (true) { \
switch (*Ptr) { \
default: \
return MCDisassembler_Fail; \
case MCD_OPC_ExtractField: { \
unsigned Start = *++Ptr; \
unsigned Len = *++Ptr; \
++Ptr; \
CurFieldValue = fieldname(insn, Start, Len); \
break; \
} \
case MCD_OPC_FilterValue: { \
/* Decode the field value. */ \
unsigned Len; \
uint64_t Val = decodeULEB128(++Ptr, &Len); \
Ptr += Len; \
/* NumToSkip is a plain 24-bit integer. */ \
unsigned NumToSkip = *Ptr++; \
NumToSkip |= (*Ptr++) << 8; \
NumToSkip |= (*Ptr++) << 16; \
/* Perform the filter operation. */ \
if (Val != CurFieldValue) \
Ptr += NumToSkip; \
break; \
} \
case MCD_OPC_CheckField: { \
unsigned Start = *++Ptr; \
unsigned Len = *++Ptr; \
uint64_t FieldValue = fieldname(insn, Start, Len); \
/* Decode the field value. */ \
unsigned PtrLen = 0; \
uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen); \
Ptr += PtrLen; \
/* NumToSkip is a plain 24-bit integer. */ \
unsigned NumToSkip = *Ptr++; \
NumToSkip |= (*Ptr++) << 8; \
NumToSkip |= (*Ptr++) << 16; \
/* If the actual and expected values don't match, skip. */ \
if (ExpectedValue != FieldValue) \
Ptr += NumToSkip; \
break; \
} \
case MCD_OPC_CheckPredicate: { \
unsigned Len; \
/* Decode the Predicate Index value. */ \
unsigned PIdx = decodeULEB128(++Ptr, &Len); \
Ptr += Len; \
/* NumToSkip is a plain 24-bit integer. */ \
unsigned NumToSkip = *Ptr++; \
NumToSkip |= (*Ptr++) << 8; \
NumToSkip |= (*Ptr++) << 16; \
/* Check the predicate. */ \
bool Pred = checkDecoderPredicate(MI, PIdx); \
if (!Pred) \
Ptr += NumToSkip; \
break; \
} \
case MCD_OPC_Decode: { \
unsigned Len; \
/* Decode the Opcode value. */ \
unsigned Opc = decodeULEB128(++Ptr, &Len); \
Ptr += Len; \
unsigned DecodeIdx = decodeULEB128(Ptr, &Len); \
Ptr += Len; \
MCInst_clear(MI); \
MCInst_setOpcode(MI, Opc); \
bool DecodeComplete; \
S = decoder(S, DecodeIdx, insn, MI, Address, Decoder, &DecodeComplete); \
return S; \
} \
case MCD_OPC_TryDecode: { \
unsigned Len; \
/* Decode the Opcode value. */ \
unsigned Opc = decodeULEB128(++Ptr, &Len); \
Ptr += Len; \
unsigned DecodeIdx = decodeULEB128(Ptr, &Len); \
Ptr += Len; \
/* NumToSkip is a plain 24-bit integer. */ \
unsigned NumToSkip = *Ptr++; \
NumToSkip |= (*Ptr++) << 8; \
NumToSkip |= (*Ptr++) << 16; \
/* Perform the decode operation. */ \
MCInst_setOpcode(MI, Opc); \
bool DecodeComplete; \
S = decoder(S, DecodeIdx, insn, MI, Address, Decoder, &DecodeComplete); \
if (DecodeComplete) { \
/* Decoding complete. */ \
return S; \
} else { \
/* If the decoding was incomplete, skip. */ \
Ptr += NumToSkip; \
/* Reset decode status. This also drops a SoftFail status that could be */ \
/* set before the decode attempt. */ \
S = MCDisassembler_Success; \
} \
break; \
} \
case MCD_OPC_SoftFail: { \
/* Decode the mask values. */ \
unsigned Len; \
uint64_t PositiveMask = decodeULEB128(++Ptr, &Len); \
Ptr += Len; \
uint64_t NegativeMask = decodeULEB128(Ptr, &Len); \
Ptr += Len; \
bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0; \
if (Fail) \
S = MCDisassembler_SoftFail; \
break; \
} \
case MCD_OPC_Fail: { \
return MCDisassembler_Fail; \
} \
} \
} \
/* Bogisity detected in disassembler state machine! */ \
}

View File

@ -0,0 +1,814 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
#ifdef GET_INSTRINFO_ENUM
#undef GET_INSTRINFO_ENUM
enum {
Xtensa_PHI = 0,
Xtensa_INLINEASM = 1,
Xtensa_INLINEASM_BR = 2,
Xtensa_CFI_INSTRUCTION = 3,
Xtensa_EH_LABEL = 4,
Xtensa_GC_LABEL = 5,
Xtensa_ANNOTATION_LABEL = 6,
Xtensa_KILL = 7,
Xtensa_EXTRACT_SUBREG = 8,
Xtensa_INSERT_SUBREG = 9,
Xtensa_IMPLICIT_DEF = 10,
Xtensa_SUBREG_TO_REG = 11,
Xtensa_COPY_TO_REGCLASS = 12,
Xtensa_DBG_VALUE = 13,
Xtensa_DBG_VALUE_LIST = 14,
Xtensa_DBG_INSTR_REF = 15,
Xtensa_DBG_PHI = 16,
Xtensa_DBG_LABEL = 17,
Xtensa_REG_SEQUENCE = 18,
Xtensa_COPY = 19,
Xtensa_BUNDLE = 20,
Xtensa_LIFETIME_START = 21,
Xtensa_LIFETIME_END = 22,
Xtensa_PSEUDO_PROBE = 23,
Xtensa_ARITH_FENCE = 24,
Xtensa_STACKMAP = 25,
Xtensa_FENTRY_CALL = 26,
Xtensa_PATCHPOINT = 27,
Xtensa_LOAD_STACK_GUARD = 28,
Xtensa_PREALLOCATED_SETUP = 29,
Xtensa_PREALLOCATED_ARG = 30,
Xtensa_STATEPOINT = 31,
Xtensa_LOCAL_ESCAPE = 32,
Xtensa_FAULTING_OP = 33,
Xtensa_PATCHABLE_OP = 34,
Xtensa_PATCHABLE_FUNCTION_ENTER = 35,
Xtensa_PATCHABLE_RET = 36,
Xtensa_PATCHABLE_FUNCTION_EXIT = 37,
Xtensa_PATCHABLE_TAIL_CALL = 38,
Xtensa_PATCHABLE_EVENT_CALL = 39,
Xtensa_PATCHABLE_TYPED_EVENT_CALL = 40,
Xtensa_ICALL_BRANCH_FUNNEL = 41,
Xtensa_MEMBARRIER = 42,
Xtensa_JUMP_TABLE_DEBUG_INFO = 43,
Xtensa_G_ASSERT_SEXT = 44,
Xtensa_G_ASSERT_ZEXT = 45,
Xtensa_G_ASSERT_ALIGN = 46,
Xtensa_G_ADD = 47,
Xtensa_G_SUB = 48,
Xtensa_G_MUL = 49,
Xtensa_G_SDIV = 50,
Xtensa_G_UDIV = 51,
Xtensa_G_SREM = 52,
Xtensa_G_UREM = 53,
Xtensa_G_SDIVREM = 54,
Xtensa_G_UDIVREM = 55,
Xtensa_G_AND = 56,
Xtensa_G_OR = 57,
Xtensa_G_XOR = 58,
Xtensa_G_IMPLICIT_DEF = 59,
Xtensa_G_PHI = 60,
Xtensa_G_FRAME_INDEX = 61,
Xtensa_G_GLOBAL_VALUE = 62,
Xtensa_G_CONSTANT_POOL = 63,
Xtensa_G_EXTRACT = 64,
Xtensa_G_UNMERGE_VALUES = 65,
Xtensa_G_INSERT = 66,
Xtensa_G_MERGE_VALUES = 67,
Xtensa_G_BUILD_VECTOR = 68,
Xtensa_G_BUILD_VECTOR_TRUNC = 69,
Xtensa_G_CONCAT_VECTORS = 70,
Xtensa_G_PTRTOINT = 71,
Xtensa_G_INTTOPTR = 72,
Xtensa_G_BITCAST = 73,
Xtensa_G_FREEZE = 74,
Xtensa_G_CONSTANT_FOLD_BARRIER = 75,
Xtensa_G_INTRINSIC_FPTRUNC_ROUND = 76,
Xtensa_G_INTRINSIC_TRUNC = 77,
Xtensa_G_INTRINSIC_ROUND = 78,
Xtensa_G_INTRINSIC_LRINT = 79,
Xtensa_G_INTRINSIC_ROUNDEVEN = 80,
Xtensa_G_READCYCLECOUNTER = 81,
Xtensa_G_LOAD = 82,
Xtensa_G_SEXTLOAD = 83,
Xtensa_G_ZEXTLOAD = 84,
Xtensa_G_INDEXED_LOAD = 85,
Xtensa_G_INDEXED_SEXTLOAD = 86,
Xtensa_G_INDEXED_ZEXTLOAD = 87,
Xtensa_G_STORE = 88,
Xtensa_G_INDEXED_STORE = 89,
Xtensa_G_ATOMIC_CMPXCHG_WITH_SUCCESS = 90,
Xtensa_G_ATOMIC_CMPXCHG = 91,
Xtensa_G_ATOMICRMW_XCHG = 92,
Xtensa_G_ATOMICRMW_ADD = 93,
Xtensa_G_ATOMICRMW_SUB = 94,
Xtensa_G_ATOMICRMW_AND = 95,
Xtensa_G_ATOMICRMW_NAND = 96,
Xtensa_G_ATOMICRMW_OR = 97,
Xtensa_G_ATOMICRMW_XOR = 98,
Xtensa_G_ATOMICRMW_MAX = 99,
Xtensa_G_ATOMICRMW_MIN = 100,
Xtensa_G_ATOMICRMW_UMAX = 101,
Xtensa_G_ATOMICRMW_UMIN = 102,
Xtensa_G_ATOMICRMW_FADD = 103,
Xtensa_G_ATOMICRMW_FSUB = 104,
Xtensa_G_ATOMICRMW_FMAX = 105,
Xtensa_G_ATOMICRMW_FMIN = 106,
Xtensa_G_ATOMICRMW_UINC_WRAP = 107,
Xtensa_G_ATOMICRMW_UDEC_WRAP = 108,
Xtensa_G_FENCE = 109,
Xtensa_G_PREFETCH = 110,
Xtensa_G_BRCOND = 111,
Xtensa_G_BRINDIRECT = 112,
Xtensa_G_INVOKE_REGION_START = 113,
Xtensa_G_INTRINSIC = 114,
Xtensa_G_INTRINSIC_W_SIDE_EFFECTS = 115,
Xtensa_G_INTRINSIC_CONVERGENT = 116,
Xtensa_G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS = 117,
Xtensa_G_ANYEXT = 118,
Xtensa_G_TRUNC = 119,
Xtensa_G_CONSTANT = 120,
Xtensa_G_FCONSTANT = 121,
Xtensa_G_VASTART = 122,
Xtensa_G_VAARG = 123,
Xtensa_G_SEXT = 124,
Xtensa_G_SEXT_INREG = 125,
Xtensa_G_ZEXT = 126,
Xtensa_G_SHL = 127,
Xtensa_G_LSHR = 128,
Xtensa_G_ASHR = 129,
Xtensa_G_FSHL = 130,
Xtensa_G_FSHR = 131,
Xtensa_G_ROTR = 132,
Xtensa_G_ROTL = 133,
Xtensa_G_ICMP = 134,
Xtensa_G_FCMP = 135,
Xtensa_G_SELECT = 136,
Xtensa_G_UADDO = 137,
Xtensa_G_UADDE = 138,
Xtensa_G_USUBO = 139,
Xtensa_G_USUBE = 140,
Xtensa_G_SADDO = 141,
Xtensa_G_SADDE = 142,
Xtensa_G_SSUBO = 143,
Xtensa_G_SSUBE = 144,
Xtensa_G_UMULO = 145,
Xtensa_G_SMULO = 146,
Xtensa_G_UMULH = 147,
Xtensa_G_SMULH = 148,
Xtensa_G_UADDSAT = 149,
Xtensa_G_SADDSAT = 150,
Xtensa_G_USUBSAT = 151,
Xtensa_G_SSUBSAT = 152,
Xtensa_G_USHLSAT = 153,
Xtensa_G_SSHLSAT = 154,
Xtensa_G_SMULFIX = 155,
Xtensa_G_UMULFIX = 156,
Xtensa_G_SMULFIXSAT = 157,
Xtensa_G_UMULFIXSAT = 158,
Xtensa_G_SDIVFIX = 159,
Xtensa_G_UDIVFIX = 160,
Xtensa_G_SDIVFIXSAT = 161,
Xtensa_G_UDIVFIXSAT = 162,
Xtensa_G_FADD = 163,
Xtensa_G_FSUB = 164,
Xtensa_G_FMUL = 165,
Xtensa_G_FMA = 166,
Xtensa_G_FMAD = 167,
Xtensa_G_FDIV = 168,
Xtensa_G_FREM = 169,
Xtensa_G_FPOW = 170,
Xtensa_G_FPOWI = 171,
Xtensa_G_FEXP = 172,
Xtensa_G_FEXP2 = 173,
Xtensa_G_FEXP10 = 174,
Xtensa_G_FLOG = 175,
Xtensa_G_FLOG2 = 176,
Xtensa_G_FLOG10 = 177,
Xtensa_G_FLDEXP = 178,
Xtensa_G_FFREXP = 179,
Xtensa_G_FNEG = 180,
Xtensa_G_FPEXT = 181,
Xtensa_G_FPTRUNC = 182,
Xtensa_G_FPTOSI = 183,
Xtensa_G_FPTOUI = 184,
Xtensa_G_SITOFP = 185,
Xtensa_G_UITOFP = 186,
Xtensa_G_FABS = 187,
Xtensa_G_FCOPYSIGN = 188,
Xtensa_G_IS_FPCLASS = 189,
Xtensa_G_FCANONICALIZE = 190,
Xtensa_G_FMINNUM = 191,
Xtensa_G_FMAXNUM = 192,
Xtensa_G_FMINNUM_IEEE = 193,
Xtensa_G_FMAXNUM_IEEE = 194,
Xtensa_G_FMINIMUM = 195,
Xtensa_G_FMAXIMUM = 196,
Xtensa_G_GET_FPENV = 197,
Xtensa_G_SET_FPENV = 198,
Xtensa_G_RESET_FPENV = 199,
Xtensa_G_GET_FPMODE = 200,
Xtensa_G_SET_FPMODE = 201,
Xtensa_G_RESET_FPMODE = 202,
Xtensa_G_PTR_ADD = 203,
Xtensa_G_PTRMASK = 204,
Xtensa_G_SMIN = 205,
Xtensa_G_SMAX = 206,
Xtensa_G_UMIN = 207,
Xtensa_G_UMAX = 208,
Xtensa_G_ABS = 209,
Xtensa_G_LROUND = 210,
Xtensa_G_LLROUND = 211,
Xtensa_G_BR = 212,
Xtensa_G_BRJT = 213,
Xtensa_G_INSERT_VECTOR_ELT = 214,
Xtensa_G_EXTRACT_VECTOR_ELT = 215,
Xtensa_G_SHUFFLE_VECTOR = 216,
Xtensa_G_CTTZ = 217,
Xtensa_G_CTTZ_ZERO_UNDEF = 218,
Xtensa_G_CTLZ = 219,
Xtensa_G_CTLZ_ZERO_UNDEF = 220,
Xtensa_G_CTPOP = 221,
Xtensa_G_BSWAP = 222,
Xtensa_G_BITREVERSE = 223,
Xtensa_G_FCEIL = 224,
Xtensa_G_FCOS = 225,
Xtensa_G_FSIN = 226,
Xtensa_G_FSQRT = 227,
Xtensa_G_FFLOOR = 228,
Xtensa_G_FRINT = 229,
Xtensa_G_FNEARBYINT = 230,
Xtensa_G_ADDRSPACE_CAST = 231,
Xtensa_G_BLOCK_ADDR = 232,
Xtensa_G_JUMP_TABLE = 233,
Xtensa_G_DYN_STACKALLOC = 234,
Xtensa_G_STACKSAVE = 235,
Xtensa_G_STACKRESTORE = 236,
Xtensa_G_STRICT_FADD = 237,
Xtensa_G_STRICT_FSUB = 238,
Xtensa_G_STRICT_FMUL = 239,
Xtensa_G_STRICT_FDIV = 240,
Xtensa_G_STRICT_FREM = 241,
Xtensa_G_STRICT_FMA = 242,
Xtensa_G_STRICT_FSQRT = 243,
Xtensa_G_STRICT_FLDEXP = 244,
Xtensa_G_READ_REGISTER = 245,
Xtensa_G_WRITE_REGISTER = 246,
Xtensa_G_MEMCPY = 247,
Xtensa_G_MEMCPY_INLINE = 248,
Xtensa_G_MEMMOVE = 249,
Xtensa_G_MEMSET = 250,
Xtensa_G_BZERO = 251,
Xtensa_G_VECREDUCE_SEQ_FADD = 252,
Xtensa_G_VECREDUCE_SEQ_FMUL = 253,
Xtensa_G_VECREDUCE_FADD = 254,
Xtensa_G_VECREDUCE_FMUL = 255,
Xtensa_G_VECREDUCE_FMAX = 256,
Xtensa_G_VECREDUCE_FMIN = 257,
Xtensa_G_VECREDUCE_FMAXIMUM = 258,
Xtensa_G_VECREDUCE_FMINIMUM = 259,
Xtensa_G_VECREDUCE_ADD = 260,
Xtensa_G_VECREDUCE_MUL = 261,
Xtensa_G_VECREDUCE_AND = 262,
Xtensa_G_VECREDUCE_OR = 263,
Xtensa_G_VECREDUCE_XOR = 264,
Xtensa_G_VECREDUCE_SMAX = 265,
Xtensa_G_VECREDUCE_SMIN = 266,
Xtensa_G_VECREDUCE_UMAX = 267,
Xtensa_G_VECREDUCE_UMIN = 268,
Xtensa_G_SBFX = 269,
Xtensa_G_UBFX = 270,
Xtensa_ABS = 271,
Xtensa_ADD = 272,
Xtensa_ADDI = 273,
Xtensa_ADDMI = 274,
Xtensa_ADDX2 = 275,
Xtensa_ADDX4 = 276,
Xtensa_ADDX8 = 277,
Xtensa_AND = 278,
Xtensa_BALL = 279,
Xtensa_BANY = 280,
Xtensa_BBC = 281,
Xtensa_BBCI = 282,
Xtensa_BBS = 283,
Xtensa_BBSI = 284,
Xtensa_BEQ = 285,
Xtensa_BEQI = 286,
Xtensa_BEQZ = 287,
Xtensa_BGE = 288,
Xtensa_BGEI = 289,
Xtensa_BGEU = 290,
Xtensa_BGEUI = 291,
Xtensa_BGEZ = 292,
Xtensa_BLT = 293,
Xtensa_BLTI = 294,
Xtensa_BLTU = 295,
Xtensa_BLTUI = 296,
Xtensa_BLTZ = 297,
Xtensa_BNALL = 298,
Xtensa_BNE = 299,
Xtensa_BNEI = 300,
Xtensa_BNEZ = 301,
Xtensa_BNONE = 302,
Xtensa_CALL0 = 303,
Xtensa_CALLX0 = 304,
Xtensa_DSYNC = 305,
Xtensa_ESYNC = 306,
Xtensa_EXTUI = 307,
Xtensa_EXTW = 308,
Xtensa_ISYNC = 309,
Xtensa_J = 310,
Xtensa_JX = 311,
Xtensa_L16SI = 312,
Xtensa_L16UI = 313,
Xtensa_L32I = 314,
Xtensa_L32R = 315,
Xtensa_L8UI = 316,
Xtensa_MEMW = 317,
Xtensa_MOVEQZ = 318,
Xtensa_MOVGEZ = 319,
Xtensa_MOVI = 320,
Xtensa_MOVLTZ = 321,
Xtensa_MOVNEZ = 322,
Xtensa_NEG = 323,
Xtensa_NOP = 324,
Xtensa_OR = 325,
Xtensa_RET = 326,
Xtensa_RSR = 327,
Xtensa_RSYNC = 328,
Xtensa_S16I = 329,
Xtensa_S32I = 330,
Xtensa_S8I = 331,
Xtensa_SLL = 332,
Xtensa_SLLI = 333,
Xtensa_SRA = 334,
Xtensa_SRAI = 335,
Xtensa_SRC = 336,
Xtensa_SRL = 337,
Xtensa_SRLI = 338,
Xtensa_SSA8L = 339,
Xtensa_SSAI = 340,
Xtensa_SSL = 341,
Xtensa_SSR = 342,
Xtensa_SUB = 343,
Xtensa_SUBX2 = 344,
Xtensa_SUBX4 = 345,
Xtensa_SUBX8 = 346,
Xtensa_WSR = 347,
Xtensa_XOR = 348,
Xtensa_XSR = 349,
INSTRUCTION_LIST_END = 350
};
#endif // GET_INSTRINFO_ENUM
#if defined(GET_INSTRINFO_MC_DESC) || defined(GET_INSTRINFO_CTOR_DTOR)
typedef struct XtensaInstrTable {
MCInstrDesc Insts[350];
MCOperandInfo OperandInfo[169];
MCPhysReg ImplicitOps[2];
} XtensaInstrTable;
#endif // defined(GET_INSTRINFO_MC_DESC) || defined(GET_INSTRINFO_CTOR_DTOR)
#ifdef GET_INSTRINFO_MC_DESC
#undef GET_INSTRINFO_MC_DESC
static const unsigned XtensaImpOpBase = sizeof(MCOperandInfo) / (sizeof(MCPhysReg));
static const XtensaInstrTable XtensaDescs = {
{
{ 4, &XtensaDescs.OperandInfo[165] }, // Inst #349 = XSR
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #348 = XOR
{ 2, &XtensaDescs.OperandInfo[163] }, // Inst #347 = WSR
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #346 = SUBX8
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #345 = SUBX4
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #344 = SUBX2
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #343 = SUB
{ 1, &XtensaDescs.OperandInfo[153] }, // Inst #342 = SSR
{ 1, &XtensaDescs.OperandInfo[153] }, // Inst #341 = SSL
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #340 = SSAI
{ 1, &XtensaDescs.OperandInfo[153] }, // Inst #339 = SSA8L
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #338 = SRLI
{ 2, &XtensaDescs.OperandInfo[140] }, // Inst #337 = SRL
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #336 = SRC
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #335 = SRAI
{ 2, &XtensaDescs.OperandInfo[140] }, // Inst #334 = SRA
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #333 = SLLI
{ 2, &XtensaDescs.OperandInfo[140] }, // Inst #332 = SLL
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #331 = S8I
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #330 = S32I
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #329 = S16I
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #328 = RSYNC
{ 2, &XtensaDescs.OperandInfo[161] }, // Inst #327 = RSR
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #326 = RET
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #325 = OR
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #324 = NOP
{ 2, &XtensaDescs.OperandInfo[140] }, // Inst #323 = NEG
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #322 = MOVNEZ
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #321 = MOVLTZ
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #320 = MOVI
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #319 = MOVGEZ
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #318 = MOVEQZ
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #317 = MEMW
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #316 = L8UI
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #315 = L32R
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #314 = L32I
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #313 = L16UI
{ 3, &XtensaDescs.OperandInfo[158] }, // Inst #312 = L16SI
{ 1, &XtensaDescs.OperandInfo[153] }, // Inst #311 = JX
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #310 = J
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #309 = ISYNC
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #308 = EXTW
{ 4, &XtensaDescs.OperandInfo[154] }, // Inst #307 = EXTUI
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #306 = ESYNC
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #305 = DSYNC
{ 1, &XtensaDescs.OperandInfo[153] }, // Inst #304 = CALLX0
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #303 = CALL0
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #302 = BNONE
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #301 = BNEZ
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #300 = BNEI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #299 = BNE
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #298 = BNALL
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #297 = BLTZ
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #296 = BLTUI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #295 = BLTU
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #294 = BLTI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #293 = BLT
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #292 = BGEZ
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #291 = BGEUI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #290 = BGEU
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #289 = BGEI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #288 = BGE
{ 2, &XtensaDescs.OperandInfo[151] }, // Inst #287 = BEQZ
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #286 = BEQI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #285 = BEQ
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #284 = BBSI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #283 = BBS
{ 3, &XtensaDescs.OperandInfo[148] }, // Inst #282 = BBCI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #281 = BBC
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #280 = BANY
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #279 = BALL
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #278 = AND
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #277 = ADDX8
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #276 = ADDX4
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #275 = ADDX2
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #274 = ADDMI
{ 3, &XtensaDescs.OperandInfo[145] }, // Inst #273 = ADDI
{ 3, &XtensaDescs.OperandInfo[142] }, // Inst #272 = ADD
{ 2, &XtensaDescs.OperandInfo[140] }, // Inst #271 = ABS
{ 4, &XtensaDescs.OperandInfo[136] }, // Inst #270 = G_UBFX
{ 4, &XtensaDescs.OperandInfo[136] }, // Inst #269 = G_SBFX
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #268 = G_VECREDUCE_UMIN
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #267 = G_VECREDUCE_UMAX
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #266 = G_VECREDUCE_SMIN
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #265 = G_VECREDUCE_SMAX
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #264 = G_VECREDUCE_XOR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #263 = G_VECREDUCE_OR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #262 = G_VECREDUCE_AND
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #261 = G_VECREDUCE_MUL
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #260 = G_VECREDUCE_ADD
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #259 = G_VECREDUCE_FMINIMUM
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #258 = G_VECREDUCE_FMAXIMUM
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #257 = G_VECREDUCE_FMIN
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #256 = G_VECREDUCE_FMAX
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #255 = G_VECREDUCE_FMUL
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #254 = G_VECREDUCE_FADD
{ 3, &XtensaDescs.OperandInfo[123] }, // Inst #253 = G_VECREDUCE_SEQ_FMUL
{ 3, &XtensaDescs.OperandInfo[123] }, // Inst #252 = G_VECREDUCE_SEQ_FADD
{ 3, &XtensaDescs.OperandInfo[53] }, // Inst #251 = G_BZERO
{ 4, &XtensaDescs.OperandInfo[132] }, // Inst #250 = G_MEMSET
{ 4, &XtensaDescs.OperandInfo[132] }, // Inst #249 = G_MEMMOVE
{ 3, &XtensaDescs.OperandInfo[123] }, // Inst #248 = G_MEMCPY_INLINE
{ 4, &XtensaDescs.OperandInfo[132] }, // Inst #247 = G_MEMCPY
{ 2, &XtensaDescs.OperandInfo[130] }, // Inst #246 = G_WRITE_REGISTER
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #245 = G_READ_REGISTER
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #244 = G_STRICT_FLDEXP
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #243 = G_STRICT_FSQRT
{ 4, &XtensaDescs.OperandInfo[46] }, // Inst #242 = G_STRICT_FMA
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #241 = G_STRICT_FREM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #240 = G_STRICT_FDIV
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #239 = G_STRICT_FMUL
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #238 = G_STRICT_FSUB
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #237 = G_STRICT_FADD
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #236 = G_STACKRESTORE
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #235 = G_STACKSAVE
{ 3, &XtensaDescs.OperandInfo[64] }, // Inst #234 = G_DYN_STACKALLOC
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #233 = G_JUMP_TABLE
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #232 = G_BLOCK_ADDR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #231 = G_ADDRSPACE_CAST
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #230 = G_FNEARBYINT
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #229 = G_FRINT
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #228 = G_FFLOOR
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #227 = G_FSQRT
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #226 = G_FSIN
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #225 = G_FCOS
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #224 = G_FCEIL
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #223 = G_BITREVERSE
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #222 = G_BSWAP
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #221 = G_CTPOP
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #220 = G_CTLZ_ZERO_UNDEF
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #219 = G_CTLZ
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #218 = G_CTTZ_ZERO_UNDEF
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #217 = G_CTTZ
{ 4, &XtensaDescs.OperandInfo[126] }, // Inst #216 = G_SHUFFLE_VECTOR
{ 3, &XtensaDescs.OperandInfo[123] }, // Inst #215 = G_EXTRACT_VECTOR_ELT
{ 4, &XtensaDescs.OperandInfo[119] }, // Inst #214 = G_INSERT_VECTOR_ELT
{ 3, &XtensaDescs.OperandInfo[116] }, // Inst #213 = G_BRJT
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #212 = G_BR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #211 = G_LLROUND
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #210 = G_LROUND
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #209 = G_ABS
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #208 = G_UMAX
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #207 = G_UMIN
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #206 = G_SMAX
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #205 = G_SMIN
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #204 = G_PTRMASK
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #203 = G_PTR_ADD
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #202 = G_RESET_FPMODE
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #201 = G_SET_FPMODE
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #200 = G_GET_FPMODE
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #199 = G_RESET_FPENV
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #198 = G_SET_FPENV
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #197 = G_GET_FPENV
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #196 = G_FMAXIMUM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #195 = G_FMINIMUM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #194 = G_FMAXNUM_IEEE
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #193 = G_FMINNUM_IEEE
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #192 = G_FMAXNUM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #191 = G_FMINNUM
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #190 = G_FCANONICALIZE
{ 3, &XtensaDescs.OperandInfo[93] }, // Inst #189 = G_IS_FPCLASS
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #188 = G_FCOPYSIGN
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #187 = G_FABS
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #186 = G_UITOFP
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #185 = G_SITOFP
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #184 = G_FPTOUI
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #183 = G_FPTOSI
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #182 = G_FPTRUNC
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #181 = G_FPEXT
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #180 = G_FNEG
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #179 = G_FFREXP
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #178 = G_FLDEXP
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #177 = G_FLOG10
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #176 = G_FLOG2
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #175 = G_FLOG
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #174 = G_FEXP10
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #173 = G_FEXP2
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #172 = G_FEXP
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #171 = G_FPOWI
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #170 = G_FPOW
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #169 = G_FREM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #168 = G_FDIV
{ 4, &XtensaDescs.OperandInfo[46] }, // Inst #167 = G_FMAD
{ 4, &XtensaDescs.OperandInfo[46] }, // Inst #166 = G_FMA
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #165 = G_FMUL
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #164 = G_FSUB
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #163 = G_FADD
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #162 = G_UDIVFIXSAT
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #161 = G_SDIVFIXSAT
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #160 = G_UDIVFIX
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #159 = G_SDIVFIX
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #158 = G_UMULFIXSAT
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #157 = G_SMULFIXSAT
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #156 = G_UMULFIX
{ 4, &XtensaDescs.OperandInfo[112] }, // Inst #155 = G_SMULFIX
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #154 = G_SSHLSAT
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #153 = G_USHLSAT
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #152 = G_SSUBSAT
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #151 = G_USUBSAT
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #150 = G_SADDSAT
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #149 = G_UADDSAT
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #148 = G_SMULH
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #147 = G_UMULH
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #146 = G_SMULO
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #145 = G_UMULO
{ 5, &XtensaDescs.OperandInfo[107] }, // Inst #144 = G_SSUBE
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #143 = G_SSUBO
{ 5, &XtensaDescs.OperandInfo[107] }, // Inst #142 = G_SADDE
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #141 = G_SADDO
{ 5, &XtensaDescs.OperandInfo[107] }, // Inst #140 = G_USUBE
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #139 = G_USUBO
{ 5, &XtensaDescs.OperandInfo[107] }, // Inst #138 = G_UADDE
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #137 = G_UADDO
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #136 = G_SELECT
{ 4, &XtensaDescs.OperandInfo[103] }, // Inst #135 = G_FCMP
{ 4, &XtensaDescs.OperandInfo[103] }, // Inst #134 = G_ICMP
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #133 = G_ROTL
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #132 = G_ROTR
{ 4, &XtensaDescs.OperandInfo[99] }, // Inst #131 = G_FSHR
{ 4, &XtensaDescs.OperandInfo[99] }, // Inst #130 = G_FSHL
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #129 = G_ASHR
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #128 = G_LSHR
{ 3, &XtensaDescs.OperandInfo[96] }, // Inst #127 = G_SHL
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #126 = G_ZEXT
{ 3, &XtensaDescs.OperandInfo[40] }, // Inst #125 = G_SEXT_INREG
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #124 = G_SEXT
{ 3, &XtensaDescs.OperandInfo[93] }, // Inst #123 = G_VAARG
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #122 = G_VASTART
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #121 = G_FCONSTANT
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #120 = G_CONSTANT
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #119 = G_TRUNC
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #118 = G_ANYEXT
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #117 = G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #116 = G_INTRINSIC_CONVERGENT
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #115 = G_INTRINSIC_W_SIDE_EFFECTS
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #114 = G_INTRINSIC
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #113 = G_INVOKE_REGION_START
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #112 = G_BRINDIRECT
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #111 = G_BRCOND
{ 4, &XtensaDescs.OperandInfo[89] }, // Inst #110 = G_PREFETCH
{ 2, &XtensaDescs.OperandInfo[21] }, // Inst #109 = G_FENCE
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #108 = G_ATOMICRMW_UDEC_WRAP
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #107 = G_ATOMICRMW_UINC_WRAP
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #106 = G_ATOMICRMW_FMIN
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #105 = G_ATOMICRMW_FMAX
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #104 = G_ATOMICRMW_FSUB
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #103 = G_ATOMICRMW_FADD
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #102 = G_ATOMICRMW_UMIN
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #101 = G_ATOMICRMW_UMAX
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #100 = G_ATOMICRMW_MIN
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #99 = G_ATOMICRMW_MAX
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #98 = G_ATOMICRMW_XOR
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #97 = G_ATOMICRMW_OR
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #96 = G_ATOMICRMW_NAND
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #95 = G_ATOMICRMW_AND
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #94 = G_ATOMICRMW_SUB
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #93 = G_ATOMICRMW_ADD
{ 3, &XtensaDescs.OperandInfo[86] }, // Inst #92 = G_ATOMICRMW_XCHG
{ 4, &XtensaDescs.OperandInfo[82] }, // Inst #91 = G_ATOMIC_CMPXCHG
{ 5, &XtensaDescs.OperandInfo[77] }, // Inst #90 = G_ATOMIC_CMPXCHG_WITH_SUCCESS
{ 5, &XtensaDescs.OperandInfo[72] }, // Inst #89 = G_INDEXED_STORE
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #88 = G_STORE
{ 5, &XtensaDescs.OperandInfo[67] }, // Inst #87 = G_INDEXED_ZEXTLOAD
{ 5, &XtensaDescs.OperandInfo[67] }, // Inst #86 = G_INDEXED_SEXTLOAD
{ 5, &XtensaDescs.OperandInfo[67] }, // Inst #85 = G_INDEXED_LOAD
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #84 = G_ZEXTLOAD
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #83 = G_SEXTLOAD
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #82 = G_LOAD
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #81 = G_READCYCLECOUNTER
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #80 = G_INTRINSIC_ROUNDEVEN
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #79 = G_INTRINSIC_LRINT
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #78 = G_INTRINSIC_ROUND
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #77 = G_INTRINSIC_TRUNC
{ 3, &XtensaDescs.OperandInfo[64] }, // Inst #76 = G_INTRINSIC_FPTRUNC_ROUND
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #75 = G_CONSTANT_FOLD_BARRIER
{ 2, &XtensaDescs.OperandInfo[62] }, // Inst #74 = G_FREEZE
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #73 = G_BITCAST
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #72 = G_INTTOPTR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #71 = G_PTRTOINT
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #70 = G_CONCAT_VECTORS
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #69 = G_BUILD_VECTOR_TRUNC
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #68 = G_BUILD_VECTOR
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #67 = G_MERGE_VALUES
{ 4, &XtensaDescs.OperandInfo[58] }, // Inst #66 = G_INSERT
{ 2, &XtensaDescs.OperandInfo[56] }, // Inst #65 = G_UNMERGE_VALUES
{ 3, &XtensaDescs.OperandInfo[53] }, // Inst #64 = G_EXTRACT
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #63 = G_CONSTANT_POOL
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #62 = G_GLOBAL_VALUE
{ 2, &XtensaDescs.OperandInfo[51] }, // Inst #61 = G_FRAME_INDEX
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #60 = G_PHI
{ 1, &XtensaDescs.OperandInfo[50] }, // Inst #59 = G_IMPLICIT_DEF
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #58 = G_XOR
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #57 = G_OR
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #56 = G_AND
{ 4, &XtensaDescs.OperandInfo[46] }, // Inst #55 = G_UDIVREM
{ 4, &XtensaDescs.OperandInfo[46] }, // Inst #54 = G_SDIVREM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #53 = G_UREM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #52 = G_SREM
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #51 = G_UDIV
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #50 = G_SDIV
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #49 = G_MUL
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #48 = G_SUB
{ 3, &XtensaDescs.OperandInfo[43] }, // Inst #47 = G_ADD
{ 3, &XtensaDescs.OperandInfo[40] }, // Inst #46 = G_ASSERT_ALIGN
{ 3, &XtensaDescs.OperandInfo[40] }, // Inst #45 = G_ASSERT_ZEXT
{ 3, &XtensaDescs.OperandInfo[40] }, // Inst #44 = G_ASSERT_SEXT
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #43 = JUMP_TABLE_DEBUG_INFO
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #42 = MEMBARRIER
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #41 = ICALL_BRANCH_FUNNEL
{ 3, &XtensaDescs.OperandInfo[37] }, // Inst #40 = PATCHABLE_TYPED_EVENT_CALL
{ 2, &XtensaDescs.OperandInfo[35] }, // Inst #39 = PATCHABLE_EVENT_CALL
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #38 = PATCHABLE_TAIL_CALL
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #37 = PATCHABLE_FUNCTION_EXIT
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #36 = PATCHABLE_RET
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #35 = PATCHABLE_FUNCTION_ENTER
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #34 = PATCHABLE_OP
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #33 = FAULTING_OP
{ 2, &XtensaDescs.OperandInfo[33] }, // Inst #32 = LOCAL_ESCAPE
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #31 = STATEPOINT
{ 3, &XtensaDescs.OperandInfo[30] }, // Inst #30 = PREALLOCATED_ARG
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #29 = PREALLOCATED_SETUP
{ 1, &XtensaDescs.OperandInfo[29] }, // Inst #28 = LOAD_STACK_GUARD
{ 6, &XtensaDescs.OperandInfo[23] }, // Inst #27 = PATCHPOINT
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #26 = FENTRY_CALL
{ 2, &XtensaDescs.OperandInfo[21] }, // Inst #25 = STACKMAP
{ 2, &XtensaDescs.OperandInfo[19] }, // Inst #24 = ARITH_FENCE
{ 4, &XtensaDescs.OperandInfo[15] }, // Inst #23 = PSEUDO_PROBE
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #22 = LIFETIME_END
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #21 = LIFETIME_START
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #20 = BUNDLE
{ 2, &XtensaDescs.OperandInfo[13] }, // Inst #19 = COPY
{ 2, &XtensaDescs.OperandInfo[13] }, // Inst #18 = REG_SEQUENCE
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #17 = DBG_LABEL
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #16 = DBG_PHI
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #15 = DBG_INSTR_REF
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #14 = DBG_VALUE_LIST
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #13 = DBG_VALUE
{ 3, &XtensaDescs.OperandInfo[2] }, // Inst #12 = COPY_TO_REGCLASS
{ 4, &XtensaDescs.OperandInfo[9] }, // Inst #11 = SUBREG_TO_REG
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #10 = IMPLICIT_DEF
{ 4, &XtensaDescs.OperandInfo[5] }, // Inst #9 = INSERT_SUBREG
{ 3, &XtensaDescs.OperandInfo[2] }, // Inst #8 = EXTRACT_SUBREG
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #7 = KILL
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #6 = ANNOTATION_LABEL
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #5 = GC_LABEL
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #4 = EH_LABEL
{ 1, &XtensaDescs.OperandInfo[1] }, // Inst #3 = CFI_INSTRUCTION
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #2 = INLINEASM_BR
{ 0, &XtensaDescs.OperandInfo[1] }, // Inst #1 = INLINEASM
{ 1, &XtensaDescs.OperandInfo[0] }, // Inst #0 = PHI
}, {
/* 0 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 1 */
/* 1 */ { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 2 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 5 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, CONSTRAINT_MCOI_TIED_TO(0) }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 9 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 13 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 15 */ { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 19 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, CONSTRAINT_MCOI_TIED_TO(0) },
/* 21 */ { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 23 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 29 */ { 0, 0|(1<<MCOI_LookupPtrRegClass), MCOI_OPERAND_UNKNOWN, 0 },
/* 30 */ { 0, 0|(1<<MCOI_LookupPtrRegClass), MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 33 */ { 0, 0|(1<<MCOI_LookupPtrRegClass), MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 35 */ { 0, 0|(1<<MCOI_LookupPtrRegClass), MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 37 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { 0, 0|(1<<MCOI_LookupPtrRegClass), MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 40 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_IMM_0, 0 },
/* 43 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 46 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 50 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 51 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 53 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_IMM_0, 0 },
/* 56 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 58 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_IMM_0, 0 },
/* 62 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 64 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 67 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 72 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 77 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 82 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 86 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 89 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 }, { -1, 0, MCOI_OPERAND_IMMEDIATE, 0 },
/* 93 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 96 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 99 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 103 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 107 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 112 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_IMM_0, 0 },
/* 116 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 119 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 },
/* 123 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 },
/* 126 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 130 */ { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 },
/* 132 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_2, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_IMM_0, 0 },
/* 136 */ { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_0, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 }, { -1, 0, MCOI_OPERAND_GENERIC_1, 0 },
/* 140 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 },
/* 142 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 },
/* 145 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 148 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 151 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 153 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 },
/* 154 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 }, { -1, 0, MCOI_OPERAND_UNKNOWN, 0 },
/* 158 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_MEMORY, 0 }, { -1, 0, MCOI_OPERAND_MEMORY, 0 },
/* 161 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_SRRegClassID, 0, MCOI_OPERAND_REGISTER, 0 },
/* 163 */ { Xtensa_SRRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 },
/* 165 */ { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_SRRegClassID, 0, MCOI_OPERAND_REGISTER, 0 }, { Xtensa_ARRegClassID, 0, MCOI_OPERAND_REGISTER, CONSTRAINT_MCOI_TIED_TO(0) }, { Xtensa_SRRegClassID, 0, MCOI_OPERAND_REGISTER, CONSTRAINT_MCOI_TIED_TO(1) },
}, {
/* 0 */
/* 0 */ Xtensa_A0,
/* 1 */ Xtensa_SAR,
}
};
#endif // GET_INSTRINFO_MC_DESC
#ifdef GET_COMPUTE_FEATURES
#undef GET_COMPUTE_FEATURES
#endif // GET_COMPUTE_FEATURES
#ifdef GET_AVAILABLE_OPCODE_CHECKER
#undef GET_AVAILABLE_OPCODE_CHECKER
#endif // GET_AVAILABLE_OPCODE_CHECKER

View File

@ -0,0 +1,128 @@
#ifdef GET_REGINFO_ENUM
#undef GET_REGINFO_ENUM
enum {
Xtensa_NoRegister,
Xtensa_SAR = 1,
Xtensa_SP = 2,
Xtensa_A0 = 3,
Xtensa_A2 = 4,
Xtensa_A3 = 5,
Xtensa_A4 = 6,
Xtensa_A5 = 7,
Xtensa_A6 = 8,
Xtensa_A7 = 9,
Xtensa_A8 = 10,
Xtensa_A9 = 11,
Xtensa_A10 = 12,
Xtensa_A11 = 13,
Xtensa_A12 = 14,
Xtensa_A13 = 15,
Xtensa_A14 = 16,
Xtensa_A15 = 17,
NUM_TARGET_REGS // 18
};
// Register classes
enum {
Xtensa_ARRegClassID = 0,
Xtensa_SRRegClassID = 1,
};
#endif // GET_REGINFO_ENUM
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
#ifdef GET_REGINFO_MC_DESC
#undef GET_REGINFO_MC_DESC
static const MCPhysReg XtensaRegDiffLists[] = {
/* 0 */ 0,
};
static const uint16_t XtensaSubRegIdxLists[] = {
/* 0 */ 0,
};
static const MCRegisterDesc XtensaRegDesc[] = { // Descriptors
{ 3, 0, 0, 0, 0, 0 },
{ 54, 0, 0, 0, 0, 0 },
{ 51, 0, 0, 0, 1, 0 },
{ 4, 0, 0, 0, 2, 0 },
{ 15, 0, 0, 0, 3, 0 },
{ 22, 0, 0, 0, 4, 0 },
{ 29, 0, 0, 0, 5, 0 },
{ 36, 0, 0, 0, 6, 0 },
{ 39, 0, 0, 0, 7, 0 },
{ 42, 0, 0, 0, 8, 0 },
{ 45, 0, 0, 0, 9, 0 },
{ 48, 0, 0, 0, 10, 0 },
{ 0, 0, 0, 0, 11, 0 },
{ 7, 0, 0, 0, 12, 0 },
{ 11, 0, 0, 0, 13, 0 },
{ 18, 0, 0, 0, 14, 0 },
{ 25, 0, 0, 0, 15, 0 },
{ 32, 0, 0, 0, 16, 0 },
};
// AR Register Class...
static const MCPhysReg AR[] = {
Xtensa_A8, Xtensa_A9, Xtensa_A10, Xtensa_A11, Xtensa_A12, Xtensa_A13, Xtensa_A14, Xtensa_A15, Xtensa_A7, Xtensa_A6, Xtensa_A5, Xtensa_A4, Xtensa_A3, Xtensa_A2, Xtensa_A0, Xtensa_SP,
};
// AR Bit set.
static const uint8_t ARBits[] = {
0xfc, 0xff, 0x03,
};
// SR Register Class...
static const MCPhysReg SR[] = {
Xtensa_SAR,
};
// SR Bit set.
static const uint8_t SRBits[] = {
0x02,
};
static const MCRegisterClass XtensaMCRegisterClasses[] = {
{ AR, ARBits, sizeof(ARBits) },
{ SR, SRBits, sizeof(SRBits) },
};
static const uint16_t XtensaRegEncodingTable[] = {
0,
3,
1,
0,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
};
#endif // GET_REGINFO_MC_DESC

View File

@ -0,0 +1,24 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2024 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
#ifdef GET_SUBTARGETINFO_ENUM
#undef GET_SUBTARGETINFO_ENUM
enum {
Xtensa_FeatureDensity = 0,
Xtensa_NumSubtargetFeatures = 1
};
#endif // GET_SUBTARGETINFO_ENUM

View File

@ -0,0 +1,317 @@
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2023 */
/* Automatically translated source file from LLVM. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Only small edits allowed. */
/* For multiple similar edits, please create a Patch for the translator. */
/* Capstone's C++ file translator: */
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//
//
// The LLVM Compiler Infrastructure
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This class prints an Xtensa MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include "../../MCInstPrinter.h"
#include "../../SStream.h"
#include "./priv.h"
#include "../../Mapping.h"
#include "XtensaMapping.h"
#include "../../MathExtras.h"
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
#define DEBUG_TYPE "asm-printer"
static MnemonicBitsInfo getMnemonic(MCInst *MI, SStream *O);
static const char *getRegisterName(unsigned RegNo);
static void printOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_OPERAND, OpNum);
const MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isReg(MC)) {
SStream_concat0(O, getRegisterName(MCOperand_getReg(MC)));
} else if (MCOperand_isImm(MC)) {
printInt64(O, MCOperand_getImm(MC));
} else if (MCOperand_isExpr(MC)) {
printExpr(MCOperand_getExpr(MC), O);
} else
CS_ASSERT("Invalid operand");
}
static inline void printMemOperand(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_MEMOPERAND, OpNum);
SStream_concat0(OS, getRegisterName(MCOperand_getReg(
MCInst_getOperand(MI, (OpNum)))));
SStream_concat0(OS, ", ");
printInt64(OS, MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)));
}
static inline void printBranchTarget(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_BRANCHTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Val = MCOperand_getImm(MC) + 4;
SStream_concat0(OS, ". ");
if (Val > 0)
SStream_concat0(OS, "+");
printInt64(OS, Val);
} else if (MCOperand_isExpr(MC))
MCExpr_print(MCOperand_getExpr(MC), O, NULL, true);
else
CS_ASSERT(0 && "Invalid operand");
}
static inline void printJumpTarget(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_JUMPTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Val = MCOperand_getImm(MC) + 4;
SStream_concat0(OS, ". ");
if (Val > 0)
SStream_concat0(OS, "+");
printInt64(OS, Val);
} else if (MCOperand_isExpr(MC))
MCExpr_print(MCOperand_getExpr(MC), O, NULL, true);
else
assert(0 && "Invalid operand");
;
}
static inline void printCallOperand(MCInst *MI, int OpNum, SStream *OS)
{
add_cs_detail(MI, XTENSA_OP_GROUP_CALLOPERAND, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Val = MCOperand_getImm(MC) + 4;
SStream_concat0(OS, ". ");
if (Val > 0)
SStream_concat0(OS, "+");
printInt64(OS, Val);
} else if (MCOperand_isExpr(MC))
MCExpr_print(MCOperand_getExpr(MC), O, NULL, true);
else
assert(0 && "Invalid operand");
}
static inline void printL32RTarget(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_L32RTARGET, OpNum);
MCOperand *MC = MCInst_getOperand(MI, (OpNum));
if (MCOperand_isImm(MC)) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
int64_t InstrOff = OneExtend32(Value << 2, 14);
CS_ASSERT(
(Value >= -262144 && Value <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]");
SStream_concat0(O, ". ");
if (MI->csh->LITBASE & 0x1) {
Value = (int64_t)(MI->csh->LITBASE & 0x7ff) + InstrOff;
} else {
Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff;
}
printInt64(O, Value);
} else if (MCOperand_isExpr(MC))
MCExpr_print(MCOperand_getExpr(MC), O, NULL, true);
else
assert(0 && "Invalid operand");
}
static inline void printImm8_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM8_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT(
isIntN(8, Value) &&
"Invalid argument, value must be in ranges [-128,127]");
printInt64(O, Value);
} else {
printOperand(MI, OpNum, O);
}
}
static inline void printImm8_sh8_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT(
(isIntN(16, Value) && ((Value & 0xFF) == 0)) &&
"Invalid argument, value must be multiples of 256 in range "
"[-32768,32512]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printImm12m_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM12M_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT(
(Value >= -2048 && Value <= 2047) &&
"Invalid argument, value must be in ranges [-2048,2047]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printUimm4_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_UIMM4_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT((Value >= 0 && Value <= 15) && "Invalid argument");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printUimm5_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_UIMM5_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT((Value >= 0 && Value <= 31) && "Invalid argument");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printShimm1_31_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT((Value >= 1 && Value <= 31) &&
"Invalid argument, value must be in range [1,31]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printImm1_16_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_IMM1_16_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
CS_ASSERT((Value >= 1 && Value <= 16) &&
"Invalid argument, value must be in range [1,16]");
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printB4const_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_B4CONST_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
switch (Value) {
case -1:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 10:
case 12:
case 16:
case 32:
case 64:
case 128:
case 256:
break;
default:
CS_ASSERT((0) && "Invalid B4const argument");
}
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
static inline void printB4constu_AsmOperand(MCInst *MI, int OpNum, SStream *O)
{
add_cs_detail(MI, XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND, OpNum);
if (MCOperand_isImm(MCInst_getOperand(MI, (OpNum)))) {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
switch (Value) {
case 32768:
case 65536:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 10:
case 12:
case 16:
case 32:
case 64:
case 128:
case 256:
break;
default:
CS_ASSERT((0) && "Invalid B4constu argument");
}
printInt64(O, Value);
} else
printOperand(MI, OpNum, O);
}
#include "XtensaGenAsmWriter.inc"
const char *Xtensa_LLVM_getRegisterName(unsigned RegNo)
{
return getRegisterName(RegNo);
}
void Xtensa_LLVM_printInstruction(MCInst *MI, uint64_t Address, SStream *O)
{
printInstruction(MI, Address, O);
}

View File

@ -0,0 +1,45 @@
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2023 */
/* Automatically translated source file from LLVM. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Only small edits allowed. */
/* For multiple similar edits, please create a Patch for the translator. */
/* Capstone's C++ file translator: */
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
//===- XtensaInstPrinter.h - Convert Xtensa MCInst to asm syntax -*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This class prints an Xtensa MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H
#define LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
#include "priv.h"
const char *Xtensa_LLVM_getRegisterName(unsigned RegNo);
void Xtensa_LLVM_printInstruction(MCInst *MI, uint64_t Address, SStream *O);
#endif /* LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H */

229
arch/Xtensa/XtensaMapping.c Normal file
View File

@ -0,0 +1,229 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#include <capstone/xtensa.h>
#include "../../MCRegisterInfo.h"
#include "../../MCInst.h"
#include "../../SStream.h"
#include "../../Mapping.h"
#include "../../utils.h"
#include "../../cs_simple_types.h"
#include "XtensaDisassembler.h"
#include "XtensaInstPrinter.h"
#include "priv.h"
#include "XtensaMapping.h"
#ifndef CAPSTONE_DIET
static const char *const insn_name_maps[] = {
#include "XtensaGenCSMappingInsnName.inc"
};
static const name_map group_name_maps[] = {
#include "XtensaGenCSFeatureName.inc"
};
const insn_map mapping_insns[] = {
#include "XtensaGenCSMappingInsn.inc"
};
static const map_insn_ops insn_operands[] = {
#include "XtensaGenCSMappingInsnOp.inc"
};
#endif
#define GET_REGINFO_MC_DESC
#include "XtensaGenRegisterInfo.inc"
#include "../../MathExtras.h"
void Xtensa_init_mri(MCRegisterInfo *mri)
{
MCRegisterInfo_InitMCRegisterInfo(
mri, XtensaRegDesc, ARR_SIZE(XtensaRegDesc), 0, 0,
XtensaMCRegisterClasses, ARR_SIZE(XtensaMCRegisterClasses), 0,
0, XtensaRegDiffLists, NULL, XtensaSubRegIdxLists,
ARR_SIZE(XtensaSubRegIdxLists), XtensaRegEncodingTable);
}
void Xtensa_printer(MCInst *MI, SStream *OS, void *info)
{
Xtensa_LLVM_printInstruction(MI, MI->address, OS);
}
static void set_instr_map_data(MCInst *MI)
{
#ifndef CAPSTONE_DIET
map_cs_id(MI, mapping_insns, ARR_SIZE(mapping_insns));
map_implicit_reads(MI, mapping_insns);
map_implicit_writes(MI, mapping_insns);
map_groups(MI, mapping_insns);
#endif
}
bool Xtensa_disasm(csh handle, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address, void *info)
{
DecodeStatus res = Xtensa_LLVM_getInstruction(instr, size, code,
code_len, address);
if (res == MCDisassembler_Success) {
set_instr_map_data(instr);
}
return res == MCDisassembler_Success;
}
const char *Xtensa_reg_name(csh handle, unsigned int id)
{
return Xtensa_LLVM_getRegisterName(id);
}
void Xtensa_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{
// Done in Xtensa_disasm
}
const char *Xtensa_insn_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
if (id >= ARR_SIZE(insn_name_maps)) {
return NULL;
}
return insn_name_maps[id];
#else
return NULL;
#endif
}
const char *Xtensa_group_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
#else
return NULL;
#endif
}
#ifndef CAPSTONE_DIET
void Xtensa_reg_access(const cs_insn *insn, cs_regs regs_read,
uint8_t *regs_read_count, cs_regs regs_write,
uint8_t *regs_write_count)
{
uint8_t i;
uint8_t read_count, write_count;
cs_xtensa *detail = &(insn->detail->xtensa);
read_count = insn->detail->regs_read_count;
write_count = insn->detail->regs_write_count;
// implicit registers
memcpy(regs_read, insn->detail->regs_read,
read_count * sizeof(insn->detail->regs_read[0]));
memcpy(regs_write, insn->detail->regs_write,
write_count * sizeof(insn->detail->regs_write[0]));
// explicit registers
for (i = 0; i < detail->op_count; i++) {
cs_xtensa_op *op = &(detail->operands[i]);
switch (op->type) {
case XTENSA_OP_REG:
if ((op->access & CS_AC_READ) &&
!arr_exist(regs_read, read_count, op->reg)) {
regs_read[read_count] = (uint16_t)op->reg;
read_count++;
}
if ((op->access & CS_AC_WRITE) &&
!arr_exist(regs_write, write_count, op->reg)) {
regs_write[write_count] = (uint16_t)op->reg;
write_count++;
}
break;
case XTENSA_OP_MEM:
// registers appeared in memory references always being read
if ((op->mem.base != XTENSA_REG_INVALID) &&
!arr_exist(regs_read, read_count, op->mem.base)) {
regs_read[read_count] = (uint16_t)op->mem.base;
read_count++;
}
if ((insn->detail->writeback) &&
(op->mem.base != XTENSA_REG_INVALID) &&
!arr_exist(regs_write, write_count, op->mem.base)) {
regs_write[write_count] =
(uint16_t)op->mem.base;
write_count++;
}
default:
break;
}
}
*regs_read_count = read_count;
*regs_write_count = write_count;
}
#endif
void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args)
{
int op_num = va_arg(args, int);
cs_xtensa_op *xop = Xtensa_get_detail_op(MI, 0);
switch (op_group) {
case XTENSA_OP_GROUP_OPERAND: {
const MCOperand *MC = MCInst_getOperand(MI, op_num);
if (MCOperand_isReg(MC)) {
xop->type = XTENSA_OP_REG;
xop->reg = MC->RegVal;
} else if (MCOperand_isImm(MC)) {
xop->type = XTENSA_OP_IMM;
xop->imm = MC->ImmVal;
}
} break;
case XTENSA_OP_GROUP_IMM8_ASMOPERAND:
case XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND:
case XTENSA_OP_GROUP_UIMM5_ASMOPERAND:
case XTENSA_OP_GROUP_B4CONST_ASMOPERAND:
case XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND:
case XTENSA_OP_GROUP_IMM1_16_ASMOPERAND:
case XTENSA_OP_GROUP_IMM12M_ASMOPERAND:
case XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND:
case XTENSA_OP_GROUP_UIMM4_ASMOPERAND: {
int64_t val = MCOperand_getImm(MCInst_getOperand(MI, op_num));
xop->type = XTENSA_OP_IMM;
xop->imm = (int32_t)val;
} break;
case XTENSA_OP_GROUP_BRANCHTARGET:
case XTENSA_OP_GROUP_JUMPTARGET:
case XTENSA_OP_GROUP_CALLOPERAND: {
int64_t val =
MCOperand_getImm(MCInst_getOperand(MI, op_num)) + 4;
xop->type = XTENSA_OP_MEM_IMM;
xop->mem.base = (int32_t)val;
} break;
case XTENSA_OP_GROUP_L32RTARGET: {
int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (op_num)));
int64_t InstrOff = OneExtend32(Value << 2, 14);
CS_ASSERT(
(Value >= -262144 && Value <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]");
if (MI->csh->LITBASE & 0x1) {
Value = (int64_t)(MI->csh->LITBASE & 0x7ff) + InstrOff;
} else {
Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff;
}
xop->type = XTENSA_OP_L32R;
xop->imm = (int32_t)Value;
} break;
case XTENSA_OP_GROUP_MEMOPERAND: {
unsigned reg =
MCOperand_getReg(MCInst_getOperand(MI, (op_num)));
int64_t imm8 =
MCOperand_getImm(MCInst_getOperand(MI, op_num + 1));
xop->type = XTENSA_OP_MEM;
xop->mem.base = reg;
xop->mem.disp = (uint8_t)imm8;
} break;
}
xop->access = map_get_op_access(MI, op_num);
Xtensa_inc_op_count(MI);
}

View File

@ -0,0 +1,39 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#ifndef XTENSA_MAPPING_H
#define XTENSA_MAPPING_H
#include "../../Mapping.h"
typedef enum {
#include "XtensaGenCSOpGroup.inc"
} xtensa_op_group;
void Xtensa_init_mri(MCRegisterInfo *mri);
void Xtensa_printer(MCInst *MI, SStream *OS, void *info);
bool Xtensa_disasm(csh handle, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address, void *info);
const char *Xtensa_reg_name(csh handle, unsigned int id);
void Xtensa_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *Xtensa_insn_name(csh handle, unsigned int id);
const char *Xtensa_group_name(csh handle, unsigned int id);
#ifndef CAPSTONE_DIET
void Xtensa_reg_access(const cs_insn *insn, cs_regs regs_read,
uint8_t *regs_read_count, cs_regs regs_write,
uint8_t *regs_write_count);
#endif
void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args);
static inline void add_cs_detail(MCInst *MI, xtensa_op_group op_group, ...)
{
if (!detail_is_set(MI))
return;
va_list args;
va_start(args, op_group);
Xtensa_add_cs_detail(MI, op_group, args);
va_end(args);
}
#endif

View File

@ -0,0 +1,47 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#include "../../utils.h"
#include "../../MCRegisterInfo.h"
#include "XtensaInstPrinter.h"
#include "XtensaMapping.h"
#include "XtensaModule.h"
cs_err Xtensa_global_init(cs_struct *ud)
{
MCRegisterInfo *mri;
mri = cs_mem_calloc(1, sizeof(*mri));
Xtensa_init_mri(mri);
ud->printer = Xtensa_printer;
ud->printer_info = mri;
ud->getinsn_info = mri;
ud->disasm = Xtensa_disasm;
ud->reg_name = Xtensa_reg_name;
ud->insn_id = Xtensa_insn_id;
ud->insn_name = Xtensa_insn_name;
ud->group_name = Xtensa_group_name;
ud->post_printer = NULL;
#ifndef CAPSTONE_DIET
ud->reg_access = Xtensa_reg_access;
#endif
return CS_ERR_OK;
}
cs_err Xtensa_option(cs_struct *handle, cs_opt_type type, size_t value)
{
if (type == CS_OPT_SYNTAX) {
handle->syntax |= (int)value;
}
if (type == CS_OPT_MODE) {
handle->mode |= (cs_mode)value;
}
if (type == CS_OPT_LITBASE) {
handle->LITBASE = (uint32_t)value;
}
return CS_ERR_OK;
}

View File

@ -0,0 +1,10 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#ifndef CS_XTENSA_MODULE_H
#define CS_XTENSA_MODULE_H
cs_err Xtensa_global_init(cs_struct *ud);
cs_err Xtensa_option(cs_struct *handle, cs_opt_type type, size_t value);
#endif

17
arch/Xtensa/priv.h Normal file
View File

@ -0,0 +1,17 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#ifndef CAPSTONE_PRIV_H
#define CAPSTONE_PRIV_H
#define llvm_unreachable(x) assert(0 && x)
#define printExpr(E, O) assert(0 && "unimplemented expr")
#define MCExpr_print(E, OS, MAI, InParens) assert(0 && "unimplemented expr")
#define GET_REGINFO_ENUM
#include "XtensaGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#include "XtensaGenInstrInfo.inc"
#endif //CAPSTONE_PRIV_H

View File

@ -6,7 +6,9 @@ import re
INCL_DIR = '../include/capstone/' INCL_DIR = '../include/capstone/'
include = [ 'arm.h', 'aarch64.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', 'sh.h', 'tricore.h', 'alpha.h', 'hppa.h', 'loongarch.h' ] include = ['arm.h', 'aarch64.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', 'sh.h', 'tricore.h',
'alpha.h', 'hppa.h', 'loongarch.h', 'xtensa.h']
template = { template = {
'java': { 'java': {
@ -60,6 +62,7 @@ template = {
'alpha.h': ['ALPHA', 'Alpha'], 'alpha.h': ['ALPHA', 'Alpha'],
'hppa.h': 'hppa', 'hppa.h': 'hppa',
'loongarch.h': 'loongarch', 'loongarch.h': 'loongarch',
'xtensa.h': 'xtensa',
'comment_open': '#', 'comment_open': '#',
'comment_close': '', 'comment_close': '',
}, },

View File

@ -36,7 +36,7 @@ TESTS = test_basic.py test_detail.py test_arm.py test_aarch64.py test_m68k.py te
TESTS += test_ppc.py test_sparc.py test_systemz.py test_x86.py test_xcore.py test_tms320c64x.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 test_riscv.py TESTS += test_m680x.py test_skipdata.py test_mos65xx.py test_bpf.py test_riscv.py
TESTS += test_evm.py test_tricore.py test_wasm.py test_sh.py test_hppa.py TESTS += test_evm.py test_tricore.py test_wasm.py test_sh.py test_hppa.py
TESTS += test_lite.py test_iter.py test_customized_mnem.py test_alpha.py TESTS += test_lite.py test_iter.py test_customized_mnem.py test_alpha.py test_xtensa.py
check: check:
@for t in $(TESTS); do \ @for t in $(TESTS); do \

View File

@ -41,6 +41,7 @@ __all__ = [
'CS_ARCH_ALPHA', 'CS_ARCH_ALPHA',
'CS_ARCH_HPPA', 'CS_ARCH_HPPA',
'CS_ARCH_LOONGARCH', 'CS_ARCH_LOONGARCH',
'CS_ARCH_XTENSA',
'CS_ARCH_ALL', 'CS_ARCH_ALL',
'CS_MODE_LITTLE_ENDIAN', 'CS_MODE_LITTLE_ENDIAN',
@ -243,7 +244,7 @@ CS_VERSION_MAJOR = CS_API_MAJOR
CS_VERSION_MINOR = CS_API_MINOR CS_VERSION_MINOR = CS_API_MINOR
CS_VERSION_EXTRA = 0 CS_VERSION_EXTRA = 0
__version__ = "%u.%u.%u" %(CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA) __version__ = "%u.%u.%u" % (CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA)
# architectures # architectures
CS_ARCH_ARM = 0 CS_ARCH_ARM = 0
@ -267,7 +268,8 @@ CS_ARCH_TRICORE = 17
CS_ARCH_ALPHA = 18 CS_ARCH_ALPHA = 18
CS_ARCH_HPPA = 19 CS_ARCH_HPPA = 19
CS_ARCH_LOONGARCH = 20 CS_ARCH_LOONGARCH = 20
CS_ARCH_MAX = 20 CS_ARCH_XTENSA = 21
CS_ARCH_MAX = 21
CS_ARCH_ALL = 0xFFFF CS_ARCH_ALL = 0xFFFF
# disasm mode # disasm mode
@ -340,7 +342,7 @@ CS_MODE_MOS65XX_6502 = (1 << 1) # MOS65XXX MOS 6502
CS_MODE_MOS65XX_65C02 = (1 << 2) # MOS65XXX WDC 65c02 CS_MODE_MOS65XX_65C02 = (1 << 2) # MOS65XXX WDC 65c02
CS_MODE_MOS65XX_W65C02 = (1 << 3) # MOS65XXX WDC W65c02 CS_MODE_MOS65XX_W65C02 = (1 << 3) # MOS65XXX WDC W65c02
CS_MODE_MOS65XX_65816 = (1 << 4) # MOS65XXX WDC 65816, 8-bit m/x CS_MODE_MOS65XX_65816 = (1 << 4) # MOS65XXX WDC 65816, 8-bit m/x
CS_MODE_MOS65XX_65816_LONG_M = (1 << 5) # MOS65XXX WDC 65816, 16-bit m, 8-bit x CS_MODE_MOS65XX_65816_LONG_M = (1 << 5) # MOS65XXX WDC 65816, 16-bit m, 8-bit x
CS_MODE_MOS65XX_65816_LONG_X = (1 << 6) # MOS65XXX WDC 65816, 8-bit m, 16-bit x CS_MODE_MOS65XX_65816_LONG_X = (1 << 6) # MOS65XXX WDC 65816, 8-bit m, 16-bit x
CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X
CS_MODE_SH2 = 1 << 1 # SH2 CS_MODE_SH2 = 1 << 1 # SH2
@ -413,8 +415,8 @@ CS_OP_RESERVED_14 = 14
CS_OP_RESERVED_15 = 15 CS_OP_RESERVED_15 = 15
CS_OP_SPECIAL = 0x10 # Special operands from archs CS_OP_SPECIAL = 0x10 # Special operands from archs
CS_OP_MEM = 0x80 # Memory operand. Can be ORed with another operand type. CS_OP_MEM = 0x80 # Memory operand. Can be ORed with another operand type.
CS_OP_MEM_REG = CS_OP_MEM | CS_OP_IMM, CS_OP_MEM_REG = CS_OP_MEM | CS_OP_REG # Memory referencing register operand.
CS_OP_MEM_IMM = CS_OP_MEM | CS_OP_IMM, CS_OP_MEM_IMM = CS_OP_MEM | CS_OP_IMM # Memory referencing immediate operand.
# Common instruction groups - to be consistent across all architectures. # Common instruction groups - to be consistent across all architectures.
CS_GRP_INVALID = 0 # uninitialized/invalid group. CS_GRP_INVALID = 0 # uninitialized/invalid group.
@ -498,6 +500,7 @@ else:
_found = False _found = False
def _load_lib(path): def _load_lib(path):
lib_file = join(path, _lib) lib_file = join(path, _lib)
if os.path.exists(lib_file): if os.path.exists(lib_file):
@ -509,6 +512,7 @@ def _load_lib(path):
return ctypes.cdll.LoadLibrary(lib_file + '.{}'.format(CS_VERSION_MAJOR)) return ctypes.cdll.LoadLibrary(lib_file + '.{}'.format(CS_VERSION_MAJOR))
return None return None
_cs = None _cs = None
# Loading attempts, in order # Loading attempts, in order
@ -542,11 +546,15 @@ def copy_ctypes(src):
ctypes.memmove(ctypes.byref(dst), ctypes.byref(src), ctypes.sizeof(type(src))) ctypes.memmove(ctypes.byref(dst), ctypes.byref(src), ctypes.sizeof(type(src)))
return dst return dst
def copy_ctypes_list(src): def copy_ctypes_list(src):
return [copy_ctypes(n) for n in 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 # Weird import placement because these modules are needed by the below code but need the above functions
from . import arm, aarch64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, alpha, hppa, loongarch from . import arm, aarch64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, \
riscv, sh, tricore, alpha, hppa, loongarch, xtensa
class _cs_arch(ctypes.Union): class _cs_arch(ctypes.Union):
_fields_ = ( _fields_ = (
@ -571,8 +579,10 @@ class _cs_arch(ctypes.Union):
('alpha', alpha.CsAlpha), ('alpha', alpha.CsAlpha),
('hppa', hppa.CsHPPA), ('hppa', hppa.CsHPPA),
('loongarch', loongarch.CsLoongArch), ('loongarch', loongarch.CsLoongArch),
('xtensa', xtensa.CsXtensa),
) )
class _cs_detail(ctypes.Structure): class _cs_detail(ctypes.Structure):
_fields_ = ( _fields_ = (
('regs_read', ctypes.c_uint16 * 20), ('regs_read', ctypes.c_uint16 * 20),
@ -585,6 +595,7 @@ class _cs_detail(ctypes.Structure):
('arch', _cs_arch), ('arch', _cs_arch),
) )
class _cs_insn(ctypes.Structure): class _cs_insn(ctypes.Structure):
_fields_ = ( _fields_ = (
('id', ctypes.c_uint), ('id', ctypes.c_uint),
@ -599,8 +610,11 @@ class _cs_insn(ctypes.Structure):
('detail', ctypes.POINTER(_cs_detail)), ('detail', ctypes.POINTER(_cs_detail)),
) )
# callback for SKIPDATA option # callback for SKIPDATA option
CS_SKIPDATA_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p) CS_SKIPDATA_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t,
ctypes.c_size_t, ctypes.c_void_p)
class _cs_opt_skipdata(ctypes.Structure): class _cs_opt_skipdata(ctypes.Structure):
_fields_ = ( _fields_ = (
@ -609,17 +623,20 @@ class _cs_opt_skipdata(ctypes.Structure):
('user_data', ctypes.c_void_p), ('user_data', ctypes.c_void_p),
) )
class _cs_opt_mnem(ctypes.Structure): class _cs_opt_mnem(ctypes.Structure):
_fields_ = ( _fields_ = (
('id', ctypes.c_uint), ('id', ctypes.c_uint),
('mnemonic', ctypes.c_char_p), ('mnemonic', ctypes.c_char_p),
) )
# setup all the function prototype # setup all the function prototype
def _setup_prototype(lib, fname, restype, *argtypes): def _setup_prototype(lib, fname, restype, *argtypes):
getattr(lib, fname).restype = restype getattr(lib, fname).restype = restype
getattr(lib, fname).argtypes = argtypes getattr(lib, fname).argtypes = argtypes
_setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t)) _setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t))
_setup_prototype(_cs, "cs_disasm", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \ _setup_prototype(_cs, "cs_disasm", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \
ctypes.c_uint64, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn))) ctypes.c_uint64, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn)))
@ -709,6 +726,7 @@ def cs_disasm_quick(arch, mode, code, offset, count=0):
if status != CS_ERR_OK: if status != CS_ERR_OK:
raise CsError(status) raise CsError(status)
# Another quick, but lighter function to disasm raw binary code. # Another quick, but lighter function to disasm raw binary code.
# This function is faster than cs_disasm_quick() around 20% because # This function is faster than cs_disasm_quick() around 20% because
# cs_disasm_lite() only return tuples of (address, size, mnemonic, op_str), # cs_disasm_lite() only return tuples of (address, size, mnemonic, op_str),
@ -750,6 +768,7 @@ def cs_disasm_lite(arch, mode, code, offset, count=0):
if status != CS_ERR_OK: if status != CS_ERR_OK:
raise CsError(status) raise CsError(status)
def _ascii_name_or_default(name, default): def _ascii_name_or_default(name, default):
return default if name is None else name.decode('ascii') return default if name is None else name.decode('ascii')
@ -762,11 +781,12 @@ class CsInsn(object):
if self._cs._detail and self._raw.id != 0: if self._cs._detail and self._raw.id != 0:
# save detail # save detail
self._raw.detail = ctypes.pointer(all_info.detail._type_()) self._raw.detail = ctypes.pointer(all_info.detail._type_())
ctypes.memmove(ctypes.byref(self._raw.detail[0]), ctypes.byref(all_info.detail[0]), ctypes.sizeof(type(all_info.detail[0]))) ctypes.memmove(ctypes.byref(self._raw.detail[0]), ctypes.byref(all_info.detail[0]),
ctypes.sizeof(type(all_info.detail[0])))
def __repr__(self): def __repr__(self):
return '<CsInsn 0x%x [%s]: %s %s>' % (self.address, self.bytes.hex(), self.mnemonic, self.op_str) return '<CsInsn 0x%x [%s]: %s %s>' % (self.address, self.bytes.hex(), self.mnemonic, self.op_str)
# return instruction's ID. # return instruction's ID.
@property @property
def id(self): def id(self):
@ -864,7 +884,7 @@ class CsInsn(object):
return self._raw.detail.contents.groups[:self._raw.detail.contents.groups_count] return self._raw.detail.contents.groups[:self._raw.detail.contents.groups_count]
raise CsError(CS_ERR_DETAIL) raise CsError(CS_ERR_DETAIL)
# return whether instruction has writeback operands. # return whether instruction has writeback operands.
@property @property
def writeback(self): def writeback(self):
@ -888,7 +908,7 @@ class CsInsn(object):
arch = self._cs.arch arch = self._cs.arch
if arch == CS_ARCH_ARM: if arch == CS_ARCH_ARM:
(self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.vcc, self.update_flags, \ (self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.vcc, self.update_flags, \
self.post_index, self.mem_barrier, self.pred_mask, self.operands) = arm.get_arch_info(self._raw.detail.contents.arch.arm) self.post_index, self.mem_barrier, self.pred_mask, self.operands) = arm.get_arch_info(self._raw.detail.contents.arch.arm)
elif arch == CS_ARCH_AARCH64: elif arch == CS_ARCH_AARCH64:
(self.cc, self.update_flags, self.post_index, self.operands) = \ (self.cc, self.update_flags, self.post_index, self.operands) = \
aarch64.get_arch_info(self._raw.detail.contents.arch.aarch64) aarch64.get_arch_info(self._raw.detail.contents.arch.aarch64)
@ -936,7 +956,8 @@ class CsInsn(object):
(self.operands) = hppa.get_arch_info(self._raw.detail.contents.arch.hppa) (self.operands) = hppa.get_arch_info(self._raw.detail.contents.arch.hppa)
elif arch == CS_ARCH_LOONGARCH: elif arch == CS_ARCH_LOONGARCH:
(self.format, self.operands) = loongarch.get_arch_info(self._raw.detail.contents.arch.loongarch) (self.format, self.operands) = loongarch.get_arch_info(self._raw.detail.contents.arch.loongarch)
elif arch == CS_ARCH_XTENSA:
(self.operands) = xtensa.get_arch_info(self._raw.detail.contents.arch.xtensa)
def __getattr__(self, name): def __getattr__(self, name):
if not self._cs._detail: if not self._cs._detail:
@ -985,7 +1006,6 @@ class CsInsn(object):
return _ascii_name_or_default(_cs.cs_group_name(self._cs.csh, group_id), default) return _ascii_name_or_default(_cs.cs_group_name(self._cs.csh, group_id), default)
# verify if this insn belong to group with id as @group_id # verify if this insn belong to group with id as @group_id
def group(self, group_id): def group(self, group_id):
if self._raw.id == 0: if self._raw.id == 0:
@ -1053,7 +1073,8 @@ class CsInsn(object):
regs_write = (ctypes.c_uint16 * 64)() regs_write = (ctypes.c_uint16 * 64)()
regs_write_count = ctypes.c_uint8() regs_write_count = ctypes.c_uint8()
status = _cs.cs_regs_access(self._cs.csh, self._raw, ctypes.byref(regs_read), ctypes.byref(regs_read_count), ctypes.byref(regs_write), ctypes.byref(regs_write_count)) status = _cs.cs_regs_access(self._cs.csh, self._raw, ctypes.byref(regs_read), ctypes.byref(regs_read_count),
ctypes.byref(regs_write), ctypes.byref(regs_write_count))
if status != CS_ERR_OK: if status != CS_ERR_OK:
raise CsError(status) raise CsError(status)
@ -1070,7 +1091,6 @@ class CsInsn(object):
return (regs_read, regs_write) return (regs_read, regs_write)
class Cs(object): class Cs(object):
def __init__(self, arch, mode): def __init__(self, arch, mode):
# verify version compatibility with the core before doing anything # verify version compatibility with the core before doing anything
@ -1113,8 +1133,6 @@ class Cs(object):
self._skipdata_opt = _cs_opt_skipdata() self._skipdata_opt = _cs_opt_skipdata()
self._skipdata = False self._skipdata = False
# destructor to be called automatically when object is destroyed. # destructor to be called automatically when object is destroyed.
def __del__(self): def __del__(self):
if self.csh: if self.csh:
@ -1136,25 +1154,21 @@ class Cs(object):
elif opt_type == CS_OPT_UNSIGNED: elif opt_type == CS_OPT_UNSIGNED:
self._imm_unsigned = opt_value == CS_OPT_ON self._imm_unsigned = opt_value == CS_OPT_ON
# is this a diet engine? # is this a diet engine?
@property @property
def diet(self): def diet(self):
return self._diet return self._diet
# is this engine compiled with X86-reduce option? # is this engine compiled with X86-reduce option?
@property @property
def x86_reduce(self): def x86_reduce(self):
return self._x86reduce return self._x86reduce
# return assembly syntax. # return assembly syntax.
@property @property
def syntax(self): def syntax(self):
return self._syntax return self._syntax
# syntax setter: modify assembly syntax. # syntax setter: modify assembly syntax.
@syntax.setter @syntax.setter
def syntax(self, style): def syntax(self, style):
@ -1164,13 +1178,11 @@ class Cs(object):
# save syntax # save syntax
self._syntax = style self._syntax = style
# return current skipdata status # return current skipdata status
@property @property
def skipdata(self): def skipdata(self):
return self._skipdata return self._skipdata
# setter: modify skipdata status # setter: modify skipdata status
@skipdata.setter @skipdata.setter
def skipdata(self, opt): def skipdata(self, opt):
@ -1184,41 +1196,36 @@ class Cs(object):
# save this option # save this option
self._skipdata = opt self._skipdata = opt
@property @property
def skipdata_setup(self): def skipdata_setup(self):
return (self._skipdata_mnem,) + self._skipdata_cb return (self._skipdata_mnem,) + self._skipdata_cb
@skipdata_setup.setter @skipdata_setup.setter
def skipdata_setup(self, opt): def skipdata_setup(self, opt):
_mnem, _cb, _ud = opt _mnem, _cb, _ud = opt
self._skipdata_opt.mnemonic = _mnem.encode() self._skipdata_opt.mnemonic = _mnem.encode()
self._skipdata_opt.callback = CS_SKIPDATA_CALLBACK(_cb or 0) self._skipdata_opt.callback = CS_SKIPDATA_CALLBACK(_cb or 0)
self._skipdata_opt.user_data = ctypes.cast(_ud, ctypes.c_void_p) self._skipdata_opt.user_data = ctypes.cast(_ud, ctypes.c_void_p)
status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA_SETUP, ctypes.cast(ctypes.byref(self._skipdata_opt), ctypes.c_void_p)) status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA_SETUP,
ctypes.cast(ctypes.byref(self._skipdata_opt), ctypes.c_void_p))
if status != CS_ERR_OK: if status != CS_ERR_OK:
raise CsError(status) raise CsError(status)
self._skipdata_mnem = _mnem self._skipdata_mnem = _mnem
self._skipdata_cb = (_cb, _ud) self._skipdata_cb = (_cb, _ud)
@property @property
def skipdata_mnem(self): def skipdata_mnem(self):
return self._skipdata_mnem return self._skipdata_mnem
@skipdata_mnem.setter @skipdata_mnem.setter
def skipdata_mnem(self, mnem): def skipdata_mnem(self, mnem):
self.skipdata_setup = (mnem,) + self._skipdata_cb self.skipdata_setup = (mnem,) + self._skipdata_cb
@property @property
def skipdata_callback(self): def skipdata_callback(self):
return self._skipdata_cb return self._skipdata_cb
@skipdata_callback.setter @skipdata_callback.setter
def skipdata_callback(self, val): def skipdata_callback(self, val):
if not isinstance(val, tuple): if not isinstance(val, tuple):
@ -1226,7 +1233,6 @@ class Cs(object):
func, data = val func, data = val
self.skipdata_setup = (self._skipdata_mnem, func, data) self.skipdata_setup = (self._skipdata_mnem, func, data)
# customize instruction mnemonic # customize instruction mnemonic
def mnemonic_setup(self, id, mnem): def mnemonic_setup(self, id, mnem):
_mnem_opt = _cs_opt_mnem() _mnem_opt = _cs_opt_mnem()
@ -1239,19 +1245,16 @@ class Cs(object):
if status != CS_ERR_OK: if status != CS_ERR_OK:
raise CsError(status) raise CsError(status)
# check to see if this engine supports a particular arch, # check to see if this engine supports a particular arch,
# or diet mode (depending on @query). # or diet mode (depending on @query).
def support(self, query): def support(self, query):
return cs_support(query) return cs_support(query)
# is detail mode enable? # is detail mode enable?
@property @property
def detail(self): def detail(self):
return self._detail return self._detail
# modify detail mode. # modify detail mode.
@detail.setter @detail.setter
def detail(self, opt): # opt is boolean type, so must be either 'True' or 'False' def detail(self, opt): # opt is boolean type, so must be either 'True' or 'False'
@ -1264,13 +1267,11 @@ class Cs(object):
# save detail # save detail
self._detail = opt self._detail = opt
# is detail mode enable? # is detail mode enable?
@property @property
def imm_unsigned(self): def imm_unsigned(self):
return self._imm_unsigned return self._imm_unsigned
# modify detail mode. # modify detail mode.
@imm_unsigned.setter @imm_unsigned.setter
def imm_unsigned(self, opt): # opt is boolean type, so must be either 'True' or 'False' def imm_unsigned(self, opt): # opt is boolean type, so must be either 'True' or 'False'
@ -1283,13 +1284,11 @@ class Cs(object):
# save detail # save detail
self._imm_unsigned = opt self._imm_unsigned = opt
# return disassembly mode of this engine. # return disassembly mode of this engine.
@property @property
def mode(self): def mode(self):
return self._mode return self._mode
# modify engine's mode at run-time. # modify engine's mode at run-time.
@mode.setter @mode.setter
def mode(self, opt): # opt is new disasm mode, of int type def mode(self, opt): # opt is new disasm mode, of int type
@ -1368,14 +1367,15 @@ class Cs(object):
code = ctypes.pointer(ctypes.c_char.from_buffer_copy(view)) code = ctypes.pointer(ctypes.c_char.from_buffer_copy(view))
if view.readonly: if view.readonly:
code = (ctypes.c_char * len(view)).from_buffer_copy(view) code = (ctypes.c_char * len(view)).from_buffer_copy(view)
else: else:
code = ctypes.pointer(ctypes.c_char.from_buffer(view)) code = ctypes.pointer(ctypes.c_char.from_buffer(view))
# since we are taking a pointer to a pointer, ctypes does not do # since we are taking a pointer to a pointer, ctypes does not do
# the typical auto conversion, so we have to cast it here. # the typical auto conversion, so we have to cast it here.
code = ctypes.cast(code, ctypes.POINTER(ctypes.c_char)) code = ctypes.cast(code, ctypes.POINTER(ctypes.c_char))
address = ctypes.c_uint64(offset) address = ctypes.c_uint64(offset)
while _cs.cs_disasm_iter(self.csh, ctypes.byref(code), ctypes.byref(size), ctypes.byref(address), ctypes.byref(insn)): while _cs.cs_disasm_iter(self.csh, ctypes.byref(code), ctypes.byref(size), ctypes.byref(address),
ctypes.byref(insn)):
yield (insn.address, insn.size, insn.mnemonic.decode('ascii'), insn.op_str.decode('ascii')) yield (insn.address, insn.size, insn.mnemonic.decode('ascii'), insn.op_str.decode('ascii'))
# Light function to disassemble binary. This is about 20% faster than disasm() because # Light function to disassemble binary. This is about 20% faster than disasm() because
@ -1432,7 +1432,7 @@ def debug():
"m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX,
'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE,
'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA, 'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, 'alpha': CS_ARCH_ALPHA,
'hppa': CS_ARCH_HPPA, 'loongarch': CS_ARCH_LOONGARCH 'hppa': CS_ARCH_HPPA, 'loongarch': CS_ARCH_LOONGARCH, 'xtensa': CS_ARCH_XTENSA
} }
all_archs = "" all_archs = ""

View File

@ -0,0 +1,52 @@
# Capstone Python bindings, by billow <billow.fun@gmail.com>
import ctypes
from . import copy_ctypes_list
from .xtensa_const import *
class XtensaOpMem(ctypes.Structure):
_fields_ = (
("base", ctypes.c_uint8),
("disp", ctypes.c_uint8),
)
class XtensaOpValue(ctypes.Union):
_fields_ = (
("reg", ctypes.c_uint8),
("imm", ctypes.c_int32),
("mem", XtensaOpMem),
)
class XtensaOp(ctypes.Structure):
_fields_ = (
("type", ctypes.c_uint8),
("access", ctypes.c_uint8),
("value", XtensaOpValue),
)
@property
def reg(self):
return self.value.reg
@property
def imm(self):
return self.value.imm
@property
def mem(self):
return self.value.mem
# Instruction structure
class CsXtensa(ctypes.Structure):
_fields_ = (
("op_count", ctypes.c_uint8),
("operands", XtensaOp * 8),
)
def get_arch_info(a):
return copy_ctypes_list(a.operands[: a.op_count])

View File

@ -0,0 +1,115 @@
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM, CS_OP_MEM_REG, CS_OP_MEM_IMM, UINT16_MAX
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [xtensa_const.py]
XTENSA_REG_INVALID = 0
XTENSA_REG_SAR = 1
XTENSA_REG_SP = 2
XTENSA_REG_A0 = 3
XTENSA_REG_A2 = 4
XTENSA_REG_A3 = 5
XTENSA_REG_A4 = 6
XTENSA_REG_A5 = 7
XTENSA_REG_A6 = 8
XTENSA_REG_A7 = 9
XTENSA_REG_A8 = 10
XTENSA_REG_A9 = 11
XTENSA_REG_A10 = 12
XTENSA_REG_A11 = 13
XTENSA_REG_A12 = 14
XTENSA_REG_A13 = 15
XTENSA_REG_A14 = 16
XTENSA_REG_A15 = 17
XTENSA_REG_ENDING = 18
XTENSA_INS_INVALID = 19
XTENSA_INS_ABS = 20
XTENSA_INS_ADD = 21
XTENSA_INS_ADDI = 22
XTENSA_INS_ADDMI = 23
XTENSA_INS_ADDX2 = 24
XTENSA_INS_ADDX4 = 25
XTENSA_INS_ADDX8 = 26
XTENSA_INS_AND = 27
XTENSA_INS_BALL = 28
XTENSA_INS_BANY = 29
XTENSA_INS_BBC = 30
XTENSA_INS_BBCI = 31
XTENSA_INS_BBS = 32
XTENSA_INS_BBSI = 33
XTENSA_INS_BEQ = 34
XTENSA_INS_BEQI = 35
XTENSA_INS_BEQZ = 36
XTENSA_INS_BGE = 37
XTENSA_INS_BGEI = 38
XTENSA_INS_BGEU = 39
XTENSA_INS_BGEUI = 40
XTENSA_INS_BGEZ = 41
XTENSA_INS_BLT = 42
XTENSA_INS_BLTI = 43
XTENSA_INS_BLTU = 44
XTENSA_INS_BLTUI = 45
XTENSA_INS_BLTZ = 46
XTENSA_INS_BNALL = 47
XTENSA_INS_BNE = 48
XTENSA_INS_BNEI = 49
XTENSA_INS_BNEZ = 50
XTENSA_INS_BNONE = 51
XTENSA_INS_CALL0 = 52
XTENSA_INS_CALLX0 = 53
XTENSA_INS_DSYNC = 54
XTENSA_INS_ESYNC = 55
XTENSA_INS_EXTUI = 56
XTENSA_INS_EXTW = 57
XTENSA_INS_ISYNC = 58
XTENSA_INS_J = 59
XTENSA_INS_JX = 60
XTENSA_INS_L16SI = 61
XTENSA_INS_L16UI = 62
XTENSA_INS_L32I = 63
XTENSA_INS_L32R = 64
XTENSA_INS_L8UI = 65
XTENSA_INS_MEMW = 66
XTENSA_INS_MOVEQZ = 67
XTENSA_INS_MOVGEZ = 68
XTENSA_INS_MOVI = 69
XTENSA_INS_MOVLTZ = 70
XTENSA_INS_MOVNEZ = 71
XTENSA_INS_NEG = 72
XTENSA_INS_NOP = 73
XTENSA_INS_OR = 74
XTENSA_INS_RET = 75
XTENSA_INS_RSR = 76
XTENSA_INS_RSYNC = 77
XTENSA_INS_S16I = 78
XTENSA_INS_S32I = 79
XTENSA_INS_S8I = 80
XTENSA_INS_SLL = 81
XTENSA_INS_SLLI = 82
XTENSA_INS_SRA = 83
XTENSA_INS_SRAI = 84
XTENSA_INS_SRC = 85
XTENSA_INS_SRL = 86
XTENSA_INS_SRLI = 87
XTENSA_INS_SSA8L = 88
XTENSA_INS_SSAI = 89
XTENSA_INS_SSL = 90
XTENSA_INS_SSR = 91
XTENSA_INS_SUB = 92
XTENSA_INS_SUBX2 = 93
XTENSA_INS_SUBX4 = 94
XTENSA_INS_SUBX8 = 95
XTENSA_INS_WSR = 96
XTENSA_INS_XOR = 97
XTENSA_INS_XSR = 98
XTENSA_GRP_INVALID = 0
XTENSA_GRP_CALL = 1
XTENSA_GRP_JUMP = 2
XTENSA_GRP_RET = 3
XTENSA_FEATURE_HASDENSITY = 128
XTENSA_GRP_ENDING = 129
XTENSA_OP_INVALID = CS_OP_INVALID
XTENSA_OP_REG = CS_OP_REG
XTENSA_OP_IMM = CS_OP_IMM
XTENSA_OP_MEM = CS_OP_MEM
XTENSA_OP_MEM_REG = CS_OP_MEM_REG
XTENSA_OP_MEM_IMM = CS_OP_MEM_IMM

30
bindings/stdout_cmp.py Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env python3
import argparse
import difflib
import re
import subprocess
import sys
def stdout_cmp(f1, f2):
def lines_run(xs):
out = subprocess.run(xs, stdout=subprocess.PIPE, check=True).stdout.decode()
lines = out.splitlines(keepends=True)
return out, [re.sub(r'([\t ])', '', ln) for ln in lines]
out1, lns1 = lines_run(f1)
out2, lns2 = lines_run(f2)
dif = list(difflib.unified_diff(lns1, lns2))
return len(dif) == 0, dif
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Comparing the standard output of two threads')
parser.add_argument("-f1", nargs='+')
parser.add_argument("-f2", nargs='+')
argv = parser.parse_args(sys.argv[1:])
res, dif = stdout_cmp(argv.f1, argv.f2)
if not res:
print('\n'.join(dif))
exit(1)
exit(0)

View File

@ -4,7 +4,7 @@
################################################################################ ################################################################################
# Specify which archs you want to compile in. By default, we build all archs. # 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 riscv mos65xx wasm bpf sh tricore alpha hppa loongarch CAPSTONE_ARCHS ?= arm aarch64 m68k mips powerpc sparc systemz x86 xcore tms320c64x m680x evm riscv mos65xx wasm bpf sh tricore alpha hppa loongarch xtensa
################################################################################ ################################################################################

88
cs.c
View File

@ -71,6 +71,7 @@
#include "arch/Alpha/AlphaModule.h" #include "arch/Alpha/AlphaModule.h"
#include "arch/HPPA/HPPAModule.h" #include "arch/HPPA/HPPAModule.h"
#include "arch/LoongArch/LoongArchModule.h" #include "arch/LoongArch/LoongArchModule.h"
#include "arch/Xtensa/XtensaModule.h"
typedef struct cs_arch_config { typedef struct cs_arch_config {
// constructor initialization // constructor initialization
@ -255,6 +256,12 @@ typedef struct cs_arch_config {
LoongArch_option, \ LoongArch_option, \
~(CS_MODE_LITTLE_ENDIAN | CS_MODE_LOONGARCH32 | CS_MODE_LOONGARCH64), \ ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_LOONGARCH32 | CS_MODE_LOONGARCH64), \
} }
#define CS_ARCH_CONFIG_XTENSA \
{ \
Xtensa_global_init, \
Xtensa_option, \
~(CS_MODE_XTENSA), \
}
#ifdef CAPSTONE_USE_ARCH_REGISTRATION #ifdef CAPSTONE_USE_ARCH_REGISTRATION
static cs_arch_config arch_configs[MAX_ARCH]; static cs_arch_config arch_configs[MAX_ARCH];
@ -360,8 +367,8 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
{ {
HPPA_global_init, HPPA_global_init,
HPPA_option, HPPA_option,
~(CS_MODE_LITTLE_ENDIAN | CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11 ~(CS_MODE_LITTLE_ENDIAN | CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11 |
| CS_MODE_HPPA_20 | CS_MODE_HPPA_20W), CS_MODE_HPPA_20 | CS_MODE_HPPA_20W),
}, },
#else #else
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
@ -371,74 +378,82 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
#else #else
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
#endif #endif
#ifdef CAPSTONE_HAS_XTENSA
CS_ARCH_CONFIG_XTENSA
#else
{ NULL, NULL, 0 },
#endif
}; };
// bitmask of enabled architectures // bitmask of enabled architectures
static const uint32_t all_arch = 0 static const uint32_t all_arch = 0
#ifdef CAPSTONE_HAS_ARM #ifdef CAPSTONE_HAS_ARM
| (1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM)
#endif #endif
#if defined(CAPSTONE_HAS_AARCH64) || defined(CAPSTONE_HAS_ARM64) #if defined(CAPSTONE_HAS_AARCH64) || defined(CAPSTONE_HAS_ARM64)
| (1 << CS_ARCH_AARCH64) | (1 << CS_ARCH_AARCH64)
#endif #endif
#ifdef CAPSTONE_HAS_MIPS #ifdef CAPSTONE_HAS_MIPS
| (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_MIPS)
#endif #endif
#ifdef CAPSTONE_HAS_X86 #ifdef CAPSTONE_HAS_X86
| (1 << CS_ARCH_X86) | (1 << CS_ARCH_X86)
#endif #endif
#ifdef CAPSTONE_HAS_POWERPC #ifdef CAPSTONE_HAS_POWERPC
| (1 << CS_ARCH_PPC) | (1 << CS_ARCH_PPC)
#endif #endif
#ifdef CAPSTONE_HAS_SPARC #ifdef CAPSTONE_HAS_SPARC
| (1 << CS_ARCH_SPARC) | (1 << CS_ARCH_SPARC)
#endif #endif
#ifdef CAPSTONE_HAS_SYSTEMZ #ifdef CAPSTONE_HAS_SYSTEMZ
| (1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_SYSTEMZ)
#endif #endif
#ifdef CAPSTONE_HAS_XCORE #ifdef CAPSTONE_HAS_XCORE
| (1 << CS_ARCH_XCORE) | (1 << CS_ARCH_XCORE)
#endif #endif
#ifdef CAPSTONE_HAS_M68K #ifdef CAPSTONE_HAS_M68K
| (1 << CS_ARCH_M68K) | (1 << CS_ARCH_M68K)
#endif #endif
#ifdef CAPSTONE_HAS_TMS320C64X #ifdef CAPSTONE_HAS_TMS320C64X
| (1 << CS_ARCH_TMS320C64X) | (1 << CS_ARCH_TMS320C64X)
#endif #endif
#ifdef CAPSTONE_HAS_M680X #ifdef CAPSTONE_HAS_M680X
| (1 << CS_ARCH_M680X) | (1 << CS_ARCH_M680X)
#endif #endif
#ifdef CAPSTONE_HAS_EVM #ifdef CAPSTONE_HAS_EVM
| (1 << CS_ARCH_EVM) | (1 << CS_ARCH_EVM)
#endif #endif
#ifdef CAPSTONE_HAS_MOS65XX #ifdef CAPSTONE_HAS_MOS65XX
| (1 << CS_ARCH_MOS65XX) | (1 << CS_ARCH_MOS65XX)
#endif #endif
#ifdef CAPSTONE_HAS_WASM #ifdef CAPSTONE_HAS_WASM
| (1 << CS_ARCH_WASM) | (1 << CS_ARCH_WASM)
#endif #endif
#ifdef CAPSTONE_HAS_BPF #ifdef CAPSTONE_HAS_BPF
| (1 << CS_ARCH_BPF) | (1 << CS_ARCH_BPF)
#endif #endif
#ifdef CAPSTONE_HAS_RISCV #ifdef CAPSTONE_HAS_RISCV
| (1 << CS_ARCH_RISCV) | (1 << CS_ARCH_RISCV)
#endif #endif
#ifdef CAPSTONE_HAS_SH #ifdef CAPSTONE_HAS_SH
| (1 << CS_ARCH_SH) | (1 << CS_ARCH_SH)
#endif #endif
#ifdef CAPSTONE_HAS_TRICORE #ifdef CAPSTONE_HAS_TRICORE
| (1 << CS_ARCH_TRICORE) | (1 << CS_ARCH_TRICORE)
#endif #endif
#ifdef CAPSTONE_HAS_ALPHA #ifdef CAPSTONE_HAS_ALPHA
| (1 << CS_ARCH_ALPHA) | (1 << CS_ARCH_ALPHA)
#endif #endif
#ifdef CAPSTONE_HAS_HPPA #ifdef CAPSTONE_HAS_HPPA
| (1 << CS_ARCH_HPPA) | (1 << CS_ARCH_HPPA)
#endif #endif
#ifdef CAPSTONE_HAS_LOONGARCH #ifdef CAPSTONE_HAS_LOONGARCH
| (1 << CS_ARCH_LOONGARCH) | (1 << CS_ARCH_LOONGARCH)
#endif #endif
; #ifdef CAPSTONE_HAS_XTENSA
| (1 << CS_ARCH_XTENSA)
#endif
;
#endif #endif
@ -670,17 +685,17 @@ bool CAPSTONE_API cs_support(int query)
{ {
if (query == CS_ARCH_ALL) if (query == CS_ARCH_ALL)
return all_arch == return all_arch ==
((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) | ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) |
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) | (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) | (1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
(1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_XCORE) | (1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_XCORE) |
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) | (1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) | (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) | (1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
(1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF) | (1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF) |
(1 << CS_ARCH_SH) | (1 << CS_ARCH_TRICORE) | (1 << CS_ARCH_SH) | (1 << CS_ARCH_TRICORE) |
(1 << CS_ARCH_ALPHA) | (1 << CS_ARCH_HPPA) | (1 << CS_ARCH_ALPHA) | (1 << CS_ARCH_HPPA) |
(1 << CS_ARCH_LOONGARCH)); (1 << CS_ARCH_LOONGARCH) | (1 << CS_ARCH_XTENSA));
if ((unsigned int)query < CS_ARCH_MAX) if ((unsigned int)query < CS_ARCH_MAX)
return all_arch & (1 << query); return all_arch & (1 << query);
@ -1214,7 +1229,8 @@ size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64
if (handle->detail_opt) { if (handle->detail_opt) {
// allocate memory for @detail pointer // allocate memory for @detail pointer
insn_cache->detail = cs_mem_malloc(sizeof(cs_detail)); insn_cache->detail =
cs_mem_calloc(1, sizeof(cs_detail));
} else { } else {
insn_cache->detail = NULL; insn_cache->detail = NULL;
} }

View File

@ -81,6 +81,7 @@ struct cs_struct {
const uint8_t *regsize_map; // map to register size (x86-only for now) const uint8_t *regsize_map; // map to register size (x86-only for now)
GetRegisterAccess_t reg_access; GetRegisterAccess_t reg_access;
struct insn_mnem *mnem_list; // linked list of customized instruction mnemonic struct insn_mnem *mnem_list; // linked list of customized instruction mnemonic
uint32_t LITBASE;
}; };
#define MAX_ARCH CS_ARCH_MAX #define MAX_ARCH CS_ARCH_MAX

View File

@ -147,13 +147,13 @@ static struct {
{ "sparcv9", "Sparc v9, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 }, { "sparcv9", "Sparc v9, big endian", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 },
{ "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN }, { "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
{ "systemz_arch8", "(arch8/z10/generic)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN }, { "systemz_arch8", "(arch8/z10/generic)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch9", "(arch9/z196)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN }, { "systemz_arch9", "(arch9/z196)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch10", "(arch10/zec12)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN }, { "systemz_arch10", "(arch10/zec12)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch11", "(arch11/z13)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN }, { "systemz_arch11", "(arch11/z13)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch12", "(arch12/z14)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN }, { "systemz_arch12", "(arch12/z14)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch13", "(arch13/z15)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN }, { "systemz_arch13", "(arch13/z15)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch14", "(arch14/z16)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN }, { "systemz_arch14", "(arch14/z16)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN },
{ "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN }, { "s390x", "SystemZ s390x, big endian", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
@ -221,6 +221,8 @@ static struct {
{ "loongarch32", "LoongArch 32-bit", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH32 }, { "loongarch32", "LoongArch 32-bit", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH32 },
{ "loongarch64", "LoongArch 64-bit", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH64 }, { "loongarch64", "LoongArch 64-bit", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH64 },
{ "xtensa", "Xtensa", CS_ARCH_XTENSA, CS_MODE_XTENSA },
{ "xtensabe", "Xtensa, big endian", CS_ARCH_XTENSA, CS_MODE_XTENSA | CS_MODE_BIG_ENDIAN },
{ NULL } { NULL }
}; };
@ -422,6 +424,9 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
case CS_ARCH_LOONGARCH: case CS_ARCH_LOONGARCH:
print_insn_detail_loongarch(handle, ins); print_insn_detail_loongarch(handle, ins);
break; break;
case CS_ARCH_XTENSA:
print_insn_detail_xtensa(handle, ins);
break;
default: break; default: break;
} }
@ -608,6 +613,10 @@ int main(int argc, char **argv)
printf("loongarch=1 "); printf("loongarch=1 ");
} }
if (cs_support(CS_ARCH_XTENSA)) {
printf("xtensa=1 ");
}
printf("\n"); printf("\n");
return 0; return 0;
case 'h': case 'h':
@ -637,6 +646,7 @@ int main(int argc, char **argv)
address = strtoull(src, &temp, 16); address = strtoull(src, &temp, 16);
if (temp == src || *temp != '\0' || errno == ERANGE) { if (temp == src || *temp != '\0' || errno == ERANGE) {
fprintf(stderr, "ERROR: invalid address argument, quit!\n"); fprintf(stderr, "ERROR: invalid address argument, quit!\n");
free(assembly);
return -2; return -2;
} }
} }
@ -670,6 +680,7 @@ int main(int argc, char **argv)
if (arch == CS_ARCH_ALL) { if (arch == CS_ARCH_ALL) {
fprintf(stderr, "ERROR: Invalid <arch+mode>: \"%s\", quit!\n", choosen_arch); fprintf(stderr, "ERROR: Invalid <arch+mode>: \"%s\", quit!\n", choosen_arch);
usage(argv[0]); usage(argv[0]);
free(assembly);
return -1; return -1;
} }
@ -677,6 +688,7 @@ int main(int argc, char **argv)
const char *error = cs_strerror(err); const char *error = cs_strerror(err);
fprintf(stderr, "ERROR: Failed on cs_open(): %s\n", error); fprintf(stderr, "ERROR: Failed on cs_open(): %s\n", error);
usage(argv[0]); usage(argv[0]);
free(assembly);
return -1; return -1;
} }

View File

@ -22,5 +22,6 @@ void print_insn_detail_tricore(csh handle, cs_insn *ins);
void print_insn_detail_alpha(csh handle, cs_insn *ins); void print_insn_detail_alpha(csh handle, cs_insn *ins);
void print_insn_detail_hppa(csh handle, cs_insn *ins); void print_insn_detail_hppa(csh handle, cs_insn *ins);
void print_insn_detail_loongarch(csh handle, cs_insn *ins); void print_insn_detail_loongarch(csh handle, cs_insn *ins);
void print_insn_detail_xtensa(csh handle, cs_insn *ins);
#endif //CAPSTONE_CSTOOL_CSTOOL_H_ #endif //CAPSTONE_CSTOOL_CSTOOL_H_

71
cstool/cstool_xtensa.c Normal file
View File

@ -0,0 +1,71 @@
/* Capstone Disassembly Engine */
/* By billow <billow.fun@gmail.com>, 2024 */
#include <stdio.h>
#include <capstone/capstone.h>
void print_insn_detail_xtensa(csh handle, cs_insn *ins)
{
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
cs_xtensa *detail = &(ins->detail->xtensa);
if (detail->op_count)
printf("\top_count: %u\n", detail->op_count);
for (i = 0; i < detail->op_count; i++) {
cs_xtensa_op *op = &(detail->operands[i]);
if (op->type == CS_OP_REG)
printf("\t\toperands[%u].type: REG = %s\n", i,
cs_reg_name(handle, op->reg));
else if (op->type == CS_OP_IMM)
printf("\t\toperands[%u].type: IMM = 0x%" PRIx32 "\n",
i, op->imm);
else if (op->type == CS_OP_MEM)
printf("\t\toperands[%u].type: MEM\n"
"\t\t\t.mem.base: REG = %s\n"
"\t\t\t.mem.disp: 0x%" PRIx8 "\n",
i, cs_reg_name(handle, op->mem.base),
op->mem.disp);
else if (op->type == XTENSA_OP_L32R) {
printf("\t\toperands[%u].type: L32R\n"
"\t\t\t.l32r = %" PRIx32 "\n",
i, op->imm);
}
if (op->access & CS_AC_READ)
printf("\t\t\t.access: READ\n");
else if (op->access & CS_AC_WRITE)
printf("\t\t\t.access: WRITE\n");
else if (op->access & (CS_AC_READ | CS_AC_WRITE))
printf("\t\t\t.access: READ | WRITE\n");
}
// Print out all registers accessed by this instruction (either implicit or
// explicit)
if (!cs_regs_access(handle, ins, regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for (i = 0; i < regs_read_count; i++) {
printf(" %s",
cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for (i = 0; i < regs_write_count; i++) {
printf(" %s",
cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
}

View File

@ -171,6 +171,11 @@ Nonetheless, we hope this additional information is useful to you.
- Operands have now read/write access information - Operands have now read/write access information
**Xtensa**
- Architecture support was added (based on LLVM-18).
- Support for `LITBASE`. Set the `LITBASE` with `cs_option(handle, CS_OPT_LITBASE, litbase_value)`.
**UX** **UX**
- Instruction alias (see below). - Instruction alias (see below).

View File

@ -102,6 +102,7 @@ typedef enum cs_arch {
CS_ARCH_ALPHA, ///< Alpha architecture CS_ARCH_ALPHA, ///< Alpha architecture
CS_ARCH_HPPA, ///< HPPA architecture CS_ARCH_HPPA, ///< HPPA architecture
CS_ARCH_LOONGARCH, ///< LoongArch architecture CS_ARCH_LOONGARCH, ///< LoongArch architecture
CS_ARCH_XTENSA, ///< Xtensa architecture
CS_ARCH_MAX, CS_ARCH_MAX,
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
} cs_arch; } cs_arch;
@ -221,6 +222,7 @@ typedef enum cs_mode {
CS_MODE_SYSTEMZ_Z15 = 1 << 13, ///< Enables features of the Z15 processor CS_MODE_SYSTEMZ_Z15 = 1 << 13, ///< Enables features of the Z15 processor
CS_MODE_SYSTEMZ_Z16 = 1 << 14, ///< Enables features of the Z16 processor CS_MODE_SYSTEMZ_Z16 = 1 << 14, ///< Enables features of the Z16 processor
CS_MODE_SYSTEMZ_GENERIC = 1 << 15, ///< Enables features of the generic processor CS_MODE_SYSTEMZ_GENERIC = 1 << 15, ///< Enables features of the generic processor
CS_MODE_XTENSA = 1 << 1, ///< Xtensa
} cs_mode; } cs_mode;
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
@ -263,6 +265,7 @@ typedef enum cs_opt_type {
CS_OPT_MNEMONIC, ///< Customize instruction mnemonic CS_OPT_MNEMONIC, ///< Customize instruction mnemonic
CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form
CS_OPT_ONLY_OFFSET_BRANCH, ///< ARM, PPC, AArch64: Don't add the branch immediate value to the PC. CS_OPT_ONLY_OFFSET_BRANCH, ///< ARM, PPC, AArch64: Don't add the branch immediate value to the PC.
CS_OPT_LITBASE, ///< Xtensa, set the LITBASE value. LITBASE is set to 0 by default.
} cs_opt_type; } cs_opt_type;
/// Runtime option value (associated with option type above) /// Runtime option value (associated with option type above)
@ -377,6 +380,7 @@ typedef struct cs_opt_skipdata {
#include "alpha.h" #include "alpha.h"
#include "hppa.h" #include "hppa.h"
#include "loongarch.h" #include "loongarch.h"
#include "xtensa.h"
#define MAX_IMPL_W_REGS 47 #define MAX_IMPL_W_REGS 47
#define MAX_IMPL_R_REGS 20 #define MAX_IMPL_R_REGS 20
@ -433,6 +437,7 @@ typedef struct cs_detail {
cs_alpha alpha; ///< Alpha architecture cs_alpha alpha; ///< Alpha architecture
cs_hppa hppa; ///< HPPA architecture cs_hppa hppa; ///< HPPA architecture
cs_loongarch loongarch; ///< LoongArch architecture cs_loongarch loongarch; ///< LoongArch architecture
cs_xtensa xtensa; ///< Xtensa architecture
}; };
} cs_detail; } cs_detail;

182
include/capstone/xtensa.h Normal file
View File

@ -0,0 +1,182 @@
#ifndef CAPSTONE_XTENSA_H
#define CAPSTONE_XTENSA_H
#ifdef __cplusplus
extern "C" {
#endif
#include "cs_operand.h"
#include "platform.h"
/// Xtensa registers
typedef enum xtensa_reg {
// generated content <XtensaGenCSRegEnum.inc> begin
// clang-format off
XTENSA_REG_INVALID = 0,
XTENSA_REG_SAR = 1,
XTENSA_REG_SP = 2,
XTENSA_REG_A0 = 3,
XTENSA_REG_A2 = 4,
XTENSA_REG_A3 = 5,
XTENSA_REG_A4 = 6,
XTENSA_REG_A5 = 7,
XTENSA_REG_A6 = 8,
XTENSA_REG_A7 = 9,
XTENSA_REG_A8 = 10,
XTENSA_REG_A9 = 11,
XTENSA_REG_A10 = 12,
XTENSA_REG_A11 = 13,
XTENSA_REG_A12 = 14,
XTENSA_REG_A13 = 15,
XTENSA_REG_A14 = 16,
XTENSA_REG_A15 = 17,
XTENSA_REG_ENDING, // 18
// clang-format on
// generated content <XtensaGenCSRegEnum.inc> end
} xtensa_reg;
/// Xtensa registers
typedef enum xtensa_insn {
// generated content <XtensaGenCSInsnEnum.inc> begin
// clang-format off
XTENSA_INS_INVALID,
XTENSA_INS_ABS,
XTENSA_INS_ADD,
XTENSA_INS_ADDI,
XTENSA_INS_ADDMI,
XTENSA_INS_ADDX2,
XTENSA_INS_ADDX4,
XTENSA_INS_ADDX8,
XTENSA_INS_AND,
XTENSA_INS_BALL,
XTENSA_INS_BANY,
XTENSA_INS_BBC,
XTENSA_INS_BBCI,
XTENSA_INS_BBS,
XTENSA_INS_BBSI,
XTENSA_INS_BEQ,
XTENSA_INS_BEQI,
XTENSA_INS_BEQZ,
XTENSA_INS_BGE,
XTENSA_INS_BGEI,
XTENSA_INS_BGEU,
XTENSA_INS_BGEUI,
XTENSA_INS_BGEZ,
XTENSA_INS_BLT,
XTENSA_INS_BLTI,
XTENSA_INS_BLTU,
XTENSA_INS_BLTUI,
XTENSA_INS_BLTZ,
XTENSA_INS_BNALL,
XTENSA_INS_BNE,
XTENSA_INS_BNEI,
XTENSA_INS_BNEZ,
XTENSA_INS_BNONE,
XTENSA_INS_CALL0,
XTENSA_INS_CALLX0,
XTENSA_INS_DSYNC,
XTENSA_INS_ESYNC,
XTENSA_INS_EXTUI,
XTENSA_INS_EXTW,
XTENSA_INS_ISYNC,
XTENSA_INS_J,
XTENSA_INS_JX,
XTENSA_INS_L16SI,
XTENSA_INS_L16UI,
XTENSA_INS_L32I,
XTENSA_INS_L32R,
XTENSA_INS_L8UI,
XTENSA_INS_MEMW,
XTENSA_INS_MOVEQZ,
XTENSA_INS_MOVGEZ,
XTENSA_INS_MOVI,
XTENSA_INS_MOVLTZ,
XTENSA_INS_MOVNEZ,
XTENSA_INS_NEG,
XTENSA_INS_NOP,
XTENSA_INS_OR,
XTENSA_INS_RET,
XTENSA_INS_RSR,
XTENSA_INS_RSYNC,
XTENSA_INS_S16I,
XTENSA_INS_S32I,
XTENSA_INS_S8I,
XTENSA_INS_SLL,
XTENSA_INS_SLLI,
XTENSA_INS_SRA,
XTENSA_INS_SRAI,
XTENSA_INS_SRC,
XTENSA_INS_SRL,
XTENSA_INS_SRLI,
XTENSA_INS_SSA8L,
XTENSA_INS_SSAI,
XTENSA_INS_SSL,
XTENSA_INS_SSR,
XTENSA_INS_SUB,
XTENSA_INS_SUBX2,
XTENSA_INS_SUBX4,
XTENSA_INS_SUBX8,
XTENSA_INS_WSR,
XTENSA_INS_XOR,
XTENSA_INS_XSR,
// clang-format on
// generated content <XtensaGenCSInsnEnum.inc> end
} xtensa_insn;
typedef enum xtensa_feature {
XTENSA_GRP_INVALID = 0,
XTENSA_GRP_CALL,
XTENSA_GRP_JUMP,
XTENSA_GRP_RET,
// generated content <XtensaGenCSFeatureEnum.inc> begin
// clang-format off
XTENSA_FEATURE_HASDENSITY = 128,
// clang-format on
// generated content <XtensaGenCSFeatureEnum.inc> end
XTENSA_GRP_ENDING, ///< mark the end of the list of features
} xtensa_feature;
typedef enum cs_xtensa_op_type {
XTENSA_OP_INVALID = CS_OP_INVALID, ///< = (Uninitialized).
XTENSA_OP_REG = CS_OP_REG, ///< = (Register operand).
XTENSA_OP_IMM = CS_OP_IMM, ///< = (Immediate operand).
XTENSA_OP_MEM = CS_OP_MEM, ///< = (Memory operand).
XTENSA_OP_MEM_REG = CS_OP_MEM_REG, ///< = (Memory Register operand).
XTENSA_OP_MEM_IMM = CS_OP_MEM_IMM, ///< = (Memory Immediate operand).
XTENSA_OP_L32R, ///< = (L32R Target)
} cs_xtensa_op_type;
typedef struct cs_xtensa_op_mem {
uint8_t base;
uint8_t disp;
} cs_xtensa_op_mem;
typedef struct cs_xtensa_operand {
uint8_t type;
uint8_t access;
union {
uint8_t reg;
int32_t imm;
cs_xtensa_op_mem mem;
};
} cs_xtensa_op;
#define MAX_XTENSA_OPS 8
typedef struct cs_xtensa {
uint8_t op_count;
cs_xtensa_op operands[MAX_XTENSA_OPS];
} cs_xtensa;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -25,6 +25,7 @@ if "%1"=="RISCV" set %arch%=RISCV
if "%1"=="ALPHA" set %arch%=ALPHA if "%1"=="ALPHA" set %arch%=ALPHA
if "%1"=="HPPA" set %arch%=HPPA if "%1"=="HPPA" set %arch%=HPPA
if "%1"=="LOONGARCH" set %arch%=LOONGARCH if "%1"=="LOONGARCH" set %arch%=LOONGARCH
if "%1"=="XTENSA" set %arch%=XTENSA
if not "%arch%"=="" set flags=%flags% and " -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF -DCAPSTONE_%arch%_SUPPORT=ON" if not "%arch%"=="" set flags=%flags% and " -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF -DCAPSTONE_%arch%_SUPPORT=ON"

View File

@ -0,0 +1,17 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x60,0x51,0x60 = abs a5, a6
0x40,0x39,0x80 = add a3, a9, a4
0x10,0xf9,0x80 = add a15, a9, a1
0x82,0xc1,0x80 = addi a8, a1, -128
0x82,0xc1,0xf4 = addi a8, a1, -12
0x12,0xd2,0x7f = addmi a1, a2, 32512
0x50,0x21,0x90 = addx2 a2, a1, a5
0x60,0x31,0x0 = addx4 a3, a1, a6
0x70,0x41,0xb0 = addx8 a4, a1, a7
0x30,0x10,0x60 = neg a1, a3
0x60,0x45,0x20 = or a4, a5, a6
0x10,0x82,0xc0 = sub a8, a2, a1
0x50,0x21,0xd0 = subx2 a2, a1, a5
0x60,0x31,0xe0 = subx4 a3, a1, a6
0x70,0x41,0xf0 = subx8 a4, a1, a7
0x50,0x64,0x30 = xor a6, a4, a5

View File

@ -0,0 +1,32 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x37,0x41,0x0 = ball a1, a3, LBL0
0xd7,0x88,0x0 = bany a8, a13, LBL0
0x77,0x58,0x0 = bbc a8, a7, LBL0
0x7,0x73,0x0 = bbci a3, 16, LBL0
0x7,0x73,0x0 = bbci a3, 16, LBL0
0x57,0xdc,0x0 = bbs a12, a5, LBL0
0x7,0xf3,0x0 = bbsi a3, 16, LBL0
0x37,0xc7,0x0 = bnall a7, a3, LBL0
0x47,0x2,0x0 = bnone a2, a4, LBL0
0x27,0x11,0x0 = beq a1, a2, LBL0
0x57,0x1b,0x0 = beq a11, a5, LBL0
0x26,0xf1,0x0 = beqi a1, 256, LBL0
0x26,0xb,0x0 = beqi a11, -1, LBL0
0x16,0x8,0x0 = beqz a8, LBL0
0x27,0xe,0x0 = bge a14, a2, LBL0
0xe6,0xb,0x0 = bgei a11, -1, LBL0
0xe6,0xeb,0x0 = bgei a11, 128, LBL0
0x27,0xbe,0x0 = bgeu a14, a2, LBL0
0x17,0xbd,0x0 = bgeu a13, a1, LBL0
0xf6,0x9,0x0 = bgeui a9, 32768, LBL0
0xf6,0x17,0x0 = bgeui a7, 65536, LBL0
0xf6,0xd7,0x0 = bgeui a7, 64, LBL0
0xd6,0x8,0x0 = bgez a8, LBL0
0x27,0x2e,0x0 = blt a14, a2, LBL0
0x6,0xc,0x0 = blti a12, -1, LBL0
0x6,0xc0,0x0 = blti a0, 32, LBL0
0xb6,0xb7,0x0 = bltui a7, 16, LBL0
0x96,0x6,0x0 = bltz a6, LBL0
0x47,0x93,0x0 = bne a3, a4, LBL0
0x66,0x5,0x0 = bnei a5, 12, LBL0
0x56,0x5,0x0 = bnez a5, LBL0

View File

@ -0,0 +1,6 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x5,0x0,0x0 = call0 LBL0
0xc0,0x1,0x0 = callx0 a1
0x6,0x0,0x0 = j LBL0
0x0,0x2,0x0 = jx a2
0x80,0x0,0x0 = ret

View File

@ -0,0 +1,3 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0xd0,0x20,0x0 = extw
0xc0,0x20,0x0 = memw

View File

@ -0,0 +1,8 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x22,0x1,0x3 = l8ui a2, a1, 3
0x32,0x91,0x2 = l16si a3, a1, 4
0x42,0x11,0x3 = l16ui a4, a1, 6
0x52,0x21,0x2 = l32i a5, a1, 8
0x22,0x41,0x3 = s8i a2, a1, 3
0x32,0x51,0x2 = s16i a3, a1, 4
0x52,0x61,0x2 = s32i a5, a1, 8

View File

@ -0,0 +1,6 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x40,0x23,0x83 = moveqz a2, a3, a4
0xc0,0x3b,0xb3 = movgez a3, a11, a12
0x12,0x8,0x0 = movi a1, -2048
0x90,0x78,0x3 = movltz a7, a8, a9
0xc0,0xb,0x93 = movnez a10, a11, a12

View File

@ -0,0 +1,15 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x30,0x20,0x0 = dsync
0x20,0x20,0x0 = esync
0x0,0x20,0x0 = isync
0xf0,0x20,0x0 = nop
0x80,0x3,0x3 = rsr a8, sar
0x80,0x3,0x3 = rsr a8, sar
0x80,0x3,0x3 = rsr a8, sar
0x10,0x20,0x0 = rsync
0x80,0x3,0x13 = wsr a8, sar
0x80,0x3,0x13 = wsr a8, sar
0x80,0x3,0x13 = wsr a8, sar
0x80,0x3,0x61 = xsr a8, sar
0x80,0x3,0x61 = xsr a8, sar
0x80,0x3,0x61 = xsr a8, sar

View File

@ -0,0 +1,13 @@
# CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, None
0x20,0x17,0x74 = extui a1, a2, 7, 8
0x0,0xb,0x1 = sll a10, a11
0x10,0x51,0x11 = slli a5, a1, 15
0x30,0xc0,0xb1 = sra a12, a3
0x50,0x80,0x21 = srai a8, a5, 0
0x50,0x34,0x81 = src a3, a4, a5
0x70,0x60,0x91 = srl a6, a7
0x40,0x38,0x41 = srli a3, a4, 8
0x0,0x2e,0x40 = ssa8l a14
0x10,0x4f,0x40 = ssai 31
0x0,0x10,0x40 = ssl a0
0x0,0x2,0x40 = ssr a2

View File

@ -224,6 +224,10 @@ class TestFile:
return str(self.file_path) < str(other.file_path) return str(self.file_path) < str(other.file_path)
def exists_and_is_dir(x):
return x.exists() and x.is_dir()
class MCUpdater: class MCUpdater:
""" """
The MCUpdater parses all test files of the LLVM MC regression tests. The MCUpdater parses all test files of the LLVM MC regression tests.
@ -291,11 +295,10 @@ class MCUpdater:
self.multi_mode = multi_mode self.multi_mode = multi_mode
def check_prerequisites(self, paths): def check_prerequisites(self, paths):
for path in paths: if all(not exists_and_is_dir(path) for path in paths):
if not path.exists() or not path.is_dir(): raise ValueError(
raise ValueError( f"'{paths}' does not exits or is not a directory. Cannot generate tests from there."
f"'{path}' does not exits or is not a directory. Cannot generate tests from there." )
)
llvm_lit_cfg = get_path("{LLVM_LIT_TEST_DIR}") llvm_lit_cfg = get_path("{LLVM_LIT_TEST_DIR}")
if not llvm_lit_cfg.exists(): if not llvm_lit_cfg.exists():
raise ValueError( raise ValueError(
@ -478,9 +481,14 @@ class MCUpdater:
log.info("Check prerequisites") log.info("Check prerequisites")
disas_tests = self.mc_dir.joinpath(f"Disassembler/{self.arch}") disas_tests = self.mc_dir.joinpath(f"Disassembler/{self.arch}")
test_paths = [disas_tests] test_paths = [disas_tests]
# Xtensa only defines assembly tests.
if self.arch == "Xtensa":
test_paths.append(self.mc_dir.joinpath(self.arch))
self.check_prerequisites(test_paths) self.check_prerequisites(test_paths)
log.info("Generate MC regression tests") log.info("Generate MC regression tests")
llvm_mc_cmds = self.run_llvm_lit(test_paths) llvm_mc_cmds = self.run_llvm_lit(
[path for path in test_paths if exists_and_is_dir(path)]
)
log.info(f"Got {len(llvm_mc_cmds)} llvm-mc commands to run") log.info(f"Got {len(llvm_mc_cmds)} llvm-mc commands to run")
self.test_files = self.build_test_files(llvm_mc_cmds) self.test_files = self.build_test_files(llvm_mc_cmds)
for slink in self.symbolic_links: for slink in self.symbolic_links:

View File

@ -10,10 +10,20 @@ TARGETS_LLVM_NAMING = [
"LoongArch", "LoongArch",
"SystemZ", "SystemZ",
"Mips", "Mips",
"Xtensa",
] ]
# Names of the target architecture as they are used in code and pretty much everywhere else. # Names of the target architecture as they are used in code and pretty much everywhere else.
ARCH_LLVM_NAMING = ["ARM", "PPC", "Alpha", "AArch64", "LoongArch", "SystemZ", "Mips"] ARCH_LLVM_NAMING = [
"ARM",
"PPC",
"Alpha",
"AArch64",
"LoongArch",
"SystemZ",
"Mips",
"Xtensa",
]
# Maps the target full name to the name used in code (and pretty much everywhere else). # Maps the target full name to the name used in code (and pretty much everywhere else).
TARGET_TO_IN_CODE_NAME = { TARGET_TO_IN_CODE_NAME = {
@ -24,6 +34,7 @@ TARGET_TO_IN_CODE_NAME = {
"LoongArch": "LoongArch", "LoongArch": "LoongArch",
"SystemZ": "SystemZ", "SystemZ": "SystemZ",
"Mips": "Mips", "Mips": "Mips",
"Xtensa": "Xtensa",
} }
# Maps the name from ARCH_LLVM_NAMING to the directory name in LLVM # Maps the name from ARCH_LLVM_NAMING to the directory name in LLVM
@ -35,4 +46,5 @@ TARGET_TO_DIR_NAME = {
"LoongArch": "LoongArch", "LoongArch": "LoongArch",
"SystemZ": "SystemZ", "SystemZ": "SystemZ",
"Mips": "Mips", "Mips": "Mips",
"Xtensa": "Xtensa",
} }

View File

@ -444,6 +444,8 @@ class Translator:
cb: [(Node, str)] cb: [(Node, str)]
for cb in captures_bundle: for cb in captures_bundle:
patch_kwargs = self.get_patch_kwargs(patch) patch_kwargs = self.get_patch_kwargs(patch)
patch_kwargs["tree"] = self.tree
patch_kwargs["ts_cpp_lang"] = self.ts_cpp_lang
bytes_patch: bytes = patch.get_patch(cb, self.src, **patch_kwargs) bytes_patch: bytes = patch.get_patch(cb, self.src, **patch_kwargs)
p_list.append((bytes_patch, cb[0][0])) p_list.append((bytes_patch, cb[0][0]))
self.patch_src(p_list) self.patch_src(p_list)

View File

@ -107,7 +107,8 @@ class TestPatches(unittest.TestCase):
self.assertGreater(len(captures_bundle), 0) self.assertGreater(len(captures_bundle), 0)
for cb in captures_bundle: for cb in captures_bundle:
self.assertEqual(patch.get_patch(cb, syntax, **kwargs), expected) actual = patch.get_patch(cb, syntax, **kwargs)
self.assertEqual(actual, expected)
def test_addcsdetail(self): def test_addcsdetail(self):
patch = AddCSDetail(0, "ARCH") patch = AddCSDetail(0, "ARCH")
@ -115,7 +116,7 @@ class TestPatches(unittest.TestCase):
self.check_patching_result( self.check_patching_result(
patch, patch,
syntax, syntax,
b"void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNo, SStream *O){ " b"static inline void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNo, SStream *O){ "
b"add_cs_detail(MI, ARCH_OP_GROUP_ThumbLdrLabelOperand, OpNo); " b"add_cs_detail(MI, ARCH_OP_GROUP_ThumbLdrLabelOperand, OpNo); "
b"int i = OpNo; " b"int i = OpNo; "
b"}", b"}",
@ -132,8 +133,8 @@ class TestPatches(unittest.TestCase):
def test_assert(self): def test_assert(self):
patch = Assert(0) patch = Assert(0)
syntax = b"assert(0 == 0)" syntax = b"assert(0 == 0);"
self.check_patching_result(patch, syntax, b"CS_ASSERT((0 == 0));") self.check_patching_result(patch, syntax, b"CS_ASSERT(0 == 0);")
def test_bitcaststdarray(self): def test_bitcaststdarray(self):
patch = BitCastStdArray(0) patch = BitCastStdArray(0)

View File

@ -14,7 +14,8 @@
"AArch64InstPrinter.cpp", "AArch64InstPrinter.cpp",
"LoongArchInstPrinter.cpp", "LoongArchInstPrinter.cpp",
"MipsInstPrinter.cpp", "MipsInstPrinter.cpp",
"SystemZInstPrinter.cpp" "SystemZInstPrinter.cpp",
"XtensaInstPrinter.cpp"
] ]
}, },
"InlineToStaticInline": { "InlineToStaticInline": {
@ -242,5 +243,23 @@
], ],
"templates_with_arg_deduction": [], "templates_with_arg_deduction": [],
"manually_edited_files": [] "manually_edited_files": []
},
"Xtensa": {
"files_to_translate": [
{
"in": "{LLVM_ROOT}/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp",
"out": "XtensaDisassembler.c"
},
{
"in": "{LLVM_ROOT}/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp",
"out": "XtensaInstPrinter.c"
}
],
"files_for_template_search": [
"{CPP_INC_OUT_DIR}/XtensaGenDisassemblerTables.inc",
"{CPP_INC_OUT_DIR}/XtensaGenAsmWriter.inc"
],
"templates_with_arg_deduction": [],
"manually_edited_files": []
} }
} }

View File

@ -36,6 +36,8 @@ class AddCSDetail(Patch):
b"(MCInst*MI,unsignedOpNo,SStream*O,constchar*Modifier)", # PPC - printPredicateOperand b"(MCInst*MI,unsignedOpNo,SStream*O,constchar*Modifier)", # PPC - printPredicateOperand
b"(MCInst*MI,uint64_tAddress,unsignedOpNo,SStream*O)", # PPC - printBranchOperand b"(MCInst*MI,uint64_tAddress,unsignedOpNo,SStream*O)", # PPC - printBranchOperand
b"(MCInst*MI,intOpNum,SStream*O)", # SystemZ b"(MCInst*MI,intOpNum,SStream*O)", # SystemZ
b"(MCInst*MI,intOpNum,SStream*O)", # Xtensa printOperand parameters.
b"(MCInst*MI,intOpNum,SStream*OS)", # Xtensa printOperand parameters.
] ]
def __init__(self, priority: int, arch: str): def __init__(self, priority: int, arch: str):
@ -71,7 +73,14 @@ class AddCSDetail(Patch):
comp = captures[3][0] comp = captures[3][0]
comp = get_text(src, comp.start_byte, comp.end_byte) comp = get_text(src, comp.start_byte, comp.end_byte)
return b"void " + fcn_id + params + b"{ " + add_cs_detail + comp.strip(b"{") return (
b"static inline void "
+ fcn_id
+ params
+ b"{ "
+ add_cs_detail
+ comp.strip(b"{")
)
def get_add_cs_detail( def get_add_cs_detail(
self, src: bytes, fcn_def: Node, fcn_id: bytes, params: bytes self, src: bytes, fcn_def: Node, fcn_id: bytes, params: bytes
@ -79,6 +88,8 @@ class AddCSDetail(Patch):
op_group_enum = ( op_group_enum = (
self.arch.encode("utf8") + b"_OP_GROUP_" + fcn_id[5:] self.arch.encode("utf8") + b"_OP_GROUP_" + fcn_id[5:]
) # Remove "print" from function id ) # Remove "print" from function id
if self.arch == "Xtensa":
op_group_enum = op_group_enum.upper()
is_template = fcn_def.prev_sibling.type == "template_parameter_list" is_template = fcn_def.prev_sibling.type == "template_parameter_list"
if b"OpNum" in params: if b"OpNum" in params:

View File

@ -5,11 +5,12 @@ from tree_sitter import Node
from autosync.cpptranslator.patches.Helper import get_text from autosync.cpptranslator.patches.Helper import get_text
from autosync.cpptranslator.patches.Patch import Patch from autosync.cpptranslator.patches.Patch import Patch
from autosync.cpptranslator.patches.Helper import get_text_from_node
class Assert(Patch): class Assert(Patch):
""" """
Patch Remove asserts Patch replace `assert`|`report_fatal_error` with `CS_ASSERT`
""" """
def __init__(self, priority: int): def __init__(self, priority: int):
@ -19,7 +20,7 @@ class Assert(Patch):
return ( return (
"(expression_statement" "(expression_statement"
" (call_expression" " (call_expression"
' ((identifier) @id (#eq? @id "assert"))' ' ((identifier) @id (#match? @id "assert|report_fatal_error"))'
" ((argument_list) @arg_list)" " ((argument_list) @arg_list)"
" )" " )"
") @assert" ") @assert"
@ -28,9 +29,6 @@ class Assert(Patch):
def get_main_capture_name(self) -> str: def get_main_capture_name(self) -> str:
return "assert" return "assert"
def get_patch( def get_patch(self, captures: [(Node, str)], src: bytes, **kwargs) -> bytes:
self, captures: list[tuple[Node, str]], src: bytes, **kwargs args = get_text_from_node(src, captures[2][0])
) -> bytes: return b"CS_ASSERT" + args + b";"
arg_list = captures[2][0]
args = get_text(src, arg_list.start_byte, arg_list.end_byte)
return b"CS_ASSERT(" + args + b");"

View File

@ -12,7 +12,7 @@ class GetOperandRegImm(Patch):
Patch OPERAND.getReg() Patch OPERAND.getReg()
to MCOperand_getReg(OPERAND) to MCOperand_getReg(OPERAND)
Same for isImm() Same for getImm()|getExpr
""" """
def __init__(self, priority: int): def __init__(self, priority: int):

View File

@ -88,6 +88,10 @@ def get_text(src: bytes, start_byte: int, end_byte: int) -> bytes:
return src[start_byte:end_byte] return src[start_byte:end_byte]
def get_text_from_node(src: bytes, node: Node) -> bytes:
return src[node.start_byte : node.end_byte]
def namespace_enum(src: bytes, ns_id: bytes, enum: Node) -> bytes: def namespace_enum(src: bytes, ns_id: bytes, enum: Node) -> bytes:
""" """
Alters an enum in the way that it prepends the namespace id to every enum member. Alters an enum in the way that it prepends the namespace id to every enum member.

View File

@ -68,6 +68,8 @@ class Includes(Patch):
return res + get_Mips_includes(filename) + get_general_macros() return res + get_Mips_includes(filename) + get_general_macros()
case "SystemZ": case "SystemZ":
return res + get_SystemZ_includes(filename) + get_general_macros() return res + get_SystemZ_includes(filename) + get_general_macros()
case "Xtensa":
return res + get_Xtensa_includes(filename) + get_general_macros()
case "TEST_ARCH": case "TEST_ARCH":
return res + b"test_output" return res + b"test_output"
case _: case _:
@ -388,6 +390,32 @@ def get_SystemZ_includes(filename: str) -> bytes:
exit(1) exit(1)
def get_Xtensa_includes(filename: str) -> bytes:
match filename:
case "XtensaDisassembler.cpp":
return b"""
#include "../../MathExtras.h"
#include "../../MCDisassembler.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../SStream.h"
#include "../../cs_priv.h"
#include "priv.h"
#define GET_INSTRINFO_MC_DESC
#include "XtensaGenInstrInfo.inc"
"""
case "XtensaInstPrinter.cpp":
return b"""
#include "../../MCInstPrinter.h"
#include "../../SStream.h"
#include "XtensaMapping.h"
#include "priv.h"
"""
case _:
return b""
def get_general_macros(): def get_general_macros():
return ( return (
b"#define CONCAT(a, b) CONCAT_(a, b)\n" b"#define CONCAT_(a, b) a ## _ ## b\n" b"#define CONCAT(a, b) CONCAT_(a, b)\n" b"#define CONCAT_(a, b) a ## _ ## b\n"

View File

@ -12,7 +12,7 @@ class IsOperandRegImm(Patch):
Patch OPERAND.isReg() Patch OPERAND.isReg()
to MCOperand_isReg(OPERAND) to MCOperand_isReg(OPERAND)
Same for isImm() Same for isImm() | isExpr()
""" """
def __init__(self, priority: int): def __init__(self, priority: int):

View File

@ -33,4 +33,8 @@ class QualifiedIdentifier(Patch):
namespace = b"" namespace = b""
identifier = captures[0][0].named_children[0] identifier = captures[0][0].named_children[0]
identifier = get_text(src, identifier.start_byte, identifier.end_byte) identifier = get_text(src, identifier.start_byte, identifier.end_byte)
return namespace + b"_" + identifier match (namespace, identifier):
case (b"std", b"size"):
return b"sizeof"
case _:
return namespace + b"_" + identifier

View File

@ -3,7 +3,7 @@
from tree_sitter import Node from tree_sitter import Node
from autosync.cpptranslator.patches.Helper import get_text from autosync.cpptranslator.patches.Helper import get_text, get_text_from_node
from autosync.cpptranslator.patches.Patch import Patch from autosync.cpptranslator.patches.Patch import Patch
@ -105,6 +105,37 @@ class StreamOperations(Patch):
+ last_op_text.replace(b"'", b'"') + last_op_text.replace(b"'", b'"')
+ b");\n" + b");\n"
) )
elif last_op.type == "identifier":
queue_str = f"""
(declaration (
(primitive_type) @typ
(init_declarator
(identifier) @ident (#eq? @ident "{last_op_text.decode('utf8')}")
)
)) @decl
"""
query = kwargs["ts_cpp_lang"].query(queue_str)
root_node = kwargs["tree"].root_node
query_result = list(
filter(
lambda x: "typ" in x[1],
query.matches(root_node, end_byte=last_op.start_byte),
)
)
if len(query_result) == 0:
res += b"SStream_concat0(" + s_name + b", " + last_op_text + b");"
else:
cap = query_result[-1]
typ = get_text_from_node(src, cap[1]["typ"])
match typ:
case b"int":
res += b"printInt32(" + s_name + b", " + last_op_text + b");"
case b"int64_t":
res += b"printInt64(" + s_name + b", " + last_op_text + b");"
case _:
res += (
b"SStream_concat0(" + s_name + b", " + last_op_text + b");"
)
else: else:
res += b"SStream_concat0(" + s_name + b", " + last_op_text + b");" res += b"SStream_concat0(" + s_name + b", " + last_op_text + b");"
stream = captures[0][0] stream = captures[0][0]

View File

@ -3290,5 +3290,179 @@
"new_hash": "", "new_hash": "",
"edit": "" "edit": ""
} }
},
"XtensaDisassembler.c": {
"\"../../SStream.h\"": {
"apply_type": "OLD",
"old_hash": "2b45d68382f855f8fdc8a7cf177cda2d4dee75318bab9e1304026375ba05284f",
"new_hash": "",
"edit": ""
},
"\"../../cs_priv.h\"": {
"apply_type": "OLD",
"old_hash": "9cf77913cc1ba047983eb15f5e6dce657fb26b09f32757f02de5df2cf4023d87",
"new_hash": "",
"edit": ""
},
"\"XtensaGenInstrInfo.inc\"": {
"apply_type": "OLD",
"old_hash": "7dada799dde9a9ea873fe6933799f19a60273bd85d56804c06e7e87b761c973d",
"new_hash": "",
"edit": ""
},
"\"priv.h\"": {
"apply_type": "OLD",
"old_hash": "d09344b441eba2a943ba1323088ec14a8bad410b94e47900e170c51876794892",
"new_hash": "",
"edit": ""
},
"DecodeSRRegisterClass": {
"apply_type": "OLD",
"old_hash": "21ddebca1aac12b568bfba25e971d02c3166147ff2ba8308e7f95e07bc754e28",
"new_hash": "0bfba6491089483244f115b4130ebe5c03d5572c8267bf015f704bb5fd1526a7",
"edit": ""
},
"Xtensa_LLVM_getInstruction": {
"apply_type": "OLD",
"old_hash": "f62a9a80e3667fa51669fe7fa22da87b1c95bb1235e0840e5455069731ca42d1",
"new_hash": "",
"edit": ""
},
"getInstruction": {
"apply_type": "OLD",
"old_hash": "50b6a904fc89bab054302112bd312dff8befdca7e0fdeebbfdc5d37cb49a2eeb",
"new_hash": "9215f65202a5f06de4718f9562adc149b5271358b49ce03be887dde2fdf03a25",
"edit": ""
},
"readInstruction24": {
"apply_type": "OLD",
"old_hash": "496be4020feedac98bcb88b969c1e9a2013f664120193b45b76ff4a683e12d0d",
"new_hash": "2c39773dba873ff597df8420c2a710ecd3604ecb232406dc8b2f20bc3a11e655",
"edit": ""
},
"tryAddingSymbolicOperand": {
"apply_type": "OLD",
"old_hash": "abfdc1e7fb69748a05a49a9829618b7ff43e913c7a46476c5a5e69151e44872c",
"new_hash": "b1a20345c1f90c2ef792825a3ecd379a856dca51240a92c3b9ce3a3685f09e2a",
"edit": ""
}
},
"XtensaInstPrinter.c": {
"\"../../MCInstPrinter.h\"": {
"apply_type": "OLD",
"old_hash": "ea06257675896d185a423f8471328a8b98e74c260aad3e2e614d0ef48a744004",
"new_hash": "",
"edit": ""
},
"\"../../Mapping.h\"": {
"apply_type": "OLD",
"old_hash": "204ac68dcb32024c325b99a0843719c321ab57c60c41b12adbea497c20b7d436",
"new_hash": "",
"edit": ""
},
"\"../../SStream.h\"": {
"apply_type": "OLD",
"old_hash": "2b45d68382f855f8fdc8a7cf177cda2d4dee75318bab9e1304026375ba05284f",
"new_hash": "",
"edit": ""
},
"\"./priv.h\"": {
"apply_type": "OLD",
"old_hash": "f5f8c480fe3869886ac96a2b8b2567c6056d7a0054da06433dee8e916abbe752",
"new_hash": "",
"edit": ""
},
"\"XtensaMapping.h\"": {
"apply_type": "OLD",
"old_hash": "5dc6afd5c4beb43ecf77407bd50c579ace7cc07013610ee1e72933981da27ee2",
"new_hash": "",
"edit": ""
},
"Xtensa_LLVM_getRegisterName": {
"apply_type": "OLD",
"old_hash": "87e2ae763d6d60ffd9da21d1b70f147c552cb75960b11ae98b8b21fe58bb938c",
"new_hash": "",
"edit": ""
},
"Xtensa_LLVM_printInstruction": {
"apply_type": "OLD",
"old_hash": "1407d0fd0871a19025128731e3438bbff398ff173720e14f58cc1dbc781e5d51",
"new_hash": "",
"edit": ""
},
"printBranchTarget": {
"apply_type": "NEW",
"old_hash": "c91f9d98415c1c413489ef360bc11ebb11b6f9e3b1564d4b57d0577c0a6feaa8",
"new_hash": "760223784267d403ac29f9ed51c2a30ff2ef1ddf9679b59db71b741f23c03719",
"edit": ""
},
"printCallOperand": {
"apply_type": "NEW",
"old_hash": "62f875bf3eae5d3502f03df40ff473ddd838e38c87711a1fb5922d41960e74ed",
"new_hash": "5e936d44076c6ab4dfb8bf579b368f7107954dd391ea5f82d489afbe26184985",
"edit": ""
},
"printImm12m_AsmOperand": {
"apply_type": "NEW",
"old_hash": "a656e5282b4444835dc20ffb645e92c51b5512ed43aabb7c9f2eafa1d2c81a76",
"new_hash": "64a9511d7f18e2fce3b4d08179b8cb6681d1e5df195241706a30d00c3ea2288e",
"edit": ""
},
"printImm1_16_AsmOperand": {
"apply_type": "NEW",
"old_hash": "4a34c1913614bdaee2795f1c94d395b78be60f4d1ae84a0f28ea0e8a573381f9",
"new_hash": "c9956b1881ed5107439d2e4606cec93870837a3390436264a6e0c66762b68a5c",
"edit": ""
},
"printImm8_sh8_AsmOperand": {
"apply_type": "NEW",
"old_hash": "9affee556485b99036667d0fde115610b9b67037c5ffdfedf9f5eb379b89c146",
"new_hash": "e4ab93bab36ba4c3436618523e3ff14b330819652e4cada4f19001ad63e92560",
"edit": ""
},
"printJumpTarget": {
"apply_type": "NEW",
"old_hash": "b3fb61b967ddbdcd4ba31c0d7f6cbdb5b52880eba2d0f3b6961cb8736d65e6e0",
"new_hash": "0810cb753da2c503ec8cf969c4fa7bfb9f47fd6a9d66a83eb2c8b0166489512f",
"edit": ""
},
"printL32RTarget": {
"apply_type": "NEW",
"old_hash": "518eb907a827efe2ae569b32ec9acfda29bd106c28f53a997fa40233c84f5433",
"new_hash": "66fcd5c6ce5d625014bffc3c23bdab57a78b467dabfe3bdcb5d67af2cdfc8192",
"edit": ""
},
"printOperand": {
"apply_type": "OLD",
"old_hash": "1c19f6735e6c56ef62a9ce8eabe0a2f50e530fc6efb505b30de99a28b8299f6c",
"new_hash": "",
"edit": ""
},
"printShimm1_31_AsmOperand": {
"apply_type": "NEW",
"old_hash": "a87790f5ac96dd626e1ae77a2949ff6ca9f3ac042b4ec87069b5b20e5bc43ba6",
"new_hash": "0a881b7568ff8a62cbf47caef513cabd32928af5cd182584da59a9be618b6c2e",
"edit": ""
},
"printUimm4_AsmOperand": {
"apply_type": "NEW",
"old_hash": "d8dbc1a930c08cbb2047c4462f6102ce7a9dc516754ee06d69ed88ceb3624c64",
"new_hash": "3ba7c11490ec5eacc67595df5d26db88c4db327dc12c06f91349a29b3a31320c",
"edit": ""
},
"printUimm5_AsmOperand": {
"apply_type": "NEW",
"old_hash": "0c4dd11b6282b42f5e08458fe206ef5f34e738626f5dbf57521355f96dd820a4",
"new_hash": "5c8fe6e58c1463f1556d33c60896696340eb444e5938270d5e23c9df6a1ab4e8",
"edit": ""
}
},
"XtensaInstPrinter.h": {
"\"priv.h\"": {
"apply_type": "OLD",
"old_hash": "d09344b441eba2a943ba1323088ec14a8bad410b94e47900e170c51876794892",
"new_hash": "",
"edit": ""
}
} }
} }

View File

@ -82,6 +82,9 @@ int main()
if (cs_support(CS_ARCH_LOONGARCH)) { if (cs_support(CS_ARCH_LOONGARCH)) {
printf("loongarch=1 "); printf("loongarch=1 ");
} }
if (cs_support(CS_ARCH_XTENSA)) {
printf("xtensa=1 ");
}
printf("\n"); printf("\n");
return 0; return 0;

View File

@ -26,7 +26,7 @@ ExternalProject_Add(libcyaml_ext
URL_HASH SHA256=8dbd216e1fce90f9f7cca341e5178710adc76ee360a7793ef867edb28f3e4130 URL_HASH SHA256=8dbd216e1fce90f9f7cca341e5178710adc76ee360a7793ef867edb28f3e4130
DOWNLOAD_EXTRACT_TIMESTAMP true DOWNLOAD_EXTRACT_TIMESTAMP true
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} PKG_CONFIG=pkg-config
BUILD_IN_SOURCE true BUILD_IN_SOURCE true
INSTALL_COMMAND "" INSTALL_COMMAND ""
) )
@ -45,8 +45,8 @@ add_executable(cstest ${CSTEST_SRC})
add_library(libcstest STATIC ${CSTEST_SRC}) add_library(libcstest STATIC ${CSTEST_SRC})
add_dependencies(cstest cmocka_ext) add_dependencies(cstest cmocka_ext)
add_dependencies(cstest libcyaml_ext) add_dependencies(cstest libcyaml_ext)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml yaml) target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml yaml) target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_include_directories(cstest PRIVATE target_include_directories(cstest PRIVATE
${PROJECT_SOURCE_DIR}/include> ${PROJECT_SOURCE_DIR}/include>
${CSTEST_INCLUDE_DIR} ${CSTEST_INCLUDE_DIR}

View File

@ -37,6 +37,7 @@ static const cs_enum_id_map test_arch_map[] = {
{ .str = "CS_ARCH_WASM", .val = CS_ARCH_WASM }, { .str = "CS_ARCH_WASM", .val = CS_ARCH_WASM },
{ .str = "CS_ARCH_X86", .val = CS_ARCH_X86 }, { .str = "CS_ARCH_X86", .val = CS_ARCH_X86 },
{ .str = "CS_ARCH_XCORE", .val = CS_ARCH_XCORE }, { .str = "CS_ARCH_XCORE", .val = CS_ARCH_XCORE },
{ .str = "CS_ARCH_XTENSA", .val = CS_ARCH_XTENSA },
{ .str = "aarch64", .val = CS_ARCH_AARCH64 }, { .str = "aarch64", .val = CS_ARCH_AARCH64 },
{ .str = "alpha", .val = CS_ARCH_ALPHA }, { .str = "alpha", .val = CS_ARCH_ALPHA },
{ .str = "arm", .val = CS_ARCH_ARM }, { .str = "arm", .val = CS_ARCH_ARM },
@ -58,6 +59,7 @@ static const cs_enum_id_map test_arch_map[] = {
{ .str = "wasm", .val = CS_ARCH_WASM }, { .str = "wasm", .val = CS_ARCH_WASM },
{ .str = "x86", .val = CS_ARCH_X86 }, { .str = "x86", .val = CS_ARCH_X86 },
{ .str = "xcore", .val = CS_ARCH_XCORE }, { .str = "xcore", .val = CS_ARCH_XCORE },
{ .str = "xtensa", .val = CS_ARCH_XTENSA },
}; };
/// REMEMBER TO SORT AFTER EDIT /// REMEMBER TO SORT AFTER EDIT
@ -167,6 +169,7 @@ static const cs_enum_id_map test_mode_map[] = {
{ .str = "CS_MODE_TRICORE_162", .val = CS_MODE_TRICORE_162 }, { .str = "CS_MODE_TRICORE_162", .val = CS_MODE_TRICORE_162 },
{ .str = "CS_MODE_V8", .val = CS_MODE_V8 }, { .str = "CS_MODE_V8", .val = CS_MODE_V8 },
{ .str = "CS_MODE_V9", .val = CS_MODE_V9 }, { .str = "CS_MODE_V9", .val = CS_MODE_V9 },
{ .str = "CS_MODE_XTENSA", .val = CS_MODE_XTENSA },
}; };
static const TestOptionMapEntry test_option_map[] = { static const TestOptionMapEntry test_option_map[] = {

View File

@ -123,7 +123,8 @@ static bool parse_input_options(const TestInput *input, cs_arch *arch,
fprintf(stderr, fprintf(stderr,
"Too many options given in: '%s'. Maximum is: %" PRId64 "Too many options given in: '%s'. Maximum is: %" PRId64
"\n", "\n",
opt_str, opt_arr_size); opt_str,
(uint64_t)opt_arr_size);
return false; return false;
} }
opt_arr[opt_idx++] = test_option_map[k].opt; opt_arr[opt_idx++] = test_option_map[k].opt;

View File

@ -90,8 +90,12 @@ int main(int argc, char** argv)
} else if (strcmp(arch, "CS_ARCH_M680X") == 0 && strcmp(mode, "CS_MODE_M680X_6809") == 0) { } else if (strcmp(arch, "CS_ARCH_M680X") == 0 && strcmp(mode, "CS_MODE_M680X_6809") == 0) {
Data[0] = 24; Data[0] = 24;
} else if (strcmp(arch, "CS_ARCH_EVM") == 0 && strcmp(mode, "0") == 0) { } else if (strcmp(arch, "CS_ARCH_EVM") == 0 && strcmp(mode, "0") == 0) {
Data[0] = 25; Data[0] = 25;
} else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) { } else if (strcmp(arch, "CS_ARCH_XTENSA") == 0 && strcmp(mode, "CS_MODE_XTENSA") == 0) {
Data[0] = 26;
} else if (strcmp(arch, "CS_ARCH_XTENSA") == 0 && strcmp(mode, "CS_MODE_XTENSA+CS_MODE_BIG_ENDIAN") == 0) {
Data[0] = 27;
} else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) {
Data[0] = 29; Data[0] = 29;
} else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_EXTENDED") != NULL) { } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_EXTENDED") != NULL) {
Data[0] = 30; Data[0] = 30;

View File

@ -172,6 +172,18 @@ struct platform platforms[] = {
(cs_mode)0, (cs_mode)0,
"EVM" "EVM"
}, },
{
//item 26
CS_ARCH_XTENSA,
(cs_mode)CS_MODE_XTENSA,
"Xtensa"
},
{
//item 27
CS_ARCH_XTENSA,
(cs_mode)CS_MODE_XTENSA + CS_MODE_BIG_ENDIAN,
"Xtensa (Big-Endian)"
},
}; };
void LLVMFuzzerInit(); void LLVMFuzzerInit();

View File

@ -117,6 +117,16 @@ int main(int argc, char **argv)
(cs_mode)CS_MODE_M680X_6809, (cs_mode)CS_MODE_M680X_6809,
"M680X_M6809" "M680X_M6809"
}, },
{
CS_ARCH_XTENSA,
(cs_mode)CS_MODE_XTENSA,
"Xtensa"
},
{
CS_ARCH_XTENSA,
(cs_mode)CS_MODE_XTENSA + CS_MODE_BIG_ENDIAN,
"Xtensa (Big-Endian)"
},
}; };
// Read input // Read input

View File

@ -379,8 +379,19 @@ struct platform platforms[] = {
"TRICORE", "TRICORE",
"tc162" "tc162"
}, },
{
// dummy entry to mark the end of this array. CS_ARCH_XTENSA,
CS_MODE_XTENSA,
"XTENSA",
"xtensa"
},
{
CS_ARCH_XTENSA,
CS_MODE_XTENSA + CS_MODE_BIG_ENDIAN,
"XTENSA (Big-Endian)",
"xtensabe"
},
// dummy entry to mark the end of this array.
// DO NOT DELETE THIS // DO NOT DELETE THIS
{ {
0, 0,

View File

@ -0,0 +1,159 @@
test_cases:
-
input:
bytes: [ 0x60, 0x51, 0x60 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "abs a5, a6"
-
input:
bytes: [ 0x40, 0x39, 0x80 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "add a3, a9, a4"
-
input:
bytes: [ 0x10, 0xf9, 0x80 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "add a15, a9, a1"
-
input:
bytes: [ 0x82, 0xc1, 0x80 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "addi a8, a1, -128"
-
input:
bytes: [ 0x82, 0xc1, 0xf4 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "addi a8, a1, -12"
-
input:
bytes: [ 0x12, 0xd2, 0x7f ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
- asm_text: "addmi a1, a2, 0"
-
input:
bytes: [ 0x50, 0x21, 0x90 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "addx2 a2, a1, a5"
-
input:
bytes: [ 0x60, 0x31, 0xa0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "addx4 a3, a1, a6"
-
input:
bytes: [ 0x70, 0x41, 0xb0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "addx8 a4, a1, a7"
-
input:
bytes: [ 0x30, 0x10, 0x60 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "neg a1, a3"
-
input:
bytes: [ 0x60, 0x45, 0x20 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "or a4, a5, a6"
-
input:
bytes: [ 0x10, 0x82, 0xc0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "sub a8, a2, a1"
-
input:
bytes: [ 0x50, 0x21, 0xd0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "subx2 a2, a1, a5"
-
input:
bytes: [ 0x60, 0x31, 0xe0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "subx4 a3, a1, a6"
-
input:
bytes: [ 0x70, 0x41, 0xf0 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "subx8 a4, a1, a7"
-
input:
bytes: [ 0x50, 0x64, 0x30 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "xor a6, a4, a5"

View File

@ -0,0 +1,30 @@
test_cases:
-
input:
bytes: [ 0xc0, 0x01, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "callx0 a1"
-
input:
bytes: [ 0xa0, 0x02, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "jx a2"
-
input:
bytes: [ 0x80, 0x00, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "ret"

View File

@ -0,0 +1,20 @@
test_cases:
-
input:
bytes: [ 0xd0, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "extw"
-
input:
bytes: [ 0xc0, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "memw"

View File

@ -0,0 +1,70 @@
test_cases:
-
input:
bytes: [ 0x22, 0x01, 0x03 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "l8ui a2, a1, 3"
-
input:
bytes: [ 0x32, 0x91, 0x02 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "l16si a3, a1, 4"
-
input:
bytes: [ 0x42, 0x11, 0x03 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "l16ui a4, a1, 6"
-
input:
bytes: [ 0x52, 0x21, 0x02 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "l32i a5, a1, 8"
-
input:
bytes: [ 0x22, 0x41, 0x03 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "s8i a2, a1, 3"
-
input:
bytes: [ 0x32, 0x51, 0x02 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "s16i a3, a1, 4"
-
input:
bytes: [ 0x52, 0x61, 0x02 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "s32i a5, a1, 8"

View File

@ -0,0 +1,50 @@
test_cases:
-
input:
bytes: [ 0x40, 0x23, 0x83 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "moveqz a2, a3, a4"
-
input:
bytes: [ 0xc0, 0x3b, 0xb3 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "movgez a3, a11, a12"
-
input:
bytes: [ 0x12, 0xa8, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "movi a1, -2048"
-
input:
bytes: [ 0x90, 0x78, 0xa3 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "movltz a7, a8, a9"
-
input:
bytes: [ 0xc0, 0xab, 0x93 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "movnez a10, a11, a12"

View File

@ -0,0 +1,80 @@
test_cases:
-
input:
bytes: [ 0x30, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "dsync"
-
input:
bytes: [ 0x20, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "esync"
-
input:
bytes: [ 0x00, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "isync"
-
input:
bytes: [ 0xf0, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "nop"
-
input:
bytes: [ 0x80, 0x03, 0x03 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "rsr a8, sar"
-
input:
bytes: [ 0x10, 0x20, 0x00 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "rsync"
-
input:
bytes: [ 0x80, 0x03, 0x13 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "wsr a8, sar"
-
input:
bytes: [ 0x80, 0x03, 0x61 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "xsr a8, sar"

View File

@ -0,0 +1,120 @@
test_cases:
-
input:
bytes: [ 0x20, 0x17, 0x74 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "extui a1, a2, 7, 8"
-
input:
bytes: [ 0x00, 0xab, 0xa1 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "sll a10, a11"
-
input:
bytes: [ 0x10, 0x51, 0x11 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "slli a5, a1, 15"
-
input:
bytes: [ 0x30, 0xc0, 0xb1 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "sra a12, a3"
-
input:
bytes: [ 0x50, 0x80, 0x21 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "srai a8, a5, 0"
-
input:
bytes: [ 0x50, 0x34, 0x81 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "src a3, a4, a5"
-
input:
bytes: [ 0x70, 0x60, 0x91 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "srl a6, a7"
-
input:
bytes: [ 0x40, 0x38, 0x41 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "srli a3, a4, 8"
-
input:
bytes: [ 0x00, 0x2e, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "ssa8l a14"
-
input:
bytes: [ 0x10, 0x4f, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "ssai 31"
-
input:
bytes: [ 0x00, 0x10, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "ssl a0"
-
input:
bytes: [ 0x00, 0x02, 0x40 ]
arch: "CS_ARCH_XTENSA"
options: [ "xtensa" ]
expected:
insns:
-
asm_text: "ssr a2"

View File

@ -32,3 +32,11 @@ add_test(NAME integration_compat_headers
COMMAND compat_header_build_test COMMAND compat_header_build_test
WORKING_DIRECTORY ${COMPAT_C_TEST_DIR} WORKING_DIRECTORY ${COMPAT_C_TEST_DIR}
) )
set(INTEGRATION_TEST_SRC test_litbase.c)
foreach(TSRC ${INTEGRATION_TEST_SRC})
string(REGEX REPLACE ".c$" "" TBIN ${TSRC})
add_executable(${TBIN} "${TESTS_INTEGRATION_DIR}/${TSRC}")
target_link_libraries(${TBIN} PRIVATE capstone)
add_test(NAME "integration_${TBIN}" COMMAND ${TBIN})
endforeach()

View File

@ -0,0 +1,90 @@
// This sample code demonstrates the option CS_OPT_LITBASE
#include <stdio.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include <capstone/capstone.h>
#define DATA "\x11\x00\x00\x11\xff\xff"
static void print_string_hex(unsigned char *str, size_t len)
{
unsigned char *c;
for (c = str; c < str + len; c++) {
printf("%02x ", *c & 0xff);
}
printf("\t");
}
static void print_insn(cs_insn *insn, size_t count)
{
if (count) {
for (int i = 0; i < count; ++i) {
print_string_hex((unsigned char *)DATA,
sizeof(DATA) - 1);
printf("\t%s\t%s\n", insn[i].mnemonic, insn[i].op_str);
}
// Free memory allocated by cs_disasm()
cs_free(insn, count);
} else {
printf("ERROR: Failed to disasm given code!\n");
abort();
}
}
static void check_insn(cs_insn *insn, const char *mnemonic, const char *op_str)
{
assert(strcmp(insn[0].mnemonic, mnemonic) == 0);
assert(strcmp(insn[0].op_str, op_str) == 0);
}
static void test()
{
csh handle;
cs_err err;
err = cs_open(CS_ARCH_XTENSA, CS_MODE_XTENSA, &handle);
if (err) {
if (cs_support(CS_ARCH_XTENSA)) {
printf("Failed on cs_open() with error returned: %u\n",
err);
abort();
} else
return;
}
cs_insn *insn = NULL;
size_t count = 0;
count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1,
0x10000, 2, &insn);
// 1. Print out the instruction in default setup.
printf("Disassemble xtensa code with PC=0x10000\n");
check_insn(insn, "l32r", "a1, . 0xc000");
check_insn(insn + 1, "l32r", "a1, . 0x10000");
print_insn(insn, count);
// Customized mnemonic JNE to JNZ using CS_OPT_LITBASE option
printf("\nNow customize engine to change LITBASA to 0xff001\n");
cs_option(handle, CS_OPT_LITBASE, (size_t)0xff001);
count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1,
0x10000, 2, &insn);
// 2. Now print out the instruction in newly customized setup.
check_insn(insn, "l32r", "a1, . -0x3fff");
check_insn(insn + 1, "l32r", "a1, . -3");
print_insn(insn, count);
// Done
cs_close(&handle);
}
int main()
{
test();
return 0;
}

29
tests/issues/fuzzing.yaml Normal file
View File

@ -0,0 +1,29 @@
test_cases:
-
input:
name: "OOB read should be 2 bytes"
bytes: [ 0x00 ]
arch: "CS_ARCH_SYSTEMZ"
options: [ CS_MODE_BIG_ENDIAN ]
address: 0x0
expected:
insns: []
-
input:
name: "OOB read should be 4 bytes"
bytes: [ 0xb0, 0xff ]
arch: "CS_ARCH_SYSTEMZ"
options: [ CS_MODE_BIG_ENDIAN ]
address: 0x0
expected:
insns: []
-
input:
name: "OOB read should be 6 bytes"
bytes: [ 0xc0, 0xff, 0xff ]
arch: "CS_ARCH_SYSTEMZ"
options: [ CS_MODE_BIG_ENDIAN ]
address: 0x0
expected:
insns: []

14
utils.c
View File

@ -146,6 +146,20 @@ uint32_t readBytes32(MCInst *MI, const uint8_t *Bytes)
return Insn; return Insn;
} }
/// Reads 3 bytes in the endian order specified in MI->cs->mode.
uint32_t readBytes24(MCInst *MI, const uint8_t *Bytes)
{
assert(MI && Bytes);
uint32_t Insn;
if (MODE_IS_BIG_ENDIAN(MI->csh->mode))
Insn = (Bytes[2]) | (Bytes[1] << 8) |
((uint32_t)Bytes[0] << 16);
else
Insn = (Bytes[2] << 16) | (Bytes[1] << 8) |
((uint32_t)Bytes[0]);
return Insn;
}
/// Reads 2 bytes in the endian order specified in MI->cs->mode. /// Reads 2 bytes in the endian order specified in MI->cs->mode.
uint16_t readBytes16(MCInst *MI, const uint8_t *Bytes) uint16_t readBytes16(MCInst *MI, const uint8_t *Bytes)
{ {

View File

@ -39,6 +39,7 @@ bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id);
bool arr_exist_int(int *table, size_t table_size, int id); bool arr_exist_int(int *table, size_t table_size, int id);
uint16_t readBytes16(MCInst *MI, const uint8_t *Bytes); uint16_t readBytes16(MCInst *MI, const uint8_t *Bytes);
uint32_t readBytes24(MCInst *MI, const uint8_t *Bytes);
uint32_t readBytes32(MCInst *MI, const uint8_t *Bytes); uint32_t readBytes32(MCInst *MI, const uint8_t *Bytes);
uint64_t readBytes48(MCInst *MI, const uint8_t *Bytes); uint64_t readBytes48(MCInst *MI, const uint8_t *Bytes);
uint64_t readBytes64(MCInst *MI, const uint8_t *Bytes); uint64_t readBytes64(MCInst *MI, const uint8_t *Bytes);