Skip to content

Commit

Permalink
[RISCV] Add MC support of RISCV zcmt Extension
Browse files Browse the repository at this point in the history
This patch add the instructions of zcmt extension.
[[ https://github.com/riscv/riscv-code-size-reduction/releases/tag/v1.0.0-RC5.7 | spac is here ]]
Which includes two instructions (cm.jt&cm.jalt) and a CSR Reg JVT

co-author: @scott Egerton

Reviewed By: kito-cheng, craig.topper

Differential Revision: https://reviews.llvm.org/D133863
  • Loading branch information
Xinlong-Wu committed May 3, 2023
1 parent 72f6ea6 commit 9f0d725
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 6 deletions.
8 changes: 8 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Expand Up @@ -48,6 +48,7 @@
// CHECK-NOT: __riscv_zcb {{.*$}}
// CHECK-NOT: __riscv_zcd {{.*$}}
// CHECK-NOT: __riscv_zcf {{.*$}}
// CHECK-NOT: __riscv_zcmt {{.*$}}
// CHECK-NOT: __riscv_h {{.*$}}
// CHECK-NOT: __riscv_zvbb {{.*$}}
// CHECK-NOT: __riscv_zvbc {{.*$}}
Expand Down Expand Up @@ -511,6 +512,13 @@
// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCF-EXT %s
// CHECK-ZCF-EXT: __riscv_zcf 1000000{{$}}

// RUN: %clang -target riscv32 -march=rv32izcmt1p0 -menable-experimental-extensions \
// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMT-EXT %s
// RUN: %clang -target riscv64 -march=rv64izcmt1p0 -menable-experimental-extensions \
// RUN: -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-ZCMT-EXT %s
// CHECK-ZCMT-EXT: __riscv_zca 1000000{{$}}
// CHECK-ZCMT-EXT: __riscv_zcmt 1000000{{$}}

// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32izicsr2p0 -x c -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZICSR-EXT %s
// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64izicsr2p0 -x c -E -dM %s \
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Expand Up @@ -195,6 +195,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-zcf``
LLVM implements the `1.0.1 draft specification <https://github.com/riscv/riscv-code-size-reduction/releases/tag/v1.0.1>`__.

``experimental-zcmt``
LLVM implements the `1.0.1 draft specification <https://github.com/riscv/riscv-code-size-reduction/releases/tag/v1.0.1>`_.

``experimental-zfa``
LLVM implements the `0.2 draft specification <https://github.com/riscv/riscv-isa-manual/releases/download/draft-20230131-c0b298a/zfa-20230414.pdf>`__.

Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -144,6 +144,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zcb", RISCVExtensionVersion{1, 0}},
{"zcd", RISCVExtensionVersion{1, 0}},
{"zcf", RISCVExtensionVersion{1, 0}},
{"zcmt", RISCVExtensionVersion{1, 0}},
{"zfa", RISCVExtensionVersion{0, 2}},
{"zicond", RISCVExtensionVersion{1, 0}},
{"zvfh", RISCVExtensionVersion{0, 1}},
Expand Down Expand Up @@ -851,6 +852,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
}

Error RISCVISAInfo::checkDependency() {
bool HasC = Exts.count("c") != 0;
bool HasD = Exts.count("d") != 0;
bool HasF = Exts.count("f") != 0;
bool HasZfinx = Exts.count("zfinx") != 0;
Expand All @@ -859,6 +861,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasZve32f = Exts.count("zve32f") != 0;
bool HasZve64d = Exts.count("zve64d") != 0;
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
bool HasZcd = Exts.count("zcd") != 0;

if (HasF && HasZfinx)
return createStringError(errc::invalid_argument,
Expand Down Expand Up @@ -908,6 +912,16 @@ Error RISCVISAInfo::checkDependency() {
errc::invalid_argument,
"'zvknhb' requires 'v' or 'zve64*' extension to also be specified");

if (HasZcmt && HasD && HasC)
return createStringError(
errc::invalid_argument,
"'zcmt' is incompatible with 'c' extension when 'd' extension is set");

if (HasZcmt && HasD && HasZcd)
return createStringError(errc::invalid_argument,
"'zcmt' is incompatible with 'zcd' extension when "
"'d' extension is set");

// Additional dependency checks.
// TODO: The 'q' extension requires rv64.
// TODO: It is illegal to specify 'e' extensions with 'f' and 'd'.
Expand All @@ -921,6 +935,7 @@ static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"};
static const char *ImpliedExtsXTHeadVdot[] = {"v"};
static const char *ImpliedExtsXsfvcp[] = {"zve32x"};
static const char *ImpliedExtsZcb[] = {"zca"};
static const char *ImpliedExtsZcmt[] = {"zca"};
static const char *ImpliedExtsZdinx[] = {"zfinx"};
static const char *ImpliedExtsZfa[] = {"f"};
static const char *ImpliedExtsZfh[] = {"f"};
Expand Down Expand Up @@ -978,6 +993,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
{{"xsfvcp"}, {ImpliedExtsXsfvcp}},
{{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
{{"zcb"}, {ImpliedExtsZcb}},
{{"zcmt"}, {ImpliedExtsZcmt}},
{{"zdinx"}, {ImpliedExtsZdinx}},
{{"zfa"}, {ImpliedExtsZfa}},
{{"zfh"}, {ImpliedExtsZfh}},
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Expand Up @@ -361,6 +361,14 @@ def HasStdExtCOrZcf
"'C' (Compressed Instructions) or "
"'Zcf' (Compressed Single-Precision Floating-Point Instructions)">;

def FeatureStdExtZcmt
: SubtargetFeature<"experimental-zcmt", "HasStdExtZcmt", "true",
"'Zcmt' (table jump instuctions for code-size reduction)",
[FeatureStdExtZca, FeatureStdExtZicsr]>;
def HasStdExtZcmt : Predicate<"Subtarget->hasStdExtZcmt()">,
AssemblerPredicate<(all_of FeatureStdExtZcmt),
"'Zcmt' (table jump instuctions for code-size reduction)">;

def FeatureNoRVCHints
: SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false",
"Disable RVC Hint Instructions.">;
Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZc.td
Expand Up @@ -125,6 +125,26 @@ def C_SH : CStoreH_rri<0b100011, 0b1, "c.sh">,
Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
}

let Predicates = [HasStdExtZcmt],
hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
def CM_JT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm5:$index),
"cm.jt", "$index">{
bits<5> index;

let Inst{12-7} = 0b000000;
let Inst{6-2} = index;
}

def CM_JALT : RVInst16CJ<0b101, 0b10, (outs), (ins uimm8:$index),
"cm.jalt", "$index">{
bits<8> index;

let Inst{12-10} = 0b000;
let Inst{9-2} = index;
}
} // Predicates = [HasStdExtZcmt]


let Predicates = [HasStdExtZcb, HasStdExtMOrZmmul] in{
def : CompressPat<(MUL GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
(C_MUL GPRC:$rs1, GPRC:$rs2)>;
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/RISCV/RISCVSchedRocket.td
Expand Up @@ -18,9 +18,9 @@ def RocketModel : SchedMachineModel {
let MispredictPenalty = 3;
let CompleteModel = false;
let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
HasVInstructions, HasVInstructionsI64];
HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne,
HasStdExtZknh, HasStdExtZksed, HasStdExtZksh,
HasStdExtZkr, HasVInstructions, HasVInstructionsI64];
}

//===----------------------------------------------------------------------===//
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
Expand Up @@ -16,9 +16,9 @@ def SiFive7Model : SchedMachineModel {
let MispredictPenalty = 3;
let CompleteModel = 0;
let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
HasVInstructions];
HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne,
HasStdExtZknh, HasStdExtZksed, HasStdExtZksh,
HasStdExtZkr, HasVInstructions];
}

// The SiFive7 microarchitecture has two pipelines: A and B.
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSystemOperands.td
Expand Up @@ -407,3 +407,8 @@ def : SysReg<"hviprio2h", 0x657>;
def : SysReg<"vsieh", 0x214>;
def : SysReg<"vsiph", 0x254>;
} // isRV32Only

// Jump Vector Table CSR
//===-----------------------------------------------

def : SysReg<"jvt", 0x017>;
4 changes: 4 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Expand Up @@ -52,6 +52,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcb %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCB %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcd %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCD %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcf %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCF %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcmt %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCMT %s
; RUN: llc -mtriple=riscv32 -mattr=+zicsr %s -o - | FileCheck --check-prefixes=CHECK,RV32ZICSR %s
; RUN: llc -mtriple=riscv32 -mattr=+zifencei %s -o - | FileCheck --check-prefixes=CHECK,RV32ZIFENCEI %s
; RUN: llc -mtriple=riscv32 -mattr=+zicntr %s -o - | FileCheck --check-prefixes=CHECK,RV32ZICNTR %s
Expand Down Expand Up @@ -132,6 +133,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zca %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCA %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcb %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCB %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcd %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCD %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcmt %s -o - | FileCheck --check-prefixes=CHECK,RV64ZCMT %s
; RUN: llc -mtriple=riscv64 -mattr=+zicsr %s -o - | FileCheck --check-prefixes=CHECK,RV64ZICSR %s
; RUN: llc -mtriple=riscv64 -mattr=+zifencei %s -o - | FileCheck --check-prefixes=CHECK,RV64ZIFENCEI %s
; RUN: llc -mtriple=riscv64 -mattr=+zicntr %s -o - | FileCheck --check-prefixes=CHECK,RV64ZICNTR %s
Expand Down Expand Up @@ -207,6 +209,7 @@
; RV32ZCB: .attribute 5, "rv32i2p1_zca1p0_zcb1p0"
; RV32ZCD: .attribute 5, "rv32i2p1_zcd1p0"
; RV32ZCF: .attribute 5, "rv32i2p1_zcf1p0"
; RV32ZCMT: .attribute 5, "rv32i2p1_zicsr2p0_zca1p0_zcmt1p0"
; RV32ZICSR: .attribute 5, "rv32i2p1_zicsr2p0"
; RV32ZIFENCEI: .attribute 5, "rv32i2p1_zifencei2p0"
; RV32ZICNTR: .attribute 5, "rv32i2p1_zicntr1p0_zicsr2p0"
Expand Down Expand Up @@ -286,6 +289,7 @@
; RV64ZCA: .attribute 5, "rv64i2p1_zca1p0"
; RV64ZCB: .attribute 5, "rv64i2p1_zca1p0_zcb1p0"
; RV64ZCD: .attribute 5, "rv64i2p1_zcd1p0"
; RV64ZCMT: .attribute 5, "rv64i2p1_zicsr2p0_zca1p0_zcmt1p0"
; RV64ZICSR: .attribute 5, "rv64i2p1_zicsr2p0"
; RV64ZIFENCEI: .attribute 5, "rv64i2p1_zifencei2p0"
; RV64ZICNTR: .attribute 5, "rv64i2p1_zicntr1p0_zicsr2p0"
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/attribute-arch.s
Expand Up @@ -231,6 +231,9 @@
.attribute arch, "rv32izcb1p0"
# CHECK: attribute 5, "rv32i2p1_zca1p0_zcb1p0"

.attribute arch, "rv32izcmt1p0"
# CHECK: attribute 5, "rv32i2p1_zca1p0_zcmt1p0"

.attribute arch, "rv64i_xsfvcp"
# CHECK: attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfvcp1p0"

Expand Down
10 changes: 10 additions & 0 deletions llvm/test/MC/RISCV/rv32zcmt-invalid.s
@@ -0,0 +1,10 @@
# RUN: not llvm-mc -triple=riscv32 -mattr=+experimental-zcmt -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
# RUN: not llvm-mc -triple=riscv64 -mattr=+experimental-zcmt -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s

# CHECK-ERROR: error: immediate must be an integer in the range [0, 31]
cm.jt 64

# CHECK-ERROR: error: immediate must be an integer in the range [0, 255]
cm.jalt 256
39 changes: 39 additions & 0 deletions llvm/test/MC/RISCV/rv32zcmt-valid.s
@@ -0,0 +1,39 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zcmt\
# RUN: -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zcmt\
# RUN: -mattr=m < %s \
# RUN: | llvm-objdump --mattr=+experimental-zcmt\
# RUN: -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zcmt\
# RUN: -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zcmt\
# RUN: -mattr=m < %s \
# RUN: | llvm-objdump --mattr=+experimental-zcmt\
# RUN: -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 \
# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s
# RUN: not llvm-mc -triple riscv64 \
# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s

# CHECK-ASM-AND-OBJ: cm.jt 1
# CHECK-ASM: encoding: [0x06,0xa0]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}}
cm.jt 1

# CHECK-ASM: cm.jalt 1
# CHECK-OBJ: cm.jt 1
# CHECK-ASM: encoding: [0x06,0xa0]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}}
cm.jalt 1

# CHECK-ASM-AND-OBJ: cm.jalt 32
# CHECK-ASM: encoding: [0x82,0xa0]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmt' (table jump instuctions for code-size reduction){{$}}
cm.jalt 32
29 changes: 29 additions & 0 deletions llvm/test/MC/RISCV/rvzcmt-user-csr-name.s
@@ -0,0 +1,29 @@
# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases -mattr=+experimental-zcmt -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zcmt < %s \
# RUN: | llvm-objdump -d --mattr=+experimental-zcmt - \
# RUN: | FileCheck -check-prefix=CHECK-INST-ALIAS %s
#
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -mattr=+experimental-zcmt -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+experimental-zcmt < %s \
# RUN: | llvm-objdump -d --mattr=+experimental-zcmt - \
# RUN: | FileCheck -check-prefix=CHECK-INST-ALIAS %s

##################################
# Jump Vector Table CSR
##################################

# jvt
# name
# CHECK-INST: csrrs t1, jvt, zero
# CHECK-ENC: encoding: [0x73,0x23,0x70,0x01]
# CHECK-INST-ALIAS: csrr t1, jvt
# uimm12
# CHECK-INST: csrrs t2, jvt, zero
# CHECK-ENC: encoding: [0xf3,0x23,0x70,0x01]
# CHECK-INST-ALIAS: csrr t2, jvt
# name
csrrs t1, jvt, zero
# uimm12
csrrs t2, 0x017, zero

0 comments on commit 9f0d725

Please sign in to comment.