1 /* TI C6X disassembler.
3 Free Software Foundation, Inc.
4 Contributed by Joseph Myers <joseph@codesourcery.com>
5 Bernd Schmidt <bernds@codesourcery.com>
7 This file is part of libopcodes.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
26 #include "opcode/tic6x.h"
27 #include "libiberty.h"
29 /* Define the instruction format table. */
30 const tic6x_insn_format tic6x_insn_format_table
[tic6x_insn_format_max
] =
32 #define FMT(name, num_bits, cst_bits, mask, fields) \
33 { num_bits, cst_bits, mask, fields },
34 #include "opcode/tic6x-insn-formats.h"
38 /* Define the control register table. */
39 const tic6x_ctrl tic6x_ctrl_table
[tic6x_ctrl_max
] =
41 #define CTRL(name, isa, rw, crlo, crhi_mask) \
44 CONCAT2(TIC6X_INSN_,isa), \
45 CONCAT2(tic6x_rw_,rw), \
49 #include "opcode/tic6x-control-registers.h"
53 /* Define the opcode table. */
54 const tic6x_opcode tic6x_opcode_table
[tic6x_opcode_max
] =
56 #define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
59 CONCAT2(tic6x_func_unit_,func_unit), \
60 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
61 CONCAT2(tic6x_pipeline_,type), \
62 CONCAT2(TIC6X_INSN_,isa), \
68 #define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
71 CONCAT2(tic6x_func_unit_,func_unit), \
72 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
73 CONCAT2(tic6x_pipeline_,type), \
74 CONCAT2(TIC6X_INSN_,isa), \
80 #include "opcode/tic6x-opcode-table.h"
85 /* If instruction format FMT has a field FIELD, return a pointer to
86 the description of that field; otherwise return NULL. */
88 const tic6x_insn_field
*
89 tic6x_field_from_fmt (const tic6x_insn_format
*fmt
, tic6x_insn_field_id field
)
93 for (f
= 0; f
< fmt
->num_fields
; f
++)
94 if (fmt
->fields
[f
].field_id
== field
)
95 return &fmt
->fields
[f
];
100 /* Extract the bits corresponding to FIELD from OPCODE. */
103 tic6x_field_bits (unsigned int opcode
, const tic6x_insn_field
*field
)
105 return (opcode
>> field
->low_pos
) & ((1u << field
->width
) - 1);
108 /* Extract a 32-bit value read from the instruction stream. */
111 tic6x_extract_32 (unsigned char *p
, struct disassemble_info
*info
)
113 if (info
->endian
== BFD_ENDIAN_LITTLE
)
114 return (p
[0]) | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
116 return (p
[3]) | (p
[2] << 8) | (p
[1] << 16) | (p
[0] << 24);
119 /* Extract a 16-bit value read from the instruction stream. */
122 tic6x_extract_16 (unsigned char *p
, struct disassemble_info
*info
)
124 if (info
->endian
== BFD_ENDIAN_LITTLE
)
125 return (p
[0]) | (p
[1] << 8);
127 return (p
[1]) | (p
[0] << 8);
130 /* FP points to a fetch packet. Return whether it is header-based; if
131 it is, fill in HEADER. */
134 tic6x_check_fetch_packet_header (unsigned char *fp
,
135 tic6x_fetch_packet_header
*header
,
136 struct disassemble_info
*info
)
140 header
->header
= tic6x_extract_32 (fp
+ 28, info
);
141 if ((header
->header
& 0xf0000000) != 0xe0000000)
144 for (i
= 0; i
< 7; i
++)
145 header
->word_compact
[i
]
146 = (header
->header
& (1u << (21 + i
))) ? TRUE
: FALSE
;
148 header
->prot
= (header
->header
& (1u << 20)) ? TRUE
: FALSE
;
149 header
->rs
= (header
->header
& (1u << 19)) ? TRUE
: FALSE
;
150 header
->dsz
= (header
->header
>> 16) & 0x7;
151 header
->br
= (header
->header
& (1u << 15)) ? TRUE
: FALSE
;
152 header
->sat
= (header
->header
& (1u << 14)) ? TRUE
: FALSE
;
154 for (i
= 0; i
< 14; i
++)
156 = (header
->header
& (1u << i
)) ? TRUE
: FALSE
;
161 /* Disassemble the instruction at ADDR and print it using
162 INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes
166 print_insn_tic6x (bfd_vma addr
, struct disassemble_info
*info
)
171 unsigned char fp
[32];
173 tic6x_opcode_id opcode_id
;
174 bfd_boolean fetch_packet_header_based
;
175 tic6x_fetch_packet_header header
;
176 unsigned int num_bits
;
177 bfd_boolean bad_offset
= FALSE
;
179 fp_offset
= addr
& 0x1f;
180 fp_addr
= addr
- fp_offset
;
181 status
= info
->read_memory_func (fp_addr
, fp
, 32, info
);
184 info
->memory_error_func (status
, addr
, info
);
188 fetch_packet_header_based
189 = tic6x_check_fetch_packet_header (fp
, &header
, info
);
190 if (fetch_packet_header_based
)
194 if ((fp_offset
& 0x3) && (fp_offset
>= 28
195 || !header
.word_compact
[fp_offset
>> 2]))
199 info
->bytes_per_chunk
= 4;
200 info
->fprintf_func (info
->stream
, "<fetch packet header 0x%.8x>",
204 num_bits
= (header
.word_compact
[fp_offset
>> 2] ? 16 : 32);
215 info
->bytes_per_chunk
= 1;
216 info
->fprintf_func (info
->stream
, ".byte 0x%.2x", fp
[fp_offset
]);
222 /* The least-significant part of a 32-bit word comes logically
223 before the most-significant part. For big-endian, follow the
224 TI assembler in showing instructions in logical order by
225 pretending that the two halves of the word are in opposite
226 locations to where they actually are. */
227 if (info
->endian
== BFD_ENDIAN_LITTLE
)
228 opcode
= tic6x_extract_16 (fp
+ fp_offset
, info
);
230 opcode
= tic6x_extract_16 (fp
+ (fp_offset
^ 2), info
);
233 opcode
= tic6x_extract_32 (fp
+ fp_offset
, info
);
235 for (opcode_id
= 0; opcode_id
< tic6x_opcode_max
; opcode_id
++)
237 const tic6x_opcode
*const opc
= &tic6x_opcode_table
[opcode_id
];
238 const tic6x_insn_format
*const fmt
239 = &tic6x_insn_format_table
[opc
->format
];
240 const tic6x_insn_field
*creg_field
;
242 const char *parallel
;
243 const char *cond
= "";
244 const char *func_unit
;
245 char func_unit_buf
[7];
246 unsigned int func_unit_side
= 0;
247 unsigned int func_unit_data_side
= 0;
248 unsigned int func_unit_cross
= 0;
249 /* The maximum length of the text of a non-PC-relative operand
250 is 24 bytes (SPMASK masking all eight functional units, with
251 separating commas and trailing NUL). */
252 char operands
[TIC6X_MAX_OPERANDS
][24] = { { 0 } };
253 bfd_vma operands_addresses
[TIC6X_MAX_OPERANDS
] = { 0 };
254 bfd_boolean operands_text
[TIC6X_MAX_OPERANDS
] = { FALSE
};
255 bfd_boolean operands_pcrel
[TIC6X_MAX_OPERANDS
] = { FALSE
};
257 unsigned int num_operands
;
259 bfd_boolean fixed_ok
;
260 bfd_boolean operands_ok
;
262 if (opc
->flags
& TIC6X_FLAG_MACRO
)
264 if (fmt
->num_bits
!= num_bits
)
266 if ((opcode
& fmt
->mask
) != fmt
->cst_bits
)
269 /* If the format has a creg field, it is only a candidate for a
270 match if the creg and z fields have values indicating a valid
271 condition; reserved values indicate either an instruction
272 format without a creg field, or an invalid instruction. */
273 creg_field
= tic6x_field_from_fmt (fmt
, tic6x_field_creg
);
276 const tic6x_insn_field
*z_field
;
277 unsigned int creg_value
, z_value
;
278 static const char *const conds
[8][2] =
281 { "[b0] ", "[!b0] " },
282 { "[b1] ", "[!b1] " },
283 { "[b2] ", "[!b2] " },
284 { "[a1] ", "[!a1] " },
285 { "[a2] ", "[!a2] " },
286 { "[a0] ", "[!a0] " },
290 /* A creg field is not meaningful without a z field, so if
291 the z field is not present this is an error in the format
293 z_field
= tic6x_field_from_fmt (fmt
, tic6x_field_z
);
297 creg_value
= tic6x_field_bits (opcode
, creg_field
);
298 z_value
= tic6x_field_bits (opcode
, z_field
);
299 cond
= conds
[creg_value
][z_value
];
304 /* All fixed fields must have matching values; all fields with
305 restricted ranges must have values within those ranges. */
307 for (fix
= 0; fix
< opc
->num_fixed_fields
; fix
++)
309 unsigned int field_bits
;
310 const tic6x_insn_field
*const field
311 = tic6x_field_from_fmt (fmt
, opc
->fixed_fields
[fix
].field_id
);
315 field_bits
= tic6x_field_bits (opcode
, field
);
316 if (field_bits
< opc
->fixed_fields
[fix
].min_val
317 || field_bits
> opc
->fixed_fields
[fix
].max_val
)
326 /* The instruction matches. */
328 /* The p-bit indicates whether this instruction is in parallel
329 with the *next* instruction, whereas the parallel bars
330 indicate the instruction is in parallel with the *previous*
331 instruction. Thus, we must find the p-bit for the previous
333 if (num_bits
== 16 && (fp_offset
& 0x2) == 2)
335 /* This is the logically second (most significant; second in
336 fp_offset terms because fp_offset relates to logical not
337 physical addresses) instruction of a compact pair; find
338 the p-bit for the first (least significant). */
339 p_bit
= header
.p_bits
[(fp_offset
>> 2) << 1];
341 else if (fp_offset
>= 4)
343 /* Find the last instruction of the previous word in this
344 fetch packet. For compact instructions, this is the most
345 significant 16 bits. */
346 if (fetch_packet_header_based
347 && header
.word_compact
[(fp_offset
>> 2) - 1])
348 p_bit
= header
.p_bits
[(fp_offset
>> 1) - 1];
351 unsigned int prev_opcode
352 = tic6x_extract_32 (fp
+ (fp_offset
& 0x1c) - 4, info
);
353 p_bit
= (prev_opcode
& 0x1) ? TRUE
: FALSE
;
358 /* Find the last instruction of the previous fetch
360 unsigned char fp_prev
[32];
361 status
= info
->read_memory_func (fp_addr
- 32, fp_prev
, 32, info
);
363 /* No previous instruction to be parallel with. */
367 bfd_boolean prev_header_based
;
368 tic6x_fetch_packet_header prev_header
;
371 = tic6x_check_fetch_packet_header (fp_prev
, &prev_header
, info
);
372 if (prev_header_based
&& prev_header
.word_compact
[6])
373 p_bit
= prev_header
.p_bits
[13];
376 unsigned int prev_opcode
= tic6x_extract_32 (fp_prev
+ 28,
378 p_bit
= (prev_opcode
& 0x1) ? TRUE
: FALSE
;
382 parallel
= p_bit
? "|| " : "";
384 if (opc
->func_unit
== tic6x_func_unit_nfu
)
388 unsigned int fld_num
;
390 const char *data_str
;
391 bfd_boolean have_areg
= FALSE
;
392 bfd_boolean have_cross
= FALSE
;
394 func_unit_side
= (opc
->flags
& TIC6X_FLAG_SIDE_B_ONLY
) ? 2 : 0;
396 func_unit_data_side
= (opc
->flags
& TIC6X_FLAG_SIDE_T2_ONLY
) ? 2 : 0;
398 for (fld_num
= 0; fld_num
< opc
->num_variable_fields
; fld_num
++)
400 const tic6x_coding_field
*const enc
= &opc
->variable_fields
[fld_num
];
401 const tic6x_insn_field
*field
;
402 unsigned int fld_val
;
404 field
= tic6x_field_from_fmt (fmt
, enc
->field_id
);
407 fld_val
= tic6x_field_bits (opcode
, field
);
408 switch (enc
->coding_method
)
410 case tic6x_coding_fu
:
411 /* The side must be specified exactly once. */
414 func_unit_side
= (fld_val
? 2 : 1);
417 case tic6x_coding_data_fu
:
418 /* The data side must be specified exactly once. */
419 if (func_unit_data_side
)
421 func_unit_data_side
= (fld_val
? 2 : 1);
424 case tic6x_coding_xpath
:
425 /* Cross path use must be specified exactly
430 func_unit_cross
= fld_val
;
433 case tic6x_coding_areg
:
438 /* Don't relate to functional units. */
443 /* The side of the functional unit used must now have been
444 determined either from the flags or from an instruction
446 if (func_unit_side
!= 1 && func_unit_side
!= 2)
449 /* Cross paths are not applicable when sides are specified
450 for both address and data paths. */
451 if (func_unit_data_side
&& have_cross
)
454 /* Separate address and data paths are only applicable for
456 if (func_unit_data_side
&& opc
->func_unit
!= tic6x_func_unit_d
)
459 /* If an address register is being used but in ADDA rather
460 than a load or store, it uses a cross path for side-A
461 instructions, and the cross path use is not specified by
462 an instruction field. */
463 if (have_areg
&& !func_unit_data_side
)
467 func_unit_cross
= (func_unit_side
== 1 ? TRUE
: FALSE
);
470 switch (opc
->func_unit
)
472 case tic6x_func_unit_d
:
473 func_unit_char
= 'D';
476 case tic6x_func_unit_l
:
477 func_unit_char
= 'L';
480 case tic6x_func_unit_m
:
481 func_unit_char
= 'M';
484 case tic6x_func_unit_s
:
485 func_unit_char
= 'S';
492 switch (func_unit_data_side
)
510 snprintf (func_unit_buf
, 7, " .%c%u%s%s", func_unit_char
,
511 func_unit_side
, (func_unit_cross
? "X" : ""), data_str
);
512 func_unit
= func_unit_buf
;
515 /* For each operand there must be one or more fields set based
516 on that operand, that can together be used to derive the
519 num_operands
= opc
->num_operands
;
520 for (op_num
= 0; op_num
< num_operands
; op_num
++)
522 unsigned int fld_num
;
523 unsigned int mem_base_reg
= 0;
524 bfd_boolean mem_base_reg_known
= FALSE
;
525 bfd_boolean mem_base_reg_known_long
= FALSE
;
526 unsigned int mem_offset
= 0;
527 bfd_boolean mem_offset_known
= FALSE
;
528 bfd_boolean mem_offset_known_long
= FALSE
;
529 unsigned int mem_mode
= 0;
530 bfd_boolean mem_mode_known
= FALSE
;
531 unsigned int mem_scaled
= 0;
532 bfd_boolean mem_scaled_known
= FALSE
;
533 unsigned int crlo
= 0;
534 bfd_boolean crlo_known
= FALSE
;
535 unsigned int crhi
= 0;
536 bfd_boolean crhi_known
= FALSE
;
537 bfd_boolean spmask_skip_operand
= FALSE
;
538 unsigned int fcyc_bits
= 0;
539 bfd_boolean prev_sploop_found
= FALSE
;
541 switch (opc
->operand_info
[op_num
].form
)
543 case tic6x_operand_retreg
:
544 /* Fully determined by the functional unit. */
545 operands_text
[op_num
] = TRUE
;
546 snprintf (operands
[op_num
], 24, "%c3",
547 (func_unit_side
== 2 ? 'b' : 'a'));
550 case tic6x_operand_irp
:
551 operands_text
[op_num
] = TRUE
;
552 snprintf (operands
[op_num
], 24, "irp");
555 case tic6x_operand_nrp
:
556 operands_text
[op_num
] = TRUE
;
557 snprintf (operands
[op_num
], 24, "nrp");
564 for (fld_num
= 0; fld_num
< opc
->num_variable_fields
; fld_num
++)
566 const tic6x_coding_field
*const enc
567 = &opc
->variable_fields
[fld_num
];
568 const tic6x_insn_field
*field
;
569 unsigned int fld_val
;
570 signed int signed_fld_val
;
572 if (enc
->operand_num
!= op_num
)
574 field
= tic6x_field_from_fmt (fmt
, enc
->field_id
);
577 fld_val
= tic6x_field_bits (opcode
, field
);
578 switch (enc
->coding_method
)
580 case tic6x_coding_ucst
:
581 case tic6x_coding_ulcst_dpr_byte
:
582 case tic6x_coding_ulcst_dpr_half
:
583 case tic6x_coding_ulcst_dpr_word
:
584 case tic6x_coding_lcst_low16
:
585 switch (opc
->operand_info
[op_num
].form
)
587 case tic6x_operand_asm_const
:
588 case tic6x_operand_link_const
:
589 operands_text
[op_num
] = TRUE
;
590 snprintf (operands
[op_num
], 24, "%u", fld_val
);
593 case tic6x_operand_mem_long
:
594 mem_offset
= fld_val
;
595 mem_offset_known_long
= TRUE
;
603 case tic6x_coding_lcst_high16
:
604 operands_text
[op_num
] = TRUE
;
605 snprintf (operands
[op_num
], 24, "%u", fld_val
<< 16);
608 case tic6x_coding_scst
:
609 operands_text
[op_num
] = TRUE
;
610 signed_fld_val
= (signed int) fld_val
;
611 signed_fld_val
^= (1 << (field
->width
- 1));
612 signed_fld_val
-= (1 << (field
->width
- 1));
613 snprintf (operands
[op_num
], 24, "%d", signed_fld_val
);
616 case tic6x_coding_ucst_minus_one
:
617 operands_text
[op_num
] = TRUE
;
618 snprintf (operands
[op_num
], 24, "%u", fld_val
+ 1);
621 case tic6x_coding_pcrel
:
622 case tic6x_coding_pcrel_half
:
623 signed_fld_val
= (signed int) fld_val
;
624 signed_fld_val
^= (1 << (field
->width
- 1));
625 signed_fld_val
-= (1 << (field
->width
- 1));
626 if (fetch_packet_header_based
627 && enc
->coding_method
== tic6x_coding_pcrel_half
)
631 operands_pcrel
[op_num
] = TRUE
;
632 operands_addresses
[op_num
] = fp_addr
+ signed_fld_val
;
635 case tic6x_coding_reg_shift
:
638 case tic6x_coding_reg
:
639 switch (opc
->operand_info
[op_num
].form
)
641 case tic6x_operand_reg
:
642 operands_text
[op_num
] = TRUE
;
643 snprintf (operands
[op_num
], 24, "%c%u",
644 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
647 case tic6x_operand_xreg
:
648 operands_text
[op_num
] = TRUE
;
649 snprintf (operands
[op_num
], 24, "%c%u",
650 (((func_unit_side
== 2) ^ func_unit_cross
)
655 case tic6x_operand_dreg
:
656 operands_text
[op_num
] = TRUE
;
657 snprintf (operands
[op_num
], 24, "%c%u",
658 (func_unit_data_side
== 2 ? 'b' : 'a'),
662 case tic6x_operand_regpair
:
663 operands_text
[op_num
] = TRUE
;
666 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
667 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
+ 1,
668 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
671 case tic6x_operand_xregpair
:
672 operands_text
[op_num
] = TRUE
;
675 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
676 (((func_unit_side
== 2) ^ func_unit_cross
)
679 (((func_unit_side
== 2) ^ func_unit_cross
)
684 case tic6x_operand_dregpair
:
685 operands_text
[op_num
] = TRUE
;
688 snprintf (operands
[op_num
], 24, "%c%u:%c%u",
689 (func_unit_data_side
== 2 ? 'b' : 'a'),
691 (func_unit_data_side
== 2 ? 'b' : 'a'),
695 case tic6x_operand_mem_deref
:
696 operands_text
[op_num
] = TRUE
;
697 snprintf (operands
[op_num
], 24, "*%c%u",
698 (func_unit_side
== 2 ? 'b' : 'a'), fld_val
);
701 case tic6x_operand_mem_short
:
702 case tic6x_operand_mem_ndw
:
703 mem_base_reg
= fld_val
;
704 mem_base_reg_known
= TRUE
;
712 case tic6x_coding_areg
:
713 switch (opc
->operand_info
[op_num
].form
)
715 case tic6x_operand_areg
:
716 operands_text
[op_num
] = TRUE
;
717 snprintf (operands
[op_num
], 24, "b%u",
718 fld_val
? 15u : 14u);
721 case tic6x_operand_mem_long
:
722 mem_base_reg
= fld_val
? 15u : 14u;
723 mem_base_reg_known_long
= TRUE
;
731 case tic6x_coding_mem_offset
:
732 case tic6x_coding_mem_offset_noscale
:
733 mem_offset
= fld_val
;
734 mem_offset_known
= TRUE
;
737 case tic6x_coding_mem_mode
:
739 mem_mode_known
= TRUE
;
742 case tic6x_coding_scaled
:
743 mem_scaled
= fld_val
;
744 mem_scaled_known
= TRUE
;
747 case tic6x_coding_crlo
:
752 case tic6x_coding_crhi
:
757 case tic6x_coding_fstg
:
758 case tic6x_coding_fcyc
:
759 if (!prev_sploop_found
)
761 bfd_vma search_fp_addr
= fp_addr
;
762 bfd_vma search_fp_offset
= fp_offset
;
763 bfd_boolean search_fp_header_based
764 = fetch_packet_header_based
;
765 tic6x_fetch_packet_header search_fp_header
= header
;
766 unsigned char search_fp
[32];
767 unsigned int search_num_bits
;
768 unsigned int search_opcode
;
769 unsigned int sploop_ii
= 0;
772 memcpy (search_fp
, fp
, 32);
774 /* To interpret these bits in an SPKERNEL
775 instruction, we must find the previous
776 SPLOOP-family instruction. It may come up to
777 48 execute packets earlier. */
778 for (i
= 0; i
< 48 * 8; i
++)
780 /* Find the previous instruction. */
781 if (search_fp_offset
& 2)
782 search_fp_offset
-= 2;
783 else if (search_fp_offset
>= 4)
785 if (search_fp_header_based
786 && (search_fp_header
.word_compact
787 [(search_fp_offset
>> 2) - 1]))
788 search_fp_offset
-= 2;
790 search_fp_offset
-= 4;
794 search_fp_addr
-= 32;
795 status
= info
->read_memory_func (search_fp_addr
,
799 /* No previous SPLOOP instruction. */
801 search_fp_header_based
802 = (tic6x_check_fetch_packet_header
803 (search_fp
, &search_fp_header
, info
));
804 if (search_fp_header_based
)
806 = search_fp_header
.word_compact
[6] ? 26 : 24;
808 search_fp_offset
= 28;
811 /* Extract the previous instruction. */
812 if (search_fp_header_based
)
814 = (search_fp_header
.word_compact
[search_fp_offset
819 search_num_bits
= 32;
820 if (search_num_bits
== 16)
822 if (info
->endian
== BFD_ENDIAN_LITTLE
)
825 (search_fp
+ search_fp_offset
, info
));
829 (search_fp
+ (search_fp_offset
^ 2),
834 = tic6x_extract_32 (search_fp
+ search_fp_offset
,
837 /* Check whether it is an SPLOOP-family
839 if (search_num_bits
== 32
840 && ((search_opcode
& 0x003ffffe) == 0x00038000
841 || (search_opcode
& 0x003ffffe) == 0x0003a000
842 || ((search_opcode
& 0x003ffffe)
845 prev_sploop_found
= TRUE
;
846 sploop_ii
= ((search_opcode
>> 23) & 0x1f) + 1;
848 else if (search_num_bits
== 16
849 && (search_opcode
& 0x3c7e) == 0x0c66)
851 prev_sploop_found
= TRUE
;
853 = (((search_opcode
>> 7) & 0x7)
854 | ((search_opcode
>> 11) & 0x8)) + 1;
856 if (prev_sploop_found
)
860 else if (sploop_ii
<= 1)
862 else if (sploop_ii
<= 2)
864 else if (sploop_ii
<= 4)
866 else if (sploop_ii
<= 8)
868 else if (sploop_ii
<= 14)
871 prev_sploop_found
= FALSE
;
873 if (prev_sploop_found
)
877 if (!prev_sploop_found
)
880 operands_text
[op_num
] = TRUE
;
883 if (fcyc_bits
> field
->width
)
885 if (enc
->coding_method
== tic6x_coding_fstg
)
888 for (t
= 0, i
= fcyc_bits
; i
< 6; i
++)
889 t
= (t
<< 1) | ((fld_val
>> i
) & 1);
890 operands_text
[op_num
] = TRUE
;
891 snprintf (operands
[op_num
], 24, "%u", t
);
895 operands_text
[op_num
] = TRUE
;
896 snprintf (operands
[op_num
], 24, "%u",
897 fld_val
& ((1 << fcyc_bits
) - 1));
901 case tic6x_coding_spmask
:
903 spmask_skip_operand
= TRUE
;
909 operands_text
[op_num
] = TRUE
;
910 p
= operands
[op_num
];
911 for (i
= 0; i
< 8; i
++)
912 if (fld_val
& (1 << i
))
915 *p
++ = '1' + (i
& 1);
922 case tic6x_coding_fu
:
923 case tic6x_coding_data_fu
:
924 case tic6x_coding_xpath
:
925 /* Don't relate to operands, so operand number is
933 if (mem_base_reg_known_long
&& mem_offset_known_long
)
935 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
937 operands_text
[op_num
] = TRUE
;
938 snprintf (operands
[op_num
], 24, "*+b%u(%u)", mem_base_reg
,
939 mem_offset
* opc
->operand_info
[op_num
].size
);
942 if (mem_base_reg_known
&& mem_offset_known
&& mem_mode_known
944 || (opc
->operand_info
[op_num
].form
945 != tic6x_operand_mem_ndw
)))
949 bfd_boolean offset_is_reg
;
950 bfd_boolean offset_scaled
;
954 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
957 side
= func_unit_side
== 2 ? 'b' : 'a';
958 snprintf (base
, 4, "%c%u", side
, mem_base_reg
);
960 offset_is_reg
= ((mem_mode
& 4) ? TRUE
: FALSE
);
963 snprintf (offset
, 4, "%c%u", side
, mem_offset
);
964 if (opc
->operand_info
[op_num
].form
965 == tic6x_operand_mem_ndw
)
966 offset_scaled
= mem_scaled
? TRUE
: FALSE
;
968 offset_scaled
= TRUE
;
972 if (opc
->operand_info
[op_num
].form
973 == tic6x_operand_mem_ndw
)
975 offset_scaled
= mem_scaled
? TRUE
: FALSE
;
976 snprintf (offset
, 4, "%u", mem_offset
);
980 offset_scaled
= FALSE
;
981 snprintf (offset
, 4, "%u",
983 * opc
->operand_info
[op_num
].size
));
988 snprintf (offsetp
, 6, "[%s]", offset
);
990 snprintf (offsetp
, 6, "(%s)", offset
);
992 operands_text
[op_num
] = TRUE
;
993 switch (mem_mode
& ~4u)
996 snprintf (operands
[op_num
], 24, "*-%s%s", base
, offsetp
);
1000 snprintf (operands
[op_num
], 24, "*+%s%s", base
, offsetp
);
1005 operands_ok
= FALSE
;
1009 snprintf (operands
[op_num
], 24, "*--%s%s", base
,
1014 snprintf (operands
[op_num
], 24, "*++%s%s", base
,
1019 snprintf (operands
[op_num
], 24, "*%s--%s", base
,
1024 snprintf (operands
[op_num
], 24, "*%s++%s", base
,
1033 if (crlo_known
&& crhi_known
)
1038 if (operands_text
[op_num
] || operands_pcrel
[op_num
])
1041 rw
= opc
->operand_info
[op_num
].rw
;
1042 if (rw
!= tic6x_rw_read
1043 && rw
!= tic6x_rw_write
)
1046 for (crid
= 0; crid
< tic6x_ctrl_max
; crid
++)
1048 if (crlo
== tic6x_ctrl_table
[crid
].crlo
1049 && (crhi
& tic6x_ctrl_table
[crid
].crhi_mask
) == 0
1050 && (rw
== tic6x_rw_read
1051 ? (tic6x_ctrl_table
[crid
].rw
== tic6x_rw_read
1052 || (tic6x_ctrl_table
[crid
].rw
1053 == tic6x_rw_read_write
))
1054 : (tic6x_ctrl_table
[crid
].rw
== tic6x_rw_write
1055 || (tic6x_ctrl_table
[crid
].rw
1056 == tic6x_rw_read_write
))))
1059 if (crid
== tic6x_ctrl_max
)
1061 operands_text
[op_num
] = TRUE
;
1062 operands_ok
= FALSE
;
1066 operands_text
[op_num
] = TRUE
;
1067 snprintf (operands
[op_num
], 24, "%s",
1068 tic6x_ctrl_table
[crid
].name
);
1072 if (operands_text
[op_num
] || operands_pcrel
[op_num
]
1073 || spmask_skip_operand
)
1076 if (spmask_skip_operand
)
1078 /* SPMASK operands are only valid as the single operand
1079 in the opcode table. */
1080 if (num_operands
!= 1)
1085 /* The operand must by now have been decoded. */
1086 if (!operands_text
[op_num
] && !operands_pcrel
[op_num
])
1093 info
->bytes_per_chunk
= num_bits
/ 8;
1094 info
->fprintf_func (info
->stream
, "%s%s%s%s", parallel
, cond
,
1095 opc
->name
, func_unit
);
1096 for (op_num
= 0; op_num
< num_operands
; op_num
++)
1098 info
->fprintf_func (info
->stream
, "%c", (op_num
== 0 ? ' ' : ','));
1099 if (operands_pcrel
[op_num
])
1100 info
->print_address_func (operands_addresses
[op_num
], info
);
1102 info
->fprintf_func (info
->stream
, "%s", operands
[op_num
]);
1104 if (fetch_packet_header_based
&& header
.prot
)
1105 info
->fprintf_func (info
->stream
, " || nop 5");
1107 return num_bits
/ 8;
1110 info
->bytes_per_chunk
= num_bits
/ 8;
1111 info
->fprintf_func (info
->stream
, "<undefined instruction 0x%.*x>",
1112 (int) num_bits
/ 4, opcode
);
1113 return num_bits
/ 8;