1 // RUN: llvm-tblgen -gen-global-isel -I %p/../../include -I %p/Common -optimize-match-table=false %s -o %T/hwmode-non-optimized.cpp
2 // RUN: FileCheck %s --check-prefixes=CHECK -input-file=%T/hwmode-non-optimized.cpp
4 include "llvm/Target/Target.td"
6 def MyTargetISA : InstrInfo;
7 def MyTarget : Target { let InstructionSet = MyTargetISA; }
9 class MyTargetGenericInstruction : GenericInstruction {
10 let Namespace = "MyTarget";
13 //def Has32 : Predicate<"Subtarget->has32()">;
14 def Has64 : Predicate<"Subtarget->has64()">;
16 //def Mode32 : HwMode<"+a", [Has32]>;
17 def Mode64 : HwMode<"+b", [Has64]>;
19 def ModeVT : ValueTypeByHwMode<[DefaultMode, Mode64],
21 def ModeRI : RegInfoByHwMode<
22 [DefaultMode, Mode64],
23 [RegInfo<32,32,32>, RegInfo<64,64,64>]>;
25 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
26 def GPR : RegisterClass<"MyTarget", [ModeVT], 32, (add R0)> {
27 let RegInfos = ModeRI;
30 def p0 : PtrValueTypeByHwMode<ModeVT, 0>;
32 class I<dag OOps, dag IOps, list<dag> Pat>
34 let Namespace = "MyTarget";
35 let OutOperandList = OOps;
36 let InOperandList = IOps;
40 //===- Test the function boilerplate. -------------------------------------===//
42 // CHECK: const unsigned MAX_SUBTARGET_PREDICATES = 2;
43 // CHECK: using PredicateBitset = llvm::Bitset<MAX_SUBTARGET_PREDICATES>;
45 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_DECL
46 // CHECK-NEXT: mutable MatcherState State;
47 // CHECK-NEXT: typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;
48 // CHECK-NEXT: typedef void(MyTargetInstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const MachineInstr &, int) const;
49 // CHECK-NEXT: const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> ExecInfo;
50 // CHECK-NEXT: static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];
51 // CHECK-NEXT: static MyTargetInstructionSelector::CustomRendererFn CustomRenderers[];
52 // CHECK-NEXT: bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const override;
53 // CHECK-NEXT: bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) const override;
54 // CHECK-NEXT: bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat &Imm) const override;
55 // CHECK-NEXT: const uint8_t *getMatchTable() const override;
56 // CHECK-NEXT: bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI, const MatcherState &State) const override;
57 // CHECK-NEXT: bool testSimplePredicate(unsigned PredicateID) const override;
58 // CHECK-NEXT: bool runCustomAction(unsigned FnID, const MatcherState &State, NewMIVector &OutMIs) const override;
59 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL
61 // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT
62 // CHECK-NEXT: , State(0),
63 // CHECK-NEXT: ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets, ComplexPredicateFns, CustomRenderers)
64 // CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT
66 // CHECK-LABEL: // LLT Objects.
68 // CHECK-NEXT: GILLT_p0s32,
69 // CHECK-NEXT: GILLT_p0s64,
70 // CHECK-NEXT: GILLT_s32,
71 // CHECK-NEXT: GILLT_s64,
73 // CHECK-NEXT: const static size_t NumTypeObjects = 4;
74 // CHECK-NEXT: const static LLT TypeObjects[] = {
75 // CHECK-NEXT: LLT::pointer(0, 32),
76 // CHECK-NEXT: LLT::pointer(0, 64),
77 // CHECK-NEXT: LLT::scalar(32),
78 // CHECK-NEXT: LLT::scalar(64),
81 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
82 // CHECK-NEXT: Feature_HwMode1Bit = 1,
83 // CHECK-NEXT: Feature_HwMode0Bit = 0,
86 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
87 // CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
88 // CHECK-NEXT: PredicateBitset Features{};
89 // CHECK-NEXT: if (!((Subtarget->has64())))
90 // CHECK-NEXT: Features.set(Feature_HwMode1Bit);
91 // CHECK-NEXT: if ((Subtarget->has64()))
92 // CHECK-NEXT: Features.set(Feature_HwMode0Bit);
93 // CHECK-NEXT: return Features;
96 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
97 // CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
98 // CHECK-NEXT: PredicateBitset Features{};
99 // CHECK-NEXT: return Features;
102 // CHECK-LABEL: // Feature bitsets.
103 // CHECK-NEXT: enum {
104 // CHECK-NEXT: GIFBS_Invalid,
105 // CHECK-NEXT: GIFBS_HwMode0,
106 // CHECK-NEXT: GIFBS_HwMode1,
108 // CHECK-NEXT: constexpr static PredicateBitset FeatureBitsets[] {
109 // CHECK-NEXT: {}, // GIFBS_Invalid
110 // CHECK-NEXT: {Feature_HwMode0Bit, },
111 // CHECK-NEXT: {Feature_HwMode1Bit, },
114 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const {
115 // CHECK-NEXT: const PredicateBitset AvailableFeatures = getAvailableFeatures();
116 // CHECK-NEXT: MachineIRBuilder B(I);
117 // CHECK-NEXT: State.MIs.clear();
118 // CHECK-NEXT: State.MIs.push_back(&I);
120 // CHECK: if (executeMatchTable(*this, State, ExecInfo, B, getMatchTable(), TII, MF->getRegInfo(), TRI, RBI, AvailableFeatures, &CoverageInfo)) {
121 // CHECK-NEXT: return true;
124 // CHECK: const uint8_t *
125 // CHECK-LABEL: MyTargetInstructionSelector::getMatchTable() const {
126 // CHECK-NEXT: MatchTable0[] = {
128 //===- Test a simple pattern with inferred pointer operands. ---------------===//
130 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
131 // CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode0),
132 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
133 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
134 // CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
135 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
136 // CHECK-NEXT: // MIs[0] DstI[dst]
137 // CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s64,
138 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
139 // CHECK-NEXT: // MIs[0] src1
140 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/64,
141 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
142 // CHECK-NEXT: // (ld:{ *:[i64] } GPR:{ *:[i64] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i64] } GPR:{ *:[i64] }:$src1)
143 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),
144 // CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
145 // CHECK-NEXT: // GIR_Coverage, 0,
146 // CHECK-NEXT: GIR_Done,
147 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
148 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
149 // CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode1),
150 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
151 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
152 // CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
153 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
154 // CHECK-NEXT: // MIs[0] DstI[dst]
155 // CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
156 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
157 // CHECK-NEXT: // MIs[0] src1
158 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
159 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
160 // CHECK-NEXT: // (ld:{ *:[i32] } GPR:{ *:[i32] }:$src1)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR:{ *:[i32] }:$src1)
161 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),
162 // CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
163 // CHECK-NEXT: // GIR_Coverage, 1,
164 // CHECK-NEXT: GIR_Done,
165 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
167 def LOAD : I<(outs GPR:$dst), (ins GPR:$src1),
168 [(set GPR:$dst, (load GPR:$src1))]>;
170 //===- Test a simple pattern with explicit pointer operands. ---------------===//
172 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
173 // CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode0),
174 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
175 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
176 // CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
177 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
178 // CHECK-NEXT: // MIs[0] DstI[dst]
179 // CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s64,
180 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
181 // CHECK-NEXT: // MIs[0] src
182 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/64,
183 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
184 // CHECK-NEXT: // (ld:{ *:[i64] } GPR:{ *:[i64] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i64] } GPR:{ *:[i64] }:$src)
185 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),
186 // CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
187 // CHECK-NEXT: // GIR_Coverage, 2,
188 // CHECK-NEXT: GIR_Done,
189 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
190 // CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
191 // CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode1),
192 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
193 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
194 // CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
195 // CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
196 // CHECK-NEXT: // MIs[0] DstI[dst]
197 // CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s32,
198 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
199 // CHECK-NEXT: // MIs[0] src
200 // CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
201 // CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
202 // CHECK-NEXT: // (ld:{ *:[i32] } GPR:{ *:[i32] }:$src)<<P:Predicate_unindexedload>><<P:Predicate_load>> => (LOAD:{ *:[i32] } GPR:{ *:[i32] }:$src)
203 // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::LOAD),
204 // CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
205 // CHECK-NEXT: // GIR_Coverage, 3,
206 // CHECK-NEXT: GIR_Done,
207 // CHECK-NEXT: // Label [[LABEL_NUM]]: @[[LABEL]]
209 def : Pat<(load GPR:$src),
210 (p0 (LOAD GPR:$src))>;