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 Mips -s IncGen
./src/autosync/ASUpdater.py -d -a SystemZ -s IncGen
./src/autosync/ASUpdater.py -d -a Xtensa -s IncGen
- name: CppTranslator - Patch tests
run: |
@ -96,3 +97,4 @@ jobs:
./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 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")
endif()
set(BUILD_RPATH_USE_ORIGIN true)
# Detect whether capstone is compiled as top-level or a subdirectory
set(PROJECT_IS_TOP_LEVEL OFF)
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")
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_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_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 Xtensa)
# If building for OSX it's best to allow CMake to handle building both architectures
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
@ -211,6 +213,7 @@ set(HEADERS_COMMON
include/capstone/alpha.h
include/capstone/hppa.h
include/capstone/loongarch.h
include/capstone/xtensa.h
)
## architecture support
@ -680,6 +683,22 @@ if (CAPSTONE_LOONGARCH_SUPPORT)
)
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)
add_definitions(-DCAPSTONE_HAS_OSXKERNEL)
endif()
@ -707,6 +726,7 @@ set(ALL_SOURCES
${SOURCES_ALPHA}
${SOURCES_HPPA}
${SOURCES_LOONGARCH}
${SOURCES_XTENSA}
)
set(ALL_HEADERS
@ -733,6 +753,7 @@ set(ALL_HEADERS
${HEADERS_ALPHA}
${HEADERS_HPPA}
${HEADERS_LOONGARCH}
${HEADERS_XTENSA}
)
## properties
@ -785,6 +806,7 @@ source_group("Source\\TriCore" FILES ${SOURCES_TRICORE})
source_group("Source\\Alpha" FILES ${SOURCES_ALPHA})
source_group("Source\\HPPA" FILES ${SOURCES_HPPA})
source_group("Source\\LoongArch" FILES ${SOURCES_LOONGARCH})
source_group("Source\\Xtensa" FILES ${SOURCES_XTENSA})
source_group("Include\\Common" FILES ${HEADERS_COMMON})
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\\HPPA" FILES ${HEADERS_HPPA})
source_group("Include\\LoongArch" FILES ${HEADERS_LOONGARCH})
source_group("Include\\Xtensa" FILES ${HEADERS_XTENSA})
## installation
if(CAPSTONE_INSTALL)

View File

@ -87,6 +87,7 @@ david942j: BPF (both classic and extended) architecture.
fanfuqiang & citypw & porto703 : RISCV architecture.
Josh "blacktop" Maine: Arm64 architecture improvements.
Finn Wilkinson: AArch64 update to Armv9.2-a (SME + SVE2 support)
Billow & Sidneyp : TriCore architecture.
Billow & Sidneyp: TriCore 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 cs_struct cs_struct;
typedef struct MCOperand MCOperand;
typedef unsigned MCRegister;
typedef void MCExpr;
/// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.

View File

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

View File

@ -355,11 +355,21 @@ ifneq (,$(findstring loongarch,$(CAPSTONE_ARCHS)))
LIBOBJ_LOONGARCH += $(LIBSRC_LOONGARCH:%.c=$(OBJDIR)/%.o)
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 += $(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_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),)
@ -492,6 +502,7 @@ $(LIBOBJ_TRICORE): $(DEP_TRICORE)
$(LIBOBJ_ALPHA): $(DEP_ALPHA)
$(LIBOBJ_HPPA): $(DEP_HPPA)
$(LIBOBJ_LOONGARCH): $(DEP_LOONGARCH)
$(LIBOBJ_XTENSA): $(DEP_XTENSA)
ifeq ($(CAPSTONE_STATIC),yes)
$(ARCHIVE): $(LIBOBJ)

View File

@ -347,6 +347,7 @@ DEFINE_get_detail_op(loongarch, LoongArch);
DEFINE_get_detail_op(mips, Mips);
DEFINE_get_detail_op(riscv, RISCV);
DEFINE_get_detail_op(systemz, SystemZ);
DEFINE_get_detail_op(xtensa, Xtensa);
/// Returns true if for this architecture the
/// 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(riscv, RISCV);
DECL_get_detail_op(systemz, SystemZ);
DECL_get_detail_op(xtensa, Xtensa);
/// Increments the detail->arch.op_count by one.
#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_inc_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.
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(riscv, RISCV);
DEFINE_get_arch_detail(systemz, SystemZ);
DEFINE_get_arch_detail(xtensa, Xtensa);
#define DEFINE_check_safe_inc(Arch, ARCH) \
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)
/// bit width.
//static inline bool isIntN(unsigned N, int64_t x) {
// return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
//}
static inline bool isIntN(unsigned N, int64_t x) {
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
/// 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)
> [!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
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,
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.

View File

@ -381,10 +381,16 @@ static DecodeStatus getInstruction(MCInst *MI, uint16_t *Size, const uint8_t *By
Table = DecoderTable16;
Inst = readBytes16(MI, Bytes);
} else if (Bytes[0] < 0xc0) {
if (BytesLen < 4) {
return MCDisassembler_Fail;
}
*Size = 4;
Table = DecoderTable32;
Inst = readBytes32(MI, Bytes);
} else {
if (BytesLen < 6) {
return MCDisassembler_Fail;
}
*Size = 6;
Table = DecoderTable48;
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/'
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 = {
'java': {
@ -60,6 +62,7 @@ template = {
'alpha.h': ['ALPHA', 'Alpha'],
'hppa.h': 'hppa',
'loongarch.h': 'loongarch',
'xtensa.h': 'xtensa',
'comment_open': '#',
'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_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_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:
@for t in $(TESTS); do \

View File

@ -41,6 +41,7 @@ __all__ = [
'CS_ARCH_ALPHA',
'CS_ARCH_HPPA',
'CS_ARCH_LOONGARCH',
'CS_ARCH_XTENSA',
'CS_ARCH_ALL',
'CS_MODE_LITTLE_ENDIAN',
@ -243,7 +244,7 @@ CS_VERSION_MAJOR = CS_API_MAJOR
CS_VERSION_MINOR = CS_API_MINOR
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
CS_ARCH_ARM = 0
@ -267,7 +268,8 @@ CS_ARCH_TRICORE = 17
CS_ARCH_ALPHA = 18
CS_ARCH_HPPA = 19
CS_ARCH_LOONGARCH = 20
CS_ARCH_MAX = 20
CS_ARCH_XTENSA = 21
CS_ARCH_MAX = 21
CS_ARCH_ALL = 0xFFFF
# 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_W65C02 = (1 << 3) # MOS65XXX WDC W65c02
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_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X
CS_MODE_SH2 = 1 << 1 # SH2
@ -413,8 +415,8 @@ CS_OP_RESERVED_14 = 14
CS_OP_RESERVED_15 = 15
CS_OP_SPECIAL = 0x10 # Special operands from archs
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_IMM = 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 # Memory referencing immediate operand.
# Common instruction groups - to be consistent across all architectures.
CS_GRP_INVALID = 0 # uninitialized/invalid group.
@ -498,6 +500,7 @@ else:
_found = False
def _load_lib(path):
lib_file = join(path, _lib)
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 None
_cs = None
# Loading attempts, in order
@ -542,11 +546,15 @@ def copy_ctypes(src):
ctypes.memmove(ctypes.byref(dst), ctypes.byref(src), ctypes.sizeof(type(src)))
return dst
def copy_ctypes_list(src):
return [copy_ctypes(n) for n in src]
# Weird import placement because these modules are needed by the below code but need the above functions
from . import arm, 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):
_fields_ = (
@ -571,8 +579,10 @@ class _cs_arch(ctypes.Union):
('alpha', alpha.CsAlpha),
('hppa', hppa.CsHPPA),
('loongarch', loongarch.CsLoongArch),
('xtensa', xtensa.CsXtensa),
)
class _cs_detail(ctypes.Structure):
_fields_ = (
('regs_read', ctypes.c_uint16 * 20),
@ -585,6 +595,7 @@ class _cs_detail(ctypes.Structure):
('arch', _cs_arch),
)
class _cs_insn(ctypes.Structure):
_fields_ = (
('id', ctypes.c_uint),
@ -599,8 +610,11 @@ class _cs_insn(ctypes.Structure):
('detail', ctypes.POINTER(_cs_detail)),
)
# 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):
_fields_ = (
@ -609,17 +623,20 @@ class _cs_opt_skipdata(ctypes.Structure):
('user_data', ctypes.c_void_p),
)
class _cs_opt_mnem(ctypes.Structure):
_fields_ = (
('id', ctypes.c_uint),
('mnemonic', ctypes.c_char_p),
)
# setup all the function prototype
def _setup_prototype(lib, fname, restype, *argtypes):
getattr(lib, fname).restype = restype
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_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)))
@ -709,6 +726,7 @@ def cs_disasm_quick(arch, mode, code, offset, count=0):
if status != CS_ERR_OK:
raise CsError(status)
# Another quick, but lighter function to disasm raw binary code.
# This function is faster than cs_disasm_quick() around 20% because
# 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:
raise CsError(status)
def _ascii_name_or_default(name, default):
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:
# save detail
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):
return '<CsInsn 0x%x [%s]: %s %s>' % (self.address, self.bytes.hex(), self.mnemonic, self.op_str)
# return instruction's ID.
@property
def id(self):
@ -864,7 +884,7 @@ class CsInsn(object):
return self._raw.detail.contents.groups[:self._raw.detail.contents.groups_count]
raise CsError(CS_ERR_DETAIL)
# return whether instruction has writeback operands.
@property
def writeback(self):
@ -888,7 +908,7 @@ class CsInsn(object):
arch = self._cs.arch
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.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:
(self.cc, self.update_flags, self.post_index, self.operands) = \
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)
elif arch == CS_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):
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)
# verify if this insn belong to group with id as @group_id
def group(self, group_id):
if self._raw.id == 0:
@ -1053,7 +1073,8 @@ class CsInsn(object):
regs_write = (ctypes.c_uint16 * 64)()
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:
raise CsError(status)
@ -1070,7 +1091,6 @@ class CsInsn(object):
return (regs_read, regs_write)
class Cs(object):
def __init__(self, arch, mode):
# verify version compatibility with the core before doing anything
@ -1113,8 +1133,6 @@ class Cs(object):
self._skipdata_opt = _cs_opt_skipdata()
self._skipdata = False
# destructor to be called automatically when object is destroyed.
def __del__(self):
if self.csh:
@ -1136,25 +1154,21 @@ class Cs(object):
elif opt_type == CS_OPT_UNSIGNED:
self._imm_unsigned = opt_value == CS_OPT_ON
# is this a diet engine?
@property
def diet(self):
return self._diet
# is this engine compiled with X86-reduce option?
@property
def x86_reduce(self):
return self._x86reduce
# return assembly syntax.
@property
def syntax(self):
return self._syntax
# syntax setter: modify assembly syntax.
@syntax.setter
def syntax(self, style):
@ -1164,13 +1178,11 @@ class Cs(object):
# save syntax
self._syntax = style
# return current skipdata status
@property
def skipdata(self):
return self._skipdata
# setter: modify skipdata status
@skipdata.setter
def skipdata(self, opt):
@ -1184,41 +1196,36 @@ class Cs(object):
# save this option
self._skipdata = opt
@property
def skipdata_setup(self):
return (self._skipdata_mnem,) + self._skipdata_cb
@skipdata_setup.setter
def skipdata_setup(self, opt):
_mnem, _cb, _ud = opt
self._skipdata_opt.mnemonic = _mnem.encode()
self._skipdata_opt.callback = CS_SKIPDATA_CALLBACK(_cb or 0)
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:
raise CsError(status)
self._skipdata_mnem = _mnem
self._skipdata_cb = (_cb, _ud)
@property
def skipdata_mnem(self):
return self._skipdata_mnem
@skipdata_mnem.setter
def skipdata_mnem(self, mnem):
self.skipdata_setup = (mnem,) + self._skipdata_cb
@property
def skipdata_callback(self):
return self._skipdata_cb
@skipdata_callback.setter
def skipdata_callback(self, val):
if not isinstance(val, tuple):
@ -1226,7 +1233,6 @@ class Cs(object):
func, data = val
self.skipdata_setup = (self._skipdata_mnem, func, data)
# customize instruction mnemonic
def mnemonic_setup(self, id, mnem):
_mnem_opt = _cs_opt_mnem()
@ -1239,19 +1245,16 @@ class Cs(object):
if status != CS_ERR_OK:
raise CsError(status)
# check to see if this engine supports a particular arch,
# or diet mode (depending on @query).
def support(self, query):
return cs_support(query)
# is detail mode enable?
@property
def detail(self):
return self._detail
# modify detail mode.
@detail.setter
def detail(self, opt): # opt is boolean type, so must be either 'True' or 'False'
@ -1264,13 +1267,11 @@ class Cs(object):
# save detail
self._detail = opt
# is detail mode enable?
@property
def imm_unsigned(self):
return self._imm_unsigned
# modify detail mode.
@imm_unsigned.setter
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
self._imm_unsigned = opt
# return disassembly mode of this engine.
@property
def mode(self):
return self._mode
# modify engine's mode at run-time.
@mode.setter
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))
if view.readonly:
code = (ctypes.c_char * len(view)).from_buffer_copy(view)
else:
else:
code = ctypes.pointer(ctypes.c_char.from_buffer(view))
# since we are taking a pointer to a pointer, ctypes does not do
# the typical auto conversion, so we have to cast it here.
code = ctypes.cast(code, ctypes.POINTER(ctypes.c_char))
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'))
# 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,
'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE,
'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 = ""

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.
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/HPPA/HPPAModule.h"
#include "arch/LoongArch/LoongArchModule.h"
#include "arch/Xtensa/XtensaModule.h"
typedef struct cs_arch_config {
// constructor initialization
@ -255,6 +256,12 @@ typedef struct cs_arch_config {
LoongArch_option, \
~(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
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_option,
~(CS_MODE_LITTLE_ENDIAN | CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11
| CS_MODE_HPPA_20 | CS_MODE_HPPA_20W),
~(CS_MODE_LITTLE_ENDIAN | CS_MODE_BIG_ENDIAN | CS_MODE_HPPA_11 |
CS_MODE_HPPA_20 | CS_MODE_HPPA_20W),
},
#else
{ NULL, NULL, 0 },
@ -371,74 +378,82 @@ static const cs_arch_config arch_configs[MAX_ARCH] = {
#else
{ NULL, NULL, 0 },
#endif
#ifdef CAPSTONE_HAS_XTENSA
CS_ARCH_CONFIG_XTENSA
#else
{ NULL, NULL, 0 },
#endif
};
// bitmask of enabled architectures
static const uint32_t all_arch = 0
#ifdef CAPSTONE_HAS_ARM
| (1 << CS_ARCH_ARM)
| (1 << CS_ARCH_ARM)
#endif
#if defined(CAPSTONE_HAS_AARCH64) || defined(CAPSTONE_HAS_ARM64)
| (1 << CS_ARCH_AARCH64)
| (1 << CS_ARCH_AARCH64)
#endif
#ifdef CAPSTONE_HAS_MIPS
| (1 << CS_ARCH_MIPS)
| (1 << CS_ARCH_MIPS)
#endif
#ifdef CAPSTONE_HAS_X86
| (1 << CS_ARCH_X86)
| (1 << CS_ARCH_X86)
#endif
#ifdef CAPSTONE_HAS_POWERPC
| (1 << CS_ARCH_PPC)
| (1 << CS_ARCH_PPC)
#endif
#ifdef CAPSTONE_HAS_SPARC
| (1 << CS_ARCH_SPARC)
| (1 << CS_ARCH_SPARC)
#endif
#ifdef CAPSTONE_HAS_SYSTEMZ
| (1 << CS_ARCH_SYSTEMZ)
| (1 << CS_ARCH_SYSTEMZ)
#endif
#ifdef CAPSTONE_HAS_XCORE
| (1 << CS_ARCH_XCORE)
| (1 << CS_ARCH_XCORE)
#endif
#ifdef CAPSTONE_HAS_M68K
| (1 << CS_ARCH_M68K)
| (1 << CS_ARCH_M68K)
#endif
#ifdef CAPSTONE_HAS_TMS320C64X
| (1 << CS_ARCH_TMS320C64X)
| (1 << CS_ARCH_TMS320C64X)
#endif
#ifdef CAPSTONE_HAS_M680X
| (1 << CS_ARCH_M680X)
| (1 << CS_ARCH_M680X)
#endif
#ifdef CAPSTONE_HAS_EVM
| (1 << CS_ARCH_EVM)
| (1 << CS_ARCH_EVM)
#endif
#ifdef CAPSTONE_HAS_MOS65XX
| (1 << CS_ARCH_MOS65XX)
| (1 << CS_ARCH_MOS65XX)
#endif
#ifdef CAPSTONE_HAS_WASM
| (1 << CS_ARCH_WASM)
| (1 << CS_ARCH_WASM)
#endif
#ifdef CAPSTONE_HAS_BPF
| (1 << CS_ARCH_BPF)
| (1 << CS_ARCH_BPF)
#endif
#ifdef CAPSTONE_HAS_RISCV
| (1 << CS_ARCH_RISCV)
| (1 << CS_ARCH_RISCV)
#endif
#ifdef CAPSTONE_HAS_SH
| (1 << CS_ARCH_SH)
| (1 << CS_ARCH_SH)
#endif
#ifdef CAPSTONE_HAS_TRICORE
| (1 << CS_ARCH_TRICORE)
| (1 << CS_ARCH_TRICORE)
#endif
#ifdef CAPSTONE_HAS_ALPHA
| (1 << CS_ARCH_ALPHA)
| (1 << CS_ARCH_ALPHA)
#endif
#ifdef CAPSTONE_HAS_HPPA
| (1 << CS_ARCH_HPPA)
| (1 << CS_ARCH_HPPA)
#endif
#ifdef CAPSTONE_HAS_LOONGARCH
| (1 << CS_ARCH_LOONGARCH)
| (1 << CS_ARCH_LOONGARCH)
#endif
;
#ifdef CAPSTONE_HAS_XTENSA
| (1 << CS_ARCH_XTENSA)
#endif
;
#endif
@ -670,17 +685,17 @@ bool CAPSTONE_API cs_support(int query)
{
if (query == CS_ARCH_ALL)
return all_arch ==
((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) |
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
(1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_XCORE) |
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
(1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF) |
(1 << CS_ARCH_SH) | (1 << CS_ARCH_TRICORE) |
(1 << CS_ARCH_ALPHA) | (1 << CS_ARCH_HPPA) |
(1 << CS_ARCH_LOONGARCH));
((1 << CS_ARCH_ARM) | (1 << CS_ARCH_AARCH64) |
(1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
(1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
(1 << CS_ARCH_SYSTEMZ) | (1 << CS_ARCH_XCORE) |
(1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
(1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) |
(1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) |
(1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF) |
(1 << CS_ARCH_SH) | (1 << CS_ARCH_TRICORE) |
(1 << CS_ARCH_ALPHA) | (1 << CS_ARCH_HPPA) |
(1 << CS_ARCH_LOONGARCH) | (1 << CS_ARCH_XTENSA));
if ((unsigned int)query < CS_ARCH_MAX)
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) {
// 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 {
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)
GetRegisterAccess_t reg_access;
struct insn_mnem *mnem_list; // linked list of customized instruction mnemonic
uint32_t LITBASE;
};
#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 },
{ "systemz", "systemz (s390x) - all features", CS_ARCH_SYSTEMZ, CS_MODE_BIG_ENDIAN },
{ "systemz_arch8", "(arch8/z10/generic)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch9", "(arch9/z196)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch10", "(arch10/zec12)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch11", "(arch11/z13)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch12", "(arch12/z14)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch13", "(arch13/z15)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch14", "(arch14/z16)\n", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH14 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch8", "(arch8/z10/generic)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH8 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch9", "(arch9/z196)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH9 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch10", "(arch10/zec12)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH10 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch11", "(arch11/z13)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH11 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch12", "(arch12/z14)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH12 | CS_MODE_BIG_ENDIAN },
{ "systemz_arch13", "(arch13/z15)", CS_ARCH_SYSTEMZ, CS_MODE_SYSTEMZ_ARCH13 | 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 },
@ -221,6 +221,8 @@ static struct {
{ "loongarch32", "LoongArch 32-bit", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH32 },
{ "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 }
};
@ -422,6 +424,9 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
case CS_ARCH_LOONGARCH:
print_insn_detail_loongarch(handle, ins);
break;
case CS_ARCH_XTENSA:
print_insn_detail_xtensa(handle, ins);
break;
default: break;
}
@ -608,6 +613,10 @@ int main(int argc, char **argv)
printf("loongarch=1 ");
}
if (cs_support(CS_ARCH_XTENSA)) {
printf("xtensa=1 ");
}
printf("\n");
return 0;
case 'h':
@ -637,6 +646,7 @@ int main(int argc, char **argv)
address = strtoull(src, &temp, 16);
if (temp == src || *temp != '\0' || errno == ERANGE) {
fprintf(stderr, "ERROR: invalid address argument, quit!\n");
free(assembly);
return -2;
}
}
@ -670,6 +680,7 @@ int main(int argc, char **argv)
if (arch == CS_ARCH_ALL) {
fprintf(stderr, "ERROR: Invalid <arch+mode>: \"%s\", quit!\n", choosen_arch);
usage(argv[0]);
free(assembly);
return -1;
}
@ -677,6 +688,7 @@ int main(int argc, char **argv)
const char *error = cs_strerror(err);
fprintf(stderr, "ERROR: Failed on cs_open(): %s\n", error);
usage(argv[0]);
free(assembly);
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_hppa(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_

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
**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**
- Instruction alias (see below).

View File

@ -102,6 +102,7 @@ typedef enum cs_arch {
CS_ARCH_ALPHA, ///< Alpha architecture
CS_ARCH_HPPA, ///< HPPA architecture
CS_ARCH_LOONGARCH, ///< LoongArch architecture
CS_ARCH_XTENSA, ///< Xtensa architecture
CS_ARCH_MAX,
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
} 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_Z16 = 1 << 14, ///< Enables features of the Z16 processor
CS_MODE_SYSTEMZ_GENERIC = 1 << 15, ///< Enables features of the generic processor
CS_MODE_XTENSA = 1 << 1, ///< Xtensa
} cs_mode;
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_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_LITBASE, ///< Xtensa, set the LITBASE value. LITBASE is set to 0 by default.
} cs_opt_type;
/// Runtime option value (associated with option type above)
@ -377,6 +380,7 @@ typedef struct cs_opt_skipdata {
#include "alpha.h"
#include "hppa.h"
#include "loongarch.h"
#include "xtensa.h"
#define MAX_IMPL_W_REGS 47
#define MAX_IMPL_R_REGS 20
@ -433,6 +437,7 @@ typedef struct cs_detail {
cs_alpha alpha; ///< Alpha architecture
cs_hppa hppa; ///< HPPA architecture
cs_loongarch loongarch; ///< LoongArch architecture
cs_xtensa xtensa; ///< Xtensa architecture
};
} 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"=="HPPA" set %arch%=HPPA
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"

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)
def exists_and_is_dir(x):
return x.exists() and x.is_dir()
class MCUpdater:
"""
The MCUpdater parses all test files of the LLVM MC regression tests.
@ -291,11 +295,10 @@ class MCUpdater:
self.multi_mode = multi_mode
def check_prerequisites(self, paths):
for path in paths:
if not path.exists() or not path.is_dir():
raise ValueError(
f"'{path}' does not exits or is not a directory. Cannot generate tests from there."
)
if all(not exists_and_is_dir(path) for path in paths):
raise ValueError(
f"'{paths}' does not exits or is not a directory. Cannot generate tests from there."
)
llvm_lit_cfg = get_path("{LLVM_LIT_TEST_DIR}")
if not llvm_lit_cfg.exists():
raise ValueError(
@ -478,9 +481,14 @@ class MCUpdater:
log.info("Check prerequisites")
disas_tests = self.mc_dir.joinpath(f"Disassembler/{self.arch}")
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)
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")
self.test_files = self.build_test_files(llvm_mc_cmds)
for slink in self.symbolic_links:

View File

@ -10,10 +10,20 @@ TARGETS_LLVM_NAMING = [
"LoongArch",
"SystemZ",
"Mips",
"Xtensa",
]
# 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).
TARGET_TO_IN_CODE_NAME = {
@ -24,6 +34,7 @@ TARGET_TO_IN_CODE_NAME = {
"LoongArch": "LoongArch",
"SystemZ": "SystemZ",
"Mips": "Mips",
"Xtensa": "Xtensa",
}
# Maps the name from ARCH_LLVM_NAMING to the directory name in LLVM
@ -35,4 +46,5 @@ TARGET_TO_DIR_NAME = {
"LoongArch": "LoongArch",
"SystemZ": "SystemZ",
"Mips": "Mips",
"Xtensa": "Xtensa",
}

View File

@ -444,6 +444,8 @@ class Translator:
cb: [(Node, str)]
for cb in captures_bundle:
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)
p_list.append((bytes_patch, cb[0][0]))
self.patch_src(p_list)

View File

@ -107,7 +107,8 @@ class TestPatches(unittest.TestCase):
self.assertGreater(len(captures_bundle), 0)
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):
patch = AddCSDetail(0, "ARCH")
@ -115,7 +116,7 @@ class TestPatches(unittest.TestCase):
self.check_patching_result(
patch,
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"int i = OpNo; "
b"}",
@ -132,8 +133,8 @@ class TestPatches(unittest.TestCase):
def test_assert(self):
patch = Assert(0)
syntax = b"assert(0 == 0)"
self.check_patching_result(patch, syntax, b"CS_ASSERT((0 == 0));")
syntax = b"assert(0 == 0);"
self.check_patching_result(patch, syntax, b"CS_ASSERT(0 == 0);")
def test_bitcaststdarray(self):
patch = BitCastStdArray(0)

View File

@ -14,7 +14,8 @@
"AArch64InstPrinter.cpp",
"LoongArchInstPrinter.cpp",
"MipsInstPrinter.cpp",
"SystemZInstPrinter.cpp"
"SystemZInstPrinter.cpp",
"XtensaInstPrinter.cpp"
]
},
"InlineToStaticInline": {
@ -242,5 +243,23 @@
],
"templates_with_arg_deduction": [],
"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,uint64_tAddress,unsignedOpNo,SStream*O)", # PPC - printBranchOperand
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):
@ -71,7 +73,14 @@ class AddCSDetail(Patch):
comp = captures[3][0]
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(
self, src: bytes, fcn_def: Node, fcn_id: bytes, params: bytes
@ -79,6 +88,8 @@ class AddCSDetail(Patch):
op_group_enum = (
self.arch.encode("utf8") + b"_OP_GROUP_" + fcn_id[5:]
) # 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"
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.Patch import Patch
from autosync.cpptranslator.patches.Helper import get_text_from_node
class Assert(Patch):
"""
Patch Remove asserts
Patch replace `assert`|`report_fatal_error` with `CS_ASSERT`
"""
def __init__(self, priority: int):
@ -19,7 +20,7 @@ class Assert(Patch):
return (
"(expression_statement"
" (call_expression"
' ((identifier) @id (#eq? @id "assert"))'
' ((identifier) @id (#match? @id "assert|report_fatal_error"))'
" ((argument_list) @arg_list)"
" )"
") @assert"
@ -28,9 +29,6 @@ class Assert(Patch):
def get_main_capture_name(self) -> str:
return "assert"
def get_patch(
self, captures: list[tuple[Node, str]], src: bytes, **kwargs
) -> bytes:
arg_list = captures[2][0]
args = get_text(src, arg_list.start_byte, arg_list.end_byte)
return b"CS_ASSERT(" + args + b");"
def get_patch(self, captures: [(Node, str)], src: bytes, **kwargs) -> bytes:
args = get_text_from_node(src, captures[2][0])
return b"CS_ASSERT" + args + b";"

View File

@ -12,7 +12,7 @@ class GetOperandRegImm(Patch):
Patch OPERAND.getReg()
to MCOperand_getReg(OPERAND)
Same for isImm()
Same for getImm()|getExpr
"""
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]
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:
"""
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()
case "SystemZ":
return res + get_SystemZ_includes(filename) + get_general_macros()
case "Xtensa":
return res + get_Xtensa_includes(filename) + get_general_macros()
case "TEST_ARCH":
return res + b"test_output"
case _:
@ -388,6 +390,32 @@ def get_SystemZ_includes(filename: str) -> bytes:
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():
return (
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()
to MCOperand_isReg(OPERAND)
Same for isImm()
Same for isImm() | isExpr()
"""
def __init__(self, priority: int):

View File

@ -33,4 +33,8 @@ class QualifiedIdentifier(Patch):
namespace = b""
identifier = captures[0][0].named_children[0]
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 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
@ -105,6 +105,37 @@ class StreamOperations(Patch):
+ last_op_text.replace(b"'", b'"')
+ 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:
res += b"SStream_concat0(" + s_name + b", " + last_op_text + b");"
stream = captures[0][0]

View File

@ -3290,5 +3290,179 @@
"new_hash": "",
"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)) {
printf("loongarch=1 ");
}
if (cs_support(CS_ARCH_XTENSA)) {
printf("xtensa=1 ");
}
printf("\n");
return 0;

View File

@ -26,7 +26,7 @@ ExternalProject_Add(libcyaml_ext
URL_HASH SHA256=8dbd216e1fce90f9f7cca341e5178710adc76ee360a7793ef867edb28f3e4130
DOWNLOAD_EXTRACT_TIMESTAMP true
CONFIGURE_COMMAND ""
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT}
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} PKG_CONFIG=pkg-config
BUILD_IN_SOURCE true
INSTALL_COMMAND ""
)
@ -45,8 +45,8 @@ add_executable(cstest ${CSTEST_SRC})
add_library(libcstest STATIC ${CSTEST_SRC})
add_dependencies(cstest cmocka_ext)
add_dependencies(cstest libcyaml_ext)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml yaml)
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml yaml)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_include_directories(cstest PRIVATE
${PROJECT_SOURCE_DIR}/include>
${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_X86", .val = CS_ARCH_X86 },
{ .str = "CS_ARCH_XCORE", .val = CS_ARCH_XCORE },
{ .str = "CS_ARCH_XTENSA", .val = CS_ARCH_XTENSA },
{ .str = "aarch64", .val = CS_ARCH_AARCH64 },
{ .str = "alpha", .val = CS_ARCH_ALPHA },
{ .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 = "x86", .val = CS_ARCH_X86 },
{ .str = "xcore", .val = CS_ARCH_XCORE },
{ .str = "xtensa", .val = CS_ARCH_XTENSA },
};
/// 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_V8", .val = CS_MODE_V8 },
{ .str = "CS_MODE_V9", .val = CS_MODE_V9 },
{ .str = "CS_MODE_XTENSA", .val = CS_MODE_XTENSA },
};
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,
"Too many options given in: '%s'. Maximum is: %" PRId64
"\n",
opt_str, opt_arr_size);
opt_str,
(uint64_t)opt_arr_size);
return false;
}
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) {
Data[0] = 24;
} else if (strcmp(arch, "CS_ARCH_EVM") == 0 && strcmp(mode, "0") == 0) {
Data[0] = 25;
} else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) {
Data[0] = 25;
} else if (strcmp(arch, "CS_ARCH_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;
} else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_EXTENDED") != NULL) {
Data[0] = 30;

View File

@ -172,6 +172,18 @@ struct platform platforms[] = {
(cs_mode)0,
"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();

View File

@ -117,6 +117,16 @@ int main(int argc, char **argv)
(cs_mode)CS_MODE_M680X_6809,
"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

View File

@ -379,8 +379,19 @@ struct platform platforms[] = {
"TRICORE",
"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
{
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
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;
}
/// 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.
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);
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);
uint64_t readBytes48(MCInst *MI, const uint8_t *Bytes);
uint64_t readBytes64(MCInst *MI, const uint8_t *Bytes);