1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "qemu/osdep.h"
29#include "disas/dis-asm.h"
30#include "hw/xtensa/xtensa-isa.h"
31
32int 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
127out:
128 g_free(buffer);
129 xtensa_insnbuf_free(isa, insnbuf);
130 xtensa_insnbuf_free(isa, slotbuf);
131
132 return len;
133}
134