| // 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).isImm() && MI->getOperand(1).getImm() == 0)) | |
| // CHECK-NEXT: return {{.*}}; // SchedWriteResC | |
| // CHECK-NEXT: if (!((MI->getOperand(3).isImm() && 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 final { | |
| // 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).isImm() && MI->getOperand(1).getImm() == 0)) | |
| // CHECK-NEXT: return {{.*}}; // SchedWriteResC | |
| // CHECK-NEXT: if ((this->hasFeature(TestTarget::FeatureFoo) && (MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0)) || !(this->hasFeature(TestTarget::FeatureBar) || (/*hello=*/false))) | |
| // CHECK-NEXT: return {{.*}}; // SchedWriteResD | |
| // CHECK-NEXT: if (!((MI->getOperand(3).isImm() && MI->getOperand(3).getImm() == 0) && !this->hasFeature(TestTarget::FeatureFoo))) | |
| // CHECK-NEXT: return {{.*}}; // SchedWriteResE | |
| // CHECK-NEXT: return {{.*}}; // SchedWriteResB |