Skip to content

[RISCV] Add MC layer support for Zicfiss. #66043

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
// CHECK-NOT: __riscv_zfa {{.*$}}
// CHECK-NOT: __riscv_zfbfmin {{.*$}}
// CHECK-NOT: __riscv_zicfilp {{.*$}}
// CHECK-NOT: __riscv_zicfiss {{.*$}}
// CHECK-NOT: __riscv_zicond {{.*$}}
// CHECK-NOT: __riscv_zimop {{.*$}}
// CHECK-NOT: __riscv_zcmop {{.*$}}
Expand Down Expand Up @@ -1296,3 +1297,11 @@
// RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -E -dM %s \
// RUN: -munaligned-access -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST
// CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1

// RUN: %clang -target riscv32 -menable-experimental-extensions \
// RUN: -march=rv32izicfiss0p4 -x c -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s
// RUN: %clang -target riscv64 -menable-experimental-extensions \
// RUN: -march=rv64izicfiss0p4 -x c -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s
// CHECK-ZICFISS-EXT: __riscv_zicfiss 4000{{$}}
2 changes: 1 addition & 1 deletion llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-zfbfmin``, ``experimental-zvfbfmin``, ``experimental-zvfbfwma``
LLVM implements assembler support for the `0.8.0 draft specification <https://github.com/riscv/riscv-bfloat16/releases/tag/20230629>`_.

``experimental-zicfilp``
``experimental-zicfilp``, ``experimental-zicfiss``
LLVM implements the `0.4 draft specification <https://github.com/riscv/riscv-cfi/releases/tag/v0.4.0>`__.

``experimental-zicond``
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zfbfmin", RISCVExtensionVersion{0, 8}},

{"zicfilp", RISCVExtensionVersion{0, 4}},
{"zicfiss", RISCVExtensionVersion{0, 4}},

{"zicond", RISCVExtensionVersion{1, 0}},

{"zimop", RISCVExtensionVersion{0, 1}},
Expand Down Expand Up @@ -1022,6 +1024,7 @@ static const char *ImpliedExtsZfinx[] = {"zicsr"};
static const char *ImpliedExtsZhinx[] = {"zhinxmin"};
static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
static const char *ImpliedExtsZicntr[] = {"zicsr"};
static const char *ImpliedExtsZicfiss[] = {"zicsr", "zimop"};
static const char *ImpliedExtsZihpm[] = {"zicsr"};
static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"};
static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zbkx",
Expand Down Expand Up @@ -1094,6 +1097,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
{{"zfinx"}, {ImpliedExtsZfinx}},
{{"zhinx"}, {ImpliedExtsZhinx}},
{{"zhinxmin"}, {ImpliedExtsZhinxmin}},
{{"zicfiss"}, {ImpliedExtsZicfiss}},
{{"zicntr"}, {ImpliedExtsZicntr}},
{{"zihpm"}, {ImpliedExtsZihpm}},
{{"zk"}, {ImpliedExtsZk}},
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}

static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
MCRegister Reg = RISCV::X0 + RegNo;
if (Reg != RISCV::X1 && Reg != RISCV::X5)
return MCDisassembler::Fail;

Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
Expand Down Expand Up @@ -359,6 +370,10 @@ static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder);

static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
uint64_t Address,
const MCDisassembler *Decoder);

#include "RISCVGenDisassemblerTables.inc"

static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
Expand All @@ -373,6 +388,16 @@ static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
return MCDisassembler::Success;
}

static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
uint64_t Address,
const MCDisassembler *Decoder) {
uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5);
DecodeStatus Result = DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
(void)Result;
assert(Result == MCDisassembler::Success && "Invalid register");
return MCDisassembler::Success;
}

static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
uint64_t Address,
const MCDisassembler *Decoder) {
Expand Down Expand Up @@ -598,6 +623,8 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
DecoderTableRISCV32Only_16,
"RISCV32Only_16 table (16-bit Instruction)");
TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,
"RVZicfiss table (Shadow Stack)");
TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
"Zcmt table (16-bit Table Jump Instructions)");
TRY_TO_DECODE_FEATURE(
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,15 @@ def HasStdExtZcmop : Predicate<"Subtarget->hasStdExtZcmop()">,
AssemblerPredicate<(all_of FeatureStdExtZcmop),
"'Zcmop' (Compressed May-Be-Operations)">;

def FeatureStdExtZicfiss
: SubtargetFeature<"experimental-zicfiss", "HasStdExtZicfiss", "true",
"'Zicfiss' (Shadow stack)",
[FeatureStdExtZicsr, FeatureStdExtZimop]>;
def HasStdExtZicfiss : Predicate<"Subtarget->hasStdExtZicfiss()">,
AssemblerPredicate<(all_of FeatureStdExtZicfiss),
"'Zicfiss' (Shadow stack)">;
def NoHasStdExtZicfiss : Predicate<"!Subtarget->hasStdExtZicfiss()">;

def FeatureStdExtSmaia
: SubtargetFeature<"smaia", "HasStdExtSmaia", "true",
"'Smaia' (Smaia encompasses all added CSRs and all "
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2111,16 +2111,17 @@ include "RISCVInstrInfoZk.td"
include "RISCVInstrInfoV.td"
include "RISCVInstrInfoZvk.td"

// Integer
include "RISCVInstrInfoZimop.td"
include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"

// Compressed
include "RISCVInstrInfoC.td"
include "RISCVInstrInfoZc.td"
include "RISCVInstrInfoZcmop.td"

// Integer
include "RISCVInstrInfoZimop.td"
include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZicfiss.td"

//===----------------------------------------------------------------------===//
// Vendor extensions
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 9 additions & 5 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ class CMOPInst<bits<3> imm3, string opcodestr>
let Inst{12-11} = 0;
}

foreach i = 0...7 in {
let Predicates = [HasStdExtZcmop] in {
defvar n = !add(!mul(i, 2), 1);
def CMOP # n : CMOPInst<i, "cmop." # n>, Sched<[]>;
} // Predicates = [HasStdExtZcmop]
// CMOP1, CMOP5 is used by Zicfiss.
let Predicates = [HasStdExtZcmop, NoHasStdExtZicfiss] in {
def CMOP1 : CMOPInst<0, "cmop.1">, Sched<[]>;
def CMOP5 : CMOPInst<2, "cmop.5">, Sched<[]>;
}

foreach n = [3, 7, 9, 11, 13, 15] in {
let Predicates = [HasStdExtZcmop] in
def CMOP # n : CMOPInst<!srl(n, 1), "cmop." # n>, Sched<[]>;
}
72 changes: 72 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//===------ RISCVInstrInfoZicfiss.td - RISC-V Zicfiss -*- tablegen -*------===//
//
// 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
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Instruction class templates
//===----------------------------------------------------------------------===//

class RVC_SSInst<bits<5> rs1val, RegisterClass reg_class, string opcodestr> :
RVInst16<(outs), (ins reg_class:$rs1), opcodestr, "$rs1", [], InstFormatOther> {
let Inst{15-13} = 0b011;
let Inst{12} = 0;
let Inst{11-7} = rs1val;
let Inst{6-2} = 0b00000;
let Inst{1-0} = 0b01;
let DecoderMethod = "decodeCSSPushPopchk";
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZicfiss] in {
let Uses = [SSP], Defs = [SSP], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def SSPOPCHK : RVInstI<0b100, OPC_SYSTEM, (outs), (ins GPRX1X5:$rs1), "sspopchk",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these instructions be aliases of MOPs now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should use same encoding as some instructions of Zimop, but currently, there is no mop.r could be fitted to sspush and sspopchk. The 24th bit of sspush is 0 but the 24th bit of all mop.r is 1. The 25th bit of sspopchk is 0 but but the 25th bit of all mop.r is 1.

ref:
https://github.com/riscv/riscv-isa-manual/blob/main/src/images/wavedrom/mop-r.adoc
https://github.com/riscv/riscv-cfi/blob/main/cfi_backward.adoc

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, I haven't looked at it in details, is this a document mistake? They should have the same encoding.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I don't find any mistake, sspush uses mop.rr and sspopchk uses mop.r.

The 25th bit of sspopchk is 0 but but the 25th bit of all mop.r is 1.

This is wrong as it's { bits: 4, name: 0x7 }, so its value is 0b0111.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I will give a fix for this.

"$rs1"> {
let rd = 0;
let imm12 = 0b110011011100;
} // Uses = [SSP], Defs = [SSP], hasSideEffects = 0, mayLoad = 1, mayStore = 0

let Uses = [SSP], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
def SSRDP : RVInstI<0b100, OPC_SYSTEM, (outs GPRNoX0:$rd), (ins), "ssrdp", "$rd"> {
let imm12 = 0b110011011100;
let rs1 = 0b00000;
}
} // Uses = [SSP], hasSideEffects = 0, mayLoad = 0, mayStore = 0

let Uses = [SSP], Defs = [SSP], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def SSPUSH : RVInstR<0b1100111, 0b100, OPC_SYSTEM, (outs), (ins GPRX1X5:$rs2),
"sspush", "$rs2"> {
let rd = 0b00000;
let rs1 = 0b00000;
}
} // Predicates = [HasStdExtZicfiss]

let Predicates = [HasStdExtZicfiss, HasStdExtZcmop],
DecoderNamespace = "Zicfiss" in {
let Uses = [SSP], Defs = [SSP], hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def C_SSPUSH : RVC_SSInst<0b00001, GPRX1, "c.sspush">;

let Uses = [SSP], Defs = [SSP], hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def C_SSPOPCHK : RVC_SSInst<0b00101, GPRX5, "c.sspopchk">;
} // Predicates = [HasStdExtZicfiss, HasStdExtZcmop]

let Predicates = [HasStdExtZicfiss] in
defm SSAMOSWAP_W : AMO_rr_aq_rl<0b01001, 0b010, "ssamoswap.w">;

let Predicates = [HasStdExtZicfiss, IsRV64] in
defm SSAMOSWAP_D : AMO_rr_aq_rl<0b01001, 0b011, "ssamoswap.d">;

//===----------------------------------------------------------------------===/
// Compress Instruction tablegen backend.
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZicfiss, HasStdExtZcmop] in {
def : CompressPat<(SSPUSH X1), (C_SSPUSH X1)>;
def : CompressPat<(SSPOPCHK X5), (C_SSPOPCHK X5)>;
} // Predicates = [HasStdExtZicfiss, HasStdExtZcmop]
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
markSuperRegs(Reserved, RISCV::X27);
}

// Shadow stack pointer.
markSuperRegs(Reserved, RISCV::SSP);

assert(checkAllSuperRegsMarked(Reserved));
return Reserved;
}
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def GPR : GPRRegisterClass<(add (sequence "X%u", 10, 17),
(sequence "X%u", 0, 4))>;

def GPRX0 : GPRRegisterClass<(add X0)>;
def GPRX1 : GPRRegisterClass<(add X1)>;
def GPRX5 : GPRRegisterClass<(add X5)>;

def GPRNoX0 : GPRRegisterClass<(sub GPR, X0)>;

Expand Down Expand Up @@ -165,6 +167,8 @@ def SP : GPRRegisterClass<(add X2)>;
def SR07 : GPRRegisterClass<(add (sequence "X%u", 8, 9),
(sequence "X%u", 18, 23))>;

def GPRX1X5 : GPRRegisterClass<(add X1, X5)>;

// Floating point registers
let RegAltNameIndices = [ABIRegAltName] in {
def F0_H : RISCVReg16<0, "f0", ["ft0"]>, DwarfRegNum<[32]>;
Expand Down Expand Up @@ -591,3 +595,6 @@ foreach m = LMULList in {
// Special registers
def FFLAGS : RISCVReg<0, "fflags">;
def FRM : RISCVReg<0, "frm">;

// Shadow Stack register
def SSP : RISCVReg<0, "ssp">;
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/attribute-arch.s
Original file line number Diff line number Diff line change
Expand Up @@ -312,5 +312,8 @@
.attribute arch, "rv32i_zicfilp0p4"
# CHECK: attribute 5, "rv32i2p1_zicfilp0p4"

.attribute arch, "rv32i_zicfiss0p4"
# CHECK: .attribute 5, "rv32i2p1_zicfiss0p4_zicsr2p0_zimop0p1"

.attribute arch, "rv64i_xsfvfwmaccqqq"
# CHECK: attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p8_zvl32b1p0_xsfvfwmaccqqq1p0"
53 changes: 53 additions & 0 deletions llvm/test/MC/RISCV/compressed-zicfiss.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zicfiss,+experimental-zcmop -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-zicfiss,+experimental-zcmop < %s \
# RUN: | llvm-objdump --mattr=+experimental-zicfiss,+experimental-zcmop -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zicfiss,+experimental-zcmop -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-zicfiss,+experimental-zcmop < %s \
# RUN: | llvm-objdump --mattr=+experimental-zicfiss,+experimental-zcmop -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s

# CHECK-ASM-AND-OBJ: c.sspopchk t0
# CHECK-ASM: encoding: [0x81,0x62]
# CHECK-NO-EXT: error: instruction requires the following: 'Zicfiss' (Shadow stack)
sspopchk x5

# CHECK-ASM-AND-OBJ: c.sspopchk t0
# CHECK-ASM: encoding: [0x81,0x62]
# CHECK-NO-EXT: error: instruction requires the following: 'Zicfiss' (Shadow stack)
sspopchk t0

# CHECK-ASM-AND-OBJ: c.sspush ra
# CHECK-ASM: encoding: [0x81,0x60]
# CHECK-NO-EXT: error: instruction requires the following: 'Zicfiss' (Shadow stack)
sspush x1

# CHECK-ASM-AND-OBJ: c.sspush ra
# CHECK-ASM: encoding: [0x81,0x60]
# CHECK-NO-EXT: error: instruction requires the following: 'Zicfiss' (Shadow stack)
sspush ra

# CHECK-ASM-AND-OBJ: c.sspush ra
# CHECK-ASM: encoding: [0x81,0x60]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmop' (Compressed May-Be-Operations), 'Zicfiss' (Shadow stack)
c.sspush x1

# CHECK-ASM-AND-OBJ: c.sspush ra
# CHECK-ASM: encoding: [0x81,0x60]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmop' (Compressed May-Be-Operations), 'Zicfiss' (Shadow stack)
c.sspush ra

# CHECK-ASM-AND-OBJ: c.sspopchk t0
# CHECK-ASM: encoding: [0x81,0x62]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmop' (Compressed May-Be-Operations), 'Zicfiss' (Shadow stack)
c.sspopchk x5

# CHECK-ASM-AND-OBJ: c.sspopchk t0
# CHECK-ASM: encoding: [0x81,0x62]
# CHECK-NO-EXT: error: instruction requires the following: 'Zcmop' (Compressed May-Be-Operations), 'Zicfiss' (Shadow stack)
c.sspopchk t0
17 changes: 17 additions & 0 deletions llvm/test/MC/RISCV/rv32zicfiss-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# RUN: not llvm-mc %s -triple=riscv32 -mattr=+experimental-zicfiss,+c -riscv-no-aliases -show-encoding \
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s

# CHECK-ERR: error: invalid operand for instruction
sspopchk a1

# CHECK-ERR: error: invalid operand for instruction
c.sspush t0

# CHECK-ERR: error: invalid operand for instruction
c.sspopchk ra

# CHECK-ERR: error: invalid operand for instruction
sspush a0

# CHECK-ERR: error: invalid operand for instruction
ssrdp zero
17 changes: 17 additions & 0 deletions llvm/test/MC/RISCV/rv64zicfiss-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# RUN: not llvm-mc %s -triple=riscv64 -mattr=+experimental-zicfiss,+c -riscv-no-aliases -show-encoding \
# RUN: 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s

# CHECK-ERR: error: invalid operand for instruction
sspopchk a1

# CHECK-ERR: error: invalid operand for instruction
c.sspush t0

# CHECK-ERR: error: invalid operand for instruction
c.sspopchk ra

# CHECK-ERR: error: invalid operand for instruction
sspush a0

# CHECK-ERR: error: invalid operand for instruction
ssrdp zero
Loading