1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright (C) 1999, 2000 Free Software Foundation.
3 Contributed by Timothy Wall (twall@cygnus.com)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* Texas Instruments TMS320C54X machine specific gas.
23 Written by Timothy Wall (twall@alum.mit.edu).
25 Valuable things to do:
26 Pipeline conflict warnings
27 We encode/decode "ld #_label, dp" differently in relocatable files
28 This means we're not compatible with TI output containing those
29 expressions. We store the upper nine bits; TI stores the lower nine
30 bits. How they recover the original upper nine bits is beyond me.
32 Tests to add to expect testsuite:
33 '=' and '==' with .if, .elseif, and .break
35 Incompatibilities (mostly trivial):
37 We fill text section with zeroes instead of "nop"s
38 We don't convert '' or "" to a single instance
39 We don't convert '' to '\0'
40 We don't allow strings with .byte/.half/.short/.long
41 Probably details of the subsym stuff are different
42 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL. */
51 #include "struc-symbol.h"
52 #include "opcode/tic54x.h"
56 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
58 const char comment_chars
[] = ";";
59 const char line_comment_chars
[] = ";*#"; /* At column zero only. */
60 const char line_separator_chars
[] = ""; /* Not permitted. */
62 /* Characters which indicate that this is a floating point constant. */
63 const char FLT_CHARS
[] = "fF";
65 /* Characters that can be used to separate mantissa from exp in FP
67 const char EXP_CHARS
[] = "eE";
69 /* Only word (et al.), align, or conditionals are allowed within
71 #define ILLEGAL_WITHIN_STRUCT() \
73 if (current_stag != NULL) \
75 as_bad (_("pseudo-op illegal within .struct/.union")); \
81 md_show_usage (stream
)
84 fprintf (stream
, _("C54x-specific command line options:\n"));
85 fprintf (stream
, _("-mfar-mode | -mf Use extended addressing\n"));
86 fprintf (stream
, _("-mcpu=<CPU version> Specify the CPU version\n"));
88 fprintf (stream
, _("-mcoff-version={0|1|2} Select COFF version\n"));
90 fprintf (stream
, _("-merrors-to-file <filename>\n"));
91 fprintf (stream
, _("-me <filename> Redirect errors to a file\n"));
94 const char *md_shortopts
= "";
98 VNONE
= 0, V541
= 1, V542
= 2, V543
= 3, V545
= 5, V548
= 8, V549
= 9,
99 V545LP
= 15, V546LP
= 16
104 c_mode
, /* 16-bit addresses. */
105 far_mode
/* >16-bit addresses. */
108 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
109 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
110 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
111 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
113 struct option md_longopts
[] =
115 { "mfar-mode", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
116 { "mf", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
117 { "mcpu", required_argument
, NULL
, OPTION_CPU_VERSION
},
119 { "mcoff-version", required_argument
, NULL
, OPTION_COFF_VERSION
},
121 { "merrors-to-file", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
122 { "me", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
123 { NULL
, no_argument
, NULL
, 0},
126 size_t md_longopts_size
= sizeof (md_longopts
);
128 static int assembly_begun
= 0;
129 /* Addressing mode is not entirely implemented; the latest rev of the Other
130 assembler doesn't seem to make any distinction whatsoever; all relocations
131 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
132 but now it seems all relocations are RELEXT16. We use all RELEXT16.
134 The cpu version is kind of a waste of time as well. There is one
135 instruction (RND) for LP devices only, and several for devices with
136 extended addressing only. We include it for compatibility. */
137 static enum address_mode amode
= c_mode
;
138 static enum cpu_version cpu
= VNONE
;
140 /* Include string substitutions in listing? */
141 static int listing_sslist
= 0;
143 /* Did we do subsym substitutions on the line? */
144 static int substitution_line
= 0;
146 /* Last label seen. */
147 static symbolS
*last_label_seen
= NULL
;
149 /* This ensures that all new labels are unique. */
150 static int local_label_id
;
152 static struct hash_control
*subsym_recurse_hash
; /* Prevent infinite recurse. */
153 static struct hash_control
*math_hash
; /* Built-in math functions. */
154 /* Allow maximum levels of macro nesting; level 0 is the main substitution
155 symbol table. The other assembler only does 32 levels, so there! */
156 static struct hash_control
*subsym_hash
[100];
158 /* Keep track of local labels so we can substitute them before GAS sees them
159 since macros use their own 'namespace' for local labels, use a separate hash
161 We do our own local label handling 'cuz it's subtly different from the
164 We use our own macro nesting counter, since GAS overloads it when expanding
165 other things (like conditionals and repeat loops). */
166 static int macro_level
= 0;
167 static struct hash_control
*local_label_hash
[100];
168 /* Keep track of struct/union tags. */
169 static struct hash_control
*stag_hash
;
170 static struct hash_control
*op_hash
;
171 static struct hash_control
*parop_hash
;
172 static struct hash_control
*reg_hash
;
173 static struct hash_control
*mmreg_hash
;
174 static struct hash_control
*cc_hash
;
175 static struct hash_control
*cc2_hash
;
176 static struct hash_control
*cc3_hash
;
177 static struct hash_control
*sbit_hash
;
178 static struct hash_control
*misc_symbol_hash
;
180 static char *subsym_substitute
PARAMS ((char *line
, int forced
));
181 static char *subsym_lookup
PARAMS ((char *name
, int nest_level
));
182 static void subsym_create_or_replace
PARAMS ((char *name
, char *value
));
183 static float math_ceil
PARAMS ((float, float));
184 static float math_cvi
PARAMS ((float, float));
185 static float math_floor
PARAMS ((float, float));
186 static float math_fmod
PARAMS ((float, float));
187 static float math_int
PARAMS ((float, float));
188 static float math_round
PARAMS ((float, float));
189 static float math_sgn
PARAMS ((float, float));
190 static float math_trunc
PARAMS ((float, float));
191 static float math_acos
PARAMS ((float, float));
192 static float math_asin
PARAMS ((float, float));
193 static float math_atan
PARAMS ((float, float));
194 static float math_atan2
PARAMS ((float, float));
195 static float math_cosh
PARAMS ((float, float));
196 static float math_cos
PARAMS ((float, float));
197 static float math_cvf
PARAMS ((float, float));
198 static float math_exp
PARAMS ((float, float));
199 static float math_fabs
PARAMS ((float, float));
200 static float math_ldexp
PARAMS ((float, float));
201 static float math_log10
PARAMS ((float, float));
202 static float math_log
PARAMS ((float, float));
203 static float math_max
PARAMS ((float, float));
204 static float math_pow
PARAMS ((float, float));
205 static float math_sin
PARAMS ((float, float));
206 static float math_sinh
PARAMS ((float, float));
207 static float math_sqrt
PARAMS ((float, float));
208 static float math_tan
PARAMS ((float, float));
209 static float math_tanh
PARAMS ((float, float));
213 symbolS
*sym
; /* Symbol for this stag; value is offset. */
214 const char *name
; /* Shortcut to symbol name. */
215 bfd_vma size
; /* Size of struct/union. */
216 int current_bitfield_offset
; /* Temporary for tracking fields. */
218 struct stag_field
/* List of fields. */
221 bfd_vma offset
; /* Of start of this field. */
222 int bitfield_offset
; /* Of start of this field. */
223 struct stag
*stag
; /* If field is struct/union. */
224 struct stag_field
*next
;
226 /* For nesting; used only in stag construction. */
227 struct stag
*inner
; /* Enclosed .struct. */
228 struct stag
*outer
; /* Enclosing .struct. */
229 } *current_stag
= NULL
;
231 static segT stag_saved_seg
;
232 static subsegT stag_saved_subseg
;
234 /* Output a single character (upper octect is zero). */
242 exp
.X_op
= O_constant
;
243 exp
.X_add_number
= c
;
247 /* Walk backwards in the frag chain. */
250 frag_prev (frag
, seg
)
254 segment_info_type
*seginfo
= seg_info (seg
);
257 for (fragp
= seginfo
->frchainP
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
258 if (fragp
->fr_next
== frag
)
265 bit_offset_frag (frag
, seg
)
271 if (frag
->fr_fix
== 0
272 && frag
->fr_opcode
== NULL
273 && frag
->tc_frag_data
== 0)
274 frag
= frag_prev (frag
, seg
);
281 /* Return the number of bits allocated in the most recent word, or zero if
282 none. .field/.space/.bes may leave words partially allocated. */
285 frag_bit_offset (frag
, seg
)
289 frag
= bit_offset_frag (frag
, seg
);
292 return frag
->fr_opcode
!= NULL
? -1 : frag
->tc_frag_data
;
297 /* Read an expression from a C string; returns a pointer past the end of the
301 parse_expression (char *str
, expressionS
* exp
)
306 tmp
= input_line_pointer
; /* Save line pointer. */
307 input_line_pointer
= str
;
309 s
= input_line_pointer
;
310 input_line_pointer
= tmp
; /* Restore line pointer. */
311 return s
; /* Return pointer to where parsing stopped. */
314 /* .asg "character-string"|character-string, symbol
316 .eval is the only pseudo-op allowed to perform arithmetic on substitution
317 symbols. all other use of symbols defined with .asg are currently
322 int x ATTRIBUTE_UNUSED
;
328 int quoted
= *input_line_pointer
== '"';
330 ILLEGAL_WITHIN_STRUCT ();
335 str
= demand_copy_C_string (&len
);
336 c
= *input_line_pointer
;
340 str
= input_line_pointer
;
341 while ((c
= *input_line_pointer
) != ',')
343 if (is_end_of_line
[(int) *input_line_pointer
])
345 ++input_line_pointer
;
347 *input_line_pointer
= 0;
351 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
352 ignore_rest_of_line ();
356 name
= ++input_line_pointer
;
357 c
= get_symbol_end (); /* Get terminator. */
358 if (!isalpha (*name
))
360 as_bad ("symbols assigned with .asg must begin with a letter");
361 ignore_rest_of_line ();
365 tmp
= xmalloc (strlen (str
) + 1);
368 tmp
= xmalloc (strlen (name
) + 1);
371 subsym_create_or_replace (name
, str
);
372 *input_line_pointer
= c
;
373 demand_empty_rest_of_line ();
376 /* .eval expression, symbol
377 There's something screwy about this. The other assembler sometimes does and
378 sometimes doesn't substitute symbols defined with .eval.
379 We'll put the symbols into the subsym table as well as the normal symbol
380 table, since that's what works best. */
384 int x ATTRIBUTE_UNUSED
;
390 char valuestr
[32], *tmp
;
393 ILLEGAL_WITHIN_STRUCT ();
397 quoted
= *input_line_pointer
== '"';
399 ++input_line_pointer
;
400 value
= get_absolute_expression ();
403 if (*input_line_pointer
!= '"')
405 as_bad (_("Unterminated string after absolute expression"));
406 ignore_rest_of_line ();
409 ++input_line_pointer
;
411 if (*input_line_pointer
++ != ',')
413 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
414 ignore_rest_of_line ();
417 name
= input_line_pointer
;
418 c
= get_symbol_end (); /* Get terminator. */
419 tmp
= xmalloc (strlen (name
) + 1);
420 name
= strcpy (tmp
, name
);
421 *input_line_pointer
= c
;
423 if (!isalpha (*name
))
425 as_bad (_("symbols assigned with .eval must begin with a letter"));
426 ignore_rest_of_line ();
429 symbolP
= symbol_new (name
, absolute_section
,
430 (valueT
) value
, &zero_address_frag
);
431 SF_SET_LOCAL (symbolP
);
432 symbol_table_insert (symbolP
);
434 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
435 But since there's not written rule as to when, don't even bother trying
436 to match their behavior. */
437 sprintf (valuestr
, "%d", value
);
438 tmp
= xmalloc (strlen (valuestr
) + 1);
439 strcpy (tmp
, valuestr
);
440 subsym_create_or_replace (name
, tmp
);
442 demand_empty_rest_of_line ();
445 /* .bss symbol, size [, [blocking flag] [, alignment flag]
447 alignment is to a longword boundary; blocking is to 128-word boundary.
449 1) if there is a hole in memory, this directive should attempt to fill it
450 (not yet implemented).
452 2) if the blocking flag is not set, allocate at the current SPC
453 otherwise, check to see if the current SPC plus the space to be
454 allocated crosses the page boundary (128 words).
455 if there's not enough space, create a hole and align with the next page
457 (not yet implemented). */
461 int x ATTRIBUTE_UNUSED
;
468 subsegT current_subseg
;
473 ILLEGAL_WITHIN_STRUCT ();
475 current_seg
= now_seg
; /* Save current seg. */
476 current_subseg
= now_subseg
; /* Save current subseg. */
478 name
= input_line_pointer
;
479 c
= get_symbol_end (); /* Get terminator. */
482 as_bad (".bss size argument missing\n");
483 ignore_rest_of_line ();
487 ++input_line_pointer
;
488 words
= get_absolute_expression ();
491 as_bad (".bss size %d < 0!", words
);
492 ignore_rest_of_line ();
496 if (*input_line_pointer
== ',')
498 /* The blocking flag may be missing. */
499 ++input_line_pointer
;
500 if (*input_line_pointer
!= ',')
501 block
= get_absolute_expression ();
505 if (*input_line_pointer
== ',')
507 ++input_line_pointer
;
508 align
= get_absolute_expression ();
516 subseg_set (bss_section
, 0);
517 symbolP
= symbol_find_or_make (name
);
519 if (S_GET_SEGMENT (symbolP
) == bss_section
)
520 symbolP
->sy_frag
->fr_symbol
= (symbolS
*) NULL
;
522 symbol_set_frag (symbolP
, frag_now
);
523 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
524 (offsetT
) (words
<< 1), (char *) 0);
525 *p
= 0; /* Fill char. */
527 S_SET_SEGMENT (symbolP
, bss_section
);
529 /* The symbol may already have been created with a preceding
530 ".globl" directive -- be careful not to step on storage class
531 in that case. Otherwise, set it to static. */
532 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
533 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
537 /* s_align eats end of line; restore it */
539 --input_line_pointer
;
543 bss_section
->flags
|= SEC_BLOCK
;
545 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
546 demand_empty_rest_of_line ();
550 stag_add_field_symbols (stag
, path
, base_offset
, rootsym
, root_stag_name
)
555 const char *root_stag_name
;
557 char prefix
[strlen (path
) + 2];
558 struct stag_field
*field
= stag
->field
;
560 /* Construct a symbol for every field contained within this structure
561 including fields within structure fields. */
562 strcpy (prefix
, path
);
564 strcat (prefix
, ".");
566 while (field
!= NULL
)
568 int len
= strlen (prefix
) + strlen (field
->name
) + 2;
569 char *name
= xmalloc (len
);
570 strcpy (name
, prefix
);
571 strcat (name
, field
->name
);
576 sym
= symbol_new (name
, absolute_section
,
577 (field
->stag
? field
->offset
:
578 (valueT
) (base_offset
+ field
->offset
)),
581 symbol_table_insert (sym
);
585 char *replacement
= xmalloc (strlen (name
)
586 + strlen (stag
->name
) + 2);
587 strcpy (replacement
, S_GET_NAME (rootsym
));
588 strcat (replacement
, "+");
589 strcat (replacement
, root_stag_name
);
590 strcat (replacement
, name
+ strlen (S_GET_NAME (rootsym
)));
591 hash_insert (subsym_hash
[0], name
, replacement
);
594 /* Recurse if the field is a structure.
595 Note the field offset is relative to the outermost struct. */
596 if (field
->stag
!= NULL
)
597 stag_add_field_symbols (field
->stag
, name
,
599 rootsym
, root_stag_name
);
604 /* Keep track of stag fields so that when structures are nested we can add the
605 complete dereferencing symbols to the symbol table. */
608 stag_add_field (parent
, name
, offset
, stag
)
614 struct stag_field
*sfield
= xmalloc (sizeof (struct stag_field
));
616 memset (sfield
, 0, sizeof (*sfield
));
617 sfield
->name
= strcpy (xmalloc (strlen (name
) + 1), name
);
618 sfield
->offset
= offset
;
619 sfield
->bitfield_offset
= parent
->current_bitfield_offset
;
621 if (parent
->field
== NULL
)
622 parent
->field
= sfield
;
625 struct stag_field
*sf
= parent
->field
;
626 while (sf
->next
!= NULL
)
630 /* Only create a symbol for this field if the parent has no name. */
631 if (!strncmp (".fake", parent
->name
, 5))
633 symbolS
*sym
= symbol_new (name
, absolute_section
,
634 (valueT
) offset
, &zero_address_frag
);
636 symbol_table_insert (sym
);
640 /* [STAG] .struct [OFFSET]
641 Start defining structure offsets (symbols in absolute section). */
644 tic54x_struct (int arg
)
646 int start_offset
= 0;
651 /* Starting a new struct, switch to absolute section. */
652 stag_saved_seg
= now_seg
;
653 stag_saved_subseg
= now_subseg
;
654 subseg_set (absolute_section
, 0);
656 /* Align the current pointer. */
657 else if (current_stag
->current_bitfield_offset
!= 0)
659 ++abs_section_offset
;
660 current_stag
->current_bitfield_offset
= 0;
663 /* Offset expression is only meaningful for global .structs. */
666 /* Offset is ignored in inner structs. */
668 if (!is_end_of_line
[(int) *input_line_pointer
])
669 start_offset
= get_absolute_expression ();
676 /* Nesting, link to outer one. */
677 current_stag
->inner
= (struct stag
*) xmalloc (sizeof (struct stag
));
678 memset (current_stag
->inner
, 0, sizeof (struct stag
));
679 current_stag
->inner
->outer
= current_stag
;
680 current_stag
= current_stag
->inner
;
682 as_warn (_("Offset on nested structures is ignored"));
683 start_offset
= abs_section_offset
;
687 current_stag
= (struct stag
*) xmalloc (sizeof (struct stag
));
688 memset (current_stag
, 0, sizeof (struct stag
));
689 abs_section_offset
= start_offset
;
691 current_stag
->is_union
= is_union
;
693 if (line_label
== NULL
)
695 static int struct_count
= 0;
696 char fake
[] = ".fake_stagNNNNNNN";
697 sprintf (fake
, ".fake_stag%d", struct_count
++);
698 current_stag
->sym
= symbol_new (fake
, absolute_section
,
699 (valueT
) abs_section_offset
,
704 char label
[strlen (S_GET_NAME (line_label
)) + 1];
705 strcpy (label
, S_GET_NAME (line_label
));
706 current_stag
->sym
= symbol_new (label
, absolute_section
,
707 (valueT
) abs_section_offset
,
710 current_stag
->name
= S_GET_NAME (current_stag
->sym
);
711 SF_SET_LOCAL (current_stag
->sym
);
712 /* Nested .structs don't go into the symbol table. */
713 if (current_stag
->outer
== NULL
)
714 symbol_table_insert (current_stag
->sym
);
719 /* [LABEL] .endstruct
720 finish defining structure offsets; optional LABEL's value will be the size
724 tic54x_endstruct (int is_union
)
728 !strncmp (current_stag
->name
, ".fake", 5) ? "" : current_stag
->name
;
730 if (!current_stag
|| current_stag
->is_union
!= is_union
)
732 as_bad (_(".end%s without preceding .%s"),
733 is_union
? "union" : "struct",
734 is_union
? "union" : "struct");
735 ignore_rest_of_line ();
739 /* Align end of structures. */
740 if (current_stag
->current_bitfield_offset
)
742 ++abs_section_offset
;
743 current_stag
->current_bitfield_offset
= 0;
746 if (current_stag
->is_union
)
747 size
= current_stag
->size
;
749 size
= abs_section_offset
- S_GET_VALUE (current_stag
->sym
);
750 if (line_label
!= NULL
)
752 S_SET_VALUE (line_label
, size
);
753 symbol_table_insert (line_label
);
757 /* Union size has already been calculated. */
758 if (!current_stag
->is_union
)
759 current_stag
->size
= size
;
760 /* Nested .structs don't get put in the stag table. */
761 if (current_stag
->outer
== NULL
)
763 hash_insert (stag_hash
, current_stag
->name
, current_stag
);
764 stag_add_field_symbols (current_stag
, path
,
765 S_GET_VALUE (current_stag
->sym
),
768 current_stag
= current_stag
->outer
;
770 /* If this is a nested .struct/.union, add it as a field to the enclosing
771 one. otherwise, restore the section we were in. */
772 if (current_stag
!= NULL
)
774 stag_add_field (current_stag
, current_stag
->inner
->name
,
775 S_GET_VALUE (current_stag
->inner
->sym
),
776 current_stag
->inner
);
779 subseg_set (stag_saved_seg
, stag_saved_subseg
);
783 Reference a structure within a structure, as a sized field with an optional
785 If used outside of a .struct/.endstruct, overlays the given structure
786 format on the existing allocated space. */
790 int ignore ATTRIBUTE_UNUSED
;
792 char *name
= input_line_pointer
;
793 int c
= get_symbol_end ();
794 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
799 as_bad (_("Unrecognized struct/union tag '%s'"), name
);
801 as_bad (_(".tag requires a structure tag"));
802 ignore_rest_of_line ();
805 if (line_label
== NULL
)
807 as_bad (_("Label required for .tag"));
808 ignore_rest_of_line ();
813 char label
[strlen (S_GET_NAME (line_label
)) + 1];
815 strcpy (label
, S_GET_NAME (line_label
));
816 if (current_stag
!= NULL
)
817 stag_add_field (current_stag
, label
,
818 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
822 symbolS
*sym
= symbol_find (label
);
825 as_bad (_(".tag target '%s' undefined"), label
);
826 ignore_rest_of_line ();
829 stag_add_field_symbols (stag
, S_GET_NAME (sym
),
830 S_GET_VALUE (stag
->sym
), sym
, stag
->name
);
834 /* Bump by the struct size, but only if we're within a .struct section. */
835 if (current_stag
!= NULL
&& !current_stag
->is_union
)
836 abs_section_offset
+= stag
->size
;
838 *input_line_pointer
= c
;
839 demand_empty_rest_of_line ();
843 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
844 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
848 tic54x_struct_field (int type
)
852 int new_bitfield_offset
= 0;
853 int field_align
= current_stag
->current_bitfield_offset
!= 0;
854 int longword_align
= 0;
857 if (!is_end_of_line
[(int) *input_line_pointer
])
858 count
= get_absolute_expression ();
874 case '*': /* String. */
883 case '.': /* Bitfield. */
885 if (count
< 1 || count
> 32)
887 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count
);
888 ignore_rest_of_line ();
891 if (current_stag
->current_bitfield_offset
+ count
> 16)
893 /* Set the appropriate size and new field offset. */
903 new_bitfield_offset
= count
- 16;
907 new_bitfield_offset
= count
;
913 new_bitfield_offset
= current_stag
->current_bitfield_offset
+ count
;
917 as_bad (_("Unrecognized field type '%c'"), type
);
918 ignore_rest_of_line ();
924 /* Align to the actual starting position of the field. */
925 current_stag
->current_bitfield_offset
= 0;
926 ++abs_section_offset
;
928 /* Align to longword boundary. */
929 if (longword_align
&& (abs_section_offset
& 0x1))
930 ++abs_section_offset
;
932 if (line_label
== NULL
)
934 static int fieldno
= 0;
935 char fake
[] = ".fake_fieldNNNNN";
936 sprintf (fake
, ".fake_field%d", fieldno
++);
937 stag_add_field (current_stag
, fake
,
938 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
943 char label
[strlen (S_GET_NAME (line_label
) + 1)];
944 strcpy (label
, S_GET_NAME (line_label
));
945 stag_add_field (current_stag
, label
,
946 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
950 if (current_stag
->is_union
)
952 /* Note we treat the element as if it were an array of COUNT. */
953 if (current_stag
->size
< (unsigned) size
* count
)
954 current_stag
->size
= size
* count
;
958 abs_section_offset
+= (unsigned) size
* count
;
959 current_stag
->current_bitfield_offset
= new_bitfield_offset
;
964 /* Handle .byte, .word. .int, .long and all variants. */
966 int emitting_long
= 0;
968 tic54x_cons (int type
)
970 register unsigned int c
;
973 /* If we're within a .struct construct, don't actually allocate space. */
974 if (current_stag
!= NULL
)
976 tic54x_struct_field (type
);
980 #ifdef md_flush_pending_output
981 md_flush_pending_output ();
984 generate_lineno_debug ();
986 /* Align long words to long word boundaries (4 octets). */
987 if (type
== 'l' || type
== 'L')
989 frag_align (2, 0, 2);
990 /* If there's a label, assign it to the first allocated word. */
991 if (line_label
!= NULL
)
993 symbol_set_frag (line_label
, frag_now
);
994 S_SET_VALUE (line_label
, frag_now_fix ());
1018 if (*input_line_pointer
== '"')
1020 input_line_pointer
++;
1021 while (is_a_char (c
= next_char_of_string ()))
1022 tic54x_emit_char (c
);
1023 know (input_line_pointer
[-1] == '\"');
1029 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1030 if (exp
.X_op
== O_constant
)
1032 offsetT value
= exp
.X_add_number
;
1033 /* Truncate overflows. */
1037 if ((value
> 0 && value
> 0xFF)
1038 || (value
< 0 && value
< - 0x100))
1039 as_warn ("Overflow in expression, truncated to 8 bits");
1042 if ((value
> 0 && value
> 0xFFFF)
1043 || (value
< 0 && value
< - 0x10000))
1044 as_warn ("Overflow in expression, truncated to 16 bits");
1048 if (exp
.X_op
!= O_constant
&& octets
< 2)
1050 /* Disallow .byte with a non constant expression that will
1051 require relocation. */
1052 as_bad (_("Relocatable values require at least WORD storage"));
1053 ignore_rest_of_line ();
1057 if (exp
.X_op
!= O_constant
1061 /* FIXME -- at one point TI tools used to output REL16
1062 relocations, but I don't think the latest tools do at all
1063 The current tools output extended relocations regardless of
1064 the addresing mode (I actually think that ".c_mode" is
1065 totally ignored in the latest tools). */
1068 emit_expr (&exp
, 4);
1074 emitting_long
= octets
== 4;
1075 emit_expr (&exp
, (octets
== 1) ? 2 : octets
);
1080 while (*input_line_pointer
++ == ',');
1082 input_line_pointer
--; /* Put terminator back into stream. */
1083 demand_empty_rest_of_line ();
1086 /* .global <symbol>[,...,<symbolN>]
1087 .def <symbol>[,...,<symbolN>]
1088 .ref <symbol>[,...,<symbolN>]
1090 These all identify global symbols.
1092 .def means the symbol is defined in the current module and can be accessed
1093 by other files. The symbol should be placed in the symbol table.
1095 .ref means the symbol is used in the current module but defined in another
1096 module. The linker is to resolve this symbol's definition at link time.
1098 .global should act as a .ref or .def, as needed.
1100 global, def and ref all have symbol storage classes of C_EXT.
1102 I can't identify any difference in how the "other" c54x assembler treats
1103 these, so we ignore the type here. */
1106 tic54x_global (type
)
1114 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1116 ILLEGAL_WITHIN_STRUCT ();
1120 name
= input_line_pointer
;
1121 c
= get_symbol_end ();
1122 symbolP
= symbol_find_or_make (name
);
1124 *input_line_pointer
= c
;
1125 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
1128 input_line_pointer
++;
1129 if (is_end_of_line
[(int) *input_line_pointer
])
1130 c
= *input_line_pointer
;
1135 demand_empty_rest_of_line ();
1138 /* Remove the symbol from the local label hash lookup. */
1141 tic54x_remove_local_label (key
, value
)
1143 PTR value ATTRIBUTE_UNUSED
;
1145 PTR
*elem
= hash_delete (local_label_hash
[macro_level
], key
);
1149 /* Reset all local labels. */
1152 tic54x_clear_local_labels (ignored
)
1153 int ignored ATTRIBUTE_UNUSED
;
1155 hash_traverse (local_label_hash
[macro_level
], tic54x_remove_local_label
);
1160 .sect "section name"
1163 make sure local labels get cleared when changing sections
1165 ARG is 't' for text, 'd' for data, or '*' for a named section
1167 For compatibility, '*' sections have SEC_DATA set instead of SEC_CODE. */
1170 tic54x_sect (int arg
)
1172 ILLEGAL_WITHIN_STRUCT ();
1174 /* Local labels are cleared when changing sections. */
1175 tic54x_clear_local_labels (0);
1179 else if (arg
== 'd')
1185 /* If there are quotes, remove them. */
1186 if (*input_line_pointer
== '"')
1188 name
= demand_copy_C_string (&len
);
1189 demand_empty_rest_of_line ();
1190 name
= strcpy (xmalloc (len
+ 10), name
);
1195 name
= input_line_pointer
;
1196 c
= get_symbol_end ();
1197 name
= strcpy (xmalloc (len
+ 10), name
);
1198 *input_line_pointer
= c
;
1199 demand_empty_rest_of_line ();
1201 /* Make sure all named initialized sections are SEC_DATA. */
1202 strcat (name
, ",\"w\"\n");
1203 input_scrub_insert_line (name
);
1204 obj_coff_section (0);
1206 /* If there was a line label, make sure that it gets assigned the proper
1207 section. This is for compatibility, even though the actual behavior
1208 is not explicitly defined. For consistency, we make .sect behave
1209 like .usect, since that is probably what people expect. */
1210 if (line_label
!= NULL
)
1212 S_SET_SEGMENT (line_label
, now_seg
);
1213 symbol_set_frag (line_label
, frag_now
);
1214 S_SET_VALUE (line_label
, frag_now_fix ());
1215 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1216 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1221 /* [symbol] .space space_in_bits
1222 [symbol] .bes space_in_bits
1223 BES puts the symbol at the *last* word allocated
1225 cribbed from s_space. */
1228 tic54x_space (int arg
)
1234 int bits_per_byte
= (OCTETS_PER_BYTE
* 8);
1236 symbolS
*label
= line_label
;
1239 ILLEGAL_WITHIN_STRUCT ();
1241 #ifdef md_flush_pending_output
1242 md_flush_pending_output ();
1245 /* Read the bit count. */
1248 /* Some expressions are unresolvable until later in the assembly pass;
1249 postpone until relaxation/fixup. we also have to postpone if a previous
1250 partial allocation has not been completed yet. */
1251 if (exp
.X_op
!= O_constant
|| frag_bit_offset (frag_now
, now_seg
) == -1)
1253 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1259 p
= frag_var (rs_machine_dependent
,
1260 65536 * 2, 1, (relax_substateT
) 0,
1261 make_expr_symbol (&exp
), (offsetT
) 0,
1269 /* Reduce the required size by any bit offsets currently left over
1270 from a previous .space/.bes/.field directive. */
1271 bit_offset
= frag_now
->tc_frag_data
;
1272 if (bit_offset
!= 0 && bit_offset
< 16)
1274 int spare_bits
= bits_per_byte
- bit_offset
;
1275 if (spare_bits
>= exp
.X_add_number
)
1277 /* Don't have to do anything; sufficient bits have already been
1278 allocated; just point the label to the right place. */
1281 symbol_set_frag (label
, frag_now
);
1282 S_SET_VALUE (label
, frag_now_fix () - 1);
1285 frag_now
->tc_frag_data
+= exp
.X_add_number
;
1288 exp
.X_add_number
-= spare_bits
;
1289 /* Set the label to point to the first word allocated, which in this
1290 case is the previous word, which was only partially filled. */
1291 if (!bes
&& label
!= NULL
)
1293 symbol_set_frag (label
, frag_now
);
1294 S_SET_VALUE (label
, frag_now_fix () - 1);
1298 /* Convert bits to bytes/words and octets, rounding up. */
1299 words
= ((exp
.X_add_number
+ bits_per_byte
- 1) / bits_per_byte
);
1300 /* How many do we have left over? */
1301 bit_offset
= exp
.X_add_number
% bits_per_byte
;
1302 octets
= words
* OCTETS_PER_BYTE
;
1305 as_warn (_(".space/.bes repeat count is negative, ignored"));
1308 else if (octets
== 0)
1310 as_warn (_(".space/.bes repeat count is zero, ignored"));
1314 /* If we are in the absolute section, just bump the offset. */
1315 if (now_seg
== absolute_section
)
1317 abs_section_offset
+= words
;
1318 if (bes
&& label
!= NULL
)
1319 S_SET_VALUE (label
, abs_section_offset
- 1);
1320 frag_now
->tc_frag_data
= bit_offset
;
1325 p
= frag_var (rs_fill
, 1, 1,
1326 (relax_substateT
) 0, (symbolS
*) 0,
1327 (offsetT
) octets
, (char *) 0);
1329 /* Make note of how many bits of this word we've allocated so far. */
1330 frag_now
->tc_frag_data
= bit_offset
;
1332 /* .bes puts label at *last* word allocated. */
1333 if (bes
&& label
!= NULL
)
1335 symbol_set_frag (label
, frag_now
);
1336 S_SET_VALUE (label
, frag_now_fix () - 1);
1344 demand_empty_rest_of_line ();
1347 /* [symbol] .usect "section-name", size-in-words
1348 [, [blocking-flag] [, alignment-flag]]
1350 Unitialized section.
1351 Non-zero blocking means that if the section would cross a page (128-word)
1352 boundary, it will be page-aligned.
1353 Non-zero alignment aligns on a longword boundary.
1355 Has no effect on the current section. */
1359 int x ATTRIBUTE_UNUSED
;
1366 int size
, blocking_flag
, alignment_flag
;
1368 subsegT current_subseg
;
1371 ILLEGAL_WITHIN_STRUCT ();
1373 current_seg
= now_seg
; /* Save current seg. */
1374 current_subseg
= now_subseg
; /* Save current subseg. */
1376 if (*input_line_pointer
== '"')
1377 input_line_pointer
++;
1378 section_name
= input_line_pointer
;
1379 c
= get_symbol_end (); /* Get terminator. */
1380 input_line_pointer
++; /* Skip null symbol terminator. */
1381 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1382 strcpy (name
, section_name
);
1384 if (*input_line_pointer
== ',')
1385 ++input_line_pointer
;
1388 as_bad (_("Missing size argument"));
1389 ignore_rest_of_line ();
1393 size
= get_absolute_expression ();
1395 /* Read a possibly present third argument (blocking flag). */
1396 if (*input_line_pointer
== ',')
1398 ++input_line_pointer
;
1399 if (*input_line_pointer
!= ',')
1400 blocking_flag
= get_absolute_expression ();
1404 /* Read a possibly present fourth argument (alignment flag). */
1405 if (*input_line_pointer
== ',')
1407 ++input_line_pointer
;
1408 alignment_flag
= get_absolute_expression ();
1414 blocking_flag
= alignment_flag
= 0;
1416 seg
= subseg_new (name
, 0);
1417 flags
= bfd_get_section_flags (stdoutput
, seg
) | SEC_ALLOC
;
1421 /* s_align eats end of line; restore it. */
1423 --input_line_pointer
;
1426 if (line_label
!= NULL
)
1428 S_SET_SEGMENT (line_label
, seg
);
1429 symbol_set_frag (line_label
, frag_now
);
1430 S_SET_VALUE (line_label
, frag_now_fix ());
1431 /* Set scl to label, since that's what TI does. */
1432 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1433 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1436 seg_info (seg
)->bss
= 1; /* Uninitialized data. */
1438 p
= frag_var (rs_fill
, 1, 1,
1439 (relax_substateT
) 0, (symbolS
*) line_label
,
1440 size
* OCTETS_PER_BYTE
, (char *) 0);
1446 if (!bfd_set_section_flags (stdoutput
, seg
, flags
))
1447 as_warn ("Error setting flags for \"%s\": %s", name
,
1448 bfd_errmsg (bfd_get_error ()));
1450 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1451 demand_empty_rest_of_line ();
1454 static enum cpu_version
1455 lookup_version (ver
)
1458 enum cpu_version version
= VNONE
;
1460 if (ver
[0] == '5' && ver
[1] == '4')
1462 if (strlen (ver
) == 3
1463 && (ver
[2] == '1' || ver
[2] == '2' || ver
[2] == '3'
1464 || ver
[2] == '5' || ver
[2] == '8' || ver
[2] == '9'))
1465 version
= ver
[2] - '0';
1466 else if (strlen (ver
) == 5
1467 && toupper (ver
[3]) == 'L'
1468 && toupper (ver
[4]) == 'P'
1469 && (ver
[2] == '5' || ver
[2] == '6'))
1470 version
= ver
[2] - '0' + 10;
1478 enum cpu_version version
;
1481 if (version
== V545LP
|| version
== V546LP
)
1483 symbolS
*symbolP
= symbol_new ("__allow_lp", absolute_section
,
1484 (valueT
) 1, &zero_address_frag
);
1485 SF_SET_LOCAL (symbolP
);
1486 symbol_table_insert (symbolP
);
1490 /* .version cpu-version
1491 cpu-version may be one of the following:
1501 This is for compatibility only. It currently has no affect on assembly. */
1502 static int cpu_needs_set
= 1;
1506 int x ATTRIBUTE_UNUSED
;
1508 enum cpu_version version
= VNONE
;
1509 enum cpu_version old_version
= cpu
;
1513 ILLEGAL_WITHIN_STRUCT ();
1516 ver
= input_line_pointer
;
1517 while (!is_end_of_line
[(int) *input_line_pointer
])
1518 ++input_line_pointer
;
1519 c
= *input_line_pointer
;
1520 *input_line_pointer
= 0;
1522 version
= lookup_version (ver
);
1524 if (cpu
!= VNONE
&& cpu
!= version
)
1525 as_warn (_("CPU version has already been set"));
1527 if (version
== VNONE
)
1529 as_bad (_("Unrecognized version '%s'"), ver
);
1530 ignore_rest_of_line ();
1533 else if (assembly_begun
&& version
!= old_version
)
1535 as_bad (_("Changing of CPU version on the fly not supported"));
1536 ignore_rest_of_line ();
1542 *input_line_pointer
= c
;
1543 demand_empty_rest_of_line ();
1546 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1549 tic54x_float_cons (int type
)
1551 if (current_stag
!= 0)
1552 tic54x_struct_field ('f');
1554 #ifdef md_flush_pending_output
1555 md_flush_pending_output ();
1558 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1561 frag_align (2, 0, 2);
1562 /* If there's a label, assign it to the first allocated word. */
1563 if (line_label
!= NULL
)
1565 symbol_set_frag (line_label
, frag_now
);
1566 S_SET_VALUE (line_label
, frag_now_fix ());
1573 /* The argument is capitalized if it should be zero-terminated
1574 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1575 Code copied from read.c, and slightly modified so that strings are packed
1576 and encoded into the correct octets. */
1579 tic54x_stringer (type
)
1582 register unsigned int c
;
1584 int append_zero
= type
== 'S' || type
== 'P';
1585 int packed
= type
== 'p' || type
== 'P';
1586 int last_char
= -1; /* Packed strings need two bytes at a time to encode. */
1588 if (current_stag
!= NULL
)
1590 tic54x_struct_field ('*');
1594 #ifdef md_flush_pending_output
1595 md_flush_pending_output ();
1598 c
= ','; /* Do loop. */
1602 switch (*input_line_pointer
)
1606 unsigned short value
= get_absolute_expression ();
1607 FRAG_APPEND_1_CHAR ( value
& 0xFF);
1608 FRAG_APPEND_1_CHAR ((value
>> 8) & 0xFF);
1612 ++input_line_pointer
; /* -> 1st char of string. */
1613 start
= input_line_pointer
;
1614 while (is_a_char (c
= next_char_of_string ()))
1618 FRAG_APPEND_1_CHAR (c
);
1619 FRAG_APPEND_1_CHAR (0);
1623 /* Packed strings are filled MS octet first. */
1624 if (last_char
== -1)
1628 FRAG_APPEND_1_CHAR (c
);
1629 FRAG_APPEND_1_CHAR (last_char
);
1636 if (packed
&& last_char
!= -1)
1638 FRAG_APPEND_1_CHAR (0);
1639 FRAG_APPEND_1_CHAR (last_char
);
1644 FRAG_APPEND_1_CHAR (0);
1645 FRAG_APPEND_1_CHAR (0);
1648 know (input_line_pointer
[-1] == '\"');
1652 c
= *input_line_pointer
;
1653 if (!is_end_of_line
[c
])
1654 ++input_line_pointer
;
1657 /* Finish up any leftover packed string. */
1658 if (packed
&& last_char
!= -1)
1660 FRAG_APPEND_1_CHAR (0);
1661 FRAG_APPEND_1_CHAR (last_char
);
1663 demand_empty_rest_of_line ();
1667 tic54x_p2align (arg
)
1668 int arg ATTRIBUTE_UNUSED
;
1670 as_bad (_("p2align not supported on this target"));
1674 tic54x_align_words (arg
)
1677 /* Only ".align" with no argument is allowed within .struct/.union. */
1680 if (!is_end_of_line
[(int) *input_line_pointer
])
1683 as_warn (_("Argument to .even ignored"));
1685 count
= get_absolute_expression ();
1688 if (current_stag
!= NULL
&& arg
== 128)
1690 if (current_stag
->current_bitfield_offset
!= 0)
1692 current_stag
->current_bitfield_offset
= 0;
1693 ++abs_section_offset
;
1695 demand_empty_rest_of_line ();
1699 ILLEGAL_WITHIN_STRUCT ();
1701 s_align_bytes (count
<< 1);
1704 /* Initialize multiple-bit fields withing a single word of memory. */
1707 tic54x_field (ignore
)
1708 int ignore ATTRIBUTE_UNUSED
;
1714 symbolS
*label
= line_label
;
1716 if (current_stag
!= NULL
)
1718 tic54x_struct_field ('.');
1722 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1724 if (*input_line_pointer
== ',')
1726 ++input_line_pointer
;
1727 size
= get_absolute_expression ();
1728 if (size
< 1 || size
> 32)
1730 as_bad (_("Invalid field size, must be from 1 to 32"));
1731 ignore_rest_of_line ();
1736 /* Truncate values to the field width. */
1737 if (exp
.X_op
!= O_constant
)
1739 /* If the expression value is relocatable, the field size *must*
1743 as_bad (_("field size must be 16 when value is relocatable"));
1744 ignore_rest_of_line ();
1748 frag_now
->tc_frag_data
= 0;
1749 emit_expr (&exp
, 2);
1753 unsigned long fmask
= (size
== 32) ? 0xFFFFFFFF : (1ul << size
) - 1;
1754 value
= exp
.X_add_number
;
1755 exp
.X_add_number
&= fmask
;
1756 if (value
!= (valueT
) exp
.X_add_number
)
1757 as_warn (_("field value truncated"));
1758 value
= exp
.X_add_number
;
1759 /* Bits are stored MS first. */
1762 frag_now
->tc_frag_data
= 0;
1764 md_number_to_chars (p
, (value
>> (size
- 16)) & 0xFFFF, 2);
1769 int bit_offset
= frag_bit_offset (frag_now
, now_seg
);
1770 fragS
*alloc_frag
= bit_offset_frag (frag_now
, now_seg
);
1771 if (bit_offset
== -1)
1773 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1774 /* We don't know the previous offset at this time, so store the
1775 info we need and figure it out later. */
1776 expressionS size_exp
;
1777 size_exp
.X_op
= O_constant
;
1778 size_exp
.X_add_number
= size
;
1780 bi
->type
= TYPE_FIELD
;
1782 p
= frag_var (rs_machine_dependent
,
1783 4, 1, (relax_substateT
) 0,
1784 make_expr_symbol (&size_exp
), (offsetT
) 0,
1788 else if (bit_offset
== 0 || bit_offset
+ size
> 16)
1790 /* Align a new field. */
1792 frag_now
->tc_frag_data
= 0;
1793 alloc_frag
= frag_now
;
1797 /* Put the new value entirely within the existing one. */
1798 p
= alloc_frag
== frag_now
?
1799 frag_now
->fr_literal
+ frag_now_fix_octets () - 2 :
1800 alloc_frag
->fr_literal
;
1803 symbol_set_frag (label
, alloc_frag
);
1804 if (alloc_frag
== frag_now
)
1805 S_SET_VALUE (label
, frag_now_fix () - 1);
1809 value
<<= 16 - alloc_frag
->tc_frag_data
- size
;
1811 /* OR in existing value. */
1812 if (alloc_frag
->tc_frag_data
)
1813 value
|= ((unsigned short) p
[1] << 8) | p
[0];
1814 md_number_to_chars (p
, value
, 2);
1815 alloc_frag
->tc_frag_data
+= size
;
1816 if (alloc_frag
->tc_frag_data
== 16)
1817 alloc_frag
->tc_frag_data
= 0;
1821 demand_empty_rest_of_line ();
1824 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1825 available yet. seg_info ()->bss is the next best thing. */
1828 tic54x_initialized_section (seg
)
1831 return !seg_info (seg
)->bss
;
1834 /* .clink ["section name"]
1836 Marks the section as conditionally linked (link only if contents are
1837 referenced elsewhere.
1838 Without a name, refers to the current initialized section.
1839 Name is required for uninitialized sections. */
1842 tic54x_clink (ignored
)
1843 int ignored ATTRIBUTE_UNUSED
;
1847 ILLEGAL_WITHIN_STRUCT ();
1849 if (*input_line_pointer
== '\"')
1851 char *section_name
= ++input_line_pointer
;
1853 while (is_a_char (next_char_of_string ()))
1855 know (input_line_pointer
[-1] == '\"');
1856 input_line_pointer
[-1] = 0;
1857 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1858 strcpy (name
, section_name
);
1860 seg
= bfd_get_section_by_name (stdoutput
, name
);
1863 as_bad (_("Unrecognized section '%s'"), section_name
);
1864 ignore_rest_of_line ();
1870 if (!tic54x_initialized_section (seg
))
1872 as_bad (_("Current section is unitialized, "
1873 "section name required for .clink"));
1874 ignore_rest_of_line ();
1879 seg
->flags
|= SEC_CLINK
;
1881 demand_empty_rest_of_line ();
1884 /* Change the default include directory to be the current source file's
1885 directory, instead of the current working directory. If DOT is non-zero,
1886 set to "." instead. */
1889 tic54x_set_default_include (dot
)
1900 as_where (&curfile
, &lineno
);
1901 dir
= strcpy (xmalloc (strlen (curfile
) + 1), curfile
);
1902 tmp
= strrchr (dir
, '/');
1909 if (include_dir_count
== 0)
1911 include_dirs
= (char **) xmalloc (sizeof (*include_dirs
));
1912 include_dir_count
= 1;
1914 include_dirs
[0] = dir
;
1915 if (len
> include_dir_maxlen
)
1916 include_dir_maxlen
= len
;
1918 else if (include_dirs
!= NULL
)
1919 include_dirs
[0] = ".";
1922 /* .include "filename" | filename
1923 .copy "filename" | filename
1925 FIXME 'include' file should be omitted from any output listing,
1926 'copy' should be included in any output listing
1927 FIXME -- prevent any included files from changing listing (compat only)
1928 FIXME -- need to include source file directory in search path; what's a
1929 good way to do this?
1931 Entering/exiting included/copied file clears all local labels. */
1934 tic54x_include (ignored
)
1935 int ignored ATTRIBUTE_UNUSED
;
1937 char newblock
[] = " .newblock\n";
1942 ILLEGAL_WITHIN_STRUCT ();
1946 if (*input_line_pointer
== '"')
1948 filename
= demand_copy_C_string (&len
);
1949 demand_empty_rest_of_line ();
1953 filename
= input_line_pointer
;
1954 while (!is_end_of_line
[(int) *input_line_pointer
])
1955 ++input_line_pointer
;
1956 c
= *input_line_pointer
;
1957 *input_line_pointer
= '\0';
1958 filename
= strcpy (xmalloc (strlen (filename
) + 1), filename
);
1959 *input_line_pointer
= c
;
1960 demand_empty_rest_of_line ();
1962 /* Insert a partial line with the filename (for the sake of s_include)
1964 The included file will be inserted before the newblock, so that the
1965 newblock is executed after the included file is processed. */
1966 input
= xmalloc (sizeof (newblock
) + strlen (filename
) + 4);
1967 sprintf (input
, "\"%s\"\n%s", filename
, newblock
);
1968 input_scrub_insert_line (input
);
1970 tic54x_clear_local_labels (0);
1972 tic54x_set_default_include (0);
1978 tic54x_message (type
)
1985 ILLEGAL_WITHIN_STRUCT ();
1987 if (*input_line_pointer
== '"')
1988 msg
= demand_copy_C_string (&len
);
1991 msg
= input_line_pointer
;
1992 while (!is_end_of_line
[(int) *input_line_pointer
])
1993 ++input_line_pointer
;
1994 c
= *input_line_pointer
;
1995 *input_line_pointer
= 0;
1996 msg
= strcpy (xmalloc (strlen (msg
) + 1), msg
);
1997 *input_line_pointer
= c
;
2003 as_tsktsk ("%s", msg
);
2006 as_warn ("%s", msg
);
2013 demand_empty_rest_of_line ();
2017 Define a special symbol that refers to the loadtime address rather than the
2018 runtime address within the current section.
2020 This symbol gets a special storage class so that when it is resolved, it is
2021 resolved relative to the load address (lma) of the section rather than the
2022 run address (vma). */
2025 tic54x_label (ignored
)
2026 int ignored ATTRIBUTE_UNUSED
;
2028 char *name
= input_line_pointer
;
2032 ILLEGAL_WITHIN_STRUCT ();
2034 c
= get_symbol_end ();
2035 symbolP
= colon (name
);
2036 S_SET_STORAGE_CLASS (symbolP
, C_STATLAB
);
2038 *input_line_pointer
= c
;
2039 demand_empty_rest_of_line ();
2043 Install all memory-mapped register names into the symbol table as
2044 absolute local symbols. */
2047 tic54x_mmregs (ignored
)
2048 int ignored ATTRIBUTE_UNUSED
;
2052 ILLEGAL_WITHIN_STRUCT ();
2054 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
2056 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
2057 (valueT
) sym
->value
, &zero_address_frag
);
2058 SF_SET_LOCAL (symbolP
);
2059 symbol_table_insert (symbolP
);
2064 Count defaults to 1024. */
2067 tic54x_loop (int count
)
2069 ILLEGAL_WITHIN_STRUCT ();
2072 if (!is_end_of_line
[(int) *input_line_pointer
])
2073 count
= get_absolute_expression ();
2075 do_repeat (count
, "LOOP", "ENDLOOP");
2078 /* Normally, endloop gets eaten by the preceding loop. */
2081 tic54x_endloop (ignore
)
2082 int ignore ATTRIBUTE_UNUSED
;
2084 as_bad (_("ENDLOOP without corresponding LOOP"));
2085 ignore_rest_of_line ();
2088 /* .break [condition]. */
2091 tic54x_break (ignore
)
2092 int ignore ATTRIBUTE_UNUSED
;
2096 ILLEGAL_WITHIN_STRUCT ();
2099 if (!is_end_of_line
[(int) *input_line_pointer
])
2100 cond
= get_absolute_expression ();
2103 end_repeat (substitution_line
? 1 : 0);
2107 set_address_mode (mode
)
2111 if (mode
== far_mode
)
2113 symbolS
*symbolP
= symbol_new ("__allow_far", absolute_section
,
2114 (valueT
) 1, &zero_address_frag
);
2115 SF_SET_LOCAL (symbolP
);
2116 symbol_table_insert (symbolP
);
2120 static int address_mode_needs_set
= 1;
2122 tic54x_address_mode (mode
)
2125 if (assembly_begun
&& amode
!= (unsigned) mode
)
2127 as_bad (_("Mixing of normal and extended addressing not supported"));
2128 ignore_rest_of_line ();
2131 if (mode
== far_mode
&& cpu
!= VNONE
&& cpu
!= V548
&& cpu
!= V549
)
2133 as_bad (_("Extended addressing not supported on the specified CPU"));
2134 ignore_rest_of_line ();
2138 set_address_mode (mode
);
2139 demand_empty_rest_of_line ();
2142 /* .sblock "section"|section [,...,"section"|section]
2143 Designate initialized sections for blocking. */
2146 tic54x_sblock (ignore
)
2147 int ignore ATTRIBUTE_UNUSED
;
2151 ILLEGAL_WITHIN_STRUCT ();
2158 if (*input_line_pointer
== '"')
2161 name
= demand_copy_C_string (&len
);
2165 char *section_name
= input_line_pointer
;
2166 c
= get_symbol_end ();
2167 name
= xmalloc (strlen (section_name
) + 1);
2168 strcpy (name
, section_name
);
2169 *input_line_pointer
= c
;
2172 seg
= bfd_get_section_by_name (stdoutput
, name
);
2175 as_bad (_("Unrecognized section '%s'"), name
);
2176 ignore_rest_of_line ();
2179 else if (!tic54x_initialized_section (seg
))
2181 as_bad (_(".sblock may be used for initialized sections only"));
2182 ignore_rest_of_line ();
2185 seg
->flags
|= SEC_BLOCK
;
2187 c
= *input_line_pointer
;
2188 if (!is_end_of_line
[(int) c
])
2189 ++input_line_pointer
;
2192 demand_empty_rest_of_line ();
2195 /* symbol .set value
2198 value must be defined externals; no forward-referencing allowed
2199 symbols assigned with .set/.equ may not be redefined. */
2203 int ignore ATTRIBUTE_UNUSED
;
2208 ILLEGAL_WITHIN_STRUCT ();
2212 as_bad (_("Symbol missing for .set/.equ"));
2213 ignore_rest_of_line ();
2216 name
= xstrdup (S_GET_NAME (line_label
));
2218 if ((symbolP
= symbol_find (name
)) == NULL
2219 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2221 symbolP
= symbol_new (name
, absolute_section
, 0, &zero_address_frag
);
2222 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2225 S_SET_DATA_TYPE (symbolP
, T_INT
);
2226 S_SET_SEGMENT (symbolP
, absolute_section
);
2227 symbol_table_insert (symbolP
);
2228 pseudo_set (symbolP
);
2229 demand_empty_rest_of_line ();
2234 List false conditional blocks. */
2237 tic54x_fclist (int show
)
2240 listing
&= ~LISTING_NOCOND
;
2242 listing
|= LISTING_NOCOND
;
2243 demand_empty_rest_of_line ();
2247 tic54x_sslist (int show
)
2249 ILLEGAL_WITHIN_STRUCT ();
2251 listing_sslist
= show
;
2254 /* .var SYM[,...,SYMN]
2255 Define a substitution string to be local to a macro. */
2259 int ignore ATTRIBUTE_UNUSED
;
2261 static char empty
[] = "";
2265 ILLEGAL_WITHIN_STRUCT ();
2267 if (macro_level
== 0)
2269 as_bad (_(".var may only be used within a macro definition"));
2270 ignore_rest_of_line ();
2275 if (!isalpha (*input_line_pointer
))
2277 as_bad (_("Substitution symbols must begin with a letter"));
2278 ignore_rest_of_line ();
2281 name
= input_line_pointer
;
2282 c
= get_symbol_end ();
2283 /* .var symbols start out with a null string. */
2284 name
= strcpy (xmalloc (strlen (name
) + 1), name
);
2285 hash_insert (subsym_hash
[macro_level
], name
, empty
);
2286 *input_line_pointer
= c
;
2289 ++input_line_pointer
;
2290 if (is_end_of_line
[(int) *input_line_pointer
])
2291 c
= *input_line_pointer
;
2296 demand_empty_rest_of_line ();
2299 /* .mlib <macro library filename>
2301 Macro libraries are archived (standard AR-format) text macro definitions
2302 Expand the file and include it.
2304 FIXME need to try the source file directory as well. */
2307 tic54x_mlib (ignore
)
2308 int ignore ATTRIBUTE_UNUSED
;
2315 ILLEGAL_WITHIN_STRUCT ();
2317 /* Parse the filename. */
2318 if (*input_line_pointer
== '"')
2320 if ((filename
= demand_copy_C_string (&len
)) == NULL
)
2327 while (!is_end_of_line
[(int) *input_line_pointer
]
2328 && !isspace (*input_line_pointer
))
2330 obstack_1grow (¬es
, *input_line_pointer
);
2331 ++input_line_pointer
;
2334 obstack_1grow (¬es
, '\0');
2335 filename
= obstack_finish (¬es
);
2337 demand_empty_rest_of_line ();
2339 tic54x_set_default_include (0);
2340 path
= xmalloc ((unsigned long) len
+ include_dir_maxlen
+ 5);
2341 for (i
= 0; i
< include_dir_count
; i
++)
2344 strcpy (path
, include_dirs
[i
]);
2346 strcat (path
, filename
);
2347 if ((try = fopen (path
, "r")) != NULL
)
2353 if (i
>= include_dir_count
)
2359 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2360 happens all over the place, and since the assembler doesn't usually keep
2361 running for a very long time, it really doesn't matter. */
2362 register_dependency (path
);
2364 /* Expand all archive entries to temporary files and include them. */
2365 abfd
= bfd_openr (path
, NULL
);
2368 as_bad (_("Can't open macro library file '%s' for reading."), path
);
2369 as_perror ("%s", path
);
2370 ignore_rest_of_line ();
2373 if (!bfd_check_format (abfd
, bfd_archive
))
2375 as_bad (_("File '%s' not in macro archive format"), path
);
2376 ignore_rest_of_line ();
2380 /* Open each BFD as binary (it should be straight ASCII text). */
2381 for (mbfd
= bfd_openr_next_archived_file (abfd
, NULL
);
2382 mbfd
!= NULL
; mbfd
= bfd_openr_next_archived_file (abfd
, mbfd
))
2384 /* Get a size at least as big as the archive member. */
2385 bfd_size_type size
= bfd_get_size (mbfd
);
2386 char *buf
= xmalloc (size
);
2387 char *fname
= tmpnam (NULL
);
2390 /* We're not sure how big it is, but it will be smaller than "size". */
2391 bfd_read (buf
, size
, 1, mbfd
);
2393 /* Write to a temporary file, then use s_include to include it
2395 ftmp
= fopen (fname
, "w+b");
2396 fwrite ((void *) buf
, size
, 1, ftmp
);
2397 if (buf
[size
- 1] != '\n')
2398 fwrite ("\n", 1, 1, ftmp
);
2401 input_scrub_insert_file (fname
);
2406 const pseudo_typeS md_pseudo_table
[] =
2408 { "algebraic", s_ignore
, 0 },
2409 { "align" , tic54x_align_words
, 128 },
2410 { "even" , tic54x_align_words
, 2 },
2411 { "asg" , tic54x_asg
, 0 },
2412 { "eval" , tic54x_eval
, 0 },
2413 { "bss" , tic54x_bss
, 0 },
2414 { "byte" , tic54x_cons
, 'b' },
2415 { "ubyte" , tic54x_cons
, 'B' },
2416 { "char" , tic54x_cons
, 'c' },
2417 { "uchar" , tic54x_cons
, 'C' },
2418 { "clink" , tic54x_clink
, 0 },
2419 { "c_mode" , tic54x_address_mode
, c_mode
},
2420 { "copy" , tic54x_include
, 'c' },
2421 { "include" , tic54x_include
, 'i' },
2422 { "data" , tic54x_sect
, 'd' },
2423 { "double" , tic54x_float_cons
, 'd' },
2424 { "ldouble" , tic54x_float_cons
, 'l' },
2425 { "drlist" , s_ignore
, 0 },
2426 { "drnolist" , s_ignore
, 0 },
2427 { "emsg" , tic54x_message
, 'e' },
2428 { "mmsg" , tic54x_message
, 'm' },
2429 { "wmsg" , tic54x_message
, 'w' },
2431 { "end" , s_end
, 0 },
2433 { "far_mode" , tic54x_address_mode
, far_mode
},
2434 { "fclist" , tic54x_fclist
, 1 },
2435 { "fcnolist" , tic54x_fclist
, 0 },
2436 { "field" , tic54x_field
, -1 },
2437 { "float" , tic54x_float_cons
, 'f' },
2438 { "xfloat" , tic54x_float_cons
, 'x' },
2439 { "global" , tic54x_global
, 'g' },
2440 { "def" , tic54x_global
, 'd' },
2441 { "ref" , tic54x_global
, 'r' },
2442 { "half" , tic54x_cons
, 'h' },
2443 { "uhalf" , tic54x_cons
, 'H' },
2444 { "short" , tic54x_cons
, 's' },
2445 { "ushort" , tic54x_cons
, 'S' },
2446 { "if" , s_if
, (int) O_ne
},
2447 { "elseif" , s_elseif
, (int) O_ne
},
2448 { "else" , s_else
, 0 },
2449 { "endif" , s_endif
, 0 },
2450 { "int" , tic54x_cons
, 'i' },
2451 { "uint" , tic54x_cons
, 'I' },
2452 { "word" , tic54x_cons
, 'w' },
2453 { "uword" , tic54x_cons
, 'W' },
2454 { "label" , tic54x_label
, 0 }, /* Loadtime
2456 { "length" , s_ignore
, 0 },
2457 { "width" , s_ignore
, 0 },
2459 { "list" , listing_list
, 1 },
2460 { "nolist" , listing_list
, 0 },
2462 { "long" , tic54x_cons
, 'l' },
2463 { "ulong" , tic54x_cons
, 'L' },
2464 { "xlong" , tic54x_cons
, 'x' },
2465 { "loop" , tic54x_loop
, 1024 },
2466 { "break" , tic54x_break
, 0 },
2467 { "endloop" , tic54x_endloop
, 0 },
2468 { "mlib" , tic54x_mlib
, 0 },
2469 { "mlist" , s_ignore
, 0 },
2470 { "mnolist" , s_ignore
, 0 },
2471 { "mmregs" , tic54x_mmregs
, 0 },
2472 { "newblock" , tic54x_clear_local_labels
, 0 },
2473 { "option" , s_ignore
, 0 },
2474 { "p2align" , tic54x_p2align
, 0 },
2476 { "page" , listing_eject
, 0 },
2478 { "sblock" , tic54x_sblock
, 0 },
2479 { "sect" , tic54x_sect
, '*' },
2480 { "set" , tic54x_set
, 0 },
2481 { "equ" , tic54x_set
, 0 },
2482 { "space" , tic54x_space
, 0 },
2483 { "bes" , tic54x_space
, 1 },
2484 { "sslist" , tic54x_sslist
, 1 },
2485 { "ssnolist" , tic54x_sslist
, 0 },
2486 { "string" , tic54x_stringer
, 's' },
2487 { "pstring" , tic54x_stringer
, 'p' },
2488 { "struct" , tic54x_struct
, 0 },
2489 { "tag" , tic54x_tag
, 0 },
2490 { "endstruct", tic54x_endstruct
, 0 },
2491 { "tab" , s_ignore
, 0 },
2492 { "text" , tic54x_sect
, 't' },
2494 { "title" , listing_title
, 0 },
2496 { "union" , tic54x_struct
, 1 },
2497 { "endunion" , tic54x_endstruct
, 1 },
2498 { "usect" , tic54x_usect
, 0 },
2499 { "var" , tic54x_var
, 0 },
2500 { "version" , tic54x_version
, 0 },
2505 /* For debugging, strings for each operand type. */
2506 static const char *optypes
[] =
2508 "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
2509 "Sind", "xpmad", "xpmad+", "MMRX", "MMRY",
2510 "SRC1", "SRC", "RND", "DST",
2513 "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031",
2514 "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
2520 md_parse_option (c
, arg
)
2528 case OPTION_COFF_VERSION
:
2530 int version
= atoi (arg
);
2531 if (version
!= 0 && version
!= 1 && version
!= 2)
2532 as_fatal (_("Bad COFF version '%s'"), arg
);
2533 /* FIXME -- not yet implemented. */
2536 case OPTION_CPU_VERSION
:
2538 cpu
= lookup_version (arg
);
2541 as_fatal (_("Bad CPU version '%s'"), arg
);
2544 case OPTION_ADDRESS_MODE
:
2546 address_mode_needs_set
= 1;
2548 case OPTION_STDERR_TO_FILE
:
2550 char *filename
= arg
;
2551 FILE *fp
= fopen (filename
, "w+");
2553 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2555 if ((fp
= freopen (filename
, "w+", stderr
)) == NULL
)
2556 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2564 /* Create a "local" substitution string hash table for a new macro level
2565 Some docs imply that macros have to use .newblock in order to be able
2566 to re-use a local label. We effectively do an automatic .newblock by
2567 deleting the local label hash between macro invocations. */
2570 tic54x_macro_start ()
2573 subsym_hash
[macro_level
] = hash_new ();
2574 local_label_hash
[macro_level
] = hash_new ();
2578 tic54x_macro_info (info
)
2581 struct formal_struct
2583 struct formal_struct
*next
; /* Next formal in list */
2584 sb name
; /* Name of the formal */
2585 sb def
; /* The default value */
2586 sb actual
; /* The actual argument (changed on
2588 int index
; /* The index of the formal
2589 0 .. formal_count - 1 */
2593 sb sub
; /* Substitution text. */
2594 int formal_count
; /* Number of formal args. */
2595 struct formal_struct
*formals
; /* Pointer to list of
2597 struct hash_control
*formal_hash
; /* Hash table of formals. */
2600 macro
= (struct macro_struct
*) info
;
2602 /* Put the formal args into the substitution symbol table. */
2603 for (entry
= macro
->formals
; entry
; entry
= entry
->next
)
2605 char *name
= strncpy (xmalloc (entry
->name
.len
+ 1),
2606 entry
->name
.ptr
, entry
->name
.len
);
2607 char *value
= strncpy (xmalloc (entry
->actual
.len
+ 1),
2608 entry
->actual
.ptr
, entry
->actual
.len
);
2609 name
[entry
->name
.len
] = '\0';
2610 value
[entry
->actual
.len
] = '\0';
2611 hash_insert (subsym_hash
[macro_level
], name
, value
);
2615 /* Get rid of this macro's .var's, arguments, and local labels. */
2620 hash_die (subsym_hash
[macro_level
]);
2621 subsym_hash
[macro_level
] = NULL
;
2622 hash_die (local_label_hash
[macro_level
]);
2623 local_label_hash
[macro_level
] = NULL
;
2628 subsym_symlen (a
, ignore
)
2630 char *ignore ATTRIBUTE_UNUSED
;
2635 /* Compare symbol A to string B. */
2638 subsym_symcmp (a
, b
)
2642 return strcmp (a
, b
);
2645 /* Return the index of the first occurence of B in A, or zero if none
2646 assumes b is an integer char value as a string. Index is one-based. */
2649 subsym_firstch (a
, b
)
2654 char *tmp
= strchr (a
, val
);
2656 return tmp
? tmp
- a
+ 1 : 0;
2659 /* Similar to firstch, but returns index of last occurrence of B in A. */
2662 subsym_lastch (a
, b
)
2667 char *tmp
= strrchr (a
, val
);
2669 return tmp
? tmp
- a
+ 1 : 0;
2672 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2676 subsym_isdefed (a
, ignore
)
2678 char *ignore ATTRIBUTE_UNUSED
;
2680 symbolS
*symbolP
= symbol_find (a
);
2682 return symbolP
!= NULL
;
2685 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2686 A, or zero if B is a null string. Both arguments *must* be substitution
2687 symbols, unsubstituted. */
2690 subsym_ismember (sym
, list
)
2694 char *elem
, *ptr
, *listv
;
2699 listv
= subsym_lookup (list
, macro_level
);
2702 as_bad (_("Undefined substitution symbol '%s'"), list
);
2703 ignore_rest_of_line ();
2707 ptr
= elem
= xmalloc (strlen (listv
) + 1);
2708 strcpy (elem
, listv
);
2709 while (*ptr
&& *ptr
!= ',')
2713 subsym_create_or_replace (sym
, elem
);
2715 /* Reassign the list. */
2716 subsym_create_or_replace (list
, ptr
);
2718 /* Assume this value, docs aren't clear. */
2722 /* Return zero if not a constant; otherwise:
2730 subsym_iscons (a
, ignore
)
2732 char *ignore ATTRIBUTE_UNUSED
;
2736 parse_expression (a
, &exp
);
2738 if (exp
.X_op
== O_constant
)
2740 int len
= strlen (a
);
2742 switch (toupper (a
[len
- 1]))
2755 /* No suffix; either octal, hex, or decimal. */
2756 if (*a
== '0' && len
> 1)
2758 if (toupper (a
[1]) == 'X')
2768 /* Return 1 if A is a valid symbol name. Expects string input. */
2771 subsym_isname (a
, ignore
)
2773 char *ignore ATTRIBUTE_UNUSED
;
2775 if (!is_name_beginner (*a
))
2779 if (!is_part_of_name (*a
))
2786 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2787 been seen; if so, recognize any memory-mapped register.
2788 Note this does not recognize "A" or "B" accumulators. */
2791 subsym_isreg (a
, ignore
)
2793 char *ignore ATTRIBUTE_UNUSED
;
2795 if (hash_find (reg_hash
, a
))
2797 if (hash_find (mmreg_hash
, a
))
2802 /* Return the structrure size, given the stag. */
2805 subsym_structsz (name
, ignore
)
2807 char *ignore ATTRIBUTE_UNUSED
;
2809 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
2816 /* If anybody actually uses this, they can fix it :)
2817 FIXME I'm not sure what the "reference point" of a structure is. It might
2818 be either the initial offset given .struct, or it may be the offset of the
2819 structure within another structure, or it might be something else
2820 altogether. since the TI assembler doesn't seem to ever do anything but
2821 return zero, we punt and return zero. */
2824 subsym_structacc (stag_name
, ignore
)
2825 char *stag_name ATTRIBUTE_UNUSED
;
2826 char *ignore ATTRIBUTE_UNUSED
;
2832 math_ceil (arg1
, ignore
)
2834 float ignore ATTRIBUTE_UNUSED
;
2836 return (float) ceil (arg1
);
2840 math_cvi (arg1
, ignore
)
2842 float ignore ATTRIBUTE_UNUSED
;
2848 math_floor (arg1
, ignore
)
2850 float ignore ATTRIBUTE_UNUSED
;
2852 return (float) floor (arg1
);
2856 math_fmod (float arg1
, float arg2
)
2858 return (int) arg1
% (int) arg2
;
2862 math_int (arg1
, ignore
)
2864 float ignore ATTRIBUTE_UNUSED
;
2866 return ((float) ((int) arg1
)) == arg1
;
2870 math_round (arg1
, ignore
)
2872 float ignore ATTRIBUTE_UNUSED
;
2874 return arg1
> 0 ? (int) (arg1
+ 0.5) : (int) (arg1
- 0.5);
2878 math_sgn (arg1
, ignore
)
2880 float ignore ATTRIBUTE_UNUSED
;
2882 return (arg1
< 0) ? -1 : (arg1
? 1 : 0);
2886 math_trunc (arg1
, ignore
)
2888 float ignore ATTRIBUTE_UNUSED
;
2894 math_acos (arg1
, ignore
)
2896 float ignore ATTRIBUTE_UNUSED
;
2898 return (float) acos (arg1
);
2902 math_asin (arg1
, ignore
)
2904 float ignore ATTRIBUTE_UNUSED
;
2906 return (float) asin (arg1
);
2910 math_atan (arg1
, ignore
)
2912 float ignore ATTRIBUTE_UNUSED
;
2914 return (float) atan (arg1
);
2918 math_atan2 (float arg1
, float arg2
)
2920 return (float) atan2 (arg1
, arg2
);
2924 math_cosh (arg1
, ignore
)
2926 float ignore ATTRIBUTE_UNUSED
;
2928 return (float) cosh (arg1
);
2932 math_cos (arg1
, ignore
)
2934 float ignore ATTRIBUTE_UNUSED
;
2936 return (float) cos (arg1
);
2940 math_cvf (arg1
, ignore
)
2942 float ignore ATTRIBUTE_UNUSED
;
2944 return (float) arg1
;
2948 math_exp (arg1
, ignore
)
2950 float ignore ATTRIBUTE_UNUSED
;
2952 return (float) exp (arg1
);
2956 math_fabs (arg1
, ignore
)
2958 float ignore ATTRIBUTE_UNUSED
;
2960 return (float) fabs (arg1
);
2963 /* expr1 * 2^expr2. */
2966 math_ldexp (float arg1
, float arg2
)
2968 return arg1
* (float) pow (2.0, arg2
);
2972 math_log10 (arg1
, ignore
)
2974 float ignore ATTRIBUTE_UNUSED
;
2976 return (float) log10 (arg1
);
2980 math_log (arg1
, ignore
)
2982 float ignore ATTRIBUTE_UNUSED
;
2984 return (float) log (arg1
);
2988 math_max (float arg1
, float arg2
)
2990 return (arg1
> arg2
) ? arg1
: arg2
;
2994 math_min (float arg1
, float arg2
)
2996 return (arg1
< arg2
) ? arg1
: arg2
;
3000 math_pow (float arg1
, float arg2
)
3002 return (float) pow (arg1
, arg2
);
3006 math_sin (arg1
, ignore
)
3008 float ignore ATTRIBUTE_UNUSED
;
3010 return (float) sin (arg1
);
3014 math_sinh (arg1
, ignore
)
3016 float ignore ATTRIBUTE_UNUSED
;
3018 return (float) sinh (arg1
);
3022 math_sqrt (arg1
, ignore
)
3024 float ignore ATTRIBUTE_UNUSED
;
3026 return (float) sqrt (arg1
);
3030 math_tan (arg1
, ignore
)
3032 float ignore ATTRIBUTE_UNUSED
;
3034 return (float) tan (arg1
);
3038 math_tanh (arg1
, ignore
)
3040 float ignore ATTRIBUTE_UNUSED
;
3042 return (float) tanh (arg1
);
3045 /* Built-in substitution symbol functions and math functions. */
3049 int (*proc
) (char *, char *);
3051 } subsym_proc_entry
;
3053 static const subsym_proc_entry subsym_procs
[] =
3055 /* Assembler built-in string substitution functions. */
3056 { "$symlen", subsym_symlen
, 1, },
3057 { "$symcmp", subsym_symcmp
, 2, },
3058 { "$firstch", subsym_firstch
, 2, },
3059 { "$lastch", subsym_lastch
, 2, },
3060 { "$isdefed", subsym_isdefed
, 1, },
3061 { "$ismember", subsym_ismember
, 2, },
3062 { "$iscons", subsym_iscons
, 1, },
3063 { "$isname", subsym_isname
, 1, },
3064 { "$isreg", subsym_isreg
, 1, },
3065 { "$structsz", subsym_structsz
, 1, },
3066 { "$structacc", subsym_structacc
, 1, },
3073 float (*proc
) (float, float);
3078 static const math_proc_entry math_procs
[] =
3080 /* Integer-returning built-in math functions. */
3081 { "$cvi", math_cvi
, 1, 1 },
3082 { "$int", math_int
, 1, 1 },
3083 { "$sgn", math_sgn
, 1, 1 },
3085 /* Float-returning built-in math functions. */
3086 { "$acos", math_acos
, 1, 0 },
3087 { "$asin", math_asin
, 1, 0 },
3088 { "$atan", math_atan
, 1, 0 },
3089 { "$atan2", math_atan2
, 2, 0 },
3090 { "$ceil", math_ceil
, 1, 0 },
3091 { "$cosh", math_cosh
, 1, 0 },
3092 { "$cos", math_cos
, 1, 0 },
3093 { "$cvf", math_cvf
, 1, 0 },
3094 { "$exp", math_exp
, 1, 0 },
3095 { "$fabs", math_fabs
, 1, 0 },
3096 { "$floor", math_floor
, 1, 0 },
3097 { "$fmod", math_fmod
, 2, 0 },
3098 { "$ldexp", math_ldexp
, 2, 0 },
3099 { "$log10", math_log10
, 1, 0 },
3100 { "$log", math_log
, 1, 0 },
3101 { "$max", math_max
, 2, 0 },
3102 { "$min", math_min
, 2, 0 },
3103 { "$pow", math_pow
, 2, 0 },
3104 { "$round", math_round
, 1, 0 },
3105 { "$sin", math_sin
, 1, 0 },
3106 { "$sinh", math_sinh
, 1, 0 },
3107 { "$sqrt", math_sqrt
, 1, 0 },
3108 { "$tan", math_tan
, 1, 0 },
3109 { "$tanh", math_tanh
, 1, 0 },
3110 { "$trunc", math_trunc
, 1, 0 },
3111 { NULL
, NULL
, 0, 0 },
3118 partemplate
*paropcode
;
3120 const subsym_proc_entry
*subsym_proc
;
3121 const math_proc_entry
*math_proc
;
3122 const char *hash_err
;
3124 char *TIC54X_DIR
= getenv ("TIC54X_DIR");
3125 char *A_DIR
= TIC54X_DIR
? TIC54X_DIR
: getenv ("A_DIR");
3129 /* Look for A_DIR and add it to the include list. a */
3132 char *tmp
= xstrdup (A_DIR
);
3135 char *next
= strchr (tmp
, ';');
3138 add_include_dir (tmp
);
3141 while (tmp
!= NULL
);
3144 op_hash
= hash_new ();
3145 for (opcode
= (template *) tic54x_optab
; opcode
->name
; opcode
++)
3147 if (hash_find (op_hash
, opcode
->name
))
3149 hash_err
= hash_insert (op_hash
, opcode
->name
, (char *) opcode
);
3151 as_fatal ("Internal Error: Can't hash %s: %s",
3152 opcode
->name
, hash_err
);
3154 parop_hash
= hash_new ();
3155 for (paropcode
= (partemplate
*) tic54x_paroptab
;
3159 if (hash_find (parop_hash
, paropcode
->name
))
3161 hash_err
= hash_insert (parop_hash
, paropcode
->name
, (char *) paropcode
);
3163 as_fatal ("Internal Error: Can't hash %s: %s",
3164 paropcode
->name
, hash_err
);
3166 reg_hash
= hash_new ();
3167 for (sym
= (symbol
*) regs
; sym
->name
; sym
++)
3169 /* Add basic registers to the symbol table. */
3170 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
3171 (valueT
) sym
->value
, &zero_address_frag
);
3172 SF_SET_LOCAL (symbolP
);
3173 symbol_table_insert (symbolP
);
3174 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3176 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3177 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3178 mmreg_hash
= hash_new ();
3179 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3181 hash_err
= hash_insert (mmreg_hash
, sym
->name
, (char *) sym
);
3183 cc_hash
= hash_new ();
3184 for (sym
= (symbol
*) condition_codes
; sym
->name
; sym
++)
3186 hash_err
= hash_insert (cc_hash
, sym
->name
, (char *) sym
);
3188 cc2_hash
= hash_new ();
3189 for (sym
= (symbol
*) cc2_codes
; sym
->name
; sym
++)
3191 hash_err
= hash_insert (cc2_hash
, sym
->name
, (char *) sym
);
3193 cc3_hash
= hash_new ();
3194 for (sym
= (symbol
*) cc3_codes
; sym
->name
; sym
++)
3196 hash_err
= hash_insert (cc3_hash
, sym
->name
, (char *) sym
);
3198 sbit_hash
= hash_new ();
3199 for (sym
= (symbol
*) status_bits
; sym
->name
; sym
++)
3201 hash_err
= hash_insert (sbit_hash
, sym
->name
, (char *) sym
);
3203 misc_symbol_hash
= hash_new ();
3204 for (symname
= (char **) misc_symbols
; *symname
; symname
++)
3206 hash_err
= hash_insert (misc_symbol_hash
, *symname
, *symname
);
3208 /* Only the base substitution table and local label table are initialized;
3209 the others (for local macro substitution) get instantiated as needed. */
3210 local_label_hash
[0] = hash_new ();
3211 subsym_hash
[0] = hash_new ();
3212 for (subsym_proc
= subsym_procs
; subsym_proc
->name
; subsym_proc
++)
3214 hash_err
= hash_insert (subsym_hash
[0], subsym_proc
->name
,
3215 (char *) subsym_proc
);
3217 math_hash
= hash_new ();
3218 for (math_proc
= math_procs
; math_proc
->name
; math_proc
++)
3220 /* Insert into the main subsym hash for recognition; insert into
3221 the math hash to actually store information. */
3222 hash_err
= hash_insert (subsym_hash
[0], math_proc
->name
,
3223 (char *) math_proc
);
3224 hash_err
= hash_insert (math_hash
, math_proc
->name
,
3225 (char *) math_proc
);
3227 subsym_recurse_hash
= hash_new ();
3228 stag_hash
= hash_new ();
3231 typedef struct _tic54x_insn
3233 const template *tm
; /* Opcode template. */
3234 const partemplate
*ptm
; /* Parallel opcode template. */
3236 char mnemonic
[MAX_LINE
]; /* Opcode name/mnemonic. */
3237 char parmnemonic
[MAX_LINE
]; /* 2nd mnemonic of parallel insn. */
3245 } operands
[MAX_OPERANDS
];
3248 struct opstruct paroperands
[MAX_OPERANDS
];
3252 int words
; /* Size of insn in 16-bit words. */
3253 int using_default_dst
; /* Do we need to explicitly set an
3254 omitted OP_DST operand? */
3257 unsigned short word
; /* Final encoded opcode data. */
3259 int r_nchars
; /* Relocation size. */
3260 bfd_reloc_code_real_type r_type
; /* Relocation type. */
3261 expressionS addr_expr
; /* Storage for unresolved expressions. */
3265 static int encode_operand (tic54x_insn
*, enum optype
, struct opstruct
*);
3266 static int encode_dmad (tic54x_insn
*, struct opstruct
*, int);
3267 static int operands_match (tic54x_insn
*, struct opstruct
*, int,
3268 const enum optype
*, int, int);
3269 static int encode_address (tic54x_insn
*, struct opstruct
*);
3272 is_accumulator (operand
)
3273 struct opstruct
*operand
;
3275 return strcasecmp (operand
->buf
, "a") == 0
3276 || strcasecmp (operand
->buf
, "b") == 0;
3279 /* Return the number of operands found, or -1 on error, copying the
3280 operands into the given array and the accompanying expressions into
3284 get_operands (operands
, line
)
3285 struct opstruct operands
[];
3290 int expecting_operand
= 0;
3293 while (numexp
< MAX_OPERANDS
&& !is_end_of_line
[(int) *lptr
])
3295 int paren_not_balanced
= 0;
3296 char *op_start
, *op_end
;
3297 while (*lptr
&& isspace (*lptr
))
3300 while (paren_not_balanced
|| *lptr
!= ',')
3304 if (paren_not_balanced
)
3306 as_bad ("Unbalanced parenthesis in operand %d", numexp
);
3313 ++paren_not_balanced
;
3314 else if (*lptr
== ')')
3315 --paren_not_balanced
;
3319 if (op_end
!= op_start
)
3321 int len
= op_end
- op_start
;
3322 strncpy (operands
[numexp
].buf
, op_start
, len
);
3323 operands
[numexp
].buf
[len
] = 0;
3324 /* Trim trailing spaces; while the preprocessor gets rid of most,
3325 there are weird usage patterns that can introduce them
3326 (i.e. using strings for macro args). */
3327 while (len
> 0 && isspace (operands
[numexp
].buf
[len
- 1]))
3328 operands
[numexp
].buf
[--len
] = 0;
3334 if (expecting_operand
|| *lptr
== ',')
3336 as_bad ("Expecting operand after ','");
3342 if (*++lptr
== '\0')
3344 as_bad ("Expecting operand after ','");
3347 expecting_operand
= 1;
3351 while (*lptr
&& isspace (*lptr
++))
3353 if (!is_end_of_line
[(int) *lptr
])
3355 as_bad ("Extra junk on line");
3359 /* OK, now parse them into expressions. */
3360 for (i
= 0; i
< numexp
; i
++)
3362 memset (&operands
[i
].exp
, 0, sizeof (operands
[i
].exp
));
3363 if (operands
[i
].buf
[0] == '#')
3366 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3368 else if (operands
[i
].buf
[0] == '@')
3370 /* Direct notation. */
3371 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3373 else if (operands
[i
].buf
[0] == '*')
3376 char *paren
= strchr (operands
[i
].buf
, '(');
3377 /* Allow immediate syntax in the inner expression. */
3378 if (paren
&& paren
[1] == '#')
3381 /* Pull out the lk expression or SP offset, if present. */
3384 int len
= strlen (paren
);
3385 char *end
= paren
+ len
;
3387 while (end
[-1] != ')')
3390 as_bad (_("Badly formed address expression"));
3395 parse_expression (paren
, &operands
[i
].exp
);
3399 operands
[i
].exp
.X_op
= O_absent
;
3402 parse_expression (operands
[i
].buf
, &operands
[i
].exp
);
3408 /* Predicates for different operand types. */
3411 is_immediate (operand
)
3412 struct opstruct
*operand
;
3414 return *operand
->buf
== '#';
3417 /* This is distinguished from immediate because some numbers must be constants
3418 and must *not* have the '#' prefix. */
3421 is_absolute (operand
)
3422 struct opstruct
*operand
;
3424 return operand
->exp
.X_op
== O_constant
&& !is_immediate (operand
);
3427 /* Is this an indirect operand? */
3430 is_indirect (operand
)
3431 struct opstruct
*operand
;
3433 return operand
->buf
[0] == '*';
3436 /* Is this a valid dual-memory operand? */
3440 struct opstruct
*operand
;
3442 if (is_indirect (operand
) && strncasecmp (operand
->buf
, "*ar", 3) == 0)
3444 char *tmp
= operand
->buf
+ 3;
3449 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3450 valid_mod
= *tmp
== '\0' ||
3451 strcasecmp (tmp
, "-") == 0 ||
3452 strcasecmp (tmp
, "+") == 0 ||
3453 strcasecmp (tmp
, "+0%") == 0;
3454 return arf
>= 2 && arf
<= 5 && valid_mod
;
3461 struct opstruct
*operand
;
3463 return (is_absolute (operand
)
3464 || is_immediate (operand
)
3465 || hash_find (mmreg_hash
, operand
->buf
) != 0);
3469 is_type (operand
, type
)
3470 struct opstruct
*operand
;
3476 return operand
->buf
[0] == 0;
3479 return is_dual (operand
);
3481 return is_indirect (operand
);
3483 /* This one *must* be immediate. */
3484 return is_immediate (operand
);
3493 /* Address may be a numeric, indirect, or an expression. */
3494 return !is_immediate (operand
);
3497 return is_mmreg (operand
);
3502 return is_accumulator (operand
);
3504 return is_accumulator (operand
) && toupper (operand
->buf
[0]) == 'B';
3506 return is_accumulator (operand
) && toupper (operand
->buf
[0]) == 'A';
3508 return strncasecmp ("ar", operand
->buf
, 2) == 0
3509 && isdigit (operand
->buf
[2]);
3511 return hash_find (sbit_hash
, operand
->buf
) != 0 || is_absolute (operand
);
3513 return hash_find (cc_hash
, operand
->buf
) != 0;
3515 return hash_find (cc2_hash
, operand
->buf
) != 0;
3517 return hash_find (cc3_hash
, operand
->buf
) != 0
3518 || is_immediate (operand
) || is_absolute (operand
);
3520 return (is_immediate (operand
) || is_absolute (operand
))
3521 && operand
->exp
.X_add_number
== 16;
3523 /* Allow st0 or st1 instead of a numeric. */
3524 return is_absolute (operand
) || is_immediate (operand
) ||
3525 strcasecmp ("st0", operand
->buf
) == 0 ||
3526 strcasecmp ("st1", operand
->buf
) == 0;
3529 return is_absolute (operand
) || is_immediate (operand
);
3531 return (is_immediate (operand
) || is_absolute (operand
))
3532 && operand
->exp
.X_add_number
>= 0 && operand
->exp
.X_add_number
< 16;
3534 /* Let this one catch out-of-range values. */
3535 return (is_immediate (operand
) || is_absolute (operand
))
3536 && operand
->exp
.X_add_number
!= 16;
3540 return is_absolute (operand
) || is_immediate (operand
);
3542 return is_immediate (operand
)
3543 && operand
->exp
.X_op
== O_constant
3544 && operand
->exp
.X_add_number
>= 0
3545 && operand
->exp
.X_add_number
< 256;
3548 /* Allow anything; assumes opcodes are ordered with Smem operands
3554 /* Just make sure it's an integer; check range later. */
3555 return is_immediate (operand
);
3557 return strcasecmp ("t", operand
->buf
) == 0 ||
3558 strcasecmp ("treg", operand
->buf
) == 0;
3560 return strcasecmp ("ts", operand
->buf
) == 0;
3562 return strcasecmp ("asm", operand
->buf
) == 0;
3564 return strcasecmp ("trn", operand
->buf
) == 0;
3566 return strcasecmp ("dp", operand
->buf
) == 0;
3568 return strcasecmp ("arp", operand
->buf
) == 0;
3575 operands_match (insn
, operands
, opcount
, refoptype
, minops
, maxops
)
3577 struct opstruct
*operands
;
3579 const enum optype
*refoptype
;
3582 int op
= 0, refop
= 0;
3584 if (opcount
== 0 && minops
== 0)
3589 while (op
<= maxops
&& refop
<= maxops
)
3591 while (!is_type (&operands
[op
], OPTYPE (refoptype
[refop
])))
3593 /* Skip an optional template operand if it doesn't agree
3594 with the current operand. */
3595 if (refoptype
[refop
] & OPT
)
3606 /* Save the actual operand type for later use. */
3607 operands
[op
].type
= OPTYPE (refoptype
[refop
]);
3610 /* Have we matched them all yet? */
3615 /* If a later operand is *not* optional, no match. */
3616 if ((refoptype
[refop
] & OPT
) == 0)
3618 /* Flag any implicit default OP_DST operands so we know to add
3619 them explicitly when encoding the operand later. */
3620 if (OPTYPE (refoptype
[refop
]) == OP_DST
)
3621 insn
->using_default_dst
= 1;
3633 /* 16-bit direct memory address
3634 Explicit dmad operands are always in last word of insn (usually second
3635 word, but bumped to third if lk addressing is used)
3637 We allow *(dmad) notation because the TI assembler allows it.
3640 0 for 16-bit addresses
3641 1 for full 23-bit addresses
3642 2 for the upper 7 bits of a 23-bit address (LDX). */
3645 encode_dmad (insn
, operand
, xpc_code
)
3647 struct opstruct
*operand
;
3650 int op
= 1 + insn
->is_lkaddr
;
3652 /* Only allow *(dmad) expressions; all others are invalid. */
3653 if (is_indirect (operand
) && operand
->buf
[strlen (operand
->buf
) - 1] != ')')
3655 as_bad (_("Invalid dmad syntax '%s'"), operand
->buf
);
3659 insn
->opcode
[op
].addr_expr
= operand
->exp
;
3661 if (insn
->opcode
[op
].addr_expr
.X_op
== O_constant
)
3663 valueT value
= insn
->opcode
[op
].addr_expr
.X_add_number
;
3666 insn
->opcode
[0].word
&= 0xFF80;
3667 insn
->opcode
[0].word
|= (value
>> 16) & 0x7F;
3668 insn
->opcode
[1].word
= value
& 0xFFFF;
3670 else if (xpc_code
== 2)
3671 insn
->opcode
[op
].word
= (value
>> 16) & 0xFFFF;
3673 insn
->opcode
[op
].word
= value
;
3677 /* Do the fixup later; just store the expression. */
3678 insn
->opcode
[op
].word
= 0;
3679 insn
->opcode
[op
].r_nchars
= 2;
3681 if (amode
== c_mode
)
3682 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3683 else if (xpc_code
== 1)
3685 /* This relocation spans two words, so adjust accordingly. */
3686 insn
->opcode
[0].addr_expr
= operand
->exp
;
3687 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_23
;
3688 insn
->opcode
[0].r_nchars
= 4;
3689 insn
->opcode
[0].unresolved
= 1;
3690 /* It's really 2 words, but we want to stop encoding after the
3691 first, since we must encode both words at once. */
3694 else if (xpc_code
== 2)
3695 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_MS7_OF_23
;
3697 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3699 insn
->opcode
[op
].unresolved
= 1;
3705 /* 7-bit direct address encoding. */
3708 encode_address (insn
, operand
)
3710 struct opstruct
*operand
;
3712 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3713 insn
->opcode
[0].addr_expr
= operand
->exp
;
3715 if (operand
->exp
.X_op
== O_constant
)
3716 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
& 0x7F);
3719 /* Do the fixup later; just store the expression. */
3720 insn
->opcode
[0].r_nchars
= 1;
3721 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_PARTLS7
;
3722 insn
->opcode
[0].unresolved
= 1;
3729 encode_indirect (insn
, operand
)
3731 struct opstruct
*operand
;
3736 if (insn
->is_lkaddr
)
3738 /* lk addresses always go in the second insn word. */
3739 mod
= ((toupper (operand
->buf
[1]) == 'A') ? 12 :
3740 (operand
->buf
[1] == '(') ? 15 :
3741 (strchr (operand
->buf
, '%') != NULL
) ? 14 : 13);
3742 arf
= ((mod
== 12) ? operand
->buf
[3] - '0' :
3743 (mod
== 15) ? 0 : operand
->buf
[4] - '0');
3745 insn
->opcode
[1].addr_expr
= operand
->exp
;
3747 if (operand
->exp
.X_op
== O_constant
)
3748 insn
->opcode
[1].word
= operand
->exp
.X_add_number
;
3751 insn
->opcode
[1].word
= 0;
3752 insn
->opcode
[1].r_nchars
= 2;
3753 insn
->opcode
[1].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3754 insn
->opcode
[1].unresolved
= 1;
3757 else if (strncasecmp (operand
->buf
, "*sp (", 4) == 0)
3759 /* Stack offsets look the same as 7-bit direct addressing. */
3760 return encode_address (insn
, operand
);
3764 arf
= (toupper (operand
->buf
[1]) == 'A' ?
3765 operand
->buf
[3] : operand
->buf
[4]) - '0';
3767 if (operand
->buf
[1] == '+')
3769 mod
= 3; /* *+ARx */
3770 if (insn
->tm
->flags
& FL_SMR
)
3771 as_warn (_("Address mode *+ARx is write-only. "
3772 "Results of reading are undefined."));
3774 else if (operand
->buf
[4] == '\0')
3776 else if (operand
->buf
[5] == '\0')
3777 mod
= (operand
->buf
[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3778 else if (operand
->buf
[6] == '\0')
3780 if (operand
->buf
[5] == '0')
3781 mod
= (operand
->buf
[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3783 mod
= (operand
->buf
[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3785 else if (toupper (operand
->buf
[6]) == 'B')
3786 mod
= (operand
->buf
[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3787 else if (toupper (operand
->buf
[6]) == '%')
3788 mod
= (operand
->buf
[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3791 as_bad (_("Unrecognized indirect address format \"%s\""),
3797 insn
->opcode
[0].word
|= 0x80 | (mod
<< 3) | arf
;
3803 encode_integer (insn
, operand
, which
, min
, max
, mask
)
3805 struct opstruct
*operand
;
3806 int which
, min
, max
;
3807 unsigned short mask
;
3809 long parse
, integer
;
3811 insn
->opcode
[which
].addr_expr
= operand
->exp
;
3813 if (operand
->exp
.X_op
== O_constant
)
3815 parse
= operand
->exp
.X_add_number
;
3816 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3817 instead of negative. */
3818 if ((parse
& 0x8000) && min
== -32768 && max
== 32767)
3819 integer
= (short) parse
;
3823 if (integer
>= min
&& integer
<= max
)
3825 insn
->opcode
[which
].word
|= (integer
& mask
);
3828 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3829 operand
->buf
, min
, max
);
3833 if (insn
->opcode
[which
].addr_expr
.X_op
== O_constant
)
3835 insn
->opcode
[which
].word
|=
3836 insn
->opcode
[which
].addr_expr
.X_add_number
& mask
;
3840 /* Do the fixup later; just store the expression. */
3841 bfd_reloc_code_real_type rtype
=
3842 (mask
== 0x1FF ? BFD_RELOC_TIC54X_PARTMS9
:
3843 mask
== 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23
:
3844 mask
== 0x7F ? BFD_RELOC_TIC54X_PARTLS7
: BFD_RELOC_8
);
3845 int size
= (mask
== 0x1FF || mask
== 0xFFFF) ? 2 : 1;
3847 if (rtype
== BFD_RELOC_8
)
3848 as_bad (_("Error in relocation handling"));
3850 insn
->opcode
[which
].r_nchars
= size
;
3851 insn
->opcode
[which
].r_type
= rtype
;
3852 insn
->opcode
[which
].unresolved
= 1;
3862 encode_condition (insn
, operand
)
3864 struct opstruct
*operand
;
3866 symbol
*cc
= (symbol
*) hash_find (cc_hash
, operand
->buf
);
3869 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3872 #define CC_GROUP 0x40
3874 #define CATG_A1 0x07
3875 #define CATG_B1 0x30
3876 #define CATG_A2 0x30
3877 #define CATG_B2 0x0C
3878 #define CATG_C2 0x03
3879 /* Disallow group 1 conditions mixed with group 2 conditions
3880 if group 1, allow only one category A and one category B
3881 if group 2, allow only one each of category A, B, and C. */
3882 if (((insn
->opcode
[0].word
& 0xFF) != 0))
3884 if ((insn
->opcode
[0].word
& CC_GROUP
) != (cc
->value
& CC_GROUP
))
3886 as_bad (_("Condition \"%s\" does not match preceding group"),
3890 if (insn
->opcode
[0].word
& CC_GROUP
)
3892 if ((insn
->opcode
[0].word
& CC_ACC
) != (cc
->value
& CC_ACC
))
3894 as_bad (_("Condition \"%s\" uses a different accumulator from "
3895 "a preceding condition"),
3899 if ((insn
->opcode
[0].word
& CATG_A1
) && (cc
->value
& CATG_A1
))
3901 as_bad (_("Only one comparison conditional allowed"));
3904 if ((insn
->opcode
[0].word
& CATG_B1
) && (cc
->value
& CATG_B1
))
3906 as_bad (_("Only one overflow conditional allowed"));
3910 else if (((insn
->opcode
[0].word
& CATG_A2
) && (cc
->value
& CATG_A2
)) ||
3911 ((insn
->opcode
[0].word
& CATG_B2
) && (cc
->value
& CATG_B2
)) ||
3912 ((insn
->opcode
[0].word
& CATG_C2
) && (cc
->value
& CATG_C2
)))
3914 as_bad (_("Duplicate %s conditional"), operand
->buf
);
3919 insn
->opcode
[0].word
|= cc
->value
;
3924 encode_cc3 (insn
, operand
)
3926 struct opstruct
*operand
;
3928 symbol
*cc3
= (symbol
*) hash_find (cc3_hash
, operand
->buf
);
3929 int value
= cc3
? cc3
->value
: operand
->exp
.X_add_number
<< 8;
3931 if ((value
& 0x0300) != value
)
3933 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3936 insn
->opcode
[0].word
|= value
;
3941 encode_arx (insn
, operand
)
3943 struct opstruct
*operand
;
3945 int arf
= strlen (operand
->buf
) >= 3 ? operand
->buf
[2] - '0' : -1;
3946 if (strncasecmp ("ar", operand
->buf
, 2) || arf
< 0 || arf
> 7)
3948 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
3951 insn
->opcode
[0].word
|= arf
;
3956 encode_cc2 (insn
, operand
)
3958 struct opstruct
*operand
;
3960 symbol
*cc2
= (symbol
*) hash_find (cc2_hash
, operand
->buf
);
3963 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3966 insn
->opcode
[0].word
|= cc2
->value
;
3971 encode_operand (insn
, type
, operand
)
3974 struct opstruct
*operand
;
3976 int ext
= insn
->tm
&& ((insn
->tm
->flags
& FL_EXT
) != 0);
3978 if (type
== OP_MMR
&& operand
->exp
.X_op
!= O_constant
)
3980 /* Disallow long-constant addressing for memory-mapped addressing. */
3981 if (insn
->is_lkaddr
)
3983 as_bad (_("lk addressing modes are invalid for memory-mapped "
3984 "register addressing"));
3988 /* Warn about *+ARx when used with MMR operands. */
3989 if (strncasecmp (operand
->buf
, "*+ar", 4) == 0)
3991 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
3992 "register addressing. Resulting behavior is "
4002 /* 16-bit immediate value. */
4003 return encode_dmad (insn
, operand
, 0);
4005 if (toupper (*operand
->buf
) == 'B')
4007 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 9);
4008 if (insn
->using_default_dst
)
4009 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4013 /* Make sure this agrees with with the OP_DST operand. */
4014 if (!((toupper (operand
->buf
[0]) == 'B') ^
4015 ((insn
->opcode
[0].word
& (1 << 8)) != 0)))
4017 as_bad (_("Destination accumulator for each part of this parallel "
4018 "instruction must be different"));
4024 if (toupper (operand
->buf
[0]) == 'B')
4025 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4030 int mod
= (operand
->buf
[4] == '\0' ? 0 : /* *arx */
4031 operand
->buf
[4] == '-' ? 1 : /* *arx- */
4032 operand
->buf
[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
4033 int arf
= operand
->buf
[3] - '0' - 2;
4034 int code
= (mod
<< 2) | arf
;
4035 insn
->opcode
[0].word
|= (code
<< (type
== OP_Xmem
? 4 : 0));
4040 if (!is_indirect (operand
))
4041 return encode_address (insn
, operand
);
4044 return encode_indirect (insn
, operand
);
4046 return encode_dmad (insn
, operand
, 2);
4048 return encode_dmad (insn
, operand
, 1);
4051 return encode_dmad (insn
, operand
, 0);
4053 return encode_arx (insn
, operand
);
4058 int value
= operand
->exp
.X_add_number
;
4061 insn
->opcode
[0].word
|= value
;
4064 if (value
< 16 || value
> 24)
4066 as_bad (_("Memory mapped register \"%s\" out of range"),
4070 if (type
== OP_MMRX
)
4071 insn
->opcode
[0].word
|= (value
- 16) << 4;
4073 insn
->opcode
[0].word
|= (value
- 16);
4081 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4084 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4087 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4088 -32768, 32767, 0xFFFF);
4090 return encode_condition (insn
, operand
);
4092 return encode_cc2 (insn
, operand
);
4094 return encode_cc3 (insn
, operand
);
4096 return encode_integer (insn
, operand
, 0, 0, 15, 0xF);
4098 return encode_integer (insn
, operand
, 0, -128, 127, 0xFF);
4101 int value
= operand
->exp
.X_add_number
;
4103 if (value
< 1 || value
> 3)
4105 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4108 code
= value
== 1 ? 0 : value
== 2 ? 0x2 : 0x1;
4109 insn
->opcode
[0].word
|= (code
<< 8);
4113 return encode_integer (insn
, operand
, 0, 0, 31, 0x1F);
4115 return encode_integer (insn
, operand
, 0, 0, 255, 0xFF);
4117 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4121 symbol
*sbit
= (symbol
*) hash_find (sbit_hash
, operand
->buf
);
4122 int value
= is_absolute (operand
) ?
4123 operand
->exp
.X_add_number
: (sbit
? sbit
->value
: -1);
4126 if (insn
->opcount
== 1)
4130 as_bad (_("A status register or status bit name is required"));
4133 /* Guess the register based on the status bit; "ovb" is the last
4134 status bit defined for st0. */
4135 if (sbit
> (symbol
*) hash_find (sbit_hash
, "ovb"))
4140 as_bad (_("Unrecognized status bit \"%s\""), operand
->buf
);
4143 insn
->opcode
[0].word
|= value
;
4144 insn
->opcode
[0].word
|= (reg
<< 9);
4148 if (strcasecmp (operand
->buf
, "st0") == 0
4149 || strcasecmp (operand
->buf
, "st1") == 0)
4151 insn
->opcode
[0].word
|=
4152 ((unsigned short) (operand
->buf
[2] - '0')) << 9;
4155 else if (operand
->exp
.X_op
== O_constant
4156 && (operand
->exp
.X_add_number
== 0
4157 || operand
->exp
.X_add_number
== 1))
4159 insn
->opcode
[0].word
|=
4160 ((unsigned short) (operand
->exp
.X_add_number
)) << 9;
4163 as_bad (_("Invalid status register \"%s\""), operand
->buf
);
4166 return encode_integer (insn
, operand
, 0, -16, 15, 0x1F);
4168 return encode_integer (insn
, operand
, 0, 0, 7, 0x7);
4170 return encode_integer (insn
, operand
, 0, 0, 0x1FF, 0x1FF);
4172 if (operand
->exp
.X_add_number
!= 1
4173 && operand
->exp
.X_add_number
!= 2)
4175 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand
->buf
);
4178 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
- 1) << 9;
4187 /* No encoding necessary. */
4202 for (i
= 0; i
< insn
->words
; i
++)
4204 int size
= (insn
->opcode
[i
].unresolved
4205 && insn
->opcode
[i
].r_type
== BFD_RELOC_TIC54X_23
) ? 4 : 2;
4206 char *p
= frag_more (size
);
4209 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
, 2);
4211 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
<< 16, 4);
4213 if (insn
->opcode
[i
].unresolved
)
4214 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
,
4215 insn
->opcode
[i
].r_nchars
, &insn
->opcode
[i
].addr_expr
,
4216 false, insn
->opcode
[i
].r_type
);
4220 /* Convert the operand strings into appropriate opcode values
4221 return the total number of words used by the instruction. */
4229 /* Only non-parallel instructions support lk addressing. */
4232 for (i
= 0; i
< insn
->opcount
; i
++)
4234 if ((OPTYPE (insn
->operands
[i
].type
) == OP_Smem
4235 || OPTYPE (insn
->operands
[i
].type
) == OP_Lmem
4236 || OPTYPE (insn
->operands
[i
].type
) == OP_Sind
)
4237 && strchr (insn
->operands
[i
].buf
, '(')
4238 /* Don't mistake stack-relative addressing for lk addressing. */
4239 && strncasecmp (insn
->operands
[i
].buf
, "*sp (", 4) != 0)
4241 insn
->is_lkaddr
= 1;
4242 insn
->lkoperand
= i
;
4248 (insn
->tm
? insn
->tm
->words
: insn
->ptm
->words
) + insn
->is_lkaddr
;
4250 insn
->opcode
[0].word
= insn
->tm
? insn
->tm
->opcode
: insn
->ptm
->opcode
;
4251 if (insn
->tm
&& (insn
->tm
->flags
& FL_EXT
))
4252 insn
->opcode
[1 + insn
->is_lkaddr
].word
= insn
->tm
->opcode2
;
4254 for (i
= 0; i
< insn
->opcount
; i
++)
4256 enum optype type
= insn
->operands
[i
].type
;
4257 if (!encode_operand (insn
, type
, &insn
->operands
[i
]))
4261 for (i
= 0; i
< insn
->paropcount
; i
++)
4263 enum optype partype
= insn
->paroperands
[i
].type
;
4264 if (!encode_operand (insn
, partype
, &insn
->paroperands
[i
]))
4274 optimize_insn (insn
)
4277 /* Optimize some instructions, helping out the brain-dead programmer. */
4278 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4279 if (strcasecmp (insn
->tm
->name
, "add") == 0)
4281 if (insn
->opcount
> 1
4282 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4283 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4284 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4285 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4288 insn
->using_default_dst
= 1;
4292 /* Try to collapse if Xmem and shift count is zero. */
4293 if ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4294 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
4295 && is_zero (insn
->operands
[1]))
4296 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4297 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4298 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4299 && is_type (&insn
->operands
[1], OP_SHIFT
)
4300 && is_zero (insn
->operands
[1]) && insn
->opcount
== 3))
4302 insn
->operands
[1] = insn
->operands
[2];
4307 else if (strcasecmp (insn
->tm
->name
, "ld") == 0)
4309 if (insn
->opcount
== 3 && insn
->operands
[0].type
!= OP_SRC
)
4311 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4312 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4313 && is_zero (insn
->operands
[1])
4314 && (OPTYPE (insn
->tm
->operand_types
[0]) != OP_lk
4315 || (insn
->operands
[0].exp
.X_op
== O_constant
4316 && insn
->operands
[0].exp
.X_add_number
<= 255
4317 && insn
->operands
[0].exp
.X_add_number
>= 0)))
4319 insn
->operands
[1] = insn
->operands
[2];
4325 else if (strcasecmp (insn
->tm
->name
, "sth") == 0
4326 || strcasecmp (insn
->tm
->name
, "stl") == 0)
4328 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4329 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4330 && is_zero (insn
->operands
[1]))
4332 insn
->operands
[1] = insn
->operands
[2];
4337 else if (strcasecmp (insn
->tm
->name
, "sub") == 0)
4339 if (insn
->opcount
> 1
4340 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4341 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4342 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4343 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4346 insn
->using_default_dst
= 1;
4350 if (((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4351 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
)
4352 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4353 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
))
4354 && is_zero (insn
->operands
[1])
4355 && insn
->opcount
== 3)
4357 insn
->operands
[1] = insn
->operands
[2];
4365 /* Find a matching template if possible, and get the operand strings. */
4368 tic54x_parse_insn (insn
, line
)
4372 insn
->tm
= (template *) hash_find (op_hash
, insn
->mnemonic
);
4375 as_bad (_("Unrecognized instruction \"%s\""), insn
->mnemonic
);
4379 insn
->opcount
= get_operands (insn
->operands
, line
);
4380 if (insn
->opcount
< 0)
4383 /* Check each variation of operands for this mnemonic. */
4384 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
, insn
->mnemonic
) == 0)
4386 if (insn
->opcount
>= insn
->tm
->minops
4387 && insn
->opcount
<= insn
->tm
->maxops
4388 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4389 insn
->tm
->operand_types
,
4390 insn
->tm
->minops
, insn
->tm
->maxops
))
4392 /* SUCCESS! now try some optimizations. */
4393 if (optimize_insn (insn
))
4395 insn
->tm
= (template *) hash_find (op_hash
,
4404 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4405 line
, insn
->mnemonic
);
4409 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4410 won't be able to see the next line. */
4411 static int parallel_on_next_line_hint
= 0;
4413 /* See if this is part of a parallel instruction
4414 Look for a subsequent line starting with "||". */
4417 next_line_shows_parallel (next_line
)
4420 /* Look for the second half. */
4421 while (isspace (*next_line
))
4424 return (next_line
[0] == PARALLEL_SEPARATOR
4425 && next_line
[1] == PARALLEL_SEPARATOR
);
4429 tic54x_parse_parallel_insn_firstline (insn
, line
)
4433 insn
->ptm
= (partemplate
*) hash_find (parop_hash
, insn
->mnemonic
);
4436 as_bad (_("Unrecognized parallel instruction \"%s\""),
4441 while (insn
->ptm
->name
&& strcasecmp (insn
->ptm
->name
,
4442 insn
->mnemonic
) == 0)
4444 insn
->opcount
= get_operands (insn
->operands
, line
);
4445 if (insn
->opcount
< 0)
4447 if (insn
->opcount
== 2
4448 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4449 insn
->ptm
->operand_types
, 2, 2))
4455 /* Didn't find a matching parallel; try for a normal insn. */
4459 /* Parse the second line of a two-line parallel instruction. */
4462 tic54x_parse_parallel_insn_lastline (insn
, line
)
4466 int valid_mnemonic
= 0;
4468 insn
->paropcount
= get_operands (insn
->paroperands
, line
);
4469 while (insn
->ptm
->name
&& strcasecmp (insn
->ptm
->name
,
4470 insn
->mnemonic
) == 0)
4472 if (strcasecmp (insn
->ptm
->parname
, insn
->parmnemonic
) == 0)
4475 if (insn
->paropcount
>= insn
->ptm
->minops
4476 && insn
->paropcount
<= insn
->ptm
->maxops
4477 && operands_match (insn
, insn
->paroperands
,
4479 insn
->ptm
->paroperand_types
,
4480 insn
->ptm
->minops
, insn
->ptm
->maxops
))
4488 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4491 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4492 insn
->mnemonic
, insn
->parmnemonic
);
4497 /* If quotes found, return copy of line up to closing quote;
4498 otherwise up until terminator.
4499 If it's a string, pass as-is; otherwise attempt substitution symbol
4500 replacement on the value. */
4503 subsym_get_arg (char *line
, char *terminators
, char **str
, int nosub
)
4507 int is_string
= *line
== '"';
4508 int is_char
= isdigit (*line
);
4512 while (isdigit (*ptr
))
4515 *str
= xmalloc (ptr
- line
+ 1);
4516 strncpy (*str
, line
, ptr
- line
);
4517 (*str
)[ptr
- line
] = 0;
4521 char *savedp
= input_line_pointer
;
4523 input_line_pointer
= ptr
;
4524 *str
= demand_copy_C_string (&len
);
4525 endp
= input_line_pointer
;
4526 input_line_pointer
= savedp
;
4528 /* Do forced substitutions if requested. */
4529 if (!nosub
&& **str
== ':')
4530 *str
= subsym_substitute (*str
, 1);
4534 char *term
= terminators
;
4537 while (*ptr
&& *ptr
!= *term
)
4548 *str
= xmalloc (ptr
- line
+ 1);
4549 strncpy (*str
, line
, ptr
- line
);
4550 (*str
)[ptr
- line
] = 0;
4551 /* Do simple substitution, if available. */
4552 if (!nosub
&& (value
= subsym_lookup (*str
, macro_level
)) != NULL
)
4559 /* Replace the given substitution string.
4560 We start at the innermost macro level, so that existing locals remain local
4561 Note: we're treating macro args identically to .var's; I don't know if
4562 that's compatible w/TI's assembler. */
4565 subsym_create_or_replace (name
, value
)
4571 for (i
= macro_level
; i
> 0; i
--)
4573 if (hash_find (subsym_hash
[i
], name
))
4575 hash_replace (subsym_hash
[i
], name
, value
);
4579 if (hash_find (subsym_hash
[0], name
))
4580 hash_replace (subsym_hash
[0], name
, value
);
4582 hash_insert (subsym_hash
[0], name
, value
);
4585 /* Look up the substitution string replacement for the given symbol.
4586 Start with the innermost macro substituion table given and work
4590 subsym_lookup (name
, nest_level
)
4594 char *value
= hash_find (subsym_hash
[nest_level
], name
);
4596 if (value
|| nest_level
== 0)
4599 return subsym_lookup (name
, nest_level
- 1);
4602 /* Do substitution-symbol replacement on the given line (recursively).
4603 return the argument if no substitution was done
4605 Also look for built-in functions ($func (arg)) and local labels.
4607 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4610 subsym_substitute (char *line
, int forced
)
4612 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4613 replace it in the input. */
4614 char *replacement
; /* current replacement for LINE. */
4615 char *head
; /* Start of line. */
4616 char *ptr
; /* Current examination point. */
4617 int changed
= 0; /* Did we make a substitution? */
4618 int eval_line
= 0; /* Is this line a .eval/.asg statement? */
4619 int eval_symbol
= 0; /* Are we in the middle of the symbol for
4621 char *eval_end
= NULL
;
4623 int line_conditional
= 0;
4626 /* Work with a copy of the input line. */
4627 replacement
= xmalloc (strlen (line
) + 1);
4628 strcpy (replacement
, line
);
4630 ptr
= head
= replacement
;
4632 /* Flag lines where we might need to replace a single '=' with two;
4633 GAS uses single '=' to assign macro args values, and possibly other
4634 places, so limit what we replace. */
4635 if (strstr (line
, ".if")
4636 || strstr (line
, ".elseif")
4637 || strstr (line
, ".break"))
4639 line_conditional
= 1;
4642 /* Watch out for .eval, so that we avoid doing substitution on the
4643 symbol being assigned a value. */
4644 if (strstr (line
, ".eval") || strstr (line
, ".asg"))
4647 /* If it's a macro definition, don't do substitution on the argument
4649 if (strstr (line
, ".macro"))
4652 while (!is_end_of_line
[(int) *ptr
])
4654 int current_char
= *ptr
;
4656 /* Need to update this since LINE may have been modified. */
4658 eval_end
= strrchr (ptr
, ',');
4660 /* Replace triple double quotes with bounding quote/escapes. */
4661 if (current_char
== '"' && ptr
[1] == '"' && ptr
[2] == '"')
4664 tmp
= strstr (ptr
+ 2, "\"\"\"");
4670 /* Replace a single '=' with a '==';
4671 for compatibility with older code only. */
4672 if (line_conditional
&& current_char
== '=')
4680 tmp
= xmalloc (strlen (head
) + 2 + strlen (ptr
) + 1);
4681 sprintf (tmp
, "%s==%s", head
, ptr
);
4682 /* Continue examining after the '=='. */
4683 ptr
= tmp
+ strlen (head
) + 2;
4685 head
= replacement
= tmp
;
4689 /* Flag when we've reached the symbol part of .eval/.asg. */
4690 if (eval_line
&& ptr
>= eval_end
)
4693 /* For each apparent symbol, see if it's a substitution symbol, and if
4694 so, replace it in the input. */
4695 if ((forced
&& current_char
== ':')
4696 || (!forced
&& is_name_beginner (current_char
)))
4698 char *name
; /* Symbol to be replaced. */
4699 char *savedp
= input_line_pointer
;
4702 char *tail
; /* Rest of line after symbol. */
4704 /* Skip the colon. */
4708 name
= input_line_pointer
= ptr
;
4709 c
= get_symbol_end ();
4710 /* '?' is not normally part of a symbol, but it IS part of a local
4714 *input_line_pointer
++ = c
;
4715 c
= *input_line_pointer
;
4716 *input_line_pointer
= '\0';
4718 /* Avoid infinite recursion; if a symbol shows up a second time for
4719 substitution, leave it as is. */
4720 if (hash_find (subsym_recurse_hash
, name
) == NULL
)
4721 value
= subsym_lookup (name
, macro_level
);
4723 as_warn (_("%s symbol recursion stopped at "
4724 "second appearance of '%s'"),
4725 forced
? "Forced substitution" : "Substitution", name
);
4726 ptr
= tail
= input_line_pointer
;
4727 input_line_pointer
= savedp
;
4729 /* Check for local labels; replace them with the appropriate
4731 if ((*name
== '$' && isdigit (name
[1]) && name
[2] == '\0')
4732 || name
[strlen (name
) - 1] == '?')
4734 /* Use an existing identifier for that label if, available, or
4735 create a new, unique identifier. */
4736 value
= hash_find (local_label_hash
[macro_level
], name
);
4740 char *namecopy
= strcpy (xmalloc (strlen (name
) + 1), name
);
4741 value
= strcpy (xmalloc (strlen (name
) + sizeof (digit
) + 1),
4744 value
[strlen (value
) - 1] = '\0';
4745 sprintf (digit
, ".%d", local_label_id
++);
4746 strcat (value
, digit
);
4747 hash_insert (local_label_hash
[macro_level
], namecopy
, value
);
4749 /* Indicate where to continue looking for substitutions. */
4752 /* Check for built-in subsym and math functions. */
4753 else if (value
!= NULL
&& *name
== '$')
4755 subsym_proc_entry
*entry
= (subsym_proc_entry
*) value
;
4756 math_proc_entry
*math_entry
= hash_find (math_hash
, name
);
4757 char *arg1
, *arg2
= NULL
;
4762 as_bad (_("Unrecognized substitution symbol function"));
4765 else if (*ptr
!= '(')
4767 as_bad (_("Missing '(' after substitution symbol function"));
4771 if (math_entry
!= NULL
)
4773 float arg1
, arg2
= 0;
4774 volatile float fresult
;
4776 arg1
= (float) strtod (ptr
, &ptr
);
4777 if (math_entry
->nargs
== 2)
4781 as_bad (_("Expecting second argument"));
4784 arg2
= (float) strtod (ptr
, &ptr
);
4786 fresult
= (*math_entry
->proc
) (arg1
, arg2
);
4787 value
= xmalloc (128);
4788 if (math_entry
->int_return
)
4789 sprintf (value
, "%d", (int) fresult
);
4791 sprintf (value
, "%f", fresult
);
4794 as_bad (_("Extra junk in function call, expecting ')'"));
4797 /* Don't bother recursing; the replacement isn't a
4804 int arg_type
[2] = { *ptr
== '"' , 0 };
4805 int ismember
= !strcmp (entry
->name
, "$ismember");
4806 /* Parse one or two args, which must be a substitution
4807 symbol, string or a character-string constant. */
4808 /* For all functions, a string or substitution symbol may be
4809 used, with the following exceptions:
4810 firstch/lastch: 2nd arg must be character constant
4811 ismember: both args must be substitution symbols. */
4812 ptr
= subsym_get_arg (ptr
, ",)", &arg1
, ismember
);
4815 if (entry
->nargs
== 2)
4819 as_bad (_("Function expects two arguments"));
4822 /* Character constants are converted to numerics
4823 by the preprocessor. */
4824 arg_type
[1] = (isdigit (*ptr
)) ? 2 : (*ptr
== '"');
4825 ptr
= subsym_get_arg (ptr
, ")", &arg2
, ismember
);
4827 /* Args checking. */
4828 if ((!strcmp (entry
->name
, "$firstch")
4829 || !strcmp (entry
->name
, "$lastch"))
4830 && arg_type
[1] != 2)
4832 as_bad (_("Expecting character constant argument"));
4836 && (arg_type
[0] != 0 || arg_type
[1] != 0))
4838 as_bad (_("Both arguments must be substitution symbols"));
4843 as_bad (_("Extra junk in function call, expecting ')'"));
4846 val
= (*entry
->proc
) (arg1
, arg2
);
4847 value
= xmalloc (64);
4848 sprintf (value
, "%d", val
);
4850 /* Fix things up to replace the entire expression, not just the
4856 if (value
!= NULL
&& !eval_symbol
)
4858 /* Replace the symbol with its string replacement and
4859 continue. Recursively replace VALUE until either no
4860 substitutions are performed, or a substitution that has been
4861 previously made is encountered again.
4863 put the symbol into the recursion hash table so we only
4864 try to replace a symbol once. */
4867 hash_insert (subsym_recurse_hash
, name
, name
);
4868 value
= subsym_substitute (value
, macro_level
> 0);
4869 hash_delete (subsym_recurse_hash
, name
);
4872 /* Temporarily zero-terminate where the symbol started. */
4878 /* Subscripted substitution symbol -- use just the
4879 indicated portion of the string; the description
4880 kinda indicates that forced substituion is not
4881 supposed to be recursive, but I'm not sure. */
4882 unsigned beg
, len
= 1; /* default to a single char */
4883 char *newval
= strcpy (xmalloc (strlen (value
) + 1),
4886 savedp
= input_line_pointer
;
4887 input_line_pointer
= tail
+ 1;
4888 beg
= get_absolute_expression ();
4891 as_bad (_("Invalid subscript (use 1 to %d)"),
4895 if (*input_line_pointer
== ',')
4897 ++input_line_pointer
;
4898 len
= get_absolute_expression ();
4899 if (beg
+ len
> strlen (value
))
4901 as_bad (_("Invalid length (use 0 to %d"),
4902 strlen (value
) - beg
);
4908 tail
= input_line_pointer
;
4911 as_bad (_("Missing ')' in subscripted substitution "
4912 "symbol expression"));
4916 input_line_pointer
= savedp
;
4922 tmp
= xmalloc (strlen (head
) + strlen (value
) +
4923 strlen (tail
+ 1) + 2);
4925 strcat (tmp
, value
);
4926 /* Make sure forced substitutions are properly terminated. */
4931 as_bad (_("Missing forced substitution terminator ':'"));
4936 /* Try to replace required whitespace
4937 eliminated by the preprocessor; technically, a forced
4938 substitution could come anywhere, even mid-symbol,
4939 e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
4940 but 'sym:x: end' should result in 'sym0 end'.
4941 FIXME -- this should really be fixed in the preprocessor,
4942 but would require several new states;
4943 KEEP_WHITE_AROUND_COLON does part of the job, but isn't
4945 if ((is_part_of_name (tail
[1])
4948 || tail
[1] == '\0' || tail
[1] == ',' || tail
[1] == '"')
4955 /* Restore the character after the symbol end. */
4958 /* Continue examining after the replacement value. */
4959 ptr
= tmp
+ strlen (head
) + strlen (value
);
4961 head
= replacement
= tmp
;
4979 /* We use this to handle substitution symbols
4980 hijack input_line_pointer, replacing it with our substituted string.
4982 .sslist should enable listing the line after replacements are made...
4984 returns the new buffer limit. */
4987 tic54x_start_line_hook ()
4990 char *replacement
= NULL
;
4992 /* Work with a copy of the input line, including EOL char. */
4993 endp
= input_line_pointer
;
4994 while (!is_end_of_line
[(int) *endp
++])
4996 line
= xmalloc (endp
- input_line_pointer
+ 1);
4997 strncpy (line
, input_line_pointer
, endp
- input_line_pointer
+ 1);
4998 line
[endp
- input_line_pointer
] = 0;
5000 /* Scan ahead for parallel insns. */
5001 parallel_on_next_line_hint
= next_line_shows_parallel (endp
+ 1);
5003 /* If within a macro, first process forced replacements. */
5004 if (macro_level
> 0)
5005 replacement
= subsym_substitute (line
, 1);
5008 replacement
= subsym_substitute (replacement
, 0);
5010 if (replacement
!= line
)
5012 char *tmp
= replacement
;
5013 char *comment
= strchr (replacement
, ';');
5014 char endc
= replacement
[strlen (replacement
) - 1];
5016 /* Clean up the replacement; we'd prefer to have this done by the
5017 standard preprocessing equipment (maybe do_scrub_chars?)
5018 but for now, do a quick-and-dirty. */
5019 if (comment
!= NULL
)
5026 comment
= replacement
+ strlen (replacement
) - 1;
5028 /* Trim trailing whitespace. */
5029 while (isspace (*comment
))
5036 /* Compact leading whitespace. */
5037 while (isspace (tmp
[0]) && isspace (tmp
[1]))
5040 input_line_pointer
= endp
;
5041 input_scrub_insert_line (tmp
);
5044 /* Keep track of whether we've done a substitution. */
5045 substitution_line
= 1;
5051 substitution_line
= 0;
5055 /* This is the guts of the machine-dependent assembler. STR points to a
5056 machine dependent instruction. This function is supposed to emit
5057 the frags/bytes it assembles to. */
5062 static int repeat_slot
= 0;
5063 static int delay_slots
= 0; /* How many delay slots left to fill? */
5064 static int is_parallel
= 0;
5065 static tic54x_insn insn
;
5067 char *savedp
= input_line_pointer
;
5070 input_line_pointer
= line
;
5071 c
= get_symbol_end ();
5075 if (address_mode_needs_set
)
5077 set_address_mode (amode
);
5078 address_mode_needs_set
= 0;
5091 strcpy (insn
.parmnemonic
, line
);
5092 lptr
= input_line_pointer
;
5094 input_line_pointer
= savedp
;
5096 if (tic54x_parse_parallel_insn_lastline (&insn
, lptr
))
5098 int words
= build_insn (&insn
);
5100 if (delay_slots
!= 0)
5102 if (words
> delay_slots
)
5104 as_bad (_("Instruction does not fit in available delay "
5105 "slots (%d-word insn, %d slots left)"),
5106 words
, delay_slots
);
5110 delay_slots
-= words
;
5116 memset (&insn
, 0, sizeof (insn
));
5117 strcpy (insn
.mnemonic
, line
);
5118 lptr
= input_line_pointer
;
5120 input_line_pointer
= savedp
;
5122 /* See if this line is part of a parallel instruction; if so, either this
5123 line or the next line will have the "||" specifier preceding the
5124 mnemonic, and we look for it in the parallel insn hash table. */
5125 if (strstr (line
, "||") != NULL
|| parallel_on_next_line_hint
)
5127 char *tmp
= strstr (line
, "||");
5131 if (tic54x_parse_parallel_insn_firstline (&insn
, lptr
))
5134 /* If the parallel part is on the same line, process it now,
5135 otherwise let the assembler pick up the next line for us. */
5138 while (isspace (tmp
[2]))
5140 md_assemble (tmp
+ 2);
5145 as_bad (_("Unrecognized parallel instruction '%s'"), line
);
5150 if (tic54x_parse_insn (&insn
, lptr
))
5154 if ((insn
.tm
->flags
& FL_LP
)
5155 && cpu
!= V545LP
&& cpu
!= V546LP
)
5157 as_bad (_("Instruction '%s' requires an LP cpu version"),
5161 if ((insn
.tm
->flags
& FL_FAR
)
5162 && amode
!= far_mode
)
5164 as_bad (_("Instruction '%s' requires far mode addressing"),
5169 words
= build_insn (&insn
);
5171 /* Is this instruction in a delay slot? */
5174 if (words
> delay_slots
)
5176 as_warn (_("Instruction does not fit in available delay "
5177 "slots (%d-word insn, %d slots left). "
5178 "Resulting behavior is undefined."),
5179 words
, delay_slots
);
5183 /* Branches in delay slots are not allowed. */
5184 if (insn
.tm
->flags
& FL_BMASK
)
5186 as_warn (_("Instructions which cause PC discontinuity are not "
5187 "allowed in a delay slot. "
5188 "Resulting behavior is undefined."));
5190 delay_slots
-= words
;
5193 /* Is this instruction the target of a repeat? */
5196 if (insn
.tm
->flags
& FL_NR
)
5197 as_warn (_("'%s' is not repeatable. "
5198 "Resulting behavior is undefined."),
5200 else if (insn
.is_lkaddr
)
5201 as_warn (_("Instructions using long offset modifiers or absolute "
5202 "addresses are not repeatable. "
5203 "Resulting behavior is undefined."));
5207 /* Make sure we check the target of a repeat instruction. */
5208 if (insn
.tm
->flags
& B_REPEAT
)
5211 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5213 /* Make sure we check our delay slots for validity. */
5214 if (insn
.tm
->flags
& FL_DELAY
)
5217 /* FIXME -- warn if delay_slots != 0 at EOF. */
5222 /* Do a final adjustment on the symbol table; in this case, make sure we have
5223 a ".file" symbol. */
5226 tic54x_adjust_symtab ()
5228 if (symbol_rootP
== NULL
5229 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
5233 as_where (&filename
, &lineno
);
5234 c_dot_file_symbol (filename
);
5238 /* In order to get gas to ignore any | chars at the start of a line,
5239 this function returns true if a | is found in a line.
5240 This lets us process parallel instructions, which span two lines. */
5243 tic54x_unrecognized_line (int c
)
5245 return c
== PARALLEL_SEPARATOR
;
5248 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5249 Encode their names so that only we see them and can map them to the
5251 FIXME -- obviously this isn't done yet. These locals still show up in the
5254 tic54x_define_label (sym
)
5258 static int local_label_count
= 0;
5259 const char *name
= S_GET_NAME (sym
);
5262 /* Just in case we need this later; note that this is not necessarily the
5263 same thing as line_label...
5264 When aligning or assigning labels to fields, sometimes the label is
5265 assigned other than the address at which the label appears.
5266 FIXME -- is this really needed? I think all the proper label assignment
5267 is done in tic54x_cons. */
5268 last_label_seen
= sym
;
5271 /* Try to parse something that normal parsing failed at. */
5274 tic54x_undefined_symbol (name
)
5279 /* Not sure how to handle predefined symbols. */
5280 if ((sym
= (symbol
*) hash_find (cc_hash
, name
)) != NULL
||
5281 (sym
= (symbol
*) hash_find (cc2_hash
, name
)) != NULL
||
5282 (sym
= (symbol
*) hash_find (cc3_hash
, name
)) != NULL
||
5283 (sym
= (symbol
*) hash_find (misc_symbol_hash
, name
)) != NULL
||
5284 (sym
= (symbol
*) hash_find (sbit_hash
, name
)) != NULL
)
5286 return symbol_new (name
, reg_section
,
5287 (valueT
) sym
->value
,
5288 &zero_address_frag
);
5291 if ((sym
= (symbol
*) hash_find (reg_hash
, name
)) != NULL
||
5292 (sym
= (symbol
*) hash_find (mmreg_hash
, name
)) != NULL
||
5293 !strcasecmp (name
, "a") || !strcasecmp (name
, "b"))
5295 return symbol_new (name
, reg_section
,
5296 (valueT
) sym
? sym
->value
: 0,
5297 &zero_address_frag
);
5303 /* Parse a name in an expression before the expression parser takes a stab at
5307 tic54x_parse_name (name
, exp
)
5308 char *name ATTRIBUTE_UNUSED
;
5309 expressionS
*exp ATTRIBUTE_UNUSED
;
5312 symbol
*sym
= (symbol
*) hash_find (mmreg_hash
, name
);
5314 /* If it's a MMREG, replace it with its constant value. */
5317 exp
->X_op
= O_constant
;
5318 exp
->X_add_number
= sym
->value
;
5326 md_atof (type
, literalP
, sizeP
)
5331 #define MAX_LITTLENUMS 2
5332 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5333 LITTLENUM_TYPE
*word
;
5334 /* Only one precision on the c54x. */
5336 char *t
= atof_ieee (input_line_pointer
, type
, words
);
5338 input_line_pointer
= t
;
5341 /* Target data is little-endian, but floats are stored
5342 big-"word"ian. ugh. */
5343 for (word
= words
; prec
--;)
5345 md_number_to_chars (literalP
, (long) (*word
++), sizeof (LITTLENUM_TYPE
));
5346 literalP
+= sizeof (LITTLENUM_TYPE
);
5353 tc_gen_reloc (section
, fixP
)
5358 bfd_reloc_code_real_type code
= fixP
->fx_r_type
;
5359 asymbol
*sym
= symbol_get_bfdsym (fixP
->fx_addsy
);
5361 rel
= (arelent
*) xmalloc (sizeof (arelent
));
5362 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5363 *rel
->sym_ptr_ptr
= sym
;
5364 /* We assume that all rel->address are host byte offsets. */
5365 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5366 rel
->address
/= OCTETS_PER_BYTE
;
5367 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5368 if (!strcmp (sym
->name
, section
->name
))
5369 rel
->howto
+= HOWTO_BANK
;
5373 const char *name
= S_GET_NAME (fixP
->fx_addsy
);
5376 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5377 name
, bfd_get_reloc_code_name (code
));
5383 /* Handle cons expressions. */
5386 tic54x_cons_fix_new (fragS
*frag
, int where
, int octets
, expressionS
*exp
)
5388 bfd_reloc_code_real_type r
;
5392 as_bad (_("Unsupported relocation size %d"), octets
);
5393 r
= BFD_RELOC_TIC54X_16_OF_23
;
5396 r
= BFD_RELOC_TIC54X_16_OF_23
;
5399 /* TI assembler always uses this, regardless of addressing mode. */
5401 r
= BFD_RELOC_TIC54X_23
;
5403 /* We never want to directly generate this; this is provided for
5404 stabs support only. */
5408 fix_new_exp (frag
, where
, octets
, exp
, 0, r
);
5411 /* Attempt to simplify or even eliminate a fixup.
5412 To indicate that a fixup has been eliminated, set fixP->fx_done.
5414 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5417 md_apply_fix (fixP
, valP
)
5421 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5424 switch (fixP
->fx_r_type
)
5427 as_fatal ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
5429 case BFD_RELOC_TIC54X_MS7_OF_23
:
5430 val
= (val
>> 16) & 0x7F;
5432 case BFD_RELOC_TIC54X_16_OF_23
:
5434 bfd_put_16 (stdoutput
, val
, buf
);
5435 /* Indicate what we're actually writing, so that we don't get warnings
5436 about exceeding available space. */
5437 *valP
= val
& 0xFFFF;
5439 case BFD_RELOC_TIC54X_PARTLS7
:
5440 bfd_put_16 (stdoutput
,
5441 (bfd_get_16 (stdoutput
, buf
) & 0xFF80) | (val
& 0x7F),
5443 /* Indicate what we're actually writing, so that we don't get warnings
5444 about exceeding available space. */
5447 case BFD_RELOC_TIC54X_PARTMS9
:
5448 /* TI assembler doesn't shift its encoding for relocatable files, and is
5449 thus incompatible with this implementation's relocatable files. */
5450 bfd_put_16 (stdoutput
,
5451 (bfd_get_16 (stdoutput
, buf
) & 0xFE00) | (val
>> 7),
5455 case BFD_RELOC_TIC54X_23
:
5456 bfd_put_32 (stdoutput
,
5457 (bfd_get_32 (stdoutput
, buf
) & 0xFF800000) | val
,
5462 return 0; /* Return value is ignored. */
5465 /* This is our chance to record section alignment
5466 don't need to do anything here, since BFD does the proper encoding. */
5469 md_section_align (segment
, section_size
)
5470 segT segment ATTRIBUTE_UNUSED
;
5471 valueT section_size
;
5473 return section_size
;
5477 md_pcrel_from (fixP
)
5478 fixS
*fixP ATTRIBUTE_UNUSED
;
5483 #if defined OBJ_COFF
5486 tc_coff_fix2rtype (fixP
)
5489 return (fixP
->fx_r_type
);
5492 #endif /* OBJ_COFF */
5494 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5498 tic54x_number_to_chars (buf
, val
, n
)
5504 number_to_chars_littleendian (buf
, val
, n
);
5507 number_to_chars_littleendian (buf
, val
>> 16 , 2);
5508 number_to_chars_littleendian (buf
+ 2, val
& 0xFFFF, 2);
5513 tic54x_estimate_size_before_relax (frag
, seg
)
5514 fragS
*frag ATTRIBUTE_UNUSED
;
5515 segT seg ATTRIBUTE_UNUSED
;
5520 /* We use this to handle bit allocations which we couldn't handle before due
5521 to symbols being in different frags. return number of octets added. */
5524 tic54x_relax_frag (frag
, stretch
)
5526 long stretch ATTRIBUTE_UNUSED
;
5528 symbolS
*sym
= frag
->fr_symbol
;
5534 struct bit_info
*bi
= (struct bit_info
*) frag
->fr_opcode
;
5535 int bit_offset
= frag_bit_offset (frag_prev (frag
, bi
->seg
), bi
->seg
);
5536 int size
= S_GET_VALUE (sym
);
5537 fragS
*prev_frag
= bit_offset_frag (frag_prev (frag
, bi
->seg
), bi
->seg
);
5538 int available
= 16 - bit_offset
;
5540 if (symbol_get_frag (sym
) != &zero_address_frag
5541 || S_IS_COMMON (sym
)
5542 || !S_IS_DEFINED (sym
))
5543 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5544 _("non-absolute value used with .space/.bes"));
5548 as_warn (_("negative value ignored in %s"),
5549 bi
->type
== TYPE_SPACE
? ".space" :
5550 bi
->type
== TYPE_BES
? ".bes" : ".field");
5552 frag
->tc_frag_data
= frag
->fr_fix
= 0;
5556 if (bi
->type
== TYPE_FIELD
)
5558 /* Bit fields of 16 or larger will have already been handled. */
5559 if (bit_offset
!= 0 && available
>= size
)
5561 char *p
= prev_frag
->fr_literal
;
5562 valueT value
= bi
->value
;
5563 value
<<= available
- size
;
5564 value
|= ((unsigned short) p
[1] << 8) | p
[0];
5565 md_number_to_chars (p
, value
, 2);
5566 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5567 prev_frag
->tc_frag_data
= 0;
5569 symbol_set_frag (bi
->sym
, prev_frag
);
5570 /* This frag is no longer used. */
5571 growth
= -frag
->fr_fix
;
5573 frag
->tc_frag_data
= 0;
5577 char *p
= frag
->fr_literal
;
5578 valueT value
= bi
->value
<< (16 - size
);
5579 md_number_to_chars (p
, value
, 2);
5580 if ((frag
->tc_frag_data
= size
) == 16)
5581 frag
->tc_frag_data
= 0;
5587 if (bit_offset
!= 0 && bit_offset
< 16)
5589 if (available
>= size
)
5591 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5592 prev_frag
->tc_frag_data
= 0;
5594 symbol_set_frag (bi
->sym
, prev_frag
);
5595 /* This frag is no longer used. */
5596 growth
= -frag
->fr_fix
;
5598 frag
->tc_frag_data
= 0;
5601 if (bi
->type
== TYPE_SPACE
&& bi
->sym
)
5602 symbol_set_frag (bi
->sym
, prev_frag
);
5605 growth
= (size
+ 15) / 16 * OCTETS_PER_BYTE
- frag
->fr_fix
;
5606 for (i
= 0; i
< growth
; i
++)
5607 frag
->fr_literal
[i
] = 0;
5608 frag
->fr_fix
= growth
;
5609 frag
->tc_frag_data
= size
% 16;
5610 /* Make sure any BES label points to the LAST word allocated. */
5611 if (bi
->type
== TYPE_BES
&& bi
->sym
)
5612 S_SET_VALUE (bi
->sym
, frag
->fr_fix
/ OCTETS_PER_BYTE
- 1);
5615 frag
->fr_symbol
= 0;
5616 frag
->fr_opcode
= 0;
5623 tic54x_convert_frag (abfd
, seg
, frag
)
5624 bfd
*abfd ATTRIBUTE_UNUSED
;
5625 segT seg ATTRIBUTE_UNUSED
;
5628 /* Offset is in bytes. */
5629 frag
->fr_offset
= (frag
->fr_next
->fr_address
5631 - frag
->fr_fix
) / frag
->fr_var
;
5632 if (frag
->fr_offset
< 0)
5634 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5635 _("attempt to .space/.bes backwards? (%ld)"),
5636 (long) frag
->fr_offset
);
5638 frag
->fr_type
= rs_space
;
5641 /* We need to avoid having labels defined for certain directives/pseudo-ops
5642 since once the label is defined, it's in the symbol table for good. TI
5643 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5644 I guess, except I've never seen a definition of MRI syntax).
5646 C is the character that used to be at *REST, which points to the end of the
5649 Don't allow labels to start with '.' */
5652 tic54x_start_label (c
, rest
)
5656 /* If within .struct/.union, no auto line labels, please. */
5657 if (current_stag
!= NULL
)
5660 /* Disallow labels starting with "." */
5664 while (!is_end_of_line
[(int) label
[-1]])
5668 as_bad (_("Invalid label '%s'"), label
);
5673 if (is_end_of_line
[(int) c
])
5677 while (isspace (c
= *++rest
))
5681 /* Don't let colon () define a label for any of these... */
5682 return (strncasecmp (rest
, ".tag", 4) != 0 || !isspace (rest
[4]))
5683 && (strncasecmp (rest
, ".struct", 7) != 0 || !isspace (rest
[7]))
5684 && (strncasecmp (rest
, ".union", 6) != 0 || !isspace (rest
[6]))
5685 && (strncasecmp (rest
, ".macro", 6) != 0 || !isspace (rest
[6]))
5686 && (strncasecmp (rest
, ".set", 4) != 0 || !isspace (rest
[4]))
5687 && (strncasecmp (rest
, ".equ", 4) != 0 || !isspace (rest
[4]));