2 * Copyright (c) 2017, Max Filippov, Open Source and Linux Lab.
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/bfd.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
);
44 info
->memory_error_func(status
, memaddr
, info
);
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]);
54 buffer
= g_realloc(buffer
, len
);
55 status
= info
->read_memory_func(memaddr
+ 1, buffer
+ 1, len
- 1, info
);
57 info
->fprintf_func(info
->stream
, ".byte 0x%02x", buffer
[0]);
58 info
->memory_error_func(status
, memaddr
+ 1, info
);
63 xtensa_insnbuf_from_chars(isa
, insnbuf
, buffer
, len
);
64 fmt
= xtensa_format_decode(isa
, insnbuf
);
65 if (fmt
== XTENSA_UNDEFINED
) {
68 for (i
= 0; i
< len
; ++i
) {
69 info
->fprintf_func(info
->stream
, "%s 0x%02x",
70 i
? ", " : ".byte ", buffer
[i
]);
74 slots
= xtensa_format_num_slots(isa
, fmt
);
77 info
->fprintf_func(info
->stream
, "{ ");
80 for (slot
= 0; slot
< slots
; ++slot
) {
82 unsigned opnd
, vopnd
, opnds
;
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
, "???");
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;
102 info
->fprintf_func(info
->stream
, vopnd
? ", " : "\t");
103 xtensa_operand_get_field(isa
, opc
, opnd
, fmt
, slot
,
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
);
117 info
->fprintf_func(info
->stream
, "%d", v
);
124 info
->fprintf_func(info
->stream
, " }");
129 xtensa_insnbuf_free(isa
, insnbuf
);
130 xtensa_insnbuf_free(isa
, slotbuf
);