3 Free Software Foundation, Inc.
4 Contributed by Joseph Myers <joseph@codesourcery.com>
5 Bernd Schmidt <bernds@codesourcery.com>
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "dwarf2dbg.h"
26 #include "dw2gencfi.h"
27 #include "safe-ctype.h"
29 #include "opcode/tic6x.h"
30 #include "elf/tic6x.h"
31 #include "elf32-tic6x.h"
33 /* Truncate and sign-extend at 32 bits, so that building on a 64-bit
34 host gives identical results to a 32-bit host. */
35 #define TRUNC(X) ((valueT) (X) & 0xffffffffU)
36 #define SEXT(X) ((TRUNC (X) ^ 0x80000000U) - 0x80000000U)
38 #define streq(a, b) (strcmp (a, b) == 0)
40 /* Stuff for .scomm symbols. */
41 static segT sbss_section
;
42 static asection scom_section
;
43 static asymbol scom_symbol
;
45 const char comment_chars
[] = ";";
46 const char line_comment_chars
[] = "#*;";
47 const char line_separator_chars
[] = "@";
49 const char EXP_CHARS
[] = "eE";
50 const char FLT_CHARS
[] = "dDfF";
52 const char *md_shortopts
= "";
56 OPTION_MARCH
= OPTION_MD_BASE
,
58 OPTION_MLITTLE_ENDIAN
,
67 struct option md_longopts
[] =
69 { "march", required_argument
, NULL
, OPTION_MARCH
},
70 { "mbig-endian", no_argument
, NULL
, OPTION_MBIG_ENDIAN
},
71 { "mlittle-endian", no_argument
, NULL
, OPTION_MLITTLE_ENDIAN
},
72 { "mdsbt", no_argument
, NULL
, OPTION_MDSBT
},
73 { "mno-dsbt", no_argument
, NULL
, OPTION_MNO_DSBT
},
74 { "mpid", required_argument
, NULL
, OPTION_MPID
},
75 { "mpic", no_argument
, NULL
, OPTION_MPIC
},
76 { "mno-pic", no_argument
, NULL
, OPTION_MNO_PIC
},
77 { "mgenerate-rel", no_argument
, NULL
, OPTION_MGENERATE_REL
},
78 { NULL
, no_argument
, NULL
, 0 }
80 size_t md_longopts_size
= sizeof (md_longopts
);
82 /* The instructions enabled based only on the selected architecture
83 (all instructions, if no architecture specified). */
84 static unsigned short tic6x_arch_enable
= (TIC6X_INSN_C62X
91 /* The instructions enabled based on the current set of features
92 (architecture, as modified by other options). */
93 static unsigned short tic6x_features
;
95 /* The architecture attribute value, or C6XABI_Tag_ISA_none if
97 static int tic6x_arch_attribute
= C6XABI_Tag_ISA_none
;
99 /* Whether any instructions at all have been seen. Once any
100 instructions have been seen, architecture attributes merge into the
101 previous attribute value rather than replacing it. */
102 static bfd_boolean tic6x_seen_insns
= FALSE
;
104 /* The number of registers in each register file supported by the
105 current architecture. */
106 static unsigned int tic6x_num_registers
;
108 /* Whether predication on A0 is possible. */
109 static bfd_boolean tic6x_predicate_a0
;
111 /* Whether execute packets can cross fetch packet boundaries. */
112 static bfd_boolean tic6x_can_cross_fp_boundary
;
114 /* Whether there are constraints on simultaneous reads and writes of
116 static bfd_boolean tic6x_long_data_constraints
;
118 /* Whether compact instructions are available. */
119 static bfd_boolean tic6x_compact_insns
;
121 /* Whether to generate RELA relocations. */
122 static bfd_boolean tic6x_generate_rela
= TRUE
;
124 /* Whether the code uses DSBT addressing. */
125 static bfd_boolean tic6x_dsbt
;
127 /* Types of position-independent data (attribute values for
136 /* The type of data addressing used in this code. */
137 static tic6x_pid_type tic6x_pid
;
139 /* Whether the code uses position-independent code. */
140 static bfd_boolean tic6x_pic
;
142 /* Table of supported architecture variants. */
147 unsigned short features
;
149 static const tic6x_arch_table tic6x_arches
[] =
151 { "c62x", C6XABI_Tag_ISA_C62X
, TIC6X_INSN_C62X
},
152 { "c64x", C6XABI_Tag_ISA_C64X
, TIC6X_INSN_C62X
| TIC6X_INSN_C64X
},
153 { "c64x+", C6XABI_Tag_ISA_C64XP
, (TIC6X_INSN_C62X
155 | TIC6X_INSN_C64XP
) },
156 { "c67x", C6XABI_Tag_ISA_C67X
, TIC6X_INSN_C62X
| TIC6X_INSN_C67X
},
157 { "c67x+", C6XABI_Tag_ISA_C67XP
, (TIC6X_INSN_C62X
159 | TIC6X_INSN_C67XP
) },
160 { "c674x", C6XABI_Tag_ISA_C674X
, (TIC6X_INSN_C62X
165 | TIC6X_INSN_C674X
) }
168 /* Caller saved register encodings. The standard frame layout uses this
169 order, starting from the highest address. There must be
170 TIC6X_NUM_UNWIND_REGS values. */
188 static void tic6x_output_unwinding (bfd_boolean need_extab
);
190 /* Return the frame unwind state for the current function, allocating
193 static tic6x_unwind_info
*tic6x_get_unwind (void)
195 tic6x_unwind_info
*unwind
;
197 unwind
= seg_info (now_seg
)->tc_segment_info_data
.unwind
;
201 unwind
= seg_info (now_seg
)->tc_segment_info_data
.text_unwind
;
205 unwind
= (tic6x_unwind_info
*)xmalloc (sizeof (tic6x_unwind_info
));
206 seg_info (now_seg
)->tc_segment_info_data
.unwind
= unwind
;
207 memset (unwind
, 0, sizeof (*unwind
));
211 /* Update the selected architecture based on ARCH, giving an error if
212 ARCH is an invalid value. Does not call tic6x_update_features; the
213 caller must do that if necessary. */
216 tic6x_use_arch (const char *arch
)
220 for (i
= 0; i
< ARRAY_SIZE (tic6x_arches
); i
++)
221 if (strcmp (arch
, tic6x_arches
[i
].arch
) == 0)
223 tic6x_arch_enable
= tic6x_arches
[i
].features
;
224 if (tic6x_seen_insns
)
226 = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute
,
227 tic6x_arches
[i
].attr
);
229 tic6x_arch_attribute
= tic6x_arches
[i
].attr
;
233 as_bad (_("unknown architecture '%s'"), arch
);
236 /* Table of supported -mpid arguments. */
241 } tic6x_pid_type_table
;
242 static const tic6x_pid_type_table tic6x_pid_types
[] =
244 { "no", tic6x_pid_no
},
245 { "near", tic6x_pid_near
},
246 { "far", tic6x_pid_far
}
249 /* Handle -mpid=ARG. */
252 tic6x_use_pid (const char *arg
)
256 for (i
= 0; i
< ARRAY_SIZE (tic6x_pid_types
); i
++)
257 if (strcmp (arg
, tic6x_pid_types
[i
].arg
) == 0)
259 tic6x_pid
= tic6x_pid_types
[i
].attr
;
263 as_bad (_("unknown -mpid= argument '%s'"), arg
);
266 /* Parse a target-specific option. */
269 md_parse_option (int c
, char *arg
)
274 tic6x_use_arch (arg
);
277 case OPTION_MBIG_ENDIAN
:
278 target_big_endian
= 1;
281 case OPTION_MLITTLE_ENDIAN
:
282 target_big_endian
= 0;
289 case OPTION_MNO_DSBT
:
305 case OPTION_MGENERATE_REL
:
306 tic6x_generate_rela
= FALSE
;
316 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
320 fputc ('\n', stream
);
321 fprintf (stream
, _("TMS320C6000 options:\n"));
322 fprintf (stream
, _(" -march=ARCH enable instructions from architecture ARCH\n"));
323 fprintf (stream
, _(" -mbig-endian generate big-endian code\n"));
324 fprintf (stream
, _(" -mlittle-endian generate little-endian code\n"));
325 fprintf (stream
, _(" -mdsbt code uses DSBT addressing\n"));
326 fprintf (stream
, _(" -mno-dsbt code does not use DSBT addressing\n"));
327 fprintf (stream
, _(" -mpid=no code uses position-dependent data addressing\n"));
328 fprintf (stream
, _(" -mpid=near code uses position-independent data addressing,\n"
329 " GOT accesses use near DP addressing\n"));
330 fprintf (stream
, _(" -mpid=far code uses position-independent data addressing,\n"
331 " GOT accesses use far DP addressing\n"));
332 fprintf (stream
, _(" -mpic code addressing is position-independent\n"));
333 fprintf (stream
, _(" -mno-pic code addressing is position-dependent\n"));
334 /* -mgenerate-rel is only for testsuite use and is deliberately
337 fputc ('\n', stream
);
338 fprintf (stream
, _("Supported ARCH values are:"));
339 for (i
= 0; i
< ARRAY_SIZE (tic6x_arches
); i
++)
340 fprintf (stream
, " %s", tic6x_arches
[i
].arch
);
341 fputc ('\n', stream
);
344 /* Update enabled features based on the current architecture and
347 tic6x_update_features (void)
349 tic6x_features
= tic6x_arch_enable
;
352 = (tic6x_arch_enable
& (TIC6X_INSN_C64X
| TIC6X_INSN_C67XP
)) ? 32 : 16;
354 tic6x_predicate_a0
= (tic6x_arch_enable
& TIC6X_INSN_C64X
) ? TRUE
: FALSE
;
356 tic6x_can_cross_fp_boundary
358 & (TIC6X_INSN_C64X
| TIC6X_INSN_C67XP
)) ? TRUE
: FALSE
;
360 tic6x_long_data_constraints
361 = (tic6x_arch_enable
& TIC6X_INSN_C64X
) ? FALSE
: TRUE
;
363 tic6x_compact_insns
= (tic6x_arch_enable
& TIC6X_INSN_C64XP
) ? TRUE
: FALSE
;
366 /* Do configuration after all options have been parsed. */
369 tic6x_after_parse_args (void)
371 tic6x_update_features ();
374 /* Parse a .cantunwind directive. */
376 s_tic6x_cantunwind (int ignored ATTRIBUTE_UNUSED
)
378 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
380 /* GCC sometimes spits out superfluous .cantunwind directives, so ignore
382 if (unwind
->data_bytes
== 0)
385 if (unwind
->data_bytes
!= -1)
387 as_bad (_("unexpected .cantunwind directive"));
391 demand_empty_rest_of_line ();
393 if (unwind
->personality_routine
|| unwind
->personality_index
!= -1)
394 as_bad (_("personality routine specified for cantunwind frame"));
396 unwind
->personality_index
= -2;
399 /* Parse a .handlerdata directive. */
401 s_tic6x_handlerdata (int ignored ATTRIBUTE_UNUSED
)
403 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
405 if (!unwind
->saved_seg
)
407 as_bad (_("unexpected .handlerdata directive"));
411 if (unwind
->table_entry
|| unwind
->personality_index
== -2)
413 as_bad (_("duplicate .handlerdata directive"));
417 if (unwind
->personality_index
== -1 && unwind
->personality_routine
== NULL
)
419 as_bad (_("personality routine required before .handlerdata directive"));
423 tic6x_output_unwinding (TRUE
);
426 /* Parse a .endp directive. */
428 s_tic6x_endp (int ignored ATTRIBUTE_UNUSED
)
430 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
432 if (unwind
->data_bytes
!= 0)
434 /* Output a .exidx entry if we have not already done so.
435 Then switch back to the text section. */
436 if (!unwind
->table_entry
)
437 tic6x_output_unwinding (FALSE
);
439 subseg_set (unwind
->saved_seg
, unwind
->saved_subseg
);
442 unwind
->saved_seg
= NULL
;
443 unwind
->table_entry
= NULL
;
444 unwind
->data_bytes
= 0;
447 /* Parse a .personalityindex directive. */
449 s_tic6x_personalityindex (int ignored ATTRIBUTE_UNUSED
)
451 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
454 if (unwind
->personality_routine
|| unwind
->personality_index
!= -1)
455 as_bad (_("duplicate .personalityindex directive"));
459 if (exp
.X_op
!= O_constant
460 || exp
.X_add_number
< 0 || exp
.X_add_number
> 15)
462 as_bad (_("bad personality routine number"));
463 ignore_rest_of_line ();
467 unwind
->personality_index
= exp
.X_add_number
;
469 demand_empty_rest_of_line ();
473 s_tic6x_personality (int ignored ATTRIBUTE_UNUSED
)
476 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
478 if (unwind
->personality_routine
|| unwind
->personality_index
!= -1)
479 as_bad (_("duplicate .personality directive"));
481 name
= input_line_pointer
;
482 c
= get_symbol_end ();
483 p
= input_line_pointer
;
484 unwind
->personality_routine
= symbol_find_or_make (name
);
486 demand_empty_rest_of_line ();
489 /* Parse a .arch directive. */
491 s_tic6x_arch (int ignored ATTRIBUTE_UNUSED
)
496 arch
= input_line_pointer
;
497 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
498 input_line_pointer
++;
499 c
= *input_line_pointer
;
500 *input_line_pointer
= 0;
502 tic6x_use_arch (arch
);
503 tic6x_update_features ();
504 *input_line_pointer
= c
;
505 demand_empty_rest_of_line ();
508 /* Parse a .ehtype directive. */
511 s_tic6x_ehtype (int ignored ATTRIBUTE_UNUSED
)
516 #ifdef md_flush_pending_output
517 md_flush_pending_output ();
520 if (is_it_end_of_statement ())
522 demand_empty_rest_of_line ();
533 if (exp
.X_op
!= O_symbol
)
535 as_bad (_("expected symbol"));
540 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
541 &exp
, 0, BFD_RELOC_C6000_EHTYPE
);
543 demand_empty_rest_of_line ();
546 /* Parse a .nocmp directive. */
549 s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED
)
551 seg_info (now_seg
)->tc_segment_info_data
.nocmp
= TRUE
;
552 demand_empty_rest_of_line ();
555 /* .scomm pseudo-op handler.
557 This is a new pseudo-op to handle putting objects in .scommon.
558 By doing this the linker won't need to do any work,
559 and more importantly it removes the implicit -G arg necessary to
560 correctly link the object file. */
563 s_tic6x_scomm (int ignore ATTRIBUTE_UNUSED
)
573 name
= input_line_pointer
;
574 c
= get_symbol_end ();
576 /* Just after name is now '\0'. */
577 p
= input_line_pointer
;
580 if (*input_line_pointer
!= ',')
582 as_bad (_("expected comma after symbol name"));
583 ignore_rest_of_line ();
588 input_line_pointer
++;
589 if ((size
= get_absolute_expression ()) < 0)
591 /* xgettext:c-format */
592 as_warn (_("invalid length for .scomm directive"));
593 ignore_rest_of_line ();
597 /* The third argument to .scomm is the alignment. */
598 if (*input_line_pointer
!= ',')
602 ++input_line_pointer
;
603 align
= get_absolute_expression ();
606 as_warn (_("alignment is not a positive number"));
611 /* Convert to a power of 2 alignment. */
614 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
)
618 as_bad (_("alignment is not a power of 2"));
619 ignore_rest_of_line ();
627 symbolP
= symbol_find_or_make (name
);
630 if (S_IS_DEFINED (symbolP
))
632 /* xgettext:c-format */
633 as_bad (_("attempt to re-define symbol `%s'"),
634 S_GET_NAME (symbolP
));
635 ignore_rest_of_line ();
639 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
641 /* xgettext:c-format */
642 as_bad (_("attempt to redefine `%s' with a different length"),
643 S_GET_NAME (symbolP
));
645 ignore_rest_of_line ();
649 if (symbol_get_obj (symbolP
)->local
)
651 segT old_sec
= now_seg
;
652 int old_subsec
= now_subseg
;
655 record_alignment (sbss_section
, align2
);
656 subseg_set (sbss_section
, 0);
659 frag_align (align2
, 0, 0);
661 if (S_GET_SEGMENT (symbolP
) == sbss_section
)
662 symbol_get_frag (symbolP
)->fr_symbol
= 0;
664 symbol_set_frag (symbolP
, frag_now
);
666 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
669 S_SET_SIZE (symbolP
, size
);
670 S_SET_SEGMENT (symbolP
, sbss_section
);
671 S_CLEAR_EXTERNAL (symbolP
);
672 subseg_set (old_sec
, old_subsec
);
676 S_SET_VALUE (symbolP
, (valueT
) size
);
677 S_SET_ALIGN (symbolP
, 1 << align2
);
678 S_SET_EXTERNAL (symbolP
);
679 S_SET_SEGMENT (symbolP
, &scom_section
);
682 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
684 demand_empty_rest_of_line ();
687 /* Track for each attribute whether it has been set explicitly (and so
688 should not have a default value set by the assembler). */
689 static bfd_boolean tic6x_attributes_set_explicitly
[NUM_KNOWN_OBJ_ATTRIBUTES
];
691 /* Parse a .c6xabi_attribute directive. */
694 s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED
)
696 int tag
= s_vendor_attribute (OBJ_ATTR_PROC
);
698 if (tag
< NUM_KNOWN_OBJ_ATTRIBUTES
)
699 tic6x_attributes_set_explicitly
[tag
] = TRUE
;
706 } tic6x_attribute_table
;
708 static const tic6x_attribute_table tic6x_attributes
[] =
710 #define TAG(tag, value) { #tag, tag },
711 #include "elf/tic6x-attrs.h"
715 /* Convert an attribute name to a number. */
718 tic6x_convert_symbolic_attribute (const char *name
)
722 for (i
= 0; i
< ARRAY_SIZE (tic6x_attributes
); i
++)
723 if (strcmp (name
, tic6x_attributes
[i
].name
) == 0)
724 return tic6x_attributes
[i
].tag
;
729 const pseudo_typeS md_pseudo_table
[] =
731 { "arch", s_tic6x_arch
, 0 },
732 { "c6xabi_attribute", s_tic6x_c6xabi_attribute
, 0 },
733 { "nocmp", s_tic6x_nocmp
, 0 },
734 { "scomm", s_tic6x_scomm
, 0 },
736 { "ehtype", s_tic6x_ehtype
, 0 },
737 { "endp", s_tic6x_endp
, 0 },
738 { "handlerdata", s_tic6x_handlerdata
, 0 },
739 { "personalityindex", s_tic6x_personalityindex
, 0 },
740 { "personality", s_tic6x_personality
, 0 },
741 { "cantunwind", s_tic6x_cantunwind
, 0 },
745 /* Hash table of opcodes. For each opcode name, this stores a pointer
746 to a tic6x_opcode_list listing (in an arbitrary order) all opcode
747 table entries with that name. */
748 static struct hash_control
*opcode_hash
;
750 /* Initialize the assembler (called once at assembler startup). */
760 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
762 /* Insert opcodes into the hash table. */
763 opcode_hash
= hash_new ();
764 for (id
= 0; id
< tic6x_opcode_max
; id
++)
767 tic6x_opcode_list
*opc
= xmalloc (sizeof (tic6x_opcode_list
));
770 opc
->next
= hash_find (opcode_hash
, tic6x_opcode_table
[id
].name
);
771 if ((errmsg
= hash_jam (opcode_hash
, tic6x_opcode_table
[id
].name
, opc
))
773 as_fatal ("%s", _(errmsg
));
776 /* Save the current subseg so we can restore it [it's the default one and
777 we don't want the initial section to be .sbss]. */
781 /* The sbss section is for local .scomm symbols. */
782 sbss_section
= subseg_new (".bss", 0);
783 seg_info (sbss_section
)->bss
= 1;
785 /* This is copied from perform_an_assembly_pass. */
786 applicable
= bfd_applicable_section_flags (stdoutput
);
787 bfd_set_section_flags (stdoutput
, sbss_section
, applicable
& SEC_ALLOC
);
789 subseg_set (seg
, subseg
);
791 /* We must construct a fake section similar to bfd_com_section
792 but with the name .scommon. */
793 scom_section
= bfd_com_section
;
794 scom_section
.name
= ".scommon";
795 scom_section
.output_section
= & scom_section
;
796 scom_section
.symbol
= & scom_symbol
;
797 scom_section
.symbol_ptr_ptr
= & scom_section
.symbol
;
798 scom_symbol
= * bfd_com_section
.symbol
;
799 scom_symbol
.name
= ".scommon";
800 scom_symbol
.section
= & scom_section
;
803 /* Whether the current line being parsed had the "||" parallel bars. */
804 static bfd_boolean tic6x_line_parallel
;
806 /* Whether the current line being parsed started "||^" to indicate an
807 SPMASKed parallel instruction. */
808 static bfd_boolean tic6x_line_spmask
;
810 /* If the current line being parsed had an instruction predicate, the
811 creg value for that predicate (which must be nonzero); otherwise
813 static unsigned int tic6x_line_creg
;
815 /* If the current line being parsed had an instruction predicate, the
816 z value for that predicate; otherwise 0. */
817 static unsigned int tic6x_line_z
;
819 /* Return 1 (updating input_line_pointer as appropriate) if the line
820 starting with C (immediately before input_line_pointer) starts with
821 pre-opcode text appropriate for this target, 0 otherwise. */
824 tic6x_unrecognized_line (int c
)
829 bfd_boolean bad_predicate
;
834 if (input_line_pointer
[0] == '|')
836 if (input_line_pointer
[1] == '^')
838 tic6x_line_spmask
= TRUE
;
839 input_line_pointer
+= 2;
842 input_line_pointer
+= 1;
843 if (tic6x_line_parallel
)
844 as_bad (_("multiple '||' on same line"));
845 tic6x_line_parallel
= TRUE
;
847 as_bad (_("'||' after predicate"));
853 /* If it doesn't look like a predicate at all, just return 0.
854 If it looks like one but not a valid one, give a better
856 p
= input_line_pointer
;
857 while (*p
!= ']' && !is_end_of_line
[(unsigned char) *p
])
862 p
= input_line_pointer
;
864 bad_predicate
= FALSE
;
870 if (*p
== 'A' || *p
== 'a')
872 else if (*p
== 'B' || *p
== 'b')
876 areg
= TRUE
; /* Avoid uninitialized warning. */
877 bad_predicate
= TRUE
;
882 if (*p
!= '0' && *p
!= '1' && *p
!= '2')
883 bad_predicate
= TRUE
;
884 else if (p
[1] != ']')
885 bad_predicate
= TRUE
;
887 input_line_pointer
= p
+ 2;
891 as_bad (_("multiple predicates on same line"));
897 as_bad (_("bad predicate '%s'"), input_line_pointer
- 1);
899 input_line_pointer
= endp
;
906 tic6x_line_creg
= (areg
? 6 : 1);
907 if (areg
&& !tic6x_predicate_a0
)
908 as_bad (_("predication on A0 not supported on this architecture"));
912 tic6x_line_creg
= (areg
? 4 : 2);
916 tic6x_line_creg
= (areg
? 5 : 3);
931 /* Do any target-specific handling of a label required. */
934 tic6x_frob_label (symbolS
*sym
)
936 segment_info_type
*si
;
937 tic6x_label_list
*list
;
939 if (tic6x_line_parallel
)
941 as_bad (_("label after '||'"));
942 tic6x_line_parallel
= FALSE
;
943 tic6x_line_spmask
= FALSE
;
947 as_bad (_("label after predicate"));
952 si
= seg_info (now_seg
);
953 list
= si
->tc_segment_info_data
.label_list
;
954 si
->tc_segment_info_data
.label_list
= xmalloc (sizeof (tic6x_label_list
));
955 si
->tc_segment_info_data
.label_list
->next
= list
;
956 si
->tc_segment_info_data
.label_list
->label
= sym
;
958 /* Defining tc_frob_label overrides the ELF definition of
959 obj_frob_label, so we need to apply its effects here. */
960 dwarf2_emit_label (sym
);
963 /* At end-of-line, give errors for start-of-line decorations that
964 needed an instruction but were not followed by one. */
967 tic6x_end_of_line (void)
969 if (tic6x_line_parallel
)
971 as_bad (_("'||' not followed by instruction"));
972 tic6x_line_parallel
= FALSE
;
973 tic6x_line_spmask
= FALSE
;
977 as_bad (_("predicate not followed by instruction"));
983 /* Do any target-specific handling of the start of a logical line. */
986 tic6x_start_line_hook (void)
988 tic6x_end_of_line ();
991 /* Do target-specific handling immediately after an input file from
992 the command line, and any other inputs it includes, have been
998 tic6x_end_of_line ();
1001 /* Do target-specific initialization after arguments have been
1002 processed and the output file created. */
1005 tic6x_init_after_args (void)
1007 elf32_tic6x_set_use_rela_p (stdoutput
, tic6x_generate_rela
);
1010 /* Free LIST of labels (possibly NULL). */
1013 tic6x_free_label_list (tic6x_label_list
*list
)
1017 tic6x_label_list
*old
= list
;
1024 /* Handle a data alignment of N bytes. */
1027 tic6x_cons_align (int n ATTRIBUTE_UNUSED
)
1029 segment_info_type
*seginfo
= seg_info (now_seg
);
1031 /* Data means there is no current execute packet, and that any label
1032 applies to that data rather than a subsequent instruction. */
1033 tic6x_free_label_list (seginfo
->tc_segment_info_data
.label_list
);
1034 seginfo
->tc_segment_info_data
.label_list
= NULL
;
1035 seginfo
->tc_segment_info_data
.execute_packet_frag
= NULL
;
1036 seginfo
->tc_segment_info_data
.last_insn_lsb
= NULL
;
1037 seginfo
->tc_segment_info_data
.spmask_addr
= NULL
;
1038 seginfo
->tc_segment_info_data
.func_units_used
= 0;
1041 /* Handle an alignment directive. Return TRUE if the
1042 machine-independent frag generation should be skipped. */
1045 tic6x_do_align (int n
, char *fill
, int len ATTRIBUTE_UNUSED
, int max
)
1047 /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
1048 them in the md_end pass by inserting NOPs in parallel with
1049 previous instructions. We only do this in sections containing
1050 nothing but instructions. Code alignments of 1 or 2 bytes have
1051 no effect in such sections (but we record them with
1052 machine-dependent frags anyway so they can be skipped or
1053 converted to machine-independent), while those of more than 64
1054 bytes cannot reliably be handled in this way. */
1060 && subseg_text_p (now_seg
))
1068 /* Machine-independent code would generate a frag here, but we
1069 wish to handle it in a machine-dependent way. */
1070 if (frag_now_fix () != 0)
1072 if (frag_now
->fr_type
!= rs_machine_dependent
)
1073 frag_wane (frag_now
);
1078 align_frag
= frag_now
;
1079 p
= frag_var (rs_machine_dependent
, 32, 32, max
, NULL
, n
, NULL
);
1080 /* This must be the same as the frag to which a pointer was just
1082 if (p
!= align_frag
->fr_literal
)
1084 align_frag
->tc_frag_data
.is_insns
= FALSE
;
1091 /* Types of operand for parsing purposes. These are used as bit-masks
1092 to tell tic6x_parse_operand what forms of operand are
1094 #define TIC6X_OP_EXP 0x0001u
1095 #define TIC6X_OP_REG 0x0002u
1096 #define TIC6X_OP_REGPAIR 0x0004u
1097 #define TIC6X_OP_IRP 0x0008u
1098 #define TIC6X_OP_NRP 0x0010u
1099 /* With TIC6X_OP_MEM_NOUNREG, the contents of a () offset are always
1100 interpreted as an expression, which may be a symbol with the same
1101 name as a register that ends up being implicitly DP-relative. With
1102 TIC6X_OP_MEM_UNREG, the contents of a () offset are interpreted as
1103 a register if they match one, and failing that as an expression,
1104 which must be constant. */
1105 #define TIC6X_OP_MEM_NOUNREG 0x0020u
1106 #define TIC6X_OP_MEM_UNREG 0x0040u
1107 #define TIC6X_OP_CTRL 0x0080u
1108 #define TIC6X_OP_FUNC_UNIT 0x0100u
1110 /* A register or register pair read by the assembler. */
1113 /* The side the register is on (1 or 2). */
1115 /* The register number (0 to 31). */
1119 /* Types of modification of a base address. */
1124 tic6x_mem_mod_minus
,
1125 tic6x_mem_mod_preinc
,
1126 tic6x_mem_mod_predec
,
1127 tic6x_mem_mod_postinc
,
1128 tic6x_mem_mod_postdec
1131 /* Scaled [] or unscaled () nature of an offset. */
1135 tic6x_offset_scaled
,
1136 tic6x_offset_unscaled
1137 } tic6x_mem_scaling
;
1139 /* A memory operand read by the assembler. */
1142 /* The base register. */
1143 tic6x_register base_reg
;
1144 /* How the base register is modified. */
1146 /* Whether there is an offset (required with plain "+" and "-"), and
1147 whether it is scaled or unscaled if so. */
1148 tic6x_mem_scaling scaled
;
1149 /* Whether the offset is a register (TRUE) or an expression
1151 bfd_boolean offset_is_reg
;
1160 /* A functional unit in SPMASK operands read by the assembler. */
1163 /* The basic unit. */
1164 tic6x_func_unit_base base
;
1165 /* The side (1 or 2). */
1167 } tic6x_func_unit_operand
;
1169 /* An operand read by the assembler. */
1172 /* The syntactic form of the operand, as one of the bit-masks
1175 /* The operand value. */
1178 /* An expression: TIC6X_OP_EXP. */
1180 /* A register: TIC6X_OP_REG, TIC6X_OP_REGPAIR. */
1182 /* A memory reference: TIC6X_OP_MEM_NOUNREG,
1183 TIC6X_OP_MEM_UNREG. */
1185 /* A control register: TIC6X_OP_CTRL. */
1187 /* A functional unit: TIC6X_OP_FUNC_UNIT. */
1188 tic6x_func_unit_operand func_unit
;
1192 #define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1194 /* Parse a register operand, or part of an operand, starting at *P.
1195 If syntactically OK (including that the number is in the range 0 to
1196 31, but not necessarily in range for this architecture), return
1197 TRUE, putting the register side and number in *REG and update *P to
1198 point immediately after the register number; otherwise return FALSE
1199 without changing *P (but possibly changing *REG). Do not print any
1203 tic6x_parse_register (char **p
, tic6x_register
*reg
)
1224 if (*r
>= '0' && *r
<= '9')
1226 reg
->num
= *r
- '0';
1232 if (reg
->num
> 0 && *r
>= '0' && *r
<= '9')
1234 reg
->num
= reg
->num
* 10 + (*r
- '0');
1238 if (*r
>= '0' && *r
<= '9')
1247 /* Parse the initial two characters of a functional unit name starting
1248 at *P. If OK, set *BASE and *SIDE and return TRUE; otherwise,
1252 tic6x_parse_func_unit_base (char *p
, tic6x_func_unit_base
*base
,
1255 bfd_boolean good_func_unit
= TRUE
;
1256 tic6x_func_unit_base maybe_base
= tic6x_func_unit_nfu
;
1257 unsigned int maybe_side
= 0;
1263 maybe_base
= tic6x_func_unit_d
;
1268 maybe_base
= tic6x_func_unit_l
;
1273 maybe_base
= tic6x_func_unit_m
;
1278 maybe_base
= tic6x_func_unit_s
;
1282 good_func_unit
= FALSE
;
1298 good_func_unit
= FALSE
;
1308 return good_func_unit
;
1311 /* Parse an operand starting at *P. If the operand parses OK, return
1312 TRUE and store the value in *OP; otherwise return FALSE (possibly
1313 changing *OP). In any case, update *P to point to the following
1314 comma or end of line. The possible operand forms are given by
1315 OP_FORMS. For diagnostics, this is operand OPNO of an opcode
1316 starting at STR, length OPC_LEN. */
1319 tic6x_parse_operand (char **p
, tic6x_operand
*op
, unsigned int op_forms
,
1320 char *str
, int opc_len
, unsigned int opno
)
1322 bfd_boolean operand_parsed
= FALSE
;
1325 if ((op_forms
& (TIC6X_OP_MEM_NOUNREG
| TIC6X_OP_MEM_UNREG
))
1326 == (TIC6X_OP_MEM_NOUNREG
| TIC6X_OP_MEM_UNREG
))
1329 /* Check for functional unit names for SPMASK and SPMASKR. */
1330 if (!operand_parsed
&& (op_forms
& TIC6X_OP_FUNC_UNIT
))
1332 tic6x_func_unit_base base
= tic6x_func_unit_nfu
;
1333 unsigned int side
= 0;
1335 if (tic6x_parse_func_unit_base (q
, &base
, &side
))
1339 skip_whitespace (rq
);
1340 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1342 op
->form
= TIC6X_OP_FUNC_UNIT
;
1343 op
->value
.func_unit
.base
= base
;
1344 op
->value
.func_unit
.side
= side
;
1345 operand_parsed
= TRUE
;
1351 /* Check for literal "irp". */
1352 if (!operand_parsed
&& (op_forms
& TIC6X_OP_IRP
))
1354 if ((q
[0] == 'i' || q
[0] == 'I')
1355 && (q
[1] == 'r' || q
[1] == 'R')
1356 && (q
[2] == 'p' || q
[2] == 'P'))
1360 skip_whitespace (rq
);
1361 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1363 op
->form
= TIC6X_OP_IRP
;
1364 operand_parsed
= TRUE
;
1370 /* Check for literal "nrp". */
1371 if (!operand_parsed
&& (op_forms
& TIC6X_OP_NRP
))
1373 if ((q
[0] == 'n' || q
[0] == 'N')
1374 && (q
[1] == 'r' || q
[1] == 'R')
1375 && (q
[2] == 'p' || q
[2] == 'P'))
1379 skip_whitespace (rq
);
1380 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1382 op
->form
= TIC6X_OP_NRP
;
1383 operand_parsed
= TRUE
;
1389 /* Check for control register names. */
1390 if (!operand_parsed
&& (op_forms
& TIC6X_OP_CTRL
))
1394 for (crid
= 0; crid
< tic6x_ctrl_max
; crid
++)
1396 size_t len
= strlen (tic6x_ctrl_table
[crid
].name
);
1398 if (strncasecmp (tic6x_ctrl_table
[crid
].name
, q
, len
) == 0)
1402 skip_whitespace (rq
);
1403 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1405 op
->form
= TIC6X_OP_CTRL
;
1406 op
->value
.ctrl
= crid
;
1407 operand_parsed
= TRUE
;
1409 if (!(tic6x_ctrl_table
[crid
].isa_variants
& tic6x_features
))
1410 as_bad (_("control register '%s' not supported "
1411 "on this architecture"),
1412 tic6x_ctrl_table
[crid
].name
);
1418 /* See if this looks like a memory reference. */
1420 && (op_forms
& (TIC6X_OP_MEM_NOUNREG
| TIC6X_OP_MEM_UNREG
)))
1422 bfd_boolean mem_ok
= TRUE
;
1424 tic6x_mem_mod mem_mod
= tic6x_mem_mod_none
;
1425 tic6x_register base_reg
;
1426 bfd_boolean require_offset
, permit_offset
;
1427 tic6x_mem_scaling scaled
;
1428 bfd_boolean offset_is_reg
;
1429 expressionS offset_exp
;
1430 tic6x_register offset_reg
;
1439 skip_whitespace (mq
);
1445 mem_mod
= tic6x_mem_mod_preinc
;
1450 mem_mod
= tic6x_mem_mod_plus
;
1458 mem_mod
= tic6x_mem_mod_predec
;
1463 mem_mod
= tic6x_mem_mod_minus
;
1475 skip_whitespace (mq
);
1476 mem_ok
= tic6x_parse_register (&mq
, &base_reg
);
1479 if (mem_ok
&& mem_mod
== tic6x_mem_mod_none
)
1481 skip_whitespace (mq
);
1482 if (mq
[0] == '+' && mq
[1] == '+')
1484 mem_mod
= tic6x_mem_mod_postinc
;
1487 else if (mq
[0] == '-' && mq
[1] == '-')
1489 mem_mod
= tic6x_mem_mod_postdec
;
1494 if (mem_mod
== tic6x_mem_mod_none
)
1495 permit_offset
= FALSE
;
1497 permit_offset
= TRUE
;
1498 if (mem_mod
== tic6x_mem_mod_plus
|| mem_mod
== tic6x_mem_mod_minus
)
1499 require_offset
= TRUE
;
1501 require_offset
= FALSE
;
1502 scaled
= tic6x_offset_none
;
1503 offset_is_reg
= FALSE
;
1505 if (mem_ok
&& permit_offset
)
1509 skip_whitespace (mq
);
1513 scaled
= tic6x_offset_scaled
;
1519 scaled
= tic6x_offset_unscaled
;
1527 if (scaled
!= tic6x_offset_none
)
1529 skip_whitespace (mq
);
1530 if (scaled
== tic6x_offset_scaled
1531 || (op_forms
& TIC6X_OP_MEM_UNREG
))
1536 reg_ok
= tic6x_parse_register (&rq
, &offset_reg
);
1539 skip_whitespace (rq
);
1543 offset_is_reg
= TRUE
;
1549 char *save_input_line_pointer
;
1551 save_input_line_pointer
= input_line_pointer
;
1552 input_line_pointer
= mq
;
1553 expression (&offset_exp
);
1554 mq
= input_line_pointer
;
1555 input_line_pointer
= save_input_line_pointer
;
1557 skip_whitespace (mq
);
1565 if (mem_ok
&& require_offset
&& scaled
== tic6x_offset_none
)
1570 skip_whitespace (mq
);
1571 if (!is_end_of_line
[(unsigned char) *mq
] && *mq
!= ',')
1577 op
->form
= op_forms
& (TIC6X_OP_MEM_NOUNREG
| TIC6X_OP_MEM_UNREG
);
1578 op
->value
.mem
.base_reg
= base_reg
;
1579 op
->value
.mem
.mod
= mem_mod
;
1580 op
->value
.mem
.scaled
= scaled
;
1581 op
->value
.mem
.offset_is_reg
= offset_is_reg
;
1583 op
->value
.mem
.offset
.reg
= offset_reg
;
1585 op
->value
.mem
.offset
.exp
= offset_exp
;
1586 operand_parsed
= TRUE
;
1588 if (base_reg
.num
>= tic6x_num_registers
)
1589 as_bad (_("register number %u not supported on this architecture"),
1591 if (offset_is_reg
&& offset_reg
.num
>= tic6x_num_registers
)
1592 as_bad (_("register number %u not supported on this architecture"),
1597 /* See if this looks like a register or register pair. */
1598 if (!operand_parsed
&& (op_forms
& (TIC6X_OP_REG
| TIC6X_OP_REGPAIR
)))
1600 tic6x_register first_reg
, second_reg
;
1604 reg_ok
= tic6x_parse_register (&rq
, &first_reg
);
1608 if (*rq
== ':' && (op_forms
& TIC6X_OP_REGPAIR
))
1611 reg_ok
= tic6x_parse_register (&rq
, &second_reg
);
1614 skip_whitespace (rq
);
1615 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1617 if ((second_reg
.num
& 1)
1618 || (first_reg
.num
!= second_reg
.num
+ 1)
1619 || (first_reg
.side
!= second_reg
.side
))
1620 as_bad (_("register pair for operand %u of '%.*s'"
1621 " not a valid even/odd pair"), opno
,
1623 op
->form
= TIC6X_OP_REGPAIR
;
1624 op
->value
.reg
= second_reg
;
1625 operand_parsed
= TRUE
;
1630 else if (op_forms
& TIC6X_OP_REG
)
1632 skip_whitespace (rq
);
1633 if (is_end_of_line
[(unsigned char) *rq
] || *rq
== ',')
1635 op
->form
= TIC6X_OP_REG
;
1636 op
->value
.reg
= first_reg
;
1637 operand_parsed
= TRUE
;
1644 if (first_reg
.num
>= tic6x_num_registers
)
1645 as_bad (_("register number %u not supported on this architecture"),
1647 if (op
->form
== TIC6X_OP_REGPAIR
1648 && second_reg
.num
>= tic6x_num_registers
)
1649 as_bad (_("register number %u not supported on this architecture"),
1654 /* Otherwise, parse it as an expression. */
1655 if (!operand_parsed
&& (op_forms
& TIC6X_OP_EXP
))
1657 char *save_input_line_pointer
;
1659 save_input_line_pointer
= input_line_pointer
;
1660 input_line_pointer
= q
;
1661 op
->form
= TIC6X_OP_EXP
;
1662 expression (&op
->value
.exp
);
1663 q
= input_line_pointer
;
1664 input_line_pointer
= save_input_line_pointer
;
1665 operand_parsed
= TRUE
;
1670 /* Now the operand has been parsed, there must be nothing more
1671 before the comma or end of line. */
1672 skip_whitespace (q
);
1673 if (!is_end_of_line
[(unsigned char) *q
] && *q
!= ',')
1675 operand_parsed
= FALSE
;
1676 as_bad (_("junk after operand %u of '%.*s'"), opno
,
1678 while (!is_end_of_line
[(unsigned char) *q
] && *q
!= ',')
1684 /* This could not be parsed as any acceptable form of
1688 case TIC6X_OP_REG
| TIC6X_OP_REGPAIR
:
1689 as_bad (_("bad register or register pair for operand %u of '%.*s'"),
1690 opno
, opc_len
, str
);
1693 case TIC6X_OP_REG
| TIC6X_OP_CTRL
:
1695 as_bad (_("bad register for operand %u of '%.*s'"),
1696 opno
, opc_len
, str
);
1699 case TIC6X_OP_REGPAIR
:
1700 as_bad (_("bad register pair for operand %u of '%.*s'"),
1701 opno
, opc_len
, str
);
1704 case TIC6X_OP_FUNC_UNIT
:
1705 as_bad (_("bad functional unit for operand %u of '%.*s'"),
1706 opno
, opc_len
, str
);
1710 as_bad (_("bad operand %u of '%.*s'"),
1711 opno
, opc_len
, str
);
1715 while (!is_end_of_line
[(unsigned char) *q
] && *q
!= ',')
1719 return operand_parsed
;
1722 /* Table of assembler operators and associated O_* values. */
1727 } tic6x_operator_table
;
1728 static const tic6x_operator_table tic6x_operators
[] = {
1729 #define O_dsbt_index O_md1
1730 { "dsbt_index", O_dsbt_index
},
1733 #define O_dpr_got O_md3
1734 { "dpr_got", O_dpr_got
},
1735 #define O_dpr_byte O_md4
1736 { "dpr_byte", O_dpr_byte
},
1737 #define O_dpr_hword O_md5
1738 { "dpr_hword", O_dpr_hword
},
1739 #define O_dpr_word O_md6
1740 { "dpr_word", O_dpr_word
},
1741 #define O_pcr_offset O_md7
1742 { "pcr_offset", O_pcr_offset
}
1745 /* Parse a name in some machine-specific way. Used on C6X to handle
1746 assembler operators. */
1749 tic6x_parse_name (const char *name
, expressionS
*exprP
,
1750 enum expr_mode mode ATTRIBUTE_UNUSED
, char *nextchar
)
1752 char *p
= input_line_pointer
;
1753 char c
, *name_start
, *name_end
;
1754 const char *inner_name
;
1756 operatorT op
= O_illegal
;
1757 symbolS
*sym
, *op_sym
= NULL
;
1762 for (i
= 0; i
< ARRAY_SIZE (tic6x_operators
); i
++)
1763 if (strcasecmp (name
+ 1, tic6x_operators
[i
].name
) == 0)
1765 op
= tic6x_operators
[i
].op
;
1769 if (op
== O_illegal
)
1772 *input_line_pointer
= *nextchar
;
1773 skip_whitespace (p
);
1777 *input_line_pointer
= 0;
1781 skip_whitespace (p
);
1783 if (!is_name_beginner (*p
))
1785 *input_line_pointer
= 0;
1791 while (is_part_of_name (*p
))
1794 skip_whitespace (p
);
1796 if (op
== O_pcr_offset
)
1798 char *op_name_start
, *op_name_end
;
1802 *input_line_pointer
= 0;
1806 skip_whitespace (p
);
1808 if (!is_name_beginner (*p
))
1810 *input_line_pointer
= 0;
1816 while (is_part_of_name (*p
))
1819 skip_whitespace (p
);
1823 op_sym
= symbol_find_or_make (op_name_start
);
1829 *input_line_pointer
= 0;
1833 input_line_pointer
= p
+ 1;
1834 *nextchar
= *input_line_pointer
;
1835 *input_line_pointer
= 0;
1839 inner_name
= name_start
;
1840 if (op
== O_dsbt_index
&& strcmp (inner_name
, "__c6xabi_DSBT_BASE") != 0)
1842 as_bad (_("$DSBT_INDEX must be used with __c6xabi_DSBT_BASE"));
1843 inner_name
= "__c6xabi_DSBT_BASE";
1845 sym
= symbol_find_or_make (inner_name
);
1849 exprP
->X_add_symbol
= sym
;
1850 exprP
->X_add_number
= 0;
1851 exprP
->X_op_symbol
= op_sym
;
1857 /* Create a fixup for an expression. Same arguments as fix_new_exp,
1858 plus FIX_ADDA which is TRUE for ADDA instructions (to indicate that
1859 fixes resolving to constants should have those constants implicitly
1860 shifted) and FALSE otherwise, but look for C6X-specific expression
1861 types and adjust the relocations or give errors accordingly. */
1864 tic6x_fix_new_exp (fragS
*frag
, int where
, int size
, expressionS
*exp
,
1865 int pcrel
, bfd_reloc_code_real_type r_type
,
1866 bfd_boolean fix_adda
)
1868 bfd_reloc_code_real_type new_reloc
= BFD_RELOC_UNUSED
;
1869 symbolS
*subsy
= NULL
;
1877 case BFD_RELOC_C6000_SBR_U15_W
:
1878 new_reloc
= BFD_RELOC_C6000_DSBT_INDEX
;
1882 as_bad (_("$DSBT_INDEX not supported in this context"));
1890 case BFD_RELOC_C6000_SBR_U15_W
:
1891 new_reloc
= BFD_RELOC_C6000_SBR_GOT_U15_W
;
1895 as_bad (_("$GOT not supported in this context"));
1903 case BFD_RELOC_C6000_ABS_L16
:
1904 new_reloc
= BFD_RELOC_C6000_SBR_GOT_L16_W
;
1907 case BFD_RELOC_C6000_ABS_H16
:
1908 new_reloc
= BFD_RELOC_C6000_SBR_GOT_H16_W
;
1912 as_bad (_("$DPR_GOT not supported in this context"));
1920 case BFD_RELOC_C6000_ABS_S16
:
1921 new_reloc
= BFD_RELOC_C6000_SBR_S16
;
1924 case BFD_RELOC_C6000_ABS_L16
:
1925 new_reloc
= BFD_RELOC_C6000_SBR_L16_B
;
1928 case BFD_RELOC_C6000_ABS_H16
:
1929 new_reloc
= BFD_RELOC_C6000_SBR_H16_B
;
1933 as_bad (_("$DPR_BYTE not supported in this context"));
1941 case BFD_RELOC_C6000_ABS_L16
:
1942 new_reloc
= BFD_RELOC_C6000_SBR_L16_H
;
1945 case BFD_RELOC_C6000_ABS_H16
:
1946 new_reloc
= BFD_RELOC_C6000_SBR_H16_H
;
1950 as_bad (_("$DPR_HWORD not supported in this context"));
1958 case BFD_RELOC_C6000_ABS_L16
:
1959 new_reloc
= BFD_RELOC_C6000_SBR_L16_W
;
1962 case BFD_RELOC_C6000_ABS_H16
:
1963 new_reloc
= BFD_RELOC_C6000_SBR_H16_W
;
1967 as_bad (_("$DPR_WORD not supported in this context"));
1973 subsy
= exp
->X_op_symbol
;
1976 case BFD_RELOC_C6000_ABS_S16
:
1977 case BFD_RELOC_C6000_ABS_L16
:
1978 new_reloc
= BFD_RELOC_C6000_PCR_L16
;
1981 case BFD_RELOC_C6000_ABS_H16
:
1982 new_reloc
= BFD_RELOC_C6000_PCR_H16
;
1986 as_bad (_("$PCR_OFFSET not supported in this context"));
1997 as_bad (_("invalid PC-relative operand"));
2003 if (new_reloc
== BFD_RELOC_UNUSED
)
2004 fix
= fix_new_exp (frag
, where
, size
, exp
, pcrel
, r_type
);
2006 fix
= fix_new (frag
, where
, size
, exp
->X_add_symbol
, exp
->X_add_number
,
2008 fix
->tc_fix_data
.fix_subsy
= subsy
;
2009 fix
->tc_fix_data
.fix_adda
= fix_adda
;
2012 /* Generate a fix for a constant (.word etc.). Needed to ensure these
2013 go through the error checking in tic6x_fix_new_exp. */
2016 tic6x_cons_fix_new (fragS
*frag
, int where
, int size
, expressionS
*exp
)
2018 bfd_reloc_code_real_type r_type
;
2023 r_type
= BFD_RELOC_8
;
2027 r_type
= BFD_RELOC_16
;
2031 r_type
= BFD_RELOC_32
;
2035 as_bad (_("no %d-byte relocations available"), size
);
2039 tic6x_fix_new_exp (frag
, where
, size
, exp
, 0, r_type
, FALSE
);
2042 /* Initialize target-specific fix data. */
2045 tic6x_init_fix_data (fixS
*fixP
)
2047 fixP
->tc_fix_data
.fix_adda
= FALSE
;
2048 fixP
->tc_fix_data
.fix_subsy
= NULL
;
2051 /* Return true if the fix can be handled by GAS, false if it must
2052 be passed through to the linker. */
2055 tic6x_fix_adjustable (fixS
*fixP
)
2057 switch (fixP
->fx_r_type
)
2059 /* Adjust_reloc_syms doesn't know about the GOT. */
2060 case BFD_RELOC_C6000_SBR_GOT_U15_W
:
2061 case BFD_RELOC_C6000_SBR_GOT_H16_W
:
2062 case BFD_RELOC_C6000_SBR_GOT_L16_W
:
2063 case BFD_RELOC_C6000_EHTYPE
:
2066 case BFD_RELOC_C6000_PREL31
:
2069 case BFD_RELOC_C6000_PCR_H16
:
2070 case BFD_RELOC_C6000_PCR_L16
:
2078 /* Given the fine-grained form of an operand, return the coarse
2082 tic6x_coarse_operand_form (tic6x_operand_form form
)
2086 case tic6x_operand_asm_const
:
2087 case tic6x_operand_link_const
:
2088 return TIC6X_OP_EXP
;
2090 case tic6x_operand_reg
:
2091 case tic6x_operand_xreg
:
2092 case tic6x_operand_dreg
:
2093 case tic6x_operand_areg
:
2094 case tic6x_operand_retreg
:
2095 return TIC6X_OP_REG
;
2097 case tic6x_operand_regpair
:
2098 case tic6x_operand_xregpair
:
2099 case tic6x_operand_dregpair
:
2100 return TIC6X_OP_REGPAIR
;
2102 case tic6x_operand_irp
:
2103 return TIC6X_OP_IRP
;
2105 case tic6x_operand_nrp
:
2106 return TIC6X_OP_NRP
;
2108 case tic6x_operand_ctrl
:
2109 return TIC6X_OP_CTRL
;
2111 case tic6x_operand_mem_short
:
2112 case tic6x_operand_mem_long
:
2113 case tic6x_operand_mem_deref
:
2114 return TIC6X_OP_MEM_NOUNREG
;
2116 case tic6x_operand_mem_ndw
:
2117 return TIC6X_OP_MEM_UNREG
;
2119 case tic6x_operand_func_unit
:
2120 return TIC6X_OP_FUNC_UNIT
;
2127 /* How an operand may match or not match a desired form. If different
2128 instruction alternatives fail in different ways, the first failure
2129 in this list determines the diagnostic. */
2133 tic6x_match_matches
,
2134 /* Bad coarse form. */
2137 tic6x_match_non_const
,
2138 /* Register on wrong side. */
2139 tic6x_match_wrong_side
,
2140 /* Not a valid address register. */
2141 tic6x_match_bad_address
,
2142 /* Not a valid return address register. */
2143 tic6x_match_bad_return
,
2144 /* Control register not readable. */
2145 tic6x_match_ctrl_write_only
,
2146 /* Control register not writable. */
2147 tic6x_match_ctrl_read_only
,
2148 /* Not a valid memory reference for this instruction. */
2150 } tic6x_operand_match
;
2152 /* Return whether an operand matches the given fine-grained form and
2153 read/write usage, and, if it does not match, how it fails to match.
2154 The main functional unit side is SIDE; the cross-path side is CROSS
2155 (the same as SIDE if a cross path not used); the data side is
2157 static tic6x_operand_match
2158 tic6x_operand_matches_form (const tic6x_operand
*op
, tic6x_operand_form form
,
2159 tic6x_rw rw
, unsigned int side
, unsigned int cross
,
2160 unsigned int data_side
)
2162 unsigned int coarse
= tic6x_coarse_operand_form (form
);
2164 if (coarse
!= op
->form
)
2165 return tic6x_match_coarse
;
2169 case tic6x_operand_asm_const
:
2170 if (op
->value
.exp
.X_op
== O_constant
)
2171 return tic6x_match_matches
;
2173 return tic6x_match_non_const
;
2175 case tic6x_operand_link_const
:
2176 case tic6x_operand_irp
:
2177 case tic6x_operand_nrp
:
2178 case tic6x_operand_func_unit
:
2179 /* All expressions are link-time constants, although there may
2180 not be relocations to express them in the output file. "irp"
2181 and "nrp" are unique operand values. All parsed functional
2182 unit names are valid. */
2183 return tic6x_match_matches
;
2185 case tic6x_operand_reg
:
2186 case tic6x_operand_regpair
:
2187 if (op
->value
.reg
.side
== side
)
2188 return tic6x_match_matches
;
2190 return tic6x_match_wrong_side
;
2192 case tic6x_operand_xreg
:
2193 case tic6x_operand_xregpair
:
2194 if (op
->value
.reg
.side
== cross
)
2195 return tic6x_match_matches
;
2197 return tic6x_match_wrong_side
;
2199 case tic6x_operand_dreg
:
2200 case tic6x_operand_dregpair
:
2201 if (op
->value
.reg
.side
== data_side
)
2202 return tic6x_match_matches
;
2204 return tic6x_match_wrong_side
;
2206 case tic6x_operand_areg
:
2207 if (op
->value
.reg
.side
!= cross
)
2208 return tic6x_match_wrong_side
;
2209 else if (op
->value
.reg
.side
== 2
2210 && (op
->value
.reg
.num
== 14 || op
->value
.reg
.num
== 15))
2211 return tic6x_match_matches
;
2213 return tic6x_match_bad_address
;
2215 case tic6x_operand_retreg
:
2216 if (op
->value
.reg
.side
!= side
)
2217 return tic6x_match_wrong_side
;
2218 else if (op
->value
.reg
.num
!= 3)
2219 return tic6x_match_bad_return
;
2221 return tic6x_match_matches
;
2223 case tic6x_operand_ctrl
:
2227 if (tic6x_ctrl_table
[op
->value
.ctrl
].rw
== tic6x_rw_read
2228 || tic6x_ctrl_table
[op
->value
.ctrl
].rw
== tic6x_rw_read_write
)
2229 return tic6x_match_matches
;
2231 return tic6x_match_ctrl_write_only
;
2233 case tic6x_rw_write
:
2234 if (tic6x_ctrl_table
[op
->value
.ctrl
].rw
== tic6x_rw_write
2235 || tic6x_ctrl_table
[op
->value
.ctrl
].rw
== tic6x_rw_read_write
)
2236 return tic6x_match_matches
;
2238 return tic6x_match_ctrl_read_only
;
2244 case tic6x_operand_mem_deref
:
2245 if (op
->value
.mem
.mod
!= tic6x_mem_mod_none
)
2246 return tic6x_match_bad_mem
;
2247 else if (op
->value
.mem
.scaled
!= tic6x_offset_none
)
2249 else if (op
->value
.mem
.base_reg
.side
!= side
)
2250 return tic6x_match_bad_mem
;
2252 return tic6x_match_matches
;
2254 case tic6x_operand_mem_short
:
2255 case tic6x_operand_mem_ndw
:
2256 if (op
->value
.mem
.base_reg
.side
!= side
)
2257 return tic6x_match_bad_mem
;
2258 if (op
->value
.mem
.mod
== tic6x_mem_mod_none
)
2260 if (op
->value
.mem
.scaled
!= tic6x_offset_none
)
2262 return tic6x_match_matches
;
2264 if (op
->value
.mem
.scaled
== tic6x_offset_none
)
2266 if (op
->value
.mem
.mod
== tic6x_mem_mod_plus
2267 || op
->value
.mem
.mod
== tic6x_mem_mod_minus
)
2269 return tic6x_match_matches
;
2271 if (op
->value
.mem
.offset_is_reg
)
2273 if (op
->value
.mem
.scaled
== tic6x_offset_unscaled
2274 && form
!= tic6x_operand_mem_ndw
)
2276 if (op
->value
.mem
.offset
.reg
.side
== side
)
2277 return tic6x_match_matches
;
2279 return tic6x_match_bad_mem
;
2283 if (op
->value
.mem
.offset
.exp
.X_op
== O_constant
)
2284 return tic6x_match_matches
;
2286 return tic6x_match_bad_mem
;
2289 case tic6x_operand_mem_long
:
2290 if (op
->value
.mem
.base_reg
.side
== 2
2291 && (op
->value
.mem
.base_reg
.num
== 14
2292 || op
->value
.mem
.base_reg
.num
== 15))
2294 switch (op
->value
.mem
.mod
)
2296 case tic6x_mem_mod_none
:
2297 if (op
->value
.mem
.scaled
!= tic6x_offset_none
)
2299 return tic6x_match_matches
;
2301 case tic6x_mem_mod_plus
:
2302 if (op
->value
.mem
.scaled
== tic6x_offset_none
)
2304 if (op
->value
.mem
.offset_is_reg
)
2305 return tic6x_match_bad_mem
;
2306 else if (op
->value
.mem
.scaled
== tic6x_offset_scaled
2307 && op
->value
.mem
.offset
.exp
.X_op
!= O_constant
)
2308 return tic6x_match_bad_mem
;
2310 return tic6x_match_matches
;
2312 case tic6x_mem_mod_minus
:
2313 case tic6x_mem_mod_preinc
:
2314 case tic6x_mem_mod_predec
:
2315 case tic6x_mem_mod_postinc
:
2316 case tic6x_mem_mod_postdec
:
2317 return tic6x_match_bad_mem
;
2325 return tic6x_match_bad_mem
;
2332 /* Return the number of bits shift used with DP-relative coding method
2336 tic6x_dpr_shift (tic6x_coding_method coding
)
2340 case tic6x_coding_ulcst_dpr_byte
:
2343 case tic6x_coding_ulcst_dpr_half
:
2346 case tic6x_coding_ulcst_dpr_word
:
2354 /* Return the relocation used with DP-relative coding method
2357 static bfd_reloc_code_real_type
2358 tic6x_dpr_reloc (tic6x_coding_method coding
)
2362 case tic6x_coding_ulcst_dpr_byte
:
2363 return BFD_RELOC_C6000_SBR_U15_B
;
2365 case tic6x_coding_ulcst_dpr_half
:
2366 return BFD_RELOC_C6000_SBR_U15_H
;
2368 case tic6x_coding_ulcst_dpr_word
:
2369 return BFD_RELOC_C6000_SBR_U15_W
;
2376 /* Given a memory reference *MEM_REF as originally parsed, fill in
2377 defaults for missing offsets. */
2380 tic6x_default_mem_ref (tic6x_mem_ref
*mem_ref
)
2382 switch (mem_ref
->mod
)
2384 case tic6x_mem_mod_none
:
2385 if (mem_ref
->scaled
!= tic6x_offset_none
)
2387 mem_ref
->mod
= tic6x_mem_mod_plus
;
2388 mem_ref
->scaled
= tic6x_offset_unscaled
;
2389 mem_ref
->offset_is_reg
= FALSE
;
2390 memset (&mem_ref
->offset
.exp
, 0, sizeof mem_ref
->offset
.exp
);
2391 mem_ref
->offset
.exp
.X_op
= O_constant
;
2392 mem_ref
->offset
.exp
.X_add_number
= 0;
2393 mem_ref
->offset
.exp
.X_unsigned
= 0;
2396 case tic6x_mem_mod_plus
:
2397 case tic6x_mem_mod_minus
:
2398 if (mem_ref
->scaled
== tic6x_offset_none
)
2402 case tic6x_mem_mod_preinc
:
2403 case tic6x_mem_mod_predec
:
2404 case tic6x_mem_mod_postinc
:
2405 case tic6x_mem_mod_postdec
:
2406 if (mem_ref
->scaled
!= tic6x_offset_none
)
2408 mem_ref
->scaled
= tic6x_offset_scaled
;
2409 mem_ref
->offset_is_reg
= FALSE
;
2410 memset (&mem_ref
->offset
.exp
, 0, sizeof mem_ref
->offset
.exp
);
2411 mem_ref
->offset
.exp
.X_op
= O_constant
;
2412 mem_ref
->offset
.exp
.X_add_number
= 1;
2413 mem_ref
->offset
.exp
.X_unsigned
= 0;
2421 /* Return the encoding in the 8-bit field of an SPMASK or SPMASKR
2422 instruction of the specified UNIT, side SIDE. */
2425 tic6x_encode_spmask (tic6x_func_unit_base unit
, unsigned int side
)
2429 case tic6x_func_unit_l
:
2430 return 1 << (side
- 1);
2432 case tic6x_func_unit_s
:
2433 return 1 << (side
+ 1);
2435 case tic6x_func_unit_d
:
2436 return 1 << (side
+ 3);
2438 case tic6x_func_unit_m
:
2439 return 1 << (side
+ 5);
2446 /* Try to encode the instruction with opcode number ID and operands
2447 OPERANDS (number NUM_OPERANDS), creg value THIS_LINE_CREG and z
2448 value THIS_LINE_Z; FUNC_UNIT_SIDE, FUNC_UNIT_CROSS and
2449 FUNC_UNIT_DATA_SIDE describe the functional unit specification;
2450 SPLOOP_II is the ii value from the previous SPLOOP-family
2451 instruction, or 0 if not in such a loop; the only possible problems
2452 are operands being out of range (they already match the
2453 fine-grained form), and inappropriate predication. If this
2454 succeeds, return the encoding and set *OK to TRUE; otherwise return
2455 0 and set *OK to FALSE. If a fix is needed, set *FIX_NEEDED to
2456 true and fill in *FIX_EXP, *FIX_PCREL, *FX_R_TYPE and *FIX_ADDA.
2457 Print error messages for failure if PRINT_ERRORS is TRUE; the
2458 opcode starts at STR and has length OPC_LEN. */
2461 tic6x_try_encode (tic6x_opcode_id id
, tic6x_operand
*operands
,
2462 unsigned int num_operands
, unsigned int this_line_creg
,
2463 unsigned int this_line_z
, unsigned int func_unit_side
,
2464 unsigned int func_unit_cross
,
2465 unsigned int func_unit_data_side
, int sploop_ii
,
2466 expressionS
**fix_exp
, int *fix_pcrel
,
2467 bfd_reloc_code_real_type
*fx_r_type
, bfd_boolean
*fix_adda
,
2468 bfd_boolean
*fix_needed
, bfd_boolean
*ok
,
2469 bfd_boolean print_errors
, char *str
, int opc_len
)
2471 const tic6x_opcode
*opct
;
2472 const tic6x_insn_format
*fmt
;
2473 unsigned int opcode_value
;
2476 opct
= &tic6x_opcode_table
[id
];
2477 fmt
= &tic6x_insn_format_table
[opct
->format
];
2478 opcode_value
= fmt
->cst_bits
;
2480 for (fld
= 0; fld
< opct
->num_fixed_fields
; fld
++)
2482 if (opct
->fixed_fields
[fld
].min_val
== opct
->fixed_fields
[fld
].max_val
)
2484 const tic6x_insn_field
*fldd
;
2485 fldd
= tic6x_field_from_fmt (fmt
, opct
->fixed_fields
[fld
].field_id
);
2488 opcode_value
|= opct
->fixed_fields
[fld
].min_val
<< fldd
->low_pos
;
2492 for (fld
= 0; fld
< opct
->num_variable_fields
; fld
++)
2494 const tic6x_insn_field
*fldd
;
2500 unsigned int fcyc_bits
;
2505 fldd
= tic6x_field_from_fmt (fmt
, opct
->variable_fields
[fld
].field_id
);
2508 opno
= opct
->variable_fields
[fld
].operand_num
;
2509 switch (opct
->variable_fields
[fld
].coding_method
)
2511 case tic6x_coding_ucst
:
2512 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2514 if (operands
[opno
].value
.exp
.X_op
!= O_constant
)
2516 ucexp
= operands
[opno
].value
.exp
;
2518 if (ucexp
.X_add_number
< 0
2519 || ucexp
.X_add_number
>= (1 << fldd
->width
))
2522 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
2527 value
= ucexp
.X_add_number
;
2530 case tic6x_coding_scst
:
2531 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2533 if (operands
[opno
].value
.exp
.X_op
!= O_constant
)
2536 /* Opcode table should not permit non-constants without
2537 a known relocation for them. */
2538 if (fldd
->low_pos
!= 7 || fldd
->width
!= 16)
2541 *fix_exp
= &operands
[opno
].value
.exp
;
2543 *fx_r_type
= BFD_RELOC_C6000_ABS_S16
;
2547 sign_value
= SEXT (operands
[opno
].value
.exp
.X_add_number
);
2549 if (sign_value
< -(1 << (fldd
->width
- 1))
2550 || (sign_value
>= (1 << (fldd
->width
- 1))))
2553 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
2558 value
= sign_value
+ (1 << (fldd
->width
- 1));
2559 value
^= (1 << (fldd
->width
- 1));
2562 case tic6x_coding_ucst_minus_one
:
2563 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2565 if (operands
[opno
].value
.exp
.X_op
!= O_constant
)
2567 if (operands
[opno
].value
.exp
.X_add_number
<= 0
2568 || operands
[opno
].value
.exp
.X_add_number
> (1 << fldd
->width
))
2571 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
2576 value
= operands
[opno
].value
.exp
.X_add_number
- 1;
2579 case tic6x_coding_scst_negate
:
2580 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2582 if (operands
[opno
].value
.exp
.X_op
!= O_constant
)
2584 sign_value
= SEXT (-operands
[opno
].value
.exp
.X_add_number
);
2585 goto signed_constant
;
2587 case tic6x_coding_ulcst_dpr_byte
:
2588 case tic6x_coding_ulcst_dpr_half
:
2589 case tic6x_coding_ulcst_dpr_word
:
2590 bits
= tic6x_dpr_shift (opct
->variable_fields
[fld
].coding_method
);
2591 switch (operands
[opno
].form
)
2594 if (operands
[opno
].value
.exp
.X_op
== O_constant
)
2596 ucexp
= operands
[opno
].value
.exp
;
2597 goto unsigned_constant
;
2599 expp
= &operands
[opno
].value
.exp
;
2602 case TIC6X_OP_MEM_NOUNREG
:
2603 mem
= operands
[opno
].value
.mem
;
2604 tic6x_default_mem_ref (&mem
);
2605 if (mem
.offset_is_reg
)
2607 if (mem
.offset
.exp
.X_op
== O_constant
)
2609 ucexp
= mem
.offset
.exp
;
2610 if (mem
.scaled
== tic6x_offset_unscaled
)
2612 if (ucexp
.X_add_number
& ((1 << bits
) - 1))
2615 as_bad (_("offset in operand %u of '%.*s' not "
2616 "divisible by %u"), opno
+ 1, opc_len
,
2621 ucexp
.X_add_number
>>= bits
;
2623 goto unsigned_constant
;
2625 if (mem
.scaled
!= tic6x_offset_unscaled
)
2627 if (operands
[opno
].value
.mem
.mod
== tic6x_mem_mod_none
2628 || operands
[opno
].value
.mem
.scaled
!= tic6x_offset_unscaled
2629 || operands
[opno
].value
.mem
.offset_is_reg
)
2631 expp
= &operands
[opno
].value
.mem
.offset
.exp
;
2638 /* Opcode table should not use this encoding without a known
2640 if (fldd
->low_pos
!= 8 || fldd
->width
!= 15)
2642 /* We do not check for offset divisibility here; such a
2643 check is not needed at this point to encode the value,
2644 and if there is eventually a problem it will be detected
2645 either in md_apply_fix or at link time. */
2650 = tic6x_dpr_reloc (opct
->variable_fields
[fld
].coding_method
);
2651 if (operands
[opno
].form
== TIC6X_OP_EXP
)
2657 case tic6x_coding_lcst_low16
:
2658 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2660 if (operands
[opno
].value
.exp
.X_op
== O_constant
)
2661 value
= operands
[opno
].value
.exp
.X_add_number
& 0xffff;
2665 /* Opcode table should not use this encoding without a
2666 known relocation. */
2667 if (fldd
->low_pos
!= 7 || fldd
->width
!= 16)
2670 *fix_exp
= &operands
[opno
].value
.exp
;
2672 *fx_r_type
= BFD_RELOC_C6000_ABS_L16
;
2677 case tic6x_coding_lcst_high16
:
2678 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2680 if (operands
[opno
].value
.exp
.X_op
== O_constant
)
2681 value
= (operands
[opno
].value
.exp
.X_add_number
>> 16) & 0xffff;
2685 /* Opcode table should not use this encoding without a
2686 known relocation. */
2687 if (fldd
->low_pos
!= 7 || fldd
->width
!= 16)
2690 *fix_exp
= &operands
[opno
].value
.exp
;
2692 *fx_r_type
= BFD_RELOC_C6000_ABS_H16
;
2697 case tic6x_coding_pcrel
:
2698 case tic6x_coding_pcrel_half
:
2699 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2703 *fix_exp
= &operands
[opno
].value
.exp
;
2705 if (fldd
->low_pos
== 7 && fldd
->width
== 21)
2706 *fx_r_type
= BFD_RELOC_C6000_PCR_S21
;
2707 else if (fldd
->low_pos
== 16 && fldd
->width
== 12)
2708 *fx_r_type
= BFD_RELOC_C6000_PCR_S12
;
2709 else if (fldd
->low_pos
== 13 && fldd
->width
== 10)
2710 *fx_r_type
= BFD_RELOC_C6000_PCR_S10
;
2711 else if (fldd
->low_pos
== 16 && fldd
->width
== 7)
2712 *fx_r_type
= BFD_RELOC_C6000_PCR_S7
;
2714 /* Opcode table should not use this encoding without a
2715 known relocation. */
2720 case tic6x_coding_reg
:
2721 switch (operands
[opno
].form
)
2724 case TIC6X_OP_REGPAIR
:
2725 value
= operands
[opno
].value
.reg
.num
;
2728 case TIC6X_OP_MEM_NOUNREG
:
2729 case TIC6X_OP_MEM_UNREG
:
2730 value
= operands
[opno
].value
.mem
.base_reg
.num
;
2738 case tic6x_coding_areg
:
2739 switch (operands
[opno
].form
)
2742 value
= (operands
[opno
].value
.reg
.num
== 15 ? 1 : 0);
2745 case TIC6X_OP_MEM_NOUNREG
:
2746 value
= (operands
[opno
].value
.mem
.base_reg
.num
== 15 ? 1 : 0);
2754 case tic6x_coding_crlo
:
2755 if (operands
[opno
].form
!= TIC6X_OP_CTRL
)
2757 value
= tic6x_ctrl_table
[operands
[opno
].value
.ctrl
].crlo
;
2760 case tic6x_coding_crhi
:
2761 if (operands
[opno
].form
!= TIC6X_OP_CTRL
)
2766 case tic6x_coding_reg_shift
:
2767 if (operands
[opno
].form
!= TIC6X_OP_REGPAIR
)
2769 value
= operands
[opno
].value
.reg
.num
>> 1;
2772 case tic6x_coding_mem_offset
:
2773 if (operands
[opno
].form
!= TIC6X_OP_MEM_NOUNREG
)
2775 mem
= operands
[opno
].value
.mem
;
2776 tic6x_default_mem_ref (&mem
);
2777 if (mem
.offset_is_reg
)
2779 if (mem
.scaled
!= tic6x_offset_scaled
)
2781 value
= mem
.offset
.reg
.num
;
2787 if (mem
.offset
.exp
.X_op
!= O_constant
)
2791 case tic6x_offset_scaled
:
2795 case tic6x_offset_unscaled
:
2796 scale
= opct
->operand_info
[opno
].size
;
2797 if (scale
!= 1 && scale
!= 2 && scale
!= 4 && scale
!= 8)
2804 if (mem
.offset
.exp
.X_add_number
< 0
2805 || mem
.offset
.exp
.X_add_number
>= (1 << fldd
->width
) * scale
)
2808 as_bad (_("offset in operand %u of '%.*s' out of range"),
2809 opno
+ 1, opc_len
, str
);
2813 if (mem
.offset
.exp
.X_add_number
% scale
)
2816 as_bad (_("offset in operand %u of '%.*s' not "
2818 opno
+ 1, opc_len
, str
, scale
);
2822 value
= mem
.offset
.exp
.X_add_number
/ scale
;
2826 case tic6x_coding_mem_offset_noscale
:
2827 if (operands
[opno
].form
!= TIC6X_OP_MEM_UNREG
)
2829 mem
= operands
[opno
].value
.mem
;
2830 tic6x_default_mem_ref (&mem
);
2831 if (mem
.offset_is_reg
)
2832 value
= mem
.offset
.reg
.num
;
2835 if (mem
.offset
.exp
.X_op
!= O_constant
)
2837 if (mem
.offset
.exp
.X_add_number
< 0
2838 || mem
.offset
.exp
.X_add_number
>= (1 << fldd
->width
))
2841 as_bad (_("offset in operand %u of '%.*s' out of range"),
2842 opno
+ 1, opc_len
, str
);
2846 value
= mem
.offset
.exp
.X_add_number
;
2850 case tic6x_coding_mem_mode
:
2851 if (operands
[opno
].form
!= TIC6X_OP_MEM_NOUNREG
2852 && operands
[opno
].form
!= TIC6X_OP_MEM_UNREG
)
2854 mem
= operands
[opno
].value
.mem
;
2855 tic6x_default_mem_ref (&mem
);
2858 case tic6x_mem_mod_plus
:
2862 case tic6x_mem_mod_minus
:
2866 case tic6x_mem_mod_preinc
:
2870 case tic6x_mem_mod_predec
:
2874 case tic6x_mem_mod_postinc
:
2878 case tic6x_mem_mod_postdec
:
2885 value
+= (mem
.offset_is_reg
? 4 : 0);
2888 case tic6x_coding_scaled
:
2889 if (operands
[opno
].form
!= TIC6X_OP_MEM_UNREG
)
2891 mem
= operands
[opno
].value
.mem
;
2892 tic6x_default_mem_ref (&mem
);
2895 case tic6x_offset_unscaled
:
2899 case tic6x_offset_scaled
:
2908 case tic6x_coding_spmask
:
2909 /* The position of such a field is hardcoded in the handling
2911 if (fldd
->low_pos
!= 18)
2914 for (opno
= 0; opno
< num_operands
; opno
++)
2918 v
= tic6x_encode_spmask (operands
[opno
].value
.func_unit
.base
,
2919 operands
[opno
].value
.func_unit
.side
);
2923 as_bad (_("functional unit already masked for operand "
2924 "%u of '%.*s'"), opno
+ 1, opc_len
, str
);
2932 case tic6x_coding_reg_unused
:
2933 /* This is a placeholder; correct handling goes along with
2934 resource constraint checks. */
2938 case tic6x_coding_fstg
:
2939 case tic6x_coding_fcyc
:
2940 if (operands
[opno
].form
!= TIC6X_OP_EXP
)
2942 if (operands
[opno
].value
.exp
.X_op
!= O_constant
)
2947 as_bad (_("'%.*s' instruction not in a software "
2956 else if (sploop_ii
<= 2)
2958 else if (sploop_ii
<= 4)
2960 else if (sploop_ii
<= 8)
2962 else if (sploop_ii
<= 14)
2966 if (fcyc_bits
> fldd
->width
)
2969 if (opct
->variable_fields
[fld
].coding_method
== tic6x_coding_fstg
)
2972 if (operands
[opno
].value
.exp
.X_add_number
< 0
2973 || (operands
[opno
].value
.exp
.X_add_number
2974 >= (1 << (fldd
->width
- fcyc_bits
))))
2977 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
2982 value
= operands
[opno
].value
.exp
.X_add_number
;
2983 for (t
= 0, i
= fcyc_bits
; i
< fldd
->width
; i
++)
2985 t
= (t
<< 1) | (value
& 1);
2988 value
= t
<< fcyc_bits
;
2992 if (operands
[opno
].value
.exp
.X_add_number
< 0
2993 || (operands
[opno
].value
.exp
.X_add_number
>= sploop_ii
))
2996 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
3001 value
= operands
[opno
].value
.exp
.X_add_number
;
3005 case tic6x_coding_fu
:
3006 value
= func_unit_side
== 2 ? 1 : 0;
3009 case tic6x_coding_data_fu
:
3010 value
= func_unit_data_side
== 2 ? 1 : 0;
3013 case tic6x_coding_xpath
:
3014 value
= func_unit_cross
;
3021 for (ffld
= 0; ffld
< opct
->num_fixed_fields
; ffld
++)
3022 if ((opct
->fixed_fields
[ffld
].field_id
3023 == opct
->variable_fields
[fld
].field_id
)
3024 && (value
< opct
->fixed_fields
[ffld
].min_val
3025 || value
> opct
->fixed_fields
[ffld
].max_val
))
3028 as_bad (_("operand %u of '%.*s' out of range"), opno
+ 1,
3034 opcode_value
|= value
<< fldd
->low_pos
;
3039 const tic6x_insn_field
*creg
;
3040 const tic6x_insn_field
*z
;
3042 creg
= tic6x_field_from_fmt (fmt
, tic6x_field_creg
);
3046 as_bad (_("instruction '%.*s' cannot be predicated"),
3051 z
= tic6x_field_from_fmt (fmt
, tic6x_field_z
);
3052 /* If there is a creg field, there must be a z field; otherwise
3053 there is an error in the format table. */
3057 opcode_value
|= this_line_creg
<< creg
->low_pos
;
3058 opcode_value
|= this_line_z
<< z
->low_pos
;
3062 return opcode_value
;
3065 /* Convert the target integer stored in N bytes in BUF to a host
3066 integer, returning that value. */
3069 md_chars_to_number (char *buf
, int n
)
3072 unsigned char *p
= (unsigned char *) buf
;
3074 if (target_big_endian
)
3079 result
|= (*p
++ & 0xff);
3087 result
|= (p
[n
] & 0xff);
3094 /* Assemble the instruction starting at STR (an opcode, with the
3095 opcode name all-lowercase). */
3098 md_assemble (char *str
)
3102 bfd_boolean this_line_parallel
;
3103 bfd_boolean this_line_spmask
;
3104 unsigned int this_line_creg
;
3105 unsigned int this_line_z
;
3106 tic6x_label_list
*this_insn_label_list
;
3107 segment_info_type
*seginfo
;
3108 tic6x_opcode_list
*opc_list
, *opc
;
3109 tic6x_func_unit_base func_unit_base
= tic6x_func_unit_nfu
;
3110 unsigned int func_unit_side
= 0;
3111 unsigned int func_unit_cross
= 0;
3112 unsigned int cross_side
= 0;
3113 unsigned int func_unit_data_side
= 0;
3114 unsigned int max_matching_opcodes
, num_matching_opcodes
;
3115 tic6x_opcode_id
*opcm
= NULL
;
3116 unsigned int opc_rank
[TIC6X_NUM_PREFER
];
3117 const tic6x_opcode
*opct
= NULL
;
3118 int min_rank
, try_rank
, max_rank
;
3119 bfd_boolean num_operands_permitted
[TIC6X_MAX_SOURCE_OPERANDS
+ 1]
3121 unsigned int operand_forms
[TIC6X_MAX_SOURCE_OPERANDS
] = { 0 };
3122 tic6x_operand operands
[TIC6X_MAX_SOURCE_OPERANDS
];
3123 unsigned int max_num_operands
;
3124 unsigned int num_operands_read
;
3125 bfd_boolean ok_this_arch
, ok_this_fu
, ok_this_arch_fu
;
3126 bfd_boolean bad_operands
= FALSE
;
3127 unsigned int opcode_value
;
3128 bfd_boolean encoded_ok
;
3129 bfd_boolean fix_needed
= FALSE
;
3130 expressionS
*fix_exp
= NULL
;
3132 bfd_reloc_code_real_type fx_r_type
= BFD_RELOC_UNUSED
;
3133 bfd_boolean fix_adda
= FALSE
;
3138 while (*p
&& !is_end_of_line
[(unsigned char) *p
] && *p
!= ' ')
3141 /* This function should only have been called when there is actually
3142 an instruction to assemble. */
3146 /* Now an instruction has been seen, architecture attributes from
3147 .arch directives merge with rather than overriding the previous
3149 tic6x_seen_insns
= TRUE
;
3150 /* If no .arch directives or -march options have been seen, we are
3151 assessing instruction validity based on the C674X default, so set
3152 the attribute accordingly. */
3153 if (tic6x_arch_attribute
== C6XABI_Tag_ISA_none
)
3154 tic6x_arch_attribute
= C6XABI_Tag_ISA_C674X
;
3156 /* Reset global settings for parallel bars and predicates now to
3157 avoid extra errors if there are problems with this opcode. */
3158 this_line_parallel
= tic6x_line_parallel
;
3159 this_line_spmask
= tic6x_line_spmask
;
3160 this_line_creg
= tic6x_line_creg
;
3161 this_line_z
= tic6x_line_z
;
3162 tic6x_line_parallel
= FALSE
;
3163 tic6x_line_spmask
= FALSE
;
3164 tic6x_line_creg
= 0;
3166 seginfo
= seg_info (now_seg
);
3167 this_insn_label_list
= seginfo
->tc_segment_info_data
.label_list
;
3168 seginfo
->tc_segment_info_data
.label_list
= NULL
;
3170 opc_list
= hash_find_n (opcode_hash
, str
, p
- str
);
3171 if (opc_list
== NULL
)
3175 as_bad (_("unknown opcode '%s'"), str
);
3181 skip_whitespace (p
);
3183 /* See if there is something that looks like a functional unit
3187 bfd_boolean good_func_unit
;
3188 tic6x_func_unit_base maybe_base
= tic6x_func_unit_nfu
;
3189 unsigned int maybe_side
= 0;
3190 unsigned int maybe_cross
= 0;
3191 unsigned int maybe_data_side
= 0;
3193 good_func_unit
= tic6x_parse_func_unit_base (p
+ 1, &maybe_base
,
3198 if (p
[3] == ' ' || is_end_of_line
[(unsigned char) p
[3]])
3200 else if ((p
[3] == 'x' || p
[3] == 'X')
3201 && (p
[4] == ' ' || is_end_of_line
[(unsigned char) p
[4]]))
3206 else if (maybe_base
== tic6x_func_unit_d
3207 && (p
[3] == 't' || p
[3] == 'T')
3208 && (p
[4] == '1' || p
[4] == '2')
3209 && (p
[5] == ' ' || is_end_of_line
[(unsigned char) p
[5]]))
3211 maybe_data_side
= p
[4] - '0';
3215 good_func_unit
= FALSE
;
3220 func_unit_base
= maybe_base
;
3221 func_unit_side
= maybe_side
;
3222 func_unit_cross
= maybe_cross
;
3223 cross_side
= (func_unit_cross
? 3 - func_unit_side
: func_unit_side
);
3224 func_unit_data_side
= maybe_data_side
;
3227 skip_whitespace (p
);
3230 /* Determine which entries in the opcode table match, and the
3231 associated permitted forms of operands. */
3232 max_matching_opcodes
= 0;
3233 for (opc
= opc_list
; opc
; opc
= opc
->next
)
3234 max_matching_opcodes
++;
3235 num_matching_opcodes
= 0;
3236 opcm
= xmalloc (max_matching_opcodes
* sizeof (*opcm
));
3237 max_num_operands
= 0;
3238 ok_this_arch
= FALSE
;
3240 ok_this_arch_fu
= FALSE
;
3241 for (opc
= opc_list
; opc
; opc
= opc
->next
)
3243 unsigned int num_operands
;
3245 bfd_boolean this_opc_arch_ok
= TRUE
;
3246 bfd_boolean this_opc_fu_ok
= TRUE
;
3248 if (tic6x_insn_format_table
[tic6x_opcode_table
[opc
->id
].format
].num_bits
3251 if (!(tic6x_opcode_table
[opc
->id
].isa_variants
& tic6x_features
))
3252 this_opc_arch_ok
= FALSE
;
3253 if (tic6x_opcode_table
[opc
->id
].func_unit
!= func_unit_base
)
3254 this_opc_fu_ok
= FALSE
;
3255 if (func_unit_side
== 1
3256 && (tic6x_opcode_table
[opc
->id
].flags
& TIC6X_FLAG_SIDE_B_ONLY
))
3257 this_opc_fu_ok
= FALSE
;
3259 && (tic6x_opcode_table
[opc
->id
].flags
& TIC6X_FLAG_NO_CROSS
))
3260 this_opc_fu_ok
= FALSE
;
3261 if (!func_unit_data_side
3262 && (tic6x_opcode_table
[opc
->id
].flags
3263 & (TIC6X_FLAG_LOAD
| TIC6X_FLAG_STORE
)))
3264 this_opc_fu_ok
= FALSE
;
3265 if (func_unit_data_side
3266 && !(tic6x_opcode_table
[opc
->id
].flags
3267 & (TIC6X_FLAG_LOAD
| TIC6X_FLAG_STORE
)))
3268 this_opc_fu_ok
= FALSE
;
3269 if (func_unit_data_side
== 1
3270 && (tic6x_opcode_table
[opc
->id
].flags
& TIC6X_FLAG_SIDE_T2_ONLY
))
3271 this_opc_fu_ok
= FALSE
;
3272 if (this_opc_arch_ok
)
3273 ok_this_arch
= TRUE
;
3276 if (!this_opc_arch_ok
|| !this_opc_fu_ok
)
3278 ok_this_arch_fu
= TRUE
;
3279 opcm
[num_matching_opcodes
] = opc
->id
;
3280 num_matching_opcodes
++;
3281 num_operands
= tic6x_opcode_table
[opc
->id
].num_operands
;
3283 if (tic6x_opcode_table
[opc
->id
].flags
& TIC6X_FLAG_SPMASK
)
3285 if (num_operands
!= 1
3286 || (tic6x_opcode_table
[opc
->id
].operand_info
[0].form
3287 != tic6x_operand_func_unit
))
3290 for (i
= 0; i
< num_operands
; i
++)
3293 |= tic6x_coarse_operand_form (tic6x_operand_func_unit
);
3294 num_operands_permitted
[i
] = TRUE
;
3299 for (i
= 0; i
< num_operands
; i
++)
3301 tic6x_operand_form f
3302 = tic6x_opcode_table
[opc
->id
].operand_info
[i
].form
;
3304 operand_forms
[i
] |= tic6x_coarse_operand_form (f
);
3307 num_operands_permitted
[num_operands
] = TRUE
;
3308 if (num_operands
> max_num_operands
)
3309 max_num_operands
= num_operands
;
3314 as_bad (_("'%.*s' instruction not supported on this architecture"),
3322 as_bad (_("'%.*s' instruction not supported on this functional unit"),
3328 if (!ok_this_arch_fu
)
3330 as_bad (_("'%.*s' instruction not supported on this functional unit"
3331 " for this architecture"),
3337 /* If there were no instructions matching the above availability
3338 checks, we should now have given an error and returned. */
3339 if (num_matching_opcodes
== 0)
3342 num_operands_read
= 0;
3345 skip_whitespace (p
);
3346 if (is_end_of_line
[(unsigned char) *p
])
3348 if (num_operands_read
> 0)
3350 as_bad (_("missing operand after comma"));
3351 bad_operands
= TRUE
;
3356 if (max_num_operands
== 0)
3358 as_bad (_("too many operands to '%.*s'"), opc_len
, str
);
3359 bad_operands
= TRUE
;
3363 if (!tic6x_parse_operand (&p
, &operands
[num_operands_read
],
3364 operand_forms
[num_operands_read
], str
, opc_len
,
3365 num_operands_read
+ 1))
3366 bad_operands
= TRUE
;
3367 num_operands_read
++;
3369 if (is_end_of_line
[(unsigned char) *p
])
3374 if (num_operands_read
== max_num_operands
)
3376 as_bad (_("too many operands to '%.*s'"), opc_len
, str
);
3377 bad_operands
= TRUE
;
3383 /* Operand parsing should consume whole operands. */
3387 if (!bad_operands
&& !num_operands_permitted
[num_operands_read
])
3389 as_bad (_("bad number of operands to '%.*s'"), opc_len
, str
);
3390 bad_operands
= TRUE
;
3395 /* Each operand is of the right syntactic form for some opcode
3396 choice, and the number of operands is valid. Check that each
3397 operand is OK in detail for some opcode choice with the right
3398 number of operands. */
3401 for (i
= 0; i
< num_operands_read
; i
++)
3403 bfd_boolean coarse_ok
= FALSE
;
3404 bfd_boolean fine_ok
= FALSE
;
3405 tic6x_operand_match fine_failure
= tic6x_match_matches
;
3408 for (j
= 0; j
< num_matching_opcodes
; j
++)
3410 tic6x_operand_form f
;
3413 tic6x_operand_match this_fine_failure
;
3415 if (tic6x_opcode_table
[opcm
[j
]].flags
& TIC6X_FLAG_SPMASK
)
3417 f
= tic6x_operand_func_unit
;
3422 if (tic6x_opcode_table
[opcm
[j
]].num_operands
3423 != num_operands_read
)
3426 f
= tic6x_opcode_table
[opcm
[j
]].operand_info
[i
].form
;
3427 rw
= tic6x_opcode_table
[opcm
[j
]].operand_info
[i
].rw
;
3429 cf
= tic6x_coarse_operand_form (f
);
3431 if (operands
[i
].form
!= cf
)
3436 = tic6x_operand_matches_form (&operands
[i
], f
, rw
,
3439 func_unit_data_side
);
3440 if (this_fine_failure
== tic6x_match_matches
)
3445 if (fine_failure
== tic6x_match_matches
3446 || fine_failure
> this_fine_failure
)
3447 fine_failure
= this_fine_failure
;
3450 /* No instructions should have operand syntactic forms only
3451 acceptable with certain numbers of operands, so no
3452 diagnostic for this case. */
3458 switch (fine_failure
)
3460 case tic6x_match_non_const
:
3461 as_bad (_("operand %u of '%.*s' not constant"),
3462 i
+ 1, opc_len
, str
);
3465 case tic6x_match_wrong_side
:
3466 as_bad (_("operand %u of '%.*s' on wrong side"),
3467 i
+ 1, opc_len
, str
);
3470 case tic6x_match_bad_return
:
3471 as_bad (_("operand %u of '%.*s' not a valid return "
3472 "address register"),
3473 i
+ 1, opc_len
, str
);
3476 case tic6x_match_ctrl_write_only
:
3477 as_bad (_("operand %u of '%.*s' is write-only"),
3478 i
+ 1, opc_len
, str
);
3481 case tic6x_match_ctrl_read_only
:
3482 as_bad (_("operand %u of '%.*s' is read-only"),
3483 i
+ 1, opc_len
, str
);
3486 case tic6x_match_bad_mem
:
3487 as_bad (_("operand %u of '%.*s' not a valid memory "
3489 i
+ 1, opc_len
, str
);
3492 case tic6x_match_bad_address
:
3493 as_bad (_("operand %u of '%.*s' not a valid base "
3494 "address register"),
3495 i
+ 1, opc_len
, str
);
3501 bad_operands
= TRUE
;
3509 /* Each operand is OK for some opcode choice, and the number of
3510 operands is valid. Check whether there is an opcode choice
3511 for which all operands are simultaneously valid. */
3513 bfd_boolean found_match
= FALSE
;
3515 for (i
= 0; i
< TIC6X_NUM_PREFER
; i
++)
3516 opc_rank
[i
] = (unsigned int) -1;
3518 min_rank
= TIC6X_NUM_PREFER
- 1;
3521 for (i
= 0; i
< num_matching_opcodes
; i
++)
3524 bfd_boolean this_matches
= TRUE
;
3526 if (!(tic6x_opcode_table
[opcm
[i
]].flags
& TIC6X_FLAG_SPMASK
)
3527 && tic6x_opcode_table
[opcm
[i
]].num_operands
!= num_operands_read
)
3530 for (j
= 0; j
< num_operands_read
; j
++)
3532 tic6x_operand_form f
;
3535 if (tic6x_opcode_table
[opcm
[i
]].flags
& TIC6X_FLAG_SPMASK
)
3537 f
= tic6x_operand_func_unit
;
3542 f
= tic6x_opcode_table
[opcm
[i
]].operand_info
[j
].form
;
3543 rw
= tic6x_opcode_table
[opcm
[i
]].operand_info
[j
].rw
;
3545 if (tic6x_operand_matches_form (&operands
[j
], f
, rw
,
3548 func_unit_data_side
)
3549 != tic6x_match_matches
)
3551 this_matches
= FALSE
;
3558 int rank
= TIC6X_PREFER_VAL (tic6x_opcode_table
[opcm
[i
]].flags
);
3560 if (rank
< min_rank
)
3562 if (rank
> max_rank
)
3565 if (opc_rank
[rank
] == (unsigned int) -1)
3568 /* The opcode table should provide a total ordering
3569 for all cases where multiple matches may get
3579 as_bad (_("bad operand combination for '%.*s'"), opc_len
, str
);
3580 bad_operands
= TRUE
;
3592 for (try_rank
= max_rank
; try_rank
>= min_rank
; try_rank
--)
3596 if (opc_rank
[try_rank
] == (unsigned int) -1)
3599 opcode_value
= tic6x_try_encode (opcm
[opc_rank
[try_rank
]], operands
,
3600 num_operands_read
, this_line_creg
,
3601 this_line_z
, func_unit_side
,
3602 func_unit_cross
, func_unit_data_side
,
3603 seginfo
->tc_segment_info_data
.sploop_ii
,
3604 &fix_exp
, &fix_pcrel
, &fx_r_type
,
3605 &fix_adda
, &fix_needed
, &encoded_ok
,
3606 (try_rank
== min_rank
? TRUE
: FALSE
),
3610 opct
= &tic6x_opcode_table
[opcm
[opc_rank
[try_rank
]]];
3620 if (this_line_parallel
)
3622 insn_frag
= seginfo
->tc_segment_info_data
.execute_packet_frag
;
3623 if (insn_frag
== NULL
)
3625 as_bad (_("parallel instruction not following another instruction"));
3629 if (insn_frag
->fr_fix
>= 32)
3631 as_bad (_("too many instructions in execute packet"));
3635 if (this_insn_label_list
!= NULL
)
3636 as_bad (_("label not at start of execute packet"));
3638 if (opct
->flags
& TIC6X_FLAG_FIRST
)
3639 as_bad (_("'%.*s' instruction not at start of execute packet"),
3642 *seginfo
->tc_segment_info_data
.last_insn_lsb
|= 0x1;
3643 output
= insn_frag
->fr_literal
+ insn_frag
->fr_fix
;
3647 tic6x_label_list
*l
;
3649 seginfo
->tc_segment_info_data
.spmask_addr
= NULL
;
3650 seginfo
->tc_segment_info_data
.func_units_used
= 0;
3652 /* Start a new frag for this execute packet. */
3653 if (frag_now_fix () != 0)
3655 if (frag_now
->fr_type
!= rs_machine_dependent
)
3656 frag_wane (frag_now
);
3661 insn_frag
= seginfo
->tc_segment_info_data
.execute_packet_frag
= frag_now
;
3662 for (l
= this_insn_label_list
; l
; l
= l
->next
)
3664 symbol_set_frag (l
->label
, frag_now
);
3665 S_SET_VALUE (l
->label
, 0);
3666 S_SET_SEGMENT (l
->label
, now_seg
);
3668 tic6x_free_label_list (this_insn_label_list
);
3669 dwarf2_emit_insn (0);
3670 output
= frag_var (rs_machine_dependent
, 32, 32, 0, NULL
, 0, NULL
);
3671 /* This must be the same as the frag to which a pointer was just
3673 if (output
!= insn_frag
->fr_literal
)
3675 insn_frag
->tc_frag_data
.is_insns
= TRUE
;
3676 insn_frag
->tc_frag_data
.can_cross_fp_boundary
3677 = tic6x_can_cross_fp_boundary
;
3680 if (func_unit_base
!= tic6x_func_unit_nfu
)
3682 unsigned int func_unit_enc
;
3684 func_unit_enc
= tic6x_encode_spmask (func_unit_base
, func_unit_side
);
3686 if (seginfo
->tc_segment_info_data
.func_units_used
& func_unit_enc
)
3687 as_bad (_("functional unit already used in this execute packet"));
3689 seginfo
->tc_segment_info_data
.func_units_used
|= func_unit_enc
;
3692 if (opct
->flags
& TIC6X_FLAG_SPLOOP
)
3694 if (seginfo
->tc_segment_info_data
.sploop_ii
)
3695 as_bad (_("nested software pipelined loop"));
3696 if (num_operands_read
!= 1
3697 || operands
[0].form
!= TIC6X_OP_EXP
3698 || operands
[0].value
.exp
.X_op
!= O_constant
)
3700 seginfo
->tc_segment_info_data
.sploop_ii
3701 = operands
[0].value
.exp
.X_add_number
;
3703 else if (opct
->flags
& TIC6X_FLAG_SPKERNEL
)
3705 if (!seginfo
->tc_segment_info_data
.sploop_ii
)
3706 as_bad (_("'%.*s' instruction not in a software pipelined loop"),
3708 seginfo
->tc_segment_info_data
.sploop_ii
= 0;
3711 if (this_line_spmask
)
3713 if (seginfo
->tc_segment_info_data
.spmask_addr
== NULL
)
3714 as_bad (_("'||^' without previous SPMASK"));
3715 else if (func_unit_base
== tic6x_func_unit_nfu
)
3716 as_bad (_("cannot mask instruction using no functional unit"));
3719 unsigned int spmask_opcode
;
3720 unsigned int mask_bit
;
3723 = md_chars_to_number (seginfo
->tc_segment_info_data
.spmask_addr
,
3725 mask_bit
= tic6x_encode_spmask (func_unit_base
, func_unit_side
);
3727 if (spmask_opcode
& mask_bit
)
3728 as_bad (_("functional unit already masked"));
3729 spmask_opcode
|= mask_bit
;
3730 md_number_to_chars (seginfo
->tc_segment_info_data
.spmask_addr
,
3735 record_alignment (now_seg
, 5);
3736 md_number_to_chars (output
, opcode_value
, 4);
3738 tic6x_fix_new_exp (insn_frag
, output
- insn_frag
->fr_literal
, 4, fix_exp
,
3739 fix_pcrel
, fx_r_type
, fix_adda
);
3740 insn_frag
->fr_fix
+= 4;
3741 insn_frag
->fr_var
-= 4;
3742 seginfo
->tc_segment_info_data
.last_insn_lsb
3743 = (target_big_endian
? output
+ 3 : output
);
3744 if (opct
->flags
& TIC6X_FLAG_SPMASK
)
3745 seginfo
->tc_segment_info_data
.spmask_addr
= output
;
3748 /* Modify NEWVAL (32-bit) by inserting VALUE, shifted right by SHIFT
3749 and the least significant BITS bits taken, at position POS. */
3750 #define MODIFY_VALUE(NEWVAL, VALUE, SHIFT, POS, BITS) \
3752 (NEWVAL) &= 0xffffffffU & ~(((1U << (BITS)) - 1) << (POS)); \
3753 (NEWVAL) |= (((VALUE) >> (SHIFT)) & ((1U << (BITS)) - 1)) << (POS); \
3756 /* Apply a fixup to the object file. */
3759 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
3761 offsetT value
= *valP
;
3762 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3764 value
= SEXT (value
);
3767 fixP
->fx_offset
= SEXT (fixP
->fx_offset
);
3769 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
3772 /* We do our own overflow checks. */
3773 fixP
->fx_no_overflow
= 1;
3775 switch (fixP
->fx_r_type
)
3777 case BFD_RELOC_NONE
:
3778 case BFD_RELOC_C6000_EHTYPE
:
3779 /* Force output to the object file. */
3784 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3785 md_number_to_chars (buf
, value
, 4);
3789 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3791 if (value
< -0x8000 || value
> 0xffff)
3792 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3793 _("value too large for 2-byte field"));
3794 md_number_to_chars (buf
, value
, 2);
3799 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3801 if (value
< -0x80 || value
> 0xff)
3802 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3803 _("value too large for 1-byte field"));
3804 md_number_to_chars (buf
, value
, 1);
3808 case BFD_RELOC_C6000_ABS_S16
:
3809 case BFD_RELOC_C6000_ABS_L16
:
3810 case BFD_RELOC_C6000_SBR_S16
:
3811 case BFD_RELOC_C6000_SBR_L16_B
:
3812 case BFD_RELOC_C6000_SBR_L16_H
:
3813 case BFD_RELOC_C6000_SBR_L16_W
:
3814 case BFD_RELOC_C6000_SBR_GOT_L16_W
:
3815 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3817 offsetT newval
= md_chars_to_number (buf
, 4);
3820 switch (fixP
->fx_r_type
)
3822 case BFD_RELOC_C6000_SBR_L16_H
:
3826 case BFD_RELOC_C6000_SBR_L16_W
:
3827 case BFD_RELOC_C6000_SBR_GOT_L16_W
:
3836 MODIFY_VALUE (newval
, value
, shift
, 7, 16);
3837 if ((value
< -0x8000 || value
> 0x7fff)
3838 && (fixP
->fx_r_type
== BFD_RELOC_C6000_ABS_S16
3839 || fixP
->fx_r_type
== BFD_RELOC_C6000_SBR_S16
))
3840 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3841 _("immediate offset out of range"));
3843 md_number_to_chars (buf
, newval
, 4);
3846 && fixP
->fx_r_type
!= BFD_RELOC_C6000_ABS_S16
3847 && fixP
->fx_r_type
!= BFD_RELOC_C6000_ABS_L16
)
3851 case BFD_RELOC_C6000_ABS_H16
:
3852 case BFD_RELOC_C6000_SBR_H16_B
:
3853 case BFD_RELOC_C6000_SBR_H16_H
:
3854 case BFD_RELOC_C6000_SBR_H16_W
:
3855 case BFD_RELOC_C6000_SBR_GOT_H16_W
:
3856 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3858 offsetT newval
= md_chars_to_number (buf
, 4);
3861 switch (fixP
->fx_r_type
)
3863 case BFD_RELOC_C6000_SBR_H16_H
:
3867 case BFD_RELOC_C6000_SBR_H16_W
:
3868 case BFD_RELOC_C6000_SBR_GOT_H16_W
:
3877 MODIFY_VALUE (newval
, value
, shift
, 7, 16);
3879 md_number_to_chars (buf
, newval
, 4);
3881 if (fixP
->fx_done
&& fixP
->fx_r_type
!= BFD_RELOC_C6000_ABS_H16
)
3885 case BFD_RELOC_C6000_PCR_H16
:
3886 case BFD_RELOC_C6000_PCR_L16
:
3887 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3889 offsetT newval
= md_chars_to_number (buf
, 4);
3890 int shift
= fixP
->fx_r_type
== BFD_RELOC_C6000_PCR_H16
? 16 : 0;
3892 MODIFY_VALUE (newval
, value
, shift
, 7, 16);
3894 md_number_to_chars (buf
, newval
, 4);
3898 case BFD_RELOC_C6000_SBR_U15_B
:
3899 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3901 offsetT newval
= md_chars_to_number (buf
, 4);
3903 MODIFY_VALUE (newval
, value
, 0, 8, 15);
3904 if (value
< 0 || value
> 0x7fff)
3905 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3906 _("immediate offset out of range"));
3908 md_number_to_chars (buf
, newval
, 4);
3912 case BFD_RELOC_C6000_SBR_U15_H
:
3913 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3915 offsetT newval
= md_chars_to_number (buf
, 4);
3917 /* Constant ADDA operands, processed as constant when the
3918 instruction is parsed, are encoded as-is rather than
3919 shifted. If the operand of an ADDA instruction is now
3920 constant (for example, the difference between two labels
3921 found after the instruction), ensure it is encoded the
3922 same way it would have been if the constant value had
3923 been known when the instruction was parsed. */
3924 if (fixP
->tc_fix_data
.fix_adda
&& fixP
->fx_done
)
3927 MODIFY_VALUE (newval
, value
, 1, 8, 15);
3929 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3930 _("immediate offset not 2-byte-aligned"));
3931 if (value
< 0 || value
> 0xfffe)
3932 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3933 _("immediate offset out of range"));
3935 md_number_to_chars (buf
, newval
, 4);
3939 case BFD_RELOC_C6000_SBR_U15_W
:
3940 case BFD_RELOC_C6000_SBR_GOT_U15_W
:
3941 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3943 offsetT newval
= md_chars_to_number (buf
, 4);
3945 /* Constant ADDA operands, processed as constant when the
3946 instruction is parsed, are encoded as-is rather than
3947 shifted. If the operand of an ADDA instruction is now
3948 constant (for example, the difference between two labels
3949 found after the instruction), ensure it is encoded the
3950 same way it would have been if the constant value had
3951 been known when the instruction was parsed. */
3952 if (fixP
->tc_fix_data
.fix_adda
&& fixP
->fx_done
)
3955 MODIFY_VALUE (newval
, value
, 2, 8, 15);
3957 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3958 _("immediate offset not 4-byte-aligned"));
3959 if (value
< 0 || value
> 0x1fffc)
3960 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3961 _("immediate offset out of range"));
3963 md_number_to_chars (buf
, newval
, 4);
3965 if (fixP
->fx_done
&& fixP
->fx_r_type
!= BFD_RELOC_C6000_SBR_U15_W
)
3969 case BFD_RELOC_C6000_DSBT_INDEX
:
3971 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3972 _("addend used with $DSBT_INDEX"));
3977 case BFD_RELOC_C6000_PCR_S21
:
3978 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3980 offsetT newval
= md_chars_to_number (buf
, 4);
3982 MODIFY_VALUE (newval
, value
, 2, 7, 21);
3985 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3986 _("PC-relative offset not 4-byte-aligned"));
3987 if (value
< -0x400000 || value
> 0x3ffffc)
3988 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3989 _("PC-relative offset out of range"));
3991 md_number_to_chars (buf
, newval
, 4);
3995 case BFD_RELOC_C6000_PCR_S12
:
3996 if (fixP
->fx_done
|| !seg
->use_rela_p
)
3998 offsetT newval
= md_chars_to_number (buf
, 4);
4000 MODIFY_VALUE (newval
, value
, 2, 16, 12);
4003 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4004 _("PC-relative offset not 4-byte-aligned"));
4005 if (value
< -0x2000 || value
> 0x1ffc)
4006 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4007 _("PC-relative offset out of range"));
4009 md_number_to_chars (buf
, newval
, 4);
4013 case BFD_RELOC_C6000_PCR_S10
:
4014 if (fixP
->fx_done
|| !seg
->use_rela_p
)
4016 offsetT newval
= md_chars_to_number (buf
, 4);
4018 MODIFY_VALUE (newval
, value
, 2, 13, 10);
4021 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4022 _("PC-relative offset not 4-byte-aligned"));
4023 if (value
< -0x800 || value
> 0x7fc)
4024 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4025 _("PC-relative offset out of range"));
4027 md_number_to_chars (buf
, newval
, 4);
4031 case BFD_RELOC_C6000_PCR_S7
:
4032 if (fixP
->fx_done
|| !seg
->use_rela_p
)
4034 offsetT newval
= md_chars_to_number (buf
, 4);
4036 MODIFY_VALUE (newval
, value
, 2, 16, 7);
4039 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4040 _("PC-relative offset not 4-byte-aligned"));
4041 if (value
< -0x100 || value
> 0xfc)
4042 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4043 _("PC-relative offset out of range"));
4045 md_number_to_chars (buf
, newval
, 4);
4049 case BFD_RELOC_C6000_PREL31
:
4050 /* Force output to the object file. */
4059 /* Convert a floating-point number to target (IEEE) format. */
4062 md_atof (int type
, char *litP
, int *sizeP
)
4064 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
4067 /* Adjust the frags in SECTION (see tic6x_end). */
4070 tic6x_adjust_section (bfd
*abfd ATTRIBUTE_UNUSED
, segT section
,
4071 void *dummy ATTRIBUTE_UNUSED
)
4073 segment_info_type
*info
;
4076 bfd_boolean have_code
= FALSE
;
4077 bfd_boolean have_non_code
= FALSE
;
4079 info
= seg_info (section
);
4083 for (frchp
= info
->frchainP
; frchp
; frchp
= frchp
->frch_next
)
4084 for (fragp
= frchp
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
4085 switch (fragp
->fr_type
)
4087 case rs_machine_dependent
:
4088 if (fragp
->tc_frag_data
.is_insns
)
4094 if (fragp
->fr_fix
> 0)
4095 have_non_code
= TRUE
;
4099 have_non_code
= TRUE
;
4103 /* Process alignment requirements in a code-only section. */
4104 if (have_code
&& !have_non_code
)
4106 /* If we need to insert an odd number of instructions to meet an
4107 alignment requirement, there must have been an odd number of
4108 instructions since the last 8-byte-aligned execute packet
4109 boundary. So there must have been an execute packet with an
4110 odd number (and so a number fewer than 8) of instructions
4111 into which we can insert a NOP without breaking any previous
4114 If then we need to insert a number 2 mod 4 of instructions,
4115 the number of instructions since the last 16-byte-aligned
4116 execute packet boundary must be 2 mod 4. So between that
4117 boundary and the following 8-byte-aligned boundary there must
4118 either be at least one execute packet with 2-mod-4
4119 instructions, or at least two with an odd number of
4120 instructions; again, greedily inserting NOPs as soon as
4121 possible suffices to meet the alignment requirement.
4123 If then we need to insert 4 instructions, we look between the
4124 last 32-byte-aligned boundary and the following
4125 16-byte-aligned boundary. The sizes of the execute packets
4126 in this range total 4 instructions mod 8, so again there is
4127 room for greedy insertion of NOPs to meet the alignment
4128 requirement, and before any intermediate point with 8-byte
4129 (2-instruction) alignment requirement the sizes of execute
4130 packets (and so the room for NOPs) will total 2 instructions
4131 mod 4 so greedy insertion will not break such alignments.
4133 So we can always meet these alignment requirements by
4134 inserting NOPs in parallel with existing execute packets, and
4135 by induction the approach described above inserts the minimum
4136 number of such NOPs. */
4138 /* The number of NOPs we are currently looking to insert, if we
4139 have gone back to insert NOPs. */
4140 unsigned int want_insert
= 0;
4142 /* Out of that number, the number inserted so far in the current
4143 stage of the above algorithm. */
4144 unsigned int want_insert_done_so_far
= 0;
4146 /* The position mod 32 at the start of the current frag. */
4147 unsigned int pos
= 0;
4149 /* The locations in the frag chain of the most recent frags at
4150 the start of which there is the given alignment. */
4151 frchainS
*frchp_last32
, *frchp_last16
, *frchp_last8
;
4152 fragS
*fragp_last32
, *fragp_last16
, *fragp_last8
;
4153 unsigned int pos_last32
, pos_last16
, pos_last8
;
4155 frchp_last32
= frchp_last16
= frchp_last8
= info
->frchainP
;
4156 fragp_last32
= fragp_last16
= fragp_last8
= info
->frchainP
->frch_root
;
4157 pos_last32
= pos_last16
= pos_last8
= 0;
4159 for (frchp
= info
->frchainP
; frchp
; frchp
= frchp
->frch_next
)
4160 for (fragp
= frchp
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
4163 bfd_boolean go_back
= FALSE
;
4164 frchainS
*frchp_next
;
4167 if (fragp
->fr_type
!= rs_machine_dependent
)
4170 if (fragp
->tc_frag_data
.is_insns
4171 && pos
+ fragp
->fr_fix
> 32
4172 && !fragp
->tc_frag_data
.can_cross_fp_boundary
)
4174 /* As described above, we should always have met an
4175 alignment requirement by the time we come back to
4182 want_insert
= (32 - pos
) >> 2;
4183 if (want_insert
> 7)
4185 want_insert_done_so_far
= 0;
4189 if (!fragp
->tc_frag_data
.is_insns
)
4191 unsigned int would_insert_bytes
;
4193 if (!(pos
& ((1 << fragp
->fr_offset
) - 1)))
4194 /* This alignment requirement is already met. */
4197 /* As described above, we should always have met an
4198 alignment requirement by the time we come back to
4203 /* We may not be able to meet this requirement within
4204 the given number of characters. */
4206 = ((1 << fragp
->fr_offset
)
4207 - (pos
& ((1 << fragp
->fr_offset
) - 1)));
4209 if (fragp
->fr_subtype
!= 0
4210 && would_insert_bytes
> fragp
->fr_subtype
)
4213 /* An unmet alignment must be 8, 16 or 32 bytes;
4214 smaller ones must always be met within code-only
4215 sections and larger ones cause the section not to
4217 if (fragp
->fr_offset
!= 3
4218 && fragp
->fr_offset
!= 4
4219 && fragp
->fr_offset
!= 5)
4222 if (would_insert_bytes
& 3)
4224 want_insert
= would_insert_bytes
>> 2;
4225 if (want_insert
> 7)
4227 want_insert_done_so_far
= 0;
4230 else if (want_insert
&& !go_back
)
4232 unsigned int num_insns
= fragp
->fr_fix
>> 2;
4233 unsigned int max_poss_nops
= 8 - num_insns
;
4237 unsigned int cur_want_nops
, max_want_nops
, do_nops
, i
;
4239 if (want_insert
& 1)
4241 else if (want_insert
& 2)
4243 else if (want_insert
& 4)
4248 max_want_nops
= cur_want_nops
- want_insert_done_so_far
;
4250 do_nops
= (max_poss_nops
< max_want_nops
4253 for (i
= 0; i
< do_nops
; i
++)
4255 md_number_to_chars (fragp
->fr_literal
+ fragp
->fr_fix
,
4257 if (target_big_endian
)
4258 fragp
->fr_literal
[fragp
->fr_fix
- 1] |= 0x1;
4260 fragp
->fr_literal
[fragp
->fr_fix
- 4] |= 0x1;
4264 want_insert_done_so_far
+= do_nops
;
4265 if (want_insert_done_so_far
== cur_want_nops
)
4267 want_insert
-= want_insert_done_so_far
;
4268 want_insert_done_so_far
= 0;
4276 if (want_insert
& 1)
4278 frchp
= frchp_last8
;
4279 fragp
= fragp_last8
;
4282 else if (want_insert
& 2)
4284 frchp
= frchp_last8
= frchp_last16
;
4285 fragp
= fragp_last8
= fragp_last16
;
4286 pos
= pos_last8
= pos_last16
;
4288 else if (want_insert
& 4)
4290 frchp
= frchp_last8
= frchp_last16
= frchp_last32
;
4291 fragp
= fragp_last8
= fragp_last16
= fragp_last32
;
4292 pos
= pos_last8
= pos_last16
= pos_last32
;
4300 /* Update current position for moving past a code
4302 pos
+= fragp
->fr_fix
;
4305 fragp_next
= fragp
->fr_next
;
4306 if (fragp_next
== NULL
)
4308 frchp_next
= frchp
->frch_next
;
4309 if (frchp_next
!= NULL
)
4310 fragp_next
= frchp_next
->frch_root
;
4314 frchp_last8
= frchp_next
;
4315 fragp_last8
= fragp_next
;
4320 frchp_last16
= frchp_next
;
4321 fragp_last16
= fragp_next
;
4326 frchp_last32
= frchp_next
;
4327 fragp_last32
= fragp_next
;
4333 /* Now convert the machine-dependent frags to machine-independent
4335 for (frchp
= info
->frchainP
; frchp
; frchp
= frchp
->frch_next
)
4336 for (fragp
= frchp
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
4338 if (fragp
->fr_type
== rs_machine_dependent
)
4340 if (fragp
->tc_frag_data
.is_insns
)
4344 fragp
->fr_type
= rs_align_code
;
4346 *fragp
->fr_literal
= 0;
4352 /* Initialize the machine-dependent parts of a frag. */
4355 tic6x_frag_init (fragS
*fragp
)
4357 fragp
->tc_frag_data
.is_insns
= FALSE
;
4358 fragp
->tc_frag_data
.can_cross_fp_boundary
= FALSE
;
4361 /* Set an attribute if it has not already been set by the user. */
4364 tic6x_set_attribute_int (int tag
, int value
)
4367 || tag
>= NUM_KNOWN_OBJ_ATTRIBUTES
)
4369 if (!tic6x_attributes_set_explicitly
[tag
])
4370 bfd_elf_add_proc_attr_int (stdoutput
, tag
, value
);
4373 /* Set object attributes deduced from the input file and command line
4374 rather than given explicitly. */
4376 tic6x_set_attributes (void)
4378 if (tic6x_arch_attribute
== C6XABI_Tag_ISA_none
)
4379 tic6x_arch_attribute
= C6XABI_Tag_ISA_C674X
;
4381 tic6x_set_attribute_int (Tag_ISA
, tic6x_arch_attribute
);
4382 tic6x_set_attribute_int (Tag_ABI_DSBT
, tic6x_dsbt
);
4383 tic6x_set_attribute_int (Tag_ABI_PID
, tic6x_pid
);
4384 tic6x_set_attribute_int (Tag_ABI_PIC
, tic6x_pic
);
4387 /* Do machine-dependent manipulations of the frag chains after all
4388 input has been read and before the machine-independent sizing and
4394 /* Set object attributes at this point if not explicitly set. */
4395 tic6x_set_attributes ();
4397 /* Meeting alignment requirements may require inserting NOPs in
4398 parallel in execute packets earlier in the segment. Future
4399 16-bit instruction generation involves whole-segment optimization
4400 to determine the best choice and ordering of 32-bit or 16-bit
4401 instructions. This doesn't fit will in the general relaxation
4402 framework, so handle alignment and 16-bit instruction generation
4404 bfd_map_over_sections (stdoutput
, tic6x_adjust_section
, NULL
);
4407 /* No machine-dependent frags at this stage; all converted in
4411 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec ATTRIBUTE_UNUSED
,
4412 fragS
*fragp ATTRIBUTE_UNUSED
)
4417 /* No machine-dependent frags at this stage; all converted in
4421 md_estimate_size_before_relax (fragS
*fragp ATTRIBUTE_UNUSED
,
4422 segT seg ATTRIBUTE_UNUSED
)
4427 /* Put a number into target byte order. */
4430 md_number_to_chars (char *buf
, valueT val
, int n
)
4432 if (target_big_endian
)
4433 number_to_chars_bigendian (buf
, val
, n
);
4435 number_to_chars_littleendian (buf
, val
, n
);
4438 /* Machine-dependent operand parsing not currently needed. */
4441 md_operand (expressionS
*op ATTRIBUTE_UNUSED
)
4445 /* PC-relative operands are relative to the start of the fetch
4449 tic6x_pcrel_from_section (fixS
*fixp
, segT sec
)
4451 if (fixp
->fx_addsy
!= NULL
4452 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4453 || S_GET_SEGMENT (fixp
->fx_addsy
) != sec
))
4455 return (fixp
->fx_where
+ fixp
->fx_frag
->fr_address
) & ~(long) 0x1f;
4458 /* Round up a section size to the appropriate boundary. */
4461 md_section_align (segT segment ATTRIBUTE_UNUSED
,
4464 /* Round up section sizes to ensure that text sections consist of
4465 whole fetch packets. */
4466 int align
= bfd_get_section_alignment (stdoutput
, segment
);
4467 return ((size
+ (1 << align
) - 1) & ((valueT
) -1 << align
));
4470 /* No special undefined symbol handling needed for now. */
4473 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
4478 /* Translate internal representation of relocation info to BFD target
4482 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
4486 bfd_reloc_code_real_type r_type
;
4488 reloc
= xmalloc (sizeof (arelent
));
4489 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4490 symbol
= symbol_get_bfdsym (fixp
->fx_addsy
);
4491 *reloc
->sym_ptr_ptr
= symbol
;
4492 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4493 reloc
->addend
= (tic6x_generate_rela
? fixp
->fx_offset
: 0);
4494 r_type
= fixp
->fx_r_type
;
4495 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, r_type
);
4497 if (reloc
->howto
== NULL
)
4499 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4500 _("Cannot represent relocation type %s"),
4501 bfd_get_reloc_code_name (r_type
));
4505 /* Correct for adjustments bfd_install_relocation will make. */
4506 if (reloc
->howto
->pcrel_offset
&& reloc
->howto
->partial_inplace
)
4508 reloc
->addend
+= reloc
->address
;
4509 if (!bfd_is_com_section (symbol
))
4510 reloc
->addend
-= symbol
->value
;
4512 if (r_type
== BFD_RELOC_C6000_PCR_H16
4513 || r_type
== BFD_RELOC_C6000_PCR_L16
)
4515 symbolS
*t
= fixp
->tc_fix_data
.fix_subsy
;
4516 segT sub_symbol_segment
;
4518 resolve_symbol_value (t
);
4519 sub_symbol_segment
= S_GET_SEGMENT (t
);
4520 if (sub_symbol_segment
== undefined_section
)
4521 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4522 _("undefined symbol %s in PCR relocation"),
4526 reloc
->addend
= reloc
->address
& ~0x1F;
4527 reloc
->addend
-= S_GET_VALUE (t
);
4533 /* Convert REGNAME to a DWARF-2 register number. */
4536 tic6x_regname_to_dw2regnum (char *regname
)
4542 reg_ok
= tic6x_parse_register (&rq
, ®
);
4549 case 1: /* A regs. */
4552 else if (reg
.num
< 32)
4553 return (reg
.num
- 16) + 37;
4557 case 2: /* B regs. */
4559 return reg
.num
+ 16;
4560 else if (reg
.num
< 32)
4561 return (reg
.num
- 16) + 53;
4570 /* Initialize the DWARF-2 unwind information for this procedure. */
4573 tic6x_frame_initial_instructions (void)
4575 /* CFA is initial stack pointer (B15). */
4576 cfi_add_CFA_def_cfa (31, 0);
4579 /* Start an exception table entry. If idx is nonzero this is an index table
4583 tic6x_start_unwind_section (const segT text_seg
, int idx
)
4585 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4586 const char * text_name
;
4587 const char * prefix
;
4588 const char * prefix_once
;
4589 const char * group_name
;
4593 size_t sec_name_len
;
4600 prefix
= ELF_STRING_C6000_unwind
;
4601 prefix_once
= ELF_STRING_C6000_unwind_once
;
4602 type
= SHT_C6000_UNWIND
;
4606 prefix
= ELF_STRING_C6000_unwind_info
;
4607 prefix_once
= ELF_STRING_C6000_unwind_info_once
;
4608 type
= SHT_PROGBITS
;
4611 text_name
= segment_name (text_seg
);
4612 if (streq (text_name
, ".text"))
4615 if (strncmp (text_name
, ".gnu.linkonce.t.",
4616 strlen (".gnu.linkonce.t.")) == 0)
4618 prefix
= prefix_once
;
4619 text_name
+= strlen (".gnu.linkonce.t.");
4622 prefix_len
= strlen (prefix
);
4623 text_len
= strlen (text_name
);
4624 sec_name_len
= prefix_len
+ text_len
;
4625 sec_name
= (char *) xmalloc (sec_name_len
+ 1);
4626 memcpy (sec_name
, prefix
, prefix_len
);
4627 memcpy (sec_name
+ prefix_len
, text_name
, text_len
);
4628 sec_name
[prefix_len
+ text_len
] = '\0';
4634 /* Handle COMDAT group. */
4635 if (prefix
!= prefix_once
&& (text_seg
->flags
& SEC_LINK_ONCE
) != 0)
4637 group_name
= elf_group_name (text_seg
);
4638 if (group_name
== NULL
)
4640 as_bad (_("group section `%s' has no group signature"),
4641 segment_name (text_seg
));
4642 ignore_rest_of_line ();
4649 obj_elf_change_section (sec_name
, type
, flags
, 0, group_name
, linkonce
, 0);
4651 /* Set the section link for index tables. */
4653 elf_linked_to_section (now_seg
) = text_seg
;
4655 seg_info (now_seg
)->tc_segment_info_data
.text_unwind
= unwind
;
4660 tic6x_unwind_frame_regs
[TIC6X_NUM_UNWIND_REGS
] =
4661 /* A15 B15 B14 B13 B12 B11 B10 B3 A14 A13 A12 A11 A10. */
4662 { 15, 31, 30, 29, 28, 27, 26, 19, 14, 13, 12, 11, 10 };
4664 /* Register save offsets for __c6xabi_push_rts. */
4666 tic6x_pop_rts_offset_little
[TIC6X_NUM_UNWIND_REGS
] =
4667 /* A15 B15 B14 B13 B12 B11 B10 B3 A14 A13 A12 A11 A10. */
4668 { -1, 1, 0, -3, -4, -7, -8,-11, -2, -5, -6, -9,-10};
4671 tic6x_pop_rts_offset_big
[TIC6X_NUM_UNWIND_REGS
] =
4672 /* A15 B15 B14 B13 B12 B11 B10 B3 A14 A13 A12 A11 A10. */
4673 { -2, 1, 0, -4, -3, -8, -7,-12, -1, -6, -5,-10, -9};
4675 /* Map from dwarf register number to unwind frame register number. */
4677 tic6x_unwind_reg_from_dwarf (int dwarf
)
4681 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
4683 if (tic6x_unwind_frame_regs
[reg
] == dwarf
)
4690 /* Unwinding bytecode definitions. */
4691 #define UNWIND_OP_ADD_SP 0x00
4692 #define UNWIND_OP_ADD_SP2 0xd2
4693 #define UNWIND_OP2_POP 0x8000
4694 #define UNWIND_OP2_POP_COMPACT 0xa000
4695 #define UNWIND_OP_POP_REG 0xc0
4696 #define UNWIND_OP_MV_FP 0xd0
4697 #define UNWIND_OP_POP_RTS 0xd1
4698 #define UNWIND_OP_RET 0xe0
4700 /* Maximum stack adjustment for __c6xabi_unwind_cpp_pr3/4 */
4701 #define MAX_COMPACT_SP_OFFSET (0x7f << 3)
4704 tic6x_flush_unwind_word (valueT data
)
4706 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4709 /* Create EXTAB entry if it does not exist. */
4710 if (unwind
->table_entry
== NULL
)
4712 tic6x_start_unwind_section (unwind
->saved_seg
, 0);
4713 frag_align (2, 0, 0);
4714 record_alignment (now_seg
, 2);
4715 unwind
->table_entry
= expr_build_dot ();
4716 ptr
= frag_more (4);
4717 unwind
->frag_start
= ptr
;
4721 /* Append additional word of data. */
4722 ptr
= frag_more (4);
4725 md_number_to_chars (ptr
, data
, 4);
4728 /* Add a single byte of unwinding data. */
4731 tic6x_unwind_byte (int byte
)
4733 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4735 unwind
->data_bytes
++;
4736 /* Only flush the first word after we know multiple words are required. */
4737 if (unwind
->data_bytes
== 5)
4739 if (unwind
->personality_index
== -1)
4741 /* At this point we know we are too big for pr0. */
4742 unwind
->personality_index
= 1;
4743 tic6x_flush_unwind_word (0x81000000 | ((unwind
->data
>> 8) & 0xffff));
4744 unwind
->data
= ((unwind
->data
& 0xff) << 8) | byte
;
4745 unwind
->data_bytes
++;
4749 tic6x_flush_unwind_word (unwind
->data
);
4750 unwind
->data
= byte
;
4755 unwind
->data
= (unwind
->data
<< 8) | byte
;
4756 if ((unwind
->data_bytes
& 3) == 0 && unwind
->data_bytes
> 4)
4758 tic6x_flush_unwind_word (unwind
->data
);
4764 /* Add a two-byte unwinding opcode. */
4766 tic6x_unwind_2byte (int bytes
)
4768 tic6x_unwind_byte (bytes
>> 8);
4769 tic6x_unwind_byte (bytes
& 0xff);
4773 tic6x_unwind_uleb (offsetT offset
)
4775 while (offset
> 0x7f)
4777 tic6x_unwind_byte ((offset
& 0x7f) | 0x80);
4780 tic6x_unwind_byte (offset
);
4784 tic6x_cfi_startproc (void)
4786 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4788 unwind
->personality_index
= -1;
4789 unwind
->personality_routine
= NULL
;
4790 if (unwind
->table_entry
)
4791 as_bad (_("missing .endp before .cfi_startproc"));
4793 unwind
->table_entry
= NULL
;
4794 unwind
->data_bytes
= -1;
4798 tic6x_output_exidx_entry (void)
4802 unsigned int marked_pr_dependency
;
4805 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4808 old_subseg
= now_subseg
;
4810 /* Add index table entry. This is two words. */
4811 tic6x_start_unwind_section (unwind
->saved_seg
, 1);
4812 frag_align (2, 0, 0);
4813 record_alignment (now_seg
, 2);
4815 ptr
= frag_more (8);
4816 where
= frag_now_fix () - 8;
4818 /* Self relative offset of the function start. */
4819 fix_new (frag_now
, where
, 4, unwind
->function_start
, 0, 1,
4820 BFD_RELOC_C6000_PREL31
);
4822 /* Indicate dependency on ABI-defined personality routines to the
4823 linker, if it hasn't been done already. */
4824 marked_pr_dependency
4825 = seg_info (now_seg
)->tc_segment_info_data
.marked_pr_dependency
;
4826 if (unwind
->personality_index
>= 0 && unwind
->personality_index
< 5
4827 && !(marked_pr_dependency
& (1 << unwind
->personality_index
)))
4829 static const char *const name
[] =
4831 "__c6xabi_unwind_cpp_pr0",
4832 "__c6xabi_unwind_cpp_pr1",
4833 "__c6xabi_unwind_cpp_pr2",
4834 "__c6xabi_unwind_cpp_pr3",
4835 "__c6xabi_unwind_cpp_pr4"
4837 symbolS
*pr
= symbol_find_or_make (name
[unwind
->personality_index
]);
4838 fix_new (frag_now
, where
, 0, pr
, 0, 1, BFD_RELOC_NONE
);
4839 seg_info (now_seg
)->tc_segment_info_data
.marked_pr_dependency
4840 |= 1 << unwind
->personality_index
;
4843 if (unwind
->table_entry
)
4845 /* Self relative offset of the table entry. */
4846 fix_new (frag_now
, where
+ 4, 4, unwind
->table_entry
, 0, 1,
4847 BFD_RELOC_C6000_PREL31
);
4851 /* Inline exception table entry. */
4852 md_number_to_chars (ptr
+ 4, unwind
->data
, 4);
4855 /* Restore the original section. */
4856 subseg_set (old_seg
, old_subseg
);
4860 tic6x_output_unwinding (bfd_boolean need_extab
)
4862 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
4863 unsigned safe_mask
= unwind
->safe_mask
;
4864 unsigned compact_mask
= unwind
->compact_mask
;
4865 unsigned reg_saved_mask
= unwind
->reg_saved_mask
;
4866 offsetT cfa_offset
= unwind
->cfa_offset
;
4870 if (unwind
->personality_index
== -2)
4872 /* Function can not be unwound. */
4874 tic6x_output_exidx_entry ();
4878 if (unwind
->personality_index
== -1 && unwind
->personality_routine
== NULL
)
4880 /* Auto-select a personality routine if none specified. */
4881 if (reg_saved_mask
|| cfa_offset
>= MAX_COMPACT_SP_OFFSET
)
4882 unwind
->personality_index
= -1;
4884 unwind
->personality_index
= 3;
4886 unwind
->personality_index
= 4;
4889 /* Calculate unwinding opcodes, and emit to EXTAB if necessary. */
4890 unwind
->table_entry
= NULL
;
4891 if (unwind
->personality_index
== 3 || unwind
->personality_index
== 4)
4893 if (cfa_offset
>= MAX_COMPACT_SP_OFFSET
)
4895 as_bad (_("stack pointer offset too large for personality routine"));
4899 || (unwind
->personality_index
== 3 && compact_mask
!= 0)
4900 || (unwind
->personality_index
== 4 && safe_mask
!= 0))
4902 as_bad (_("stack frame layout does not match personality routine"));
4906 unwind
->data
= (1u << 31) | (unwind
->personality_index
<< 24);
4907 if (unwind
->cfa_reg
== 15)
4908 unwind
->data
|= 0x7f << 17;
4910 unwind
->data
|= cfa_offset
<< (17 - 3);
4912 if (unwind
->personality_index
== 3)
4913 unwind
->data
|= safe_mask
<< 4;
4915 unwind
->data
|= compact_mask
<< 4;
4916 unwind
->data
|= unwind
->return_reg
;
4917 unwind
->data_bytes
= 4;
4921 if (unwind
->personality_routine
)
4924 unwind
->data_bytes
= 5;
4925 tic6x_flush_unwind_word (0);
4926 /* First word is personality routine. */
4927 where
= frag_now_fix () - 4;
4928 fix_new (frag_now
, where
, 4, unwind
->personality_routine
, 0, 1,
4929 BFD_RELOC_C6000_PREL31
);
4931 else if (unwind
->personality_index
> 0)
4933 unwind
->data
= 0x8000 | (unwind
->personality_index
<< 8);
4934 unwind
->data_bytes
= 2;
4936 else /* pr0 or undecided */
4938 unwind
->data
= 0x80;
4939 unwind
->data_bytes
= 1;
4942 if (unwind
->return_reg
!= UNWIND_B3
)
4944 tic6x_unwind_byte (UNWIND_OP_RET
| unwind
->return_reg
);
4947 if (unwind
->cfa_reg
== 15)
4949 tic6x_unwind_byte (UNWIND_OP_MV_FP
);
4951 else if (cfa_offset
!= 0)
4954 if (cfa_offset
> 0x80)
4956 tic6x_unwind_byte (UNWIND_OP_ADD_SP2
);
4957 tic6x_unwind_uleb (cfa_offset
- 0x81);
4959 else if (cfa_offset
> 0x40)
4961 tic6x_unwind_byte (UNWIND_OP_ADD_SP
| 0x3f);
4962 tic6x_unwind_byte (UNWIND_OP_ADD_SP
| (cfa_offset
- 0x40));
4966 tic6x_unwind_byte (UNWIND_OP_ADD_SP
| (cfa_offset
- 1));
4971 tic6x_unwind_2byte (UNWIND_OP2_POP
| unwind
->safe_mask
);
4972 else if (unwind
->pop_rts
)
4973 tic6x_unwind_byte (UNWIND_OP_POP_RTS
);
4974 else if (compact_mask
)
4975 tic6x_unwind_2byte (UNWIND_OP2_POP_COMPACT
| unwind
->compact_mask
);
4976 else if (reg_saved_mask
)
4982 tic6x_unwind_byte (UNWIND_OP_POP_REG
| unwind
->saved_reg_count
);
4984 for (cur_offset
= 0; unwind
->saved_reg_count
> 0; cur_offset
-= 4)
4987 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
4989 if (!unwind
->reg_saved
[reg
])
4992 if (unwind
->reg_offset
[reg
] == cur_offset
)
4994 unwind
->saved_reg_count
--;
4999 if ((cur_offset
& 4) == 4)
5000 tic6x_unwind_byte ((last_val
<< 4) | val
);
5004 if ((cur_offset
& 4) == 4)
5005 tic6x_unwind_byte ((last_val
<< 4) | 0xf);
5008 /* Pad with RETURN opcodes. */
5009 while ((unwind
->data_bytes
& 3) != 0)
5010 tic6x_unwind_byte (UNWIND_OP_RET
| UNWIND_B3
);
5012 if (unwind
->personality_index
== -1 && unwind
->personality_routine
== NULL
)
5013 unwind
->personality_index
= 0;
5016 /* Force creation of an EXTAB entry if an LSDA is required. */
5017 if (need_extab
&& !unwind
->table_entry
)
5019 if (unwind
->data_bytes
!= 4)
5022 tic6x_flush_unwind_word (unwind
->data
);
5024 else if (unwind
->table_entry
&& !need_extab
)
5026 /* Add an empty descriptor if there is no user-specified data. */
5027 char *ptr
= frag_more (4);
5028 md_number_to_chars (ptr
, 0, 4);
5031 /* Fill in length of unwinding bytecode. */
5032 if (unwind
->table_entry
)
5035 if (unwind
->data_bytes
> 0x400)
5036 as_bad (_("too many unwinding instructions"));
5038 if (unwind
->personality_index
== -1)
5040 tmp
= md_chars_to_number (unwind
->frag_start
+ 4, 4);
5041 tmp
|= ((unwind
->data_bytes
- 8) >> 2) << 24;
5042 md_number_to_chars (unwind
->frag_start
+ 4, tmp
, 4);
5044 else if (unwind
->personality_index
== 1 || unwind
->personality_index
== 2)
5046 tmp
= md_chars_to_number (unwind
->frag_start
, 4);
5047 tmp
|= ((unwind
->data_bytes
- 4) >> 2) << 16;
5048 md_number_to_chars (unwind
->frag_start
, tmp
, 4);
5051 tic6x_output_exidx_entry ();
5054 /* FIXME: This will get horribly confused if cfi directives are emitted for
5055 function epilogue. */
5057 tic6x_cfi_endproc (struct fde_entry
*fde
)
5059 tic6x_unwind_info
*unwind
= tic6x_get_unwind ();
5060 struct cfi_insn_data
*insn
;
5062 unsigned safe_mask
= 0;
5063 unsigned compact_mask
= 0;
5064 unsigned reg_saved_mask
= 0;
5065 offsetT cfa_offset
= 0;
5066 offsetT save_offset
= 0;
5068 unwind
->cfa_reg
= 31;
5069 unwind
->return_reg
= UNWIND_B3
;
5070 unwind
->saved_reg_count
= 0;
5071 unwind
->pop_rts
= FALSE
;
5073 unwind
->saved_seg
= now_seg
;
5074 unwind
->saved_subseg
= now_subseg
;
5076 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5077 unwind
->reg_saved
[reg
] = FALSE
;
5079 /* Scan FDE instructions to build up stack frame layout. */
5080 for (insn
= fde
->data
; insn
; insn
= insn
->next
)
5084 case DW_CFA_advance_loc
:
5087 case DW_CFA_def_cfa
:
5088 unwind
->cfa_reg
= insn
->u
.ri
.reg
;
5089 cfa_offset
= insn
->u
.ri
.offset
;
5092 case DW_CFA_def_cfa_register
:
5093 unwind
->cfa_reg
= insn
->u
.r
;
5096 case DW_CFA_def_cfa_offset
:
5097 cfa_offset
= insn
->u
.i
;
5100 case DW_CFA_undefined
:
5101 case DW_CFA_same_value
:
5102 reg
= tic6x_unwind_reg_from_dwarf (insn
->u
.r
);
5104 unwind
->reg_saved
[reg
] = FALSE
;
5108 reg
= tic6x_unwind_reg_from_dwarf (insn
->u
.ri
.reg
);
5111 as_bad (_("unable to generate unwinding opcode for reg %d"),
5115 unwind
->reg_saved
[reg
] = TRUE
;
5116 unwind
->reg_offset
[reg
] = insn
->u
.ri
.offset
;
5117 if (insn
->u
.ri
.reg
== UNWIND_B3
)
5118 unwind
->return_reg
= UNWIND_B3
;
5121 case DW_CFA_register
:
5122 if (insn
->u
.rr
.reg1
!= 19)
5124 as_bad (_("unable to generate unwinding opcode for reg %d"),
5129 reg
= tic6x_unwind_reg_from_dwarf (insn
->u
.rr
.reg2
);
5132 as_bad (_("unable to generate unwinding opcode for reg %d"),
5137 unwind
->return_reg
= reg
;
5138 unwind
->reg_saved
[UNWIND_B3
] = FALSE
;
5139 if (unwind
->reg_saved
[reg
])
5141 as_bad (_("unable to restore return address from "
5142 "previously restored reg"));
5147 case DW_CFA_restore
:
5148 case DW_CFA_remember_state
:
5149 case DW_CFA_restore_state
:
5150 case DW_CFA_GNU_window_save
:
5152 case CFI_val_encoded_addr
:
5153 as_bad (_("unhandled CFA insn for unwinding (%d)"), insn
->insn
);
5161 if (unwind
->cfa_reg
!= 15 && unwind
->cfa_reg
!= 31)
5163 as_bad (_("unable to generate unwinding opcode for frame pointer reg %d"),
5168 if (unwind
->cfa_reg
== 15)
5170 if (cfa_offset
!= 0)
5172 as_bad (_("unable to generate unwinding opcode for "
5173 "frame pointer offset"));
5179 if ((cfa_offset
& 7) != 0)
5181 as_bad (_("unwound stack pointer not doubleword aligned"));
5186 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5188 if (unwind
->reg_saved
[reg
])
5189 reg_saved_mask
|= 1 << (TIC6X_NUM_UNWIND_REGS
- (reg
+ 1));
5192 /* Check for standard "safe debug" frame layout */
5196 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5198 if (!unwind
->reg_saved
[reg
])
5201 if (target_big_endian
5202 && reg
< TIC6X_NUM_UNWIND_REGS
- 1
5203 && unwind
->reg_saved
[reg
+ 1]
5204 && tic6x_unwind_frame_regs
[reg
]
5205 == tic6x_unwind_frame_regs
[reg
+ 1] + 1
5206 && (tic6x_unwind_frame_regs
[reg
] & 1) == 1
5207 && (save_offset
& 4) == 4)
5210 if (save_offset
!= unwind
->reg_offset
[reg
+ 1]
5211 || save_offset
- 4 != unwind
->reg_offset
[reg
])
5218 if (save_offset
!= unwind
->reg_offset
[reg
])
5223 if (reg
== TIC6X_NUM_UNWIND_REGS
)
5225 safe_mask
= reg_saved_mask
;
5230 /* Check for compact frame layout. */
5234 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5238 if (!unwind
->reg_saved
[reg
])
5241 if (reg
< TIC6X_NUM_UNWIND_REGS
- 1)
5245 if (!unwind
->reg_saved
[reg2
]
5246 || tic6x_unwind_frame_regs
[reg
]
5247 != tic6x_unwind_frame_regs
[reg2
] + 1
5248 || (tic6x_unwind_frame_regs
[reg2
] & 1) != 0
5249 || save_offset
== 0)
5258 if (target_big_endian
)
5259 high_offset
= 4; /* lower address = positive stack offset. */
5263 if (save_offset
+ 4 - high_offset
!= unwind
->reg_offset
[reg
]
5264 || save_offset
+ high_offset
!= unwind
->reg_offset
[reg2
])
5272 if (save_offset
!= unwind
->reg_offset
[reg
])
5278 if (reg
== TIC6X_NUM_UNWIND_REGS
)
5280 compact_mask
= reg_saved_mask
;
5285 /* Check for __c6xabi_pop_rts format */
5286 if (reg_saved_mask
== 0x17ff)
5288 const int *pop_rts_offset
= target_big_endian
5289 ? tic6x_pop_rts_offset_big
5290 : tic6x_pop_rts_offset_little
;
5293 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5295 if (reg
== UNWIND_B15
)
5298 if (unwind
->reg_offset
[reg
] != pop_rts_offset
[reg
] * 4)
5302 if (reg
== TIC6X_NUM_UNWIND_REGS
)
5304 unwind
->pop_rts
= TRUE
;
5308 /* If all else fails then describe the frame manually. */
5313 for (reg
= 0; reg
< TIC6X_NUM_UNWIND_REGS
; reg
++)
5315 if (!unwind
->reg_saved
[reg
])
5318 unwind
->saved_reg_count
++;
5319 /* Encoding uses 4 bits per word, so size of unwinding opcode data
5320 limits the save area size. The exact cap will be figured out
5321 later due to overflow, the 0x800 here is just a quick sanity
5322 check to weed out obviously excessive offsets. */
5323 if (unwind
->reg_offset
[reg
] > 0 || unwind
->reg_offset
[reg
] < -0x800
5324 || (unwind
->reg_offset
[reg
] & 3) != 0)
5326 as_bad (_("stack frame layout too complex for unwinder"));
5330 if (unwind
->reg_offset
[reg
] < save_offset
)
5331 save_offset
= unwind
->reg_offset
[reg
] - 4;
5335 /* Align to 8-byte boundary (stack grows towards negative offsets). */
5338 if (unwind
->cfa_reg
== 31 && !reg_saved_mask
)
5340 cfa_offset
+= save_offset
;
5343 as_bad (_("unwound frame has negative size"));
5348 unwind
->safe_mask
= safe_mask
;
5349 unwind
->compact_mask
= compact_mask
;
5350 unwind
->reg_saved_mask
= reg_saved_mask
;
5351 unwind
->cfa_offset
= cfa_offset
;
5352 unwind
->function_start
= fde
->start_address
;