Fix disassembling of TIC6X parallel instructions where the previous fetch packet...
[deliverable/binutils-gdb.git] / opcodes / tic6x-dis.c
1 /* TI C6X disassembler.
2 Copyright (C) 2010-2017 Free Software Foundation, Inc.
3 Contributed by Joseph Myers <joseph@codesourcery.com>
4 Bernd Schmidt <bernds@codesourcery.com>
5
6 This file is part of libopcodes.
7
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #include "opcode/tic6x.h"
26 #include "libiberty.h"
27
28 /* Define the instruction format table. */
29 const tic6x_insn_format tic6x_insn_format_table[tic6x_insn_format_max] =
30 {
31 #define FMT(name, num_bits, cst_bits, mask, fields) \
32 { num_bits, cst_bits, mask, fields },
33 #include "opcode/tic6x-insn-formats.h"
34 #undef FMT
35 };
36
37 /* Define the control register table. */
38 const tic6x_ctrl tic6x_ctrl_table[tic6x_ctrl_max] =
39 {
40 #define CTRL(name, isa, rw, crlo, crhi_mask) \
41 { \
42 STRINGX(name), \
43 CONCAT2(TIC6X_INSN_,isa), \
44 CONCAT2(tic6x_rw_,rw), \
45 crlo, \
46 crhi_mask \
47 },
48 #include "opcode/tic6x-control-registers.h"
49 #undef CTRL
50 };
51
52 /* Define the opcode table. */
53 const tic6x_opcode tic6x_opcode_table[tic6x_opcode_max] =
54 {
55 #define INSNU(name, func_unit, format, type, isa, flags, fixed, ops, var) \
56 { \
57 STRINGX(name), \
58 CONCAT2(tic6x_func_unit_,func_unit), \
59 CONCAT3(tic6x_insn_format,_,format), \
60 CONCAT2(tic6x_pipeline_,type), \
61 CONCAT2(TIC6X_INSN_,isa), \
62 flags, \
63 fixed, \
64 ops, \
65 var \
66 },
67 #define INSNUE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
68 { \
69 STRINGX(name), \
70 CONCAT2(tic6x_func_unit_,func_unit), \
71 CONCAT3(tic6x_insn_format,_,format), \
72 CONCAT2(tic6x_pipeline_,type), \
73 CONCAT2(TIC6X_INSN_,isa), \
74 flags, \
75 fixed, \
76 ops, \
77 var \
78 },
79 #define INSN(name, func_unit, format, type, isa, flags, fixed, ops, var) \
80 { \
81 STRINGX(name), \
82 CONCAT2(tic6x_func_unit_,func_unit), \
83 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
84 CONCAT2(tic6x_pipeline_,type), \
85 CONCAT2(TIC6X_INSN_,isa), \
86 flags, \
87 fixed, \
88 ops, \
89 var \
90 },
91 #define INSNE(name, e, func_unit, format, type, isa, flags, fixed, ops, var) \
92 { \
93 STRINGX(name), \
94 CONCAT2(tic6x_func_unit_,func_unit), \
95 CONCAT4(tic6x_insn_format_,func_unit,_,format), \
96 CONCAT2(tic6x_pipeline_,type), \
97 CONCAT2(TIC6X_INSN_,isa), \
98 flags, \
99 fixed, \
100 ops, \
101 var \
102 },
103 #include "opcode/tic6x-opcode-table.h"
104 #undef INSN
105 #undef INSNE
106 #undef INSNU
107 #undef INSNUE
108 };
109
110 /* If instruction format FMT has a field FIELD, return a pointer to
111 the description of that field; otherwise return NULL. */
112
113 const tic6x_insn_field *
114 tic6x_field_from_fmt (const tic6x_insn_format *fmt, tic6x_insn_field_id field)
115 {
116 unsigned int f;
117
118 for (f = 0; f < fmt->num_fields; f++)
119 if (fmt->fields[f].field_id == field)
120 return &fmt->fields[f];
121
122 return NULL;
123 }
124
125 /* Extract the field width. */
126
127 static unsigned int
128 tic6x_field_width (const tic6x_insn_field *field)
129 {
130 unsigned int i;
131 unsigned int width = 0;
132
133 if (!field->num_bitfields)
134 return field->bitfields[0].width;
135
136 for (i = 0 ; i < field->num_bitfields ; i++)
137 width += field->bitfields[i].width;
138
139 return width;
140 }
141
142 /* Extract the bits corresponding to FIELD from OPCODE. */
143
144 static unsigned int
145 tic6x_field_bits (unsigned int opcode, const tic6x_insn_field *field)
146 {
147 unsigned int i;
148 unsigned int val = 0;
149
150 if (!field->num_bitfields)
151 return (opcode >> field->bitfields[0].low_pos) & ((1u << field->bitfields[0].width) - 1);
152
153 for (i = 0 ; i < field->num_bitfields ; i++)
154 val |= ((opcode >> field->bitfields[i].low_pos) & ((1u << field->bitfields[i].width) - 1))
155 << field->bitfields[i].pos;
156
157 return val;
158 }
159
160 /* Extract a 32-bit value read from the instruction stream. */
161
162 static unsigned int
163 tic6x_extract_32 (unsigned char *p, struct disassemble_info *info)
164 {
165 if (info->endian == BFD_ENDIAN_LITTLE)
166 return (p[0]) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
167 else
168 return (p[3]) | (p[2] << 8) | (p[1] << 16) | (p[0] << 24);
169 }
170
171 /* Extract a 16-bit value read from the instruction stream. */
172
173 static unsigned int
174 tic6x_extract_16 (unsigned char *p, tic6x_fetch_packet_header *header,
175 struct disassemble_info *info)
176 {
177 unsigned int op16;
178
179 if (info->endian == BFD_ENDIAN_LITTLE)
180 op16 = (p[0]) | (p[1] << 8);
181 else
182 op16 = (p[1]) | (p[0] << 8);
183 op16 |= (header->sat << TIC6X_COMPACT_SAT_POS);
184 op16 |= (header->br << TIC6X_COMPACT_BR_POS);
185 op16 |= (header->dsz << TIC6X_COMPACT_DSZ_POS);
186 return op16;
187 }
188
189 /* FP points to a fetch packet. Return whether it is header-based; if
190 it is, fill in HEADER. */
191
192 static bfd_boolean
193 tic6x_check_fetch_packet_header (unsigned char *fp,
194 tic6x_fetch_packet_header *header,
195 struct disassemble_info *info)
196 {
197 int i;
198
199 header->header = tic6x_extract_32 (fp + 28, info);
200
201 if ((header->header & 0xf0000000) != 0xe0000000)
202 {
203 header->prot = 0;
204 header->rs = 0;
205 header->dsz = 0;
206 header->br = 0;
207 header->sat = 0;
208 for (i = 0; i < 7; i++)
209 header->word_compact[i] = FALSE;
210 for (i = 0; i < 14; i++)
211 header->p_bits[i] = FALSE;
212 return FALSE;
213 }
214
215 for (i = 0; i < 7; i++)
216 header->word_compact[i]
217 = (header->header & (1u << (21 + i))) ? TRUE : FALSE;
218
219 header->prot = (header->header & (1u << 20)) ? TRUE : FALSE;
220 header->rs = (header->header & (1u << 19)) ? TRUE : FALSE;
221 header->dsz = (header->header >> 16) & 0x7;
222 header->br = (header->header & (1u << 15)) ? TRUE : FALSE;
223 header->sat = (header->header & (1u << 14)) ? TRUE : FALSE;
224
225 for (i = 0; i < 14; i++)
226 header->p_bits[i]
227 = (header->header & (1u << i)) ? TRUE : FALSE;
228
229 return TRUE;
230 }
231
232 /* Disassemble the instruction at ADDR and print it using
233 INFO->FPRINTF_FUNC and INFO->STREAM, returning the number of bytes
234 consumed. */
235
236 int
237 print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
238 {
239 int status;
240 bfd_vma fp_addr;
241 bfd_vma fp_offset;
242 unsigned char fp[32];
243 unsigned int opcode;
244 tic6x_opcode_id opcode_id;
245 bfd_boolean fetch_packet_header_based;
246 tic6x_fetch_packet_header header;
247 unsigned int num_bits;
248 bfd_boolean bad_offset = FALSE;
249
250 fp_offset = addr & 0x1f;
251 fp_addr = addr - fp_offset;
252 /* Read in a block of instructions. Since there might be a
253 symbol in the middle of this block, disable stop_vma. */
254 info->stop_vma = 0;
255 status = info->read_memory_func (fp_addr, fp, 32, info);
256 if (status)
257 {
258 info->memory_error_func (status, addr, info);
259 return -1;
260 }
261
262 fetch_packet_header_based
263 = tic6x_check_fetch_packet_header (fp, &header, info);
264 if (fetch_packet_header_based)
265 {
266 if (fp_offset & 0x1)
267 bad_offset = TRUE;
268 if ((fp_offset & 0x3) && (fp_offset >= 28
269 || !header.word_compact[fp_offset >> 2]))
270 bad_offset = TRUE;
271 if (fp_offset == 28)
272 {
273 info->bytes_per_chunk = 4;
274 info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
275 header.header);
276 return 4;
277 }
278 num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
279 }
280 else
281 {
282 num_bits = 32;
283 if (fp_offset & 0x3)
284 bad_offset = TRUE;
285 }
286
287 if (bad_offset)
288 {
289 info->bytes_per_chunk = 1;
290 info->fprintf_func (info->stream, ".byte 0x%.2x", fp[fp_offset]);
291 return 1;
292 }
293
294 if (num_bits == 16)
295 {
296 /* The least-significant part of a 32-bit word comes logically
297 before the most-significant part. For big-endian, follow the
298 TI assembler in showing instructions in logical order by
299 pretending that the two halves of the word are in opposite
300 locations to where they actually are. */
301 if (info->endian == BFD_ENDIAN_LITTLE)
302 opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
303 else
304 opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
305 }
306 else
307 opcode = tic6x_extract_32 (fp + fp_offset, info);
308
309 for (opcode_id = 0; opcode_id < tic6x_opcode_max; opcode_id++)
310 {
311 const tic6x_opcode *const opc = &tic6x_opcode_table[opcode_id];
312 const tic6x_insn_format *const fmt
313 = &tic6x_insn_format_table[opc->format];
314 const tic6x_insn_field *creg_field;
315 bfd_boolean p_bit;
316 const char *parallel;
317 const char *cond = "";
318 const char *func_unit;
319 char func_unit_buf[7];
320 unsigned int func_unit_side = 0;
321 unsigned int func_unit_data_side = 0;
322 unsigned int func_unit_cross = 0;
323 unsigned int t_val = 0;
324 /* The maximum length of the text of a non-PC-relative operand
325 is 24 bytes (SPMASK masking all eight functional units, with
326 separating commas and trailing NUL). */
327 char operands[TIC6X_MAX_OPERANDS][24] = { { 0 } };
328 bfd_vma operands_addresses[TIC6X_MAX_OPERANDS] = { 0 };
329 bfd_boolean operands_text[TIC6X_MAX_OPERANDS] = { FALSE };
330 bfd_boolean operands_pcrel[TIC6X_MAX_OPERANDS] = { FALSE };
331 unsigned int fix;
332 unsigned int num_operands;
333 unsigned int op_num;
334 bfd_boolean fixed_ok;
335 bfd_boolean operands_ok;
336 bfd_boolean have_t = FALSE;
337
338 if (opc->flags & TIC6X_FLAG_MACRO)
339 continue;
340 if (fmt->num_bits != num_bits)
341 continue;
342 if ((opcode & fmt->mask) != fmt->cst_bits)
343 continue;
344
345 /* If the format has a creg field, it is only a candidate for a
346 match if the creg and z fields have values indicating a valid
347 condition; reserved values indicate either an instruction
348 format without a creg field, or an invalid instruction. */
349 creg_field = tic6x_field_from_fmt (fmt, tic6x_field_creg);
350 if (creg_field)
351 {
352 const tic6x_insn_field *z_field;
353 unsigned int creg_value, z_value;
354 static const char *const conds[8][2] =
355 {
356 { "", NULL },
357 { "[b0] ", "[!b0] " },
358 { "[b1] ", "[!b1] " },
359 { "[b2] ", "[!b2] " },
360 { "[a1] ", "[!a1] " },
361 { "[a2] ", "[!a2] " },
362 { "[a0] ", "[!a0] " },
363 { NULL, NULL }
364 };
365
366 /* A creg field is not meaningful without a z field, so if
367 the z field is not present this is an error in the format
368 table. */
369 z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
370 if (!z_field)
371 {
372 printf ("*** opcode %x: missing z field", opcode);
373 abort ();
374 }
375
376 creg_value = tic6x_field_bits (opcode, creg_field);
377 z_value = tic6x_field_bits (opcode, z_field);
378 cond = conds[creg_value][z_value];
379 if (cond == NULL)
380 continue;
381 }
382
383 if (opc->flags & TIC6X_FLAG_INSN16_SPRED)
384 {
385 const tic6x_insn_field *cc_field;
386 unsigned int s_value = 0;
387 unsigned int z_value = 0;
388 bfd_boolean cond_known = FALSE;
389 static const char *const conds[2][2] =
390 {
391 { "[a0] ", "[!a0] " },
392 { "[b0] ", "[!b0] " }
393 };
394
395 cc_field = tic6x_field_from_fmt (fmt, tic6x_field_cc);
396
397 if (cc_field)
398 {
399 unsigned int cc_value;
400
401 cc_value = tic6x_field_bits (opcode, cc_field);
402 s_value = (cc_value & 0x2) >> 1;
403 z_value = (cc_value & 0x1);
404 cond_known = TRUE;
405 }
406 else
407 {
408 const tic6x_insn_field *z_field;
409 const tic6x_insn_field *s_field;
410
411 s_field = tic6x_field_from_fmt (fmt, tic6x_field_s);
412
413 if (!s_field)
414 {
415 printf ("opcode %x: missing compact insn predicate register field (s field)\n",
416 opcode);
417 abort ();
418 }
419 s_value = tic6x_field_bits (opcode, s_field);
420 z_field = tic6x_field_from_fmt (fmt, tic6x_field_z);
421 if (!z_field)
422 {
423 printf ("opcode %x: missing compact insn predicate z_value (z field)\n", opcode);
424 abort ();
425 }
426
427 z_value = tic6x_field_bits (opcode, z_field);
428 cond_known = TRUE;
429 }
430
431 if (!cond_known)
432 {
433 printf ("opcode %x: unspecified ompact insn predicate\n", opcode);
434 abort ();
435 }
436 cond = conds[s_value][z_value];
437 }
438
439 /* All fixed fields must have matching values; all fields with
440 restricted ranges must have values within those ranges. */
441 fixed_ok = TRUE;
442 for (fix = 0; fix < opc->num_fixed_fields; fix++)
443 {
444 unsigned int field_bits;
445 const tic6x_insn_field *const field
446 = tic6x_field_from_fmt (fmt, opc->fixed_fields[fix].field_id);
447
448 if (!field)
449 {
450 printf ("opcode %x: missing field #%d for FIX #%d\n",
451 opcode, opc->fixed_fields[fix].field_id, fix);
452 abort ();
453 }
454
455 field_bits = tic6x_field_bits (opcode, field);
456 if (field_bits < opc->fixed_fields[fix].min_val
457 || field_bits > opc->fixed_fields[fix].max_val)
458 {
459 fixed_ok = FALSE;
460 break;
461 }
462 }
463 if (!fixed_ok)
464 continue;
465
466 /* The instruction matches. */
467
468 /* The p-bit indicates whether this instruction is in parallel
469 with the *next* instruction, whereas the parallel bars
470 indicate the instruction is in parallel with the *previous*
471 instruction. Thus, we must find the p-bit for the previous
472 instruction. */
473 if (num_bits == 16 && (fp_offset & 0x2) == 2)
474 {
475 /* This is the logically second (most significant; second in
476 fp_offset terms because fp_offset relates to logical not
477 physical addresses) instruction of a compact pair; find
478 the p-bit for the first (least significant). */
479 p_bit = header.p_bits[(fp_offset >> 2) << 1];
480 }
481 else if (fp_offset >= 4)
482 {
483 /* Find the last instruction of the previous word in this
484 fetch packet. For compact instructions, this is the most
485 significant 16 bits. */
486 if (fetch_packet_header_based
487 && header.word_compact[(fp_offset >> 2) - 1])
488 p_bit = header.p_bits[(fp_offset >> 1) - 1];
489 else
490 {
491 unsigned int prev_opcode
492 = tic6x_extract_32 (fp + (fp_offset & 0x1c) - 4, info);
493 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
494 }
495 }
496 else
497 {
498 /* Find the last instruction of the previous fetch
499 packet. */
500 unsigned char fp_prev[32];
501
502 status = info->read_memory_func (fp_addr - 32, fp_prev, 32, info);
503 if (status)
504 /* No previous instruction to be parallel with. */
505 p_bit = FALSE;
506 else
507 {
508 bfd_boolean prev_header_based;
509 tic6x_fetch_packet_header prev_header;
510
511 prev_header_based
512 = tic6x_check_fetch_packet_header (fp_prev, &prev_header, info);
513 if (prev_header_based)
514 {
515 if (prev_header.word_compact[6])
516 p_bit = prev_header.p_bits[13];
517 else
518 {
519 unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 24,
520 info);
521 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
522 }
523 }
524 else
525 {
526 unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
527 info);
528 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
529 }
530 }
531 }
532 parallel = p_bit ? "|| " : "";
533
534 if (opc->func_unit == tic6x_func_unit_nfu)
535 func_unit = "";
536 else
537 {
538 unsigned int fld_num;
539 char func_unit_char;
540 const char *data_str;
541 bfd_boolean have_areg = FALSE;
542 bfd_boolean have_cross = FALSE;
543
544 func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
545 func_unit_cross = 0;
546 func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
547
548 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
549 {
550 const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
551 const tic6x_insn_field *field;
552 unsigned int fld_val;
553
554 field = tic6x_field_from_fmt (fmt, enc->field_id);
555
556 if (!field)
557 {
558 printf ("opcode %x: could not retrieve field (field_id:%d)\n",
559 opcode, fld_num);
560 abort ();
561 }
562
563 fld_val = tic6x_field_bits (opcode, field);
564
565 switch (enc->coding_method)
566 {
567 case tic6x_coding_fu:
568 /* The side must be specified exactly once. */
569 if (func_unit_side)
570 {
571 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
572 opcode, fld_num);
573 abort ();
574 }
575 func_unit_side = (fld_val ? 2 : 1);
576 break;
577
578 case tic6x_coding_data_fu:
579 /* The data side must be specified exactly once. */
580 if (func_unit_data_side)
581 {
582 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
583 opcode, fld_num);
584 abort ();
585 }
586 func_unit_data_side = (fld_val ? 2 : 1);
587 break;
588
589 case tic6x_coding_xpath:
590 /* Cross path use must be specified exactly
591 once. */
592 if (have_cross)
593 {
594 printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
595 opcode, fld_num);
596 abort ();
597 }
598 have_cross = TRUE;
599 func_unit_cross = fld_val;
600 break;
601
602 case tic6x_coding_rside:
603 /* If the format has a t field, use it for src/dst register side. */
604 have_t = TRUE;
605 t_val = fld_val;
606 func_unit_data_side = (t_val ? 2 : 1);
607 break;
608
609 case tic6x_coding_areg:
610 have_areg = TRUE;
611 break;
612
613 default:
614 /* Don't relate to functional units. */
615 break;
616 }
617 }
618
619 /* The side of the functional unit used must now have been
620 determined either from the flags or from an instruction
621 field. */
622 if (func_unit_side != 1 && func_unit_side != 2)
623 {
624 printf ("opcode %x: func_unit_side is not encoded!\n", opcode);
625 abort ();
626 }
627
628 /* Cross paths are not applicable when sides are specified
629 for both address and data paths. */
630 if (func_unit_data_side && have_cross)
631 {
632 printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n",
633 opcode);
634 abort ();
635 }
636
637 /* Separate address and data paths are only applicable for
638 the D unit. */
639 if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
640 {
641 printf ("opcode %x: separate address and data paths only applicable for D unit!\n",
642 opcode);
643 abort ();
644 }
645
646 /* If an address register is being used but in ADDA rather
647 than a load or store, it uses a cross path for side-A
648 instructions, and the cross path use is not specified by
649 an instruction field. */
650 if (have_areg && !func_unit_data_side)
651 {
652 if (have_cross)
653 {
654 printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode);
655 abort ();
656 }
657 func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
658 }
659
660 switch (opc->func_unit)
661 {
662 case tic6x_func_unit_d:
663 func_unit_char = 'D';
664 break;
665
666 case tic6x_func_unit_l:
667 func_unit_char = 'L';
668 break;
669
670 case tic6x_func_unit_m:
671 func_unit_char = 'M';
672 break;
673
674 case tic6x_func_unit_s:
675 func_unit_char = 'S';
676 break;
677
678 default:
679 printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
680 abort ();
681 }
682
683 switch (func_unit_data_side)
684 {
685 case 0:
686 data_str = "";
687 break;
688
689 case 1:
690 data_str = "T1";
691 break;
692
693 case 2:
694 data_str = "T2";
695 break;
696
697 default:
698 printf ("opcode %x: illegal data func_unit specifier %d\n",
699 opcode, func_unit_data_side);
700 abort ();
701 }
702
703 if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
704 func_unit_cross = 1;
705
706 snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
707 func_unit_side, (func_unit_cross ? "X" : ""), data_str);
708 func_unit = func_unit_buf;
709 }
710
711 /* For each operand there must be one or more fields set based
712 on that operand, that can together be used to derive the
713 operand value. */
714 operands_ok = TRUE;
715 num_operands = opc->num_operands;
716 for (op_num = 0; op_num < num_operands; op_num++)
717 {
718 unsigned int fld_num;
719 unsigned int mem_base_reg = 0;
720 bfd_boolean mem_base_reg_known = FALSE;
721 bfd_boolean mem_base_reg_known_long = FALSE;
722 unsigned int mem_offset = 0;
723 bfd_boolean mem_offset_known = FALSE;
724 bfd_boolean mem_offset_known_long = FALSE;
725 unsigned int mem_mode = 0;
726 bfd_boolean mem_mode_known = FALSE;
727 unsigned int mem_scaled = 0;
728 bfd_boolean mem_scaled_known = FALSE;
729 unsigned int crlo = 0;
730 bfd_boolean crlo_known = FALSE;
731 unsigned int crhi = 0;
732 bfd_boolean crhi_known = FALSE;
733 bfd_boolean spmask_skip_operand = FALSE;
734 unsigned int fcyc_bits = 0;
735 bfd_boolean prev_sploop_found = FALSE;
736
737 switch (opc->operand_info[op_num].form)
738 {
739 case tic6x_operand_b15reg:
740 /* Fully determined by the functional unit. */
741 operands_text[op_num] = TRUE;
742 snprintf (operands[op_num], 24, "b15");
743 continue;
744
745 case tic6x_operand_zreg:
746 /* Fully determined by the functional unit. */
747 operands_text[op_num] = TRUE;
748 snprintf (operands[op_num], 24, "%c0",
749 (func_unit_side == 2 ? 'b' : 'a'));
750 continue;
751
752 case tic6x_operand_retreg:
753 /* Fully determined by the functional unit. */
754 operands_text[op_num] = TRUE;
755 snprintf (operands[op_num], 24, "%c3",
756 (func_unit_side == 2 ? 'b' : 'a'));
757 continue;
758
759 case tic6x_operand_irp:
760 operands_text[op_num] = TRUE;
761 snprintf (operands[op_num], 24, "irp");
762 continue;
763
764 case tic6x_operand_nrp:
765 operands_text[op_num] = TRUE;
766 snprintf (operands[op_num], 24, "nrp");
767 continue;
768
769 case tic6x_operand_ilc:
770 operands_text[op_num] = TRUE;
771 snprintf (operands[op_num], 24, "ilc");
772 continue;
773
774 case tic6x_operand_hw_const_minus_1:
775 operands_text[op_num] = TRUE;
776 snprintf (operands[op_num], 24, "-1");
777 continue;
778
779 case tic6x_operand_hw_const_0:
780 operands_text[op_num] = TRUE;
781 snprintf (operands[op_num], 24, "0");
782 continue;
783
784 case tic6x_operand_hw_const_1:
785 operands_text[op_num] = TRUE;
786 snprintf (operands[op_num], 24, "1");
787 continue;
788
789 case tic6x_operand_hw_const_5:
790 operands_text[op_num] = TRUE;
791 snprintf (operands[op_num], 24, "5");
792 continue;
793
794 case tic6x_operand_hw_const_16:
795 operands_text[op_num] = TRUE;
796 snprintf (operands[op_num], 24, "16");
797 continue;
798
799 case tic6x_operand_hw_const_24:
800 operands_text[op_num] = TRUE;
801 snprintf (operands[op_num], 24, "24");
802 continue;
803
804 case tic6x_operand_hw_const_31:
805 operands_text[op_num] = TRUE;
806 snprintf (operands[op_num], 24, "31");
807 continue;
808
809 default:
810 break;
811 }
812
813 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
814 {
815 const tic6x_coding_field *const enc
816 = &opc->variable_fields[fld_num];
817 const tic6x_insn_field *field;
818 unsigned int fld_val;
819 unsigned int reg_base = 0;
820 signed int signed_fld_val;
821 char reg_side = '?';
822
823 if (enc->operand_num != op_num)
824 continue;
825 field = tic6x_field_from_fmt (fmt, enc->field_id);
826 if (!field)
827 {
828 printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
829 abort ();
830 }
831 fld_val = tic6x_field_bits (opcode, field);
832 switch (enc->coding_method)
833 {
834 case tic6x_coding_cst_s3i:
835 (fld_val == 0x00) && (fld_val = 0x10);
836 (fld_val == 0x07) && (fld_val = 0x08);
837 /* Fall through. */
838 case tic6x_coding_ucst:
839 case tic6x_coding_ulcst_dpr_byte:
840 case tic6x_coding_ulcst_dpr_half:
841 case tic6x_coding_ulcst_dpr_word:
842 case tic6x_coding_lcst_low16:
843 switch (opc->operand_info[op_num].form)
844 {
845 case tic6x_operand_asm_const:
846 case tic6x_operand_link_const:
847 operands_text[op_num] = TRUE;
848 snprintf (operands[op_num], 24, "%u", fld_val);
849 break;
850
851 case tic6x_operand_mem_long:
852 mem_offset = fld_val;
853 mem_offset_known_long = TRUE;
854 break;
855
856 default:
857 printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
858 abort ();
859 }
860 break;
861
862 case tic6x_coding_lcst_high16:
863 operands_text[op_num] = TRUE;
864 snprintf (operands[op_num], 24, "%u", fld_val << 16);
865 break;
866
867 case tic6x_coding_scst_l3i:
868 operands_text[op_num] = TRUE;
869 if (fld_val == 0)
870 {
871 signed_fld_val = 8;
872 }
873 else
874 {
875 signed_fld_val = (signed int) fld_val;
876 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
877 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
878 }
879 snprintf (operands[op_num], 24, "%d", signed_fld_val);
880 break;
881
882 case tic6x_coding_scst:
883 operands_text[op_num] = TRUE;
884 signed_fld_val = (signed int) fld_val;
885 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
886 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
887 snprintf (operands[op_num], 24, "%d", signed_fld_val);
888 break;
889
890 case tic6x_coding_ucst_minus_one:
891 operands_text[op_num] = TRUE;
892 snprintf (operands[op_num], 24, "%u", fld_val + 1);
893 break;
894
895 case tic6x_coding_pcrel:
896 case tic6x_coding_pcrel_half:
897 signed_fld_val = (signed int) fld_val;
898 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
899 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
900 if (fetch_packet_header_based
901 && enc->coding_method == tic6x_coding_pcrel_half)
902 signed_fld_val *= 2;
903 else
904 signed_fld_val *= 4;
905 operands_pcrel[op_num] = TRUE;
906 operands_addresses[op_num] = fp_addr + signed_fld_val;
907 break;
908
909 case tic6x_coding_regpair_msb:
910 if (opc->operand_info[op_num].form != tic6x_operand_regpair)
911 abort ();
912 operands_text[op_num] = TRUE;
913 snprintf (operands[op_num], 24, "%c%u:%c%u",
914 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
915 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
916 break;
917
918 case tic6x_coding_pcrel_half_unsigned:
919 operands_pcrel[op_num] = TRUE;
920 operands_addresses[op_num] = fp_addr + 2 * fld_val;
921 break;
922
923 case tic6x_coding_reg_shift:
924 fld_val <<= 1;
925 /* Fall through. */
926 case tic6x_coding_reg:
927 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
928 {
929 reg_base = 16;
930 }
931 switch (opc->operand_info[op_num].form)
932 {
933 case tic6x_operand_treg:
934 if (!have_t)
935 {
936 printf ("opcode %x: operand treg but missing t field\n", opcode);
937 abort ();
938 }
939 operands_text[op_num] = TRUE;
940 reg_side = t_val ? 'b' : 'a';
941 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
942 break;
943
944 case tic6x_operand_reg:
945 operands_text[op_num] = TRUE;
946 reg_side = (func_unit_side == 2) ? 'b' : 'a';
947 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
948 break;
949
950 case tic6x_operand_reg_nors:
951 operands_text[op_num] = TRUE;
952 reg_side = (func_unit_side == 2) ? 'b' : 'a';
953 snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
954 break;
955
956 case tic6x_operand_reg_bside:
957 operands_text[op_num] = TRUE;
958 snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
959 break;
960
961 case tic6x_operand_reg_bside_nors:
962 operands_text[op_num] = TRUE;
963 snprintf (operands[op_num], 24, "b%u", fld_val);
964 break;
965
966 case tic6x_operand_xreg:
967 operands_text[op_num] = TRUE;
968 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
969 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
970 break;
971
972 case tic6x_operand_dreg:
973 operands_text[op_num] = TRUE;
974 reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
975 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
976 break;
977
978 case tic6x_operand_regpair:
979 operands_text[op_num] = TRUE;
980 if (fld_val & 1)
981 operands_ok = FALSE;
982 reg_side = (func_unit_side == 2) ? 'b' : 'a';
983 snprintf (operands[op_num], 24, "%c%u:%c%u",
984 reg_side, reg_base + fld_val + 1,
985 reg_side, reg_base + fld_val);
986 break;
987
988 case tic6x_operand_xregpair:
989 operands_text[op_num] = TRUE;
990 if (fld_val & 1)
991 operands_ok = FALSE;
992 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
993 snprintf (operands[op_num], 24, "%c%u:%c%u",
994 reg_side, reg_base + fld_val + 1,
995 reg_side, reg_base + fld_val);
996 break;
997
998 case tic6x_operand_tregpair:
999 if (!have_t)
1000 {
1001 printf ("opcode %x: operand tregpair but missing t field\n", opcode);
1002 abort ();
1003 }
1004 operands_text[op_num] = TRUE;
1005 if (fld_val & 1)
1006 operands_ok = FALSE;
1007 reg_side = t_val ? 'b' : 'a';
1008 snprintf (operands[op_num], 24, "%c%u:%c%u",
1009 reg_side, reg_base + fld_val + 1,
1010 reg_side, reg_base + fld_val);
1011 break;
1012
1013 case tic6x_operand_dregpair:
1014 operands_text[op_num] = TRUE;
1015 if (fld_val & 1)
1016 operands_ok = FALSE;
1017 reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1018 snprintf (operands[op_num], 24, "%c%u:%c%u",
1019 reg_side, reg_base + fld_val + 1,
1020 reg_side, reg_base + fld_val);
1021 break;
1022
1023 case tic6x_operand_mem_deref:
1024 operands_text[op_num] = TRUE;
1025 reg_side = func_unit_side == 2 ? 'b' : 'a';
1026 snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1027 break;
1028
1029 case tic6x_operand_mem_short:
1030 case tic6x_operand_mem_ndw:
1031 mem_base_reg = fld_val;
1032 mem_base_reg_known = TRUE;
1033 break;
1034
1035 default:
1036 printf ("opcode %x: unexpected operand form %d for operand #%d",
1037 opcode, opc->operand_info[op_num].form, op_num);
1038 abort ();
1039 }
1040 break;
1041
1042 case tic6x_coding_reg_ptr:
1043 switch (opc->operand_info[op_num].form)
1044 {
1045 case tic6x_operand_mem_short:
1046 case tic6x_operand_mem_ndw:
1047 if (fld_val > 0x3u)
1048 {
1049 printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
1050 opcode, op_num, fld_val);
1051 abort ();
1052 }
1053 mem_base_reg = 0x4 | fld_val;
1054 mem_base_reg_known = TRUE;
1055 break;
1056
1057 default:
1058 printf ("opcode %x: unexpected operand form %d for operand #%d",
1059 opcode, opc->operand_info[op_num].form, op_num);
1060 abort ();
1061 }
1062 break;
1063
1064 case tic6x_coding_areg:
1065 switch (opc->operand_info[op_num].form)
1066 {
1067 case tic6x_operand_areg:
1068 operands_text[op_num] = TRUE;
1069 snprintf (operands[op_num], 24, "b%u",
1070 fld_val ? 15u : 14u);
1071 break;
1072
1073 case tic6x_operand_mem_long:
1074 mem_base_reg = fld_val ? 15u : 14u;
1075 mem_base_reg_known_long = TRUE;
1076 break;
1077
1078 default:
1079 printf ("opcode %x: bad operand form\n", opcode);
1080 abort ();
1081 }
1082 break;
1083
1084 case tic6x_coding_mem_offset_minus_one_noscale:
1085 case tic6x_coding_mem_offset_minus_one:
1086 fld_val += 1;
1087 /* Fall through. */
1088 case tic6x_coding_mem_offset_noscale:
1089 case tic6x_coding_mem_offset:
1090 mem_offset = fld_val;
1091 mem_offset_known = TRUE;
1092 if (num_bits == 16)
1093 {
1094 mem_mode_known = TRUE;
1095 mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1096 mem_scaled_known = TRUE;
1097 mem_scaled = TRUE;
1098 if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1099 {
1100 mem_base_reg_known = TRUE;
1101 mem_base_reg = 15;
1102 }
1103 if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1104 || enc->coding_method == tic6x_coding_mem_offset_noscale )
1105 mem_scaled = FALSE;
1106 }
1107 break;
1108
1109 case tic6x_coding_mem_mode:
1110 mem_mode = fld_val;
1111 mem_mode_known = TRUE;
1112 break;
1113
1114 case tic6x_coding_scaled:
1115 mem_scaled = fld_val;
1116 mem_scaled_known = TRUE;
1117 break;
1118
1119 case tic6x_coding_crlo:
1120 crlo = fld_val;
1121 crlo_known = TRUE;
1122 break;
1123
1124 case tic6x_coding_crhi:
1125 crhi = fld_val;
1126 crhi_known = TRUE;
1127 break;
1128
1129 case tic6x_coding_fstg:
1130 case tic6x_coding_fcyc:
1131 if (!prev_sploop_found)
1132 {
1133 bfd_vma search_fp_addr = fp_addr;
1134 bfd_vma search_fp_offset = fp_offset;
1135 bfd_boolean search_fp_header_based
1136 = fetch_packet_header_based;
1137 tic6x_fetch_packet_header search_fp_header = header;
1138 unsigned char search_fp[32];
1139 unsigned int search_num_bits;
1140 unsigned int search_opcode;
1141 unsigned int sploop_ii = 0;
1142 int i;
1143
1144 memcpy (search_fp, fp, 32);
1145
1146 /* To interpret these bits in an SPKERNEL
1147 instruction, we must find the previous
1148 SPLOOP-family instruction. It may come up to
1149 48 execute packets earlier. */
1150 for (i = 0; i < 48 * 8; i++)
1151 {
1152 /* Find the previous instruction. */
1153 if (search_fp_offset & 2)
1154 search_fp_offset -= 2;
1155 else if (search_fp_offset >= 4)
1156 {
1157 if (search_fp_header_based
1158 && (search_fp_header.word_compact
1159 [(search_fp_offset >> 2) - 1]))
1160 search_fp_offset -= 2;
1161 else
1162 search_fp_offset -= 4;
1163 }
1164 else
1165 {
1166 search_fp_addr -= 32;
1167 status = info->read_memory_func (search_fp_addr,
1168 search_fp,
1169 32, info);
1170 if (status)
1171 /* No previous SPLOOP instruction. */
1172 break;
1173 search_fp_header_based
1174 = (tic6x_check_fetch_packet_header
1175 (search_fp, &search_fp_header, info));
1176 if (search_fp_header_based)
1177 search_fp_offset
1178 = search_fp_header.word_compact[6] ? 26 : 24;
1179 else
1180 search_fp_offset = 28;
1181 }
1182
1183 /* Extract the previous instruction. */
1184 if (search_fp_header_based)
1185 search_num_bits
1186 = (search_fp_header.word_compact[search_fp_offset
1187 >> 2]
1188 ? 16
1189 : 32);
1190 else
1191 search_num_bits = 32;
1192 if (search_num_bits == 16)
1193 {
1194 if (info->endian == BFD_ENDIAN_LITTLE)
1195 search_opcode
1196 = (tic6x_extract_16
1197 (search_fp + search_fp_offset, &header, info));
1198 else
1199 search_opcode
1200 = (tic6x_extract_16
1201 (search_fp + (search_fp_offset ^ 2), &header,
1202 info));
1203 }
1204 else
1205 search_opcode
1206 = tic6x_extract_32 (search_fp + search_fp_offset,
1207 info);
1208
1209 /* Check whether it is an SPLOOP-family
1210 instruction. */
1211 if (search_num_bits == 32
1212 && ((search_opcode & 0x003ffffe) == 0x00038000
1213 || (search_opcode & 0x003ffffe) == 0x0003a000
1214 || ((search_opcode & 0x003ffffe)
1215 == 0x0003e000)))
1216 {
1217 prev_sploop_found = TRUE;
1218 sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1219 }
1220 else if (search_num_bits == 16
1221 && (search_opcode & 0x3c7e) == 0x0c66)
1222 {
1223 prev_sploop_found = TRUE;
1224 sploop_ii
1225 = (((search_opcode >> 7) & 0x7)
1226 | ((search_opcode >> 11) & 0x8)) + 1;
1227 }
1228 if (prev_sploop_found)
1229 {
1230 if (sploop_ii <= 0)
1231 {
1232 printf ("opcode %x: sloop index not found (%d)\n", opcode, sploop_ii);
1233 abort ();
1234 }
1235 else if (sploop_ii <= 1)
1236 fcyc_bits = 0;
1237 else if (sploop_ii <= 2)
1238 fcyc_bits = 1;
1239 else if (sploop_ii <= 4)
1240 fcyc_bits = 2;
1241 else if (sploop_ii <= 8)
1242 fcyc_bits = 3;
1243 else if (sploop_ii <= 14)
1244 fcyc_bits = 4;
1245 else
1246 prev_sploop_found = FALSE;
1247 }
1248 if (prev_sploop_found)
1249 break;
1250 }
1251 }
1252 if (!prev_sploop_found)
1253 {
1254 operands_ok = FALSE;
1255 operands_text[op_num] = TRUE;
1256 break;
1257 }
1258 if (fcyc_bits > tic6x_field_width(field))
1259 {
1260 printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1261 abort ();
1262 }
1263 if (enc->coding_method == tic6x_coding_fstg)
1264 {
1265 int i, t;
1266 for (t = 0, i = fcyc_bits; i < 6; i++)
1267 t = (t << 1) | ((fld_val >> i) & 1);
1268 operands_text[op_num] = TRUE;
1269 snprintf (operands[op_num], 24, "%u", t);
1270 }
1271 else
1272 {
1273 operands_text[op_num] = TRUE;
1274 snprintf (operands[op_num], 24, "%u",
1275 fld_val & ((1 << fcyc_bits) - 1));
1276 }
1277 break;
1278
1279 case tic6x_coding_spmask:
1280 if (fld_val == 0)
1281 spmask_skip_operand = TRUE;
1282 else
1283 {
1284 char *p;
1285 unsigned int i;
1286
1287 operands_text[op_num] = TRUE;
1288 p = operands[op_num];
1289 for (i = 0; i < 8; i++)
1290 if (fld_val & (1 << i))
1291 {
1292 *p++ = "LSDM"[i/2];
1293 *p++ = '1' + (i & 1);
1294 *p++ = ',';
1295 }
1296 p[-1] = 0;
1297 }
1298 break;
1299
1300 case tic6x_coding_fu:
1301 case tic6x_coding_data_fu:
1302 case tic6x_coding_xpath:
1303 case tic6x_coding_rside:
1304 /* Don't relate to operands, so operand number is
1305 meaningless. */
1306 break;
1307
1308 default:
1309 printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1310 abort ();
1311 }
1312
1313 if (mem_base_reg_known_long && mem_offset_known_long)
1314 {
1315 if (operands_text[op_num] || operands_pcrel[op_num])
1316 {
1317 printf ("opcode %x: long access but operands already known ?\n", opcode);
1318 abort ();
1319 }
1320 operands_text[op_num] = TRUE;
1321 snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1322 mem_offset * opc->operand_info[op_num].size);
1323 }
1324
1325 if (mem_base_reg_known && mem_offset_known && mem_mode_known
1326 && (mem_scaled_known
1327 || (opc->operand_info[op_num].form
1328 != tic6x_operand_mem_ndw)))
1329 {
1330 char side;
1331 char base[4];
1332 bfd_boolean offset_is_reg;
1333 bfd_boolean offset_scaled;
1334 char offset[4];
1335 char offsetp[6];
1336
1337 if (operands_text[op_num] || operands_pcrel[op_num])
1338 {
1339 printf ("opcode %x: mem access operands already known ?\n", opcode);
1340 abort ();
1341 }
1342
1343 side = func_unit_side == 2 ? 'b' : 'a';
1344 snprintf (base, 4, "%c%u", side, mem_base_reg);
1345
1346 offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
1347 if (offset_is_reg)
1348 {
1349
1350 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1351 {
1352 reg_base = 16;
1353 }
1354 snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1355 if (opc->operand_info[op_num].form
1356 == tic6x_operand_mem_ndw)
1357 offset_scaled = mem_scaled ? TRUE : FALSE;
1358 else
1359 offset_scaled = TRUE;
1360 }
1361 else
1362 {
1363 if (opc->operand_info[op_num].form
1364 == tic6x_operand_mem_ndw)
1365 {
1366 offset_scaled = mem_scaled ? TRUE : FALSE;
1367 snprintf (offset, 4, "%u", mem_offset);
1368 }
1369 else
1370 {
1371 offset_scaled = FALSE;
1372 snprintf (offset, 4, "%u",
1373 (mem_offset
1374 * opc->operand_info[op_num].size));
1375 }
1376 }
1377
1378 if (offset_scaled)
1379 snprintf (offsetp, 6, "[%s]", offset);
1380 else
1381 snprintf (offsetp, 6, "(%s)", offset);
1382
1383 operands_text[op_num] = TRUE;
1384 switch (mem_mode & ~4u)
1385 {
1386 case 0:
1387 snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1388 break;
1389
1390 case 1:
1391 snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1392 break;
1393
1394 case 2:
1395 case 3:
1396 operands_ok = FALSE;
1397 break;
1398
1399 case 8:
1400 snprintf (operands[op_num], 24, "*--%s%s", base,
1401 offsetp);
1402 break;
1403
1404 case 9:
1405 snprintf (operands[op_num], 24, "*++%s%s", base,
1406 offsetp);
1407 break;
1408
1409 case 10:
1410 snprintf (operands[op_num], 24, "*%s--%s", base,
1411 offsetp);
1412 break;
1413
1414 case 11:
1415 snprintf (operands[op_num], 24, "*%s++%s", base,
1416 offsetp);
1417 break;
1418
1419 default:
1420 printf ("*** unknown mem_mode : %d \n", mem_mode);
1421 abort ();
1422 }
1423 }
1424
1425 if (crlo_known && crhi_known)
1426 {
1427 tic6x_rw rw;
1428 tic6x_ctrl_id crid;
1429
1430 if (operands_text[op_num] || operands_pcrel[op_num])
1431 {
1432 printf ("*** abort crlo crli\n");
1433 abort ();
1434 }
1435
1436 rw = opc->operand_info[op_num].rw;
1437 if (rw != tic6x_rw_read
1438 && rw != tic6x_rw_write)
1439 {
1440 printf ("*** abort rw : %d\n", rw);
1441 abort ();
1442 }
1443
1444 for (crid = 0; crid < tic6x_ctrl_max; crid++)
1445 {
1446 if (crlo == tic6x_ctrl_table[crid].crlo
1447 && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1448 && (rw == tic6x_rw_read
1449 ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1450 || (tic6x_ctrl_table[crid].rw
1451 == tic6x_rw_read_write))
1452 : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1453 || (tic6x_ctrl_table[crid].rw
1454 == tic6x_rw_read_write))))
1455 break;
1456 }
1457 if (crid == tic6x_ctrl_max)
1458 {
1459 operands_text[op_num] = TRUE;
1460 operands_ok = FALSE;
1461 }
1462 else
1463 {
1464 operands_text[op_num] = TRUE;
1465 snprintf (operands[op_num], 24, "%s",
1466 tic6x_ctrl_table[crid].name);
1467 }
1468 }
1469
1470 if (operands_text[op_num] || operands_pcrel[op_num]
1471 || spmask_skip_operand)
1472 break;
1473 }
1474 /* end for fld_num */
1475
1476 if (spmask_skip_operand)
1477 {
1478 /* SPMASK operands are only valid as the single operand
1479 in the opcode table. */
1480 if (num_operands != 1)
1481 {
1482 printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
1483 abort ();
1484 }
1485 num_operands = 0;
1486 break;
1487 }
1488
1489 /* The operand must by now have been decoded. */
1490 if (!operands_text[op_num] && !operands_pcrel[op_num])
1491 {
1492 printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
1493 abort ();
1494 }
1495 }
1496 /* end for op_num */
1497
1498 if (!operands_ok)
1499 continue;
1500
1501 info->bytes_per_chunk = num_bits / 8;
1502 info->fprintf_func (info->stream, "%s", parallel);
1503 info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1504 func_unit);
1505 for (op_num = 0; op_num < num_operands; op_num++)
1506 {
1507 info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1508 if (operands_pcrel[op_num])
1509 info->print_address_func (operands_addresses[op_num], info);
1510 else
1511 info->fprintf_func (info->stream, "%s", operands[op_num]);
1512 }
1513 if (fetch_packet_header_based && header.prot)
1514 info->fprintf_func (info->stream, " || nop 5");
1515
1516 return num_bits / 8;
1517 }
1518
1519 info->bytes_per_chunk = num_bits / 8;
1520 info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1521 (int) num_bits / 4, opcode);
1522 return num_bits / 8;
1523 }
This page took 0.085825 seconds and 5 git commands to generate.