1 /* TI C6X disassembler.
3 Free Software Foundation, Inc.
5 This file is part of libopcodes.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
24 #include "opcode/tic6x.h"
25 #include "libiberty.h"
27 /* Define the instruction format table. */
28 const tic6x_insn_format tic6x_insn_format_table
[tic6x_insn_format_max
] =
30 #define FMT(name, num_bits, cst_bits, mask, fields) \
31 { num_bits, cst_bits, mask, fields },
32 #include "opcode/tic6x-insn-formats.h"
36 /* Define the control register table. */
37 const tic6x_ctrl tic6x_ctrl_table
[tic6x_ctrl_max
] =
39 #define CTRL(name, isa, rw, crlo, crhi_mask) \
42 CONCAT2(TIC6X_INSN_,isa), \
43 CONCAT2(tic6x_rw_,rw), \
47 #include "opcode/tic6x-control-registers.h"
51 /* Define the opcode table. */
52 const tic6x_opcode tic6x_opcode_table
[tic6x_opcode_max
] =
54 #define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
57 CONCAT2(tic6x_func_unit_,func_unit), \
58 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
59 CONCAT2(tic6x_pipeline_,type), \
60 CONCAT2(TIC6X_INSN_,isa), \
66 #define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
69 CONCAT2(tic6x_func_unit_,func_unit), \
70 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
71 CONCAT2(tic6x_pipeline_,type), \
72 CONCAT2(TIC6X_INSN_,isa), \
78 #include "opcode/tic6x-opcode-table.h"
83 /* If instruction format FMT has a field FIELD, return a pointer to
84 the description of that field; otherwise return NULL. */
86 const tic6x_insn_field
*
87 tic6x_field_from_fmt (const tic6x_insn_format
*fmt
, tic6x_insn_field_id field
)
91 for (f
= 0; f
< fmt
->num_fields
; f
++)
92 if (fmt
->fields
[f
].field_id
== field
)
93 return &fmt
->fields
[f
];
98 /* Extract the bits corresponding to FIELD from OPCODE. */
101 tic6x_field_bits (unsigned int opcode
, const tic6x_insn_field
*field
)
103 return (opcode
>> field
->low_pos
) & ((1u << field
->width
) - 1);
106 /* Extract a 32-bit value read from the instruction stream. */
109 tic6x_extract_32 (unsigned char *p
, struct disassemble_info
*info
)
111 if (info
->endian
== BFD_ENDIAN_LITTLE
)
112 return (p
[0]) | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
114 return (p
[3]) | (p
[2] << 8) | (p
[1] << 16) | (p
[0] << 24);
117 /* Extract a 16-bit value read from the instruction stream. */
120 tic6x_extract_16 (unsigned char *p
, struct disassemble_info
*info
)
122 if (info
->endian
== BFD_ENDIAN_LITTLE
)
123 return (p
[0]) | (p
[1] << 8);
125 return (p
[1]) | (p
[0] << 8);
128 /* FP points to a fetch packet. Return whether it is header-based; if
129 it is, fill in HEADER. */
132 tic6x_check_fetch_packet_header (unsigned char *fp
,
133 tic6x_fetch_packet_header
*header
,
134 struct disassemble_info
*info
)
138 header
->header
= tic6x_extract_32 (fp
+ 28, info
);
139 if ((header
->header
& 0xf0000000) != 0xe0000000)
142 for (i
= 0; i
< 7; i
++)
143 header
->word_compact
[i
]
144 = (header
->header
& (1u << (21 + i
))) ? TRUE
: FALSE
;
146 header
->prot
= (header
->header
& (1u << 20)) ? TRUE
: FALSE
;
147 header
->rs
= (header
->header
& (1u << 19)) ? TRUE
: FALSE
;
148 header
->dsz
= (header
->header
>> 16) & 0x7;
149 header
->br
= (header
->header
& (1u << 15)) ? TRUE
: FALSE
;
150 header
->sat
= (header
->header
& (1u << 14)) ? TRUE
: FALSE
;
152 for (i
= 0; i
< 14; i
++)
154 = (header
->header
& (1u << i
)) ? TRUE
: FALSE
;
159 /* Disassemble the instruction at ADDR and print it using
160 INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes
164 print_insn_tic6x (bfd_vma addr
, struct disassemble_info
*info
)
169 unsigned char fp
[32];
171 tic6x_opcode_id opcode_id
;
172 bfd_boolean fetch_packet_header_based
;
173 tic6x_fetch_packet_header header
;
174 unsigned int num_bits
;
175 bfd_boolean bad_offset
= FALSE
;
177 fp_offset
= addr
& 0x1f;
178 fp_addr
= addr
- fp_offset
;
179 status
= info
->read_memory_func (fp_addr
, fp
, 32, info
);
182 info
->memory_error_func (status
, addr
, info
);
186 fetch_packet_header_based
187 = tic6x_check_fetch_packet_header (fp
, &header
, info
);
188 if (fetch_packet_header_based
)
192 if ((fp_offset
& 0x3) && (fp_offset
>= 28
193 || !header
.word_compact
[fp_offset
>> 2]))
197 info
->bytes_per_chunk
= 4;
198 info
->fprintf_func (info
->stream
, "<fetch packet header 0x%.8x>",
202 num_bits
= (header
.word_compact
[fp_offset
>> 2] ? 16 : 32);
213 info
->bytes_per_chunk
= 1;
214 info
->fprintf_func (info
->stream
, ".byte 0x%.2x", fp
[fp_offset
]);
220 /* The least-significant part of a 32-bit word comes logically
221 before the most-significant part. For big-endian, follow the
222 TI assembler in showing instructions in logical order by
223 pretending that the two halves of the word are in opposite
224 locations to where they actually are. */
225 if (info
->endian
== BFD_ENDIAN_LITTLE
)
226 opcode
= tic6x_extract_16 (fp
+ fp_offset
, info
);
228 opcode
= tic6x_extract_16 (fp
+ (fp_offset
^ 2), info
);
231 opcode
= tic6x_extract_32 (fp
+ fp_offset
, info
);
233 for (opcode_id
= 0; opcode_id
< tic6x_opcode_max
; opcode_id
++)
235 const tic6x_opcode
*const opc
= &tic6x_opcode_table
[opcode_id
];
236 const tic6x_insn_format
*const fmt
237 = &tic6x_insn_format_table
[opc
->format
];
238 const tic6x_insn_field
*creg_field
;
240 const char *parallel
;
241 const char *cond
= "";
242 const char *func_unit
;
243 char func_unit_buf
[7];
244 unsigned int func_unit_side
= 0;
245 unsigned int func_unit_data_side
= 0;
246 unsigned int func_unit_cross
= 0;
247 /* The maximum length of the text of a non-PC-relative operand
248 is 24 bytes (SPMASK masking all eight functional units, with
249 separating commas and trailing NUL). */
250 char operands
[TIC6X_MAX_OPERANDS
][24] = { { 0 } };
251 bfd_vma operands_addresses
[TIC6X_MAX_OPERANDS
] = { 0 };
252 bfd_boolean operands_text
[TIC6X_MAX_OPERANDS
] = { FALSE
};
253 bfd_boolean operands_pcrel
[TIC6X_MAX_OPERANDS
] = { FALSE
};
255 unsigned int num_operands
;
257 bfd_boolean fixed_ok
;
258 bfd_boolean operands_ok
;
260 if (opc
->flags
& TIC6X_FLAG_MACRO
)
262 if (fmt
->num_bits
!= num_bits
)
264 if ((opcode
& fmt
->mask
) != fmt
->cst_bits
)
267 /* If the format has a creg field, it is only a candidate for a
268 match if the creg and z fields have values indicating a valid
269 condition; reserved values indicate either an instruction
270 format without a creg field, or an invalid instruction. */
271 creg_field
= tic6x_field_from_fmt (fmt
, tic6x_field_creg
);
274 const tic6x_insn_field
*z_field
;
275 unsigned int creg_value
, z_value
;
276 static const char *const conds
[8][2] =
279 { "[b0] ", "[!b0] " },
280 { "[b1] ", "[!b1] " },
281 { "[b2] ", "[!b2] " },
282 { "[a1] ", "[!a1] " },
283 { "[a2] ", "[!a2] " },
284 { "[a0] ", "[!a0] " },
288 /* A creg field is not meaningful without a z field, so if
289 the z field is not present this is an error in the format
291 z_field
= tic6x_field_from_fmt (fmt
, tic6x_field_z
);
295 creg_value
= tic6x_field_bits (opcode
, creg_field
);
296 z_value
= tic6x_field_bits (opcode
, z_field
);
297 cond
= conds
[creg_value
][z_value
];
302 /* All fixed fields must have matching values; all fields with
303 restricted ranges must have values within those ranges. */
305 for (fix
= 0; fix
< opc
->num_fixed_fields
; fix
++)
307 unsigned int field_bits
;
308 const tic6x_insn_field
*const field
309 = tic6x_field_from_fmt (fmt
, opc
->fixed_fields
[fix
].field_id
);
313 field_bits
= tic6x_field_bits (opcode
, field
);
314 if (field_bits
< opc
->fixed_fields
[fix
].min_val
315 || field_bits
> opc
->fixed_fields
[fix
].max_val
)
324 /* The instruction matches. */
326 /* The p-bit indicates whether this instruction is in parallel
327 with the *next* instruction, whereas the parallel bars
328 indicate the instruction is in parallel with the *previous*
329 instruction. Thus, we must find the p-bit for the previous
331 if (num_bits
== 16 && (fp_offset
& 0x2) == 2)
333 /* This is the logically second (most significant; second in
334 fp_offset terms because fp_offset relates to logical not
335 physical addresses) instruction of a compact pair; find
336 the p-bit for the first (least significant). */
337 p_bit
= header
.p_bits
[(fp_offset
>> 2) << 1];
339 else if (fp_offset
>= 4)
341 /* Find the last instruction of the previous word in this
342 fetch packet. For compact instructions, this is the most
343 significant 16 bits. */
344 if (fetch_packet_header_based
345 && header
.word_compact
[(fp_offset
>> 2) - 1])
346 p_bit
= header
.p_bits
[(fp_offset
>> 1) - 1];
349 unsigned int prev_opcode
350 = tic6x_extract_32 (fp
+ (fp_offset
& 0x1c) - 4, info
);
351 p_bit
= (prev_opcode
& 0x1) ? TRUE
: FALSE
;
356 /* Find the last instruction of the previous fetch
358 unsigned char fp_prev
[32];
359 status
= info
->read_memory_func (fp_addr
- 32, fp_prev
, 32, info
);
361 /* No previous instruction to be parallel with. */
365 bfd_boolean prev_header_based
;
366 tic6x_fetch_packet_header prev_header
;
369 = tic6x_check_fetch_packet_header (fp_prev
, &prev_header
, info
);
370 if (prev_header_based
&& prev_header
.word_compact
[6])
371 p_bit
= prev_header
.p_bits
[13];
374 unsigned int prev_opcode
= tic6x_extract_32 (fp_prev
+ 28,
376 p_bit
= (prev_opcode
& 0x1) ? TRUE
: FALSE
;
380 parallel
= p_bit
? "|| " : "";
382 if (opc
->func_unit
== tic6x_func_unit_nfu
)
386 unsigned int fld_num
;
388 const char *data_str
;
389 bfd_boolean have_areg
= FALSE
;
390 bfd_boolean have_cross
= FALSE
;
392 func_unit_side
= (opc
->flags
& TIC6X_FLAG_SIDE_B_ONLY
) ? 2 : 0;
394 func_unit_data_side
= (opc
->flags
& TIC6X_FLAG_SIDE_T2_ONLY
) ? 2 : 0;
396 for (fld_num
= 0; fld_num
< opc
->num_variable_fields
; fld_num
++)
398 const tic6x_coding_field
*const enc
= &opc
->variable_fields
[fld_num
];
399 const tic6x_insn_field
*field
;
400 unsigned int fld_val
;
402 field
= tic6x_field_from_fmt (fmt
, enc
->field_id
);
405 fld_val
= tic6x_field_bits (opcode
, field
);
406 switch (enc
->coding_method
)
408 case tic6x_coding_fu
:
409 /* The side must be specified exactly once. */
412 func_unit_side
= (fld_val
? 2 : 1);
415 case tic6x_coding_data_fu
:
416 /* The data side must be specified exactly once. */
417 if (func_unit_data_side
)
419 func_unit_data_side
= (fld_val
? 2 : 1);
422 case tic6x_coding_xpath
:
423 /* Cross path use must be specified exactly
428 func_unit_cross
= fld_val
;
431 case tic6x_coding_areg
:
436 /* Don't relate to functional units. */
441 /* The side of the functional unit used must now have been
442 determined either from the flags or from an instruction
444 if (func_unit_side
!= 1 && func_unit_side
!= 2)
447 /* Cross paths are not applicable when sides are specified
448 for both address and data paths. */
449 if (func_unit_data_side
&& have_cross
)
452 /* Separate address and data paths are only applicable for
454 if (func_unit_data_side
&& opc
->func_unit
!= tic6x_func_unit_d
)
457 /* If an address register is being used but in ADDA rather
458 than a load or store, it uses a cross path for side-A
459 instructions, and the cross path use is not specified by
460 an instruction field. */
461 if (have_areg
&& !func_unit_data_side
)
465 func_unit_cross
= (func_unit_side
== 1 ? TRUE
: FALSE
);
468 switch (opc
->func_unit
)
470 case tic6x_func_unit_d
:
471 func_unit_char
= 'D';
474 case tic6x_func_unit_l
:
475 func_unit_char
= 'L';
478 case tic6x_func_unit_m
:
479 func_unit_char
= 'M';
482 case tic6x_func_unit_s
:
483 func_unit_char
= 'S';
490 switch (func_unit_data_side
)
508 snprintf (func_unit_buf
, 7, " .%c%u%s%s", func_unit_char
,
509 func_unit_side
, (func_unit_cross
? "X" : ""), data_str
);
510 func_unit
= func_unit_buf
;
513 /* For each operand there must be one or more fields set based
514 on that operand, that can together be used to derive the
517 num_operands
= opc
->num_operands
;
518 for (op_num
= 0; op_num
< num_operands
; op_num
++)
520 unsigned int fld_num
;
521 unsigned int mem_base_reg
= 0;
522 bfd_boolean mem_base_reg_known
= FALSE
;
523 bfd_boolean mem_base_reg_known_long
= FALSE
;
524 unsigned int mem_offset
= 0;
525 bfd_boolean mem_offset_known
= FALSE
;
526 bfd_boolean mem_offset_known_long
= FALSE
;
527 unsigned int mem_mode
= 0;
528 bfd_boolean mem_mode_known
= FALSE
;
529 unsigned int mem_scaled
= 0;
530 bfd_boolean mem_scaled_known
= FALSE
;
531 unsigned int crlo
= 0;
532 bfd_boolean crlo_known
= FALSE
;
533 unsigned int crhi
= 0;
534 bfd_boolean crhi_known
= FALSE
;
535 bfd_boolean spmask_skip_operand
= FALSE
;
536 unsigned int fcyc_bits
= 0;
537 bfd_boolean prev_sploop_found
= FALSE
;
539 switch (opc
->operand_info
[op_num
].form
)
541 case tic6x_operand_retreg
:
542 /* Fully determined by the functional unit. */
543 operands_text
[op_num
] = TRUE
;
544 snprintf (operands
[op_num
], 24, "%c3",
545 (func_unit_side
== 2 ? 'b' : 'a'));
548 case tic6x_operand_irp
:
549 operands_text
[op_num
] = TRUE
;
550 snprintf (operands
[op_num
], 24, "irp");
553 case tic6x_operand_nrp
:
554 operands_text
[op_num
] = TRUE
;
555 snprintf (operands
[op_num
], 24, "nrp");
562 for (fld_num
= 0; fld_num
< opc
->num_variable_fields
; fld_num
++)
564 const tic6x_coding_field
*const enc
565 = &opc
->variable_fields
[fld_num
];
566 const tic6x_insn_field
*field
;
567 unsigned int fld_val
;
568 signed int signed_fld_val
;
570 if (enc
->operand_num
!= op_num
)
572 field
= tic6x_field_from_fmt (fmt
, enc
->field_id
);
575 fld_val
= tic6x_field_bits (opcode
, field
);
576 switch (enc
->coding_method
)
578 case tic6x_coding_ucst
:
579 case tic6x_coding_ulcst_dpr_byte
:
580 case tic6x_coding_ulcst_dpr_half
:
581 case tic6x_coding_ulcst_dpr_word
:
582 case tic6x_coding_lcst_low16
:
583 switch (opc
->operand_info
[op_num
].form
)
585 case tic6x_operand_asm_const
:
586 case tic6x_operand_link_const
:
587 operands_text
[op_num
] = TRUE
;
588 snprintf (operands
[op_num
], 24, "%u", fld_val
);
591 case tic6x_operand_mem_long
:
592 mem_offset
= fld_val
;
593 mem_offset_known_long
= TRUE
;
601 case tic6x_coding_lcst_high16
:
602 operands_text
[op_num
] = TRUE
;
603 snprintf (operands
[op_num
], 24, "%u", fld_val
<< 16);
606 case tic6x_coding_scst
:
607 operands_text
[op_num
] = TRUE
;
608 signed_fld_val
= (signed int) fld_val
;
609 signed_fld_val
^= (1 << (field
->width
- 1));
610 signed_fld_val
-= (1 << (field
->width
- 1));
611 snprintf (operands
[op_num
], 24, "%d", signed_fld_val
);
614 case tic6x_coding_ucst_minus_one
:
615 operands_text
[op_num
] = TRUE
;
616 snprintf (operands
[op_num
], 24, "%u", fld_val
+ 1);
619 case tic6x_coding_pcrel
:
620 case tic6x_coding_pcrel_half
:
621 signed_fld_val
= (signed int) fld_val
;
622 signed_fld_val
^= (1 << (field
->width
- 1));
623 signed_fld_val
-= (1 << (field
->width
- 1));
624 if (fetch_packet_header_based
625 && enc
->coding_method
== tic6x_coding_pcrel_half
)
629 operands_pcrel
[op_num
] = TRUE
;
630 operands_addresses
[op_num
] = fp_addr
+ signed_fld_val
;
633 case tic6x_coding_reg_shift
:
636 case tic6x_coding_reg
:
637 switch (opc
->operand_info
[op_num
].form
)
639 case tic6x_operand_reg
:
640 operands_text
[op_num
] = TRUE
;
641 snprintf (operands
[op_num
], 24, "%c%u",
642 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
645 case tic6x_operand_xreg
:
646 operands_text
[op_num
] = TRUE
;
647 snprintf (operands
[op_num
], 24, "%c%u",
648 (((func_unit_side
== 2) ^ func_unit_cross
)
653 case tic6x_operand_dreg
:
654 operands_text
[op_num
] = TRUE
;
655 snprintf (operands
[op_num
], 24, "%c%u",
656 (func_unit_data_side
== 2 ? 'b' : 'a'),
660 case tic6x_operand_regpair
:
661 operands_text
[op_num
] = TRUE
;
664 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
665 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
+ 1,
666 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
669 case tic6x_operand_xregpair
:
670 operands_text
[op_num
] = TRUE
;
673 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
674 (((func_unit_side
== 2) ^ func_unit_cross
)
677 (((func_unit_side
== 2) ^ func_unit_cross
)
682 case tic6x_operand_dregpair
:
683 operands_text
[op_num
] = TRUE
;
686 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
687 (func_unit_data_side
== 2 ? 'b' : 'a'),
689 (func_unit_data_side
== 2 ? 'b' : 'a'),
693 case tic6x_operand_mem_deref
:
694 operands_text
[op_num
] = TRUE
;
695 snprintf (operands
[op_num
], 24, "*%c%u",
696 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
699 case tic6x_operand_mem_short
:
700 case tic6x_operand_mem_ndw
:
701 mem_base_reg
= fld_val
;
702 mem_base_reg_known
= TRUE
;
710 case tic6x_coding_areg
:
711 switch (opc
->operand_info
[op_num
].form
)
713 case tic6x_operand_areg
:
714 operands_text
[op_num
] = TRUE
;
715 snprintf (operands
[op_num
], 24, "b%u",
716 fld_val
? 15u : 14u);
719 case tic6x_operand_mem_long
:
720 mem_base_reg
= fld_val
? 15u : 14u;
721 mem_base_reg_known_long
= TRUE
;
729 case tic6x_coding_mem_offset
:
730 case tic6x_coding_mem_offset_noscale
:
731 mem_offset
= fld_val
;
732 mem_offset_known
= TRUE
;
735 case tic6x_coding_mem_mode
:
737 mem_mode_known
= TRUE
;
740 case tic6x_coding_scaled
:
741 mem_scaled
= fld_val
;
742 mem_scaled_known
= TRUE
;
745 case tic6x_coding_crlo
:
750 case tic6x_coding_crhi
:
755 case tic6x_coding_fstg
:
756 case tic6x_coding_fcyc
:
757 if (!prev_sploop_found
)
759 bfd_vma search_fp_addr
= fp_addr
;
760 bfd_vma search_fp_offset
= fp_offset
;
761 bfd_boolean search_fp_header_based
762 = fetch_packet_header_based
;
763 tic6x_fetch_packet_header search_fp_header
= header
;
764 unsigned char search_fp
[32];
765 unsigned int search_num_bits
;
766 unsigned int search_opcode
;
767 unsigned int sploop_ii
= 0;
770 memcpy (search_fp
, fp
, 32);
772 /* To interpret these bits in an SPKERNEL
773 instruction, we must find the previous
774 SPLOOP-family instruction. It may come up to
775 48 execute packets earlier. */
776 for (i
= 0; i
< 48 * 8; i
++)
778 /* Find the previous instruction. */
779 if (search_fp_offset
& 2)
780 search_fp_offset
-= 2;
781 else if (search_fp_offset
>= 4)
783 if (search_fp_header_based
784 && (search_fp_header
.word_compact
785 [(search_fp_offset
>> 2) - 1]))
786 search_fp_offset
-= 2;
788 search_fp_offset
-= 4;
792 search_fp_addr
-= 32;
793 status
= info
->read_memory_func (search_fp_addr
,
797 /* No previous SPLOOP instruction. */
799 search_fp_header_based
800 = (tic6x_check_fetch_packet_header
801 (search_fp
, &search_fp_header
, info
));
802 if (search_fp_header_based
)
804 = search_fp_header
.word_compact
[6] ? 26 : 24;
806 search_fp_offset
= 28;
809 /* Extract the previous instruction. */
810 if (search_fp_header_based
)
812 = (search_fp_header
.word_compact
[search_fp_offset
817 search_num_bits
= 32;
818 if (search_num_bits
== 16)
820 if (info
->endian
== BFD_ENDIAN_LITTLE
)
823 (search_fp
+ search_fp_offset
, info
));
827 (search_fp
+ (search_fp_offset
^ 2),
832 = tic6x_extract_32 (search_fp
+ search_fp_offset
,
835 /* Check whether it is an SPLOOP-family
837 if (search_num_bits
== 32
838 && ((search_opcode
& 0x003ffffe) == 0x00038000
839 || (search_opcode
& 0x003ffffe) == 0x0003a000
840 || ((search_opcode
& 0x003ffffe)
843 prev_sploop_found
= TRUE
;
844 sploop_ii
= ((search_opcode
>> 23) & 0x1f) + 1;
846 else if (search_num_bits
== 16
847 && (search_opcode
& 0x3c7e) == 0x0c66)
849 prev_sploop_found
= TRUE
;
851 = (((search_opcode
>> 7) & 0x7)
852 | ((search_opcode
>> 11) & 0x8)) + 1;
854 if (prev_sploop_found
)
858 else if (sploop_ii
<= 1)
860 else if (sploop_ii
<= 2)
862 else if (sploop_ii
<= 4)
864 else if (sploop_ii
<= 8)
866 else if (sploop_ii
<= 14)
869 prev_sploop_found
= FALSE
;
871 if (prev_sploop_found
)
875 if (!prev_sploop_found
)
878 operands_text
[op_num
] = TRUE
;
881 if (fcyc_bits
> field
->width
)
883 if (enc
->coding_method
== tic6x_coding_fstg
)
886 for (t
= 0, i
= fcyc_bits
; i
< 6; i
++)
887 t
= (t
<< 1) | ((fld_val
>> i
) & 1);
888 operands_text
[op_num
] = TRUE
;
889 snprintf (operands
[op_num
], 24, "%u", t
);
893 operands_text
[op_num
] = TRUE
;
894 snprintf (operands
[op_num
], 24, "%u",
895 fld_val
& ((1 << fcyc_bits
) - 1));
899 case tic6x_coding_spmask
:
901 spmask_skip_operand
= TRUE
;
907 operands_text
[op_num
] = TRUE
;
908 p
= operands
[op_num
];
909 for (i
= 0; i
< 8; i
++)
910 if (fld_val
& (1 << i
))
913 *p
++ = '1' + (i
& 1);
920 case tic6x_coding_fu
:
921 case tic6x_coding_data_fu
:
922 case tic6x_coding_xpath
:
923 /* Don't relate to operands, so operand number is
931 if (mem_base_reg_known_long
&& mem_offset_known_long
)
933 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
935 operands_text
[op_num
] = TRUE
;
936 snprintf (operands
[op_num
], 24, "*+b%u(%u)", mem_base_reg
,
937 mem_offset
* opc
->operand_info
[op_num
].size
);
940 if (mem_base_reg_known
&& mem_offset_known
&& mem_mode_known
942 || (opc
->operand_info
[op_num
].form
943 != tic6x_operand_mem_ndw
)))
947 bfd_boolean offset_is_reg
;
948 bfd_boolean offset_scaled
;
952 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
955 side
= func_unit_side
== 2 ? 'b' : 'a';
956 snprintf (base
, 4, "%c%u", side
, mem_base_reg
);
958 offset_is_reg
= ((mem_mode
& 4) ? TRUE
: FALSE
);
961 snprintf (offset
, 4, "%c%u", side
, mem_offset
);
962 if (opc
->operand_info
[op_num
].form
963 == tic6x_operand_mem_ndw
)
964 offset_scaled
= mem_scaled
? TRUE
: FALSE
;
966 offset_scaled
= TRUE
;
970 if (opc
->operand_info
[op_num
].form
971 == tic6x_operand_mem_ndw
)
973 offset_scaled
= mem_scaled
? TRUE
: FALSE
;
974 snprintf (offset
, 4, "%u", mem_offset
);
978 offset_scaled
= FALSE
;
979 snprintf (offset
, 4, "%u",
981 * opc
->operand_info
[op_num
].size
));
986 snprintf (offsetp
, 6, "[%s]", offset
);
988 snprintf (offsetp
, 6, "(%s)", offset
);
990 operands_text
[op_num
] = TRUE
;
991 switch (mem_mode
& ~4u)
994 snprintf (operands
[op_num
], 24, "*-%s%s", base
, offsetp
);
998 snprintf (operands
[op_num
], 24, "*+%s%s", base
, offsetp
);
1003 operands_ok
= FALSE
;
1007 snprintf (operands
[op_num
], 24, "*--%s%s", base
,
1012 snprintf (operands
[op_num
], 24, "*++%s%s", base
,
1017 snprintf (operands
[op_num
], 24, "*%s--%s", base
,
1022 snprintf (operands
[op_num
], 24, "*%s++%s", base
,
1031 if (crlo_known
&& crhi_known
)
1036 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
1039 rw
= opc
->operand_info
[op_num
].rw
;
1040 if (rw
!= tic6x_rw_read
1041 && rw
!= tic6x_rw_write
)
1044 for (crid
= 0; crid
< tic6x_ctrl_max
; crid
++)
1046 if (crlo
== tic6x_ctrl_table
[crid
].crlo
1047 && (crhi
& tic6x_ctrl_table
[crid
].crhi_mask
) == 0
1048 && (rw
== tic6x_rw_read
1049 ? (tic6x_ctrl_table
[crid
].rw
== tic6x_rw_read
1050 || (tic6x_ctrl_table
[crid
].rw
1051 == tic6x_rw_read_write
))
1052 : (tic6x_ctrl_table
[crid
].rw
== tic6x_rw_write
1053 || (tic6x_ctrl_table
[crid
].rw
1054 == tic6x_rw_read_write
))))
1057 if (crid
== tic6x_ctrl_max
)
1059 operands_text
[op_num
] = TRUE
;
1060 operands_ok
= FALSE
;
1064 operands_text
[op_num
] = TRUE
;
1065 snprintf (operands
[op_num
], 24, "%s",
1066 tic6x_ctrl_table
[crid
].name
);
1070 if (operands_text
[op_num
] || operands_pcrel
[op_num
]
1071 || spmask_skip_operand
)
1074 if (spmask_skip_operand
)
1076 /* SPMASK operands are only valid as the single operand
1077 in the opcode table. */
1078 if (num_operands
!= 1)
1083 /* The operand must by now have been decoded. */
1084 if (!operands_text
[op_num
] && !operands_pcrel
[op_num
])
1091 info
->bytes_per_chunk
= num_bits
/ 8;
1092 info
->fprintf_func (info
->stream
, "%s%s%s%s", parallel
, cond
,
1093 opc
->name
, func_unit
);
1094 for (op_num
= 0; op_num
< num_operands
; op_num
++)
1096 info
->fprintf_func (info
->stream
, "%c", (op_num
== 0 ? ' ' : ','));
1097 if (operands_pcrel
[op_num
])
1098 info
->print_address_func (operands_addresses
[op_num
], info
);
1100 info
->fprintf_func (info
->stream
, "%s", operands
[op_num
]);
1102 if (fetch_packet_header_based
&& header
.prot
)
1103 info
->fprintf_func (info
->stream
, " || nop 5");
1105 return num_bits
/ 8;
1108 info
->bytes_per_chunk
= num_bits
/ 8;
1109 info
->fprintf_func (info
->stream
, "<undefined instruction 0x%.*x>",
1110 (int) num_bits
/ 4, opcode
);
1111 return num_bits
/ 8;