1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Timothy Wall (twall@cygnus.com)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* Texas Instruments TMS320C54X machine specific gas.
23 Written by Timothy Wall (twall@alum.mit.edu).
25 Valuable things to do:
26 Pipeline conflict warnings
27 We encode/decode "ld #_label, dp" differently in relocatable files
28 This means we're not compatible with TI output containing those
29 expressions. We store the upper nine bits; TI stores the lower nine
30 bits. How they recover the original upper nine bits is beyond me.
32 Tests to add to expect testsuite:
33 '=' and '==' with .if, .elseif, and .break
35 Incompatibilities (mostly trivial):
37 We fill text section with zeroes instead of "nop"s
38 We don't convert '' or "" to a single instance
39 We don't convert '' to '\0'
40 We don't allow strings with .byte/.half/.short/.long
41 Probably details of the subsym stuff are different
42 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
44 COFF1 limits section names to 8 characters.
45 Some of the default behavior changed from COFF1 to COFF2. */
51 #include "safe-ctype.h"
55 #include "struc-symbol.h"
56 #include "opcode/tic54x.h"
63 symbolS
*sym
; /* Symbol for this stag; value is offset. */
64 const char *name
; /* Shortcut to symbol name. */
65 bfd_vma size
; /* Size of struct/union. */
66 int current_bitfield_offset
; /* Temporary for tracking fields. */
68 struct stag_field
/* List of fields. */
71 bfd_vma offset
; /* Of start of this field. */
72 int bitfield_offset
; /* Of start of this field. */
73 struct stag
*stag
; /* If field is struct/union. */
74 struct stag_field
*next
;
76 /* For nesting; used only in stag construction. */
77 struct stag
*inner
; /* Enclosed .struct. */
78 struct stag
*outer
; /* Enclosing .struct. */
79 } *current_stag
= NULL
;
81 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
83 typedef struct _tic54x_insn
85 const template *tm
; /* Opcode template. */
87 char mnemonic
[MAX_LINE
]; /* Opcode name/mnemonic. */
88 char parmnemonic
[MAX_LINE
]; /* 2nd mnemonic of parallel insn. */
96 } operands
[MAX_OPERANDS
];
99 struct opstruct paroperands
[MAX_OPERANDS
];
103 int words
; /* Size of insn in 16-bit words. */
104 int using_default_dst
; /* Do we need to explicitly set an
105 omitted OP_DST operand? */
108 unsigned short word
; /* Final encoded opcode data. */
110 int r_nchars
; /* Relocation size. */
111 bfd_reloc_code_real_type r_type
; /* Relocation type. */
112 expressionS addr_expr
; /* Storage for unresolved expressions. */
118 VNONE
= 0, V541
= 1, V542
= 2, V543
= 3, V545
= 5, V548
= 8, V549
= 9,
119 V545LP
= 15, V546LP
= 16
124 c_mode
, /* 16-bit addresses. */
125 far_mode
/* >16-bit addresses. */
128 static segT stag_saved_seg
;
129 static subsegT stag_saved_subseg
;
131 const char comment_chars
[] = ";";
132 const char line_comment_chars
[] = ";*#"; /* At column zero only. */
133 const char line_separator_chars
[] = ""; /* Not permitted. */
135 int emitting_long
= 0;
137 /* Characters which indicate that this is a floating point constant. */
138 const char FLT_CHARS
[] = "fF";
140 /* Characters that can be used to separate mantissa from exp in FP
142 const char EXP_CHARS
[] = "eE";
144 const char *md_shortopts
= "";
146 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
147 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
148 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
149 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
151 struct option md_longopts
[] =
153 { "mfar-mode", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
154 { "mf", no_argument
, NULL
, OPTION_ADDRESS_MODE
},
155 { "mcpu", required_argument
, NULL
, OPTION_CPU_VERSION
},
157 { "mcoff-version", required_argument
, NULL
, OPTION_COFF_VERSION
},
159 { "merrors-to-file", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
160 { "me", required_argument
, NULL
, OPTION_STDERR_TO_FILE
},
161 { NULL
, no_argument
, NULL
, 0},
164 size_t md_longopts_size
= sizeof (md_longopts
);
166 static int assembly_begun
= 0;
167 /* Addressing mode is not entirely implemented; the latest rev of the Other
168 assembler doesn't seem to make any distinction whatsoever; all relocations
169 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
170 but now it seems all relocations are RELEXT16. We use all RELEXT16.
172 The cpu version is kind of a waste of time as well. There is one
173 instruction (RND) for LP devices only, and several for devices with
174 extended addressing only. We include it for compatibility. */
175 static enum address_mode amode
= c_mode
;
176 static enum cpu_version cpu
= VNONE
;
178 /* Include string substitutions in listing? */
179 static int listing_sslist
= 0;
181 /* Did we do subsym substitutions on the line? */
182 static int substitution_line
= 0;
184 /* Last label seen. */
185 static symbolS
*last_label_seen
= NULL
;
187 /* This ensures that all new labels are unique. */
188 static int local_label_id
;
190 static struct hash_control
*subsym_recurse_hash
; /* Prevent infinite recurse. */
191 static struct hash_control
*math_hash
; /* Built-in math functions. */
192 /* Allow maximum levels of macro nesting; level 0 is the main substitution
193 symbol table. The other assembler only does 32 levels, so there! */
194 static struct hash_control
*subsym_hash
[100];
196 /* Keep track of local labels so we can substitute them before GAS sees them
197 since macros use their own 'namespace' for local labels, use a separate hash
199 We do our own local label handling 'cuz it's subtly different from the
202 We use our own macro nesting counter, since GAS overloads it when expanding
203 other things (like conditionals and repeat loops). */
204 static int macro_level
= 0;
205 static struct hash_control
*local_label_hash
[100];
206 /* Keep track of struct/union tags. */
207 static struct hash_control
*stag_hash
;
208 static struct hash_control
*op_hash
;
209 static struct hash_control
*parop_hash
;
210 static struct hash_control
*reg_hash
;
211 static struct hash_control
*mmreg_hash
;
212 static struct hash_control
*cc_hash
;
213 static struct hash_control
*cc2_hash
;
214 static struct hash_control
*cc3_hash
;
215 static struct hash_control
*sbit_hash
;
216 static struct hash_control
*misc_symbol_hash
;
218 /* Only word (et al.), align, or conditionals are allowed within
220 #define ILLEGAL_WITHIN_STRUCT() \
222 if (current_stag != NULL) \
224 as_bad (_("pseudo-op illegal within .struct/.union")); \
229 static void tic54x_emit_char
PARAMS ((char));
230 static fragS
* frag_prev
PARAMS ((fragS
*, segT
));
231 static fragS
* bit_offset_frag
PARAMS ((fragS
*, segT
));
232 static int frag_bit_offset
PARAMS ((fragS
*, segT
));
233 static char * parse_expression
PARAMS ((char *, expressionS
*));
234 static void tic54x_asg
PARAMS ((int));
235 static void tic54x_eval
PARAMS ((int));
236 static void tic54x_bss
PARAMS ((int));
237 static void stag_add_field_symbols
PARAMS ((struct stag
*, const char *, bfd_vma
, symbolS
*, const char *));
238 static void stag_add_field
PARAMS ((struct stag
*, const char *, bfd_vma
, struct stag
*));
239 static void tic54x_struct
PARAMS ((int));
240 static void tic54x_endstruct
PARAMS ((int));
241 static void tic54x_tag
PARAMS ((int));
242 static void tic54x_struct_field
PARAMS ((int));
243 static void tic54x_cons
PARAMS ((int));
244 static void tic54x_remove_local_label
PARAMS ((const char *, PTR
));
245 static void tic54x_clear_local_labels
PARAMS ((int));
246 static void tic54x_sect
PARAMS ((int));
247 static void tic54x_space
PARAMS ((int));
248 static void tic54x_usect
PARAMS ((int));
249 static enum cpu_version lookup_version
PARAMS ((const char *));
250 static void set_cpu
PARAMS ((enum cpu_version
));
251 static void tic54x_version
PARAMS ((int));
252 static void tic54x_float_cons
PARAMS ((int));
253 static void tic54x_stringer
PARAMS ((int));
254 static void tic54x_p2align
PARAMS ((int));
255 static void tic54x_align_words
PARAMS ((int));
256 static void tic54x_field
PARAMS ((int));
257 static int tic54x_initialized_section
PARAMS ((segT
));
258 static void tic54x_clink
PARAMS ((int));
259 static void tic54x_set_default_include
PARAMS ((int));
260 static void tic54x_include
PARAMS ((int));
261 static void tic54x_message
PARAMS ((int));
262 static void tic54x_label
PARAMS ((int));
263 static void tic54x_mmregs
PARAMS ((int));
264 static void tic54x_loop
PARAMS ((int));
265 static void tic54x_endloop
PARAMS ((int));
266 static void tic54x_break
PARAMS ((int));
267 static void set_address_mode
PARAMS ((int));
268 static void tic54x_address_mode
PARAMS ((int));
269 static void tic54x_sblock
PARAMS ((int));
270 static void tic54x_set
PARAMS ((int));
271 static void tic54x_fclist
PARAMS ((int));
272 static void tic54x_sslist
PARAMS ((int));
273 static void tic54x_var
PARAMS ((int));
274 static void tic54x_mlib
PARAMS ((int));
275 static int subsym_symlen
PARAMS ((char *, char *));
276 static int subsym_symcmp
PARAMS ((char *, char *));
277 static int subsym_firstch
PARAMS ((char *, char *));
278 static int subsym_lastch
PARAMS ((char *, char *));
279 static int subsym_isdefed
PARAMS ((char *, char *));
280 static int subsym_ismember
PARAMS ((char *, char *));
281 static int subsym_iscons
PARAMS ((char *, char *));
282 static int subsym_isname
PARAMS ((char *, char *));
283 static int subsym_isreg
PARAMS ((char *, char *));
284 static int subsym_structsz
PARAMS ((char *, char *));
285 static int subsym_structacc
PARAMS ((char *, char *));
286 static float math_ceil
PARAMS ((float, float));
287 static float math_cvi
PARAMS ((float, float));
288 static float math_floor
PARAMS ((float, float));
289 static float math_fmod
PARAMS ((float, float));
290 static float math_int
PARAMS ((float, float));
291 static float math_round
PARAMS ((float, float));
292 static float math_sgn
PARAMS ((float, float));
293 static float math_trunc
PARAMS ((float, float));
294 static float math_acos
PARAMS ((float, float));
295 static float math_asin
PARAMS ((float, float));
296 static float math_atan
PARAMS ((float, float));
297 static float math_atan2
PARAMS ((float, float));
298 static float math_cosh
PARAMS ((float, float));
299 static float math_cos
PARAMS ((float, float));
300 static float math_cvf
PARAMS ((float, float));
301 static float math_exp
PARAMS ((float, float));
302 static float math_fabs
PARAMS ((float, float));
303 static float math_ldexp
PARAMS ((float, float));
304 static float math_log10
PARAMS ((float, float));
305 static float math_log
PARAMS ((float, float));
306 static float math_max
PARAMS ((float, float));
307 static float math_min
PARAMS ((float, float));
308 static float math_pow
PARAMS ((float, float));
309 static float math_sin
PARAMS ((float, float));
310 static float math_sinh
PARAMS ((float, float));
311 static float math_sqrt
PARAMS ((float, float));
312 static float math_tan
PARAMS ((float, float));
313 static float math_tanh
PARAMS ((float, float));
314 static int is_accumulator
PARAMS ((struct opstruct
*));
315 static int get_operands
PARAMS ((struct opstruct operands
[], char *));
316 static int is_immediate
PARAMS ((struct opstruct
*));
317 static int is_absolute
PARAMS ((struct opstruct
*));
318 static int is_indirect
PARAMS ((struct opstruct
*));
319 static int is_dual
PARAMS ((struct opstruct
*));
320 static int is_mmreg
PARAMS ((struct opstruct
*));
321 static int is_type
PARAMS ((struct opstruct
*, enum optype
));
322 static int operands_match
PARAMS ((tic54x_insn
*, struct opstruct
*, int, const enum optype
*, int, int));
323 static int encode_dmad
PARAMS ((tic54x_insn
*, struct opstruct
*, int));
324 static int encode_address
PARAMS ((tic54x_insn
*, struct opstruct
*));
325 static int encode_indirect
PARAMS ((tic54x_insn
*, struct opstruct
*));
326 static int encode_integer
PARAMS ((tic54x_insn
*, struct opstruct
*, int, int, int, unsigned short));
327 static int encode_condition
PARAMS ((tic54x_insn
*, struct opstruct
*));
328 static int encode_cc3
PARAMS ((tic54x_insn
*, struct opstruct
*));
329 static int encode_arx
PARAMS ((tic54x_insn
*, struct opstruct
*));
330 static int encode_cc2
PARAMS ((tic54x_insn
*, struct opstruct
*));
331 static int encode_operand
PARAMS ((tic54x_insn
*, enum optype
, struct opstruct
*));
332 static void emit_insn
PARAMS ((tic54x_insn
*));
333 static int build_insn
PARAMS ((tic54x_insn
*));
334 static int optimize_insn
PARAMS ((tic54x_insn
*));
335 static int tic54x_parse_insn
PARAMS ((tic54x_insn
*, char *));
336 static int next_line_shows_parallel
PARAMS ((char *));
337 static int tic54x_parse_parallel_insn_firstline
PARAMS ((tic54x_insn
*, char *));
338 static int tic54x_parse_parallel_insn_lastline
PARAMS ((tic54x_insn
*, char *));
339 static char * subsym_get_arg
PARAMS ((char *, char *, char **, int));
340 static void subsym_create_or_replace
PARAMS ((char *, char *));
341 static char * subsym_lookup
PARAMS ((char *, int));
342 static char * subsym_substitute
PARAMS ((char *, int));
346 md_show_usage (stream
)
349 fprintf (stream
, _("C54x-specific command line options:\n"));
350 fprintf (stream
, _("-mfar-mode | -mf Use extended addressing\n"));
351 fprintf (stream
, _("-mcpu=<CPU version> Specify the CPU version\n"));
353 fprintf (stream
, _("-mcoff-version={0|1|2} Select COFF version\n"));
355 fprintf (stream
, _("-merrors-to-file <filename>\n"));
356 fprintf (stream
, _("-me <filename> Redirect errors to a file\n"));
359 /* Output a single character (upper octect is zero). */
367 exp
.X_op
= O_constant
;
368 exp
.X_add_number
= c
;
372 /* Walk backwards in the frag chain. */
375 frag_prev (frag
, seg
)
379 segment_info_type
*seginfo
= seg_info (seg
);
382 for (fragp
= seginfo
->frchainP
->frch_root
; fragp
; fragp
= fragp
->fr_next
)
383 if (fragp
->fr_next
== frag
)
390 bit_offset_frag (frag
, seg
)
396 if (frag
->fr_fix
== 0
397 && frag
->fr_opcode
== NULL
398 && frag
->tc_frag_data
== 0)
399 frag
= frag_prev (frag
, seg
);
406 /* Return the number of bits allocated in the most recent word, or zero if
407 none. .field/.space/.bes may leave words partially allocated. */
410 frag_bit_offset (frag
, seg
)
414 frag
= bit_offset_frag (frag
, seg
);
417 return frag
->fr_opcode
!= NULL
? -1 : frag
->tc_frag_data
;
422 /* Read an expression from a C string; returns a pointer past the end of the
426 parse_expression (str
, exp
)
433 tmp
= input_line_pointer
; /* Save line pointer. */
434 input_line_pointer
= str
;
436 s
= input_line_pointer
;
437 input_line_pointer
= tmp
; /* Restore line pointer. */
438 return s
; /* Return pointer to where parsing stopped. */
441 /* .asg "character-string"|character-string, symbol
443 .eval is the only pseudo-op allowed to perform arithmetic on substitution
444 symbols. all other use of symbols defined with .asg are currently
449 int x ATTRIBUTE_UNUSED
;
455 int quoted
= *input_line_pointer
== '"';
457 ILLEGAL_WITHIN_STRUCT ();
462 str
= demand_copy_C_string (&len
);
463 c
= *input_line_pointer
;
467 str
= input_line_pointer
;
468 while ((c
= *input_line_pointer
) != ',')
470 if (is_end_of_line
[(int) *input_line_pointer
])
472 ++input_line_pointer
;
474 *input_line_pointer
= 0;
478 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
479 ignore_rest_of_line ();
483 name
= ++input_line_pointer
;
484 c
= get_symbol_end (); /* Get terminator. */
485 if (!ISALPHA (*name
))
487 as_bad ("symbols assigned with .asg must begin with a letter");
488 ignore_rest_of_line ();
492 tmp
= xmalloc (strlen (str
) + 1);
495 tmp
= xmalloc (strlen (name
) + 1);
498 subsym_create_or_replace (name
, str
);
499 *input_line_pointer
= c
;
500 demand_empty_rest_of_line ();
503 /* .eval expression, symbol
504 There's something screwy about this. The other assembler sometimes does and
505 sometimes doesn't substitute symbols defined with .eval.
506 We'll put the symbols into the subsym table as well as the normal symbol
507 table, since that's what works best. */
511 int x ATTRIBUTE_UNUSED
;
517 char valuestr
[32], *tmp
;
520 ILLEGAL_WITHIN_STRUCT ();
524 quoted
= *input_line_pointer
== '"';
526 ++input_line_pointer
;
527 value
= get_absolute_expression ();
530 if (*input_line_pointer
!= '"')
532 as_bad (_("Unterminated string after absolute expression"));
533 ignore_rest_of_line ();
536 ++input_line_pointer
;
538 if (*input_line_pointer
++ != ',')
540 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
541 ignore_rest_of_line ();
544 name
= input_line_pointer
;
545 c
= get_symbol_end (); /* Get terminator. */
546 tmp
= xmalloc (strlen (name
) + 1);
547 name
= strcpy (tmp
, name
);
548 *input_line_pointer
= c
;
550 if (!ISALPHA (*name
))
552 as_bad (_("symbols assigned with .eval must begin with a letter"));
553 ignore_rest_of_line ();
556 symbolP
= symbol_new (name
, absolute_section
,
557 (valueT
) value
, &zero_address_frag
);
558 SF_SET_LOCAL (symbolP
);
559 symbol_table_insert (symbolP
);
561 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
562 But since there's not written rule as to when, don't even bother trying
563 to match their behavior. */
564 sprintf (valuestr
, "%d", value
);
565 tmp
= xmalloc (strlen (valuestr
) + 1);
566 strcpy (tmp
, valuestr
);
567 subsym_create_or_replace (name
, tmp
);
569 demand_empty_rest_of_line ();
572 /* .bss symbol, size [, [blocking flag] [, alignment flag]
574 alignment is to a longword boundary; blocking is to 128-word boundary.
576 1) if there is a hole in memory, this directive should attempt to fill it
577 (not yet implemented).
579 2) if the blocking flag is not set, allocate at the current SPC
580 otherwise, check to see if the current SPC plus the space to be
581 allocated crosses the page boundary (128 words).
582 if there's not enough space, create a hole and align with the next page
584 (not yet implemented). */
588 int x ATTRIBUTE_UNUSED
;
595 subsegT current_subseg
;
600 ILLEGAL_WITHIN_STRUCT ();
602 current_seg
= now_seg
; /* Save current seg. */
603 current_subseg
= now_subseg
; /* Save current subseg. */
605 name
= input_line_pointer
;
606 c
= get_symbol_end (); /* Get terminator. */
609 as_bad (".bss size argument missing\n");
610 ignore_rest_of_line ();
614 ++input_line_pointer
;
615 words
= get_absolute_expression ();
618 as_bad (".bss size %d < 0!", words
);
619 ignore_rest_of_line ();
623 if (*input_line_pointer
== ',')
625 /* The blocking flag may be missing. */
626 ++input_line_pointer
;
627 if (*input_line_pointer
!= ',')
628 block
= get_absolute_expression ();
632 if (*input_line_pointer
== ',')
634 ++input_line_pointer
;
635 align
= get_absolute_expression ();
643 subseg_set (bss_section
, 0);
644 symbolP
= symbol_find_or_make (name
);
646 if (S_GET_SEGMENT (symbolP
) == bss_section
)
647 symbolP
->sy_frag
->fr_symbol
= (symbolS
*) NULL
;
649 symbol_set_frag (symbolP
, frag_now
);
650 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
651 (offsetT
) (words
* OCTETS_PER_BYTE
), (char *) 0);
652 *p
= 0; /* Fill char. */
654 S_SET_SEGMENT (symbolP
, bss_section
);
656 /* The symbol may already have been created with a preceding
657 ".globl" directive -- be careful not to step on storage class
658 in that case. Otherwise, set it to static. */
659 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
660 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
664 /* s_align eats end of line; restore it */
666 --input_line_pointer
;
670 bss_section
->flags
|= SEC_BLOCK
;
672 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
673 demand_empty_rest_of_line ();
677 stag_add_field_symbols (stag
, path
, base_offset
, rootsym
, root_stag_name
)
682 const char *root_stag_name
;
684 char prefix
[strlen (path
) + 2];
685 struct stag_field
*field
= stag
->field
;
687 /* Construct a symbol for every field contained within this structure
688 including fields within structure fields. */
689 strcpy (prefix
, path
);
691 strcat (prefix
, ".");
693 while (field
!= NULL
)
695 int len
= strlen (prefix
) + strlen (field
->name
) + 2;
696 char *name
= xmalloc (len
);
697 strcpy (name
, prefix
);
698 strcat (name
, field
->name
);
703 sym
= symbol_new (name
, absolute_section
,
704 (field
->stag
? field
->offset
:
705 (valueT
) (base_offset
+ field
->offset
)),
708 symbol_table_insert (sym
);
712 char *replacement
= xmalloc (strlen (name
)
713 + strlen (stag
->name
) + 2);
714 strcpy (replacement
, S_GET_NAME (rootsym
));
715 strcat (replacement
, "+");
716 strcat (replacement
, root_stag_name
);
717 strcat (replacement
, name
+ strlen (S_GET_NAME (rootsym
)));
718 hash_insert (subsym_hash
[0], name
, replacement
);
721 /* Recurse if the field is a structure.
722 Note the field offset is relative to the outermost struct. */
723 if (field
->stag
!= NULL
)
724 stag_add_field_symbols (field
->stag
, name
,
726 rootsym
, root_stag_name
);
731 /* Keep track of stag fields so that when structures are nested we can add the
732 complete dereferencing symbols to the symbol table. */
735 stag_add_field (parent
, name
, offset
, stag
)
741 struct stag_field
*sfield
= xmalloc (sizeof (struct stag_field
));
743 memset (sfield
, 0, sizeof (*sfield
));
744 sfield
->name
= strcpy (xmalloc (strlen (name
) + 1), name
);
745 sfield
->offset
= offset
;
746 sfield
->bitfield_offset
= parent
->current_bitfield_offset
;
748 if (parent
->field
== NULL
)
749 parent
->field
= sfield
;
752 struct stag_field
*sf
= parent
->field
;
753 while (sf
->next
!= NULL
)
757 /* Only create a symbol for this field if the parent has no name. */
758 if (!strncmp (".fake", parent
->name
, 5))
760 symbolS
*sym
= symbol_new (name
, absolute_section
,
761 (valueT
) offset
, &zero_address_frag
);
763 symbol_table_insert (sym
);
767 /* [STAG] .struct [OFFSET]
768 Start defining structure offsets (symbols in absolute section). */
774 int start_offset
= 0;
779 /* Starting a new struct, switch to absolute section. */
780 stag_saved_seg
= now_seg
;
781 stag_saved_subseg
= now_subseg
;
782 subseg_set (absolute_section
, 0);
784 /* Align the current pointer. */
785 else if (current_stag
->current_bitfield_offset
!= 0)
787 ++abs_section_offset
;
788 current_stag
->current_bitfield_offset
= 0;
791 /* Offset expression is only meaningful for global .structs. */
794 /* Offset is ignored in inner structs. */
796 if (!is_end_of_line
[(int) *input_line_pointer
])
797 start_offset
= get_absolute_expression ();
804 /* Nesting, link to outer one. */
805 current_stag
->inner
= (struct stag
*) xmalloc (sizeof (struct stag
));
806 memset (current_stag
->inner
, 0, sizeof (struct stag
));
807 current_stag
->inner
->outer
= current_stag
;
808 current_stag
= current_stag
->inner
;
810 as_warn (_("Offset on nested structures is ignored"));
811 start_offset
= abs_section_offset
;
815 current_stag
= (struct stag
*) xmalloc (sizeof (struct stag
));
816 memset (current_stag
, 0, sizeof (struct stag
));
817 abs_section_offset
= start_offset
;
819 current_stag
->is_union
= is_union
;
821 if (line_label
== NULL
)
823 static int struct_count
= 0;
824 char fake
[] = ".fake_stagNNNNNNN";
825 sprintf (fake
, ".fake_stag%d", struct_count
++);
826 current_stag
->sym
= symbol_new (fake
, absolute_section
,
827 (valueT
) abs_section_offset
,
832 char label
[strlen (S_GET_NAME (line_label
)) + 1];
833 strcpy (label
, S_GET_NAME (line_label
));
834 current_stag
->sym
= symbol_new (label
, absolute_section
,
835 (valueT
) abs_section_offset
,
838 current_stag
->name
= S_GET_NAME (current_stag
->sym
);
839 SF_SET_LOCAL (current_stag
->sym
);
840 /* Nested .structs don't go into the symbol table. */
841 if (current_stag
->outer
== NULL
)
842 symbol_table_insert (current_stag
->sym
);
847 /* [LABEL] .endstruct
848 finish defining structure offsets; optional LABEL's value will be the size
852 tic54x_endstruct (is_union
)
857 !strncmp (current_stag
->name
, ".fake", 5) ? "" : current_stag
->name
;
859 if (!current_stag
|| current_stag
->is_union
!= is_union
)
861 as_bad (_(".end%s without preceding .%s"),
862 is_union
? "union" : "struct",
863 is_union
? "union" : "struct");
864 ignore_rest_of_line ();
868 /* Align end of structures. */
869 if (current_stag
->current_bitfield_offset
)
871 ++abs_section_offset
;
872 current_stag
->current_bitfield_offset
= 0;
875 if (current_stag
->is_union
)
876 size
= current_stag
->size
;
878 size
= abs_section_offset
- S_GET_VALUE (current_stag
->sym
);
879 if (line_label
!= NULL
)
881 S_SET_VALUE (line_label
, size
);
882 symbol_table_insert (line_label
);
886 /* Union size has already been calculated. */
887 if (!current_stag
->is_union
)
888 current_stag
->size
= size
;
889 /* Nested .structs don't get put in the stag table. */
890 if (current_stag
->outer
== NULL
)
892 hash_insert (stag_hash
, current_stag
->name
, current_stag
);
893 stag_add_field_symbols (current_stag
, path
,
894 S_GET_VALUE (current_stag
->sym
),
897 current_stag
= current_stag
->outer
;
899 /* If this is a nested .struct/.union, add it as a field to the enclosing
900 one. otherwise, restore the section we were in. */
901 if (current_stag
!= NULL
)
903 stag_add_field (current_stag
, current_stag
->inner
->name
,
904 S_GET_VALUE (current_stag
->inner
->sym
),
905 current_stag
->inner
);
908 subseg_set (stag_saved_seg
, stag_saved_subseg
);
912 Reference a structure within a structure, as a sized field with an optional
914 If used outside of a .struct/.endstruct, overlays the given structure
915 format on the existing allocated space. */
919 int ignore ATTRIBUTE_UNUSED
;
921 char *name
= input_line_pointer
;
922 int c
= get_symbol_end ();
923 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
928 as_bad (_("Unrecognized struct/union tag '%s'"), name
);
930 as_bad (_(".tag requires a structure tag"));
931 ignore_rest_of_line ();
934 if (line_label
== NULL
)
936 as_bad (_("Label required for .tag"));
937 ignore_rest_of_line ();
942 char label
[strlen (S_GET_NAME (line_label
)) + 1];
944 strcpy (label
, S_GET_NAME (line_label
));
945 if (current_stag
!= NULL
)
946 stag_add_field (current_stag
, label
,
947 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
951 symbolS
*sym
= symbol_find (label
);
955 as_bad (_(".tag target '%s' undefined"), label
);
956 ignore_rest_of_line ();
959 stag_add_field_symbols (stag
, S_GET_NAME (sym
),
960 S_GET_VALUE (stag
->sym
), sym
, stag
->name
);
964 /* Bump by the struct size, but only if we're within a .struct section. */
965 if (current_stag
!= NULL
&& !current_stag
->is_union
)
966 abs_section_offset
+= stag
->size
;
968 *input_line_pointer
= c
;
969 demand_empty_rest_of_line ();
973 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
974 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
978 tic54x_struct_field (type
)
983 int new_bitfield_offset
= 0;
984 int field_align
= current_stag
->current_bitfield_offset
!= 0;
985 int longword_align
= 0;
988 if (!is_end_of_line
[(int) *input_line_pointer
])
989 count
= get_absolute_expression ();
1005 case '*': /* String. */
1014 case '.': /* Bitfield. */
1016 if (count
< 1 || count
> 32)
1018 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count
);
1019 ignore_rest_of_line ();
1022 if (current_stag
->current_bitfield_offset
+ count
> 16)
1024 /* Set the appropriate size and new field offset. */
1030 else if (count
> 16)
1034 new_bitfield_offset
= count
- 16;
1037 new_bitfield_offset
= count
;
1042 new_bitfield_offset
= current_stag
->current_bitfield_offset
+ count
;
1046 as_bad (_("Unrecognized field type '%c'"), type
);
1047 ignore_rest_of_line ();
1053 /* Align to the actual starting position of the field. */
1054 current_stag
->current_bitfield_offset
= 0;
1055 ++abs_section_offset
;
1057 /* Align to longword boundary. */
1058 if (longword_align
&& (abs_section_offset
& 0x1))
1059 ++abs_section_offset
;
1061 if (line_label
== NULL
)
1063 static int fieldno
= 0;
1064 char fake
[] = ".fake_fieldNNNNN";
1066 sprintf (fake
, ".fake_field%d", fieldno
++);
1067 stag_add_field (current_stag
, fake
,
1068 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
1073 char label
[strlen (S_GET_NAME (line_label
) + 1)];
1075 strcpy (label
, S_GET_NAME (line_label
));
1076 stag_add_field (current_stag
, label
,
1077 abs_section_offset
- S_GET_VALUE (current_stag
->sym
),
1081 if (current_stag
->is_union
)
1083 /* Note we treat the element as if it were an array of COUNT. */
1084 if (current_stag
->size
< (unsigned) size
* count
)
1085 current_stag
->size
= size
* count
;
1089 abs_section_offset
+= (unsigned) size
* count
;
1090 current_stag
->current_bitfield_offset
= new_bitfield_offset
;
1095 /* Handle .byte, .word. .int, .long and all variants. */
1104 /* If we're within a .struct construct, don't actually allocate space. */
1105 if (current_stag
!= NULL
)
1107 tic54x_struct_field (type
);
1111 #ifdef md_flush_pending_output
1112 md_flush_pending_output ();
1115 generate_lineno_debug ();
1117 /* Align long words to long word boundaries (4 octets). */
1118 if (type
== 'l' || type
== 'L')
1120 frag_align (2, 0, 2);
1121 /* If there's a label, assign it to the first allocated word. */
1122 if (line_label
!= NULL
)
1124 symbol_set_frag (line_label
, frag_now
);
1125 S_SET_VALUE (line_label
, frag_now_fix ());
1149 if (*input_line_pointer
== '"')
1151 input_line_pointer
++;
1152 while (is_a_char (c
= next_char_of_string ()))
1153 tic54x_emit_char (c
);
1154 know (input_line_pointer
[-1] == '\"');
1160 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1161 if (exp
.X_op
== O_constant
)
1163 offsetT value
= exp
.X_add_number
;
1164 /* Truncate overflows. */
1168 if ((value
> 0 && value
> 0xFF)
1169 || (value
< 0 && value
< - 0x100))
1170 as_warn ("Overflow in expression, truncated to 8 bits");
1173 if ((value
> 0 && value
> 0xFFFF)
1174 || (value
< 0 && value
< - 0x10000))
1175 as_warn ("Overflow in expression, truncated to 16 bits");
1179 if (exp
.X_op
!= O_constant
&& octets
< 2)
1181 /* Disallow .byte with a non constant expression that will
1182 require relocation. */
1183 as_bad (_("Relocatable values require at least WORD storage"));
1184 ignore_rest_of_line ();
1188 if (exp
.X_op
!= O_constant
1192 /* FIXME -- at one point TI tools used to output REL16
1193 relocations, but I don't think the latest tools do at all
1194 The current tools output extended relocations regardless of
1195 the addressing mode (I actually think that ".c_mode" is
1196 totally ignored in the latest tools). */
1199 emit_expr (&exp
, 4);
1205 emitting_long
= octets
== 4;
1206 emit_expr (&exp
, (octets
== 1) ? 2 : octets
);
1211 while (*input_line_pointer
++ == ',');
1213 input_line_pointer
--; /* Put terminator back into stream. */
1214 demand_empty_rest_of_line ();
1217 /* .global <symbol>[,...,<symbolN>]
1218 .def <symbol>[,...,<symbolN>]
1219 .ref <symbol>[,...,<symbolN>]
1221 These all identify global symbols.
1223 .def means the symbol is defined in the current module and can be accessed
1224 by other files. The symbol should be placed in the symbol table.
1226 .ref means the symbol is used in the current module but defined in another
1227 module. The linker is to resolve this symbol's definition at link time.
1229 .global should act as a .ref or .def, as needed.
1231 global, def and ref all have symbol storage classes of C_EXT.
1233 I can't identify any difference in how the "other" c54x assembler treats
1234 these, so we ignore the type here. */
1237 tic54x_global (type
)
1245 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1247 ILLEGAL_WITHIN_STRUCT ();
1251 name
= input_line_pointer
;
1252 c
= get_symbol_end ();
1253 symbolP
= symbol_find_or_make (name
);
1255 *input_line_pointer
= c
;
1256 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
1259 input_line_pointer
++;
1260 if (is_end_of_line
[(int) *input_line_pointer
])
1261 c
= *input_line_pointer
;
1266 demand_empty_rest_of_line ();
1269 /* Remove the symbol from the local label hash lookup. */
1272 tic54x_remove_local_label (key
, value
)
1274 PTR value ATTRIBUTE_UNUSED
;
1276 PTR
*elem
= hash_delete (local_label_hash
[macro_level
], key
);
1280 /* Reset all local labels. */
1283 tic54x_clear_local_labels (ignored
)
1284 int ignored ATTRIBUTE_UNUSED
;
1286 hash_traverse (local_label_hash
[macro_level
], tic54x_remove_local_label
);
1291 .sect "section name"
1294 make sure local labels get cleared when changing sections
1296 ARG is 't' for text, 'd' for data, or '*' for a named section
1298 For compatibility, '*' sections are SEC_CODE if instructions are
1299 encountered, or SEC_DATA if not.
1306 ILLEGAL_WITHIN_STRUCT ();
1308 /* Local labels are cleared when changing sections. */
1309 tic54x_clear_local_labels (0);
1313 else if (arg
== 'd')
1320 /* If there are quotes, remove them. */
1321 if (*input_line_pointer
== '"')
1323 name
= demand_copy_C_string (&len
);
1324 demand_empty_rest_of_line ();
1325 name
= strcpy (xmalloc (len
+ 10), name
);
1330 name
= input_line_pointer
;
1331 c
= get_symbol_end ();
1333 name
= strcpy (xmalloc (len
+ 10), name
);
1334 *input_line_pointer
= c
;
1335 demand_empty_rest_of_line ();
1337 /* Make sure all named initialized sections flagged properly. If we
1338 encounter instructions, we'll flag it with SEC_CODE as well. */
1339 strcat (name
, ",\"w\"\n");
1340 input_scrub_insert_line (name
);
1341 obj_coff_section (0);
1343 /* If there was a line label, make sure that it gets assigned the proper
1344 section. This is for compatibility, even though the actual behavior
1345 is not explicitly defined. For consistency, we make .sect behave
1346 like .usect, since that is probably what people expect. */
1347 if (line_label
!= NULL
)
1349 S_SET_SEGMENT (line_label
, now_seg
);
1350 symbol_set_frag (line_label
, frag_now
);
1351 S_SET_VALUE (line_label
, frag_now_fix ());
1352 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1353 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1358 /* [symbol] .space space_in_bits
1359 [symbol] .bes space_in_bits
1360 BES puts the symbol at the *last* word allocated
1362 cribbed from s_space. */
1372 int bits_per_byte
= (OCTETS_PER_BYTE
* 8);
1374 symbolS
*label
= line_label
;
1377 ILLEGAL_WITHIN_STRUCT ();
1379 #ifdef md_flush_pending_output
1380 md_flush_pending_output ();
1383 /* Read the bit count. */
1386 /* Some expressions are unresolvable until later in the assembly pass;
1387 postpone until relaxation/fixup. we also have to postpone if a previous
1388 partial allocation has not been completed yet. */
1389 if (exp
.X_op
!= O_constant
|| frag_bit_offset (frag_now
, now_seg
) == -1)
1391 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1397 p
= frag_var (rs_machine_dependent
,
1398 65536 * 2, 1, (relax_substateT
) 0,
1399 make_expr_symbol (&exp
), (offsetT
) 0,
1407 /* Reduce the required size by any bit offsets currently left over
1408 from a previous .space/.bes/.field directive. */
1409 bit_offset
= frag_now
->tc_frag_data
;
1410 if (bit_offset
!= 0 && bit_offset
< 16)
1412 int spare_bits
= bits_per_byte
- bit_offset
;
1414 if (spare_bits
>= exp
.X_add_number
)
1416 /* Don't have to do anything; sufficient bits have already been
1417 allocated; just point the label to the right place. */
1420 symbol_set_frag (label
, frag_now
);
1421 S_SET_VALUE (label
, frag_now_fix () - 1);
1424 frag_now
->tc_frag_data
+= exp
.X_add_number
;
1427 exp
.X_add_number
-= spare_bits
;
1428 /* Set the label to point to the first word allocated, which in this
1429 case is the previous word, which was only partially filled. */
1430 if (!bes
&& label
!= NULL
)
1432 symbol_set_frag (label
, frag_now
);
1433 S_SET_VALUE (label
, frag_now_fix () - 1);
1437 /* Convert bits to bytes/words and octets, rounding up. */
1438 words
= ((exp
.X_add_number
+ bits_per_byte
- 1) / bits_per_byte
);
1439 /* How many do we have left over? */
1440 bit_offset
= exp
.X_add_number
% bits_per_byte
;
1441 octets
= words
* OCTETS_PER_BYTE
;
1444 as_warn (_(".space/.bes repeat count is negative, ignored"));
1447 else if (octets
== 0)
1449 as_warn (_(".space/.bes repeat count is zero, ignored"));
1453 /* If we are in the absolute section, just bump the offset. */
1454 if (now_seg
== absolute_section
)
1456 abs_section_offset
+= words
;
1457 if (bes
&& label
!= NULL
)
1458 S_SET_VALUE (label
, abs_section_offset
- 1);
1459 frag_now
->tc_frag_data
= bit_offset
;
1464 p
= frag_var (rs_fill
, 1, 1,
1465 (relax_substateT
) 0, (symbolS
*) 0,
1466 (offsetT
) octets
, (char *) 0);
1468 /* Make note of how many bits of this word we've allocated so far. */
1469 frag_now
->tc_frag_data
= bit_offset
;
1471 /* .bes puts label at *last* word allocated. */
1472 if (bes
&& label
!= NULL
)
1474 symbol_set_frag (label
, frag_now
);
1475 S_SET_VALUE (label
, frag_now_fix () - 1);
1483 demand_empty_rest_of_line ();
1486 /* [symbol] .usect "section-name", size-in-words
1487 [, [blocking-flag] [, alignment-flag]]
1489 Uninitialized section.
1490 Non-zero blocking means that if the section would cross a page (128-word)
1491 boundary, it will be page-aligned.
1492 Non-zero alignment aligns on a longword boundary.
1494 Has no effect on the current section. */
1498 int x ATTRIBUTE_UNUSED
;
1505 int size
, blocking_flag
, alignment_flag
;
1507 subsegT current_subseg
;
1510 ILLEGAL_WITHIN_STRUCT ();
1512 current_seg
= now_seg
; /* Save current seg. */
1513 current_subseg
= now_subseg
; /* Save current subseg. */
1515 if (*input_line_pointer
== '"')
1516 input_line_pointer
++;
1517 section_name
= input_line_pointer
;
1518 c
= get_symbol_end (); /* Get terminator. */
1519 input_line_pointer
++; /* Skip null symbol terminator. */
1520 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1521 strcpy (name
, section_name
);
1523 if (*input_line_pointer
== ',')
1524 ++input_line_pointer
;
1527 as_bad (_("Missing size argument"));
1528 ignore_rest_of_line ();
1532 size
= get_absolute_expression ();
1534 /* Read a possibly present third argument (blocking flag). */
1535 if (*input_line_pointer
== ',')
1537 ++input_line_pointer
;
1538 if (*input_line_pointer
!= ',')
1539 blocking_flag
= get_absolute_expression ();
1543 /* Read a possibly present fourth argument (alignment flag). */
1544 if (*input_line_pointer
== ',')
1546 ++input_line_pointer
;
1547 alignment_flag
= get_absolute_expression ();
1553 blocking_flag
= alignment_flag
= 0;
1555 seg
= subseg_new (name
, 0);
1556 flags
= bfd_get_section_flags (stdoutput
, seg
) | SEC_ALLOC
;
1560 /* s_align eats end of line; restore it. */
1562 --input_line_pointer
;
1565 if (line_label
!= NULL
)
1567 S_SET_SEGMENT (line_label
, seg
);
1568 symbol_set_frag (line_label
, frag_now
);
1569 S_SET_VALUE (line_label
, frag_now_fix ());
1570 /* Set scl to label, since that's what TI does. */
1571 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1572 S_SET_STORAGE_CLASS (line_label
, C_LABEL
);
1575 seg_info (seg
)->bss
= 1; /* Uninitialized data. */
1577 p
= frag_var (rs_fill
, 1, 1,
1578 (relax_substateT
) 0, (symbolS
*) line_label
,
1579 size
* OCTETS_PER_BYTE
, (char *) 0);
1585 if (!bfd_set_section_flags (stdoutput
, seg
, flags
))
1586 as_warn ("Error setting flags for \"%s\": %s", name
,
1587 bfd_errmsg (bfd_get_error ()));
1589 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1590 demand_empty_rest_of_line ();
1593 static enum cpu_version
1594 lookup_version (ver
)
1597 enum cpu_version version
= VNONE
;
1599 if (ver
[0] == '5' && ver
[1] == '4')
1601 if (strlen (ver
) == 3
1602 && (ver
[2] == '1' || ver
[2] == '2' || ver
[2] == '3'
1603 || ver
[2] == '5' || ver
[2] == '8' || ver
[2] == '9'))
1604 version
= ver
[2] - '0';
1605 else if (strlen (ver
) == 5
1606 && TOUPPER (ver
[3]) == 'L'
1607 && TOUPPER (ver
[4]) == 'P'
1608 && (ver
[2] == '5' || ver
[2] == '6'))
1609 version
= ver
[2] - '0' + 10;
1617 enum cpu_version version
;
1620 if (version
== V545LP
|| version
== V546LP
)
1622 symbolS
*symbolP
= symbol_new ("__allow_lp", absolute_section
,
1623 (valueT
) 1, &zero_address_frag
);
1624 SF_SET_LOCAL (symbolP
);
1625 symbol_table_insert (symbolP
);
1629 /* .version cpu-version
1630 cpu-version may be one of the following:
1640 This is for compatibility only. It currently has no affect on assembly. */
1641 static int cpu_needs_set
= 1;
1645 int x ATTRIBUTE_UNUSED
;
1647 enum cpu_version version
= VNONE
;
1648 enum cpu_version old_version
= cpu
;
1652 ILLEGAL_WITHIN_STRUCT ();
1655 ver
= input_line_pointer
;
1656 while (!is_end_of_line
[(int) *input_line_pointer
])
1657 ++input_line_pointer
;
1658 c
= *input_line_pointer
;
1659 *input_line_pointer
= 0;
1661 version
= lookup_version (ver
);
1663 if (cpu
!= VNONE
&& cpu
!= version
)
1664 as_warn (_("CPU version has already been set"));
1666 if (version
== VNONE
)
1668 as_bad (_("Unrecognized version '%s'"), ver
);
1669 ignore_rest_of_line ();
1672 else if (assembly_begun
&& version
!= old_version
)
1674 as_bad (_("Changing of CPU version on the fly not supported"));
1675 ignore_rest_of_line ();
1681 *input_line_pointer
= c
;
1682 demand_empty_rest_of_line ();
1685 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1688 tic54x_float_cons (type
)
1691 if (current_stag
!= 0)
1692 tic54x_struct_field ('f');
1694 #ifdef md_flush_pending_output
1695 md_flush_pending_output ();
1698 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1701 frag_align (2, 0, 2);
1702 /* If there's a label, assign it to the first allocated word. */
1703 if (line_label
!= NULL
)
1705 symbol_set_frag (line_label
, frag_now
);
1706 S_SET_VALUE (line_label
, frag_now_fix ());
1713 /* The argument is capitalized if it should be zero-terminated
1714 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1715 Code copied from stringer, and slightly modified so that strings are packed
1716 and encoded into the correct octets. */
1719 tic54x_stringer (type
)
1724 int append_zero
= type
== 'S' || type
== 'P';
1725 int packed
= type
== 'p' || type
== 'P';
1726 int last_char
= -1; /* Packed strings need two bytes at a time to encode. */
1728 if (current_stag
!= NULL
)
1730 tic54x_struct_field ('*');
1734 #ifdef md_flush_pending_output
1735 md_flush_pending_output ();
1738 c
= ','; /* Do loop. */
1742 switch (*input_line_pointer
)
1746 unsigned short value
= get_absolute_expression ();
1747 FRAG_APPEND_1_CHAR ( value
& 0xFF);
1748 FRAG_APPEND_1_CHAR ((value
>> 8) & 0xFF);
1752 ++input_line_pointer
; /* -> 1st char of string. */
1753 start
= input_line_pointer
;
1754 while (is_a_char (c
= next_char_of_string ()))
1758 FRAG_APPEND_1_CHAR (c
);
1759 FRAG_APPEND_1_CHAR (0);
1763 /* Packed strings are filled MS octet first. */
1764 if (last_char
== -1)
1768 FRAG_APPEND_1_CHAR (c
);
1769 FRAG_APPEND_1_CHAR (last_char
);
1776 if (packed
&& last_char
!= -1)
1778 FRAG_APPEND_1_CHAR (0);
1779 FRAG_APPEND_1_CHAR (last_char
);
1784 FRAG_APPEND_1_CHAR (0);
1785 FRAG_APPEND_1_CHAR (0);
1788 know (input_line_pointer
[-1] == '\"');
1792 c
= *input_line_pointer
;
1793 if (!is_end_of_line
[c
])
1794 ++input_line_pointer
;
1797 /* Finish up any leftover packed string. */
1798 if (packed
&& last_char
!= -1)
1800 FRAG_APPEND_1_CHAR (0);
1801 FRAG_APPEND_1_CHAR (last_char
);
1803 demand_empty_rest_of_line ();
1807 tic54x_p2align (arg
)
1808 int arg ATTRIBUTE_UNUSED
;
1810 as_bad (_("p2align not supported on this target"));
1814 tic54x_align_words (arg
)
1817 /* Only ".align" with no argument is allowed within .struct/.union. */
1820 if (!is_end_of_line
[(int) *input_line_pointer
])
1823 as_warn (_("Argument to .even ignored"));
1825 count
= get_absolute_expression ();
1828 if (current_stag
!= NULL
&& arg
== 128)
1830 if (current_stag
->current_bitfield_offset
!= 0)
1832 current_stag
->current_bitfield_offset
= 0;
1833 ++abs_section_offset
;
1835 demand_empty_rest_of_line ();
1839 ILLEGAL_WITHIN_STRUCT ();
1841 s_align_bytes (count
<< 1);
1844 /* Initialize multiple-bit fields withing a single word of memory. */
1847 tic54x_field (ignore
)
1848 int ignore ATTRIBUTE_UNUSED
;
1854 symbolS
*label
= line_label
;
1856 if (current_stag
!= NULL
)
1858 tic54x_struct_field ('.');
1862 input_line_pointer
= parse_expression (input_line_pointer
, &exp
);
1864 if (*input_line_pointer
== ',')
1866 ++input_line_pointer
;
1867 size
= get_absolute_expression ();
1868 if (size
< 1 || size
> 32)
1870 as_bad (_("Invalid field size, must be from 1 to 32"));
1871 ignore_rest_of_line ();
1876 /* Truncate values to the field width. */
1877 if (exp
.X_op
!= O_constant
)
1879 /* If the expression value is relocatable, the field size *must*
1883 as_bad (_("field size must be 16 when value is relocatable"));
1884 ignore_rest_of_line ();
1888 frag_now
->tc_frag_data
= 0;
1889 emit_expr (&exp
, 2);
1893 unsigned long fmask
= (size
== 32) ? 0xFFFFFFFF : (1ul << size
) - 1;
1895 value
= exp
.X_add_number
;
1896 exp
.X_add_number
&= fmask
;
1897 if (value
!= (valueT
) exp
.X_add_number
)
1898 as_warn (_("field value truncated"));
1899 value
= exp
.X_add_number
;
1900 /* Bits are stored MS first. */
1903 frag_now
->tc_frag_data
= 0;
1905 md_number_to_chars (p
, (value
>> (size
- 16)) & 0xFFFF, 2);
1910 int bit_offset
= frag_bit_offset (frag_now
, now_seg
);
1912 fragS
*alloc_frag
= bit_offset_frag (frag_now
, now_seg
);
1913 if (bit_offset
== -1)
1915 struct bit_info
*bi
= xmalloc (sizeof (struct bit_info
));
1916 /* We don't know the previous offset at this time, so store the
1917 info we need and figure it out later. */
1918 expressionS size_exp
;
1920 size_exp
.X_op
= O_constant
;
1921 size_exp
.X_add_number
= size
;
1923 bi
->type
= TYPE_FIELD
;
1925 p
= frag_var (rs_machine_dependent
,
1926 4, 1, (relax_substateT
) 0,
1927 make_expr_symbol (&size_exp
), (offsetT
) 0,
1931 else if (bit_offset
== 0 || bit_offset
+ size
> 16)
1933 /* Align a new field. */
1935 frag_now
->tc_frag_data
= 0;
1936 alloc_frag
= frag_now
;
1940 /* Put the new value entirely within the existing one. */
1941 p
= alloc_frag
== frag_now
?
1942 frag_now
->fr_literal
+ frag_now_fix_octets () - 2 :
1943 alloc_frag
->fr_literal
;
1946 symbol_set_frag (label
, alloc_frag
);
1947 if (alloc_frag
== frag_now
)
1948 S_SET_VALUE (label
, frag_now_fix () - 1);
1952 value
<<= 16 - alloc_frag
->tc_frag_data
- size
;
1954 /* OR in existing value. */
1955 if (alloc_frag
->tc_frag_data
)
1956 value
|= ((unsigned short) p
[1] << 8) | p
[0];
1957 md_number_to_chars (p
, value
, 2);
1958 alloc_frag
->tc_frag_data
+= size
;
1959 if (alloc_frag
->tc_frag_data
== 16)
1960 alloc_frag
->tc_frag_data
= 0;
1964 demand_empty_rest_of_line ();
1967 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1968 available yet. seg_info ()->bss is the next best thing. */
1971 tic54x_initialized_section (seg
)
1974 return !seg_info (seg
)->bss
;
1977 /* .clink ["section name"]
1979 Marks the section as conditionally linked (link only if contents are
1980 referenced elsewhere.
1981 Without a name, refers to the current initialized section.
1982 Name is required for uninitialized sections. */
1985 tic54x_clink (ignored
)
1986 int ignored ATTRIBUTE_UNUSED
;
1990 ILLEGAL_WITHIN_STRUCT ();
1992 if (*input_line_pointer
== '\"')
1994 char *section_name
= ++input_line_pointer
;
1997 while (is_a_char (next_char_of_string ()))
1999 know (input_line_pointer
[-1] == '\"');
2000 input_line_pointer
[-1] = 0;
2001 name
= xmalloc (input_line_pointer
- section_name
+ 1);
2002 strcpy (name
, section_name
);
2004 seg
= bfd_get_section_by_name (stdoutput
, name
);
2007 as_bad (_("Unrecognized section '%s'"), section_name
);
2008 ignore_rest_of_line ();
2014 if (!tic54x_initialized_section (seg
))
2016 as_bad (_("Current section is unitialized, "
2017 "section name required for .clink"));
2018 ignore_rest_of_line ();
2023 seg
->flags
|= SEC_CLINK
;
2025 demand_empty_rest_of_line ();
2028 /* Change the default include directory to be the current source file's
2029 directory, instead of the current working directory. If DOT is non-zero,
2030 set to "." instead. */
2033 tic54x_set_default_include (dot
)
2044 as_where (&curfile
, &lineno
);
2045 dir
= strcpy (xmalloc (strlen (curfile
) + 1), curfile
);
2046 tmp
= strrchr (dir
, '/');
2054 if (include_dir_count
== 0)
2056 include_dirs
= (char **) xmalloc (sizeof (*include_dirs
));
2057 include_dir_count
= 1;
2059 include_dirs
[0] = dir
;
2060 if (len
> include_dir_maxlen
)
2061 include_dir_maxlen
= len
;
2063 else if (include_dirs
!= NULL
)
2064 include_dirs
[0] = ".";
2067 /* .include "filename" | filename
2068 .copy "filename" | filename
2070 FIXME 'include' file should be omitted from any output listing,
2071 'copy' should be included in any output listing
2072 FIXME -- prevent any included files from changing listing (compat only)
2073 FIXME -- need to include source file directory in search path; what's a
2074 good way to do this?
2076 Entering/exiting included/copied file clears all local labels. */
2079 tic54x_include (ignored
)
2080 int ignored ATTRIBUTE_UNUSED
;
2082 char newblock
[] = " .newblock\n";
2087 ILLEGAL_WITHIN_STRUCT ();
2091 if (*input_line_pointer
== '"')
2093 filename
= demand_copy_C_string (&len
);
2094 demand_empty_rest_of_line ();
2098 filename
= input_line_pointer
;
2099 while (!is_end_of_line
[(int) *input_line_pointer
])
2100 ++input_line_pointer
;
2101 c
= *input_line_pointer
;
2102 *input_line_pointer
= '\0';
2103 filename
= strcpy (xmalloc (strlen (filename
) + 1), filename
);
2104 *input_line_pointer
= c
;
2105 demand_empty_rest_of_line ();
2107 /* Insert a partial line with the filename (for the sake of s_include)
2109 The included file will be inserted before the newblock, so that the
2110 newblock is executed after the included file is processed. */
2111 input
= xmalloc (sizeof (newblock
) + strlen (filename
) + 4);
2112 sprintf (input
, "\"%s\"\n%s", filename
, newblock
);
2113 input_scrub_insert_line (input
);
2115 tic54x_clear_local_labels (0);
2117 tic54x_set_default_include (0);
2123 tic54x_message (type
)
2130 ILLEGAL_WITHIN_STRUCT ();
2132 if (*input_line_pointer
== '"')
2133 msg
= demand_copy_C_string (&len
);
2136 msg
= input_line_pointer
;
2137 while (!is_end_of_line
[(int) *input_line_pointer
])
2138 ++input_line_pointer
;
2139 c
= *input_line_pointer
;
2140 *input_line_pointer
= 0;
2141 msg
= strcpy (xmalloc (strlen (msg
) + 1), msg
);
2142 *input_line_pointer
= c
;
2148 as_tsktsk ("%s", msg
);
2151 as_warn ("%s", msg
);
2158 demand_empty_rest_of_line ();
2162 Define a special symbol that refers to the loadtime address rather than the
2163 runtime address within the current section.
2165 This symbol gets a special storage class so that when it is resolved, it is
2166 resolved relative to the load address (lma) of the section rather than the
2167 run address (vma). */
2170 tic54x_label (ignored
)
2171 int ignored ATTRIBUTE_UNUSED
;
2173 char *name
= input_line_pointer
;
2177 ILLEGAL_WITHIN_STRUCT ();
2179 c
= get_symbol_end ();
2180 symbolP
= colon (name
);
2181 S_SET_STORAGE_CLASS (symbolP
, C_STATLAB
);
2183 *input_line_pointer
= c
;
2184 demand_empty_rest_of_line ();
2188 Install all memory-mapped register names into the symbol table as
2189 absolute local symbols. */
2192 tic54x_mmregs (ignored
)
2193 int ignored ATTRIBUTE_UNUSED
;
2197 ILLEGAL_WITHIN_STRUCT ();
2199 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
2201 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
2202 (valueT
) sym
->value
, &zero_address_frag
);
2203 SF_SET_LOCAL (symbolP
);
2204 symbol_table_insert (symbolP
);
2209 Count defaults to 1024. */
2215 ILLEGAL_WITHIN_STRUCT ();
2218 if (!is_end_of_line
[(int) *input_line_pointer
])
2219 count
= get_absolute_expression ();
2221 do_repeat (count
, "LOOP", "ENDLOOP");
2224 /* Normally, endloop gets eaten by the preceding loop. */
2227 tic54x_endloop (ignore
)
2228 int ignore ATTRIBUTE_UNUSED
;
2230 as_bad (_("ENDLOOP without corresponding LOOP"));
2231 ignore_rest_of_line ();
2234 /* .break [condition]. */
2237 tic54x_break (ignore
)
2238 int ignore ATTRIBUTE_UNUSED
;
2242 ILLEGAL_WITHIN_STRUCT ();
2245 if (!is_end_of_line
[(int) *input_line_pointer
])
2246 cond
= get_absolute_expression ();
2249 end_repeat (substitution_line
? 1 : 0);
2253 set_address_mode (mode
)
2257 if (mode
== far_mode
)
2259 symbolS
*symbolP
= symbol_new ("__allow_far", absolute_section
,
2260 (valueT
) 1, &zero_address_frag
);
2261 SF_SET_LOCAL (symbolP
);
2262 symbol_table_insert (symbolP
);
2266 static int address_mode_needs_set
= 1;
2269 tic54x_address_mode (mode
)
2272 if (assembly_begun
&& amode
!= (unsigned) mode
)
2274 as_bad (_("Mixing of normal and extended addressing not supported"));
2275 ignore_rest_of_line ();
2278 if (mode
== far_mode
&& cpu
!= VNONE
&& cpu
!= V548
&& cpu
!= V549
)
2280 as_bad (_("Extended addressing not supported on the specified CPU"));
2281 ignore_rest_of_line ();
2285 set_address_mode (mode
);
2286 demand_empty_rest_of_line ();
2289 /* .sblock "section"|section [,...,"section"|section]
2290 Designate initialized sections for blocking. */
2293 tic54x_sblock (ignore
)
2294 int ignore ATTRIBUTE_UNUSED
;
2298 ILLEGAL_WITHIN_STRUCT ();
2305 if (*input_line_pointer
== '"')
2309 name
= demand_copy_C_string (&len
);
2313 char *section_name
= input_line_pointer
;
2315 c
= get_symbol_end ();
2316 name
= xmalloc (strlen (section_name
) + 1);
2317 strcpy (name
, section_name
);
2318 *input_line_pointer
= c
;
2321 seg
= bfd_get_section_by_name (stdoutput
, name
);
2324 as_bad (_("Unrecognized section '%s'"), name
);
2325 ignore_rest_of_line ();
2328 else if (!tic54x_initialized_section (seg
))
2330 as_bad (_(".sblock may be used for initialized sections only"));
2331 ignore_rest_of_line ();
2334 seg
->flags
|= SEC_BLOCK
;
2336 c
= *input_line_pointer
;
2337 if (!is_end_of_line
[(int) c
])
2338 ++input_line_pointer
;
2341 demand_empty_rest_of_line ();
2344 /* symbol .set value
2347 value must be defined externals; no forward-referencing allowed
2348 symbols assigned with .set/.equ may not be redefined. */
2352 int ignore ATTRIBUTE_UNUSED
;
2357 ILLEGAL_WITHIN_STRUCT ();
2361 as_bad (_("Symbol missing for .set/.equ"));
2362 ignore_rest_of_line ();
2365 name
= xstrdup (S_GET_NAME (line_label
));
2367 if ((symbolP
= symbol_find (name
)) == NULL
2368 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2370 symbolP
= symbol_new (name
, absolute_section
, 0, &zero_address_frag
);
2371 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
2374 S_SET_DATA_TYPE (symbolP
, T_INT
);
2375 S_SET_SEGMENT (symbolP
, absolute_section
);
2376 symbol_table_insert (symbolP
);
2377 pseudo_set (symbolP
);
2378 demand_empty_rest_of_line ();
2383 List false conditional blocks. */
2386 tic54x_fclist (show
)
2390 listing
&= ~LISTING_NOCOND
;
2392 listing
|= LISTING_NOCOND
;
2393 demand_empty_rest_of_line ();
2397 tic54x_sslist (show
)
2400 ILLEGAL_WITHIN_STRUCT ();
2402 listing_sslist
= show
;
2405 /* .var SYM[,...,SYMN]
2406 Define a substitution string to be local to a macro. */
2410 int ignore ATTRIBUTE_UNUSED
;
2412 static char empty
[] = "";
2416 ILLEGAL_WITHIN_STRUCT ();
2418 if (macro_level
== 0)
2420 as_bad (_(".var may only be used within a macro definition"));
2421 ignore_rest_of_line ();
2426 if (!ISALPHA (*input_line_pointer
))
2428 as_bad (_("Substitution symbols must begin with a letter"));
2429 ignore_rest_of_line ();
2432 name
= input_line_pointer
;
2433 c
= get_symbol_end ();
2434 /* .var symbols start out with a null string. */
2435 name
= strcpy (xmalloc (strlen (name
) + 1), name
);
2436 hash_insert (subsym_hash
[macro_level
], name
, empty
);
2437 *input_line_pointer
= c
;
2440 ++input_line_pointer
;
2441 if (is_end_of_line
[(int) *input_line_pointer
])
2442 c
= *input_line_pointer
;
2447 demand_empty_rest_of_line ();
2450 /* .mlib <macro library filename>
2452 Macro libraries are archived (standard AR-format) text macro definitions
2453 Expand the file and include it.
2455 FIXME need to try the source file directory as well. */
2458 tic54x_mlib (ignore
)
2459 int ignore ATTRIBUTE_UNUSED
;
2466 ILLEGAL_WITHIN_STRUCT ();
2468 /* Parse the filename. */
2469 if (*input_line_pointer
== '"')
2471 if ((filename
= demand_copy_C_string (&len
)) == NULL
)
2478 while (!is_end_of_line
[(int) *input_line_pointer
]
2479 && !ISSPACE (*input_line_pointer
))
2481 obstack_1grow (¬es
, *input_line_pointer
);
2482 ++input_line_pointer
;
2485 obstack_1grow (¬es
, '\0');
2486 filename
= obstack_finish (¬es
);
2488 demand_empty_rest_of_line ();
2490 tic54x_set_default_include (0);
2491 path
= xmalloc ((unsigned long) len
+ include_dir_maxlen
+ 5);
2493 for (i
= 0; i
< include_dir_count
; i
++)
2497 strcpy (path
, include_dirs
[i
]);
2499 strcat (path
, filename
);
2500 if ((try = fopen (path
, "r")) != NULL
)
2507 if (i
>= include_dir_count
)
2513 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2514 happens all over the place, and since the assembler doesn't usually keep
2515 running for a very long time, it really doesn't matter. */
2516 register_dependency (path
);
2518 /* Expand all archive entries to temporary files and include them. */
2519 abfd
= bfd_openr (path
, NULL
);
2522 as_bad (_("Can't open macro library file '%s' for reading."), path
);
2523 as_perror ("%s", path
);
2524 ignore_rest_of_line ();
2527 if (!bfd_check_format (abfd
, bfd_archive
))
2529 as_bad (_("File '%s' not in macro archive format"), path
);
2530 ignore_rest_of_line ();
2534 /* Open each BFD as binary (it should be straight ASCII text). */
2535 for (mbfd
= bfd_openr_next_archived_file (abfd
, NULL
);
2536 mbfd
!= NULL
; mbfd
= bfd_openr_next_archived_file (abfd
, mbfd
))
2538 /* Get a size at least as big as the archive member. */
2539 bfd_size_type size
= bfd_get_size (mbfd
);
2540 char *buf
= xmalloc (size
);
2541 char *fname
= tmpnam (NULL
);
2544 /* We're not sure how big it is, but it will be smaller than "size". */
2545 bfd_bread (buf
, size
, mbfd
);
2547 /* Write to a temporary file, then use s_include to include it
2549 ftmp
= fopen (fname
, "w+b");
2550 fwrite ((void *) buf
, size
, 1, ftmp
);
2551 if (buf
[size
- 1] != '\n')
2552 fwrite ("\n", 1, 1, ftmp
);
2555 input_scrub_insert_file (fname
);
2560 const pseudo_typeS md_pseudo_table
[] =
2562 { "algebraic", s_ignore
, 0 },
2563 { "align" , tic54x_align_words
, 128 },
2564 { "ascii" , tic54x_stringer
, 'p' },
2565 { "asciz" , tic54x_stringer
, 'P' },
2566 { "even" , tic54x_align_words
, 2 },
2567 { "asg" , tic54x_asg
, 0 },
2568 { "eval" , tic54x_eval
, 0 },
2569 { "bss" , tic54x_bss
, 0 },
2570 { "byte" , tic54x_cons
, 'b' },
2571 { "ubyte" , tic54x_cons
, 'B' },
2572 { "char" , tic54x_cons
, 'c' },
2573 { "uchar" , tic54x_cons
, 'C' },
2574 { "clink" , tic54x_clink
, 0 },
2575 { "c_mode" , tic54x_address_mode
, c_mode
},
2576 { "copy" , tic54x_include
, 'c' },
2577 { "include" , tic54x_include
, 'i' },
2578 { "data" , tic54x_sect
, 'd' },
2579 { "double" , tic54x_float_cons
, 'd' },
2580 { "ldouble" , tic54x_float_cons
, 'l' },
2581 { "drlist" , s_ignore
, 0 },
2582 { "drnolist" , s_ignore
, 0 },
2583 { "emsg" , tic54x_message
, 'e' },
2584 { "mmsg" , tic54x_message
, 'm' },
2585 { "wmsg" , tic54x_message
, 'w' },
2587 { "end" , s_end
, 0 },
2589 { "far_mode" , tic54x_address_mode
, far_mode
},
2590 { "fclist" , tic54x_fclist
, 1 },
2591 { "fcnolist" , tic54x_fclist
, 0 },
2592 { "field" , tic54x_field
, -1 },
2593 { "float" , tic54x_float_cons
, 'f' },
2594 { "xfloat" , tic54x_float_cons
, 'x' },
2595 { "global" , tic54x_global
, 'g' },
2596 { "def" , tic54x_global
, 'd' },
2597 { "ref" , tic54x_global
, 'r' },
2598 { "half" , tic54x_cons
, 'h' },
2599 { "uhalf" , tic54x_cons
, 'H' },
2600 { "short" , tic54x_cons
, 's' },
2601 { "ushort" , tic54x_cons
, 'S' },
2602 { "if" , s_if
, (int) O_ne
},
2603 { "elseif" , s_elseif
, (int) O_ne
},
2604 { "else" , s_else
, 0 },
2605 { "endif" , s_endif
, 0 },
2606 { "int" , tic54x_cons
, 'i' },
2607 { "uint" , tic54x_cons
, 'I' },
2608 { "word" , tic54x_cons
, 'w' },
2609 { "uword" , tic54x_cons
, 'W' },
2610 { "label" , tic54x_label
, 0 }, /* Loadtime
2612 { "length" , s_ignore
, 0 },
2613 { "width" , s_ignore
, 0 },
2615 { "list" , listing_list
, 1 },
2616 { "nolist" , listing_list
, 0 },
2618 { "long" , tic54x_cons
, 'l' },
2619 { "ulong" , tic54x_cons
, 'L' },
2620 { "xlong" , tic54x_cons
, 'x' },
2621 { "loop" , tic54x_loop
, 1024 },
2622 { "break" , tic54x_break
, 0 },
2623 { "endloop" , tic54x_endloop
, 0 },
2624 { "mlib" , tic54x_mlib
, 0 },
2625 { "mlist" , s_ignore
, 0 },
2626 { "mnolist" , s_ignore
, 0 },
2627 { "mmregs" , tic54x_mmregs
, 0 },
2628 { "newblock" , tic54x_clear_local_labels
, 0 },
2629 { "option" , s_ignore
, 0 },
2630 { "p2align" , tic54x_p2align
, 0 },
2632 { "page" , listing_eject
, 0 },
2634 { "sblock" , tic54x_sblock
, 0 },
2635 { "sect" , tic54x_sect
, '*' },
2636 { "set" , tic54x_set
, 0 },
2637 { "equ" , tic54x_set
, 0 },
2638 { "space" , tic54x_space
, 0 },
2639 { "bes" , tic54x_space
, 1 },
2640 { "sslist" , tic54x_sslist
, 1 },
2641 { "ssnolist" , tic54x_sslist
, 0 },
2642 { "string" , tic54x_stringer
, 's' },
2643 { "pstring" , tic54x_stringer
, 'p' },
2644 { "struct" , tic54x_struct
, 0 },
2645 { "tag" , tic54x_tag
, 0 },
2646 { "endstruct", tic54x_endstruct
, 0 },
2647 { "tab" , s_ignore
, 0 },
2648 { "text" , tic54x_sect
, 't' },
2650 { "title" , listing_title
, 0 },
2652 { "union" , tic54x_struct
, 1 },
2653 { "endunion" , tic54x_endstruct
, 1 },
2654 { "usect" , tic54x_usect
, 0 },
2655 { "var" , tic54x_var
, 0 },
2656 { "version" , tic54x_version
, 0 },
2661 /* For debugging, strings for each operand type. */
2662 static const char *optypes
[] =
2664 "none", "Xmem", "Ymem", "pmad", "dmad", "Smem", "Lmem", "MMR", "PA",
2665 "Sind", "xpmad", "xpmad+", "MMRX", "MMRY",
2666 "SRC1", "SRC", "RND", "DST",
2669 "B", "A", "lk", "TS", "k8", "16", "BITC", "CC", "CC2", "CC3", "123", "031",
2670 "k5", "k8u", "ASM", "T", "DP", "ARP", "k3", "lku", "N", "SBIT", "12",
2676 md_parse_option (c
, arg
)
2684 case OPTION_COFF_VERSION
:
2686 int version
= atoi (arg
);
2688 if (version
!= 0 && version
!= 1 && version
!= 2)
2689 as_fatal (_("Bad COFF version '%s'"), arg
);
2690 /* FIXME -- not yet implemented. */
2693 case OPTION_CPU_VERSION
:
2695 cpu
= lookup_version (arg
);
2698 as_fatal (_("Bad CPU version '%s'"), arg
);
2701 case OPTION_ADDRESS_MODE
:
2703 address_mode_needs_set
= 1;
2705 case OPTION_STDERR_TO_FILE
:
2707 char *filename
= arg
;
2708 FILE *fp
= fopen (filename
, "w+");
2711 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2713 if ((fp
= freopen (filename
, "w+", stderr
)) == NULL
)
2714 as_fatal (_("Can't redirect stderr to the file '%s'"), filename
);
2722 /* Create a "local" substitution string hash table for a new macro level
2723 Some docs imply that macros have to use .newblock in order to be able
2724 to re-use a local label. We effectively do an automatic .newblock by
2725 deleting the local label hash between macro invocations. */
2728 tic54x_macro_start ()
2731 subsym_hash
[macro_level
] = hash_new ();
2732 local_label_hash
[macro_level
] = hash_new ();
2736 tic54x_macro_info (info
)
2739 struct formal_struct
2741 struct formal_struct
*next
; /* Next formal in list */
2742 sb name
; /* Name of the formal */
2743 sb def
; /* The default value */
2744 sb actual
; /* The actual argument (changed on
2746 int index
; /* The index of the formal
2747 0 .. formal_count - 1 */
2751 sb sub
; /* Substitution text. */
2752 int formal_count
; /* Number of formal args. */
2753 struct formal_struct
*formals
; /* Pointer to list of
2755 struct hash_control
*formal_hash
; /* Hash table of formals. */
2758 macro
= (struct macro_struct
*) info
;
2760 /* Put the formal args into the substitution symbol table. */
2761 for (entry
= macro
->formals
; entry
; entry
= entry
->next
)
2763 char *name
= strncpy (xmalloc (entry
->name
.len
+ 1),
2764 entry
->name
.ptr
, entry
->name
.len
);
2765 char *value
= strncpy (xmalloc (entry
->actual
.len
+ 1),
2766 entry
->actual
.ptr
, entry
->actual
.len
);
2768 name
[entry
->name
.len
] = '\0';
2769 value
[entry
->actual
.len
] = '\0';
2770 hash_insert (subsym_hash
[macro_level
], name
, value
);
2774 /* Get rid of this macro's .var's, arguments, and local labels. */
2779 hash_die (subsym_hash
[macro_level
]);
2780 subsym_hash
[macro_level
] = NULL
;
2781 hash_die (local_label_hash
[macro_level
]);
2782 local_label_hash
[macro_level
] = NULL
;
2787 subsym_symlen (a
, ignore
)
2789 char *ignore ATTRIBUTE_UNUSED
;
2794 /* Compare symbol A to string B. */
2797 subsym_symcmp (a
, b
)
2801 return strcmp (a
, b
);
2804 /* Return the index of the first occurrence of B in A, or zero if none
2805 assumes b is an integer char value as a string. Index is one-based. */
2808 subsym_firstch (a
, b
)
2813 char *tmp
= strchr (a
, val
);
2815 return tmp
? tmp
- a
+ 1 : 0;
2818 /* Similar to firstch, but returns index of last occurrence of B in A. */
2821 subsym_lastch (a
, b
)
2826 char *tmp
= strrchr (a
, val
);
2828 return tmp
? tmp
- a
+ 1 : 0;
2831 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2835 subsym_isdefed (a
, ignore
)
2837 char *ignore ATTRIBUTE_UNUSED
;
2839 symbolS
*symbolP
= symbol_find (a
);
2841 return symbolP
!= NULL
;
2844 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2845 A, or zero if B is a null string. Both arguments *must* be substitution
2846 symbols, unsubstituted. */
2849 subsym_ismember (sym
, list
)
2853 char *elem
, *ptr
, *listv
;
2858 listv
= subsym_lookup (list
, macro_level
);
2861 as_bad (_("Undefined substitution symbol '%s'"), list
);
2862 ignore_rest_of_line ();
2866 ptr
= elem
= xmalloc (strlen (listv
) + 1);
2867 strcpy (elem
, listv
);
2868 while (*ptr
&& *ptr
!= ',')
2872 subsym_create_or_replace (sym
, elem
);
2874 /* Reassign the list. */
2875 subsym_create_or_replace (list
, ptr
);
2877 /* Assume this value, docs aren't clear. */
2881 /* Return zero if not a constant; otherwise:
2889 subsym_iscons (a
, ignore
)
2891 char *ignore ATTRIBUTE_UNUSED
;
2895 parse_expression (a
, &exp
);
2897 if (exp
.X_op
== O_constant
)
2899 int len
= strlen (a
);
2901 switch (TOUPPER (a
[len
- 1]))
2914 /* No suffix; either octal, hex, or decimal. */
2915 if (*a
== '0' && len
> 1)
2917 if (TOUPPER (a
[1]) == 'X')
2927 /* Return 1 if A is a valid symbol name. Expects string input. */
2930 subsym_isname (a
, ignore
)
2932 char *ignore ATTRIBUTE_UNUSED
;
2934 if (!is_name_beginner (*a
))
2938 if (!is_part_of_name (*a
))
2945 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2946 been seen; if so, recognize any memory-mapped register.
2947 Note this does not recognize "A" or "B" accumulators. */
2950 subsym_isreg (a
, ignore
)
2952 char *ignore ATTRIBUTE_UNUSED
;
2954 if (hash_find (reg_hash
, a
))
2956 if (hash_find (mmreg_hash
, a
))
2961 /* Return the structure size, given the stag. */
2964 subsym_structsz (name
, ignore
)
2966 char *ignore ATTRIBUTE_UNUSED
;
2968 struct stag
*stag
= (struct stag
*) hash_find (stag_hash
, name
);
2976 /* If anybody actually uses this, they can fix it :)
2977 FIXME I'm not sure what the "reference point" of a structure is. It might
2978 be either the initial offset given .struct, or it may be the offset of the
2979 structure within another structure, or it might be something else
2980 altogether. since the TI assembler doesn't seem to ever do anything but
2981 return zero, we punt and return zero. */
2984 subsym_structacc (stag_name
, ignore
)
2985 char *stag_name ATTRIBUTE_UNUSED
;
2986 char *ignore ATTRIBUTE_UNUSED
;
2992 math_ceil (arg1
, ignore
)
2994 float ignore ATTRIBUTE_UNUSED
;
2996 return (float) ceil (arg1
);
3000 math_cvi (arg1
, ignore
)
3002 float ignore ATTRIBUTE_UNUSED
;
3008 math_floor (arg1
, ignore
)
3010 float ignore ATTRIBUTE_UNUSED
;
3012 return (float) floor (arg1
);
3016 math_fmod (arg1
, arg2
)
3020 return (int) arg1
% (int) arg2
;
3024 math_int (arg1
, ignore
)
3026 float ignore ATTRIBUTE_UNUSED
;
3028 return ((float) ((int) arg1
)) == arg1
;
3032 math_round (arg1
, ignore
)
3034 float ignore ATTRIBUTE_UNUSED
;
3036 return arg1
> 0 ? (int) (arg1
+ 0.5) : (int) (arg1
- 0.5);
3040 math_sgn (arg1
, ignore
)
3042 float ignore ATTRIBUTE_UNUSED
;
3044 return (arg1
< 0) ? -1 : (arg1
? 1 : 0);
3048 math_trunc (arg1
, ignore
)
3050 float ignore ATTRIBUTE_UNUSED
;
3056 math_acos (arg1
, ignore
)
3058 float ignore ATTRIBUTE_UNUSED
;
3060 return (float) acos (arg1
);
3064 math_asin (arg1
, ignore
)
3066 float ignore ATTRIBUTE_UNUSED
;
3068 return (float) asin (arg1
);
3072 math_atan (arg1
, ignore
)
3074 float ignore ATTRIBUTE_UNUSED
;
3076 return (float) atan (arg1
);
3080 math_atan2 (arg1
, arg2
)
3084 return (float) atan2 (arg1
, arg2
);
3088 math_cosh (arg1
, ignore
)
3090 float ignore ATTRIBUTE_UNUSED
;
3092 return (float) cosh (arg1
);
3096 math_cos (arg1
, ignore
)
3098 float ignore ATTRIBUTE_UNUSED
;
3100 return (float) cos (arg1
);
3104 math_cvf (arg1
, ignore
)
3106 float ignore ATTRIBUTE_UNUSED
;
3108 return (float) arg1
;
3112 math_exp (arg1
, ignore
)
3114 float ignore ATTRIBUTE_UNUSED
;
3116 return (float) exp (arg1
);
3120 math_fabs (arg1
, ignore
)
3122 float ignore ATTRIBUTE_UNUSED
;
3124 return (float) fabs (arg1
);
3127 /* expr1 * 2^expr2. */
3130 math_ldexp (arg1
, arg2
)
3134 return arg1
* (float) pow (2.0, arg2
);
3138 math_log10 (arg1
, ignore
)
3140 float ignore ATTRIBUTE_UNUSED
;
3142 return (float) log10 (arg1
);
3146 math_log (arg1
, ignore
)
3148 float ignore ATTRIBUTE_UNUSED
;
3150 return (float) log (arg1
);
3154 math_max (arg1
, arg2
)
3158 return (arg1
> arg2
) ? arg1
: arg2
;
3162 math_min (arg1
, arg2
)
3166 return (arg1
< arg2
) ? arg1
: arg2
;
3170 math_pow (arg1
, arg2
)
3174 return (float) pow (arg1
, arg2
);
3178 math_sin (arg1
, ignore
)
3180 float ignore ATTRIBUTE_UNUSED
;
3182 return (float) sin (arg1
);
3186 math_sinh (arg1
, ignore
)
3188 float ignore ATTRIBUTE_UNUSED
;
3190 return (float) sinh (arg1
);
3194 math_sqrt (arg1
, ignore
)
3196 float ignore ATTRIBUTE_UNUSED
;
3198 return (float) sqrt (arg1
);
3202 math_tan (arg1
, ignore
)
3204 float ignore ATTRIBUTE_UNUSED
;
3206 return (float) tan (arg1
);
3210 math_tanh (arg1
, ignore
)
3212 float ignore ATTRIBUTE_UNUSED
;
3214 return (float) tanh (arg1
);
3217 /* Built-in substitution symbol functions and math functions. */
3221 int (*proc
) PARAMS ((char *, char *));
3223 } subsym_proc_entry
;
3225 static const subsym_proc_entry subsym_procs
[] =
3227 /* Assembler built-in string substitution functions. */
3228 { "$symlen", subsym_symlen
, 1, },
3229 { "$symcmp", subsym_symcmp
, 2, },
3230 { "$firstch", subsym_firstch
, 2, },
3231 { "$lastch", subsym_lastch
, 2, },
3232 { "$isdefed", subsym_isdefed
, 1, },
3233 { "$ismember", subsym_ismember
, 2, },
3234 { "$iscons", subsym_iscons
, 1, },
3235 { "$isname", subsym_isname
, 1, },
3236 { "$isreg", subsym_isreg
, 1, },
3237 { "$structsz", subsym_structsz
, 1, },
3238 { "$structacc", subsym_structacc
, 1, },
3245 float (*proc
) PARAMS ((float, float));
3250 static const math_proc_entry math_procs
[] =
3252 /* Integer-returning built-in math functions. */
3253 { "$cvi", math_cvi
, 1, 1 },
3254 { "$int", math_int
, 1, 1 },
3255 { "$sgn", math_sgn
, 1, 1 },
3257 /* Float-returning built-in math functions. */
3258 { "$acos", math_acos
, 1, 0 },
3259 { "$asin", math_asin
, 1, 0 },
3260 { "$atan", math_atan
, 1, 0 },
3261 { "$atan2", math_atan2
, 2, 0 },
3262 { "$ceil", math_ceil
, 1, 0 },
3263 { "$cosh", math_cosh
, 1, 0 },
3264 { "$cos", math_cos
, 1, 0 },
3265 { "$cvf", math_cvf
, 1, 0 },
3266 { "$exp", math_exp
, 1, 0 },
3267 { "$fabs", math_fabs
, 1, 0 },
3268 { "$floor", math_floor
, 1, 0 },
3269 { "$fmod", math_fmod
, 2, 0 },
3270 { "$ldexp", math_ldexp
, 2, 0 },
3271 { "$log10", math_log10
, 1, 0 },
3272 { "$log", math_log
, 1, 0 },
3273 { "$max", math_max
, 2, 0 },
3274 { "$min", math_min
, 2, 0 },
3275 { "$pow", math_pow
, 2, 0 },
3276 { "$round", math_round
, 1, 0 },
3277 { "$sin", math_sin
, 1, 0 },
3278 { "$sinh", math_sinh
, 1, 0 },
3279 { "$sqrt", math_sqrt
, 1, 0 },
3280 { "$tan", math_tan
, 1, 0 },
3281 { "$tanh", math_tanh
, 1, 0 },
3282 { "$trunc", math_trunc
, 1, 0 },
3283 { NULL
, NULL
, 0, 0 },
3291 const subsym_proc_entry
*subsym_proc
;
3292 const math_proc_entry
*math_proc
;
3293 const char *hash_err
;
3295 char *TIC54X_DIR
= getenv ("TIC54X_DIR");
3296 char *A_DIR
= TIC54X_DIR
? TIC54X_DIR
: getenv ("A_DIR");
3300 /* Look for A_DIR and add it to the include list. */
3303 char *tmp
= xstrdup (A_DIR
);
3307 char *next
= strchr (tmp
, ';');
3311 add_include_dir (tmp
);
3314 while (tmp
!= NULL
);
3317 op_hash
= hash_new ();
3318 for (tm
= (template *) tic54x_optab
; tm
->name
; tm
++)
3320 if (hash_find (op_hash
, tm
->name
))
3322 hash_err
= hash_insert (op_hash
, tm
->name
, (char *) tm
);
3324 as_fatal ("Internal Error: Can't hash %s: %s",
3325 tm
->name
, hash_err
);
3327 parop_hash
= hash_new ();
3328 for (tm
= (template *) tic54x_paroptab
; tm
->name
; tm
++)
3330 if (hash_find (parop_hash
, tm
->name
))
3332 hash_err
= hash_insert (parop_hash
, tm
->name
, (char *) tm
);
3334 as_fatal ("Internal Error: Can't hash %s: %s",
3335 tm
->name
, hash_err
);
3337 reg_hash
= hash_new ();
3338 for (sym
= (symbol
*) regs
; sym
->name
; sym
++)
3340 /* Add basic registers to the symbol table. */
3341 symbolS
*symbolP
= symbol_new (sym
->name
, absolute_section
,
3342 (valueT
) sym
->value
, &zero_address_frag
);
3343 SF_SET_LOCAL (symbolP
);
3344 symbol_table_insert (symbolP
);
3345 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3347 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3348 hash_err
= hash_insert (reg_hash
, sym
->name
, (char *) sym
);
3349 mmreg_hash
= hash_new ();
3350 for (sym
= (symbol
*) mmregs
; sym
->name
; sym
++)
3351 hash_err
= hash_insert (mmreg_hash
, sym
->name
, (char *) sym
);
3353 cc_hash
= hash_new ();
3354 for (sym
= (symbol
*) condition_codes
; sym
->name
; sym
++)
3355 hash_err
= hash_insert (cc_hash
, sym
->name
, (char *) sym
);
3357 cc2_hash
= hash_new ();
3358 for (sym
= (symbol
*) cc2_codes
; sym
->name
; sym
++)
3359 hash_err
= hash_insert (cc2_hash
, sym
->name
, (char *) sym
);
3361 cc3_hash
= hash_new ();
3362 for (sym
= (symbol
*) cc3_codes
; sym
->name
; sym
++)
3363 hash_err
= hash_insert (cc3_hash
, sym
->name
, (char *) sym
);
3365 sbit_hash
= hash_new ();
3366 for (sym
= (symbol
*) status_bits
; sym
->name
; sym
++)
3367 hash_err
= hash_insert (sbit_hash
, sym
->name
, (char *) sym
);
3369 misc_symbol_hash
= hash_new ();
3370 for (symname
= (char **) misc_symbols
; *symname
; symname
++)
3371 hash_err
= hash_insert (misc_symbol_hash
, *symname
, *symname
);
3373 /* Only the base substitution table and local label table are initialized;
3374 the others (for local macro substitution) get instantiated as needed. */
3375 local_label_hash
[0] = hash_new ();
3376 subsym_hash
[0] = hash_new ();
3377 for (subsym_proc
= subsym_procs
; subsym_proc
->name
; subsym_proc
++)
3378 hash_err
= hash_insert (subsym_hash
[0], subsym_proc
->name
,
3379 (char *) subsym_proc
);
3381 math_hash
= hash_new ();
3382 for (math_proc
= math_procs
; math_proc
->name
; math_proc
++)
3384 /* Insert into the main subsym hash for recognition; insert into
3385 the math hash to actually store information. */
3386 hash_err
= hash_insert (subsym_hash
[0], math_proc
->name
,
3387 (char *) math_proc
);
3388 hash_err
= hash_insert (math_hash
, math_proc
->name
,
3389 (char *) math_proc
);
3391 subsym_recurse_hash
= hash_new ();
3392 stag_hash
= hash_new ();
3396 is_accumulator (operand
)
3397 struct opstruct
*operand
;
3399 return strcasecmp (operand
->buf
, "a") == 0
3400 || strcasecmp (operand
->buf
, "b") == 0;
3403 /* Return the number of operands found, or -1 on error, copying the
3404 operands into the given array and the accompanying expressions into
3408 get_operands (operands
, line
)
3409 struct opstruct operands
[];
3414 int expecting_operand
= 0;
3417 while (numexp
< MAX_OPERANDS
&& !is_end_of_line
[(int) *lptr
])
3419 int paren_not_balanced
= 0;
3420 char *op_start
, *op_end
;
3422 while (*lptr
&& ISSPACE (*lptr
))
3425 while (paren_not_balanced
|| *lptr
!= ',')
3429 if (paren_not_balanced
)
3431 as_bad ("Unbalanced parenthesis in operand %d", numexp
);
3438 ++paren_not_balanced
;
3439 else if (*lptr
== ')')
3440 --paren_not_balanced
;
3444 if (op_end
!= op_start
)
3446 int len
= op_end
- op_start
;
3448 strncpy (operands
[numexp
].buf
, op_start
, len
);
3449 operands
[numexp
].buf
[len
] = 0;
3450 /* Trim trailing spaces; while the preprocessor gets rid of most,
3451 there are weird usage patterns that can introduce them
3452 (i.e. using strings for macro args). */
3453 while (len
> 0 && ISSPACE (operands
[numexp
].buf
[len
- 1]))
3454 operands
[numexp
].buf
[--len
] = 0;
3460 if (expecting_operand
|| *lptr
== ',')
3462 as_bad ("Expecting operand after ','");
3468 if (*++lptr
== '\0')
3470 as_bad ("Expecting operand after ','");
3473 expecting_operand
= 1;
3477 while (*lptr
&& ISSPACE (*lptr
++))
3479 if (!is_end_of_line
[(int) *lptr
])
3481 as_bad ("Extra junk on line");
3485 /* OK, now parse them into expressions. */
3486 for (i
= 0; i
< numexp
; i
++)
3488 memset (&operands
[i
].exp
, 0, sizeof (operands
[i
].exp
));
3489 if (operands
[i
].buf
[0] == '#')
3492 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3494 else if (operands
[i
].buf
[0] == '@')
3496 /* Direct notation. */
3497 parse_expression (operands
[i
].buf
+ 1, &operands
[i
].exp
);
3499 else if (operands
[i
].buf
[0] == '*')
3502 char *paren
= strchr (operands
[i
].buf
, '(');
3504 /* Allow immediate syntax in the inner expression. */
3505 if (paren
&& paren
[1] == '#')
3508 /* Pull out the lk expression or SP offset, if present. */
3511 int len
= strlen (paren
);
3512 char *end
= paren
+ len
;
3515 while (end
[-1] != ')')
3518 as_bad (_("Badly formed address expression"));
3523 parse_expression (paren
, &operands
[i
].exp
);
3527 operands
[i
].exp
.X_op
= O_absent
;
3530 parse_expression (operands
[i
].buf
, &operands
[i
].exp
);
3536 /* Predicates for different operand types. */
3539 is_immediate (operand
)
3540 struct opstruct
*operand
;
3542 return *operand
->buf
== '#';
3545 /* This is distinguished from immediate because some numbers must be constants
3546 and must *not* have the '#' prefix. */
3549 is_absolute (operand
)
3550 struct opstruct
*operand
;
3552 return operand
->exp
.X_op
== O_constant
&& !is_immediate (operand
);
3555 /* Is this an indirect operand? */
3558 is_indirect (operand
)
3559 struct opstruct
*operand
;
3561 return operand
->buf
[0] == '*';
3564 /* Is this a valid dual-memory operand? */
3568 struct opstruct
*operand
;
3570 if (is_indirect (operand
) && strncasecmp (operand
->buf
, "*ar", 3) == 0)
3572 char *tmp
= operand
->buf
+ 3;
3577 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3578 valid_mod
= *tmp
== '\0' ||
3579 strcasecmp (tmp
, "-") == 0 ||
3580 strcasecmp (tmp
, "+") == 0 ||
3581 strcasecmp (tmp
, "+0%") == 0;
3582 return arf
>= 2 && arf
<= 5 && valid_mod
;
3589 struct opstruct
*operand
;
3591 return (is_absolute (operand
)
3592 || is_immediate (operand
)
3593 || hash_find (mmreg_hash
, operand
->buf
) != 0);
3597 is_type (operand
, type
)
3598 struct opstruct
*operand
;
3604 return operand
->buf
[0] == 0;
3607 return is_dual (operand
);
3609 return is_indirect (operand
);
3611 /* This one *must* be immediate. */
3612 return is_immediate (operand
);
3621 /* Address may be a numeric, indirect, or an expression. */
3622 return !is_immediate (operand
);
3625 return is_mmreg (operand
);
3630 return is_accumulator (operand
);
3632 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'B';
3634 return is_accumulator (operand
) && TOUPPER (operand
->buf
[0]) == 'A';
3636 return strncasecmp ("ar", operand
->buf
, 2) == 0
3637 && ISDIGIT (operand
->buf
[2]);
3639 return hash_find (sbit_hash
, operand
->buf
) != 0 || is_absolute (operand
);
3641 return hash_find (cc_hash
, operand
->buf
) != 0;
3643 return hash_find (cc2_hash
, operand
->buf
) != 0;
3645 return hash_find (cc3_hash
, operand
->buf
) != 0
3646 || is_immediate (operand
) || is_absolute (operand
);
3648 return (is_immediate (operand
) || is_absolute (operand
))
3649 && operand
->exp
.X_add_number
== 16;
3651 /* Allow st0 or st1 instead of a numeric. */
3652 return is_absolute (operand
) || is_immediate (operand
) ||
3653 strcasecmp ("st0", operand
->buf
) == 0 ||
3654 strcasecmp ("st1", operand
->buf
) == 0;
3657 return is_absolute (operand
) || is_immediate (operand
);
3659 return (is_immediate (operand
) || is_absolute (operand
))
3660 && operand
->exp
.X_add_number
>= 0 && operand
->exp
.X_add_number
< 16;
3662 /* Let this one catch out-of-range values. */
3663 return (is_immediate (operand
) || is_absolute (operand
))
3664 && operand
->exp
.X_add_number
!= 16;
3668 return is_absolute (operand
) || is_immediate (operand
);
3670 return is_immediate (operand
)
3671 && operand
->exp
.X_op
== O_constant
3672 && operand
->exp
.X_add_number
>= 0
3673 && operand
->exp
.X_add_number
< 256;
3676 /* Allow anything; assumes opcodes are ordered with Smem operands
3682 /* Just make sure it's an integer; check range later. */
3683 return is_immediate (operand
);
3685 return strcasecmp ("t", operand
->buf
) == 0 ||
3686 strcasecmp ("treg", operand
->buf
) == 0;
3688 return strcasecmp ("ts", operand
->buf
) == 0;
3690 return strcasecmp ("asm", operand
->buf
) == 0;
3692 return strcasecmp ("trn", operand
->buf
) == 0;
3694 return strcasecmp ("dp", operand
->buf
) == 0;
3696 return strcasecmp ("arp", operand
->buf
) == 0;
3703 operands_match (insn
, operands
, opcount
, refoptype
, minops
, maxops
)
3705 struct opstruct
*operands
;
3707 const enum optype
*refoptype
;
3711 int op
= 0, refop
= 0;
3713 if (opcount
== 0 && minops
== 0)
3716 while (op
<= maxops
&& refop
<= maxops
)
3718 while (!is_type (&operands
[op
], OPTYPE (refoptype
[refop
])))
3720 /* Skip an optional template operand if it doesn't agree
3721 with the current operand. */
3722 if (refoptype
[refop
] & OPT
)
3733 /* Save the actual operand type for later use. */
3734 operands
[op
].type
= OPTYPE (refoptype
[refop
]);
3737 /* Have we matched them all yet? */
3742 /* If a later operand is *not* optional, no match. */
3743 if ((refoptype
[refop
] & OPT
) == 0)
3745 /* Flag any implicit default OP_DST operands so we know to add
3746 them explicitly when encoding the operand later. */
3747 if (OPTYPE (refoptype
[refop
]) == OP_DST
)
3748 insn
->using_default_dst
= 1;
3760 /* 16-bit direct memory address
3761 Explicit dmad operands are always in last word of insn (usually second
3762 word, but bumped to third if lk addressing is used)
3764 We allow *(dmad) notation because the TI assembler allows it.
3767 0 for 16-bit addresses
3768 1 for full 23-bit addresses
3769 2 for the upper 7 bits of a 23-bit address (LDX). */
3772 encode_dmad (insn
, operand
, xpc_code
)
3774 struct opstruct
*operand
;
3777 int op
= 1 + insn
->is_lkaddr
;
3779 /* Only allow *(dmad) expressions; all others are invalid. */
3780 if (is_indirect (operand
) && operand
->buf
[strlen (operand
->buf
) - 1] != ')')
3782 as_bad (_("Invalid dmad syntax '%s'"), operand
->buf
);
3786 insn
->opcode
[op
].addr_expr
= operand
->exp
;
3788 if (insn
->opcode
[op
].addr_expr
.X_op
== O_constant
)
3790 valueT value
= insn
->opcode
[op
].addr_expr
.X_add_number
;
3794 insn
->opcode
[0].word
&= 0xFF80;
3795 insn
->opcode
[0].word
|= (value
>> 16) & 0x7F;
3796 insn
->opcode
[1].word
= value
& 0xFFFF;
3798 else if (xpc_code
== 2)
3799 insn
->opcode
[op
].word
= (value
>> 16) & 0xFFFF;
3801 insn
->opcode
[op
].word
= value
;
3805 /* Do the fixup later; just store the expression. */
3806 insn
->opcode
[op
].word
= 0;
3807 insn
->opcode
[op
].r_nchars
= 2;
3809 if (amode
== c_mode
)
3810 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3811 else if (xpc_code
== 1)
3813 /* This relocation spans two words, so adjust accordingly. */
3814 insn
->opcode
[0].addr_expr
= operand
->exp
;
3815 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_23
;
3816 insn
->opcode
[0].r_nchars
= 4;
3817 insn
->opcode
[0].unresolved
= 1;
3818 /* It's really 2 words, but we want to stop encoding after the
3819 first, since we must encode both words at once. */
3822 else if (xpc_code
== 2)
3823 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_MS7_OF_23
;
3825 insn
->opcode
[op
].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3827 insn
->opcode
[op
].unresolved
= 1;
3833 /* 7-bit direct address encoding. */
3836 encode_address (insn
, operand
)
3838 struct opstruct
*operand
;
3840 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3841 insn
->opcode
[0].addr_expr
= operand
->exp
;
3843 if (operand
->exp
.X_op
== O_constant
)
3844 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
& 0x7F);
3847 if (operand
->exp
.X_op
== O_register
)
3848 as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand
->buf
);
3849 /* Do the fixup later; just store the expression. */
3850 insn
->opcode
[0].r_nchars
= 1;
3851 insn
->opcode
[0].r_type
= BFD_RELOC_TIC54X_PARTLS7
;
3852 insn
->opcode
[0].unresolved
= 1;
3859 encode_indirect (insn
, operand
)
3861 struct opstruct
*operand
;
3866 if (insn
->is_lkaddr
)
3868 /* lk addresses always go in the second insn word. */
3869 mod
= ((TOUPPER (operand
->buf
[1]) == 'A') ? 12 :
3870 (operand
->buf
[1] == '(') ? 15 :
3871 (strchr (operand
->buf
, '%') != NULL
) ? 14 : 13);
3872 arf
= ((mod
== 12) ? operand
->buf
[3] - '0' :
3873 (mod
== 15) ? 0 : operand
->buf
[4] - '0');
3875 insn
->opcode
[1].addr_expr
= operand
->exp
;
3877 if (operand
->exp
.X_op
== O_constant
)
3878 insn
->opcode
[1].word
= operand
->exp
.X_add_number
;
3881 insn
->opcode
[1].word
= 0;
3882 insn
->opcode
[1].r_nchars
= 2;
3883 insn
->opcode
[1].r_type
= BFD_RELOC_TIC54X_16_OF_23
;
3884 insn
->opcode
[1].unresolved
= 1;
3887 else if (strncasecmp (operand
->buf
, "*sp (", 4) == 0)
3889 /* Stack offsets look the same as 7-bit direct addressing. */
3890 return encode_address (insn
, operand
);
3894 arf
= (TOUPPER (operand
->buf
[1]) == 'A' ?
3895 operand
->buf
[3] : operand
->buf
[4]) - '0';
3897 if (operand
->buf
[1] == '+')
3899 mod
= 3; /* *+ARx */
3900 if (insn
->tm
->flags
& FL_SMR
)
3901 as_warn (_("Address mode *+ARx is write-only. "
3902 "Results of reading are undefined."));
3904 else if (operand
->buf
[4] == '\0')
3906 else if (operand
->buf
[5] == '\0')
3907 mod
= (operand
->buf
[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3908 else if (operand
->buf
[6] == '\0')
3910 if (operand
->buf
[5] == '0')
3911 mod
= (operand
->buf
[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3913 mod
= (operand
->buf
[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3915 else if (TOUPPER (operand
->buf
[6]) == 'B')
3916 mod
= (operand
->buf
[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3917 else if (TOUPPER (operand
->buf
[6]) == '%')
3918 mod
= (operand
->buf
[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3921 as_bad (_("Unrecognized indirect address format \"%s\""),
3927 insn
->opcode
[0].word
|= 0x80 | (mod
<< 3) | arf
;
3933 encode_integer (insn
, operand
, which
, min
, max
, mask
)
3935 struct opstruct
*operand
;
3939 unsigned short mask
;
3941 long parse
, integer
;
3943 insn
->opcode
[which
].addr_expr
= operand
->exp
;
3945 if (operand
->exp
.X_op
== O_constant
)
3947 parse
= operand
->exp
.X_add_number
;
3948 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3949 instead of negative. */
3950 if ((parse
& 0x8000) && min
== -32768 && max
== 32767)
3951 integer
= (short) parse
;
3955 if (integer
>= min
&& integer
<= max
)
3957 insn
->opcode
[which
].word
|= (integer
& mask
);
3960 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3961 operand
->buf
, min
, max
);
3965 if (insn
->opcode
[which
].addr_expr
.X_op
== O_constant
)
3967 insn
->opcode
[which
].word
|=
3968 insn
->opcode
[which
].addr_expr
.X_add_number
& mask
;
3972 /* Do the fixup later; just store the expression. */
3973 bfd_reloc_code_real_type rtype
=
3974 (mask
== 0x1FF ? BFD_RELOC_TIC54X_PARTMS9
:
3975 mask
== 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23
:
3976 mask
== 0x7F ? BFD_RELOC_TIC54X_PARTLS7
: BFD_RELOC_8
);
3977 int size
= (mask
== 0x1FF || mask
== 0xFFFF) ? 2 : 1;
3979 if (rtype
== BFD_RELOC_8
)
3980 as_bad (_("Error in relocation handling"));
3982 insn
->opcode
[which
].r_nchars
= size
;
3983 insn
->opcode
[which
].r_type
= rtype
;
3984 insn
->opcode
[which
].unresolved
= 1;
3994 encode_condition (insn
, operand
)
3996 struct opstruct
*operand
;
3998 symbol
*cc
= (symbol
*) hash_find (cc_hash
, operand
->buf
);
4001 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
4004 #define CC_GROUP 0x40
4006 #define CATG_A1 0x07
4007 #define CATG_B1 0x30
4008 #define CATG_A2 0x30
4009 #define CATG_B2 0x0C
4010 #define CATG_C2 0x03
4011 /* Disallow group 1 conditions mixed with group 2 conditions
4012 if group 1, allow only one category A and one category B
4013 if group 2, allow only one each of category A, B, and C. */
4014 if (((insn
->opcode
[0].word
& 0xFF) != 0))
4016 if ((insn
->opcode
[0].word
& CC_GROUP
) != (cc
->value
& CC_GROUP
))
4018 as_bad (_("Condition \"%s\" does not match preceding group"),
4022 if (insn
->opcode
[0].word
& CC_GROUP
)
4024 if ((insn
->opcode
[0].word
& CC_ACC
) != (cc
->value
& CC_ACC
))
4026 as_bad (_("Condition \"%s\" uses a different accumulator from "
4027 "a preceding condition"),
4031 if ((insn
->opcode
[0].word
& CATG_A1
) && (cc
->value
& CATG_A1
))
4033 as_bad (_("Only one comparison conditional allowed"));
4036 if ((insn
->opcode
[0].word
& CATG_B1
) && (cc
->value
& CATG_B1
))
4038 as_bad (_("Only one overflow conditional allowed"));
4042 else if ( ((insn
->opcode
[0].word
& CATG_A2
) && (cc
->value
& CATG_A2
))
4043 || ((insn
->opcode
[0].word
& CATG_B2
) && (cc
->value
& CATG_B2
))
4044 || ((insn
->opcode
[0].word
& CATG_C2
) && (cc
->value
& CATG_C2
)))
4046 as_bad (_("Duplicate %s conditional"), operand
->buf
);
4051 insn
->opcode
[0].word
|= cc
->value
;
4056 encode_cc3 (insn
, operand
)
4058 struct opstruct
*operand
;
4060 symbol
*cc3
= (symbol
*) hash_find (cc3_hash
, operand
->buf
);
4061 int value
= cc3
? cc3
->value
: operand
->exp
.X_add_number
<< 8;
4063 if ((value
& 0x0300) != value
)
4065 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
4068 insn
->opcode
[0].word
|= value
;
4073 encode_arx (insn
, operand
)
4075 struct opstruct
*operand
;
4077 int arf
= strlen (operand
->buf
) >= 3 ? operand
->buf
[2] - '0' : -1;
4079 if (strncasecmp ("ar", operand
->buf
, 2) || arf
< 0 || arf
> 7)
4081 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
4084 insn
->opcode
[0].word
|= arf
;
4089 encode_cc2 (insn
, operand
)
4091 struct opstruct
*operand
;
4093 symbol
*cc2
= (symbol
*) hash_find (cc2_hash
, operand
->buf
);
4097 as_bad (_("Unrecognized condition code \"%s\""), operand
->buf
);
4100 insn
->opcode
[0].word
|= cc2
->value
;
4105 encode_operand (insn
, type
, operand
)
4108 struct opstruct
*operand
;
4110 int ext
= (insn
->tm
->flags
& FL_EXT
) != 0;
4112 if (type
== OP_MMR
&& operand
->exp
.X_op
!= O_constant
)
4114 /* Disallow long-constant addressing for memory-mapped addressing. */
4115 if (insn
->is_lkaddr
)
4117 as_bad (_("lk addressing modes are invalid for memory-mapped "
4118 "register addressing"));
4122 /* Warn about *+ARx when used with MMR operands. */
4123 if (strncasecmp (operand
->buf
, "*+ar", 4) == 0)
4125 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
4126 "register addressing. Resulting behavior is "
4136 /* 16-bit immediate value. */
4137 return encode_dmad (insn
, operand
, 0);
4139 if (TOUPPER (*operand
->buf
) == 'B')
4141 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 9);
4142 if (insn
->using_default_dst
)
4143 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4147 /* Make sure this agrees with the OP_DST operand. */
4148 if (!((TOUPPER (operand
->buf
[0]) == 'B') ^
4149 ((insn
->opcode
[0].word
& (1 << 8)) != 0)))
4151 as_bad (_("Destination accumulator for each part of this parallel "
4152 "instruction must be different"));
4158 if (TOUPPER (operand
->buf
[0]) == 'B')
4159 insn
->opcode
[ext
? (1 + insn
->is_lkaddr
) : 0].word
|= (1 << 8);
4164 int mod
= (operand
->buf
[4] == '\0' ? 0 : /* *arx */
4165 operand
->buf
[4] == '-' ? 1 : /* *arx- */
4166 operand
->buf
[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
4167 int arf
= operand
->buf
[3] - '0' - 2;
4168 int code
= (mod
<< 2) | arf
;
4169 insn
->opcode
[0].word
|= (code
<< (type
== OP_Xmem
? 4 : 0));
4174 if (!is_indirect (operand
))
4175 return encode_address (insn
, operand
);
4178 return encode_indirect (insn
, operand
);
4180 return encode_dmad (insn
, operand
, 2);
4182 return encode_dmad (insn
, operand
, 1);
4185 return encode_dmad (insn
, operand
, 0);
4187 return encode_arx (insn
, operand
);
4192 int value
= operand
->exp
.X_add_number
;
4195 insn
->opcode
[0].word
|= value
;
4198 if (value
< 16 || value
> 24)
4200 as_bad (_("Memory mapped register \"%s\" out of range"),
4204 if (type
== OP_MMRX
)
4205 insn
->opcode
[0].word
|= (value
- 16) << 4;
4207 insn
->opcode
[0].word
|= (value
- 16);
4215 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4218 return encode_integer (insn
, operand
, ext
+ insn
->is_lkaddr
,
4221 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4222 -32768, 32767, 0xFFFF);
4224 return encode_condition (insn
, operand
);
4226 return encode_cc2 (insn
, operand
);
4228 return encode_cc3 (insn
, operand
);
4230 return encode_integer (insn
, operand
, 0, 0, 15, 0xF);
4232 return encode_integer (insn
, operand
, 0, -128, 127, 0xFF);
4235 int value
= operand
->exp
.X_add_number
;
4237 if (value
< 1 || value
> 3)
4239 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4242 code
= value
== 1 ? 0 : value
== 2 ? 0x2 : 0x1;
4243 insn
->opcode
[0].word
|= (code
<< 8);
4247 return encode_integer (insn
, operand
, 0, 0, 31, 0x1F);
4249 return encode_integer (insn
, operand
, 0, 0, 255, 0xFF);
4251 return encode_integer (insn
, operand
, 1 + insn
->is_lkaddr
,
4255 symbol
*sbit
= (symbol
*) hash_find (sbit_hash
, operand
->buf
);
4256 int value
= is_absolute (operand
) ?
4257 operand
->exp
.X_add_number
: (sbit
? sbit
->value
: -1);
4260 if (insn
->opcount
== 1)
4264 as_bad (_("A status register or status bit name is required"));
4267 /* Guess the register based on the status bit; "ovb" is the last
4268 status bit defined for st0. */
4269 if (sbit
> (symbol
*) hash_find (sbit_hash
, "ovb"))
4274 as_bad (_("Unrecognized status bit \"%s\""), operand
->buf
);
4277 insn
->opcode
[0].word
|= value
;
4278 insn
->opcode
[0].word
|= (reg
<< 9);
4282 if (strcasecmp (operand
->buf
, "st0") == 0
4283 || strcasecmp (operand
->buf
, "st1") == 0)
4285 insn
->opcode
[0].word
|=
4286 ((unsigned short) (operand
->buf
[2] - '0')) << 9;
4289 else if (operand
->exp
.X_op
== O_constant
4290 && (operand
->exp
.X_add_number
== 0
4291 || operand
->exp
.X_add_number
== 1))
4293 insn
->opcode
[0].word
|=
4294 ((unsigned short) (operand
->exp
.X_add_number
)) << 9;
4297 as_bad (_("Invalid status register \"%s\""), operand
->buf
);
4300 return encode_integer (insn
, operand
, 0, -16, 15, 0x1F);
4302 return encode_integer (insn
, operand
, 0, 0, 7, 0x7);
4304 return encode_integer (insn
, operand
, 0, 0, 0x1FF, 0x1FF);
4306 if (operand
->exp
.X_add_number
!= 1
4307 && operand
->exp
.X_add_number
!= 2)
4309 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand
->buf
);
4312 insn
->opcode
[0].word
|= (operand
->exp
.X_add_number
- 1) << 9;
4321 /* No encoding necessary. */
4335 flagword oldflags
= bfd_get_section_flags (stdoutput
, now_seg
);
4336 flagword flags
= oldflags
| SEC_CODE
;
4338 if (! bfd_set_section_flags (stdoutput
, now_seg
, flags
))
4339 as_warn (_("error setting flags for \"%s\": %s"),
4340 bfd_section_name (stdoutput
, now_seg
),
4341 bfd_errmsg (bfd_get_error ()));
4343 for (i
= 0; i
< insn
->words
; i
++)
4345 int size
= (insn
->opcode
[i
].unresolved
4346 && insn
->opcode
[i
].r_type
== BFD_RELOC_TIC54X_23
) ? 4 : 2;
4347 char *p
= frag_more (size
);
4350 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
, 2);
4352 md_number_to_chars (p
, (valueT
) insn
->opcode
[i
].word
<< 16, 4);
4354 if (insn
->opcode
[i
].unresolved
)
4355 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
,
4356 insn
->opcode
[i
].r_nchars
, &insn
->opcode
[i
].addr_expr
,
4357 FALSE
, insn
->opcode
[i
].r_type
);
4361 /* Convert the operand strings into appropriate opcode values
4362 return the total number of words used by the instruction. */
4370 /* Only non-parallel instructions support lk addressing. */
4371 if (!(insn
->tm
->flags
& FL_PAR
))
4373 for (i
= 0; i
< insn
->opcount
; i
++)
4375 if ((OPTYPE (insn
->operands
[i
].type
) == OP_Smem
4376 || OPTYPE (insn
->operands
[i
].type
) == OP_Lmem
4377 || OPTYPE (insn
->operands
[i
].type
) == OP_Sind
)
4378 && strchr (insn
->operands
[i
].buf
, '(')
4379 /* Don't mistake stack-relative addressing for lk addressing. */
4380 && strncasecmp (insn
->operands
[i
].buf
, "*sp (", 4) != 0)
4382 insn
->is_lkaddr
= 1;
4383 insn
->lkoperand
= i
;
4388 insn
->words
= insn
->tm
->words
+ insn
->is_lkaddr
;
4390 insn
->opcode
[0].word
= insn
->tm
->opcode
;
4391 if (insn
->tm
->flags
& FL_EXT
)
4392 insn
->opcode
[1 + insn
->is_lkaddr
].word
= insn
->tm
->opcode2
;
4394 for (i
= 0; i
< insn
->opcount
; i
++)
4396 enum optype type
= insn
->operands
[i
].type
;
4398 if (!encode_operand (insn
, type
, &insn
->operands
[i
]))
4401 if (insn
->tm
->flags
& FL_PAR
)
4402 for (i
= 0; i
< insn
->paropcount
; i
++)
4404 enum optype partype
= insn
->paroperands
[i
].type
;
4406 if (!encode_operand (insn
, partype
, &insn
->paroperands
[i
]))
4416 optimize_insn (insn
)
4419 /* Optimize some instructions, helping out the brain-dead programmer. */
4420 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4421 if (strcasecmp (insn
->tm
->name
, "add") == 0)
4423 if (insn
->opcount
> 1
4424 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4425 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4426 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4427 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4430 insn
->using_default_dst
= 1;
4434 /* Try to collapse if Xmem and shift count is zero. */
4435 if ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4436 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
4437 && is_zero (insn
->operands
[1]))
4438 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4439 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4440 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4441 && is_type (&insn
->operands
[1], OP_SHIFT
)
4442 && is_zero (insn
->operands
[1]) && insn
->opcount
== 3))
4444 insn
->operands
[1] = insn
->operands
[2];
4449 else if (strcasecmp (insn
->tm
->name
, "ld") == 0)
4451 if (insn
->opcount
== 3 && insn
->operands
[0].type
!= OP_SRC
)
4453 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4454 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4455 && is_zero (insn
->operands
[1])
4456 && (OPTYPE (insn
->tm
->operand_types
[0]) != OP_lk
4457 || (insn
->operands
[0].exp
.X_op
== O_constant
4458 && insn
->operands
[0].exp
.X_add_number
<= 255
4459 && insn
->operands
[0].exp
.X_add_number
>= 0)))
4461 insn
->operands
[1] = insn
->operands
[2];
4467 else if (strcasecmp (insn
->tm
->name
, "sth") == 0
4468 || strcasecmp (insn
->tm
->name
, "stl") == 0)
4470 if ((OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
4471 || OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
)
4472 && is_zero (insn
->operands
[1]))
4474 insn
->operands
[1] = insn
->operands
[2];
4479 else if (strcasecmp (insn
->tm
->name
, "sub") == 0)
4481 if (insn
->opcount
> 1
4482 && is_accumulator (&insn
->operands
[insn
->opcount
- 2])
4483 && is_accumulator (&insn
->operands
[insn
->opcount
- 1])
4484 && strcasecmp (insn
->operands
[insn
->opcount
- 2].buf
,
4485 insn
->operands
[insn
->opcount
- 1].buf
) == 0)
4488 insn
->using_default_dst
= 1;
4492 if ( ((OPTYPE (insn
->tm
->operand_types
[0]) == OP_Smem
4493 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHIFT
)
4494 || (OPTYPE (insn
->tm
->operand_types
[0]) == OP_Xmem
4495 && OPTYPE (insn
->tm
->operand_types
[1]) == OP_SHFT
))
4496 && is_zero (insn
->operands
[1])
4497 && insn
->opcount
== 3)
4499 insn
->operands
[1] = insn
->operands
[2];
4507 /* Find a matching template if possible, and get the operand strings. */
4510 tic54x_parse_insn (insn
, line
)
4514 insn
->tm
= (template *) hash_find (op_hash
, insn
->mnemonic
);
4517 as_bad (_("Unrecognized instruction \"%s\""), insn
->mnemonic
);
4521 insn
->opcount
= get_operands (insn
->operands
, line
);
4522 if (insn
->opcount
< 0)
4525 /* Check each variation of operands for this mnemonic. */
4526 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
, insn
->mnemonic
) == 0)
4528 if (insn
->opcount
>= insn
->tm
->minops
4529 && insn
->opcount
<= insn
->tm
->maxops
4530 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4531 insn
->tm
->operand_types
,
4532 insn
->tm
->minops
, insn
->tm
->maxops
))
4534 /* SUCCESS! now try some optimizations. */
4535 if (optimize_insn (insn
))
4537 insn
->tm
= (template *) hash_find (op_hash
,
4546 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4547 line
, insn
->mnemonic
);
4551 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4552 won't be able to see the next line. */
4553 static int parallel_on_next_line_hint
= 0;
4555 /* See if this is part of a parallel instruction
4556 Look for a subsequent line starting with "||". */
4559 next_line_shows_parallel (next_line
)
4562 /* Look for the second half. */
4563 while (ISSPACE (*next_line
))
4566 return (next_line
[0] == PARALLEL_SEPARATOR
4567 && next_line
[1] == PARALLEL_SEPARATOR
);
4571 tic54x_parse_parallel_insn_firstline (insn
, line
)
4575 insn
->tm
= (template *) hash_find (parop_hash
, insn
->mnemonic
);
4578 as_bad (_("Unrecognized parallel instruction \"%s\""),
4583 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4584 insn
->mnemonic
) == 0)
4586 insn
->opcount
= get_operands (insn
->operands
, line
);
4587 if (insn
->opcount
< 0)
4589 if (insn
->opcount
== 2
4590 && operands_match (insn
, &insn
->operands
[0], insn
->opcount
,
4591 insn
->tm
->operand_types
, 2, 2))
4597 /* Didn't find a matching parallel; try for a normal insn. */
4601 /* Parse the second line of a two-line parallel instruction. */
4604 tic54x_parse_parallel_insn_lastline (insn
, line
)
4608 int valid_mnemonic
= 0;
4610 insn
->paropcount
= get_operands (insn
->paroperands
, line
);
4611 while (insn
->tm
->name
&& strcasecmp (insn
->tm
->name
,
4612 insn
->mnemonic
) == 0)
4614 if (strcasecmp (insn
->tm
->parname
, insn
->parmnemonic
) == 0)
4618 if (insn
->paropcount
>= insn
->tm
->minops
4619 && insn
->paropcount
<= insn
->tm
->maxops
4620 && operands_match (insn
, insn
->paroperands
,
4622 insn
->tm
->paroperand_types
,
4623 insn
->tm
->minops
, insn
->tm
->maxops
))
4629 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4632 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4633 insn
->mnemonic
, insn
->parmnemonic
);
4638 /* If quotes found, return copy of line up to closing quote;
4639 otherwise up until terminator.
4640 If it's a string, pass as-is; otherwise attempt substitution symbol
4641 replacement on the value. */
4644 subsym_get_arg (line
, terminators
, str
, nosub
)
4652 int is_string
= *line
== '"';
4653 int is_char
= ISDIGIT (*line
);
4657 while (ISDIGIT (*ptr
))
4660 *str
= xmalloc (ptr
- line
+ 1);
4661 strncpy (*str
, line
, ptr
- line
);
4662 (*str
)[ptr
- line
] = 0;
4666 char *savedp
= input_line_pointer
;
4669 input_line_pointer
= ptr
;
4670 *str
= demand_copy_C_string (&len
);
4671 endp
= input_line_pointer
;
4672 input_line_pointer
= savedp
;
4674 /* Do forced substitutions if requested. */
4675 if (!nosub
&& **str
== ':')
4676 *str
= subsym_substitute (*str
, 1);
4680 char *term
= terminators
;
4683 while (*ptr
&& *ptr
!= *term
)
4694 *str
= xmalloc (ptr
- line
+ 1);
4695 strncpy (*str
, line
, ptr
- line
);
4696 (*str
)[ptr
- line
] = 0;
4697 /* Do simple substitution, if available. */
4698 if (!nosub
&& (value
= subsym_lookup (*str
, macro_level
)) != NULL
)
4705 /* Replace the given substitution string.
4706 We start at the innermost macro level, so that existing locals remain local
4707 Note: we're treating macro args identically to .var's; I don't know if
4708 that's compatible w/TI's assembler. */
4711 subsym_create_or_replace (name
, value
)
4717 for (i
= macro_level
; i
> 0; i
--)
4719 if (hash_find (subsym_hash
[i
], name
))
4721 hash_replace (subsym_hash
[i
], name
, value
);
4725 if (hash_find (subsym_hash
[0], name
))
4726 hash_replace (subsym_hash
[0], name
, value
);
4728 hash_insert (subsym_hash
[0], name
, value
);
4731 /* Look up the substitution string replacement for the given symbol.
4732 Start with the innermost macro substitution table given and work
4736 subsym_lookup (name
, nest_level
)
4740 char *value
= hash_find (subsym_hash
[nest_level
], name
);
4742 if (value
|| nest_level
== 0)
4745 return subsym_lookup (name
, nest_level
- 1);
4748 /* Do substitution-symbol replacement on the given line (recursively).
4749 return the argument if no substitution was done
4751 Also look for built-in functions ($func (arg)) and local labels.
4753 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4756 subsym_substitute (line
, forced
)
4760 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4761 replace it in the input. */
4762 char *replacement
; /* current replacement for LINE. */
4763 char *head
; /* Start of line. */
4764 char *ptr
; /* Current examination point. */
4765 int changed
= 0; /* Did we make a substitution? */
4766 int eval_line
= 0; /* Is this line a .eval/.asg statement? */
4767 int eval_symbol
= 0; /* Are we in the middle of the symbol for
4769 char *eval_end
= NULL
;
4771 int line_conditional
= 0;
4774 /* Work with a copy of the input line. */
4775 replacement
= xmalloc (strlen (line
) + 1);
4776 strcpy (replacement
, line
);
4778 ptr
= head
= replacement
;
4780 /* Flag lines where we might need to replace a single '=' with two;
4781 GAS uses single '=' to assign macro args values, and possibly other
4782 places, so limit what we replace. */
4783 if (strstr (line
, ".if")
4784 || strstr (line
, ".elseif")
4785 || strstr (line
, ".break"))
4786 line_conditional
= 1;
4788 /* Watch out for .eval, so that we avoid doing substitution on the
4789 symbol being assigned a value. */
4790 if (strstr (line
, ".eval") || strstr (line
, ".asg"))
4793 /* If it's a macro definition, don't do substitution on the argument
4795 if (strstr (line
, ".macro"))
4798 while (!is_end_of_line
[(int) *ptr
])
4800 int current_char
= *ptr
;
4802 /* Need to update this since LINE may have been modified. */
4804 eval_end
= strrchr (ptr
, ',');
4806 /* Replace triple double quotes with bounding quote/escapes. */
4807 if (current_char
== '"' && ptr
[1] == '"' && ptr
[2] == '"')
4810 tmp
= strstr (ptr
+ 2, "\"\"\"");
4816 /* Replace a single '=' with a '==';
4817 for compatibility with older code only. */
4818 if (line_conditional
&& current_char
== '=')
4826 tmp
= xmalloc (strlen (head
) + 2 + strlen (ptr
) + 1);
4827 sprintf (tmp
, "%s==%s", head
, ptr
);
4828 /* Continue examining after the '=='. */
4829 ptr
= tmp
+ strlen (head
) + 2;
4831 head
= replacement
= tmp
;
4835 /* Flag when we've reached the symbol part of .eval/.asg. */
4836 if (eval_line
&& ptr
>= eval_end
)
4839 /* For each apparent symbol, see if it's a substitution symbol, and if
4840 so, replace it in the input. */
4841 if ((forced
&& current_char
== ':')
4842 || (!forced
&& is_name_beginner (current_char
)))
4844 char *name
; /* Symbol to be replaced. */
4845 char *savedp
= input_line_pointer
;
4848 char *tail
; /* Rest of line after symbol. */
4850 /* Skip the colon. */
4854 name
= input_line_pointer
= ptr
;
4855 c
= get_symbol_end ();
4856 /* '?' is not normally part of a symbol, but it IS part of a local
4860 *input_line_pointer
++ = c
;
4861 c
= *input_line_pointer
;
4862 *input_line_pointer
= '\0';
4864 /* Avoid infinite recursion; if a symbol shows up a second time for
4865 substitution, leave it as is. */
4866 if (hash_find (subsym_recurse_hash
, name
) == NULL
)
4867 value
= subsym_lookup (name
, macro_level
);
4869 as_warn (_("%s symbol recursion stopped at "
4870 "second appearance of '%s'"),
4871 forced
? "Forced substitution" : "Substitution", name
);
4872 ptr
= tail
= input_line_pointer
;
4873 input_line_pointer
= savedp
;
4875 /* Check for local labels; replace them with the appropriate
4877 if ((*name
== '$' && ISDIGIT (name
[1]) && name
[2] == '\0')
4878 || name
[strlen (name
) - 1] == '?')
4880 /* Use an existing identifier for that label if, available, or
4881 create a new, unique identifier. */
4882 value
= hash_find (local_label_hash
[macro_level
], name
);
4886 char *namecopy
= strcpy (xmalloc (strlen (name
) + 1), name
);
4888 value
= strcpy (xmalloc (strlen (name
) + sizeof (digit
) + 1),
4891 value
[strlen (value
) - 1] = '\0';
4892 sprintf (digit
, ".%d", local_label_id
++);
4893 strcat (value
, digit
);
4894 hash_insert (local_label_hash
[macro_level
], namecopy
, value
);
4896 /* Indicate where to continue looking for substitutions. */
4899 /* Check for built-in subsym and math functions. */
4900 else if (value
!= NULL
&& *name
== '$')
4902 subsym_proc_entry
*entry
= (subsym_proc_entry
*) value
;
4903 math_proc_entry
*math_entry
= hash_find (math_hash
, name
);
4904 char *arg1
, *arg2
= NULL
;
4909 as_bad (_("Unrecognized substitution symbol function"));
4912 else if (*ptr
!= '(')
4914 as_bad (_("Missing '(' after substitution symbol function"));
4918 if (math_entry
!= NULL
)
4920 float arg1
, arg2
= 0;
4921 volatile float fresult
;
4923 arg1
= (float) strtod (ptr
, &ptr
);
4924 if (math_entry
->nargs
== 2)
4928 as_bad (_("Expecting second argument"));
4931 arg2
= (float) strtod (ptr
, &ptr
);
4933 fresult
= (*math_entry
->proc
) (arg1
, arg2
);
4934 value
= xmalloc (128);
4935 if (math_entry
->int_return
)
4936 sprintf (value
, "%d", (int) fresult
);
4938 sprintf (value
, "%f", fresult
);
4941 as_bad (_("Extra junk in function call, expecting ')'"));
4944 /* Don't bother recursing; the replacement isn't a
4951 int arg_type
[2] = { *ptr
== '"' , 0 };
4952 int ismember
= !strcmp (entry
->name
, "$ismember");
4954 /* Parse one or two args, which must be a substitution
4955 symbol, string or a character-string constant. */
4956 /* For all functions, a string or substitution symbol may be
4957 used, with the following exceptions:
4958 firstch/lastch: 2nd arg must be character constant
4959 ismember: both args must be substitution symbols. */
4960 ptr
= subsym_get_arg (ptr
, ",)", &arg1
, ismember
);
4963 if (entry
->nargs
== 2)
4967 as_bad (_("Function expects two arguments"));
4970 /* Character constants are converted to numerics
4971 by the preprocessor. */
4972 arg_type
[1] = (ISDIGIT (*ptr
)) ? 2 : (*ptr
== '"');
4973 ptr
= subsym_get_arg (ptr
, ")", &arg2
, ismember
);
4975 /* Args checking. */
4976 if ((!strcmp (entry
->name
, "$firstch")
4977 || !strcmp (entry
->name
, "$lastch"))
4978 && arg_type
[1] != 2)
4980 as_bad (_("Expecting character constant argument"));
4984 && (arg_type
[0] != 0 || arg_type
[1] != 0))
4986 as_bad (_("Both arguments must be substitution symbols"));
4991 as_bad (_("Extra junk in function call, expecting ')'"));
4994 val
= (*entry
->proc
) (arg1
, arg2
);
4995 value
= xmalloc (64);
4996 sprintf (value
, "%d", val
);
4998 /* Fix things up to replace the entire expression, not just the
5004 if (value
!= NULL
&& !eval_symbol
)
5006 /* Replace the symbol with its string replacement and
5007 continue. Recursively replace VALUE until either no
5008 substitutions are performed, or a substitution that has been
5009 previously made is encountered again.
5011 put the symbol into the recursion hash table so we only
5012 try to replace a symbol once. */
5015 hash_insert (subsym_recurse_hash
, name
, name
);
5016 value
= subsym_substitute (value
, macro_level
> 0);
5017 hash_delete (subsym_recurse_hash
, name
);
5020 /* Temporarily zero-terminate where the symbol started. */
5026 /* Subscripted substitution symbol -- use just the
5027 indicated portion of the string; the description
5028 kinda indicates that forced substitution is not
5029 supposed to be recursive, but I'm not sure. */
5030 unsigned beg
, len
= 1; /* default to a single char */
5031 char *newval
= strcpy (xmalloc (strlen (value
) + 1),
5034 savedp
= input_line_pointer
;
5035 input_line_pointer
= tail
+ 1;
5036 beg
= get_absolute_expression ();
5039 as_bad (_("Invalid subscript (use 1 to %d)"),
5043 if (*input_line_pointer
== ',')
5045 ++input_line_pointer
;
5046 len
= get_absolute_expression ();
5047 if (beg
+ len
> strlen (value
))
5049 as_bad (_("Invalid length (use 0 to %d"),
5050 strlen (value
) - beg
);
5056 tail
= input_line_pointer
;
5059 as_bad (_("Missing ')' in subscripted substitution "
5060 "symbol expression"));
5064 input_line_pointer
= savedp
;
5070 tmp
= xmalloc (strlen (head
) + strlen (value
) +
5071 strlen (tail
+ 1) + 2);
5073 strcat (tmp
, value
);
5074 /* Make sure forced substitutions are properly terminated. */
5079 as_bad (_("Missing forced substitution terminator ':'"));
5084 /* Try to replace required whitespace
5085 eliminated by the preprocessor; technically, a forced
5086 substitution could come anywhere, even mid-symbol,
5087 e.g. if x is "0", 'sym:x:end' should result in 'sym0end',
5088 but 'sym:x: end' should result in 'sym0 end'.
5089 FIXME -- this should really be fixed in the preprocessor,
5090 but would require several new states;
5091 KEEP_WHITE_AROUND_COLON does part of the job, but isn't
5093 if ((is_part_of_name (tail
[1])
5096 || tail
[1] == '\0' || tail
[1] == ',' || tail
[1] == '"')
5103 /* Restore the character after the symbol end. */
5106 /* Continue examining after the replacement value. */
5107 ptr
= tmp
+ strlen (head
) + strlen (value
);
5109 head
= replacement
= tmp
;
5127 /* We use this to handle substitution symbols
5128 hijack input_line_pointer, replacing it with our substituted string.
5130 .sslist should enable listing the line after replacements are made...
5132 returns the new buffer limit. */
5135 tic54x_start_line_hook ()
5138 char *replacement
= NULL
;
5140 /* Work with a copy of the input line, including EOL char. */
5141 endp
= input_line_pointer
;
5142 while (!is_end_of_line
[(int) *endp
++])
5144 line
= xmalloc (endp
- input_line_pointer
+ 1);
5145 strncpy (line
, input_line_pointer
, endp
- input_line_pointer
+ 1);
5146 line
[endp
- input_line_pointer
] = 0;
5148 /* Scan ahead for parallel insns. */
5149 parallel_on_next_line_hint
= next_line_shows_parallel (endp
+ 1);
5151 /* If within a macro, first process forced replacements. */
5152 if (macro_level
> 0)
5153 replacement
= subsym_substitute (line
, 1);
5156 replacement
= subsym_substitute (replacement
, 0);
5158 if (replacement
!= line
)
5160 char *tmp
= replacement
;
5161 char *comment
= strchr (replacement
, ';');
5162 char endc
= replacement
[strlen (replacement
) - 1];
5164 /* Clean up the replacement; we'd prefer to have this done by the
5165 standard preprocessing equipment (maybe do_scrub_chars?)
5166 but for now, do a quick-and-dirty. */
5167 if (comment
!= NULL
)
5174 comment
= replacement
+ strlen (replacement
) - 1;
5176 /* Trim trailing whitespace. */
5177 while (ISSPACE (*comment
))
5184 /* Compact leading whitespace. */
5185 while (ISSPACE (tmp
[0]) && ISSPACE (tmp
[1]))
5188 input_line_pointer
= endp
;
5189 input_scrub_insert_line (tmp
);
5192 /* Keep track of whether we've done a substitution. */
5193 substitution_line
= 1;
5199 substitution_line
= 0;
5203 /* This is the guts of the machine-dependent assembler. STR points to a
5204 machine dependent instruction. This function is supposed to emit
5205 the frags/bytes it assembles to. */
5210 static int repeat_slot
= 0;
5211 static int delay_slots
= 0; /* How many delay slots left to fill? */
5212 static int is_parallel
= 0;
5213 static tic54x_insn insn
;
5215 char *savedp
= input_line_pointer
;
5218 input_line_pointer
= line
;
5219 c
= get_symbol_end ();
5223 if (address_mode_needs_set
)
5225 set_address_mode (amode
);
5226 address_mode_needs_set
= 0;
5239 strcpy (insn
.parmnemonic
, line
);
5240 lptr
= input_line_pointer
;
5242 input_line_pointer
= savedp
;
5244 if (tic54x_parse_parallel_insn_lastline (&insn
, lptr
))
5246 int words
= build_insn (&insn
);
5248 if (delay_slots
!= 0)
5250 if (words
> delay_slots
)
5252 as_bad (_("Instruction does not fit in available delay "
5253 "slots (%d-word insn, %d slots left)"),
5254 words
, delay_slots
);
5258 delay_slots
-= words
;
5264 memset (&insn
, 0, sizeof (insn
));
5265 strcpy (insn
.mnemonic
, line
);
5266 lptr
= input_line_pointer
;
5268 input_line_pointer
= savedp
;
5270 /* See if this line is part of a parallel instruction; if so, either this
5271 line or the next line will have the "||" specifier preceding the
5272 mnemonic, and we look for it in the parallel insn hash table. */
5273 if (strstr (line
, "||") != NULL
|| parallel_on_next_line_hint
)
5275 char *tmp
= strstr (line
, "||");
5279 if (tic54x_parse_parallel_insn_firstline (&insn
, lptr
))
5282 /* If the parallel part is on the same line, process it now,
5283 otherwise let the assembler pick up the next line for us. */
5286 while (ISSPACE (tmp
[2]))
5288 md_assemble (tmp
+ 2);
5293 as_bad (_("Unrecognized parallel instruction '%s'"), line
);
5298 if (tic54x_parse_insn (&insn
, lptr
))
5302 if ((insn
.tm
->flags
& FL_LP
)
5303 && cpu
!= V545LP
&& cpu
!= V546LP
)
5305 as_bad (_("Instruction '%s' requires an LP cpu version"),
5309 if ((insn
.tm
->flags
& FL_FAR
)
5310 && amode
!= far_mode
)
5312 as_bad (_("Instruction '%s' requires far mode addressing"),
5317 words
= build_insn (&insn
);
5319 /* Is this instruction in a delay slot? */
5322 if (words
> delay_slots
)
5324 as_warn (_("Instruction does not fit in available delay "
5325 "slots (%d-word insn, %d slots left). "
5326 "Resulting behavior is undefined."),
5327 words
, delay_slots
);
5331 /* Branches in delay slots are not allowed. */
5332 if (insn
.tm
->flags
& FL_BMASK
)
5334 as_warn (_("Instructions which cause PC discontinuity are not "
5335 "allowed in a delay slot. "
5336 "Resulting behavior is undefined."));
5338 delay_slots
-= words
;
5341 /* Is this instruction the target of a repeat? */
5344 if (insn
.tm
->flags
& FL_NR
)
5345 as_warn (_("'%s' is not repeatable. "
5346 "Resulting behavior is undefined."),
5348 else if (insn
.is_lkaddr
)
5349 as_warn (_("Instructions using long offset modifiers or absolute "
5350 "addresses are not repeatable. "
5351 "Resulting behavior is undefined."));
5355 /* Make sure we check the target of a repeat instruction. */
5356 if (insn
.tm
->flags
& B_REPEAT
)
5359 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5361 /* Make sure we check our delay slots for validity. */
5362 if (insn
.tm
->flags
& FL_DELAY
)
5365 /* FIXME -- warn if delay_slots != 0 at EOF. */
5370 /* Do a final adjustment on the symbol table; in this case, make sure we have
5371 a ".file" symbol. */
5374 tic54x_adjust_symtab ()
5376 if (symbol_rootP
== NULL
5377 || S_GET_STORAGE_CLASS (symbol_rootP
) != C_FILE
)
5381 as_where (&filename
, &lineno
);
5382 c_dot_file_symbol (filename
);
5386 /* In order to get gas to ignore any | chars at the start of a line,
5387 this function returns true if a | is found in a line.
5388 This lets us process parallel instructions, which span two lines. */
5391 tic54x_unrecognized_line (int c
)
5393 return c
== PARALLEL_SEPARATOR
;
5396 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5397 Encode their names so that only we see them and can map them to the
5399 FIXME -- obviously this isn't done yet. These locals still show up in the
5402 tic54x_define_label (sym
)
5406 static int local_label_count
= 0;
5407 const char *name
= S_GET_NAME (sym
);
5410 /* Just in case we need this later; note that this is not necessarily the
5411 same thing as line_label...
5412 When aligning or assigning labels to fields, sometimes the label is
5413 assigned other than the address at which the label appears.
5414 FIXME -- is this really needed? I think all the proper label assignment
5415 is done in tic54x_cons. */
5416 last_label_seen
= sym
;
5419 /* Try to parse something that normal parsing failed at. */
5422 tic54x_undefined_symbol (name
)
5427 /* Not sure how to handle predefined symbols. */
5428 if ((sym
= (symbol
*) hash_find (cc_hash
, name
)) != NULL
||
5429 (sym
= (symbol
*) hash_find (cc2_hash
, name
)) != NULL
||
5430 (sym
= (symbol
*) hash_find (cc3_hash
, name
)) != NULL
||
5431 (sym
= (symbol
*) hash_find (misc_symbol_hash
, name
)) != NULL
||
5432 (sym
= (symbol
*) hash_find (sbit_hash
, name
)) != NULL
)
5434 return symbol_new (name
, reg_section
,
5435 (valueT
) sym
->value
,
5436 &zero_address_frag
);
5439 if ((sym
= (symbol
*) hash_find (reg_hash
, name
)) != NULL
||
5440 (sym
= (symbol
*) hash_find (mmreg_hash
, name
)) != NULL
||
5441 !strcasecmp (name
, "a") || !strcasecmp (name
, "b"))
5443 return symbol_new (name
, reg_section
,
5444 (valueT
) sym
? sym
->value
: 0,
5445 &zero_address_frag
);
5451 /* Parse a name in an expression before the expression parser takes a stab at
5455 tic54x_parse_name (name
, exp
)
5456 char *name ATTRIBUTE_UNUSED
;
5457 expressionS
*exp ATTRIBUTE_UNUSED
;
5460 symbol
*sym
= (symbol
*) hash_find (mmreg_hash
, name
);
5462 /* If it's a MMREG, replace it with its constant value. */
5465 exp
->X_op
= O_constant
;
5466 exp
->X_add_number
= sym
->value
;
5474 md_atof (type
, literalP
, sizeP
)
5479 #define MAX_LITTLENUMS 2
5480 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5481 LITTLENUM_TYPE
*word
;
5482 /* Only one precision on the c54x. */
5484 char *t
= atof_ieee (input_line_pointer
, type
, words
);
5486 input_line_pointer
= t
;
5489 /* Target data is little-endian, but floats are stored
5490 big-"word"ian. ugh. */
5491 for (word
= words
; prec
--;)
5493 md_number_to_chars (literalP
, (long) (*word
++), sizeof (LITTLENUM_TYPE
));
5494 literalP
+= sizeof (LITTLENUM_TYPE
);
5501 tc_gen_reloc (section
, fixP
)
5506 bfd_reloc_code_real_type code
= fixP
->fx_r_type
;
5507 asymbol
*sym
= symbol_get_bfdsym (fixP
->fx_addsy
);
5509 rel
= (arelent
*) xmalloc (sizeof (arelent
));
5510 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5511 *rel
->sym_ptr_ptr
= sym
;
5512 /* We assume that all rel->address are host byte offsets. */
5513 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5514 rel
->address
/= OCTETS_PER_BYTE
;
5515 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5516 if (!strcmp (sym
->name
, section
->name
))
5517 rel
->howto
+= HOWTO_BANK
;
5521 const char *name
= S_GET_NAME (fixP
->fx_addsy
);
5524 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5525 name
, bfd_get_reloc_code_name (code
));
5531 /* Handle cons expressions. */
5534 tic54x_cons_fix_new (frag
, where
, octets
, exp
)
5540 bfd_reloc_code_real_type r
;
5545 as_bad (_("Unsupported relocation size %d"), octets
);
5546 r
= BFD_RELOC_TIC54X_16_OF_23
;
5549 r
= BFD_RELOC_TIC54X_16_OF_23
;
5552 /* TI assembler always uses this, regardless of addressing mode. */
5554 r
= BFD_RELOC_TIC54X_23
;
5556 /* We never want to directly generate this; this is provided for
5557 stabs support only. */
5561 fix_new_exp (frag
, where
, octets
, exp
, 0, r
);
5564 /* Attempt to simplify or even eliminate a fixup.
5565 To indicate that a fixup has been eliminated, set fixP->fx_done.
5567 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5570 md_apply_fix3 (fixP
, valP
, seg
)
5573 segT seg ATTRIBUTE_UNUSED
;
5575 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5576 valueT val
= * valP
;
5578 switch (fixP
->fx_r_type
)
5581 as_fatal ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
5583 case BFD_RELOC_TIC54X_MS7_OF_23
:
5584 val
= (val
>> 16) & 0x7F;
5586 case BFD_RELOC_TIC54X_16_OF_23
:
5588 bfd_put_16 (stdoutput
, val
, buf
);
5589 /* Indicate what we're actually writing, so that we don't get warnings
5590 about exceeding available space. */
5591 *valP
= val
& 0xFFFF;
5593 case BFD_RELOC_TIC54X_PARTLS7
:
5594 bfd_put_16 (stdoutput
,
5595 (bfd_get_16 (stdoutput
, buf
) & 0xFF80) | (val
& 0x7F),
5597 /* Indicate what we're actually writing, so that we don't get warnings
5598 about exceeding available space. */
5601 case BFD_RELOC_TIC54X_PARTMS9
:
5602 /* TI assembler doesn't shift its encoding for relocatable files, and is
5603 thus incompatible with this implementation's relocatable files. */
5604 bfd_put_16 (stdoutput
,
5605 (bfd_get_16 (stdoutput
, buf
) & 0xFE00) | (val
>> 7),
5609 case BFD_RELOC_TIC54X_23
:
5610 bfd_put_32 (stdoutput
,
5611 (bfd_get_32 (stdoutput
, buf
) & 0xFF800000) | val
,
5616 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
5620 /* This is our chance to record section alignment
5621 don't need to do anything here, since BFD does the proper encoding. */
5624 md_section_align (segment
, section_size
)
5625 segT segment ATTRIBUTE_UNUSED
;
5626 valueT section_size
;
5628 return section_size
;
5632 md_pcrel_from (fixP
)
5633 fixS
*fixP ATTRIBUTE_UNUSED
;
5638 #if defined OBJ_COFF
5641 tc_coff_fix2rtype (fixP
)
5644 return (fixP
->fx_r_type
);
5647 #endif /* OBJ_COFF */
5649 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5653 tic54x_number_to_chars (buf
, val
, n
)
5659 number_to_chars_littleendian (buf
, val
, n
);
5662 number_to_chars_littleendian (buf
, val
>> 16 , 2);
5663 number_to_chars_littleendian (buf
+ 2, val
& 0xFFFF, 2);
5668 tic54x_estimate_size_before_relax (frag
, seg
)
5669 fragS
*frag ATTRIBUTE_UNUSED
;
5670 segT seg ATTRIBUTE_UNUSED
;
5675 /* We use this to handle bit allocations which we couldn't handle before due
5676 to symbols being in different frags. return number of octets added. */
5679 tic54x_relax_frag (frag
, stretch
)
5681 long stretch ATTRIBUTE_UNUSED
;
5683 symbolS
*sym
= frag
->fr_symbol
;
5689 struct bit_info
*bi
= (struct bit_info
*) frag
->fr_opcode
;
5690 int bit_offset
= frag_bit_offset (frag_prev (frag
, bi
->seg
), bi
->seg
);
5691 int size
= S_GET_VALUE (sym
);
5692 fragS
*prev_frag
= bit_offset_frag (frag_prev (frag
, bi
->seg
), bi
->seg
);
5693 int available
= 16 - bit_offset
;
5695 if (symbol_get_frag (sym
) != &zero_address_frag
5696 || S_IS_COMMON (sym
)
5697 || !S_IS_DEFINED (sym
))
5698 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5699 _("non-absolute value used with .space/.bes"));
5703 as_warn (_("negative value ignored in %s"),
5704 bi
->type
== TYPE_SPACE
? ".space" :
5705 bi
->type
== TYPE_BES
? ".bes" : ".field");
5707 frag
->tc_frag_data
= frag
->fr_fix
= 0;
5711 if (bi
->type
== TYPE_FIELD
)
5713 /* Bit fields of 16 or larger will have already been handled. */
5714 if (bit_offset
!= 0 && available
>= size
)
5716 char *p
= prev_frag
->fr_literal
;
5718 valueT value
= bi
->value
;
5719 value
<<= available
- size
;
5720 value
|= ((unsigned short) p
[1] << 8) | p
[0];
5721 md_number_to_chars (p
, value
, 2);
5722 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5723 prev_frag
->tc_frag_data
= 0;
5725 symbol_set_frag (bi
->sym
, prev_frag
);
5726 /* This frag is no longer used. */
5727 growth
= -frag
->fr_fix
;
5729 frag
->tc_frag_data
= 0;
5733 char *p
= frag
->fr_literal
;
5735 valueT value
= bi
->value
<< (16 - size
);
5736 md_number_to_chars (p
, value
, 2);
5737 if ((frag
->tc_frag_data
= size
) == 16)
5738 frag
->tc_frag_data
= 0;
5744 if (bit_offset
!= 0 && bit_offset
< 16)
5746 if (available
>= size
)
5748 if ((prev_frag
->tc_frag_data
+= size
) == 16)
5749 prev_frag
->tc_frag_data
= 0;
5751 symbol_set_frag (bi
->sym
, prev_frag
);
5752 /* This frag is no longer used. */
5753 growth
= -frag
->fr_fix
;
5755 frag
->tc_frag_data
= 0;
5758 if (bi
->type
== TYPE_SPACE
&& bi
->sym
)
5759 symbol_set_frag (bi
->sym
, prev_frag
);
5762 growth
= (size
+ 15) / 16 * OCTETS_PER_BYTE
- frag
->fr_fix
;
5763 for (i
= 0; i
< growth
; i
++)
5764 frag
->fr_literal
[i
] = 0;
5765 frag
->fr_fix
= growth
;
5766 frag
->tc_frag_data
= size
% 16;
5767 /* Make sure any BES label points to the LAST word allocated. */
5768 if (bi
->type
== TYPE_BES
&& bi
->sym
)
5769 S_SET_VALUE (bi
->sym
, frag
->fr_fix
/ OCTETS_PER_BYTE
- 1);
5772 frag
->fr_symbol
= 0;
5773 frag
->fr_opcode
= 0;
5780 tic54x_convert_frag (abfd
, seg
, frag
)
5781 bfd
*abfd ATTRIBUTE_UNUSED
;
5782 segT seg ATTRIBUTE_UNUSED
;
5785 /* Offset is in bytes. */
5786 frag
->fr_offset
= (frag
->fr_next
->fr_address
5788 - frag
->fr_fix
) / frag
->fr_var
;
5789 if (frag
->fr_offset
< 0)
5791 as_bad_where (frag
->fr_file
, frag
->fr_line
,
5792 _("attempt to .space/.bes backwards? (%ld)"),
5793 (long) frag
->fr_offset
);
5795 frag
->fr_type
= rs_space
;
5798 /* We need to avoid having labels defined for certain directives/pseudo-ops
5799 since once the label is defined, it's in the symbol table for good. TI
5800 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5801 I guess, except I've never seen a definition of MRI syntax).
5803 C is the character that used to be at *REST, which points to the end of the
5806 Don't allow labels to start with '.' */
5809 tic54x_start_label (c
, rest
)
5813 /* If within .struct/.union, no auto line labels, please. */
5814 if (current_stag
!= NULL
)
5817 /* Disallow labels starting with "." */
5822 while (!is_end_of_line
[(int) label
[-1]])
5826 as_bad (_("Invalid label '%s'"), label
);
5831 if (is_end_of_line
[(int) c
])
5835 while (ISSPACE (c
= *++rest
))
5839 /* Don't let colon () define a label for any of these... */
5840 return (strncasecmp (rest
, ".tag", 4) != 0 || !ISSPACE (rest
[4]))
5841 && (strncasecmp (rest
, ".struct", 7) != 0 || !ISSPACE (rest
[7]))
5842 && (strncasecmp (rest
, ".union", 6) != 0 || !ISSPACE (rest
[6]))
5843 && (strncasecmp (rest
, ".macro", 6) != 0 || !ISSPACE (rest
[6]))
5844 && (strncasecmp (rest
, ".set", 4) != 0 || !ISSPACE (rest
[4]))
5845 && (strncasecmp (rest
, ".equ", 4) != 0 || !ISSPACE (rest
[4]));