https://github.com/JivanH updated https://github.com/llvm/llvm-project/pull/75182
>From e6bf0819c96fcfbd73d711acc951065e2ed22d8c Mon Sep 17 00:00:00 2001 From: ln8-8 <lyut.nersis...@gmail.com> Date: Tue, 12 Dec 2023 12:47:32 +0400 Subject: [PATCH] [RISCV][MC] Add support for experimental Zimop extension This implements experimental support for the Zimop extension as specified here: https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc. This change adds only assembly support. --- llvm/docs/RISCVUsage.rst | 3 ++ llvm/include/llvm/IR/IntrinsicsRISCV.td | 23 +++++++++++ llvm/lib/Support/RISCVISAInfo.cpp | 2 + llvm/lib/Target/RISCV/RISCVFeatures.td | 5 +++ llvm/lib/Target/RISCV/RISCVInstrFormats.td | 21 ++++++++++ llvm/lib/Target/RISCV/RISCVInstrInfo.td | 45 +++++++++++++++++++++ llvm/test/CodeGen/RISCV/attributes.ll | 4 ++ llvm/test/MC/RISCV/rv32zimop-invalid.s | 6 +++ llvm/test/MC/RISCV/rvzimop-valid.s | 26 ++++++++++++ llvm/unittests/Support/RISCVISAInfoTest.cpp | 1 + 10 files changed, 136 insertions(+) create mode 100644 llvm/test/MC/RISCV/rv32zimop-invalid.s create mode 100644 llvm/test/MC/RISCV/rvzimop-valid.s diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 65dd0d83448ed1..bd2f81fba186df 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -208,6 +208,9 @@ The primary goal of experimental support is to assist in the process of ratifica ``experimental-zvbb``, ``experimental-zvbc``, ``experimental-zvkb``, ``experimental-zvkg``, ``experimental-zvkn``, ``experimental-zvknc``, ``experimental-zvkned``, ``experimental-zvkng``, ``experimental-zvknha``, ``experimental-zvknhb``, ``experimental-zvks``, ``experimental-zvksc``, ``experimental-zvksed``, ``experimental-zvksg``, ``experimental-zvksh``, ``experimental-zvkt`` LLVM implements the `1.0.0-rc2 specification <https://github.com/riscv/riscv-crypto/releases/download/v/riscv-crypto-spec-vector.pdf>`__. Note that current vector crypto extension version can be found in: <https://github.com/riscv/riscv-crypto>. +``experimental-zimop`` + LLVM implements the `v0.1 proposed specification <https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc>`__. + To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`. Vendor Extensions diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 20c6a525a86ba7..fcb11c8c51398d 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -108,6 +108,29 @@ let TargetPrefix = "riscv" in { def int_riscv_xperm8 : BitManipGPRGPRIntrinsics; } // TargetPrefix = "riscv" +//===----------------------------------------------------------------------===// +// May-Be-Operations + +let TargetPrefix = "riscv" in { + + class MOPGPRIntrinsics + : DefaultAttrsIntrinsic<[llvm_any_ty], + [LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable]>; + class MOPGPRGPRIntrinsics + : DefaultAttrsIntrinsic<[llvm_any_ty], + [LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable]>; + + // Zimop + foreach i = 0...31 in { + def int_riscv_mopr#i : MOPGPRIntrinsics; + } + foreach i = 0...7 in { + def int_riscv_moprr#i : MOPGPRGPRIntrinsics; + } +} // TargetPrefix = "riscv" + //===----------------------------------------------------------------------===// // Vectors diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 6322748430063c..1b303ba1e9431d 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -177,6 +177,8 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { {"zicfilp", RISCVExtensionVersion{0, 2}}, {"zicond", RISCVExtensionVersion{1, 0}}, + {"zimop", RISCVExtensionVersion{0, 1}}, + {"ztso", RISCVExtensionVersion{0, 1}}, {"zvbb", RISCVExtensionVersion{1, 0}}, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 294927aecb94b8..5b642090b7b9eb 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -687,6 +687,11 @@ def HasStdExtZicond : Predicate<"Subtarget->hasStdExtZicond()">, AssemblerPredicate<(all_of FeatureStdExtZicond), "'Zicond' (Integer Conditional Operations)">; +def FeatureStdExtZimop : SubtargetFeature<"experimental-zimop", "HasStdExtZimop", "true", + "'Zimop' (May-Be-Operations)">; +def HasStdExtZimop : Predicate<"Subtarget->hasStdExtZimop()">, + AssemblerPredicate<(all_of FeatureStdExtZimop), + "'Zimop' (May-Be-Operations)">; def FeatureStdExtSmaia : SubtargetFeature<"smaia", "HasStdExtSmaia", "true", "'Smaia' (Smaia encompasses all added CSRs and all " diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index e80ba26800a131..cb68752210d540 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -401,6 +401,27 @@ class RVInstIUnary<bits<12> imm12, bits<3> funct3, RISCVOpcode opcode, let Inst{31-20} = imm12; } +class RVInstIMopr<bits<7> imm7, bits<5> imm5, bits<3> funct3, RISCVOpcode opcode, + dag outs, dag ins, string opcodestr, string argstr> + : RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> { + let Inst{31} = imm7{6}; + let Inst{30} = imm5{4}; + let Inst{29-28} = imm7{5-4}; + let Inst{27-26} = imm5{3-2}; + let Inst{25-22} = imm7{3-0}; + let Inst{21-20} = imm5{1-0}; +} + +class RVInstRMoprr<bits<4> imm4, bits<3> imm3, bits<3> funct3, RISCVOpcode opcode, + dag outs, dag ins, string opcodestr, string argstr> + : RVInstRBase<funct3, opcode, outs, ins, opcodestr, argstr> { + let Inst{31} = imm4{3}; + let Inst{30} = imm3{2}; + let Inst{29-28} = imm4{2-1}; + let Inst{27-26} = imm3{1-0}; + let Inst{25} = imm4{0}; +} + class RVInstS<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins, string opcodestr, string argstr> : RVInst<outs, ins, opcodestr, argstr, [], InstFormatS> { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index edc08187d8f775..bf1ed705474447 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -597,6 +597,16 @@ class Priv_rr<string opcodestr, bits<7> funct7> let rd = 0; } +class RVMopr<bits<7> imm7, bits<5> imm5, bits<3> funct3, + RISCVOpcode opcode, string opcodestr> + : RVInstIMopr<imm7, imm5, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1), + opcodestr, "$rd, $rs1">; + +class RVMoprr<bits<4> imm4, bits<3> imm3, bits<3> funct3, + RISCVOpcode opcode, string opcodestr> + : RVInstRMoprr<imm4, imm3, funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), + opcodestr, "$rd, $rs1, $rs2">; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -786,6 +796,22 @@ def SRAW : ALUW_rr<0b0100000, 0b101, "sraw">, } // IsSignExtendingOpW = 1 } // Predicates = [IsRV64] +// Zimop instructions + +foreach i = 0...31 in { + let Predicates = [HasStdExtZimop] in { + def MOPR#i : RVMopr<0b1000111, i, 0b100, OPC_SYSTEM, "mop.r."#i>, + Sched<[]>; + } // Predicates = [HasStdExtZimop] +} + +foreach i = 0...7 in { + let Predicates = [HasStdExtZimop] in { + def MOPRR#i : RVMoprr<0b1001, i, 0b100, OPC_SYSTEM, "mop.rr."#i>, + Sched<[]>; + } // Predicates = [HasStdExtZimop] +} + //===----------------------------------------------------------------------===// // Privileged instructions //===----------------------------------------------------------------------===// @@ -1551,6 +1577,25 @@ let Predicates = [HasStdExtC, OptForMinSize] in { def : SelectCompressOpt<SETNE>; } +// Zimop instructions +foreach i = 0...31 in { + defvar moprx = !cast<Instruction>("MOPR"#i); + defvar riscv_moprx = !cast<Intrinsic>("int_riscv_mopr"#i); + let Predicates = [HasStdExtZimop] in { + def : Pat<(XLenVT (riscv_moprx (XLenVT GPR:$rs1))), + (moprx GPR:$rs1)>; + } // Predicates = [HasStdExtZimop] +} + +foreach i = 0...7 in { + defvar moprrx = !cast<Instruction>("MOPRR"#i); + defvar riscv_moprrx = !cast<Intrinsic>("int_riscv_moprr"#i); + let Predicates = [HasStdExtZimop] in { + def : Pat<(XLenVT (riscv_moprrx (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))), + (moprrx GPR:$rs1, GPR:$rs2)>; + } // Predicates = [HasStdExtZimop] +} + /// Branches and jumps // Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction. diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 030ae06af6d282..0afe9b9f916d8c 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -83,6 +83,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvksh %s -o - | FileCheck --check-prefix=RV32ZVKSH %s ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvkt %s -o - | FileCheck --check-prefix=RV32ZVKT %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zimop %s -o - | FileCheck --check-prefix=RV32ZIMOP %s ; RUN: llc -mtriple=riscv32 -mattr=+smaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SMAIA %s ; RUN: llc -mtriple=riscv32 -mattr=+ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SSAIA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZFBFMIN %s @@ -173,6 +174,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvksh %s -o - | FileCheck --check-prefix=RV64ZVKSH %s ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvkt %s -o - | FileCheck --check-prefix=RV64ZVKT %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV64ZICOND %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zimop %s -o - | FileCheck --check-prefix=RV64ZIMOP %s ; RUN: llc -mtriple=riscv64 -mattr=+smaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SMAIA %s ; RUN: llc -mtriple=riscv64 -mattr=+ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SSAIA %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZFBFMIN %s @@ -265,6 +267,7 @@ ; RV32ZVKSH: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvksh1p0_zvl32b1p0" ; RV32ZVKT: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvkt1p0_zvl32b1p0" ; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0" +; RV32ZIMOP: .attribute 5, "rv32i2p1_zimop0p1" ; RV32SMAIA: .attribute 5, "rv32i2p1_smaia1p0" ; RV32SSAIA: .attribute 5, "rv32i2p1_ssaia1p0" ; RV32ZFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin0p8" @@ -354,6 +357,7 @@ ; RV64ZVKSH: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvksh1p0_zvl32b1p0" ; RV64ZVKT: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvkt1p0_zvl32b1p0" ; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0" +; RV64ZIMOP: .attribute 5, "rv64i2p1_zimop0p1" ; RV64SMAIA: .attribute 5, "rv64i2p1_smaia1p0" ; RV64SSAIA: .attribute 5, "rv64i2p1_ssaia1p0" ; RV64ZFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin0p8" diff --git a/llvm/test/MC/RISCV/rv32zimop-invalid.s b/llvm/test/MC/RISCV/rv32zimop-invalid.s new file mode 100644 index 00000000000000..e6c3adc4cd3092 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zimop-invalid.s @@ -0,0 +1,6 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zimop < %s 2>&1 | FileCheck %s + +# Too few operands +mop.r.0 t0 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +# Too few operands +mop.rr.0 t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction diff --git a/llvm/test/MC/RISCV/rvzimop-valid.s b/llvm/test/MC/RISCV/rvzimop-valid.s new file mode 100644 index 00000000000000..1552936629902c --- /dev/null +++ b/llvm/test/MC/RISCV/rvzimop-valid.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zimop -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zimop -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zimop < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zimop -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zimop < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zimop -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: mop.r.0 a2, a1 +# CHECK-ASM: encoding: [0x73,0xc6,0xc5,0x81] +mop.r.0 a2, a1 + +# CHECK-ASM-AND-OBJ: mop.r.31 a2, a1 +# CHECK-ASM: encoding: [0x73,0xc6,0xf5,0xcd] +mop.r.31 a2, a1 + +# CHECK-ASM-AND-OBJ: mop.rr.0 a3, a2, a1 +# CHECK-ASM: encoding: [0xf3,0x46,0xb6,0x82] +mop.rr.0 a3, a2, a1 + +# CHECK-ASM-AND-OBJ: mop.rr.7 a3, a2, a1 +# CHECK-ASM: encoding: [0xf3,0x46,0xb6,0xce] +mop.rr.7 a3, a2, a1 \ No newline at end of file diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp index 549964eed55518..bd41fa23387399 100644 --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -738,6 +738,7 @@ R"(All available -march extensions for RISC-V Experimental extensions zicfilp 0.2 This is a long dummy description zicond 1.0 + zimop 0.1 zacas 1.0 zfbfmin 0.8 ztso 0.1 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits