Path: blob/21.2-virgl/src/intel/common/intel_disasm.c
4547 views
/*1* Copyright © 2014 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <stdlib.h>2425#include "compiler/brw_inst.h"26#include "compiler/brw_eu.h"2728#include "intel_disasm.h"2930static bool31is_send(uint32_t opcode)32{33return (opcode == BRW_OPCODE_SEND ||34opcode == BRW_OPCODE_SENDC ||35opcode == BRW_OPCODE_SENDS ||36opcode == BRW_OPCODE_SENDSC );37}3839static int40intel_disasm_find_end(const struct intel_device_info *devinfo,41const void *assembly, int start)42{43int offset = start;4445/* This loop exits when send-with-EOT or when opcode is 0 */46while (true) {47const brw_inst *insn = assembly + offset;4849if (brw_inst_cmpt_control(devinfo, insn)) {50offset += 8;51} else {52offset += 16;53}5455/* Simplistic, but efficient way to terminate disasm */56uint32_t opcode = brw_inst_opcode(devinfo, insn);57if (opcode == 0 || (is_send(opcode) && brw_inst_eot(devinfo, insn))) {58break;59}60}6162return offset;63}6465void66intel_disassemble(const struct intel_device_info *devinfo,67const void *assembly, int start, FILE *out)68{69int end = intel_disasm_find_end(devinfo, assembly, start);7071/* Make a dummy disasm structure that brw_validate_instructions72* can work from.73*/74struct disasm_info *disasm_info = disasm_initialize(devinfo, NULL);75disasm_new_inst_group(disasm_info, start);76disasm_new_inst_group(disasm_info, end);7778brw_validate_instructions(devinfo, assembly, start, end, disasm_info);7980void *mem_ctx = ralloc_context(NULL);81const struct brw_label *root_label =82brw_label_assembly(devinfo, assembly, start, end, mem_ctx);8384foreach_list_typed(struct inst_group, group, link,85&disasm_info->group_list) {86struct exec_node *next_node = exec_node_get_next(&group->link);87if (exec_node_is_tail_sentinel(next_node))88break;8990struct inst_group *next =91exec_node_data(struct inst_group, next_node, link);9293int start_offset = group->offset;94int end_offset = next->offset;9596brw_disassemble(devinfo, assembly, start_offset, end_offset,97root_label, out);9899if (group->error) {100fputs(group->error, out);101}102}103104ralloc_free(mem_ctx);105ralloc_free(disasm_info);106}107108109