Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / disas / xtensa.c
blobd7dda8c2d6a61333eed4b6a4e20fc2098f60225f
1 /*
2 * Copyright (c) 2017, Max Filippov, Open Source and Linux Lab.
3 * All rights reserved.
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.
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.
28 #include "qemu/osdep.h"
29 #include "disas/dis-asm.h"
30 #include "hw/xtensa/xtensa-isa.h"
32 int print_insn_xtensa(bfd_vma memaddr, struct disassemble_info *info)
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;
43 if (status) {
44 info->memory_error_func(status, memaddr, info);
45 len = -1;
46 goto out;
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;
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;
63 xtensa_insnbuf_from_chars(isa, insnbuf, buffer, len);
64 fmt = xtensa_format_decode(isa, insnbuf);
65 if (fmt == XTENSA_UNDEFINED) {
66 unsigned i;
68 for (i = 0; i < len; ++i) {
69 info->fprintf_func(info->stream, "%s 0x%02x",
70 i ? ", " : ".byte ", buffer[i]);
72 goto out;
74 slots = xtensa_format_num_slots(isa, fmt);
76 if (slots > 1) {
77 info->fprintf_func(info->stream, "{ ");
80 for (slot = 0; slot < slots; ++slot) {
81 xtensa_opcode opc;
82 int opnd, vopnd, opnds;
84 if (slot) {
85 info->fprintf_func(info->stream, "; ");
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;
93 opnds = xtensa_opcode_num_operands(isa, opc);
95 info->fprintf_func(info->stream, "%s", xtensa_opcode_name(isa, opc));
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;
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);
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);
119 ++vopnd;
123 if (slots > 1) {
124 info->fprintf_func(info->stream, " }");
127 out:
128 g_free(buffer);
129 xtensa_insnbuf_free(isa, insnbuf);
130 xtensa_insnbuf_free(isa, slotbuf);
132 return len;