1 /* tilepro-dis.c. Disassembly routines for the TILEPro architecture.
2 Copyright (C) 2011-2024 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include "elf/tilepro.h"
27 #include "disassemble.h"
28 #include "opcode/tilepro.h"
34 contains_insn (tilepro_mnemonic expected_mnemonic
,
35 int expected_first_operand
,
36 int expected_second_operand
,
38 int *last_operand_ret
,
39 disassemble_info
*info
)
41 struct tilepro_decoded_instruction
42 decoded
[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE
];
43 bfd_byte opbuf
[TILEPRO_BUNDLE_SIZE_IN_BYTES
];
44 int i
, num_instructions
;
46 if ((*info
->read_memory_func
) (memaddr
, opbuf
,
47 TILEPRO_BUNDLE_SIZE_IN_BYTES
, info
) != 0)
48 /* If we cannot even read the memory, it obviously does not have the
49 instruction for which we are looking. */
52 /* Parse the instructions in the bundle. */
53 num_instructions
= parse_insn_tilepro (bfd_getl64 (opbuf
), memaddr
, decoded
);
55 for (i
= 0; i
< num_instructions
; i
++)
57 const struct tilepro_opcode
*opcode
= decoded
[i
].opcode
;
59 if (opcode
->mnemonic
!= expected_mnemonic
)
62 if (expected_first_operand
!= -1
63 && decoded
[i
].operand_values
[0] != expected_first_operand
)
66 if (expected_second_operand
!= -1
67 && decoded
[i
].operand_values
[1] != expected_second_operand
)
70 *last_operand_ret
= decoded
[i
].operand_values
[opcode
->num_operands
- 1];
80 print_insn_tilepro (bfd_vma memaddr
, disassemble_info
*info
)
82 struct tilepro_decoded_instruction
83 decoded
[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE
];
84 bfd_byte opbuf
[TILEPRO_BUNDLE_SIZE_IN_BYTES
];
85 int status
, i
, num_instructions
, num_printed
;
86 tilepro_mnemonic padding_mnemonic
;
88 status
= (*info
->read_memory_func
) (memaddr
, opbuf
,
89 TILEPRO_BUNDLE_SIZE_IN_BYTES
, info
);
92 (*info
->memory_error_func
) (status
, memaddr
, info
);
96 info
->bytes_per_line
= TILEPRO_BUNDLE_SIZE_IN_BYTES
;
97 info
->bytes_per_chunk
= TILEPRO_BUNDLE_SIZE_IN_BYTES
;
98 info
->octets_per_byte
= 1;
99 info
->display_endian
= BFD_ENDIAN_LITTLE
;
101 /* Parse the instructions in the bundle. */
102 num_instructions
= parse_insn_tilepro (bfd_getl64 (opbuf
), memaddr
, decoded
);
104 /* Print the instructions in the bundle. */
105 info
->fprintf_func (info
->stream
, "{ ");
108 /* Determine which nop opcode is used for padding and should be skipped. */
109 padding_mnemonic
= TILEPRO_OPC_FNOP
;
110 for (i
= 0; i
< num_instructions
; i
++)
112 if (!decoded
[i
].opcode
->can_bundle
)
114 /* Instructions that cannot be bundled are padded out with nops,
115 rather than fnops. Displaying them is always clutter. */
116 padding_mnemonic
= TILEPRO_OPC_NOP
;
121 for (i
= 0; i
< num_instructions
; i
++)
123 const struct tilepro_opcode
*opcode
= decoded
[i
].opcode
;
127 /* Do not print out fnops, unless everything is an fnop, in
128 which case we will print out just the last one. */
129 if (opcode
->mnemonic
== padding_mnemonic
130 && (num_printed
> 0 || i
+ 1 < num_instructions
))
134 info
->fprintf_func (info
->stream
, " ; ");
140 info
->fprintf_func (info
->stream
, "%s", name
);
142 for (j
= 0; j
< opcode
->num_operands
; j
++)
145 const struct tilepro_operand
*op
;
146 const char *spr_name
;
149 info
->fprintf_func (info
->stream
, ",");
150 info
->fprintf_func (info
->stream
, " ");
152 num
= decoded
[i
].operand_values
[j
];
154 op
= decoded
[i
].operands
[j
];
157 case TILEPRO_OP_TYPE_REGISTER
:
158 info
->fprintf_func (info
->stream
, "%s",
159 tilepro_register_names
[num
]);
162 case TILEPRO_OP_TYPE_SPR
:
163 spr_name
= get_tilepro_spr_name(num
);
164 if (spr_name
!= NULL
)
165 info
->fprintf_func (info
->stream
, "%s", spr_name
);
167 info
->fprintf_func (info
->stream
, "%d", num
);
170 case TILEPRO_OP_TYPE_IMMEDIATE
:
176 switch (opcode
->mnemonic
)
178 case TILEPRO_OPC_ADDLI
:
179 if (contains_insn (TILEPRO_OPC_AULI
,
180 decoded
[i
].operand_values
[1],
182 memaddr
- TILEPRO_BUNDLE_SIZE_IN_BYTES
,
186 addr
= num
+ (addr_piece
<< 16);
191 case TILEPRO_OPC_AULI
:
192 if (contains_insn (TILEPRO_OPC_MOVELI
,
193 decoded
[i
].operand_values
[1],
195 memaddr
- TILEPRO_BUNDLE_SIZE_IN_BYTES
,
199 addr
= (num
<< 16) + addr_piece
;
205 /* Operand does not look like a constructed address. */
209 info
->fprintf_func (info
->stream
, "%d", num
);
213 info
->fprintf_func (info
->stream
, " /* ");
214 info
->print_address_func (addr
, info
);
215 info
->fprintf_func (info
->stream
, " */");
220 case TILEPRO_OP_TYPE_ADDRESS
:
221 info
->print_address_func ((bfd_vma
)(unsigned int) num
, info
);
229 info
->fprintf_func (info
->stream
, " }");
231 return TILEPRO_BUNDLE_SIZE_IN_BYTES
;