@@ -32,9 +32,18 @@ using namespace llvm::dxil;
3232
3333namespace {
3434
35+ struct DXILArgSelect {
36+ enum class Type {
37+ Index,
38+ I32,
39+ I8,
40+ };
41+ Type Type = Type::Index;
42+ int Value = 0 ;
43+ };
3544struct DXILIntrinsicSelect {
3645 StringRef Intrinsic;
37- SmallVector<StringRef , 4 > ExtraArgs ;
46+ SmallVector<DXILArgSelect , 4 > Args ;
3847};
3948
4049struct DXILOperationDesc {
@@ -75,6 +84,21 @@ static void ascendingSortByVersion(std::vector<const Record *> &Recs) {
7584 });
7685}
7786
87+ // / Take a `int_{intrinsic_name}` and return just the intrinsic_name part if available.
88+ // / Otherwise return the empty string.
89+ static StringRef GetIntrinsicName (const RecordVal *RV){
90+ if (RV && RV->getValue ()) {
91+ if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
92+ auto *IntrinsicDef = DI->getDef ();
93+ auto DefName = IntrinsicDef->getName ();
94+ assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
95+ // Remove the int_ from intrinsic name.
96+ return DefName.substr (4 );
97+ }
98+ }
99+ return " " ;
100+ }
101+
78102// / Construct an object using the DXIL Operation records specified
79103// / in DXIL.td. This serves as the single source of reference of
80104// / the information extracted from the specified Record R, for
@@ -161,40 +185,50 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
161185 OpName);
162186 }
163187
164- auto GetIntrinsicName = [](const RecordVal *RV) -> StringRef {
165- if (RV && RV->getValue ()) {
166- if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue ())) {
167- auto *IntrinsicDef = DI->getDef ();
168- auto DefName = IntrinsicDef->getName ();
169- assert (DefName.starts_with (" int_" ) && " invalid intrinsic name" );
170- // Remove the int_ from intrinsic name.
171- return DefName.substr (4 );
172- }
173- }
174- return " " ;
175- };
176-
177188 {
178189 DXILIntrinsicSelect IntrSelect;
179190 IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" LLVMIntrinsic" ));
180191 if (IntrSelect.Intrinsic .size ())
181192 IntrinsicSelects.emplace_back (std::move (IntrSelect));
182193 }
183194
184- Recs = R->getValueAsListOfDefs (" intrinsic_selects" );
185- if (Recs .size ()) {
195+ auto IntrinsicSelectRecords = R->getValueAsListOfDefs (" intrinsic_selects" );
196+ if (IntrinsicSelectRecords .size ()) {
186197 if (IntrinsicSelects.size ()) {
187- PrintFatalError (R,
188- Twine (" LLVMIntrinsic and intrinsic_match cannot be both "
189- " defined for DXIL operation - " ) +
190- OpName);
198+ PrintFatalError (
199+ R, Twine (" LLVMIntrinsic and intrinsic_selects cannot be both "
200+ " defined for DXIL operation - " ) +
201+ OpName);
191202 } else {
192- for (const Record *R : Recs ) {
203+ for (const Record *R : IntrinsicSelectRecords ) {
193204 DXILIntrinsicSelect IntrSelect;
194- IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" Intr" ));
195- auto ExtraArgs = R->getValueAsListOfStrings (" ExtraArgs" );
196- for (StringRef Arg : ExtraArgs) {
197- IntrSelect.ExtraArgs .push_back (Arg);
205+ IntrSelect.Intrinsic = GetIntrinsicName (R->getValue (" intrinsic" ));
206+ auto Args = R->getValueAsListOfDefs (" args" );
207+ for (const Record *Arg : Args) {
208+ bool IsI8 = Arg->getValueAsBit (" is_i8" );
209+ bool IsI32 = Arg->getValueAsBit (" is_i32" );
210+ int Index = Arg->getValueAsInt (" index" );
211+ const Record *ValueRec = Arg->getValueAsDef (" value" );
212+
213+ DXILArgSelect ArgSelect;
214+ if (IsI8) {
215+ ArgSelect.Type = DXILArgSelect::Type::I8;
216+ ArgSelect.Value = ValueRec->getValueAsInt (" value" );
217+ } else if (IsI32) {
218+ ArgSelect.Type = DXILArgSelect::Type::I32;
219+ ArgSelect.Value = ValueRec->getValueAsInt (" value" );
220+ } else {
221+ if (Index < 0 ) {
222+ PrintFatalError (
223+ R, Twine (" Index in ArgSelect<index> must be equal to or "
224+ " greater than 0 for DXIL operation - " ) +
225+ OpName);
226+ }
227+ ArgSelect.Type = DXILArgSelect::Type::Index;
228+ ArgSelect.Value = Index;
229+ }
230+
231+ IntrSelect.Args .emplace_back (std::move (ArgSelect));
198232 }
199233 IntrinsicSelects.emplace_back (std::move (IntrSelect));
200234 }
@@ -415,11 +449,23 @@ static void emitDXILIntrinsicMap(ArrayRef<DXILOperationDesc> Ops,
415449 }
416450 for (const DXILIntrinsicSelect &MappedIntr : Op.IntrinsicSelects ) {
417451 OS << " DXIL_OP_INTRINSIC(dxil::OpCode::" << Op.OpName
418- << " , Intrinsic::" << MappedIntr.Intrinsic << " , (ArrayRef<Value *> {" ;
419- for (const StringRef &Arg : MappedIntr.ExtraArgs ) {
420- OS << Arg << " , " ;
452+ << " , Intrinsic::" << MappedIntr.Intrinsic ;
453+ for (const DXILArgSelect &ArgSelect : MappedIntr.Args ) {
454+ OS << " , (Arg { " ;
455+ switch (ArgSelect.Type ) {
456+ case DXILArgSelect::Type::Index:
457+ OS << " Arg::Type::Index, " ;
458+ break ;
459+ case DXILArgSelect::Type::I8:
460+ OS << " Arg::Type::I8, " ;
461+ break ;
462+ case DXILArgSelect::Type::I32:
463+ OS << " Arg::Type::I32, " ;
464+ break ;
465+ }
466+ OS << ArgSelect.Value << " })" ;
421467 }
422- OS << " }) )\n " ;
468+ OS << " )\n " ;
423469 }
424470 }
425471 OS << " \n " ;
0 commit comments