@@ -572,6 +572,8 @@ class SPIRVModuleImpl : public SPIRVModule {
572
572
SPIRVAliasInstMDMap AliasInstMDMap;
573
573
574
574
void layoutEntry (SPIRVEntry *Entry);
575
+ std::istream &parseSPT (std::istream &I);
576
+ std::istream &parseSPIRV (std::istream &I);
575
577
};
576
578
577
579
SPIRVModuleImpl::~SPIRVModuleImpl () {
@@ -2123,70 +2125,273 @@ void SPIRVModuleImpl::addUnknownStructField(SPIRVTypeStruct *Struct, unsigned I,
2123
2125
UnknownStructFieldMap[Struct].push_back (std::make_pair (I, ID));
2124
2126
}
2125
2127
2126
- std::istream &operator >>(std::istream &I, SPIRVModule &M) {
2127
- SPIRVDecoder Decoder (I, M);
2128
- SPIRVModuleImpl &MI = *static_cast <SPIRVModuleImpl *>(&M);
2129
- // Disable automatic capability filling.
2128
+ namespace {
2129
+ SPIRVEntry *parseAndCreateSPIRVEntry (SPIRVWord &WordCount, Op &OpCode,
2130
+ SPIRVEntry *Scope, SPIRVModuleImpl &M,
2131
+ std::istream &IS) {
2132
+ if (WordCount == 0 || OpCode == OpNop) {
2133
+ return nullptr ;
2134
+ }
2135
+ SPIRVEntry *Entry = SPIRVEntry::create (OpCode);
2136
+ assert (Entry);
2137
+ Entry->setModule (&M);
2138
+ if (Scope && !isModuleScopeAllowedOpCode (OpCode)) {
2139
+ Entry->setScope (Scope);
2140
+ }
2141
+ Entry->setWordCount (WordCount);
2142
+ if (OpCode != OpLine)
2143
+ Entry->setLine (M.getCurrentLine ());
2144
+ if (!Entry->isExtInst (SPIRVEIS_NonSemantic_Shader_DebugInfo_100,
2145
+ SPIRVDebug::DebugLine) &&
2146
+ !Entry->isExtInst (SPIRVEIS_NonSemantic_Shader_DebugInfo_200,
2147
+ SPIRVDebug::DebugLine)) {
2148
+ Entry->setDebugLine (M.getCurrentDebugLine ());
2149
+ }
2150
+ IS >> *Entry;
2151
+ if (Entry->isEndOfBlock () || OpCode == OpNoLine) {
2152
+ M.setCurrentLine (nullptr );
2153
+ }
2154
+ if (Entry->isEndOfBlock () ||
2155
+ Entry->isExtInst (SPIRVEIS_NonSemantic_Shader_DebugInfo_100,
2156
+ SPIRVDebug::DebugNoLine) ||
2157
+ Entry->isExtInst (SPIRVEIS_NonSemantic_Shader_DebugInfo_200,
2158
+ SPIRVDebug::DebugNoLine)) {
2159
+ M.setCurrentDebugLine (nullptr );
2160
+ }
2161
+
2162
+ if (OpExtension == OpCode) {
2163
+ auto *OpExt = static_cast <SPIRVExtension *>(Entry);
2164
+ ExtensionID ExtID = {};
2165
+ bool ExtIsKnown = SPIRVMap<ExtensionID, std::string>::rfind (
2166
+ OpExt->getExtensionName (), &ExtID);
2167
+ if (!M.getErrorLog ().checkError (
2168
+ ExtIsKnown, SPIRVEC_InvalidModule,
2169
+ " input SPIR-V module uses unknown extension '" +
2170
+ OpExt->getExtensionName () + " '" )) {
2171
+ M.setInvalid ();
2172
+ }
2173
+
2174
+ if (!M.getErrorLog ().checkError (
2175
+ M.isAllowedToUseExtension (ExtID), SPIRVEC_InvalidModule,
2176
+ " input SPIR-V module uses extension '" + OpExt->getExtensionName () +
2177
+ " ' which were disabled by --spirv-ext option" )) {
2178
+ M.setInvalid ();
2179
+ }
2180
+ }
2181
+
2182
+ if (!M.getErrorLog ().checkError (Entry->isImplemented (),
2183
+ SPIRVEC_UnimplementedOpCode,
2184
+ std::to_string (Entry->getOpCode ()))) {
2185
+ M.setInvalid ();
2186
+ }
2187
+
2188
+ assert (!IS.bad () && !IS.fail () && " SPIRV stream fails" );
2189
+ return Entry;
2190
+ }
2191
+ } // namespace
2192
+
2193
+ std::istream &SPIRVModuleImpl::parseSPT (std::istream &I) {
2194
+ SPIRVModuleImpl &MI = *this ;
2130
2195
MI.setAutoAddCapability (false );
2131
2196
MI.setAutoAddExtensions (false );
2197
+ auto ReadSPIRVWord = [](std::istream &I) {
2198
+ uint32_t W;
2199
+ I >> skipcomment >> W;
2200
+ SPIRVDBG (spvdbgs () << " Read word: W = " << W << " V = 0\n " );
2201
+ return W;
2202
+ };
2203
+ SPIRVErrorLog ErrorLog = MI.getErrorLog ();
2204
+ SPIRVWord Magic = ReadSPIRVWord (I);
2205
+
2206
+ if (!ErrorLog.checkError (!I.eof (), SPIRVEC_InvalidModule,
2207
+ " input file is empty" ) ||
2208
+ !ErrorLog.checkError (!I.fail (), SPIRVEC_InvalidModule,
2209
+ " header parsing error" )) {
2210
+ MI.setInvalid ();
2211
+ return I;
2212
+ }
2132
2213
2133
- SPIRVWord Magic;
2134
- Decoder >> Magic;
2135
- if (!M.getErrorLog ().checkError (Magic == MagicNumber, SPIRVEC_InvalidModule,
2136
- " invalid magic number" )) {
2137
- M.setInvalid ();
2214
+ if (!ErrorLog.checkError (Magic == MagicNumber, SPIRVEC_InvalidModule,
2215
+ " invalid magic number" )) {
2216
+ MI.setInvalid ();
2217
+ return I;
2218
+ }
2219
+
2220
+ MI.SPIRVVersion = ReadSPIRVWord (I);
2221
+ if (!ErrorLog.checkError (!I.fail (), SPIRVEC_InvalidModule,
2222
+ " header parsing error" )) {
2223
+ MI.setInvalid ();
2138
2224
return I;
2139
2225
}
2140
2226
2141
- Decoder >> MI.SPIRVVersion ;
2142
2227
bool SPIRVVersionIsKnown = isSPIRVVersionKnown (MI.SPIRVVersion );
2143
- if (!M. getErrorLog () .checkError (
2228
+ if (!ErrorLog .checkError (
2144
2229
SPIRVVersionIsKnown, SPIRVEC_InvalidModule,
2145
2230
" unsupported SPIR-V version number '" + to_string (MI.SPIRVVersion ) +
2146
2231
" '. Range of supported/known SPIR-V "
2147
2232
" versions is " +
2148
2233
to_string (VersionNumber::MinimumVersion) + " - " +
2149
2234
to_string (VersionNumber::MaximumVersion))) {
2150
- M .setInvalid ();
2235
+ MI .setInvalid ();
2151
2236
return I;
2152
2237
}
2153
2238
2154
- bool SPIRVVersionIsAllowed = M .isAllowedToUseVersion (MI.SPIRVVersion );
2155
- if (!M. getErrorLog () .checkError (
2239
+ bool SPIRVVersionIsAllowed = MI .isAllowedToUseVersion (MI.SPIRVVersion );
2240
+ if (!ErrorLog .checkError (
2156
2241
SPIRVVersionIsAllowed, SPIRVEC_InvalidModule,
2157
2242
" incorrect SPIR-V version number " + to_string (MI.SPIRVVersion ) +
2158
2243
" - it conflicts with maximum allowed version which is set to " +
2159
- to_string (M.getMaximumAllowedSPIRVVersion ()))) {
2160
- M.setInvalid ();
2244
+ to_string (MI.getMaximumAllowedSPIRVVersion ()))) {
2245
+ MI.setInvalid ();
2246
+ return I;
2247
+ }
2248
+
2249
+ SPIRVWord Generator = ReadSPIRVWord (I);
2250
+ if (!ErrorLog.checkError (!I.fail (), SPIRVEC_InvalidModule,
2251
+ " header parsing error" )) {
2252
+ MI.setInvalid ();
2161
2253
return I;
2162
2254
}
2163
2255
2164
- SPIRVWord Generator = 0 ;
2165
- Decoder >> Generator;
2166
2256
MI.GeneratorId = Generator >> 16 ;
2167
2257
MI.GeneratorVer = Generator & 0xFFFF ;
2168
2258
2169
2259
// Bound for Id
2170
- Decoder >> MI.NextId ;
2260
+ MI.NextId = ReadSPIRVWord (I);
2261
+ if (!ErrorLog.checkError (!I.fail (), SPIRVEC_InvalidModule,
2262
+ " header parsing error" )) {
2263
+ MI.setInvalid ();
2264
+ return I;
2265
+ }
2171
2266
2172
- Decoder >> MI.InstSchema ;
2173
- if (!M. getErrorLog () .checkError (MI.InstSchema == SPIRVISCH_Default,
2174
- SPIRVEC_InvalidModule,
2175
- " unsupported instruction schema" )) {
2176
- M .setInvalid ();
2267
+ MI.InstSchema = static_cast <SPIRVInstructionSchemaKind>( ReadSPIRVWord (I)) ;
2268
+ if (!ErrorLog .checkError (MI.InstSchema == SPIRVISCH_Default,
2269
+ SPIRVEC_InvalidModule,
2270
+ " unsupported instruction schema" )) {
2271
+ MI .setInvalid ();
2177
2272
return I;
2178
2273
}
2179
2274
2180
- while (Decoder.getWordCountAndOpCode () && M.isModuleValid ()) {
2181
- SPIRVEntry *Entry = Decoder.getEntry ();
2182
- if (Entry != nullptr )
2183
- M.add (Entry);
2275
+ SPIRVWord WordCount = 0 ;
2276
+ Op OpCode = OpNop;
2277
+ SPIRVEntry *Scope = nullptr ;
2278
+ while (true ) {
2279
+ WordCount = ReadSPIRVWord (I);
2280
+ if (I.fail ()) {
2281
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode FAIL 0 0\n " );
2282
+ break ;
2283
+ }
2284
+ std::string RawOp;
2285
+ I >> RawOp;
2286
+ OpCode = getNameMap (OpCode).rmap (RawOp);
2287
+ SPIRVDBG (spvdbgs () << " Read word: W = " << RawOp << " V = " << OpCode
2288
+ << ' \n ' );
2289
+ if (I.fail ()) {
2290
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode FAIL 0 0\n " );
2291
+ break ;
2292
+ }
2293
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode " << WordCount << " "
2294
+ << OpCodeNameMap::map (OpCode) << ' \n ' );
2295
+ if (!MI.isModuleValid ()) {
2296
+ break ;
2297
+ }
2298
+
2299
+ SPIRVEntry *Entry =
2300
+ parseAndCreateSPIRVEntry (WordCount, OpCode, Scope, MI, I);
2301
+ if (Entry != nullptr ) {
2302
+ MI.add (Entry);
2303
+ }
2304
+ if (I.eof ()) {
2305
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode EOF 0 0\n " );
2306
+ break ;
2307
+ }
2184
2308
}
2185
2309
2186
2310
MI.resolveUnknownStructFields ();
2187
2311
return I;
2188
2312
}
2189
2313
2314
+ std::istream &SPIRVModuleImpl::parseSPIRV (std::istream &I) {
2315
+ SPIRVModuleImpl &MI = *this ;
2316
+ MI.setAutoAddCapability (false );
2317
+ MI.setAutoAddExtensions (false );
2318
+
2319
+ SPIRVWord Header[5 ] = {0 };
2320
+ I.read (reinterpret_cast <char *>(&Header), sizeof (Header));
2321
+
2322
+ SPIRVErrorLog ErrorLog = MI.getErrorLog ();
2323
+ if (!ErrorLog.checkError (!I.eof (), SPIRVEC_InvalidModule,
2324
+ " input file is empty" ) ||
2325
+ !ErrorLog.checkError (!I.fail (), SPIRVEC_InvalidModule,
2326
+ " header parsing error" ) ||
2327
+ !ErrorLog.checkError (Header[0 ] == MagicNumber, SPIRVEC_InvalidModule,
2328
+ " invalid magic number" ) ||
2329
+ !ErrorLog.checkError (
2330
+ isSPIRVVersionKnown (Header[1 ]), SPIRVEC_InvalidModule,
2331
+ " unsupported SPIR-V version number '" + to_string (Header[1 ]) +
2332
+ " '. Range of supported/known SPIR-V "
2333
+ " versions is " +
2334
+ to_string (VersionNumber::MinimumVersion) + " - " +
2335
+ to_string (VersionNumber::MaximumVersion)) ||
2336
+ !ErrorLog.checkError (
2337
+ MI.isAllowedToUseVersion (Header[1 ]), SPIRVEC_InvalidModule,
2338
+ " incorrect SPIR-V version number " + to_string (Header[1 ]) +
2339
+ " - it conflicts with maximum allowed version which is set to " +
2340
+ to_string (MI.getMaximumAllowedSPIRVVersion ())) ||
2341
+ !ErrorLog.checkError (Header[4 ] == SPIRVISCH_Default,
2342
+ SPIRVEC_InvalidModule,
2343
+ " unsupported instruction schema" )) {
2344
+ MI.setInvalid ();
2345
+ return I;
2346
+ }
2347
+
2348
+ MI.SPIRVVersion = Header[1 ];
2349
+ MI.GeneratorId = Header[2 ] >> 16 ;
2350
+ MI.GeneratorVer = Header[2 ] & 0xFFFF ;
2351
+ MI.NextId = Header[3 ];
2352
+ MI.InstSchema = static_cast <SPIRVInstructionSchemaKind>(Header[4 ]);
2353
+
2354
+ SPIRVEntry *Scope = nullptr ;
2355
+ while (true ) {
2356
+ SPIRVWord WordCountAndOpCode = 0 ;
2357
+ I.read (reinterpret_cast <char *>(&WordCountAndOpCode), sizeof (SPIRVWord));
2358
+ SPIRVDBG (spvdbgs () << " Read word: W = " << WordCountAndOpCode
2359
+ << " V = 0\n " );
2360
+ SPIRVWord WordCount = WordCountAndOpCode >> 16 ;
2361
+ Op OpCode = static_cast <Op>(WordCountAndOpCode & 0xFFFF );
2362
+ if (I.fail ()) {
2363
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode FAIL 0 0\n " );
2364
+ break ;
2365
+ }
2366
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode " << WordCount << " "
2367
+ << OpCodeNameMap::map (OpCode) << ' \n ' );
2368
+ if (!MI.isModuleValid ()) {
2369
+ break ;
2370
+ }
2371
+ SPIRVEntry *Entry =
2372
+ parseAndCreateSPIRVEntry (WordCount, OpCode, Scope, MI, I);
2373
+ if (Entry != nullptr ) {
2374
+ MI.add (Entry);
2375
+ }
2376
+ if (I.eof ()) {
2377
+ SPIRVDBG (spvdbgs () << " getWordCountAndOpCode EOF 0 0\n " );
2378
+ break ;
2379
+ }
2380
+ }
2381
+ MI.resolveUnknownStructFields ();
2382
+ return I;
2383
+ }
2384
+
2385
+ std::istream &operator >>(std::istream &I, SPIRVModule &M) {
2386
+ SPIRVModuleImpl &MI = *static_cast <SPIRVModuleImpl *>(&M);
2387
+ #ifdef _SPIRV_SUPPORT_TEXT_FMT
2388
+ if (SPIRVUseTextFormat) {
2389
+ return MI.parseSPT (I);
2390
+ }
2391
+ #endif
2392
+ return MI.parseSPIRV (I);
2393
+ }
2394
+
2190
2395
SPIRVModule *SPIRVModule::createSPIRVModule () { return new SPIRVModuleImpl (); }
2191
2396
2192
2397
SPIRVModule *SPIRVModule::createSPIRVModule (const SPIRV::TranslatorOpts &Opts) {
0 commit comments