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";
64 /* Characters that can be used to separate mantissa from exp in FP
66 const char EXP_CHARS
[] = "eE";
68 /* Only word (et al.), align, or conditionals are allowed within
70 #define ILLEGAL_WITHIN_STRUCT() \
71 do if (current_stag != NULL){ \
72 as_bad (_("pseudo-op illegal within .struct/.union"));return; } while (0)
75 md_show_usage (stream
)
78 fprintf (stream
, _("C54x-specific command line options:\n"));
79 fprintf (stream
, _("-mfar-mode | -mf Use extended addressing\n"));
80 fprintf (stream
, _("-mcpu=<CPU version> Specify the CPU version\n"));
82 fprintf (stream
, _("-mcoff-version={0|1|2} Select COFF version\n"));
84 fprintf (stream
, _("-merrors-to-file <filename>\n"));
85 fprintf (stream
, _("-me <filename> Redirect errors to a file\n"));
88 const char *md_shortopts
= "";
92 VNONE
= 0, V541
= 1, V542
= 2, V543
= 3, V545
= 5, V548
= 8, V549
= 9,
93 V545LP
= 15, V546LP
= 16
98 c_mode
, /* 16-bit addresses */
99 far_mode
/* >16-bit addresses */
102 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
103 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE+1)
104 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION+1)
105 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION+1)
107 struct option md_longopts
[] =
109 { "mfar-mode", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
110 { "mf", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
111 { "mcpu", required_argument
, NULL
, OPTION_CPU_VERSION
},
112 /* { "mcoff-version", required_argument, NULL, OPTION_COFF_VERSION },*/
113 { "merrors-to-file", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
114 { "me", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
115 { NULL
, no_argument
, NULL
, 0},
118 size_t md_longopts_size
= sizeof (md_longopts
);
120 static int assembly_begun
= 0;
121 /* Addressing mode is not entirely implemented; the latest rev of the Other
122 assembler doesn't seem to make any distinction whatsoever; all relocations
123 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
124 but now it seems all relocations are RELEXT16. We use all RELEXT16.
126 The cpu version is kind of a waste of time as well. There is one
127 instruction (RND) for LP devices only, and several for devices with
128 extended addressing only. We include it for compatibility. */
129 static enum address_mode amode
= c_mode
;
130 static enum cpu_version cpu
= VNONE
;
132 /* Include string substitutions in listing? */
133 static int listing_sslist
= 0;
134 /* Did we do subsym substitutions on the line? */
135 static int substitution_line
= 0;
136 /* Last label seen. */
137 static symbolS
*last_label_seen
= NULL
;
138 /* This ensures that all new labels are unique. */
139 static int local_label_id
;
141 static struct hash_control
*subsym_recurse_hash
; /* prevent infinite recurse */
142 static struct hash_control
*math_hash
; /* built-in math functions */
143 /* Allow maximum levels of macro nesting; level 0 is the main substitution
144 symbol table. The other assembler only does 32 levels, so there! */
145 static struct hash_control
*subsym_hash
[100];
146 /* Keep track of local labels so we can substitute them before GAS sees them
147 since macros use their own 'namespace' for local labels, use a separate hash
149 We do our own local label handling 'cuz it's subtly different from the
152 We use our own macro nesting counter, since GAS overloads it when expanding
153 other things (like conditionals and repeat loops). */
154 static int macro_level
= 0;
155 static struct hash_control
*local_label_hash
[100];
156 /* Keep track of struct/union tags. */
157 static struct hash_control
*stag_hash
;
158 static struct hash_control
*op_hash
;
159 static struct hash_control
*parop_hash
;
160 static struct hash_control
*reg_hash
;
161 static struct hash_control
*mmreg_hash
;
162 static struct hash_control
*cc_hash
;
163 static struct hash_control
*cc2_hash
;
164 static struct hash_control
*cc3_hash
;
165 static struct hash_control
*sbit_hash
;
166 static struct hash_control
*misc_symbol_hash
;
168 static char *subsym_substitute
PARAMS ((char *line
, int forced
));
169 static char *subsym_lookup
PARAMS ((char *name
, int nest_level
));
170 static void subsym_create_or_replace
PARAMS ((char *name
, char *value
));
171 static float math_ceil
PARAMS ((float, float));
172 static float math_cvi
PARAMS ((float, float));
173 static float math_floor
PARAMS ((float, float));
174 static float math_fmod
PARAMS ((float, float));
175 static float math_int
PARAMS ((float, float));
176 static float math_round
PARAMS ((float, float));
177 static float math_sgn
PARAMS ((float, float));
178 static float math_trunc
PARAMS ((float, float));
179 static float math_acos
PARAMS ((float, float));
180 static float math_asin
PARAMS ((float, float));
181 static float math_atan
PARAMS ((float, float));
182 static float math_atan2
PARAMS ((float, float));
183 static float math_cosh
PARAMS ((float, float));
184 static float math_cos
PARAMS ((float, float));
185 static float math_cvf
PARAMS ((float, float));
186 static float math_exp
PARAMS ((float, float));
187 static float math_fabs
PARAMS ((float, float));
188 static float math_ldexp
PARAMS ((float, float));
189 static float math_log10
PARAMS ((float, float));
190 static float math_log
PARAMS ((float, float));
191 static float math_max
PARAMS ((float, float));
192 static float math_pow
PARAMS ((float, float));
193 static float math_sin
PARAMS ((float, float));
194 static float math_sinh
PARAMS ((float, float));
195 static float math_sqrt
PARAMS ((float, float));
196 static float math_tan
PARAMS ((float, float));
197 static float math_tanh
PARAMS ((float, float));
201 symbolS
*sym
; /* symbol for this stag; value is offset */
202 const char *name
; /* shortcut to symbol name */
203 bfd_vma size
; /* size of struct/union */
204 int current_bitfield_offset
; /* temporary for tracking fields */
206 struct stag_field
/* list of fields */
209 bfd_vma offset
; /* of start of this field */
210 int bitfield_offset
; /* of start of this field */
211 struct stag
*stag
; /* if field is struct/union */
212 struct stag_field
*next
;
214 /* for nesting; used only in stag construction */
215 struct stag
*inner
; /* enclosed .struct */
216 struct stag
*outer
; /* enclosing .struct */
217 } *current_stag
= NULL
;
219 static segT stag_saved_seg
;
220 static subsegT stag_saved_subseg
;
222 /* Output a single character (upper octect is zero). */
229 exp
.X_op
= O_constant
;
230 exp
.X_add_number
= c
;
234 /* Walk backwards in the frag chain. */
236 frag_prev (frag
, seg
)
240 segment_info_type
*seginfo
= seg_info (seg
);
243 for (fragp
= seginfo
->frchainP
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
244 if (fragp
->fr_next
== frag
)
251 bit_offset_frag (frag
, seg
)
257 if (frag
->fr_fix
== 0
258 && frag
->fr_opcode
== NULL
259 && frag
->tc_frag_data
== 0)
260 frag
= frag_prev (frag
, seg
);
267 /* Return the number of bits allocated in the most recent word, or zero if
268 none. .field/.space/.bes may leave words partially allocated. */
270 frag_bit_offset (frag
, seg
)
274 frag
= bit_offset_frag (frag
, seg
);
277 return frag
->fr_opcode
!= NULL
? -1 : frag
->tc_frag_data
;
282 /* Read an expression from a C string; returns a pointer past the end of the
285 parse_expression (char *str
, expressionS
* exp
)
290 tmp
= input_line_pointer
; /* Save line pointer. */
291 input_line_pointer
= str
;
293 s
= input_line_pointer
;
294 input_line_pointer
= tmp
; /* Restore line pointer. */
295 return s
; /* Return pointer to where parsing stopped. */
298 /* .asg "character-string"|character-string, symbol
300 .eval is the only pseudo-op allowed to perform arithmetic on substitution
301 symbols. all other use of symbols defined with .asg are currently
305 int x ATTRIBUTE_UNUSED
;
311 int quoted
= *input_line_pointer
== '"';
313 ILLEGAL_WITHIN_STRUCT ();
318 str
= demand_copy_C_string (&len
);
319 c
= *input_line_pointer
;
323 str
= input_line_pointer
;
324 while ((c
= *input_line_pointer
) != ',')
326 if (is_end_of_line
[(int) *input_line_pointer
])
328 ++input_line_pointer
;
330 *input_line_pointer
= 0;
334 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
335 ignore_rest_of_line ();
339 name
= ++input_line_pointer
;
340 c
= get_symbol_end (); /* Get terminator. */
341 if (!isalpha (*name
))
343 as_bad ("symbols assigned with .asg must begin with a letter");
344 ignore_rest_of_line ();
348 tmp
= xmalloc (strlen (str
) + 1);
351 tmp
= xmalloc (strlen (name
) + 1);
354 subsym_create_or_replace (name
, str
);
355 *input_line_pointer
= c
;
356 demand_empty_rest_of_line ();
359 /* .eval expression, symbol
360 There's something screwy about this. The other assembler sometimes does and
361 sometimes doesn't substitute symbols defined with .eval.
362 We'll put the symbols into the subsym table as well as the normal symbol
363 table, since that's what works best. */
366 int x ATTRIBUTE_UNUSED
;
372 char valuestr
[32], *tmp
;
375 ILLEGAL_WITHIN_STRUCT ();
379 quoted
= *input_line_pointer
== '"';
381 ++input_line_pointer
;
382 value
= get_absolute_expression ();
385 if (*input_line_pointer
!= '"')
387 as_bad (_("Unterminated string after absolute expression"));
388 ignore_rest_of_line ();
391 ++input_line_pointer
;
393 if (*input_line_pointer
++ != ',')
395 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
396 ignore_rest_of_line ();
399 name
= input_line_pointer
;
400 c
= get_symbol_end (); /* Get terminator. */
401 tmp
= xmalloc (strlen (name
) + 1);
402 name
= strcpy (tmp
, name
);
403 *input_line_pointer
= c
;
405 if (!isalpha (*name
))
407 as_bad (_("symbols assigned with .eval must begin with a letter"));
408 ignore_rest_of_line ();
411 symbolP
= symbol_new (name
, absolute_section
,
412 (valueT
) value
, &zero_address_frag
);
413 SF_SET_LOCAL (symbolP
);
414 symbol_table_insert (symbolP
);
416 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
417 But since there's not written rule as to when, don't even bother trying
418 to match their behavior. */
419 sprintf (valuestr
, "%d", value
);
420 tmp
= xmalloc (strlen (valuestr
) + 1);
421 strcpy (tmp
, valuestr
);
422 subsym_create_or_replace (name
, tmp
);
424 demand_empty_rest_of_line ();
427 /* .bss symbol, size [, [blocking flag] [, alignment flag]
429 alignment is to a longword boundary; blocking is to 128-word boundary.
431 1) if there is a hole in memory, this directive should attempt to fill it
432 (not yet implemented).
434 2) if the blocking flag is not set, allocate at the current SPC
435 otherwise, check to see if the current SPC plus the space to be
436 allocated crosses the page boundary (128 words).
437 if there's not enough space, create a hole and align with the next page
439 (not yet implemented). */
442 int x ATTRIBUTE_UNUSED
;
449 subsegT current_subseg
;
454 ILLEGAL_WITHIN_STRUCT ();
456 current_seg
= now_seg
; /* Save current seg. */
457 current_subseg
= now_subseg
; /* Save current subseg. */
459 name
= input_line_pointer
;
460 c
= get_symbol_end (); /* Get terminator. */
463 as_bad (".bss size argument missing\n");
464 ignore_rest_of_line ();
468 ++input_line_pointer
;
469 words
= get_absolute_expression ();
472 as_bad (".bss size %d < 0!", words
);
473 ignore_rest_of_line ();
477 if (*input_line_pointer
== ',')
479 /* the blocking flag may be missing */
480 ++input_line_pointer
;
481 if (*input_line_pointer
!= ',')
482 block
= get_absolute_expression ();
486 if (*input_line_pointer
== ',')
488 ++input_line_pointer
;
489 align
= get_absolute_expression ();
497 subseg_set (bss_section
, 0);
498 symbolP
= symbol_find_or_make (name
);
500 if (S_GET_SEGMENT (symbolP
) == bss_section
)
501 symbolP
->sy_frag
->fr_symbol
= (symbolS
*) NULL
;
503 symbol_set_frag (symbolP
, frag_now
);
504 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
505 (offsetT
) (words
<< 1), (char *) 0);
506 *p
= 0; /* fill char. */
508 S_SET_SEGMENT (symbolP
, bss_section
);
510 /* The symbol may already have been created with a preceding
511 ".globl" directive -- be careful not to step on storage class
512 in that case. Otherwise, set it to static. */
513 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
514 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
518 /* s_align eats end of line; restore it */
520 --input_line_pointer
;
524 bss_section
->flags
|= SEC_BLOCK
;
526 subseg_set (current_seg
, current_subseg
); /* restore current seg. */
527 demand_empty_rest_of_line ();
531 stag_add_field_symbols (stag
, path
, base_offset
, rootsym
, root_stag_name
)
536 const char *root_stag_name
;
538 char prefix
[strlen (path
) + 2];
539 struct stag_field
*field
= stag
->field
;
541 /* Construct a symbol for every field contained within this structure
542 including fields within structure fields. */
543 strcpy (prefix
, path
);
545 strcat (prefix
, ".");
547 while (field
!= NULL
)
549 int len
= strlen (prefix
) + strlen (field
->name
) + 2;
550 char *name
= xmalloc (len
);
551 strcpy (name
, prefix
);
552 strcat (name
, field
->name
);
557 sym
= symbol_new (name
, absolute_section
,
558 (field
->stag
? field
->offset
:
559 (valueT
)(base_offset
+ field
->offset
)),
562 symbol_table_insert (sym
);
566 char *replacement
= xmalloc (strlen (name
) + strlen (stag
->name
) + 2);
567 strcpy (replacement
, S_GET_NAME (rootsym
));
568 strcat (replacement
, "+");
569 strcat (replacement
, root_stag_name
);
570 strcat (replacement
, name
+ strlen (S_GET_NAME (rootsym
)));
571 hash_insert (subsym_hash
[0], name
, replacement
);
574 /* Recurse if the field is a structure.
575 Note the field offset is relative to the outermost struct. */
576 if (field
->stag
!= NULL
)
577 stag_add_field_symbols (field
->stag
, name
,
579 rootsym
, root_stag_name
);
584 /* Keep track of stag fields so that when structures are nested we can add the
585 complete dereferencing symbols to the symbol table. */
587 stag_add_field (parent
, name
, offset
, stag
)
593 struct stag_field
*sfield
= xmalloc (sizeof (struct stag_field
));
595 memset (sfield
, 0, sizeof (*sfield
));
596 sfield
->name
= strcpy (xmalloc (strlen (name
)+1), name
);
597 sfield
->offset
= offset
;
598 sfield
->bitfield_offset
= parent
->current_bitfield_offset
;
600 if (parent
->field
== NULL
)
601 parent
->field
= sfield
;
603 struct stag_field
*sf
= parent
->field
;
604 while (sf
->next
!= NULL
)
608 /* Only create a symbol for this field if the parent has no name. */
609 if (!strncmp (".fake", parent
->name
, 5))
611 symbolS
*sym
= symbol_new (name
, absolute_section
,
612 (valueT
)offset
, &zero_address_frag
);
614 symbol_table_insert (sym
);
618 /* [STAG] .struct [OFFSET]
619 start defining structure offsets (symbols in absolute section). */
621 tic54x_struct (int arg
)
623 int start_offset
= 0;
628 /* Starting a new struct, switch to absolute section. */
629 stag_saved_seg
= now_seg
;
630 stag_saved_subseg
= now_subseg
;
631 subseg_set (absolute_section
, 0);
633 /* Align the current pointer. */
634 else if (current_stag
->current_bitfield_offset
!= 0)
636 ++abs_section_offset
;
637 current_stag
->current_bitfield_offset
= 0;
640 /* Offset expression is only meaningful for global .structs. */
643 /* Offset is ignored in inner structs. */
645 if (!is_end_of_line
[(int)*input_line_pointer
])
646 start_offset
= get_absolute_expression ();
653 /* Nesting, link to outer one. */
654 current_stag
->inner
= (struct stag
*)xmalloc (sizeof (struct stag
));
655 memset (current_stag
->inner
, 0, sizeof (struct stag
));
656 current_stag
->inner
->outer
= current_stag
;
657 current_stag
= current_stag
->inner
;
659 as_warn (_("Offset on nested structures is ignored"));
660 start_offset
= abs_section_offset
;
664 current_stag
= (struct stag
*)xmalloc (sizeof (struct stag
));
665 memset (current_stag
, 0, sizeof (struct stag
));
666 abs_section_offset
= start_offset
;
668 current_stag
->is_union
= is_union
;
670 if (line_label
== NULL
)
672 static int struct_count
= 0;
673 char fake
[] = ".fake_stagNNNNNNN";
674 sprintf (fake
, ".fake_stag%d", struct_count
++);
675 current_stag
->sym
= symbol_new (fake
, absolute_section
,
676 (valueT
)abs_section_offset
,
681 char label
[strlen (S_GET_NAME (line_label
)) + 1];
682 strcpy (label
, S_GET_NAME (line_label
));
683 current_stag
->sym
= symbol_new (label
, absolute_section
,
684 (valueT
)abs_section_offset
,
687 current_stag
->name
= S_GET_NAME (current_stag
->sym
);
688 SF_SET_LOCAL (current_stag
->sym
);
689 /* Nested .structs don't go into the symbol table. */
690 if (current_stag
->outer
== NULL
)
691 symbol_table_insert (current_stag
->sym
);
696 /* [LABEL] .endstruct
697 finish defining structure offsets; optional LABEL's value will be the size
700 tic54x_endstruct (int is_union
)
704 !strncmp (current_stag
->name
, ".fake", 5) ? "" : current_stag
->name
;
706 if (!current_stag
|| current_stag
->is_union
!= is_union
)
708 as_bad (_(".end%s without preceding .%s"),
709 is_union
? "union" : "struct",
710 is_union
? "union" : "struct");
711 ignore_rest_of_line ();
715 /* Align end of structures. */
716 if (current_stag
->current_bitfield_offset
)
718 ++abs_section_offset
;
719 current_stag
->current_bitfield_offset
= 0;
722 if (current_stag
->is_union
)
723 size
= current_stag
->size
;
725 size
= abs_section_offset
- S_GET_VALUE (current_stag
->sym
);
726 if (line_label
!= NULL
)
728 S_SET_VALUE (line_label
, size
);
729 symbol_table_insert (line_label
);
733 /* Union size has already been calculated. */
734 if (!current_stag
->is_union
)
735 current_stag
->size
= size
;
736 /* Nested .structs don't get put in the stag table. */
737 if (current_stag
->outer
== NULL
)
739 hash_insert (stag_hash
, current_stag
->name
, current_stag
);
740 stag_add_field_symbols (current_stag
, path
,
741 S_GET_VALUE (current_stag
->sym
),
744 current_stag
= current_stag
->outer
;
746 /* If this is a nested .struct/.union, add it as a field to the enclosing
747 one. otherwise, restore the section we were in. */
748 if (current_stag
!= NULL
)
750 stag_add_field (current_stag
, current_stag
->inner
->name
,
751 S_GET_VALUE (current_stag
->inner
->sym
),
752 current_stag
->inner
);
755 subseg_set (stag_saved_seg
, stag_saved_subseg
);
759 Reference a structure within a structure, as a sized field with an optional
761 If used outside of a .struct/.endstruct, overlays the given structure
762 format on the existing allocated space. */
765 int ignore ATTRIBUTE_UNUSED
;
767 char *name
= input_line_pointer
;
768 int c
= get_symbol_end ();
769 struct stag
*stag
= (struct stag
*)hash_find (stag_hash
, name
);
774 as_bad (_("Unrecognized struct/union tag '%s'"), name
);
776 as_bad (_(".tag requires a structure tag"));
777 ignore_rest_of_line ();
780 if (line_label
== NULL
)
782 as_bad (_("Label required for .tag"));
783 ignore_rest_of_line ();
788 char label
[strlen (S_GET_NAME (line_label
))+1];
789 strcpy (label
, S_GET_NAME (line_label
));
790 if (current_stag
!= NULL
)
791 stag_add_field (current_stag
, label
,
792 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
796 symbolS
*sym
= symbol_find (label
);
799 as_bad (_(".tag target '%s' undefined"), label
);
800 ignore_rest_of_line ();
803 stag_add_field_symbols (stag
, S_GET_NAME (sym
),
804 S_GET_VALUE (stag
->sym
), sym
, stag
->name
);
808 /* Bump by the struct size, but only if we're within a .struct section. */
809 if (current_stag
!= NULL
&& !current_stag
->is_union
)
810 abs_section_offset
+= stag
->size
;
812 *input_line_pointer
= c
;
813 demand_empty_rest_of_line ();
817 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
818 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
821 tic54x_struct_field (int type
)
825 int new_bitfield_offset
= 0;
826 int field_align
= current_stag
->current_bitfield_offset
!= 0;
827 int longword_align
= 0;
830 if (!is_end_of_line
[(int)*input_line_pointer
])
831 count
= get_absolute_expression ();
847 case '*': /* string */
856 case '.': /* bitfield */
858 if (count
< 1 || count
> 32)
860 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count
);
861 ignore_rest_of_line ();
864 if (current_stag
->current_bitfield_offset
+ count
> 16)
866 /* Set the appropriate size and new field offset. */
874 new_bitfield_offset
= count
- 16;
878 new_bitfield_offset
= count
;
884 new_bitfield_offset
= current_stag
->current_bitfield_offset
+ count
;
888 as_bad (_("Unrecognized field type '%c'"), type
);
889 ignore_rest_of_line ();
895 /* Align to the actual starting position of the field. */
896 current_stag
->current_bitfield_offset
= 0;
897 ++abs_section_offset
;
899 /* Align to longword boundary. */
900 if (longword_align
&& (abs_section_offset
& 0x1))
901 ++abs_section_offset
;
903 if (line_label
== NULL
)
905 static int fieldno
= 0;
906 char fake
[] = ".fake_fieldNNNNN";
907 sprintf (fake
, ".fake_field%d", fieldno
++);
908 stag_add_field (current_stag
, fake
,
909 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
914 char label
[strlen (S_GET_NAME (line_label
) + 1)];
915 strcpy (label
, S_GET_NAME (line_label
));
916 stag_add_field (current_stag
, label
,
917 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
921 if (current_stag
->is_union
)
923 /* Note we treat the element as if it were an array of COUNT. */
924 if (current_stag
->size
< (unsigned)size
* count
)
925 current_stag
->size
= size
* count
;
929 abs_section_offset
+= (unsigned)size
* count
;
930 current_stag
->current_bitfield_offset
= new_bitfield_offset
;
935 /* Handle .byte, .word. .int, .long and all variants. */
936 int emitting_long
= 0;
938 tic54x_cons (int type
)
940 register unsigned int c
;
943 /* If we're within a .struct construct, don't actually allocate space. */
944 if (current_stag
!= NULL
)
946 tic54x_struct_field (type
);
950 #ifdef md_flush_pending_output
951 md_flush_pending_output ();
954 generate_lineno_debug ();
956 /* Align long words to long word boundaries (4 octets). */
957 if (type
== 'l' || type
== 'L')
959 frag_align (2, 0, 2);
960 /* If there's a label, assign it to the first allocated word. */
961 if (line_label
!= NULL
)
963 symbol_set_frag (line_label
, frag_now
);
964 S_SET_VALUE (line_label
, frag_now_fix ());
988 if (*input_line_pointer
== '"')
990 input_line_pointer
++;
991 while (is_a_char (c
= next_char_of_string ()))
992 tic54x_emit_char (c
);
993 know (input_line_pointer
[-1] == '\"');
999 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1000 if (exp
.X_op
== O_constant
)
1002 offsetT value
= exp
.X_add_number
;
1003 /* Truncate overflows. */
1007 if ((value
> 0 && value
> 0xFF)
1008 || (value
< 0 && value
< - 0x100))
1009 as_warn ("Overflow in expression, truncated to 8 bits");
1012 if ((value
> 0 && value
> 0xFFFF)
1013 || (value
< 0 && value
< - 0x10000))
1014 as_warn ("Overflow in expression, truncated to 16 bits");
1018 if (exp
.X_op
!= O_constant
&& octets
< 2)
1020 /* Disallow .byte with a non constant expression that will
1021 require relocation. */
1022 as_bad (_("Relocatable values require at least WORD storage"));
1023 ignore_rest_of_line ();
1027 if (exp
.X_op
!= O_constant
1031 /* FIXME -- at one point TI tools used to output REL16
1032 relocations, but I don't think the latest tools do at all
1033 The current tools output extended relocations regardless of
1034 the addresing mode (I actually think that ".c_mode" is
1035 totally ignored in the latest tools). */
1038 emit_expr (&exp
, 4);
1044 emitting_long
= octets
== 4;
1045 emit_expr (&exp
, (octets
== 1) ? 2 : octets
);
1050 while (*input_line_pointer
++ == ',');
1052 input_line_pointer
--; /* Put terminator back into stream. */
1053 demand_empty_rest_of_line ();
1056 /* .global <symbol>[,...,<symbolN>]
1057 .def <symbol>[,...,<symbolN>]
1058 .ref <symbol>[,...,<symbolN>]
1060 These all identify global symbols.
1062 .def means the symbol is defined in the current module and can be accessed
1063 by other files. The symbol should be placed in the symbol table.
1065 .ref means the symbol is used in the current module but defined in another
1066 module. The linker is to resolve this symbol's definition at link time.
1068 .global should act as a .ref or .def, as needed.
1070 global, def and ref all have symbol storage classes of C_EXT.
1072 I can't identify any difference in how the "other" c54x assembler treats
1073 these, so we ignore the type here. */
1075 tic54x_global (type
)
1083 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1085 ILLEGAL_WITHIN_STRUCT ();
1089 name
= input_line_pointer
;
1090 c
= get_symbol_end ();
1091 symbolP
= symbol_find_or_make (name
);
1093 *input_line_pointer
= c
;
1094 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
1097 input_line_pointer
++;
1098 if (is_end_of_line
[(int)*input_line_pointer
])
1099 c
= *input_line_pointer
;
1104 demand_empty_rest_of_line ();
1107 /* Remove the symbol from the local label hash lookup. */
1109 tic54x_remove_local_label (key
, value
)
1111 PTR value ATTRIBUTE_UNUSED
;
1113 PTR
*elem
= hash_delete (local_label_hash
[macro_level
], key
);
1117 /* Reset all local labels. */
1119 tic54x_clear_local_labels (ignored
)
1120 int ignored ATTRIBUTE_UNUSED
;
1122 hash_traverse (local_label_hash
[macro_level
], tic54x_remove_local_label
);
1127 .sect "section name"
1130 make sure local labels get cleared when changing sections
1132 ARG is 't' for text, 'd' for data, or '*' for a named section
1134 For compatibility, '*' sections have SEC_DATA set instead of SEC_CODE. */
1136 tic54x_sect (int arg
)
1138 ILLEGAL_WITHIN_STRUCT ();
1140 /* Local labels are cleared when changing sections. */
1141 tic54x_clear_local_labels (0);
1145 else if (arg
== 'd')
1151 /* If there are quotes, remove them. */
1152 if (*input_line_pointer
== '"')
1154 name
= demand_copy_C_string (&len
);
1155 demand_empty_rest_of_line ();
1156 name
= strcpy (xmalloc (len
+10), name
);
1161 name
= input_line_pointer
;
1162 c
= get_symbol_end ();
1163 name
= strcpy (xmalloc (len
+10), name
);
1164 *input_line_pointer
= c
;
1165 demand_empty_rest_of_line ();
1167 /* Make sure all named initialized sections are SEC_DATA. */
1168 strcat (name
, ",\"w\"\n");
1169 input_scrub_insert_line (name
);
1170 obj_coff_section (0);
1172 /* If there was a line label, make sure that it gets assigned the proper
1173 section. This is for compatibility, even though the actual behavior
1174 is not explicitly defined. For consistency, we make .sect behave
1175 like .usect, since that is probably what people expect. */
1176 if (line_label
!= NULL
)
1178 S_SET_SEGMENT (line_label
, now_seg
);
1179 symbol_set_frag (line_label
, frag_now
);
1180 S_SET_VALUE (line_label
, frag_now_fix ());
1181 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1182 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1187 /* [symbol] .space space_in_bits
1188 [symbol] .bes space_in_bits
1189 BES puts the symbol at the *last* word allocated
1191 cribbed from s_space. */
1193 tic54x_space (int arg
)
1199 int bits_per_byte
= (OCTETS_PER_BYTE
* 8);
1201 symbolS
*label
= line_label
;
1204 ILLEGAL_WITHIN_STRUCT ();
1206 #ifdef md_flush_pending_output
1207 md_flush_pending_output ();
1210 /* Read the bit count. */
1213 /* Some expressions are unresolvable until later in the assembly pass;
1214 postpone until relaxation/fixup. we also have to postpone if a previous
1215 partial allocation has not been completed yet. */
1216 if (exp
.X_op
!= O_constant
|| frag_bit_offset (frag_now
, now_seg
) == -1)
1218 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1224 p
= frag_var (rs_machine_dependent
,
1225 65536*2, 1, (relax_substateT
) 0,
1226 make_expr_symbol (&exp
), (offsetT
) 0,
1234 /* Reduce the required size by any bit offsets currently left over
1235 from a previous .space/.bes/.field directive. */
1236 bit_offset
= frag_now
->tc_frag_data
;
1237 if (bit_offset
!= 0 && bit_offset
< 16)
1239 int spare_bits
= bits_per_byte
- bit_offset
;
1240 if (spare_bits
>= exp
.X_add_number
)
1242 /* Don't have to do anything; sufficient bits have already been
1243 allocated; just point the label to the right place. */
1246 symbol_set_frag (label
, frag_now
);
1247 S_SET_VALUE (label
, frag_now_fix () - 1);
1250 frag_now
->tc_frag_data
+= exp
.X_add_number
;
1253 exp
.X_add_number
-= spare_bits
;
1254 /* Set the label to point to the first word allocated, which in this
1255 case is the previous word, which was only partially filled. */
1256 if (!bes
&& label
!= NULL
)
1258 symbol_set_frag (label
, frag_now
);
1259 S_SET_VALUE (label
, frag_now_fix () - 1);
1263 /* Convert bits to bytes/words and octets, rounding up. */
1264 words
= ((exp
.X_add_number
+ bits_per_byte
- 1) / bits_per_byte
);
1265 /* How many do we have left over? */
1266 bit_offset
= exp
.X_add_number
% bits_per_byte
;
1267 octets
= words
* OCTETS_PER_BYTE
;
1270 as_warn (_(".space/.bes repeat count is negative, ignored"));
1273 else if (octets
== 0)
1275 as_warn (_(".space/.bes repeat count is zero, ignored"));
1279 /* If we are in the absolute section, just bump the offset. */
1280 if (now_seg
== absolute_section
)
1282 abs_section_offset
+= words
;
1283 if (bes
&& label
!= NULL
)
1284 S_SET_VALUE (label
, abs_section_offset
- 1);
1285 frag_now
->tc_frag_data
= bit_offset
;
1290 p
= frag_var (rs_fill
, 1, 1,
1291 (relax_substateT
) 0, (symbolS
*) 0,
1292 (offsetT
) octets
, (char *) 0);
1294 /* Make note of how many bits of this word we've allocated so far. */
1295 frag_now
->tc_frag_data
= bit_offset
;
1297 /* .bes puts label at *last* word allocated. */
1298 if (bes
&& label
!= NULL
)
1300 symbol_set_frag (label
, frag_now
);
1301 S_SET_VALUE (label
, frag_now_fix ()-1);
1309 demand_empty_rest_of_line ();
1312 /* [symbol] .usect "section-name", size-in-words
1313 [, [blocking-flag] [, alignment-flag]]
1315 Unitialized section.
1316 Non-zero blocking means that if the section would cross a page (128-word)
1317 boundary, it will be page-aligned.
1318 Non-zero alignment aligns on a longword boundary.
1320 Has no effect on the current section. */
1323 int x ATTRIBUTE_UNUSED
;
1330 int size
, blocking_flag
, alignment_flag
;
1332 subsegT current_subseg
;
1335 ILLEGAL_WITHIN_STRUCT ();
1337 current_seg
= now_seg
; /* save current seg. */
1338 current_subseg
= now_subseg
; /* save current subseg. */
1340 if (*input_line_pointer
== '"')
1341 input_line_pointer
++;
1342 section_name
= input_line_pointer
;
1343 c
= get_symbol_end (); /* Get terminator. */
1344 input_line_pointer
++; /* Skip null symbol terminator. */
1345 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1346 strcpy (name
, section_name
);
1348 if (*input_line_pointer
== ',')
1349 ++input_line_pointer
;
1352 as_bad (_("Missing size argument"));
1353 ignore_rest_of_line ();
1357 size
= get_absolute_expression ();
1359 /* Read a possibly present third argument (blocking flag). */
1360 if (*input_line_pointer
== ',')
1362 ++input_line_pointer
;
1363 if (*input_line_pointer
!= ',')
1364 blocking_flag
= get_absolute_expression ();
1368 /* Read a possibly present fourth argument (alignment flag). */
1369 if (*input_line_pointer
== ',')
1371 ++input_line_pointer
;
1372 alignment_flag
= get_absolute_expression ();
1378 blocking_flag
= alignment_flag
= 0;
1380 seg
= subseg_new (name
, 0);
1381 flags
= bfd_get_section_flags (stdoutput
, seg
) | SEC_ALLOC
;
1385 /* s_align eats end of line; restore it. */
1387 --input_line_pointer
;
1390 if (line_label
!= NULL
)
1392 S_SET_SEGMENT (line_label
, seg
);
1393 symbol_set_frag (line_label
, frag_now
);
1394 S_SET_VALUE (line_label
, frag_now_fix ());
1395 /* set scl to label, since that's what TI does */
1396 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1397 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1400 seg_info (seg
)->bss
= 1; /* Uninitialized data. */
1402 p
= frag_var (rs_fill
, 1, 1,
1403 (relax_substateT
) 0, (symbolS
*) line_label
,
1404 size
* OCTETS_PER_BYTE
, (char *) 0);
1410 if (!bfd_set_section_flags (stdoutput
, seg
, flags
))
1411 as_warn ("Error setting flags for \"%s\": %s", name
,
1412 bfd_errmsg (bfd_get_error ()));
1414 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1415 demand_empty_rest_of_line ();
1418 static enum cpu_version
1419 lookup_version (ver
)
1422 enum cpu_version version
= VNONE
;
1424 if (ver
[0] == '5' && ver
[1] == '4')
1426 if (strlen (ver
) == 3 &&
1427 (ver
[2] == '1' || ver
[2] == '2' || ver
[2] == '3' ||
1428 ver
[2] == '5' || ver
[2] == '8' || ver
[2] == '9'))
1429 version
= ver
[2] - '0';
1430 else if (strlen (ver
) == 5 &&
1431 toupper (ver
[3]) == 'L' &&
1432 toupper (ver
[4]) == 'P' &&
1433 (ver
[2] == '5' || ver
[2] == '6'))
1434 version
= ver
[2] - '0' + 10;
1442 enum cpu_version version
;
1445 if (version
== V545LP
|| version
== V546LP
)
1447 symbolS
*symbolP
= symbol_new ("__allow_lp", absolute_section
,
1448 (valueT
)1, &zero_address_frag
);
1449 SF_SET_LOCAL (symbolP
);
1450 symbol_table_insert (symbolP
);
1454 /* .version cpu-version
1455 cpu-version may be one of the following:
1465 This is for compatibility only. It currently has no affect on assembly. */
1466 static int cpu_needs_set
= 1;
1470 int x ATTRIBUTE_UNUSED
;
1472 enum cpu_version version
= VNONE
;
1473 enum cpu_version old_version
= cpu
;
1477 ILLEGAL_WITHIN_STRUCT ();
1480 ver
= input_line_pointer
;
1481 while (!is_end_of_line
[(int)*input_line_pointer
])
1482 ++input_line_pointer
;
1483 c
= *input_line_pointer
;
1484 *input_line_pointer
= 0;
1486 version
= lookup_version (ver
);
1488 if (cpu
!= VNONE
&& cpu
!= version
)
1489 as_warn (_("CPU version has already been set"));
1491 if (version
== VNONE
)
1493 as_bad (_("Unrecognized version '%s'"), ver
);
1494 ignore_rest_of_line ();
1497 else if (assembly_begun
&& version
!= old_version
)
1499 as_bad (_("Changing of CPU version on the fly not supported"));
1500 ignore_rest_of_line ();
1506 *input_line_pointer
= c
;
1507 demand_empty_rest_of_line ();
1510 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1512 tic54x_float_cons (int type
)
1514 if (current_stag
!= 0)
1515 tic54x_struct_field ('f');
1517 #ifdef md_flush_pending_output
1518 md_flush_pending_output ();
1521 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1524 frag_align (2, 0, 2);
1525 /* If there's a label, assign it to the first allocated word. */
1526 if (line_label
!= NULL
)
1528 symbol_set_frag (line_label
, frag_now
);
1529 S_SET_VALUE (line_label
, frag_now_fix ());
1536 /* The argument is capitalized if it should be zero-terminated
1537 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1538 Code copied from read.c, and slightly modified so that strings are packed
1539 and encoded into the correct octets. */
1541 tic54x_stringer (type
)
1544 register unsigned int c
;
1546 int append_zero
= type
== 'S' || type
== 'P';
1547 int packed
= type
== 'p' || type
== 'P';
1548 int last_char
= -1; /* Packed strings need two bytes at a time to encode. */
1550 if (current_stag
!= NULL
)
1552 tic54x_struct_field ('*');
1556 #ifdef md_flush_pending_output
1557 md_flush_pending_output ();
1560 c
= ','; /* Do loop. */
1564 switch (*input_line_pointer
)
1568 unsigned short value
= get_absolute_expression ();
1569 FRAG_APPEND_1_CHAR (value
&0xFF);
1570 FRAG_APPEND_1_CHAR ((value
>>8)&0xFF);
1574 ++input_line_pointer
; /*->1st char of string. */
1575 start
= input_line_pointer
;
1576 while (is_a_char (c
= next_char_of_string ()))
1580 FRAG_APPEND_1_CHAR (c
);
1581 FRAG_APPEND_1_CHAR (0);
1585 /* Packed strings are filled MS octet first. */
1586 if (last_char
== -1)
1590 FRAG_APPEND_1_CHAR (c
);
1591 FRAG_APPEND_1_CHAR (last_char
);
1598 if (packed
&& last_char
!= -1)
1600 FRAG_APPEND_1_CHAR (0);
1601 FRAG_APPEND_1_CHAR (last_char
);
1606 FRAG_APPEND_1_CHAR (0);
1607 FRAG_APPEND_1_CHAR (0);
1610 know (input_line_pointer
[-1] == '\"');
1614 c
= *input_line_pointer
;
1615 if (!is_end_of_line
[c
])
1616 ++input_line_pointer
;
1619 /* Finish up any leftover packed string. */
1620 if (packed
&& last_char
!= -1)
1622 FRAG_APPEND_1_CHAR (0);
1623 FRAG_APPEND_1_CHAR (last_char
);
1625 demand_empty_rest_of_line ();
1629 tic54x_p2align (arg
)
1630 int arg ATTRIBUTE_UNUSED
;
1632 as_bad (_("p2align not supported on this target"));
1636 tic54x_align_words (arg
)
1639 /* Only ".align" with no argument is allowed within .struct/.union. */
1642 if (!is_end_of_line
[(int)*input_line_pointer
])
1645 as_warn (_("Argument to .even ignored"));
1647 count
= get_absolute_expression ();
1650 if (current_stag
!= NULL
&& arg
== 128)
1652 if (current_stag
->current_bitfield_offset
!= 0)
1654 current_stag
->current_bitfield_offset
= 0;
1655 ++abs_section_offset
;
1657 demand_empty_rest_of_line ();
1661 ILLEGAL_WITHIN_STRUCT ();
1663 s_align_bytes (count
<< 1);
1666 /* Initialize multiple-bit fields withing a single word of memory. */
1668 tic54x_field (ignore
)
1669 int ignore ATTRIBUTE_UNUSED
;
1675 symbolS
*label
= line_label
;
1677 if (current_stag
!= NULL
)
1679 tic54x_struct_field ('.');
1683 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1685 if (*input_line_pointer
== ',')
1687 ++input_line_pointer
;
1688 size
= get_absolute_expression ();
1689 if (size
< 1 || size
> 32)
1691 as_bad (_("Invalid field size, must be from 1 to 32"));
1692 ignore_rest_of_line ();
1697 /* Truncate values to the field width. */
1698 if (exp
.X_op
!= O_constant
)
1700 /* If the expression value is relocatable, the field size *must* be 16. */
1703 as_bad (_("field size must be 16 when value is relocatable"));
1704 ignore_rest_of_line ();
1708 frag_now
->tc_frag_data
= 0;
1709 emit_expr (&exp
, 2);
1713 unsigned long fmask
= (size
== 32) ? 0xFFFFFFFF : (1ul << size
) - 1;
1714 value
= exp
.X_add_number
;
1715 exp
.X_add_number
&= fmask
;
1716 if (value
!= (valueT
)exp
.X_add_number
)
1717 as_warn (_("field value truncated"));
1718 value
= exp
.X_add_number
;
1719 /* Bits are stored MS first. */
1722 frag_now
->tc_frag_data
= 0;
1724 md_number_to_chars (p
, (value
>> (size
- 16)) & 0xFFFF, 2);
1729 int bit_offset
= frag_bit_offset (frag_now
, now_seg
);
1730 fragS
*alloc_frag
= bit_offset_frag (frag_now
, now_seg
);
1731 if (bit_offset
== -1)
1733 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1734 /* We don't know the previous offset at this time, so store the
1735 info we need and figure it out later. */
1736 expressionS size_exp
;
1737 size_exp
.X_op
= O_constant
;
1738 size_exp
.X_add_number
= size
;
1740 bi
->type
= TYPE_FIELD
;
1742 p
= frag_var (rs_machine_dependent
,
1743 4, 1, (relax_substateT
) 0,
1744 make_expr_symbol (&size_exp
), (offsetT
) 0,
1748 else if (bit_offset
== 0 || bit_offset
+ size
> 16)
1750 /* Align a new field. */
1752 frag_now
->tc_frag_data
= 0;
1753 alloc_frag
= frag_now
;
1757 /* Put the new value entirely within the existing one. */
1758 p
= alloc_frag
== frag_now
?
1759 frag_now
->fr_literal
+ frag_now_fix_octets () - 2 :
1760 alloc_frag
->fr_literal
;
1763 symbol_set_frag (label
, alloc_frag
);
1764 if (alloc_frag
== frag_now
)
1765 S_SET_VALUE (label
, frag_now_fix () - 1);
1769 value
<<= 16 - alloc_frag
->tc_frag_data
- size
;
1771 /* OR in existing value. */
1772 if (alloc_frag
->tc_frag_data
)
1773 value
|= ((unsigned short)p
[1]<<8) | p
[0];
1774 md_number_to_chars (p
, value
, 2);
1775 alloc_frag
->tc_frag_data
+= size
;
1776 if (alloc_frag
->tc_frag_data
== 16)
1777 alloc_frag
->tc_frag_data
= 0;
1781 demand_empty_rest_of_line ();
1784 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1785 available yet. seg_info ()->bss is the next best thing. */
1787 tic54x_initialized_section (seg
)
1790 return !seg_info (seg
)->bss
;
1793 /* .clink ["section name"]
1795 Marks the section as conditionally linked (link only if contents are
1796 referenced elsewhere.
1797 Without a name, refers to the current initialized section.
1798 Name is required for uninitialized sections. */
1800 tic54x_clink (ignored
)
1801 int ignored ATTRIBUTE_UNUSED
;
1805 ILLEGAL_WITHIN_STRUCT ();
1807 if (*input_line_pointer
== '\"')
1809 char *section_name
= ++input_line_pointer
;
1811 while (is_a_char (next_char_of_string ()))
1813 know (input_line_pointer
[-1] == '\"');
1814 input_line_pointer
[-1] = 0;
1815 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1816 strcpy (name
, section_name
);
1818 seg
= bfd_get_section_by_name (stdoutput
, name
);
1821 as_bad (_("Unrecognized section '%s'"), section_name
);
1822 ignore_rest_of_line ();
1828 if (!tic54x_initialized_section (seg
))
1830 as_bad (_("Current section is unitialized, "
1831 "section name required for .clink"));
1832 ignore_rest_of_line ();
1837 seg
->flags
|= SEC_CLINK
;
1839 demand_empty_rest_of_line ();
1842 /* Change the default include directory to be the current source file's
1843 directory, instead of the current working directory. If DOT is non-zero,
1844 set to "." instead. */
1846 tic54x_set_default_include (dot
)
1857 as_where (&curfile
, &lineno
);
1858 dir
= strcpy (xmalloc (strlen (curfile
)+1), curfile
);
1859 tmp
= strrchr (dir
, '/');
1866 if (include_dir_count
== 0)
1868 include_dirs
= (char **) xmalloc (sizeof (*include_dirs
));
1869 include_dir_count
= 1;
1871 include_dirs
[0] = dir
;
1872 if (len
> include_dir_maxlen
)
1873 include_dir_maxlen
= len
;
1875 else if (include_dirs
!= NULL
)
1876 include_dirs
[0] = ".";
1879 /* .include "filename" | filename
1880 .copy "filename" | filename
1882 FIXME 'include' file should be omitted from any output listing,
1883 'copy' should be included in any output listing
1884 FIXME -- prevent any included files from changing listing (compat only)
1885 FIXME -- need to include source file directory in search path; what's a
1886 good way to do this?
1888 Entering/exiting included/copied file clears all local labels. */
1890 tic54x_include (ignored
)
1891 int ignored ATTRIBUTE_UNUSED
;
1893 char newblock
[] = " .newblock\n";
1898 ILLEGAL_WITHIN_STRUCT ();
1902 if (*input_line_pointer
== '"')
1904 filename
= demand_copy_C_string (&len
);
1905 demand_empty_rest_of_line ();
1909 filename
= input_line_pointer
;
1910 while (!is_end_of_line
[(int)*input_line_pointer
])
1911 ++input_line_pointer
;
1912 c
= *input_line_pointer
;
1913 *input_line_pointer
= '\0';
1914 filename
= strcpy (xmalloc (strlen (filename
)+1), filename
);
1915 *input_line_pointer
= c
;
1916 demand_empty_rest_of_line ();
1918 /* Insert a partial line with the filename (for the sake of s_include)
1920 The included file will be inserted before the newblock, so that the
1921 newblock is executed after the included file is processed. */
1922 input
= xmalloc (sizeof (newblock
) + strlen (filename
) + 4);
1923 sprintf (input
, "\"%s\"\n%s", filename
, newblock
);
1924 input_scrub_insert_line (input
);
1926 tic54x_clear_local_labels (0);
1928 tic54x_set_default_include (0);
1934 tic54x_message (type
)
1941 ILLEGAL_WITHIN_STRUCT ();
1943 if (*input_line_pointer
== '"')
1944 msg
= demand_copy_C_string (&len
);
1947 msg
= input_line_pointer
;
1948 while (! is_end_of_line
[(int)*input_line_pointer
])
1949 ++input_line_pointer
;
1950 c
= *input_line_pointer
;
1951 *input_line_pointer
= 0;
1952 msg
= strcpy (xmalloc (strlen (msg
) + 1), msg
);
1953 *input_line_pointer
= c
;
1959 as_tsktsk ("%s", msg
);
1962 as_warn ("%s", msg
);
1969 demand_empty_rest_of_line ();
1973 define a special symbol that refers to the loadtime address rather than the
1974 runtime address within the current section.
1976 This symbol gets a special storage class so that when it is resolved, it is
1977 resolved relative to the load address (lma) of the section rather than the
1978 run address (vma). */
1980 tic54x_label (ignored
)
1981 int ignored ATTRIBUTE_UNUSED
;
1983 char *name
= input_line_pointer
;
1987 ILLEGAL_WITHIN_STRUCT ();
1989 c
= get_symbol_end ();
1990 symbolP
= colon (name
);
1991 S_SET_STORAGE_CLASS (symbolP
, C_STATLAB
);
1993 *input_line_pointer
= c
;
1994 demand_empty_rest_of_line ();
1998 install all memory-mapped register names into the symbol table as absolute
2001 tic54x_mmregs (ignored
)
2002 int ignored ATTRIBUTE_UNUSED
;
2006 ILLEGAL_WITHIN_STRUCT ();
2008 for (sym
= (symbol
*)mmregs
; sym
->name
; sym
++)
2010 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
2011 (valueT
) sym
->value
, &zero_address_frag
);
2012 SF_SET_LOCAL (symbolP
);
2013 symbol_table_insert (symbolP
);
2018 count defaults to 1024. */
2020 tic54x_loop (int count
)
2022 ILLEGAL_WITHIN_STRUCT ();
2025 if (!is_end_of_line
[(int)*input_line_pointer
])
2026 count
= get_absolute_expression ();
2028 do_repeat (count
, "LOOP", "ENDLOOP");
2031 /* Normally, endloop gets eaten by the preceding loop. */
2033 tic54x_endloop (ignore
)
2034 int ignore ATTRIBUTE_UNUSED
;
2036 as_bad (_("ENDLOOP without corresponding LOOP"));
2037 ignore_rest_of_line ();
2040 /* .break [condition]. */
2042 tic54x_break (ignore
)
2043 int ignore ATTRIBUTE_UNUSED
;
2047 ILLEGAL_WITHIN_STRUCT ();
2050 if (!is_end_of_line
[(int)*input_line_pointer
])
2052 cond
= get_absolute_expression ();
2056 end_repeat (substitution_line
? 1 : 0);
2061 set_address_mode (mode
)
2065 if (mode
== far_mode
)
2067 symbolS
*symbolP
= symbol_new ("__allow_far", absolute_section
,
2068 (valueT
)1, &zero_address_frag
);
2069 SF_SET_LOCAL (symbolP
);
2070 symbol_table_insert (symbolP
);
2074 static int address_mode_needs_set
= 1;
2076 tic54x_address_mode (mode
)
2079 if (assembly_begun
&& amode
!= (unsigned)mode
)
2081 as_bad (_("Mixing of normal and extended addressing not supported"));
2082 ignore_rest_of_line ();
2085 if (mode
== far_mode
&& cpu
!= VNONE
&& cpu
!= V548
&& cpu
!= V549
)
2087 as_bad (_("Extended addressing not supported on the specified CPU"));
2088 ignore_rest_of_line ();
2092 set_address_mode (mode
);
2093 demand_empty_rest_of_line ();
2096 /* .sblock "section"|section [,...,"section"|section]
2097 designate initialized sections for blocking. */
2099 tic54x_sblock (ignore
)
2100 int ignore ATTRIBUTE_UNUSED
;
2104 ILLEGAL_WITHIN_STRUCT ();
2111 if (*input_line_pointer
== '"')
2114 name
= demand_copy_C_string (&len
);
2118 char *section_name
= input_line_pointer
;
2119 c
= get_symbol_end ();
2120 name
= xmalloc (strlen (section_name
)+1);
2121 strcpy (name
, section_name
);
2122 *input_line_pointer
= c
;
2125 seg
= bfd_get_section_by_name (stdoutput
, name
);
2128 as_bad (_("Unrecognized section '%s'"), name
);
2129 ignore_rest_of_line ();
2132 else if (!tic54x_initialized_section (seg
))
2134 as_bad (_(".sblock may be used for initialized sections only"));
2135 ignore_rest_of_line ();
2138 seg
->flags
|= SEC_BLOCK
;
2140 c
= *input_line_pointer
;
2141 if (!is_end_of_line
[(int)c
])
2142 ++input_line_pointer
;
2145 demand_empty_rest_of_line ();
2148 /* symbol .set value
2151 value must be defined externals; no forward-referencing allowed
2152 symbols assigned with .set/.equ may not be redefined. */
2155 int ignore ATTRIBUTE_UNUSED
;
2160 ILLEGAL_WITHIN_STRUCT ();
2164 as_bad (_("Symbol missing for .set/.equ"));
2165 ignore_rest_of_line ();
2168 name
= xstrdup (S_GET_NAME (line_label
));
2170 if ((symbolP
= symbol_find (name
)) == NULL
2171 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2173 symbolP
= symbol_new (name
, absolute_section
, 0, &zero_address_frag
);
2174 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2177 S_SET_DATA_TYPE (symbolP
, T_INT
);
2178 S_SET_SEGMENT (symbolP
, absolute_section
);
2179 symbol_table_insert (symbolP
);
2180 pseudo_set (symbolP
);
2181 demand_empty_rest_of_line ();
2186 list false conditional blocks. */
2188 tic54x_fclist (int show
)
2191 listing
&= ~LISTING_NOCOND
;
2193 listing
|= LISTING_NOCOND
;
2194 demand_empty_rest_of_line ();
2198 tic54x_sslist (int show
)
2200 ILLEGAL_WITHIN_STRUCT ();
2202 listing_sslist
= show
;
2205 /* .var SYM[,...,SYMN]
2206 define a substitution string to be local to a macro. */
2209 int ignore ATTRIBUTE_UNUSED
;
2211 static char empty
[] = "";
2215 ILLEGAL_WITHIN_STRUCT ();
2217 if (macro_level
== 0)
2219 as_bad (_(".var may only be used within a macro definition"));
2220 ignore_rest_of_line ();
2225 if (!isalpha (*input_line_pointer
))
2227 as_bad (_("Substitution symbols must begin with a letter"));
2228 ignore_rest_of_line ();
2231 name
= input_line_pointer
;
2232 c
= get_symbol_end ();
2233 /* .var symbols start out with a null string */
2234 name
= strcpy (xmalloc (strlen (name
)+1), name
);
2235 hash_insert (subsym_hash
[macro_level
], name
, empty
);
2236 *input_line_pointer
= c
;
2239 ++input_line_pointer
;
2240 if (is_end_of_line
[(int)*input_line_pointer
])
2241 c
= *input_line_pointer
;
2246 demand_empty_rest_of_line ();
2249 /* .mlib <macro library filename>
2251 Macro libraries are archived (standard AR-format) text macro definitions
2252 Expand the file and include it.
2254 FIXME need to try the source file directory as well. */
2256 tic54x_mlib (ignore
)
2257 int ignore ATTRIBUTE_UNUSED
;
2264 ILLEGAL_WITHIN_STRUCT ();
2266 /* parse the filename */
2267 if (*input_line_pointer
== '"')
2269 if ((filename
= demand_copy_C_string (&len
)) == NULL
)
2276 while (! is_end_of_line
[(int)*input_line_pointer
]
2277 && !isspace (*input_line_pointer
))
2279 obstack_1grow (¬es
, *input_line_pointer
);
2280 ++input_line_pointer
;
2283 obstack_1grow (¬es
, '\0');
2284 filename
= obstack_finish (¬es
);
2286 demand_empty_rest_of_line ();
2288 tic54x_set_default_include (0);
2289 path
= xmalloc ((unsigned long) len
+ include_dir_maxlen
+ 5);
2290 for (i
=0;i
< include_dir_count
; i
++)
2293 strcpy (path
, include_dirs
[i
]);
2295 strcat (path
, filename
);
2296 if ((try = fopen (path
, "r")) != NULL
)
2302 if (i
>= include_dir_count
)
2308 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2309 happens all over the place, and since the assembler doesn't usually keep
2310 running for a very long time, it really doesn't matter... */
2311 register_dependency (path
);
2313 /* Expand all archive entries to temporary files and include them. */
2314 abfd
= bfd_openr (path
, NULL
);
2317 as_bad (_("Can't open macro library file '%s' for reading."), path
);
2318 as_perror ("%s", path
);
2319 ignore_rest_of_line ();
2322 if (!bfd_check_format (abfd
, bfd_archive
))
2324 as_bad (_("File '%s' not in macro archive format"), path
);
2325 ignore_rest_of_line ();
2329 /* Open each BFD as binary (it should be straight ASCII text). */
2330 for (mbfd
= bfd_openr_next_archived_file (abfd
, NULL
);
2331 mbfd
!= NULL
; mbfd
= bfd_openr_next_archived_file (abfd
, mbfd
))
2333 /* Get a size at least as big as the archive member. */
2334 bfd_size_type size
= bfd_get_size (mbfd
);
2335 char *buf
= xmalloc (size
);
2336 char *fname
= tmpnam (NULL
);
2339 /* We're not sure how big it is, but it will be smaller than "size". */
2340 bfd_read (buf
, size
, 1, mbfd
);
2342 /* Write to a temporary file, then use s_include to include it
2343 a bit of a hack... */
2344 ftmp
= fopen (fname
, "w+b");
2345 fwrite ((void *)buf
, size
, 1, ftmp
);
2346 if (buf
[size
-1] != '\n')
2347 fwrite ("\n", 1, 1, ftmp
);
2350 input_scrub_insert_file (fname
);
2355 const pseudo_typeS md_pseudo_table
[] =
2357 { "algebraic", s_ignore
, 0 },
2358 { "align", tic54x_align_words
, 128 },
2359 { "even", tic54x_align_words
, 2 },
2360 { "asg", tic54x_asg
, 0 },
2361 { "eval", tic54x_eval
, 0 },
2362 { "bss", tic54x_bss
, 0 },
2363 { "byte", tic54x_cons
, 'b' },
2364 { "ubyte", tic54x_cons
, 'B' },
2365 { "char", tic54x_cons
, 'c' },
2366 { "uchar", tic54x_cons
, 'C' },
2367 { "clink", tic54x_clink
, 0 },
2368 { "c_mode", tic54x_address_mode
, c_mode
},
2369 { "copy", tic54x_include
, 'c' },
2370 { "include", tic54x_include
, 'i' },
2371 { "data", tic54x_sect
, 'd' },
2372 { "double", tic54x_float_cons
, 'd' },
2373 { "ldouble", tic54x_float_cons
, 'l' },
2374 { "drlist", s_ignore
, 0 },
2375 { "drnolist", s_ignore
, 0 },
2376 { "emsg", tic54x_message
, 'e' },
2377 { "mmsg", tic54x_message
, 'm' },
2378 { "wmsg", tic54x_message
, 'w' },
2379 /*{ "end", s_end, 0 }, */
2380 { "far_mode", tic54x_address_mode
, far_mode
},
2381 { "fclist", tic54x_fclist
, 1 },
2382 { "fcnolist", tic54x_fclist
, 0 },
2383 { "field", tic54x_field
, -1 },
2384 { "float", tic54x_float_cons
, 'f' },
2385 { "xfloat", tic54x_float_cons
, 'x' },
2386 { "global", tic54x_global
, 'g' },
2387 { "def", tic54x_global
, 'd' },
2388 { "ref", tic54x_global
, 'r' },
2389 { "half", tic54x_cons
, 'h' },
2390 { "uhalf", tic54x_cons
, 'H' },
2391 { "short", tic54x_cons
, 's' },
2392 { "ushort", tic54x_cons
, 'S' },
2393 { "if", s_if
, (int)O_ne
},
2394 { "elseif", s_elseif
, (int)O_ne
},
2395 { "else", s_else
, 0 },
2396 { "endif", s_endif
, 0 },
2397 { "int", tic54x_cons
, 'i' },
2398 { "uint", tic54x_cons
, 'I' },
2399 { "word", tic54x_cons
, 'w' },
2400 { "uword", tic54x_cons
, 'W' },
2401 { "label", tic54x_label
, 0 }, /* loadtime address */
2402 { "length", s_ignore
, 0 },
2403 { "width", s_ignore
, 0 },
2404 /*{ "list", listing_list, 1 }, */
2405 /*{ "nolist", listing_list, 0 }, */
2406 { "long", tic54x_cons
, 'l' },
2407 { "ulong", tic54x_cons
, 'L' },
2408 { "xlong", tic54x_cons
, 'x' },
2409 { "loop", tic54x_loop
, 1024 },
2410 { "break", tic54x_break
, 0 },
2411 { "endloop", tic54x_endloop
, 0 },
2412 { "mlib", tic54x_mlib
, 0 },
2413 { "mlist", s_ignore
, 0 },
2414 { "mnolist", s_ignore
, 0 },
2415 { "mmregs", tic54x_mmregs
, 0 },
2416 { "newblock", tic54x_clear_local_labels
, 0 },
2417 { "option", s_ignore
, 0 },
2418 { "p2align", tic54x_p2align
, 0 },
2419 /*{ "page", listing_eject, 0 }, */
2420 { "sblock", tic54x_sblock
, 0 },
2421 { "sect", tic54x_sect
, '*' },
2422 { "set", tic54x_set
, 0 },
2423 { "equ", tic54x_set
, 0 },
2424 { "space", tic54x_space
, 0 },
2425 { "bes", tic54x_space
, 1 },
2426 { "sslist", tic54x_sslist
, 1 },
2427 { "ssnolist", tic54x_sslist
, 0 },
2428 { "string", tic54x_stringer
, 's' },
2429 { "pstring", tic54x_stringer
, 'p' },
2430 { "struct", tic54x_struct
, 0 },
2431 { "tag", tic54x_tag
, 0 },
2432 { "endstruct", tic54x_endstruct
, 0 },
2433 { "tab", s_ignore
, 0 },
2434 { "text", tic54x_sect
, 't' },
2435 /*{ "title", listing_title, 0 }, */
2436 { "union", tic54x_struct
, 1 },
2437 { "endunion", tic54x_endstruct
, 1 },
2438 { "usect", tic54x_usect
, 0 },
2439 { "var", tic54x_var
, 0 },
2440 { "version", tic54x_version
, 0 },
2445 /* For debugging, strings for each operand type. */
2446 static const char *optypes
[] =
2448 "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
2449 "Sind", "xpmad", "xpmad+", "MMRX", "MMRY",
2450 "SRC1", "SRC", "RND", "DST",
2453 "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031",
2454 "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
2460 md_parse_option (c
, arg
)
2468 case OPTION_COFF_VERSION
:
2470 int version
= atoi (arg
);
2471 if (version
!= 0 && version
!= 1 && version
!= 2)
2472 as_fatal (_("Bad COFF version '%s'"), arg
);
2473 /* FIXME -- not yet implemented */
2476 case OPTION_CPU_VERSION
:
2478 cpu
= lookup_version (arg
);
2481 as_fatal (_("Bad CPU version '%s'"), arg
);
2484 case OPTION_ADDRESS_MODE
:
2486 address_mode_needs_set
= 1;
2488 case OPTION_STDERR_TO_FILE
:
2490 char *filename
= arg
;
2491 FILE *fp
= fopen (filename
, "w+");
2493 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2495 if ((fp
= freopen (filename
, "w+", stderr
)) == NULL
)
2496 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2504 /* Create a "local" substitution string hash table for a new macro level
2505 Some docs imply that macros have to use .newblock in order to be able
2506 to re-use a local label. We effectively do an automatic .newblock by
2507 deleting the local label hash between macro invocations. */
2509 tic54x_macro_start ()
2512 subsym_hash
[macro_level
] = hash_new ();
2513 local_label_hash
[macro_level
] = hash_new ();
2517 tic54x_macro_info (info
)
2520 struct formal_struct
2522 struct formal_struct
*next
; /* next formal in list */
2523 sb name
; /* name of the formal */
2524 sb def
; /* the default value */
2525 sb actual
; /* the actual argument (changed on each expansion) */
2526 int index
; /* the index of the formal 0..formal_count-1 */
2530 sb sub
; /* substitution text. */
2531 int formal_count
; /* number of formal args. */
2532 struct formal_struct
*formals
; /* pointer to list of formal_structs */
2533 struct hash_control
*formal_hash
; /* hash table of formals. */
2536 macro
= (struct macro_struct
*)info
;
2538 /* Put the formal args into the substitution symbol table. */
2539 for (entry
= macro
->formals
; entry
; entry
= entry
->next
)
2541 char *name
= strncpy (xmalloc (entry
->name
.len
+ 1),
2542 entry
->name
.ptr
, entry
->name
.len
);
2543 char *value
= strncpy (xmalloc (entry
->actual
.len
+ 1),
2544 entry
->actual
.ptr
, entry
->actual
.len
);
2545 name
[entry
->name
.len
] = '\0';
2546 value
[entry
->actual
.len
] = '\0';
2547 hash_insert (subsym_hash
[macro_level
], name
, value
);
2551 /* Get rid of this macro's .var's, arguments, and local labels. */
2555 hash_die (subsym_hash
[macro_level
]);
2556 subsym_hash
[macro_level
] = NULL
;
2557 hash_die (local_label_hash
[macro_level
]);
2558 local_label_hash
[macro_level
] = NULL
;
2563 subsym_symlen (a
, ignore
)
2565 char *ignore ATTRIBUTE_UNUSED
;
2570 /* Compare symbol A to string B. */
2572 subsym_symcmp (a
, b
)
2576 return strcmp (a
, b
);
2579 /* Return the index of the first occurence of B in A, or zero if none
2580 assumes b is an integer char value as a string. Index is one-based. */
2582 subsym_firstch (a
, b
)
2587 char *tmp
= strchr (a
, val
);
2589 return tmp
? tmp
- a
+ 1 : 0;
2592 /* Similar to firstch, but returns index of last occurrence of B in A. */
2594 subsym_lastch (a
, b
)
2599 char *tmp
= strrchr (a
, val
);
2601 return tmp
? tmp
- a
+ 1 : 0;
2604 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2607 subsym_isdefed (a
, ignore
)
2609 char *ignore ATTRIBUTE_UNUSED
;
2611 symbolS
*symbolP
= symbol_find (a
);
2613 return symbolP
!= NULL
;
2616 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2617 A, or zero if B is a null string. Both arguments *must* be substitution
2618 symbols, unsubstituted. */
2620 subsym_ismember (sym
, list
)
2624 char *elem
, *ptr
, *listv
;
2629 listv
= subsym_lookup (list
, macro_level
);
2632 as_bad (_("Undefined substitution symbol '%s'"), list
);
2633 ignore_rest_of_line ();
2637 ptr
= elem
= xmalloc (strlen (listv
)+1);
2638 strcpy (elem
, listv
);
2639 while (*ptr
&& *ptr
!= ',')
2643 subsym_create_or_replace (sym
, elem
);
2645 /* Reassign the list. */
2646 subsym_create_or_replace (list
, ptr
);
2648 /* Assume this value, docs aren't clear. */
2652 /* Return zero if not a constant; otherwise:
2659 subsym_iscons (a
, ignore
)
2661 char *ignore ATTRIBUTE_UNUSED
;
2665 parse_expression (a
, &exp
);
2667 if (exp
.X_op
== O_constant
)
2669 int len
= strlen (a
);
2671 switch (toupper (a
[len
-1]))
2684 /* No suffix; either octal, hex, or decimal. */
2685 if (*a
== '0' && len
> 1)
2687 if (toupper (a
[1]) == 'X')
2697 /* Return 1 if A is a valid symbol name. Expects string input. */
2699 subsym_isname (a
, ignore
)
2701 char *ignore ATTRIBUTE_UNUSED
;
2703 if (!is_name_beginner (*a
))
2707 if (!is_part_of_name (*a
))
2714 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2715 been seen; if so, recognize any memory-mapped register.
2716 Note this does not recognize "A" or "B" accumulators. */
2718 subsym_isreg (a
, ignore
)
2720 char *ignore ATTRIBUTE_UNUSED
;
2722 if (hash_find (reg_hash
, a
))
2724 if (hash_find (mmreg_hash
, a
))
2729 /* Return the structrure size, given the stag. */
2731 subsym_structsz (name
, ignore
)
2733 char *ignore ATTRIBUTE_UNUSED
;
2735 struct stag
*stag
= (struct stag
*)hash_find (stag_hash
, name
);
2742 /* If anybody actually uses this, they can fix it :)
2743 FIXME I'm not sure what the "reference point" of a structure is. It might
2744 be either the initial offset given .struct, or it may be the offset of the
2745 structure within another structure, or it might be something else
2746 altogether. since the TI assembler doesn't seem to ever do anything but
2747 return zero, we punt and return zero. */
2749 subsym_structacc (stag_name
, ignore
)
2750 char *stag_name ATTRIBUTE_UNUSED
;
2751 char *ignore ATTRIBUTE_UNUSED
;
2757 math_ceil (arg1
, ignore
)
2759 float ignore ATTRIBUTE_UNUSED
;
2761 return (float)ceil (arg1
);
2765 math_cvi (arg1
, ignore
)
2767 float ignore ATTRIBUTE_UNUSED
;
2773 math_floor (arg1
, ignore
)
2775 float ignore ATTRIBUTE_UNUSED
;
2777 return (float)floor (arg1
);
2781 math_fmod (float arg1
, float arg2
)
2783 return (int)arg1
% (int)arg2
;
2787 math_int (arg1
, ignore
)
2789 float ignore ATTRIBUTE_UNUSED
;
2791 return ((float)((int)arg1
)) == arg1
;
2795 math_round (arg1
, ignore
)
2797 float ignore ATTRIBUTE_UNUSED
;
2799 return arg1
> 0 ? (int)(arg1
+ 0.5) : (int)(arg1
- 0.5);
2803 math_sgn (arg1
, ignore
)
2805 float ignore ATTRIBUTE_UNUSED
;
2807 return (arg1
< 0) ? -1 : (arg1
? 1 : 0);
2811 math_trunc (arg1
, ignore
)
2813 float ignore ATTRIBUTE_UNUSED
;
2819 math_acos (arg1
, ignore
)
2821 float ignore ATTRIBUTE_UNUSED
;
2823 return (float)acos (arg1
);
2827 math_asin (arg1
, ignore
)
2829 float ignore ATTRIBUTE_UNUSED
;
2831 return (float)asin (arg1
);
2835 math_atan (arg1
, ignore
)
2837 float ignore ATTRIBUTE_UNUSED
;
2839 return (float)atan (arg1
);
2843 math_atan2(float arg1
, float arg2
)
2845 return (float)atan2 (arg1
, arg2
);
2849 math_cosh (arg1
, ignore
)
2851 float ignore ATTRIBUTE_UNUSED
;
2853 return (float)cosh (arg1
);
2857 math_cos (arg1
, ignore
)
2859 float ignore ATTRIBUTE_UNUSED
;
2861 return (float)cos (arg1
);
2865 math_cvf (arg1
, ignore
)
2867 float ignore ATTRIBUTE_UNUSED
;
2873 math_exp (arg1
, ignore
)
2875 float ignore ATTRIBUTE_UNUSED
;
2877 return (float)exp (arg1
);
2881 math_fabs (arg1
, ignore
)
2883 float ignore ATTRIBUTE_UNUSED
;
2885 return (float)fabs (arg1
);
2888 /* expr1 * 2^expr2. */
2890 math_ldexp (float arg1
, float arg2
)
2892 return arg1
* (float)pow (2.0, arg2
);
2896 math_log10 (arg1
, ignore
)
2898 float ignore ATTRIBUTE_UNUSED
;
2900 return (float)log10 (arg1
);
2904 math_log (arg1
, ignore
)
2906 float ignore ATTRIBUTE_UNUSED
;
2908 return (float)log (arg1
);
2912 math_max (float arg1
, float arg2
)
2914 return (arg1
> arg2
) ? arg1
: arg2
;
2918 math_min (float arg1
, float arg2
)
2920 return (arg1
< arg2
) ? arg1
: arg2
;
2924 math_pow (float arg1
, float arg2
)
2926 return (float)pow (arg1
, arg2
);
2930 math_sin (arg1
, ignore
)
2932 float ignore ATTRIBUTE_UNUSED
;
2934 return (float)sin (arg1
);
2938 math_sinh (arg1
, ignore
)
2940 float ignore ATTRIBUTE_UNUSED
;
2942 return (float)sinh (arg1
);
2946 math_sqrt (arg1
, ignore
)
2948 float ignore ATTRIBUTE_UNUSED
;
2950 return (float)sqrt (arg1
);
2954 math_tan (arg1
, ignore
)
2956 float ignore ATTRIBUTE_UNUSED
;
2958 return (float)tan (arg1
);
2962 math_tanh (arg1
, ignore
)
2964 float ignore ATTRIBUTE_UNUSED
;
2966 return (float)tanh (arg1
);
2969 /* Built-in substitution symbol functions and math functions. */
2973 int (*proc
)(char *, char *);
2975 } subsym_proc_entry
;
2977 static const subsym_proc_entry subsym_procs
[] =
2979 /* Assembler built-in string substitution functions. */
2980 { "$symlen", subsym_symlen
, 1, },
2981 { "$symcmp", subsym_symcmp
, 2, },
2982 { "$firstch", subsym_firstch
, 2, },
2983 { "$lastch", subsym_lastch
, 2, },
2984 { "$isdefed", subsym_isdefed
, 1, },
2985 { "$ismember", subsym_ismember
, 2, },
2986 { "$iscons", subsym_iscons
, 1, },
2987 { "$isname", subsym_isname
, 1, },
2988 { "$isreg", subsym_isreg
, 1, },
2989 { "$structsz", subsym_structsz
, 1, },
2990 { "$structacc", subsym_structacc
, 1, },
2997 float (*proc
)(float, float);
3002 static const math_proc_entry math_procs
[] =
3004 /* Integer-returning built-in math functions. */
3005 { "$cvi", math_cvi
, 1, 1 },
3006 { "$int", math_int
, 1, 1 },
3007 { "$sgn", math_sgn
, 1, 1 },
3009 /* Float-returning built-in math functions. */
3010 { "$acos", math_acos
, 1, 0 },
3011 { "$asin", math_asin
, 1, 0 },
3012 { "$atan", math_atan
, 1, 0 },
3013 { "$atan2", math_atan2
, 2, 0 },
3014 { "$ceil", math_ceil
, 1, 0 },
3015 { "$cosh", math_cosh
, 1, 0 },
3016 { "$cos", math_cos
, 1, 0 },
3017 { "$cvf", math_cvf
, 1, 0 },
3018 { "$exp", math_exp
, 1, 0 },
3019 { "$fabs", math_fabs
, 1, 0 },
3020 { "$floor", math_floor
, 1, 0 },
3021 { "$fmod", math_fmod
, 2, 0 },
3022 { "$ldexp", math_ldexp
, 2, 0 },
3023 { "$log10", math_log10
, 1, 0 },
3024 { "$log", math_log
, 1, 0 },
3025 { "$max", math_max
, 2, 0 },
3026 { "$min", math_min
, 2, 0 },
3027 { "$pow", math_pow
, 2, 0 },
3028 { "$round", math_round
, 1, 0 },
3029 { "$sin", math_sin
, 1, 0 },
3030 { "$sinh", math_sinh
, 1, 0 },
3031 { "$sqrt", math_sqrt
, 1, 0 },
3032 { "$tan", math_tan
, 1, 0 },
3033 { "$tanh", math_tanh
, 1, 0 },
3034 { "$trunc", math_trunc
, 1, 0 },
3035 { NULL
, NULL
, 0, 0 },
3042 partemplate
*paropcode
;
3044 const subsym_proc_entry
*subsym_proc
;
3045 const math_proc_entry
*math_proc
;
3046 const char *hash_err
;
3048 char *TIC54X_DIR
= getenv ("TIC54X_DIR");
3049 char *A_DIR
= TIC54X_DIR
? TIC54X_DIR
: getenv ("A_DIR");
3053 /* Look for A_DIR and add it to the include list. a */
3056 char *tmp
= xstrdup (A_DIR
);
3058 char *next
= strchr (tmp
, ';');
3061 add_include_dir (tmp
);
3063 } while (tmp
!= NULL
);
3066 op_hash
= hash_new ();
3067 for (opcode
=(template *)tic54x_optab
; opcode
->name
; opcode
++)
3069 if (hash_find (op_hash
, opcode
->name
))
3071 hash_err
= hash_insert (op_hash
, opcode
->name
, (char *)opcode
);
3073 as_fatal ("Internal Error: Can't hash %s: %s",
3074 opcode
->name
, hash_err
);
3076 parop_hash
= hash_new ();
3077 for (paropcode
=(partemplate
*)tic54x_paroptab
; paropcode
->name
; paropcode
++)
3079 if (hash_find (parop_hash
, paropcode
->name
))
3081 hash_err
= hash_insert (parop_hash
, paropcode
->name
, (char *)paropcode
);
3083 as_fatal ("Internal Error: Can't hash %s: %s",
3084 paropcode
->name
, hash_err
);
3086 reg_hash
= hash_new ();
3087 for (sym
= (symbol
*)regs
; sym
->name
; sym
++)
3089 /* Add basic registers to the symbol table. */
3090 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
3091 (valueT
)sym
->value
, &zero_address_frag
);
3092 SF_SET_LOCAL (symbolP
);
3093 symbol_table_insert (symbolP
);
3094 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *)sym
);
3096 for (sym
= (symbol
*)mmregs
; sym
->name
; sym
++)
3097 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *)sym
);
3098 mmreg_hash
= hash_new ();
3099 for (sym
= (symbol
*)mmregs
; sym
->name
; sym
++)
3101 hash_err
= hash_insert (mmreg_hash
, sym
->name
, (char *)sym
);
3103 cc_hash
= hash_new ();
3104 for (sym
= (symbol
*)condition_codes
; sym
->name
; sym
++)
3106 hash_err
= hash_insert (cc_hash
, sym
->name
, (char *)sym
);
3108 cc2_hash
= hash_new ();
3109 for (sym
= (symbol
*)cc2_codes
; sym
->name
; sym
++)
3111 hash_err
= hash_insert (cc2_hash
, sym
->name
, (char *)sym
);
3113 cc3_hash
= hash_new ();
3114 for (sym
= (symbol
*)cc3_codes
; sym
->name
; sym
++)
3116 hash_err
= hash_insert (cc3_hash
, sym
->name
, (char *)sym
);
3118 sbit_hash
= hash_new ();
3119 for (sym
= (symbol
*)status_bits
; sym
->name
; sym
++)
3121 hash_err
= hash_insert (sbit_hash
, sym
->name
, (char *)sym
);
3123 misc_symbol_hash
= hash_new ();
3124 for (symname
= (char **)misc_symbols
; *symname
; symname
++)
3126 hash_err
= hash_insert (misc_symbol_hash
, *symname
, *symname
);
3128 /* Only the base substitution table and local label table are initialized;
3129 the others (for local macro substitution) get instantiated as needed. */
3130 local_label_hash
[0] = hash_new ();
3131 subsym_hash
[0] = hash_new ();
3132 for (subsym_proc
= subsym_procs
; subsym_proc
->name
; subsym_proc
++)
3134 hash_err
= hash_insert (subsym_hash
[0], subsym_proc
->name
,
3135 (char *)subsym_proc
);
3137 math_hash
= hash_new ();
3138 for (math_proc
= math_procs
; math_proc
->name
; math_proc
++)
3140 /* Insert into the main subsym hash for recognition; insert into
3141 the math hash to actually store information. */
3142 hash_err
= hash_insert (subsym_hash
[0], math_proc
->name
,
3144 hash_err
= hash_insert (math_hash
, math_proc
->name
,
3147 subsym_recurse_hash
= hash_new ();
3148 stag_hash
= hash_new ();
3151 typedef struct _tic54x_insn
3153 const template *tm
; /* opcode template */
3154 const partemplate
*ptm
; /* parallel opcode template */
3156 char mnemonic
[MAX_LINE
]; /* opcode name/mnemonic */
3157 char parmnemonic
[MAX_LINE
]; /* 2nd mnemonic of parallel insn */
3165 } operands
[MAX_OPERANDS
];
3168 struct opstruct paroperands
[MAX_OPERANDS
];
3172 int words
; /* size of insn in 16-bit words */
3173 int using_default_dst
; /* do we need to explicitly set an
3174 omitted OP_DST operand? */
3177 unsigned short word
; /* final encoded opcode data */
3179 int r_nchars
; /* relocation size */
3180 bfd_reloc_code_real_type r_type
; /* relocation type */
3181 expressionS addr_expr
; /* storage for unresolved expressions */
3185 static int encode_operand (tic54x_insn
*, enum optype
, struct opstruct
*);
3186 static int encode_dmad (tic54x_insn
*, struct opstruct
*, int);
3187 static int operands_match (tic54x_insn
*, struct opstruct
*, int,
3188 const enum optype
*, int, int);
3189 static int encode_address (tic54x_insn
*, struct opstruct
*);
3192 is_accumulator (operand
)
3193 struct opstruct
*operand
;
3195 return strcasecmp (operand
->buf
, "a") == 0
3196 || strcasecmp (operand
->buf
, "b") == 0;
3199 /* Return the number of operands found, or -1 on error, copying the operands
3200 into the given array and the accompanying expressions into the next array. */
3202 get_operands (operands
, line
)
3203 struct opstruct operands
[];
3208 int expecting_operand
= 0;
3211 while (numexp
< MAX_OPERANDS
&& !is_end_of_line
[(int)*lptr
])
3213 int paren_not_balanced
= 0;
3214 char *op_start
, *op_end
;
3215 while (*lptr
&& isspace (*lptr
))
3218 while (paren_not_balanced
|| *lptr
!= ',')
3222 if (paren_not_balanced
)
3224 as_bad ("Unbalanced parenthesis in operand %d", numexp
);
3231 ++paren_not_balanced
;
3232 else if (*lptr
== ')')
3233 --paren_not_balanced
;
3237 if (op_end
!= op_start
)
3239 int len
= op_end
- op_start
;
3240 strncpy (operands
[numexp
].buf
, op_start
, len
);
3241 operands
[numexp
].buf
[len
] = 0;
3242 /* Trim trailing spaces; while the preprocessor gets rid of most,
3243 there are weird usage patterns that can introduce them
3244 (i.e. using strings for macro args). */
3245 while (len
> 0 && isspace (operands
[numexp
].buf
[len
-1]))
3246 operands
[numexp
].buf
[--len
] = 0;
3252 if (expecting_operand
|| *lptr
== ',')
3254 as_bad ("Expecting operand after ','");
3260 if (*++lptr
== '\0')
3262 as_bad ("Expecting operand after ','");
3265 expecting_operand
= 1;
3269 while (*lptr
&& isspace (*lptr
++))
3271 if (!is_end_of_line
[(int)*lptr
])
3273 as_bad ("Extra junk on line");
3277 /* OK, now parse them into expressions. */
3278 for (i
=0;i
< numexp
;i
++)
3280 memset (&operands
[i
].exp
, 0, sizeof (operands
[i
].exp
));
3281 if (operands
[i
].buf
[0] == '#')
3284 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3286 else if (operands
[i
].buf
[0] == '@')
3288 /* direct notation */
3289 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3291 else if (operands
[i
].buf
[0] == '*')
3294 char *paren
= strchr (operands
[i
].buf
, '(');
3295 /* Allow immediate syntax in the inner expression. */
3296 if (paren
&& paren
[1] == '#')
3299 /* Pull out the lk expression or SP offset, if present. */
3302 int len
= strlen (paren
);
3303 char *end
= paren
+ len
;
3305 while (end
[-1] != ')')
3308 as_bad (_("Badly formed address expression"));
3313 parse_expression (paren
, &operands
[i
].exp
);
3317 operands
[i
].exp
.X_op
= O_absent
;
3321 parse_expression (operands
[i
].buf
, &operands
[i
].exp
);
3328 /* Predicates for different operand types. */
3330 is_immediate (operand
)
3331 struct opstruct
*operand
;
3333 return *operand
->buf
== '#';
3336 /* This is distinguished from immediate because some numbers must be constants
3337 and must *not* have the '#' prefix. */
3339 is_absolute (operand
)
3340 struct opstruct
*operand
;
3342 return operand
->exp
.X_op
== O_constant
&& !is_immediate (operand
);
3345 /* Is this an indirect operand? */
3347 is_indirect (operand
)
3348 struct opstruct
*operand
;
3350 return operand
->buf
[0] == '*';
3353 /* Is this a valid dual-memory operand? */
3356 struct opstruct
*operand
;
3358 if (is_indirect (operand
) && strncasecmp (operand
->buf
, "*ar", 3) == 0)
3360 char *tmp
= operand
->buf
+ 3;
3365 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3366 valid_mod
= *tmp
== '\0' ||
3367 strcasecmp (tmp
, "-") == 0 ||
3368 strcasecmp (tmp
, "+") == 0 ||
3369 strcasecmp (tmp
, "+0%") == 0;
3370 return arf
>= 2 && arf
<= 5 && valid_mod
;
3377 struct opstruct
*operand
;
3379 return is_absolute (operand
) || is_immediate (operand
)
3380 || hash_find (mmreg_hash
, operand
->buf
) != 0;
3384 is_type (operand
, type
)
3385 struct opstruct
*operand
;
3391 return operand
->buf
[0] == 0;
3394 return is_dual (operand
);
3396 return is_indirect (operand
);
3398 /* This one *must* be immediate. */
3399 return is_immediate (operand
);
3408 /* Address may be a numeric, indirect, or an expression. */
3409 return !is_immediate (operand
);
3412 return is_mmreg (operand
);
3417 return is_accumulator (operand
);
3419 return is_accumulator (operand
) && toupper (operand
->buf
[0]) == 'B';
3421 return is_accumulator (operand
) && toupper (operand
->buf
[0]) == 'A';
3423 return strncasecmp ("ar", operand
->buf
, 2) == 0
3424 && isdigit (operand
->buf
[2]);
3426 return hash_find (sbit_hash
, operand
->buf
) != 0 || is_absolute (operand
);
3428 return hash_find (cc_hash
, operand
->buf
) != 0;
3430 return hash_find (cc2_hash
, operand
->buf
) != 0;
3432 return hash_find (cc3_hash
, operand
->buf
) != 0
3433 || is_immediate (operand
) || is_absolute (operand
);
3435 return (is_immediate (operand
) || is_absolute (operand
))
3436 && operand
->exp
.X_add_number
== 16;
3438 /* Allow st0 or st1 instead of a numeric. */
3439 return is_absolute (operand
) || is_immediate (operand
) ||
3440 strcasecmp ("st0", operand
->buf
) == 0 ||
3441 strcasecmp ("st1", operand
->buf
) == 0;
3444 return is_absolute (operand
) || is_immediate (operand
);
3446 return (is_immediate (operand
) || is_absolute (operand
))
3447 && operand
->exp
.X_add_number
>= 0 && operand
->exp
.X_add_number
< 16;
3449 /* Let this one catch out-of-range values. */
3450 return (is_immediate (operand
) || is_absolute (operand
))
3451 && operand
->exp
.X_add_number
!= 16;
3455 return is_absolute (operand
) || is_immediate (operand
);
3457 return is_immediate (operand
)
3458 && operand
->exp
.X_op
== O_constant
3459 && operand
->exp
.X_add_number
>= 0
3460 && operand
->exp
.X_add_number
< 256;
3463 /* Allow anything; assumes opcodes are ordered with Smem operands
3469 /* Just make sure it's an integer; check range later. */
3470 return is_immediate (operand
);
3472 return strcasecmp ("t", operand
->buf
) == 0 ||
3473 strcasecmp ("treg", operand
->buf
) == 0;
3475 return strcasecmp ("ts", operand
->buf
) == 0;
3477 return strcasecmp ("asm", operand
->buf
) == 0;
3479 return strcasecmp ("trn", operand
->buf
) == 0;
3481 return strcasecmp ("dp", operand
->buf
) == 0;
3483 return strcasecmp ("arp", operand
->buf
) == 0;
3490 operands_match (insn
, operands
, opcount
, refoptype
, minops
, maxops
)
3492 struct opstruct
*operands
;
3494 const enum optype
*refoptype
;
3497 int op
= 0, refop
= 0;
3499 if (opcount
== 0 && minops
== 0)
3504 while (op
<= maxops
&& refop
<= maxops
)
3506 while (!is_type (&operands
[op
], OPTYPE (refoptype
[refop
])))
3508 /* Skip an optional template operand if it doesn't agree
3509 with the current operand. */
3510 if (refoptype
[refop
] & OPT
)
3521 /* Save the actual operand type for later use. */
3522 operands
[op
].type
= OPTYPE (refoptype
[refop
]);
3525 /* Have we matched them all yet? */
3530 /* If a later operand is *not* optional, no match. */
3531 if ((refoptype
[refop
] & OPT
) == 0)
3533 /* Flag any implicit default OP_DST operands so we know to add
3534 them explicitly when encoding the operand later. */
3535 if (OPTYPE (refoptype
[refop
]) == OP_DST
)
3536 insn
->using_default_dst
= 1;
3548 /* 16-bit direct memory address
3549 Explicit dmad operands are always in last word of insn (usually second
3550 word, but bumped to third if lk addressing is used)
3552 We allow *(dmad) notation because the TI assembler allows it.
3555 0 for 16-bit addresses
3556 1 for full 23-bit addresses
3557 2 for the upper 7 bits of a 23-bit address (LDX). */
3559 encode_dmad (insn
, operand
, xpc_code
)
3561 struct opstruct
*operand
;
3564 int op
= 1 + insn
->is_lkaddr
;
3566 /* Only allow *(dmad) expressions; all others are invalid. */
3567 if (is_indirect (operand
) && operand
->buf
[strlen (operand
->buf
)-1] != ')')
3569 as_bad (_("Invalid dmad syntax '%s'"), operand
->buf
);
3573 insn
->opcode
[op
].addr_expr
= operand
->exp
;
3575 if (insn
->opcode
[op
].addr_expr
.X_op
== O_constant
)
3577 valueT value
= insn
->opcode
[op
].addr_expr
.X_add_number
;
3580 insn
->opcode
[0].word
&= 0xFF80;
3581 insn
->opcode
[0].word
|= (value
>> 16) & 0x7F;
3582 insn
->opcode
[1].word
= value
& 0xFFFF;
3584 else if (xpc_code
== 2)
3585 insn
->opcode
[op
].word
= (value
>> 16) & 0xFFFF;
3587 insn
->opcode
[op
].word
= value
;
3591 /* Do the fixup later; just store the expression. */
3592 insn
->opcode
[op
].word
= 0;
3593 insn
->opcode
[op
].r_nchars
= 2;
3595 if (amode
== c_mode
)
3596 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3597 else if (xpc_code
== 1)
3599 /* This relocation spans two words, so adjust accordingly. */
3600 insn
->opcode
[0].addr_expr
= operand
->exp
;
3601 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_23
;
3602 insn
->opcode
[0].r_nchars
= 4;
3603 insn
->opcode
[0].unresolved
= 1;
3604 /* It's really 2 words, but we want to stop encoding after the
3605 first, since we must encode both words at once. */
3608 else if (xpc_code
== 2)
3609 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_MS7_OF_23
;
3611 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3613 insn
->opcode
[op
].unresolved
= 1;
3620 /* 7-bit direct address encoding. */
3622 encode_address (insn
, operand
)
3624 struct opstruct
*operand
;
3626 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3627 insn
->opcode
[0].addr_expr
= operand
->exp
;
3629 if (operand
->exp
.X_op
== O_constant
)
3630 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
& 0x7F);
3633 /* Do the fixup later; just store the expression. */
3634 insn
->opcode
[0].r_nchars
= 1;
3635 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_PARTLS7
;
3636 insn
->opcode
[0].unresolved
= 1;
3643 encode_indirect (insn
, operand
)
3645 struct opstruct
*operand
;
3650 if (insn
->is_lkaddr
)
3652 /* lk addresses always go in the second insn word. */
3653 mod
= ((toupper (operand
->buf
[1]) == 'A') ? 12 :
3654 (operand
->buf
[1] == '(') ? 15 :
3655 (strchr (operand
->buf
, '%') != NULL
) ? 14 : 13);
3656 arf
= ((mod
== 12) ? operand
->buf
[3] - '0' :
3657 (mod
== 15) ? 0 : operand
->buf
[4] - '0');
3659 insn
->opcode
[1].addr_expr
= operand
->exp
;
3661 if (operand
->exp
.X_op
== O_constant
)
3662 insn
->opcode
[1].word
= operand
->exp
.X_add_number
;
3665 insn
->opcode
[1].word
= 0;
3666 insn
->opcode
[1].r_nchars
= 2;
3667 insn
->opcode
[1].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3668 insn
->opcode
[1].unresolved
= 1;
3671 else if (strncasecmp (operand
->buf
, "*sp (", 4) == 0)
3673 /* Stack offsets look the same as 7-bit direct addressing. */
3674 return encode_address (insn
, operand
);
3678 arf
= (toupper (operand
->buf
[1]) == 'A' ?
3679 operand
->buf
[3] : operand
->buf
[4]) - '0';
3681 if (operand
->buf
[1] == '+')
3683 mod
= 3; /* *+ARx */
3684 if (insn
->tm
->flags
& FL_SMR
)
3685 as_warn (_("Address mode *+ARx is write-only. "
3686 "Results of reading are undefined."));
3688 else if (operand
->buf
[4] == '\0')
3690 else if (operand
->buf
[5] == '\0')
3691 mod
= (operand
->buf
[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3692 else if (operand
->buf
[6] == '\0')
3694 if (operand
->buf
[5] == '0')
3695 mod
= (operand
->buf
[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3697 mod
= (operand
->buf
[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3699 else if (toupper (operand
->buf
[6]) == 'B')
3700 mod
= (operand
->buf
[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3701 else if (toupper (operand
->buf
[6]) == '%')
3702 mod
= (operand
->buf
[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3705 as_bad (_("Unrecognized indirect address format \"%s\""),
3711 insn
->opcode
[0].word
|= 0x80 | (mod
<<3) | arf
;
3717 encode_integer (insn
, operand
, which
, min
, max
, mask
)
3719 struct opstruct
*operand
;
3720 int which
, min
, max
;
3721 unsigned short mask
;
3723 long parse
, integer
;
3725 insn
->opcode
[which
].addr_expr
= operand
->exp
;
3727 if (operand
->exp
.X_op
== O_constant
)
3729 parse
= operand
->exp
.X_add_number
;
3730 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3731 instead of negative. */
3732 if ((parse
& 0x8000) && min
== -32768 && max
== 32767)
3733 integer
= (short)parse
;
3737 if (integer
>= min
&& integer
<= max
)
3739 insn
->opcode
[which
].word
|= (integer
& mask
);
3742 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3743 operand
->buf
, min
, max
);
3747 if (insn
->opcode
[which
].addr_expr
.X_op
== O_constant
)
3749 insn
->opcode
[which
].word
|=
3750 insn
->opcode
[which
].addr_expr
.X_add_number
& mask
;
3754 /* Do the fixup later; just store the expression. */
3755 bfd_reloc_code_real_type rtype
=
3756 (mask
== 0x1FF ? BFD_RELOC_TIC54X_PARTMS9
:
3757 mask
== 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23
:
3758 mask
== 0x7F ? BFD_RELOC_TIC54X_PARTLS7
: BFD_RELOC_8
);
3759 int size
= (mask
== 0x1FF || mask
== 0xFFFF) ? 2 : 1;
3761 if (rtype
== BFD_RELOC_8
)
3762 as_bad (_("Error in relocation handling"));
3764 insn
->opcode
[which
].r_nchars
= size
;
3765 insn
->opcode
[which
].r_type
= rtype
;
3766 insn
->opcode
[which
].unresolved
= 1;
3776 encode_condition (insn
, operand
)
3778 struct opstruct
*operand
;
3780 symbol
*cc
= (symbol
*)hash_find (cc_hash
, operand
->buf
);
3783 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3786 #define CC_GROUP 0x40
3788 #define CATG_A1 0x07
3789 #define CATG_B1 0x30
3790 #define CATG_A2 0x30
3791 #define CATG_B2 0x0C
3792 #define CATG_C2 0x03
3793 /* Disallow group 1 conditions mixed with group 2 conditions
3794 if group 1, allow only one category A and one category B
3795 if group 2, allow only one each of category A, B, and C. */
3796 if (((insn
->opcode
[0].word
& 0xFF) != 0))
3798 if ((insn
->opcode
[0].word
& CC_GROUP
) != (cc
->value
& CC_GROUP
))
3800 as_bad (_("Condition \"%s\" does not match preceding group"),
3804 if (insn
->opcode
[0].word
& CC_GROUP
)
3806 if ((insn
->opcode
[0].word
& CC_ACC
) != (cc
->value
& CC_ACC
))
3808 as_bad (_("Condition \"%s\" uses a different accumulator from "
3809 "a preceding condition"),
3813 if ((insn
->opcode
[0].word
& CATG_A1
) && (cc
->value
& CATG_A1
))
3815 as_bad (_("Only one comparison conditional allowed"));
3818 if ((insn
->opcode
[0].word
& CATG_B1
) && (cc
->value
& CATG_B1
))
3820 as_bad (_("Only one overflow conditional allowed"));
3824 else if (((insn
->opcode
[0].word
& CATG_A2
) && (cc
->value
& CATG_A2
)) ||
3825 ((insn
->opcode
[0].word
& CATG_B2
) && (cc
->value
& CATG_B2
)) ||
3826 ((insn
->opcode
[0].word
& CATG_C2
) && (cc
->value
& CATG_C2
)))
3828 as_bad (_("Duplicate %s conditional"), operand
->buf
);
3833 insn
->opcode
[0].word
|= cc
->value
;
3838 encode_cc3 (insn
, operand
)
3840 struct opstruct
*operand
;
3842 symbol
*cc3
= (symbol
*)hash_find (cc3_hash
, operand
->buf
);
3843 int value
= cc3
? cc3
->value
: operand
->exp
.X_add_number
<< 8;
3845 if ((value
& 0x0300) != value
)
3847 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3850 insn
->opcode
[0].word
|= value
;
3855 encode_arx (insn
, operand
)
3857 struct opstruct
*operand
;
3859 int arf
= strlen (operand
->buf
) >= 3 ? operand
->buf
[2] - '0' : -1;
3860 if (strncasecmp ("ar", operand
->buf
, 2) || arf
< 0 || arf
> 7)
3862 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
3865 insn
->opcode
[0].word
|= arf
;
3870 encode_cc2 (insn
, operand
)
3872 struct opstruct
*operand
;
3874 symbol
*cc2
= (symbol
*)hash_find (cc2_hash
, operand
->buf
);
3877 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3880 insn
->opcode
[0].word
|= cc2
->value
;
3885 encode_operand (insn
, type
, operand
)
3888 struct opstruct
*operand
;
3890 int ext
= insn
->tm
&& ((insn
->tm
->flags
& FL_EXT
) != 0);
3892 if (type
== OP_MMR
&& operand
->exp
.X_op
!= O_constant
)
3894 /* Disallow long-constant addressing for memory-mapped addressing. */
3895 if (insn
->is_lkaddr
)
3897 as_bad (_("lk addressing modes are invalid for memory-mapped "
3898 "register addressing"));
3902 /* Warn about *+ARx when used with MMR operands. */
3903 if (strncasecmp (operand
->buf
, "*+ar", 4) == 0)
3905 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
3906 "register addressing. Resulting behavior is "
3916 /* 16-bit immediate value. */
3917 return encode_dmad (insn
, operand
, 0);
3919 if (toupper (*operand
->buf
) == 'B')
3921 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1<<9);
3922 if (insn
->using_default_dst
)
3923 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1<<8);
3927 /* Make sure this agrees with with the OP_DST operand. */
3928 if (!((toupper (operand
->buf
[0]) == 'B') ^
3929 ((insn
->opcode
[0].word
& (1<<8)) != 0)))
3931 as_bad (_("Destination accumulator for each part of this parallel "
3932 "instruction must be different"));
3938 if (toupper (operand
->buf
[0]) == 'B')
3939 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1<<8);
3944 int mod
= (operand
->buf
[4] == '\0' ? 0 : /* *arx */
3945 operand
->buf
[4] == '-' ? 1 : /* *arx- */
3946 operand
->buf
[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
3947 int arf
= operand
->buf
[3] - '0' - 2;
3948 int code
= (mod
<< 2)|arf
;
3949 insn
->opcode
[0].word
|= (code
<< (type
== OP_Xmem
? 4 : 0));
3954 if (!is_indirect (operand
))
3955 return encode_address (insn
, operand
);
3958 return encode_indirect (insn
, operand
);
3960 return encode_dmad (insn
, operand
, 2);
3962 return encode_dmad (insn
, operand
, 1);
3965 return encode_dmad (insn
, operand
, 0);
3967 return encode_arx (insn
, operand
);
3972 int value
= operand
->exp
.X_add_number
;
3974 insn
->opcode
[0].word
|= value
;
3976 if (value
< 16 || value
> 24)
3978 as_bad (_("Memory mapped register \"%s\" out of range"),
3982 if (type
== OP_MMRX
)
3983 insn
->opcode
[0].word
|= (value
- 16) << 4;
3985 insn
->opcode
[0].word
|= (value
- 16);
3993 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
3996 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
3999 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4000 -32768, 32767, 0xFFFF);
4002 return encode_condition (insn
, operand
);
4004 return encode_cc2 (insn
, operand
);
4006 return encode_cc3 (insn
, operand
);
4008 return encode_integer (insn
, operand
, 0, 0, 15, 0xF);
4010 return encode_integer (insn
, operand
, 0, -128, 127, 0xFF);
4013 int value
= operand
->exp
.X_add_number
;
4015 if (value
< 1 || value
> 3)
4017 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4020 code
= value
== 1 ? 0 : value
== 2 ? 0x2 : 0x1;
4021 insn
->opcode
[0].word
|= (code
<< 8);
4025 return encode_integer (insn
, operand
, 0, 0, 31, 0x1F);
4027 return encode_integer (insn
, operand
, 0, 0, 255, 0xFF);
4029 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4033 symbol
*sbit
= (symbol
*)hash_find (sbit_hash
, operand
->buf
);
4034 int value
= is_absolute (operand
) ?
4035 operand
->exp
.X_add_number
: (sbit
? sbit
->value
: -1);
4038 if (insn
->opcount
== 1)
4042 as_bad (_("A status register or status bit name is required"));
4045 /* Guess the register based on the status bit; "ovb" is the last
4046 status bit defined for st0. */
4047 if (sbit
> (symbol
*)hash_find (sbit_hash
, "ovb"))
4052 as_bad (_("Unrecognized status bit \"%s\""), operand
->buf
);
4055 insn
->opcode
[0].word
|= value
;
4056 insn
->opcode
[0].word
|= (reg
<< 9);
4060 if (strcasecmp (operand
->buf
, "st0") == 0
4061 || strcasecmp (operand
->buf
, "st1") == 0)
4063 insn
->opcode
[0].word
|= ((unsigned short)(operand
->buf
[2] - '0'))<<9;
4066 else if (operand
->exp
.X_op
== O_constant
4067 && (operand
->exp
.X_add_number
== 0
4068 || operand
->exp
.X_add_number
== 1))
4070 insn
->opcode
[0].word
|= ((unsigned short)
4071 (operand
->exp
.X_add_number
))<<9;
4074 as_bad (_("Invalid status register \"%s\""), operand
->buf
);
4077 return encode_integer (insn
, operand
, 0, -16, 15, 0x1F);
4079 return encode_integer (insn
, operand
, 0, 0, 7, 0x7);
4081 return encode_integer (insn
, operand
, 0, 0, 0x1FF, 0x1FF);
4083 if (operand
->exp
.X_add_number
!= 1
4084 && operand
->exp
.X_add_number
!= 2)
4086 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand
->buf
);
4089 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
- 1) << 9;
4098 /* No encoding necessary. */
4112 for (i
=0;i
< insn
->words
;i
++)
4114 int size
= (insn
->opcode
[i
].unresolved
4115 && insn
->opcode
[i
].r_type
== BFD_RELOC_TIC54X_23
) ? 4 : 2;
4116 char *p
= frag_more (size
);
4119 md_number_to_chars (p
, (valueT
)insn
->opcode
[i
].word
, 2);
4121 md_number_to_chars (p
, (valueT
)insn
->opcode
[i
].word
<< 16, 4);
4123 if (insn
->opcode
[i
].unresolved
)
4124 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
,
4125 insn
->opcode
[i
].r_nchars
, &insn
->opcode
[i
].addr_expr
,
4126 false, insn
->opcode
[i
].r_type
);
4130 /* Convert the operand strings into appropriate opcode values
4131 return the total number of words used by the instruction. */
4138 /* Only non-parallel instructions support lk addressing. */
4141 for (i
=0; i
< insn
->opcount
; i
++)
4143 if ((OPTYPE (insn
->operands
[i
].type
) == OP_Smem
||
4144 OPTYPE (insn
->operands
[i
].type
) == OP_Lmem
||
4145 OPTYPE (insn
->operands
[i
].type
) == OP_Sind
) &&
4146 strchr (insn
->operands
[i
].buf
, '(') &&
4147 /* Don't mistake stack-relative addressing for lk addressing. */
4148 strncasecmp (insn
->operands
[i
].buf
, "*sp (", 4) != 0)
4150 insn
->is_lkaddr
= 1;
4151 insn
->lkoperand
= i
;
4157 (insn
->tm
? insn
->tm
->words
: insn
->ptm
->words
) + insn
->is_lkaddr
;
4159 insn
->opcode
[0].word
= insn
->tm
? insn
->tm
->opcode
: insn
->ptm
->opcode
;
4160 if (insn
->tm
&& (insn
->tm
->flags
& FL_EXT
))
4161 insn
->opcode
[1 + insn
->is_lkaddr
].word
= insn
->tm
->opcode2
;
4163 for (i
=0; i
< insn
->opcount
; i
++)
4165 enum optype type
= insn
->operands
[i
].type
;
4166 if (!encode_operand (insn
, type
, &insn
->operands
[i
]))
4169 if (insn
->ptm
) for (i
=0; i
< insn
->paropcount
; i
++)
4171 enum optype partype
= insn
->paroperands
[i
].type
;
4172 if (!encode_operand (insn
, partype
, &insn
->paroperands
[i
]))
4182 optimize_insn (insn
)
4185 /* Optimize some instructions, helping out the brain-dead programmer. */
4186 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4187 if (strcasecmp (insn
->tm
->name
, "add") == 0)
4189 if (insn
->opcount
> 1 &&
4190 is_accumulator (&insn
->operands
[insn
->opcount
-2]) &&
4191 is_accumulator (&insn
->operands
[insn
->opcount
-1]) &&
4192 strcasecmp (insn
->operands
[insn
->opcount
-2].buf
,
4193 insn
->operands
[insn
->opcount
-1].buf
) == 0)
4196 insn
->using_default_dst
= 1;
4200 /* Try to collapse if Xmem and shift count is zero. */
4201 if ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
&&
4202 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
&&
4203 is_zero (insn
->operands
[1])) ||
4204 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4205 (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
&&
4206 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
&&
4207 is_type (&insn
->operands
[1], OP_SHIFT
) &&
4208 is_zero (insn
->operands
[1]) && insn
->opcount
== 3))
4210 insn
->operands
[1] = insn
->operands
[2];
4215 else if (strcasecmp (insn
->tm
->name
, "ld") == 0)
4217 if (insn
->opcount
== 3 && insn
->operands
[0].type
!= OP_SRC
)
4219 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
||
4220 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
) &&
4221 is_zero (insn
->operands
[1]) &&
4222 (OPTYPE (insn
->tm
->operand_types
[0]) != OP_lk
||
4223 (insn
->operands
[0].exp
.X_op
== O_constant
&&
4224 insn
->operands
[0].exp
.X_add_number
<= 255 &&
4225 insn
->operands
[0].exp
.X_add_number
>= 0)))
4227 insn
->operands
[1] = insn
->operands
[2];
4233 else if (strcasecmp (insn
->tm
->name
, "sth") == 0 ||
4234 strcasecmp (insn
->tm
->name
, "stl") == 0)
4236 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
||
4237 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
) &&
4238 is_zero (insn
->operands
[1]))
4240 insn
->operands
[1] = insn
->operands
[2];
4245 else if (strcasecmp (insn
->tm
->name
, "sub") == 0)
4247 if (insn
->opcount
> 1 &&
4248 is_accumulator (&insn
->operands
[insn
->opcount
-2]) &&
4249 is_accumulator (&insn
->operands
[insn
->opcount
-1]) &&
4250 strcasecmp (insn
->operands
[insn
->opcount
-2].buf
,
4251 insn
->operands
[insn
->opcount
-1].buf
) == 0)
4254 insn
->using_default_dst
= 1;
4258 if (((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
&&
4259 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
) ||
4260 (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
&&
4261 OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)) &&
4262 is_zero (insn
->operands
[1]) &&
4265 insn
->operands
[1] = insn
->operands
[2];
4273 /* Find a matching template if possible, and get the operand strings. */
4275 tic54x_parse_insn (insn
, line
)
4279 insn
->tm
= (template *)hash_find (op_hash
, insn
->mnemonic
);
4282 as_bad (_("Unrecognized instruction \"%s\""), insn
->mnemonic
);
4286 insn
->opcount
= get_operands (insn
->operands
, line
);
4287 if (insn
->opcount
< 0)
4290 /* Check each variation of operands for this mnemonic. */
4291 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
, insn
->mnemonic
) == 0)
4293 if (insn
->opcount
>= insn
->tm
->minops
&&
4294 insn
->opcount
<= insn
->tm
->maxops
&&
4295 operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4296 insn
->tm
->operand_types
,
4297 insn
->tm
->minops
, insn
->tm
->maxops
))
4299 /* SUCCESS! now try some optimizations. */
4300 if (optimize_insn (insn
))
4302 insn
->tm
= (template *)hash_find (op_hash
,
4311 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4312 line
, insn
->mnemonic
);
4316 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4317 won't be able to see the next line. */
4318 static int parallel_on_next_line_hint
= 0;
4319 /* See if this is part of a parallel instruction
4320 Look for a subsequent line starting with "||". */
4322 next_line_shows_parallel (next_line
)
4325 /* look for the second half */
4326 while (isspace (*next_line
))
4329 return (next_line
[0] == PARALLEL_SEPARATOR
&&
4330 next_line
[1] == PARALLEL_SEPARATOR
);
4334 tic54x_parse_parallel_insn_firstline (insn
, line
)
4338 insn
->ptm
= (partemplate
*)hash_find (parop_hash
, insn
->mnemonic
);
4341 as_bad (_("Unrecognized parallel instruction \"%s\""),
4346 while (insn
->ptm
->name
&& strcasecmp (insn
->ptm
->name
,
4347 insn
->mnemonic
) == 0)
4349 insn
->opcount
= get_operands (insn
->operands
, line
);
4350 if (insn
->opcount
< 0)
4352 if (insn
->opcount
== 2 &&
4353 operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4354 insn
->ptm
->operand_types
, 2, 2))
4360 /* Didn't find a matching parallel; try for a normal insn. */
4364 /* Parse the second line of a two-line parallel instruction. */
4366 tic54x_parse_parallel_insn_lastline (insn
, line
)
4370 int valid_mnemonic
= 0;
4372 insn
->paropcount
= get_operands (insn
->paroperands
, line
);
4373 while (insn
->ptm
->name
&& strcasecmp (insn
->ptm
->name
,
4374 insn
->mnemonic
) == 0)
4376 if (strcasecmp (insn
->ptm
->parname
, insn
->parmnemonic
) == 0)
4379 if (insn
->paropcount
>= insn
->ptm
->minops
&&
4380 insn
->paropcount
<= insn
->ptm
->maxops
&&
4381 operands_match (insn
, insn
->paroperands
,
4383 insn
->ptm
->paroperand_types
,
4384 insn
->ptm
->minops
, insn
->ptm
->maxops
))
4392 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4395 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4396 insn
->mnemonic
, insn
->parmnemonic
);
4401 /* If quotes found, return copy of line up to closing quote;
4402 otherwise up until terminator
4403 if it's a string, pass as-is; otherwise attempt substitution symbol
4404 replacement on the value. */
4406 subsym_get_arg (char *line
, char *terminators
, char **str
, int nosub
)
4410 int is_string
= *line
== '"';
4411 int is_char
= isdigit (*line
);
4415 while (isdigit (*ptr
))
4418 *str
= xmalloc (ptr
- line
+ 1);
4419 strncpy (*str
, line
, ptr
- line
);
4420 (*str
)[ptr
- line
] = 0;
4424 char *savedp
= input_line_pointer
;
4426 input_line_pointer
= ptr
;
4427 *str
= demand_copy_C_string (&len
);
4428 endp
= input_line_pointer
;
4429 input_line_pointer
= savedp
;
4431 /* Do forced substitutions if requested. */
4432 if (!nosub
&& **str
== ':')
4433 *str
= subsym_substitute (*str
, 1);
4437 char *term
= terminators
;
4440 while (*ptr
&& *ptr
!= *term
)
4451 *str
= xmalloc (ptr
- line
+ 1);
4452 strncpy (*str
, line
, ptr
- line
);
4453 (*str
)[ptr
- line
] = 0;
4454 /* Do simple substitution, if available. */
4455 if (!nosub
&& (value
= subsym_lookup (*str
, macro_level
)) != NULL
)
4462 /* Replace the given substitution string.
4463 We start at the innermost macro level, so that existing locals remain local
4464 Note: we're treating macro args identically to .var's; I don't know if
4465 that's compatible w/TI's assembler. */
4467 subsym_create_or_replace (name
, value
)
4473 for (i
=macro_level
;i
> 0;i
--)
4475 if (hash_find (subsym_hash
[i
], name
))
4477 hash_replace (subsym_hash
[i
], name
, value
);
4481 if (hash_find (subsym_hash
[0], name
))
4482 hash_replace (subsym_hash
[0], name
, value
);
4484 hash_insert (subsym_hash
[0], name
, value
);
4487 /* Look up the substitution string replacement for the given symbol
4488 start with the innermost macro substituion table given and work outwards. */
4490 subsym_lookup (name
, nest_level
)
4494 char *value
= hash_find (subsym_hash
[nest_level
], name
);
4496 if (value
|| nest_level
== 0)
4499 return subsym_lookup (name
, nest_level
-1);
4502 /* Do substitution-symbol replacement on the given line (recursively).
4503 return the argument if no substitution was done
4505 Also look for built-in functions ($func (arg)) and local labels.
4507 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4509 subsym_substitute (char *line
, int forced
)
4511 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4512 replace it in the input. */
4513 char *replacement
; /* current replacement for LINE */
4514 char *head
; /* start of line */
4515 char *ptr
; /* current examination point */
4516 int changed
= 0; /* did we make a substitution? */
4517 int eval_line
= 0; /* is this line a .eval/.asg statement? */
4518 int eval_symbol
= 0; /* are we in the middle of the symbol for .eval/.asg? */
4519 char *eval_end
= NULL
;
4521 int line_conditional
= 0;
4524 /* Work with a copy of the input line. */
4525 replacement
= xmalloc (strlen (line
) + 1);
4526 strcpy (replacement
, line
);
4528 ptr
= head
= replacement
;
4530 /* Flag lines where we might need to replace a single '=' with two;
4531 GAS uses single '=' to assign macro args values, and possibly other
4532 places, so limit what we replace. */
4533 if (strstr (line
, ".if")
4534 || strstr (line
, ".elseif")
4535 || strstr (line
, ".break"))
4537 line_conditional
= 1;
4540 /* Watch out for .eval, so that we avoid doing substitution on the
4541 symbol being assigned a value. */
4542 if (strstr (line
, ".eval") || strstr (line
, ".asg"))
4545 /* If it's a macro definition, don't do substitution on the argument names. */
4546 if (strstr (line
, ".macro"))
4549 while (!is_end_of_line
[(int)*ptr
])
4551 int current_char
= *ptr
;
4553 /* Need to update this since LINE may have been modified. */
4555 eval_end
= strrchr (ptr
, ',');
4557 /* Replace triple double quotes with bounding quote/escapes. */
4558 if (current_char
== '"' && ptr
[1] == '"' && ptr
[2] == '"')
4561 tmp
= strstr (ptr
+2, "\"\"\"");
4567 /* Replace a single '=' with a '==';
4568 for compatibility with older code only. */
4569 if (line_conditional
&& current_char
== '=')
4577 tmp
= xmalloc (strlen (head
) + 2 + strlen (ptr
) + 1);
4578 sprintf (tmp
, "%s==%s", head
, ptr
);
4579 /* Continue examining after the '=='. */
4580 ptr
= tmp
+ strlen (head
) + 2;
4582 head
= replacement
= tmp
;
4586 /* Flag when we've reached the symbol part of .eval/.asg. */
4587 if (eval_line
&& ptr
>= eval_end
)
4590 /* For each apparent symbol, see if it's a substitution symbol, and if
4591 so, replace it in the input. */
4592 if ((forced
&& current_char
== ':')
4593 || (!forced
&& is_name_beginner (current_char
)))
4595 char *name
; /* symbol to be replaced */
4596 char *savedp
= input_line_pointer
;
4599 char *tail
; /* rest of line after symbol */
4601 /* Skip the colon. */
4605 name
= input_line_pointer
= ptr
;
4606 c
= get_symbol_end ();
4607 /* '?' is not normally part of a symbol, but it IS part of a local
4611 *input_line_pointer
++ = c
;
4612 c
= *input_line_pointer
;
4613 *input_line_pointer
= '\0';
4615 /* Avoid infinite recursion; if a symbol shows up a second time for
4616 substitution, leave it as is. */
4617 if (hash_find (subsym_recurse_hash
, name
) == NULL
)
4618 value
= subsym_lookup (name
, macro_level
);
4620 as_warn (_("%s symbol recursion stopped at "
4621 "second appearance of '%s'"),
4622 forced
? "Forced substitution": "Substitution", name
);
4623 ptr
= tail
= input_line_pointer
;
4624 input_line_pointer
= savedp
;
4626 /* Check for local labels; replace them with the appropriate
4628 if ((*name
== '$' && isdigit (name
[1]) && name
[2] == '\0')
4629 || name
[strlen (name
)-1] == '?')
4631 /* Use an existing identifier for that label if, available, or
4632 create a new, unique identifier. */
4633 value
= hash_find (local_label_hash
[macro_level
], name
);
4637 char *namecopy
= strcpy (xmalloc (strlen (name
) + 1), name
);
4638 value
= strcpy (xmalloc (strlen (name
) + sizeof (digit
) + 1),
4641 value
[strlen (value
)-1] = '\0';
4642 sprintf (digit
, ".%d", local_label_id
++);
4643 strcat (value
, digit
);
4644 hash_insert (local_label_hash
[macro_level
], namecopy
, value
);
4646 /* Indicate where to continue looking for substitutions. */
4649 /* Check for built-in subsym and math functions. */
4650 else if (value
!= NULL
&& *name
== '$')
4652 subsym_proc_entry
*entry
= (subsym_proc_entry
*)value
;
4653 math_proc_entry
*math_entry
= hash_find (math_hash
, name
);
4654 char *arg1
, *arg2
= NULL
;
4659 as_bad (_("Unrecognized substitution symbol function"));
4662 else if (*ptr
!= '(')
4664 as_bad (_("Missing '(' after substitution symbol function"));
4668 if (math_entry
!= NULL
)
4670 float arg1
, arg2
= 0;
4671 volatile float fresult
;
4673 arg1
= (float)strtod (ptr
, &ptr
);
4674 if (math_entry
->nargs
== 2)
4678 as_bad (_("Expecting second argument"));
4681 arg2
= (float)strtod (ptr
, &ptr
);
4683 fresult
= (*math_entry
->proc
)(arg1
, arg2
);
4684 value
= xmalloc (128);
4685 if (math_entry
->int_return
)
4686 sprintf (value
, "%d", (int)fresult
);
4688 sprintf (value
, "%f", fresult
);
4691 as_bad (_("Extra junk in function call, expecting ')'"));
4694 /* Don't bother recursing; the replacement isn't a symbol. */
4700 int arg_type
[2] = {*ptr
== '"',0};
4701 int ismember
= !strcmp (entry
->name
, "$ismember");
4702 /* Parse one or two args, which must be a substitution
4703 symbol, string or a character-string constant. */
4704 /* For all functions, a string or substitution symbol may be
4705 used, with the following exceptions:
4706 firstch/lastch: 2nd arg must be character constant
4707 ismember: both args must be substitution symbols. */
4708 ptr
= subsym_get_arg (ptr
, ",)", &arg1
, ismember
);
4711 if (entry
->nargs
== 2)
4715 as_bad (_("Function expects two arguments"));
4718 /* Character constants are converted to numerics
4719 by the preprocessor. */
4720 arg_type
[1] = (isdigit (*ptr
)) ? 2 : (*ptr
== '"');
4721 ptr
= subsym_get_arg (ptr
, ")", &arg2
, ismember
);
4723 /* Args checking. */
4724 if ((!strcmp (entry
->name
, "$firstch")
4725 || !strcmp (entry
->name
, "$lastch"))
4726 && arg_type
[1] != 2)
4728 as_bad (_("Expecting character constant argument"));
4732 && (arg_type
[0] != 0 || arg_type
[1] != 0))
4734 as_bad (_("Both arguments must be substitution symbols"));
4739 as_bad (_("Extra junk in function call, expecting ')'"));
4742 val
= (*entry
->proc
)(arg1
, arg2
);
4743 value
= xmalloc (64);
4744 sprintf (value
, "%d", val
);
4746 /* Fix things up to replace the entire expression, not just the
4752 if (value
!= NULL
&& !eval_symbol
)
4754 /* Replace the symbol with its string replacement and
4755 continue. Recursively replace VALUE until either no
4756 substitutions are performed, or a substitution that has been
4757 previously made is encountered again.
4759 put the symbol into the recursion hash table so we only
4760 try to replace a symbol once. */
4763 hash_insert (subsym_recurse_hash
, name
, name
);
4764 value
= subsym_substitute (value
, macro_level
> 0);
4765 hash_delete (subsym_recurse_hash
, name
);
4768 /* Temporarily zero-terminate where the symbol started. */
4774 /* Subscripted substitution symbol -- use just the
4775 indicated portion of the string; the description
4776 kinda indicates that forced substituion is not
4777 supposed to be recursive, but I'm not sure. */
4778 unsigned beg
, len
= 1; /* default to a single char */
4779 char *newval
= strcpy (xmalloc (strlen (value
)+1), value
);
4781 savedp
= input_line_pointer
;
4782 input_line_pointer
= tail
+ 1;
4783 beg
= get_absolute_expression ();
4786 as_bad (_("Invalid subscript (use 1 to %d)"),
4790 if (*input_line_pointer
== ',')
4792 ++input_line_pointer
;
4793 len
= get_absolute_expression ();
4794 if (beg
+ len
> strlen (value
))
4796 as_bad (_("Invalid length (use 0 to %d"),
4797 strlen (value
) - beg
);
4803 tail
= input_line_pointer
;
4806 as_bad (_("Missing ')' in subscripted substitution "
4807 "symbol expression"));
4811 input_line_pointer
= savedp
;
4817 tmp
= xmalloc (strlen (head
) + strlen (value
) +
4818 strlen (tail
+1) + 2);
4820 strcat (tmp
, value
);
4821 /* Make sure forced substitutions are properly terminated. */
4826 as_bad (_("Missing forced substitution terminator ':'"));
4831 /* Try to replace required whitespace
4832 eliminated by the preprocessor; technically, a forced
4833 substitution could come anywhere, even mid-symbol,
4834 e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
4835 but 'sym:x: end' should result in 'sym0 end'.
4836 FIXME -- this should really be fixed in the preprocessor,
4837 but would require several new states;
4838 KEEP_WHITE_AROUND_COLON does part of the job, but isn't
4840 if ((is_part_of_name (tail
[1])
4843 || tail
[1] == '\0' || tail
[1] == ',' || tail
[1] == '"')
4850 /* Restore the character after the symbol end. */
4853 /* Continue examining after the replacement value. */
4854 ptr
= tmp
+ strlen (head
) + strlen (value
);
4856 head
= replacement
= tmp
;
4874 /* We use this to handle substitution symbols
4875 hijack input_line_pointer, replacing it with our substituted string.
4877 .sslist should enable listing the line after replacements are made...
4879 returns the new buffer limit. */
4881 tic54x_start_line_hook ()
4884 char *replacement
= NULL
;
4886 /* Work with a copy of the input line, including EOL char. */
4887 endp
= input_line_pointer
;
4888 while (!is_end_of_line
[(int)*endp
++])
4890 line
= xmalloc (endp
- input_line_pointer
+ 1);
4891 strncpy (line
, input_line_pointer
, endp
- input_line_pointer
+ 1);
4892 line
[endp
- input_line_pointer
] = 0;
4894 /* Scan ahead for parallel insns. */
4895 parallel_on_next_line_hint
= next_line_shows_parallel (endp
+ 1);
4897 /* If within a macro, first process forced replacements. */
4898 if (macro_level
> 0)
4899 replacement
= subsym_substitute (line
, 1);
4902 replacement
= subsym_substitute (replacement
, 0);
4904 if (replacement
!= line
)
4906 char *tmp
= replacement
;
4907 char *comment
= strchr (replacement
,';');
4908 char endc
= replacement
[strlen (replacement
)-1];
4910 /* Clean up the replacement; we'd prefer to have this done by the
4911 standard preprocessing equipment (maybe do_scrub_chars?)
4912 but for now, do a quick-and-dirty. */
4913 if (comment
!= NULL
)
4920 comment
= replacement
+ strlen (replacement
) - 1;
4922 /* Trim trailing whitespace. */
4923 while (isspace (*comment
))
4930 /* Compact leading whitespace. */
4931 while (isspace (tmp
[0]) && isspace (tmp
[1]))
4934 input_line_pointer
= endp
;
4935 input_scrub_insert_line (tmp
);
4938 /* Keep track of whether we've done a substitution. */
4939 substitution_line
= 1;
4945 substitution_line
= 0;
4949 /* This is the guts of the machine-dependent assembler. STR points to a
4950 machine dependent instruction. This function is supposed to emit
4951 the frags/bytes it assembles to. */
4956 static int repeat_slot
= 0;
4957 static int delay_slots
= 0; /* how many delay slots left to fill? */
4958 static int is_parallel
= 0;
4959 static tic54x_insn insn
;
4961 char *savedp
= input_line_pointer
;
4964 input_line_pointer
= line
;
4965 c
= get_symbol_end ();
4969 if (address_mode_needs_set
)
4971 set_address_mode (amode
);
4972 address_mode_needs_set
= 0;
4985 strcpy (insn
.parmnemonic
, line
);
4986 lptr
= input_line_pointer
;
4988 input_line_pointer
= savedp
;
4990 if (tic54x_parse_parallel_insn_lastline (&insn
, lptr
))
4992 int words
= build_insn (&insn
);
4994 if (delay_slots
!= 0)
4996 if (words
> delay_slots
)
4998 as_bad (_("Instruction does not fit in available delay "
4999 "slots (%d-word insn, %d slots left)"),
5000 words
, delay_slots
);
5004 delay_slots
-= words
;
5010 memset (&insn
, 0, sizeof (insn
));
5011 strcpy (insn
.mnemonic
, line
);
5012 lptr
= input_line_pointer
;
5014 input_line_pointer
= savedp
;
5016 /* See if this line is part of a parallel instruction; if so, either this
5017 line or the next line will have the "||" specifier preceding the
5018 mnemonic, and we look for it in the parallel insn hash table. */
5019 if (strstr (line
, "||") != NULL
|| parallel_on_next_line_hint
)
5021 char *tmp
= strstr (line
, "||");
5025 if (tic54x_parse_parallel_insn_firstline (&insn
, lptr
))
5028 /* If the parallel part is on the same line, process it now,
5029 otherwise let the assembler pick up the next line for us. */
5032 while (isspace (tmp
[2]))
5034 md_assemble (tmp
+2);
5039 as_bad (_("Unrecognized parallel instruction '%s'"), line
);
5044 if (tic54x_parse_insn (&insn
, lptr
))
5048 if ((insn
.tm
->flags
& FL_LP
)
5049 && cpu
!= V545LP
&& cpu
!= V546LP
)
5051 as_bad (_("Instruction '%s' requires an LP cpu version"),
5055 if ((insn
.tm
->flags
& FL_FAR
)
5056 && amode
!= far_mode
)
5058 as_bad (_("Instruction '%s' requires far mode addressing"),
5063 words
= build_insn (&insn
);
5065 /* Is this instruction in a delay slot? */
5068 if (words
> delay_slots
)
5070 as_warn (_("Instruction does not fit in available delay "
5071 "slots (%d-word insn, %d slots left). "
5072 "Resulting behavior is undefined."),
5073 words
, delay_slots
);
5077 /* Branches in delay slots are not allowed. */
5078 if (insn
.tm
->flags
& FL_BMASK
)
5080 as_warn (_("Instructions which cause PC discontinuity are not "
5081 "allowed in a delay slot. "
5082 "Resulting behavior is undefined."));
5084 delay_slots
-= words
;
5087 /* Is this instruction the target of a repeat? */
5090 if (insn
.tm
->flags
& FL_NR
)
5091 as_warn (_("'%s' is not repeatable. "
5092 "Resulting behavior is undefined."),
5094 else if (insn
.is_lkaddr
)
5095 as_warn (_("Instructions using long offset modifiers or absolute "
5096 "addresses are not repeatable. "
5097 "Resulting behavior is undefined."));
5101 /* Make sure we check the target of a repeat instruction. */
5102 if (insn
.tm
->flags
& B_REPEAT
)
5105 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5107 /* Make sure we check our delay slots for validity. */
5108 if (insn
.tm
->flags
& FL_DELAY
)
5111 /* FIXME -- warn if delay_slots != 0 at EOF. */
5116 /* Do a final adjustment on the symbol table; in this case, make sure we have
5117 a ".file" symbol. */
5119 tic54x_adjust_symtab ()
5121 if (symbol_rootP
== NULL
5122 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
5126 as_where (&filename
, &lineno
);
5127 c_dot_file_symbol (filename
);
5131 /* In order to get gas to ignore any | chars at the start of a line,
5132 this function returns true if a | is found in a line.
5133 This lets us process parallel instructions, which span two lines. */
5135 tic54x_unrecognized_line (int c
)
5137 return c
== PARALLEL_SEPARATOR
;
5140 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5141 Encode their names so that only we see them and can map them to the
5143 FIXME -- obviously this isn't done yet. These locals still show up in the
5146 tic54x_define_label (sym
)
5149 /*static int local_label_count = 0;*/
5150 /*const char *name = S_GET_NAME (sym);*/
5152 /* Just in case we need this later; note that this is not necessarily the
5153 same thing as line_label...
5154 When aligning or assigning labels to fields, sometimes the label is
5155 assigned other than the address at which the label appears.
5156 FIXME -- is this really needed? I think all the proper label assignment
5157 is done in tic54x_cons. */
5158 last_label_seen
= sym
;
5161 /* Try to parse something that normal parsing failed at. */
5163 tic54x_undefined_symbol (name
)
5168 /* Not sure how to handle predefined symbols. */
5169 if ((sym
= (symbol
*)hash_find (cc_hash
, name
)) != NULL
||
5170 (sym
= (symbol
*)hash_find (cc2_hash
, name
)) != NULL
||
5171 (sym
= (symbol
*)hash_find (cc3_hash
, name
)) != NULL
||
5172 (sym
= (symbol
*)hash_find (misc_symbol_hash
, name
)) != NULL
||
5173 (sym
= (symbol
*)hash_find (sbit_hash
, name
)) != NULL
)
5175 return symbol_new (name
, reg_section
,
5176 (valueT
) sym
->value
,
5177 &zero_address_frag
);
5180 if ((sym
= (symbol
*)hash_find (reg_hash
, name
)) != NULL
||
5181 (sym
= (symbol
*)hash_find (mmreg_hash
, name
)) != NULL
||
5182 !strcasecmp (name
, "a") || !strcasecmp (name
, "b"))
5184 return symbol_new (name
, reg_section
,
5185 (valueT
) sym
? sym
->value
: 0,
5186 &zero_address_frag
);
5192 /* Parse a name in an expression before the expression parser takes a stab at
5195 tic54x_parse_name (name
, exp
)
5196 char *name ATTRIBUTE_UNUSED
;
5197 expressionS
*exp ATTRIBUTE_UNUSED
;
5200 symbol
*sym
= (symbol
*)hash_find (mmreg_hash
, name
);
5201 /* If it's a MMREG, replace it with its constant value. */
5204 exp
->X_op
= O_constant
;
5205 exp
->X_add_number
= sym
->value
;
5213 md_atof (type
, literalP
, sizeP
)
5218 #define MAX_LITTLENUMS 2
5219 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5220 LITTLENUM_TYPE
*word
;
5221 /* only one precision on the c54x */
5223 char *t
= atof_ieee (input_line_pointer
, type
, words
);
5225 input_line_pointer
= t
;
5228 /* Target data is little-endian, but floats are stored big-"word"ian. ugh. */
5229 for (word
= words
; prec
--;)
5231 md_number_to_chars (literalP
, (long)(*word
++), sizeof (LITTLENUM_TYPE
));
5232 literalP
+= sizeof (LITTLENUM_TYPE
);
5239 tc_gen_reloc (section
, fixP
)
5244 bfd_reloc_code_real_type code
= fixP
->fx_r_type
;
5245 asymbol
*sym
= symbol_get_bfdsym (fixP
->fx_addsy
);
5247 rel
= (arelent
*) xmalloc (sizeof (arelent
));
5248 rel
->sym_ptr_ptr
= (asymbol
**)xmalloc (sizeof (asymbol
*));
5249 *rel
->sym_ptr_ptr
= sym
;
5250 /* We assume that all rel->address are host byte offsets */
5251 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5252 rel
->address
/= OCTETS_PER_BYTE
;
5253 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5254 if (!strcmp (sym
->name
, section
->name
))
5255 rel
->howto
+= HOWTO_BANK
;
5259 const char *name
= S_GET_NAME (fixP
->fx_addsy
);
5262 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5263 name
, bfd_get_reloc_code_name (code
));
5269 /* Handle cons expressions. */
5271 tic54x_cons_fix_new (fragS
*frag
, int where
, int octets
, expressionS
*exp
)
5273 bfd_reloc_code_real_type r
;
5277 as_bad (_("Unsupported relocation size %d"), octets
);
5278 r
= BFD_RELOC_TIC54X_16_OF_23
;
5281 r
= BFD_RELOC_TIC54X_16_OF_23
;
5284 /* TI assembler always uses this, regardless of addressing mode. */
5286 r
= BFD_RELOC_TIC54X_23
;
5288 /* We never want to directly generate this; this is provided for
5289 stabs support only. */
5293 fix_new_exp (frag
, where
, octets
, exp
, 0, r
);
5296 /* Attempt to simplify or even eliminate a fixup.
5297 To indicate that a fixup has been eliminated, set fixP->fx_done.
5299 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5301 md_apply_fix (fixP
, valP
)
5305 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5308 switch (fixP
->fx_r_type
)
5311 as_fatal ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
5313 case BFD_RELOC_TIC54X_MS7_OF_23
:
5314 val
= (val
>> 16) & 0x7F;
5316 case BFD_RELOC_TIC54X_16_OF_23
:
5318 bfd_put_16 (stdoutput
, val
, buf
);
5319 /* Indicate what we're actually writing, so that we don't get warnings
5320 about exceeding available space. */
5321 *valP
= val
& 0xFFFF;
5323 case BFD_RELOC_TIC54X_PARTLS7
:
5324 bfd_put_16 (stdoutput
,
5325 (bfd_get_16 (stdoutput
, buf
) & 0xFF80) | (val
& 0x7F),
5327 /* Indicate what we're actually writing, so that we don't get warnings
5328 about exceeding available space. */
5331 case BFD_RELOC_TIC54X_PARTMS9
:
5332 /* TI assembler doesn't shift its encoding for relocatable files, and is
5333 thus incompatible with this implementation's relocatable files. */
5334 bfd_put_16 (stdoutput
,
5335 (bfd_get_16 (stdoutput
, buf
) & 0xFE00) | (val
>> 7),
5339 case BFD_RELOC_TIC54X_23
:
5340 bfd_put_32 (stdoutput
,
5341 (bfd_get_32 (stdoutput
, buf
) & 0xFF800000) | val
,
5346 return 0; /* Return value is ignored. */
5349 /* This is our chance to record section alignment
5350 don't need to do anything here, since BFD does the proper encoding. */
5352 md_section_align (segment
, section_size
)
5353 segT segment ATTRIBUTE_UNUSED
;
5354 valueT section_size
;
5356 return section_size
;
5360 md_pcrel_from (fixP
)
5361 fixS
*fixP ATTRIBUTE_UNUSED
;
5366 #if defined OBJ_COFF
5369 tc_coff_fix2rtype (fixP
)
5372 return (fixP
->fx_r_type
);
5375 #endif /* OBJ_COFF */
5377 /* Mostly little-endian, but longwords (4 octets) get MS word stored first. */
5379 tic54x_number_to_chars (buf
, val
, n
)
5385 number_to_chars_littleendian (buf
, val
, n
);
5388 number_to_chars_littleendian (buf
, val
>>16, 2);
5389 number_to_chars_littleendian (buf
+2, val
&0xFFFF, 2);
5394 tic54x_estimate_size_before_relax (frag
, seg
)
5395 fragS
*frag ATTRIBUTE_UNUSED
;
5396 segT seg ATTRIBUTE_UNUSED
;
5401 /* We use this to handle bit allocations which we couldn't handle before due
5402 to symbols being in different frags. return number of octets added. */
5404 tic54x_relax_frag (frag
, stretch
)
5406 long stretch ATTRIBUTE_UNUSED
;
5408 symbolS
*sym
= frag
->fr_symbol
;
5414 struct bit_info
*bi
= (struct bit_info
*)frag
->fr_opcode
;
5415 int bit_offset
= frag_bit_offset (frag_prev (frag
, bi
->seg
), bi
->seg
);
5416 int size
= S_GET_VALUE (sym
);
5417 fragS
*prev_frag
= bit_offset_frag (frag_prev (frag
, bi
->seg
), bi
->seg
);
5418 int available
= 16 - bit_offset
;
5420 if (symbol_get_frag (sym
) != &zero_address_frag
5421 || S_IS_COMMON (sym
)
5422 || !S_IS_DEFINED (sym
))
5423 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5424 _("non-absolute value used with .space/.bes"));
5428 as_warn (_("negative value ignored in %s"),
5429 bi
->type
== TYPE_SPACE
? ".space" :
5430 bi
->type
== TYPE_BES
? ".bes" : ".field");
5432 frag
->tc_frag_data
= frag
->fr_fix
= 0;
5436 if (bi
->type
== TYPE_FIELD
)
5438 /* Bit fields of 16 or larger will have already been handled. */
5439 if (bit_offset
!= 0 && available
>= size
)
5441 char *p
= prev_frag
->fr_literal
;
5442 valueT value
= bi
->value
;
5443 value
<<= available
- size
;
5444 value
|= ((unsigned short)p
[1]<<8) | p
[0];
5445 md_number_to_chars (p
, value
, 2);
5446 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5447 prev_frag
->tc_frag_data
= 0;
5449 symbol_set_frag (bi
->sym
, prev_frag
);
5450 /* This frag is no longer used. */
5451 growth
= -frag
->fr_fix
;
5453 frag
->tc_frag_data
= 0;
5457 char *p
= frag
->fr_literal
;
5458 valueT value
= bi
->value
<< (16 - size
);
5459 md_number_to_chars (p
, value
, 2);
5460 if ((frag
->tc_frag_data
= size
) == 16)
5461 frag
->tc_frag_data
= 0;
5467 if (bit_offset
!= 0 && bit_offset
< 16)
5469 if (available
>= size
)
5471 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5472 prev_frag
->tc_frag_data
= 0;
5474 symbol_set_frag (bi
->sym
, prev_frag
);
5475 /* this frag is no longer used */
5476 growth
= -frag
->fr_fix
;
5478 frag
->tc_frag_data
= 0;
5481 if (bi
->type
== TYPE_SPACE
&& bi
->sym
)
5482 symbol_set_frag (bi
->sym
, prev_frag
);
5485 growth
= (size
+ 15) / 16 * OCTETS_PER_BYTE
- frag
->fr_fix
;
5486 for (i
=0;i
< growth
;i
++)
5487 frag
->fr_literal
[i
] = 0;
5488 frag
->fr_fix
= growth
;
5489 frag
->tc_frag_data
= size
% 16;
5490 /* Make sure any BES label points to the LAST word allocated. */
5491 if (bi
->type
== TYPE_BES
&& bi
->sym
)
5492 S_SET_VALUE (bi
->sym
, frag
->fr_fix
/ OCTETS_PER_BYTE
- 1);
5495 frag
->fr_symbol
= 0;
5496 frag
->fr_opcode
= 0;
5503 tic54x_convert_frag (abfd
, seg
, frag
)
5504 bfd
*abfd ATTRIBUTE_UNUSED
;
5505 segT seg ATTRIBUTE_UNUSED
;
5508 /* Offset is in bytes. */
5509 frag
->fr_offset
= (frag
->fr_next
->fr_address
5511 - frag
->fr_fix
) / frag
->fr_var
;
5512 if (frag
->fr_offset
< 0)
5514 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5515 _("attempt to .space/.bes backwards? (%ld)"),
5516 (long) frag
->fr_offset
);
5518 frag
->fr_type
= rs_space
;
5521 /* We need to avoid having labels defined for certain directives/pseudo-ops
5522 since once the label is defined, it's in the symbol table for good. TI
5523 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5524 I guess, except I've never seen a definition of MRI syntax).
5526 C is the character that used to be at *REST, which points to the end of the
5529 Don't allow labels to start with '.' */
5531 tic54x_start_label (c
, rest
)
5535 /* If within .struct/.union, no auto line labels, please. */
5536 if (current_stag
!= NULL
)
5539 /* Disallow labels starting with "." */
5543 while (!is_end_of_line
[(int)label
[-1]])
5547 as_bad (_("Invalid label '%s'"), label
);
5552 if (is_end_of_line
[(int)c
])
5556 while (isspace (c
= *++rest
))
5560 /* Don't let colon () define a label for any of these... */
5561 return (strncasecmp (rest
, ".tag", 4) != 0 || !isspace (rest
[4]))
5562 && (strncasecmp (rest
, ".struct", 7) != 0 || !isspace (rest
[7]))
5563 && (strncasecmp (rest
, ".union", 6) != 0 || !isspace (rest
[6]))
5564 && (strncasecmp (rest
, ".macro", 6) != 0 || !isspace (rest
[6]))
5565 && (strncasecmp (rest
, ".set", 4) != 0 || !isspace (rest
[4]))
5566 && (strncasecmp (rest
, ".equ", 4) != 0 || !isspace (rest
[4]));