254 const auto bytecode_length = bytecode.size();
256 if (pos >= bytecode_length) {
257 std::string error_msg =
format(
"Invalid program counter ", pos,
", max is ", bytecode_length - 1);
262 const uint8_t opcode_byte = bytecode[pos];
264 if (!is_wire_opcode_valid(opcode_byte)) {
265 std::string error_msg =
format(
"Opcode ",
266 static_cast<uint32_t
>(opcode_byte),
269 ") value is not in the range of valid opcodes (at PC ",
276 const auto opcode =
static_cast<WireOpCode>(opcode_byte);
277 const auto iter = get_wire_opcode_wire_format().find(opcode);
278 BB_ASSERT_DEBUG(iter != get_wire_opcode_wire_format().end(),
"Wire opcode not found in wire opcode wire format");
279 const auto& inst_format = iter->second;
283 if (pos + instruction_size > bytecode_length) {
284 std::string error_msg =
format(
"Instruction at PC ",
286 " does not fit in bytecode (instruction size: ",
289 bytecode_length - pos,
298 uint16_t addressing_mode = 0;
301 const auto operand_size = get_operand_type_size_bytes().at(op_type);
303 BB_ASSERT_DEBUG(pos + operand_size <= bytecode_length,
"Operand size is out of range");
308 operands.emplace_back(Operand::from<uint8_t>(bytecode[pos]));
312 addressing_mode = bytecode[pos];
316 uint16_t operand_u16 = 0;
317 uint8_t
const* pos_ptr = &bytecode[pos];
319 addressing_mode = operand_u16;
323 uint16_t operand_u16 = 0;
324 uint8_t
const* pos_ptr = &bytecode[pos];
326 operands.emplace_back(Operand::from<uint16_t>(operand_u16));
330 uint32_t operand_u32 = 0;
331 uint8_t
const* pos_ptr = &bytecode[pos];
333 operands.emplace_back(Operand::from<uint32_t>(operand_u32));
337 uint64_t operand_u64 = 0;
338 uint8_t
const* pos_ptr = &bytecode[pos];
340 operands.emplace_back(Operand::from<uint64_t>(operand_u64));
345 uint8_t
const* pos_ptr = &bytecode[pos];
347 operands.emplace_back(Operand::from<uint128_t>(operand_u128));
352 uint8_t
const* pos_ptr = &bytecode[pos];
353 read(pos_ptr, operand_ff);
354 operands.emplace_back(Operand::from<FF>(operand_ff));
362 .addressing_mode = addressing_mode,
399 std::vector<uint8_t> output;
401 output.emplace_back(
static_cast<uint8_t
>(
opcode));
402 size_t operand_pos = 0;
404 for (
const auto& operand_type : get_wire_opcode_wire_format().at(
opcode)) {
405 switch (operand_type) {
411 output.insert(output.end(),
417 output.emplace_back(
operands.at(operand_pos++).as<uint8_t>());