@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
35
#include < fstream>
36
36
#include < iostream>
37
37
#include < iomanip>
38
+ #include < sstream>
38
39
#include < string>
39
40
40
41
@@ -78,16 +79,16 @@ static void formatSIMT(
78
79
for (int vecIx = 0 ; vecIx < mi.elemsPerAddr ; vecIx++) {
79
80
int dataSize = mi.elemSizeBitsRegFile /8 ;
80
81
int bytesPerVecElem = mi.execWidth *dataSize;
81
- int regsPerVecElem = std::max<int >(1 ,bytesPerVecElem/grfSizeB);
82
+ int regsPerVecElem = std::max<int >(1 , bytesPerVecElem/grfSizeB);
82
83
// 32B, float (4B), SIMD16 ==> 8
83
84
// 32B/4B == 8
84
- int chsPerGrf = std::min<int >(grfSizeB/dataSize,mi.execWidth );
85
+ int chsPerGrf = std::min<int >(grfSizeB/dataSize, mi.execWidth );
85
86
int chIxBase = 0 ;
86
87
for (int regIx = 0 ; regIx < regsPerVecElem; regIx++) {
87
88
// walk the channels in reverse order
88
89
emitSpan (os, ' -' , grfSizeB - mi.execWidth *dataSize);
89
90
for (int chIxR = chsPerGrf - 1 ; chIxR >= 0 ; chIxR--) {
90
- emitDataElem (os, chIxBase+ chIxR, mi);
91
+ emitDataElem (os, chIxBase + chIxR, mi);
91
92
}
92
93
emitRegName (os, currGrf++);
93
94
if (regIx == 0 && mi.elemsPerAddr > 1 )
@@ -112,7 +113,7 @@ static void formatSIMD(
112
113
// exists and we can make this algorithm aware of that possible
113
114
// extension
114
115
for (int chIx = 0 ; chIx < mi.execWidth ; chIx++) {
115
- int totalRegs = std::max<int >(1 ,mi.elemsPerAddr /vecElemsPerReg);
116
+ int totalRegs = std::max<int >(1 , mi.elemsPerAddr /vecElemsPerReg);
116
117
int elemsLeft = mi.elemsPerAddr ;
117
118
int vecIx = 0 ;
118
119
for (int regIx = 0 ; regIx < totalRegs; regIx++) {
@@ -123,7 +124,7 @@ static void formatSIMD(
123
124
// a register
124
125
emitSpan (os, ' -' , (vecElemsPerReg - elemsLeft)*dataSize);
125
126
}
126
- int elemsToPrint = std::min<int >(elemsLeft,vecElemsPerReg);
127
+ int elemsToPrint = std::min<int >(elemsLeft, vecElemsPerReg);
127
128
for (int vi = elemsToPrint - 1 ; vi >= 0 ; --vi) {
128
129
emitDataElem (os, chIx, mi);
129
130
}
@@ -150,8 +151,17 @@ bool decodeSendDescriptor(const Opts &opts)
150
151
151
152
ensurePlatformIsSet (opts);
152
153
153
- if (opts.inputFiles .size () != 3 && opts.inputFiles .size () != 2 ) {
154
- fatalExitWithMessage (" -Xdsd: expects: SFID ex_desc desc" );
154
+ size_t minArgs = opts.platform < IGA_GEN12p1 ? 2 : 3 ;
155
+
156
+ if (opts.inputFiles .size () != minArgs &&
157
+ opts.inputFiles .size () != minArgs + 1 )
158
+ {
159
+ if (minArgs == 2 )
160
+ fatalExitWithMessage (" -Xdsd: for this platform expects: "
161
+ " ExecSize? ExDesc Desc" );
162
+ else
163
+ fatalExitWithMessage (" -Xdsd: for this platform expects: "
164
+ " SFID ExecSize? ExDesc Desc" );
155
165
}
156
166
auto parseSendDescArg =
157
167
[&] (const char *which, std::string inp) {
@@ -162,8 +172,8 @@ bool decodeSendDescriptor(const Opts &opts)
162
172
a0rr.subRegNum = (uint16_t )std::stoul (inp, nullptr , 10 );
163
173
} catch (...) {
164
174
fatalExitWithMessage (
165
- " -Xdsd: %s: %s: invalid a0 subregister " ,
166
- which, inp. c_str () );
175
+ " -Xdsd: " , which, " : " , inp ,
176
+ " : invalid a0 subregister " );
167
177
}
168
178
return iga::SendDesc (a0rr);
169
179
}
@@ -177,42 +187,101 @@ bool decodeSendDescriptor(const Opts &opts)
177
187
val = std::stoul (inp, nullptr , base);
178
188
} catch (std::invalid_argument i) {
179
189
fatalExitWithMessage (
180
- " -Xdsd: %s: %s: parse error " , which, inp. c_str () );
190
+ " -Xdsd: " , which, " : " , inp, " : parse error " );
181
191
} catch (std::out_of_range i) {
182
192
fatalExitWithMessage (
183
- " -Xdsd: %s: %s : value out of range" , which, inp. c_str () );
193
+ " -Xdsd: " , which, " : " , inp, " : value out of range" );
184
194
}
185
195
return iga::SendDesc (val);
186
196
};
187
- int descArgOff = opts.inputFiles .size () == 2 ? 0 : 1 ;
188
- auto exDesc = parseSendDescArg (" ex_desc" , opts.inputFiles [descArgOff]);
189
- auto desc = parseSendDescArg (" desc" , opts.inputFiles [descArgOff+1 ]);
190
-
191
- iga::SFID sfid = iga::SFID::INVALID;
192
- if (opts.inputFiles .size () == 3 ) {
193
- std::string sfidSym = opts.inputFiles [0 ];
197
+ auto tryParseSFID = [&](std::string sfidSym) {
194
198
std::transform (
195
199
sfidSym.begin (), sfidSym.end (), sfidSym.begin (), toLower);
196
- sfid = iga::FromSyntax<iga::SFID>(sfidSym);
197
- if (sfid == iga::SFID::INVALID) {
200
+ return iga::FromSyntax<iga::SFID>(sfidSym);
201
+ };
202
+ int argOff = 0 ;
203
+ iga::SFID sfid = tryParseSFID (opts.inputFiles [argOff]);
204
+ if (sfid != iga::SFID::INVALID) {
205
+ argOff++;
206
+ if (opts.platform < IGA_GEN12p1)
198
207
fatalExitWithMessage (
199
- " -Xdsd: %s: invalid or unsupported SFID for this platform" ,
200
- opts.inputFiles [0 ].c_str ());
208
+ " -Xdsd: " , opts.inputFiles [argOff],
209
+ " : SFID is encoded in ExDesc[3:0] for this platform" );
210
+ } else if (sfid == iga::SFID::INVALID && opts.platform >= IGA_GEN12p1) {
211
+ fatalExitWithMessage (
212
+ " -Xdsd: " , opts.inputFiles [argOff],
213
+ " : invalid SFID for this platform" );
214
+ }
215
+ // Formats are:
216
+ // <=GEN11: ExecSize? ExDesc Desc
217
+ // >=GEN12: SFID ExecSize? ExDesc Desc
218
+ //
219
+ // If ExecSize is not given, then we deduce it from the platform.
220
+
221
+ // ExecSize is '(' INT ('|' ('M0' | 'M4' | ...))? ')'
222
+ // e.g. all the following produce ExecSize::SIMD8:
223
+ // "(8)", "( 8 )", "(8|M24)"
224
+ //
225
+ iga::ExecSize execSize = iga::ExecSize::INVALID;
226
+ auto tryExecSize = [&](std::string str) {
227
+ if (str.empty () ||
228
+ str.substr (0 , 1 ) != " (" ||
229
+ str.substr (str.size () - 1 ) != " )" )
230
+ {
231
+ return iga::ExecSize::INVALID;
232
+ }
233
+ size_t off = 1 ;
234
+ while (off < str.size () && std::isspace (str[off]))
235
+ off++;
236
+ size_t len = 0 ;
237
+ int execSizeInt = 0 ;
238
+ while (off + len < str.size () && std::isdigit (str[off + len])) {
239
+ execSizeInt = 10 * execSizeInt + str[off + len] - ' 0' ;
240
+ len++;
241
+ }
242
+ while (off + len < str.size () && std::isspace (str[off + len])) {
243
+ len++;
244
+ }
245
+ if (len == 0 || off + len == str.size () || (str[off + len] != ' )' && str[off + len] != ' |' ))
246
+ return iga::ExecSize::INVALID;
247
+ switch (execSizeInt) {
248
+ case 1 : return iga::ExecSize::SIMD1;
249
+ case 2 : return iga::ExecSize::SIMD2;
250
+ case 4 : return iga::ExecSize::SIMD4;
251
+ case 8 : return iga::ExecSize::SIMD8;
252
+ case 16 : return iga::ExecSize::SIMD16;
253
+ case 32 : return iga::ExecSize::SIMD32;
254
+ default : return iga::ExecSize::INVALID;
201
255
}
202
- } else if (opts.platform <= IGA_GEN11) {
256
+ };
257
+
258
+ // ExecSize? (optional SIMD argument)
259
+ if (opts.inputFiles .size () > minArgs) {
260
+ execSize = tryExecSize (opts.inputFiles [argOff]);
261
+ if (execSize == iga::ExecSize::INVALID)
262
+ fatalExitWithMessage (
263
+ " -Xdsd: " , opts.inputFiles [argOff], " : invalid ExecSize" );
264
+ argOff++;
265
+ }
266
+
267
+ // ExDesc
268
+ const iga::SendDesc exDesc =
269
+ parseSendDescArg (" ExDesc" , opts.inputFiles [argOff]);
270
+ if (opts.platform < IGA_GEN12p1 && sfid == iga::SFID::INVALID) {
203
271
// decode it from ex_desc[3:0]
204
272
if (exDesc.isImm ())
205
273
sfid = iga::sfidFromEncoding (
206
274
static_cast <iga::Platform>(opts.platform ),
207
275
exDesc.imm & 0xF );
208
276
if (sfid == iga::SFID::INVALID) {
277
+ std::stringstream ss;
278
+ ss << " 0x" << std::hex << std::uppercase << (exDesc.imm & 0xF );
209
279
fatalExitWithMessage (
210
- " -Xdsd: 0x%x: invalid or unsupported SFID for this platform " ,
211
- exDesc );
280
+ " -Xdsd: " , ss. str () ,
281
+ " : invalid or unsupported SFID for this platform " );
212
282
}
213
- } else {
214
- fatalExitWithMessage (" -Xdsd: expected three arguments" );
215
283
}
284
+ auto desc = parseSendDescArg (" Desc" , opts.inputFiles [argOff+1 ]);
216
285
217
286
auto emitDiagnostics =
218
287
[&](const iga::DiagnosticList &ds, bool errors) {
@@ -239,10 +308,20 @@ bool decodeSendDescriptor(const Opts &opts)
239
308
}
240
309
};
241
310
242
- // TODO: allow an extra parameter for indDesc
311
+ iga::Platform p = iga::Platform (opts.platform );
312
+
313
+ if (execSize == iga::ExecSize::INVALID) {
314
+ // Normally tryDecode() gets the ExecSize from IR or decoded from the
315
+ // descriptor; since we don't have that here, cheat and guess with a
316
+ // sort of pre-decode scam. It's not ideal, but I can't think of
317
+ // anything better right now.
318
+ execSize =
319
+ iga::ExecSize::SIMD16;
320
+ }
321
+ //
243
322
iga::DecodedDescFields decodedFields;
244
323
const auto dr = iga::tryDecode (
245
- static_cast <iga::Platform>(opts. platform ) , sfid,
324
+ p , sfid, execSize ,
246
325
exDesc, desc, iga::REGREF_INVALID,
247
326
&decodedFields);
248
327
emitDiagnostics (dr.warnings , false );
@@ -326,7 +405,8 @@ bool decodeSendDescriptor(const Opts &opts)
326
405
} else if (dr.info .addrType == iga::AddrType::BTI) {
327
406
os << " Surface: " ;
328
407
std::stringstream ss;
329
- ss << " surface index " << emitDesc (dr.info .surfaceId );
408
+ ss << " surface binding table index " <<
409
+ emitDesc (dr.info .surfaceId );
330
410
emitYellowText (os,ss.str ());
331
411
os << " \n " ;
332
412
}
@@ -349,7 +429,8 @@ bool decodeSendDescriptor(const Opts &opts)
349
429
os << " Data Elements Per Address: " ;
350
430
emitYellowText (os, dr.info .elemsPerAddr );
351
431
os << " element" << (dr.info .elemsPerAddr != 1 ? " s" : " " );
352
- if (iga::SendOpHasCmask (dr.info .op )) {
432
+ const iga::SendOpInfo &opInfo = iga::lookupSendOpInfo (dr.info .op );
433
+ if (opInfo.hasChMask ()) {
353
434
os << " (" ;
354
435
emitYellowText (os, " ." );
355
436
if (dr.info .channelsEnabled & 0x1 )
0 commit comments