blob: c7c31869b82e5a0d5a5191e5164f9628372b356d [file] [log] [blame] [edit]
// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - | FileCheck %s
include "llvm/Target/Target.td"
def TestTargetInstrInfo : InstrInfo;
def TestTarget : Target {
let InstructionSet = TestTargetInstrInfo;
}
def FeatureFoo : SubtargetFeature<"foo", "HasFoo", "true", "enable foo">;
def FeatureBar : SubtargetFeature<"bar", "HasBar", "true", "enable bar">;
def ResX0 : ProcResource<1>;
let OutOperandList = (outs), InOperandList = (ins) in
def Inst_A : Instruction;
def SchedModel_A: SchedMachineModel {
let CompleteModel = false;
}
let SchedModel = SchedModel_A in {
def SchedWriteResA : SchedWriteRes<[ResX0]> {
let Latency = 2;
}
def SchedWriteResB : SchedWriteRes<[ResX0]> {
let Latency = 4;
}
def SchedWriteResC : SchedWriteRes<[ResX0]> {
let Latency = 8;
}
def SchedWriteResD : SchedWriteRes<[ResX0]> {
let Latency = 16;
}
def SchedWriteResE : SchedWriteRes<[ResX0]> {
let Latency = 32;
}
// Check SchedPredicate with subtarget feature.
def FeatureFooPred : FeatureSchedPredicate<FeatureFoo>;
def FeatureBarPred : FeatureSchedPredicate<FeatureBar>;
// Check SchedPredicate combiners.
// First, check MC-only combiners.
def CombinedAllOfPred: AllOfSchedPreds<[FeatureFooPred, MCSchedPredicate<CheckZeroOperand<1>>]>;
// Then, check nested combiner that can be used with MCInst and MachineInstr.
def CombinedAnyOfPred: AnyOfSchedPreds<[CombinedAllOfPred,
NoneOfSchedPreds<[FeatureBarPred,
SchedPredicate<[{/*hello=*/false}]>]>]>;
// Check if the inverse predicate correctly wraps (or not wrap) its sub-predicates.
def CombinedNotPred : NotSchedPred<AllOfSchedPreds<[MCSchedPredicate<CheckZeroOperand<3>>,
NotSchedPred<FeatureFooPred>]>>;
def Variant : SchedWriteVariant<[
SchedVar<FeatureFooPred, [SchedWriteResA]>,
SchedVar<NoSchedPred, [SchedWriteResB]>,
SchedVar<CombinedAllOfPred, [SchedWriteResC]>,
SchedVar<CombinedAnyOfPred, [SchedWriteResD]>,
SchedVar<CombinedNotPred, [SchedWriteResE]>,
]>;
def : InstRW<[Variant], (instrs Inst_A)>;
}
def ProcessorA: ProcessorModel<"ProcessorA", SchedModel_A, []>;
// CHECK: unsigned resolveVariantSchedClassImpl(unsigned SchedClass,
// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII, const MCSubtargetInfo &STI, unsigned CPUID)
// CHECK: case {{.*}}: // Inst_A
// CHECK-NEXT: if (CPUID == {{.*}}) { // SchedModel_A
// CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo))
// CHECK-NEXT: return {{.*}}; // SchedWriteResA
// CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0)
// CHECK-NEXT: return {{.*}}; // SchedWriteResC
// CHECK-NEXT: if (!(MI->getOperand(3).getImm() == 0 && !STI.hasFeature(TestTarget::FeatureFoo)))
// CHECK-NEXT: return {{.*}}; // SchedWriteResE
// CHECK-NEXT: return {{.*}}; // SchedWriteResB
// CHECK: unsigned resolveVariantSchedClass(unsigned SchedClass,
// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII,
// CHECK-NEXT: unsigned CPUID) const override {
// CHECK-NEXT: return TestTarget_MC::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID);
// CHECK-NEXT: }
// CHECK: unsigned TestTargetGenSubtargetInfo
// CHECK-NEXT: ::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, const TargetSchedModel *SchedModel) const {
// CHECK-NEXT: switch (SchedClass) {
// CHECK-NEXT: case {{.*}}: // Inst_A
// CHECK-NEXT: if (SchedModel->getProcessorID() == {{.*}}) { // SchedModel_A
// CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo))
// CHECK-NEXT: return {{.*}}; // SchedWriteResA
// CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0)
// CHECK-NEXT: return {{.*}}; // SchedWriteResC
// CHECK-NEXT: if ((this->hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0) || !(this->hasFeature(TestTarget::FeatureBar) || (/*hello=*/false)))
// CHECK-NEXT: return {{.*}}; // SchedWriteResD
// CHECK-NEXT: if (!(MI->getOperand(3).getImm() == 0 && !this->hasFeature(TestTarget::FeatureFoo)))
// CHECK-NEXT: return {{.*}}; // SchedWriteResE
// CHECK-NEXT: return {{.*}}; // SchedWriteResB