| // Copyright 2021 The IREE Authors |
| // |
| // Licensed under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #include "iree/vm/bytecode/disassembler.h" |
| |
| #include <inttypes.h> |
| |
| #include "iree/vm/ops.h" |
| |
| #define BEGIN_DISASM_PREFIX(op_name, ext) \ |
| case IREE_VM_OP_CORE_##op_name: { \ |
| switch (bytecode_data[pc++]) { |
| #define END_DISASM_PREFIX() \ |
| default: \ |
| return iree_make_status(IREE_STATUS_UNIMPLEMENTED, \ |
| "unhandled ext opcode"); \ |
| } \ |
| break; \ |
| } |
| #define UNHANDLED_DISASM_PREFIX(op_name, ext) \ |
| case IREE_VM_OP_CORE_##op_name: { \ |
| return iree_make_status(IREE_STATUS_UNIMPLEMENTED, \ |
| "unhandled dispatch extension " #ext); \ |
| } |
| |
| #define DISASM_OP(ext, op_name) case IREE_VM_OP_##ext##_##op_name: |
| |
| #define VM_ParseConstI8(name) \ |
| OP_I8(0); \ |
| ++pc; |
| #define VM_ParseConstI16(name) \ |
| OP_I16(0); \ |
| pc += 2; |
| #define VM_ParseConstI32(name) \ |
| OP_I32(0); \ |
| pc += 4; |
| #define VM_ParseConstI64(name) \ |
| OP_I64(0); \ |
| pc += 8; |
| #define VM_ParseConstF32(name) \ |
| OP_F32(0); \ |
| pc += 4; |
| #define VM_ParseConstF64(name) \ |
| OP_F64(0); \ |
| pc += 8; |
| #define VM_ParseOpcode(opcode) VM_ParseConstI8(#opcode) |
| #define VM_ParseFuncAttr(name) VM_ParseConstI32(name) |
| #define VM_ParseGlobalAttr(name) VM_ParseConstI32(name) |
| #define VM_ParseRodataAttr(name) VM_ParseConstI32(name) |
| #define VM_ParseType(name) \ |
| iree_vm_map_type(module, OP_I32(0)); \ |
| pc += 4; |
| #define VM_ParseTypeOf(name) VM_ParseType(name) |
| #define VM_ParseAttrI32(name) VM_ParseConstI32(name) |
| #define VM_ParseAttrI64(name) VM_ParseConstI64(name) |
| #define VM_ParseAttrF32(name) VM_ParseConstF32(name) |
| #define VM_ParseAttrF64(name) VM_ParseConstF64(name) |
| #define VM_ParseStrAttr(name, out_str) \ |
| (out_str)->size = (iree_host_size_t)OP_I16(0); \ |
| (out_str)->data = (const char*)&bytecode_data[pc + 2]; \ |
| pc += 2 + (out_str)->size; |
| #define VM_ParseBranchTarget(block_name) VM_ParseConstI32(name) |
| #define VM_ParseBranchOperands(operands_name) \ |
| VM_DecBranchOperandsImpl(bytecode_data, &pc) |
| #define VM_ParseOperandRegI32(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseOperandRegI64(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseOperandRegF32(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseOperandRegF64(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseOperandRegRef(name, out_is_move) \ |
| OP_I16(0) & IREE_REF_REGISTER_MASK; \ |
| *(out_is_move) = 0; /*= OP_I16(0) & IREE_REF_REGISTER_MOVE_BIT;*/ \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseVariadicOperands(name) \ |
| VM_DecVariadicOperandsImpl(bytecode_data, &pc) |
| #define VM_ParseResultRegI32(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseResultRegI64(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseResultRegF32(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseResultRegF64(name) \ |
| OP_I16(0); \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseResultRegRef(name, out_is_move) \ |
| OP_I16(0) & IREE_REF_REGISTER_MASK; \ |
| *(out_is_move) = 0; /*= OP_I16(0) & IREE_REF_REGISTER_MOVE_BIT;*/ \ |
| pc += IREE_REGISTER_ORDINAL_SIZE; |
| #define VM_ParseVariadicResults(name) VM_ParseVariadicOperands(name) |
| |
| #define EMIT_REG_NAME(reg) \ |
| if ((reg) & IREE_REF_REGISTER_TYPE_BIT) { \ |
| EMIT_REF_REG_NAME(reg); \ |
| } else { \ |
| EMIT_I32_REG_NAME(reg); \ |
| } |
| #define EMIT_I32_REG_NAME(reg) \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "%%i%u", ((reg) & IREE_I32_REGISTER_MASK))); |
| #define EMIT_I64_REG_NAME(reg) \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "%%i%u:%u", ((reg) & IREE_I32_REGISTER_MASK), \ |
| ((reg) & IREE_I32_REGISTER_MASK) + 1)); |
| #define EMIT_F32_REG_NAME(reg) EMIT_I32_REG_NAME(reg) |
| #define EMIT_F64_REG_NAME(reg) EMIT_I64_REG_NAME(reg) |
| #define EMIT_REF_REG_NAME(reg) \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "%%r%u", ((reg) & IREE_REF_REGISTER_MASK))); |
| |
| #define EMIT_REG_VALUE(regs, reg) \ |
| if ((reg) & IREE_REF_REGISTER_TYPE_BIT) { \ |
| iree_vm_ref_t* ref = &(regs)->ref[(reg) & IREE_REF_REGISTER_MASK]; \ |
| if (iree_vm_ref_is_null(ref)) { \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "null")); \ |
| } else { \ |
| iree_string_view_t type_name = iree_vm_ref_type_name(ref->type); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "!%.*s/0x%p", (int)type_name.size, type_name.data, ref->ptr)); \ |
| } \ |
| } else { \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "%u", ((regs)->i32[(reg) & IREE_I32_REGISTER_MASK]))); \ |
| } |
| |
| static iree_status_t iree_vm_bytecode_disassembler_emit_type_name( |
| iree_vm_type_def_t type_def, iree_string_builder_t* b) { |
| if (iree_vm_type_def_is_value(type_def)) { |
| const char* type_name; |
| switch (iree_vm_type_def_as_value(type_def)) { |
| case IREE_VM_VALUE_TYPE_I8: |
| type_name = "i8"; |
| break; |
| case IREE_VM_VALUE_TYPE_I16: |
| type_name = "i16"; |
| break; |
| case IREE_VM_VALUE_TYPE_I32: |
| type_name = "i32"; |
| break; |
| case IREE_VM_VALUE_TYPE_I64: |
| type_name = "i64"; |
| break; |
| case IREE_VM_VALUE_TYPE_F32: |
| type_name = "f32"; |
| break; |
| case IREE_VM_VALUE_TYPE_F64: |
| type_name = "f64"; |
| break; |
| default: |
| type_name = "unknown"; |
| break; |
| } |
| return iree_string_builder_append_cstring(b, type_name); |
| } else if (iree_vm_type_def_is_ref(type_def)) { |
| iree_string_view_t type_name = |
| iree_vm_ref_type_name(iree_vm_type_def_as_ref(type_def)); |
| return iree_string_builder_append_format(b, "%.*s", (int)type_name.size, |
| type_name.data); |
| } else { |
| return iree_string_builder_append_cstring(b, "*"); |
| } |
| } |
| #define EMIT_TYPE_NAME(type_def) \ |
| iree_vm_bytecode_disassembler_emit_type_name(type_def, b); |
| |
| static iree_status_t iree_vm_bytecode_disassembler_emit_operand_list( |
| const iree_vm_registers_t* regs, const iree_vm_register_list_t* list, |
| iree_vm_bytecode_disassembly_format_t format, iree_string_builder_t* b) { |
| bool include_values = |
| regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES); |
| for (uint16_t i = 0; i < list->size; ++i) { |
| if (i > 0) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| } |
| uint16_t reg = list->registers[i]; |
| EMIT_REG_NAME(reg); |
| if (include_values) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "(")); |
| EMIT_REG_VALUE(regs, reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| } |
| } |
| return iree_ok_status(); |
| } |
| #define EMIT_OPERAND_REG_LIST(reg_list) \ |
| iree_vm_bytecode_disassembler_emit_operand_list(regs, reg_list, format, b) |
| static iree_status_t iree_vm_bytecode_disassembler_emit_result_list( |
| const iree_vm_register_list_t* list, |
| iree_vm_bytecode_disassembly_format_t format, iree_string_builder_t* b) { |
| for (uint16_t i = 0; i < list->size; ++i) { |
| if (i > 0) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| } |
| uint16_t reg = list->registers[i]; |
| EMIT_REG_NAME(reg); |
| } |
| return iree_ok_status(); |
| } |
| #define EMIT_RESULT_REG_LIST(reg_list) \ |
| iree_vm_bytecode_disassembler_emit_result_list(reg_list, format, b) |
| static iree_status_t iree_vm_bytecode_disassembler_emit_remap_list( |
| const iree_vm_registers_t* regs, |
| const iree_vm_register_remap_list_t* remap_list, |
| iree_vm_bytecode_disassembly_format_t format, iree_string_builder_t* b) { |
| bool include_values = |
| regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES); |
| for (uint16_t i = 0; i < remap_list->size; ++i) { |
| if (i > 0) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| } |
| EMIT_REG_NAME(remap_list->pairs[i].src_reg); |
| if (include_values) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "(")); |
| EMIT_REG_VALUE(regs, remap_list->pairs[i].src_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| } |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "->")); |
| EMIT_REG_NAME(remap_list->pairs[i].dst_reg); |
| } |
| return iree_ok_status(); |
| } |
| #define EMIT_REMAP_LIST(remap_list) \ |
| iree_vm_bytecode_disassembler_emit_remap_list(regs, remap_list, format, b) |
| |
| #define EMIT_OPTIONAL_VALUE_I32(expr) \ |
| if (regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES)) { \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format(b, "(%" PRId32 ")", \ |
| (int32_t)(expr))); \ |
| } |
| #define EMIT_OPTIONAL_VALUE_I64(expr) \ |
| if (regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES)) { \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "(%" PRId64 ")", *(int64_t*)&(expr))); \ |
| } |
| #define EMIT_OPTIONAL_VALUE_F32(expr) \ |
| if (regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES)) { \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, "(%f)", *(float*)&(expr))); \ |
| } |
| #define EMIT_OPTIONAL_VALUE_F64(expr) \ |
| if (regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES)) { \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, "(%f)", *(double*)&(expr))); \ |
| } |
| #define EMIT_OPTIONAL_VALUE_REF(expr) \ |
| if (regs && (format & IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES)) { \ |
| iree_vm_ref_t* ref = (expr); \ |
| if (iree_vm_ref_is_null(ref)) { \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "(null)")); \ |
| } else { \ |
| iree_string_view_t type_name = iree_vm_ref_type_name(ref->type); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( \ |
| b, "(!%.*s/0x%p)", (int)type_name.size, type_name.data, ref->ptr)); \ |
| } \ |
| } |
| |
| #define DISASM_OP_CORE_UNARY_I32(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I32_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_CORE_BINARY_I32(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegI32("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegI32("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I32_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I32_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_CORE_TERNARY_I32(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t a_reg = VM_ParseOperandRegI32("a"); \ |
| uint16_t b_reg = VM_ParseOperandRegI32("b"); \ |
| uint16_t c_reg = VM_ParseOperandRegI32("c"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I32_REG_NAME(a_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[a_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I32_REG_NAME(b_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[b_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I32_REG_NAME(c_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[c_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_CORE_UNARY_I64(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); \ |
| uint16_t result_reg = VM_ParseResultRegI64("result"); \ |
| EMIT_I64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I64_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_CORE_BINARY_I64(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegI64("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegI64("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegI64("result"); \ |
| EMIT_I64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I64_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I64_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_CORE_TERNARY_I64(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t a_reg = VM_ParseOperandRegI64("a"); \ |
| uint16_t b_reg = VM_ParseOperandRegI64("b"); \ |
| uint16_t c_reg = VM_ParseOperandRegI64("c"); \ |
| uint16_t result_reg = VM_ParseResultRegI64("result"); \ |
| EMIT_I64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I64_REG_NAME(a_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[a_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I64_REG_NAME(b_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[b_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I64_REG_NAME(c_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[c_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F32_UNARY_F32(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F32, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); \ |
| uint16_t result_reg = VM_ParseResultRegF32("result"); \ |
| EMIT_F32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F32_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F32_BINARY_F32(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F32, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegF32("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegF32("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegF32("result"); \ |
| EMIT_F32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F32_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F32_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F32_TERNARY_F32(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F32, op_name) { \ |
| uint16_t a_reg = VM_ParseOperandRegF32("a"); \ |
| uint16_t b_reg = VM_ParseOperandRegF32("b"); \ |
| uint16_t c_reg = VM_ParseOperandRegF32("c"); \ |
| uint16_t result_reg = VM_ParseResultRegF32("result"); \ |
| EMIT_F32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F32_REG_NAME(a_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[a_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F32_REG_NAME(b_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[b_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F32_REG_NAME(c_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[c_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F64_UNARY_F64(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F64, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); \ |
| uint16_t result_reg = VM_ParseResultRegF64("result"); \ |
| EMIT_F64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F64_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F64_BINARY_F64(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F64, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegF64("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegF64("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegF64("result"); \ |
| EMIT_F64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F64_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F64_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| #define DISASM_OP_EXT_F64_TERNARY_F64(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F64, op_name) { \ |
| uint16_t a_reg = VM_ParseOperandRegF64("a"); \ |
| uint16_t b_reg = VM_ParseOperandRegF64("b"); \ |
| uint16_t c_reg = VM_ParseOperandRegF64("c"); \ |
| uint16_t result_reg = VM_ParseResultRegF64("result"); \ |
| EMIT_F64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F64_REG_NAME(a_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[a_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F64_REG_NAME(b_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[b_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F64_REG_NAME(c_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[c_reg]); \ |
| break; \ |
| } |
| |
| iree_status_t iree_vm_bytecode_disassemble_op( |
| iree_vm_bytecode_module_t* module, |
| iree_vm_bytecode_module_state_t* module_state, uint16_t function_ordinal, |
| iree_vm_source_offset_t pc, const iree_vm_registers_t* regs, |
| iree_vm_bytecode_disassembly_format_t format, iree_string_builder_t* b) { |
| const uint8_t* IREE_RESTRICT bytecode_data = |
| module->bytecode_data.data + |
| module->function_descriptor_table[function_ordinal].bytecode_offset; |
| |
| switch (bytecode_data[pc++]) { |
| //===------------------------------------------------------------------===// |
| // Globals |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, GlobalLoadI32) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseResultRegI32("value"); |
| EMIT_I32_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.global.load.i32 .rwdata[%u]", byte_offset)); |
| EMIT_OPTIONAL_VALUE_I32( |
| vm_global_load_i32(module_state->rwdata_storage.data, byte_offset)); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreI32) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.global.store.i32 ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", .rwdata[%u]", byte_offset)); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalLoadIndirectI32) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseResultRegI32("value"); |
| EMIT_I32_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, " = vm.global.load.indirect.i32 .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| EMIT_OPTIONAL_VALUE_I32(vm_global_load_i32( |
| module_state->rwdata_storage.data, regs->i32[byte_offset_reg])); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreIndirectI32) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, "vm.global.store.indirect.i32 ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalLoadI64) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseResultRegI64("value"); |
| EMIT_I32_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.global.load.i64 .rwdata[%u]", byte_offset)); |
| EMIT_OPTIONAL_VALUE_I64(module_state->rwdata_storage.data[byte_offset]); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreI64) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseOperandRegI64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.global.store.i64 ")); |
| EMIT_I64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", .rwdata[%u]", byte_offset)); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalLoadIndirectI64) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseResultRegI64("value"); |
| EMIT_I64_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, " = vm.global.load.indirect.i64 .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| EMIT_OPTIONAL_VALUE_I64( |
| module_state->rwdata_storage.data[regs->i32[byte_offset_reg]]); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreIndirectI64) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseOperandRegI64("value"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, "vm.global.store.indirect.i64 ")); |
| EMIT_I64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalLoadRef) { |
| uint32_t global = VM_ParseGlobalAttr("global"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("value"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("value", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.global.load.ref .refs[%u]", global)); |
| EMIT_OPTIONAL_VALUE_REF(&module_state->global_ref_table[global]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : !")); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreRef) { |
| uint32_t global = VM_ParseGlobalAttr("global"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("value"); |
| bool value_is_move; |
| uint16_t value_reg = VM_ParseOperandRegRef("value", &value_is_move); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.global.store.ref ")); |
| EMIT_REF_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[value_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", .refs[%u] : !", global)); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalLoadIndirectRef) { |
| uint16_t global_reg = VM_ParseOperandRegI32("global"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("value"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("value", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, " = vm.global.load.indirect.ref .refs[")); |
| EMIT_I32_REG_NAME(global_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[global_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| EMIT_OPTIONAL_VALUE_REF( |
| &module_state->global_ref_table[regs->i32[global_reg]]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : !")); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| DISASM_OP(CORE, GlobalStoreIndirectRef) { |
| uint16_t global_reg = VM_ParseOperandRegI32("global"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("value"); |
| bool value_is_move; |
| uint16_t value_reg = VM_ParseOperandRegRef("value", &value_is_move); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "vm.global.store.indirect.ref ")); |
| EMIT_REF_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format(b, ", .refs[")); |
| EMIT_I32_REG_NAME(global_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[global_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format(b, "] : !")); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Constants |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, ConstI32) { |
| int32_t value = VM_ParseAttrI32("value"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.const.i32 %d // 0x%08X", value, value)); |
| break; |
| } |
| |
| DISASM_OP(CORE, ConstI32Zero) { |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.const.i32.zero")); |
| break; |
| } |
| |
| DISASM_OP(CORE, ConstI64) { |
| int64_t value = VM_ParseAttrI64("value"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.const.i64 %" PRId64 " // 0x%016" PRIX64 "", value, value)); |
| break; |
| } |
| |
| DISASM_OP(CORE, ConstI64Zero) { |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.const.i64.zero")); |
| break; |
| } |
| |
| DISASM_OP(CORE, ConstRefZero) { |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.const.ref.zero")); |
| break; |
| } |
| |
| DISASM_OP(CORE, ConstRefRodata) { |
| uint32_t rodata_ordinal = VM_ParseRodataAttr("rodata"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("value", &result_is_move); |
| iree_vm_buffer_t* buffer = &module->rodata_ref_table[rodata_ordinal]; |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.const.ref.rodata %u // 0x%p %" PRIhsz "b", rodata_ordinal, |
| buffer->data.data, buffer->data.data_length)); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Buffers |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, BufferAlloc) { |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t alignment_reg = VM_ParseOperandRegI32("alignment"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.alloc ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(alignment_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[alignment_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferClone) { |
| bool source_is_move; |
| uint16_t source_reg = VM_ParseOperandRegRef("source", &source_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t alignment_reg = VM_ParseOperandRegI32("alignment"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.clone ")); |
| EMIT_REF_REG_NAME(source_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[source_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(alignment_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[alignment_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferLength) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = VM_ParseOperandRegRef("buffer", &buffer_is_move); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.length ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferCopy) { |
| bool source_buffer_is_move; |
| uint16_t source_buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &source_buffer_is_move); |
| uint16_t source_offset_reg = VM_ParseOperandRegI64("source_offset"); |
| bool target_buffer_is_move; |
| uint16_t target_buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &target_buffer_is_move); |
| uint16_t target_offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.copy ")); |
| EMIT_REF_REG_NAME(source_buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[source_buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(source_offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[source_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(target_buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[target_buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(target_offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[target_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferCompare) { |
| bool lhs_buffer_is_move; |
| uint16_t lhs_buffer_reg = |
| VM_ParseOperandRegRef("lhs_buffer", &lhs_buffer_is_move); |
| uint16_t lhs_offset_reg = VM_ParseOperandRegI64("lhs_offset"); |
| bool rhs_buffer_is_move; |
| uint16_t rhs_buffer_reg = |
| VM_ParseOperandRegRef("rhs_buffer", &rhs_buffer_is_move); |
| uint16_t rhs_offset_reg = VM_ParseOperandRegI64("rhs_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.compare ")); |
| EMIT_REF_REG_NAME(lhs_buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[lhs_buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(lhs_offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[lhs_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(rhs_buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[rhs_buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(rhs_offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[rhs_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferFillI8) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.i8 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32((uint8_t)regs->i32[value_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferFillI16) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.i16 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32((uint16_t)regs->i32[value_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferFillI32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.i32 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferFillI64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegI64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.i64 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferLoadI8U) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i8.u ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferLoadI8S) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i8.s ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferLoadI16U) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i16.u ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferLoadI16S) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i16.s ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferLoadI32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i32 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferLoadI64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.i64 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferStoreI8) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.i8 ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32((uint8_t)regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferStoreI16) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.i16 ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32((uint16_t)regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferStoreI32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegI32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.i32 ")); |
| EMIT_I32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| DISASM_OP(CORE, BufferStoreI64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegI64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.i64 ")); |
| EMIT_I64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, BufferHash) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.hash ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Lists |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, ListAlloc) { |
| const iree_vm_type_def_t element_type_def = |
| VM_ParseTypeOf("element_type"); |
| uint16_t initial_capacity_reg = VM_ParseOperandRegI32("initial_capacity"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.alloc ")); |
| EMIT_I32_REG_NAME(initial_capacity_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[initial_capacity_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " : !vm.list<")); |
| EMIT_TYPE_NAME(element_type_def); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ">")); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListReserve) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t minimum_capacity_reg = VM_ParseOperandRegI32("minimum_capacity"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.reserve ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(minimum_capacity_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[minimum_capacity_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListSize) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.size ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListResize) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t new_size_reg = VM_ParseOperandRegI32("new_size"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.resize ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(new_size_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[new_size_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListGetI32) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.get.i32 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListSetI32) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t raw_value_reg = VM_ParseOperandRegI32("raw_value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.set.i32 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(raw_value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[raw_value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListGetI64) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.get.i64 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListSetI64) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t value_reg = VM_ParseOperandRegI64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.set.i64 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListGetRef) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("result"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.get.ref ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| DISASM_OP(CORE, ListSetRef) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| bool operand_is_move; |
| uint16_t operand_reg = VM_ParseOperandRegRef("value", &operand_is_move); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.set.ref ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[operand_reg]); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Conditional assignment |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, SelectI32) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| uint16_t true_value_reg = VM_ParseOperandRegI32("true_value"); |
| uint16_t false_value_reg = VM_ParseOperandRegI32("false_value"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.select.i32 ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " ? ")); |
| EMIT_I32_REG_NAME(true_value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[true_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : ")); |
| EMIT_I32_REG_NAME(false_value_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[false_value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, SelectI64) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| uint16_t true_value_reg = VM_ParseOperandRegI64("true_value"); |
| uint16_t false_value_reg = VM_ParseOperandRegI64("false_value"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.select.i64 ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " ? ")); |
| EMIT_I64_REG_NAME(true_value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[true_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : ")); |
| EMIT_I64_REG_NAME(false_value_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[false_value_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, SelectRef) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("true_value"); |
| bool true_value_is_move; |
| uint16_t true_value_reg = |
| VM_ParseOperandRegRef("true_value", &true_value_is_move); |
| bool false_value_is_move; |
| uint16_t false_value_reg = |
| VM_ParseOperandRegRef("false_value", &false_value_is_move); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.select.ref ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " ? ")); |
| EMIT_REF_REG_NAME(true_value_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[true_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : ")); |
| EMIT_REF_REG_NAME(false_value_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[false_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " -> !")); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| DISASM_OP(CORE, SwitchI32) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| int32_t default_value = VM_ParseOperandRegI32("default_value"); |
| const iree_vm_register_list_t* value_reg_list = |
| VM_ParseVariadicOperands("values"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.switch.i32 ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "[")); |
| EMIT_OPERAND_REG_LIST(value_reg_list); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "] else %u", default_value)); |
| break; |
| } |
| |
| DISASM_OP(CORE, SwitchI64) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| int64_t default_value = VM_ParseOperandRegI64("default_value"); |
| const iree_vm_register_list_t* value_reg_list = |
| VM_ParseVariadicOperands("values"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.switch.i64 ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "[")); |
| EMIT_OPERAND_REG_LIST(value_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "] else %" PRId64, default_value)); |
| break; |
| } |
| |
| DISASM_OP(CORE, SwitchRef) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| bool default_is_move; |
| uint16_t default_value_reg = |
| VM_ParseOperandRegRef("default_value", &default_is_move); |
| const iree_vm_register_list_t* value_reg_list = |
| VM_ParseVariadicOperands("values"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.switch.ref ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "[")); |
| EMIT_OPERAND_REG_LIST(value_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "] else ")); |
| EMIT_REF_REG_NAME(default_value_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[default_value_reg]); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Native integer arithmetic |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP_CORE_BINARY_I32(AddI32, "vm.add.i32"); |
| DISASM_OP_CORE_BINARY_I32(SubI32, "vm.sub.i32"); |
| DISASM_OP_CORE_BINARY_I32(MulI32, "vm.mul.i32"); |
| DISASM_OP_CORE_BINARY_I32(DivI32S, "vm.div.i32.s"); |
| DISASM_OP_CORE_BINARY_I32(DivI32U, "vm.div.i32.u"); |
| DISASM_OP_CORE_BINARY_I32(RemI32S, "vm.rem.i32.s"); |
| DISASM_OP_CORE_BINARY_I32(RemI32U, "vm.rem.i32.u"); |
| DISASM_OP_CORE_TERNARY_I32(FMAI32, "vm.fma.i32"); |
| DISASM_OP_CORE_UNARY_I32(AbsI32, "vm.abs.i32"); |
| DISASM_OP_CORE_BINARY_I32(MinI32S, "vm.min.i32.s"); |
| DISASM_OP_CORE_BINARY_I32(MinI32U, "vm.min.i32.u"); |
| DISASM_OP_CORE_BINARY_I32(MaxI32S, "vm.max.i32.s"); |
| DISASM_OP_CORE_BINARY_I32(MaxI32U, "vm.max.i32.u"); |
| DISASM_OP_CORE_UNARY_I32(NotI32, "vm.not.i32"); |
| DISASM_OP_CORE_BINARY_I32(AndI32, "vm.and.i32"); |
| DISASM_OP_CORE_BINARY_I32(OrI32, "vm.or.i32"); |
| DISASM_OP_CORE_BINARY_I32(XorI32, "vm.xor.i32"); |
| DISASM_OP_CORE_UNARY_I32(CtlzI32, "vm.ctlz.i32"); |
| |
| DISASM_OP_CORE_BINARY_I64(AddI64, "vm.add.i64"); |
| DISASM_OP_CORE_BINARY_I64(SubI64, "vm.sub.i64"); |
| DISASM_OP_CORE_BINARY_I64(MulI64, "vm.mul.i64"); |
| DISASM_OP_CORE_BINARY_I64(DivI64S, "vm.div.i64.s"); |
| DISASM_OP_CORE_BINARY_I64(DivI64U, "vm.div.i64.u"); |
| DISASM_OP_CORE_BINARY_I64(RemI64S, "vm.rem.i64.s"); |
| DISASM_OP_CORE_BINARY_I64(RemI64U, "vm.rem.i64.u"); |
| DISASM_OP_CORE_TERNARY_I64(FMAI64, "vm.fma.i64"); |
| DISASM_OP_CORE_UNARY_I64(AbsI64, "vm.abs.i64"); |
| DISASM_OP_CORE_BINARY_I64(MinI64S, "vm.min.i64.s"); |
| DISASM_OP_CORE_BINARY_I64(MinI64U, "vm.min.i64.u"); |
| DISASM_OP_CORE_BINARY_I64(MaxI64S, "vm.max.i64.s"); |
| DISASM_OP_CORE_BINARY_I64(MaxI64U, "vm.max.i64.u"); |
| DISASM_OP_CORE_UNARY_I64(NotI64, "vm.not.i64"); |
| DISASM_OP_CORE_BINARY_I64(AndI64, "vm.and.i64"); |
| DISASM_OP_CORE_BINARY_I64(OrI64, "vm.or.i64"); |
| DISASM_OP_CORE_BINARY_I64(XorI64, "vm.xor.i64"); |
| DISASM_OP_CORE_UNARY_I64(CtlzI64, "vm.ctlz.i64"); |
| |
| //===------------------------------------------------------------------===// |
| // Casting and type conversion/emulation |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP_CORE_UNARY_I32(TruncI32I8, "vm.trunc.i32.i8"); |
| DISASM_OP_CORE_UNARY_I32(TruncI32I16, "vm.trunc.i32.i16"); |
| DISASM_OP_CORE_UNARY_I32(ExtI8I32S, "vm.ext.i8.i32.s"); |
| DISASM_OP_CORE_UNARY_I32(ExtI8I32U, "vm.ext.i8.i32.u"); |
| DISASM_OP_CORE_UNARY_I32(ExtI16I32S, "vm.ext.i16.i32.s"); |
| DISASM_OP_CORE_UNARY_I32(ExtI16I32U, "vm.ext.i16.i32.u"); |
| |
| DISASM_OP(CORE, TruncI64I32) { |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.trunc.i64.i32 ")); |
| EMIT_I64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(CORE, ExtI32I64S) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.ext.i32.i64.s ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(CORE, ExtI32I64U) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.ext.i32.i64.u ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, CastAnyRef) { |
| bool operand_is_move; |
| uint16_t operand_reg = VM_ParseOperandRegRef("operand", &operand_is_move); |
| const iree_vm_type_def_t type_def = VM_ParseTypeOf("result"); |
| bool result_is_move; |
| uint16_t result_reg = VM_ParseResultRegRef("result", &result_is_move); |
| EMIT_REF_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.any.ref ")); |
| EMIT_REF_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[operand_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " : !vm.ref<?> -> ")); |
| EMIT_TYPE_NAME(type_def); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Native bitwise shifts and rotates |
| //===------------------------------------------------------------------===// |
| |
| #define DISASM_OP_CORE_SHIFT_I32(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); \ |
| uint16_t amount_reg = VM_ParseOperandRegI32("amount"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I32_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I32_REG_NAME(amount_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[amount_reg]); \ |
| break; \ |
| } |
| |
| DISASM_OP_CORE_SHIFT_I32(ShlI32, "vm.shl.i32"); |
| DISASM_OP_CORE_SHIFT_I32(ShrI32S, "vm.shr.i32.s"); |
| DISASM_OP_CORE_SHIFT_I32(ShrI32U, "vm.shr.i32.u"); |
| |
| #define DISASM_OP_CORE_SHIFT_I64(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); \ |
| uint16_t amount_reg = VM_ParseOperandRegI32("amount"); \ |
| uint16_t result_reg = VM_ParseResultRegI64("result"); \ |
| EMIT_I64_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I64_REG_NAME(operand_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I32_REG_NAME(amount_reg); \ |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[amount_reg]); \ |
| break; \ |
| } |
| |
| DISASM_OP_CORE_SHIFT_I64(ShlI64, "vm.shl.i64"); |
| DISASM_OP_CORE_SHIFT_I64(ShrI64S, "vm.shr.i64.s"); |
| DISASM_OP_CORE_SHIFT_I64(ShrI64U, "vm.shr.i64.u"); |
| |
| //===------------------------------------------------------------------===// |
| // Comparison ops |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP_CORE_BINARY_I32(CmpEQI32, "vm.cmp.eq.i32"); |
| DISASM_OP_CORE_BINARY_I32(CmpNEI32, "vm.cmp.ne.i32"); |
| DISASM_OP_CORE_BINARY_I32(CmpLTI32S, "vm.cmp.lt.i32.s"); |
| DISASM_OP_CORE_BINARY_I32(CmpLTI32U, "vm.cmp.lt.i32.u"); |
| DISASM_OP_CORE_UNARY_I32(CmpNZI32, "vm.cmp.nz.i32"); |
| |
| #define DISASM_OP_CORE_CMP_I64(op_name, op_mnemonic) \ |
| DISASM_OP(CORE, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegI64("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegI64("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_I64_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_I64_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| DISASM_OP_CORE_CMP_I64(CmpEQI64, "vm.cmp.eq.i64"); |
| DISASM_OP_CORE_CMP_I64(CmpNEI64, "vm.cmp.ne.i64"); |
| DISASM_OP_CORE_CMP_I64(CmpLTI64S, "vm.cmp.lt.i64.s"); |
| DISASM_OP_CORE_CMP_I64(CmpLTI64U, "vm.cmp.lt.i64.u"); |
| DISASM_OP(CORE, CmpNZI64) { |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.nz.i64 ")); |
| EMIT_I64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); |
| break; |
| } |
| |
| DISASM_OP(CORE, CmpEQRef) { |
| bool lhs_is_move; |
| uint16_t lhs_reg = VM_ParseOperandRegRef("lhs", &lhs_is_move); |
| bool rhs_is_move; |
| uint16_t rhs_reg = VM_ParseOperandRegRef("rhs", &rhs_is_move); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.eq.ref ")); |
| EMIT_REF_REG_NAME(lhs_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[lhs_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(rhs_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[rhs_reg]); |
| break; |
| } |
| DISASM_OP(CORE, CmpNERef) { |
| bool lhs_is_move; |
| uint16_t lhs_reg = VM_ParseOperandRegRef("lhs", &lhs_is_move); |
| bool rhs_is_move; |
| uint16_t rhs_reg = VM_ParseOperandRegRef("rhs", &rhs_is_move); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.ne.ref ")); |
| EMIT_REF_REG_NAME(lhs_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[lhs_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(rhs_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[rhs_reg]); |
| break; |
| } |
| DISASM_OP(CORE, CmpNZRef) { |
| bool operand_is_move; |
| uint16_t operand_reg = VM_ParseOperandRegRef("operand", &operand_is_move); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.nz.ref ")); |
| EMIT_REF_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[operand_reg]); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Control flow |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, Block) { |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_string(b, IREE_SV("<block>"))); |
| break; |
| } |
| |
| DISASM_OP(CORE, Branch) { |
| int32_t block_pc = VM_ParseBranchTarget("dest"); |
| const iree_vm_register_remap_list_t* remap_list = |
| VM_ParseBranchOperands("operands"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.br ^%08X(", block_pc)); |
| EMIT_REMAP_LIST(remap_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, CondBranch) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| int32_t true_block_pc = VM_ParseBranchTarget("true_dest"); |
| const iree_vm_register_remap_list_t* true_remap_list = |
| VM_ParseBranchOperands("true_operands"); |
| int32_t false_block_pc = VM_ParseBranchTarget("false_dest"); |
| const iree_vm_register_remap_list_t* false_remap_list = |
| VM_ParseBranchOperands("false_operands"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.cond_br ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", ^%08X(", true_block_pc)); |
| EMIT_REMAP_LIST(true_remap_list); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "), ^%08X(", false_block_pc)); |
| EMIT_REMAP_LIST(false_remap_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, BranchTable) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.br_table ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| int32_t default_block_pc = VM_ParseBranchTarget("default_dest"); |
| const iree_vm_register_remap_list_t* default_remap_list = |
| VM_ParseBranchOperands("default_operands"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " { default: ^%08X(", default_block_pc)); |
| EMIT_REMAP_LIST(default_remap_list); |
| uint16_t table_size = VM_ParseConstI16(table_size); |
| for (uint16_t i = 0; i < table_size; ++i) { |
| int32_t case_block_pc = VM_ParseBranchTarget("case_dest"); |
| const iree_vm_register_remap_list_t* case_remap_list = |
| VM_ParseBranchOperands("case_operands"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "), %u: ^%08X(", i, case_block_pc)); |
| EMIT_REMAP_LIST(case_remap_list); |
| } |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ") }")); |
| break; |
| } |
| |
| DISASM_OP(CORE, Call) { |
| int32_t function_ordinal = VM_ParseFuncAttr("callee"); |
| const iree_vm_register_list_t* src_reg_list = |
| VM_ParseVariadicOperands("operands"); |
| const iree_vm_register_list_t* dst_reg_list = |
| VM_ParseVariadicResults("results"); |
| if (dst_reg_list->size > 0) { |
| EMIT_RESULT_REG_LIST(dst_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " = ")); |
| } |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "vm.call @")); |
| int is_import = (function_ordinal & 0x80000000u) != 0; |
| iree_vm_function_t function; |
| if (is_import) { |
| const iree_vm_bytecode_import_t* import = |
| &module_state->import_table[function_ordinal & 0x7FFFFFFFu]; |
| function = import->function; |
| } else { |
| function.module = &module->interface; |
| function.linkage = IREE_VM_FUNCTION_LINKAGE_INTERNAL; |
| function.ordinal = function_ordinal; |
| } |
| if (function.module) { |
| iree_string_view_t module_name = iree_vm_module_name(function.module); |
| iree_string_view_t func_name = iree_vm_function_name(&function); |
| if (iree_string_view_is_empty(func_name)) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "%.*s:%u", (int)module_name.size, module_name.data, |
| function.ordinal)); |
| } else { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "%.*s.%.*s", (int)module_name.size, module_name.data, |
| (int)func_name.size, func_name.data)); |
| } |
| } else { |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "{{UNRESOLVED}}")); |
| } |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "(")); |
| EMIT_OPERAND_REG_LIST(src_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, CallVariadic) { |
| int32_t function_ordinal = VM_ParseFuncAttr("callee"); |
| // TODO(benvanik): print segment sizes. |
| // const iree_vm_register_list_t* segment_size_list = |
| VM_ParseVariadicOperands("segment_sizes"); |
| const iree_vm_register_list_t* src_reg_list = |
| VM_ParseVariadicOperands("operands"); |
| const iree_vm_register_list_t* dst_reg_list = |
| VM_ParseVariadicResults("results"); |
| if (dst_reg_list->size > 0) { |
| EMIT_RESULT_REG_LIST(dst_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " = ")); |
| } |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.call.varadic @")); |
| int is_import = (function_ordinal & 0x80000000u) != 0; |
| iree_vm_function_t function; |
| if (is_import) { |
| const iree_vm_bytecode_import_t* import = |
| &module_state->import_table[function_ordinal & 0x7FFFFFFFu]; |
| function = import->function; |
| } else { |
| function.module = &module->interface; |
| function.linkage = IREE_VM_FUNCTION_LINKAGE_INTERNAL; |
| function.ordinal = function_ordinal; |
| } |
| iree_string_view_t module_name = iree_vm_module_name(function.module); |
| iree_string_view_t func_name = iree_vm_function_name(&function); |
| if (iree_string_view_is_empty(func_name)) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "%.*s:%u", (int)module_name.size, module_name.data, |
| function.ordinal)); |
| } else { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "%.*s.%.*s", (int)module_name.size, module_name.data, |
| (int)func_name.size, func_name.data)); |
| } |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "(")); |
| EMIT_OPERAND_REG_LIST(src_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, Return) { |
| const iree_vm_register_list_t* src_reg_list = |
| VM_ParseVariadicOperands("operands"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "vm.return ")); |
| EMIT_OPERAND_REG_LIST(src_reg_list); |
| break; |
| } |
| |
| DISASM_OP(CORE, Fail) { |
| uint16_t status_code_reg = VM_ParseOperandRegI32("status"); |
| iree_string_view_t message; |
| VM_ParseStrAttr("message", &message); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "vm.fail ")); |
| EMIT_I32_REG_NAME(status_code_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[status_code_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, ", \"%.*s\"", (int)message.size, message.data)); |
| break; |
| } |
| |
| DISASM_OP(CORE, ImportResolved) { |
| int32_t function_ordinal = VM_ParseFuncAttr("import"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.import.exists @")); |
| int is_import = (function_ordinal & 0x80000000u) != 0; |
| if (IREE_UNLIKELY(!is_import)) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "{{INVALID ORDINAL %d}}", function_ordinal)); |
| break; |
| } |
| uint32_t import_ordinal = function_ordinal & 0x7FFFFFFFu; |
| if (IREE_UNLIKELY(import_ordinal >= module_state->import_count)) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "{{OUT OF RANGE ORDINAL %u}}", import_ordinal)); |
| break; |
| } |
| iree_vm_function_t decl_function; |
| IREE_RETURN_IF_ERROR(iree_vm_module_lookup_function_by_ordinal( |
| &module->interface, IREE_VM_FUNCTION_LINKAGE_IMPORT_OPTIONAL, |
| import_ordinal, &decl_function)); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_string( |
| b, iree_vm_function_name(&decl_function))); |
| const iree_vm_bytecode_import_t* import = |
| &module_state->import_table[import_ordinal]; |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, import->function.module != NULL ? " // (resolved)" |
| : " // (unresolved)")); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Async/fiber ops |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, Yield) { |
| int32_t block_pc = VM_DecBranchTarget("dest"); |
| const iree_vm_register_remap_list_t* remap_list = |
| VM_ParseBranchOperands("operands"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.yield ^%08X(", block_pc)); |
| EMIT_REMAP_LIST(remap_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Debugging |
| //===------------------------------------------------------------------===// |
| |
| DISASM_OP(CORE, Trace) { |
| iree_string_view_t event_name; |
| VM_ParseStrAttr("event_name", &event_name); |
| const iree_vm_register_list_t* src_reg_list = |
| VM_ParseVariadicOperands("operands"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "vm.trace \"%.*s\"(", (int)event_name.size, event_name.data)); |
| EMIT_OPERAND_REG_LIST(src_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, Print) { |
| iree_string_view_t event_name; |
| VM_ParseStrAttr("event_name", &event_name); |
| const iree_vm_register_list_t* src_reg_list = |
| VM_ParseVariadicOperands("operands"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, "vm.print \"%.*s\"(", (int)event_name.size, event_name.data)); |
| EMIT_OPERAND_REG_LIST(src_reg_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, Break) { |
| int32_t block_pc = VM_DecBranchTarget("dest"); |
| const iree_vm_register_remap_list_t* remap_list = |
| VM_ParseBranchOperands("operands"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.break ^%08X(", block_pc)); |
| EMIT_REMAP_LIST(remap_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| DISASM_OP(CORE, CondBreak) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| int32_t block_pc = VM_ParseBranchTarget("dest"); |
| const iree_vm_register_remap_list_t* remap_list = |
| VM_ParseBranchOperands("operands"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.cond_break ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", ^%08X(", block_pc)); |
| EMIT_REMAP_LIST(remap_list); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ")")); |
| break; |
| } |
| |
| //===------------------------------------------------------------------===// |
| // Extension trampolines |
| //===------------------------------------------------------------------===// |
| |
| #if IREE_VM_EXT_F32_ENABLE |
| BEGIN_DISASM_PREFIX(PrefixExtF32, EXT_F32) |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Globals |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, GlobalLoadF32) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseResultRegF32("value"); |
| EMIT_F32_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.global.load.f32 .rwdata[%u]", byte_offset)); |
| EMIT_OPTIONAL_VALUE_F32(module_state->rwdata_storage.data[byte_offset]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, GlobalStoreF32) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseOperandRegF32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.global.store.f32 ")); |
| EMIT_F32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", .rwdata[%u]", byte_offset)); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, GlobalLoadIndirectF32) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseResultRegI32("value"); |
| EMIT_F32_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, " = vm.global.load.indirect.f32 .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| EMIT_OPTIONAL_VALUE_F32( |
| module_state->rwdata_storage.data[regs->i32[byte_offset_reg]]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, GlobalStoreIndirectF32) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseOperandRegF32("value"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, "vm.global.store.indirect.f32 ")); |
| EMIT_F32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Constants |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, ConstF32) { |
| float value = VM_ParseAttrF32("value"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, " = vm.const.f32 %f", value)); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, ConstF32Zero) { |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.const.f32.zero")); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Lists |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, ListGetF32) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.get.f32 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, ListSetF32) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t raw_value_reg = VM_ParseOperandRegF32("raw_value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.set.f32 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_F32_REG_NAME(raw_value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[raw_value_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Conditional assignment |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, SelectF32) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| uint16_t true_value_reg = VM_ParseOperandRegF32("true_value"); |
| uint16_t false_value_reg = VM_ParseOperandRegF32("false_value"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.select.f32 ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " ? ")); |
| EMIT_F32_REG_NAME(true_value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[true_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : ")); |
| EMIT_F32_REG_NAME(false_value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[false_value_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, SwitchF32) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| float default_value = VM_ParseOperandRegF32("default_value"); |
| const iree_vm_register_list_t* value_reg_list = |
| VM_ParseVariadicOperands("values"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.switch.f32 ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "[")); |
| EMIT_OPERAND_REG_LIST(value_reg_list); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "] else %f", default_value)); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Native floating-point arithmetic |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP_EXT_F32_BINARY_F32(AddF32, "vm.add.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(SubF32, "vm.sub.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(MulF32, "vm.mul.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(DivF32, "vm.div.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(RemF32, "vm.rem.f32"); |
| DISASM_OP_EXT_F32_TERNARY_F32(FMAF32, "vm.fma.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(AbsF32, "vm.abs.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(NegF32, "vm.neg.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(CeilF32, "vm.ceil.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(FloorF32, "vm.floor.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(RoundF32, "vm.round.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(RoundF32Even, "vm.round.f32.even"); |
| DISASM_OP_EXT_F32_BINARY_F32(MinF32, "vm.min.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(MaxF32, "vm.max.f32"); |
| |
| DISASM_OP_EXT_F32_UNARY_F32(AtanF32, "vm.atan.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(Atan2F32, "vm.atan2.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(CosF32, "vm.cos.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(SinF32, "vm.sin.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(ExpF32, "vm.exp.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(Exp2F32, "vm.exp2.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(ExpM1F32, "vm.expm1.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(LogF32, "vm.log.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(Log10F32, "vm.log10.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(Log1pF32, "vm.log1p.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(Log2F32, "vm.log2.f32"); |
| DISASM_OP_EXT_F32_BINARY_F32(PowF32, "vm.pow.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(RsqrtF32, "vm.rsqrt.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(SqrtF32, "vm.sqrt.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(TanhF32, "vm.tanh.f32"); |
| DISASM_OP_EXT_F32_UNARY_F32(ErfF32, "vm.erf.f32"); |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Casting and type conversion/emulation |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, CastSI32F32) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.si32.f32 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F32, CastUI32F32) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.ui32.f32 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F32, CastF32SI32) { |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f32.sif32 ")); |
| EMIT_F32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F32, CastF32UI32) { |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f32.uif32 ")); |
| EMIT_F32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F32, BitcastI32F32) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.bitcast.i32.f32 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F32, BitcastF32I32) { |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.bitcast.f32.i32 ")); |
| EMIT_F32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Comparison ops |
| //===----------------------------------------------------------------===// |
| |
| #define DISASM_OP_EXT_F32_CMP_F32(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F32, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegF32("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegF32("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F32_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F32_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| DISASM_OP_EXT_F32_CMP_F32(CmpEQF32O, "vm.cmp.eq.f32.o"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpEQF32U, "vm.cmp.eq.f32.u"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpNEF32O, "vm.cmp.ne.f32.o"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpNEF32U, "vm.cmp.ne.f32.u"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpLTF32O, "vm.cmp.lt.f32.o"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpLTF32U, "vm.cmp.lt.f32.u"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpLTEF32O, "vm.cmp.lte.f32.o"); |
| DISASM_OP_EXT_F32_CMP_F32(CmpLTEF32U, "vm.cmp.lte.f32.u"); |
| DISASM_OP(EXT_F32, CmpNaNF32) { |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.nan.f32 ")); |
| EMIT_F32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF32: Buffers |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F32, BufferFillF32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegF32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.f32 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_F32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[value_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, BufferLoadF32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.f32 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F32, BufferStoreF32) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegF32("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.f32 ")); |
| EMIT_F32_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| END_DISASM_PREFIX() |
| #else |
| UNHANDLED_DISASM_PREFIX(PrefixExtF32, EXT_F32) |
| #endif // IREE_VM_EXT_F32_ENABLE |
| |
| #if IREE_VM_EXT_F64_ENABLE |
| BEGIN_DISASM_PREFIX(PrefixExtF64, EXT_F64) |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Globals |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, GlobalLoadF64) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseResultRegF64("value"); |
| EMIT_F64_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| b, " = vm.global.load.f64 .rwdata[%u]", byte_offset)); |
| EMIT_OPTIONAL_VALUE_F64(module_state->rwdata_storage.data[byte_offset]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, GlobalStoreF64) { |
| uint32_t byte_offset = VM_ParseGlobalAttr("global"); |
| uint16_t value_reg = VM_ParseOperandRegF64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "vm.global.store.f64 ")); |
| EMIT_F64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, ", .rwdata[%u]", byte_offset)); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, GlobalLoadIndirectF64) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseResultRegI32("value"); |
| EMIT_F64_REG_NAME(value_reg); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, " = vm.global.load.indirect.f64 .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| EMIT_OPTIONAL_VALUE_F64( |
| module_state->rwdata_storage.data[regs->i32[byte_offset_reg]]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, GlobalStoreIndirectF64) { |
| uint16_t byte_offset_reg = VM_ParseOperandRegI32("global"); |
| uint16_t value_reg = VM_ParseOperandRegF64("value"); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring( |
| b, "vm.global.store.indirect.f64 ")); |
| EMIT_F64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", .rwdata[")); |
| EMIT_I32_REG_NAME(byte_offset_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[byte_offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "]")); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Constants |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, ConstF64) { |
| double value = VM_ParseAttrF64("value"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, " = vm.const.f64 %f", value)); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, ConstF64Zero) { |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.const.f64.zero")); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Lists |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, ListGetF64) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.list.get.f64 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, ListSetF64) { |
| bool list_is_move; |
| uint16_t list_reg = VM_ParseOperandRegRef("list", &list_is_move); |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| uint16_t raw_value_reg = VM_ParseOperandRegF64("raw_value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.list.set.f64 ")); |
| EMIT_REF_REG_NAME(list_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[list_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_F64_REG_NAME(raw_value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[raw_value_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Conditional assignment |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, SelectF64) { |
| uint16_t condition_reg = VM_ParseOperandRegI32("condition"); |
| uint16_t true_value_reg = VM_ParseOperandRegF64("true_value"); |
| uint16_t false_value_reg = VM_ParseOperandRegF64("false_value"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.select.f64 ")); |
| EMIT_I32_REG_NAME(condition_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[condition_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " ? ")); |
| EMIT_F64_REG_NAME(true_value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[true_value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, " : ")); |
| EMIT_F64_REG_NAME(false_value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[false_value_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, SwitchF64) { |
| uint16_t index_reg = VM_ParseOperandRegI32("index"); |
| double default_value = VM_ParseOperandRegF64("default_value"); |
| const iree_vm_register_list_t* value_reg_list = |
| VM_ParseVariadicOperands("values"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.switch.f64 ")); |
| EMIT_I32_REG_NAME(index_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[index_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, "[")); |
| EMIT_OPERAND_REG_LIST(value_reg_list); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_format(b, "] else %f", default_value)); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Native floating-point arithmetic |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP_EXT_F64_BINARY_F64(AddF64, "vm.add.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(SubF64, "vm.sub.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(MulF64, "vm.mul.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(DivF64, "vm.div.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(RemF64, "vm.rem.f64"); |
| DISASM_OP_EXT_F64_TERNARY_F64(FMAF64, "vm.fma.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(AbsF64, "vm.abs.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(NegF64, "vm.neg.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(CeilF64, "vm.ceil.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(FloorF64, "vm.floor.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(RoundF64, "vm.round.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(RoundF64Even, "vm.round.f64.even"); |
| DISASM_OP_EXT_F64_BINARY_F64(MinF64, "vm.min.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(MaxF64, "vm.max.f64"); |
| |
| DISASM_OP_EXT_F64_UNARY_F64(AtanF64, "vm.atan.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(Atan2F64, "vm.atan2.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(CosF64, "vm.cos.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(SinF64, "vm.sin.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(ExpF64, "vm.exp.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(Exp2F64, "vm.exp2.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(ExpM1F64, "vm.expm1.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(LogF64, "vm.log.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(Log10F64, "vm.log10.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(Log1pF64, "vm.log1p.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(Log2F64, "vm.log2.f64"); |
| DISASM_OP_EXT_F64_BINARY_F64(PowF64, "vm.pow.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(RsqrtF64, "vm.rsqrt.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(SqrtF64, "vm.sqrt.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(TanhF64, "vm.tanh.f64"); |
| DISASM_OP_EXT_F64_UNARY_F64(ErfF64, "vm.erf.f64"); |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Casting and type conversion/emulation |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, TruncF64F32) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegF32("result"); |
| EMIT_F32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.trunc.f64.f32 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, ExtF32F64) { |
| uint16_t operand_reg = VM_ParseOperandRegF32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.ext.f32.f64 ")); |
| EMIT_F32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastSI32F64) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.si32.f64 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastUI32F64) { |
| uint16_t operand_reg = VM_ParseOperandRegI32("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.ui32.f64 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I32(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastF64SI32) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f64.si32 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastF64UI32) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f64.ui32 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastSI64F64) { |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.si64.f64 ")); |
| EMIT_I64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastUI64F64) { |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.ui64.f64 ")); |
| EMIT_I64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastF64SI64) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f64.si64 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, CastF64UI64) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cast.f64.ui64 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, BitcastI64F64) { |
| uint16_t operand_reg = VM_ParseOperandRegI64("operand"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.bitcast.i64.f64 ")); |
| EMIT_I32_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[operand_reg]); |
| break; |
| } |
| DISASM_OP(EXT_F64, BitcastF64I64) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI64("result"); |
| EMIT_I64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.bitcast.f64.i64 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Comparison ops |
| //===----------------------------------------------------------------===// |
| |
| #define DISASM_OP_EXT_F64_CMP_F64(op_name, op_mnemonic) \ |
| DISASM_OP(EXT_F64, op_name) { \ |
| uint16_t lhs_reg = VM_ParseOperandRegF64("lhs"); \ |
| uint16_t rhs_reg = VM_ParseOperandRegF64("rhs"); \ |
| uint16_t result_reg = VM_ParseResultRegI32("result"); \ |
| EMIT_I32_REG_NAME(result_reg); \ |
| IREE_RETURN_IF_ERROR( \ |
| iree_string_builder_append_format(b, " = %s ", op_mnemonic)); \ |
| EMIT_F64_REG_NAME(lhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[lhs_reg]); \ |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); \ |
| EMIT_F64_REG_NAME(rhs_reg); \ |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[rhs_reg]); \ |
| break; \ |
| } |
| |
| DISASM_OP_EXT_F64_CMP_F64(CmpEQF64O, "vm.cmp.eq.f64.o"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpEQF64U, "vm.cmp.eq.f64.u"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpNEF64O, "vm.cmp.ne.f64.o"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpNEF64U, "vm.cmp.ne.f64.u"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpLTF64O, "vm.cmp.lt.f64.o"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpLTF64U, "vm.cmp.lt.f64.u"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpLTEF64O, "vm.cmp.lte.f64.o"); |
| DISASM_OP_EXT_F64_CMP_F64(CmpLTEF64U, "vm.cmp.lte.f64.u"); |
| DISASM_OP(EXT_F64, CmpNaNF64) { |
| uint16_t operand_reg = VM_ParseOperandRegF64("operand"); |
| uint16_t result_reg = VM_ParseResultRegI32("result"); |
| EMIT_I32_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.cmp.nan.f64 ")); |
| EMIT_F64_REG_NAME(operand_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[operand_reg]); |
| break; |
| } |
| |
| //===----------------------------------------------------------------===// |
| // ExtF64: Buffers |
| //===----------------------------------------------------------------===// |
| |
| DISASM_OP(EXT_F64, BufferFillF64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t length_reg = VM_ParseOperandRegI64("length"); |
| uint16_t value_reg = VM_ParseOperandRegF64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.fill.f64 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(length_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[length_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_F64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[value_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, BufferLoadF64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("source_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("source_offset"); |
| uint16_t result_reg = VM_ParseResultRegF64("result"); |
| EMIT_F64_REG_NAME(result_reg); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, " = vm.buffer.load.f64 ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| DISASM_OP(EXT_F64, BufferStoreF64) { |
| bool buffer_is_move; |
| uint16_t buffer_reg = |
| VM_ParseOperandRegRef("target_buffer", &buffer_is_move); |
| uint16_t offset_reg = VM_ParseOperandRegI64("target_offset"); |
| uint16_t value_reg = VM_ParseOperandRegF64("value"); |
| IREE_RETURN_IF_ERROR( |
| iree_string_builder_append_cstring(b, "vm.buffer.store.f64 ")); |
| EMIT_F64_REG_NAME(value_reg); |
| EMIT_OPTIONAL_VALUE_F64(regs->i32[value_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_REF_REG_NAME(buffer_reg); |
| EMIT_OPTIONAL_VALUE_REF(®s->ref[buffer_reg]); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_cstring(b, ", ")); |
| EMIT_I64_REG_NAME(offset_reg); |
| EMIT_OPTIONAL_VALUE_I64(regs->i32[offset_reg]); |
| break; |
| } |
| |
| END_DISASM_PREFIX() |
| #else |
| UNHANDLED_DISASM_PREFIX(PrefixExtF64, EXT_F64) |
| #endif // IREE_VM_EXT_F64_ENABLE |
| |
| default: |
| return iree_make_status(IREE_STATUS_UNIMPLEMENTED, |
| "unhandled core opcode"); |
| } |
| return iree_ok_status(); |
| } |
| |
| iree_status_t iree_vm_bytecode_trace_disassembly( |
| iree_vm_stack_frame_t* frame, iree_vm_source_offset_t pc, |
| const iree_vm_registers_t* regs, FILE* file) { |
| IREE_ALLOCATOR_INLINE_STORAGE(inline_storage, 2048); |
| iree_string_builder_t b; |
| iree_string_builder_initialize( |
| iree_allocator_inline_arena(&inline_storage.header), &b); |
| |
| // TODO(benvanik): ensure frame is in-sync before call or restore original. |
| // It's shady to manipulate the frame here but I know we expect the pc to be |
| // valid only on entry/exit from a function. |
| frame->pc = pc; |
| |
| #if IREE_VM_EXECUTION_TRACING_SRC_LOC_ENABLE |
| iree_vm_source_location_t source_location; |
| iree_status_t status = iree_vm_module_resolve_source_location( |
| frame->function.module, frame->function, pc, &source_location); |
| if (iree_status_is_ok(status)) { |
| status = iree_vm_source_location_format( |
| &source_location, IREE_VM_SOURCE_LOCATION_FORMAT_FLAG_SINGLE_LINE, &b); |
| } |
| if (iree_status_is_ok(status)) { |
| // Pad out to keep alignment. This is just guesswork based on my machine. |
| static const iree_host_size_t pad_to = 80; |
| iree_host_size_t col = iree_string_builder_size(&b); |
| if (col < pad_to) { |
| iree_string_builder_append_format(&b, "%*s ", (int)(pad_to - col), ""); |
| } else { |
| status = iree_string_builder_append_cstring(&b, " "); |
| } |
| } else { |
| // Ignore failures when no source location is available. |
| if (iree_status_is_unavailable(status)) { |
| status = iree_ok_status(); |
| } else { |
| return status; |
| } |
| } |
| #else |
| iree_status_t status = iree_ok_status(); |
| #endif // IREE_VM_EXECUTION_TRACING_ENABLE |
| |
| if (iree_status_is_ok(status)) { |
| iree_string_view_t module_name = |
| iree_vm_module_name(frame->function.module); |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| &b, "[%.*s", (int)module_name.size, module_name.data)); |
| iree_string_view_t function_name = iree_vm_function_name(&frame->function); |
| if (iree_string_view_is_empty(function_name)) { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| &b, "@%u", (uint32_t)frame->function.ordinal)); |
| } else { |
| IREE_RETURN_IF_ERROR(iree_string_builder_append_format( |
| &b, ".%.*s", (int)function_name.size, function_name.data)); |
| } |
| status = iree_string_builder_append_format(&b, "+%08" PRIX64 "] ", pc); |
| } |
| |
| if (iree_status_is_ok(status)) { |
| status = iree_vm_bytecode_disassemble_op( |
| (iree_vm_bytecode_module_t*)frame->function.module, |
| (iree_vm_bytecode_module_state_t*)frame->module_state, |
| frame->function.ordinal, pc, regs, |
| IREE_VM_BYTECODE_DISASSEMBLY_FORMAT_INLINE_VALUES, &b); |
| } |
| |
| if (iree_status_is_ok(status)) { |
| fprintf(file, "%.*s\n", (int)iree_string_builder_size(&b), |
| iree_string_builder_buffer(&b)); |
| } |
| |
| iree_string_builder_deinitialize(&b); |
| return status; |
| } |