qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

xtensa.c (5162B)


      1 /*
      2  * Copyright (c) 2017, Max Filippov, Open Source and Linux Lab.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *     * Redistributions of source code must retain the above copyright
      8  *       notice, this list of conditions and the following disclaimer.
      9  *     * Redistributions in binary form must reproduce the above copyright
     10  *       notice, this list of conditions and the following disclaimer in the
     11  *       documentation and/or other materials provided with the distribution.
     12  *     * Neither the name of the Open Source and Linux Lab nor the
     13  *       names of its contributors may be used to endorse or promote products
     14  *       derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "qemu/osdep.h"
     29 #include "disas/dis-asm.h"
     30 #include "hw/xtensa/xtensa-isa.h"
     31 
     32 int print_insn_xtensa(bfd_vma memaddr, struct disassemble_info *info)
     33 {
     34     xtensa_isa isa = info->private_data;
     35     xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc(isa);
     36     xtensa_insnbuf slotbuf = xtensa_insnbuf_alloc(isa);
     37     bfd_byte *buffer = g_malloc(1);
     38     int status = info->read_memory_func(memaddr, buffer, 1, info);
     39     xtensa_format fmt;
     40     int slot, slots;
     41     unsigned len;
     42 
     43     if (status) {
     44         info->memory_error_func(status, memaddr, info);
     45         len = -1;
     46         goto out;
     47     }
     48     len = xtensa_isa_length_from_chars(isa, buffer);
     49     if (len == XTENSA_UNDEFINED) {
     50         info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]);
     51         len = 1;
     52         goto out;
     53     }
     54     buffer = g_realloc(buffer, len);
     55     status = info->read_memory_func(memaddr + 1, buffer + 1, len - 1, info);
     56     if (status) {
     57         info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]);
     58         info->memory_error_func(status, memaddr + 1, info);
     59         len = 1;
     60         goto out;
     61     }
     62 
     63     xtensa_insnbuf_from_chars(isa, insnbuf, buffer, len);
     64     fmt = xtensa_format_decode(isa, insnbuf);
     65     if (fmt == XTENSA_UNDEFINED) {
     66         unsigned i;
     67 
     68         for (i = 0; i < len; ++i) {
     69             info->fprintf_func(info->stream, "%s 0x%02x",
     70                                i ? ", " : ".byte ", buffer[i]);
     71         }
     72         goto out;
     73     }
     74     slots = xtensa_format_num_slots(isa, fmt);
     75 
     76     if (slots > 1) {
     77         info->fprintf_func(info->stream, "{ ");
     78     }
     79 
     80     for (slot = 0; slot < slots; ++slot) {
     81         xtensa_opcode opc;
     82         int opnd, vopnd, opnds;
     83 
     84         if (slot) {
     85             info->fprintf_func(info->stream, "; ");
     86         }
     87         xtensa_format_get_slot(isa, fmt, slot, insnbuf, slotbuf);
     88         opc = xtensa_opcode_decode(isa, fmt, slot, slotbuf);
     89         if (opc == XTENSA_UNDEFINED) {
     90             info->fprintf_func(info->stream, "???");
     91             continue;
     92         }
     93         opnds = xtensa_opcode_num_operands(isa, opc);
     94 
     95         info->fprintf_func(info->stream, "%s", xtensa_opcode_name(isa, opc));
     96 
     97         for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
     98             if (xtensa_operand_is_visible(isa, opc, opnd)) {
     99                 uint32_t v = 0xbadc0de;
    100                 int rc;
    101 
    102                 info->fprintf_func(info->stream, vopnd ? ", " : "\t");
    103                 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
    104                                          slotbuf, &v);
    105                 rc = xtensa_operand_decode(isa, opc, opnd, &v);
    106                 if (rc == XTENSA_UNDEFINED) {
    107                     info->fprintf_func(info->stream, "???");
    108                 } else if (xtensa_operand_is_register(isa, opc, opnd)) {
    109                     xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
    110 
    111                     info->fprintf_func(info->stream, "%s%d",
    112                                        xtensa_regfile_shortname(isa, rf), v);
    113                 } else if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
    114                     xtensa_operand_undo_reloc(isa, opc, opnd, &v, memaddr);
    115                     info->fprintf_func(info->stream, "0x%x", v);
    116                 } else {
    117                     info->fprintf_func(info->stream, "%d", v);
    118                 }
    119                 ++vopnd;
    120             }
    121         }
    122     }
    123     if (slots > 1) {
    124         info->fprintf_func(info->stream, " }");
    125     }
    126 
    127 out:
    128     g_free(buffer);
    129     xtensa_insnbuf_free(isa, insnbuf);
    130     xtensa_insnbuf_free(isa, slotbuf);
    131 
    132     return len;
    133 }