Skip to content

Commit

Permalink
Initial auto-sync LoongArch support
Browse files Browse the repository at this point in the history
Co-authored-by: CoA <[email protected]>
  • Loading branch information
jiegec and FurryAcetylCoA committed May 3, 2024
1 parent f81eb3a commit c02fcbd
Show file tree
Hide file tree
Showing 55 changed files with 60,881 additions and 30 deletions.
28 changes: 26 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,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 SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA)
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA)
set(SUPPORTED_ARCHITECTURES ARM AARCH64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE ALPHA HPPA LOONGARCH)
set(SUPPORTED_ARCHITECTURE_LABELS ARM AARCH64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore Alpha HPPA LoongArch)

list(LENGTH SUPPORTED_ARCHITECTURES count)
math(EXPR count "${count}-1")
Expand Down Expand Up @@ -180,6 +180,7 @@ set(HEADERS_COMMON
include/capstone/sh.h
include/capstone/alpha.h
include/capstone/hppa.h
include/capstone/loongarch.h
)

set(TEST_SOURCES test_basic.c test_detail.c test_skipdata.c test_iter.c)
Expand Down Expand Up @@ -646,6 +647,25 @@ if(CAPSTONE_HPPA_SUPPORT)
set(TEST_SOURCES ${TEST_SOURCES} test_hppa.c)
endif()

if (CAPSTONE_LOONGARCH_SUPPORT)
add_definitions(-DCAPSTONE_HAS_LOONGARCH)
set(SOURCES_LOONGARCH
arch/LoongArch/LoongArchDisassembler.c
arch/LoongArch/LoongArchDisassemblerExtension.c
arch/LoongArch/LoongArchInstPrinter.c
arch/LoongArch/LoongArchMapping.c
arch/LoongArch/LoongArchModule.c
)
set(HEADERS_LOONGARCH
arch/LoongArch/LoongArchInstPrinter.h
arch/LoongArch/LoongArchMapping.h
arch/LoongArch/LoongArchDisassembler.h
arch/LoongArch/LoongArchModule.h
arch/LoongArch/LoongArchLinkage.h
)
set(TEST_SOURCES ${TEST_SOURCES} test_loongarch.c)
endif ()

if (CAPSTONE_OSXKERNEL_SUPPORT)
add_definitions(-DCAPSTONE_HAS_OSXKERNEL)
endif()
Expand All @@ -672,6 +692,7 @@ set(ALL_SOURCES
${SOURCES_TRICORE}
${SOURCES_ALPHA}
${SOURCES_HPPA}
${SOURCES_LOONGARCH}
)

set(ALL_HEADERS
Expand All @@ -697,6 +718,7 @@ set(ALL_HEADERS
${HEADERS_TRICORE}
${HEADERS_ALPHA}
${HEADERS_HPPA}
${HEADERS_LOONGARCH}
)

## properties
Expand Down Expand Up @@ -762,6 +784,7 @@ source_group("Source\\SH" FILES ${SOURCES_SH})
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("Include\\Common" FILES ${HEADERS_COMMON})
source_group("Include\\Engine" FILES ${HEADERS_ENGINE})
Expand All @@ -785,6 +808,7 @@ source_group("Include\\SH" FILES ${HEADERS_SH})
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})

## installation
if(CAPSTONE_INSTALL)
Expand Down
1 change: 1 addition & 0 deletions COMPILE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Capstone requires no prerequisite packages, so it is easy to compile & install.
/usr/include/capstone/capstone.h
/usr/include/capstone/evm.h
/usr/include/capstone/hppa.h
/usr/include/capstone/loongarch.h
/usr/include/capstone/m680x.h
/usr/include/capstone/m68k.h
/usr/include/capstone/mips.h
Expand Down
3 changes: 2 additions & 1 deletion COMPILE_CMAKE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Get CMake for free from http://www.cmake.org.
- CAPSTONE_AARCH64_SUPPORT: support AARCH64. Run cmake with -DCAPSTONE_AARCH64_SUPPORT=0 to remove AARCH64.
- CAPSTONE_ALPHA_SUPPORT: support Alpha. Run cmake with -DCAPSTONE_ALPHA_SUPPORT=0 to remove Alpha.
- CAPSTONE_HPPA_SUPPORT: support HPPA. Run cmake with -DCAPSTONE_HPPA_SUPPORT=0 to remove HPPA.
- CAPSTONE_LOONGARCH_SUPPORT: support LoongArch. Run cmake with -DCAPSTONE_LOONGARCH_SUPPORT=0 to remove LoongArch.
- CAPSTONE_M680X_SUPPORT: support M680X. Run cmake with -DCAPSTONE_M680X_SUPPORT=0 to remove M680X.
- CAPSTONE_M68K_SUPPORT: support M68K. Run cmake with -DCAPSTONE_M68K_SUPPORT=0 to remove M68K.
- CAPSTONE_MIPS_SUPPORT: support Mips. Run cmake with -DCAPSTONE_MIPS_SUPPORT=0 to remove Mips.
Expand Down Expand Up @@ -118,7 +119,7 @@ Get CMake for free from http://www.cmake.org.

Will just target the x86 architecture. The list of available architectures is: ARM,
AARCH64, M68K, MIPS, PowerPC, Sparc, SystemZ, XCore, x86, TMS320C64x, M680x, EVM, MOS65XX,
WASM, BPF, RISCV, Alpha, HPPA.
WASM, BPF, RISCV, Alpha, HPPA, LoongArch.

(4) You can also create an installation image with cmake, by using the 'install' target.
Use:
Expand Down
3 changes: 2 additions & 1 deletion CREDITS.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ 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.
Dmitry Sibirtsev: Alpha & HPPA architecture.
Dmitry Sibirtsev: Alpha & HPPA architecture.
Jiajie Chen & Yanglin Xun: LoongArch architecture.
1 change: 1 addition & 0 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
typedef struct MCInst MCInst;
typedef struct cs_struct cs_struct;
typedef struct MCOperand MCOperand;
typedef unsigned MCRegister;

/// MCOperand - Instances of this class represent operands of the MCInst class.
/// This is a simple discriminated union.
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,21 @@ ifneq (,$(findstring hppa,$(CAPSTONE_ARCHS)))
LIBOBJ_HPPA += $(LIBSRC_HPPA:%.c=$(OBJDIR)/%.o)
endif

DEP_LOONGARCH =
DEP_LOONGARCH += $(wildcard arch/LoongArch/LoongArch*.inc)

LIBOBJ_LOONGARCH =
ifneq (,$(findstring loongarch,$(CAPSTONE_ARCHS)))
CFLAGS += -DCAPSTONE_HAS_LOONGARCH
LIBSRC_LOONGARCH += $(wildcard arch/LoongArch/LoongArch*.c)
LIBOBJ_LOONGARCH += $(LIBSRC_LOONGARCH:%.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 += $(LIBOBJ_TRICORE) $(LIBOBJ_ALPHA) $(LIBOBJ_HPPA) $(LIBOBJ_LOONGARCH)


ifeq ($(PKG_EXTRA),)
Expand Down Expand Up @@ -488,6 +497,7 @@ $(LIBOBJ_BPF): $(DEP_BPF)
$(LIBOBJ_TRICORE): $(DEP_TRICORE)
$(LIBOBJ_ALPHA): $(DEP_ALPHA)
$(LIBOBJ_HPPA): $(DEP_HPPA)
$(LIBOBJ_LOONGARCH): $(DEP_LOONGARCH)

ifeq ($(CAPSTONE_STATIC),yes)
$(ARCHIVE): $(LIBOBJ)
Expand Down Expand Up @@ -575,11 +585,13 @@ dist:

TESTS = test_basic test_detail test_arm test_aarch64 test_m68k test_mips test_ppc test_sparc test_tricore test_hppa
TESTS += test_systemz test_x86 test_xcore test_iter test_evm test_riscv test_mos65xx test_wasm test_bpf test_alpha
TESTS += test_loongarch
TESTS += test_basic.static test_detail.static test_arm.static test_aarch64.static
TESTS += test_m68k.static test_mips.static test_ppc.static test_sparc.static
TESTS += test_systemz.static test_x86.static test_xcore.static test_m680x.static
TESTS += test_skipdata test_skipdata.static test_iter.static test_evm.static test_riscv.static
TESTS += test_mos65xx.static test_wasm.static test_bpf.static test_alpha.static test_hppa.static
TESTS += test_loongarch.static

check: $(TESTS)

Expand Down
1 change: 1 addition & 0 deletions Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ DEFINE_get_detail_op(tricore, TriCore);
DEFINE_get_detail_op(aarch64, AArch64);
DEFINE_get_detail_op(alpha, Alpha);
DEFINE_get_detail_op(hppa, HPPA);
DEFINE_get_detail_op(loongarch, LoongArch);

/// Returns true if for this architecture the
/// alias operands should be filled.
Expand Down
4 changes: 4 additions & 0 deletions Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ DECL_get_detail_op(tricore, TriCore);
DECL_get_detail_op(aarch64, AArch64);
DECL_get_detail_op(alpha, Alpha);
DECL_get_detail_op(hppa, HPPA);
DECL_get_detail_op(loongarch, LoongArch);

/// Increments the detail->arch.op_count by one.
#define DEFINE_inc_detail_op_count(arch, ARCH) \
Expand Down Expand Up @@ -152,6 +153,8 @@ DEFINE_inc_detail_op_count(alpha, Alpha);
DEFINE_dec_detail_op_count(alpha, Alpha);
DEFINE_inc_detail_op_count(hppa, HPPA);
DEFINE_dec_detail_op_count(hppa, HPPA);
DEFINE_inc_detail_op_count(loongarch, LoongArch);
DEFINE_dec_detail_op_count(loongarch, LoongArch);

/// Returns true if a memory operand is currently edited.
static inline bool doing_mem(const MCInst *MI)
Expand Down Expand Up @@ -179,6 +182,7 @@ DEFINE_get_arch_detail(tricore, TriCore);
DEFINE_get_arch_detail(aarch64, AArch64);
DEFINE_get_arch_detail(alpha, Alpha);
DEFINE_get_arch_detail(hppa, HPPA);
DEFINE_get_arch_detail(loongarch, LoongArch);

static inline bool detail_is_set(const MCInst *MI)
{
Expand Down
193 changes: 193 additions & 0 deletions arch/LoongArch/LoongArchDisassembler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <[email protected]>, 2013-2022, */
/* Rot127 <[email protected]> 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 */

//===-- LoongArchDisassembler.cpp - Disassembler for LoongArch ------------===//
//
// 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 LoongArchDisassembler class.
//
//===----------------------------------------------------------------------===//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>

#include "../../MCInst.h"
#include "../../MathExtras.h"
#include "../../MCInstPrinter.h"
#include "../../MCDisassembler.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../cs_priv.h"
#include "../../utils.h"
#include "LoongArchDisassemblerExtension.h"
#define GET_SUBTARGETINFO_ENUM
#include "LoongArchGenSubtargetInfo.inc"

#define GET_INSTRINFO_ENUM
#include "LoongArchGenInstrInfo.inc"

#define GET_REGINFO_ENUM
#include "LoongArchGenRegisterInfo.inc"

#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b

#define DEBUG_TYPE "loongarch-disassembler"

static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_R0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_F0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_F0_64 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeCFRRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 8)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_FCC0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeFCSRRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 4)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_FCSR0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeLSX128RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_VR0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeLASX256RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_XR0 + RegNo));
return MCDisassembler_Success;
}

static DecodeStatus DecodeSCRRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 4)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (LoongArch_SCR0 + RegNo));
return MCDisassembler_Success;
}

#define DEFINE_decodeUImmOperand(N, P) \
static DecodeStatus CONCAT(decodeUImmOperand, CONCAT(N, P))( \
MCInst * Inst, uint64_t Imm, int64_t Address, \
const void *Decoder) \
{ \
MCOperand_CreateImm0(Inst, (Imm + P)); \
return MCDisassembler_Success; \
}
DEFINE_decodeUImmOperand(2, 1);
DEFINE_decodeUImmOperand(12, 0);

#define DEFINE_decodeSImmOperand(N, S) \
static DecodeStatus CONCAT(decodeSImmOperand, CONCAT(N, S))( \
MCInst * Inst, uint64_t Imm, int64_t Address, \
const void *Decoder) \
{ \
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << S), N + S))); \
return MCDisassembler_Success; \
}
DEFINE_decodeSImmOperand(5, 0);
DEFINE_decodeSImmOperand(12, 0);
DEFINE_decodeSImmOperand(16, 0);
DEFINE_decodeSImmOperand(20, 0);
DEFINE_decodeSImmOperand(14, 2);
DEFINE_decodeSImmOperand(9, 3);
DEFINE_decodeSImmOperand(10, 2);
DEFINE_decodeSImmOperand(11, 1);
DEFINE_decodeSImmOperand(8, 3);
DEFINE_decodeSImmOperand(8, 2);
DEFINE_decodeSImmOperand(8, 1);
DEFINE_decodeSImmOperand(8, 0);
DEFINE_decodeSImmOperand(21, 2);
DEFINE_decodeSImmOperand(16, 2);
DEFINE_decodeSImmOperand(26, 2);
DEFINE_decodeSImmOperand(13, 0);

#include "LoongArchGenDisassemblerTables.inc"

DecodeStatus LoongArch_LLVM_getInstruction(MCInst *MI, uint64_t *Size,
const uint8_t *Bytes,
size_t BytesLen, uint64_t Address,
SStream *CS)
{
uint32_t Insn;
DecodeStatus Result;

// We want to read exactly 4 bytes of data because all LoongArch instructions
// are fixed 32 bits.
if (BytesLen < 4) {
*Size = 0;
return MCDisassembler_Fail;
}

Insn = readBytes32(MI, Bytes);
// Calling the auto-generated decoder function.
Result = decodeInstruction_4(DecoderTable32, MI, Insn, Address, NULL);
*Size = 4;

return Result;
}
Loading

0 comments on commit c02fcbd

Please sign in to comment.