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