1a00cfed0STaylor Simpson /*
2a00cfed0STaylor Simpson * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
3a00cfed0STaylor Simpson *
4a00cfed0STaylor Simpson * This program is free software; you can redistribute it and/or modify
5a00cfed0STaylor Simpson * it under the terms of the GNU General Public License as published by
6a00cfed0STaylor Simpson * the Free Software Foundation; either version 2 of the License, or
7a00cfed0STaylor Simpson * (at your option) any later version.
8a00cfed0STaylor Simpson *
9a00cfed0STaylor Simpson * This program is distributed in the hope that it will be useful,
10a00cfed0STaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a00cfed0STaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12a00cfed0STaylor Simpson * GNU General Public License for more details.
13a00cfed0STaylor Simpson *
14a00cfed0STaylor Simpson * You should have received a copy of the GNU General Public License
15a00cfed0STaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>.
16a00cfed0STaylor Simpson */
17a00cfed0STaylor Simpson
18a00cfed0STaylor Simpson /*
19a00cfed0STaylor Simpson * QEMU Hexagon Disassembler
20a00cfed0STaylor Simpson */
21a00cfed0STaylor Simpson
22a00cfed0STaylor Simpson #include "qemu/osdep.h"
23a00cfed0STaylor Simpson #include "disas/dis-asm.h"
24a00cfed0STaylor Simpson #include "target/hexagon/cpu_bits.h"
25a00cfed0STaylor Simpson
26a00cfed0STaylor Simpson /*
27a00cfed0STaylor Simpson * We will disassemble a packet with up to 4 instructions, so we need
28a00cfed0STaylor Simpson * a hefty size buffer.
29a00cfed0STaylor Simpson */
30a00cfed0STaylor Simpson #define PACKET_BUFFER_LEN 1028
31a00cfed0STaylor Simpson
print_insn_hexagon(bfd_vma memaddr,struct disassemble_info * info)32a00cfed0STaylor Simpson int print_insn_hexagon(bfd_vma memaddr, struct disassemble_info *info)
33a00cfed0STaylor Simpson {
34a00cfed0STaylor Simpson uint32_t words[PACKET_WORDS_MAX];
35a00cfed0STaylor Simpson bool found_end = false;
36*a7686d5dSTaylor Simpson GString *buf;
37a00cfed0STaylor Simpson int i, len;
38a00cfed0STaylor Simpson
39a00cfed0STaylor Simpson for (i = 0; i < PACKET_WORDS_MAX && !found_end; i++) {
40a00cfed0STaylor Simpson int status = (*info->read_memory_func)(memaddr + i * sizeof(uint32_t),
41a00cfed0STaylor Simpson (bfd_byte *)&words[i],
42a00cfed0STaylor Simpson sizeof(uint32_t), info);
43a00cfed0STaylor Simpson if (status) {
44a00cfed0STaylor Simpson if (i > 0) {
45a00cfed0STaylor Simpson break;
46a00cfed0STaylor Simpson }
47a00cfed0STaylor Simpson (*info->memory_error_func)(status, memaddr, info);
48a00cfed0STaylor Simpson return status;
49a00cfed0STaylor Simpson }
50a00cfed0STaylor Simpson if (is_packet_end(words[i])) {
51a00cfed0STaylor Simpson found_end = true;
52a00cfed0STaylor Simpson }
53a00cfed0STaylor Simpson }
54a00cfed0STaylor Simpson
55a00cfed0STaylor Simpson if (!found_end) {
56a00cfed0STaylor Simpson (*info->fprintf_func)(info->stream, "<invalid>");
57a00cfed0STaylor Simpson return PACKET_WORDS_MAX * sizeof(uint32_t);
58a00cfed0STaylor Simpson }
59a00cfed0STaylor Simpson
60*a7686d5dSTaylor Simpson buf = g_string_sized_new(PACKET_BUFFER_LEN);
61a00cfed0STaylor Simpson len = disassemble_hexagon(words, i, memaddr, buf);
62a00cfed0STaylor Simpson (*info->fprintf_func)(info->stream, "%s", buf->str);
63a00cfed0STaylor Simpson g_string_free(buf, true);
64a00cfed0STaylor Simpson
65a00cfed0STaylor Simpson return len;
66a00cfed0STaylor Simpson }
67