1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Timothy Wall (twall@cygnus.com)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 /* Texas Instruments TMS320C54X machine specific gas.
24 Written by Timothy Wall (twall@alum.mit.edu).
26 Valuable things to do:
27 Pipeline conflict warnings
28 We encode/decode "ld #_label, dp" differently in relocatable files
29 This means we're not compatible with TI output containing those
30 expressions. We store the upper nine bits; TI stores the lower nine
31 bits. How they recover the original upper nine bits is beyond me.
33 Tests to add to expect testsuite:
34 '=' and '==' with .if, .elseif, and .break
36 Incompatibilities (mostly trivial):
38 We fill text section with zeroes instead of "nop"s
39 We don't convert '' or "" to a single instance
40 We don't convert '' to '\0'
41 We don't allow strings with .byte/.half/.short/.long
42 Probably details of the subsym stuff are different
43 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
45 COFF1 limits section names to 8 characters.
46 Some of the default behavior changed from COFF1 to COFF2. */
50 #include "safe-ctype.h"
54 #include "struc-symbol.h"
55 #include "opcode/tic54x.h"
62 symbolS
*sym
; /* Symbol for this stag; value is offset. */
63 const char *name
; /* Shortcut to symbol name. */
64 bfd_vma size
; /* Size of struct/union. */
65 int current_bitfield_offset
; /* Temporary for tracking fields. */
67 struct stag_field
/* List of fields. */
70 bfd_vma offset
; /* Of start of this field. */
71 int bitfield_offset
; /* Of start of this field. */
72 struct stag
*stag
; /* If field is struct/union. */
73 struct stag_field
*next
;
75 /* For nesting; used only in stag construction. */
76 struct stag
*inner
; /* Enclosed .struct. */
77 struct stag
*outer
; /* Enclosing .struct. */
78 } *current_stag
= NULL
;
80 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
82 typedef struct _tic54x_insn
84 const template *tm
; /* Opcode template. */
86 char mnemonic
[MAX_LINE
]; /* Opcode name/mnemonic. */
87 char parmnemonic
[MAX_LINE
]; /* 2nd mnemonic of parallel insn. */
95 } operands
[MAX_OPERANDS
];
98 struct opstruct paroperands
[MAX_OPERANDS
];
102 int words
; /* Size of insn in 16-bit words. */
103 int using_default_dst
; /* Do we need to explicitly set an
104 omitted OP_DST operand? */
107 unsigned short word
; /* Final encoded opcode data. */
109 int r_nchars
; /* Relocation size. */
110 bfd_reloc_code_real_type r_type
; /* Relocation type. */
111 expressionS addr_expr
; /* Storage for unresolved expressions. */
117 VNONE
= 0, V541
= 1, V542
= 2, V543
= 3, V545
= 5, V548
= 8, V549
= 9,
118 V545LP
= 15, V546LP
= 16
123 c_mode
, /* 16-bit addresses. */
124 far_mode
/* >16-bit addresses. */
127 static segT stag_saved_seg
;
128 static subsegT stag_saved_subseg
;
130 const char comment_chars
[] = ";";
131 const char line_comment_chars
[] = ";*#"; /* At column zero only. */
132 const char line_separator_chars
[] = ""; /* Not permitted. */
134 int emitting_long
= 0;
136 /* Characters which indicate that this is a floating point constant. */
137 const char FLT_CHARS
[] = "fF";
139 /* Characters that can be used to separate mantissa from exp in FP
141 const char EXP_CHARS
[] = "eE";
143 const char *md_shortopts
= "";
145 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
146 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
147 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
148 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
150 struct option md_longopts
[] =
152 { "mfar-mode", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
153 { "mf", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
154 { "mcpu", required_argument
, NULL
, OPTION_CPU_VERSION
},
155 { "merrors-to-file", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
156 { "me", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
157 { NULL
, no_argument
, NULL
, 0},
160 size_t md_longopts_size
= sizeof (md_longopts
);
162 static int assembly_begun
= 0;
163 /* Addressing mode is not entirely implemented; the latest rev of the Other
164 assembler doesn't seem to make any distinction whatsoever; all relocations
165 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
166 but now it seems all relocations are RELEXT16. We use all RELEXT16.
168 The cpu version is kind of a waste of time as well. There is one
169 instruction (RND) for LP devices only, and several for devices with
170 extended addressing only. We include it for compatibility. */
171 static enum address_mode amode
= c_mode
;
172 static enum cpu_version cpu
= VNONE
;
174 /* Include string substitutions in listing? */
175 static int listing_sslist
= 0;
177 /* Did we do subsym substitutions on the line? */
178 static int substitution_line
= 0;
180 /* Last label seen. */
181 static symbolS
*last_label_seen
= NULL
;
183 /* This ensures that all new labels are unique. */
184 static int local_label_id
;
186 static struct hash_control
*subsym_recurse_hash
; /* Prevent infinite recurse. */
187 static struct hash_control
*math_hash
; /* Built-in math functions. */
188 /* Allow maximum levels of macro nesting; level 0 is the main substitution
189 symbol table. The other assembler only does 32 levels, so there! */
190 static struct hash_control
*subsym_hash
[100];
192 /* Keep track of local labels so we can substitute them before GAS sees them
193 since macros use their own 'namespace' for local labels, use a separate hash
195 We do our own local label handling 'cuz it's subtly different from the
198 We use our own macro nesting counter, since GAS overloads it when expanding
199 other things (like conditionals and repeat loops). */
200 static int macro_level
= 0;
201 static struct hash_control
*local_label_hash
[100];
202 /* Keep track of struct/union tags. */
203 static struct hash_control
*stag_hash
;
204 static struct hash_control
*op_hash
;
205 static struct hash_control
*parop_hash
;
206 static struct hash_control
*reg_hash
;
207 static struct hash_control
*mmreg_hash
;
208 static struct hash_control
*cc_hash
;
209 static struct hash_control
*cc2_hash
;
210 static struct hash_control
*cc3_hash
;
211 static struct hash_control
*sbit_hash
;
212 static struct hash_control
*misc_symbol_hash
;
214 /* Only word (et al.), align, or conditionals are allowed within
216 #define ILLEGAL_WITHIN_STRUCT() \
218 if (current_stag != NULL) \
220 as_bad (_("pseudo-op illegal within .struct/.union")); \
225 static void tic54x_emit_char
PARAMS ((char));
226 static fragS
* frag_prev
PARAMS ((fragS
*, segT
));
227 static fragS
* bit_offset_frag
PARAMS ((fragS
*, segT
));
228 static int frag_bit_offset
PARAMS ((fragS
*, segT
));
229 static char * parse_expression
PARAMS ((char *, expressionS
*));
230 static void tic54x_asg
PARAMS ((int));
231 static void tic54x_eval
PARAMS ((int));
232 static void tic54x_bss
PARAMS ((int));
233 static void stag_add_field_symbols
PARAMS ((struct stag
*, const char *, bfd_vma
, symbolS
*, const char *));
234 static void stag_add_field
PARAMS ((struct stag
*, const char *, bfd_vma
, struct stag
*));
235 static void tic54x_struct
PARAMS ((int));
236 static void tic54x_endstruct
PARAMS ((int));
237 static void tic54x_tag
PARAMS ((int));
238 static void tic54x_struct_field
PARAMS ((int));
239 static void tic54x_cons
PARAMS ((int));
240 static void tic54x_remove_local_label
PARAMS ((const char *, PTR
));
241 static void tic54x_clear_local_labels
PARAMS ((int));
242 static void tic54x_sect
PARAMS ((int));
243 static void tic54x_space
PARAMS ((int));
244 static void tic54x_usect
PARAMS ((int));
245 static enum cpu_version lookup_version
PARAMS ((const char *));
246 static void set_cpu
PARAMS ((enum cpu_version
));
247 static void tic54x_version
PARAMS ((int));
248 static void tic54x_float_cons
PARAMS ((int));
249 static void tic54x_stringer
PARAMS ((int));
250 static void tic54x_p2align
PARAMS ((int));
251 static void tic54x_align_words
PARAMS ((int));
252 static void tic54x_field
PARAMS ((int));
253 static int tic54x_initialized_section
PARAMS ((segT
));
254 static void tic54x_clink
PARAMS ((int));
255 static void tic54x_set_default_include
PARAMS ((int));
256 static void tic54x_include
PARAMS ((int));
257 static void tic54x_message
PARAMS ((int));
258 static void tic54x_label
PARAMS ((int));
259 static void tic54x_mmregs
PARAMS ((int));
260 static void tic54x_loop
PARAMS ((int));
261 static void tic54x_endloop
PARAMS ((int));
262 static void tic54x_break
PARAMS ((int));
263 static void set_address_mode
PARAMS ((int));
264 static void tic54x_address_mode
PARAMS ((int));
265 static void tic54x_sblock
PARAMS ((int));
266 static void tic54x_set
PARAMS ((int));
267 static void tic54x_fclist
PARAMS ((int));
268 static void tic54x_sslist
PARAMS ((int));
269 static void tic54x_var
PARAMS ((int));
270 static void tic54x_mlib
PARAMS ((int));
271 static int subsym_symlen
PARAMS ((char *, char *));
272 static int subsym_symcmp
PARAMS ((char *, char *));
273 static int subsym_firstch
PARAMS ((char *, char *));
274 static int subsym_lastch
PARAMS ((char *, char *));
275 static int subsym_isdefed
PARAMS ((char *, char *));
276 static int subsym_ismember
PARAMS ((char *, char *));
277 static int subsym_iscons
PARAMS ((char *, char *));
278 static int subsym_isname
PARAMS ((char *, char *));
279 static int subsym_isreg
PARAMS ((char *, char *));
280 static int subsym_structsz
PARAMS ((char *, char *));
281 static int subsym_structacc
PARAMS ((char *, char *));
282 static float math_ceil
PARAMS ((float, float));
283 static float math_cvi
PARAMS ((float, float));
284 static float math_floor
PARAMS ((float, float));
285 static float math_fmod
PARAMS ((float, float));
286 static float math_int
PARAMS ((float, float));
287 static float math_round
PARAMS ((float, float));
288 static float math_sgn
PARAMS ((float, float));
289 static float math_trunc
PARAMS ((float, float));
290 static float math_acos
PARAMS ((float, float));
291 static float math_asin
PARAMS ((float, float));
292 static float math_atan
PARAMS ((float, float));
293 static float math_atan2
PARAMS ((float, float));
294 static float math_cosh
PARAMS ((float, float));
295 static float math_cos
PARAMS ((float, float));
296 static float math_cvf
PARAMS ((float, float));
297 static float math_exp
PARAMS ((float, float));
298 static float math_fabs
PARAMS ((float, float));
299 static float math_ldexp
PARAMS ((float, float));
300 static float math_log10
PARAMS ((float, float));
301 static float math_log
PARAMS ((float, float));
302 static float math_max
PARAMS ((float, float));
303 static float math_min
PARAMS ((float, float));
304 static float math_pow
PARAMS ((float, float));
305 static float math_sin
PARAMS ((float, float));
306 static float math_sinh
PARAMS ((float, float));
307 static float math_sqrt
PARAMS ((float, float));
308 static float math_tan
PARAMS ((float, float));
309 static float math_tanh
PARAMS ((float, float));
310 static int is_accumulator
PARAMS ((struct opstruct
*));
311 static int get_operands
PARAMS ((struct opstruct operands
[], char *));
312 static int is_immediate
PARAMS ((struct opstruct
*));
313 static int is_absolute
PARAMS ((struct opstruct
*));
314 static int is_indirect
PARAMS ((struct opstruct
*));
315 static int is_dual
PARAMS ((struct opstruct
*));
316 static int is_mmreg
PARAMS ((struct opstruct
*));
317 static int is_type
PARAMS ((struct opstruct
*, enum optype
));
318 static int operands_match
PARAMS ((tic54x_insn
*, struct opstruct
*, int, const enum optype
*, int, int));
319 static int encode_dmad
PARAMS ((tic54x_insn
*, struct opstruct
*, int));
320 static int encode_address
PARAMS ((tic54x_insn
*, struct opstruct
*));
321 static int encode_indirect
PARAMS ((tic54x_insn
*, struct opstruct
*));
322 static int encode_integer
PARAMS ((tic54x_insn
*, struct opstruct
*, int, int, int, unsigned short));
323 static int encode_condition
PARAMS ((tic54x_insn
*, struct opstruct
*));
324 static int encode_cc3
PARAMS ((tic54x_insn
*, struct opstruct
*));
325 static int encode_arx
PARAMS ((tic54x_insn
*, struct opstruct
*));
326 static int encode_cc2
PARAMS ((tic54x_insn
*, struct opstruct
*));
327 static int encode_operand
PARAMS ((tic54x_insn
*, enum optype
, struct opstruct
*));
328 static void emit_insn
PARAMS ((tic54x_insn
*));
329 static int build_insn
PARAMS ((tic54x_insn
*));
330 static int optimize_insn
PARAMS ((tic54x_insn
*));
331 static int tic54x_parse_insn
PARAMS ((tic54x_insn
*, char *));
332 static int next_line_shows_parallel
PARAMS ((char *));
333 static int tic54x_parse_parallel_insn_firstline
PARAMS ((tic54x_insn
*, char *));
334 static int tic54x_parse_parallel_insn_lastline
PARAMS ((tic54x_insn
*, char *));
335 static char * subsym_get_arg
PARAMS ((char *, char *, char **, int));
336 static void subsym_create_or_replace
PARAMS ((char *, char *));
337 static char * subsym_lookup
PARAMS ((char *, int));
338 static char * subsym_substitute
PARAMS ((char *, int));
342 md_show_usage (stream
)
345 fprintf (stream
, _("C54x-specific command line options:\n"));
346 fprintf (stream
, _("-mfar-mode | -mf Use extended addressing\n"));
347 fprintf (stream
, _("-mcpu=<CPU version> Specify the CPU version\n"));
348 fprintf (stream
, _("-merrors-to-file <filename>\n"));
349 fprintf (stream
, _("-me <filename> Redirect errors to a file\n"));
352 /* Output a single character (upper octect is zero). */
360 exp
.X_op
= O_constant
;
361 exp
.X_add_number
= c
;
365 /* Walk backwards in the frag chain. */
368 frag_prev (frag
, seg
)
372 segment_info_type
*seginfo
= seg_info (seg
);
375 for (fragp
= seginfo
->frchainP
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
376 if (fragp
->fr_next
== frag
)
383 bit_offset_frag (frag
, seg
)
389 if (frag
->fr_fix
== 0
390 && frag
->fr_opcode
== NULL
391 && frag
->tc_frag_data
== 0)
392 frag
= frag_prev (frag
, seg
);
399 /* Return the number of bits allocated in the most recent word, or zero if
400 none. .field/.space/.bes may leave words partially allocated. */
403 frag_bit_offset (frag
, seg
)
407 frag
= bit_offset_frag (frag
, seg
);
410 return frag
->fr_opcode
!= NULL
? -1 : frag
->tc_frag_data
;
415 /* Read an expression from a C string; returns a pointer past the end of the
419 parse_expression (str
, exp
)
426 tmp
= input_line_pointer
; /* Save line pointer. */
427 input_line_pointer
= str
;
429 s
= input_line_pointer
;
430 input_line_pointer
= tmp
; /* Restore line pointer. */
431 return s
; /* Return pointer to where parsing stopped. */
434 /* .asg "character-string"|character-string, symbol
436 .eval is the only pseudo-op allowed to perform arithmetic on substitution
437 symbols. all other use of symbols defined with .asg are currently
442 int x ATTRIBUTE_UNUSED
;
448 int quoted
= *input_line_pointer
== '"';
450 ILLEGAL_WITHIN_STRUCT ();
455 str
= demand_copy_C_string (&len
);
456 c
= *input_line_pointer
;
460 str
= input_line_pointer
;
461 while ((c
= *input_line_pointer
) != ',')
463 if (is_end_of_line
[(int) *input_line_pointer
])
465 ++input_line_pointer
;
467 *input_line_pointer
= 0;
471 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
472 ignore_rest_of_line ();
476 name
= ++input_line_pointer
;
477 c
= get_symbol_end (); /* Get terminator. */
478 if (!ISALPHA (*name
))
480 as_bad ("symbols assigned with .asg must begin with a letter");
481 ignore_rest_of_line ();
485 tmp
= xmalloc (strlen (str
) + 1);
488 tmp
= xmalloc (strlen (name
) + 1);
491 subsym_create_or_replace (name
, str
);
492 *input_line_pointer
= c
;
493 demand_empty_rest_of_line ();
496 /* .eval expression, symbol
497 There's something screwy about this. The other assembler sometimes does and
498 sometimes doesn't substitute symbols defined with .eval.
499 We'll put the symbols into the subsym table as well as the normal symbol
500 table, since that's what works best. */
504 int x ATTRIBUTE_UNUSED
;
510 char valuestr
[32], *tmp
;
513 ILLEGAL_WITHIN_STRUCT ();
517 quoted
= *input_line_pointer
== '"';
519 ++input_line_pointer
;
520 value
= get_absolute_expression ();
523 if (*input_line_pointer
!= '"')
525 as_bad (_("Unterminated string after absolute expression"));
526 ignore_rest_of_line ();
529 ++input_line_pointer
;
531 if (*input_line_pointer
++ != ',')
533 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
534 ignore_rest_of_line ();
537 name
= input_line_pointer
;
538 c
= get_symbol_end (); /* Get terminator. */
539 tmp
= xmalloc (strlen (name
) + 1);
540 name
= strcpy (tmp
, name
);
541 *input_line_pointer
= c
;
543 if (!ISALPHA (*name
))
545 as_bad (_("symbols assigned with .eval must begin with a letter"));
546 ignore_rest_of_line ();
549 symbolP
= symbol_new (name
, absolute_section
,
550 (valueT
) value
, &zero_address_frag
);
551 SF_SET_LOCAL (symbolP
);
552 symbol_table_insert (symbolP
);
554 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
555 But since there's not written rule as to when, don't even bother trying
556 to match their behavior. */
557 sprintf (valuestr
, "%d", value
);
558 tmp
= xmalloc (strlen (valuestr
) + 1);
559 strcpy (tmp
, valuestr
);
560 subsym_create_or_replace (name
, tmp
);
562 demand_empty_rest_of_line ();
565 /* .bss symbol, size [, [blocking flag] [, alignment flag]
567 alignment is to a longword boundary; blocking is to 128-word boundary.
569 1) if there is a hole in memory, this directive should attempt to fill it
570 (not yet implemented).
572 2) if the blocking flag is not set, allocate at the current SPC
573 otherwise, check to see if the current SPC plus the space to be
574 allocated crosses the page boundary (128 words).
575 if there's not enough space, create a hole and align with the next page
577 (not yet implemented). */
581 int x ATTRIBUTE_UNUSED
;
588 subsegT current_subseg
;
593 ILLEGAL_WITHIN_STRUCT ();
595 current_seg
= now_seg
; /* Save current seg. */
596 current_subseg
= now_subseg
; /* Save current subseg. */
598 name
= input_line_pointer
;
599 c
= get_symbol_end (); /* Get terminator. */
602 as_bad (".bss size argument missing\n");
603 ignore_rest_of_line ();
607 ++input_line_pointer
;
608 words
= get_absolute_expression ();
611 as_bad (".bss size %d < 0!", words
);
612 ignore_rest_of_line ();
616 if (*input_line_pointer
== ',')
618 /* The blocking flag may be missing. */
619 ++input_line_pointer
;
620 if (*input_line_pointer
!= ',')
621 block
= get_absolute_expression ();
625 if (*input_line_pointer
== ',')
627 ++input_line_pointer
;
628 align
= get_absolute_expression ();
636 subseg_set (bss_section
, 0);
637 symbolP
= symbol_find_or_make (name
);
639 if (S_GET_SEGMENT (symbolP
) == bss_section
)
640 symbolP
->sy_frag
->fr_symbol
= (symbolS
*) NULL
;
642 symbol_set_frag (symbolP
, frag_now
);
643 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
644 (offsetT
) (words
* OCTETS_PER_BYTE
), (char *) 0);
645 *p
= 0; /* Fill char. */
647 S_SET_SEGMENT (symbolP
, bss_section
);
649 /* The symbol may already have been created with a preceding
650 ".globl" directive -- be careful not to step on storage class
651 in that case. Otherwise, set it to static. */
652 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
653 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
657 /* s_align eats end of line; restore it */
659 --input_line_pointer
;
663 bss_section
->flags
|= SEC_TIC54X_BLOCK
;
665 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
666 demand_empty_rest_of_line ();
670 stag_add_field_symbols (stag
, path
, base_offset
, rootsym
, root_stag_name
)
675 const char *root_stag_name
;
677 char prefix
[strlen (path
) + 2];
678 struct stag_field
*field
= stag
->field
;
680 /* Construct a symbol for every field contained within this structure
681 including fields within structure fields. */
682 strcpy (prefix
, path
);
684 strcat (prefix
, ".");
686 while (field
!= NULL
)
688 int len
= strlen (prefix
) + strlen (field
->name
) + 2;
689 char *name
= xmalloc (len
);
690 strcpy (name
, prefix
);
691 strcat (name
, field
->name
);
696 sym
= symbol_new (name
, absolute_section
,
697 (field
->stag
? field
->offset
:
698 (valueT
) (base_offset
+ field
->offset
)),
701 symbol_table_insert (sym
);
705 char *replacement
= xmalloc (strlen (name
)
706 + strlen (stag
->name
) + 2);
707 strcpy (replacement
, S_GET_NAME (rootsym
));
708 strcat (replacement
, "+");
709 strcat (replacement
, root_stag_name
);
710 strcat (replacement
, name
+ strlen (S_GET_NAME (rootsym
)));
711 hash_insert (subsym_hash
[0], name
, replacement
);
714 /* Recurse if the field is a structure.
715 Note the field offset is relative to the outermost struct. */
716 if (field
->stag
!= NULL
)
717 stag_add_field_symbols (field
->stag
, name
,
719 rootsym
, root_stag_name
);
724 /* Keep track of stag fields so that when structures are nested we can add the
725 complete dereferencing symbols to the symbol table. */
728 stag_add_field (parent
, name
, offset
, stag
)
734 struct stag_field
*sfield
= xmalloc (sizeof (struct stag_field
));
736 memset (sfield
, 0, sizeof (*sfield
));
737 sfield
->name
= strcpy (xmalloc (strlen (name
) + 1), name
);
738 sfield
->offset
= offset
;
739 sfield
->bitfield_offset
= parent
->current_bitfield_offset
;
741 if (parent
->field
== NULL
)
742 parent
->field
= sfield
;
745 struct stag_field
*sf
= parent
->field
;
746 while (sf
->next
!= NULL
)
750 /* Only create a symbol for this field if the parent has no name. */
751 if (!strncmp (".fake", parent
->name
, 5))
753 symbolS
*sym
= symbol_new (name
, absolute_section
,
754 (valueT
) offset
, &zero_address_frag
);
756 symbol_table_insert (sym
);
760 /* [STAG] .struct [OFFSET]
761 Start defining structure offsets (symbols in absolute section). */
767 int start_offset
= 0;
772 /* Starting a new struct, switch to absolute section. */
773 stag_saved_seg
= now_seg
;
774 stag_saved_subseg
= now_subseg
;
775 subseg_set (absolute_section
, 0);
777 /* Align the current pointer. */
778 else if (current_stag
->current_bitfield_offset
!= 0)
780 ++abs_section_offset
;
781 current_stag
->current_bitfield_offset
= 0;
784 /* Offset expression is only meaningful for global .structs. */
787 /* Offset is ignored in inner structs. */
789 if (!is_end_of_line
[(int) *input_line_pointer
])
790 start_offset
= get_absolute_expression ();
797 /* Nesting, link to outer one. */
798 current_stag
->inner
= (struct stag
*) xmalloc (sizeof (struct stag
));
799 memset (current_stag
->inner
, 0, sizeof (struct stag
));
800 current_stag
->inner
->outer
= current_stag
;
801 current_stag
= current_stag
->inner
;
803 as_warn (_("Offset on nested structures is ignored"));
804 start_offset
= abs_section_offset
;
808 current_stag
= (struct stag
*) xmalloc (sizeof (struct stag
));
809 memset (current_stag
, 0, sizeof (struct stag
));
810 abs_section_offset
= start_offset
;
812 current_stag
->is_union
= is_union
;
814 if (line_label
== NULL
)
816 static int struct_count
= 0;
817 char fake
[] = ".fake_stagNNNNNNN";
818 sprintf (fake
, ".fake_stag%d", struct_count
++);
819 current_stag
->sym
= symbol_new (fake
, absolute_section
,
820 (valueT
) abs_section_offset
,
825 char label
[strlen (S_GET_NAME (line_label
)) + 1];
826 strcpy (label
, S_GET_NAME (line_label
));
827 current_stag
->sym
= symbol_new (label
, absolute_section
,
828 (valueT
) abs_section_offset
,
831 current_stag
->name
= S_GET_NAME (current_stag
->sym
);
832 SF_SET_LOCAL (current_stag
->sym
);
833 /* Nested .structs don't go into the symbol table. */
834 if (current_stag
->outer
== NULL
)
835 symbol_table_insert (current_stag
->sym
);
840 /* [LABEL] .endstruct
841 finish defining structure offsets; optional LABEL's value will be the size
845 tic54x_endstruct (is_union
)
850 !strncmp (current_stag
->name
, ".fake", 5) ? "" : current_stag
->name
;
852 if (!current_stag
|| current_stag
->is_union
!= is_union
)
854 as_bad (_(".end%s without preceding .%s"),
855 is_union
? "union" : "struct",
856 is_union
? "union" : "struct");
857 ignore_rest_of_line ();
861 /* Align end of structures. */
862 if (current_stag
->current_bitfield_offset
)
864 ++abs_section_offset
;
865 current_stag
->current_bitfield_offset
= 0;
868 if (current_stag
->is_union
)
869 size
= current_stag
->size
;
871 size
= abs_section_offset
- S_GET_VALUE (current_stag
->sym
);
872 if (line_label
!= NULL
)
874 S_SET_VALUE (line_label
, size
);
875 symbol_table_insert (line_label
);
879 /* Union size has already been calculated. */
880 if (!current_stag
->is_union
)
881 current_stag
->size
= size
;
882 /* Nested .structs don't get put in the stag table. */
883 if (current_stag
->outer
== NULL
)
885 hash_insert (stag_hash
, current_stag
->name
, current_stag
);
886 stag_add_field_symbols (current_stag
, path
,
887 S_GET_VALUE (current_stag
->sym
),
890 current_stag
= current_stag
->outer
;
892 /* If this is a nested .struct/.union, add it as a field to the enclosing
893 one. otherwise, restore the section we were in. */
894 if (current_stag
!= NULL
)
896 stag_add_field (current_stag
, current_stag
->inner
->name
,
897 S_GET_VALUE (current_stag
->inner
->sym
),
898 current_stag
->inner
);
901 subseg_set (stag_saved_seg
, stag_saved_subseg
);
905 Reference a structure within a structure, as a sized field with an optional
907 If used outside of a .struct/.endstruct, overlays the given structure
908 format on the existing allocated space. */
912 int ignore ATTRIBUTE_UNUSED
;
914 char *name
= input_line_pointer
;
915 int c
= get_symbol_end ();
916 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
921 as_bad (_("Unrecognized struct/union tag '%s'"), name
);
923 as_bad (_(".tag requires a structure tag"));
924 ignore_rest_of_line ();
927 if (line_label
== NULL
)
929 as_bad (_("Label required for .tag"));
930 ignore_rest_of_line ();
935 char label
[strlen (S_GET_NAME (line_label
)) + 1];
937 strcpy (label
, S_GET_NAME (line_label
));
938 if (current_stag
!= NULL
)
939 stag_add_field (current_stag
, label
,
940 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
944 symbolS
*sym
= symbol_find (label
);
948 as_bad (_(".tag target '%s' undefined"), label
);
949 ignore_rest_of_line ();
952 stag_add_field_symbols (stag
, S_GET_NAME (sym
),
953 S_GET_VALUE (stag
->sym
), sym
, stag
->name
);
957 /* Bump by the struct size, but only if we're within a .struct section. */
958 if (current_stag
!= NULL
&& !current_stag
->is_union
)
959 abs_section_offset
+= stag
->size
;
961 *input_line_pointer
= c
;
962 demand_empty_rest_of_line ();
966 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
967 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
971 tic54x_struct_field (type
)
976 int new_bitfield_offset
= 0;
977 int field_align
= current_stag
->current_bitfield_offset
!= 0;
978 int longword_align
= 0;
981 if (!is_end_of_line
[(int) *input_line_pointer
])
982 count
= get_absolute_expression ();
998 case '*': /* String. */
1007 case '.': /* Bitfield. */
1009 if (count
< 1 || count
> 32)
1011 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count
);
1012 ignore_rest_of_line ();
1015 if (current_stag
->current_bitfield_offset
+ count
> 16)
1017 /* Set the appropriate size and new field offset. */
1023 else if (count
> 16)
1027 new_bitfield_offset
= count
- 16;
1030 new_bitfield_offset
= count
;
1035 new_bitfield_offset
= current_stag
->current_bitfield_offset
+ count
;
1039 as_bad (_("Unrecognized field type '%c'"), type
);
1040 ignore_rest_of_line ();
1046 /* Align to the actual starting position of the field. */
1047 current_stag
->current_bitfield_offset
= 0;
1048 ++abs_section_offset
;
1050 /* Align to longword boundary. */
1051 if (longword_align
&& (abs_section_offset
& 0x1))
1052 ++abs_section_offset
;
1054 if (line_label
== NULL
)
1056 static int fieldno
= 0;
1057 char fake
[] = ".fake_fieldNNNNN";
1059 sprintf (fake
, ".fake_field%d", fieldno
++);
1060 stag_add_field (current_stag
, fake
,
1061 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
1066 char label
[strlen (S_GET_NAME (line_label
) + 1)];
1068 strcpy (label
, S_GET_NAME (line_label
));
1069 stag_add_field (current_stag
, label
,
1070 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
1074 if (current_stag
->is_union
)
1076 /* Note we treat the element as if it were an array of COUNT. */
1077 if (current_stag
->size
< (unsigned) size
* count
)
1078 current_stag
->size
= size
* count
;
1082 abs_section_offset
+= (unsigned) size
* count
;
1083 current_stag
->current_bitfield_offset
= new_bitfield_offset
;
1088 /* Handle .byte, .word. .int, .long and all variants. */
1097 /* If we're within a .struct construct, don't actually allocate space. */
1098 if (current_stag
!= NULL
)
1100 tic54x_struct_field (type
);
1104 #ifdef md_flush_pending_output
1105 md_flush_pending_output ();
1108 generate_lineno_debug ();
1110 /* Align long words to long word boundaries (4 octets). */
1111 if (type
== 'l' || type
== 'L')
1113 frag_align (2, 0, 2);
1114 /* If there's a label, assign it to the first allocated word. */
1115 if (line_label
!= NULL
)
1117 symbol_set_frag (line_label
, frag_now
);
1118 S_SET_VALUE (line_label
, frag_now_fix ());
1142 if (*input_line_pointer
== '"')
1144 input_line_pointer
++;
1145 while (is_a_char (c
= next_char_of_string ()))
1146 tic54x_emit_char (c
);
1147 know (input_line_pointer
[-1] == '\"');
1153 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1154 if (exp
.X_op
== O_constant
)
1156 offsetT value
= exp
.X_add_number
;
1157 /* Truncate overflows. */
1161 if ((value
> 0 && value
> 0xFF)
1162 || (value
< 0 && value
< - 0x100))
1163 as_warn ("Overflow in expression, truncated to 8 bits");
1166 if ((value
> 0 && value
> 0xFFFF)
1167 || (value
< 0 && value
< - 0x10000))
1168 as_warn ("Overflow in expression, truncated to 16 bits");
1172 if (exp
.X_op
!= O_constant
&& octets
< 2)
1174 /* Disallow .byte with a non constant expression that will
1175 require relocation. */
1176 as_bad (_("Relocatable values require at least WORD storage"));
1177 ignore_rest_of_line ();
1181 if (exp
.X_op
!= O_constant
1185 /* FIXME -- at one point TI tools used to output REL16
1186 relocations, but I don't think the latest tools do at all
1187 The current tools output extended relocations regardless of
1188 the addressing mode (I actually think that ".c_mode" is
1189 totally ignored in the latest tools). */
1192 emit_expr (&exp
, 4);
1198 emitting_long
= octets
== 4;
1199 emit_expr (&exp
, (octets
== 1) ? 2 : octets
);
1204 while (*input_line_pointer
++ == ',');
1206 input_line_pointer
--; /* Put terminator back into stream. */
1207 demand_empty_rest_of_line ();
1210 /* .global <symbol>[,...,<symbolN>]
1211 .def <symbol>[,...,<symbolN>]
1212 .ref <symbol>[,...,<symbolN>]
1214 These all identify global symbols.
1216 .def means the symbol is defined in the current module and can be accessed
1217 by other files. The symbol should be placed in the symbol table.
1219 .ref means the symbol is used in the current module but defined in another
1220 module. The linker is to resolve this symbol's definition at link time.
1222 .global should act as a .ref or .def, as needed.
1224 global, def and ref all have symbol storage classes of C_EXT.
1226 I can't identify any difference in how the "other" c54x assembler treats
1227 these, so we ignore the type here. */
1230 tic54x_global (type
)
1238 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1240 ILLEGAL_WITHIN_STRUCT ();
1244 name
= input_line_pointer
;
1245 c
= get_symbol_end ();
1246 symbolP
= symbol_find_or_make (name
);
1248 *input_line_pointer
= c
;
1249 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
1252 input_line_pointer
++;
1253 if (is_end_of_line
[(int) *input_line_pointer
])
1254 c
= *input_line_pointer
;
1259 demand_empty_rest_of_line ();
1262 /* Remove the symbol from the local label hash lookup. */
1265 tic54x_remove_local_label (key
, value
)
1267 PTR value ATTRIBUTE_UNUSED
;
1269 PTR
*elem
= hash_delete (local_label_hash
[macro_level
], key
);
1273 /* Reset all local labels. */
1276 tic54x_clear_local_labels (ignored
)
1277 int ignored ATTRIBUTE_UNUSED
;
1279 hash_traverse (local_label_hash
[macro_level
], tic54x_remove_local_label
);
1284 .sect "section name"
1287 make sure local labels get cleared when changing sections
1289 ARG is 't' for text, 'd' for data, or '*' for a named section
1291 For compatibility, '*' sections are SEC_CODE if instructions are
1292 encountered, or SEC_DATA if not.
1299 ILLEGAL_WITHIN_STRUCT ();
1301 /* Local labels are cleared when changing sections. */
1302 tic54x_clear_local_labels (0);
1306 else if (arg
== 'd')
1313 /* If there are quotes, remove them. */
1314 if (*input_line_pointer
== '"')
1316 name
= demand_copy_C_string (&len
);
1317 demand_empty_rest_of_line ();
1318 name
= strcpy (xmalloc (len
+ 10), name
);
1323 name
= input_line_pointer
;
1324 c
= get_symbol_end ();
1326 name
= strcpy (xmalloc (len
+ 10), name
);
1327 *input_line_pointer
= c
;
1328 demand_empty_rest_of_line ();
1330 /* Make sure all named initialized sections flagged properly. If we
1331 encounter instructions, we'll flag it with SEC_CODE as well. */
1332 strcat (name
, ",\"w\"\n");
1333 input_scrub_insert_line (name
);
1334 obj_coff_section (0);
1336 /* If there was a line label, make sure that it gets assigned the proper
1337 section. This is for compatibility, even though the actual behavior
1338 is not explicitly defined. For consistency, we make .sect behave
1339 like .usect, since that is probably what people expect. */
1340 if (line_label
!= NULL
)
1342 S_SET_SEGMENT (line_label
, now_seg
);
1343 symbol_set_frag (line_label
, frag_now
);
1344 S_SET_VALUE (line_label
, frag_now_fix ());
1345 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1346 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1351 /* [symbol] .space space_in_bits
1352 [symbol] .bes space_in_bits
1353 BES puts the symbol at the *last* word allocated
1355 cribbed from s_space. */
1365 int bits_per_byte
= (OCTETS_PER_BYTE
* 8);
1367 symbolS
*label
= line_label
;
1370 ILLEGAL_WITHIN_STRUCT ();
1372 #ifdef md_flush_pending_output
1373 md_flush_pending_output ();
1376 /* Read the bit count. */
1379 /* Some expressions are unresolvable until later in the assembly pass;
1380 postpone until relaxation/fixup. we also have to postpone if a previous
1381 partial allocation has not been completed yet. */
1382 if (exp
.X_op
!= O_constant
|| frag_bit_offset (frag_now
, now_seg
) == -1)
1384 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1390 p
= frag_var (rs_machine_dependent
,
1391 65536 * 2, 1, (relax_substateT
) 0,
1392 make_expr_symbol (&exp
), (offsetT
) 0,
1400 /* Reduce the required size by any bit offsets currently left over
1401 from a previous .space/.bes/.field directive. */
1402 bit_offset
= frag_now
->tc_frag_data
;
1403 if (bit_offset
!= 0 && bit_offset
< 16)
1405 int spare_bits
= bits_per_byte
- bit_offset
;
1407 if (spare_bits
>= exp
.X_add_number
)
1409 /* Don't have to do anything; sufficient bits have already been
1410 allocated; just point the label to the right place. */
1413 symbol_set_frag (label
, frag_now
);
1414 S_SET_VALUE (label
, frag_now_fix () - 1);
1417 frag_now
->tc_frag_data
+= exp
.X_add_number
;
1420 exp
.X_add_number
-= spare_bits
;
1421 /* Set the label to point to the first word allocated, which in this
1422 case is the previous word, which was only partially filled. */
1423 if (!bes
&& label
!= NULL
)
1425 symbol_set_frag (label
, frag_now
);
1426 S_SET_VALUE (label
, frag_now_fix () - 1);
1430 /* Convert bits to bytes/words and octets, rounding up. */
1431 words
= ((exp
.X_add_number
+ bits_per_byte
- 1) / bits_per_byte
);
1432 /* How many do we have left over? */
1433 bit_offset
= exp
.X_add_number
% bits_per_byte
;
1434 octets
= words
* OCTETS_PER_BYTE
;
1437 as_warn (_(".space/.bes repeat count is negative, ignored"));
1440 else if (octets
== 0)
1442 as_warn (_(".space/.bes repeat count is zero, ignored"));
1446 /* If we are in the absolute section, just bump the offset. */
1447 if (now_seg
== absolute_section
)
1449 abs_section_offset
+= words
;
1450 if (bes
&& label
!= NULL
)
1451 S_SET_VALUE (label
, abs_section_offset
- 1);
1452 frag_now
->tc_frag_data
= bit_offset
;
1457 p
= frag_var (rs_fill
, 1, 1,
1458 (relax_substateT
) 0, (symbolS
*) 0,
1459 (offsetT
) octets
, (char *) 0);
1461 /* Make note of how many bits of this word we've allocated so far. */
1462 frag_now
->tc_frag_data
= bit_offset
;
1464 /* .bes puts label at *last* word allocated. */
1465 if (bes
&& label
!= NULL
)
1467 symbol_set_frag (label
, frag_now
);
1468 S_SET_VALUE (label
, frag_now_fix () - 1);
1476 demand_empty_rest_of_line ();
1479 /* [symbol] .usect "section-name", size-in-words
1480 [, [blocking-flag] [, alignment-flag]]
1482 Uninitialized section.
1483 Non-zero blocking means that if the section would cross a page (128-word)
1484 boundary, it will be page-aligned.
1485 Non-zero alignment aligns on a longword boundary.
1487 Has no effect on the current section. */
1491 int x ATTRIBUTE_UNUSED
;
1498 int size
, blocking_flag
, alignment_flag
;
1500 subsegT current_subseg
;
1503 ILLEGAL_WITHIN_STRUCT ();
1505 current_seg
= now_seg
; /* Save current seg. */
1506 current_subseg
= now_subseg
; /* Save current subseg. */
1508 if (*input_line_pointer
== '"')
1509 input_line_pointer
++;
1510 section_name
= input_line_pointer
;
1511 c
= get_symbol_end (); /* Get terminator. */
1512 input_line_pointer
++; /* Skip null symbol terminator. */
1513 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1514 strcpy (name
, section_name
);
1516 if (*input_line_pointer
== ',')
1517 ++input_line_pointer
;
1520 as_bad (_("Missing size argument"));
1521 ignore_rest_of_line ();
1525 size
= get_absolute_expression ();
1527 /* Read a possibly present third argument (blocking flag). */
1528 if (*input_line_pointer
== ',')
1530 ++input_line_pointer
;
1531 if (*input_line_pointer
!= ',')
1532 blocking_flag
= get_absolute_expression ();
1536 /* Read a possibly present fourth argument (alignment flag). */
1537 if (*input_line_pointer
== ',')
1539 ++input_line_pointer
;
1540 alignment_flag
= get_absolute_expression ();
1546 blocking_flag
= alignment_flag
= 0;
1548 seg
= subseg_new (name
, 0);
1549 flags
= bfd_get_section_flags (stdoutput
, seg
) | SEC_ALLOC
;
1553 /* s_align eats end of line; restore it. */
1555 --input_line_pointer
;
1558 if (line_label
!= NULL
)
1560 S_SET_SEGMENT (line_label
, seg
);
1561 symbol_set_frag (line_label
, frag_now
);
1562 S_SET_VALUE (line_label
, frag_now_fix ());
1563 /* Set scl to label, since that's what TI does. */
1564 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1565 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1568 seg_info (seg
)->bss
= 1; /* Uninitialized data. */
1570 p
= frag_var (rs_fill
, 1, 1,
1571 (relax_substateT
) 0, (symbolS
*) line_label
,
1572 size
* OCTETS_PER_BYTE
, (char *) 0);
1576 flags
|= SEC_TIC54X_BLOCK
;
1578 if (!bfd_set_section_flags (stdoutput
, seg
, flags
))
1579 as_warn ("Error setting flags for \"%s\": %s", name
,
1580 bfd_errmsg (bfd_get_error ()));
1582 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1583 demand_empty_rest_of_line ();
1586 static enum cpu_version
1587 lookup_version (ver
)
1590 enum cpu_version version
= VNONE
;
1592 if (ver
[0] == '5' && ver
[1] == '4')
1594 if (strlen (ver
) == 3
1595 && (ver
[2] == '1' || ver
[2] == '2' || ver
[2] == '3'
1596 || ver
[2] == '5' || ver
[2] == '8' || ver
[2] == '9'))
1597 version
= ver
[2] - '0';
1598 else if (strlen (ver
) == 5
1599 && TOUPPER (ver
[3]) == 'L'
1600 && TOUPPER (ver
[4]) == 'P'
1601 && (ver
[2] == '5' || ver
[2] == '6'))
1602 version
= ver
[2] - '0' + 10;
1610 enum cpu_version version
;
1613 if (version
== V545LP
|| version
== V546LP
)
1615 symbolS
*symbolP
= symbol_new ("__allow_lp", absolute_section
,
1616 (valueT
) 1, &zero_address_frag
);
1617 SF_SET_LOCAL (symbolP
);
1618 symbol_table_insert (symbolP
);
1622 /* .version cpu-version
1623 cpu-version may be one of the following:
1633 This is for compatibility only. It currently has no affect on assembly. */
1634 static int cpu_needs_set
= 1;
1638 int x ATTRIBUTE_UNUSED
;
1640 enum cpu_version version
= VNONE
;
1641 enum cpu_version old_version
= cpu
;
1645 ILLEGAL_WITHIN_STRUCT ();
1648 ver
= input_line_pointer
;
1649 while (!is_end_of_line
[(int) *input_line_pointer
])
1650 ++input_line_pointer
;
1651 c
= *input_line_pointer
;
1652 *input_line_pointer
= 0;
1654 version
= lookup_version (ver
);
1656 if (cpu
!= VNONE
&& cpu
!= version
)
1657 as_warn (_("CPU version has already been set"));
1659 if (version
== VNONE
)
1661 as_bad (_("Unrecognized version '%s'"), ver
);
1662 ignore_rest_of_line ();
1665 else if (assembly_begun
&& version
!= old_version
)
1667 as_bad (_("Changing of CPU version on the fly not supported"));
1668 ignore_rest_of_line ();
1674 *input_line_pointer
= c
;
1675 demand_empty_rest_of_line ();
1678 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1681 tic54x_float_cons (type
)
1684 if (current_stag
!= 0)
1685 tic54x_struct_field ('f');
1687 #ifdef md_flush_pending_output
1688 md_flush_pending_output ();
1691 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1694 frag_align (2, 0, 2);
1695 /* If there's a label, assign it to the first allocated word. */
1696 if (line_label
!= NULL
)
1698 symbol_set_frag (line_label
, frag_now
);
1699 S_SET_VALUE (line_label
, frag_now_fix ());
1706 /* The argument is capitalized if it should be zero-terminated
1707 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1708 Code copied from stringer, and slightly modified so that strings are packed
1709 and encoded into the correct octets. */
1712 tic54x_stringer (type
)
1717 int append_zero
= type
== 'S' || type
== 'P';
1718 int packed
= type
== 'p' || type
== 'P';
1719 int last_char
= -1; /* Packed strings need two bytes at a time to encode. */
1721 if (current_stag
!= NULL
)
1723 tic54x_struct_field ('*');
1727 #ifdef md_flush_pending_output
1728 md_flush_pending_output ();
1731 c
= ','; /* Do loop. */
1735 switch (*input_line_pointer
)
1739 unsigned short value
= get_absolute_expression ();
1740 FRAG_APPEND_1_CHAR ( value
& 0xFF);
1741 FRAG_APPEND_1_CHAR ((value
>> 8) & 0xFF);
1745 ++input_line_pointer
; /* -> 1st char of string. */
1746 start
= input_line_pointer
;
1747 while (is_a_char (c
= next_char_of_string ()))
1751 FRAG_APPEND_1_CHAR (c
);
1752 FRAG_APPEND_1_CHAR (0);
1756 /* Packed strings are filled MS octet first. */
1757 if (last_char
== -1)
1761 FRAG_APPEND_1_CHAR (c
);
1762 FRAG_APPEND_1_CHAR (last_char
);
1769 if (packed
&& last_char
!= -1)
1771 FRAG_APPEND_1_CHAR (0);
1772 FRAG_APPEND_1_CHAR (last_char
);
1777 FRAG_APPEND_1_CHAR (0);
1778 FRAG_APPEND_1_CHAR (0);
1781 know (input_line_pointer
[-1] == '\"');
1785 c
= *input_line_pointer
;
1786 if (!is_end_of_line
[c
])
1787 ++input_line_pointer
;
1790 /* Finish up any leftover packed string. */
1791 if (packed
&& last_char
!= -1)
1793 FRAG_APPEND_1_CHAR (0);
1794 FRAG_APPEND_1_CHAR (last_char
);
1796 demand_empty_rest_of_line ();
1800 tic54x_p2align (arg
)
1801 int arg ATTRIBUTE_UNUSED
;
1803 as_bad (_("p2align not supported on this target"));
1807 tic54x_align_words (arg
)
1810 /* Only ".align" with no argument is allowed within .struct/.union. */
1813 if (!is_end_of_line
[(int) *input_line_pointer
])
1816 as_warn (_("Argument to .even ignored"));
1818 count
= get_absolute_expression ();
1821 if (current_stag
!= NULL
&& arg
== 128)
1823 if (current_stag
->current_bitfield_offset
!= 0)
1825 current_stag
->current_bitfield_offset
= 0;
1826 ++abs_section_offset
;
1828 demand_empty_rest_of_line ();
1832 ILLEGAL_WITHIN_STRUCT ();
1834 s_align_bytes (count
<< 1);
1837 /* Initialize multiple-bit fields withing a single word of memory. */
1840 tic54x_field (ignore
)
1841 int ignore ATTRIBUTE_UNUSED
;
1847 symbolS
*label
= line_label
;
1849 if (current_stag
!= NULL
)
1851 tic54x_struct_field ('.');
1855 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1857 if (*input_line_pointer
== ',')
1859 ++input_line_pointer
;
1860 size
= get_absolute_expression ();
1861 if (size
< 1 || size
> 32)
1863 as_bad (_("Invalid field size, must be from 1 to 32"));
1864 ignore_rest_of_line ();
1869 /* Truncate values to the field width. */
1870 if (exp
.X_op
!= O_constant
)
1872 /* If the expression value is relocatable, the field size *must*
1876 as_bad (_("field size must be 16 when value is relocatable"));
1877 ignore_rest_of_line ();
1881 frag_now
->tc_frag_data
= 0;
1882 emit_expr (&exp
, 2);
1886 unsigned long fmask
= (size
== 32) ? 0xFFFFFFFF : (1ul << size
) - 1;
1888 value
= exp
.X_add_number
;
1889 exp
.X_add_number
&= fmask
;
1890 if (value
!= (valueT
) exp
.X_add_number
)
1891 as_warn (_("field value truncated"));
1892 value
= exp
.X_add_number
;
1893 /* Bits are stored MS first. */
1896 frag_now
->tc_frag_data
= 0;
1898 md_number_to_chars (p
, (value
>> (size
- 16)) & 0xFFFF, 2);
1903 int bit_offset
= frag_bit_offset (frag_now
, now_seg
);
1905 fragS
*alloc_frag
= bit_offset_frag (frag_now
, now_seg
);
1906 if (bit_offset
== -1)
1908 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1909 /* We don't know the previous offset at this time, so store the
1910 info we need and figure it out later. */
1911 expressionS size_exp
;
1913 size_exp
.X_op
= O_constant
;
1914 size_exp
.X_add_number
= size
;
1916 bi
->type
= TYPE_FIELD
;
1918 p
= frag_var (rs_machine_dependent
,
1919 4, 1, (relax_substateT
) 0,
1920 make_expr_symbol (&size_exp
), (offsetT
) 0,
1924 else if (bit_offset
== 0 || bit_offset
+ size
> 16)
1926 /* Align a new field. */
1928 frag_now
->tc_frag_data
= 0;
1929 alloc_frag
= frag_now
;
1933 /* Put the new value entirely within the existing one. */
1934 p
= alloc_frag
== frag_now
?
1935 frag_now
->fr_literal
+ frag_now_fix_octets () - 2 :
1936 alloc_frag
->fr_literal
;
1939 symbol_set_frag (label
, alloc_frag
);
1940 if (alloc_frag
== frag_now
)
1941 S_SET_VALUE (label
, frag_now_fix () - 1);
1945 value
<<= 16 - alloc_frag
->tc_frag_data
- size
;
1947 /* OR in existing value. */
1948 if (alloc_frag
->tc_frag_data
)
1949 value
|= ((unsigned short) p
[1] << 8) | p
[0];
1950 md_number_to_chars (p
, value
, 2);
1951 alloc_frag
->tc_frag_data
+= size
;
1952 if (alloc_frag
->tc_frag_data
== 16)
1953 alloc_frag
->tc_frag_data
= 0;
1957 demand_empty_rest_of_line ();
1960 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1961 available yet. seg_info ()->bss is the next best thing. */
1964 tic54x_initialized_section (seg
)
1967 return !seg_info (seg
)->bss
;
1970 /* .clink ["section name"]
1972 Marks the section as conditionally linked (link only if contents are
1973 referenced elsewhere.
1974 Without a name, refers to the current initialized section.
1975 Name is required for uninitialized sections. */
1978 tic54x_clink (ignored
)
1979 int ignored ATTRIBUTE_UNUSED
;
1983 ILLEGAL_WITHIN_STRUCT ();
1985 if (*input_line_pointer
== '\"')
1987 char *section_name
= ++input_line_pointer
;
1990 while (is_a_char (next_char_of_string ()))
1992 know (input_line_pointer
[-1] == '\"');
1993 input_line_pointer
[-1] = 0;
1994 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1995 strcpy (name
, section_name
);
1997 seg
= bfd_get_section_by_name (stdoutput
, name
);
2000 as_bad (_("Unrecognized section '%s'"), section_name
);
2001 ignore_rest_of_line ();
2007 if (!tic54x_initialized_section (seg
))
2009 as_bad (_("Current section is unitialized, "
2010 "section name required for .clink"));
2011 ignore_rest_of_line ();
2016 seg
->flags
|= SEC_TIC54X_CLINK
;
2018 demand_empty_rest_of_line ();
2021 /* Change the default include directory to be the current source file's
2022 directory, instead of the current working directory. If DOT is non-zero,
2023 set to "." instead. */
2026 tic54x_set_default_include (dot
)
2037 as_where (&curfile
, &lineno
);
2038 dir
= strcpy (xmalloc (strlen (curfile
) + 1), curfile
);
2039 tmp
= strrchr (dir
, '/');
2047 if (include_dir_count
== 0)
2049 include_dirs
= (char **) xmalloc (sizeof (*include_dirs
));
2050 include_dir_count
= 1;
2052 include_dirs
[0] = dir
;
2053 if (len
> include_dir_maxlen
)
2054 include_dir_maxlen
= len
;
2056 else if (include_dirs
!= NULL
)
2057 include_dirs
[0] = ".";
2060 /* .include "filename" | filename
2061 .copy "filename" | filename
2063 FIXME 'include' file should be omitted from any output listing,
2064 'copy' should be included in any output listing
2065 FIXME -- prevent any included files from changing listing (compat only)
2066 FIXME -- need to include source file directory in search path; what's a
2067 good way to do this?
2069 Entering/exiting included/copied file clears all local labels. */
2072 tic54x_include (ignored
)
2073 int ignored ATTRIBUTE_UNUSED
;
2075 char newblock
[] = " .newblock\n";
2080 ILLEGAL_WITHIN_STRUCT ();
2084 if (*input_line_pointer
== '"')
2086 filename
= demand_copy_C_string (&len
);
2087 demand_empty_rest_of_line ();
2091 filename
= input_line_pointer
;
2092 while (!is_end_of_line
[(int) *input_line_pointer
])
2093 ++input_line_pointer
;
2094 c
= *input_line_pointer
;
2095 *input_line_pointer
= '\0';
2096 filename
= strcpy (xmalloc (strlen (filename
) + 1), filename
);
2097 *input_line_pointer
= c
;
2098 demand_empty_rest_of_line ();
2100 /* Insert a partial line with the filename (for the sake of s_include)
2102 The included file will be inserted before the newblock, so that the
2103 newblock is executed after the included file is processed. */
2104 input
= xmalloc (sizeof (newblock
) + strlen (filename
) + 4);
2105 sprintf (input
, "\"%s\"\n%s", filename
, newblock
);
2106 input_scrub_insert_line (input
);
2108 tic54x_clear_local_labels (0);
2110 tic54x_set_default_include (0);
2116 tic54x_message (type
)
2123 ILLEGAL_WITHIN_STRUCT ();
2125 if (*input_line_pointer
== '"')
2126 msg
= demand_copy_C_string (&len
);
2129 msg
= input_line_pointer
;
2130 while (!is_end_of_line
[(int) *input_line_pointer
])
2131 ++input_line_pointer
;
2132 c
= *input_line_pointer
;
2133 *input_line_pointer
= 0;
2134 msg
= strcpy (xmalloc (strlen (msg
) + 1), msg
);
2135 *input_line_pointer
= c
;
2141 as_tsktsk ("%s", msg
);
2144 as_warn ("%s", msg
);
2151 demand_empty_rest_of_line ();
2155 Define a special symbol that refers to the loadtime address rather than the
2156 runtime address within the current section.
2158 This symbol gets a special storage class so that when it is resolved, it is
2159 resolved relative to the load address (lma) of the section rather than the
2160 run address (vma). */
2163 tic54x_label (ignored
)
2164 int ignored ATTRIBUTE_UNUSED
;
2166 char *name
= input_line_pointer
;
2170 ILLEGAL_WITHIN_STRUCT ();
2172 c
= get_symbol_end ();
2173 symbolP
= colon (name
);
2174 S_SET_STORAGE_CLASS (symbolP
, C_STATLAB
);
2176 *input_line_pointer
= c
;
2177 demand_empty_rest_of_line ();
2181 Install all memory-mapped register names into the symbol table as
2182 absolute local symbols. */
2185 tic54x_mmregs (ignored
)
2186 int ignored ATTRIBUTE_UNUSED
;
2190 ILLEGAL_WITHIN_STRUCT ();
2192 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
2194 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
2195 (valueT
) sym
->value
, &zero_address_frag
);
2196 SF_SET_LOCAL (symbolP
);
2197 symbol_table_insert (symbolP
);
2202 Count defaults to 1024. */
2208 ILLEGAL_WITHIN_STRUCT ();
2211 if (!is_end_of_line
[(int) *input_line_pointer
])
2212 count
= get_absolute_expression ();
2214 do_repeat (count
, "LOOP", "ENDLOOP");
2217 /* Normally, endloop gets eaten by the preceding loop. */
2220 tic54x_endloop (ignore
)
2221 int ignore ATTRIBUTE_UNUSED
;
2223 as_bad (_("ENDLOOP without corresponding LOOP"));
2224 ignore_rest_of_line ();
2227 /* .break [condition]. */
2230 tic54x_break (ignore
)
2231 int ignore ATTRIBUTE_UNUSED
;
2235 ILLEGAL_WITHIN_STRUCT ();
2238 if (!is_end_of_line
[(int) *input_line_pointer
])
2239 cond
= get_absolute_expression ();
2242 end_repeat (substitution_line
? 1 : 0);
2246 set_address_mode (mode
)
2250 if (mode
== far_mode
)
2252 symbolS
*symbolP
= symbol_new ("__allow_far", absolute_section
,
2253 (valueT
) 1, &zero_address_frag
);
2254 SF_SET_LOCAL (symbolP
);
2255 symbol_table_insert (symbolP
);
2259 static int address_mode_needs_set
= 1;
2262 tic54x_address_mode (mode
)
2265 if (assembly_begun
&& amode
!= (unsigned) mode
)
2267 as_bad (_("Mixing of normal and extended addressing not supported"));
2268 ignore_rest_of_line ();
2271 if (mode
== far_mode
&& cpu
!= VNONE
&& cpu
!= V548
&& cpu
!= V549
)
2273 as_bad (_("Extended addressing not supported on the specified CPU"));
2274 ignore_rest_of_line ();
2278 set_address_mode (mode
);
2279 demand_empty_rest_of_line ();
2282 /* .sblock "section"|section [,...,"section"|section]
2283 Designate initialized sections for blocking. */
2286 tic54x_sblock (ignore
)
2287 int ignore ATTRIBUTE_UNUSED
;
2291 ILLEGAL_WITHIN_STRUCT ();
2298 if (*input_line_pointer
== '"')
2302 name
= demand_copy_C_string (&len
);
2306 char *section_name
= input_line_pointer
;
2308 c
= get_symbol_end ();
2309 name
= xmalloc (strlen (section_name
) + 1);
2310 strcpy (name
, section_name
);
2311 *input_line_pointer
= c
;
2314 seg
= bfd_get_section_by_name (stdoutput
, name
);
2317 as_bad (_("Unrecognized section '%s'"), name
);
2318 ignore_rest_of_line ();
2321 else if (!tic54x_initialized_section (seg
))
2323 as_bad (_(".sblock may be used for initialized sections only"));
2324 ignore_rest_of_line ();
2327 seg
->flags
|= SEC_TIC54X_BLOCK
;
2329 c
= *input_line_pointer
;
2330 if (!is_end_of_line
[(int) c
])
2331 ++input_line_pointer
;
2334 demand_empty_rest_of_line ();
2337 /* symbol .set value
2340 value must be defined externals; no forward-referencing allowed
2341 symbols assigned with .set/.equ may not be redefined. */
2345 int ignore ATTRIBUTE_UNUSED
;
2350 ILLEGAL_WITHIN_STRUCT ();
2354 as_bad (_("Symbol missing for .set/.equ"));
2355 ignore_rest_of_line ();
2358 name
= xstrdup (S_GET_NAME (line_label
));
2360 if ((symbolP
= symbol_find (name
)) == NULL
2361 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2363 symbolP
= symbol_new (name
, absolute_section
, 0, &zero_address_frag
);
2364 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2367 S_SET_DATA_TYPE (symbolP
, T_INT
);
2368 S_SET_SEGMENT (symbolP
, absolute_section
);
2369 symbol_table_insert (symbolP
);
2370 pseudo_set (symbolP
);
2371 demand_empty_rest_of_line ();
2376 List false conditional blocks. */
2379 tic54x_fclist (show
)
2383 listing
&= ~LISTING_NOCOND
;
2385 listing
|= LISTING_NOCOND
;
2386 demand_empty_rest_of_line ();
2390 tic54x_sslist (show
)
2393 ILLEGAL_WITHIN_STRUCT ();
2395 listing_sslist
= show
;
2398 /* .var SYM[,...,SYMN]
2399 Define a substitution string to be local to a macro. */
2403 int ignore ATTRIBUTE_UNUSED
;
2405 static char empty
[] = "";
2409 ILLEGAL_WITHIN_STRUCT ();
2411 if (macro_level
== 0)
2413 as_bad (_(".var may only be used within a macro definition"));
2414 ignore_rest_of_line ();
2419 if (!ISALPHA (*input_line_pointer
))
2421 as_bad (_("Substitution symbols must begin with a letter"));
2422 ignore_rest_of_line ();
2425 name
= input_line_pointer
;
2426 c
= get_symbol_end ();
2427 /* .var symbols start out with a null string. */
2428 name
= strcpy (xmalloc (strlen (name
) + 1), name
);
2429 hash_insert (subsym_hash
[macro_level
], name
, empty
);
2430 *input_line_pointer
= c
;
2433 ++input_line_pointer
;
2434 if (is_end_of_line
[(int) *input_line_pointer
])
2435 c
= *input_line_pointer
;
2440 demand_empty_rest_of_line ();
2443 /* .mlib <macro library filename>
2445 Macro libraries are archived (standard AR-format) text macro definitions
2446 Expand the file and include it.
2448 FIXME need to try the source file directory as well. */
2451 tic54x_mlib (ignore
)
2452 int ignore ATTRIBUTE_UNUSED
;
2459 ILLEGAL_WITHIN_STRUCT ();
2461 /* Parse the filename. */
2462 if (*input_line_pointer
== '"')
2464 if ((filename
= demand_copy_C_string (&len
)) == NULL
)
2471 while (!is_end_of_line
[(int) *input_line_pointer
]
2472 && !ISSPACE (*input_line_pointer
))
2474 obstack_1grow (¬es
, *input_line_pointer
);
2475 ++input_line_pointer
;
2478 obstack_1grow (¬es
, '\0');
2479 filename
= obstack_finish (¬es
);
2481 demand_empty_rest_of_line ();
2483 tic54x_set_default_include (0);
2484 path
= xmalloc ((unsigned long) len
+ include_dir_maxlen
+ 5);
2486 for (i
= 0; i
< include_dir_count
; i
++)
2490 strcpy (path
, include_dirs
[i
]);
2492 strcat (path
, filename
);
2493 if ((try = fopen (path
, "r")) != NULL
)
2500 if (i
>= include_dir_count
)
2506 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2507 happens all over the place, and since the assembler doesn't usually keep
2508 running for a very long time, it really doesn't matter. */
2509 register_dependency (path
);
2511 /* Expand all archive entries to temporary files and include them. */
2512 abfd
= bfd_openr (path
, NULL
);
2515 as_bad (_("can't open macro library file '%s' for reading: %s"),
2516 path
, bfd_errmsg (bfd_get_error ()));
2517 ignore_rest_of_line ();
2520 if (!bfd_check_format (abfd
, bfd_archive
))
2522 as_bad (_("File '%s' not in macro archive format"), path
);
2523 ignore_rest_of_line ();
2527 /* Open each BFD as binary (it should be straight ASCII text). */
2528 for (mbfd
= bfd_openr_next_archived_file (abfd
, NULL
);
2529 mbfd
!= NULL
; mbfd
= bfd_openr_next_archived_file (abfd
, mbfd
))
2531 /* Get a size at least as big as the archive member. */
2532 bfd_size_type size
= bfd_get_size (mbfd
);
2533 char *buf
= xmalloc (size
);
2534 char *fname
= tmpnam (NULL
);
2537 /* We're not sure how big it is, but it will be smaller than "size". */
2538 bfd_bread (buf
, size
, mbfd
);
2540 /* Write to a temporary file, then use s_include to include it
2542 ftmp
= fopen (fname
, "w+b");
2543 fwrite ((void *) buf
, size
, 1, ftmp
);
2544 if (buf
[size
- 1] != '\n')
2545 fwrite ("\n", 1, 1, ftmp
);
2548 input_scrub_insert_file (fname
);
2553 const pseudo_typeS md_pseudo_table
[] =
2555 { "algebraic", s_ignore
, 0 },
2556 { "align" , tic54x_align_words
, 128 },
2557 { "ascii" , tic54x_stringer
, 'p' },
2558 { "asciz" , tic54x_stringer
, 'P' },
2559 { "even" , tic54x_align_words
, 2 },
2560 { "asg" , tic54x_asg
, 0 },
2561 { "eval" , tic54x_eval
, 0 },
2562 { "bss" , tic54x_bss
, 0 },
2563 { "byte" , tic54x_cons
, 'b' },
2564 { "ubyte" , tic54x_cons
, 'B' },
2565 { "char" , tic54x_cons
, 'c' },
2566 { "uchar" , tic54x_cons
, 'C' },
2567 { "clink" , tic54x_clink
, 0 },
2568 { "c_mode" , tic54x_address_mode
, c_mode
},
2569 { "copy" , tic54x_include
, 'c' },
2570 { "include" , tic54x_include
, 'i' },
2571 { "data" , tic54x_sect
, 'd' },
2572 { "double" , tic54x_float_cons
, 'd' },
2573 { "ldouble" , tic54x_float_cons
, 'l' },
2574 { "drlist" , s_ignore
, 0 },
2575 { "drnolist" , s_ignore
, 0 },
2576 { "emsg" , tic54x_message
, 'e' },
2577 { "mmsg" , tic54x_message
, 'm' },
2578 { "wmsg" , tic54x_message
, 'w' },
2579 { "far_mode" , tic54x_address_mode
, far_mode
},
2580 { "fclist" , tic54x_fclist
, 1 },
2581 { "fcnolist" , tic54x_fclist
, 0 },
2582 { "field" , tic54x_field
, -1 },
2583 { "float" , tic54x_float_cons
, 'f' },
2584 { "xfloat" , tic54x_float_cons
, 'x' },
2585 { "global" , tic54x_global
, 'g' },
2586 { "def" , tic54x_global
, 'd' },
2587 { "ref" , tic54x_global
, 'r' },
2588 { "half" , tic54x_cons
, 'h' },
2589 { "uhalf" , tic54x_cons
, 'H' },
2590 { "short" , tic54x_cons
, 's' },
2591 { "ushort" , tic54x_cons
, 'S' },
2592 { "if" , s_if
, (int) O_ne
},
2593 { "elseif" , s_elseif
, (int) O_ne
},
2594 { "else" , s_else
, 0 },
2595 { "endif" , s_endif
, 0 },
2596 { "int" , tic54x_cons
, 'i' },
2597 { "uint" , tic54x_cons
, 'I' },
2598 { "word" , tic54x_cons
, 'w' },
2599 { "uword" , tic54x_cons
, 'W' },
2600 { "label" , tic54x_label
, 0 }, /* Loadtime
2602 { "length" , s_ignore
, 0 },
2603 { "width" , s_ignore
, 0 },
2604 { "long" , tic54x_cons
, 'l' },
2605 { "ulong" , tic54x_cons
, 'L' },
2606 { "xlong" , tic54x_cons
, 'x' },
2607 { "loop" , tic54x_loop
, 1024 },
2608 { "break" , tic54x_break
, 0 },
2609 { "endloop" , tic54x_endloop
, 0 },
2610 { "mlib" , tic54x_mlib
, 0 },
2611 { "mlist" , s_ignore
, 0 },
2612 { "mnolist" , s_ignore
, 0 },
2613 { "mmregs" , tic54x_mmregs
, 0 },
2614 { "newblock" , tic54x_clear_local_labels
, 0 },
2615 { "option" , s_ignore
, 0 },
2616 { "p2align" , tic54x_p2align
, 0 },
2617 { "sblock" , tic54x_sblock
, 0 },
2618 { "sect" , tic54x_sect
, '*' },
2619 { "set" , tic54x_set
, 0 },
2620 { "equ" , tic54x_set
, 0 },
2621 { "space" , tic54x_space
, 0 },
2622 { "bes" , tic54x_space
, 1 },
2623 { "sslist" , tic54x_sslist
, 1 },
2624 { "ssnolist" , tic54x_sslist
, 0 },
2625 { "string" , tic54x_stringer
, 's' },
2626 { "pstring" , tic54x_stringer
, 'p' },
2627 { "struct" , tic54x_struct
, 0 },
2628 { "tag" , tic54x_tag
, 0 },
2629 { "endstruct", tic54x_endstruct
, 0 },
2630 { "tab" , s_ignore
, 0 },
2631 { "text" , tic54x_sect
, 't' },
2632 { "union" , tic54x_struct
, 1 },
2633 { "endunion" , tic54x_endstruct
, 1 },
2634 { "usect" , tic54x_usect
, 0 },
2635 { "var" , tic54x_var
, 0 },
2636 { "version" , tic54x_version
, 0 },
2641 md_parse_option (c
, arg
)
2649 case OPTION_COFF_VERSION
:
2651 int version
= atoi (arg
);
2653 if (version
!= 0 && version
!= 1 && version
!= 2)
2654 as_fatal (_("Bad COFF version '%s'"), arg
);
2655 /* FIXME -- not yet implemented. */
2658 case OPTION_CPU_VERSION
:
2660 cpu
= lookup_version (arg
);
2663 as_fatal (_("Bad CPU version '%s'"), arg
);
2666 case OPTION_ADDRESS_MODE
:
2668 address_mode_needs_set
= 1;
2670 case OPTION_STDERR_TO_FILE
:
2672 char *filename
= arg
;
2673 FILE *fp
= fopen (filename
, "w+");
2676 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2678 if ((fp
= freopen (filename
, "w+", stderr
)) == NULL
)
2679 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2687 /* Create a "local" substitution string hash table for a new macro level
2688 Some docs imply that macros have to use .newblock in order to be able
2689 to re-use a local label. We effectively do an automatic .newblock by
2690 deleting the local label hash between macro invocations. */
2693 tic54x_macro_start ()
2696 subsym_hash
[macro_level
] = hash_new ();
2697 local_label_hash
[macro_level
] = hash_new ();
2701 tic54x_macro_info (macro
)
2702 const macro_entry
*macro
;
2704 const formal_entry
*entry
;
2706 /* Put the formal args into the substitution symbol table. */
2707 for (entry
= macro
->formals
; entry
; entry
= entry
->next
)
2709 char *name
= strncpy (xmalloc (entry
->name
.len
+ 1),
2710 entry
->name
.ptr
, entry
->name
.len
);
2711 char *value
= strncpy (xmalloc (entry
->actual
.len
+ 1),
2712 entry
->actual
.ptr
, entry
->actual
.len
);
2714 name
[entry
->name
.len
] = '\0';
2715 value
[entry
->actual
.len
] = '\0';
2716 hash_insert (subsym_hash
[macro_level
], name
, value
);
2720 /* Get rid of this macro's .var's, arguments, and local labels. */
2725 hash_die (subsym_hash
[macro_level
]);
2726 subsym_hash
[macro_level
] = NULL
;
2727 hash_die (local_label_hash
[macro_level
]);
2728 local_label_hash
[macro_level
] = NULL
;
2733 subsym_symlen (a
, ignore
)
2735 char *ignore ATTRIBUTE_UNUSED
;
2740 /* Compare symbol A to string B. */
2743 subsym_symcmp (a
, b
)
2747 return strcmp (a
, b
);
2750 /* Return the index of the first occurrence of B in A, or zero if none
2751 assumes b is an integer char value as a string. Index is one-based. */
2754 subsym_firstch (a
, b
)
2759 char *tmp
= strchr (a
, val
);
2761 return tmp
? tmp
- a
+ 1 : 0;
2764 /* Similar to firstch, but returns index of last occurrence of B in A. */
2767 subsym_lastch (a
, b
)
2772 char *tmp
= strrchr (a
, val
);
2774 return tmp
? tmp
- a
+ 1 : 0;
2777 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2781 subsym_isdefed (a
, ignore
)
2783 char *ignore ATTRIBUTE_UNUSED
;
2785 symbolS
*symbolP
= symbol_find (a
);
2787 return symbolP
!= NULL
;
2790 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2791 A, or zero if B is a null string. Both arguments *must* be substitution
2792 symbols, unsubstituted. */
2795 subsym_ismember (sym
, list
)
2799 char *elem
, *ptr
, *listv
;
2804 listv
= subsym_lookup (list
, macro_level
);
2807 as_bad (_("Undefined substitution symbol '%s'"), list
);
2808 ignore_rest_of_line ();
2812 ptr
= elem
= xmalloc (strlen (listv
) + 1);
2813 strcpy (elem
, listv
);
2814 while (*ptr
&& *ptr
!= ',')
2818 subsym_create_or_replace (sym
, elem
);
2820 /* Reassign the list. */
2821 subsym_create_or_replace (list
, ptr
);
2823 /* Assume this value, docs aren't clear. */
2827 /* Return zero if not a constant; otherwise:
2835 subsym_iscons (a
, ignore
)
2837 char *ignore ATTRIBUTE_UNUSED
;
2841 parse_expression (a
, &exp
);
2843 if (exp
.X_op
== O_constant
)
2845 int len
= strlen (a
);
2847 switch (TOUPPER (a
[len
- 1]))
2860 /* No suffix; either octal, hex, or decimal. */
2861 if (*a
== '0' && len
> 1)
2863 if (TOUPPER (a
[1]) == 'X')
2873 /* Return 1 if A is a valid symbol name. Expects string input. */
2876 subsym_isname (a
, ignore
)
2878 char *ignore ATTRIBUTE_UNUSED
;
2880 if (!is_name_beginner (*a
))
2884 if (!is_part_of_name (*a
))
2891 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2892 been seen; if so, recognize any memory-mapped register.
2893 Note this does not recognize "A" or "B" accumulators. */
2896 subsym_isreg (a
, ignore
)
2898 char *ignore ATTRIBUTE_UNUSED
;
2900 if (hash_find (reg_hash
, a
))
2902 if (hash_find (mmreg_hash
, a
))
2907 /* Return the structure size, given the stag. */
2910 subsym_structsz (name
, ignore
)
2912 char *ignore ATTRIBUTE_UNUSED
;
2914 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
2922 /* If anybody actually uses this, they can fix it :)
2923 FIXME I'm not sure what the "reference point" of a structure is. It might
2924 be either the initial offset given .struct, or it may be the offset of the
2925 structure within another structure, or it might be something else
2926 altogether. since the TI assembler doesn't seem to ever do anything but
2927 return zero, we punt and return zero. */
2930 subsym_structacc (stag_name
, ignore
)
2931 char *stag_name ATTRIBUTE_UNUSED
;
2932 char *ignore ATTRIBUTE_UNUSED
;
2938 math_ceil (arg1
, ignore
)
2940 float ignore ATTRIBUTE_UNUSED
;
2942 return (float) ceil (arg1
);
2946 math_cvi (arg1
, ignore
)
2948 float ignore ATTRIBUTE_UNUSED
;
2954 math_floor (arg1
, ignore
)
2956 float ignore ATTRIBUTE_UNUSED
;
2958 return (float) floor (arg1
);
2962 math_fmod (arg1
, arg2
)
2966 return (int) arg1
% (int) arg2
;
2970 math_int (arg1
, ignore
)
2972 float ignore ATTRIBUTE_UNUSED
;
2974 return ((float) ((int) arg1
)) == arg1
;
2978 math_round (arg1
, ignore
)
2980 float ignore ATTRIBUTE_UNUSED
;
2982 return arg1
> 0 ? (int) (arg1
+ 0.5) : (int) (arg1
- 0.5);
2986 math_sgn (arg1
, ignore
)
2988 float ignore ATTRIBUTE_UNUSED
;
2990 return (arg1
< 0) ? -1 : (arg1
? 1 : 0);
2994 math_trunc (arg1
, ignore
)
2996 float ignore ATTRIBUTE_UNUSED
;
3002 math_acos (arg1
, ignore
)
3004 float ignore ATTRIBUTE_UNUSED
;
3006 return (float) acos (arg1
);
3010 math_asin (arg1
, ignore
)
3012 float ignore ATTRIBUTE_UNUSED
;
3014 return (float) asin (arg1
);
3018 math_atan (arg1
, ignore
)
3020 float ignore ATTRIBUTE_UNUSED
;
3022 return (float) atan (arg1
);
3026 math_atan2 (arg1
, arg2
)
3030 return (float) atan2 (arg1
, arg2
);
3034 math_cosh (arg1
, ignore
)
3036 float ignore ATTRIBUTE_UNUSED
;
3038 return (float) cosh (arg1
);
3042 math_cos (arg1
, ignore
)
3044 float ignore ATTRIBUTE_UNUSED
;
3046 return (float) cos (arg1
);
3050 math_cvf (arg1
, ignore
)
3052 float ignore ATTRIBUTE_UNUSED
;
3054 return (float) arg1
;
3058 math_exp (arg1
, ignore
)
3060 float ignore ATTRIBUTE_UNUSED
;
3062 return (float) exp (arg1
);
3066 math_fabs (arg1
, ignore
)
3068 float ignore ATTRIBUTE_UNUSED
;
3070 return (float) fabs (arg1
);
3073 /* expr1 * 2^expr2. */
3076 math_ldexp (arg1
, arg2
)
3080 return arg1
* (float) pow (2.0, arg2
);
3084 math_log10 (arg1
, ignore
)
3086 float ignore ATTRIBUTE_UNUSED
;
3088 return (float) log10 (arg1
);
3092 math_log (arg1
, ignore
)
3094 float ignore ATTRIBUTE_UNUSED
;
3096 return (float) log (arg1
);
3100 math_max (arg1
, arg2
)
3104 return (arg1
> arg2
) ? arg1
: arg2
;
3108 math_min (arg1
, arg2
)
3112 return (arg1
< arg2
) ? arg1
: arg2
;
3116 math_pow (arg1
, arg2
)
3120 return (float) pow (arg1
, arg2
);
3124 math_sin (arg1
, ignore
)
3126 float ignore ATTRIBUTE_UNUSED
;
3128 return (float) sin (arg1
);
3132 math_sinh (arg1
, ignore
)
3134 float ignore ATTRIBUTE_UNUSED
;
3136 return (float) sinh (arg1
);
3140 math_sqrt (arg1
, ignore
)
3142 float ignore ATTRIBUTE_UNUSED
;
3144 return (float) sqrt (arg1
);
3148 math_tan (arg1
, ignore
)
3150 float ignore ATTRIBUTE_UNUSED
;
3152 return (float) tan (arg1
);
3156 math_tanh (arg1
, ignore
)
3158 float ignore ATTRIBUTE_UNUSED
;
3160 return (float) tanh (arg1
);
3163 /* Built-in substitution symbol functions and math functions. */
3167 int (*proc
) PARAMS ((char *, char *));
3169 } subsym_proc_entry
;
3171 static const subsym_proc_entry subsym_procs
[] =
3173 /* Assembler built-in string substitution functions. */
3174 { "$symlen", subsym_symlen
, 1, },
3175 { "$symcmp", subsym_symcmp
, 2, },
3176 { "$firstch", subsym_firstch
, 2, },
3177 { "$lastch", subsym_lastch
, 2, },
3178 { "$isdefed", subsym_isdefed
, 1, },
3179 { "$ismember", subsym_ismember
, 2, },
3180 { "$iscons", subsym_iscons
, 1, },
3181 { "$isname", subsym_isname
, 1, },
3182 { "$isreg", subsym_isreg
, 1, },
3183 { "$structsz", subsym_structsz
, 1, },
3184 { "$structacc", subsym_structacc
, 1, },
3191 float (*proc
) PARAMS ((float, float));
3196 static const math_proc_entry math_procs
[] =
3198 /* Integer-returning built-in math functions. */
3199 { "$cvi", math_cvi
, 1, 1 },
3200 { "$int", math_int
, 1, 1 },
3201 { "$sgn", math_sgn
, 1, 1 },
3203 /* Float-returning built-in math functions. */
3204 { "$acos", math_acos
, 1, 0 },
3205 { "$asin", math_asin
, 1, 0 },
3206 { "$atan", math_atan
, 1, 0 },
3207 { "$atan2", math_atan2
, 2, 0 },
3208 { "$ceil", math_ceil
, 1, 0 },
3209 { "$cosh", math_cosh
, 1, 0 },
3210 { "$cos", math_cos
, 1, 0 },
3211 { "$cvf", math_cvf
, 1, 0 },
3212 { "$exp", math_exp
, 1, 0 },
3213 { "$fabs", math_fabs
, 1, 0 },
3214 { "$floor", math_floor
, 1, 0 },
3215 { "$fmod", math_fmod
, 2, 0 },
3216 { "$ldexp", math_ldexp
, 2, 0 },
3217 { "$log10", math_log10
, 1, 0 },
3218 { "$log", math_log
, 1, 0 },
3219 { "$max", math_max
, 2, 0 },
3220 { "$min", math_min
, 2, 0 },
3221 { "$pow", math_pow
, 2, 0 },
3222 { "$round", math_round
, 1, 0 },
3223 { "$sin", math_sin
, 1, 0 },
3224 { "$sinh", math_sinh
, 1, 0 },
3225 { "$sqrt", math_sqrt
, 1, 0 },
3226 { "$tan", math_tan
, 1, 0 },
3227 { "$tanh", math_tanh
, 1, 0 },
3228 { "$trunc", math_trunc
, 1, 0 },
3229 { NULL
, NULL
, 0, 0 },
3237 const subsym_proc_entry
*subsym_proc
;
3238 const math_proc_entry
*math_proc
;
3239 const char *hash_err
;
3241 char *TIC54X_DIR
= getenv ("TIC54X_DIR");
3242 char *A_DIR
= TIC54X_DIR
? TIC54X_DIR
: getenv ("A_DIR");
3246 /* Look for A_DIR and add it to the include list. */
3249 char *tmp
= xstrdup (A_DIR
);
3253 char *next
= strchr (tmp
, ';');
3257 add_include_dir (tmp
);
3260 while (tmp
!= NULL
);
3263 op_hash
= hash_new ();
3264 for (tm
= (template *) tic54x_optab
; tm
->name
; tm
++)
3266 if (hash_find (op_hash
, tm
->name
))
3268 hash_err
= hash_insert (op_hash
, tm
->name
, (char *) tm
);
3270 as_fatal ("Internal Error: Can't hash %s: %s",
3271 tm
->name
, hash_err
);
3273 parop_hash
= hash_new ();
3274 for (tm
= (template *) tic54x_paroptab
; tm
->name
; tm
++)
3276 if (hash_find (parop_hash
, tm
->name
))
3278 hash_err
= hash_insert (parop_hash
, tm
->name
, (char *) tm
);
3280 as_fatal ("Internal Error: Can't hash %s: %s",
3281 tm
->name
, hash_err
);
3283 reg_hash
= hash_new ();
3284 for (sym
= (symbol
*) regs
; sym
->name
; sym
++)
3286 /* Add basic registers to the symbol table. */
3287 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
3288 (valueT
) sym
->value
, &zero_address_frag
);
3289 SF_SET_LOCAL (symbolP
);
3290 symbol_table_insert (symbolP
);
3291 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3293 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3294 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3295 mmreg_hash
= hash_new ();
3296 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3297 hash_err
= hash_insert (mmreg_hash
, sym
->name
, (char *) sym
);
3299 cc_hash
= hash_new ();
3300 for (sym
= (symbol
*) condition_codes
; sym
->name
; sym
++)
3301 hash_err
= hash_insert (cc_hash
, sym
->name
, (char *) sym
);
3303 cc2_hash
= hash_new ();
3304 for (sym
= (symbol
*) cc2_codes
; sym
->name
; sym
++)
3305 hash_err
= hash_insert (cc2_hash
, sym
->name
, (char *) sym
);
3307 cc3_hash
= hash_new ();
3308 for (sym
= (symbol
*) cc3_codes
; sym
->name
; sym
++)
3309 hash_err
= hash_insert (cc3_hash
, sym
->name
, (char *) sym
);
3311 sbit_hash
= hash_new ();
3312 for (sym
= (symbol
*) status_bits
; sym
->name
; sym
++)
3313 hash_err
= hash_insert (sbit_hash
, sym
->name
, (char *) sym
);
3315 misc_symbol_hash
= hash_new ();
3316 for (symname
= (char **) misc_symbols
; *symname
; symname
++)
3317 hash_err
= hash_insert (misc_symbol_hash
, *symname
, *symname
);
3319 /* Only the base substitution table and local label table are initialized;
3320 the others (for local macro substitution) get instantiated as needed. */
3321 local_label_hash
[0] = hash_new ();
3322 subsym_hash
[0] = hash_new ();
3323 for (subsym_proc
= subsym_procs
; subsym_proc
->name
; subsym_proc
++)
3324 hash_err
= hash_insert (subsym_hash
[0], subsym_proc
->name
,
3325 (char *) subsym_proc
);
3327 math_hash
= hash_new ();
3328 for (math_proc
= math_procs
; math_proc
->name
; math_proc
++)
3330 /* Insert into the main subsym hash for recognition; insert into
3331 the math hash to actually store information. */
3332 hash_err
= hash_insert (subsym_hash
[0], math_proc
->name
,
3333 (char *) math_proc
);
3334 hash_err
= hash_insert (math_hash
, math_proc
->name
,
3335 (char *) math_proc
);
3337 subsym_recurse_hash
= hash_new ();
3338 stag_hash
= hash_new ();
3342 is_accumulator (operand
)
3343 struct opstruct
*operand
;
3345 return strcasecmp (operand
->buf
, "a") == 0
3346 || strcasecmp (operand
->buf
, "b") == 0;
3349 /* Return the number of operands found, or -1 on error, copying the
3350 operands into the given array and the accompanying expressions into
3354 get_operands (operands
, line
)
3355 struct opstruct operands
[];
3360 int expecting_operand
= 0;
3363 while (numexp
< MAX_OPERANDS
&& !is_end_of_line
[(int) *lptr
])
3365 int paren_not_balanced
= 0;
3366 char *op_start
, *op_end
;
3368 while (*lptr
&& ISSPACE (*lptr
))
3371 while (paren_not_balanced
|| *lptr
!= ',')
3375 if (paren_not_balanced
)
3377 as_bad ("Unbalanced parenthesis in operand %d", numexp
);
3384 ++paren_not_balanced
;
3385 else if (*lptr
== ')')
3386 --paren_not_balanced
;
3390 if (op_end
!= op_start
)
3392 int len
= op_end
- op_start
;
3394 strncpy (operands
[numexp
].buf
, op_start
, len
);
3395 operands
[numexp
].buf
[len
] = 0;
3396 /* Trim trailing spaces; while the preprocessor gets rid of most,
3397 there are weird usage patterns that can introduce them
3398 (i.e. using strings for macro args). */
3399 while (len
> 0 && ISSPACE (operands
[numexp
].buf
[len
- 1]))
3400 operands
[numexp
].buf
[--len
] = 0;
3406 if (expecting_operand
|| *lptr
== ',')
3408 as_bad ("Expecting operand after ','");
3414 if (*++lptr
== '\0')
3416 as_bad ("Expecting operand after ','");
3419 expecting_operand
= 1;
3423 while (*lptr
&& ISSPACE (*lptr
++))
3425 if (!is_end_of_line
[(int) *lptr
])
3427 as_bad ("Extra junk on line");
3431 /* OK, now parse them into expressions. */
3432 for (i
= 0; i
< numexp
; i
++)
3434 memset (&operands
[i
].exp
, 0, sizeof (operands
[i
].exp
));
3435 if (operands
[i
].buf
[0] == '#')
3438 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3440 else if (operands
[i
].buf
[0] == '@')
3442 /* Direct notation. */
3443 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3445 else if (operands
[i
].buf
[0] == '*')
3448 char *paren
= strchr (operands
[i
].buf
, '(');
3450 /* Allow immediate syntax in the inner expression. */
3451 if (paren
&& paren
[1] == '#')
3454 /* Pull out the lk expression or SP offset, if present. */
3457 int len
= strlen (paren
);
3458 char *end
= paren
+ len
;
3461 while (end
[-1] != ')')
3464 as_bad (_("Badly formed address expression"));
3469 parse_expression (paren
, &operands
[i
].exp
);
3473 operands
[i
].exp
.X_op
= O_absent
;
3476 parse_expression (operands
[i
].buf
, &operands
[i
].exp
);
3482 /* Predicates for different operand types. */
3485 is_immediate (operand
)
3486 struct opstruct
*operand
;
3488 return *operand
->buf
== '#';
3491 /* This is distinguished from immediate because some numbers must be constants
3492 and must *not* have the '#' prefix. */
3495 is_absolute (operand
)
3496 struct opstruct
*operand
;
3498 return operand
->exp
.X_op
== O_constant
&& !is_immediate (operand
);
3501 /* Is this an indirect operand? */
3504 is_indirect (operand
)
3505 struct opstruct
*operand
;
3507 return operand
->buf
[0] == '*';
3510 /* Is this a valid dual-memory operand? */
3514 struct opstruct
*operand
;
3516 if (is_indirect (operand
) && strncasecmp (operand
->buf
, "*ar", 3) == 0)
3518 char *tmp
= operand
->buf
+ 3;
3523 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3524 valid_mod
= *tmp
== '\0' ||
3525 strcasecmp (tmp
, "-") == 0 ||
3526 strcasecmp (tmp
, "+") == 0 ||
3527 strcasecmp (tmp
, "+0%") == 0;
3528 return arf
>= 2 && arf
<= 5 && valid_mod
;
3535 struct opstruct
*operand
;
3537 return (is_absolute (operand
)
3538 || is_immediate (operand
)
3539 || hash_find (mmreg_hash
, operand
->buf
) != 0);
3543 is_type (operand
, type
)
3544 struct opstruct
*operand
;
3550 return operand
->buf
[0] == 0;
3553 return is_dual (operand
);
3555 return is_indirect (operand
);
3557 /* This one *must* be immediate. */
3558 return is_immediate (operand
);
3567 /* Address may be a numeric, indirect, or an expression. */
3568 return !is_immediate (operand
);
3571 return is_mmreg (operand
);
3576 return is_accumulator (operand
);
3578 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'B';
3580 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'A';
3582 return strncasecmp ("ar", operand
->buf
, 2) == 0
3583 && ISDIGIT (operand
->buf
[2]);
3585 return hash_find (sbit_hash
, operand
->buf
) != 0 || is_absolute (operand
);
3587 return hash_find (cc_hash
, operand
->buf
) != 0;
3589 return hash_find (cc2_hash
, operand
->buf
) != 0;
3591 return hash_find (cc3_hash
, operand
->buf
) != 0
3592 || is_immediate (operand
) || is_absolute (operand
);
3594 return (is_immediate (operand
) || is_absolute (operand
))
3595 && operand
->exp
.X_add_number
== 16;
3597 /* Allow st0 or st1 instead of a numeric. */
3598 return is_absolute (operand
) || is_immediate (operand
) ||
3599 strcasecmp ("st0", operand
->buf
) == 0 ||
3600 strcasecmp ("st1", operand
->buf
) == 0;
3603 return is_absolute (operand
) || is_immediate (operand
);
3605 return (is_immediate (operand
) || is_absolute (operand
))
3606 && operand
->exp
.X_add_number
>= 0 && operand
->exp
.X_add_number
< 16;
3608 /* Let this one catch out-of-range values. */
3609 return (is_immediate (operand
) || is_absolute (operand
))
3610 && operand
->exp
.X_add_number
!= 16;
3614 return is_absolute (operand
) || is_immediate (operand
);
3616 return is_immediate (operand
)
3617 && operand
->exp
.X_op
== O_constant
3618 && operand
->exp
.X_add_number
>= 0
3619 && operand
->exp
.X_add_number
< 256;
3622 /* Allow anything; assumes opcodes are ordered with Smem operands
3628 /* Just make sure it's an integer; check range later. */
3629 return is_immediate (operand
);
3631 return strcasecmp ("t", operand
->buf
) == 0 ||
3632 strcasecmp ("treg", operand
->buf
) == 0;
3634 return strcasecmp ("ts", operand
->buf
) == 0;
3636 return strcasecmp ("asm", operand
->buf
) == 0;
3638 return strcasecmp ("trn", operand
->buf
) == 0;
3640 return strcasecmp ("dp", operand
->buf
) == 0;
3642 return strcasecmp ("arp", operand
->buf
) == 0;
3649 operands_match (insn
, operands
, opcount
, refoptype
, minops
, maxops
)
3651 struct opstruct
*operands
;
3653 const enum optype
*refoptype
;
3657 int op
= 0, refop
= 0;
3659 if (opcount
== 0 && minops
== 0)
3662 while (op
<= maxops
&& refop
<= maxops
)
3664 while (!is_type (&operands
[op
], OPTYPE (refoptype
[refop
])))
3666 /* Skip an optional template operand if it doesn't agree
3667 with the current operand. */
3668 if (refoptype
[refop
] & OPT
)
3679 /* Save the actual operand type for later use. */
3680 operands
[op
].type
= OPTYPE (refoptype
[refop
]);
3683 /* Have we matched them all yet? */
3688 /* If a later operand is *not* optional, no match. */
3689 if ((refoptype
[refop
] & OPT
) == 0)
3691 /* Flag any implicit default OP_DST operands so we know to add
3692 them explicitly when encoding the operand later. */
3693 if (OPTYPE (refoptype
[refop
]) == OP_DST
)
3694 insn
->using_default_dst
= 1;
3706 /* 16-bit direct memory address
3707 Explicit dmad operands are always in last word of insn (usually second
3708 word, but bumped to third if lk addressing is used)
3710 We allow *(dmad) notation because the TI assembler allows it.
3713 0 for 16-bit addresses
3714 1 for full 23-bit addresses
3715 2 for the upper 7 bits of a 23-bit address (LDX). */
3718 encode_dmad (insn
, operand
, xpc_code
)
3720 struct opstruct
*operand
;
3723 int op
= 1 + insn
->is_lkaddr
;
3725 /* Only allow *(dmad) expressions; all others are invalid. */
3726 if (is_indirect (operand
) && operand
->buf
[strlen (operand
->buf
) - 1] != ')')
3728 as_bad (_("Invalid dmad syntax '%s'"), operand
->buf
);
3732 insn
->opcode
[op
].addr_expr
= operand
->exp
;
3734 if (insn
->opcode
[op
].addr_expr
.X_op
== O_constant
)
3736 valueT value
= insn
->opcode
[op
].addr_expr
.X_add_number
;
3740 insn
->opcode
[0].word
&= 0xFF80;
3741 insn
->opcode
[0].word
|= (value
>> 16) & 0x7F;
3742 insn
->opcode
[1].word
= value
& 0xFFFF;
3744 else if (xpc_code
== 2)
3745 insn
->opcode
[op
].word
= (value
>> 16) & 0xFFFF;
3747 insn
->opcode
[op
].word
= value
;
3751 /* Do the fixup later; just store the expression. */
3752 insn
->opcode
[op
].word
= 0;
3753 insn
->opcode
[op
].r_nchars
= 2;
3755 if (amode
== c_mode
)
3756 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3757 else if (xpc_code
== 1)
3759 /* This relocation spans two words, so adjust accordingly. */
3760 insn
->opcode
[0].addr_expr
= operand
->exp
;
3761 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_23
;
3762 insn
->opcode
[0].r_nchars
= 4;
3763 insn
->opcode
[0].unresolved
= 1;
3764 /* It's really 2 words, but we want to stop encoding after the
3765 first, since we must encode both words at once. */
3768 else if (xpc_code
== 2)
3769 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_MS7_OF_23
;
3771 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3773 insn
->opcode
[op
].unresolved
= 1;
3779 /* 7-bit direct address encoding. */
3782 encode_address (insn
, operand
)
3784 struct opstruct
*operand
;
3786 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3787 insn
->opcode
[0].addr_expr
= operand
->exp
;
3789 if (operand
->exp
.X_op
== O_constant
)
3790 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
& 0x7F);
3793 if (operand
->exp
.X_op
== O_register
)
3794 as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand
->buf
);
3795 /* Do the fixup later; just store the expression. */
3796 insn
->opcode
[0].r_nchars
= 1;
3797 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_PARTLS7
;
3798 insn
->opcode
[0].unresolved
= 1;
3805 encode_indirect (insn
, operand
)
3807 struct opstruct
*operand
;
3812 if (insn
->is_lkaddr
)
3814 /* lk addresses always go in the second insn word. */
3815 mod
= ((TOUPPER (operand
->buf
[1]) == 'A') ? 12 :
3816 (operand
->buf
[1] == '(') ? 15 :
3817 (strchr (operand
->buf
, '%') != NULL
) ? 14 : 13);
3818 arf
= ((mod
== 12) ? operand
->buf
[3] - '0' :
3819 (mod
== 15) ? 0 : operand
->buf
[4] - '0');
3821 insn
->opcode
[1].addr_expr
= operand
->exp
;
3823 if (operand
->exp
.X_op
== O_constant
)
3824 insn
->opcode
[1].word
= operand
->exp
.X_add_number
;
3827 insn
->opcode
[1].word
= 0;
3828 insn
->opcode
[1].r_nchars
= 2;
3829 insn
->opcode
[1].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3830 insn
->opcode
[1].unresolved
= 1;
3833 else if (strncasecmp (operand
->buf
, "*sp (", 4) == 0)
3835 /* Stack offsets look the same as 7-bit direct addressing. */
3836 return encode_address (insn
, operand
);
3840 arf
= (TOUPPER (operand
->buf
[1]) == 'A' ?
3841 operand
->buf
[3] : operand
->buf
[4]) - '0';
3843 if (operand
->buf
[1] == '+')
3845 mod
= 3; /* *+ARx */
3846 if (insn
->tm
->flags
& FL_SMR
)
3847 as_warn (_("Address mode *+ARx is write-only. "
3848 "Results of reading are undefined."));
3850 else if (operand
->buf
[4] == '\0')
3852 else if (operand
->buf
[5] == '\0')
3853 mod
= (operand
->buf
[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3854 else if (operand
->buf
[6] == '\0')
3856 if (operand
->buf
[5] == '0')
3857 mod
= (operand
->buf
[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3859 mod
= (operand
->buf
[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3861 else if (TOUPPER (operand
->buf
[6]) == 'B')
3862 mod
= (operand
->buf
[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3863 else if (TOUPPER (operand
->buf
[6]) == '%')
3864 mod
= (operand
->buf
[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3867 as_bad (_("Unrecognized indirect address format \"%s\""),
3873 insn
->opcode
[0].word
|= 0x80 | (mod
<< 3) | arf
;
3879 encode_integer (insn
, operand
, which
, min
, max
, mask
)
3881 struct opstruct
*operand
;
3885 unsigned short mask
;
3887 long parse
, integer
;
3889 insn
->opcode
[which
].addr_expr
= operand
->exp
;
3891 if (operand
->exp
.X_op
== O_constant
)
3893 parse
= operand
->exp
.X_add_number
;
3894 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3895 instead of negative. */
3896 if ((parse
& 0x8000) && min
== -32768 && max
== 32767)
3897 integer
= (short) parse
;
3901 if (integer
>= min
&& integer
<= max
)
3903 insn
->opcode
[which
].word
|= (integer
& mask
);
3906 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3907 operand
->buf
, min
, max
);
3911 if (insn
->opcode
[which
].addr_expr
.X_op
== O_constant
)
3913 insn
->opcode
[which
].word
|=
3914 insn
->opcode
[which
].addr_expr
.X_add_number
& mask
;
3918 /* Do the fixup later; just store the expression. */
3919 bfd_reloc_code_real_type rtype
=
3920 (mask
== 0x1FF ? BFD_RELOC_TIC54X_PARTMS9
:
3921 mask
== 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23
:
3922 mask
== 0x7F ? BFD_RELOC_TIC54X_PARTLS7
: BFD_RELOC_8
);
3923 int size
= (mask
== 0x1FF || mask
== 0xFFFF) ? 2 : 1;
3925 if (rtype
== BFD_RELOC_8
)
3926 as_bad (_("Error in relocation handling"));
3928 insn
->opcode
[which
].r_nchars
= size
;
3929 insn
->opcode
[which
].r_type
= rtype
;
3930 insn
->opcode
[which
].unresolved
= 1;
3940 encode_condition (insn
, operand
)
3942 struct opstruct
*operand
;
3944 symbol
*cc
= (symbol
*) hash_find (cc_hash
, operand
->buf
);
3947 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
3950 #define CC_GROUP 0x40
3952 #define CATG_A1 0x07
3953 #define CATG_B1 0x30
3954 #define CATG_A2 0x30
3955 #define CATG_B2 0x0C
3956 #define CATG_C2 0x03
3957 /* Disallow group 1 conditions mixed with group 2 conditions
3958 if group 1, allow only one category A and one category B
3959 if group 2, allow only one each of category A, B, and C. */
3960 if (((insn
->opcode
[0].word
& 0xFF) != 0))
3962 if ((insn
->opcode
[0].word
& CC_GROUP
) != (cc
->value
& CC_GROUP
))
3964 as_bad (_("Condition \"%s\" does not match preceding group"),
3968 if (insn
->opcode
[0].word
& CC_GROUP
)
3970 if ((insn
->opcode
[0].word
& CC_ACC
) != (cc
->value
& CC_ACC
))
3972 as_bad (_("Condition \"%s\" uses a different accumulator from "
3973 "a preceding condition"),
3977 if ((insn
->opcode
[0].word
& CATG_A1
) && (cc
->value
& CATG_A1
))
3979 as_bad (_("Only one comparison conditional allowed"));
3982 if ((insn
->opcode
[0].word
& CATG_B1
) && (cc
->value
& CATG_B1
))
3984 as_bad (_("Only one overflow conditional allowed"));
3988 else if ( ((insn
->opcode
[0].word
& CATG_A2
) && (cc
->value
& CATG_A2
))
3989 || ((insn
->opcode
[0].word
& CATG_B2
) && (cc
->value
& CATG_B2
))
3990 || ((insn
->opcode
[0].word
& CATG_C2
) && (cc
->value
& CATG_C2
)))
3992 as_bad (_("Duplicate %s conditional"), operand
->buf
);
3997 insn
->opcode
[0].word
|= cc
->value
;
4002 encode_cc3 (insn
, operand
)
4004 struct opstruct
*operand
;
4006 symbol
*cc3
= (symbol
*) hash_find (cc3_hash
, operand
->buf
);
4007 int value
= cc3
? cc3
->value
: operand
->exp
.X_add_number
<< 8;
4009 if ((value
& 0x0300) != value
)
4011 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
4014 insn
->opcode
[0].word
|= value
;
4019 encode_arx (insn
, operand
)
4021 struct opstruct
*operand
;
4023 int arf
= strlen (operand
->buf
) >= 3 ? operand
->buf
[2] - '0' : -1;
4025 if (strncasecmp ("ar", operand
->buf
, 2) || arf
< 0 || arf
> 7)
4027 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
4030 insn
->opcode
[0].word
|= arf
;
4035 encode_cc2 (insn
, operand
)
4037 struct opstruct
*operand
;
4039 symbol
*cc2
= (symbol
*) hash_find (cc2_hash
, operand
->buf
);
4043 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
4046 insn
->opcode
[0].word
|= cc2
->value
;
4051 encode_operand (insn
, type
, operand
)
4054 struct opstruct
*operand
;
4056 int ext
= (insn
->tm
->flags
& FL_EXT
) != 0;
4058 if (type
== OP_MMR
&& operand
->exp
.X_op
!= O_constant
)
4060 /* Disallow long-constant addressing for memory-mapped addressing. */
4061 if (insn
->is_lkaddr
)
4063 as_bad (_("lk addressing modes are invalid for memory-mapped "
4064 "register addressing"));
4068 /* Warn about *+ARx when used with MMR operands. */
4069 if (strncasecmp (operand
->buf
, "*+ar", 4) == 0)
4071 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
4072 "register addressing. Resulting behavior is "
4082 /* 16-bit immediate value. */
4083 return encode_dmad (insn
, operand
, 0);
4085 if (TOUPPER (*operand
->buf
) == 'B')
4087 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 9);
4088 if (insn
->using_default_dst
)
4089 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4093 /* Make sure this agrees with the OP_DST operand. */
4094 if (!((TOUPPER (operand
->buf
[0]) == 'B') ^
4095 ((insn
->opcode
[0].word
& (1 << 8)) != 0)))
4097 as_bad (_("Destination accumulator for each part of this parallel "
4098 "instruction must be different"));
4104 if (TOUPPER (operand
->buf
[0]) == 'B')
4105 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4110 int mod
= (operand
->buf
[4] == '\0' ? 0 : /* *arx */
4111 operand
->buf
[4] == '-' ? 1 : /* *arx- */
4112 operand
->buf
[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
4113 int arf
= operand
->buf
[3] - '0' - 2;
4114 int code
= (mod
<< 2) | arf
;
4115 insn
->opcode
[0].word
|= (code
<< (type
== OP_Xmem
? 4 : 0));
4120 if (!is_indirect (operand
))
4121 return encode_address (insn
, operand
);
4124 return encode_indirect (insn
, operand
);
4126 return encode_dmad (insn
, operand
, 2);
4128 return encode_dmad (insn
, operand
, 1);
4131 return encode_dmad (insn
, operand
, 0);
4133 return encode_arx (insn
, operand
);
4138 int value
= operand
->exp
.X_add_number
;
4141 insn
->opcode
[0].word
|= value
;
4144 if (value
< 16 || value
> 24)
4146 as_bad (_("Memory mapped register \"%s\" out of range"),
4150 if (type
== OP_MMRX
)
4151 insn
->opcode
[0].word
|= (value
- 16) << 4;
4153 insn
->opcode
[0].word
|= (value
- 16);
4161 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4164 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4167 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4168 -32768, 32767, 0xFFFF);
4170 return encode_condition (insn
, operand
);
4172 return encode_cc2 (insn
, operand
);
4174 return encode_cc3 (insn
, operand
);
4176 return encode_integer (insn
, operand
, 0, 0, 15, 0xF);
4178 return encode_integer (insn
, operand
, 0, -128, 127, 0xFF);
4181 int value
= operand
->exp
.X_add_number
;
4183 if (value
< 1 || value
> 3)
4185 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4188 code
= value
== 1 ? 0 : value
== 2 ? 0x2 : 0x1;
4189 insn
->opcode
[0].word
|= (code
<< 8);
4193 return encode_integer (insn
, operand
, 0, 0, 31, 0x1F);
4195 return encode_integer (insn
, operand
, 0, 0, 255, 0xFF);
4197 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4201 symbol
*sbit
= (symbol
*) hash_find (sbit_hash
, operand
->buf
);
4202 int value
= is_absolute (operand
) ?
4203 operand
->exp
.X_add_number
: (sbit
? sbit
->value
: -1);
4206 if (insn
->opcount
== 1)
4210 as_bad (_("A status register or status bit name is required"));
4213 /* Guess the register based on the status bit; "ovb" is the last
4214 status bit defined for st0. */
4215 if (sbit
> (symbol
*) hash_find (sbit_hash
, "ovb"))
4220 as_bad (_("Unrecognized status bit \"%s\""), operand
->buf
);
4223 insn
->opcode
[0].word
|= value
;
4224 insn
->opcode
[0].word
|= (reg
<< 9);
4228 if (strcasecmp (operand
->buf
, "st0") == 0
4229 || strcasecmp (operand
->buf
, "st1") == 0)
4231 insn
->opcode
[0].word
|=
4232 ((unsigned short) (operand
->buf
[2] - '0')) << 9;
4235 else if (operand
->exp
.X_op
== O_constant
4236 && (operand
->exp
.X_add_number
== 0
4237 || operand
->exp
.X_add_number
== 1))
4239 insn
->opcode
[0].word
|=
4240 ((unsigned short) (operand
->exp
.X_add_number
)) << 9;
4243 as_bad (_("Invalid status register \"%s\""), operand
->buf
);
4246 return encode_integer (insn
, operand
, 0, -16, 15, 0x1F);
4248 return encode_integer (insn
, operand
, 0, 0, 7, 0x7);
4250 return encode_integer (insn
, operand
, 0, 0, 0x1FF, 0x1FF);
4252 if (operand
->exp
.X_add_number
!= 1
4253 && operand
->exp
.X_add_number
!= 2)
4255 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand
->buf
);
4258 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
- 1) << 9;
4267 /* No encoding necessary. */
4281 flagword oldflags
= bfd_get_section_flags (stdoutput
, now_seg
);
4282 flagword flags
= oldflags
| SEC_CODE
;
4284 if (! bfd_set_section_flags (stdoutput
, now_seg
, flags
))
4285 as_warn (_("error setting flags for \"%s\": %s"),
4286 bfd_section_name (stdoutput
, now_seg
),
4287 bfd_errmsg (bfd_get_error ()));
4289 for (i
= 0; i
< insn
->words
; i
++)
4291 int size
= (insn
->opcode
[i
].unresolved
4292 && insn
->opcode
[i
].r_type
== BFD_RELOC_TIC54X_23
) ? 4 : 2;
4293 char *p
= frag_more (size
);
4296 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
, 2);
4298 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
<< 16, 4);
4300 if (insn
->opcode
[i
].unresolved
)
4301 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
,
4302 insn
->opcode
[i
].r_nchars
, &insn
->opcode
[i
].addr_expr
,
4303 FALSE
, insn
->opcode
[i
].r_type
);
4307 /* Convert the operand strings into appropriate opcode values
4308 return the total number of words used by the instruction. */
4316 /* Only non-parallel instructions support lk addressing. */
4317 if (!(insn
->tm
->flags
& FL_PAR
))
4319 for (i
= 0; i
< insn
->opcount
; i
++)
4321 if ((OPTYPE (insn
->operands
[i
].type
) == OP_Smem
4322 || OPTYPE (insn
->operands
[i
].type
) == OP_Lmem
4323 || OPTYPE (insn
->operands
[i
].type
) == OP_Sind
)
4324 && strchr (insn
->operands
[i
].buf
, '(')
4325 /* Don't mistake stack-relative addressing for lk addressing. */
4326 && strncasecmp (insn
->operands
[i
].buf
, "*sp (", 4) != 0)
4328 insn
->is_lkaddr
= 1;
4329 insn
->lkoperand
= i
;
4334 insn
->words
= insn
->tm
->words
+ insn
->is_lkaddr
;
4336 insn
->opcode
[0].word
= insn
->tm
->opcode
;
4337 if (insn
->tm
->flags
& FL_EXT
)
4338 insn
->opcode
[1 + insn
->is_lkaddr
].word
= insn
->tm
->opcode2
;
4340 for (i
= 0; i
< insn
->opcount
; i
++)
4342 enum optype type
= insn
->operands
[i
].type
;
4344 if (!encode_operand (insn
, type
, &insn
->operands
[i
]))
4347 if (insn
->tm
->flags
& FL_PAR
)
4348 for (i
= 0; i
< insn
->paropcount
; i
++)
4350 enum optype partype
= insn
->paroperands
[i
].type
;
4352 if (!encode_operand (insn
, partype
, &insn
->paroperands
[i
]))
4362 optimize_insn (insn
)
4365 /* Optimize some instructions, helping out the brain-dead programmer. */
4366 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4367 if (strcasecmp (insn
->tm
->name
, "add") == 0)
4369 if (insn
->opcount
> 1
4370 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4371 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4372 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4373 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4376 insn
->using_default_dst
= 1;
4380 /* Try to collapse if Xmem and shift count is zero. */
4381 if ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4382 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
4383 && is_zero (insn
->operands
[1]))
4384 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4385 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4386 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4387 && is_type (&insn
->operands
[1], OP_SHIFT
)
4388 && is_zero (insn
->operands
[1]) && insn
->opcount
== 3))
4390 insn
->operands
[1] = insn
->operands
[2];
4395 else if (strcasecmp (insn
->tm
->name
, "ld") == 0)
4397 if (insn
->opcount
== 3 && insn
->operands
[0].type
!= OP_SRC
)
4399 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4400 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4401 && is_zero (insn
->operands
[1])
4402 && (OPTYPE (insn
->tm
->operand_types
[0]) != OP_lk
4403 || (insn
->operands
[0].exp
.X_op
== O_constant
4404 && insn
->operands
[0].exp
.X_add_number
<= 255
4405 && insn
->operands
[0].exp
.X_add_number
>= 0)))
4407 insn
->operands
[1] = insn
->operands
[2];
4413 else if (strcasecmp (insn
->tm
->name
, "sth") == 0
4414 || strcasecmp (insn
->tm
->name
, "stl") == 0)
4416 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4417 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4418 && is_zero (insn
->operands
[1]))
4420 insn
->operands
[1] = insn
->operands
[2];
4425 else if (strcasecmp (insn
->tm
->name
, "sub") == 0)
4427 if (insn
->opcount
> 1
4428 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4429 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4430 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4431 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4434 insn
->using_default_dst
= 1;
4438 if ( ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4439 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
)
4440 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4441 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
))
4442 && is_zero (insn
->operands
[1])
4443 && insn
->opcount
== 3)
4445 insn
->operands
[1] = insn
->operands
[2];
4453 /* Find a matching template if possible, and get the operand strings. */
4456 tic54x_parse_insn (insn
, line
)
4460 insn
->tm
= (template *) hash_find (op_hash
, insn
->mnemonic
);
4463 as_bad (_("Unrecognized instruction \"%s\""), insn
->mnemonic
);
4467 insn
->opcount
= get_operands (insn
->operands
, line
);
4468 if (insn
->opcount
< 0)
4471 /* Check each variation of operands for this mnemonic. */
4472 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
, insn
->mnemonic
) == 0)
4474 if (insn
->opcount
>= insn
->tm
->minops
4475 && insn
->opcount
<= insn
->tm
->maxops
4476 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4477 insn
->tm
->operand_types
,
4478 insn
->tm
->minops
, insn
->tm
->maxops
))
4480 /* SUCCESS! now try some optimizations. */
4481 if (optimize_insn (insn
))
4483 insn
->tm
= (template *) hash_find (op_hash
,
4492 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4493 line
, insn
->mnemonic
);
4497 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4498 won't be able to see the next line. */
4499 static int parallel_on_next_line_hint
= 0;
4501 /* See if this is part of a parallel instruction
4502 Look for a subsequent line starting with "||". */
4505 next_line_shows_parallel (next_line
)
4508 /* Look for the second half. */
4509 while (ISSPACE (*next_line
))
4512 return (next_line
[0] == PARALLEL_SEPARATOR
4513 && next_line
[1] == PARALLEL_SEPARATOR
);
4517 tic54x_parse_parallel_insn_firstline (insn
, line
)
4521 insn
->tm
= (template *) hash_find (parop_hash
, insn
->mnemonic
);
4524 as_bad (_("Unrecognized parallel instruction \"%s\""),
4529 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4530 insn
->mnemonic
) == 0)
4532 insn
->opcount
= get_operands (insn
->operands
, line
);
4533 if (insn
->opcount
< 0)
4535 if (insn
->opcount
== 2
4536 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4537 insn
->tm
->operand_types
, 2, 2))
4543 /* Didn't find a matching parallel; try for a normal insn. */
4547 /* Parse the second line of a two-line parallel instruction. */
4550 tic54x_parse_parallel_insn_lastline (insn
, line
)
4554 int valid_mnemonic
= 0;
4556 insn
->paropcount
= get_operands (insn
->paroperands
, line
);
4557 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4558 insn
->mnemonic
) == 0)
4560 if (strcasecmp (insn
->tm
->parname
, insn
->parmnemonic
) == 0)
4564 if (insn
->paropcount
>= insn
->tm
->minops
4565 && insn
->paropcount
<= insn
->tm
->maxops
4566 && operands_match (insn
, insn
->paroperands
,
4568 insn
->tm
->paroperand_types
,
4569 insn
->tm
->minops
, insn
->tm
->maxops
))
4575 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4578 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4579 insn
->mnemonic
, insn
->parmnemonic
);
4584 /* If quotes found, return copy of line up to closing quote;
4585 otherwise up until terminator.
4586 If it's a string, pass as-is; otherwise attempt substitution symbol
4587 replacement on the value. */
4590 subsym_get_arg (line
, terminators
, str
, nosub
)
4598 int is_string
= *line
== '"';
4599 int is_char
= ISDIGIT (*line
);
4603 while (ISDIGIT (*ptr
))
4606 *str
= xmalloc (ptr
- line
+ 1);
4607 strncpy (*str
, line
, ptr
- line
);
4608 (*str
)[ptr
- line
] = 0;
4612 char *savedp
= input_line_pointer
;
4615 input_line_pointer
= ptr
;
4616 *str
= demand_copy_C_string (&len
);
4617 endp
= input_line_pointer
;
4618 input_line_pointer
= savedp
;
4620 /* Do forced substitutions if requested. */
4621 if (!nosub
&& **str
== ':')
4622 *str
= subsym_substitute (*str
, 1);
4626 char *term
= terminators
;
4629 while (*ptr
&& *ptr
!= *term
)
4640 *str
= xmalloc (ptr
- line
+ 1);
4641 strncpy (*str
, line
, ptr
- line
);
4642 (*str
)[ptr
- line
] = 0;
4643 /* Do simple substitution, if available. */
4644 if (!nosub
&& (value
= subsym_lookup (*str
, macro_level
)) != NULL
)
4651 /* Replace the given substitution string.
4652 We start at the innermost macro level, so that existing locals remain local
4653 Note: we're treating macro args identically to .var's; I don't know if
4654 that's compatible w/TI's assembler. */
4657 subsym_create_or_replace (name
, value
)
4663 for (i
= macro_level
; i
> 0; i
--)
4665 if (hash_find (subsym_hash
[i
], name
))
4667 hash_replace (subsym_hash
[i
], name
, value
);
4671 if (hash_find (subsym_hash
[0], name
))
4672 hash_replace (subsym_hash
[0], name
, value
);
4674 hash_insert (subsym_hash
[0], name
, value
);
4677 /* Look up the substitution string replacement for the given symbol.
4678 Start with the innermost macro substitution table given and work
4682 subsym_lookup (name
, nest_level
)
4686 char *value
= hash_find (subsym_hash
[nest_level
], name
);
4688 if (value
|| nest_level
== 0)
4691 return subsym_lookup (name
, nest_level
- 1);
4694 /* Do substitution-symbol replacement on the given line (recursively).
4695 return the argument if no substitution was done
4697 Also look for built-in functions ($func (arg)) and local labels.
4699 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4702 subsym_substitute (line
, forced
)
4706 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4707 replace it in the input. */
4708 char *replacement
; /* current replacement for LINE. */
4709 char *head
; /* Start of line. */
4710 char *ptr
; /* Current examination point. */
4711 int changed
= 0; /* Did we make a substitution? */
4712 int eval_line
= 0; /* Is this line a .eval/.asg statement? */
4713 int eval_symbol
= 0; /* Are we in the middle of the symbol for
4715 char *eval_end
= NULL
;
4717 int line_conditional
= 0;
4720 /* Work with a copy of the input line. */
4721 replacement
= xmalloc (strlen (line
) + 1);
4722 strcpy (replacement
, line
);
4724 ptr
= head
= replacement
;
4726 /* Flag lines where we might need to replace a single '=' with two;
4727 GAS uses single '=' to assign macro args values, and possibly other
4728 places, so limit what we replace. */
4729 if (strstr (line
, ".if")
4730 || strstr (line
, ".elseif")
4731 || strstr (line
, ".break"))
4732 line_conditional
= 1;
4734 /* Watch out for .eval, so that we avoid doing substitution on the
4735 symbol being assigned a value. */
4736 if (strstr (line
, ".eval") || strstr (line
, ".asg"))
4739 /* If it's a macro definition, don't do substitution on the argument
4741 if (strstr (line
, ".macro"))
4744 while (!is_end_of_line
[(int) *ptr
])
4746 int current_char
= *ptr
;
4748 /* Need to update this since LINE may have been modified. */
4750 eval_end
= strrchr (ptr
, ',');
4752 /* Replace triple double quotes with bounding quote/escapes. */
4753 if (current_char
== '"' && ptr
[1] == '"' && ptr
[2] == '"')
4756 tmp
= strstr (ptr
+ 2, "\"\"\"");
4762 /* Replace a single '=' with a '==';
4763 for compatibility with older code only. */
4764 if (line_conditional
&& current_char
== '=')
4772 tmp
= xmalloc (strlen (head
) + 2 + strlen (ptr
) + 1);
4773 sprintf (tmp
, "%s==%s", head
, ptr
);
4774 /* Continue examining after the '=='. */
4775 ptr
= tmp
+ strlen (head
) + 2;
4777 head
= replacement
= tmp
;
4781 /* Flag when we've reached the symbol part of .eval/.asg. */
4782 if (eval_line
&& ptr
>= eval_end
)
4785 /* For each apparent symbol, see if it's a substitution symbol, and if
4786 so, replace it in the input. */
4787 if ((forced
&& current_char
== ':')
4788 || (!forced
&& is_name_beginner (current_char
)))
4790 char *name
; /* Symbol to be replaced. */
4791 char *savedp
= input_line_pointer
;
4794 char *tail
; /* Rest of line after symbol. */
4796 /* Skip the colon. */
4800 name
= input_line_pointer
= ptr
;
4801 c
= get_symbol_end ();
4802 /* '?' is not normally part of a symbol, but it IS part of a local
4806 *input_line_pointer
++ = c
;
4807 c
= *input_line_pointer
;
4808 *input_line_pointer
= '\0';
4810 /* Avoid infinite recursion; if a symbol shows up a second time for
4811 substitution, leave it as is. */
4812 if (hash_find (subsym_recurse_hash
, name
) == NULL
)
4813 value
= subsym_lookup (name
, macro_level
);
4815 as_warn (_("%s symbol recursion stopped at "
4816 "second appearance of '%s'"),
4817 forced
? "Forced substitution" : "Substitution", name
);
4818 ptr
= tail
= input_line_pointer
;
4819 input_line_pointer
= savedp
;
4821 /* Check for local labels; replace them with the appropriate
4823 if ((*name
== '$' && ISDIGIT (name
[1]) && name
[2] == '\0')
4824 || name
[strlen (name
) - 1] == '?')
4826 /* Use an existing identifier for that label if, available, or
4827 create a new, unique identifier. */
4828 value
= hash_find (local_label_hash
[macro_level
], name
);
4832 char *namecopy
= strcpy (xmalloc (strlen (name
) + 1), name
);
4834 value
= strcpy (xmalloc (strlen (name
) + sizeof (digit
) + 1),
4837 value
[strlen (value
) - 1] = '\0';
4838 sprintf (digit
, ".%d", local_label_id
++);
4839 strcat (value
, digit
);
4840 hash_insert (local_label_hash
[macro_level
], namecopy
, value
);
4842 /* Indicate where to continue looking for substitutions. */
4845 /* Check for built-in subsym and math functions. */
4846 else if (value
!= NULL
&& *name
== '$')
4848 subsym_proc_entry
*entry
= (subsym_proc_entry
*) value
;
4849 math_proc_entry
*math_entry
= hash_find (math_hash
, name
);
4850 char *arg1
, *arg2
= NULL
;
4855 as_bad (_("Unrecognized substitution symbol function"));
4858 else if (*ptr
!= '(')
4860 as_bad (_("Missing '(' after substitution symbol function"));
4864 if (math_entry
!= NULL
)
4866 float arg1
, arg2
= 0;
4867 volatile float fresult
;
4869 arg1
= (float) strtod (ptr
, &ptr
);
4870 if (math_entry
->nargs
== 2)
4874 as_bad (_("Expecting second argument"));
4877 arg2
= (float) strtod (ptr
, &ptr
);
4879 fresult
= (*math_entry
->proc
) (arg1
, arg2
);
4880 value
= xmalloc (128);
4881 if (math_entry
->int_return
)
4882 sprintf (value
, "%d", (int) fresult
);
4884 sprintf (value
, "%f", fresult
);
4887 as_bad (_("Extra junk in function call, expecting ')'"));
4890 /* Don't bother recursing; the replacement isn't a
4897 int arg_type
[2] = { *ptr
== '"' , 0 };
4898 int ismember
= !strcmp (entry
->name
, "$ismember");
4900 /* Parse one or two args, which must be a substitution
4901 symbol, string or a character-string constant. */
4902 /* For all functions, a string or substitution symbol may be
4903 used, with the following exceptions:
4904 firstch/lastch: 2nd arg must be character constant
4905 ismember: both args must be substitution symbols. */
4906 ptr
= subsym_get_arg (ptr
, ",)", &arg1
, ismember
);
4909 if (entry
->nargs
== 2)
4913 as_bad (_("Function expects two arguments"));
4916 /* Character constants are converted to numerics
4917 by the preprocessor. */
4918 arg_type
[1] = (ISDIGIT (*ptr
)) ? 2 : (*ptr
== '"');
4919 ptr
= subsym_get_arg (ptr
, ")", &arg2
, ismember
);
4921 /* Args checking. */
4922 if ((!strcmp (entry
->name
, "$firstch")
4923 || !strcmp (entry
->name
, "$lastch"))
4924 && arg_type
[1] != 2)
4926 as_bad (_("Expecting character constant argument"));
4930 && (arg_type
[0] != 0 || arg_type
[1] != 0))
4932 as_bad (_("Both arguments must be substitution symbols"));
4937 as_bad (_("Extra junk in function call, expecting ')'"));
4940 val
= (*entry
->proc
) (arg1
, arg2
);
4941 value
= xmalloc (64);
4942 sprintf (value
, "%d", val
);
4944 /* Fix things up to replace the entire expression, not just the
4950 if (value
!= NULL
&& !eval_symbol
)
4952 /* Replace the symbol with its string replacement and
4953 continue. Recursively replace VALUE until either no
4954 substitutions are performed, or a substitution that has been
4955 previously made is encountered again.
4957 put the symbol into the recursion hash table so we only
4958 try to replace a symbol once. */
4961 hash_insert (subsym_recurse_hash
, name
, name
);
4962 value
= subsym_substitute (value
, macro_level
> 0);
4963 hash_delete (subsym_recurse_hash
, name
);
4966 /* Temporarily zero-terminate where the symbol started. */
4972 /* Subscripted substitution symbol -- use just the
4973 indicated portion of the string; the description
4974 kinda indicates that forced substitution is not
4975 supposed to be recursive, but I'm not sure. */
4976 unsigned beg
, len
= 1; /* default to a single char */
4977 char *newval
= strcpy (xmalloc (strlen (value
) + 1),
4980 savedp
= input_line_pointer
;
4981 input_line_pointer
= tail
+ 1;
4982 beg
= get_absolute_expression ();
4985 as_bad (_("Invalid subscript (use 1 to %d)"),
4986 (int) strlen (value
));
4989 if (*input_line_pointer
== ',')
4991 ++input_line_pointer
;
4992 len
= get_absolute_expression ();
4993 if (beg
+ len
> strlen (value
))
4995 as_bad (_("Invalid length (use 0 to %d"),
4996 (int) strlen (value
) - beg
);
5002 tail
= input_line_pointer
;
5005 as_bad (_("Missing ')' in subscripted substitution "
5006 "symbol expression"));
5010 input_line_pointer
= savedp
;
5016 tmp
= xmalloc (strlen (head
) + strlen (value
) +
5017 strlen (tail
+ 1) + 2);
5019 strcat (tmp
, value
);
5020 /* Make sure forced substitutions are properly terminated. */
5025 as_bad (_("Missing forced substitution terminator ':'"));
5031 /* Restore the character after the symbol end. */
5034 /* Continue examining after the replacement value. */
5035 ptr
= tmp
+ strlen (head
) + strlen (value
);
5037 head
= replacement
= tmp
;
5055 /* We use this to handle substitution symbols
5056 hijack input_line_pointer, replacing it with our substituted string.
5058 .sslist should enable listing the line after replacements are made...
5060 returns the new buffer limit. */
5063 tic54x_start_line_hook ()
5066 char *replacement
= NULL
;
5068 /* Work with a copy of the input line, including EOL char. */
5069 endp
= input_line_pointer
;
5070 while (!is_end_of_line
[(int) *endp
++])
5072 line
= xmalloc (endp
- input_line_pointer
+ 1);
5073 strncpy (line
, input_line_pointer
, endp
- input_line_pointer
+ 1);
5074 line
[endp
- input_line_pointer
] = 0;
5076 /* Scan ahead for parallel insns. */
5077 parallel_on_next_line_hint
= next_line_shows_parallel (endp
+ 1);
5079 /* If within a macro, first process forced replacements. */
5080 if (macro_level
> 0)
5081 replacement
= subsym_substitute (line
, 1);
5084 replacement
= subsym_substitute (replacement
, 0);
5086 if (replacement
!= line
)
5088 char *tmp
= replacement
;
5089 char *comment
= strchr (replacement
, ';');
5090 char endc
= replacement
[strlen (replacement
) - 1];
5092 /* Clean up the replacement; we'd prefer to have this done by the
5093 standard preprocessing equipment (maybe do_scrub_chars?)
5094 but for now, do a quick-and-dirty. */
5095 if (comment
!= NULL
)
5102 comment
= replacement
+ strlen (replacement
) - 1;
5104 /* Trim trailing whitespace. */
5105 while (ISSPACE (*comment
))
5112 /* Compact leading whitespace. */
5113 while (ISSPACE (tmp
[0]) && ISSPACE (tmp
[1]))
5116 input_line_pointer
= endp
;
5117 input_scrub_insert_line (tmp
);
5120 /* Keep track of whether we've done a substitution. */
5121 substitution_line
= 1;
5127 substitution_line
= 0;
5131 /* This is the guts of the machine-dependent assembler. STR points to a
5132 machine dependent instruction. This function is supposed to emit
5133 the frags/bytes it assembles to. */
5138 static int repeat_slot
= 0;
5139 static int delay_slots
= 0; /* How many delay slots left to fill? */
5140 static int is_parallel
= 0;
5141 static tic54x_insn insn
;
5143 char *savedp
= input_line_pointer
;
5146 input_line_pointer
= line
;
5147 c
= get_symbol_end ();
5151 if (address_mode_needs_set
)
5153 set_address_mode (amode
);
5154 address_mode_needs_set
= 0;
5167 strcpy (insn
.parmnemonic
, line
);
5168 lptr
= input_line_pointer
;
5170 input_line_pointer
= savedp
;
5172 if (tic54x_parse_parallel_insn_lastline (&insn
, lptr
))
5174 int words
= build_insn (&insn
);
5176 if (delay_slots
!= 0)
5178 if (words
> delay_slots
)
5180 as_bad (_("Instruction does not fit in available delay "
5181 "slots (%d-word insn, %d slots left)"),
5182 words
, delay_slots
);
5186 delay_slots
-= words
;
5192 memset (&insn
, 0, sizeof (insn
));
5193 strcpy (insn
.mnemonic
, line
);
5194 lptr
= input_line_pointer
;
5196 input_line_pointer
= savedp
;
5198 /* See if this line is part of a parallel instruction; if so, either this
5199 line or the next line will have the "||" specifier preceding the
5200 mnemonic, and we look for it in the parallel insn hash table. */
5201 if (strstr (line
, "||") != NULL
|| parallel_on_next_line_hint
)
5203 char *tmp
= strstr (line
, "||");
5207 if (tic54x_parse_parallel_insn_firstline (&insn
, lptr
))
5210 /* If the parallel part is on the same line, process it now,
5211 otherwise let the assembler pick up the next line for us. */
5214 while (ISSPACE (tmp
[2]))
5216 md_assemble (tmp
+ 2);
5221 as_bad (_("Unrecognized parallel instruction '%s'"), line
);
5226 if (tic54x_parse_insn (&insn
, lptr
))
5230 if ((insn
.tm
->flags
& FL_LP
)
5231 && cpu
!= V545LP
&& cpu
!= V546LP
)
5233 as_bad (_("Instruction '%s' requires an LP cpu version"),
5237 if ((insn
.tm
->flags
& FL_FAR
)
5238 && amode
!= far_mode
)
5240 as_bad (_("Instruction '%s' requires far mode addressing"),
5245 words
= build_insn (&insn
);
5247 /* Is this instruction in a delay slot? */
5250 if (words
> delay_slots
)
5252 as_warn (_("Instruction does not fit in available delay "
5253 "slots (%d-word insn, %d slots left). "
5254 "Resulting behavior is undefined."),
5255 words
, delay_slots
);
5259 /* Branches in delay slots are not allowed. */
5260 if (insn
.tm
->flags
& FL_BMASK
)
5262 as_warn (_("Instructions which cause PC discontinuity are not "
5263 "allowed in a delay slot. "
5264 "Resulting behavior is undefined."));
5266 delay_slots
-= words
;
5269 /* Is this instruction the target of a repeat? */
5272 if (insn
.tm
->flags
& FL_NR
)
5273 as_warn (_("'%s' is not repeatable. "
5274 "Resulting behavior is undefined."),
5276 else if (insn
.is_lkaddr
)
5277 as_warn (_("Instructions using long offset modifiers or absolute "
5278 "addresses are not repeatable. "
5279 "Resulting behavior is undefined."));
5283 /* Make sure we check the target of a repeat instruction. */
5284 if (insn
.tm
->flags
& B_REPEAT
)
5287 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5289 /* Make sure we check our delay slots for validity. */
5290 if (insn
.tm
->flags
& FL_DELAY
)
5293 /* FIXME -- warn if delay_slots != 0 at EOF. */
5298 /* Do a final adjustment on the symbol table; in this case, make sure we have
5299 a ".file" symbol. */
5302 tic54x_adjust_symtab ()
5304 if (symbol_rootP
== NULL
5305 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
5309 as_where (&filename
, &lineno
);
5310 c_dot_file_symbol (filename
, 0);
5314 /* In order to get gas to ignore any | chars at the start of a line,
5315 this function returns true if a | is found in a line.
5316 This lets us process parallel instructions, which span two lines. */
5319 tic54x_unrecognized_line (int c
)
5321 return c
== PARALLEL_SEPARATOR
;
5324 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5325 Encode their names so that only we see them and can map them to the
5327 FIXME -- obviously this isn't done yet. These locals still show up in the
5330 tic54x_define_label (sym
)
5333 /* Just in case we need this later; note that this is not necessarily the
5334 same thing as line_label...
5335 When aligning or assigning labels to fields, sometimes the label is
5336 assigned other than the address at which the label appears.
5337 FIXME -- is this really needed? I think all the proper label assignment
5338 is done in tic54x_cons. */
5339 last_label_seen
= sym
;
5342 /* Try to parse something that normal parsing failed at. */
5345 tic54x_undefined_symbol (name
)
5350 /* Not sure how to handle predefined symbols. */
5351 if ((sym
= (symbol
*) hash_find (cc_hash
, name
)) != NULL
||
5352 (sym
= (symbol
*) hash_find (cc2_hash
, name
)) != NULL
||
5353 (sym
= (symbol
*) hash_find (cc3_hash
, name
)) != NULL
||
5354 (sym
= (symbol
*) hash_find (misc_symbol_hash
, name
)) != NULL
||
5355 (sym
= (symbol
*) hash_find (sbit_hash
, name
)) != NULL
)
5357 return symbol_new (name
, reg_section
,
5358 (valueT
) sym
->value
,
5359 &zero_address_frag
);
5362 if ((sym
= (symbol
*) hash_find (reg_hash
, name
)) != NULL
||
5363 (sym
= (symbol
*) hash_find (mmreg_hash
, name
)) != NULL
||
5364 !strcasecmp (name
, "a") || !strcasecmp (name
, "b"))
5366 return symbol_new (name
, reg_section
,
5367 (valueT
) sym
? sym
->value
: 0,
5368 &zero_address_frag
);
5374 /* Parse a name in an expression before the expression parser takes a stab at
5378 tic54x_parse_name (name
, exp
)
5379 char *name ATTRIBUTE_UNUSED
;
5380 expressionS
*exp ATTRIBUTE_UNUSED
;
5386 md_atof (type
, literalP
, sizeP
)
5391 #define MAX_LITTLENUMS 2
5392 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5393 LITTLENUM_TYPE
*word
;
5394 /* Only one precision on the c54x. */
5396 char *t
= atof_ieee (input_line_pointer
, type
, words
);
5398 input_line_pointer
= t
;
5401 /* Target data is little-endian, but floats are stored
5402 big-"word"ian. ugh. */
5403 for (word
= words
; prec
--;)
5405 md_number_to_chars (literalP
, (long) (*word
++), sizeof (LITTLENUM_TYPE
));
5406 literalP
+= sizeof (LITTLENUM_TYPE
);
5413 tc_gen_reloc (section
, fixP
)
5418 bfd_reloc_code_real_type code
= fixP
->fx_r_type
;
5419 asymbol
*sym
= symbol_get_bfdsym (fixP
->fx_addsy
);
5421 rel
= (arelent
*) xmalloc (sizeof (arelent
));
5422 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5423 *rel
->sym_ptr_ptr
= sym
;
5424 /* We assume that all rel->address are host byte offsets. */
5425 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5426 rel
->address
/= OCTETS_PER_BYTE
;
5427 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5428 if (!strcmp (sym
->name
, section
->name
))
5429 rel
->howto
+= HOWTO_BANK
;
5433 const char *name
= S_GET_NAME (fixP
->fx_addsy
);
5436 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5437 name
, bfd_get_reloc_code_name (code
));
5443 /* Handle cons expressions. */
5446 tic54x_cons_fix_new (frag
, where
, octets
, exp
)
5452 bfd_reloc_code_real_type r
;
5457 as_bad (_("Unsupported relocation size %d"), octets
);
5458 r
= BFD_RELOC_TIC54X_16_OF_23
;
5461 r
= BFD_RELOC_TIC54X_16_OF_23
;
5464 /* TI assembler always uses this, regardless of addressing mode. */
5466 r
= BFD_RELOC_TIC54X_23
;
5468 /* We never want to directly generate this; this is provided for
5469 stabs support only. */
5473 fix_new_exp (frag
, where
, octets
, exp
, 0, r
);
5476 /* Attempt to simplify or even eliminate a fixup.
5477 To indicate that a fixup has been eliminated, set fixP->fx_done.
5479 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5482 md_apply_fix (fixP
, valP
, seg
)
5485 segT seg ATTRIBUTE_UNUSED
;
5487 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5488 valueT val
= * valP
;
5490 switch (fixP
->fx_r_type
)
5493 as_fatal ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
5495 case BFD_RELOC_TIC54X_MS7_OF_23
:
5496 val
= (val
>> 16) & 0x7F;
5498 case BFD_RELOC_TIC54X_16_OF_23
:
5500 bfd_put_16 (stdoutput
, val
, buf
);
5501 /* Indicate what we're actually writing, so that we don't get warnings
5502 about exceeding available space. */
5503 *valP
= val
& 0xFFFF;
5505 case BFD_RELOC_TIC54X_PARTLS7
:
5506 bfd_put_16 (stdoutput
,
5507 (bfd_get_16 (stdoutput
, buf
) & 0xFF80) | (val
& 0x7F),
5509 /* Indicate what we're actually writing, so that we don't get warnings
5510 about exceeding available space. */
5513 case BFD_RELOC_TIC54X_PARTMS9
:
5514 /* TI assembler doesn't shift its encoding for relocatable files, and is
5515 thus incompatible with this implementation's relocatable files. */
5516 bfd_put_16 (stdoutput
,
5517 (bfd_get_16 (stdoutput
, buf
) & 0xFE00) | (val
>> 7),
5521 case BFD_RELOC_TIC54X_23
:
5522 bfd_put_32 (stdoutput
,
5523 (bfd_get_32 (stdoutput
, buf
) & 0xFF800000) | val
,
5528 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
5532 /* This is our chance to record section alignment
5533 don't need to do anything here, since BFD does the proper encoding. */
5536 md_section_align (segment
, section_size
)
5537 segT segment ATTRIBUTE_UNUSED
;
5538 valueT section_size
;
5540 return section_size
;
5544 md_pcrel_from (fixP
)
5545 fixS
*fixP ATTRIBUTE_UNUSED
;
5550 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5554 tic54x_number_to_chars (buf
, val
, n
)
5560 number_to_chars_littleendian (buf
, val
, n
);
5563 number_to_chars_littleendian (buf
, val
>> 16 , 2);
5564 number_to_chars_littleendian (buf
+ 2, val
& 0xFFFF, 2);
5569 tic54x_estimate_size_before_relax (frag
, seg
)
5570 fragS
*frag ATTRIBUTE_UNUSED
;
5571 segT seg ATTRIBUTE_UNUSED
;
5576 /* We use this to handle bit allocations which we couldn't handle before due
5577 to symbols being in different frags. return number of octets added. */
5580 tic54x_relax_frag (frag
, stretch
)
5582 long stretch ATTRIBUTE_UNUSED
;
5584 symbolS
*sym
= frag
->fr_symbol
;
5590 struct bit_info
*bi
= (struct bit_info
*) frag
->fr_opcode
;
5591 int bit_offset
= frag_bit_offset (frag_prev (frag
, bi
->seg
), bi
->seg
);
5592 int size
= S_GET_VALUE (sym
);
5593 fragS
*prev_frag
= bit_offset_frag (frag_prev (frag
, bi
->seg
), bi
->seg
);
5594 int available
= 16 - bit_offset
;
5596 if (symbol_get_frag (sym
) != &zero_address_frag
5597 || S_IS_COMMON (sym
)
5598 || !S_IS_DEFINED (sym
))
5599 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5600 _("non-absolute value used with .space/.bes"));
5604 as_warn (_("negative value ignored in %s"),
5605 bi
->type
== TYPE_SPACE
? ".space" :
5606 bi
->type
== TYPE_BES
? ".bes" : ".field");
5608 frag
->tc_frag_data
= frag
->fr_fix
= 0;
5612 if (bi
->type
== TYPE_FIELD
)
5614 /* Bit fields of 16 or larger will have already been handled. */
5615 if (bit_offset
!= 0 && available
>= size
)
5617 char *p
= prev_frag
->fr_literal
;
5619 valueT value
= bi
->value
;
5620 value
<<= available
- size
;
5621 value
|= ((unsigned short) p
[1] << 8) | p
[0];
5622 md_number_to_chars (p
, value
, 2);
5623 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5624 prev_frag
->tc_frag_data
= 0;
5626 symbol_set_frag (bi
->sym
, prev_frag
);
5627 /* This frag is no longer used. */
5628 growth
= -frag
->fr_fix
;
5630 frag
->tc_frag_data
= 0;
5634 char *p
= frag
->fr_literal
;
5636 valueT value
= bi
->value
<< (16 - size
);
5637 md_number_to_chars (p
, value
, 2);
5638 if ((frag
->tc_frag_data
= size
) == 16)
5639 frag
->tc_frag_data
= 0;
5645 if (bit_offset
!= 0 && bit_offset
< 16)
5647 if (available
>= size
)
5649 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5650 prev_frag
->tc_frag_data
= 0;
5652 symbol_set_frag (bi
->sym
, prev_frag
);
5653 /* This frag is no longer used. */
5654 growth
= -frag
->fr_fix
;
5656 frag
->tc_frag_data
= 0;
5659 if (bi
->type
== TYPE_SPACE
&& bi
->sym
)
5660 symbol_set_frag (bi
->sym
, prev_frag
);
5663 growth
= (size
+ 15) / 16 * OCTETS_PER_BYTE
- frag
->fr_fix
;
5664 for (i
= 0; i
< growth
; i
++)
5665 frag
->fr_literal
[i
] = 0;
5666 frag
->fr_fix
= growth
;
5667 frag
->tc_frag_data
= size
% 16;
5668 /* Make sure any BES label points to the LAST word allocated. */
5669 if (bi
->type
== TYPE_BES
&& bi
->sym
)
5670 S_SET_VALUE (bi
->sym
, frag
->fr_fix
/ OCTETS_PER_BYTE
- 1);
5673 frag
->fr_symbol
= 0;
5674 frag
->fr_opcode
= 0;
5681 tic54x_convert_frag (abfd
, seg
, frag
)
5682 bfd
*abfd ATTRIBUTE_UNUSED
;
5683 segT seg ATTRIBUTE_UNUSED
;
5686 /* Offset is in bytes. */
5687 frag
->fr_offset
= (frag
->fr_next
->fr_address
5689 - frag
->fr_fix
) / frag
->fr_var
;
5690 if (frag
->fr_offset
< 0)
5692 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5693 _("attempt to .space/.bes backwards? (%ld)"),
5694 (long) frag
->fr_offset
);
5696 frag
->fr_type
= rs_space
;
5699 /* We need to avoid having labels defined for certain directives/pseudo-ops
5700 since once the label is defined, it's in the symbol table for good. TI
5701 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5702 I guess, except I've never seen a definition of MRI syntax).
5704 C is the character that used to be at *REST, which points to the end of the
5707 Don't allow labels to start with '.' */
5710 tic54x_start_label (c
, rest
)
5714 /* If within .struct/.union, no auto line labels, please. */
5715 if (current_stag
!= NULL
)
5718 /* Disallow labels starting with "." */
5723 while (!is_end_of_line
[(int) label
[-1]])
5727 as_bad (_("Invalid label '%s'"), label
);
5732 if (is_end_of_line
[(int) c
])
5736 while (ISSPACE (c
= *++rest
))
5740 /* Don't let colon () define a label for any of these... */
5741 return (strncasecmp (rest
, ".tag", 4) != 0 || !ISSPACE (rest
[4]))
5742 && (strncasecmp (rest
, ".struct", 7) != 0 || !ISSPACE (rest
[7]))
5743 && (strncasecmp (rest
, ".union", 6) != 0 || !ISSPACE (rest
[6]))
5744 && (strncasecmp (rest
, ".macro", 6) != 0 || !ISSPACE (rest
[6]))
5745 && (strncasecmp (rest
, ".set", 4) != 0 || !ISSPACE (rest
[4]))
5746 && (strncasecmp (rest
, ".equ", 4) != 0 || !ISSPACE (rest
[4]));