Automatic date update in version.in
[deliverable/binutils-gdb.git] / opcodes / tic6x-dis.c
1 /* TI C6X disassembler.
2 Copyright (C) 2010-2019 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 "disassemble.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) | ((unsigned) p[3] << 24);
167 else
168 return p[3] | (p[2] << 8) | (p[1] << 16) | ((unsigned) 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[8];
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, sizeof func_unit_buf, " .%c%u%s%s",
707 func_unit_char, func_unit_side,
708 (func_unit_cross ? "X" : ""), data_str);
709 func_unit = func_unit_buf;
710 }
711
712 /* For each operand there must be one or more fields set based
713 on that operand, that can together be used to derive the
714 operand value. */
715 operands_ok = TRUE;
716 num_operands = opc->num_operands;
717 for (op_num = 0; op_num < num_operands; op_num++)
718 {
719 unsigned int fld_num;
720 unsigned int mem_base_reg = 0;
721 bfd_boolean mem_base_reg_known = FALSE;
722 bfd_boolean mem_base_reg_known_long = FALSE;
723 unsigned int mem_offset = 0;
724 bfd_boolean mem_offset_known = FALSE;
725 bfd_boolean mem_offset_known_long = FALSE;
726 unsigned int mem_mode = 0;
727 bfd_boolean mem_mode_known = FALSE;
728 unsigned int mem_scaled = 0;
729 bfd_boolean mem_scaled_known = FALSE;
730 unsigned int crlo = 0;
731 bfd_boolean crlo_known = FALSE;
732 unsigned int crhi = 0;
733 bfd_boolean crhi_known = FALSE;
734 bfd_boolean spmask_skip_operand = FALSE;
735 unsigned int fcyc_bits = 0;
736 bfd_boolean prev_sploop_found = FALSE;
737
738 switch (opc->operand_info[op_num].form)
739 {
740 case tic6x_operand_b15reg:
741 /* Fully determined by the functional unit. */
742 operands_text[op_num] = TRUE;
743 snprintf (operands[op_num], 24, "b15");
744 continue;
745
746 case tic6x_operand_zreg:
747 /* Fully determined by the functional unit. */
748 operands_text[op_num] = TRUE;
749 snprintf (operands[op_num], 24, "%c0",
750 (func_unit_side == 2 ? 'b' : 'a'));
751 continue;
752
753 case tic6x_operand_retreg:
754 /* Fully determined by the functional unit. */
755 operands_text[op_num] = TRUE;
756 snprintf (operands[op_num], 24, "%c3",
757 (func_unit_side == 2 ? 'b' : 'a'));
758 continue;
759
760 case tic6x_operand_irp:
761 operands_text[op_num] = TRUE;
762 snprintf (operands[op_num], 24, "irp");
763 continue;
764
765 case tic6x_operand_nrp:
766 operands_text[op_num] = TRUE;
767 snprintf (operands[op_num], 24, "nrp");
768 continue;
769
770 case tic6x_operand_ilc:
771 operands_text[op_num] = TRUE;
772 snprintf (operands[op_num], 24, "ilc");
773 continue;
774
775 case tic6x_operand_hw_const_minus_1:
776 operands_text[op_num] = TRUE;
777 snprintf (operands[op_num], 24, "-1");
778 continue;
779
780 case tic6x_operand_hw_const_0:
781 operands_text[op_num] = TRUE;
782 snprintf (operands[op_num], 24, "0");
783 continue;
784
785 case tic6x_operand_hw_const_1:
786 operands_text[op_num] = TRUE;
787 snprintf (operands[op_num], 24, "1");
788 continue;
789
790 case tic6x_operand_hw_const_5:
791 operands_text[op_num] = TRUE;
792 snprintf (operands[op_num], 24, "5");
793 continue;
794
795 case tic6x_operand_hw_const_16:
796 operands_text[op_num] = TRUE;
797 snprintf (operands[op_num], 24, "16");
798 continue;
799
800 case tic6x_operand_hw_const_24:
801 operands_text[op_num] = TRUE;
802 snprintf (operands[op_num], 24, "24");
803 continue;
804
805 case tic6x_operand_hw_const_31:
806 operands_text[op_num] = TRUE;
807 snprintf (operands[op_num], 24, "31");
808 continue;
809
810 default:
811 break;
812 }
813
814 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
815 {
816 const tic6x_coding_field *const enc
817 = &opc->variable_fields[fld_num];
818 const tic6x_insn_field *field;
819 unsigned int fld_val;
820 unsigned int reg_base = 0;
821 signed int signed_fld_val;
822 char reg_side = '?';
823
824 if (enc->operand_num != op_num)
825 continue;
826 field = tic6x_field_from_fmt (fmt, enc->field_id);
827 if (!field)
828 {
829 printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
830 abort ();
831 }
832 fld_val = tic6x_field_bits (opcode, field);
833 switch (enc->coding_method)
834 {
835 case tic6x_coding_cst_s3i:
836 (fld_val == 0x00) && (fld_val = 0x10);
837 (fld_val == 0x07) && (fld_val = 0x08);
838 /* Fall through. */
839 case tic6x_coding_ucst:
840 case tic6x_coding_ulcst_dpr_byte:
841 case tic6x_coding_ulcst_dpr_half:
842 case tic6x_coding_ulcst_dpr_word:
843 case tic6x_coding_lcst_low16:
844 switch (opc->operand_info[op_num].form)
845 {
846 case tic6x_operand_asm_const:
847 case tic6x_operand_link_const:
848 operands_text[op_num] = TRUE;
849 snprintf (operands[op_num], 24, "%u", fld_val);
850 break;
851
852 case tic6x_operand_mem_long:
853 mem_offset = fld_val;
854 mem_offset_known_long = TRUE;
855 break;
856
857 default:
858 printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
859 abort ();
860 }
861 break;
862
863 case tic6x_coding_lcst_high16:
864 operands_text[op_num] = TRUE;
865 snprintf (operands[op_num], 24, "%u", fld_val << 16);
866 break;
867
868 case tic6x_coding_scst_l3i:
869 operands_text[op_num] = TRUE;
870 if (fld_val == 0)
871 {
872 signed_fld_val = 8;
873 }
874 else
875 {
876 signed_fld_val = (signed int) fld_val;
877 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
878 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
879 }
880 snprintf (operands[op_num], 24, "%d", signed_fld_val);
881 break;
882
883 case tic6x_coding_scst:
884 operands_text[op_num] = TRUE;
885 signed_fld_val = (signed int) fld_val;
886 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
887 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
888 snprintf (operands[op_num], 24, "%d", signed_fld_val);
889 break;
890
891 case tic6x_coding_ucst_minus_one:
892 operands_text[op_num] = TRUE;
893 snprintf (operands[op_num], 24, "%u", fld_val + 1);
894 break;
895
896 case tic6x_coding_pcrel:
897 case tic6x_coding_pcrel_half:
898 signed_fld_val = (signed int) fld_val;
899 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
900 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
901 if (fetch_packet_header_based
902 && enc->coding_method == tic6x_coding_pcrel_half)
903 signed_fld_val *= 2;
904 else
905 signed_fld_val *= 4;
906 operands_pcrel[op_num] = TRUE;
907 operands_addresses[op_num] = fp_addr + signed_fld_val;
908 break;
909
910 case tic6x_coding_regpair_msb:
911 if (opc->operand_info[op_num].form != tic6x_operand_regpair)
912 abort ();
913 operands_text[op_num] = TRUE;
914 snprintf (operands[op_num], 24, "%c%u:%c%u",
915 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
916 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
917 break;
918
919 case tic6x_coding_pcrel_half_unsigned:
920 operands_pcrel[op_num] = TRUE;
921 operands_addresses[op_num] = fp_addr + 2 * fld_val;
922 break;
923
924 case tic6x_coding_reg_shift:
925 fld_val <<= 1;
926 /* Fall through. */
927 case tic6x_coding_reg:
928 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
929 {
930 reg_base = 16;
931 }
932 switch (opc->operand_info[op_num].form)
933 {
934 case tic6x_operand_treg:
935 if (!have_t)
936 {
937 printf ("opcode %x: operand treg but missing t field\n", opcode);
938 abort ();
939 }
940 operands_text[op_num] = TRUE;
941 reg_side = t_val ? 'b' : 'a';
942 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
943 break;
944
945 case tic6x_operand_reg:
946 operands_text[op_num] = TRUE;
947 reg_side = (func_unit_side == 2) ? 'b' : 'a';
948 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
949 break;
950
951 case tic6x_operand_reg_nors:
952 operands_text[op_num] = TRUE;
953 reg_side = (func_unit_side == 2) ? 'b' : 'a';
954 snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
955 break;
956
957 case tic6x_operand_reg_bside:
958 operands_text[op_num] = TRUE;
959 snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
960 break;
961
962 case tic6x_operand_reg_bside_nors:
963 operands_text[op_num] = TRUE;
964 snprintf (operands[op_num], 24, "b%u", fld_val);
965 break;
966
967 case tic6x_operand_xreg:
968 operands_text[op_num] = TRUE;
969 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
970 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
971 break;
972
973 case tic6x_operand_dreg:
974 operands_text[op_num] = TRUE;
975 reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
976 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
977 break;
978
979 case tic6x_operand_regpair:
980 operands_text[op_num] = TRUE;
981 if (fld_val & 1)
982 operands_ok = FALSE;
983 reg_side = (func_unit_side == 2) ? 'b' : 'a';
984 snprintf (operands[op_num], 24, "%c%u:%c%u",
985 reg_side, reg_base + fld_val + 1,
986 reg_side, reg_base + fld_val);
987 break;
988
989 case tic6x_operand_xregpair:
990 operands_text[op_num] = TRUE;
991 if (fld_val & 1)
992 operands_ok = FALSE;
993 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
994 snprintf (operands[op_num], 24, "%c%u:%c%u",
995 reg_side, reg_base + fld_val + 1,
996 reg_side, reg_base + fld_val);
997 break;
998
999 case tic6x_operand_tregpair:
1000 if (!have_t)
1001 {
1002 printf ("opcode %x: operand tregpair but missing t field\n", opcode);
1003 abort ();
1004 }
1005 operands_text[op_num] = TRUE;
1006 if (fld_val & 1)
1007 operands_ok = FALSE;
1008 reg_side = t_val ? 'b' : 'a';
1009 snprintf (operands[op_num], 24, "%c%u:%c%u",
1010 reg_side, reg_base + fld_val + 1,
1011 reg_side, reg_base + fld_val);
1012 break;
1013
1014 case tic6x_operand_dregpair:
1015 operands_text[op_num] = TRUE;
1016 if (fld_val & 1)
1017 operands_ok = FALSE;
1018 reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
1019 snprintf (operands[op_num], 24, "%c%u:%c%u",
1020 reg_side, reg_base + fld_val + 1,
1021 reg_side, reg_base + fld_val);
1022 break;
1023
1024 case tic6x_operand_mem_deref:
1025 operands_text[op_num] = TRUE;
1026 reg_side = func_unit_side == 2 ? 'b' : 'a';
1027 snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
1028 break;
1029
1030 case tic6x_operand_mem_short:
1031 case tic6x_operand_mem_ndw:
1032 mem_base_reg = fld_val;
1033 mem_base_reg_known = TRUE;
1034 break;
1035
1036 default:
1037 printf ("opcode %x: unexpected operand form %d for operand #%d",
1038 opcode, opc->operand_info[op_num].form, op_num);
1039 abort ();
1040 }
1041 break;
1042
1043 case tic6x_coding_reg_ptr:
1044 switch (opc->operand_info[op_num].form)
1045 {
1046 case tic6x_operand_mem_short:
1047 case tic6x_operand_mem_ndw:
1048 if (fld_val > 0x3u)
1049 {
1050 printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
1051 opcode, op_num, fld_val);
1052 abort ();
1053 }
1054 mem_base_reg = 0x4 | fld_val;
1055 mem_base_reg_known = TRUE;
1056 break;
1057
1058 default:
1059 printf ("opcode %x: unexpected operand form %d for operand #%d",
1060 opcode, opc->operand_info[op_num].form, op_num);
1061 abort ();
1062 }
1063 break;
1064
1065 case tic6x_coding_areg:
1066 switch (opc->operand_info[op_num].form)
1067 {
1068 case tic6x_operand_areg:
1069 operands_text[op_num] = TRUE;
1070 snprintf (operands[op_num], 24, "b%u",
1071 fld_val ? 15u : 14u);
1072 break;
1073
1074 case tic6x_operand_mem_long:
1075 mem_base_reg = fld_val ? 15u : 14u;
1076 mem_base_reg_known_long = TRUE;
1077 break;
1078
1079 default:
1080 printf ("opcode %x: bad operand form\n", opcode);
1081 abort ();
1082 }
1083 break;
1084
1085 case tic6x_coding_mem_offset_minus_one_noscale:
1086 case tic6x_coding_mem_offset_minus_one:
1087 fld_val += 1;
1088 /* Fall through. */
1089 case tic6x_coding_mem_offset_noscale:
1090 case tic6x_coding_mem_offset:
1091 mem_offset = fld_val;
1092 mem_offset_known = TRUE;
1093 if (num_bits == 16)
1094 {
1095 mem_mode_known = TRUE;
1096 mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1097 mem_scaled_known = TRUE;
1098 mem_scaled = TRUE;
1099 if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1100 {
1101 mem_base_reg_known = TRUE;
1102 mem_base_reg = 15;
1103 }
1104 if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1105 || enc->coding_method == tic6x_coding_mem_offset_noscale )
1106 mem_scaled = FALSE;
1107 }
1108 break;
1109
1110 case tic6x_coding_mem_mode:
1111 mem_mode = fld_val;
1112 mem_mode_known = TRUE;
1113 break;
1114
1115 case tic6x_coding_scaled:
1116 mem_scaled = fld_val;
1117 mem_scaled_known = TRUE;
1118 break;
1119
1120 case tic6x_coding_crlo:
1121 crlo = fld_val;
1122 crlo_known = TRUE;
1123 break;
1124
1125 case tic6x_coding_crhi:
1126 crhi = fld_val;
1127 crhi_known = TRUE;
1128 break;
1129
1130 case tic6x_coding_fstg:
1131 case tic6x_coding_fcyc:
1132 if (!prev_sploop_found)
1133 {
1134 bfd_vma search_fp_addr = fp_addr;
1135 bfd_vma search_fp_offset = fp_offset;
1136 bfd_boolean search_fp_header_based
1137 = fetch_packet_header_based;
1138 tic6x_fetch_packet_header search_fp_header = header;
1139 unsigned char search_fp[32];
1140 unsigned int search_num_bits;
1141 unsigned int search_opcode;
1142 unsigned int sploop_ii = 0;
1143 int i;
1144
1145 memcpy (search_fp, fp, 32);
1146
1147 /* To interpret these bits in an SPKERNEL
1148 instruction, we must find the previous
1149 SPLOOP-family instruction. It may come up to
1150 48 execute packets earlier. */
1151 for (i = 0; i < 48 * 8; i++)
1152 {
1153 /* Find the previous instruction. */
1154 if (search_fp_offset & 2)
1155 search_fp_offset -= 2;
1156 else if (search_fp_offset >= 4)
1157 {
1158 if (search_fp_header_based
1159 && (search_fp_header.word_compact
1160 [(search_fp_offset >> 2) - 1]))
1161 search_fp_offset -= 2;
1162 else
1163 search_fp_offset -= 4;
1164 }
1165 else
1166 {
1167 search_fp_addr -= 32;
1168 status = info->read_memory_func (search_fp_addr,
1169 search_fp,
1170 32, info);
1171 if (status)
1172 /* No previous SPLOOP instruction. */
1173 break;
1174 search_fp_header_based
1175 = (tic6x_check_fetch_packet_header
1176 (search_fp, &search_fp_header, info));
1177 if (search_fp_header_based)
1178 search_fp_offset
1179 = search_fp_header.word_compact[6] ? 26 : 24;
1180 else
1181 search_fp_offset = 28;
1182 }
1183
1184 /* Extract the previous instruction. */
1185 if (search_fp_header_based)
1186 search_num_bits
1187 = (search_fp_header.word_compact[search_fp_offset
1188 >> 2]
1189 ? 16
1190 : 32);
1191 else
1192 search_num_bits = 32;
1193 if (search_num_bits == 16)
1194 {
1195 if (info->endian == BFD_ENDIAN_LITTLE)
1196 search_opcode
1197 = (tic6x_extract_16
1198 (search_fp + search_fp_offset, &header, info));
1199 else
1200 search_opcode
1201 = (tic6x_extract_16
1202 (search_fp + (search_fp_offset ^ 2), &header,
1203 info));
1204 }
1205 else
1206 search_opcode
1207 = tic6x_extract_32 (search_fp + search_fp_offset,
1208 info);
1209
1210 /* Check whether it is an SPLOOP-family
1211 instruction. */
1212 if (search_num_bits == 32
1213 && ((search_opcode & 0x003ffffe) == 0x00038000
1214 || (search_opcode & 0x003ffffe) == 0x0003a000
1215 || ((search_opcode & 0x003ffffe)
1216 == 0x0003e000)))
1217 {
1218 prev_sploop_found = TRUE;
1219 sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1220 }
1221 else if (search_num_bits == 16
1222 && (search_opcode & 0x3c7e) == 0x0c66)
1223 {
1224 prev_sploop_found = TRUE;
1225 sploop_ii
1226 = (((search_opcode >> 7) & 0x7)
1227 | ((search_opcode >> 11) & 0x8)) + 1;
1228 }
1229 if (prev_sploop_found)
1230 {
1231 if (sploop_ii <= 0)
1232 {
1233 printf ("opcode %x: sloop index not found (%d)\n", opcode, sploop_ii);
1234 abort ();
1235 }
1236 else if (sploop_ii <= 1)
1237 fcyc_bits = 0;
1238 else if (sploop_ii <= 2)
1239 fcyc_bits = 1;
1240 else if (sploop_ii <= 4)
1241 fcyc_bits = 2;
1242 else if (sploop_ii <= 8)
1243 fcyc_bits = 3;
1244 else if (sploop_ii <= 14)
1245 fcyc_bits = 4;
1246 else
1247 prev_sploop_found = FALSE;
1248 }
1249 if (prev_sploop_found)
1250 break;
1251 }
1252 }
1253 if (!prev_sploop_found)
1254 {
1255 operands_ok = FALSE;
1256 operands_text[op_num] = TRUE;
1257 break;
1258 }
1259 if (fcyc_bits > tic6x_field_width(field))
1260 {
1261 printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1262 abort ();
1263 }
1264 if (enc->coding_method == tic6x_coding_fstg)
1265 {
1266 int i, t;
1267 for (t = 0, i = fcyc_bits; i < 6; i++)
1268 t = (t << 1) | ((fld_val >> i) & 1);
1269 operands_text[op_num] = TRUE;
1270 snprintf (operands[op_num], 24, "%u", t);
1271 }
1272 else
1273 {
1274 operands_text[op_num] = TRUE;
1275 snprintf (operands[op_num], 24, "%u",
1276 fld_val & ((1 << fcyc_bits) - 1));
1277 }
1278 break;
1279
1280 case tic6x_coding_spmask:
1281 if (fld_val == 0)
1282 spmask_skip_operand = TRUE;
1283 else
1284 {
1285 char *p;
1286 unsigned int i;
1287
1288 operands_text[op_num] = TRUE;
1289 p = operands[op_num];
1290 for (i = 0; i < 8; i++)
1291 if (fld_val & (1 << i))
1292 {
1293 *p++ = "LSDM"[i/2];
1294 *p++ = '1' + (i & 1);
1295 *p++ = ',';
1296 }
1297 p[-1] = 0;
1298 }
1299 break;
1300
1301 case tic6x_coding_fu:
1302 case tic6x_coding_data_fu:
1303 case tic6x_coding_xpath:
1304 case tic6x_coding_rside:
1305 /* Don't relate to operands, so operand number is
1306 meaningless. */
1307 break;
1308
1309 default:
1310 printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
1311 abort ();
1312 }
1313
1314 if (mem_base_reg_known_long && mem_offset_known_long)
1315 {
1316 if (operands_text[op_num] || operands_pcrel[op_num])
1317 {
1318 printf ("opcode %x: long access but operands already known ?\n", opcode);
1319 abort ();
1320 }
1321 operands_text[op_num] = TRUE;
1322 snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1323 mem_offset * opc->operand_info[op_num].size);
1324 }
1325
1326 if (mem_base_reg_known && mem_offset_known && mem_mode_known
1327 && (mem_scaled_known
1328 || (opc->operand_info[op_num].form
1329 != tic6x_operand_mem_ndw)))
1330 {
1331 char side;
1332 char base[4];
1333 bfd_boolean offset_is_reg;
1334 bfd_boolean offset_scaled;
1335 char offset[4];
1336 char offsetp[6];
1337
1338 if (operands_text[op_num] || operands_pcrel[op_num])
1339 {
1340 printf ("opcode %x: mem access operands already known ?\n", opcode);
1341 abort ();
1342 }
1343
1344 side = func_unit_side == 2 ? 'b' : 'a';
1345 snprintf (base, 4, "%c%u", side, mem_base_reg);
1346
1347 offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
1348 if (offset_is_reg)
1349 {
1350
1351 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1352 {
1353 reg_base = 16;
1354 }
1355 snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
1356 if (opc->operand_info[op_num].form
1357 == tic6x_operand_mem_ndw)
1358 offset_scaled = mem_scaled ? TRUE : FALSE;
1359 else
1360 offset_scaled = TRUE;
1361 }
1362 else
1363 {
1364 if (opc->operand_info[op_num].form
1365 == tic6x_operand_mem_ndw)
1366 {
1367 offset_scaled = mem_scaled ? TRUE : FALSE;
1368 snprintf (offset, 4, "%u", mem_offset);
1369 }
1370 else
1371 {
1372 offset_scaled = FALSE;
1373 snprintf (offset, 4, "%u",
1374 (mem_offset
1375 * opc->operand_info[op_num].size));
1376 }
1377 }
1378
1379 if (offset_scaled)
1380 snprintf (offsetp, 6, "[%s]", offset);
1381 else
1382 snprintf (offsetp, 6, "(%s)", offset);
1383
1384 operands_text[op_num] = TRUE;
1385 switch (mem_mode & ~4u)
1386 {
1387 case 0:
1388 snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1389 break;
1390
1391 case 1:
1392 snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1393 break;
1394
1395 case 2:
1396 case 3:
1397 operands_ok = FALSE;
1398 break;
1399
1400 case 8:
1401 snprintf (operands[op_num], 24, "*--%s%s", base,
1402 offsetp);
1403 break;
1404
1405 case 9:
1406 snprintf (operands[op_num], 24, "*++%s%s", base,
1407 offsetp);
1408 break;
1409
1410 case 10:
1411 snprintf (operands[op_num], 24, "*%s--%s", base,
1412 offsetp);
1413 break;
1414
1415 case 11:
1416 snprintf (operands[op_num], 24, "*%s++%s", base,
1417 offsetp);
1418 break;
1419
1420 default:
1421 printf ("*** unknown mem_mode : %d \n", mem_mode);
1422 abort ();
1423 }
1424 }
1425
1426 if (crlo_known && crhi_known)
1427 {
1428 tic6x_rw rw;
1429 tic6x_ctrl_id crid;
1430
1431 if (operands_text[op_num] || operands_pcrel[op_num])
1432 {
1433 printf ("*** abort crlo crli\n");
1434 abort ();
1435 }
1436
1437 rw = opc->operand_info[op_num].rw;
1438 if (rw != tic6x_rw_read
1439 && rw != tic6x_rw_write)
1440 {
1441 printf ("*** abort rw : %d\n", rw);
1442 abort ();
1443 }
1444
1445 for (crid = 0; crid < tic6x_ctrl_max; crid++)
1446 {
1447 if (crlo == tic6x_ctrl_table[crid].crlo
1448 && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1449 && (rw == tic6x_rw_read
1450 ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1451 || (tic6x_ctrl_table[crid].rw
1452 == tic6x_rw_read_write))
1453 : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1454 || (tic6x_ctrl_table[crid].rw
1455 == tic6x_rw_read_write))))
1456 break;
1457 }
1458 if (crid == tic6x_ctrl_max)
1459 {
1460 operands_text[op_num] = TRUE;
1461 operands_ok = FALSE;
1462 }
1463 else
1464 {
1465 operands_text[op_num] = TRUE;
1466 snprintf (operands[op_num], 24, "%s",
1467 tic6x_ctrl_table[crid].name);
1468 }
1469 }
1470
1471 if (operands_text[op_num] || operands_pcrel[op_num]
1472 || spmask_skip_operand)
1473 break;
1474 }
1475 /* end for fld_num */
1476
1477 if (spmask_skip_operand)
1478 {
1479 /* SPMASK operands are only valid as the single operand
1480 in the opcode table. */
1481 if (num_operands != 1)
1482 {
1483 printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
1484 abort ();
1485 }
1486 num_operands = 0;
1487 break;
1488 }
1489
1490 /* The operand must by now have been decoded. */
1491 if (!operands_text[op_num] && !operands_pcrel[op_num])
1492 {
1493 printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
1494 abort ();
1495 }
1496 }
1497 /* end for op_num */
1498
1499 if (!operands_ok)
1500 continue;
1501
1502 info->bytes_per_chunk = num_bits / 8;
1503 info->fprintf_func (info->stream, "%s", parallel);
1504 info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1505 func_unit);
1506 for (op_num = 0; op_num < num_operands; op_num++)
1507 {
1508 info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1509 if (operands_pcrel[op_num])
1510 info->print_address_func (operands_addresses[op_num], info);
1511 else
1512 info->fprintf_func (info->stream, "%s", operands[op_num]);
1513 }
1514 if (fetch_packet_header_based && header.prot)
1515 info->fprintf_func (info->stream, " || nop 5");
1516
1517 return num_bits / 8;
1518 }
1519
1520 info->bytes_per_chunk = num_bits / 8;
1521 info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1522 (int) num_bits / 4, opcode);
1523 return num_bits / 8;
1524 }
This page took 0.064336 seconds and 4 git commands to generate.