d930c80dcc6f7ee08efa39d39ce8d7764d3ed853
1 /* Print TI TMS320C80 (MVP) instructions
2 Copyright 1996 Free Software Foundation, Inc.
4 This file is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "opcode/tic80.h"
25 print_insn_tic80 (memaddr
, info
)
27 struct disassemble_info
*info
;
31 unsigned long insn
[2];
32 const struct tic80_opcode
*opcode
;
33 const struct tic80_opcode
*opcode_end
;
34 const unsigned char *opindex
;
35 const struct tic80_operand
*operand
;
40 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
43 (*info
->memory_error_func
) (status
, memaddr
, info
);
47 if (info
-> endian
== BFD_ENDIAN_LITTLE
)
49 insn
[0] = bfd_getl32 (buffer
);
51 else if (info
-> endian
== BFD_ENDIAN_BIG
)
53 insn
[0] = bfd_getb32 (buffer
);
57 /* FIXME: Should probably just default to one or the other */
61 /* Find the first opcode match in the opcodes table. FIXME: there should
62 be faster ways to find one (hash table or binary search), but don't
63 worry too much about it until other TIc80 support is finished. */
65 opcode_end
= tic80_opcodes
+ tic80_num_opcodes
;
66 for (opcode
= tic80_opcodes
; opcode
< opcode_end
; opcode
++)
68 if ((insn
[0] & opcode
-> mask
) == opcode
-> opcode
)
74 if (opcode
== opcode_end
)
76 /* No match found, just print the bits as a .word directive */
77 (*info
-> fprintf_func
) (info
-> stream
, ".word %#08lx", insn
[0]);
81 /* Match found, decode the instruction. */
82 (*info
-> fprintf_func
) (info
-> stream
, "%s", opcode
-> name
);
84 /* Now extract and print the operands. */
87 if (opcode
-> operands
[0] != 0)
89 (*info
-> fprintf_func
) (info
-> stream
, "\t");
91 for (opindex
= opcode
-> operands
; *opindex
!= 0; opindex
++)
95 operand
= tic80_operands
+ *opindex
;
97 /* Extract the value from the instruction. */
98 if (operand
-> extract
)
100 value
= (*operand
-> extract
) (insn
[0], (int *) NULL
);
102 else if (operand
-> bits
== 32)
104 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 4, info
);
107 (*info
->memory_error_func
) (status
, memaddr
, info
);
111 if (info
-> endian
== BFD_ENDIAN_LITTLE
)
113 insn
[1] = bfd_getl32 (buffer
);
115 else if (info
-> endian
== BFD_ENDIAN_BIG
)
117 insn
[1] = bfd_getb32 (buffer
);
119 value
= (long) insn
[1];
124 value
= (insn
[0] >> operand
-> shift
) & ((1 << operand
-> bits
) - 1);
125 if ((operand
-> flags
& TIC80_OPERAND_SIGNED
) != 0
126 && (value
& (1 << (operand
-> bits
- 1))) != 0)
127 value
-= 1 << operand
-> bits
;
132 (*info
-> fprintf_func
) (info
-> stream
, ",");
136 /* Print the operand as directed by the flags. */
137 if ((operand
-> flags
& TIC80_OPERAND_GPR
) != 0)
139 (*info
-> fprintf_func
) (info
-> stream
, "r%ld", value
);
141 else if ((operand
-> flags
& TIC80_OPERAND_FPA
) != 0)
143 (*info
-> fprintf_func
) (info
-> stream
, "a%ld", value
);
145 else if ((operand
-> flags
& TIC80_OPERAND_RELATIVE
) != 0)
147 (*info
-> print_address_func
) (memaddr
+ value
, info
);
149 else if ((operand
-> flags
& TIC80_OPERAND_CC_SZ
) != 0)
152 if (operand
-> bits
== 3)
153 (*info
-> fprintf_func
) (info
-> stream
, "cr%d", value
);
156 static const char *cbnames
[4] = { "lt", "gt", "eq", "so" };
162 (*info
-> fprintf_func
) (info
-> stream
, "4*cr%d", cr
);
167 (*info
-> fprintf_func
) (info
-> stream
, "+");
168 (*info
-> fprintf_func
) (info
-> stream
, "%s", cbnames
[cc
]);
175 if ((value
> 999 || value
< -999)
176 || operand
-> flags
& TIC80_OPERAND_BITFIELD
)
178 (*info
-> fprintf_func
) (info
-> stream
, "%#lx", value
);
182 (*info
-> fprintf_func
) (info
-> stream
, "%ld", value
);
188 (*info
-> fprintf_func
) (info
-> stream
, ")");
192 if ((operand
-> flags
& TIC80_OPERAND_PARENS
) == 0)
198 (*info
-> fprintf_func
) (info
-> stream
, "(");