MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / parseInstruction

Method parseInstruction

source/binary.cpp:310–468  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

308}
309
310spv_result_t Parser::parseInstruction() {
311 _.instruction_count++;
312
313 // The zero values for all members except for opcode are the
314 // correct initial values.
315 spv_parsed_instruction_t inst = {};
316
317 const uint32_t first_word = peek();
318
319 // If the module's endianness is different from the host native endianness,
320 // then converted_words contains the endian-translated words in the
321 // instruction.
322 _.endian_converted_words.clear();
323 _.endian_converted_words.push_back(first_word);
324
325 // After a successful parse of the instruction, the inst.operands member
326 // will point to this vector's storage.
327 _.operands.clear();
328
329 assert(_.word_index < _.num_words);
330 // Decompose and check the first word.
331 uint16_t inst_word_count = 0;
332 spvOpcodeSplit(first_word, &inst_word_count, &inst.opcode);
333 if (inst_word_count < 1) {
334 return diagnostic() << "Invalid instruction word count: "
335 << inst_word_count;
336 }
337 const spvtools::InstructionDesc* opcode_desc = nullptr;
338 const bool opcode_known =
339 spvtools::LookupOpcode(static_cast<spv::Op>(inst.opcode), &opcode_desc) ==
340 SPV_SUCCESS;
341 if (!opcode_known && !handle_unknown_opcodes_)
342 return diagnostic() << "Invalid opcode: " << inst.opcode;
343
344 // Advance past the opcode word. But remember the start of the instruction.
345 const size_t inst_offset = _.word_index;
346 _.word_index++;
347
348 // Emits the instruction at inst_offset as raw data with no decoded operands.
349 auto emitAsUnknown = [&]() -> spv_result_t {
350 if (inst_offset + inst_word_count > _.num_words) {
351 return diagnostic() << "Truncated binary: instruction at word "
352 << inst_offset << " claims " << inst_word_count
353 << " words but binary ends at " << _.num_words;
354 }
355 // Repopulate endian_converted_words from scratch. The operand loop may
356 // have partially filled it before the unknown enum was detected.
357 _.endian_converted_words.clear();
358 _.endian_converted_words.push_back(first_word);
359 if (_.requires_endian_conversion) {
360 for (uint16_t i = 1; i < inst_word_count; i++) {
361 _.endian_converted_words.push_back(peekAt(inst_offset + i));
362 }
363 }
364 _.word_index = inst_offset + inst_word_count;
365 inst.words = _.requires_endian_conversion ? _.endian_converted_words.data()
366 : _.words + inst_offset;
367 inst.num_words = inst_word_count;

Callers

nothing calls this directly

Calls 13

spvOpcodeSplitFunction · 0.85
LookupOpcodeFunction · 0.85
spvPushOperandTypesFunction · 0.85
spvOperandIsOptionalFunction · 0.85
operandsMethod · 0.80
backMethod · 0.80
clearMethod · 0.45
push_backMethod · 0.45
dataMethod · 0.45
emptyMethod · 0.45
nameMethod · 0.45

Tested by

no test coverage detected