1 /* tilegx-dis.c. Disassembly routines for the TILE-Gx architecture.
2 Copyright 2011 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. */
24 #include "elf/tilegx.h"
28 #include "opcode/tilegx.h"
32 print_insn_tilegx (bfd_vma memaddr
, disassemble_info
*info
)
34 struct tilegx_decoded_instruction
35 decoded
[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
];
36 bfd_byte opbuf
[TILEGX_BUNDLE_SIZE_IN_BYTES
];
37 int status
, i
, num_instructions
, num_printed
;
38 tilegx_mnemonic padding_mnemonic
;
40 status
= (*info
->read_memory_func
) (memaddr
, opbuf
,
41 TILEGX_BUNDLE_SIZE_IN_BYTES
, info
);
44 (*info
->memory_error_func
) (status
, memaddr
, info
);
48 info
->bytes_per_line
= TILEGX_BUNDLE_SIZE_IN_BYTES
;
49 info
->bytes_per_chunk
= TILEGX_BUNDLE_SIZE_IN_BYTES
;
50 info
->octets_per_byte
= 1;
51 info
->display_endian
= BFD_ENDIAN_LITTLE
;
53 /* Parse the instructions in the bundle. */
55 parse_insn_tilegx (bfd_getl64 (opbuf
), memaddr
, decoded
);
57 /* Print the instructions in the bundle. */
58 info
->fprintf_func (info
->stream
, "{ ");
61 /* Determine which nop opcode is used for padding and should be skipped. */
62 padding_mnemonic
= TILEGX_OPC_FNOP
;
63 for (i
= 0; i
< num_instructions
; i
++)
65 if (!decoded
[i
].opcode
->can_bundle
)
67 /* Instructions that cannot be bundled are padded out with nops,
68 rather than fnops. Displaying them is always clutter. */
69 padding_mnemonic
= TILEGX_OPC_NOP
;
74 for (i
= 0; i
< num_instructions
; i
++)
76 const struct tilegx_opcode
*opcode
= decoded
[i
].opcode
;
80 /* Do not print out fnops, unless everything is an fnop, in
81 which case we will print out just the last one. */
82 if (opcode
->mnemonic
== padding_mnemonic
83 && (num_printed
> 0 || i
+ 1 < num_instructions
))
87 info
->fprintf_func (info
->stream
, " ; ");
93 info
->fprintf_func (info
->stream
, "%s", name
);
95 for (j
= 0; j
< opcode
->num_operands
; j
++)
98 const struct tilegx_operand
*op
;
102 info
->fprintf_func (info
->stream
, ",");
103 info
->fprintf_func (info
->stream
, " ");
105 num
= decoded
[i
].operand_values
[j
];
107 op
= decoded
[i
].operands
[j
];
110 case TILEGX_OP_TYPE_REGISTER
:
111 info
->fprintf_func (info
->stream
, "%s",
112 tilegx_register_names
[(int) num
]);
114 case TILEGX_OP_TYPE_SPR
:
115 spr_name
= get_tilegx_spr_name (num
);
116 if (spr_name
!= NULL
)
117 info
->fprintf_func (info
->stream
, "%s", spr_name
);
119 info
->fprintf_func (info
->stream
, "%d", (int)num
);
121 case TILEGX_OP_TYPE_IMMEDIATE
:
122 info
->fprintf_func (info
->stream
, "%d", (int)num
);
124 case TILEGX_OP_TYPE_ADDRESS
:
125 info
->print_address_func (num
, info
);
132 info
->fprintf_func (info
->stream
, " }");
134 return TILEGX_BUNDLE_SIZE_IN_BYTES
;