Stop "objdump -d" from disassembling past a symbolic address.
[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;
bdc4de1b
NC
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;
40b36596
JM
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)
51dcdd4d 302 opcode = tic6x_extract_16 (fp + fp_offset, &header, info);
40b36596 303 else
51dcdd4d 304 opcode = tic6x_extract_16 (fp + (fp_offset ^ 2), &header, info);
40b36596
JM
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;
51dcdd4d 323 unsigned int t_val = 0;
40b36596
JM
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;
51dcdd4d 336 bfd_boolean have_t = FALSE;
40b36596
JM
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)
51dcdd4d
NC
371 {
372 printf ("*** opcode %x: missing z field", opcode);
373 abort ();
374 }
40b36596
JM
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
51dcdd4d
NC
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
40b36596
JM
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)
51dcdd4d
NC
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
40b36596
JM
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];
51dcdd4d 501
40b36596
JM
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 && prev_header.word_compact[6])
514 p_bit = prev_header.p_bits[13];
515 else
516 {
517 unsigned int prev_opcode = tic6x_extract_32 (fp_prev + 28,
518 info);
519 p_bit = (prev_opcode & 0x1) ? TRUE : FALSE;
520 }
521 }
522 }
523 parallel = p_bit ? "|| " : "";
524
525 if (opc->func_unit == tic6x_func_unit_nfu)
526 func_unit = "";
527 else
528 {
529 unsigned int fld_num;
530 char func_unit_char;
531 const char *data_str;
532 bfd_boolean have_areg = FALSE;
533 bfd_boolean have_cross = FALSE;
534
535 func_unit_side = (opc->flags & TIC6X_FLAG_SIDE_B_ONLY) ? 2 : 0;
536 func_unit_cross = 0;
537 func_unit_data_side = (opc->flags & TIC6X_FLAG_SIDE_T2_ONLY) ? 2 : 0;
538
539 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
540 {
541 const tic6x_coding_field *const enc = &opc->variable_fields[fld_num];
542 const tic6x_insn_field *field;
543 unsigned int fld_val;
544
545 field = tic6x_field_from_fmt (fmt, enc->field_id);
51dcdd4d 546
40b36596 547 if (!field)
51dcdd4d
NC
548 {
549 printf ("opcode %x: could not retrieve field (field_id:%d)\n",
550 opcode, fld_num);
551 abort ();
552 }
553
40b36596 554 fld_val = tic6x_field_bits (opcode, field);
51dcdd4d 555
40b36596
JM
556 switch (enc->coding_method)
557 {
558 case tic6x_coding_fu:
559 /* The side must be specified exactly once. */
560 if (func_unit_side)
51dcdd4d
NC
561 {
562 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
563 opcode, fld_num);
564 abort ();
565 }
40b36596
JM
566 func_unit_side = (fld_val ? 2 : 1);
567 break;
568
569 case tic6x_coding_data_fu:
570 /* The data side must be specified exactly once. */
571 if (func_unit_data_side)
51dcdd4d
NC
572 {
573 printf ("opcode %x: field #%d use tic6x_coding_fu, but func_unit_side is already set!\n",
574 opcode, fld_num);
575 abort ();
576 }
40b36596
JM
577 func_unit_data_side = (fld_val ? 2 : 1);
578 break;
579
580 case tic6x_coding_xpath:
581 /* Cross path use must be specified exactly
582 once. */
583 if (have_cross)
51dcdd4d
NC
584 {
585 printf ("opcode %x: field #%d use tic6x_coding_xpath, have_cross is already set!\n",
586 opcode, fld_num);
587 abort ();
588 }
40b36596
JM
589 have_cross = TRUE;
590 func_unit_cross = fld_val;
591 break;
592
51dcdd4d
NC
593 case tic6x_coding_rside:
594 /* If the format has a t field, use it for src/dst register side. */
595 have_t = TRUE;
596 t_val = fld_val;
597 func_unit_data_side = (t_val ? 2 : 1);
598 break;
599
40b36596
JM
600 case tic6x_coding_areg:
601 have_areg = TRUE;
602 break;
603
604 default:
605 /* Don't relate to functional units. */
606 break;
607 }
608 }
609
610 /* The side of the functional unit used must now have been
611 determined either from the flags or from an instruction
612 field. */
613 if (func_unit_side != 1 && func_unit_side != 2)
51dcdd4d
NC
614 {
615 printf ("opcode %x: func_unit_side is not encoded!\n", opcode);
616 abort ();
617 }
40b36596
JM
618
619 /* Cross paths are not applicable when sides are specified
620 for both address and data paths. */
621 if (func_unit_data_side && have_cross)
51dcdd4d
NC
622 {
623 printf ("opcode %x: xpath not applicable when side are specified both for address and data!\n",
624 opcode);
625 abort ();
626 }
40b36596
JM
627
628 /* Separate address and data paths are only applicable for
629 the D unit. */
630 if (func_unit_data_side && opc->func_unit != tic6x_func_unit_d)
51dcdd4d
NC
631 {
632 printf ("opcode %x: separate address and data paths only applicable for D unit!\n",
633 opcode);
634 abort ();
635 }
40b36596
JM
636
637 /* If an address register is being used but in ADDA rather
638 than a load or store, it uses a cross path for side-A
639 instructions, and the cross path use is not specified by
640 an instruction field. */
641 if (have_areg && !func_unit_data_side)
642 {
643 if (have_cross)
51dcdd4d
NC
644 {
645 printf ("opcode %x: illegal cross path specifier in adda opcode!\n", opcode);
646 abort ();
647 }
40b36596
JM
648 func_unit_cross = (func_unit_side == 1 ? TRUE : FALSE);
649 }
650
651 switch (opc->func_unit)
652 {
653 case tic6x_func_unit_d:
654 func_unit_char = 'D';
655 break;
656
657 case tic6x_func_unit_l:
658 func_unit_char = 'L';
659 break;
660
661 case tic6x_func_unit_m:
662 func_unit_char = 'M';
663 break;
664
665 case tic6x_func_unit_s:
666 func_unit_char = 'S';
667 break;
668
669 default:
51dcdd4d 670 printf ("opcode %x: illegal func_unit specifier %d\n", opcode, opc->func_unit);
40b36596
JM
671 abort ();
672 }
673
674 switch (func_unit_data_side)
675 {
676 case 0:
677 data_str = "";
678 break;
679
680 case 1:
681 data_str = "T1";
682 break;
683
684 case 2:
685 data_str = "T2";
686 break;
687
688 default:
51dcdd4d
NC
689 printf ("opcode %x: illegal data func_unit specifier %d\n",
690 opcode, func_unit_data_side);
40b36596
JM
691 abort ();
692 }
693
51dcdd4d
NC
694 if (opc->flags & TIC6X_FLAG_INSN16_BSIDE && func_unit_side == 1)
695 func_unit_cross = 1;
696
40b36596
JM
697 snprintf (func_unit_buf, 7, " .%c%u%s%s", func_unit_char,
698 func_unit_side, (func_unit_cross ? "X" : ""), data_str);
699 func_unit = func_unit_buf;
700 }
701
702 /* For each operand there must be one or more fields set based
703 on that operand, that can together be used to derive the
704 operand value. */
705 operands_ok = TRUE;
706 num_operands = opc->num_operands;
707 for (op_num = 0; op_num < num_operands; op_num++)
708 {
709 unsigned int fld_num;
710 unsigned int mem_base_reg = 0;
711 bfd_boolean mem_base_reg_known = FALSE;
712 bfd_boolean mem_base_reg_known_long = FALSE;
713 unsigned int mem_offset = 0;
714 bfd_boolean mem_offset_known = FALSE;
715 bfd_boolean mem_offset_known_long = FALSE;
716 unsigned int mem_mode = 0;
717 bfd_boolean mem_mode_known = FALSE;
718 unsigned int mem_scaled = 0;
719 bfd_boolean mem_scaled_known = FALSE;
720 unsigned int crlo = 0;
721 bfd_boolean crlo_known = FALSE;
722 unsigned int crhi = 0;
723 bfd_boolean crhi_known = FALSE;
724 bfd_boolean spmask_skip_operand = FALSE;
725 unsigned int fcyc_bits = 0;
726 bfd_boolean prev_sploop_found = FALSE;
727
728 switch (opc->operand_info[op_num].form)
729 {
51dcdd4d
NC
730 case tic6x_operand_b15reg:
731 /* Fully determined by the functional unit. */
732 operands_text[op_num] = TRUE;
733 snprintf (operands[op_num], 24, "b15");
734 continue;
735
736 case tic6x_operand_zreg:
737 /* Fully determined by the functional unit. */
738 operands_text[op_num] = TRUE;
739 snprintf (operands[op_num], 24, "%c0",
740 (func_unit_side == 2 ? 'b' : 'a'));
741 continue;
742
40b36596
JM
743 case tic6x_operand_retreg:
744 /* Fully determined by the functional unit. */
745 operands_text[op_num] = TRUE;
746 snprintf (operands[op_num], 24, "%c3",
747 (func_unit_side == 2 ? 'b' : 'a'));
748 continue;
749
750 case tic6x_operand_irp:
751 operands_text[op_num] = TRUE;
752 snprintf (operands[op_num], 24, "irp");
753 continue;
754
755 case tic6x_operand_nrp:
756 operands_text[op_num] = TRUE;
757 snprintf (operands[op_num], 24, "nrp");
758 continue;
759
51dcdd4d
NC
760 case tic6x_operand_ilc:
761 operands_text[op_num] = TRUE;
762 snprintf (operands[op_num], 24, "ilc");
763 continue;
764
765 case tic6x_operand_hw_const_minus_1:
766 operands_text[op_num] = TRUE;
767 snprintf (operands[op_num], 24, "-1");
768 continue;
769
770 case tic6x_operand_hw_const_0:
771 operands_text[op_num] = TRUE;
772 snprintf (operands[op_num], 24, "0");
773 continue;
774
775 case tic6x_operand_hw_const_1:
776 operands_text[op_num] = TRUE;
777 snprintf (operands[op_num], 24, "1");
778 continue;
779
780 case tic6x_operand_hw_const_5:
781 operands_text[op_num] = TRUE;
782 snprintf (operands[op_num], 24, "5");
783 continue;
784
785 case tic6x_operand_hw_const_16:
786 operands_text[op_num] = TRUE;
787 snprintf (operands[op_num], 24, "16");
788 continue;
789
790 case tic6x_operand_hw_const_24:
791 operands_text[op_num] = TRUE;
792 snprintf (operands[op_num], 24, "24");
793 continue;
794
795 case tic6x_operand_hw_const_31:
796 operands_text[op_num] = TRUE;
797 snprintf (operands[op_num], 24, "31");
798 continue;
799
40b36596
JM
800 default:
801 break;
802 }
803
804 for (fld_num = 0; fld_num < opc->num_variable_fields; fld_num++)
805 {
806 const tic6x_coding_field *const enc
807 = &opc->variable_fields[fld_num];
808 const tic6x_insn_field *field;
809 unsigned int fld_val;
51dcdd4d 810 unsigned int reg_base = 0;
40b36596 811 signed int signed_fld_val;
51dcdd4d 812 char reg_side = '?';
40b36596
JM
813
814 if (enc->operand_num != op_num)
815 continue;
816 field = tic6x_field_from_fmt (fmt, enc->field_id);
817 if (!field)
51dcdd4d
NC
818 {
819 printf ("opcode %x: missing field (field_id:%d) in format\n", opcode, enc->field_id);
820 abort ();
821 }
822 fld_val = tic6x_field_bits (opcode, field);
40b36596
JM
823 switch (enc->coding_method)
824 {
51dcdd4d
NC
825 case tic6x_coding_cst_s3i:
826 (fld_val == 0x00) && (fld_val = 0x10);
827 (fld_val == 0x07) && (fld_val = 0x08);
828 /* Fall through. */
40b36596
JM
829 case tic6x_coding_ucst:
830 case tic6x_coding_ulcst_dpr_byte:
831 case tic6x_coding_ulcst_dpr_half:
832 case tic6x_coding_ulcst_dpr_word:
833 case tic6x_coding_lcst_low16:
834 switch (opc->operand_info[op_num].form)
835 {
836 case tic6x_operand_asm_const:
837 case tic6x_operand_link_const:
838 operands_text[op_num] = TRUE;
839 snprintf (operands[op_num], 24, "%u", fld_val);
840 break;
841
842 case tic6x_operand_mem_long:
843 mem_offset = fld_val;
844 mem_offset_known_long = TRUE;
845 break;
846
847 default:
51dcdd4d 848 printf ("opcode %x: illegal operand form for operand#%d\n", opcode, op_num);
40b36596
JM
849 abort ();
850 }
851 break;
852
853 case tic6x_coding_lcst_high16:
854 operands_text[op_num] = TRUE;
855 snprintf (operands[op_num], 24, "%u", fld_val << 16);
856 break;
857
51dcdd4d
NC
858 case tic6x_coding_scst_l3i:
859 operands_text[op_num] = TRUE;
860 if (fld_val == 0)
861 {
862 signed_fld_val = 8;
863 }
864 else
865 {
866 signed_fld_val = (signed int) fld_val;
867 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
868 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
869 }
870 snprintf (operands[op_num], 24, "%d", signed_fld_val);
871 break;
872
40b36596
JM
873 case tic6x_coding_scst:
874 operands_text[op_num] = TRUE;
875 signed_fld_val = (signed int) fld_val;
51dcdd4d
NC
876 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
877 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
40b36596
JM
878 snprintf (operands[op_num], 24, "%d", signed_fld_val);
879 break;
880
881 case tic6x_coding_ucst_minus_one:
882 operands_text[op_num] = TRUE;
883 snprintf (operands[op_num], 24, "%u", fld_val + 1);
884 break;
885
886 case tic6x_coding_pcrel:
887 case tic6x_coding_pcrel_half:
888 signed_fld_val = (signed int) fld_val;
51dcdd4d
NC
889 signed_fld_val ^= (1 << (tic6x_field_width (field) - 1));
890 signed_fld_val -= (1 << (tic6x_field_width (field) - 1));
40b36596
JM
891 if (fetch_packet_header_based
892 && enc->coding_method == tic6x_coding_pcrel_half)
893 signed_fld_val *= 2;
894 else
895 signed_fld_val *= 4;
896 operands_pcrel[op_num] = TRUE;
897 operands_addresses[op_num] = fp_addr + signed_fld_val;
898 break;
899
795b8e6b
NC
900 case tic6x_coding_regpair_msb:
901 if (opc->operand_info[op_num].form != tic6x_operand_regpair)
902 abort ();
903 operands_text[op_num] = TRUE;
904 snprintf (operands[op_num], 24, "%c%u:%c%u",
905 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1),
906 (func_unit_side == 2 ? 'b' : 'a'), (fld_val | 0x1) - 1);
907 break;
908
51dcdd4d
NC
909 case tic6x_coding_pcrel_half_unsigned:
910 operands_pcrel[op_num] = TRUE;
911 operands_addresses[op_num] = fp_addr + 2 * fld_val;
912 break;
913
40b36596
JM
914 case tic6x_coding_reg_shift:
915 fld_val <<= 1;
916 /* Fall through. */
917 case tic6x_coding_reg:
51dcdd4d
NC
918 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
919 {
920 reg_base = 16;
921 }
40b36596
JM
922 switch (opc->operand_info[op_num].form)
923 {
51dcdd4d
NC
924 case tic6x_operand_treg:
925 if (!have_t)
926 {
927 printf ("opcode %x: operand treg but missing t field\n", opcode);
928 abort ();
929 }
930 operands_text[op_num] = TRUE;
931 reg_side = t_val ? 'b' : 'a';
932 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
933 break;
934
40b36596
JM
935 case tic6x_operand_reg:
936 operands_text[op_num] = TRUE;
51dcdd4d
NC
937 reg_side = (func_unit_side == 2) ? 'b' : 'a';
938 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
939 break;
940
941 case tic6x_operand_reg_nors:
942 operands_text[op_num] = TRUE;
943 reg_side = (func_unit_side == 2) ? 'b' : 'a';
944 snprintf (operands[op_num], 24, "%c%u", reg_side, fld_val);
945 break;
946
947 case tic6x_operand_reg_bside:
948 operands_text[op_num] = TRUE;
949 snprintf (operands[op_num], 24, "b%u", reg_base + fld_val);
950 break;
951
952 case tic6x_operand_reg_bside_nors:
953 operands_text[op_num] = TRUE;
954 snprintf (operands[op_num], 24, "b%u", fld_val);
40b36596
JM
955 break;
956
957 case tic6x_operand_xreg:
958 operands_text[op_num] = TRUE;
51dcdd4d
NC
959 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? 'b' : 'a';
960 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
40b36596
JM
961 break;
962
963 case tic6x_operand_dreg:
964 operands_text[op_num] = TRUE;
51dcdd4d
NC
965 reg_side = (func_unit_data_side == 2) ? 'b' : 'a';
966 snprintf (operands[op_num], 24, "%c%u", reg_side, reg_base + fld_val);
40b36596
JM
967 break;
968
969 case tic6x_operand_regpair:
970 operands_text[op_num] = TRUE;
971 if (fld_val & 1)
972 operands_ok = FALSE;
51dcdd4d 973 reg_side = (func_unit_side == 2) ? 'b' : 'a';
40b36596 974 snprintf (operands[op_num], 24, "%c%u:%c%u",
51dcdd4d
NC
975 reg_side, reg_base + fld_val + 1,
976 reg_side, reg_base + fld_val);
40b36596
JM
977 break;
978
979 case tic6x_operand_xregpair:
980 operands_text[op_num] = TRUE;
981 if (fld_val & 1)
982 operands_ok = FALSE;
51dcdd4d
NC
983 reg_side = ((func_unit_side == 2) ^ func_unit_cross) ? '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_tregpair:
990 if (!have_t)
991 {
992 printf ("opcode %x: operand tregpair but missing t field\n", opcode);
993 abort ();
994 }
995 operands_text[op_num] = TRUE;
996 if (fld_val & 1)
997 operands_ok = FALSE;
998 reg_side = t_val ? 'b' : 'a';
40b36596 999 snprintf (operands[op_num], 24, "%c%u:%c%u",
51dcdd4d
NC
1000 reg_side, reg_base + fld_val + 1,
1001 reg_side, reg_base + fld_val);
40b36596
JM
1002 break;
1003
1004 case tic6x_operand_dregpair:
1005 operands_text[op_num] = TRUE;
1006 if (fld_val & 1)
1007 operands_ok = FALSE;
51dcdd4d 1008 reg_side = (func_unit_data_side) == 2 ? 'b' : 'a';
40b36596 1009 snprintf (operands[op_num], 24, "%c%u:%c%u",
51dcdd4d
NC
1010 reg_side, reg_base + fld_val + 1,
1011 reg_side, reg_base + fld_val);
40b36596
JM
1012 break;
1013
1014 case tic6x_operand_mem_deref:
1015 operands_text[op_num] = TRUE;
51dcdd4d
NC
1016 reg_side = func_unit_side == 2 ? 'b' : 'a';
1017 snprintf (operands[op_num], 24, "*%c%u", reg_side, reg_base + fld_val);
40b36596
JM
1018 break;
1019
1020 case tic6x_operand_mem_short:
1021 case tic6x_operand_mem_ndw:
1022 mem_base_reg = fld_val;
1023 mem_base_reg_known = TRUE;
1024 break;
1025
1026 default:
51dcdd4d
NC
1027 printf ("opcode %x: unexpected operand form %d for operand #%d",
1028 opcode, opc->operand_info[op_num].form, op_num);
1029 abort ();
1030 }
1031 break;
1032
1033 case tic6x_coding_reg_ptr:
1034 switch (opc->operand_info[op_num].form)
1035 {
1036 case tic6x_operand_mem_short:
1037 case tic6x_operand_mem_ndw:
1038 if (fld_val > 0x3u)
1039 {
1040 printf("opcode %x: illegal field value for ptr register of operand #%d (%d)",
1041 opcode, op_num, fld_val);
1042 abort ();
1043 }
1044 mem_base_reg = 0x4 | fld_val;
1045 mem_base_reg_known = TRUE;
1046 break;
1047
1048 default:
1049 printf ("opcode %x: unexpected operand form %d for operand #%d",
1050 opcode, opc->operand_info[op_num].form, op_num);
40b36596
JM
1051 abort ();
1052 }
1053 break;
1054
1055 case tic6x_coding_areg:
1056 switch (opc->operand_info[op_num].form)
1057 {
1058 case tic6x_operand_areg:
1059 operands_text[op_num] = TRUE;
1060 snprintf (operands[op_num], 24, "b%u",
1061 fld_val ? 15u : 14u);
1062 break;
1063
1064 case tic6x_operand_mem_long:
1065 mem_base_reg = fld_val ? 15u : 14u;
1066 mem_base_reg_known_long = TRUE;
1067 break;
1068
1069 default:
51dcdd4d 1070 printf ("opcode %x: bad operand form\n", opcode);
40b36596
JM
1071 abort ();
1072 }
1073 break;
1074
51dcdd4d
NC
1075 case tic6x_coding_mem_offset_minus_one_noscale:
1076 case tic6x_coding_mem_offset_minus_one:
1077 fld_val += 1;
40b36596 1078 case tic6x_coding_mem_offset_noscale:
51dcdd4d 1079 case tic6x_coding_mem_offset:
40b36596
JM
1080 mem_offset = fld_val;
1081 mem_offset_known = TRUE;
51dcdd4d
NC
1082 if (num_bits == 16)
1083 {
1084 mem_mode_known = TRUE;
1085 mem_mode = TIC6X_INSN16_MEM_MODE_VAL (opc->flags);
1086 mem_scaled_known = TRUE;
1087 mem_scaled = TRUE;
1088 if (opc->flags & TIC6X_FLAG_INSN16_B15PTR)
1089 {
1090 mem_base_reg_known = TRUE;
1091 mem_base_reg = 15;
1092 }
1093 if ( enc->coding_method == tic6x_coding_mem_offset_noscale
1094 || enc->coding_method == tic6x_coding_mem_offset_noscale )
1095 mem_scaled = FALSE;
1096 }
40b36596
JM
1097 break;
1098
1099 case tic6x_coding_mem_mode:
1100 mem_mode = fld_val;
1101 mem_mode_known = TRUE;
1102 break;
1103
1104 case tic6x_coding_scaled:
1105 mem_scaled = fld_val;
1106 mem_scaled_known = TRUE;
1107 break;
1108
1109 case tic6x_coding_crlo:
1110 crlo = fld_val;
1111 crlo_known = TRUE;
1112 break;
1113
1114 case tic6x_coding_crhi:
1115 crhi = fld_val;
1116 crhi_known = TRUE;
1117 break;
1118
1119 case tic6x_coding_fstg:
1120 case tic6x_coding_fcyc:
1121 if (!prev_sploop_found)
1122 {
1123 bfd_vma search_fp_addr = fp_addr;
1124 bfd_vma search_fp_offset = fp_offset;
1125 bfd_boolean search_fp_header_based
1126 = fetch_packet_header_based;
1127 tic6x_fetch_packet_header search_fp_header = header;
1128 unsigned char search_fp[32];
1129 unsigned int search_num_bits;
1130 unsigned int search_opcode;
1131 unsigned int sploop_ii = 0;
1132 int i;
1133
1134 memcpy (search_fp, fp, 32);
1135
1136 /* To interpret these bits in an SPKERNEL
1137 instruction, we must find the previous
1138 SPLOOP-family instruction. It may come up to
1139 48 execute packets earlier. */
1140 for (i = 0; i < 48 * 8; i++)
1141 {
1142 /* Find the previous instruction. */
1143 if (search_fp_offset & 2)
1144 search_fp_offset -= 2;
1145 else if (search_fp_offset >= 4)
1146 {
1147 if (search_fp_header_based
1148 && (search_fp_header.word_compact
1149 [(search_fp_offset >> 2) - 1]))
1150 search_fp_offset -= 2;
1151 else
1152 search_fp_offset -= 4;
1153 }
1154 else
1155 {
1156 search_fp_addr -= 32;
1157 status = info->read_memory_func (search_fp_addr,
1158 search_fp,
1159 32, info);
1160 if (status)
1161 /* No previous SPLOOP instruction. */
1162 break;
1163 search_fp_header_based
1164 = (tic6x_check_fetch_packet_header
1165 (search_fp, &search_fp_header, info));
1166 if (search_fp_header_based)
1167 search_fp_offset
1168 = search_fp_header.word_compact[6] ? 26 : 24;
1169 else
1170 search_fp_offset = 28;
1171 }
1172
1173 /* Extract the previous instruction. */
1174 if (search_fp_header_based)
1175 search_num_bits
1176 = (search_fp_header.word_compact[search_fp_offset
1177 >> 2]
1178 ? 16
1179 : 32);
1180 else
1181 search_num_bits = 32;
1182 if (search_num_bits == 16)
1183 {
1184 if (info->endian == BFD_ENDIAN_LITTLE)
1185 search_opcode
1186 = (tic6x_extract_16
51dcdd4d 1187 (search_fp + search_fp_offset, &header, info));
40b36596
JM
1188 else
1189 search_opcode
1190 = (tic6x_extract_16
51dcdd4d 1191 (search_fp + (search_fp_offset ^ 2), &header,
40b36596
JM
1192 info));
1193 }
1194 else
1195 search_opcode
1196 = tic6x_extract_32 (search_fp + search_fp_offset,
1197 info);
1198
1199 /* Check whether it is an SPLOOP-family
1200 instruction. */
1201 if (search_num_bits == 32
1202 && ((search_opcode & 0x003ffffe) == 0x00038000
1203 || (search_opcode & 0x003ffffe) == 0x0003a000
1204 || ((search_opcode & 0x003ffffe)
1205 == 0x0003e000)))
1206 {
1207 prev_sploop_found = TRUE;
1208 sploop_ii = ((search_opcode >> 23) & 0x1f) + 1;
1209 }
1210 else if (search_num_bits == 16
1211 && (search_opcode & 0x3c7e) == 0x0c66)
1212 {
1213 prev_sploop_found = TRUE;
1214 sploop_ii
1215 = (((search_opcode >> 7) & 0x7)
1216 | ((search_opcode >> 11) & 0x8)) + 1;
1217 }
1218 if (prev_sploop_found)
1219 {
1220 if (sploop_ii <= 0)
51dcdd4d
NC
1221 {
1222 printf ("opcode %x: sloop index not found (%d)\n", opcode, sploop_ii);
1223 abort ();
1224 }
40b36596
JM
1225 else if (sploop_ii <= 1)
1226 fcyc_bits = 0;
1227 else if (sploop_ii <= 2)
1228 fcyc_bits = 1;
1229 else if (sploop_ii <= 4)
1230 fcyc_bits = 2;
1231 else if (sploop_ii <= 8)
1232 fcyc_bits = 3;
1233 else if (sploop_ii <= 14)
1234 fcyc_bits = 4;
1235 else
1236 prev_sploop_found = FALSE;
1237 }
1238 if (prev_sploop_found)
1239 break;
1240 }
1241 }
1242 if (!prev_sploop_found)
1243 {
1244 operands_ok = FALSE;
1245 operands_text[op_num] = TRUE;
1246 break;
1247 }
51dcdd4d
NC
1248 if (fcyc_bits > tic6x_field_width(field))
1249 {
1250 printf ("opcode %x: illegal fcyc value (%d)\n", opcode, fcyc_bits);
1251 abort ();
1252 }
40b36596
JM
1253 if (enc->coding_method == tic6x_coding_fstg)
1254 {
5d4c71e1
BS
1255 int i, t;
1256 for (t = 0, i = fcyc_bits; i < 6; i++)
1257 t = (t << 1) | ((fld_val >> i) & 1);
40b36596 1258 operands_text[op_num] = TRUE;
5d4c71e1 1259 snprintf (operands[op_num], 24, "%u", t);
40b36596
JM
1260 }
1261 else
1262 {
1263 operands_text[op_num] = TRUE;
1264 snprintf (operands[op_num], 24, "%u",
1265 fld_val & ((1 << fcyc_bits) - 1));
1266 }
1267 break;
1268
1269 case tic6x_coding_spmask:
1270 if (fld_val == 0)
1271 spmask_skip_operand = TRUE;
1272 else
1273 {
1274 char *p;
1275 unsigned int i;
1276
1277 operands_text[op_num] = TRUE;
1278 p = operands[op_num];
1279 for (i = 0; i < 8; i++)
1280 if (fld_val & (1 << i))
1281 {
1282 *p++ = "LSDM"[i/2];
1283 *p++ = '1' + (i & 1);
1284 *p++ = ',';
1285 }
1286 p[-1] = 0;
1287 }
1288 break;
1289
1290 case tic6x_coding_fu:
1291 case tic6x_coding_data_fu:
1292 case tic6x_coding_xpath:
51dcdd4d 1293 case tic6x_coding_rside:
40b36596
JM
1294 /* Don't relate to operands, so operand number is
1295 meaningless. */
1296 break;
1297
1298 default:
51dcdd4d 1299 printf ("opcode %x: illegal field encoding (%d)\n", opcode, enc->coding_method);
40b36596
JM
1300 abort ();
1301 }
1302
1303 if (mem_base_reg_known_long && mem_offset_known_long)
1304 {
1305 if (operands_text[op_num] || operands_pcrel[op_num])
51dcdd4d
NC
1306 {
1307 printf ("opcode %x: long access but operands already known ?\n", opcode);
1308 abort ();
1309 }
40b36596
JM
1310 operands_text[op_num] = TRUE;
1311 snprintf (operands[op_num], 24, "*+b%u(%u)", mem_base_reg,
1312 mem_offset * opc->operand_info[op_num].size);
1313 }
1314
1315 if (mem_base_reg_known && mem_offset_known && mem_mode_known
1316 && (mem_scaled_known
1317 || (opc->operand_info[op_num].form
1318 != tic6x_operand_mem_ndw)))
1319 {
1320 char side;
1321 char base[4];
1322 bfd_boolean offset_is_reg;
1323 bfd_boolean offset_scaled;
1324 char offset[4];
1325 char offsetp[6];
1326
1327 if (operands_text[op_num] || operands_pcrel[op_num])
51dcdd4d
NC
1328 {
1329 printf ("opcode %x: mem access operands already known ?\n", opcode);
1330 abort ();
1331 }
40b36596
JM
1332
1333 side = func_unit_side == 2 ? 'b' : 'a';
1334 snprintf (base, 4, "%c%u", side, mem_base_reg);
1335
1336 offset_is_reg = ((mem_mode & 4) ? TRUE : FALSE);
1337 if (offset_is_reg)
1338 {
51dcdd4d
NC
1339
1340 if (num_bits == 16 && header.rs && !(opc->flags & TIC6X_FLAG_INSN16_NORS))
1341 {
1342 reg_base = 16;
1343 }
1344 snprintf (offset, 4, "%c%u", side, reg_base + mem_offset);
40b36596
JM
1345 if (opc->operand_info[op_num].form
1346 == tic6x_operand_mem_ndw)
1347 offset_scaled = mem_scaled ? TRUE : FALSE;
1348 else
1349 offset_scaled = TRUE;
1350 }
1351 else
1352 {
1353 if (opc->operand_info[op_num].form
1354 == tic6x_operand_mem_ndw)
1355 {
1356 offset_scaled = mem_scaled ? TRUE : FALSE;
1357 snprintf (offset, 4, "%u", mem_offset);
1358 }
1359 else
1360 {
1361 offset_scaled = FALSE;
1362 snprintf (offset, 4, "%u",
1363 (mem_offset
1364 * opc->operand_info[op_num].size));
1365 }
1366 }
1367
1368 if (offset_scaled)
1369 snprintf (offsetp, 6, "[%s]", offset);
1370 else
1371 snprintf (offsetp, 6, "(%s)", offset);
1372
1373 operands_text[op_num] = TRUE;
1374 switch (mem_mode & ~4u)
1375 {
1376 case 0:
1377 snprintf (operands[op_num], 24, "*-%s%s", base, offsetp);
1378 break;
1379
1380 case 1:
1381 snprintf (operands[op_num], 24, "*+%s%s", base, offsetp);
1382 break;
1383
1384 case 2:
1385 case 3:
1386 operands_ok = FALSE;
1387 break;
1388
1389 case 8:
1390 snprintf (operands[op_num], 24, "*--%s%s", base,
1391 offsetp);
1392 break;
1393
1394 case 9:
1395 snprintf (operands[op_num], 24, "*++%s%s", base,
1396 offsetp);
1397 break;
1398
1399 case 10:
1400 snprintf (operands[op_num], 24, "*%s--%s", base,
1401 offsetp);
1402 break;
1403
1404 case 11:
1405 snprintf (operands[op_num], 24, "*%s++%s", base,
1406 offsetp);
1407 break;
1408
1409 default:
51dcdd4d 1410 printf ("*** unknown mem_mode : %d \n", mem_mode);
40b36596
JM
1411 abort ();
1412 }
1413 }
1414
1415 if (crlo_known && crhi_known)
1416 {
1417 tic6x_rw rw;
1418 tic6x_ctrl_id crid;
1419
1420 if (operands_text[op_num] || operands_pcrel[op_num])
51dcdd4d
NC
1421 {
1422 printf ("*** abort crlo crli\n");
1423 abort ();
1424 }
40b36596
JM
1425
1426 rw = opc->operand_info[op_num].rw;
1427 if (rw != tic6x_rw_read
1428 && rw != tic6x_rw_write)
51dcdd4d
NC
1429 {
1430 printf ("*** abort rw : %d\n", rw);
1431 abort ();
1432 }
40b36596
JM
1433
1434 for (crid = 0; crid < tic6x_ctrl_max; crid++)
1435 {
1436 if (crlo == tic6x_ctrl_table[crid].crlo
1437 && (crhi & tic6x_ctrl_table[crid].crhi_mask) == 0
1438 && (rw == tic6x_rw_read
1439 ? (tic6x_ctrl_table[crid].rw == tic6x_rw_read
1440 || (tic6x_ctrl_table[crid].rw
1441 == tic6x_rw_read_write))
1442 : (tic6x_ctrl_table[crid].rw == tic6x_rw_write
1443 || (tic6x_ctrl_table[crid].rw
1444 == tic6x_rw_read_write))))
1445 break;
1446 }
1447 if (crid == tic6x_ctrl_max)
1448 {
1449 operands_text[op_num] = TRUE;
1450 operands_ok = FALSE;
1451 }
1452 else
1453 {
1454 operands_text[op_num] = TRUE;
1455 snprintf (operands[op_num], 24, "%s",
1456 tic6x_ctrl_table[crid].name);
1457 }
1458 }
1459
1460 if (operands_text[op_num] || operands_pcrel[op_num]
1461 || spmask_skip_operand)
1462 break;
1463 }
51dcdd4d
NC
1464 /* end for fld_num */
1465
40b36596
JM
1466 if (spmask_skip_operand)
1467 {
1468 /* SPMASK operands are only valid as the single operand
1469 in the opcode table. */
1470 if (num_operands != 1)
51dcdd4d
NC
1471 {
1472 printf ("opcode: %x, num_operands != 1 : %d\n", opcode, num_operands);
1473 abort ();
1474 }
40b36596
JM
1475 num_operands = 0;
1476 break;
1477 }
51dcdd4d 1478
40b36596
JM
1479 /* The operand must by now have been decoded. */
1480 if (!operands_text[op_num] && !operands_pcrel[op_num])
51dcdd4d
NC
1481 {
1482 printf ("opcode: %x, operand #%d not decoded\n", opcode, op_num);
1483 abort ();
1484 }
1485 }
1486 /* end for op_num */
40b36596
JM
1487
1488 if (!operands_ok)
1489 continue;
1490
1491 info->bytes_per_chunk = num_bits / 8;
51dcdd4d
NC
1492 info->fprintf_func (info->stream, "%s", parallel);
1493 info->fprintf_func (info->stream, "%s%s%s", cond, opc->name,
1494 func_unit);
40b36596
JM
1495 for (op_num = 0; op_num < num_operands; op_num++)
1496 {
1497 info->fprintf_func (info->stream, "%c", (op_num == 0 ? ' ' : ','));
1498 if (operands_pcrel[op_num])
1499 info->print_address_func (operands_addresses[op_num], info);
1500 else
1501 info->fprintf_func (info->stream, "%s", operands[op_num]);
1502 }
1503 if (fetch_packet_header_based && header.prot)
1504 info->fprintf_func (info->stream, " || nop 5");
1505
1506 return num_bits / 8;
1507 }
1508
1509 info->bytes_per_chunk = num_bits / 8;
1510 info->fprintf_func (info->stream, "<undefined instruction 0x%.*x>",
1511 (int) num_bits / 4, opcode);
1512 return num_bits / 8;
1513}
This page took 0.310781 seconds and 4 git commands to generate.