[llvm-branch-commits] [clang] 402aaf7 - [RISCV] Add non-standard Xin feature for N3 core
Author: Jun Ma Date: 2021-12-17T10:30:02+08:00 New Revision: 402aaf7d3f6d48e023b0aa6005c439a18cd4d029 URL: https://github.com/llvm/llvm-project/commit/402aaf7d3f6d48e023b0aa6005c439a18cd4d029 DIFF: https://github.com/llvm/llvm-project/commit/402aaf7d3f6d48e023b0aa6005c439a18cd4d029.diff LOG: [RISCV] Add non-standard Xin feature for N3 core Added: Modified: clang/test/Driver/riscv-arch.c clang/test/Preprocessor/riscv-target-features.c llvm/lib/Support/RISCVISAInfo.cpp llvm/lib/Target/RISCV/RISCV.td llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/lib/Target/RISCV/RISCVInstrInfoZb.td llvm/lib/Target/RISCV/RISCVSubtarget.h llvm/test/CodeGen/RISCV/select-bare.ll llvm/test/MC/RISCV/attribute-arch.s Removed: diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c index 5b99643309a57..8866d9301b545 100644 --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -472,3 +472,12 @@ // RUN: %clang -target riscv32-unknown-elf -march=rv32izvlsseg0p10 -menable-experimental-extensions -### %s -c 2>&1 | \ // RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVLSSEG-GOODVERS %s // RV32-EXPERIMENTAL-ZVLSSEG-GOODVERS: "-target-feature" "+experimental-zvlsseg" + +// RUN: %clang -target riscv32-unknown-elf -march=rv32ixin -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-XIN-NOFLAG %s +// RV32-EXPERIMENTAL-XIN-NOFLAG: error: invalid arch name 'rv32ixin' +// RV32-EXPERIMENTAL-XIN-NOFLAG: requires '-menable-experimental-extensions' + +// RUN: %clang -target riscv32-unknown-elf -march=rv32ixin0p1 -menable-experimental-extensions -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-XIN %s +// RV32-EXPERIMENTAL-XIN: "-target-feature" "+experimental-xin" diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index a0a1ac59cc4cc..14a605a7ef43c 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -33,6 +33,7 @@ // CHECK-NOT: __riscv_vector // CHECK-NOT: __riscv_zvamo // CHECK-NOT: __riscv_zvlsseg +// CHECK-NOT: __riscv_xin // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32im -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-M-EXT %s @@ -223,3 +224,11 @@ // RUN: -march=rv64izfh0p1 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZFH-EXT %s // CHECK-ZFH-EXT: __riscv_zfh 1000 + +// RUN: %clang -target riscv32-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv32i_xin0p1 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XIN-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu -menable-experimental-extensions \ +// RUN: -march=rv64i_xin0p1 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XIN-EXT %s +// CHECK-XIN-EXT: __riscv_xin 1000 diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 94929e7e052f1..b4a310254db59 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -66,6 +66,8 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { {"zfhmin", RISCVExtensionVersion{0, 1}}, {"zfh", RISCVExtensionVersion{0, 1}}, + +{"xin", RISCVExtensionVersion{0, 1}}, }; static bool stripExperimentalPrefix(StringRef &Ext) { diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 772a4f8ecd535..4a94581107b19 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -176,6 +176,19 @@ def HasStdExtZvamo : Predicate<"Subtarget->hasStdExtZvamo()">, AssemblerPredicate<(all_of FeatureStdExtZvamo), "'Zvamo' (Vector AMO Operations)">; +def FeatureStdExtXin +: SubtargetFeature<"experimental-xin", "HasStdExtXin", "true", + "'Xin' ('N3' Instructions)">; +def HasStdExtXin : Predicate<"Subtarget->hasStdExtXin()">, + AssemblerPredicate<(all_of FeatureStdExtXin), + "'Xin' ('N3' Instructions)">; + +def HasStdExtZbtOrXin +: Predicate<"Subtarget->hasStdExtZbt() || Subtarget->hasStdExtXin()">, +AssemblerPredicate<(any_of FeatureStdExtZbt, FeatureStdExtXin), + "'Zbt' (Ternary 'B' Instructions) or " + "'Xin' ('N3' Instructions)">; + def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">; def IsRV64 : Predicate<"Subtarget->is64Bit()">, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index f33965b504591..9c485e834b21d 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.c
[llvm-branch-commits] [llvm] eb64afd - [RISCV] Add N3 Load/Store under Xin
Author: Jun Ma Date: 2021-12-17T10:30:02+08:00 New Revision: eb64afdb5c50932d271952538a4778849029a68d URL: https://github.com/llvm/llvm-project/commit/eb64afdb5c50932d271952538a4778849029a68d DIFF: https://github.com/llvm/llvm-project/commit/eb64afdb5c50932d271952538a4778849029a68d.diff LOG: [RISCV] Add N3 Load/Store under Xin Added: llvm/lib/Target/RISCV/RISCVInstrInfoXin.td Modified: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp llvm/lib/Target/RISCV/RISCVInstrFormats.td llvm/lib/Target/RISCV/RISCVInstrInfo.td Removed: diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 75592dd4c6f54..d54faba4315a6 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -669,6 +669,14 @@ struct RISCVOperand : public MCParsedAsmOperand { VK == RISCVMCExpr::VK_RISCV_None; } + bool isSImm10Lsb000() const { +int64_t Imm; +RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; +bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); +return IsConstantImm && isShiftedInt<7, 3>(Imm) && + VK == RISCVMCExpr::VK_RISCV_None; + } + bool isUImm20LUI() const { RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; int64_t Imm; diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index 6a16b6354f954..bcb6413a17ad0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -145,6 +145,7 @@ def OPC_BRANCH: RISCVOpcode<"BRANCH",0b1100011>; def OPC_JALR : RISCVOpcode<"JALR", 0b1100111>; def OPC_JAL : RISCVOpcode<"JAL", 0b110>; def OPC_SYSTEM: RISCVOpcode<"SYSTEM",0b1110011>; +def OPC_CUSTOM1 : RISCVOpcode<"CUSTOM1", 0b0001011>; class RVInst pattern, InstFormat format> diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 71eb6f01a4f42..1db89b71af294 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1478,3 +1478,4 @@ include "RISCVInstrInfoC.td" include "RISCVInstrInfoZb.td" include "RISCVInstrInfoV.td" include "RISCVInstrInfoZfh.td" +include "RISCVInstrInfoXin.td" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXin.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXin.td new file mode 100644 index 0..eed9e8fab6a3f --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXin.td @@ -0,0 +1,90 @@ +//===-- RISCVInstrInfoXin.td - Target Description for Xin ---*- 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 +// +//===--===// +// +// This file describes the Xin instructions in TableGen format. +// +//===--===// + + +//===--===// +// Operand and SDNode transformation definitions. +//===--===// + +// A 10-bit signed immediate where the least significant three bits are zero. +def simm10_lsb000: Operand, +ImmLeaf(Imm);}]> { + let ParserMatchClass = SImmAsmOperand<10, "Lsb000">; + let EncoderMethod = "getImmOpValue"; + let DecoderMethod = "decodeSImmOperand<10>"; + let MCOperandPredicate = [{ +int64_t Imm; +if (!MCOp.evaluateAsConstantImm(Imm)) + return false; +return isShiftedInt<7, 3>(Imm); + }]; +} + +//===--===// +// Instruction class templates +//===--===// +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class RVXinLoadPair funct3, string opcodestr> + : RVInstR<0, funct3, OPC_CUSTOM1, + (outs GPR:$rd, GPR:$rs2), (ins GPR:$rs1, simm10_lsb000:$imm), + opcodestr, "$rd, $rs2, ${imm}(${rs1})"> { + bits<10> imm; + let Inst{31-25} = imm{9-3}; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +class RVXinStorePair funct3, string opcodestr> + : RVInstR<0, funct3, OPC_CUSTOM1, + (outs), (ins GPR:$rd, GPR:$rs2, GPR:$rs1, simm10_lsb000:$imm), + opcodestr, "$rd, $rs2, ${imm}(${rs1})"> { + bits<10> imm; + let Inst{31-25} = imm{9-3}; +} + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class RVXinLoadReg funct7, bits<3> funct3, string opcodestr> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +class RVXinStoreReg funct7, bits<3> funct3, string opcodestr> + : RVInstR; + +let Predicates = [HasStdE
[llvm-branch-commits] [llvm] dd399a6 - [RISCV] Use ldp/sdp for EPI
Author: Jun Ma Date: 2021-12-17T12:08:28+08:00 New Revision: dd399a6194e8506d2af87794d78cb920c66f19b0 URL: https://github.com/llvm/llvm-project/commit/dd399a6194e8506d2af87794d78cb920c66f19b0 DIFF: https://github.com/llvm/llvm-project/commit/dd399a6194e8506d2af87794d78cb920c66f19b0.diff LOG: [RISCV] Use ldp/sdp for EPI Added: llvm/test/CodeGen/RISCV/callee-saved-n3.ll llvm/test/CodeGen/RISCV/large-stack-n3.ll Modified: llvm/lib/Target/RISCV/RISCVFrameLowering.cpp Removed: diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index f5d491938050..9e1381ec5c6e 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -1010,7 +1010,11 @@ RISCVFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF) const { // Return the FirstSPAdjustAmount if the StackSize can not fit in signed // 12-bit and there exists a callee saved register need to be pushed. - if (!isInt<12>(StackSize) && (CSI.size() > 0)) { + if (!hasFP(MF) && !isInt<10>(StackSize) && + STI.hasFeature(RISCV::Feature64Bit) && + STI.hasFeature(RISCV::FeatureStdExtXin) && (CSI.size() > 1)) { +return 512 - getStackAlign().value(); + } else if (!isInt<12>(StackSize) && (CSI.size() > 0)) { // FirstSPAdjustAmount is choosed as (2048 - StackAlign) // because 2048 will cause sp = sp + 2048 in epilogue split into // multi-instructions. The offset smaller than 2048 can fit in signle @@ -1048,12 +1052,43 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( // Manually spill values not spilled by libcall. const auto &NonLibcallCSI = getNonLibcallCSI(*MF, CSI); - for (auto &CS : NonLibcallCSI) { + unsigned Count = NonLibcallCSI.size(); + for (unsigned i = 0; i < Count; i += 1) { // Insert the spill to the stack frame. -Register Reg = CS.getReg(); +Register Reg = NonLibcallCSI[i].getReg(); +int FI = NonLibcallCSI[i].getFrameIdx(); +bool IsN3 = STI.hasFeature(RISCV::Feature64Bit) && +STI.hasFeature(RISCV::FeatureStdExtXin); +if (IsN3 && unsigned(i + 1) < Count) { + unsigned NextReg = NonLibcallCSI[i + 1].getReg(); + int NextFI = NonLibcallCSI[i + 1].getFrameIdx(); + if (!hasFP(*MF) && RISCV::GPRRegClass.contains(Reg) && + RISCV::GPRRegClass.contains(NextReg) && FI + 1 == NextFI) { + +MachineFrameInfo &MFI = MF->getFrameInfo(); +MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(RISCV::SDP)); + +MIB.addReg(Reg, getKillRegState(!MBB.isLiveIn(Reg))); +MIB.addMemOperand(MF->getMachineMemOperand( +MachinePointerInfo::getFixedStack(*MF, FI), +MachineMemOperand::MOStore, MFI.getObjectSize(FI), +MFI.getObjectAlign(FI))); + +MIB.addReg(NextReg, getKillRegState(!MBB.isLiveIn(NextReg))); +MIB.addMemOperand(MF->getMachineMemOperand( +MachinePointerInfo::getFixedStack(*MF, NextFI), +MachineMemOperand::MOStore, MFI.getObjectSize(NextFI), +MFI.getObjectAlign(NextFI))); + +MIB.addFrameIndex(FI).addImm(0); + +i += 1; +continue; + } +} + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); -TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), CS.getFrameIdx(), -RC, TRI); +TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), FI, RC, TRI); } return true; @@ -1078,10 +1113,43 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( // load-to-use data hazard between loading RA and return by RA. // loadRegFromStackSlot can insert multiple instructions. const auto &NonLibcallCSI = getNonLibcallCSI(*MF, CSI); - for (auto &CS : NonLibcallCSI) { -Register Reg = CS.getReg(); + unsigned Count = NonLibcallCSI.size(); + for (unsigned i = 0; i < Count; i += 1) { +// Insert the spill to the stack frame. +Register Reg = NonLibcallCSI[i].getReg(); +int FI = NonLibcallCSI[i].getFrameIdx(); +bool IsN3 = STI.hasFeature(RISCV::Feature64Bit) && +STI.hasFeature(RISCV::FeatureStdExtXin); +if (IsN3 && unsigned(i + 1) < Count) { + unsigned NextReg = NonLibcallCSI[i + 1].getReg(); + int NextFI = NonLibcallCSI[i + 1].getFrameIdx(); + if (!hasFP(*MF) && RISCV::GPRRegClass.contains(Reg) && + RISCV::GPRRegClass.contains(NextReg) && FI + 1 == NextFI) { + +MachineFrameInfo &MFI = MF->getFrameInfo(); +MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(RISCV::LDP)); + +MIB.addReg(Reg, RegState::Define); +MIB.addMemOperand(MF->getMachineMemOperand( +MachinePointerInfo::getFixedStack(*MF, FI), +MachineMemOperand::MOLoad, MFI.getObjectSize(FI), +MFI.getObjectAlign(FI))); + +MIB.addReg(NextReg, RegState::Defi