Skip to content

Commit ec6428f

Browse files
authored
Refactoring the RISCV architecture to Auto-Sync on LLVM (#2756)
- Updated to LLVM-18 - Operands have now read/write access information - Previously only the basic extensions and the compressed ISA was supported, now every extension supported by LLVM-18 also available (e.g. vector, crypto, ...) - Changed register names * FP Regs: Instead of `RISCV_REG_F<n>_32` and `RISCV_REG_F<n>_64`, they're named `RISCV_REG_F<n>_F` and `RISCV_REG_F<n>_D` for n in `0..31` - Added register names * Vector registes and combinations thereof `RISCV_REG_V<n>[_V<n_i>]*`, examples * `RISCV_REG_V21` * `RISCV_REG_V9_V10` * `RISCV_REG_V3_V4_V5` * etc... up to 8-register combinations * Half-percision (16-bit) FP registers `RISCV_REG_F<n>_H` for n in `0..31` - Changed instruction names * Instructions ending in `_AQ_RL` now end in `_AQRL` - Added instruction names: massive amount, see `include/capstone/riscv.h` - Added `dimm` and `csr` fields inside the union data of `cs_riscv_op`, with corresponding `riscv_op_type` * `dimm` is used for instructions with FP immediates * `csr` is used for instructions with CSR systrem registes - Added ISA flags to turn ISA extensions on and off
1 parent 484857d commit ec6428f

424 files changed

Lines changed: 316795 additions & 14723 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,25 +599,38 @@ endif()
599599
if(CAPSTONE_RISCV_SUPPORT)
600600
add_definitions(-DCAPSTONE_HAS_RISCV)
601601
set(SOURCES_RISCV
602+
arch/RISCV/RISCVBaseInfo.c
602603
arch/RISCV/RISCVDisassembler.c
604+
arch/RISCV/RISCVDisassemblerExtension.c
603605
arch/RISCV/RISCVInstPrinter.c
604606
arch/RISCV/RISCVMapping.c
605607
arch/RISCV/RISCVModule.c
606608
)
607609
set(HEADERS_RISCV
608610
arch/RISCV/RISCVBaseInfo.h
609-
arch/RISCV/RISCVDisassembler.h
611+
arch/RISCV/RISCVDisassemblerExtension.h
610612
arch/RISCV/RISCVInstPrinter.h
611613
arch/RISCV/RISCVMapping.h
612614
arch/RISCV/RISCVModule.h
615+
arch/RISCV/RISCVLinkage.h
613616
arch/RISCV/RISCVGenAsmWriter.inc
617+
arch/RISCV/RISCVGenCSAliasMnemMap.inc
618+
arch/RISCV/RISCVGenCSFeatureName.inc
619+
arch/RISCV/RISCVGenCSMappingInsn.inc
620+
arch/RISCV/RISCVGenCSMappingInsnName.inc
621+
arch/RISCV/RISCVGenCSMappingInsnOp.inc
622+
arch/RISCV/RISCVGenCSOpGroup.inc
623+
arch/RISCV/RISCVGenCSSystemOperandsEnum.inc
614624
arch/RISCV/RISCVGenDisassemblerTables.inc
615-
arch/RISCV/RISCVGenInsnNameMaps.inc
616625
arch/RISCV/RISCVGenInstrInfo.inc
617626
arch/RISCV/RISCVGenRegisterInfo.inc
618627
arch/RISCV/RISCVGenSubtargetInfo.inc
619-
arch/RISCV/RISCVMappingInsn.inc
620-
arch/RISCV/RISCVMappingInsnOp.inc
628+
arch/RISCV/RISCVGenSystemOperands.inc
629+
arch/RISCV/RISCVGenCompressedInstructionsInfo.inc
630+
arch/RISCV/RISCVGenCSAliasEnum.inc
631+
arch/RISCV/RISCVGenCSFeatureEnum.inc
632+
arch/RISCV/RISCVGenCSInsnEnum.inc
633+
arch/RISCV/RISCVGenCSRegEnum.inc
621634
)
622635
endif()
623636

MCInstPrinter.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern bool Mips_getFeatureBits(unsigned int mode, unsigned int feature);
1111
extern bool AArch64_getFeatureBits(unsigned int mode, unsigned int feature);
1212
extern bool TriCore_getFeatureBits(unsigned int mode, unsigned int feature);
1313
extern bool Sparc_getFeatureBits(unsigned int mode, unsigned int feature);
14+
extern bool RISCV_getFeatureBits(unsigned int mode, unsigned int feature);
1415

1516
static bool testFeatureBits(const MCInst *MI, uint32_t Value)
1617
{
@@ -42,6 +43,10 @@ static bool testFeatureBits(const MCInst *MI, uint32_t Value)
4243
#ifdef CAPSTONE_HAS_SPARC
4344
case CS_ARCH_SPARC:
4445
return Sparc_getFeatureBits(MI->csh->mode, Value);
46+
#endif
47+
#ifdef CAPSTONE_HAS_RISCV
48+
case CS_ARCH_RISCV:
49+
return RISCV_getFeatureBits(MI->csh->mode, Value);
4550
#endif
4651
}
4752
}

Mapping.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,34 @@ DEFINE_get_detail_op(bpf, BPF, BPF);
359359
DEFINE_get_detail_op(arc, ARC, ARC);
360360
DEFINE_get_detail_op(sparc, Sparc, SPARC);
361361

362+
/// Returns the operand at detail->arch.operands[index]
363+
/// Or NULL if detail is not set or the index would be out of bounds.
364+
#define DEFINE_get_detail_op_at(arch, ARCH, ARCH_UPPER) \
365+
cs_##arch##_op *ARCH##_get_detail_op_at(MCInst *MI, int index) \
366+
{ \
367+
if (!MI->flat_insn->detail) \
368+
return NULL; \
369+
if (index < 0 || index >= NUM_##ARCH_UPPER##_OPS) { \
370+
return NULL; \
371+
} \
372+
return &MI->flat_insn->detail->arch.operands[index]; \
373+
}
374+
375+
DEFINE_get_detail_op_at(arm, ARM, ARM);
376+
DEFINE_get_detail_op_at(ppc, PPC, PPC);
377+
DEFINE_get_detail_op_at(tricore, TriCore, TRICORE);
378+
DEFINE_get_detail_op_at(aarch64, AArch64, AARCH64);
379+
DEFINE_get_detail_op_at(alpha, Alpha, ALPHA);
380+
DEFINE_get_detail_op_at(hppa, HPPA, HPPA);
381+
DEFINE_get_detail_op_at(loongarch, LoongArch, LOONGARCH);
382+
DEFINE_get_detail_op_at(mips, Mips, MIPS);
383+
DEFINE_get_detail_op_at(riscv, RISCV, RISCV);
384+
DEFINE_get_detail_op_at(systemz, SystemZ, SYSTEMZ);
385+
DEFINE_get_detail_op_at(xtensa, Xtensa, XTENSA);
386+
DEFINE_get_detail_op_at(bpf, BPF, BPF);
387+
DEFINE_get_detail_op_at(arc, ARC, ARC);
388+
DEFINE_get_detail_op_at(sparc, Sparc, SPARC);
389+
362390
/// Returns true if for this architecture the
363391
/// alias operands should be filled.
364392
/// TODO: Replace this with a proper option.

Mapping.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ typedef struct insn_map {
2121
unsigned short mapid; // The Capstone instruction id
2222
#ifndef CAPSTONE_DIET
2323
uint16_t regs_use[MAX_IMPL_R_REGS]; ///< list of implicit registers used by
24-
///< this instruction
24+
///< this instruction
2525
uint16_t regs_mod[MAX_IMPL_W_REGS]; ///< list of implicit registers modified
26-
///< by this instruction
26+
///< by this instruction
2727
unsigned char groups
2828
[MAX_NUM_GROUPS]; ///< list of group this instruction belong to
2929
bool branch; // branch instruction?
@@ -48,7 +48,7 @@ unsigned short insn_find(const insn_map *m, unsigned int max, unsigned int id,
4848
unsigned int find_cs_id(unsigned MC_Opcode, const insn_map *imap,
4949
unsigned imap_size);
5050

51-
#define MAX_NO_DATA_TYPES 16
51+
#define MAX_NO_DATA_TYPES 32
5252

5353
///< A LLVM<->CS Mapping entry of an MCOperand.
5454
typedef struct {
@@ -147,6 +147,24 @@ DECL_get_detail_op(bpf, BPF);
147147
DECL_get_detail_op(arc, ARC);
148148
DECL_get_detail_op(sparc, Sparc);
149149

150+
#define DECL_get_detail_op_at(arch, ARCH) \
151+
cs_##arch##_op *ARCH##_get_detail_op_at(MCInst *MI, int offset);
152+
153+
DECL_get_detail_op_at(arm, ARM);
154+
DECL_get_detail_op_at(ppc, PPC);
155+
DECL_get_detail_op_at(tricore, TriCore);
156+
DECL_get_detail_op_at(aarch64, AArch64);
157+
DECL_get_detail_op_at(alpha, Alpha);
158+
DECL_get_detail_op_at(hppa, HPPA);
159+
DECL_get_detail_op_at(loongarch, LoongArch);
160+
DECL_get_detail_op_at(mips, Mips);
161+
DECL_get_detail_op_at(riscv, RISCV);
162+
DECL_get_detail_op_at(systemz, SystemZ);
163+
DECL_get_detail_op_at(xtensa, Xtensa);
164+
DECL_get_detail_op_at(bpf, BPF);
165+
DECL_get_detail_op_at(arc, ARC);
166+
DECL_get_detail_op_at(sparc, Sparc);
167+
150168
/// Increments the detail->arch.op_count by one.
151169
#define DEFINE_inc_detail_op_count(arch, ARCH) \
152170
static inline void ARCH##_inc_op_count(MCInst *MI) \

MathExtras.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ static inline bool isIntN(unsigned N, int64_t x)
6262
(-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1)));
6363
}
6464

65+
/// isShiftedIntN - Checks if a signed integer is an N bit number shifted left by S.
66+
static inline bool isShiftedIntN(unsigned N, unsigned S, int64_t x)
67+
{
68+
return isIntN(N + S, x) && (x % (UINT64_C(1) << S) == 0);
69+
}
70+
71+
static inline bool isShiftedUIntN(unsigned N, unsigned S, uint64_t x)
72+
{
73+
return isUIntN(N + S, x) && (x % (UINT64_C(1) << S) == 0);
74+
}
75+
6576
/// isMask_32 - This function returns true if the argument is a sequence of ones
6677
/// starting at the least significant bit with the remainder zero (32 bit
6778
/// version). Ex. isMask_32(0x0000FFFFU) == true.

SStream.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,13 @@ void printFloat(SStream *ss, float val)
510510
SStream_concat(ss, "%e", val);
511511
}
512512

513+
void printfFloat(SStream *ss, const char *fmt, float val)
514+
{
515+
assert(ss);
516+
SSTREAM_RETURN_IF_CLOSED(ss);
517+
SStream_concat(ss, fmt, val);
518+
}
519+
513520
void printFloatBang(SStream *ss, float val)
514521
{
515522
assert(ss);

SStream.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ void printInt32BangDec(SStream *O, int32_t val);
9494

9595
void printFloat(SStream *O, float val);
9696

97+
void printfFloat(SStream *ss, const char *fmt, float val);
98+
9799
void printFloatBang(SStream *O, float val);
98100

99101
void printExpr(SStream *O, uint64_t val);

arch/RISCV/RISCVBaseInfo.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
2+
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
3+
/* Rot127 <unisono@quyllur.org> 2022-2023 */
4+
/* Automatically translated source file from LLVM. */
5+
6+
/* LLVM-commit: <commit> */
7+
/* LLVM-tag: <tag> */
8+
9+
/* Only small edits allowed. */
10+
/* For multiple similar edits, please create a Patch for the translator. */
11+
12+
/* Capstone's C++ file translator: */
13+
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14+
15+
//===-- RISCVBaseInfo.cpp - Top level definitions for RISC-V MC -----------===//
16+
//
17+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
18+
// See https://llvm.org/LICENSE.txt for license information.
19+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20+
//
21+
//===----------------------------------------------------------------------===//
22+
//
23+
// This file contains small standalone enum definitions for the RISC-V target
24+
// useful for the compiler back-end and the MC libraries.
25+
//
26+
//===----------------------------------------------------------------------===//
27+
28+
#include <stdio.h>
29+
#include <string.h>
30+
#include <stdlib.h>
31+
#include <capstone/platform.h>
32+
33+
#include "RISCVBaseInfo.h"
34+
35+
#define CONCAT(a, b) CONCAT_(a, b)
36+
#define CONCAT_(a, b) a##_##b
37+
38+
typedef struct {
39+
unsigned value;
40+
bool isFractional;
41+
} VLMULDecodeResult;
42+
VLMULDecodeResult decodeVLMUL(RISCVII_VLMUL VLMUL)
43+
{
44+
switch (VLMUL) {
45+
default:
46+
CS_ASSERT(0 && "Unexpected LMUL value!");
47+
case RISCVII_LMUL_1:
48+
case RISCVII_LMUL_2:
49+
case RISCVII_LMUL_4:
50+
case RISCVII_LMUL_8: {
51+
VLMULDecodeResult result = { .value = 1 << (unsigned)(VLMUL),
52+
.isFractional = false };
53+
return result;
54+
}
55+
case RISCVII_LMUL_F2:
56+
case RISCVII_LMUL_F4:
57+
case RISCVII_LMUL_F8: {
58+
VLMULDecodeResult result = { .value = 1 << (8 -
59+
(unsigned)(VLMUL)),
60+
.isFractional = true };
61+
return result;
62+
}
63+
}
64+
}
65+
66+
void printVType(unsigned VType, SStream *OS)
67+
{
68+
unsigned Sew = RISCVVType_getSEW(VType);
69+
SStream_concat(OS, "%s", "e");
70+
printUInt64(OS, Sew);
71+
72+
unsigned LMul;
73+
bool Fractional;
74+
VLMULDecodeResult result = decodeVLMUL(RISCVVType_getVLMUL(VType));
75+
LMul = result.value;
76+
Fractional = result.isFractional;
77+
78+
if (Fractional)
79+
SStream_concat0(OS, ", mf");
80+
else
81+
SStream_concat0(OS, ", m");
82+
printUInt64(OS, LMul);
83+
84+
if (RISCVVType_isTailAgnostic(VType))
85+
SStream_concat0(OS, ", ta");
86+
else
87+
SStream_concat0(OS, ", tu");
88+
89+
if (RISCVVType_isMaskAgnostic(VType))
90+
SStream_concat0(OS, ", ma");
91+
else
92+
SStream_concat0(OS, ", mu");
93+
}
94+
95+
typedef struct {
96+
uint8_t first;
97+
uint8_t second;
98+
} LoadFP32ImmArrElement;
99+
100+
// Lookup table for fli.s for entries 2-31.
101+
static const LoadFP32ImmArrElement LoadFP32ImmArr[] = {
102+
{ 0x6f, 0x00 }, { 0x70, 0x00 }, { 0x77, 0x00 }, { 0x78, 0x00 },
103+
{ 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x00 }, { 0x7d, 0x01 },
104+
{ 0x7d, 0x02 }, { 0x7d, 0x03 }, { 0x7e, 0x00 }, { 0x7e, 0x01 },
105+
{ 0x7e, 0x02 }, { 0x7e, 0x03 }, { 0x7f, 0x00 }, { 0x7f, 0x01 },
106+
{ 0x7f, 0x02 }, { 0x7f, 0x03 }, { 0x80, 0x00 }, { 0x80, 0x01 },
107+
{ 0x80, 0x02 }, { 0x81, 0x00 }, { 0x82, 0x00 }, { 0x83, 0x00 },
108+
{ 0x86, 0x00 }, { 0x87, 0x00 }, { 0x8e, 0x00 }, { 0x8f, 0x00 },
109+
{ 0xff, 0x00 }, { 0xff, 0x02 },
110+
};
111+
112+
float getFPImm(unsigned Imm)
113+
{
114+
CS_ASSERT(Imm != 1 && Imm != 30 && Imm != 31 &&
115+
"Unsupported immediate");
116+
CS_ASSERT((Imm == 0 || (Imm >= 2 && Imm < 30)) &&
117+
"Unsupported immediate");
118+
// Entry 0 is -1.0, the only negative value. Entry 16 is 1.0.
119+
uint32_t Sign = 0;
120+
if (Imm == 0) {
121+
Sign = 0x01;
122+
Imm = 16;
123+
}
124+
125+
uint32_t Exp = LoadFP32ImmArr[Imm - 2].first;
126+
uint32_t Mantissa = LoadFP32ImmArr[Imm - 2].second;
127+
128+
uint32_t I = Sign << 31 | Exp << 23 | Mantissa << 21;
129+
float result;
130+
memcpy(&result, &I, sizeof(float));
131+
return result;
132+
}
133+
134+
void RISCVZC_printSpimm(int64_t Spimm, SStream *OS)
135+
{
136+
printInt32(OS, Spimm);
137+
}
138+
139+
// namespace llvm

0 commit comments

Comments
 (0)