* options.cc (version_script): Fix small typo in previous
[binutils.git] / gas / config / tc-tic6x.c
blobea750ba5c306125522239b4dc7937431060a19e6
1 /* TI C6X assembler.
2 Copyright 2010
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "as.h"
23 #include "dwarf2dbg.h"
24 #include "safe-ctype.h"
25 #include "subsegs.h"
26 #include "opcode/tic6x.h"
27 #include "elf/tic6x.h"
28 #include "elf32-tic6x.h"
30 /* Truncate and sign-extend at 32 bits, so that building on a 64-bit
31 host gives identical results to a 32-bit host. */
32 #define TRUNC(X) ((valueT) (X) & 0xffffffffU)
33 #define SEXT(X) ((TRUNC (X) ^ 0x80000000U) - 0x80000000U)
35 const char comment_chars[] = ";";
36 const char line_comment_chars[] = "#*;";
37 const char line_separator_chars[] = "@";
39 const char EXP_CHARS[] = "eE";
40 const char FLT_CHARS[] = "dDfF";
42 const char *md_shortopts = "";
44 enum
46 OPTION_MARCH = OPTION_MD_BASE,
47 OPTION_MATOMIC,
48 OPTION_MNO_ATOMIC,
49 OPTION_MBIG_ENDIAN,
50 OPTION_MLITTLE_ENDIAN,
51 OPTION_MGENERATE_REL
54 struct option md_longopts[] =
56 { "march", required_argument, NULL, OPTION_MARCH },
57 { "matomic", no_argument, NULL, OPTION_MATOMIC },
58 { "mno-atomic", no_argument, NULL, OPTION_MNO_ATOMIC },
59 { "mbig-endian", no_argument, NULL, OPTION_MBIG_ENDIAN },
60 { "mlittle-endian", no_argument, NULL, OPTION_MLITTLE_ENDIAN },
61 { "mgenerate-rel", no_argument, NULL, OPTION_MGENERATE_REL },
62 { NULL, no_argument, NULL, 0 }
64 size_t md_longopts_size = sizeof (md_longopts);
66 /* Whether to enable atomic instructions. 1 to enable them, 0 to
67 disable, -1 to default from architecture. */
68 static int tic6x_atomic = -1;
70 /* The instructions enabled based only on the selected architecture
71 (all instructions, if no architecture specified). Atomic
72 instructions may be enabled or disabled separately. */
73 static unsigned short tic6x_arch_enable = (TIC6X_INSN_C62X
74 | TIC6X_INSN_C64X
75 | TIC6X_INSN_C64XP
76 | TIC6X_INSN_C67X
77 | TIC6X_INSN_C67XP
78 | TIC6X_INSN_C674X
79 | TIC6X_INSN_ATOMIC);
81 /* The instructions enabled based on the current set of features
82 (architecture, as modified by other options). */
83 static unsigned short tic6x_features;
85 /* The architecture attribute value, or C6XABI_Tag_CPU_arch_none if
86 not yet set. */
87 static int tic6x_arch_attribute = C6XABI_Tag_CPU_arch_none;
89 /* Whether any instructions at all have been seen. Once any
90 instructions have been seen, architecture attributes merge into the
91 previous attribute value rather than replacing it. */
92 static bfd_boolean tic6x_seen_insns = FALSE;
94 /* The number of registers in each register file supported by the
95 current architecture. */
96 static unsigned int tic6x_num_registers;
98 /* Whether predication on A0 is possible. */
99 static bfd_boolean tic6x_predicate_a0;
101 /* Whether execute packets can cross fetch packet boundaries. */
102 static bfd_boolean tic6x_can_cross_fp_boundary;
104 /* Whether there are constraints on simultaneous reads and writes of
105 40-bit data. */
106 static bfd_boolean tic6x_long_data_constraints;
108 /* Whether compact instructions are available. */
109 static bfd_boolean tic6x_compact_insns;
111 /* Whether to generate RELA relocations. */
112 static bfd_boolean tic6x_generate_rela = TRUE;
114 /* Table of supported architecture variants. */
115 typedef struct
117 const char *arch;
118 int attr;
119 unsigned short features;
120 } tic6x_arch_table;
121 static const tic6x_arch_table tic6x_arches[] =
123 { "c62x", C6XABI_Tag_CPU_arch_C62X, TIC6X_INSN_C62X },
124 { "c64x", C6XABI_Tag_CPU_arch_C64X, TIC6X_INSN_C62X | TIC6X_INSN_C64X },
125 { "c64x+", C6XABI_Tag_CPU_arch_C64XP, (TIC6X_INSN_C62X
126 | TIC6X_INSN_C64X
127 | TIC6X_INSN_C64XP) },
128 { "c67x", C6XABI_Tag_CPU_arch_C67X, TIC6X_INSN_C62X | TIC6X_INSN_C67X },
129 { "c67x+", C6XABI_Tag_CPU_arch_C67XP, (TIC6X_INSN_C62X
130 | TIC6X_INSN_C67X
131 | TIC6X_INSN_C67XP) },
132 { "c674x", C6XABI_Tag_CPU_arch_C674X, (TIC6X_INSN_C62X
133 | TIC6X_INSN_C64X
134 | TIC6X_INSN_C64XP
135 | TIC6X_INSN_C67X
136 | TIC6X_INSN_C67XP
137 | TIC6X_INSN_C674X) }
140 /* Update the selected architecture based on ARCH, giving an error if
141 ARCH is an invalid value. Does not call tic6x_update_features; the
142 caller must do that if necessary. */
144 static void
145 tic6x_use_arch (const char *arch)
147 unsigned int i;
149 for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
150 if (strcmp (arch, tic6x_arches[i].arch) == 0)
152 tic6x_arch_enable = tic6x_arches[i].features;
153 if (tic6x_seen_insns)
154 tic6x_arch_attribute
155 = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute,
156 tic6x_arches[i].attr);
157 else
158 tic6x_arch_attribute = tic6x_arches[i].attr;
159 return;
162 as_bad (_("unknown architecture '%s'"), arch);
165 /* Parse a target-specific option. */
168 md_parse_option (int c, char *arg)
170 switch (c)
172 case OPTION_MARCH:
173 tic6x_use_arch (arg);
174 break;
176 case OPTION_MATOMIC:
177 tic6x_atomic = 1;
178 break;
180 case OPTION_MNO_ATOMIC:
181 tic6x_atomic = 0;
182 break;
184 case OPTION_MBIG_ENDIAN:
185 target_big_endian = 1;
186 break;
188 case OPTION_MLITTLE_ENDIAN:
189 target_big_endian = 0;
190 break;
192 case OPTION_MGENERATE_REL:
193 tic6x_generate_rela = FALSE;
194 break;
196 default:
197 return 0;
199 return 1;
202 void
203 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
205 unsigned int i;
207 fputc ('\n', stream);
208 fprintf (stream, _("TMS320C6000 options:\n"));
209 fprintf (stream, _(" -march=ARCH enable instructions from architecture ARCH\n"));
210 fprintf (stream, _(" -matomic enable atomic operation instructions\n"));
211 fprintf (stream, _(" -mno-atomic disable atomic operation instructions\n"));
212 fprintf (stream, _(" -mbig-endian generate big-endian code\n"));
213 fprintf (stream, _(" -mlittle-endian generate little-endian code\n"));
214 /* -mgenerate-rel is only for testsuite use and is deliberately
215 undocumented. */
217 fputc ('\n', stream);
218 fprintf (stream, _("Supported ARCH values are:"));
219 for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
220 fprintf (stream, " %s", tic6x_arches[i].arch);
221 fputc ('\n', stream);
224 /* Update enabled features based on the current architecture and
225 related settings. */
226 static void
227 tic6x_update_features (void)
229 switch (tic6x_atomic)
231 case -1:
232 tic6x_features = tic6x_arch_enable;
233 break;
235 case 0:
236 tic6x_features = tic6x_arch_enable & ~TIC6X_INSN_ATOMIC;
237 break;
239 case 1:
240 tic6x_features = tic6x_arch_enable | TIC6X_INSN_ATOMIC;
241 break;
243 default:
244 abort ();
247 tic6x_num_registers
248 = (tic6x_arch_enable & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? 32 : 16;
250 tic6x_predicate_a0 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? TRUE : FALSE;
252 tic6x_can_cross_fp_boundary
253 = (tic6x_arch_enable
254 & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? TRUE : FALSE;
256 tic6x_long_data_constraints
257 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? FALSE : TRUE;
259 tic6x_compact_insns = (tic6x_arch_enable & TIC6X_INSN_C64XP) ? TRUE : FALSE;
262 /* Do configuration after all options have been parsed. */
264 void
265 tic6x_after_parse_args (void)
267 tic6x_update_features ();
270 /* Parse a .arch directive. */
272 static void
273 s_tic6x_arch (int ignored ATTRIBUTE_UNUSED)
275 char c;
276 char *arch;
278 arch = input_line_pointer;
279 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
280 input_line_pointer++;
281 c = *input_line_pointer;
282 *input_line_pointer = 0;
284 tic6x_use_arch (arch);
285 tic6x_update_features ();
286 *input_line_pointer = c;
287 demand_empty_rest_of_line ();
290 /* Parse a .atomic directive. */
292 static void
293 s_tic6x_atomic (int ignored ATTRIBUTE_UNUSED)
295 tic6x_atomic = 1;
296 tic6x_update_features ();
297 demand_empty_rest_of_line ();
300 /* Parse a .noatomic directive. */
302 static void
303 s_tic6x_noatomic (int ignored ATTRIBUTE_UNUSED)
305 tic6x_atomic = 0;
306 tic6x_update_features ();
307 demand_empty_rest_of_line ();
310 /* Parse a .nocmp directive. */
312 static void
313 s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED)
315 seg_info (now_seg)->tc_segment_info_data.nocmp = TRUE;
316 demand_empty_rest_of_line ();
319 /* Track for each attribute whether it has been set explicitly (and so
320 should not have a default value set by the assembler). */
321 static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
323 /* Parse a .c6xabi_attribute directive. */
325 static void
326 s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED)
328 int tag = s_vendor_attribute (OBJ_ATTR_PROC);
330 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
331 tic6x_attributes_set_explicitly[tag] = TRUE;
334 typedef struct
336 const char *name;
337 int tag;
338 } tic6x_attribute_table;
340 static const tic6x_attribute_table tic6x_attributes[] =
342 #define TAG(tag, value) { #tag, tag }
343 #include "elf/tic6x-attrs.h"
344 #undef TAG
347 /* Convert an attribute name to a number. */
350 tic6x_convert_symbolic_attribute (const char *name)
352 unsigned int i;
354 for (i = 0; i < ARRAY_SIZE (tic6x_attributes); i++)
355 if (strcmp (name, tic6x_attributes[i].name) == 0)
356 return tic6x_attributes[i].tag;
358 return -1;
361 const pseudo_typeS md_pseudo_table[] =
363 { "arch", s_tic6x_arch, 0 },
364 { "atomic", s_tic6x_atomic, 0 },
365 { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 },
366 { "noatomic", s_tic6x_noatomic, 0 },
367 { "nocmp", s_tic6x_nocmp, 0 },
368 { "word", cons, 4 },
369 { 0, 0, 0 }
372 /* Hash table of opcodes. For each opcode name, this stores a pointer
373 to a tic6x_opcode_list listing (in an arbitrary order) all opcode
374 table entries with that name. */
375 static struct hash_control *opcode_hash;
377 /* Initialize the assembler (called once at assembler startup). */
379 void
380 md_begin (void)
382 tic6x_opcode_id id;
384 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
386 /* Insert opcodes into the hash table. */
387 opcode_hash = hash_new ();
388 for (id = 0; id < tic6x_opcode_max; id++)
390 const char *errmsg;
391 tic6x_opcode_list *opc = xmalloc (sizeof (tic6x_opcode_list));
393 opc->id = id;
394 opc->next = hash_find (opcode_hash, tic6x_opcode_table[id].name);
395 if ((errmsg = hash_jam (opcode_hash, tic6x_opcode_table[id].name, opc))
396 != NULL)
397 as_fatal ("%s", _(errmsg));
401 /* Whether the current line being parsed had the "||" parallel bars. */
402 static bfd_boolean tic6x_line_parallel;
404 /* Whether the current line being parsed started "||^" to indicate an
405 SPMASKed parallel instruction. */
406 static bfd_boolean tic6x_line_spmask;
408 /* If the current line being parsed had an instruction predicate, the
409 creg value for that predicate (which must be nonzero); otherwise
410 0. */
411 static unsigned int tic6x_line_creg;
413 /* If the current line being parsed had an instruction predicate, the
414 z value for that predicate; otherwise 0. */
415 static unsigned int tic6x_line_z;
417 /* Return 1 (updating input_line_pointer as appropriate) if the line
418 starting with C (immediately before input_line_pointer) starts with
419 pre-opcode text appropriate for this target, 0 otherwise. */
422 tic6x_unrecognized_line (int c)
424 char *p, *endp;
425 unsigned int z;
426 bfd_boolean areg;
427 bfd_boolean bad_predicate;
429 switch (c)
431 case '|':
432 if (input_line_pointer[0] == '|')
434 if (input_line_pointer[1] == '^')
436 tic6x_line_spmask = TRUE;
437 input_line_pointer += 2;
439 else
440 input_line_pointer += 1;
441 if (tic6x_line_parallel)
442 as_bad (_("multiple '||' on same line"));
443 tic6x_line_parallel = TRUE;
444 if (tic6x_line_creg)
445 as_bad (_("'||' after predicate"));
446 return 1;
448 return 0;
450 case '[':
451 /* If it doesn't look like a predicate at all, just return 0.
452 If it looks like one but not a valid one, give a better
453 error. */
454 p = input_line_pointer;
455 while (*p != ']' && !is_end_of_line[(unsigned char) *p])
456 p++;
457 if (*p != ']')
458 return 0;
459 endp = p + 1;
460 p = input_line_pointer;
461 z = 0;
462 bad_predicate = FALSE;
463 if (*p == '!')
465 z = 1;
466 p++;
468 if (*p == 'A' || *p == 'a')
469 areg = TRUE;
470 else if (*p == 'B' || *p == 'b')
471 areg = FALSE;
472 else
474 areg = TRUE; /* Avoid uninitialized warning. */
475 bad_predicate = TRUE;
477 if (!bad_predicate)
479 p++;
480 if (*p != '0' && *p != '1' && *p != '2')
481 bad_predicate = TRUE;
482 else if (p[1] != ']')
483 bad_predicate = TRUE;
484 else
485 input_line_pointer = p + 2;
488 if (tic6x_line_creg)
489 as_bad (_("multiple predicates on same line"));
491 if (bad_predicate)
493 char ctmp = *endp;
494 *endp = 0;
495 as_bad (_("bad predicate '%s'"), input_line_pointer - 1);
496 *endp = ctmp;
497 input_line_pointer = endp;
498 return 1;
501 switch (*p)
503 case '0':
504 tic6x_line_creg = (areg ? 6 : 1);
505 if (areg && !tic6x_predicate_a0)
506 as_bad (_("predication on A0 not supported on this architecture"));
507 break;
509 case '1':
510 tic6x_line_creg = (areg ? 4 : 2);
511 break;
513 case '2':
514 tic6x_line_creg = (areg ? 5 : 3);
515 break;
517 default:
518 abort ();
521 tic6x_line_z = z;
522 return 1;
524 default:
525 return 0;
529 /* Do any target-specific handling of a label required. */
531 void
532 tic6x_frob_label (symbolS *sym)
534 segment_info_type *si;
535 tic6x_label_list *list;
537 if (tic6x_line_parallel)
539 as_bad (_("label after '||'"));
540 tic6x_line_parallel = FALSE;
541 tic6x_line_spmask = FALSE;
543 if (tic6x_line_creg)
545 as_bad (_("label after predicate"));
546 tic6x_line_creg = 0;
547 tic6x_line_z = 0;
550 si = seg_info (now_seg);
551 list = si->tc_segment_info_data.label_list;
552 si->tc_segment_info_data.label_list = xmalloc (sizeof (tic6x_label_list));
553 si->tc_segment_info_data.label_list->next = list;
554 si->tc_segment_info_data.label_list->label = sym;
556 /* Defining tc_frob_label overrides the ELF definition of
557 obj_frob_label, so we need to apply its effects here. */
558 dwarf2_emit_label (sym);
561 /* At end-of-line, give errors for start-of-line decorations that
562 needed an instruction but were not followed by one. */
564 static void
565 tic6x_end_of_line (void)
567 if (tic6x_line_parallel)
569 as_bad (_("'||' not followed by instruction"));
570 tic6x_line_parallel = FALSE;
571 tic6x_line_spmask = FALSE;
573 if (tic6x_line_creg)
575 as_bad (_("predicate not followed by instruction"));
576 tic6x_line_creg = 0;
577 tic6x_line_z = 0;
581 /* Do any target-specific handling of the start of a logical line. */
583 void
584 tic6x_start_line_hook (void)
586 tic6x_end_of_line ();
589 /* Do target-specific handling immediately after an input file from
590 the command line, and any other inputs it includes, have been
591 read. */
593 void
594 tic6x_cleanup (void)
596 tic6x_end_of_line ();
599 /* Do target-specific initialization after arguments have been
600 processed and the output file created. */
602 void
603 tic6x_init_after_args (void)
605 elf32_tic6x_set_use_rela_p (stdoutput, tic6x_generate_rela);
608 /* Free LIST of labels (possibly NULL). */
610 static void
611 tic6x_free_label_list (tic6x_label_list *list)
613 while (list)
615 tic6x_label_list *old = list;
617 list = list->next;
618 free (old);
622 /* Handle a data alignment of N bytes. */
624 void
625 tic6x_cons_align (int n ATTRIBUTE_UNUSED)
627 segment_info_type *seginfo = seg_info (now_seg);
629 /* Data means there is no current execute packet, and that any label
630 applies to that data rather than a subsequent instruction. */
631 tic6x_free_label_list (seginfo->tc_segment_info_data.label_list);
632 seginfo->tc_segment_info_data.label_list = NULL;
633 seginfo->tc_segment_info_data.execute_packet_frag = NULL;
634 seginfo->tc_segment_info_data.last_insn_lsb = NULL;
635 seginfo->tc_segment_info_data.spmask_addr = NULL;
636 seginfo->tc_segment_info_data.func_units_used = 0;
639 /* Handle an alignment directive. Return TRUE if the
640 machine-independent frag generation should be skipped. */
642 bfd_boolean
643 tic6x_do_align (int n, char *fill, int len ATTRIBUTE_UNUSED, int max)
645 /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
646 them in the md_end pass by inserting NOPs in parallel with
647 previous instructions. We only do this in sections containing
648 nothing but instructions. Code alignments of 1 or 2 bytes have
649 no effect in such sections (but we record them with
650 machine-dependent frags anyway so they can be skipped or
651 converted to machine-independent), while those of more than 64
652 bytes cannot reliably be handled in this way. */
653 if (n > 0
654 && max >= 0
655 && max < (1 << n)
656 && !need_pass_2
657 && fill == NULL
658 && subseg_text_p (now_seg))
660 fragS *align_frag;
661 char *p;
663 if (n > 5)
664 return FALSE;
666 /* Machine-independent code would generate a frag here, but we
667 wish to handle it in a machine-dependent way. */
668 if (frag_now_fix () != 0)
670 if (frag_now->fr_type != rs_machine_dependent)
671 frag_wane (frag_now);
673 frag_new (0);
675 frag_grow (32);
676 align_frag = frag_now;
677 p = frag_var (rs_machine_dependent, 32, 32, max, NULL, n, NULL);
678 /* This must be the same as the frag to which a pointer was just
679 saved. */
680 if (p != align_frag->fr_literal)
681 abort ();
682 align_frag->tc_frag_data.is_insns = FALSE;
683 return TRUE;
685 else
686 return FALSE;
689 /* Types of operand for parsing purposes. These are used as bit-masks
690 to tell tic6x_parse_operand what forms of operand are
691 permitted. */
692 #define TIC6X_OP_EXP 0x0001u
693 #define TIC6X_OP_REG 0x0002u
694 #define TIC6X_OP_REGPAIR 0x0004u
695 #define TIC6X_OP_IRP 0x0008u
696 #define TIC6X_OP_NRP 0x0010u
697 /* With TIC6X_OP_MEM_NOUNREG, the contents of a () offset are always
698 interpreted as an expression, which may be a symbol with the same
699 name as a register that ends up being implicitly DP-relative. With
700 TIC6X_OP_MEM_UNREG, the contents of a () offset are interpreted as
701 a register if they match one, and failing that as an expression,
702 which must be constant. */
703 #define TIC6X_OP_MEM_NOUNREG 0x0020u
704 #define TIC6X_OP_MEM_UNREG 0x0040u
705 #define TIC6X_OP_CTRL 0x0080u
706 #define TIC6X_OP_FUNC_UNIT 0x0100u
708 /* A register or register pair read by the assembler. */
709 typedef struct
711 /* The side the register is on (1 or 2). */
712 unsigned int side;
713 /* The register number (0 to 31). */
714 unsigned int num;
715 } tic6x_register;
717 /* Types of modification of a base address. */
718 typedef enum
720 tic6x_mem_mod_none,
721 tic6x_mem_mod_plus,
722 tic6x_mem_mod_minus,
723 tic6x_mem_mod_preinc,
724 tic6x_mem_mod_predec,
725 tic6x_mem_mod_postinc,
726 tic6x_mem_mod_postdec
727 } tic6x_mem_mod;
729 /* Scaled [] or unscaled () nature of an offset. */
730 typedef enum
732 tic6x_offset_none,
733 tic6x_offset_scaled,
734 tic6x_offset_unscaled
735 } tic6x_mem_scaling;
737 /* A memory operand read by the assembler. */
738 typedef struct
740 /* The base register. */
741 tic6x_register base_reg;
742 /* How the base register is modified. */
743 tic6x_mem_mod mod;
744 /* Whether there is an offset (required with plain "+" and "-"), and
745 whether it is scaled or unscaled if so. */
746 tic6x_mem_scaling scaled;
747 /* Whether the offset is a register (TRUE) or an expression
748 (FALSE). */
749 bfd_boolean offset_is_reg;
750 /* The offset. */
751 union
753 expressionS exp;
754 tic6x_register reg;
755 } offset;
756 } tic6x_mem_ref;
758 /* A functional unit in SPMASK operands read by the assembler. */
759 typedef struct
761 /* The basic unit. */
762 tic6x_func_unit_base base;
763 /* The side (1 or 2). */
764 unsigned int side;
765 } tic6x_func_unit_operand;
767 /* An operand read by the assembler. */
768 typedef struct
770 /* The syntactic form of the operand, as one of the bit-masks
771 above. */
772 unsigned int form;
773 /* The operand value. */
774 union
776 /* An expression: TIC6X_OP_EXP. */
777 expressionS exp;
778 /* A register: TIC6X_OP_REG, TIC6X_OP_REGPAIR. */
779 tic6x_register reg;
780 /* A memory reference: TIC6X_OP_MEM_NOUNREG,
781 TIC6X_OP_MEM_UNREG. */
782 tic6x_mem_ref mem;
783 /* A control register: TIC6X_OP_CTRL. */
784 tic6x_ctrl_id ctrl;
785 /* A functional unit: TIC6X_OP_FUNC_UNIT. */
786 tic6x_func_unit_operand func_unit;
787 } value;
788 } tic6x_operand;
790 #define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
792 /* Parse a register operand, or part of an operand, starting at *P.
793 If syntactically OK (including that the number is in the range 0 to
794 31, but not necessarily in range for this architecture), return
795 TRUE, putting the register side and number in *REG and update *P to
796 point immediately after the register number; otherwise return FALSE
797 without changing *P (but possibly changing *REG). Do not print any
798 diagnostics. */
800 static bfd_boolean
801 tic6x_parse_register (char **p, tic6x_register *reg)
803 char *r = *p;
805 switch (*r)
807 case 'a':
808 case 'A':
809 reg->side = 1;
810 break;
812 case 'b':
813 case 'B':
814 reg->side = 2;
815 break;
817 default:
818 return FALSE;
820 r++;
822 if (*r >= '0' && *r <= '9')
824 reg->num = *r - '0';
825 r++;
827 else
828 return FALSE;
830 if (reg->num > 0 && *r >= '0' && *r <= '9')
832 reg->num = reg->num * 10 + (*r - '0');
833 r++;
836 if (*r >= '0' && *r <= '9')
837 return FALSE;
839 if (reg->num >= 32)
840 return FALSE;
841 *p = r;
842 return TRUE;
845 /* Parse the initial two characters of a functional unit name starting
846 at *P. If OK, set *BASE and *SIDE and return TRUE; otherwise,
847 return FALSE. */
849 static bfd_boolean
850 tic6x_parse_func_unit_base (char *p, tic6x_func_unit_base *base,
851 unsigned int *side)
853 bfd_boolean good_func_unit = TRUE;
854 tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
855 unsigned int maybe_side = 0;
857 switch (p[0])
859 case 'd':
860 case 'D':
861 maybe_base = tic6x_func_unit_d;
862 break;
864 case 'l':
865 case 'L':
866 maybe_base = tic6x_func_unit_l;
867 break;
869 case 'm':
870 case 'M':
871 maybe_base = tic6x_func_unit_m;
872 break;
874 case 's':
875 case 'S':
876 maybe_base = tic6x_func_unit_s;
877 break;
879 default:
880 good_func_unit = FALSE;
881 break;
884 if (good_func_unit)
885 switch (p[1])
887 case '1':
888 maybe_side = 1;
889 break;
891 case '2':
892 maybe_side = 2;
893 break;
895 default:
896 good_func_unit = FALSE;
897 break;
900 if (good_func_unit)
902 *base = maybe_base;
903 *side = maybe_side;
906 return good_func_unit;
909 /* Parse an operand starting at *P. If the operand parses OK, return
910 TRUE and store the value in *OP; otherwise return FALSE (possibly
911 changing *OP). In any case, update *P to point to the following
912 comma or end of line. The possible operand forms are given by
913 OP_FORMS. For diagnostics, this is operand OPNO of an opcode
914 starting at STR, length OPC_LEN. */
916 static bfd_boolean
917 tic6x_parse_operand (char **p, tic6x_operand *op, unsigned int op_forms,
918 char *str, int opc_len, unsigned int opno)
920 bfd_boolean operand_parsed = FALSE;
921 char *q = *p;
923 if ((op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
924 == (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
925 abort ();
927 /* Check for functional unit names for SPMASK and SPMASKR. */
928 if (!operand_parsed && (op_forms & TIC6X_OP_FUNC_UNIT))
930 tic6x_func_unit_base base = tic6x_func_unit_nfu;
931 unsigned int side = 0;
933 if (tic6x_parse_func_unit_base (q, &base, &side))
935 char *rq = q + 2;
937 skip_whitespace (rq);
938 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
940 op->form = TIC6X_OP_FUNC_UNIT;
941 op->value.func_unit.base = base;
942 op->value.func_unit.side = side;
943 operand_parsed = TRUE;
944 q = rq;
949 /* Check for literal "irp". */
950 if (!operand_parsed && (op_forms & TIC6X_OP_IRP))
952 if ((q[0] == 'i' || q[0] == 'I')
953 && (q[1] == 'r' || q[1] == 'R')
954 && (q[2] == 'p' || q[2] == 'P'))
956 char *rq = q + 3;
958 skip_whitespace (rq);
959 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
961 op->form = TIC6X_OP_IRP;
962 operand_parsed = TRUE;
963 q = rq;
968 /* Check for literal "nrp". */
969 if (!operand_parsed && (op_forms & TIC6X_OP_NRP))
971 if ((q[0] == 'n' || q[0] == 'N')
972 && (q[1] == 'r' || q[1] == 'R')
973 && (q[2] == 'p' || q[2] == 'P'))
975 char *rq = q + 3;
977 skip_whitespace (rq);
978 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
980 op->form = TIC6X_OP_NRP;
981 operand_parsed = TRUE;
982 q = rq;
987 /* Check for control register names. */
988 if (!operand_parsed && (op_forms & TIC6X_OP_CTRL))
990 tic6x_ctrl_id crid;
992 for (crid = 0; crid < tic6x_ctrl_max; crid++)
994 size_t len = strlen (tic6x_ctrl_table[crid].name);
996 if (strncasecmp (tic6x_ctrl_table[crid].name, q, len) == 0)
998 char *rq = q + len;
1000 skip_whitespace (rq);
1001 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1003 op->form = TIC6X_OP_CTRL;
1004 op->value.ctrl = crid;
1005 operand_parsed = TRUE;
1006 q = rq;
1007 if (!(tic6x_ctrl_table[crid].isa_variants & tic6x_features))
1008 as_bad (_("control register '%s' not supported "
1009 "on this architecture"),
1010 tic6x_ctrl_table[crid].name);
1016 /* See if this looks like a memory reference. */
1017 if (!operand_parsed
1018 && (op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG)))
1020 bfd_boolean mem_ok = TRUE;
1021 char *mq = q;
1022 tic6x_mem_mod mem_mod = tic6x_mem_mod_none;
1023 tic6x_register base_reg;
1024 bfd_boolean require_offset, permit_offset;
1025 tic6x_mem_scaling scaled;
1026 bfd_boolean offset_is_reg;
1027 expressionS offset_exp;
1028 tic6x_register offset_reg;
1030 if (*mq == '*')
1031 mq++;
1032 else
1033 mem_ok = FALSE;
1035 if (mem_ok)
1037 skip_whitespace (mq);
1038 switch (*mq)
1040 case '+':
1041 if (mq[1] == '+')
1043 mem_mod = tic6x_mem_mod_preinc;
1044 mq += 2;
1046 else
1048 mem_mod = tic6x_mem_mod_plus;
1049 mq++;
1051 break;
1053 case '-':
1054 if (mq[1] == '-')
1056 mem_mod = tic6x_mem_mod_predec;
1057 mq += 2;
1059 else
1061 mem_mod = tic6x_mem_mod_minus;
1062 mq++;
1064 break;
1066 default:
1067 break;
1071 if (mem_ok)
1073 skip_whitespace (mq);
1074 mem_ok = tic6x_parse_register (&mq, &base_reg);
1077 if (mem_ok && mem_mod == tic6x_mem_mod_none)
1079 skip_whitespace (mq);
1080 if (mq[0] == '+' && mq[1] == '+')
1082 mem_mod = tic6x_mem_mod_postinc;
1083 mq += 2;
1085 else if (mq[0] == '-' && mq[1] == '-')
1087 mem_mod = tic6x_mem_mod_postdec;
1088 mq += 2;
1092 if (mem_mod == tic6x_mem_mod_none)
1093 permit_offset = FALSE;
1094 else
1095 permit_offset = TRUE;
1096 if (mem_mod == tic6x_mem_mod_plus || mem_mod == tic6x_mem_mod_minus)
1097 require_offset = TRUE;
1098 else
1099 require_offset = FALSE;
1100 scaled = tic6x_offset_none;
1101 offset_is_reg = FALSE;
1103 if (mem_ok && permit_offset)
1105 char endc = 0;
1107 skip_whitespace (mq);
1108 switch (*mq)
1110 case '[':
1111 scaled = tic6x_offset_scaled;
1112 mq++;
1113 endc = ']';
1114 break;
1116 case '(':
1117 scaled = tic6x_offset_unscaled;
1118 mq++;
1119 endc = ')';
1120 break;
1122 default:
1123 break;
1125 if (scaled != tic6x_offset_none)
1127 skip_whitespace (mq);
1128 if (scaled == tic6x_offset_scaled
1129 || (op_forms & TIC6X_OP_MEM_UNREG))
1131 bfd_boolean reg_ok;
1132 char *rq = mq;
1134 reg_ok = tic6x_parse_register (&rq, &offset_reg);
1135 if (reg_ok)
1137 skip_whitespace (rq);
1138 if (*rq == endc)
1140 mq = rq;
1141 offset_is_reg = TRUE;
1145 if (!offset_is_reg)
1147 char *save_input_line_pointer;
1149 save_input_line_pointer = input_line_pointer;
1150 input_line_pointer = mq;
1151 expression (&offset_exp);
1152 mq = input_line_pointer;
1153 input_line_pointer = save_input_line_pointer;
1155 skip_whitespace (mq);
1156 if (*mq == endc)
1157 mq++;
1158 else
1159 mem_ok = FALSE;
1163 if (mem_ok && require_offset && scaled == tic6x_offset_none)
1164 mem_ok = FALSE;
1166 if (mem_ok)
1168 skip_whitespace (mq);
1169 if (!is_end_of_line[(unsigned char) *mq] && *mq != ',')
1170 mem_ok = FALSE;
1173 if (mem_ok)
1175 op->form = op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG);
1176 op->value.mem.base_reg = base_reg;
1177 op->value.mem.mod = mem_mod;
1178 op->value.mem.scaled = scaled;
1179 op->value.mem.offset_is_reg = offset_is_reg;
1180 if (offset_is_reg)
1181 op->value.mem.offset.reg = offset_reg;
1182 else
1183 op->value.mem.offset.exp = offset_exp;
1184 operand_parsed = TRUE;
1185 q = mq;
1186 if (base_reg.num >= tic6x_num_registers)
1187 as_bad (_("register number %u not supported on this architecture"),
1188 base_reg.num);
1189 if (offset_is_reg && offset_reg.num >= tic6x_num_registers)
1190 as_bad (_("register number %u not supported on this architecture"),
1191 offset_reg.num);
1195 /* See if this looks like a register or register pair. */
1196 if (!operand_parsed && (op_forms & (TIC6X_OP_REG | TIC6X_OP_REGPAIR)))
1198 tic6x_register first_reg, second_reg;
1199 bfd_boolean reg_ok;
1200 char *rq = q;
1202 reg_ok = tic6x_parse_register (&rq, &first_reg);
1204 if (reg_ok)
1206 if (*rq == ':' && (op_forms & TIC6X_OP_REGPAIR))
1208 rq++;
1209 reg_ok = tic6x_parse_register (&rq, &second_reg);
1210 if (reg_ok)
1212 skip_whitespace (rq);
1213 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1215 if ((second_reg.num & 1)
1216 || (first_reg.num != second_reg.num + 1)
1217 || (first_reg.side != second_reg.side))
1218 as_bad (_("register pair for operand %u of '%.*s'"
1219 " not a valid even/odd pair"), opno,
1220 opc_len, str);
1221 op->form = TIC6X_OP_REGPAIR;
1222 op->value.reg = second_reg;
1223 operand_parsed = TRUE;
1224 q = rq;
1228 else if (op_forms & TIC6X_OP_REG)
1230 skip_whitespace (rq);
1231 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1233 op->form = TIC6X_OP_REG;
1234 op->value.reg = first_reg;
1235 operand_parsed = TRUE;
1236 q = rq;
1240 if (operand_parsed)
1242 if (first_reg.num >= tic6x_num_registers)
1243 as_bad (_("register number %u not supported on this architecture"),
1244 first_reg.num);
1245 if (op->form == TIC6X_OP_REGPAIR
1246 && second_reg.num >= tic6x_num_registers)
1247 as_bad (_("register number %u not supported on this architecture"),
1248 second_reg.num);
1252 /* Otherwise, parse it as an expression. */
1253 if (!operand_parsed && (op_forms & TIC6X_OP_EXP))
1255 char *save_input_line_pointer;
1257 save_input_line_pointer = input_line_pointer;
1258 input_line_pointer = q;
1259 op->form = TIC6X_OP_EXP;
1260 expression (&op->value.exp);
1261 q = input_line_pointer;
1262 input_line_pointer = save_input_line_pointer;
1263 operand_parsed = TRUE;
1266 if (operand_parsed)
1268 /* Now the operand has been parsed, there must be nothing more
1269 before the comma or end of line. */
1270 skip_whitespace (q);
1271 if (!is_end_of_line[(unsigned char) *q] && *q != ',')
1273 operand_parsed = FALSE;
1274 as_bad (_("junk after operand %u of '%.*s'"), opno,
1275 opc_len, str);
1276 while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1277 q++;
1280 else
1282 /* This could not be parsed as any acceptable form of
1283 operand. */
1284 switch (op_forms)
1286 case TIC6X_OP_REG | TIC6X_OP_REGPAIR:
1287 as_bad (_("bad register or register pair for operand %u of '%.*s'"),
1288 opno, opc_len, str);
1289 break;
1291 case TIC6X_OP_REG | TIC6X_OP_CTRL:
1292 case TIC6X_OP_REG:
1293 as_bad (_("bad register for operand %u of '%.*s'"),
1294 opno, opc_len, str);
1295 break;
1297 case TIC6X_OP_REGPAIR:
1298 as_bad (_("bad register pair for operand %u of '%.*s'"),
1299 opno, opc_len, str);
1300 break;
1302 case TIC6X_OP_FUNC_UNIT:
1303 as_bad (_("bad functional unit for operand %u of '%.*s'"),
1304 opno, opc_len, str);
1305 break;
1307 default:
1308 as_bad (_("bad operand %u of '%.*s'"),
1309 opno, opc_len, str);
1310 break;
1313 while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1314 q++;
1316 *p = q;
1317 return operand_parsed;
1320 /* Table of assembler operators and associated O_* values. */
1321 typedef struct
1323 const char *name;
1324 operatorT op;
1325 } tic6x_operator_table;
1326 static const tic6x_operator_table tic6x_operators[] = {
1327 #define O_dsbt_index O_md1
1328 { "dsbt_index", O_dsbt_index },
1329 #define O_got O_md2
1330 { "got", O_got },
1331 #define O_dpr_got O_md3
1332 { "dpr_got", O_dpr_got },
1333 #define O_dpr_byte O_md4
1334 { "dpr_byte", O_dpr_byte },
1335 #define O_dpr_hword O_md5
1336 { "dpr_hword", O_dpr_hword },
1337 #define O_dpr_word O_md6
1338 { "dpr_word", O_dpr_word },
1341 /* Parse a name in some machine-specific way. Used on C6X to handle
1342 assembler operators. */
1345 tic6x_parse_name (const char *name, expressionS *exprP,
1346 enum expr_mode mode ATTRIBUTE_UNUSED, char *nextchar)
1348 char *p = input_line_pointer;
1349 char c, *name_start, *name_end;
1350 const char *inner_name;
1351 unsigned int i;
1352 operatorT op = O_illegal;
1353 symbolS *sym;
1355 if (*name != '$')
1356 return 0;
1358 for (i = 0; i < ARRAY_SIZE (tic6x_operators); i++)
1359 if (strcasecmp (name + 1, tic6x_operators[i].name) == 0)
1361 op = tic6x_operators[i].op;
1362 break;
1365 if (op == O_illegal)
1366 return 0;
1368 *input_line_pointer = *nextchar;
1369 skip_whitespace (p);
1371 if (*p != '(')
1373 *input_line_pointer = 0;
1374 return 0;
1376 p++;
1377 skip_whitespace (p);
1379 if (!is_name_beginner (*p))
1381 *input_line_pointer = 0;
1382 return 0;
1385 name_start = p;
1386 p++;
1387 while (is_part_of_name (*p))
1388 p++;
1389 name_end = p;
1390 skip_whitespace (p);
1392 if (*p != ')')
1394 *input_line_pointer = 0;
1395 return 0;
1398 input_line_pointer = p + 1;
1399 *nextchar = *input_line_pointer;
1400 *input_line_pointer = 0;
1402 c = *name_end;
1403 *name_end = 0;
1404 inner_name = name_start;
1405 if (op == O_dsbt_index && strcmp (inner_name, "__c6xabi_DSBT_BASE") != 0)
1407 as_bad (_("$DSBT_INDEX must be used with __c6xabi_DSBT_BASE"));
1408 inner_name = "__c6xabi_DSBT_BASE";
1410 sym = symbol_find_or_make (inner_name);
1411 *name_end = c;
1413 exprP->X_op = op;
1414 exprP->X_add_symbol = sym;
1415 exprP->X_add_number = 0;
1416 exprP->X_op_symbol = NULL;
1417 exprP->X_md = 0;
1419 return 1;
1422 /* Create a fixup for an expression. Same arguments as fix_new_exp,
1423 plus FIX_ADDA which is TRUE for ADDA instructions (to indicate that
1424 fixes resolving to constants should have those constants implicitly
1425 shifted) and FALSE otherwise, but look for C6X-specific expression
1426 types and adjust the relocations or give errors accordingly. */
1428 static void
1429 tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
1430 int pcrel, bfd_reloc_code_real_type r_type,
1431 bfd_boolean fix_adda)
1433 bfd_reloc_code_real_type new_reloc = BFD_RELOC_UNUSED;
1434 fixS *fix;
1436 switch (exp->X_op)
1438 case O_dsbt_index:
1439 switch (r_type)
1441 case BFD_RELOC_C6000_SBR_U15_W:
1442 new_reloc = BFD_RELOC_C6000_DSBT_INDEX;
1443 break;
1445 default:
1446 as_bad (_("$DSBT_INDEX not supported in this context"));
1447 return;
1449 break;
1451 case O_got:
1452 switch (r_type)
1454 case BFD_RELOC_C6000_SBR_U15_W:
1455 new_reloc = BFD_RELOC_C6000_SBR_GOT_U15_W;
1456 break;
1458 default:
1459 as_bad (_("$GOT not supported in this context"));
1460 return;
1462 break;
1464 case O_dpr_got:
1465 switch (r_type)
1467 case BFD_RELOC_C6000_ABS_L16:
1468 new_reloc = BFD_RELOC_C6000_SBR_GOT_L16_W;
1469 break;
1471 case BFD_RELOC_C6000_ABS_H16:
1472 new_reloc = BFD_RELOC_C6000_SBR_GOT_H16_W;
1473 break;
1475 default:
1476 as_bad (_("$DPR_GOT not supported in this context"));
1477 return;
1479 break;
1481 case O_dpr_byte:
1482 switch (r_type)
1484 case BFD_RELOC_C6000_ABS_S16:
1485 new_reloc = BFD_RELOC_C6000_SBR_S16;
1486 break;
1488 case BFD_RELOC_C6000_ABS_L16:
1489 new_reloc = BFD_RELOC_C6000_SBR_L16_B;
1490 break;
1492 case BFD_RELOC_C6000_ABS_H16:
1493 new_reloc = BFD_RELOC_C6000_SBR_H16_B;
1494 break;
1496 default:
1497 as_bad (_("$DPR_BYTE not supported in this context"));
1498 return;
1500 break;
1502 case O_dpr_hword:
1503 switch (r_type)
1505 case BFD_RELOC_C6000_ABS_L16:
1506 new_reloc = BFD_RELOC_C6000_SBR_L16_H;
1507 break;
1509 case BFD_RELOC_C6000_ABS_H16:
1510 new_reloc = BFD_RELOC_C6000_SBR_H16_H;
1511 break;
1513 default:
1514 as_bad (_("$DPR_HWORD not supported in this context"));
1515 return;
1517 break;
1519 case O_dpr_word:
1520 switch (r_type)
1522 case BFD_RELOC_C6000_ABS_L16:
1523 new_reloc = BFD_RELOC_C6000_SBR_L16_W;
1524 break;
1526 case BFD_RELOC_C6000_ABS_H16:
1527 new_reloc = BFD_RELOC_C6000_SBR_H16_W;
1528 break;
1530 default:
1531 as_bad (_("$DPR_WORD not supported in this context"));
1532 return;
1534 break;
1536 case O_symbol:
1537 break;
1539 default:
1540 if (pcrel)
1542 as_bad (_("invalid PC-relative operand"));
1543 return;
1545 break;
1548 if (new_reloc == BFD_RELOC_UNUSED)
1549 fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
1550 else
1551 fix = fix_new (frag, where, size, exp->X_add_symbol, exp->X_add_number,
1552 pcrel, new_reloc);
1553 fix->tc_fix_data.fix_adda = fix_adda;
1556 /* Generate a fix for a constant (.word etc.). Needed to ensure these
1557 go through the error checking in tic6x_fix_new_exp. */
1559 void
1560 tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp)
1562 bfd_reloc_code_real_type r_type;
1564 switch (size)
1566 case 1:
1567 r_type = BFD_RELOC_8;
1568 break;
1570 case 2:
1571 r_type = BFD_RELOC_16;
1572 break;
1574 case 4:
1575 r_type = BFD_RELOC_32;
1576 break;
1578 default:
1579 as_bad (_("no %d-byte relocations available"), size);
1580 return;
1583 tic6x_fix_new_exp (frag, where, size, exp, 0, r_type, FALSE);
1586 /* Initialize target-specific fix data. */
1588 void
1589 tic6x_init_fix_data (fixS *fixP)
1591 fixP->tc_fix_data.fix_adda = FALSE;
1594 /* Given the fine-grained form of an operand, return the coarse
1595 (bit-mask) form. */
1597 static unsigned int
1598 tic6x_coarse_operand_form (tic6x_operand_form form)
1600 switch (form)
1602 case tic6x_operand_asm_const:
1603 case tic6x_operand_link_const:
1604 return TIC6X_OP_EXP;
1606 case tic6x_operand_reg:
1607 case tic6x_operand_xreg:
1608 case tic6x_operand_dreg:
1609 case tic6x_operand_areg:
1610 case tic6x_operand_retreg:
1611 return TIC6X_OP_REG;
1613 case tic6x_operand_regpair:
1614 case tic6x_operand_xregpair:
1615 case tic6x_operand_dregpair:
1616 return TIC6X_OP_REGPAIR;
1618 case tic6x_operand_irp:
1619 return TIC6X_OP_IRP;
1621 case tic6x_operand_nrp:
1622 return TIC6X_OP_NRP;
1624 case tic6x_operand_ctrl:
1625 return TIC6X_OP_CTRL;
1627 case tic6x_operand_mem_short:
1628 case tic6x_operand_mem_long:
1629 case tic6x_operand_mem_deref:
1630 return TIC6X_OP_MEM_NOUNREG;
1632 case tic6x_operand_mem_ndw:
1633 return TIC6X_OP_MEM_UNREG;
1635 case tic6x_operand_func_unit:
1636 return TIC6X_OP_FUNC_UNIT;
1638 default:
1639 abort ();
1643 /* How an operand may match or not match a desired form. If different
1644 instruction alternatives fail in different ways, the first failure
1645 in this list determines the diagnostic. */
1646 typedef enum
1648 /* Matches. */
1649 tic6x_match_matches,
1650 /* Bad coarse form. */
1651 tic6x_match_coarse,
1652 /* Not constant. */
1653 tic6x_match_non_const,
1654 /* Register on wrong side. */
1655 tic6x_match_wrong_side,
1656 /* Not a valid address register. */
1657 tic6x_match_bad_address,
1658 /* Not a valid return address register. */
1659 tic6x_match_bad_return,
1660 /* Control register not readable. */
1661 tic6x_match_ctrl_write_only,
1662 /* Control register not writable. */
1663 tic6x_match_ctrl_read_only,
1664 /* Not a valid memory reference for this instruction. */
1665 tic6x_match_bad_mem
1666 } tic6x_operand_match;
1668 /* Return whether an operand matches the given fine-grained form and
1669 read/write usage, and, if it does not match, how it fails to match.
1670 The main functional unit side is SIDE; the cross-path side is CROSS
1671 (the same as SIDE if a cross path not used); the data side is
1672 DATA_SIDE. */
1673 static tic6x_operand_match
1674 tic6x_operand_matches_form (const tic6x_operand *op, tic6x_operand_form form,
1675 tic6x_rw rw, unsigned int side, unsigned int cross,
1676 unsigned int data_side)
1678 unsigned int coarse = tic6x_coarse_operand_form (form);
1680 if (coarse != op->form)
1681 return tic6x_match_coarse;
1683 switch (form)
1685 case tic6x_operand_asm_const:
1686 if (op->value.exp.X_op == O_constant)
1687 return tic6x_match_matches;
1688 else
1689 return tic6x_match_non_const;
1691 case tic6x_operand_link_const:
1692 case tic6x_operand_irp:
1693 case tic6x_operand_nrp:
1694 case tic6x_operand_func_unit:
1695 /* All expressions are link-time constants, although there may
1696 not be relocations to express them in the output file. "irp"
1697 and "nrp" are unique operand values. All parsed functional
1698 unit names are valid. */
1699 return tic6x_match_matches;
1701 case tic6x_operand_reg:
1702 case tic6x_operand_regpair:
1703 if (op->value.reg.side == side)
1704 return tic6x_match_matches;
1705 else
1706 return tic6x_match_wrong_side;
1708 case tic6x_operand_xreg:
1709 case tic6x_operand_xregpair:
1710 if (op->value.reg.side == cross)
1711 return tic6x_match_matches;
1712 else
1713 return tic6x_match_wrong_side;
1715 case tic6x_operand_dreg:
1716 case tic6x_operand_dregpair:
1717 if (op->value.reg.side == data_side)
1718 return tic6x_match_matches;
1719 else
1720 return tic6x_match_wrong_side;
1722 case tic6x_operand_areg:
1723 if (op->value.reg.side != cross)
1724 return tic6x_match_wrong_side;
1725 else if (op->value.reg.side == 2
1726 && (op->value.reg.num == 14 || op->value.reg.num == 15))
1727 return tic6x_match_matches;
1728 else
1729 return tic6x_match_bad_address;
1731 case tic6x_operand_retreg:
1732 if (op->value.reg.side != side)
1733 return tic6x_match_wrong_side;
1734 else if (op->value.reg.num != 3)
1735 return tic6x_match_bad_return;
1736 else
1737 return tic6x_match_matches;
1739 case tic6x_operand_ctrl:
1740 switch (rw)
1742 case tic6x_rw_read:
1743 if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read
1744 || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
1745 return tic6x_match_matches;
1746 else
1747 return tic6x_match_ctrl_write_only;
1749 case tic6x_rw_write:
1750 if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_write
1751 || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
1752 return tic6x_match_matches;
1753 else
1754 return tic6x_match_ctrl_read_only;
1756 default:
1757 abort ();
1760 case tic6x_operand_mem_deref:
1761 if (op->value.mem.mod != tic6x_mem_mod_none)
1762 return tic6x_match_bad_mem;
1763 else if (op->value.mem.scaled != tic6x_offset_none)
1764 abort ();
1765 else if (op->value.mem.base_reg.side != side)
1766 return tic6x_match_bad_mem;
1767 else
1768 return tic6x_match_matches;
1770 case tic6x_operand_mem_short:
1771 case tic6x_operand_mem_ndw:
1772 if (op->value.mem.base_reg.side != side)
1773 return tic6x_match_bad_mem;
1774 if (op->value.mem.mod == tic6x_mem_mod_none)
1776 if (op->value.mem.scaled != tic6x_offset_none)
1777 abort ();
1778 return tic6x_match_matches;
1780 if (op->value.mem.scaled == tic6x_offset_none)
1782 if (op->value.mem.mod == tic6x_mem_mod_plus
1783 || op->value.mem.mod == tic6x_mem_mod_minus)
1784 abort ();
1785 return tic6x_match_matches;
1787 if (op->value.mem.offset_is_reg)
1789 if (op->value.mem.scaled == tic6x_offset_unscaled
1790 && form != tic6x_operand_mem_ndw)
1791 abort ();
1792 if (op->value.mem.offset.reg.side == side)
1793 return tic6x_match_matches;
1794 else
1795 return tic6x_match_bad_mem;
1797 else
1799 if (op->value.mem.offset.exp.X_op == O_constant)
1800 return tic6x_match_matches;
1801 else
1802 return tic6x_match_bad_mem;
1805 case tic6x_operand_mem_long:
1806 if (op->value.mem.base_reg.side == 2
1807 && (op->value.mem.base_reg.num == 14
1808 || op->value.mem.base_reg.num == 15))
1810 switch (op->value.mem.mod)
1812 case tic6x_mem_mod_none:
1813 if (op->value.mem.scaled != tic6x_offset_none)
1814 abort ();
1815 return tic6x_match_matches;
1817 case tic6x_mem_mod_plus:
1818 if (op->value.mem.scaled == tic6x_offset_none)
1819 abort ();
1820 if (op->value.mem.offset_is_reg)
1821 return tic6x_match_bad_mem;
1822 else if (op->value.mem.scaled == tic6x_offset_scaled
1823 && op->value.mem.offset.exp.X_op != O_constant)
1824 return tic6x_match_bad_mem;
1825 else
1826 return tic6x_match_matches;
1828 case tic6x_mem_mod_minus:
1829 case tic6x_mem_mod_preinc:
1830 case tic6x_mem_mod_predec:
1831 case tic6x_mem_mod_postinc:
1832 case tic6x_mem_mod_postdec:
1833 return tic6x_match_bad_mem;
1835 default:
1836 abort ();
1840 else
1841 return tic6x_match_bad_mem;
1843 default:
1844 abort ();
1848 /* Return the number of bits shift used with DP-relative coding method
1849 CODING. */
1851 static unsigned int
1852 tic6x_dpr_shift (tic6x_coding_method coding)
1854 switch (coding)
1856 case tic6x_coding_ulcst_dpr_byte:
1857 return 0;
1859 case tic6x_coding_ulcst_dpr_half:
1860 return 1;
1862 case tic6x_coding_ulcst_dpr_word:
1863 return 2;
1865 default:
1866 abort ();
1870 /* Return the relocation used with DP-relative coding method
1871 CODING. */
1873 static bfd_reloc_code_real_type
1874 tic6x_dpr_reloc (tic6x_coding_method coding)
1876 switch (coding)
1878 case tic6x_coding_ulcst_dpr_byte:
1879 return BFD_RELOC_C6000_SBR_U15_B;
1881 case tic6x_coding_ulcst_dpr_half:
1882 return BFD_RELOC_C6000_SBR_U15_H;
1884 case tic6x_coding_ulcst_dpr_word:
1885 return BFD_RELOC_C6000_SBR_U15_W;
1887 default:
1888 abort ();
1892 /* Given a memory reference *MEM_REF as originally parsed, fill in
1893 defaults for missing offsets. */
1895 static void
1896 tic6x_default_mem_ref (tic6x_mem_ref *mem_ref)
1898 switch (mem_ref->mod)
1900 case tic6x_mem_mod_none:
1901 if (mem_ref->scaled != tic6x_offset_none)
1902 abort ();
1903 mem_ref->mod = tic6x_mem_mod_plus;
1904 mem_ref->scaled = tic6x_offset_unscaled;
1905 mem_ref->offset_is_reg = FALSE;
1906 memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
1907 mem_ref->offset.exp.X_op = O_constant;
1908 mem_ref->offset.exp.X_add_number = 0;
1909 mem_ref->offset.exp.X_unsigned = 0;
1910 break;
1912 case tic6x_mem_mod_plus:
1913 case tic6x_mem_mod_minus:
1914 if (mem_ref->scaled == tic6x_offset_none)
1915 abort ();
1916 break;
1918 case tic6x_mem_mod_preinc:
1919 case tic6x_mem_mod_predec:
1920 case tic6x_mem_mod_postinc:
1921 case tic6x_mem_mod_postdec:
1922 if (mem_ref->scaled != tic6x_offset_none)
1923 break;
1924 mem_ref->scaled = tic6x_offset_scaled;
1925 mem_ref->offset_is_reg = FALSE;
1926 memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
1927 mem_ref->offset.exp.X_op = O_constant;
1928 mem_ref->offset.exp.X_add_number = 1;
1929 mem_ref->offset.exp.X_unsigned = 0;
1930 break;
1932 default:
1933 abort ();
1937 /* Return the encoding in the 8-bit field of an SPMASK or SPMASKR
1938 instruction of the specified UNIT, side SIDE. */
1940 static unsigned int
1941 tic6x_encode_spmask (tic6x_func_unit_base unit, unsigned int side)
1943 switch (unit)
1945 case tic6x_func_unit_l:
1946 return 1 << (side - 1);
1948 case tic6x_func_unit_s:
1949 return 1 << (side + 1);
1951 case tic6x_func_unit_d:
1952 return 1 << (side + 3);
1954 case tic6x_func_unit_m:
1955 return 1 << (side + 5);
1957 default:
1958 abort ();
1962 /* Try to encode the instruction with opcode number ID and operands
1963 OPERANDS (number NUM_OPERANDS), creg value THIS_LINE_CREG and z
1964 value THIS_LINE_Z; FUNC_UNIT_SIDE, FUNC_UNIT_CROSS and
1965 FUNC_UNIT_DATA_SIDE describe the functional unit specification;
1966 SPLOOP_II is the ii value from the previous SPLOOP-family
1967 instruction, or 0 if not in such a loop; the only possible problems
1968 are operands being out of range (they already match the
1969 fine-grained form), and inappropriate predication. If this
1970 succeeds, return the encoding and set *OK to TRUE; otherwise return
1971 0 and set *OK to FALSE. If a fix is needed, set *FIX_NEEDED to
1972 true and fill in *FIX_EXP, *FIX_PCREL, *FX_R_TYPE and *FIX_ADDA.
1973 Print error messages for failure if PRINT_ERRORS is TRUE; the
1974 opcode starts at STR and has length OPC_LEN. */
1976 static unsigned int
1977 tic6x_try_encode (tic6x_opcode_id id, tic6x_operand *operands,
1978 unsigned int num_operands, unsigned int this_line_creg,
1979 unsigned int this_line_z, unsigned int func_unit_side,
1980 unsigned int func_unit_cross,
1981 unsigned int func_unit_data_side, int sploop_ii,
1982 expressionS **fix_exp, int *fix_pcrel,
1983 bfd_reloc_code_real_type *fx_r_type, bfd_boolean *fix_adda,
1984 bfd_boolean *fix_needed, bfd_boolean *ok,
1985 bfd_boolean print_errors, char *str, int opc_len)
1987 const tic6x_opcode *opct;
1988 const tic6x_insn_format *fmt;
1989 unsigned int opcode_value;
1990 unsigned int fld;
1992 opct = &tic6x_opcode_table[id];
1993 fmt = &tic6x_insn_format_table[opct->format];
1994 opcode_value = fmt->cst_bits;
1996 for (fld = 0; fld < opct->num_fixed_fields; fld++)
1998 if (opct->fixed_fields[fld].min_val == opct->fixed_fields[fld].max_val)
2000 const tic6x_insn_field *fldd;
2001 fldd = tic6x_field_from_fmt (fmt, opct->fixed_fields[fld].field_id);
2002 if (fldd == NULL)
2003 abort ();
2004 opcode_value |= opct->fixed_fields[fld].min_val << fldd->low_pos;
2008 for (fld = 0; fld < opct->num_variable_fields; fld++)
2010 const tic6x_insn_field *fldd;
2011 unsigned int value;
2012 unsigned int opno;
2013 unsigned int ffld;
2014 offsetT sign_value;
2015 unsigned int bits;
2016 unsigned int fcyc_bits;
2017 expressionS *expp;
2018 expressionS ucexp;
2019 tic6x_mem_ref mem;
2021 fldd = tic6x_field_from_fmt (fmt, opct->variable_fields[fld].field_id);
2022 if (fldd == NULL)
2023 abort ();
2024 opno = opct->variable_fields[fld].operand_num;
2025 switch (opct->variable_fields[fld].coding_method)
2027 case tic6x_coding_ucst:
2028 if (operands[opno].form != TIC6X_OP_EXP)
2029 abort ();
2030 if (operands[opno].value.exp.X_op != O_constant)
2031 abort ();
2032 ucexp = operands[opno].value.exp;
2033 unsigned_constant:
2034 if (ucexp.X_add_number < 0
2035 || ucexp.X_add_number >= (1 << fldd->width))
2037 if (print_errors)
2038 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2039 opc_len, str);
2040 *ok = FALSE;
2041 return 0;
2043 value = ucexp.X_add_number;
2044 break;
2046 case tic6x_coding_scst:
2047 if (operands[opno].form != TIC6X_OP_EXP)
2048 abort ();
2049 if (operands[opno].value.exp.X_op != O_constant)
2051 value = 0;
2052 /* Opcode table should not permit non-constants without
2053 a known relocation for them. */
2054 if (fldd->low_pos != 7 || fldd->width != 16)
2055 abort ();
2056 *fix_needed = TRUE;
2057 *fix_exp = &operands[opno].value.exp;
2058 *fix_pcrel = 0;
2059 *fx_r_type = BFD_RELOC_C6000_ABS_S16;
2060 *fix_adda = FALSE;
2061 break;
2063 sign_value = SEXT (operands[opno].value.exp.X_add_number);
2064 signed_constant:
2065 if (sign_value < -(1 << (fldd->width - 1))
2066 || (sign_value >= (1 << (fldd->width - 1))))
2068 if (print_errors)
2069 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2070 opc_len, str);
2071 *ok = FALSE;
2072 return 0;
2074 value = sign_value + (1 << (fldd->width - 1));
2075 value ^= (1 << (fldd->width - 1));
2076 break;
2078 case tic6x_coding_ucst_minus_one:
2079 if (operands[opno].form != TIC6X_OP_EXP)
2080 abort ();
2081 if (operands[opno].value.exp.X_op != O_constant)
2082 abort ();
2083 if (operands[opno].value.exp.X_add_number <= 0
2084 || operands[opno].value.exp.X_add_number > (1 << fldd->width))
2086 if (print_errors)
2087 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2088 opc_len, str);
2089 *ok = FALSE;
2090 return 0;
2092 value = operands[opno].value.exp.X_add_number - 1;
2093 break;
2095 case tic6x_coding_scst_negate:
2096 if (operands[opno].form != TIC6X_OP_EXP)
2097 abort ();
2098 if (operands[opno].value.exp.X_op != O_constant)
2099 abort ();
2100 sign_value = SEXT (-operands[opno].value.exp.X_add_number);
2101 goto signed_constant;
2103 case tic6x_coding_ulcst_dpr_byte:
2104 case tic6x_coding_ulcst_dpr_half:
2105 case tic6x_coding_ulcst_dpr_word:
2106 bits = tic6x_dpr_shift (opct->variable_fields[fld].coding_method);
2107 switch (operands[opno].form)
2109 case TIC6X_OP_EXP:
2110 if (operands[opno].value.exp.X_op == O_constant)
2112 ucexp = operands[opno].value.exp;
2113 goto unsigned_constant;
2115 expp = &operands[opno].value.exp;
2116 break;
2118 case TIC6X_OP_MEM_NOUNREG:
2119 mem = operands[opno].value.mem;
2120 tic6x_default_mem_ref (&mem);
2121 if (mem.offset_is_reg)
2122 abort ();
2123 if (mem.offset.exp.X_op == O_constant)
2125 ucexp = mem.offset.exp;
2126 if (mem.scaled == tic6x_offset_unscaled)
2128 if (ucexp.X_add_number & ((1 << bits) - 1))
2130 if (print_errors)
2131 as_bad (_("offset in operand %u of '%.*s' not "
2132 "divisible by %u"), opno + 1, opc_len,
2133 str, 1u << bits);
2134 *ok = FALSE;
2135 return 0;
2137 ucexp.X_add_number >>= bits;
2139 goto unsigned_constant;
2141 if (mem.scaled != tic6x_offset_unscaled)
2142 abort ();
2143 if (operands[opno].value.mem.mod == tic6x_mem_mod_none
2144 || operands[opno].value.mem.scaled != tic6x_offset_unscaled
2145 || operands[opno].value.mem.offset_is_reg)
2146 abort ();
2147 expp = &operands[opno].value.mem.offset.exp;
2148 break;
2150 default:
2151 abort ();
2153 value = 0;
2154 /* Opcode table should not use this encoding without a known
2155 relocation. */
2156 if (fldd->low_pos != 8 || fldd->width != 15)
2157 abort ();
2158 /* We do not check for offset divisibility here; such a
2159 check is not needed at this point to encode the value,
2160 and if there is eventually a problem it will be detected
2161 either in md_apply_fix or at link time. */
2162 *fix_needed = TRUE;
2163 *fix_exp = expp;
2164 *fix_pcrel = 0;
2165 *fx_r_type
2166 = tic6x_dpr_reloc (opct->variable_fields[fld].coding_method);
2167 if (operands[opno].form == TIC6X_OP_EXP)
2168 *fix_adda = TRUE;
2169 else
2170 *fix_adda = FALSE;
2171 break;
2173 case tic6x_coding_lcst_low16:
2174 if (operands[opno].form != TIC6X_OP_EXP)
2175 abort ();
2176 if (operands[opno].value.exp.X_op == O_constant)
2177 value = operands[opno].value.exp.X_add_number & 0xffff;
2178 else
2180 value = 0;
2181 /* Opcode table should not use this encoding without a
2182 known relocation. */
2183 if (fldd->low_pos != 7 || fldd->width != 16)
2184 abort ();
2185 *fix_needed = TRUE;
2186 *fix_exp = &operands[opno].value.exp;
2187 *fix_pcrel = 0;
2188 *fx_r_type = BFD_RELOC_C6000_ABS_L16;
2189 *fix_adda = FALSE;
2191 break;
2193 case tic6x_coding_lcst_high16:
2194 if (operands[opno].form != TIC6X_OP_EXP)
2195 abort ();
2196 if (operands[opno].value.exp.X_op == O_constant)
2197 value = (operands[opno].value.exp.X_add_number >> 16) & 0xffff;
2198 else
2200 value = 0;
2201 /* Opcode table should not use this encoding without a
2202 known relocation. */
2203 if (fldd->low_pos != 7 || fldd->width != 16)
2204 abort ();
2205 *fix_needed = TRUE;
2206 *fix_exp = &operands[opno].value.exp;
2207 *fix_pcrel = 0;
2208 *fx_r_type = BFD_RELOC_C6000_ABS_H16;
2209 *fix_adda = FALSE;
2211 break;
2213 case tic6x_coding_pcrel:
2214 case tic6x_coding_pcrel_half:
2215 if (operands[opno].form != TIC6X_OP_EXP)
2216 abort ();
2217 value = 0;
2218 *fix_needed = TRUE;
2219 *fix_exp = &operands[opno].value.exp;
2220 *fix_pcrel = 1;
2221 if (fldd->low_pos == 7 && fldd->width == 21)
2222 *fx_r_type = BFD_RELOC_C6000_PCR_S21;
2223 else if (fldd->low_pos == 16 && fldd->width == 12)
2224 *fx_r_type = BFD_RELOC_C6000_PCR_S12;
2225 else if (fldd->low_pos == 13 && fldd->width == 10)
2226 *fx_r_type = BFD_RELOC_C6000_PCR_S10;
2227 else if (fldd->low_pos == 16 && fldd->width == 7)
2228 *fx_r_type = BFD_RELOC_C6000_PCR_S7;
2229 else
2230 /* Opcode table should not use this encoding without a
2231 known relocation. */
2232 abort ();
2233 *fix_adda = FALSE;
2234 break;
2236 case tic6x_coding_reg:
2237 switch (operands[opno].form)
2239 case TIC6X_OP_REG:
2240 case TIC6X_OP_REGPAIR:
2241 value = operands[opno].value.reg.num;
2242 break;
2244 case TIC6X_OP_MEM_NOUNREG:
2245 case TIC6X_OP_MEM_UNREG:
2246 value = operands[opno].value.mem.base_reg.num;
2247 break;
2249 default:
2250 abort ();
2252 break;
2254 case tic6x_coding_areg:
2255 switch (operands[opno].form)
2257 case TIC6X_OP_REG:
2258 value = (operands[opno].value.reg.num == 15 ? 1 : 0);
2259 break;
2261 case TIC6X_OP_MEM_NOUNREG:
2262 value = (operands[opno].value.mem.base_reg.num == 15 ? 1 : 0);
2263 break;
2265 default:
2266 abort ();
2268 break;
2270 case tic6x_coding_crlo:
2271 if (operands[opno].form != TIC6X_OP_CTRL)
2272 abort ();
2273 value = tic6x_ctrl_table[operands[opno].value.ctrl].crlo;
2274 break;
2276 case tic6x_coding_crhi:
2277 if (operands[opno].form != TIC6X_OP_CTRL)
2278 abort ();
2279 value = 0;
2280 break;
2282 case tic6x_coding_reg_shift:
2283 if (operands[opno].form != TIC6X_OP_REGPAIR)
2284 abort ();
2285 value = operands[opno].value.reg.num >> 1;
2286 break;
2288 case tic6x_coding_mem_offset:
2289 if (operands[opno].form != TIC6X_OP_MEM_NOUNREG)
2290 abort ();
2291 mem = operands[opno].value.mem;
2292 tic6x_default_mem_ref (&mem);
2293 if (mem.offset_is_reg)
2295 if (mem.scaled != tic6x_offset_scaled)
2296 abort ();
2297 value = mem.offset.reg.num;
2299 else
2301 int scale;
2303 if (mem.offset.exp.X_op != O_constant)
2304 abort ();
2305 switch (mem.scaled)
2307 case tic6x_offset_scaled:
2308 scale = 1;
2309 break;
2311 case tic6x_offset_unscaled:
2312 scale = opct->operand_info[opno].size;
2313 if (scale != 1 && scale != 2 && scale != 4 && scale != 8)
2314 abort ();
2315 break;
2317 default:
2318 abort ();
2320 if (mem.offset.exp.X_add_number < 0
2321 || mem.offset.exp.X_add_number >= (1 << fldd->width) * scale)
2323 if (print_errors)
2324 as_bad (_("offset in operand %u of '%.*s' out of range"),
2325 opno + 1, opc_len, str);
2326 *ok = FALSE;
2327 return 0;
2329 if (mem.offset.exp.X_add_number % scale)
2331 if (print_errors)
2332 as_bad (_("offset in operand %u of '%.*s' not "
2333 "divisible by %u"),
2334 opno + 1, opc_len, str, scale);
2335 *ok = FALSE;
2336 return 0;
2338 value = mem.offset.exp.X_add_number / scale;
2340 break;
2342 case tic6x_coding_mem_offset_noscale:
2343 if (operands[opno].form != TIC6X_OP_MEM_UNREG)
2344 abort ();
2345 mem = operands[opno].value.mem;
2346 tic6x_default_mem_ref (&mem);
2347 if (mem.offset_is_reg)
2348 value = mem.offset.reg.num;
2349 else
2351 if (mem.offset.exp.X_op != O_constant)
2352 abort ();
2353 if (mem.offset.exp.X_add_number < 0
2354 || mem.offset.exp.X_add_number >= (1 << fldd->width))
2356 if (print_errors)
2357 as_bad (_("offset in operand %u of '%.*s' out of range"),
2358 opno + 1, opc_len, str);
2359 *ok = FALSE;
2360 return 0;
2362 value = mem.offset.exp.X_add_number;
2364 break;
2366 case tic6x_coding_mem_mode:
2367 if (operands[opno].form != TIC6X_OP_MEM_NOUNREG
2368 && operands[opno].form != TIC6X_OP_MEM_UNREG)
2369 abort ();
2370 mem = operands[opno].value.mem;
2371 tic6x_default_mem_ref (&mem);
2372 switch (mem.mod)
2374 case tic6x_mem_mod_plus:
2375 value = 1;
2376 break;
2378 case tic6x_mem_mod_minus:
2379 value = 0;
2380 break;
2382 case tic6x_mem_mod_preinc:
2383 value = 9;
2384 break;
2386 case tic6x_mem_mod_predec:
2387 value = 8;
2388 break;
2390 case tic6x_mem_mod_postinc:
2391 value = 11;
2392 break;
2394 case tic6x_mem_mod_postdec:
2395 value = 10;
2396 break;
2398 default:
2399 abort ();
2401 value += (mem.offset_is_reg ? 4 : 0);
2402 break;
2404 case tic6x_coding_scaled:
2405 if (operands[opno].form != TIC6X_OP_MEM_UNREG)
2406 abort ();
2407 mem = operands[opno].value.mem;
2408 tic6x_default_mem_ref (&mem);
2409 switch (mem.scaled)
2411 case tic6x_offset_unscaled:
2412 value = 0;
2413 break;
2415 case tic6x_offset_scaled:
2416 value = 1;
2417 break;
2419 default:
2420 abort ();
2422 break;
2424 case tic6x_coding_spmask:
2425 /* The position of such a field is hardcoded in the handling
2426 of "||^". */
2427 if (fldd->low_pos != 18)
2428 abort ();
2429 value = 0;
2430 for (opno = 0; opno < num_operands; opno++)
2432 unsigned int v;
2434 v = tic6x_encode_spmask (operands[opno].value.func_unit.base,
2435 operands[opno].value.func_unit.side);
2436 if (value & v)
2438 if (print_errors)
2439 as_bad (_("functional unit already masked for operand "
2440 "%u of '%.*s'"), opno + 1, opc_len, str);
2441 *ok = FALSE;
2442 return 0;
2444 value |= v;
2446 break;
2448 case tic6x_coding_reg_unused:
2449 /* This is a placeholder; correct handling goes along with
2450 resource constraint checks. */
2451 value = 0;
2452 break;
2454 case tic6x_coding_fstg:
2455 case tic6x_coding_fcyc:
2456 if (operands[opno].form != TIC6X_OP_EXP)
2457 abort ();
2458 if (operands[opno].value.exp.X_op != O_constant)
2459 abort ();
2460 if (!sploop_ii)
2462 if (print_errors)
2463 as_bad (_("'%.*s' instruction not in a software "
2464 "pipelined loop"),
2465 opc_len, str);
2466 *ok = FALSE;
2467 return 0;
2470 if (sploop_ii <= 1)
2471 fcyc_bits = 0;
2472 else if (sploop_ii <= 2)
2473 fcyc_bits = 1;
2474 else if (sploop_ii <= 4)
2475 fcyc_bits = 2;
2476 else if (sploop_ii <= 8)
2477 fcyc_bits = 3;
2478 else if (sploop_ii <= 14)
2479 fcyc_bits = 4;
2480 else
2481 abort ();
2482 if (fcyc_bits > fldd->width)
2483 abort ();
2485 if (opct->variable_fields[fld].coding_method == tic6x_coding_fstg)
2487 if (operands[opno].value.exp.X_add_number < 0
2488 || (operands[opno].value.exp.X_add_number
2489 >= (1 << (fldd->width - fcyc_bits))))
2491 if (print_errors)
2492 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2493 opc_len, str);
2494 *ok = FALSE;
2495 return 0;
2497 value = operands[opno].value.exp.X_add_number << fcyc_bits;
2499 else
2501 if (operands[opno].value.exp.X_add_number < 0
2502 || (operands[opno].value.exp.X_add_number >= sploop_ii))
2504 if (print_errors)
2505 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2506 opc_len, str);
2507 *ok = FALSE;
2508 return 0;
2510 value = operands[opno].value.exp.X_add_number;
2512 break;
2514 case tic6x_coding_fu:
2515 value = func_unit_side == 2 ? 1 : 0;
2516 break;
2518 case tic6x_coding_data_fu:
2519 value = func_unit_data_side == 2 ? 1 : 0;
2520 break;
2522 case tic6x_coding_xpath:
2523 value = func_unit_cross;
2524 break;
2526 default:
2527 abort ();
2530 for (ffld = 0; ffld < opct->num_fixed_fields; ffld++)
2531 if ((opct->fixed_fields[ffld].field_id
2532 == opct->variable_fields[fld].field_id)
2533 && (value < opct->fixed_fields[ffld].min_val
2534 || value > opct->fixed_fields[ffld].max_val))
2536 if (print_errors)
2537 as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2538 opc_len, str);
2539 *ok = FALSE;
2540 return 0;
2543 opcode_value |= value << fldd->low_pos;
2546 if (this_line_creg)
2548 const tic6x_insn_field *creg;
2549 const tic6x_insn_field *z;
2551 creg = tic6x_field_from_fmt (fmt, tic6x_field_creg);
2552 if (creg == NULL)
2554 if (print_errors)
2555 as_bad (_("instruction '%.*s' cannot be predicated"),
2556 opc_len, str);
2557 *ok = FALSE;
2558 return 0;
2560 z = tic6x_field_from_fmt (fmt, tic6x_field_z);
2561 /* If there is a creg field, there must be a z field; otherwise
2562 there is an error in the format table. */
2563 if (z == NULL)
2564 abort ();
2566 opcode_value |= this_line_creg << creg->low_pos;
2567 opcode_value |= this_line_z << z->low_pos;
2570 *ok = TRUE;
2571 return opcode_value;
2574 /* Convert the target integer stored in N bytes in BUF to a host
2575 integer, returning that value. */
2577 static valueT
2578 md_chars_to_number (char *buf, int n)
2580 valueT result = 0;
2581 unsigned char *p = (unsigned char *) buf;
2583 if (target_big_endian)
2585 while (n--)
2587 result <<= 8;
2588 result |= (*p++ & 0xff);
2591 else
2593 while (n--)
2595 result <<= 8;
2596 result |= (p[n] & 0xff);
2600 return result;
2603 /* Assemble the instruction starting at STR (an opcode, with the
2604 opcode name all-lowercase). */
2606 void
2607 md_assemble (char *str)
2609 char *p;
2610 int opc_len;
2611 bfd_boolean this_line_parallel;
2612 bfd_boolean this_line_spmask;
2613 unsigned int this_line_creg;
2614 unsigned int this_line_z;
2615 tic6x_label_list *this_insn_label_list;
2616 segment_info_type *seginfo;
2617 tic6x_opcode_list *opc_list, *opc;
2618 tic6x_func_unit_base func_unit_base = tic6x_func_unit_nfu;
2619 unsigned int func_unit_side = 0;
2620 unsigned int func_unit_cross = 0;
2621 unsigned int cross_side = 0;
2622 unsigned int func_unit_data_side = 0;
2623 unsigned int max_matching_opcodes, num_matching_opcodes;
2624 tic6x_opcode_id *opcm = NULL;
2625 unsigned int opc_rank[TIC6X_NUM_PREFER];
2626 const tic6x_opcode *opct = NULL;
2627 int min_rank, try_rank, max_rank;
2628 bfd_boolean num_operands_permitted[TIC6X_MAX_SOURCE_OPERANDS + 1]
2629 = { FALSE };
2630 unsigned int operand_forms[TIC6X_MAX_SOURCE_OPERANDS] = { 0 };
2631 tic6x_operand operands[TIC6X_MAX_SOURCE_OPERANDS];
2632 unsigned int max_num_operands;
2633 unsigned int num_operands_read;
2634 bfd_boolean ok_this_arch, ok_this_fu, ok_this_arch_fu;
2635 bfd_boolean bad_operands = FALSE;
2636 unsigned int opcode_value;
2637 bfd_boolean encoded_ok;
2638 bfd_boolean fix_needed = FALSE;
2639 expressionS *fix_exp = NULL;
2640 int fix_pcrel = 0;
2641 bfd_reloc_code_real_type fx_r_type = BFD_RELOC_UNUSED;
2642 bfd_boolean fix_adda = FALSE;
2643 fragS *insn_frag;
2644 char *output;
2646 p = str;
2647 while (*p && !is_end_of_line[(unsigned char) *p] && *p != ' ')
2648 p++;
2650 /* This function should only have been called when there is actually
2651 an instruction to assemble. */
2652 if (p == str)
2653 abort ();
2655 /* Now an instruction has been seen, architecture attributes from
2656 .arch directives merge with rather than overriding the previous
2657 value. */
2658 tic6x_seen_insns = TRUE;
2659 /* If no .arch directives or -march options have been seen, we are
2660 assessing instruction validity based on the C674X default, so set
2661 the attribute accordingly. */
2662 if (tic6x_arch_attribute == C6XABI_Tag_CPU_arch_none)
2663 tic6x_arch_attribute = C6XABI_Tag_CPU_arch_C674X;
2665 /* Reset global settings for parallel bars and predicates now to
2666 avoid extra errors if there are problems with this opcode. */
2667 this_line_parallel = tic6x_line_parallel;
2668 this_line_spmask = tic6x_line_spmask;
2669 this_line_creg = tic6x_line_creg;
2670 this_line_z = tic6x_line_z;
2671 tic6x_line_parallel = FALSE;
2672 tic6x_line_spmask = FALSE;
2673 tic6x_line_creg = 0;
2674 tic6x_line_z = 0;
2675 seginfo = seg_info (now_seg);
2676 this_insn_label_list = seginfo->tc_segment_info_data.label_list;
2677 seginfo->tc_segment_info_data.label_list = NULL;
2679 opc_list = hash_find_n (opcode_hash, str, p - str);
2680 if (opc_list == NULL)
2682 char c = *p;
2683 *p = 0;
2684 as_bad (_("unknown opcode '%s'"), str);
2685 *p = c;
2686 return;
2689 opc_len = p - str;
2690 skip_whitespace (p);
2692 /* See if there is something that looks like a functional unit
2693 specifier. */
2694 if (*p == '.')
2696 bfd_boolean good_func_unit;
2697 tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
2698 unsigned int maybe_side = 0;
2699 unsigned int maybe_cross = 0;
2700 unsigned int maybe_data_side = 0;
2702 good_func_unit = tic6x_parse_func_unit_base (p + 1, &maybe_base,
2703 &maybe_side);
2705 if (good_func_unit)
2707 if (p[3] == ' ' || is_end_of_line[(unsigned char) p[3]])
2708 p += 3;
2709 else if ((p[3] == 'x' || p[3] == 'X')
2710 && (p[4] == ' ' || is_end_of_line[(unsigned char) p[4]]))
2712 maybe_cross = 1;
2713 p += 4;
2715 else if (maybe_base == tic6x_func_unit_d
2716 && (p[3] == 't' || p[3] == 'T')
2717 && (p[4] == '1' || p[4] == '2')
2718 && (p[5] == ' ' || is_end_of_line[(unsigned char) p[5]]))
2720 maybe_data_side = p[4] - '0';
2721 p += 5;
2723 else
2724 good_func_unit = FALSE;
2727 if (good_func_unit)
2729 func_unit_base = maybe_base;
2730 func_unit_side = maybe_side;
2731 func_unit_cross = maybe_cross;
2732 cross_side = (func_unit_cross ? 3 - func_unit_side : func_unit_side);
2733 func_unit_data_side = maybe_data_side;
2736 skip_whitespace (p);
2739 /* Determine which entries in the opcode table match, and the
2740 associated permitted forms of operands. */
2741 max_matching_opcodes = 0;
2742 for (opc = opc_list; opc; opc = opc->next)
2743 max_matching_opcodes++;
2744 num_matching_opcodes = 0;
2745 opcm = xmalloc (max_matching_opcodes * sizeof (*opcm));
2746 max_num_operands = 0;
2747 ok_this_arch = FALSE;
2748 ok_this_fu = FALSE;
2749 ok_this_arch_fu = FALSE;
2750 for (opc = opc_list; opc; opc = opc->next)
2752 unsigned int num_operands;
2753 unsigned int i;
2754 bfd_boolean this_opc_arch_ok = TRUE;
2755 bfd_boolean this_opc_fu_ok = TRUE;
2757 if (tic6x_insn_format_table[tic6x_opcode_table[opc->id].format].num_bits
2758 != 32)
2759 continue;
2760 if (!(tic6x_opcode_table[opc->id].isa_variants & tic6x_features))
2761 this_opc_arch_ok = FALSE;
2762 if (tic6x_opcode_table[opc->id].func_unit != func_unit_base)
2763 this_opc_fu_ok = FALSE;
2764 if (func_unit_side == 1
2765 && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_B_ONLY))
2766 this_opc_fu_ok = FALSE;
2767 if (func_unit_cross
2768 && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_NO_CROSS))
2769 this_opc_fu_ok = FALSE;
2770 if (!func_unit_data_side
2771 && (tic6x_opcode_table[opc->id].flags
2772 & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
2773 this_opc_fu_ok = FALSE;
2774 if (func_unit_data_side
2775 && !(tic6x_opcode_table[opc->id].flags
2776 & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
2777 this_opc_fu_ok = FALSE;
2778 if (func_unit_data_side == 1
2779 && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_T2_ONLY))
2780 this_opc_fu_ok = FALSE;
2781 if (this_opc_arch_ok)
2782 ok_this_arch = TRUE;
2783 if (this_opc_fu_ok)
2784 ok_this_fu = TRUE;
2785 if (!this_opc_arch_ok || !this_opc_fu_ok)
2786 continue;
2787 ok_this_arch_fu = TRUE;
2788 opcm[num_matching_opcodes] = opc->id;
2789 num_matching_opcodes++;
2790 num_operands = tic6x_opcode_table[opc->id].num_operands;
2792 if (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SPMASK)
2794 if (num_operands != 1
2795 || (tic6x_opcode_table[opc->id].operand_info[0].form
2796 != tic6x_operand_func_unit))
2797 abort ();
2798 num_operands = 8;
2799 for (i = 0; i < num_operands; i++)
2801 operand_forms[i]
2802 |= tic6x_coarse_operand_form (tic6x_operand_func_unit);
2803 num_operands_permitted[i] = TRUE;
2806 else
2808 for (i = 0; i < num_operands; i++)
2810 tic6x_operand_form f
2811 = tic6x_opcode_table[opc->id].operand_info[i].form;
2813 operand_forms[i] |= tic6x_coarse_operand_form (f);
2816 num_operands_permitted[num_operands] = TRUE;
2817 if (num_operands > max_num_operands)
2818 max_num_operands = num_operands;
2821 if (!ok_this_arch)
2823 as_bad (_("'%.*s' instruction not supported on this architecture"),
2824 opc_len, str);
2825 free (opcm);
2826 return;
2829 if (!ok_this_fu)
2831 as_bad (_("'%.*s' instruction not supported on this functional unit"),
2832 opc_len, str);
2833 free (opcm);
2834 return;
2837 if (!ok_this_arch_fu)
2839 as_bad (_("'%.*s' instruction not supported on this functional unit"
2840 " for this architecture"),
2841 opc_len, str);
2842 free (opcm);
2843 return;
2846 /* If there were no instructions matching the above availability
2847 checks, we should now have given an error and returned. */
2848 if (num_matching_opcodes == 0)
2849 abort ();
2851 num_operands_read = 0;
2852 while (TRUE)
2854 skip_whitespace (p);
2855 if (is_end_of_line[(unsigned char) *p])
2857 if (num_operands_read > 0)
2859 as_bad (_("missing operand after comma"));
2860 bad_operands = TRUE;
2862 break;
2865 if (max_num_operands == 0)
2867 as_bad (_("too many operands to '%.*s'"), opc_len, str);
2868 bad_operands = TRUE;
2869 break;
2872 if (!tic6x_parse_operand (&p, &operands[num_operands_read],
2873 operand_forms[num_operands_read], str, opc_len,
2874 num_operands_read + 1))
2875 bad_operands = TRUE;
2876 num_operands_read++;
2878 if (is_end_of_line[(unsigned char) *p])
2879 break;
2880 else if (*p == ',')
2882 p++;
2883 if (num_operands_read == max_num_operands)
2885 as_bad (_("too many operands to '%.*s'"), opc_len, str);
2886 bad_operands = TRUE;
2887 break;
2889 continue;
2891 else
2892 /* Operand parsing should consume whole operands. */
2893 abort ();
2896 if (!bad_operands && !num_operands_permitted[num_operands_read])
2898 as_bad (_("bad number of operands to '%.*s'"), opc_len, str);
2899 bad_operands = TRUE;
2902 if (!bad_operands)
2904 /* Each operand is of the right syntactic form for some opcode
2905 choice, and the number of operands is valid. Check that each
2906 operand is OK in detail for some opcode choice with the right
2907 number of operands. */
2908 unsigned int i;
2910 for (i = 0; i < num_operands_read; i++)
2912 bfd_boolean coarse_ok = FALSE;
2913 bfd_boolean fine_ok = FALSE;
2914 tic6x_operand_match fine_failure = tic6x_match_matches;
2915 unsigned int j;
2917 for (j = 0; j < num_matching_opcodes; j++)
2919 tic6x_operand_form f;
2920 tic6x_rw rw;
2921 unsigned int cf;
2922 tic6x_operand_match this_fine_failure;
2924 if (tic6x_opcode_table[opcm[j]].flags & TIC6X_FLAG_SPMASK)
2926 f = tic6x_operand_func_unit;
2927 rw = tic6x_rw_none;
2929 else
2931 if (tic6x_opcode_table[opcm[j]].num_operands
2932 != num_operands_read)
2933 continue;
2935 f = tic6x_opcode_table[opcm[j]].operand_info[i].form;
2936 rw = tic6x_opcode_table[opcm[j]].operand_info[i].rw;
2938 cf = tic6x_coarse_operand_form (f);
2940 if (operands[i].form != cf)
2941 continue;
2943 coarse_ok = TRUE;
2944 this_fine_failure
2945 = tic6x_operand_matches_form (&operands[i], f, rw,
2946 func_unit_side,
2947 cross_side,
2948 func_unit_data_side);
2949 if (this_fine_failure == tic6x_match_matches)
2951 fine_ok = TRUE;
2952 break;
2954 if (fine_failure == tic6x_match_matches
2955 || fine_failure > this_fine_failure)
2956 fine_failure = this_fine_failure;
2959 /* No instructions should have operand syntactic forms only
2960 acceptable with certain numbers of operands, so no
2961 diagnostic for this case. */
2962 if (!coarse_ok)
2963 abort ();
2965 if (!fine_ok)
2967 switch (fine_failure)
2969 case tic6x_match_non_const:
2970 as_bad (_("operand %u of '%.*s' not constant"),
2971 i + 1, opc_len, str);
2972 break;
2974 case tic6x_match_wrong_side:
2975 as_bad (_("operand %u of '%.*s' on wrong side"),
2976 i + 1, opc_len, str);
2977 break;
2979 case tic6x_match_bad_return:
2980 as_bad (_("operand %u of '%.*s' not a valid return "
2981 "address register"),
2982 i + 1, opc_len, str);
2983 break;
2985 case tic6x_match_ctrl_write_only:
2986 as_bad (_("operand %u of '%.*s' is write-only"),
2987 i + 1, opc_len, str);
2988 break;
2990 case tic6x_match_ctrl_read_only:
2991 as_bad (_("operand %u of '%.*s' is read-only"),
2992 i + 1, opc_len, str);
2993 break;
2995 case tic6x_match_bad_mem:
2996 as_bad (_("operand %u of '%.*s' not a valid memory "
2997 "reference"),
2998 i + 1, opc_len, str);
2999 break;
3001 case tic6x_match_bad_address:
3002 as_bad (_("operand %u of '%.*s' not a valid base "
3003 "address register"),
3004 i + 1, opc_len, str);
3005 break;
3007 default:
3008 abort ();
3010 bad_operands = TRUE;
3011 break;
3016 if (!bad_operands)
3018 /* Each operand is OK for some opcode choice, and the number of
3019 operands is valid. Check whether there is an opcode choice
3020 for which all operands are simultaneously valid. */
3021 unsigned int i;
3022 bfd_boolean found_match = FALSE;
3024 for (i = 0; i < TIC6X_NUM_PREFER; i++)
3025 opc_rank[i] = (unsigned int) -1;
3027 min_rank = TIC6X_NUM_PREFER - 1;
3028 max_rank = 0;
3030 for (i = 0; i < num_matching_opcodes; i++)
3032 unsigned int j;
3033 bfd_boolean this_matches = TRUE;
3035 if (!(tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
3036 && tic6x_opcode_table[opcm[i]].num_operands != num_operands_read)
3037 continue;
3039 for (j = 0; j < num_operands_read; j++)
3041 tic6x_operand_form f;
3042 tic6x_rw rw;
3044 if (tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
3046 f = tic6x_operand_func_unit;
3047 rw = tic6x_rw_none;
3049 else
3051 f = tic6x_opcode_table[opcm[i]].operand_info[j].form;
3052 rw = tic6x_opcode_table[opcm[i]].operand_info[j].rw;
3054 if (tic6x_operand_matches_form (&operands[j], f, rw,
3055 func_unit_side,
3056 cross_side,
3057 func_unit_data_side)
3058 != tic6x_match_matches)
3060 this_matches = FALSE;
3061 break;
3065 if (this_matches)
3067 int rank = TIC6X_PREFER_VAL (tic6x_opcode_table[opcm[i]].flags);
3069 if (rank < min_rank)
3070 min_rank = rank;
3071 if (rank > max_rank)
3072 max_rank = rank;
3074 if (opc_rank[rank] == (unsigned int) -1)
3075 opc_rank[rank] = i;
3076 else
3077 /* The opcode table should provide a total ordering
3078 for all cases where multiple matches may get
3079 here. */
3080 abort ();
3082 found_match = TRUE;
3086 if (!found_match)
3088 as_bad (_("bad operand combination for '%.*s'"), opc_len, str);
3089 bad_operands = TRUE;
3093 if (bad_operands)
3095 free (opcm);
3096 return;
3099 opcode_value = 0;
3100 encoded_ok = FALSE;
3101 for (try_rank = max_rank; try_rank >= min_rank; try_rank--)
3103 fix_needed = FALSE;
3105 if (opc_rank[try_rank] == (unsigned int) -1)
3106 continue;
3108 opcode_value = tic6x_try_encode (opcm[opc_rank[try_rank]], operands,
3109 num_operands_read, this_line_creg,
3110 this_line_z, func_unit_side,
3111 func_unit_cross, func_unit_data_side,
3112 seginfo->tc_segment_info_data.sploop_ii,
3113 &fix_exp, &fix_pcrel, &fx_r_type,
3114 &fix_adda, &fix_needed, &encoded_ok,
3115 (try_rank == min_rank ? TRUE : FALSE),
3116 str, opc_len);
3117 if (encoded_ok)
3119 opct = &tic6x_opcode_table[opcm[opc_rank[try_rank]]];
3120 break;
3124 free (opcm);
3126 if (!encoded_ok)
3127 return;
3129 if (this_line_parallel)
3131 insn_frag = seginfo->tc_segment_info_data.execute_packet_frag;
3132 if (insn_frag == NULL)
3134 as_bad (_("parallel instruction not following another instruction"));
3135 return;
3138 if (insn_frag->fr_fix >= 32)
3140 as_bad (_("too many instructions in execute packet"));
3141 return;
3144 if (this_insn_label_list != NULL)
3145 as_bad (_("label not at start of execute packet"));
3147 if (opct->flags & TIC6X_FLAG_FIRST)
3148 as_bad (_("'%.*s' instruction not at start of execute packet"),
3149 opc_len, str);
3151 *seginfo->tc_segment_info_data.last_insn_lsb |= 0x1;
3152 output = insn_frag->fr_literal + insn_frag->fr_fix;
3154 else
3156 tic6x_label_list *l;
3158 seginfo->tc_segment_info_data.spmask_addr = NULL;
3159 seginfo->tc_segment_info_data.func_units_used = 0;
3161 /* Start a new frag for this execute packet. */
3162 if (frag_now_fix () != 0)
3164 if (frag_now->fr_type != rs_machine_dependent)
3165 frag_wane (frag_now);
3167 frag_new (0);
3169 frag_grow (32);
3170 insn_frag = seginfo->tc_segment_info_data.execute_packet_frag = frag_now;
3171 for (l = this_insn_label_list; l; l = l->next)
3173 symbol_set_frag (l->label, frag_now);
3174 S_SET_VALUE (l->label, 0);
3175 S_SET_SEGMENT (l->label, now_seg);
3177 tic6x_free_label_list (this_insn_label_list);
3178 dwarf2_emit_insn (0);
3179 output = frag_var (rs_machine_dependent, 32, 32, 0, NULL, 0, NULL);
3180 /* This must be the same as the frag to which a pointer was just
3181 saved. */
3182 if (output != insn_frag->fr_literal)
3183 abort ();
3184 insn_frag->tc_frag_data.is_insns = TRUE;
3185 insn_frag->tc_frag_data.can_cross_fp_boundary
3186 = tic6x_can_cross_fp_boundary;
3189 if (func_unit_base != tic6x_func_unit_nfu)
3191 unsigned int func_unit_enc;
3193 func_unit_enc = tic6x_encode_spmask (func_unit_base, func_unit_side);
3195 if (seginfo->tc_segment_info_data.func_units_used & func_unit_enc)
3196 as_bad (_("functional unit already used in this execute packet"));
3198 seginfo->tc_segment_info_data.func_units_used |= func_unit_enc;
3201 if (opct->flags & TIC6X_FLAG_SPLOOP)
3203 if (seginfo->tc_segment_info_data.sploop_ii)
3204 as_bad (_("nested software pipelined loop"));
3205 if (num_operands_read != 1
3206 || operands[0].form != TIC6X_OP_EXP
3207 || operands[0].value.exp.X_op != O_constant)
3208 abort ();
3209 seginfo->tc_segment_info_data.sploop_ii
3210 = operands[0].value.exp.X_add_number;
3212 else if (opct->flags & TIC6X_FLAG_SPKERNEL)
3214 if (!seginfo->tc_segment_info_data.sploop_ii)
3215 as_bad (_("'%.*s' instruction not in a software pipelined loop"),
3216 opc_len, str);
3217 seginfo->tc_segment_info_data.sploop_ii = 0;
3220 if (this_line_spmask)
3222 if (seginfo->tc_segment_info_data.spmask_addr == NULL)
3223 as_bad (_("'||^' without previous SPMASK"));
3224 else if (func_unit_base == tic6x_func_unit_nfu)
3225 as_bad (_("cannot mask instruction using no functional unit"));
3226 else
3228 unsigned int spmask_opcode;
3229 unsigned int mask_bit;
3231 spmask_opcode
3232 = md_chars_to_number (seginfo->tc_segment_info_data.spmask_addr,
3234 mask_bit = tic6x_encode_spmask (func_unit_base, func_unit_side);
3235 mask_bit <<= 18;
3236 if (spmask_opcode & mask_bit)
3237 as_bad (_("functional unit already masked"));
3238 spmask_opcode |= mask_bit;
3239 md_number_to_chars (seginfo->tc_segment_info_data.spmask_addr,
3240 spmask_opcode, 4);
3244 record_alignment (now_seg, 5);
3245 md_number_to_chars (output, opcode_value, 4);
3246 if (fix_needed)
3247 tic6x_fix_new_exp (insn_frag, output - insn_frag->fr_literal, 4, fix_exp,
3248 fix_pcrel, fx_r_type, fix_adda);
3249 insn_frag->fr_fix += 4;
3250 insn_frag->fr_var -= 4;
3251 seginfo->tc_segment_info_data.last_insn_lsb
3252 = (target_big_endian ? output + 3 : output);
3253 if (opct->flags & TIC6X_FLAG_SPMASK)
3254 seginfo->tc_segment_info_data.spmask_addr = output;
3257 /* Modify NEWVAL (32-bit) by inserting VALUE, shifted right by SHIFT
3258 and the least significant BITS bits taken, at position POS. */
3259 #define MODIFY_VALUE(NEWVAL, VALUE, SHIFT, POS, BITS) \
3260 do { \
3261 (NEWVAL) &= 0xffffffffU & ~(((1U << (BITS)) - 1) << (POS)); \
3262 (NEWVAL) |= (((VALUE) >> (SHIFT)) & ((1U << (BITS)) - 1)) << (POS); \
3263 } while (0)
3265 /* Apply a fixup to the object file. */
3267 void
3268 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3270 offsetT value = *valP;
3271 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3273 value = SEXT (value);
3274 *valP = value;
3276 fixP->fx_offset = SEXT (fixP->fx_offset);
3278 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
3279 fixP->fx_done = 1;
3281 /* We do our own overflow checks. */
3282 fixP->fx_no_overflow = 1;
3284 switch (fixP->fx_r_type)
3286 case BFD_RELOC_NONE:
3287 /* Force output to the object file. */
3288 fixP->fx_done = 0;
3289 break;
3291 case BFD_RELOC_32:
3292 if (fixP->fx_done || !seg->use_rela_p)
3293 md_number_to_chars (buf, value, 4);
3294 break;
3296 case BFD_RELOC_16:
3297 if (fixP->fx_done || !seg->use_rela_p)
3299 if (value < -0x8000 || value > 0xffff)
3300 as_bad_where (fixP->fx_file, fixP->fx_line,
3301 _("value too large for 2-byte field"));
3302 md_number_to_chars (buf, value, 2);
3304 break;
3306 case BFD_RELOC_8:
3307 if (fixP->fx_done || !seg->use_rela_p)
3309 if (value < -0x80 || value > 0xff)
3310 as_bad_where (fixP->fx_file, fixP->fx_line,
3311 _("value too large for 1-byte field"));
3312 md_number_to_chars (buf, value, 1);
3314 break;
3316 case BFD_RELOC_C6000_ABS_S16:
3317 case BFD_RELOC_C6000_ABS_L16:
3318 case BFD_RELOC_C6000_SBR_S16:
3319 case BFD_RELOC_C6000_SBR_L16_B:
3320 case BFD_RELOC_C6000_SBR_L16_H:
3321 case BFD_RELOC_C6000_SBR_L16_W:
3322 case BFD_RELOC_C6000_SBR_GOT_L16_W:
3323 if (fixP->fx_done || !seg->use_rela_p)
3325 offsetT newval = md_chars_to_number (buf, 4);
3326 int shift;
3328 switch (fixP->fx_r_type)
3330 case BFD_RELOC_C6000_SBR_L16_H:
3331 shift = 1;
3332 break;
3334 case BFD_RELOC_C6000_SBR_L16_W:
3335 case BFD_RELOC_C6000_SBR_GOT_L16_W:
3336 shift = 2;
3337 break;
3339 default:
3340 shift = 0;
3341 break;
3344 MODIFY_VALUE (newval, value, shift, 7, 16);
3345 if ((value < -0x8000 || value > 0x7fff)
3346 && (fixP->fx_r_type == BFD_RELOC_C6000_ABS_S16
3347 || fixP->fx_r_type == BFD_RELOC_C6000_SBR_S16))
3348 as_bad_where (fixP->fx_file, fixP->fx_line,
3349 _("immediate offset out of range"));
3351 md_number_to_chars (buf, newval, 4);
3353 if (fixP->fx_done
3354 && fixP->fx_r_type != BFD_RELOC_C6000_ABS_S16
3355 && fixP->fx_r_type != BFD_RELOC_C6000_ABS_L16)
3356 abort ();
3357 break;
3359 case BFD_RELOC_C6000_ABS_H16:
3360 case BFD_RELOC_C6000_SBR_H16_B:
3361 case BFD_RELOC_C6000_SBR_H16_H:
3362 case BFD_RELOC_C6000_SBR_H16_W:
3363 case BFD_RELOC_C6000_SBR_GOT_H16_W:
3364 if (fixP->fx_done || !seg->use_rela_p)
3366 offsetT newval = md_chars_to_number (buf, 4);
3367 int shift;
3369 switch (fixP->fx_r_type)
3371 case BFD_RELOC_C6000_SBR_H16_H:
3372 shift = 17;
3373 break;
3375 case BFD_RELOC_C6000_SBR_H16_W:
3376 case BFD_RELOC_C6000_SBR_GOT_H16_W:
3377 shift = 18;
3378 break;
3380 default:
3381 shift = 16;
3382 break;
3385 MODIFY_VALUE (newval, value, shift, 7, 16);
3387 md_number_to_chars (buf, newval, 4);
3389 if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_ABS_H16)
3390 abort ();
3391 break;
3393 case BFD_RELOC_C6000_SBR_U15_B:
3394 if (fixP->fx_done || !seg->use_rela_p)
3396 offsetT newval = md_chars_to_number (buf, 4);
3398 MODIFY_VALUE (newval, value, 0, 8, 15);
3399 if (value < 0 || value > 0x7fff)
3400 as_bad_where (fixP->fx_file, fixP->fx_line,
3401 _("immediate offset out of range"));
3403 md_number_to_chars (buf, newval, 4);
3405 break;
3407 case BFD_RELOC_C6000_SBR_U15_H:
3408 if (fixP->fx_done || !seg->use_rela_p)
3410 offsetT newval = md_chars_to_number (buf, 4);
3412 /* Constant ADDA operands, processed as constant when the
3413 instruction is parsed, are encoded as-is rather than
3414 shifted. If the operand of an ADDA instruction is now
3415 constant (for example, the difference between two labels
3416 found after the instruction), ensure it is encoded the
3417 same way it would have been if the constant value had
3418 been known when the instruction was parsed. */
3419 if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
3420 value <<= 1;
3422 MODIFY_VALUE (newval, value, 1, 8, 15);
3423 if (value & 1)
3424 as_bad_where (fixP->fx_file, fixP->fx_line,
3425 _("immediate offset not 2-byte-aligned"));
3426 if (value < 0 || value > 0xfffe)
3427 as_bad_where (fixP->fx_file, fixP->fx_line,
3428 _("immediate offset out of range"));
3430 md_number_to_chars (buf, newval, 4);
3432 break;
3434 case BFD_RELOC_C6000_SBR_U15_W:
3435 case BFD_RELOC_C6000_SBR_GOT_U15_W:
3436 if (fixP->fx_done || !seg->use_rela_p)
3438 offsetT newval = md_chars_to_number (buf, 4);
3440 /* Constant ADDA operands, processed as constant when the
3441 instruction is parsed, are encoded as-is rather than
3442 shifted. If the operand of an ADDA instruction is now
3443 constant (for example, the difference between two labels
3444 found after the instruction), ensure it is encoded the
3445 same way it would have been if the constant value had
3446 been known when the instruction was parsed. */
3447 if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
3448 value <<= 2;
3450 MODIFY_VALUE (newval, value, 2, 8, 15);
3451 if (value & 3)
3452 as_bad_where (fixP->fx_file, fixP->fx_line,
3453 _("immediate offset not 4-byte-aligned"));
3454 if (value < 0 || value > 0x1fffc)
3455 as_bad_where (fixP->fx_file, fixP->fx_line,
3456 _("immediate offset out of range"));
3458 md_number_to_chars (buf, newval, 4);
3460 if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_SBR_U15_W)
3461 abort ();
3462 break;
3464 case BFD_RELOC_C6000_DSBT_INDEX:
3465 if (value != 0)
3466 as_bad_where (fixP->fx_file, fixP->fx_line,
3467 _("addend used with $DSBT_INDEX"));
3468 if (fixP->fx_done)
3469 abort ();
3470 break;
3472 case BFD_RELOC_C6000_PCR_S21:
3473 if (fixP->fx_done || !seg->use_rela_p)
3475 offsetT newval = md_chars_to_number (buf, 4);
3477 MODIFY_VALUE (newval, value, 2, 7, 21);
3479 if (value & 3)
3480 as_bad_where (fixP->fx_file, fixP->fx_line,
3481 _("PC-relative offset not 4-byte-aligned"));
3482 if (value < -0x400000 || value > 0x3ffffc)
3483 as_bad_where (fixP->fx_file, fixP->fx_line,
3484 _("PC-relative offset out of range"));
3486 md_number_to_chars (buf, newval, 4);
3488 break;
3490 case BFD_RELOC_C6000_PCR_S12:
3491 if (fixP->fx_done || !seg->use_rela_p)
3493 offsetT newval = md_chars_to_number (buf, 4);
3495 MODIFY_VALUE (newval, value, 2, 16, 12);
3497 if (value & 3)
3498 as_bad_where (fixP->fx_file, fixP->fx_line,
3499 _("PC-relative offset not 4-byte-aligned"));
3500 if (value < -0x2000 || value > 0x1ffc)
3501 as_bad_where (fixP->fx_file, fixP->fx_line,
3502 _("PC-relative offset out of range"));
3504 md_number_to_chars (buf, newval, 4);
3506 break;
3508 case BFD_RELOC_C6000_PCR_S10:
3509 if (fixP->fx_done || !seg->use_rela_p)
3511 offsetT newval = md_chars_to_number (buf, 4);
3513 MODIFY_VALUE (newval, value, 2, 13, 10);
3515 if (value & 3)
3516 as_bad_where (fixP->fx_file, fixP->fx_line,
3517 _("PC-relative offset not 4-byte-aligned"));
3518 if (value < -0x800 || value > 0x7fc)
3519 as_bad_where (fixP->fx_file, fixP->fx_line,
3520 _("PC-relative offset out of range"));
3522 md_number_to_chars (buf, newval, 4);
3524 break;
3526 case BFD_RELOC_C6000_PCR_S7:
3527 if (fixP->fx_done || !seg->use_rela_p)
3529 offsetT newval = md_chars_to_number (buf, 4);
3531 MODIFY_VALUE (newval, value, 2, 16, 7);
3533 if (value & 3)
3534 as_bad_where (fixP->fx_file, fixP->fx_line,
3535 _("PC-relative offset not 4-byte-aligned"));
3536 if (value < -0x100 || value > 0xfc)
3537 as_bad_where (fixP->fx_file, fixP->fx_line,
3538 _("PC-relative offset out of range"));
3540 md_number_to_chars (buf, newval, 4);
3542 break;
3544 default:
3545 abort ();
3549 /* Convert a floating-point number to target (IEEE) format. */
3551 char *
3552 md_atof (int type, char *litP, int *sizeP)
3554 return ieee_md_atof (type, litP, sizeP, target_big_endian);
3557 /* Adjust the frags in SECTION (see tic6x_end). */
3559 static void
3560 tic6x_adjust_section (bfd *abfd ATTRIBUTE_UNUSED, segT section,
3561 void *dummy ATTRIBUTE_UNUSED)
3563 segment_info_type *info;
3564 frchainS *frchp;
3565 fragS *fragp;
3566 bfd_boolean have_code = FALSE;
3567 bfd_boolean have_non_code = FALSE;
3569 info = seg_info (section);
3570 if (info == NULL)
3571 return;
3573 for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
3574 for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
3575 switch (fragp->fr_type)
3577 case rs_machine_dependent:
3578 if (fragp->tc_frag_data.is_insns)
3579 have_code = TRUE;
3580 break;
3582 case rs_dummy:
3583 case rs_fill:
3584 if (fragp->fr_fix > 0)
3585 have_non_code = TRUE;
3586 break;
3588 default:
3589 have_non_code = TRUE;
3590 break;
3593 /* Process alignment requirements in a code-only section. */
3594 if (have_code && !have_non_code)
3596 /* If we need to insert an odd number of instructions to meet an
3597 alignment requirement, there must have been an odd number of
3598 instructions since the last 8-byte-aligned execute packet
3599 boundary. So there must have been an execute packet with an
3600 odd number (and so a number fewer than 8) of instructions
3601 into which we can insert a NOP without breaking any previous
3602 alignments.
3604 If then we need to insert a number 2 mod 4 of instructions,
3605 the number of instructions since the last 16-byte-aligned
3606 execute packet boundary must be 2 mod 4. So between that
3607 boundary and the following 8-byte-aligned boundary there must
3608 either be at least one execute packet with 2-mod-4
3609 instructions, or at least two with an odd number of
3610 instructions; again, greedily inserting NOPs as soon as
3611 possible suffices to meet the alignment requirement.
3613 If then we need to insert 4 instructions, we look between the
3614 last 32-byte-aligned boundary and the following
3615 16-byte-aligned boundary. The sizes of the execute packets
3616 in this range total 4 instructions mod 8, so again there is
3617 room for greedy insertion of NOPs to meet the alignment
3618 requirement, and before any intermediate point with 8-byte
3619 (2-instruction) alignment requirement the sizes of execute
3620 packets (and so the room for NOPs) will total 2 instructions
3621 mod 4 so greedy insertion will not break such alignments.
3623 So we can always meet these alignment requirements by
3624 inserting NOPs in parallel with existing execute packets, and
3625 by induction the approach described above inserts the minimum
3626 number of such NOPs. */
3628 /* The number of NOPs we are currently looking to insert, if we
3629 have gone back to insert NOPs. */
3630 unsigned int want_insert = 0;
3632 /* Out of that number, the number inserted so far in the current
3633 stage of the above algorithm. */
3634 unsigned int want_insert_done_so_far = 0;
3636 /* The position mod 32 at the start of the current frag. */
3637 unsigned int pos = 0;
3639 /* The locations in the frag chain of the most recent frags at
3640 the start of which there is the given alignment. */
3641 frchainS *frchp_last32, *frchp_last16, *frchp_last8;
3642 fragS *fragp_last32, *fragp_last16, *fragp_last8;
3643 unsigned int pos_last32, pos_last16, pos_last8;
3645 frchp_last32 = frchp_last16 = frchp_last8 = info->frchainP;
3646 fragp_last32 = fragp_last16 = fragp_last8 = info->frchainP->frch_root;
3647 pos_last32 = pos_last16 = pos_last8 = 0;
3649 for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
3650 for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
3651 look_at_frag:
3653 bfd_boolean go_back = FALSE;
3654 frchainS *frchp_next;
3655 fragS *fragp_next;
3657 if (fragp->fr_type != rs_machine_dependent)
3658 continue;
3660 if (fragp->tc_frag_data.is_insns
3661 && pos + fragp->fr_fix > 32
3662 && !fragp->tc_frag_data.can_cross_fp_boundary)
3664 /* As described above, we should always have met an
3665 alignment requirement by the time we come back to
3666 it. */
3667 if (want_insert)
3668 abort ();
3670 if (pos & 3)
3671 abort ();
3672 want_insert = (32 - pos) >> 2;
3673 if (want_insert > 7)
3674 abort ();
3675 want_insert_done_so_far = 0;
3676 go_back = TRUE;
3679 if (!fragp->tc_frag_data.is_insns)
3681 unsigned int would_insert_bytes;
3683 if (!(pos & ((1 << fragp->fr_offset) - 1)))
3684 /* This alignment requirement is already met. */
3685 continue;
3687 /* As described above, we should always have met an
3688 alignment requirement by the time we come back to
3689 it. */
3690 if (want_insert)
3691 abort ();
3693 /* We may not be able to meet this requirement within
3694 the given number of characters. */
3695 would_insert_bytes
3696 = ((1 << fragp->fr_offset)
3697 - (pos & ((1 << fragp->fr_offset) - 1)));
3699 if (fragp->fr_subtype != 0
3700 && would_insert_bytes > fragp->fr_subtype)
3701 continue;
3703 /* An unmet alignment must be 8, 16 or 32 bytes;
3704 smaller ones must always be met within code-only
3705 sections and larger ones cause the section not to
3706 be code-only. */
3707 if (fragp->fr_offset != 3
3708 && fragp->fr_offset != 4
3709 && fragp->fr_offset != 5)
3710 abort ();
3712 if (would_insert_bytes & 3)
3713 abort ();
3714 want_insert = would_insert_bytes >> 2;
3715 if (want_insert > 7)
3716 abort ();
3717 want_insert_done_so_far = 0;
3718 go_back = TRUE;
3720 else if (want_insert && !go_back)
3722 unsigned int num_insns = fragp->fr_fix >> 2;
3723 unsigned int max_poss_nops = 8 - num_insns;
3725 if (max_poss_nops)
3727 unsigned int cur_want_nops, max_want_nops, do_nops, i;
3729 if (want_insert & 1)
3730 cur_want_nops = 1;
3731 else if (want_insert & 2)
3732 cur_want_nops = 2;
3733 else if (want_insert & 4)
3734 cur_want_nops = 4;
3735 else
3736 abort ();
3738 max_want_nops = cur_want_nops - want_insert_done_so_far;
3740 do_nops = (max_poss_nops < max_want_nops
3741 ? max_poss_nops
3742 : max_want_nops);
3743 for (i = 0; i < do_nops; i++)
3745 md_number_to_chars (fragp->fr_literal + fragp->fr_fix,
3746 0, 4);
3747 if (target_big_endian)
3748 fragp->fr_literal[fragp->fr_fix - 1] |= 0x1;
3749 else
3750 fragp->fr_literal[fragp->fr_fix - 4] |= 0x1;
3751 fragp->fr_fix += 4;
3752 fragp->fr_var -= 4;
3754 want_insert_done_so_far += do_nops;
3755 if (want_insert_done_so_far == cur_want_nops)
3757 want_insert -= want_insert_done_so_far;
3758 want_insert_done_so_far = 0;
3759 if (want_insert)
3760 go_back = TRUE;
3764 if (go_back)
3766 if (want_insert & 1)
3768 frchp = frchp_last8;
3769 fragp = fragp_last8;
3770 pos = pos_last8;
3772 else if (want_insert & 2)
3774 frchp = frchp_last8 = frchp_last16;
3775 fragp = fragp_last8 = fragp_last16;
3776 pos = pos_last8 = pos_last16;
3778 else if (want_insert & 4)
3780 frchp = frchp_last8 = frchp_last16 = frchp_last32;
3781 fragp = fragp_last8 = fragp_last16 = fragp_last32;
3782 pos = pos_last8 = pos_last16 = pos_last32;
3784 else
3785 abort ();
3787 goto look_at_frag;
3790 /* Update current position for moving past a code
3791 frag. */
3792 pos += fragp->fr_fix;
3793 pos &= 31;
3794 frchp_next = frchp;
3795 fragp_next = fragp->fr_next;
3796 if (fragp_next == NULL)
3798 frchp_next = frchp->frch_next;
3799 if (frchp_next != NULL)
3800 fragp_next = frchp_next->frch_root;
3802 if (!(pos & 7))
3804 frchp_last8 = frchp_next;
3805 fragp_last8 = fragp_next;
3806 pos_last8 = pos;
3808 if (!(pos & 15))
3810 frchp_last16 = frchp_next;
3811 fragp_last16 = fragp_next;
3812 pos_last16 = pos;
3814 if (!(pos & 31))
3816 frchp_last32 = frchp_next;
3817 fragp_last32 = fragp_next;
3818 pos_last32 = pos;
3823 /* Now convert the machine-dependent frags to machine-independent
3824 ones. */
3825 for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
3826 for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
3828 if (fragp->fr_type == rs_machine_dependent)
3830 if (fragp->tc_frag_data.is_insns)
3831 frag_wane (fragp);
3832 else
3834 fragp->fr_type = rs_align_code;
3835 fragp->fr_var = 1;
3836 *fragp->fr_literal = 0;
3842 /* Initialize the machine-dependent parts of a frag. */
3844 void
3845 tic6x_frag_init (fragS *fragp)
3847 fragp->tc_frag_data.is_insns = FALSE;
3848 fragp->tc_frag_data.can_cross_fp_boundary = FALSE;
3851 /* Set an attribute if it has not already been set by the user. */
3853 static void
3854 tic6x_set_attribute_int (int tag, int value)
3856 if (tag < 1
3857 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES)
3858 abort ();
3859 if (!tic6x_attributes_set_explicitly[tag])
3860 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
3863 /* Set object attributes deduced from the input file and command line
3864 rather than given explicitly. */
3865 static void
3866 tic6x_set_attributes (void)
3868 if (tic6x_arch_attribute == C6XABI_Tag_CPU_arch_none)
3869 tic6x_arch_attribute = C6XABI_Tag_CPU_arch_C674X;
3871 tic6x_set_attribute_int (Tag_C6XABI_Tag_CPU_arch, tic6x_arch_attribute);
3874 /* Do machine-dependent manipulations of the frag chains after all
3875 input has been read and before the machine-independent sizing and
3876 relaxing. */
3878 void
3879 tic6x_end (void)
3881 /* Set object attributes at this point if not explicitly set. */
3882 tic6x_set_attributes ();
3884 /* Meeting alignment requirements may require inserting NOPs in
3885 parallel in execute packets earlier in the segment. Future
3886 16-bit instruction generation involves whole-segment optimization
3887 to determine the best choice and ordering of 32-bit or 16-bit
3888 instructions. This doesn't fit will in the general relaxation
3889 framework, so handle alignment and 16-bit instruction generation
3890 here. */
3891 bfd_map_over_sections (stdoutput, tic6x_adjust_section, NULL);
3894 /* No machine-dependent frags at this stage; all converted in
3895 tic6x_end. */
3897 void
3898 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
3899 fragS *fragp ATTRIBUTE_UNUSED)
3901 abort ();
3904 /* No machine-dependent frags at this stage; all converted in
3905 tic6x_end. */
3908 md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
3909 segT seg ATTRIBUTE_UNUSED)
3911 abort ();
3914 /* Put a number into target byte order. */
3916 void
3917 md_number_to_chars (char *buf, valueT val, int n)
3919 if (target_big_endian)
3920 number_to_chars_bigendian (buf, val, n);
3921 else
3922 number_to_chars_littleendian (buf, val, n);
3925 /* Machine-dependent operand parsing not currently needed. */
3927 void
3928 md_operand (expressionS *op ATTRIBUTE_UNUSED)
3932 /* PC-relative operands are relative to the start of the fetch
3933 packet. */
3935 long
3936 tic6x_pcrel_from_section (fixS *fixp, segT sec)
3938 if (fixp->fx_addsy != NULL
3939 && (!S_IS_DEFINED (fixp->fx_addsy)
3940 || S_GET_SEGMENT (fixp->fx_addsy) != sec))
3941 return 0;
3942 return (fixp->fx_where + fixp->fx_frag->fr_address) & ~(long) 0x1f;
3945 /* Round up a section size to the appropriate boundary. */
3947 valueT
3948 md_section_align (segT segment ATTRIBUTE_UNUSED,
3949 valueT size)
3951 /* Round up section sizes to ensure that text sections consist of
3952 whole fetch packets. */
3953 int align = bfd_get_section_alignment (stdoutput, segment);
3954 return ((size + (1 << align) - 1) & ((valueT) -1 << align));
3957 /* No special undefined symbol handling needed for now. */
3959 symbolS *
3960 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
3962 return NULL;
3965 /* Translate internal representation of relocation info to BFD target
3966 format. */
3968 arelent *
3969 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
3971 arelent *reloc;
3972 bfd_reloc_code_real_type r_type;
3974 reloc = xmalloc (sizeof (arelent));
3975 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3976 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3977 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3978 reloc->addend = (tic6x_generate_rela ? fixp->fx_offset : 0);
3979 r_type = fixp->fx_r_type;
3980 reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
3982 if (reloc->howto == NULL)
3984 as_bad_where (fixp->fx_file, fixp->fx_line,
3985 _("Cannot represent relocation type %s"),
3986 bfd_get_reloc_code_name (r_type));
3987 return NULL;
3990 /* Correct for adjustments bfd_install_relocation will make. */
3991 if (reloc->howto->pcrel_offset && reloc->howto->partial_inplace)
3992 reloc->addend += reloc->address;
3994 return reloc;