From 3dc0638cfc19e140daff7bf1281648daca8212fa Mon Sep 17 00:00:00 2001 From: Yeting Kuo <46629943+yetingk@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:40:20 +0800 Subject: [RISCV] Add MC layer support for Zicfiss. (#66043) The patch adds the instructions in Zicfiss extension. Zicfiss extension is to support shadow stack for control flow integrity. This patch is based on version [0.3.1]. [0.3.1]: https://github.com/riscv/riscv-cfi/releases/tag/v0.3.1 --- .../RISCV/Disassembler/RISCVDisassembler.cpp | 27 ++++++++ llvm/lib/Target/RISCV/RISCVFeatures.td | 9 +++ llvm/lib/Target/RISCV/RISCVInstrInfo.td | 11 ++-- llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td | 14 +++-- llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td | 72 ++++++++++++++++++++++ llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 3 + llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 7 +++ 7 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td (limited to 'llvm/lib/Target') diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index a639634..ed80da1 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -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) { @@ -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, @@ -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) { @@ -596,6 +621,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( diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index bdab052..59b2026 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -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 " diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index b00cb26..35e8edf 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -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 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td index 9213b20..6fbfde5 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td @@ -22,9 +22,13 @@ class CMOPInst 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, 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, Sched<[]>; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td new file mode 100644 index 0000000..49a57f8 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicfiss.td @@ -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 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", + "$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] diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index a3c1911..24f8d60 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -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; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index c59c9b2..840fd149 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -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)>; @@ -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]>; @@ -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">; -- cgit v1.1