1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
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.
44 COFF1 limits section names to 8 characters.
45 Some of the default behavior changed from COFF1 to COFF2.
52 #include "safe-ctype.h"
56 #include "struc-symbol.h"
57 #include "opcode/tic54x.h"
61 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
63 const char comment_chars
[] = ";";
64 const char line_comment_chars
[] = ";*#"; /* At column zero only. */
65 const char line_separator_chars
[] = ""; /* Not permitted. */
67 /* Characters which indicate that this is a floating point constant. */
68 const char FLT_CHARS
[] = "fF";
70 /* Characters that can be used to separate mantissa from exp in FP
72 const char EXP_CHARS
[] = "eE";
74 /* Only word (et al.), align, or conditionals are allowed within
76 #define ILLEGAL_WITHIN_STRUCT() \
78 if (current_stag != NULL) \
80 as_bad (_("pseudo-op illegal within .struct/.union")); \
86 md_show_usage (stream
)
89 fprintf (stream
, _("C54x-specific command line options:\n"));
90 fprintf (stream
, _("-mfar-mode | -mf Use extended addressing\n"));
91 fprintf (stream
, _("-mcpu=<CPU version> Specify the CPU version\n"));
93 fprintf (stream
, _("-mcoff-version={0|1|2} Select COFF version\n"));
95 fprintf (stream
, _("-merrors-to-file <filename>\n"));
96 fprintf (stream
, _("-me <filename> Redirect errors to a file\n"));
99 const char *md_shortopts
= "";
103 VNONE
= 0, V541
= 1, V542
= 2, V543
= 3, V545
= 5, V548
= 8, V549
= 9,
104 V545LP
= 15, V546LP
= 16
109 c_mode
, /* 16-bit addresses. */
110 far_mode
/* >16-bit addresses. */
113 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
114 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
115 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
116 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
118 struct option md_longopts
[] =
120 { "mfar-mode", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
121 { "mf", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
122 { "mcpu", required_argument
, NULL
, OPTION_CPU_VERSION
},
124 { "mcoff-version", required_argument
, NULL
, OPTION_COFF_VERSION
},
126 { "merrors-to-file", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
127 { "me", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
128 { NULL
, no_argument
, NULL
, 0},
131 size_t md_longopts_size
= sizeof (md_longopts
);
133 static int assembly_begun
= 0;
134 /* Addressing mode is not entirely implemented; the latest rev of the Other
135 assembler doesn't seem to make any distinction whatsoever; all relocations
136 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
137 but now it seems all relocations are RELEXT16. We use all RELEXT16.
139 The cpu version is kind of a waste of time as well. There is one
140 instruction (RND) for LP devices only, and several for devices with
141 extended addressing only. We include it for compatibility. */
142 static enum address_mode amode
= c_mode
;
143 static enum cpu_version cpu
= VNONE
;
145 /* Include string substitutions in listing? */
146 static int listing_sslist
= 0;
148 /* Did we do subsym substitutions on the line? */
149 static int substitution_line
= 0;
151 /* Last label seen. */
152 static symbolS
*last_label_seen
= NULL
;
154 /* This ensures that all new labels are unique. */
155 static int local_label_id
;
157 static struct hash_control
*subsym_recurse_hash
; /* Prevent infinite recurse. */
158 static struct hash_control
*math_hash
; /* Built-in math functions. */
159 /* Allow maximum levels of macro nesting; level 0 is the main substitution
160 symbol table. The other assembler only does 32 levels, so there! */
161 static struct hash_control
*subsym_hash
[100];
163 /* Keep track of local labels so we can substitute them before GAS sees them
164 since macros use their own 'namespace' for local labels, use a separate hash
166 We do our own local label handling 'cuz it's subtly different from the
169 We use our own macro nesting counter, since GAS overloads it when expanding
170 other things (like conditionals and repeat loops). */
171 static int macro_level
= 0;
172 static struct hash_control
*local_label_hash
[100];
173 /* Keep track of struct/union tags. */
174 static struct hash_control
*stag_hash
;
175 static struct hash_control
*op_hash
;
176 static struct hash_control
*parop_hash
;
177 static struct hash_control
*reg_hash
;
178 static struct hash_control
*mmreg_hash
;
179 static struct hash_control
*cc_hash
;
180 static struct hash_control
*cc2_hash
;
181 static struct hash_control
*cc3_hash
;
182 static struct hash_control
*sbit_hash
;
183 static struct hash_control
*misc_symbol_hash
;
185 static char *subsym_substitute
PARAMS ((char *line
, int forced
));
186 static char *subsym_lookup
PARAMS ((char *name
, int nest_level
));
187 static void subsym_create_or_replace
PARAMS ((char *name
, char *value
));
188 static float math_ceil
PARAMS ((float, float));
189 static float math_cvi
PARAMS ((float, float));
190 static float math_floor
PARAMS ((float, float));
191 static float math_fmod
PARAMS ((float, float));
192 static float math_int
PARAMS ((float, float));
193 static float math_round
PARAMS ((float, float));
194 static float math_sgn
PARAMS ((float, float));
195 static float math_trunc
PARAMS ((float, float));
196 static float math_acos
PARAMS ((float, float));
197 static float math_asin
PARAMS ((float, float));
198 static float math_atan
PARAMS ((float, float));
199 static float math_atan2
PARAMS ((float, float));
200 static float math_cosh
PARAMS ((float, float));
201 static float math_cos
PARAMS ((float, float));
202 static float math_cvf
PARAMS ((float, float));
203 static float math_exp
PARAMS ((float, float));
204 static float math_fabs
PARAMS ((float, float));
205 static float math_ldexp
PARAMS ((float, float));
206 static float math_log10
PARAMS ((float, float));
207 static float math_log
PARAMS ((float, float));
208 static float math_max
PARAMS ((float, float));
209 static float math_pow
PARAMS ((float, float));
210 static float math_sin
PARAMS ((float, float));
211 static float math_sinh
PARAMS ((float, float));
212 static float math_sqrt
PARAMS ((float, float));
213 static float math_tan
PARAMS ((float, float));
214 static float math_tanh
PARAMS ((float, float));
218 symbolS
*sym
; /* Symbol for this stag; value is offset. */
219 const char *name
; /* Shortcut to symbol name. */
220 bfd_vma size
; /* Size of struct/union. */
221 int current_bitfield_offset
; /* Temporary for tracking fields. */
223 struct stag_field
/* List of fields. */
226 bfd_vma offset
; /* Of start of this field. */
227 int bitfield_offset
; /* Of start of this field. */
228 struct stag
*stag
; /* If field is struct/union. */
229 struct stag_field
*next
;
231 /* For nesting; used only in stag construction. */
232 struct stag
*inner
; /* Enclosed .struct. */
233 struct stag
*outer
; /* Enclosing .struct. */
234 } *current_stag
= NULL
;
236 static segT stag_saved_seg
;
237 static subsegT stag_saved_subseg
;
239 /* Output a single character (upper octect is zero). */
242 tic54x_emit_char (char c
)
246 exp
.X_op
= O_constant
;
247 exp
.X_add_number
= c
;
251 /* Walk backwards in the frag chain. */
254 frag_prev (fragS
*frag
, segT seg
)
256 segment_info_type
*seginfo
= seg_info (seg
);
259 for (fragp
= seginfo
->frchainP
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
260 if (fragp
->fr_next
== frag
)
267 bit_offset_frag (fragS
*frag
, segT seg
)
271 if (frag
->fr_fix
== 0
272 && frag
->fr_opcode
== NULL
273 && frag
->tc_frag_data
== 0)
274 frag
= frag_prev (frag
, seg
);
281 /* Return the number of bits allocated in the most recent word, or zero if
282 none. .field/.space/.bes may leave words partially allocated. */
285 frag_bit_offset (fragS
*frag
, segT seg
)
287 frag
= bit_offset_frag (frag
, seg
);
290 return frag
->fr_opcode
!= NULL
? -1 : frag
->tc_frag_data
;
295 /* Read an expression from a C string; returns a pointer past the end of the
299 parse_expression (char *str
, expressionS
* exp
)
304 tmp
= input_line_pointer
; /* Save line pointer. */
305 input_line_pointer
= str
;
307 s
= input_line_pointer
;
308 input_line_pointer
= tmp
; /* Restore line pointer. */
309 return s
; /* Return pointer to where parsing stopped. */
312 /* .asg "character-string"|character-string, symbol
314 .eval is the only pseudo-op allowed to perform arithmetic on substitution
315 symbols. all other use of symbols defined with .asg are currently
319 tic54x_asg (int x ATTRIBUTE_UNUSED
)
325 int quoted
= *input_line_pointer
== '"';
327 ILLEGAL_WITHIN_STRUCT ();
332 str
= demand_copy_C_string (&len
);
333 c
= *input_line_pointer
;
337 str
= input_line_pointer
;
338 while ((c
= *input_line_pointer
) != ',')
340 if (is_end_of_line
[(int) *input_line_pointer
])
342 ++input_line_pointer
;
344 *input_line_pointer
= 0;
348 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
349 ignore_rest_of_line ();
353 name
= ++input_line_pointer
;
354 c
= get_symbol_end (); /* Get terminator. */
355 if (!ISALPHA (*name
))
357 as_bad ("symbols assigned with .asg must begin with a letter");
358 ignore_rest_of_line ();
362 tmp
= xmalloc (strlen (str
) + 1);
365 tmp
= xmalloc (strlen (name
) + 1);
368 subsym_create_or_replace (name
, str
);
369 *input_line_pointer
= c
;
370 demand_empty_rest_of_line ();
373 /* .eval expression, symbol
374 There's something screwy about this. The other assembler sometimes does and
375 sometimes doesn't substitute symbols defined with .eval.
376 We'll put the symbols into the subsym table as well as the normal symbol
377 table, since that's what works best. */
380 tic54x_eval (int x ATTRIBUTE_UNUSED
)
386 char valuestr
[32], *tmp
;
389 ILLEGAL_WITHIN_STRUCT ();
393 quoted
= *input_line_pointer
== '"';
395 ++input_line_pointer
;
396 value
= get_absolute_expression ();
399 if (*input_line_pointer
!= '"')
401 as_bad (_("Unterminated string after absolute expression"));
402 ignore_rest_of_line ();
405 ++input_line_pointer
;
407 if (*input_line_pointer
++ != ',')
409 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
410 ignore_rest_of_line ();
413 name
= input_line_pointer
;
414 c
= get_symbol_end (); /* Get terminator. */
415 tmp
= xmalloc (strlen (name
) + 1);
416 name
= strcpy (tmp
, name
);
417 *input_line_pointer
= c
;
419 if (!ISALPHA (*name
))
421 as_bad (_("symbols assigned with .eval must begin with a letter"));
422 ignore_rest_of_line ();
425 symbolP
= symbol_new (name
, absolute_section
,
426 (valueT
) value
, &zero_address_frag
);
427 SF_SET_LOCAL (symbolP
);
428 symbol_table_insert (symbolP
);
430 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
431 But since there's not written rule as to when, don't even bother trying
432 to match their behavior. */
433 sprintf (valuestr
, "%d", value
);
434 tmp
= xmalloc (strlen (valuestr
) + 1);
435 strcpy (tmp
, valuestr
);
436 subsym_create_or_replace (name
, tmp
);
438 demand_empty_rest_of_line ();
441 /* .bss symbol, size [, [blocking flag] [, alignment flag]
443 alignment is to a longword boundary; blocking is to 128-word boundary.
445 1) if there is a hole in memory, this directive should attempt to fill it
446 (not yet implemented).
448 2) if the blocking flag is not set, allocate at the current SPC
449 otherwise, check to see if the current SPC plus the space to be
450 allocated crosses the page boundary (128 words).
451 if there's not enough space, create a hole and align with the next page
453 (not yet implemented). */
456 tic54x_bss (int x ATTRIBUTE_UNUSED
)
463 subsegT current_subseg
;
468 ILLEGAL_WITHIN_STRUCT ();
470 current_seg
= now_seg
; /* Save current seg. */
471 current_subseg
= now_subseg
; /* Save current subseg. */
473 name
= input_line_pointer
;
474 c
= get_symbol_end (); /* Get terminator. */
477 as_bad (".bss size argument missing\n");
478 ignore_rest_of_line ();
482 ++input_line_pointer
;
483 words
= get_absolute_expression ();
486 as_bad (".bss size %d < 0!", words
);
487 ignore_rest_of_line ();
491 if (*input_line_pointer
== ',')
493 /* The blocking flag may be missing. */
494 ++input_line_pointer
;
495 if (*input_line_pointer
!= ',')
496 block
= get_absolute_expression ();
500 if (*input_line_pointer
== ',')
502 ++input_line_pointer
;
503 align
= get_absolute_expression ();
511 subseg_set (bss_section
, 0);
512 symbolP
= symbol_find_or_make (name
);
514 if (S_GET_SEGMENT (symbolP
) == bss_section
)
515 symbolP
->sy_frag
->fr_symbol
= (symbolS
*) NULL
;
517 symbol_set_frag (symbolP
, frag_now
);
518 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
519 (offsetT
) (words
* OCTETS_PER_BYTE
), (char *) 0);
520 *p
= 0; /* Fill char. */
522 S_SET_SEGMENT (symbolP
, bss_section
);
524 /* The symbol may already have been created with a preceding
525 ".globl" directive -- be careful not to step on storage class
526 in that case. Otherwise, set it to static. */
527 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
528 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
532 /* s_align eats end of line; restore it */
534 --input_line_pointer
;
538 bss_section
->flags
|= SEC_BLOCK
;
540 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
541 demand_empty_rest_of_line ();
545 stag_add_field_symbols (struct stag
*stag
,
549 const char *root_stag_name
)
551 char prefix
[strlen (path
) + 2];
552 struct stag_field
*field
= stag
->field
;
554 /* Construct a symbol for every field contained within this structure
555 including fields within structure fields. */
556 strcpy (prefix
, path
);
558 strcat (prefix
, ".");
560 while (field
!= NULL
)
562 int len
= strlen (prefix
) + strlen (field
->name
) + 2;
563 char *name
= xmalloc (len
);
564 strcpy (name
, prefix
);
565 strcat (name
, field
->name
);
570 sym
= symbol_new (name
, absolute_section
,
571 (field
->stag
? field
->offset
:
572 (valueT
) (base_offset
+ field
->offset
)),
575 symbol_table_insert (sym
);
579 char *replacement
= xmalloc (strlen (name
)
580 + strlen (stag
->name
) + 2);
581 strcpy (replacement
, S_GET_NAME (rootsym
));
582 strcat (replacement
, "+");
583 strcat (replacement
, root_stag_name
);
584 strcat (replacement
, name
+ strlen (S_GET_NAME (rootsym
)));
585 hash_insert (subsym_hash
[0], name
, replacement
);
588 /* Recurse if the field is a structure.
589 Note the field offset is relative to the outermost struct. */
590 if (field
->stag
!= NULL
)
591 stag_add_field_symbols (field
->stag
, name
,
593 rootsym
, root_stag_name
);
598 /* Keep track of stag fields so that when structures are nested we can add the
599 complete dereferencing symbols to the symbol table. */
602 stag_add_field (struct stag
*parent
,
607 struct stag_field
*sfield
= xmalloc (sizeof (struct stag_field
));
609 memset (sfield
, 0, sizeof (*sfield
));
610 sfield
->name
= strcpy (xmalloc (strlen (name
) + 1), name
);
611 sfield
->offset
= offset
;
612 sfield
->bitfield_offset
= parent
->current_bitfield_offset
;
614 if (parent
->field
== NULL
)
615 parent
->field
= sfield
;
618 struct stag_field
*sf
= parent
->field
;
619 while (sf
->next
!= NULL
)
623 /* Only create a symbol for this field if the parent has no name. */
624 if (!strncmp (".fake", parent
->name
, 5))
626 symbolS
*sym
= symbol_new (name
, absolute_section
,
627 (valueT
) offset
, &zero_address_frag
);
629 symbol_table_insert (sym
);
633 /* [STAG] .struct [OFFSET]
634 Start defining structure offsets (symbols in absolute section). */
637 tic54x_struct (int arg
)
639 int start_offset
= 0;
644 /* Starting a new struct, switch to absolute section. */
645 stag_saved_seg
= now_seg
;
646 stag_saved_subseg
= now_subseg
;
647 subseg_set (absolute_section
, 0);
649 /* Align the current pointer. */
650 else if (current_stag
->current_bitfield_offset
!= 0)
652 ++abs_section_offset
;
653 current_stag
->current_bitfield_offset
= 0;
656 /* Offset expression is only meaningful for global .structs. */
659 /* Offset is ignored in inner structs. */
661 if (!is_end_of_line
[(int) *input_line_pointer
])
662 start_offset
= get_absolute_expression ();
669 /* Nesting, link to outer one. */
670 current_stag
->inner
= (struct stag
*) xmalloc (sizeof (struct stag
));
671 memset (current_stag
->inner
, 0, sizeof (struct stag
));
672 current_stag
->inner
->outer
= current_stag
;
673 current_stag
= current_stag
->inner
;
675 as_warn (_("Offset on nested structures is ignored"));
676 start_offset
= abs_section_offset
;
680 current_stag
= (struct stag
*) xmalloc (sizeof (struct stag
));
681 memset (current_stag
, 0, sizeof (struct stag
));
682 abs_section_offset
= start_offset
;
684 current_stag
->is_union
= is_union
;
686 if (line_label
== NULL
)
688 static int struct_count
= 0;
689 char fake
[] = ".fake_stagNNNNNNN";
690 sprintf (fake
, ".fake_stag%d", struct_count
++);
691 current_stag
->sym
= symbol_new (fake
, absolute_section
,
692 (valueT
) abs_section_offset
,
697 char label
[strlen (S_GET_NAME (line_label
)) + 1];
698 strcpy (label
, S_GET_NAME (line_label
));
699 current_stag
->sym
= symbol_new (label
, absolute_section
,
700 (valueT
) abs_section_offset
,
703 current_stag
->name
= S_GET_NAME (current_stag
->sym
);
704 SF_SET_LOCAL (current_stag
->sym
);
705 /* Nested .structs don't go into the symbol table. */
706 if (current_stag
->outer
== NULL
)
707 symbol_table_insert (current_stag
->sym
);
712 /* [LABEL] .endstruct
713 finish defining structure offsets; optional LABEL's value will be the size
717 tic54x_endstruct (int is_union
)
721 !strncmp (current_stag
->name
, ".fake", 5) ? "" : current_stag
->name
;
723 if (!current_stag
|| current_stag
->is_union
!= is_union
)
725 as_bad (_(".end%s without preceding .%s"),
726 is_union
? "union" : "struct",
727 is_union
? "union" : "struct");
728 ignore_rest_of_line ();
732 /* Align end of structures. */
733 if (current_stag
->current_bitfield_offset
)
735 ++abs_section_offset
;
736 current_stag
->current_bitfield_offset
= 0;
739 if (current_stag
->is_union
)
740 size
= current_stag
->size
;
742 size
= abs_section_offset
- S_GET_VALUE (current_stag
->sym
);
743 if (line_label
!= NULL
)
745 S_SET_VALUE (line_label
, size
);
746 symbol_table_insert (line_label
);
750 /* Union size has already been calculated. */
751 if (!current_stag
->is_union
)
752 current_stag
->size
= size
;
753 /* Nested .structs don't get put in the stag table. */
754 if (current_stag
->outer
== NULL
)
756 hash_insert (stag_hash
, current_stag
->name
, current_stag
);
757 stag_add_field_symbols (current_stag
, path
,
758 S_GET_VALUE (current_stag
->sym
),
761 current_stag
= current_stag
->outer
;
763 /* If this is a nested .struct/.union, add it as a field to the enclosing
764 one. otherwise, restore the section we were in. */
765 if (current_stag
!= NULL
)
767 stag_add_field (current_stag
, current_stag
->inner
->name
,
768 S_GET_VALUE (current_stag
->inner
->sym
),
769 current_stag
->inner
);
772 subseg_set (stag_saved_seg
, stag_saved_subseg
);
776 Reference a structure within a structure, as a sized field with an optional
778 If used outside of a .struct/.endstruct, overlays the given structure
779 format on the existing allocated space. */
782 tic54x_tag (int ignore ATTRIBUTE_UNUSED
)
784 char *name
= input_line_pointer
;
785 int c
= get_symbol_end ();
786 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
791 as_bad (_("Unrecognized struct/union tag '%s'"), name
);
793 as_bad (_(".tag requires a structure tag"));
794 ignore_rest_of_line ();
797 if (line_label
== NULL
)
799 as_bad (_("Label required for .tag"));
800 ignore_rest_of_line ();
805 char label
[strlen (S_GET_NAME (line_label
)) + 1];
807 strcpy (label
, S_GET_NAME (line_label
));
808 if (current_stag
!= NULL
)
809 stag_add_field (current_stag
, label
,
810 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
814 symbolS
*sym
= symbol_find (label
);
817 as_bad (_(".tag target '%s' undefined"), label
);
818 ignore_rest_of_line ();
821 stag_add_field_symbols (stag
, S_GET_NAME (sym
),
822 S_GET_VALUE (stag
->sym
), sym
, stag
->name
);
826 /* Bump by the struct size, but only if we're within a .struct section. */
827 if (current_stag
!= NULL
&& !current_stag
->is_union
)
828 abs_section_offset
+= stag
->size
;
830 *input_line_pointer
= c
;
831 demand_empty_rest_of_line ();
835 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
836 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
840 tic54x_struct_field (int type
)
844 int new_bitfield_offset
= 0;
845 int field_align
= current_stag
->current_bitfield_offset
!= 0;
846 int longword_align
= 0;
849 if (!is_end_of_line
[(int) *input_line_pointer
])
850 count
= get_absolute_expression ();
866 case '*': /* String. */
875 case '.': /* Bitfield. */
877 if (count
< 1 || count
> 32)
879 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count
);
880 ignore_rest_of_line ();
883 if (current_stag
->current_bitfield_offset
+ count
> 16)
885 /* Set the appropriate size and new field offset. */
895 new_bitfield_offset
= count
- 16;
899 new_bitfield_offset
= count
;
905 new_bitfield_offset
= current_stag
->current_bitfield_offset
+ count
;
909 as_bad (_("Unrecognized field type '%c'"), type
);
910 ignore_rest_of_line ();
916 /* Align to the actual starting position of the field. */
917 current_stag
->current_bitfield_offset
= 0;
918 ++abs_section_offset
;
920 /* Align to longword boundary. */
921 if (longword_align
&& (abs_section_offset
& 0x1))
922 ++abs_section_offset
;
924 if (line_label
== NULL
)
926 static int fieldno
= 0;
927 char fake
[] = ".fake_fieldNNNNN";
928 sprintf (fake
, ".fake_field%d", fieldno
++);
929 stag_add_field (current_stag
, fake
,
930 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
935 char label
[strlen (S_GET_NAME (line_label
) + 1)];
936 strcpy (label
, S_GET_NAME (line_label
));
937 stag_add_field (current_stag
, label
,
938 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
942 if (current_stag
->is_union
)
944 /* Note we treat the element as if it were an array of COUNT. */
945 if (current_stag
->size
< (unsigned) size
* count
)
946 current_stag
->size
= size
* count
;
950 abs_section_offset
+= (unsigned) size
* count
;
951 current_stag
->current_bitfield_offset
= new_bitfield_offset
;
956 /* Handle .byte, .word. .int, .long and all variants. */
958 int emitting_long
= 0;
960 tic54x_cons (int type
)
962 register unsigned int c
;
965 /* If we're within a .struct construct, don't actually allocate space. */
966 if (current_stag
!= NULL
)
968 tic54x_struct_field (type
);
972 #ifdef md_flush_pending_output
973 md_flush_pending_output ();
976 generate_lineno_debug ();
978 /* Align long words to long word boundaries (4 octets). */
979 if (type
== 'l' || type
== 'L')
981 frag_align (2, 0, 2);
982 /* If there's a label, assign it to the first allocated word. */
983 if (line_label
!= NULL
)
985 symbol_set_frag (line_label
, frag_now
);
986 S_SET_VALUE (line_label
, frag_now_fix ());
1010 if (*input_line_pointer
== '"')
1012 input_line_pointer
++;
1013 while (is_a_char (c
= next_char_of_string ()))
1014 tic54x_emit_char (c
);
1015 know (input_line_pointer
[-1] == '\"');
1021 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1022 if (exp
.X_op
== O_constant
)
1024 offsetT value
= exp
.X_add_number
;
1025 /* Truncate overflows. */
1029 if ((value
> 0 && value
> 0xFF)
1030 || (value
< 0 && value
< - 0x100))
1031 as_warn ("Overflow in expression, truncated to 8 bits");
1034 if ((value
> 0 && value
> 0xFFFF)
1035 || (value
< 0 && value
< - 0x10000))
1036 as_warn ("Overflow in expression, truncated to 16 bits");
1040 if (exp
.X_op
!= O_constant
&& octets
< 2)
1042 /* Disallow .byte with a non constant expression that will
1043 require relocation. */
1044 as_bad (_("Relocatable values require at least WORD storage"));
1045 ignore_rest_of_line ();
1049 if (exp
.X_op
!= O_constant
1053 /* FIXME -- at one point TI tools used to output REL16
1054 relocations, but I don't think the latest tools do at all
1055 The current tools output extended relocations regardless of
1056 the addresing mode (I actually think that ".c_mode" is
1057 totally ignored in the latest tools). */
1060 emit_expr (&exp
, 4);
1066 emitting_long
= octets
== 4;
1067 emit_expr (&exp
, (octets
== 1) ? 2 : octets
);
1072 while (*input_line_pointer
++ == ',');
1074 input_line_pointer
--; /* Put terminator back into stream. */
1075 demand_empty_rest_of_line ();
1078 /* .global <symbol>[,...,<symbolN>]
1079 .def <symbol>[,...,<symbolN>]
1080 .ref <symbol>[,...,<symbolN>]
1082 These all identify global symbols.
1084 .def means the symbol is defined in the current module and can be accessed
1085 by other files. The symbol should be placed in the symbol table.
1087 .ref means the symbol is used in the current module but defined in another
1088 module. The linker is to resolve this symbol's definition at link time.
1090 .global should act as a .ref or .def, as needed.
1092 global, def and ref all have symbol storage classes of C_EXT.
1094 I can't identify any difference in how the "other" c54x assembler treats
1095 these, so we ignore the type here. */
1098 tic54x_global (int type
)
1105 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1107 ILLEGAL_WITHIN_STRUCT ();
1111 name
= input_line_pointer
;
1112 c
= get_symbol_end ();
1113 symbolP
= symbol_find_or_make (name
);
1115 *input_line_pointer
= c
;
1116 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
1119 input_line_pointer
++;
1120 if (is_end_of_line
[(int) *input_line_pointer
])
1121 c
= *input_line_pointer
;
1126 demand_empty_rest_of_line ();
1129 /* Remove the symbol from the local label hash lookup. */
1132 tic54x_remove_local_label (const char *key
,
1133 PTR value ATTRIBUTE_UNUSED
)
1135 PTR
*elem
= hash_delete (local_label_hash
[macro_level
], key
);
1139 /* Reset all local labels. */
1142 tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED
)
1144 hash_traverse (local_label_hash
[macro_level
], tic54x_remove_local_label
);
1149 .sect "section name"
1152 make sure local labels get cleared when changing sections
1154 ARG is 't' for text, 'd' for data, or '*' for a named section
1156 For compatibility, '*' sections are SEC_CODE if instructions are
1157 encountered, or SEC_DATA if not.
1161 tic54x_sect (int arg
)
1163 ILLEGAL_WITHIN_STRUCT ();
1165 /* Local labels are cleared when changing sections. */
1166 tic54x_clear_local_labels (0);
1170 else if (arg
== 'd')
1176 /* If there are quotes, remove them. */
1177 if (*input_line_pointer
== '"')
1179 name
= demand_copy_C_string (&len
);
1180 demand_empty_rest_of_line ();
1181 name
= strcpy (xmalloc (len
+ 10), name
);
1186 name
= input_line_pointer
;
1187 c
= get_symbol_end ();
1189 name
= strcpy (xmalloc (len
+ 10), name
);
1190 *input_line_pointer
= c
;
1191 demand_empty_rest_of_line ();
1193 /* Make sure all named initialized sections flagged properly. If we
1194 encounter instructions, we'll flag it with SEC_CODE as well. */
1195 strcat (name
, ",\"w\"\n");
1196 input_scrub_insert_line (name
);
1197 obj_coff_section (0);
1199 /* If there was a line label, make sure that it gets assigned the proper
1200 section. This is for compatibility, even though the actual behavior
1201 is not explicitly defined. For consistency, we make .sect behave
1202 like .usect, since that is probably what people expect. */
1203 if (line_label
!= NULL
)
1205 S_SET_SEGMENT (line_label
, now_seg
);
1206 symbol_set_frag (line_label
, frag_now
);
1207 S_SET_VALUE (line_label
, frag_now_fix ());
1208 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1209 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1214 /* [symbol] .space space_in_bits
1215 [symbol] .bes space_in_bits
1216 BES puts the symbol at the *last* word allocated
1218 cribbed from s_space. */
1221 tic54x_space (int arg
)
1227 int bits_per_byte
= (OCTETS_PER_BYTE
* 8);
1229 symbolS
*label
= line_label
;
1232 ILLEGAL_WITHIN_STRUCT ();
1234 #ifdef md_flush_pending_output
1235 md_flush_pending_output ();
1238 /* Read the bit count. */
1241 /* Some expressions are unresolvable until later in the assembly pass;
1242 postpone until relaxation/fixup. we also have to postpone if a previous
1243 partial allocation has not been completed yet. */
1244 if (exp
.X_op
!= O_constant
|| frag_bit_offset (frag_now
, now_seg
) == -1)
1246 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1252 p
= frag_var (rs_machine_dependent
,
1253 65536 * 2, 1, (relax_substateT
) 0,
1254 make_expr_symbol (&exp
), (offsetT
) 0,
1262 /* Reduce the required size by any bit offsets currently left over
1263 from a previous .space/.bes/.field directive. */
1264 bit_offset
= frag_now
->tc_frag_data
;
1265 if (bit_offset
!= 0 && bit_offset
< 16)
1267 int spare_bits
= bits_per_byte
- bit_offset
;
1268 if (spare_bits
>= exp
.X_add_number
)
1270 /* Don't have to do anything; sufficient bits have already been
1271 allocated; just point the label to the right place. */
1274 symbol_set_frag (label
, frag_now
);
1275 S_SET_VALUE (label
, frag_now_fix () - 1);
1278 frag_now
->tc_frag_data
+= exp
.X_add_number
;
1281 exp
.X_add_number
-= spare_bits
;
1282 /* Set the label to point to the first word allocated, which in this
1283 case is the previous word, which was only partially filled. */
1284 if (!bes
&& label
!= NULL
)
1286 symbol_set_frag (label
, frag_now
);
1287 S_SET_VALUE (label
, frag_now_fix () - 1);
1291 /* Convert bits to bytes/words and octets, rounding up. */
1292 words
= ((exp
.X_add_number
+ bits_per_byte
- 1) / bits_per_byte
);
1293 /* How many do we have left over? */
1294 bit_offset
= exp
.X_add_number
% bits_per_byte
;
1295 octets
= words
* OCTETS_PER_BYTE
;
1298 as_warn (_(".space/.bes repeat count is negative, ignored"));
1301 else if (octets
== 0)
1303 as_warn (_(".space/.bes repeat count is zero, ignored"));
1307 /* If we are in the absolute section, just bump the offset. */
1308 if (now_seg
== absolute_section
)
1310 abs_section_offset
+= words
;
1311 if (bes
&& label
!= NULL
)
1312 S_SET_VALUE (label
, abs_section_offset
- 1);
1313 frag_now
->tc_frag_data
= bit_offset
;
1318 p
= frag_var (rs_fill
, 1, 1,
1319 (relax_substateT
) 0, (symbolS
*) 0,
1320 (offsetT
) octets
, (char *) 0);
1322 /* Make note of how many bits of this word we've allocated so far. */
1323 frag_now
->tc_frag_data
= bit_offset
;
1325 /* .bes puts label at *last* word allocated. */
1326 if (bes
&& label
!= NULL
)
1328 symbol_set_frag (label
, frag_now
);
1329 S_SET_VALUE (label
, frag_now_fix () - 1);
1337 demand_empty_rest_of_line ();
1340 /* [symbol] .usect "section-name", size-in-words
1341 [, [blocking-flag] [, alignment-flag]]
1343 Unitialized section.
1344 Non-zero blocking means that if the section would cross a page (128-word)
1345 boundary, it will be page-aligned.
1346 Non-zero alignment aligns on a longword boundary.
1348 Has no effect on the current section. */
1351 tic54x_usect (int x ATTRIBUTE_UNUSED
)
1358 int size
, blocking_flag
, alignment_flag
;
1360 subsegT current_subseg
;
1363 ILLEGAL_WITHIN_STRUCT ();
1365 current_seg
= now_seg
; /* Save current seg. */
1366 current_subseg
= now_subseg
; /* Save current subseg. */
1368 if (*input_line_pointer
== '"')
1369 input_line_pointer
++;
1370 section_name
= input_line_pointer
;
1371 c
= get_symbol_end (); /* Get terminator. */
1372 input_line_pointer
++; /* Skip null symbol terminator. */
1373 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1374 strcpy (name
, section_name
);
1376 if (*input_line_pointer
== ',')
1377 ++input_line_pointer
;
1380 as_bad (_("Missing size argument"));
1381 ignore_rest_of_line ();
1385 size
= get_absolute_expression ();
1387 /* Read a possibly present third argument (blocking flag). */
1388 if (*input_line_pointer
== ',')
1390 ++input_line_pointer
;
1391 if (*input_line_pointer
!= ',')
1392 blocking_flag
= get_absolute_expression ();
1396 /* Read a possibly present fourth argument (alignment flag). */
1397 if (*input_line_pointer
== ',')
1399 ++input_line_pointer
;
1400 alignment_flag
= get_absolute_expression ();
1406 blocking_flag
= alignment_flag
= 0;
1408 seg
= subseg_new (name
, 0);
1409 flags
= bfd_get_section_flags (stdoutput
, seg
) | SEC_ALLOC
;
1413 /* s_align eats end of line; restore it. */
1415 --input_line_pointer
;
1418 if (line_label
!= NULL
)
1420 S_SET_SEGMENT (line_label
, seg
);
1421 symbol_set_frag (line_label
, frag_now
);
1422 S_SET_VALUE (line_label
, frag_now_fix ());
1423 /* Set scl to label, since that's what TI does. */
1424 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1425 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1428 seg_info (seg
)->bss
= 1; /* Uninitialized data. */
1430 p
= frag_var (rs_fill
, 1, 1,
1431 (relax_substateT
) 0, (symbolS
*) line_label
,
1432 size
* OCTETS_PER_BYTE
, (char *) 0);
1438 if (!bfd_set_section_flags (stdoutput
, seg
, flags
))
1439 as_warn ("Error setting flags for \"%s\": %s", name
,
1440 bfd_errmsg (bfd_get_error ()));
1442 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1443 demand_empty_rest_of_line ();
1446 static enum cpu_version
1447 lookup_version (const char *ver
)
1449 enum cpu_version version
= VNONE
;
1451 if (ver
[0] == '5' && ver
[1] == '4')
1453 if (strlen (ver
) == 3
1454 && (ver
[2] == '1' || ver
[2] == '2' || ver
[2] == '3'
1455 || ver
[2] == '5' || ver
[2] == '8' || ver
[2] == '9'))
1456 version
= ver
[2] - '0';
1457 else if (strlen (ver
) == 5
1458 && TOUPPER (ver
[3]) == 'L'
1459 && TOUPPER (ver
[4]) == 'P'
1460 && (ver
[2] == '5' || ver
[2] == '6'))
1461 version
= ver
[2] - '0' + 10;
1468 set_cpu (enum cpu_version version
)
1471 if (version
== V545LP
|| version
== V546LP
)
1473 symbolS
*symbolP
= symbol_new ("__allow_lp", absolute_section
,
1474 (valueT
) 1, &zero_address_frag
);
1475 SF_SET_LOCAL (symbolP
);
1476 symbol_table_insert (symbolP
);
1480 /* .version cpu-version
1481 cpu-version may be one of the following:
1491 This is for compatibility only. It currently has no affect on assembly. */
1492 static int cpu_needs_set
= 1;
1495 tic54x_version (int x ATTRIBUTE_UNUSED
)
1497 enum cpu_version version
= VNONE
;
1498 enum cpu_version old_version
= cpu
;
1502 ILLEGAL_WITHIN_STRUCT ();
1505 ver
= input_line_pointer
;
1506 while (!is_end_of_line
[(int) *input_line_pointer
])
1507 ++input_line_pointer
;
1508 c
= *input_line_pointer
;
1509 *input_line_pointer
= 0;
1511 version
= lookup_version (ver
);
1513 if (cpu
!= VNONE
&& cpu
!= version
)
1514 as_warn (_("CPU version has already been set"));
1516 if (version
== VNONE
)
1518 as_bad (_("Unrecognized version '%s'"), ver
);
1519 ignore_rest_of_line ();
1522 else if (assembly_begun
&& version
!= old_version
)
1524 as_bad (_("Changing of CPU version on the fly not supported"));
1525 ignore_rest_of_line ();
1531 *input_line_pointer
= c
;
1532 demand_empty_rest_of_line ();
1535 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1538 tic54x_float_cons (int type
)
1540 if (current_stag
!= 0)
1541 tic54x_struct_field ('f');
1543 #ifdef md_flush_pending_output
1544 md_flush_pending_output ();
1547 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1550 frag_align (2, 0, 2);
1551 /* If there's a label, assign it to the first allocated word. */
1552 if (line_label
!= NULL
)
1554 symbol_set_frag (line_label
, frag_now
);
1555 S_SET_VALUE (line_label
, frag_now_fix ());
1562 /* The argument is capitalized if it should be zero-terminated
1563 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1564 Code copied from stringer, and slightly modified so that strings are packed
1565 and encoded into the correct octets. */
1568 tic54x_stringer (int type
)
1570 register unsigned int c
;
1572 int append_zero
= type
== 'S' || type
== 'P';
1573 int packed
= type
== 'p' || type
== 'P';
1574 int last_char
= -1; /* Packed strings need two bytes at a time to encode. */
1576 if (current_stag
!= NULL
)
1578 tic54x_struct_field ('*');
1582 #ifdef md_flush_pending_output
1583 md_flush_pending_output ();
1586 c
= ','; /* Do loop. */
1590 switch (*input_line_pointer
)
1594 unsigned short value
= get_absolute_expression ();
1595 FRAG_APPEND_1_CHAR ( value
& 0xFF);
1596 FRAG_APPEND_1_CHAR ((value
>> 8) & 0xFF);
1600 ++input_line_pointer
; /* -> 1st char of string. */
1601 start
= input_line_pointer
;
1602 while (is_a_char (c
= next_char_of_string ()))
1606 FRAG_APPEND_1_CHAR (c
);
1607 FRAG_APPEND_1_CHAR (0);
1611 /* Packed strings are filled MS octet first. */
1612 if (last_char
== -1)
1616 FRAG_APPEND_1_CHAR (c
);
1617 FRAG_APPEND_1_CHAR (last_char
);
1624 if (packed
&& last_char
!= -1)
1626 FRAG_APPEND_1_CHAR (0);
1627 FRAG_APPEND_1_CHAR (last_char
);
1632 FRAG_APPEND_1_CHAR (0);
1633 FRAG_APPEND_1_CHAR (0);
1636 know (input_line_pointer
[-1] == '\"');
1640 c
= *input_line_pointer
;
1641 if (!is_end_of_line
[c
])
1642 ++input_line_pointer
;
1645 /* Finish up any leftover packed string. */
1646 if (packed
&& last_char
!= -1)
1648 FRAG_APPEND_1_CHAR (0);
1649 FRAG_APPEND_1_CHAR (last_char
);
1651 demand_empty_rest_of_line ();
1655 tic54x_p2align (int arg ATTRIBUTE_UNUSED
)
1657 as_bad (_("p2align not supported on this target"));
1661 tic54x_align_words (int arg
)
1663 /* Only ".align" with no argument is allowed within .struct/.union. */
1666 if (!is_end_of_line
[(int) *input_line_pointer
])
1669 as_warn (_("Argument to .even ignored"));
1671 count
= get_absolute_expression ();
1674 if (current_stag
!= NULL
&& arg
== 128)
1676 if (current_stag
->current_bitfield_offset
!= 0)
1678 current_stag
->current_bitfield_offset
= 0;
1679 ++abs_section_offset
;
1681 demand_empty_rest_of_line ();
1685 ILLEGAL_WITHIN_STRUCT ();
1687 s_align_bytes (count
<< 1);
1690 /* Initialize multiple-bit fields withing a single word of memory. */
1693 tic54x_field (int ignore ATTRIBUTE_UNUSED
)
1699 symbolS
*label
= line_label
;
1701 if (current_stag
!= NULL
)
1703 tic54x_struct_field ('.');
1707 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1709 if (*input_line_pointer
== ',')
1711 ++input_line_pointer
;
1712 size
= get_absolute_expression ();
1713 if (size
< 1 || size
> 32)
1715 as_bad (_("Invalid field size, must be from 1 to 32"));
1716 ignore_rest_of_line ();
1721 /* Truncate values to the field width. */
1722 if (exp
.X_op
!= O_constant
)
1724 /* If the expression value is relocatable, the field size *must*
1728 as_bad (_("field size must be 16 when value is relocatable"));
1729 ignore_rest_of_line ();
1733 frag_now
->tc_frag_data
= 0;
1734 emit_expr (&exp
, 2);
1738 unsigned long fmask
= (size
== 32) ? 0xFFFFFFFF : (1ul << size
) - 1;
1739 value
= exp
.X_add_number
;
1740 exp
.X_add_number
&= fmask
;
1741 if (value
!= (valueT
) exp
.X_add_number
)
1742 as_warn (_("field value truncated"));
1743 value
= exp
.X_add_number
;
1744 /* Bits are stored MS first. */
1747 frag_now
->tc_frag_data
= 0;
1749 md_number_to_chars (p
, (value
>> (size
- 16)) & 0xFFFF, 2);
1754 int bit_offset
= frag_bit_offset (frag_now
, now_seg
);
1755 fragS
*alloc_frag
= bit_offset_frag (frag_now
, now_seg
);
1756 if (bit_offset
== -1)
1758 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1759 /* We don't know the previous offset at this time, so store the
1760 info we need and figure it out later. */
1761 expressionS size_exp
;
1762 size_exp
.X_op
= O_constant
;
1763 size_exp
.X_add_number
= size
;
1765 bi
->type
= TYPE_FIELD
;
1767 p
= frag_var (rs_machine_dependent
,
1768 4, 1, (relax_substateT
) 0,
1769 make_expr_symbol (&size_exp
), (offsetT
) 0,
1773 else if (bit_offset
== 0 || bit_offset
+ size
> 16)
1775 /* Align a new field. */
1777 frag_now
->tc_frag_data
= 0;
1778 alloc_frag
= frag_now
;
1782 /* Put the new value entirely within the existing one. */
1783 p
= alloc_frag
== frag_now
?
1784 frag_now
->fr_literal
+ frag_now_fix_octets () - 2 :
1785 alloc_frag
->fr_literal
;
1788 symbol_set_frag (label
, alloc_frag
);
1789 if (alloc_frag
== frag_now
)
1790 S_SET_VALUE (label
, frag_now_fix () - 1);
1794 value
<<= 16 - alloc_frag
->tc_frag_data
- size
;
1796 /* OR in existing value. */
1797 if (alloc_frag
->tc_frag_data
)
1798 value
|= ((unsigned short) p
[1] << 8) | p
[0];
1799 md_number_to_chars (p
, value
, 2);
1800 alloc_frag
->tc_frag_data
+= size
;
1801 if (alloc_frag
->tc_frag_data
== 16)
1802 alloc_frag
->tc_frag_data
= 0;
1806 demand_empty_rest_of_line ();
1809 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1810 available yet. seg_info ()->bss is the next best thing. */
1813 tic54x_initialized_section (segT seg
)
1815 return !seg_info (seg
)->bss
;
1818 /* .clink ["section name"]
1820 Marks the section as conditionally linked (link only if contents are
1821 referenced elsewhere.
1822 Without a name, refers to the current initialized section.
1823 Name is required for uninitialized sections. */
1826 tic54x_clink (int ignored ATTRIBUTE_UNUSED
)
1830 ILLEGAL_WITHIN_STRUCT ();
1832 if (*input_line_pointer
== '\"')
1834 char *section_name
= ++input_line_pointer
;
1836 while (is_a_char (next_char_of_string ()))
1838 know (input_line_pointer
[-1] == '\"');
1839 input_line_pointer
[-1] = 0;
1840 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1841 strcpy (name
, section_name
);
1843 seg
= bfd_get_section_by_name (stdoutput
, name
);
1846 as_bad (_("Unrecognized section '%s'"), section_name
);
1847 ignore_rest_of_line ();
1853 if (!tic54x_initialized_section (seg
))
1855 as_bad (_("Current section is unitialized, "
1856 "section name required for .clink"));
1857 ignore_rest_of_line ();
1862 seg
->flags
|= SEC_CLINK
;
1864 demand_empty_rest_of_line ();
1867 /* Change the default include directory to be the current source file's
1868 directory, instead of the current working directory. If DOT is non-zero,
1869 set to "." instead. */
1872 tic54x_set_default_include (int dot
)
1882 as_where (&curfile
, &lineno
);
1883 dir
= strcpy (xmalloc (strlen (curfile
) + 1), curfile
);
1884 tmp
= strrchr (dir
, '/');
1891 if (include_dir_count
== 0)
1893 include_dirs
= (char **) xmalloc (sizeof (*include_dirs
));
1894 include_dir_count
= 1;
1896 include_dirs
[0] = dir
;
1897 if (len
> include_dir_maxlen
)
1898 include_dir_maxlen
= len
;
1900 else if (include_dirs
!= NULL
)
1901 include_dirs
[0] = ".";
1904 /* .include "filename" | filename
1905 .copy "filename" | filename
1907 FIXME 'include' file should be omitted from any output listing,
1908 'copy' should be included in any output listing
1909 FIXME -- prevent any included files from changing listing (compat only)
1910 FIXME -- need to include source file directory in search path; what's a
1911 good way to do this?
1913 Entering/exiting included/copied file clears all local labels. */
1916 tic54x_include (int ignored ATTRIBUTE_UNUSED
)
1918 char newblock
[] = " .newblock\n";
1923 ILLEGAL_WITHIN_STRUCT ();
1927 if (*input_line_pointer
== '"')
1929 filename
= demand_copy_C_string (&len
);
1930 demand_empty_rest_of_line ();
1934 filename
= input_line_pointer
;
1935 while (!is_end_of_line
[(int) *input_line_pointer
])
1936 ++input_line_pointer
;
1937 c
= *input_line_pointer
;
1938 *input_line_pointer
= '\0';
1939 filename
= strcpy (xmalloc (strlen (filename
) + 1), filename
);
1940 *input_line_pointer
= c
;
1941 demand_empty_rest_of_line ();
1943 /* Insert a partial line with the filename (for the sake of s_include)
1945 The included file will be inserted before the newblock, so that the
1946 newblock is executed after the included file is processed. */
1947 input
= xmalloc (sizeof (newblock
) + strlen (filename
) + 4);
1948 sprintf (input
, "\"%s\"\n%s", filename
, newblock
);
1949 input_scrub_insert_line (input
);
1951 tic54x_clear_local_labels (0);
1953 tic54x_set_default_include (0);
1959 tic54x_message (int type
)
1965 ILLEGAL_WITHIN_STRUCT ();
1967 if (*input_line_pointer
== '"')
1968 msg
= demand_copy_C_string (&len
);
1971 msg
= input_line_pointer
;
1972 while (!is_end_of_line
[(int) *input_line_pointer
])
1973 ++input_line_pointer
;
1974 c
= *input_line_pointer
;
1975 *input_line_pointer
= 0;
1976 msg
= strcpy (xmalloc (strlen (msg
) + 1), msg
);
1977 *input_line_pointer
= c
;
1983 as_tsktsk ("%s", msg
);
1986 as_warn ("%s", msg
);
1993 demand_empty_rest_of_line ();
1997 Define a special symbol that refers to the loadtime address rather than the
1998 runtime address within the current section.
2000 This symbol gets a special storage class so that when it is resolved, it is
2001 resolved relative to the load address (lma) of the section rather than the
2002 run address (vma). */
2005 tic54x_label (int ignored ATTRIBUTE_UNUSED
)
2007 char *name
= input_line_pointer
;
2011 ILLEGAL_WITHIN_STRUCT ();
2013 c
= get_symbol_end ();
2014 symbolP
= colon (name
);
2015 S_SET_STORAGE_CLASS (symbolP
, C_STATLAB
);
2017 *input_line_pointer
= c
;
2018 demand_empty_rest_of_line ();
2022 Install all memory-mapped register names into the symbol table as
2023 absolute local symbols. */
2026 tic54x_mmregs (int ignored ATTRIBUTE_UNUSED
)
2030 ILLEGAL_WITHIN_STRUCT ();
2032 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
2034 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
2035 (valueT
) sym
->value
, &zero_address_frag
);
2036 SF_SET_LOCAL (symbolP
);
2037 symbol_table_insert (symbolP
);
2042 Count defaults to 1024. */
2045 tic54x_loop (int count
)
2047 ILLEGAL_WITHIN_STRUCT ();
2050 if (!is_end_of_line
[(int) *input_line_pointer
])
2051 count
= get_absolute_expression ();
2053 do_repeat (count
, "LOOP", "ENDLOOP");
2056 /* Normally, endloop gets eaten by the preceding loop. */
2059 tic54x_endloop (int ignore ATTRIBUTE_UNUSED
)
2061 as_bad (_("ENDLOOP without corresponding LOOP"));
2062 ignore_rest_of_line ();
2065 /* .break [condition]. */
2068 tic54x_break (int ignore ATTRIBUTE_UNUSED
)
2072 ILLEGAL_WITHIN_STRUCT ();
2075 if (!is_end_of_line
[(int) *input_line_pointer
])
2076 cond
= get_absolute_expression ();
2079 end_repeat (substitution_line
? 1 : 0);
2083 set_address_mode (int mode
)
2086 if (mode
== far_mode
)
2088 symbolS
*symbolP
= symbol_new ("__allow_far", absolute_section
,
2089 (valueT
) 1, &zero_address_frag
);
2090 SF_SET_LOCAL (symbolP
);
2091 symbol_table_insert (symbolP
);
2095 static int address_mode_needs_set
= 1;
2097 tic54x_address_mode (int mode
)
2099 if (assembly_begun
&& amode
!= (unsigned) mode
)
2101 as_bad (_("Mixing of normal and extended addressing not supported"));
2102 ignore_rest_of_line ();
2105 if (mode
== far_mode
&& cpu
!= VNONE
&& cpu
!= V548
&& cpu
!= V549
)
2107 as_bad (_("Extended addressing not supported on the specified CPU"));
2108 ignore_rest_of_line ();
2112 set_address_mode (mode
);
2113 demand_empty_rest_of_line ();
2116 /* .sblock "section"|section [,...,"section"|section]
2117 Designate initialized sections for blocking. */
2120 tic54x_sblock (int ignore ATTRIBUTE_UNUSED
)
2124 ILLEGAL_WITHIN_STRUCT ();
2131 if (*input_line_pointer
== '"')
2134 name
= demand_copy_C_string (&len
);
2138 char *section_name
= input_line_pointer
;
2139 c
= get_symbol_end ();
2140 name
= xmalloc (strlen (section_name
) + 1);
2141 strcpy (name
, section_name
);
2142 *input_line_pointer
= c
;
2145 seg
= bfd_get_section_by_name (stdoutput
, name
);
2148 as_bad (_("Unrecognized section '%s'"), name
);
2149 ignore_rest_of_line ();
2152 else if (!tic54x_initialized_section (seg
))
2154 as_bad (_(".sblock may be used for initialized sections only"));
2155 ignore_rest_of_line ();
2158 seg
->flags
|= SEC_BLOCK
;
2160 c
= *input_line_pointer
;
2161 if (!is_end_of_line
[(int) c
])
2162 ++input_line_pointer
;
2165 demand_empty_rest_of_line ();
2168 /* symbol .set value
2171 value must be defined externals; no forward-referencing allowed
2172 symbols assigned with .set/.equ may not be redefined. */
2175 tic54x_set (int ignore ATTRIBUTE_UNUSED
)
2180 ILLEGAL_WITHIN_STRUCT ();
2184 as_bad (_("Symbol missing for .set/.equ"));
2185 ignore_rest_of_line ();
2188 name
= xstrdup (S_GET_NAME (line_label
));
2190 if ((symbolP
= symbol_find (name
)) == NULL
2191 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2193 symbolP
= symbol_new (name
, absolute_section
, 0, &zero_address_frag
);
2194 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2197 S_SET_DATA_TYPE (symbolP
, T_INT
);
2198 S_SET_SEGMENT (symbolP
, absolute_section
);
2199 symbol_table_insert (symbolP
);
2200 pseudo_set (symbolP
);
2201 demand_empty_rest_of_line ();
2206 List false conditional blocks. */
2209 tic54x_fclist (int show
)
2212 listing
&= ~LISTING_NOCOND
;
2214 listing
|= LISTING_NOCOND
;
2215 demand_empty_rest_of_line ();
2219 tic54x_sslist (int show
)
2221 ILLEGAL_WITHIN_STRUCT ();
2223 listing_sslist
= show
;
2226 /* .var SYM[,...,SYMN]
2227 Define a substitution string to be local to a macro. */
2230 tic54x_var (int ignore ATTRIBUTE_UNUSED
)
2232 static char empty
[] = "";
2236 ILLEGAL_WITHIN_STRUCT ();
2238 if (macro_level
== 0)
2240 as_bad (_(".var may only be used within a macro definition"));
2241 ignore_rest_of_line ();
2246 if (!ISALPHA (*input_line_pointer
))
2248 as_bad (_("Substitution symbols must begin with a letter"));
2249 ignore_rest_of_line ();
2252 name
= input_line_pointer
;
2253 c
= get_symbol_end ();
2254 /* .var symbols start out with a null string. */
2255 name
= strcpy (xmalloc (strlen (name
) + 1), name
);
2256 hash_insert (subsym_hash
[macro_level
], name
, empty
);
2257 *input_line_pointer
= c
;
2260 ++input_line_pointer
;
2261 if (is_end_of_line
[(int) *input_line_pointer
])
2262 c
= *input_line_pointer
;
2267 demand_empty_rest_of_line ();
2270 /* .mlib <macro library filename>
2272 Macro libraries are archived (standard AR-format) text macro definitions
2273 Expand the file and include it.
2275 FIXME need to try the source file directory as well. */
2278 tic54x_mlib (int ignore ATTRIBUTE_UNUSED
)
2285 ILLEGAL_WITHIN_STRUCT ();
2287 /* Parse the filename. */
2288 if (*input_line_pointer
== '"')
2290 if ((filename
= demand_copy_C_string (&len
)) == NULL
)
2297 while (!is_end_of_line
[(int) *input_line_pointer
]
2298 && !ISSPACE (*input_line_pointer
))
2300 obstack_1grow (¬es
, *input_line_pointer
);
2301 ++input_line_pointer
;
2304 obstack_1grow (¬es
, '\0');
2305 filename
= obstack_finish (¬es
);
2307 demand_empty_rest_of_line ();
2309 tic54x_set_default_include (0);
2310 path
= xmalloc ((unsigned long) len
+ include_dir_maxlen
+ 5);
2311 for (i
= 0; i
< include_dir_count
; i
++)
2314 strcpy (path
, include_dirs
[i
]);
2316 strcat (path
, filename
);
2317 if ((try = fopen (path
, "r")) != NULL
)
2323 if (i
>= include_dir_count
)
2329 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2330 happens all over the place, and since the assembler doesn't usually keep
2331 running for a very long time, it really doesn't matter. */
2332 register_dependency (path
);
2334 /* Expand all archive entries to temporary files and include them. */
2335 abfd
= bfd_openr (path
, NULL
);
2338 as_bad (_("Can't open macro library file '%s' for reading."), path
);
2339 as_perror ("%s", path
);
2340 ignore_rest_of_line ();
2343 if (!bfd_check_format (abfd
, bfd_archive
))
2345 as_bad (_("File '%s' not in macro archive format"), path
);
2346 ignore_rest_of_line ();
2350 /* Open each BFD as binary (it should be straight ASCII text). */
2351 for (mbfd
= bfd_openr_next_archived_file (abfd
, NULL
);
2352 mbfd
!= NULL
; mbfd
= bfd_openr_next_archived_file (abfd
, mbfd
))
2354 /* Get a size at least as big as the archive member. */
2355 bfd_size_type size
= bfd_get_size (mbfd
);
2356 char *buf
= xmalloc (size
);
2357 char *fname
= tmpnam (NULL
);
2360 /* We're not sure how big it is, but it will be smaller than "size". */
2361 bfd_bread (buf
, size
, mbfd
);
2363 /* Write to a temporary file, then use s_include to include it
2365 ftmp
= fopen (fname
, "w+b");
2366 fwrite ((void *) buf
, size
, 1, ftmp
);
2367 if (buf
[size
- 1] != '\n')
2368 fwrite ("\n", 1, 1, ftmp
);
2371 input_scrub_insert_file (fname
);
2376 const pseudo_typeS md_pseudo_table
[] =
2378 { "algebraic", s_ignore
, 0 },
2379 { "align" , tic54x_align_words
, 128 },
2380 { "ascii" , tic54x_stringer
, 'p' },
2381 { "asciz" , tic54x_stringer
, 'P' },
2382 { "even" , tic54x_align_words
, 2 },
2383 { "asg" , tic54x_asg
, 0 },
2384 { "eval" , tic54x_eval
, 0 },
2385 { "bss" , tic54x_bss
, 0 },
2386 { "byte" , tic54x_cons
, 'b' },
2387 { "ubyte" , tic54x_cons
, 'B' },
2388 { "char" , tic54x_cons
, 'c' },
2389 { "uchar" , tic54x_cons
, 'C' },
2390 { "clink" , tic54x_clink
, 0 },
2391 { "c_mode" , tic54x_address_mode
, c_mode
},
2392 { "copy" , tic54x_include
, 'c' },
2393 { "include" , tic54x_include
, 'i' },
2394 { "data" , tic54x_sect
, 'd' },
2395 { "double" , tic54x_float_cons
, 'd' },
2396 { "ldouble" , tic54x_float_cons
, 'l' },
2397 { "drlist" , s_ignore
, 0 },
2398 { "drnolist" , s_ignore
, 0 },
2399 { "emsg" , tic54x_message
, 'e' },
2400 { "mmsg" , tic54x_message
, 'm' },
2401 { "wmsg" , tic54x_message
, 'w' },
2403 { "end" , s_end
, 0 },
2405 { "far_mode" , tic54x_address_mode
, far_mode
},
2406 { "fclist" , tic54x_fclist
, 1 },
2407 { "fcnolist" , tic54x_fclist
, 0 },
2408 { "field" , tic54x_field
, -1 },
2409 { "float" , tic54x_float_cons
, 'f' },
2410 { "xfloat" , tic54x_float_cons
, 'x' },
2411 { "global" , tic54x_global
, 'g' },
2412 { "def" , tic54x_global
, 'd' },
2413 { "ref" , tic54x_global
, 'r' },
2414 { "half" , tic54x_cons
, 'h' },
2415 { "uhalf" , tic54x_cons
, 'H' },
2416 { "short" , tic54x_cons
, 's' },
2417 { "ushort" , tic54x_cons
, 'S' },
2418 { "if" , s_if
, (int) O_ne
},
2419 { "elseif" , s_elseif
, (int) O_ne
},
2420 { "else" , s_else
, 0 },
2421 { "endif" , s_endif
, 0 },
2422 { "int" , tic54x_cons
, 'i' },
2423 { "uint" , tic54x_cons
, 'I' },
2424 { "word" , tic54x_cons
, 'w' },
2425 { "uword" , tic54x_cons
, 'W' },
2426 { "label" , tic54x_label
, 0 }, /* Loadtime
2428 { "length" , s_ignore
, 0 },
2429 { "width" , s_ignore
, 0 },
2431 { "list" , listing_list
, 1 },
2432 { "nolist" , listing_list
, 0 },
2434 { "long" , tic54x_cons
, 'l' },
2435 { "ulong" , tic54x_cons
, 'L' },
2436 { "xlong" , tic54x_cons
, 'x' },
2437 { "loop" , tic54x_loop
, 1024 },
2438 { "break" , tic54x_break
, 0 },
2439 { "endloop" , tic54x_endloop
, 0 },
2440 { "mlib" , tic54x_mlib
, 0 },
2441 { "mlist" , s_ignore
, 0 },
2442 { "mnolist" , s_ignore
, 0 },
2443 { "mmregs" , tic54x_mmregs
, 0 },
2444 { "newblock" , tic54x_clear_local_labels
, 0 },
2445 { "option" , s_ignore
, 0 },
2446 { "p2align" , tic54x_p2align
, 0 },
2448 { "page" , listing_eject
, 0 },
2450 { "sblock" , tic54x_sblock
, 0 },
2451 { "sect" , tic54x_sect
, '*' },
2452 { "set" , tic54x_set
, 0 },
2453 { "equ" , tic54x_set
, 0 },
2454 { "space" , tic54x_space
, 0 },
2455 { "bes" , tic54x_space
, 1 },
2456 { "sslist" , tic54x_sslist
, 1 },
2457 { "ssnolist" , tic54x_sslist
, 0 },
2458 { "string" , tic54x_stringer
, 's' },
2459 { "pstring" , tic54x_stringer
, 'p' },
2460 { "struct" , tic54x_struct
, 0 },
2461 { "tag" , tic54x_tag
, 0 },
2462 { "endstruct", tic54x_endstruct
, 0 },
2463 { "tab" , s_ignore
, 0 },
2464 { "text" , tic54x_sect
, 't' },
2466 { "title" , listing_title
, 0 },
2468 { "union" , tic54x_struct
, 1 },
2469 { "endunion" , tic54x_endstruct
, 1 },
2470 { "usect" , tic54x_usect
, 0 },
2471 { "var" , tic54x_var
, 0 },
2472 { "version" , tic54x_version
, 0 },
2477 /* For debugging, strings for each operand type. */
2478 static const char *optypes
[] =
2480 "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
2481 "Sind", "xpmad", "xpmad+", "MMRX", "MMRY",
2482 "SRC1", "SRC", "RND", "DST",
2485 "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031",
2486 "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
2492 md_parse_option (c
, arg
)
2500 case OPTION_COFF_VERSION
:
2502 int version
= atoi (arg
);
2503 if (version
!= 0 && version
!= 1 && version
!= 2)
2504 as_fatal (_("Bad COFF version '%s'"), arg
);
2505 /* FIXME -- not yet implemented. */
2508 case OPTION_CPU_VERSION
:
2510 cpu
= lookup_version (arg
);
2513 as_fatal (_("Bad CPU version '%s'"), arg
);
2516 case OPTION_ADDRESS_MODE
:
2518 address_mode_needs_set
= 1;
2520 case OPTION_STDERR_TO_FILE
:
2522 char *filename
= arg
;
2523 FILE *fp
= fopen (filename
, "w+");
2525 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2527 if ((fp
= freopen (filename
, "w+", stderr
)) == NULL
)
2528 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2536 /* Create a "local" substitution string hash table for a new macro level
2537 Some docs imply that macros have to use .newblock in order to be able
2538 to re-use a local label. We effectively do an automatic .newblock by
2539 deleting the local label hash between macro invocations. */
2542 tic54x_macro_start ()
2545 subsym_hash
[macro_level
] = hash_new ();
2546 local_label_hash
[macro_level
] = hash_new ();
2550 tic54x_macro_info (info
)
2553 struct formal_struct
2555 struct formal_struct
*next
; /* Next formal in list */
2556 sb name
; /* Name of the formal */
2557 sb def
; /* The default value */
2558 sb actual
; /* The actual argument (changed on
2560 int index
; /* The index of the formal
2561 0 .. formal_count - 1 */
2565 sb sub
; /* Substitution text. */
2566 int formal_count
; /* Number of formal args. */
2567 struct formal_struct
*formals
; /* Pointer to list of
2569 struct hash_control
*formal_hash
; /* Hash table of formals. */
2572 macro
= (struct macro_struct
*) info
;
2574 /* Put the formal args into the substitution symbol table. */
2575 for (entry
= macro
->formals
; entry
; entry
= entry
->next
)
2577 char *name
= strncpy (xmalloc (entry
->name
.len
+ 1),
2578 entry
->name
.ptr
, entry
->name
.len
);
2579 char *value
= strncpy (xmalloc (entry
->actual
.len
+ 1),
2580 entry
->actual
.ptr
, entry
->actual
.len
);
2581 name
[entry
->name
.len
] = '\0';
2582 value
[entry
->actual
.len
] = '\0';
2583 hash_insert (subsym_hash
[macro_level
], name
, value
);
2587 /* Get rid of this macro's .var's, arguments, and local labels. */
2592 hash_die (subsym_hash
[macro_level
]);
2593 subsym_hash
[macro_level
] = NULL
;
2594 hash_die (local_label_hash
[macro_level
]);
2595 local_label_hash
[macro_level
] = NULL
;
2600 subsym_symlen (char *a
, char *ignore ATTRIBUTE_UNUSED
)
2605 /* Compare symbol A to string B. */
2608 subsym_symcmp (char *a
, char *b
)
2610 return strcmp (a
, b
);
2613 /* Return the index of the first occurence of B in A, or zero if none
2614 assumes b is an integer char value as a string. Index is one-based. */
2617 subsym_firstch (char *a
, char *b
)
2620 char *tmp
= strchr (a
, val
);
2622 return tmp
? tmp
- a
+ 1 : 0;
2625 /* Similar to firstch, but returns index of last occurrence of B in A. */
2628 subsym_lastch (char *a
, char *b
)
2631 char *tmp
= strrchr (a
, val
);
2633 return tmp
? tmp
- a
+ 1 : 0;
2636 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2640 subsym_isdefed (char *a
, char *ignore ATTRIBUTE_UNUSED
)
2642 symbolS
*symbolP
= symbol_find (a
);
2644 return symbolP
!= NULL
;
2647 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2648 A, or zero if B is a null string. Both arguments *must* be substitution
2649 symbols, unsubstituted. */
2652 subsym_ismember (char *sym
, char *list
)
2654 char *elem
, *ptr
, *listv
;
2659 listv
= subsym_lookup (list
, macro_level
);
2662 as_bad (_("Undefined substitution symbol '%s'"), list
);
2663 ignore_rest_of_line ();
2667 ptr
= elem
= xmalloc (strlen (listv
) + 1);
2668 strcpy (elem
, listv
);
2669 while (*ptr
&& *ptr
!= ',')
2673 subsym_create_or_replace (sym
, elem
);
2675 /* Reassign the list. */
2676 subsym_create_or_replace (list
, ptr
);
2678 /* Assume this value, docs aren't clear. */
2682 /* Return zero if not a constant; otherwise:
2690 subsym_iscons (char *a
, char *ignore ATTRIBUTE_UNUSED
)
2694 parse_expression (a
, &exp
);
2696 if (exp
.X_op
== O_constant
)
2698 int len
= strlen (a
);
2700 switch (TOUPPER (a
[len
- 1]))
2713 /* No suffix; either octal, hex, or decimal. */
2714 if (*a
== '0' && len
> 1)
2716 if (TOUPPER (a
[1]) == 'X')
2726 /* Return 1 if A is a valid symbol name. Expects string input. */
2729 subsym_isname (char *a
, char *ignore ATTRIBUTE_UNUSED
)
2731 if (!is_name_beginner (*a
))
2735 if (!is_part_of_name (*a
))
2742 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2743 been seen; if so, recognize any memory-mapped register.
2744 Note this does not recognize "A" or "B" accumulators. */
2747 subsym_isreg (char *a
, char *ignore ATTRIBUTE_UNUSED
)
2749 if (hash_find (reg_hash
, a
))
2751 if (hash_find (mmreg_hash
, a
))
2756 /* Return the structrure size, given the stag. */
2759 subsym_structsz (char *name
, char *ignore ATTRIBUTE_UNUSED
)
2761 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
2768 /* If anybody actually uses this, they can fix it :)
2769 FIXME I'm not sure what the "reference point" of a structure is. It might
2770 be either the initial offset given .struct, or it may be the offset of the
2771 structure within another structure, or it might be something else
2772 altogether. since the TI assembler doesn't seem to ever do anything but
2773 return zero, we punt and return zero. */
2776 subsym_structacc (char *stag_name ATTRIBUTE_UNUSED
,
2777 char *ignore ATTRIBUTE_UNUSED
)
2783 math_ceil (arg1
, ignore
)
2785 float ignore ATTRIBUTE_UNUSED
;
2787 return (float) ceil (arg1
);
2791 math_cvi (arg1
, ignore
)
2793 float ignore ATTRIBUTE_UNUSED
;
2799 math_floor (arg1
, ignore
)
2801 float ignore ATTRIBUTE_UNUSED
;
2803 return (float) floor (arg1
);
2807 math_fmod (float arg1
, float arg2
)
2809 return (int) arg1
% (int) arg2
;
2813 math_int (arg1
, ignore
)
2815 float ignore ATTRIBUTE_UNUSED
;
2817 return ((float) ((int) arg1
)) == arg1
;
2821 math_round (arg1
, ignore
)
2823 float ignore ATTRIBUTE_UNUSED
;
2825 return arg1
> 0 ? (int) (arg1
+ 0.5) : (int) (arg1
- 0.5);
2829 math_sgn (arg1
, ignore
)
2831 float ignore ATTRIBUTE_UNUSED
;
2833 return (arg1
< 0) ? -1 : (arg1
? 1 : 0);
2837 math_trunc (arg1
, ignore
)
2839 float ignore ATTRIBUTE_UNUSED
;
2845 math_acos (arg1
, ignore
)
2847 float ignore ATTRIBUTE_UNUSED
;
2849 return (float) acos (arg1
);
2853 math_asin (arg1
, ignore
)
2855 float ignore ATTRIBUTE_UNUSED
;
2857 return (float) asin (arg1
);
2861 math_atan (arg1
, ignore
)
2863 float ignore ATTRIBUTE_UNUSED
;
2865 return (float) atan (arg1
);
2869 math_atan2 (float arg1
, float arg2
)
2871 return (float) atan2 (arg1
, arg2
);
2875 math_cosh (arg1
, ignore
)
2877 float ignore ATTRIBUTE_UNUSED
;
2879 return (float) cosh (arg1
);
2883 math_cos (arg1
, ignore
)
2885 float ignore ATTRIBUTE_UNUSED
;
2887 return (float) cos (arg1
);
2891 math_cvf (arg1
, ignore
)
2893 float ignore ATTRIBUTE_UNUSED
;
2895 return (float) arg1
;
2899 math_exp (arg1
, ignore
)
2901 float ignore ATTRIBUTE_UNUSED
;
2903 return (float) exp (arg1
);
2907 math_fabs (arg1
, ignore
)
2909 float ignore ATTRIBUTE_UNUSED
;
2911 return (float) fabs (arg1
);
2914 /* expr1 * 2^expr2. */
2917 math_ldexp (float arg1
, float arg2
)
2919 return arg1
* (float) pow (2.0, arg2
);
2923 math_log10 (arg1
, ignore
)
2925 float ignore ATTRIBUTE_UNUSED
;
2927 return (float) log10 (arg1
);
2931 math_log (arg1
, ignore
)
2933 float ignore ATTRIBUTE_UNUSED
;
2935 return (float) log (arg1
);
2939 math_max (float arg1
, float arg2
)
2941 return (arg1
> arg2
) ? arg1
: arg2
;
2945 math_min (float arg1
, float arg2
)
2947 return (arg1
< arg2
) ? arg1
: arg2
;
2951 math_pow (float arg1
, float arg2
)
2953 return (float) pow (arg1
, arg2
);
2957 math_sin (arg1
, ignore
)
2959 float ignore ATTRIBUTE_UNUSED
;
2961 return (float) sin (arg1
);
2965 math_sinh (arg1
, ignore
)
2967 float ignore ATTRIBUTE_UNUSED
;
2969 return (float) sinh (arg1
);
2973 math_sqrt (arg1
, ignore
)
2975 float ignore ATTRIBUTE_UNUSED
;
2977 return (float) sqrt (arg1
);
2981 math_tan (arg1
, ignore
)
2983 float ignore ATTRIBUTE_UNUSED
;
2985 return (float) tan (arg1
);
2989 math_tanh (arg1
, ignore
)
2991 float ignore ATTRIBUTE_UNUSED
;
2993 return (float) tanh (arg1
);
2996 /* Built-in substitution symbol functions and math functions. */
3000 int (*proc
) (char *, char *);
3002 } subsym_proc_entry
;
3004 static const subsym_proc_entry subsym_procs
[] =
3006 /* Assembler built-in string substitution functions. */
3007 { "$symlen", subsym_symlen
, 1, },
3008 { "$symcmp", subsym_symcmp
, 2, },
3009 { "$firstch", subsym_firstch
, 2, },
3010 { "$lastch", subsym_lastch
, 2, },
3011 { "$isdefed", subsym_isdefed
, 1, },
3012 { "$ismember", subsym_ismember
, 2, },
3013 { "$iscons", subsym_iscons
, 1, },
3014 { "$isname", subsym_isname
, 1, },
3015 { "$isreg", subsym_isreg
, 1, },
3016 { "$structsz", subsym_structsz
, 1, },
3017 { "$structacc", subsym_structacc
, 1, },
3024 float (*proc
) (float, float);
3029 static const math_proc_entry math_procs
[] =
3031 /* Integer-returning built-in math functions. */
3032 { "$cvi", math_cvi
, 1, 1 },
3033 { "$int", math_int
, 1, 1 },
3034 { "$sgn", math_sgn
, 1, 1 },
3036 /* Float-returning built-in math functions. */
3037 { "$acos", math_acos
, 1, 0 },
3038 { "$asin", math_asin
, 1, 0 },
3039 { "$atan", math_atan
, 1, 0 },
3040 { "$atan2", math_atan2
, 2, 0 },
3041 { "$ceil", math_ceil
, 1, 0 },
3042 { "$cosh", math_cosh
, 1, 0 },
3043 { "$cos", math_cos
, 1, 0 },
3044 { "$cvf", math_cvf
, 1, 0 },
3045 { "$exp", math_exp
, 1, 0 },
3046 { "$fabs", math_fabs
, 1, 0 },
3047 { "$floor", math_floor
, 1, 0 },
3048 { "$fmod", math_fmod
, 2, 0 },
3049 { "$ldexp", math_ldexp
, 2, 0 },
3050 { "$log10", math_log10
, 1, 0 },
3051 { "$log", math_log
, 1, 0 },
3052 { "$max", math_max
, 2, 0 },
3053 { "$min", math_min
, 2, 0 },
3054 { "$pow", math_pow
, 2, 0 },
3055 { "$round", math_round
, 1, 0 },
3056 { "$sin", math_sin
, 1, 0 },
3057 { "$sinh", math_sinh
, 1, 0 },
3058 { "$sqrt", math_sqrt
, 1, 0 },
3059 { "$tan", math_tan
, 1, 0 },
3060 { "$tanh", math_tanh
, 1, 0 },
3061 { "$trunc", math_trunc
, 1, 0 },
3062 { NULL
, NULL
, 0, 0 },
3070 const subsym_proc_entry
*subsym_proc
;
3071 const math_proc_entry
*math_proc
;
3072 const char *hash_err
;
3074 char *TIC54X_DIR
= getenv ("TIC54X_DIR");
3075 char *A_DIR
= TIC54X_DIR
? TIC54X_DIR
: getenv ("A_DIR");
3079 /* Look for A_DIR and add it to the include list. a */
3082 char *tmp
= xstrdup (A_DIR
);
3085 char *next
= strchr (tmp
, ';');
3088 add_include_dir (tmp
);
3091 while (tmp
!= NULL
);
3094 op_hash
= hash_new ();
3095 for (tm
= (template *) tic54x_optab
; tm
->name
; tm
++)
3097 if (hash_find (op_hash
, tm
->name
))
3099 hash_err
= hash_insert (op_hash
, tm
->name
, (char *) tm
);
3101 as_fatal ("Internal Error: Can't hash %s: %s",
3102 tm
->name
, hash_err
);
3104 parop_hash
= hash_new ();
3105 for (tm
= (template *) tic54x_paroptab
; tm
->name
; tm
++)
3107 if (hash_find (parop_hash
, tm
->name
))
3109 hash_err
= hash_insert (parop_hash
, tm
->name
, (char *) tm
);
3111 as_fatal ("Internal Error: Can't hash %s: %s",
3112 tm
->name
, hash_err
);
3114 reg_hash
= hash_new ();
3115 for (sym
= (symbol
*) regs
; sym
->name
; sym
++)
3117 /* Add basic registers to the symbol table. */
3118 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
3119 (valueT
) sym
->value
, &zero_address_frag
);
3120 SF_SET_LOCAL (symbolP
);
3121 symbol_table_insert (symbolP
);
3122 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3124 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3125 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3126 mmreg_hash
= hash_new ();
3127 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3129 hash_err
= hash_insert (mmreg_hash
, sym
->name
, (char *) sym
);
3131 cc_hash
= hash_new ();
3132 for (sym
= (symbol
*) condition_codes
; sym
->name
; sym
++)
3134 hash_err
= hash_insert (cc_hash
, sym
->name
, (char *) sym
);
3136 cc2_hash
= hash_new ();
3137 for (sym
= (symbol
*) cc2_codes
; sym
->name
; sym
++)
3139 hash_err
= hash_insert (cc2_hash
, sym
->name
, (char *) sym
);
3141 cc3_hash
= hash_new ();
3142 for (sym
= (symbol
*) cc3_codes
; sym
->name
; sym
++)
3144 hash_err
= hash_insert (cc3_hash
, sym
->name
, (char *) sym
);
3146 sbit_hash
= hash_new ();
3147 for (sym
= (symbol
*) status_bits
; sym
->name
; sym
++)
3149 hash_err
= hash_insert (sbit_hash
, sym
->name
, (char *) sym
);
3151 misc_symbol_hash
= hash_new ();
3152 for (symname
= (char **) misc_symbols
; *symname
; symname
++)
3154 hash_err
= hash_insert (misc_symbol_hash
, *symname
, *symname
);
3156 /* Only the base substitution table and local label table are initialized;
3157 the others (for local macro substitution) get instantiated as needed. */
3158 local_label_hash
[0] = hash_new ();
3159 subsym_hash
[0] = hash_new ();
3160 for (subsym_proc
= subsym_procs
; subsym_proc
->name
; subsym_proc
++)
3162 hash_err
= hash_insert (subsym_hash
[0], subsym_proc
->name
,
3163 (char *) subsym_proc
);
3165 math_hash
= hash_new ();
3166 for (math_proc
= math_procs
; math_proc
->name
; math_proc
++)
3168 /* Insert into the main subsym hash for recognition; insert into
3169 the math hash to actually store information. */
3170 hash_err
= hash_insert (subsym_hash
[0], math_proc
->name
,
3171 (char *) math_proc
);
3172 hash_err
= hash_insert (math_hash
, math_proc
->name
,
3173 (char *) math_proc
);
3175 subsym_recurse_hash
= hash_new ();
3176 stag_hash
= hash_new ();
3179 typedef struct _tic54x_insn
3181 const template *tm
; /* Opcode template. */
3183 char mnemonic
[MAX_LINE
]; /* Opcode name/mnemonic. */
3184 char parmnemonic
[MAX_LINE
]; /* 2nd mnemonic of parallel insn. */
3192 } operands
[MAX_OPERANDS
];
3195 struct opstruct paroperands
[MAX_OPERANDS
];
3199 int words
; /* Size of insn in 16-bit words. */
3200 int using_default_dst
; /* Do we need to explicitly set an
3201 omitted OP_DST operand? */
3204 unsigned short word
; /* Final encoded opcode data. */
3206 int r_nchars
; /* Relocation size. */
3207 bfd_reloc_code_real_type r_type
; /* Relocation type. */
3208 expressionS addr_expr
; /* Storage for unresolved expressions. */
3212 static int encode_operand (tic54x_insn
*, enum optype
, struct opstruct
*);
3213 static int encode_dmad (tic54x_insn
*, struct opstruct
*, int);
3214 static int operands_match (tic54x_insn
*, struct opstruct
*, int,
3215 const enum optype
*, int, int);
3216 static int encode_address (tic54x_insn
*, struct opstruct
*);
3217 static int is_accumulator (struct opstruct
*);
3220 is_accumulator (struct opstruct
*operand
)
3222 return strcasecmp (operand
->buf
, "a") == 0
3223 || strcasecmp (operand
->buf
, "b") == 0;
3226 /* Return the number of operands found, or -1 on error, copying the
3227 operands into the given array and the accompanying expressions into
3231 get_operands (struct opstruct operands
[], char *line
)
3235 int expecting_operand
= 0;
3238 while (numexp
< MAX_OPERANDS
&& !is_end_of_line
[(int) *lptr
])
3240 int paren_not_balanced
= 0;
3241 char *op_start
, *op_end
;
3242 while (*lptr
&& ISSPACE (*lptr
))
3245 while (paren_not_balanced
|| *lptr
!= ',')
3249 if (paren_not_balanced
)
3251 as_bad ("Unbalanced parenthesis in operand %d", numexp
);
3258 ++paren_not_balanced
;
3259 else if (*lptr
== ')')
3260 --paren_not_balanced
;
3264 if (op_end
!= op_start
)
3266 int len
= op_end
- op_start
;
3267 strncpy (operands
[numexp
].buf
, op_start
, len
);
3268 operands
[numexp
].buf
[len
] = 0;
3269 /* Trim trailing spaces; while the preprocessor gets rid of most,
3270 there are weird usage patterns that can introduce them
3271 (i.e. using strings for macro args). */
3272 while (len
> 0 && ISSPACE (operands
[numexp
].buf
[len
- 1]))
3273 operands
[numexp
].buf
[--len
] = 0;
3279 if (expecting_operand
|| *lptr
== ',')
3281 as_bad ("Expecting operand after ','");
3287 if (*++lptr
== '\0')
3289 as_bad ("Expecting operand after ','");
3292 expecting_operand
= 1;
3296 while (*lptr
&& ISSPACE (*lptr
++))
3298 if (!is_end_of_line
[(int) *lptr
])
3300 as_bad ("Extra junk on line");
3304 /* OK, now parse them into expressions. */
3305 for (i
= 0; i
< numexp
; i
++)
3307 memset (&operands
[i
].exp
, 0, sizeof (operands
[i
].exp
));
3308 if (operands
[i
].buf
[0] == '#')
3311 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3313 else if (operands
[i
].buf
[0] == '@')
3315 /* Direct notation. */
3316 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3318 else if (operands
[i
].buf
[0] == '*')
3321 char *paren
= strchr (operands
[i
].buf
, '(');
3322 /* Allow immediate syntax in the inner expression. */
3323 if (paren
&& paren
[1] == '#')
3326 /* Pull out the lk expression or SP offset, if present. */
3329 int len
= strlen (paren
);
3330 char *end
= paren
+ len
;
3332 while (end
[-1] != ')')
3335 as_bad (_("Badly formed address expression"));
3340 parse_expression (paren
, &operands
[i
].exp
);
3344 operands
[i
].exp
.X_op
= O_absent
;
3347 parse_expression (operands
[i
].buf
, &operands
[i
].exp
);
3353 /* Predicates for different operand types. */
3356 is_immediate (struct opstruct
*operand
)
3358 return *operand
->buf
== '#';
3361 /* This is distinguished from immediate because some numbers must be constants
3362 and must *not* have the '#' prefix. */
3365 is_absolute (struct opstruct
*operand
)
3367 return operand
->exp
.X_op
== O_constant
&& !is_immediate (operand
);
3370 /* Is this an indirect operand? */
3373 is_indirect (struct opstruct
*operand
)
3375 return operand
->buf
[0] == '*';
3378 /* Is this a valid dual-memory operand? */
3381 is_dual (struct opstruct
*operand
)
3383 if (is_indirect (operand
) && strncasecmp (operand
->buf
, "*ar", 3) == 0)
3385 char *tmp
= operand
->buf
+ 3;
3390 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3391 valid_mod
= *tmp
== '\0' ||
3392 strcasecmp (tmp
, "-") == 0 ||
3393 strcasecmp (tmp
, "+") == 0 ||
3394 strcasecmp (tmp
, "+0%") == 0;
3395 return arf
>= 2 && arf
<= 5 && valid_mod
;
3401 is_mmreg (struct opstruct
*operand
)
3403 return (is_absolute (operand
)
3404 || is_immediate (operand
)
3405 || hash_find (mmreg_hash
, operand
->buf
) != 0);
3409 is_type (struct opstruct
*operand
, enum optype type
)
3414 return operand
->buf
[0] == 0;
3417 return is_dual (operand
);
3419 return is_indirect (operand
);
3421 /* This one *must* be immediate. */
3422 return is_immediate (operand
);
3431 /* Address may be a numeric, indirect, or an expression. */
3432 return !is_immediate (operand
);
3435 return is_mmreg (operand
);
3440 return is_accumulator (operand
);
3442 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'B';
3444 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'A';
3446 return strncasecmp ("ar", operand
->buf
, 2) == 0
3447 && ISDIGIT (operand
->buf
[2]);
3449 return hash_find (sbit_hash
, operand
->buf
) != 0 || is_absolute (operand
);
3451 return hash_find (cc_hash
, operand
->buf
) != 0;
3453 return hash_find (cc2_hash
, operand
->buf
) != 0;
3455 return hash_find (cc3_hash
, operand
->buf
) != 0
3456 || is_immediate (operand
) || is_absolute (operand
);
3458 return (is_immediate (operand
) || is_absolute (operand
))
3459 && operand
->exp
.X_add_number
== 16;
3461 /* Allow st0 or st1 instead of a numeric. */
3462 return is_absolute (operand
) || is_immediate (operand
) ||
3463 strcasecmp ("st0", operand
->buf
) == 0 ||
3464 strcasecmp ("st1", operand
->buf
) == 0;
3467 return is_absolute (operand
) || is_immediate (operand
);
3469 return (is_immediate (operand
) || is_absolute (operand
))
3470 && operand
->exp
.X_add_number
>= 0 && operand
->exp
.X_add_number
< 16;
3472 /* Let this one catch out-of-range values. */
3473 return (is_immediate (operand
) || is_absolute (operand
))
3474 && operand
->exp
.X_add_number
!= 16;
3478 return is_absolute (operand
) || is_immediate (operand
);
3480 return is_immediate (operand
)
3481 && operand
->exp
.X_op
== O_constant
3482 && operand
->exp
.X_add_number
>= 0
3483 && operand
->exp
.X_add_number
< 256;
3486 /* Allow anything; assumes opcodes are ordered with Smem operands
3492 /* Just make sure it's an integer; check range later. */
3493 return is_immediate (operand
);
3495 return strcasecmp ("t", operand
->buf
) == 0 ||
3496 strcasecmp ("treg", operand
->buf
) == 0;
3498 return strcasecmp ("ts", operand
->buf
) == 0;
3500 return strcasecmp ("asm", operand
->buf
) == 0;
3502 return strcasecmp ("trn", operand
->buf
) == 0;
3504 return strcasecmp ("dp", operand
->buf
) == 0;
3506 return strcasecmp ("arp", operand
->buf
) == 0;
3513 operands_match (insn
, operands
, opcount
, refoptype
, minops
, maxops
)
3515 struct opstruct
*operands
;
3517 const enum optype
*refoptype
;
3520 int op
= 0, refop
= 0;
3522 if (opcount
== 0 && minops
== 0)
3527 while (op
<= maxops
&& refop
<= maxops
)
3529 while (!is_type (&operands
[op
], OPTYPE (refoptype
[refop
])))
3531 /* Skip an optional template operand if it doesn't agree
3532 with the current operand. */
3533 if (refoptype
[refop
] & OPT
)
3544 /* Save the actual operand type for later use. */
3545 operands
[op
].type
= OPTYPE (refoptype
[refop
]);
3548 /* Have we matched them all yet? */
3553 /* If a later operand is *not* optional, no match. */
3554 if ((refoptype
[refop
] & OPT
) == 0)
3556 /* Flag any implicit default OP_DST operands so we know to add
3557 them explicitly when encoding the operand later. */
3558 if (OPTYPE (refoptype
[refop
]) == OP_DST
)
3559 insn
->using_default_dst
= 1;
3571 /* 16-bit direct memory address
3572 Explicit dmad operands are always in last word of insn (usually second
3573 word, but bumped to third if lk addressing is used)
3575 We allow *(dmad) notation because the TI assembler allows it.
3578 0 for 16-bit addresses
3579 1 for full 23-bit addresses
3580 2 for the upper 7 bits of a 23-bit address (LDX). */
3583 encode_dmad (insn
, operand
, xpc_code
)
3585 struct opstruct
*operand
;
3588 int op
= 1 + insn
->is_lkaddr
;
3590 /* Only allow *(dmad) expressions; all others are invalid. */
3591 if (is_indirect (operand
) && operand
->buf
[strlen (operand
->buf
) - 1] != ')')
3593 as_bad (_("Invalid dmad syntax '%s'"), operand
->buf
);
3597 insn
->opcode
[op
].addr_expr
= operand
->exp
;
3599 if (insn
->opcode
[op
].addr_expr
.X_op
== O_constant
)
3601 valueT value
= insn
->opcode
[op
].addr_expr
.X_add_number
;
3604 insn
->opcode
[0].word
&= 0xFF80;
3605 insn
->opcode
[0].word
|= (value
>> 16) & 0x7F;
3606 insn
->opcode
[1].word
= value
& 0xFFFF;
3608 else if (xpc_code
== 2)
3609 insn
->opcode
[op
].word
= (value
>> 16) & 0xFFFF;
3611 insn
->opcode
[op
].word
= value
;
3615 /* Do the fixup later; just store the expression. */
3616 insn
->opcode
[op
].word
= 0;
3617 insn
->opcode
[op
].r_nchars
= 2;
3619 if (amode
== c_mode
)
3620 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3621 else if (xpc_code
== 1)
3623 /* This relocation spans two words, so adjust accordingly. */
3624 insn
->opcode
[0].addr_expr
= operand
->exp
;
3625 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_23
;
3626 insn
->opcode
[0].r_nchars
= 4;
3627 insn
->opcode
[0].unresolved
= 1;
3628 /* It's really 2 words, but we want to stop encoding after the
3629 first, since we must encode both words at once. */
3632 else if (xpc_code
== 2)
3633 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_MS7_OF_23
;
3635 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3637 insn
->opcode
[op
].unresolved
= 1;
3643 /* 7-bit direct address encoding. */
3646 encode_address (insn
, operand
)
3648 struct opstruct
*operand
;
3650 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3651 insn
->opcode
[0].addr_expr
= operand
->exp
;
3653 if (operand
->exp
.X_op
== O_constant
)
3654 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
& 0x7F);
3657 /* Do the fixup later; just store the expression. */
3658 insn
->opcode
[0].r_nchars
= 1;
3659 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_PARTLS7
;
3660 insn
->opcode
[0].unresolved
= 1;
3667 encode_indirect (tic54x_insn
*insn
, struct opstruct
*operand
)
3672 if (insn
->is_lkaddr
)
3674 /* lk addresses always go in the second insn word. */
3675 mod
= ((TOUPPER (operand
->buf
[1]) == 'A') ? 12 :
3676 (operand
->buf
[1] == '(') ? 15 :
3677 (strchr (operand
->buf
, '%') != NULL
) ? 14 : 13);
3678 arf
= ((mod
== 12) ? operand
->buf
[3] - '0' :
3679 (mod
== 15) ? 0 : operand
->buf
[4] - '0');
3681 insn
->opcode
[1].addr_expr
= operand
->exp
;
3683 if (operand
->exp
.X_op
== O_constant
)
3684 insn
->opcode
[1].word
= operand
->exp
.X_add_number
;
3687 insn
->opcode
[1].word
= 0;
3688 insn
->opcode
[1].r_nchars
= 2;
3689 insn
->opcode
[1].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3690 insn
->opcode
[1].unresolved
= 1;
3693 else if (strncasecmp (operand
->buf
, "*sp (", 4) == 0)
3695 /* Stack offsets look the same as 7-bit direct addressing. */
3696 return encode_address (insn
, operand
);
3700 arf
= (TOUPPER (operand
->buf
[1]) == 'A' ?
3701 operand
->buf
[3] : operand
->buf
[4]) - '0';
3703 if (operand
->buf
[1] == '+')
3705 mod
= 3; /* *+ARx */
3706 if (insn
->tm
->flags
& FL_SMR
)
3707 as_warn (_("Address mode *+ARx is write-only. "
3708 "Results of reading are undefined."));
3710 else if (operand
->buf
[4] == '\0')
3712 else if (operand
->buf
[5] == '\0')
3713 mod
= (operand
->buf
[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3714 else if (operand
->buf
[6] == '\0')
3716 if (operand
->buf
[5] == '0')
3717 mod
= (operand
->buf
[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3719 mod
= (operand
->buf
[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3721 else if (TOUPPER (operand
->buf
[6]) == 'B')
3722 mod
= (operand
->buf
[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3723 else if (TOUPPER (operand
->buf
[6]) == '%')
3724 mod
= (operand
->buf
[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3727 as_bad (_("Unrecognized indirect address format \"%s\""),
3733 insn
->opcode
[0].word
|= 0x80 | (mod
<< 3) | arf
;
3739 encode_integer (tic54x_insn
*insn
,
3740 struct opstruct
*operand
,
3741 int which
, int min
, int max
, unsigned short mask
)
3743 long parse
, integer
;
3745 insn
->opcode
[which
].addr_expr
= operand
->exp
;
3747 if (operand
->exp
.X_op
== O_constant
)
3749 parse
= operand
->exp
.X_add_number
;
3750 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3751 instead of negative. */
3752 if ((parse
& 0x8000) && min
== -32768 && max
== 32767)
3753 integer
= (short) parse
;
3757 if (integer
>= min
&& integer
<= max
)
3759 insn
->opcode
[which
].word
|= (integer
& mask
);
3762 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3763 operand
->buf
, min
, max
);
3767 if (insn
->opcode
[which
].addr_expr
.X_op
== O_constant
)
3769 insn
->opcode
[which
].word
|=
3770 insn
->opcode
[which
].addr_expr
.X_add_number
& mask
;
3774 /* Do the fixup later; just store the expression. */
3775 bfd_reloc_code_real_type rtype
=
3776 (mask
== 0x1FF ? BFD_RELOC_TIC54X_PARTMS9
:
3777 mask
== 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23
:
3778 mask
== 0x7F ? BFD_RELOC_TIC54X_PARTLS7
: BFD_RELOC_8
);
3779 int size
= (mask
== 0x1FF || mask
== 0xFFFF) ? 2 : 1;
3781 if (rtype
== BFD_RELOC_8
)
3782 as_bad (_("Error in relocation handling"));
3784 insn
->opcode
[which
].r_nchars
= size
;
3785 insn
->opcode
[which
].r_type
= rtype
;
3786 insn
->opcode
[which
].unresolved
= 1;
3796 encode_condition (tic54x_insn
*insn
, struct opstruct
*operand
)
3798 symbol
*cc
= (symbol
*) hash_find (cc_hash
, operand
->buf
);
3801 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3804 #define CC_GROUP 0x40
3806 #define CATG_A1 0x07
3807 #define CATG_B1 0x30
3808 #define CATG_A2 0x30
3809 #define CATG_B2 0x0C
3810 #define CATG_C2 0x03
3811 /* Disallow group 1 conditions mixed with group 2 conditions
3812 if group 1, allow only one category A and one category B
3813 if group 2, allow only one each of category A, B, and C. */
3814 if (((insn
->opcode
[0].word
& 0xFF) != 0))
3816 if ((insn
->opcode
[0].word
& CC_GROUP
) != (cc
->value
& CC_GROUP
))
3818 as_bad (_("Condition \"%s\" does not match preceding group"),
3822 if (insn
->opcode
[0].word
& CC_GROUP
)
3824 if ((insn
->opcode
[0].word
& CC_ACC
) != (cc
->value
& CC_ACC
))
3826 as_bad (_("Condition \"%s\" uses a different accumulator from "
3827 "a preceding condition"),
3831 if ((insn
->opcode
[0].word
& CATG_A1
) && (cc
->value
& CATG_A1
))
3833 as_bad (_("Only one comparison conditional allowed"));
3836 if ((insn
->opcode
[0].word
& CATG_B1
) && (cc
->value
& CATG_B1
))
3838 as_bad (_("Only one overflow conditional allowed"));
3842 else if (((insn
->opcode
[0].word
& CATG_A2
) && (cc
->value
& CATG_A2
)) ||
3843 ((insn
->opcode
[0].word
& CATG_B2
) && (cc
->value
& CATG_B2
)) ||
3844 ((insn
->opcode
[0].word
& CATG_C2
) && (cc
->value
& CATG_C2
)))
3846 as_bad (_("Duplicate %s conditional"), operand
->buf
);
3851 insn
->opcode
[0].word
|= cc
->value
;
3856 encode_cc3 (tic54x_insn
*insn
, struct opstruct
*operand
)
3858 symbol
*cc3
= (symbol
*) hash_find (cc3_hash
, operand
->buf
);
3859 int value
= cc3
? cc3
->value
: operand
->exp
.X_add_number
<< 8;
3861 if ((value
& 0x0300) != value
)
3863 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3866 insn
->opcode
[0].word
|= value
;
3871 encode_arx (tic54x_insn
*insn
, struct opstruct
*operand
)
3873 int arf
= strlen (operand
->buf
) >= 3 ? operand
->buf
[2] - '0' : -1;
3874 if (strncasecmp ("ar", operand
->buf
, 2) || arf
< 0 || arf
> 7)
3876 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
3879 insn
->opcode
[0].word
|= arf
;
3884 encode_cc2 (tic54x_insn
*insn
, struct opstruct
*operand
)
3886 symbol
*cc2
= (symbol
*) hash_find (cc2_hash
, operand
->buf
);
3889 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3892 insn
->opcode
[0].word
|= cc2
->value
;
3897 encode_operand (insn
, type
, operand
)
3900 struct opstruct
*operand
;
3902 int ext
= (insn
->tm
->flags
& FL_EXT
) != 0;
3904 if (type
== OP_MMR
&& operand
->exp
.X_op
!= O_constant
)
3906 /* Disallow long-constant addressing for memory-mapped addressing. */
3907 if (insn
->is_lkaddr
)
3909 as_bad (_("lk addressing modes are invalid for memory-mapped "
3910 "register addressing"));
3914 /* Warn about *+ARx when used with MMR operands. */
3915 if (strncasecmp (operand
->buf
, "*+ar", 4) == 0)
3917 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
3918 "register addressing. Resulting behavior is "
3928 /* 16-bit immediate value. */
3929 return encode_dmad (insn
, operand
, 0);
3931 if (TOUPPER (*operand
->buf
) == 'B')
3933 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 9);
3934 if (insn
->using_default_dst
)
3935 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
3939 /* Make sure this agrees with with the OP_DST operand. */
3940 if (!((TOUPPER (operand
->buf
[0]) == 'B') ^
3941 ((insn
->opcode
[0].word
& (1 << 8)) != 0)))
3943 as_bad (_("Destination accumulator for each part of this parallel "
3944 "instruction must be different"));
3950 if (TOUPPER (operand
->buf
[0]) == 'B')
3951 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
3956 int mod
= (operand
->buf
[4] == '\0' ? 0 : /* *arx */
3957 operand
->buf
[4] == '-' ? 1 : /* *arx- */
3958 operand
->buf
[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
3959 int arf
= operand
->buf
[3] - '0' - 2;
3960 int code
= (mod
<< 2) | arf
;
3961 insn
->opcode
[0].word
|= (code
<< (type
== OP_Xmem
? 4 : 0));
3966 if (!is_indirect (operand
))
3967 return encode_address (insn
, operand
);
3970 return encode_indirect (insn
, operand
);
3972 return encode_dmad (insn
, operand
, 2);
3974 return encode_dmad (insn
, operand
, 1);
3977 return encode_dmad (insn
, operand
, 0);
3979 return encode_arx (insn
, operand
);
3984 int value
= operand
->exp
.X_add_number
;
3987 insn
->opcode
[0].word
|= value
;
3990 if (value
< 16 || value
> 24)
3992 as_bad (_("Memory mapped register \"%s\" out of range"),
3996 if (type
== OP_MMRX
)
3997 insn
->opcode
[0].word
|= (value
- 16) << 4;
3999 insn
->opcode
[0].word
|= (value
- 16);
4007 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4010 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4013 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4014 -32768, 32767, 0xFFFF);
4016 return encode_condition (insn
, operand
);
4018 return encode_cc2 (insn
, operand
);
4020 return encode_cc3 (insn
, operand
);
4022 return encode_integer (insn
, operand
, 0, 0, 15, 0xF);
4024 return encode_integer (insn
, operand
, 0, -128, 127, 0xFF);
4027 int value
= operand
->exp
.X_add_number
;
4029 if (value
< 1 || value
> 3)
4031 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4034 code
= value
== 1 ? 0 : value
== 2 ? 0x2 : 0x1;
4035 insn
->opcode
[0].word
|= (code
<< 8);
4039 return encode_integer (insn
, operand
, 0, 0, 31, 0x1F);
4041 return encode_integer (insn
, operand
, 0, 0, 255, 0xFF);
4043 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4047 symbol
*sbit
= (symbol
*) hash_find (sbit_hash
, operand
->buf
);
4048 int value
= is_absolute (operand
) ?
4049 operand
->exp
.X_add_number
: (sbit
? sbit
->value
: -1);
4052 if (insn
->opcount
== 1)
4056 as_bad (_("A status register or status bit name is required"));
4059 /* Guess the register based on the status bit; "ovb" is the last
4060 status bit defined for st0. */
4061 if (sbit
> (symbol
*) hash_find (sbit_hash
, "ovb"))
4066 as_bad (_("Unrecognized status bit \"%s\""), operand
->buf
);
4069 insn
->opcode
[0].word
|= value
;
4070 insn
->opcode
[0].word
|= (reg
<< 9);
4074 if (strcasecmp (operand
->buf
, "st0") == 0
4075 || strcasecmp (operand
->buf
, "st1") == 0)
4077 insn
->opcode
[0].word
|=
4078 ((unsigned short) (operand
->buf
[2] - '0')) << 9;
4081 else if (operand
->exp
.X_op
== O_constant
4082 && (operand
->exp
.X_add_number
== 0
4083 || operand
->exp
.X_add_number
== 1))
4085 insn
->opcode
[0].word
|=
4086 ((unsigned short) (operand
->exp
.X_add_number
)) << 9;
4089 as_bad (_("Invalid status register \"%s\""), operand
->buf
);
4092 return encode_integer (insn
, operand
, 0, -16, 15, 0x1F);
4094 return encode_integer (insn
, operand
, 0, 0, 7, 0x7);
4096 return encode_integer (insn
, operand
, 0, 0, 0x1FF, 0x1FF);
4098 if (operand
->exp
.X_add_number
!= 1
4099 && operand
->exp
.X_add_number
!= 2)
4101 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand
->buf
);
4104 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
- 1) << 9;
4113 /* No encoding necessary. */
4123 emit_insn (tic54x_insn
*insn
)
4126 flagword oldflags
= bfd_get_section_flags (stdoutput
, now_seg
);
4127 flagword flags
= oldflags
| SEC_CODE
;
4129 if (! bfd_set_section_flags (stdoutput
, now_seg
, flags
))
4130 as_warn (_("error setting flags for \"%s\": %s"),
4131 bfd_section_name (stdoutput
, now_seg
),
4132 bfd_errmsg (bfd_get_error ()));
4134 for (i
= 0; i
< insn
->words
; i
++)
4136 int size
= (insn
->opcode
[i
].unresolved
4137 && insn
->opcode
[i
].r_type
== BFD_RELOC_TIC54X_23
) ? 4 : 2;
4138 char *p
= frag_more (size
);
4141 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
, 2);
4143 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
<< 16, 4);
4145 if (insn
->opcode
[i
].unresolved
)
4146 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
,
4147 insn
->opcode
[i
].r_nchars
, &insn
->opcode
[i
].addr_expr
,
4148 false, insn
->opcode
[i
].r_type
);
4152 /* Convert the operand strings into appropriate opcode values
4153 return the total number of words used by the instruction. */
4156 build_insn (tic54x_insn
*insn
)
4160 /* Only non-parallel instructions support lk addressing. */
4161 if (!(insn
->tm
->flags
& FL_PAR
))
4163 for (i
= 0; i
< insn
->opcount
; i
++)
4165 if ((OPTYPE (insn
->operands
[i
].type
) == OP_Smem
4166 || OPTYPE (insn
->operands
[i
].type
) == OP_Lmem
4167 || OPTYPE (insn
->operands
[i
].type
) == OP_Sind
)
4168 && strchr (insn
->operands
[i
].buf
, '(')
4169 /* Don't mistake stack-relative addressing for lk addressing. */
4170 && strncasecmp (insn
->operands
[i
].buf
, "*sp (", 4) != 0)
4172 insn
->is_lkaddr
= 1;
4173 insn
->lkoperand
= i
;
4178 insn
->words
= insn
->tm
->words
+ insn
->is_lkaddr
;
4180 insn
->opcode
[0].word
= insn
->tm
->opcode
;
4181 if (insn
->tm
->flags
& FL_EXT
)
4182 insn
->opcode
[1 + insn
->is_lkaddr
].word
= insn
->tm
->opcode2
;
4184 for (i
= 0; i
< insn
->opcount
; i
++)
4186 enum optype type
= insn
->operands
[i
].type
;
4187 if (!encode_operand (insn
, type
, &insn
->operands
[i
]))
4190 if (insn
->tm
->flags
& FL_PAR
)
4191 for (i
= 0; i
< insn
->paropcount
; i
++)
4193 enum optype partype
= insn
->paroperands
[i
].type
;
4194 if (!encode_operand (insn
, partype
, &insn
->paroperands
[i
]))
4204 optimize_insn (tic54x_insn
*insn
)
4206 /* Optimize some instructions, helping out the brain-dead programmer. */
4207 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4208 if (strcasecmp (insn
->tm
->name
, "add") == 0)
4210 if (insn
->opcount
> 1
4211 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4212 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4213 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4214 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4217 insn
->using_default_dst
= 1;
4221 /* Try to collapse if Xmem and shift count is zero. */
4222 if ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4223 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
4224 && is_zero (insn
->operands
[1]))
4225 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4226 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4227 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4228 && is_type (&insn
->operands
[1], OP_SHIFT
)
4229 && is_zero (insn
->operands
[1]) && insn
->opcount
== 3))
4231 insn
->operands
[1] = insn
->operands
[2];
4236 else if (strcasecmp (insn
->tm
->name
, "ld") == 0)
4238 if (insn
->opcount
== 3 && insn
->operands
[0].type
!= OP_SRC
)
4240 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4241 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4242 && is_zero (insn
->operands
[1])
4243 && (OPTYPE (insn
->tm
->operand_types
[0]) != OP_lk
4244 || (insn
->operands
[0].exp
.X_op
== O_constant
4245 && insn
->operands
[0].exp
.X_add_number
<= 255
4246 && insn
->operands
[0].exp
.X_add_number
>= 0)))
4248 insn
->operands
[1] = insn
->operands
[2];
4254 else if (strcasecmp (insn
->tm
->name
, "sth") == 0
4255 || strcasecmp (insn
->tm
->name
, "stl") == 0)
4257 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4258 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4259 && is_zero (insn
->operands
[1]))
4261 insn
->operands
[1] = insn
->operands
[2];
4266 else if (strcasecmp (insn
->tm
->name
, "sub") == 0)
4268 if (insn
->opcount
> 1
4269 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4270 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4271 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4272 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4275 insn
->using_default_dst
= 1;
4279 if (((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4280 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
)
4281 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4282 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
))
4283 && is_zero (insn
->operands
[1])
4284 && insn
->opcount
== 3)
4286 insn
->operands
[1] = insn
->operands
[2];
4294 /* Find a matching template if possible, and get the operand strings. */
4297 tic54x_parse_insn (tic54x_insn
*insn
, char *line
)
4299 insn
->tm
= (template *) hash_find (op_hash
, insn
->mnemonic
);
4302 as_bad (_("Unrecognized instruction \"%s\""), insn
->mnemonic
);
4306 insn
->opcount
= get_operands (insn
->operands
, line
);
4307 if (insn
->opcount
< 0)
4310 /* Check each variation of operands for this mnemonic. */
4311 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
, insn
->mnemonic
) == 0)
4313 if (insn
->opcount
>= insn
->tm
->minops
4314 && insn
->opcount
<= insn
->tm
->maxops
4315 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4316 insn
->tm
->operand_types
,
4317 insn
->tm
->minops
, insn
->tm
->maxops
))
4319 /* SUCCESS! now try some optimizations. */
4320 if (optimize_insn (insn
))
4322 insn
->tm
= (template *) hash_find (op_hash
,
4331 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4332 line
, insn
->mnemonic
);
4336 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4337 won't be able to see the next line. */
4338 static int parallel_on_next_line_hint
= 0;
4340 /* See if this is part of a parallel instruction
4341 Look for a subsequent line starting with "||". */
4344 next_line_shows_parallel (char *next_line
)
4346 /* Look for the second half. */
4347 while (ISSPACE (*next_line
))
4350 return (next_line
[0] == PARALLEL_SEPARATOR
4351 && next_line
[1] == PARALLEL_SEPARATOR
);
4355 tic54x_parse_parallel_insn_firstline (tic54x_insn
*insn
, char *line
)
4357 insn
->tm
= (template *) hash_find (parop_hash
, insn
->mnemonic
);
4360 as_bad (_("Unrecognized parallel instruction \"%s\""),
4365 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4366 insn
->mnemonic
) == 0)
4368 insn
->opcount
= get_operands (insn
->operands
, line
);
4369 if (insn
->opcount
< 0)
4371 if (insn
->opcount
== 2
4372 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4373 insn
->tm
->operand_types
, 2, 2))
4379 /* Didn't find a matching parallel; try for a normal insn. */
4383 /* Parse the second line of a two-line parallel instruction. */
4386 tic54x_parse_parallel_insn_lastline (tic54x_insn
*insn
, char *line
)
4388 int valid_mnemonic
= 0;
4390 insn
->paropcount
= get_operands (insn
->paroperands
, line
);
4391 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4392 insn
->mnemonic
) == 0)
4394 if (strcasecmp (insn
->tm
->parname
, insn
->parmnemonic
) == 0)
4397 if (insn
->paropcount
>= insn
->tm
->minops
4398 && insn
->paropcount
<= insn
->tm
->maxops
4399 && operands_match (insn
, insn
->paroperands
,
4401 insn
->tm
->paroperand_types
,
4402 insn
->tm
->minops
, insn
->tm
->maxops
))
4410 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4413 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4414 insn
->mnemonic
, insn
->parmnemonic
);
4419 /* If quotes found, return copy of line up to closing quote;
4420 otherwise up until terminator.
4421 If it's a string, pass as-is; otherwise attempt substitution symbol
4422 replacement on the value. */
4425 subsym_get_arg (char *line
, char *terminators
, char **str
, int nosub
)
4429 int is_string
= *line
== '"';
4430 int is_char
= ISDIGIT (*line
);
4434 while (ISDIGIT (*ptr
))
4437 *str
= xmalloc (ptr
- line
+ 1);
4438 strncpy (*str
, line
, ptr
- line
);
4439 (*str
)[ptr
- line
] = 0;
4443 char *savedp
= input_line_pointer
;
4445 input_line_pointer
= ptr
;
4446 *str
= demand_copy_C_string (&len
);
4447 endp
= input_line_pointer
;
4448 input_line_pointer
= savedp
;
4450 /* Do forced substitutions if requested. */
4451 if (!nosub
&& **str
== ':')
4452 *str
= subsym_substitute (*str
, 1);
4456 char *term
= terminators
;
4459 while (*ptr
&& *ptr
!= *term
)
4470 *str
= xmalloc (ptr
- line
+ 1);
4471 strncpy (*str
, line
, ptr
- line
);
4472 (*str
)[ptr
- line
] = 0;
4473 /* Do simple substitution, if available. */
4474 if (!nosub
&& (value
= subsym_lookup (*str
, macro_level
)) != NULL
)
4481 /* Replace the given substitution string.
4482 We start at the innermost macro level, so that existing locals remain local
4483 Note: we're treating macro args identically to .var's; I don't know if
4484 that's compatible w/TI's assembler. */
4487 subsym_create_or_replace (name
, value
)
4493 for (i
= macro_level
; i
> 0; i
--)
4495 if (hash_find (subsym_hash
[i
], name
))
4497 hash_replace (subsym_hash
[i
], name
, value
);
4501 if (hash_find (subsym_hash
[0], name
))
4502 hash_replace (subsym_hash
[0], name
, value
);
4504 hash_insert (subsym_hash
[0], name
, value
);
4507 /* Look up the substitution string replacement for the given symbol.
4508 Start with the innermost macro substituion table given and work
4512 subsym_lookup (name
, nest_level
)
4516 char *value
= hash_find (subsym_hash
[nest_level
], name
);
4518 if (value
|| nest_level
== 0)
4521 return subsym_lookup (name
, nest_level
- 1);
4524 /* Do substitution-symbol replacement on the given line (recursively).
4525 return the argument if no substitution was done
4527 Also look for built-in functions ($func (arg)) and local labels.
4529 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4532 subsym_substitute (char *line
, int forced
)
4534 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4535 replace it in the input. */
4536 char *replacement
; /* current replacement for LINE. */
4537 char *head
; /* Start of line. */
4538 char *ptr
; /* Current examination point. */
4539 int changed
= 0; /* Did we make a substitution? */
4540 int eval_line
= 0; /* Is this line a .eval/.asg statement? */
4541 int eval_symbol
= 0; /* Are we in the middle of the symbol for
4543 char *eval_end
= NULL
;
4545 int line_conditional
= 0;
4548 /* Work with a copy of the input line. */
4549 replacement
= xmalloc (strlen (line
) + 1);
4550 strcpy (replacement
, line
);
4552 ptr
= head
= replacement
;
4554 /* Flag lines where we might need to replace a single '=' with two;
4555 GAS uses single '=' to assign macro args values, and possibly other
4556 places, so limit what we replace. */
4557 if (strstr (line
, ".if")
4558 || strstr (line
, ".elseif")
4559 || strstr (line
, ".break"))
4561 line_conditional
= 1;
4564 /* Watch out for .eval, so that we avoid doing substitution on the
4565 symbol being assigned a value. */
4566 if (strstr (line
, ".eval") || strstr (line
, ".asg"))
4569 /* If it's a macro definition, don't do substitution on the argument
4571 if (strstr (line
, ".macro"))
4574 while (!is_end_of_line
[(int) *ptr
])
4576 int current_char
= *ptr
;
4578 /* Need to update this since LINE may have been modified. */
4580 eval_end
= strrchr (ptr
, ',');
4582 /* Replace triple double quotes with bounding quote/escapes. */
4583 if (current_char
== '"' && ptr
[1] == '"' && ptr
[2] == '"')
4586 tmp
= strstr (ptr
+ 2, "\"\"\"");
4592 /* Replace a single '=' with a '==';
4593 for compatibility with older code only. */
4594 if (line_conditional
&& current_char
== '=')
4602 tmp
= xmalloc (strlen (head
) + 2 + strlen (ptr
) + 1);
4603 sprintf (tmp
, "%s==%s", head
, ptr
);
4604 /* Continue examining after the '=='. */
4605 ptr
= tmp
+ strlen (head
) + 2;
4607 head
= replacement
= tmp
;
4611 /* Flag when we've reached the symbol part of .eval/.asg. */
4612 if (eval_line
&& ptr
>= eval_end
)
4615 /* For each apparent symbol, see if it's a substitution symbol, and if
4616 so, replace it in the input. */
4617 if ((forced
&& current_char
== ':')
4618 || (!forced
&& is_name_beginner (current_char
)))
4620 char *name
; /* Symbol to be replaced. */
4621 char *savedp
= input_line_pointer
;
4624 char *tail
; /* Rest of line after symbol. */
4626 /* Skip the colon. */
4630 name
= input_line_pointer
= ptr
;
4631 c
= get_symbol_end ();
4632 /* '?' is not normally part of a symbol, but it IS part of a local
4636 *input_line_pointer
++ = c
;
4637 c
= *input_line_pointer
;
4638 *input_line_pointer
= '\0';
4640 /* Avoid infinite recursion; if a symbol shows up a second time for
4641 substitution, leave it as is. */
4642 if (hash_find (subsym_recurse_hash
, name
) == NULL
)
4643 value
= subsym_lookup (name
, macro_level
);
4645 as_warn (_("%s symbol recursion stopped at "
4646 "second appearance of '%s'"),
4647 forced
? "Forced substitution" : "Substitution", name
);
4648 ptr
= tail
= input_line_pointer
;
4649 input_line_pointer
= savedp
;
4651 /* Check for local labels; replace them with the appropriate
4653 if ((*name
== '$' && ISDIGIT (name
[1]) && name
[2] == '\0')
4654 || name
[strlen (name
) - 1] == '?')
4656 /* Use an existing identifier for that label if, available, or
4657 create a new, unique identifier. */
4658 value
= hash_find (local_label_hash
[macro_level
], name
);
4662 char *namecopy
= strcpy (xmalloc (strlen (name
) + 1), name
);
4663 value
= strcpy (xmalloc (strlen (name
) + sizeof (digit
) + 1),
4666 value
[strlen (value
) - 1] = '\0';
4667 sprintf (digit
, ".%d", local_label_id
++);
4668 strcat (value
, digit
);
4669 hash_insert (local_label_hash
[macro_level
], namecopy
, value
);
4671 /* Indicate where to continue looking for substitutions. */
4674 /* Check for built-in subsym and math functions. */
4675 else if (value
!= NULL
&& *name
== '$')
4677 subsym_proc_entry
*entry
= (subsym_proc_entry
*) value
;
4678 math_proc_entry
*math_entry
= hash_find (math_hash
, name
);
4679 char *arg1
, *arg2
= NULL
;
4684 as_bad (_("Unrecognized substitution symbol function"));
4687 else if (*ptr
!= '(')
4689 as_bad (_("Missing '(' after substitution symbol function"));
4693 if (math_entry
!= NULL
)
4695 float arg1
, arg2
= 0;
4696 volatile float fresult
;
4698 arg1
= (float) strtod (ptr
, &ptr
);
4699 if (math_entry
->nargs
== 2)
4703 as_bad (_("Expecting second argument"));
4706 arg2
= (float) strtod (ptr
, &ptr
);
4708 fresult
= (*math_entry
->proc
) (arg1
, arg2
);
4709 value
= xmalloc (128);
4710 if (math_entry
->int_return
)
4711 sprintf (value
, "%d", (int) fresult
);
4713 sprintf (value
, "%f", fresult
);
4716 as_bad (_("Extra junk in function call, expecting ')'"));
4719 /* Don't bother recursing; the replacement isn't a
4726 int arg_type
[2] = { *ptr
== '"' , 0 };
4727 int ismember
= !strcmp (entry
->name
, "$ismember");
4728 /* Parse one or two args, which must be a substitution
4729 symbol, string or a character-string constant. */
4730 /* For all functions, a string or substitution symbol may be
4731 used, with the following exceptions:
4732 firstch/lastch: 2nd arg must be character constant
4733 ismember: both args must be substitution symbols. */
4734 ptr
= subsym_get_arg (ptr
, ",)", &arg1
, ismember
);
4737 if (entry
->nargs
== 2)
4741 as_bad (_("Function expects two arguments"));
4744 /* Character constants are converted to numerics
4745 by the preprocessor. */
4746 arg_type
[1] = (ISDIGIT (*ptr
)) ? 2 : (*ptr
== '"');
4747 ptr
= subsym_get_arg (ptr
, ")", &arg2
, ismember
);
4749 /* Args checking. */
4750 if ((!strcmp (entry
->name
, "$firstch")
4751 || !strcmp (entry
->name
, "$lastch"))
4752 && arg_type
[1] != 2)
4754 as_bad (_("Expecting character constant argument"));
4758 && (arg_type
[0] != 0 || arg_type
[1] != 0))
4760 as_bad (_("Both arguments must be substitution symbols"));
4765 as_bad (_("Extra junk in function call, expecting ')'"));
4768 val
= (*entry
->proc
) (arg1
, arg2
);
4769 value
= xmalloc (64);
4770 sprintf (value
, "%d", val
);
4772 /* Fix things up to replace the entire expression, not just the
4778 if (value
!= NULL
&& !eval_symbol
)
4780 /* Replace the symbol with its string replacement and
4781 continue. Recursively replace VALUE until either no
4782 substitutions are performed, or a substitution that has been
4783 previously made is encountered again.
4785 put the symbol into the recursion hash table so we only
4786 try to replace a symbol once. */
4789 hash_insert (subsym_recurse_hash
, name
, name
);
4790 value
= subsym_substitute (value
, macro_level
> 0);
4791 hash_delete (subsym_recurse_hash
, name
);
4794 /* Temporarily zero-terminate where the symbol started. */
4800 /* Subscripted substitution symbol -- use just the
4801 indicated portion of the string; the description
4802 kinda indicates that forced substituion is not
4803 supposed to be recursive, but I'm not sure. */
4804 unsigned beg
, len
= 1; /* default to a single char */
4805 char *newval
= strcpy (xmalloc (strlen (value
) + 1),
4808 savedp
= input_line_pointer
;
4809 input_line_pointer
= tail
+ 1;
4810 beg
= get_absolute_expression ();
4813 as_bad (_("Invalid subscript (use 1 to %d)"),
4817 if (*input_line_pointer
== ',')
4819 ++input_line_pointer
;
4820 len
= get_absolute_expression ();
4821 if (beg
+ len
> strlen (value
))
4823 as_bad (_("Invalid length (use 0 to %d"),
4824 strlen (value
) - beg
);
4830 tail
= input_line_pointer
;
4833 as_bad (_("Missing ')' in subscripted substitution "
4834 "symbol expression"));
4838 input_line_pointer
= savedp
;
4844 tmp
= xmalloc (strlen (head
) + strlen (value
) +
4845 strlen (tail
+ 1) + 2);
4847 strcat (tmp
, value
);
4848 /* Make sure forced substitutions are properly terminated. */
4853 as_bad (_("Missing forced substitution terminator ':'"));
4858 /* Try to replace required whitespace
4859 eliminated by the preprocessor; technically, a forced
4860 substitution could come anywhere, even mid-symbol,
4861 e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
4862 but 'sym:x: end' should result in 'sym0 end'.
4863 FIXME -- this should really be fixed in the preprocessor,
4864 but would require several new states;
4865 KEEP_WHITE_AROUND_COLON does part of the job, but isn't
4867 if ((is_part_of_name (tail
[1])
4870 || tail
[1] == '\0' || tail
[1] == ',' || tail
[1] == '"')
4877 /* Restore the character after the symbol end. */
4880 /* Continue examining after the replacement value. */
4881 ptr
= tmp
+ strlen (head
) + strlen (value
);
4883 head
= replacement
= tmp
;
4901 /* We use this to handle substitution symbols
4902 hijack input_line_pointer, replacing it with our substituted string.
4904 .sslist should enable listing the line after replacements are made...
4906 returns the new buffer limit. */
4909 tic54x_start_line_hook ()
4912 char *replacement
= NULL
;
4914 /* Work with a copy of the input line, including EOL char. */
4915 endp
= input_line_pointer
;
4916 while (!is_end_of_line
[(int) *endp
++])
4918 line
= xmalloc (endp
- input_line_pointer
+ 1);
4919 strncpy (line
, input_line_pointer
, endp
- input_line_pointer
+ 1);
4920 line
[endp
- input_line_pointer
] = 0;
4922 /* Scan ahead for parallel insns. */
4923 parallel_on_next_line_hint
= next_line_shows_parallel (endp
+ 1);
4925 /* If within a macro, first process forced replacements. */
4926 if (macro_level
> 0)
4927 replacement
= subsym_substitute (line
, 1);
4930 replacement
= subsym_substitute (replacement
, 0);
4932 if (replacement
!= line
)
4934 char *tmp
= replacement
;
4935 char *comment
= strchr (replacement
, ';');
4936 char endc
= replacement
[strlen (replacement
) - 1];
4938 /* Clean up the replacement; we'd prefer to have this done by the
4939 standard preprocessing equipment (maybe do_scrub_chars?)
4940 but for now, do a quick-and-dirty. */
4941 if (comment
!= NULL
)
4948 comment
= replacement
+ strlen (replacement
) - 1;
4950 /* Trim trailing whitespace. */
4951 while (ISSPACE (*comment
))
4958 /* Compact leading whitespace. */
4959 while (ISSPACE (tmp
[0]) && ISSPACE (tmp
[1]))
4962 input_line_pointer
= endp
;
4963 input_scrub_insert_line (tmp
);
4966 /* Keep track of whether we've done a substitution. */
4967 substitution_line
= 1;
4973 substitution_line
= 0;
4977 /* This is the guts of the machine-dependent assembler. STR points to a
4978 machine dependent instruction. This function is supposed to emit
4979 the frags/bytes it assembles to. */
4984 static int repeat_slot
= 0;
4985 static int delay_slots
= 0; /* How many delay slots left to fill? */
4986 static int is_parallel
= 0;
4987 static tic54x_insn insn
;
4989 char *savedp
= input_line_pointer
;
4992 input_line_pointer
= line
;
4993 c
= get_symbol_end ();
4997 if (address_mode_needs_set
)
4999 set_address_mode (amode
);
5000 address_mode_needs_set
= 0;
5013 strcpy (insn
.parmnemonic
, line
);
5014 lptr
= input_line_pointer
;
5016 input_line_pointer
= savedp
;
5018 if (tic54x_parse_parallel_insn_lastline (&insn
, lptr
))
5020 int words
= build_insn (&insn
);
5022 if (delay_slots
!= 0)
5024 if (words
> delay_slots
)
5026 as_bad (_("Instruction does not fit in available delay "
5027 "slots (%d-word insn, %d slots left)"),
5028 words
, delay_slots
);
5032 delay_slots
-= words
;
5038 memset (&insn
, 0, sizeof (insn
));
5039 strcpy (insn
.mnemonic
, line
);
5040 lptr
= input_line_pointer
;
5042 input_line_pointer
= savedp
;
5044 /* See if this line is part of a parallel instruction; if so, either this
5045 line or the next line will have the "||" specifier preceding the
5046 mnemonic, and we look for it in the parallel insn hash table. */
5047 if (strstr (line
, "||") != NULL
|| parallel_on_next_line_hint
)
5049 char *tmp
= strstr (line
, "||");
5053 if (tic54x_parse_parallel_insn_firstline (&insn
, lptr
))
5056 /* If the parallel part is on the same line, process it now,
5057 otherwise let the assembler pick up the next line for us. */
5060 while (ISSPACE (tmp
[2]))
5062 md_assemble (tmp
+ 2);
5067 as_bad (_("Unrecognized parallel instruction '%s'"), line
);
5072 if (tic54x_parse_insn (&insn
, lptr
))
5076 if ((insn
.tm
->flags
& FL_LP
)
5077 && cpu
!= V545LP
&& cpu
!= V546LP
)
5079 as_bad (_("Instruction '%s' requires an LP cpu version"),
5083 if ((insn
.tm
->flags
& FL_FAR
)
5084 && amode
!= far_mode
)
5086 as_bad (_("Instruction '%s' requires far mode addressing"),
5091 words
= build_insn (&insn
);
5093 /* Is this instruction in a delay slot? */
5096 if (words
> delay_slots
)
5098 as_warn (_("Instruction does not fit in available delay "
5099 "slots (%d-word insn, %d slots left). "
5100 "Resulting behavior is undefined."),
5101 words
, delay_slots
);
5105 /* Branches in delay slots are not allowed. */
5106 if (insn
.tm
->flags
& FL_BMASK
)
5108 as_warn (_("Instructions which cause PC discontinuity are not "
5109 "allowed in a delay slot. "
5110 "Resulting behavior is undefined."));
5112 delay_slots
-= words
;
5115 /* Is this instruction the target of a repeat? */
5118 if (insn
.tm
->flags
& FL_NR
)
5119 as_warn (_("'%s' is not repeatable. "
5120 "Resulting behavior is undefined."),
5122 else if (insn
.is_lkaddr
)
5123 as_warn (_("Instructions using long offset modifiers or absolute "
5124 "addresses are not repeatable. "
5125 "Resulting behavior is undefined."));
5129 /* Make sure we check the target of a repeat instruction. */
5130 if (insn
.tm
->flags
& B_REPEAT
)
5133 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5135 /* Make sure we check our delay slots for validity. */
5136 if (insn
.tm
->flags
& FL_DELAY
)
5139 /* FIXME -- warn if delay_slots != 0 at EOF. */
5144 /* Do a final adjustment on the symbol table; in this case, make sure we have
5145 a ".file" symbol. */
5148 tic54x_adjust_symtab ()
5150 if (symbol_rootP
== NULL
5151 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
5155 as_where (&filename
, &lineno
);
5156 c_dot_file_symbol (filename
);
5160 /* In order to get gas to ignore any | chars at the start of a line,
5161 this function returns true if a | is found in a line.
5162 This lets us process parallel instructions, which span two lines. */
5165 tic54x_unrecognized_line (int c
)
5167 return c
== PARALLEL_SEPARATOR
;
5170 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5171 Encode their names so that only we see them and can map them to the
5173 FIXME -- obviously this isn't done yet. These locals still show up in the
5176 tic54x_define_label (sym
)
5180 static int local_label_count
= 0;
5181 const char *name
= S_GET_NAME (sym
);
5184 /* Just in case we need this later; note that this is not necessarily the
5185 same thing as line_label...
5186 When aligning or assigning labels to fields, sometimes the label is
5187 assigned other than the address at which the label appears.
5188 FIXME -- is this really needed? I think all the proper label assignment
5189 is done in tic54x_cons. */
5190 last_label_seen
= sym
;
5193 /* Try to parse something that normal parsing failed at. */
5196 tic54x_undefined_symbol (name
)
5201 /* Not sure how to handle predefined symbols. */
5202 if ((sym
= (symbol
*) hash_find (cc_hash
, name
)) != NULL
||
5203 (sym
= (symbol
*) hash_find (cc2_hash
, name
)) != NULL
||
5204 (sym
= (symbol
*) hash_find (cc3_hash
, name
)) != NULL
||
5205 (sym
= (symbol
*) hash_find (misc_symbol_hash
, name
)) != NULL
||
5206 (sym
= (symbol
*) hash_find (sbit_hash
, name
)) != NULL
)
5208 return symbol_new (name
, reg_section
,
5209 (valueT
) sym
->value
,
5210 &zero_address_frag
);
5213 if ((sym
= (symbol
*) hash_find (reg_hash
, name
)) != NULL
||
5214 (sym
= (symbol
*) hash_find (mmreg_hash
, name
)) != NULL
||
5215 !strcasecmp (name
, "a") || !strcasecmp (name
, "b"))
5217 return symbol_new (name
, reg_section
,
5218 (valueT
) sym
? sym
->value
: 0,
5219 &zero_address_frag
);
5225 /* Parse a name in an expression before the expression parser takes a stab at
5229 tic54x_parse_name (name
, exp
)
5230 char *name ATTRIBUTE_UNUSED
;
5231 expressionS
*exp ATTRIBUTE_UNUSED
;
5234 symbol
*sym
= (symbol
*) hash_find (mmreg_hash
, name
);
5236 /* If it's a MMREG, replace it with its constant value. */
5239 exp
->X_op
= O_constant
;
5240 exp
->X_add_number
= sym
->value
;
5248 md_atof (type
, literalP
, sizeP
)
5253 #define MAX_LITTLENUMS 2
5254 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5255 LITTLENUM_TYPE
*word
;
5256 /* Only one precision on the c54x. */
5258 char *t
= atof_ieee (input_line_pointer
, type
, words
);
5260 input_line_pointer
= t
;
5263 /* Target data is little-endian, but floats are stored
5264 big-"word"ian. ugh. */
5265 for (word
= words
; prec
--;)
5267 md_number_to_chars (literalP
, (long) (*word
++), sizeof (LITTLENUM_TYPE
));
5268 literalP
+= sizeof (LITTLENUM_TYPE
);
5275 tc_gen_reloc (section
, fixP
)
5280 bfd_reloc_code_real_type code
= fixP
->fx_r_type
;
5281 asymbol
*sym
= symbol_get_bfdsym (fixP
->fx_addsy
);
5283 rel
= (arelent
*) xmalloc (sizeof (arelent
));
5284 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5285 *rel
->sym_ptr_ptr
= sym
;
5286 /* We assume that all rel->address are host byte offsets. */
5287 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5288 rel
->address
/= OCTETS_PER_BYTE
;
5289 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5290 if (!strcmp (sym
->name
, section
->name
))
5291 rel
->howto
+= HOWTO_BANK
;
5295 const char *name
= S_GET_NAME (fixP
->fx_addsy
);
5298 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5299 name
, bfd_get_reloc_code_name (code
));
5305 /* Handle cons expressions. */
5308 tic54x_cons_fix_new (fragS
*frag
, int where
, int octets
, expressionS
*exp
)
5310 bfd_reloc_code_real_type r
;
5314 as_bad (_("Unsupported relocation size %d"), octets
);
5315 r
= BFD_RELOC_TIC54X_16_OF_23
;
5318 r
= BFD_RELOC_TIC54X_16_OF_23
;
5321 /* TI assembler always uses this, regardless of addressing mode. */
5323 r
= BFD_RELOC_TIC54X_23
;
5325 /* We never want to directly generate this; this is provided for
5326 stabs support only. */
5330 fix_new_exp (frag
, where
, octets
, exp
, 0, r
);
5333 /* Attempt to simplify or even eliminate a fixup.
5334 To indicate that a fixup has been eliminated, set fixP->fx_done.
5336 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5339 md_apply_fix3 (fixP
, valP
, seg
)
5342 segT seg ATTRIBUTE_UNUSED
;
5344 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5345 valueT val
= * valP
;
5347 switch (fixP
->fx_r_type
)
5350 as_fatal ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
5352 case BFD_RELOC_TIC54X_MS7_OF_23
:
5353 val
= (val
>> 16) & 0x7F;
5355 case BFD_RELOC_TIC54X_16_OF_23
:
5357 bfd_put_16 (stdoutput
, val
, buf
);
5358 /* Indicate what we're actually writing, so that we don't get warnings
5359 about exceeding available space. */
5360 *valP
= val
& 0xFFFF;
5362 case BFD_RELOC_TIC54X_PARTLS7
:
5363 bfd_put_16 (stdoutput
,
5364 (bfd_get_16 (stdoutput
, buf
) & 0xFF80) | (val
& 0x7F),
5366 /* Indicate what we're actually writing, so that we don't get warnings
5367 about exceeding available space. */
5370 case BFD_RELOC_TIC54X_PARTMS9
:
5371 /* TI assembler doesn't shift its encoding for relocatable files, and is
5372 thus incompatible with this implementation's relocatable files. */
5373 bfd_put_16 (stdoutput
,
5374 (bfd_get_16 (stdoutput
, buf
) & 0xFE00) | (val
>> 7),
5378 case BFD_RELOC_TIC54X_23
:
5379 bfd_put_32 (stdoutput
,
5380 (bfd_get_32 (stdoutput
, buf
) & 0xFF800000) | val
,
5385 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
5389 /* This is our chance to record section alignment
5390 don't need to do anything here, since BFD does the proper encoding. */
5393 md_section_align (segment
, section_size
)
5394 segT segment ATTRIBUTE_UNUSED
;
5395 valueT section_size
;
5397 return section_size
;
5401 md_pcrel_from (fixP
)
5402 fixS
*fixP ATTRIBUTE_UNUSED
;
5407 #if defined OBJ_COFF
5410 tc_coff_fix2rtype (fixP
)
5413 return (fixP
->fx_r_type
);
5416 #endif /* OBJ_COFF */
5418 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5422 tic54x_number_to_chars (buf
, val
, n
)
5428 number_to_chars_littleendian (buf
, val
, n
);
5431 number_to_chars_littleendian (buf
, val
>> 16 , 2);
5432 number_to_chars_littleendian (buf
+ 2, val
& 0xFFFF, 2);
5437 tic54x_estimate_size_before_relax (frag
, seg
)
5438 fragS
*frag ATTRIBUTE_UNUSED
;
5439 segT seg ATTRIBUTE_UNUSED
;
5444 /* We use this to handle bit allocations which we couldn't handle before due
5445 to symbols being in different frags. return number of octets added. */
5448 tic54x_relax_frag (frag
, stretch
)
5450 long stretch ATTRIBUTE_UNUSED
;
5452 symbolS
*sym
= frag
->fr_symbol
;
5458 struct bit_info
*bi
= (struct bit_info
*) frag
->fr_opcode
;
5459 int bit_offset
= frag_bit_offset (frag_prev (frag
, bi
->seg
), bi
->seg
);
5460 int size
= S_GET_VALUE (sym
);
5461 fragS
*prev_frag
= bit_offset_frag (frag_prev (frag
, bi
->seg
), bi
->seg
);
5462 int available
= 16 - bit_offset
;
5464 if (symbol_get_frag (sym
) != &zero_address_frag
5465 || S_IS_COMMON (sym
)
5466 || !S_IS_DEFINED (sym
))
5467 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5468 _("non-absolute value used with .space/.bes"));
5472 as_warn (_("negative value ignored in %s"),
5473 bi
->type
== TYPE_SPACE
? ".space" :
5474 bi
->type
== TYPE_BES
? ".bes" : ".field");
5476 frag
->tc_frag_data
= frag
->fr_fix
= 0;
5480 if (bi
->type
== TYPE_FIELD
)
5482 /* Bit fields of 16 or larger will have already been handled. */
5483 if (bit_offset
!= 0 && available
>= size
)
5485 char *p
= prev_frag
->fr_literal
;
5486 valueT value
= bi
->value
;
5487 value
<<= available
- size
;
5488 value
|= ((unsigned short) p
[1] << 8) | p
[0];
5489 md_number_to_chars (p
, value
, 2);
5490 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5491 prev_frag
->tc_frag_data
= 0;
5493 symbol_set_frag (bi
->sym
, prev_frag
);
5494 /* This frag is no longer used. */
5495 growth
= -frag
->fr_fix
;
5497 frag
->tc_frag_data
= 0;
5501 char *p
= frag
->fr_literal
;
5502 valueT value
= bi
->value
<< (16 - size
);
5503 md_number_to_chars (p
, value
, 2);
5504 if ((frag
->tc_frag_data
= size
) == 16)
5505 frag
->tc_frag_data
= 0;
5511 if (bit_offset
!= 0 && bit_offset
< 16)
5513 if (available
>= size
)
5515 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5516 prev_frag
->tc_frag_data
= 0;
5518 symbol_set_frag (bi
->sym
, prev_frag
);
5519 /* This frag is no longer used. */
5520 growth
= -frag
->fr_fix
;
5522 frag
->tc_frag_data
= 0;
5525 if (bi
->type
== TYPE_SPACE
&& bi
->sym
)
5526 symbol_set_frag (bi
->sym
, prev_frag
);
5529 growth
= (size
+ 15) / 16 * OCTETS_PER_BYTE
- frag
->fr_fix
;
5530 for (i
= 0; i
< growth
; i
++)
5531 frag
->fr_literal
[i
] = 0;
5532 frag
->fr_fix
= growth
;
5533 frag
->tc_frag_data
= size
% 16;
5534 /* Make sure any BES label points to the LAST word allocated. */
5535 if (bi
->type
== TYPE_BES
&& bi
->sym
)
5536 S_SET_VALUE (bi
->sym
, frag
->fr_fix
/ OCTETS_PER_BYTE
- 1);
5539 frag
->fr_symbol
= 0;
5540 frag
->fr_opcode
= 0;
5547 tic54x_convert_frag (abfd
, seg
, frag
)
5548 bfd
*abfd ATTRIBUTE_UNUSED
;
5549 segT seg ATTRIBUTE_UNUSED
;
5552 /* Offset is in bytes. */
5553 frag
->fr_offset
= (frag
->fr_next
->fr_address
5555 - frag
->fr_fix
) / frag
->fr_var
;
5556 if (frag
->fr_offset
< 0)
5558 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5559 _("attempt to .space/.bes backwards? (%ld)"),
5560 (long) frag
->fr_offset
);
5562 frag
->fr_type
= rs_space
;
5565 /* We need to avoid having labels defined for certain directives/pseudo-ops
5566 since once the label is defined, it's in the symbol table for good. TI
5567 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5568 I guess, except I've never seen a definition of MRI syntax).
5570 C is the character that used to be at *REST, which points to the end of the
5573 Don't allow labels to start with '.' */
5576 tic54x_start_label (c
, rest
)
5580 /* If within .struct/.union, no auto line labels, please. */
5581 if (current_stag
!= NULL
)
5584 /* Disallow labels starting with "." */
5588 while (!is_end_of_line
[(int) label
[-1]])
5592 as_bad (_("Invalid label '%s'"), label
);
5597 if (is_end_of_line
[(int) c
])
5601 while (ISSPACE (c
= *++rest
))
5605 /* Don't let colon () define a label for any of these... */
5606 return (strncasecmp (rest
, ".tag", 4) != 0 || !ISSPACE (rest
[4]))
5607 && (strncasecmp (rest
, ".struct", 7) != 0 || !ISSPACE (rest
[7]))
5608 && (strncasecmp (rest
, ".union", 6) != 0 || !ISSPACE (rest
[6]))
5609 && (strncasecmp (rest
, ".macro", 6) != 0 || !ISSPACE (rest
[6]))
5610 && (strncasecmp (rest
, ".set", 4) != 0 || !ISSPACE (rest
[4]))
5611 && (strncasecmp (rest
, ".equ", 4) != 0 || !ISSPACE (rest
[4]));