Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions clang/test/Misc/target-invalid-cpu-note/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// RISCV64: error: unknown target CPU 'not-a-cpu'
// RISCV64-NEXT: note: valid target CPU values are:
// RISCV64-SAME: {{^}} generic-rv64
// RISCV64-SAME: {{^}}, mips-p8700
// RISCV64-SAME: {{^}}, rocket-rv64
// RISCV64-SAME: {{^}}, sifive-p450
// RISCV64-SAME: {{^}}, sifive-p470
Expand Down Expand Up @@ -72,6 +73,7 @@
// TUNE-RISCV64: error: unknown target CPU 'not-a-cpu'
// TUNE-RISCV64-NEXT: note: valid target CPU values are:
// TUNE-RISCV64-SAME: {{^}} generic-rv64
// TUNE-RISCV64-SAME: {{^}}, mips-p8700
// TUNE-RISCV64-SAME: {{^}}, rocket-rv64
// TUNE-RISCV64-SAME: {{^}}, sifive-p450
// TUNE-RISCV64-SAME: {{^}}, sifive-p470
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ include "RISCVMacroFusion.td"
// RISC-V Scheduling Models
//===----------------------------------------------------------------------===//

include "RISCVSchedMIPSP8700.td"
include "RISCVSchedRocket.td"
include "RISCVSchedSiFive7.td"
include "RISCVSchedSiFiveP400.td"
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,10 @@ def TuneConditionalCompressedMoveFusion
def HasConditionalMoveFusion : Predicate<"Subtarget->hasConditionalMoveFusion()">;
def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()">;

def TuneMIPSP8700
: SubtargetFeature<"mips-p8700", "RISCVProcFamily", "Others",
"MIPS p8700 processor">;

def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
"SiFive 7-Series processors">;

Expand Down
14 changes: 13 additions & 1 deletion llvm/lib/Target/RISCV/RISCVProcessors.td
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ def GENERIC_RV64 : RISCVProcessorModel<"generic-rv64",
// to change to the appropriate rv32/rv64 version.
def GENERIC : RISCVTuneProcessorModel<"generic", NoSchedModel>, GenericTuneInfo;

def MIPS_P8700 : RISCVProcessorModel<"mips-p8700",
MIPSP8700Model,
[Feature64Bit,
FeatureStdExtI,
FeatureStdExtM,
FeatureStdExtA,

Choose a reason for hiding this comment

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

In the A extension, P8700 doesn't support the AMO* instructions due to a bug and instead the compiler should instrument LR/SC instructions. How do you plan to disable the AMO* instructions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

P8700 emulates AMO instructions, through either illegal instruction exceptions or MIPS custom exceptions. We will share/upstream both open-sbi and linux patches very soon. At [0] you can see what we are using downstream at the moment.

[0] https://github.com/MIPS/linux/tree/mti-v6.12

Choose a reason for hiding this comment

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

performance wise, will it be better to not select AMO instructions from the first place?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, if you're only implementing AMOs through trap-and-emulate then there's really little point telling software they exist. LR/SC will be orders of magnitude faster. You don't have an RV64GCZba_Zbb core, you have an RV64IMFDCZba_Zbb_Zalrsc core, and bodge in Zaamo in order to emulate being able to run RV64GC software. But claiming RV64GCZba_Zbb is just misleading to software, it'll perform atrociously if it's actually using atomics.

FeatureStdExtF,
FeatureStdExtD,
FeatureStdExtC,
FeatureStdExtZba,
FeatureStdExtZbb],
[TuneMIPSP8700]>;

def ROCKET_RV32 : RISCVProcessorModel<"rocket-rv32",
RocketModel,
[Feature32Bit,
Expand Down Expand Up @@ -279,7 +292,6 @@ def SIFIVE_P470 : RISCVProcessorModel<"sifive-p470", SiFiveP400Model,
!listconcat(SiFiveP400TuneFeatures,
[TuneNoSinkSplatOperands])>;


def SIFIVE_P670 : RISCVProcessorModel<"sifive-p670", SiFiveP600Model,
!listconcat(RVA22U64Features,
[FeatureStdExtV,
Expand Down
279 changes: 279 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
//===-- RISCVSchedMIPSP8700.td - MIPS RISC-V Processor -----*- 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
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// RISC-V processor by MIPS.
//===----------------------------------------------------------------------===//

def MIPSP8700Model : SchedMachineModel {
int IssueWidth = 4;
int MicroOpBufferSize = 96; // as per the specification
int LoadLatency = 4;
int MispredictPenalty = 8; // TODO: Estimated
let CompleteModel = 0;
}

let SchedModel = MIPSP8700Model in {

// Handle ALQ Pipelines.
def p8700ALQ : ProcResource<1> { let BufferSize = 16; }
def p8700IssueALU : ProcResource<1> { let Super = p8700ALQ; }


// Handle AGQ Pipelines.
def p8700AGQ : ProcResource<3> { let BufferSize = 16; }
def p8700IssueAL2 : ProcResource<1> { let Super = p8700AGQ; }
def p8700IssueCTISTD : ProcResource<1> { let Super = p8700AGQ; }
def p8700IssueLDST : ProcResource<1> { let Super = p8700AGQ; }
def p8700GpDiv : ProcResource<1>;
def p8700GpMul : ProcResource<1>;
def p8700WriteEitherALU : ProcResGroup<[p8700IssueALU, p8700IssueAL2]>;

let Latency = 1 in {
def : WriteRes<WriteIALU, [p8700WriteEitherALU]>;
def : WriteRes<WriteIALU32, [p8700WriteEitherALU]>;
def : WriteRes<WriteShiftImm, [p8700WriteEitherALU]>;
def : WriteRes<WriteShiftImm32, [p8700WriteEitherALU]>;
def : WriteRes<WriteShiftReg, [p8700WriteEitherALU]>;
def : WriteRes<WriteShiftReg32, [p8700WriteEitherALU]>;

// Handle zba.
def : WriteRes<WriteSHXADD, [p8700WriteEitherALU]>;
def : WriteRes<WriteSHXADD32, [p8700WriteEitherALU]>;

// Handle zbb.
def : WriteRes<WriteRotateReg, [p8700WriteEitherALU]>;
def : WriteRes<WriteRotateImm, [p8700WriteEitherALU]>;
def : WriteRes<WriteCLZ, [p8700WriteEitherALU]>;
def : WriteRes<WriteCTZ, [p8700WriteEitherALU]>;
def : WriteRes<WriteCPOP, [p8700WriteEitherALU]>;
def : WriteRes<WriteRotateReg32, [p8700WriteEitherALU]>;
def : WriteRes<WriteRotateImm32, [p8700WriteEitherALU]>;
def : WriteRes<WriteCLZ32, [p8700WriteEitherALU]>;
def : WriteRes<WriteCTZ32, [p8700WriteEitherALU]>;
def : WriteRes<WriteCPOP32, [p8700WriteEitherALU]>;
def : WriteRes<WriteREV8, [p8700WriteEitherALU]>;
def : WriteRes<WriteORCB, [p8700WriteEitherALU]>;
def : WriteRes<WriteIMinMax, []>;
}

let Latency = 0 in {
def : WriteRes<WriteNop, [p8700WriteEitherALU]>;
}

let Latency = 4 in {
def : WriteRes<WriteLDB, [p8700IssueLDST]>;
def : WriteRes<WriteLDH, [p8700IssueLDST]>;
def : WriteRes<WriteLDW, [p8700IssueLDST]>;
def : WriteRes<WriteLDD, [p8700IssueLDST]>;

def : WriteRes<WriteAtomicW, [p8700IssueLDST]>;
def : WriteRes<WriteAtomicD, [p8700IssueLDST]>;
def : WriteRes<WriteAtomicLDW, [p8700IssueLDST]>;
def : WriteRes<WriteAtomicLDD, [p8700IssueLDST]>;
}

let Latency = 8 in {
def : WriteRes<WriteFLD32, [p8700IssueLDST]>;
def : WriteRes<WriteFLD64, [p8700IssueLDST]>;
}

let Latency = 3 in {
def : WriteRes<WriteSTB, [p8700IssueLDST]>;
def : WriteRes<WriteSTH, [p8700IssueLDST]>;
def : WriteRes<WriteSTW, [p8700IssueLDST]>;
def : WriteRes<WriteSTD, [p8700IssueLDST]>;

def : WriteRes<WriteAtomicSTW, [p8700IssueLDST]>;
def : WriteRes<WriteAtomicSTD, [p8700IssueLDST]>;
}

let Latency = 1 in {
def : WriteRes<WriteFST32, [p8700IssueLDST]>;
def : WriteRes<WriteFST64, [p8700IssueLDST]>;
}

let Latency = 7 in {
def : WriteRes<WriteFMovI32ToF32, [p8700IssueLDST]>;
def : WriteRes<WriteFMovF32ToI32, [p8700IssueLDST]>;
def : WriteRes<WriteFMovI64ToF64, [p8700IssueLDST]>;
def : WriteRes<WriteFMovF64ToI64, [p8700IssueLDST]>;
}

let Latency = 4 in {
def : WriteRes<WriteIMul, [p8700GpMul]>;
def : WriteRes<WriteIMul32, [p8700GpMul]>;
}

let Latency = 8, ReleaseAtCycles = [5] in {
def : WriteRes<WriteIDiv, [p8700GpDiv]>;
def : WriteRes<WriteIDiv32, [p8700GpDiv]>;
}

def : WriteRes<WriteIRem, []>;
def : WriteRes<WriteIRem32, []>;

// Handle CTISTD Pipeline.
let Latency = 1 in {
def : WriteRes<WriteJmp, [p8700IssueCTISTD]>;
def : WriteRes<WriteJmpReg, [p8700IssueCTISTD]>;
}

let Latency = 2 in {
def : WriteRes<WriteJal, [p8700IssueCTISTD]>;
def : WriteRes<WriteJalr, [p8700IssueCTISTD]>;
}

// Handle FPU Pipelines.
def p8700FPQ : ProcResource<3> { let BufferSize = 16; }
def p8700IssueFPUS : ProcResource<1> { let Super = p8700FPQ; }
def p8700IssueFPUL : ProcResource<1> { let Super = p8700FPQ; }
def p8700IssueFPULoad : ProcResource<1> { let Super = p8700FPQ; }
def p8700FpuApu : ProcResource<1>;
def p8700FpuLong : ProcResource<1>;

let Latency = 4, ReleaseAtCycles = [1, 1] in {
def : WriteRes<WriteFCvtI32ToF32, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtI32ToF64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtI64ToF32, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtI64ToF64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF32ToI32, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF32ToI64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF32ToF64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF64ToI32, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF64ToI64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFCvtF64ToF32, [p8700IssueFPUL, p8700FpuApu]>;

def : WriteRes<WriteFAdd32, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFAdd64, [p8700IssueFPUL, p8700FpuApu]>;
}

let Latency = 2, ReleaseAtCycles = [1, 1] in {
def : WriteRes<WriteFSGNJ32, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFMinMax32, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFSGNJ64, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFMinMax64, [p8700IssueFPUS, p8700FpuApu]>;

def : WriteRes<WriteFCmp32, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFCmp64, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFClass32, [p8700IssueFPUS, p8700FpuApu]>;
def : WriteRes<WriteFClass64, [p8700IssueFPUS, p8700FpuApu]>;
}

let Latency = 8, ReleaseAtCycles = [1, 1] in {
def : WriteRes<WriteFMA32, [p8700FpuLong, p8700FpuApu]>;
def : WriteRes<WriteFMA64, [p8700FpuLong, p8700FpuApu]>;
}

let Latency = 5, ReleaseAtCycles = [1, 1] in {
def : WriteRes<WriteFMul32, [p8700FpuLong, p8700FpuApu]>;
def : WriteRes<WriteFMul64, [p8700FpuLong, p8700FpuApu]>;
}

let Latency = 17, ReleaseAtCycles = [1, 17] in {
def : WriteRes<WriteFDiv32, [p8700FpuLong, p8700FpuApu]>;
def : WriteRes<WriteFSqrt32, [p8700FpuLong, p8700FpuApu]>;

def : WriteRes<WriteFDiv64, [p8700IssueFPUL, p8700FpuApu]>;
def : WriteRes<WriteFSqrt64, [p8700IssueFPUL, p8700FpuApu]>;
}

def : WriteRes<WriteCSR, [p8700ALQ]>;

// Bypass and advance.
def : ReadAdvance<ReadIALU, 0>;
def : ReadAdvance<ReadIALU32, 0>;
def : ReadAdvance<ReadShiftImm, 0>;
def : ReadAdvance<ReadShiftImm32, 0>;
def : ReadAdvance<ReadShiftReg, 0>;
def : ReadAdvance<ReadShiftReg32, 0>;
def : ReadAdvance<ReadSHXADD, 0>;
def : ReadAdvance<ReadSHXADD32, 0>;
def : ReadAdvance<ReadRotateReg, 0>;
def : ReadAdvance<ReadRotateImm, 0>;
def : ReadAdvance<ReadCLZ, 0>;
def : ReadAdvance<ReadCTZ, 0>;
def : ReadAdvance<ReadCPOP, 0>;
def : ReadAdvance<ReadRotateReg32, 0>;
def : ReadAdvance<ReadRotateImm32, 0>;
def : ReadAdvance<ReadCLZ32, 0>;
def : ReadAdvance<ReadCTZ32, 0>;
def : ReadAdvance<ReadCPOP32, 0>;
def : ReadAdvance<ReadREV8, 0>;
def : ReadAdvance<ReadORCB, 0>;
def : ReadAdvance<ReadIMul, 0>;
def : ReadAdvance<ReadIMul32, 0>;
def : ReadAdvance<ReadIDiv, 0>;
def : ReadAdvance<ReadIDiv32, 0>;
def : ReadAdvance<ReadJmp, 0>;
def : ReadAdvance<ReadJalr, 0>;
def : ReadAdvance<ReadFMovI32ToF32, 0>;
def : ReadAdvance<ReadFMovF32ToI32, 0>;
def : ReadAdvance<ReadFMovI64ToF64, 0>;
def : ReadAdvance<ReadFMovF64ToI64, 0>;
def : ReadAdvance<ReadFSGNJ32, 0>;
def : ReadAdvance<ReadFMinMax32, 0>;
def : ReadAdvance<ReadFSGNJ64, 0>;
def : ReadAdvance<ReadFMinMax64, 0>;
def : ReadAdvance<ReadFCmp32, 0>;
def : ReadAdvance<ReadFCmp64, 0>;
def : ReadAdvance<ReadFCvtI32ToF32, 0>;
def : ReadAdvance<ReadFCvtI32ToF64, 0>;
def : ReadAdvance<ReadFCvtI64ToF32, 0>;
def : ReadAdvance<ReadFCvtI64ToF64, 0>;
def : ReadAdvance<ReadFCvtF32ToI32, 0>;
def : ReadAdvance<ReadFCvtF32ToI64, 0>;
def : ReadAdvance<ReadFCvtF32ToF64, 0>;
def : ReadAdvance<ReadFCvtF64ToI32, 0>;
def : ReadAdvance<ReadFCvtF64ToI64, 0>;
def : ReadAdvance<ReadFCvtF64ToF32, 0>;
def : ReadAdvance<ReadFAdd32, 0>;
def : ReadAdvance<ReadFAdd64, 0>;
def : ReadAdvance<ReadFMul32, 0>;
def : ReadAdvance<ReadFMul64, 0>;
def : ReadAdvance<ReadFMA32, 0>;
def : ReadAdvance<ReadFMA32Addend, 0>;
def : ReadAdvance<ReadFMA64, 0>;
def : ReadAdvance<ReadFMA64Addend, 0>;
def : ReadAdvance<ReadFDiv32, 0>;
def : ReadAdvance<ReadFSqrt32, 0>;
def : ReadAdvance<ReadFDiv64, 0>;
def : ReadAdvance<ReadFSqrt64, 0>;
def : ReadAdvance<ReadAtomicWA, 0>;
def : ReadAdvance<ReadAtomicWD, 0>;
def : ReadAdvance<ReadAtomicDA, 0>;
def : ReadAdvance<ReadAtomicDD, 0>;
def : ReadAdvance<ReadAtomicLDW, 0>;
def : ReadAdvance<ReadAtomicLDD, 0>;
def : ReadAdvance<ReadAtomicSTW, 0>;
def : ReadAdvance<ReadAtomicSTD, 0>;
def : ReadAdvance<ReadFStoreData, 0>;
def : ReadAdvance<ReadCSR, 0>;
def : ReadAdvance<ReadMemBase, 0>;
def : ReadAdvance<ReadStoreData, 0>;
def : ReadAdvance<ReadFMemBase, 0>;
def : ReadAdvance<ReadFClass32, 0>;
def : ReadAdvance<ReadFClass64, 0>;
def : ReadAdvance<ReadIMinMax, 0>;
def : ReadAdvance<ReadIRem, 0>;
def : ReadAdvance<ReadIRem32, 0>;

// Unsupported extensions.
defm : UnsupportedSchedV;
defm : UnsupportedSchedZbc;
defm : UnsupportedSchedZbs;
defm : UnsupportedSchedZbkb;
defm : UnsupportedSchedZbkx;
defm : UnsupportedSchedZfa;
defm : UnsupportedSchedZfh;
defm : UnsupportedSchedSFB;
defm : UnsupportedSchedZabha;
defm : UnsupportedSchedXsfvcp;
defm : UnsupportedSchedZvk;
defm : UnsupportedSchedZvkned;
}
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVSchedule.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def WriteIMul32 : SchedWrite; // 32-bit multiply on RV64I
def WriteJmp : SchedWrite; // Jump
def WriteJal : SchedWrite; // Jump and link
def WriteJalr : SchedWrite; // Jump and link register
def WriteJmpReg : SchedWrite; // Jump register
def WriteNop : SchedWrite;
def WriteLDB : SchedWrite; // Load byte
def WriteLDH : SchedWrite; // Load half-word
Expand Down