This commit is contained in:
2026-03-23 12:11:07 +01:00
commit e64eb40b38
4573 changed files with 3117439 additions and 0 deletions
+199
View File
@@ -0,0 +1,199 @@
/* 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 */
//===-- 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"
static DecodeStatus 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;
}
DecodeStatus LoongArch_LLVM_getInstruction(MCInst *MI, uint64_t *Size,
const uint8_t *Bytes,
size_t BytesLen, uint64_t Address,
SStream *CS)
{
return getInstruction(MI, Size, Bytes, BytesLen, Address, CS);
}
@@ -0,0 +1,25 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
/* Rot127 <unisono@quyllur.org>, 2022-2023 */
/* Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#include <capstone/loongarch.h>
#include "LoongArchDisassemblerExtension.h"
#define GET_SUBTARGETINFO_ENUM
#include "LoongArchGenSubtargetInfo.inc"
bool LoongArch_getFeatureBits(unsigned int mode, unsigned int feature)
{
// handle loongarch32/64
if (feature == LoongArch_Feature64Bit) {
if (mode & CS_MODE_LOONGARCH64)
return true;
return false;
}
// otherwise we support everything
return true;
}
@@ -0,0 +1,14 @@
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
/* Rot127 <unisono@quyllur.org>, 2022-2023 */
/* Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifndef CS_LOONGARCH_DISASSEMBLER_EXTENSION_H
#define CS_LOONGARCH_DISASSEMBLER_EXTENSION_H
#include "capstone/capstone.h"
bool LoongArch_getFeatureBits(unsigned int mode, unsigned int feature);
#endif // CS_LOONGARCH_DISASSEMBLER_EXTENSION_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
/* 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 */
LOONGARCH_INS_ALIAS_LA, // Real instr.: LOONGARCH_PseudoLA_GOT
LOONGARCH_INS_ALIAS_LA_GLOBAL, // Real instr.: LOONGARCH_PseudoLA_GOT
LOONGARCH_INS_ALIAS_LA_LOCAL, // Real instr.: LOONGARCH_PseudoLA_PCREL
LOONGARCH_INS_ALIAS_NOP, // Real instr.: LOONGARCH_ANDI
LOONGARCH_INS_ALIAS_MOVE, // Real instr.: LOONGARCH_OR
LOONGARCH_INS_ALIAS_RET, // Real instr.: LOONGARCH_JIRL
LOONGARCH_INS_ALIAS_JR, // Real instr.: LOONGARCH_JIRL
@@ -0,0 +1,20 @@
/* 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 */
{ LOONGARCH_INS_ALIAS_LA, "la" },
{ LOONGARCH_INS_ALIAS_LA_GLOBAL, "la_global" },
{ LOONGARCH_INS_ALIAS_LA_LOCAL, "la_local" },
{ LOONGARCH_INS_ALIAS_NOP, "nop" },
{ LOONGARCH_INS_ALIAS_MOVE, "move" },
{ LOONGARCH_INS_ALIAS_RET, "ret" },
{ LOONGARCH_INS_ALIAS_JR, "jr" },
@@ -0,0 +1,18 @@
/* 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 */
{ LOONGARCH_FEATURE_ISLA64, "IsLA64" },
{ LOONGARCH_FEATURE_ISLA32, "IsLA32" },
{ LOONGARCH_FEATURE_HASLAGLOBALWITHPCREL, "HasLaGlobalWithPcrel" },
{ LOONGARCH_FEATURE_HASLAGLOBALWITHABS, "HasLaGlobalWithAbs" },
{ LOONGARCH_FEATURE_HASLALOCALWITHABS, "HasLaLocalWithAbs" },
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
/* 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 */
LoongArch_OP_GROUP_Operand = 0,
LoongArch_OP_GROUP_AtomicMemOp = 1,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,708 @@
#ifdef GET_REGINFO_ENUM
#undef GET_REGINFO_ENUM
enum {
LoongArch_NoRegister,
LoongArch_F0 = 1,
LoongArch_F1 = 2,
LoongArch_F2 = 3,
LoongArch_F3 = 4,
LoongArch_F4 = 5,
LoongArch_F5 = 6,
LoongArch_F6 = 7,
LoongArch_F7 = 8,
LoongArch_F8 = 9,
LoongArch_F9 = 10,
LoongArch_F10 = 11,
LoongArch_F11 = 12,
LoongArch_F12 = 13,
LoongArch_F13 = 14,
LoongArch_F14 = 15,
LoongArch_F15 = 16,
LoongArch_F16 = 17,
LoongArch_F17 = 18,
LoongArch_F18 = 19,
LoongArch_F19 = 20,
LoongArch_F20 = 21,
LoongArch_F21 = 22,
LoongArch_F22 = 23,
LoongArch_F23 = 24,
LoongArch_F24 = 25,
LoongArch_F25 = 26,
LoongArch_F26 = 27,
LoongArch_F27 = 28,
LoongArch_F28 = 29,
LoongArch_F29 = 30,
LoongArch_F30 = 31,
LoongArch_F31 = 32,
LoongArch_FCC0 = 33,
LoongArch_FCC1 = 34,
LoongArch_FCC2 = 35,
LoongArch_FCC3 = 36,
LoongArch_FCC4 = 37,
LoongArch_FCC5 = 38,
LoongArch_FCC6 = 39,
LoongArch_FCC7 = 40,
LoongArch_FCSR0 = 41,
LoongArch_FCSR1 = 42,
LoongArch_FCSR2 = 43,
LoongArch_FCSR3 = 44,
LoongArch_R0 = 45,
LoongArch_R1 = 46,
LoongArch_R2 = 47,
LoongArch_R3 = 48,
LoongArch_R4 = 49,
LoongArch_R5 = 50,
LoongArch_R6 = 51,
LoongArch_R7 = 52,
LoongArch_R8 = 53,
LoongArch_R9 = 54,
LoongArch_R10 = 55,
LoongArch_R11 = 56,
LoongArch_R12 = 57,
LoongArch_R13 = 58,
LoongArch_R14 = 59,
LoongArch_R15 = 60,
LoongArch_R16 = 61,
LoongArch_R17 = 62,
LoongArch_R18 = 63,
LoongArch_R19 = 64,
LoongArch_R20 = 65,
LoongArch_R21 = 66,
LoongArch_R22 = 67,
LoongArch_R23 = 68,
LoongArch_R24 = 69,
LoongArch_R25 = 70,
LoongArch_R26 = 71,
LoongArch_R27 = 72,
LoongArch_R28 = 73,
LoongArch_R29 = 74,
LoongArch_R30 = 75,
LoongArch_R31 = 76,
LoongArch_SCR0 = 77,
LoongArch_SCR1 = 78,
LoongArch_SCR2 = 79,
LoongArch_SCR3 = 80,
LoongArch_VR0 = 81,
LoongArch_VR1 = 82,
LoongArch_VR2 = 83,
LoongArch_VR3 = 84,
LoongArch_VR4 = 85,
LoongArch_VR5 = 86,
LoongArch_VR6 = 87,
LoongArch_VR7 = 88,
LoongArch_VR8 = 89,
LoongArch_VR9 = 90,
LoongArch_VR10 = 91,
LoongArch_VR11 = 92,
LoongArch_VR12 = 93,
LoongArch_VR13 = 94,
LoongArch_VR14 = 95,
LoongArch_VR15 = 96,
LoongArch_VR16 = 97,
LoongArch_VR17 = 98,
LoongArch_VR18 = 99,
LoongArch_VR19 = 100,
LoongArch_VR20 = 101,
LoongArch_VR21 = 102,
LoongArch_VR22 = 103,
LoongArch_VR23 = 104,
LoongArch_VR24 = 105,
LoongArch_VR25 = 106,
LoongArch_VR26 = 107,
LoongArch_VR27 = 108,
LoongArch_VR28 = 109,
LoongArch_VR29 = 110,
LoongArch_VR30 = 111,
LoongArch_VR31 = 112,
LoongArch_XR0 = 113,
LoongArch_XR1 = 114,
LoongArch_XR2 = 115,
LoongArch_XR3 = 116,
LoongArch_XR4 = 117,
LoongArch_XR5 = 118,
LoongArch_XR6 = 119,
LoongArch_XR7 = 120,
LoongArch_XR8 = 121,
LoongArch_XR9 = 122,
LoongArch_XR10 = 123,
LoongArch_XR11 = 124,
LoongArch_XR12 = 125,
LoongArch_XR13 = 126,
LoongArch_XR14 = 127,
LoongArch_XR15 = 128,
LoongArch_XR16 = 129,
LoongArch_XR17 = 130,
LoongArch_XR18 = 131,
LoongArch_XR19 = 132,
LoongArch_XR20 = 133,
LoongArch_XR21 = 134,
LoongArch_XR22 = 135,
LoongArch_XR23 = 136,
LoongArch_XR24 = 137,
LoongArch_XR25 = 138,
LoongArch_XR26 = 139,
LoongArch_XR27 = 140,
LoongArch_XR28 = 141,
LoongArch_XR29 = 142,
LoongArch_XR30 = 143,
LoongArch_XR31 = 144,
LoongArch_F0_64 = 145,
LoongArch_F1_64 = 146,
LoongArch_F2_64 = 147,
LoongArch_F3_64 = 148,
LoongArch_F4_64 = 149,
LoongArch_F5_64 = 150,
LoongArch_F6_64 = 151,
LoongArch_F7_64 = 152,
LoongArch_F8_64 = 153,
LoongArch_F9_64 = 154,
LoongArch_F10_64 = 155,
LoongArch_F11_64 = 156,
LoongArch_F12_64 = 157,
LoongArch_F13_64 = 158,
LoongArch_F14_64 = 159,
LoongArch_F15_64 = 160,
LoongArch_F16_64 = 161,
LoongArch_F17_64 = 162,
LoongArch_F18_64 = 163,
LoongArch_F19_64 = 164,
LoongArch_F20_64 = 165,
LoongArch_F21_64 = 166,
LoongArch_F22_64 = 167,
LoongArch_F23_64 = 168,
LoongArch_F24_64 = 169,
LoongArch_F25_64 = 170,
LoongArch_F26_64 = 171,
LoongArch_F27_64 = 172,
LoongArch_F28_64 = 173,
LoongArch_F29_64 = 174,
LoongArch_F30_64 = 175,
LoongArch_F31_64 = 176,
NUM_TARGET_REGS // 177
};
// Register classes
enum {
LoongArch_FPR32RegClassID = 0,
LoongArch_GPRRegClassID = 1,
LoongArch_GPRTRegClassID = 2,
LoongArch_CFRRegClassID = 3,
LoongArch_FCSRRegClassID = 4,
LoongArch_SCRRegClassID = 5,
LoongArch_FPR64RegClassID = 6,
LoongArch_LSX128RegClassID = 7,
LoongArch_LASX256RegClassID = 8,
};
// Register alternate name indices
enum {
LoongArch_NoRegAltName, // 0
LoongArch_RegAliasName, // 1
NUM_TARGET_REG_ALT_NAMES = 2
};
// Subregister indices
enum {
LoongArch_NoSubRegister,
LoongArch_sub_32, // 1
LoongArch_sub_64, // 2
LoongArch_sub_128, // 3
LoongArch_NUM_TARGET_SUBREGS
};
#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 LoongArchRegDiffLists[] = {
/* 0 */ -32, 64, -144, 0,
/* 4 */ 144, -64, 32, 0,
};
static const uint16_t LoongArchSubRegIdxLists[] = {
/* 0 */ 3, 2, 1, 0,
};
static const MCRegisterDesc LoongArchRegDesc[] = { // Descriptors
{ 3, 0, 0, 0, 0, 0 },
{ 47, 3, 4, 3, 12288, 2 },
{ 116, 3, 4, 3, 12289, 2 },
{ 171, 3, 4, 3, 12290, 2 },
{ 226, 3, 4, 3, 12291, 2 },
{ 495, 3, 4, 3, 12292, 2 },
{ 539, 3, 4, 3, 12293, 2 },
{ 583, 3, 4, 3, 12294, 2 },
{ 627, 3, 4, 3, 12295, 2 },
{ 666, 3, 4, 3, 12296, 2 },
{ 705, 3, 4, 3, 12297, 2 },
{ 0, 3, 4, 3, 12298, 2 },
{ 69, 3, 4, 3, 12299, 2 },
{ 138, 3, 4, 3, 12300, 2 },
{ 193, 3, 4, 3, 12301, 2 },
{ 248, 3, 4, 3, 12302, 2 },
{ 506, 3, 4, 3, 12303, 2 },
{ 550, 3, 4, 3, 12304, 2 },
{ 594, 3, 4, 3, 12305, 2 },
{ 638, 3, 4, 3, 12306, 2 },
{ 677, 3, 4, 3, 12307, 2 },
{ 14, 3, 4, 3, 12308, 2 },
{ 83, 3, 4, 3, 12309, 2 },
{ 152, 3, 4, 3, 12310, 2 },
{ 207, 3, 4, 3, 12311, 2 },
{ 262, 3, 4, 3, 12312, 2 },
{ 520, 3, 4, 3, 12313, 2 },
{ 564, 3, 4, 3, 12314, 2 },
{ 608, 3, 4, 3, 12315, 2 },
{ 652, 3, 4, 3, 12316, 2 },
{ 691, 3, 4, 3, 12317, 2 },
{ 28, 3, 4, 3, 12318, 2 },
{ 97, 3, 4, 3, 12319, 2 },
{ 42, 3, 3, 3, 12320, 2 },
{ 111, 3, 3, 3, 12321, 2 },
{ 166, 3, 3, 3, 12322, 2 },
{ 221, 3, 3, 3, 12323, 2 },
{ 490, 3, 3, 3, 12324, 2 },
{ 534, 3, 3, 3, 12325, 2 },
{ 578, 3, 3, 3, 12326, 2 },
{ 622, 3, 3, 3, 12327, 2 },
{ 55, 3, 3, 3, 12328, 2 },
{ 124, 3, 3, 3, 12329, 2 },
{ 179, 3, 3, 3, 12330, 2 },
{ 234, 3, 3, 3, 12331, 2 },
{ 52, 3, 3, 3, 12332, 2 },
{ 121, 3, 3, 3, 12333, 2 },
{ 176, 3, 3, 3, 12334, 2 },
{ 231, 3, 3, 3, 12335, 2 },
{ 499, 3, 3, 3, 12336, 2 },
{ 543, 3, 3, 3, 12337, 2 },
{ 587, 3, 3, 3, 12338, 2 },
{ 631, 3, 3, 3, 12339, 2 },
{ 670, 3, 3, 3, 12340, 2 },
{ 709, 3, 3, 3, 12341, 2 },
{ 5, 3, 3, 3, 12342, 2 },
{ 74, 3, 3, 3, 12343, 2 },
{ 143, 3, 3, 3, 12344, 2 },
{ 198, 3, 3, 3, 12345, 2 },
{ 253, 3, 3, 3, 12346, 2 },
{ 511, 3, 3, 3, 12347, 2 },
{ 555, 3, 3, 3, 12348, 2 },
{ 599, 3, 3, 3, 12349, 2 },
{ 643, 3, 3, 3, 12350, 2 },
{ 682, 3, 3, 3, 12351, 2 },
{ 19, 3, 3, 3, 12352, 2 },
{ 88, 3, 3, 3, 12353, 2 },
{ 157, 3, 3, 3, 12354, 2 },
{ 212, 3, 3, 3, 12355, 2 },
{ 267, 3, 3, 3, 12356, 2 },
{ 525, 3, 3, 3, 12357, 2 },
{ 569, 3, 3, 3, 12358, 2 },
{ 613, 3, 3, 3, 12359, 2 },
{ 657, 3, 3, 3, 12360, 2 },
{ 696, 3, 3, 3, 12361, 2 },
{ 33, 3, 3, 3, 12362, 2 },
{ 102, 3, 3, 3, 12363, 2 },
{ 50, 3, 3, 3, 12364, 2 },
{ 119, 3, 3, 3, 12365, 2 },
{ 174, 3, 3, 3, 12366, 2 },
{ 229, 3, 3, 3, 12367, 2 },
{ 61, 1, 6, 1, 12288, 0 },
{ 130, 1, 6, 1, 12289, 0 },
{ 185, 1, 6, 1, 12290, 0 },
{ 240, 1, 6, 1, 12291, 0 },
{ 498, 1, 6, 1, 12292, 0 },
{ 542, 1, 6, 1, 12293, 0 },
{ 586, 1, 6, 1, 12294, 0 },
{ 630, 1, 6, 1, 12295, 0 },
{ 669, 1, 6, 1, 12296, 0 },
{ 708, 1, 6, 1, 12297, 0 },
{ 4, 1, 6, 1, 12298, 0 },
{ 73, 1, 6, 1, 12299, 0 },
{ 142, 1, 6, 1, 12300, 0 },
{ 197, 1, 6, 1, 12301, 0 },
{ 252, 1, 6, 1, 12302, 0 },
{ 510, 1, 6, 1, 12303, 0 },
{ 554, 1, 6, 1, 12304, 0 },
{ 598, 1, 6, 1, 12305, 0 },
{ 642, 1, 6, 1, 12306, 0 },
{ 681, 1, 6, 1, 12307, 0 },
{ 18, 1, 6, 1, 12308, 0 },
{ 87, 1, 6, 1, 12309, 0 },
{ 156, 1, 6, 1, 12310, 0 },
{ 211, 1, 6, 1, 12311, 0 },
{ 266, 1, 6, 1, 12312, 0 },
{ 524, 1, 6, 1, 12313, 0 },
{ 568, 1, 6, 1, 12314, 0 },
{ 612, 1, 6, 1, 12315, 0 },
{ 656, 1, 6, 1, 12316, 0 },
{ 695, 1, 6, 1, 12317, 0 },
{ 32, 1, 6, 1, 12318, 0 },
{ 101, 1, 6, 1, 12319, 0 },
{ 65, 0, 3, 0, 12288, 0 },
{ 134, 0, 3, 0, 12289, 0 },
{ 189, 0, 3, 0, 12290, 0 },
{ 244, 0, 3, 0, 12291, 0 },
{ 502, 0, 3, 0, 12292, 0 },
{ 546, 0, 3, 0, 12293, 0 },
{ 590, 0, 3, 0, 12294, 0 },
{ 634, 0, 3, 0, 12295, 0 },
{ 673, 0, 3, 0, 12296, 0 },
{ 712, 0, 3, 0, 12297, 0 },
{ 9, 0, 3, 0, 12298, 0 },
{ 78, 0, 3, 0, 12299, 0 },
{ 147, 0, 3, 0, 12300, 0 },
{ 202, 0, 3, 0, 12301, 0 },
{ 257, 0, 3, 0, 12302, 0 },
{ 515, 0, 3, 0, 12303, 0 },
{ 559, 0, 3, 0, 12304, 0 },
{ 603, 0, 3, 0, 12305, 0 },
{ 647, 0, 3, 0, 12306, 0 },
{ 686, 0, 3, 0, 12307, 0 },
{ 23, 0, 3, 0, 12308, 0 },
{ 92, 0, 3, 0, 12309, 0 },
{ 161, 0, 3, 0, 12310, 0 },
{ 216, 0, 3, 0, 12311, 0 },
{ 271, 0, 3, 0, 12312, 0 },
{ 529, 0, 3, 0, 12313, 0 },
{ 573, 0, 3, 0, 12314, 0 },
{ 617, 0, 3, 0, 12315, 0 },
{ 661, 0, 3, 0, 12316, 0 },
{ 700, 0, 3, 0, 12317, 0 },
{ 37, 0, 3, 0, 12318, 0 },
{ 106, 0, 3, 0, 12319, 0 },
{ 297, 2, 5, 2, 12288, 0 },
{ 324, 2, 5, 2, 12289, 0 },
{ 344, 2, 5, 2, 12290, 0 },
{ 364, 2, 5, 2, 12291, 0 },
{ 384, 2, 5, 2, 12292, 0 },
{ 404, 2, 5, 2, 12293, 0 },
{ 424, 2, 5, 2, 12294, 0 },
{ 444, 2, 5, 2, 12295, 0 },
{ 464, 2, 5, 2, 12296, 0 },
{ 484, 2, 5, 2, 12297, 0 },
{ 276, 2, 5, 2, 12298, 0 },
{ 303, 2, 5, 2, 12299, 0 },
{ 330, 2, 5, 2, 12300, 0 },
{ 350, 2, 5, 2, 12301, 0 },
{ 370, 2, 5, 2, 12302, 0 },
{ 390, 2, 5, 2, 12303, 0 },
{ 410, 2, 5, 2, 12304, 0 },
{ 430, 2, 5, 2, 12305, 0 },
{ 450, 2, 5, 2, 12306, 0 },
{ 470, 2, 5, 2, 12307, 0 },
{ 283, 2, 5, 2, 12308, 0 },
{ 310, 2, 5, 2, 12309, 0 },
{ 337, 2, 5, 2, 12310, 0 },
{ 357, 2, 5, 2, 12311, 0 },
{ 377, 2, 5, 2, 12312, 0 },
{ 397, 2, 5, 2, 12313, 0 },
{ 417, 2, 5, 2, 12314, 0 },
{ 437, 2, 5, 2, 12315, 0 },
{ 457, 2, 5, 2, 12316, 0 },
{ 477, 2, 5, 2, 12317, 0 },
{ 290, 2, 5, 2, 12318, 0 },
{ 317, 2, 5, 2, 12319, 0 },
};
// FPR32 Register Class...
static const MCPhysReg FPR32[] = {
LoongArch_F0, LoongArch_F1, LoongArch_F2, LoongArch_F3, LoongArch_F4, LoongArch_F5, LoongArch_F6, LoongArch_F7, LoongArch_F8, LoongArch_F9, LoongArch_F10, LoongArch_F11, LoongArch_F12, LoongArch_F13, LoongArch_F14, LoongArch_F15, LoongArch_F16, LoongArch_F17, LoongArch_F18, LoongArch_F19, LoongArch_F20, LoongArch_F21, LoongArch_F22, LoongArch_F23, LoongArch_F24, LoongArch_F25, LoongArch_F26, LoongArch_F27, LoongArch_F28, LoongArch_F29, LoongArch_F30, LoongArch_F31,
};
// FPR32 Bit set.
static const uint8_t FPR32Bits[] = {
0xfe, 0xff, 0xff, 0xff, 0x01,
};
// GPR Register Class...
static const MCPhysReg GPR[] = {
LoongArch_R4, LoongArch_R5, LoongArch_R6, LoongArch_R7, LoongArch_R8, LoongArch_R9, LoongArch_R10, LoongArch_R11, LoongArch_R12, LoongArch_R13, LoongArch_R14, LoongArch_R15, LoongArch_R16, LoongArch_R17, LoongArch_R18, LoongArch_R19, LoongArch_R20, LoongArch_R22, LoongArch_R23, LoongArch_R24, LoongArch_R25, LoongArch_R26, LoongArch_R27, LoongArch_R28, LoongArch_R29, LoongArch_R30, LoongArch_R31, LoongArch_R0, LoongArch_R1, LoongArch_R2, LoongArch_R3, LoongArch_R21,
};
// GPR Bit set.
static const uint8_t GPRBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x1f,
};
// GPRT Register Class...
static const MCPhysReg GPRT[] = {
LoongArch_R4, LoongArch_R5, LoongArch_R6, LoongArch_R7, LoongArch_R8, LoongArch_R9, LoongArch_R10, LoongArch_R11, LoongArch_R12, LoongArch_R13, LoongArch_R14, LoongArch_R15, LoongArch_R16, LoongArch_R17, LoongArch_R18, LoongArch_R19, LoongArch_R20,
};
// GPRT Bit set.
static const uint8_t GPRTBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x03,
};
// CFR Register Class...
static const MCPhysReg CFR[] = {
LoongArch_FCC0, LoongArch_FCC1, LoongArch_FCC2, LoongArch_FCC3, LoongArch_FCC4, LoongArch_FCC5, LoongArch_FCC6, LoongArch_FCC7,
};
// CFR Bit set.
static const uint8_t CFRBits[] = {
0x00, 0x00, 0x00, 0x00, 0xfe, 0x01,
};
// FCSR Register Class...
static const MCPhysReg FCSR[] = {
LoongArch_FCSR0, LoongArch_FCSR1, LoongArch_FCSR2, LoongArch_FCSR3,
};
// FCSR Bit set.
static const uint8_t FCSRBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
};
// SCR Register Class...
static const MCPhysReg SCR[] = {
LoongArch_SCR0, LoongArch_SCR1, LoongArch_SCR2, LoongArch_SCR3,
};
// SCR Bit set.
static const uint8_t SCRBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01,
};
// FPR64 Register Class...
static const MCPhysReg FPR64[] = {
LoongArch_F0_64, LoongArch_F1_64, LoongArch_F2_64, LoongArch_F3_64, LoongArch_F4_64, LoongArch_F5_64, LoongArch_F6_64, LoongArch_F7_64, LoongArch_F8_64, LoongArch_F9_64, LoongArch_F10_64, LoongArch_F11_64, LoongArch_F12_64, LoongArch_F13_64, LoongArch_F14_64, LoongArch_F15_64, LoongArch_F16_64, LoongArch_F17_64, LoongArch_F18_64, LoongArch_F19_64, LoongArch_F20_64, LoongArch_F21_64, LoongArch_F22_64, LoongArch_F23_64, LoongArch_F24_64, LoongArch_F25_64, LoongArch_F26_64, LoongArch_F27_64, LoongArch_F28_64, LoongArch_F29_64, LoongArch_F30_64, LoongArch_F31_64,
};
// FPR64 Bit set.
static const uint8_t FPR64Bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01,
};
// LSX128 Register Class...
static const MCPhysReg LSX128[] = {
LoongArch_VR0, LoongArch_VR1, LoongArch_VR2, LoongArch_VR3, LoongArch_VR4, LoongArch_VR5, LoongArch_VR6, LoongArch_VR7, LoongArch_VR8, LoongArch_VR9, LoongArch_VR10, LoongArch_VR11, LoongArch_VR12, LoongArch_VR13, LoongArch_VR14, LoongArch_VR15, LoongArch_VR16, LoongArch_VR17, LoongArch_VR18, LoongArch_VR19, LoongArch_VR20, LoongArch_VR21, LoongArch_VR22, LoongArch_VR23, LoongArch_VR24, LoongArch_VR25, LoongArch_VR26, LoongArch_VR27, LoongArch_VR28, LoongArch_VR29, LoongArch_VR30, LoongArch_VR31,
};
// LSX128 Bit set.
static const uint8_t LSX128Bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01,
};
// LASX256 Register Class...
static const MCPhysReg LASX256[] = {
LoongArch_XR0, LoongArch_XR1, LoongArch_XR2, LoongArch_XR3, LoongArch_XR4, LoongArch_XR5, LoongArch_XR6, LoongArch_XR7, LoongArch_XR8, LoongArch_XR9, LoongArch_XR10, LoongArch_XR11, LoongArch_XR12, LoongArch_XR13, LoongArch_XR14, LoongArch_XR15, LoongArch_XR16, LoongArch_XR17, LoongArch_XR18, LoongArch_XR19, LoongArch_XR20, LoongArch_XR21, LoongArch_XR22, LoongArch_XR23, LoongArch_XR24, LoongArch_XR25, LoongArch_XR26, LoongArch_XR27, LoongArch_XR28, LoongArch_XR29, LoongArch_XR30, LoongArch_XR31,
};
// LASX256 Bit set.
static const uint8_t LASX256Bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01,
};
static const MCRegisterClass LoongArchMCRegisterClasses[] = {
{ FPR32, FPR32Bits, sizeof(FPR32Bits) },
{ GPR, GPRBits, sizeof(GPRBits) },
{ GPRT, GPRTBits, sizeof(GPRTBits) },
{ CFR, CFRBits, sizeof(CFRBits) },
{ FCSR, FCSRBits, sizeof(FCSRBits) },
{ SCR, SCRBits, sizeof(SCRBits) },
{ FPR64, FPR64Bits, sizeof(FPR64Bits) },
{ LSX128, LSX128Bits, sizeof(LSX128Bits) },
{ LASX256, LASX256Bits, sizeof(LASX256Bits) },
};
static const uint16_t LoongArchRegEncodingTable[] = {
0,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
4,
5,
6,
7,
0,
1,
2,
3,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
};
#endif // GET_REGINFO_MC_DESC
@@ -0,0 +1,38 @@
/* 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 {
LoongArch_Feature32Bit = 0,
LoongArch_Feature64Bit = 1,
LoongArch_FeatureAutoVec = 2,
LoongArch_FeatureBasicD = 3,
LoongArch_FeatureBasicF = 4,
LoongArch_FeatureExtLASX = 5,
LoongArch_FeatureExtLBT = 6,
LoongArch_FeatureExtLSX = 7,
LoongArch_FeatureExtLVZ = 8,
LoongArch_FeatureFrecipe = 9,
LoongArch_FeatureRelax = 10,
LoongArch_FeatureUAL = 11,
LoongArch_LaGlobalWithAbs = 12,
LoongArch_LaGlobalWithPcrel = 13,
LoongArch_LaLocalWithAbs = 14,
LoongArch_NumSubtargetFeatures = 15
};
#endif // GET_SUBTARGETINFO_ENUM
+141
View File
@@ -0,0 +1,141 @@
/* 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 */
//===- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to asm syntax --===//
//
// 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 LoongArch MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include "LoongArchMapping.h"
#include "LoongArchInstPrinter.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-asm-printer"
// Include the auto-generated portion of the assembly writer.
#define PRINT_ALIAS_INSTR
#include "LoongArchGenAsmWriter.inc"
static void printInst(MCInst *MI, uint64_t Address, const char *Annot,
SStream *O)
{
bool useAliasDetails = map_use_alias_details(MI);
map_set_fill_detail_ops(MI, useAliasDetails);
bool isAlias = printAliasInstr(MI, Address, O);
MCInst_setIsAlias(MI, isAlias);
if (!isAlias || !useAliasDetails) {
map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails));
if (isAlias)
SStream_Close(O);
printInstruction(MI, Address, O);
if (isAlias)
SStream_Open(O);
}
}
void LoongArch_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
SStream *O)
{
printInst(MI, Address, Annot, O);
}
const char *LoongArch_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx)
{
return getRegisterName(RegNo, AltIdx);
}
static void printRegName(MCInst *MI, SStream *O, MCRegister Reg)
{
int syntax_opt = MI->csh->syntax;
if (!(syntax_opt & CS_OPT_SYNTAX_NO_DOLLAR)) {
SStream_concat1(O, '$');
}
SStream_concat0(O, getRegisterName(Reg, LoongArch_RegAliasName));
}
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
add_cs_detail(MI, LoongArch_OP_GROUP_Operand, OpNo);
MCOperand *MO = MCInst_getOperand(MI, (OpNo));
if (MCOperand_isReg(MO)) {
printRegName(MI, O, MCOperand_getReg(MO));
return;
}
if (MCOperand_isImm(MO)) {
// rewrite offset immediate operand to absolute address in direct branch instructions
// convert e.g.
// 0x1000: beqz $t0, 0xc
// to:
// 0x1000: beqz $t0, 0x100c
switch (MI->flat_insn->id) {
case LOONGARCH_INS_B:
case LOONGARCH_INS_BCEQZ:
case LOONGARCH_INS_BCNEZ:
case LOONGARCH_INS_BEQ:
case LOONGARCH_INS_BEQZ:
case LOONGARCH_INS_BGE:
case LOONGARCH_INS_BGEU:
case LOONGARCH_INS_BL:
case LOONGARCH_INS_BLT:
case LOONGARCH_INS_BLTU:
case LOONGARCH_INS_BNE:
case LOONGARCH_INS_BNEZ:
printInt64(O, MCOperand_getImm(MO) + MI->address);
return;
default:
break;
}
printInt64(O, MCOperand_getImm(MO));
return;
}
CS_ASSERT_RET(0 && "Expressions are not supported.");
}
static void printAtomicMemOp(MCInst *MI, unsigned OpNo, SStream *O)
{
add_cs_detail(MI, LoongArch_OP_GROUP_AtomicMemOp, OpNo);
MCOperand *MO = MCInst_getOperand(MI, (OpNo));
printRegName(MI, O, MCOperand_getReg(MO));
}
+54
View File
@@ -0,0 +1,54 @@
/* 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 */
//===-- LoongArchInstPrinter.h - Convert LoongArch MCInst to asm syntax ---===//
//
// 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 a LoongArch MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include "../../MCInstPrinter.h"
#include "../../cs_priv.h"
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
static void printInst(MCInst *MI, uint64_t Address, const char *Annot,
SStream *O);
static void printRegName(MCInst *MI, SStream *O, MCRegister Reg);
static void printAtomicMemOp(MCInst *MI, unsigned OpNo, SStream *O);
// Autogenerated by tblgen.
static void printInstruction(MCInst *MI, uint64_t Address, SStream *O);
static bool printAliasInstr(MCInst *MI, uint64_t Address, SStream *O);
static void printCustomAliasOperand(MCInst *MI, uint64_t Address,
unsigned OpIdx, unsigned PrintMethodIdx,
SStream *O);
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
;
// end namespace llvm
#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
+24
View File
@@ -0,0 +1,24 @@
/* Capstone Disassembly Engine */
/* By Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifndef CS_LOONGARCH_LINKAGE_H
#define CS_LOONGARCH_LINKAGE_H
// Function definitions to call static LLVM functions.
#include "../../MCDisassembler.h"
#include "../../MCInst.h"
#include "../../MCRegisterInfo.h"
#include "../../SStream.h"
#include "capstone/capstone.h"
const char *LoongArch_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx);
void LoongArch_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,
SStream *O);
DecodeStatus LoongArch_LLVM_getInstruction(MCInst *MI, uint64_t *Size,
const uint8_t *Bytes,
size_t BytesLen, uint64_t Address,
SStream *CS);
#endif // CS_LOONGARCH_LINKAGE_H
+573
View File
@@ -0,0 +1,573 @@
/* Capstone Disassembly Engine */
/* By Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifdef CAPSTONE_HAS_LOONGARCH
#include <stdio.h>
#include <string.h>
#include <capstone/capstone.h>
#include <capstone/loongarch.h>
#include "../../Mapping.h"
#include "../../MCDisassembler.h"
#include "../../cs_priv.h"
#include "../../cs_simple_types.h"
#include "LoongArchMapping.h"
#include "LoongArchLinkage.h"
#define GET_REGINFO_ENUM
#define GET_REGINFO_MC_DESC
#include "LoongArchGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#include "LoongArchGenInstrInfo.inc"
void LoongArch_init_mri(MCRegisterInfo *MRI)
{
MCRegisterInfo_InitMCRegisterInfo(MRI, LoongArchRegDesc,
sizeof(LoongArchRegDesc), 0, 0,
LoongArchMCRegisterClasses,
ARR_SIZE(LoongArchMCRegisterClasses),
0, 0, LoongArchRegDiffLists, 0,
LoongArchSubRegIdxLists,
ARR_SIZE(LoongArchSubRegIdxLists), 0);
}
const char *LoongArch_reg_name(csh handle, unsigned int reg)
{
int syntax_opt = ((cs_struct *)(uintptr_t)handle)->syntax;
if (syntax_opt & CS_OPT_SYNTAX_NOREGNAME) {
return LoongArch_LLVM_getRegisterName(reg,
LoongArch_NoRegAltName);
}
return LoongArch_LLVM_getRegisterName(reg, LoongArch_RegAliasName);
}
void LoongArch_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{
// Not used by LoongArch. Information is set after disassembly.
}
static const char *const insn_name_maps[] = {
#include "LoongArchGenCSMappingInsnName.inc"
};
#ifndef CAPSTONE_DIET
static const name_map insn_alias_mnem_map[] = {
#include "LoongArchGenCSAliasMnemMap.inc"
{ LOONGARCH_INS_ALIAS_END, NULL },
};
#endif
const char *LoongArch_insn_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
if (id < LOONGARCH_INS_ALIAS_END && id > LOONGARCH_INS_ALIAS_BEGIN) {
if (id - LOONGARCH_INS_ALIAS_BEGIN >=
ARR_SIZE(insn_alias_mnem_map))
return NULL;
return insn_alias_mnem_map[id - LOONGARCH_INS_ALIAS_BEGIN - 1]
.name;
}
if (id >= LOONGARCH_INS_ENDING)
return NULL;
if (id < ARR_SIZE(insn_name_maps))
return insn_name_maps[id];
// not found
return NULL;
#else
return NULL;
#endif
}
#ifndef CAPSTONE_DIET
static const name_map group_name_maps[] = {
{ LOONGARCH_GRP_INVALID, NULL },
{ LOONGARCH_GRP_JUMP, "jump" },
{ LOONGARCH_GRP_CALL, "call" },
{ LOONGARCH_GRP_RET, "return" },
{ LOONGARCH_GRP_INT, "int" },
{ LOONGARCH_GRP_IRET, "iret" },
{ LOONGARCH_GRP_PRIVILEGE, "privilege" },
{ LOONGARCH_GRP_BRANCH_RELATIVE, "branch_relative" },
// architecture-specific groups
#include "LoongArchGenCSFeatureName.inc"
};
#endif
const char *LoongArch_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
}
void LoongArch_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_loongarch *loongarch = &(insn->detail->loongarch);
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 < loongarch->op_count; i++) {
cs_loongarch_op *op = &(loongarch->operands[i]);
switch ((int)op->type) {
case LOONGARCH_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 LOONGARCH_OP_MEM:
// registers appeared in memory references always being read
if ((op->mem.base != LOONGARCH_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 != LOONGARCH_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;
}
const insn_map loongarch_insns[] = {
#include "LoongArchGenCSMappingInsn.inc"
};
void LoongArch_rewrite_memory_operand(MCInst *MI)
{
// rewrite base + disp operands to memory operands in memory instructions
// convert e.g.
// ld.d $t3, $t2, 0x410
// op_count: 3
// operands[0].type: REG = t3
// operands[0].access: WRITE
// operands[1].type: REG = t2
// operands[1].access: READ
// operands[2].type: IMM = 0x410
// operands[2].access: READ
// to:
// op_count: 3
// operands[0].type: REG = t3
// operands[0].access: WRITE
// operands[1].type: MEM
// operands[1].mem.base: REG = t2
// operands[1].mem.disp: 0x410
// operands[1].access: READ
if (!detail_is_set(MI))
return;
const loongarch_suppl_info *suppl_info =
map_get_suppl_info(MI, loongarch_insns);
if (!suppl_info)
return;
if (suppl_info->memory_access == CS_AC_INVALID) {
// not memory instruction
return;
}
// handle special cases
unsigned int base;
switch (MI->flat_insn->id) {
case LOONGARCH_INS_SC_Q:
case LOONGARCH_INS_LLACQ_W:
case LOONGARCH_INS_LLACQ_D:
case LOONGARCH_INS_SCREL_W:
case LOONGARCH_INS_SCREL_D:
// last register rj is memory operand
LoongArch_get_detail_op(MI, -1)->type = LOONGARCH_OP_MEM;
base = LoongArch_get_detail_op(MI, -1)->reg;
LoongArch_get_detail_op(MI, -1)->mem.base = base;
LoongArch_get_detail_op(MI, -1)->access =
suppl_info->memory_access;
return;
case LOONGARCH_INS_LDGT_B:
case LOONGARCH_INS_LDGT_H:
case LOONGARCH_INS_LDGT_W:
case LOONGARCH_INS_LDGT_D:
case LOONGARCH_INS_LDLE_B:
case LOONGARCH_INS_LDLE_H:
case LOONGARCH_INS_LDLE_W:
case LOONGARCH_INS_LDLE_D:
case LOONGARCH_INS_STGT_B:
case LOONGARCH_INS_STGT_H:
case LOONGARCH_INS_STGT_W:
case LOONGARCH_INS_STGT_D:
case LOONGARCH_INS_STLE_B:
case LOONGARCH_INS_STLE_H:
case LOONGARCH_INS_STLE_W:
case LOONGARCH_INS_STLE_D:
case LOONGARCH_INS_FLDLE_S:
case LOONGARCH_INS_FLDLE_D:
case LOONGARCH_INS_FLDGT_S:
case LOONGARCH_INS_FLDGT_D:
case LOONGARCH_INS_FSTLE_S:
case LOONGARCH_INS_FSTLE_D:
case LOONGARCH_INS_FSTGT_S:
case LOONGARCH_INS_FSTGT_D:
// second register rj is memory operand
LoongArch_get_detail_op(MI, -2)->type = LOONGARCH_OP_MEM;
base = LoongArch_get_detail_op(MI, -2)->reg;
LoongArch_get_detail_op(MI, -2)->mem.base = base;
LoongArch_get_detail_op(MI, -2)->access =
suppl_info->memory_access;
return;
default:
break;
}
switch (suppl_info->form) {
case LOONGARCH_INSN_FORM_FMT2RI12: // ld, ldl, ldr, st, stl, str
case LOONGARCH_INSN_FORM_FMT2RI14: // ll, sc, ldptr, stptr
case LOONGARCH_INSN_FORM_FMT2RI9_VRI: // vldrepl.d
case LOONGARCH_INSN_FORM_FMT2RI10_VRI: // vldrepl.w
case LOONGARCH_INSN_FORM_FMT2RI11_VRI: // vldrepl.h
case LOONGARCH_INSN_FORM_FMT2RI12_VRI: // vld, vldrepl, vst
case LOONGARCH_INSN_FORM_FMT2RI8I1_VRII: // vstelm.d
case LOONGARCH_INSN_FORM_FMT2RI8I2_VRII: // vstelm.w
case LOONGARCH_INSN_FORM_FMT2RI8I3_VRII: // vstelm.h
case LOONGARCH_INSN_FORM_FMT2RI8I4_VRII: // vstelm.b
case LOONGARCH_INSN_FORM_FMT2RI9_XRI: // xvldrepl.d
case LOONGARCH_INSN_FORM_FMT2RI10_XRI: // xvldrepl.w
case LOONGARCH_INSN_FORM_FMT2RI11_XRI: // xvldrepl.h
case LOONGARCH_INSN_FORM_FMT2RI12_XRI: // xvld, xvldrepl, xvst
case LOONGARCH_INSN_FORM_FMT2RI8I2_XRII: // xvstelm.d
case LOONGARCH_INSN_FORM_FMT2RI8I3_XRII: // xvstelm.w
case LOONGARCH_INSN_FORM_FMT2RI8I4_XRII: // xvstelm.h
case LOONGARCH_INSN_FORM_FMT2RI8I5_XRII: // xvstelm.b
case LOONGARCH_INSN_FORM_FMTPRELD: // preld
case LOONGARCH_INSN_FORM_FPFMT2RI12: // fld, fst
// immediate offset
LoongArch_get_detail_op(MI, -2)->type = LOONGARCH_OP_MEM;
base = LoongArch_get_detail_op(MI, -2)->reg;
LoongArch_get_detail_op(MI, -2)->mem.base = base;
LoongArch_get_detail_op(MI, -2)->mem.disp =
LoongArch_get_detail_op(MI, -1)->imm;
LoongArch_get_detail_op(MI, -2)->access =
suppl_info->memory_access;
LoongArch_dec_op_count(MI);
break;
case LOONGARCH_INSN_FORM_FMT3R: // ldx, stx, amo
if (suppl_info->memory_access == CS_AC_READ_WRITE) {
// amo: read + write
// last register rj is memory operand
LoongArch_get_detail_op(MI, -1)->type =
LOONGARCH_OP_MEM;
base = LoongArch_get_detail_op(MI, -1)->reg;
LoongArch_get_detail_op(MI, -1)->mem.base = base;
LoongArch_get_detail_op(MI, -1)->access =
suppl_info->memory_access;
break;
}
// fallthrough
case LOONGARCH_INSN_FORM_FPFMTMEM: // fldx, fstx
case LOONGARCH_INSN_FORM_FMT3R_VRR: // vldx, vstx
case LOONGARCH_INSN_FORM_FMT3R_XRR: // xvldx, xvstx
case LOONGARCH_INSN_FORM_FMTPRELDX: // preldx
// register offset
LoongArch_get_detail_op(MI, -2)->type = LOONGARCH_OP_MEM;
base = LoongArch_get_detail_op(MI, -2)->reg;
LoongArch_get_detail_op(MI, -2)->mem.base = base;
LoongArch_get_detail_op(MI, -2)->mem.index =
LoongArch_get_detail_op(MI, -1)->reg;
LoongArch_get_detail_op(MI, -2)->access =
suppl_info->memory_access;
LoongArch_dec_op_count(MI);
break;
default:
CS_ASSERT_RET(0 && "Unknown LoongArch memory instruction");
break;
}
}
void LoongArch_rewrite_address_operand(MCInst *MI)
{
// rewrite offset immediate operand to absolute address in direct branch instructions
// convert e.g.
// 0x1000: beqz $t0, 0x100c
// op_count: 2
// operands[0].type: REG = t0
// operands[0].access: READ
// operands[1].type: IMM = 0xc
// operands[1].access: READ
// to:
// op_count: 2
// operands[0].type: REG = t0
// operands[0].access: READ
// operands[1].type: IMM = 0x100c
// operands[1].access: READ
if (!detail_is_set(MI))
return;
// handle different types of branch instructions
switch (MI->flat_insn->id) {
case LOONGARCH_INS_B:
case LOONGARCH_INS_BCEQZ:
case LOONGARCH_INS_BCNEZ:
case LOONGARCH_INS_BEQ:
case LOONGARCH_INS_BEQZ:
case LOONGARCH_INS_BGE:
case LOONGARCH_INS_BGEU:
case LOONGARCH_INS_BL:
case LOONGARCH_INS_BLT:
case LOONGARCH_INS_BLTU:
case LOONGARCH_INS_BNE:
case LOONGARCH_INS_BNEZ:
// last operand is address operand
LoongArch_get_detail_op(MI, -1)->imm += MI->address;
return;
default:
break;
}
}
void LoongArch_set_instr_map_data(MCInst *MI)
{
map_cs_id(MI, loongarch_insns, ARR_SIZE(loongarch_insns));
map_implicit_reads(MI, loongarch_insns);
map_implicit_writes(MI, loongarch_insns);
map_groups(MI, loongarch_insns);
const loongarch_suppl_info *suppl_info =
map_get_suppl_info(MI, loongarch_insns);
if (suppl_info) {
LoongArch_get_detail(MI)->format = suppl_info->form;
}
}
bool LoongArch_getInstruction(csh handle, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address,
void *info)
{
uint64_t temp_size;
LoongArch_init_cs_detail(instr);
DecodeStatus Result = LoongArch_LLVM_getInstruction(instr, &temp_size, code,
code_len, address, info);
LoongArch_set_instr_map_data(instr);
*size = temp_size;
if (Result == MCDisassembler_SoftFail) {
MCInst_setSoftFail(instr);
}
return Result != MCDisassembler_Fail;
}
/// Adds group to the instruction which are not defined in LLVM.
static void LoongArch_add_cs_groups(MCInst *MI)
{
if (!MI->flat_insn->detail)
return;
unsigned Opcode = MI->flat_insn->id;
cs_loongarch *loongarch = &(MI->flat_insn->detail->loongarch);
switch (Opcode) {
default:
return;
case LOONGARCH_INS_BL:
add_group(MI, LOONGARCH_GRP_CALL);
break;
case LOONGARCH_INS_JIRL:
if (loongarch->op_count == 3 &&
loongarch->operands[0].reg == LOONGARCH_REG_RA) {
// call: jirl ra, rj, offs16
add_group(MI, LOONGARCH_GRP_CALL);
} else if (loongarch->op_count == 0) {
// ret
add_group(MI, LOONGARCH_GRP_RET);
} else if (loongarch->op_count == 1) {
// jr rj
add_group(MI, LOONGARCH_GRP_JUMP);
} else if (loongarch->op_count == 3) {
// none of the above, generic jirl
add_group(MI, LOONGARCH_GRP_JUMP);
}
break;
case LOONGARCH_INS_B:
case LOONGARCH_INS_BCEQZ:
case LOONGARCH_INS_BEQ:
case LOONGARCH_INS_BEQZ:
case LOONGARCH_INS_BGE:
case LOONGARCH_INS_BGEU:
case LOONGARCH_INS_BLT:
case LOONGARCH_INS_BLTU:
case LOONGARCH_INS_BNE:
case LOONGARCH_INS_BNEZ:
add_group(MI, LOONGARCH_GRP_JUMP);
add_group(MI, LOONGARCH_GRP_BRANCH_RELATIVE);
break;
case LOONGARCH_INS_SYSCALL:
add_group(MI, LOONGARCH_GRP_INT);
break;
case LOONGARCH_INS_ERTN:
add_group(MI, LOONGARCH_GRP_IRET);
add_group(MI, LOONGARCH_GRP_PRIVILEGE);
break;
case LOONGARCH_INS_CSRXCHG:
case LOONGARCH_INS_CACOP:
case LOONGARCH_INS_LDDIR:
case LOONGARCH_INS_LDPTE:
case LOONGARCH_INS_IOCSRRD_B:
case LOONGARCH_INS_IOCSRRD_H:
case LOONGARCH_INS_IOCSRRD_W:
case LOONGARCH_INS_IOCSRRD_D:
case LOONGARCH_INS_IOCSRWR_B:
case LOONGARCH_INS_IOCSRWR_H:
case LOONGARCH_INS_IOCSRWR_W:
case LOONGARCH_INS_IOCSRWR_D:
case LOONGARCH_INS_TLBCLR:
case LOONGARCH_INS_TLBFLUSH:
case LOONGARCH_INS_TLBSRCH:
case LOONGARCH_INS_TLBRD:
case LOONGARCH_INS_TLBWR:
case LOONGARCH_INS_INVTLB:
add_group(MI, LOONGARCH_GRP_PRIVILEGE);
break;
}
}
void LoongArch_printer(MCInst *MI, SStream *O,
void * /* MCRegisterInfo* */ info)
{
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
MI->MRI = MRI;
MI->flat_insn->usesAliasDetails = map_use_alias_details(MI);
LoongArch_LLVM_printInst(MI, MI->address, "", O);
LoongArch_rewrite_memory_operand(MI);
LoongArch_rewrite_address_operand(MI);
LoongArch_add_cs_groups(MI);
#ifndef CAPSTONE_DIET
map_set_alias_id(MI, O, insn_alias_mnem_map,
ARR_SIZE(insn_alias_mnem_map));
#endif
}
void LoongArch_setup_op(cs_loongarch_op *op)
{
memset(op, 0, sizeof(cs_loongarch_op));
op->type = LOONGARCH_OP_INVALID;
}
void LoongArch_init_cs_detail(MCInst *MI)
{
if (detail_is_set(MI)) {
unsigned int i;
memset(get_detail(MI), 0,
offsetof(cs_detail, loongarch) + sizeof(cs_loongarch));
for (i = 0; i < ARR_SIZE(LoongArch_get_detail(MI)->operands);
i++)
LoongArch_setup_op(
&LoongArch_get_detail(MI)->operands[i]);
}
}
static const map_insn_ops insn_operands[] = {
#include "LoongArchGenCSMappingInsnOp.inc"
};
void LoongArch_set_detail_op_imm(MCInst *MI, unsigned OpNum,
loongarch_op_type ImmType, int64_t Imm)
{
if (!detail_is_set(MI))
return;
CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_IMM);
CS_ASSERT_RET(ImmType == LOONGARCH_OP_IMM);
LoongArch_get_detail_op(MI, 0)->type = ImmType;
LoongArch_get_detail_op(MI, 0)->imm = Imm;
LoongArch_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
LoongArch_inc_op_count(MI);
}
void LoongArch_set_detail_op_reg(MCInst *MI, unsigned OpNum, loongarch_reg Reg)
{
if (!detail_is_set(MI))
return;
CS_ASSERT_RET((map_get_op_type(MI, OpNum) & ~CS_OP_MEM) == CS_OP_REG);
LoongArch_get_detail_op(MI, 0)->type = LOONGARCH_OP_REG;
LoongArch_get_detail_op(MI, 0)->reg = Reg;
LoongArch_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
LoongArch_inc_op_count(MI);
}
void LoongArch_add_cs_detail(MCInst *MI, int /* loongarch_op_group */ op_group,
va_list args)
{
if (!detail_is_set(MI))
return;
unsigned OpNum = va_arg(args, unsigned);
// Handle memory operands later
cs_op_type op_type = map_get_op_type(MI, OpNum) & ~CS_OP_MEM;
// Fill cs_detail
switch (op_group) {
default:
printf("ERROR: Operand group %d not handled!\n", op_group);
CS_ASSERT_RET(0);
case LoongArch_OP_GROUP_Operand:
if (op_type == CS_OP_IMM) {
LoongArch_set_detail_op_imm(MI, OpNum, LOONGARCH_OP_IMM,
MCInst_getOpVal(MI, OpNum));
} else if (op_type == CS_OP_REG) {
LoongArch_set_detail_op_reg(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
} else
CS_ASSERT_RET(0 && "Op type not handled.");
break;
case LoongArch_OP_GROUP_AtomicMemOp:
CS_ASSERT_RET(op_type == CS_OP_REG);
// converted to MEM operand later in LoongArch_rewrite_memory_operand
LoongArch_set_detail_op_reg(MI, OpNum,
MCInst_getOpVal(MI, OpNum));
break;
}
}
#endif
+54
View File
@@ -0,0 +1,54 @@
/* Capstone Disassembly Engine */
/* By Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifndef CS_LOONGARCH_MAPPING_H
#define CS_LOONGARCH_MAPPING_H
#include "../../include/capstone/capstone.h"
#include "../../utils.h"
#include "../../Mapping.h"
typedef enum {
#include "LoongArchGenCSOpGroup.inc"
} loongarch_op_group;
void LoongArch_init_mri(MCRegisterInfo *MRI);
// return name of register in friendly string
const char *LoongArch_reg_name(csh handle, unsigned int reg);
void LoongArch_printer(MCInst *MI, SStream *O,
void * /* MCRegisterInfo* */ info);
// given internal insn id, return public instruction ID
void LoongArch_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
const char *LoongArch_insn_name(csh handle, unsigned int id);
const char *LoongArch_group_name(csh handle, unsigned int id);
void LoongArch_reg_access(const cs_insn *insn, cs_regs regs_read,
uint8_t *regs_read_count, cs_regs regs_write,
uint8_t *regs_write_count);
bool LoongArch_getInstruction(csh handle, const uint8_t *code, size_t code_len,
MCInst *instr, uint16_t *size, uint64_t address,
void *info);
// cs_detail related functions
void LoongArch_init_cs_detail(MCInst *MI);
void LoongArch_add_cs_detail(MCInst *MI, int /* loongarch_op_group */ op_group,
va_list args);
static inline void add_cs_detail(MCInst *MI,
int /* loongarch_op_group */ op_group, ...)
{
if (!MI->flat_insn->detail)
return;
va_list args;
va_start(args, op_group);
LoongArch_add_cs_detail(MI, op_group, args);
va_end(args);
}
#endif // CS_LOONGARCH_MAPPING_H
+53
View File
@@ -0,0 +1,53 @@
/* Capstone Disassembly Engine */
/* By Jiajie Chen <c@jia.je> 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifdef CAPSTONE_HAS_LOONGARCH
#include <capstone/capstone.h>
#include "LoongArchModule.h"
#include "../../MCRegisterInfo.h"
#include "../../cs_priv.h"
#include "LoongArchMapping.h"
cs_err LoongArch_global_init(cs_struct *ud)
{
MCRegisterInfo *mri;
mri = cs_mem_malloc(sizeof(*mri));
LoongArch_init_mri(mri);
ud->printer = LoongArch_printer;
ud->printer_info = mri;
ud->reg_name = LoongArch_reg_name;
ud->insn_id = LoongArch_get_insn_id;
ud->insn_name = LoongArch_insn_name;
ud->group_name = LoongArch_group_name;
ud->post_printer = NULL;
#ifndef CAPSTONE_DIET
ud->reg_access = LoongArch_reg_access;
#endif
ud->disasm = LoongArch_getInstruction;
return CS_ERR_OK;
}
cs_err LoongArch_option(cs_struct *handle, cs_opt_type type, size_t value)
{
switch (type) {
case CS_OPT_MODE:
handle->mode = (cs_mode)value;
break;
case CS_OPT_SYNTAX:
handle->syntax |= (int)value;
break;
default:
break;
}
return CS_ERR_OK;
}
#endif
+13
View File
@@ -0,0 +1,13 @@
/* Capstone Disassembly Engine */
/* By Jiajie Chen <c@jia.je>, 2024 */
/* Yanglin Xun <1109673069@qq.com>, 2024 */
#ifndef CS_LOONGARCH_MODULE_H
#define CS_LOONGARCH_MODULE_H
#include "../../utils.h"
cs_err LoongArch_global_init(cs_struct *ud);
cs_err LoongArch_option(cs_struct *handle, cs_opt_type type, size_t value);
#endif // CS_LOONGARCH_MODULE_H