file ms.gmo was initially added on branch binutils-2_18-branch.
[binutils.git] / gas / config / tc-tic54x.c
blob0fe8159a051aa3eabc806c568ce56342b18a40e5
1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Timothy Wall (twall@cygnus.com)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* Texas Instruments TMS320C54X machine specific gas.
24 Written by Timothy Wall (twall@alum.mit.edu).
26 Valuable things to do:
27 Pipeline conflict warnings
28 We encode/decode "ld #_label, dp" differently in relocatable files
29 This means we're not compatible with TI output containing those
30 expressions. We store the upper nine bits; TI stores the lower nine
31 bits. How they recover the original upper nine bits is beyond me.
33 Tests to add to expect testsuite:
34 '=' and '==' with .if, .elseif, and .break
36 Incompatibilities (mostly trivial):
37 We don't allow '''
38 We fill text section with zeroes instead of "nop"s
39 We don't convert '' or "" to a single instance
40 We don't convert '' to '\0'
41 We don't allow strings with .byte/.half/.short/.long
42 Probably details of the subsym stuff are different
43 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
45 COFF1 limits section names to 8 characters.
46 Some of the default behavior changed from COFF1 to COFF2. */
48 #include <limits.h>
49 #include "as.h"
50 #include "safe-ctype.h"
51 #include "sb.h"
52 #include "macro.h"
53 #include "subsegs.h"
54 #include "struc-symbol.h"
55 #include "opcode/tic54x.h"
56 #include "obj-coff.h"
57 #include <math.h>
60 static struct stag
62 symbolS *sym; /* Symbol for this stag; value is offset. */
63 const char *name; /* Shortcut to symbol name. */
64 bfd_vma size; /* Size of struct/union. */
65 int current_bitfield_offset; /* Temporary for tracking fields. */
66 int is_union;
67 struct stag_field /* List of fields. */
69 const char *name;
70 bfd_vma offset; /* Of start of this field. */
71 int bitfield_offset; /* Of start of this field. */
72 struct stag *stag; /* If field is struct/union. */
73 struct stag_field *next;
74 } *field;
75 /* For nesting; used only in stag construction. */
76 struct stag *inner; /* Enclosed .struct. */
77 struct stag *outer; /* Enclosing .struct. */
78 } *current_stag = NULL;
80 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
82 typedef struct _tic54x_insn
84 const template *tm; /* Opcode template. */
86 char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */
87 char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */
89 int opcount;
90 struct opstruct
92 char buf[MAX_LINE];
93 enum optype type;
94 expressionS exp;
95 } operands[MAX_OPERANDS];
97 int paropcount;
98 struct opstruct paroperands[MAX_OPERANDS];
100 int is_lkaddr;
101 int lkoperand;
102 int words; /* Size of insn in 16-bit words. */
103 int using_default_dst; /* Do we need to explicitly set an
104 omitted OP_DST operand? */
105 struct
107 unsigned short word; /* Final encoded opcode data. */
108 int unresolved;
109 int r_nchars; /* Relocation size. */
110 bfd_reloc_code_real_type r_type; /* Relocation type. */
111 expressionS addr_expr; /* Storage for unresolved expressions. */
112 } opcode[3];
113 } tic54x_insn;
115 enum cpu_version
117 VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9,
118 V545LP = 15, V546LP = 16
121 enum address_mode
123 c_mode, /* 16-bit addresses. */
124 far_mode /* >16-bit addresses. */
127 static segT stag_saved_seg;
128 static subsegT stag_saved_subseg;
130 const char comment_chars[] = ";";
131 const char line_comment_chars[] = ";*#"; /* At column zero only. */
132 const char line_separator_chars[] = ""; /* Not permitted. */
134 int emitting_long = 0;
136 /* Characters which indicate that this is a floating point constant. */
137 const char FLT_CHARS[] = "fF";
139 /* Characters that can be used to separate mantissa from exp in FP
140 nums. */
141 const char EXP_CHARS[] = "eE";
143 const char *md_shortopts = "";
145 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
146 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
147 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
148 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
150 struct option md_longopts[] =
152 { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE },
153 { "mf", no_argument, NULL, OPTION_ADDRESS_MODE },
154 { "mcpu", required_argument, NULL, OPTION_CPU_VERSION },
155 { "merrors-to-file", required_argument, NULL, OPTION_STDERR_TO_FILE },
156 { "me", required_argument, NULL, OPTION_STDERR_TO_FILE },
157 { NULL, no_argument, NULL, 0},
160 size_t md_longopts_size = sizeof (md_longopts);
162 static int assembly_begun = 0;
163 /* Addressing mode is not entirely implemented; the latest rev of the Other
164 assembler doesn't seem to make any distinction whatsoever; all relocations
165 are stored as extended relocatiosn. Older versions used REL16 vs RELEXT16,
166 but now it seems all relocations are RELEXT16. We use all RELEXT16.
168 The cpu version is kind of a waste of time as well. There is one
169 instruction (RND) for LP devices only, and several for devices with
170 extended addressing only. We include it for compatibility. */
171 static enum address_mode amode = c_mode;
172 static enum cpu_version cpu = VNONE;
174 /* Include string substitutions in listing? */
175 static int listing_sslist = 0;
177 /* Did we do subsym substitutions on the line? */
178 static int substitution_line = 0;
180 /* Last label seen. */
181 static symbolS *last_label_seen = NULL;
183 /* This ensures that all new labels are unique. */
184 static int local_label_id;
186 static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. */
187 static struct hash_control *math_hash; /* Built-in math functions. */
188 /* Allow maximum levels of macro nesting; level 0 is the main substitution
189 symbol table. The other assembler only does 32 levels, so there! */
190 static struct hash_control *subsym_hash[100];
192 /* Keep track of local labels so we can substitute them before GAS sees them
193 since macros use their own 'namespace' for local labels, use a separate hash
195 We do our own local label handling 'cuz it's subtly different from the
196 stock GAS handling.
198 We use our own macro nesting counter, since GAS overloads it when expanding
199 other things (like conditionals and repeat loops). */
200 static int macro_level = 0;
201 static struct hash_control *local_label_hash[100];
202 /* Keep track of struct/union tags. */
203 static struct hash_control *stag_hash;
204 static struct hash_control *op_hash;
205 static struct hash_control *parop_hash;
206 static struct hash_control *reg_hash;
207 static struct hash_control *mmreg_hash;
208 static struct hash_control *cc_hash;
209 static struct hash_control *cc2_hash;
210 static struct hash_control *cc3_hash;
211 static struct hash_control *sbit_hash;
212 static struct hash_control *misc_symbol_hash;
214 /* Only word (et al.), align, or conditionals are allowed within
215 .struct/.union. */
216 #define ILLEGAL_WITHIN_STRUCT() \
217 do \
218 if (current_stag != NULL) \
220 as_bad (_("pseudo-op illegal within .struct/.union")); \
221 return; \
223 while (0)
225 static void tic54x_emit_char PARAMS ((char));
226 static fragS * frag_prev PARAMS ((fragS *, segT));
227 static fragS * bit_offset_frag PARAMS ((fragS *, segT));
228 static int frag_bit_offset PARAMS ((fragS *, segT));
229 static char * parse_expression PARAMS ((char *, expressionS *));
230 static void tic54x_asg PARAMS ((int));
231 static void tic54x_eval PARAMS ((int));
232 static void tic54x_bss PARAMS ((int));
233 static void stag_add_field_symbols PARAMS ((struct stag *, const char *, bfd_vma, symbolS *, const char *));
234 static void stag_add_field PARAMS ((struct stag *, const char *, bfd_vma, struct stag *));
235 static void tic54x_struct PARAMS ((int));
236 static void tic54x_endstruct PARAMS ((int));
237 static void tic54x_tag PARAMS ((int));
238 static void tic54x_struct_field PARAMS ((int));
239 static void tic54x_cons PARAMS ((int));
240 static void tic54x_remove_local_label PARAMS ((const char *, PTR));
241 static void tic54x_clear_local_labels PARAMS ((int));
242 static void tic54x_sect PARAMS ((int));
243 static void tic54x_space PARAMS ((int));
244 static void tic54x_usect PARAMS ((int));
245 static enum cpu_version lookup_version PARAMS ((const char *));
246 static void set_cpu PARAMS ((enum cpu_version));
247 static void tic54x_version PARAMS ((int));
248 static void tic54x_float_cons PARAMS ((int));
249 static void tic54x_stringer PARAMS ((int));
250 static void tic54x_p2align PARAMS ((int));
251 static void tic54x_align_words PARAMS ((int));
252 static void tic54x_field PARAMS ((int));
253 static int tic54x_initialized_section PARAMS ((segT));
254 static void tic54x_clink PARAMS ((int));
255 static void tic54x_set_default_include PARAMS ((int));
256 static void tic54x_include PARAMS ((int));
257 static void tic54x_message PARAMS ((int));
258 static void tic54x_label PARAMS ((int));
259 static void tic54x_mmregs PARAMS ((int));
260 static void tic54x_loop PARAMS ((int));
261 static void tic54x_endloop PARAMS ((int));
262 static void tic54x_break PARAMS ((int));
263 static void set_address_mode PARAMS ((int));
264 static void tic54x_address_mode PARAMS ((int));
265 static void tic54x_sblock PARAMS ((int));
266 static void tic54x_set PARAMS ((int));
267 static void tic54x_fclist PARAMS ((int));
268 static void tic54x_sslist PARAMS ((int));
269 static void tic54x_var PARAMS ((int));
270 static void tic54x_mlib PARAMS ((int));
271 static int subsym_symlen PARAMS ((char *, char *));
272 static int subsym_symcmp PARAMS ((char *, char *));
273 static int subsym_firstch PARAMS ((char *, char *));
274 static int subsym_lastch PARAMS ((char *, char *));
275 static int subsym_isdefed PARAMS ((char *, char *));
276 static int subsym_ismember PARAMS ((char *, char *));
277 static int subsym_iscons PARAMS ((char *, char *));
278 static int subsym_isname PARAMS ((char *, char *));
279 static int subsym_isreg PARAMS ((char *, char *));
280 static int subsym_structsz PARAMS ((char *, char *));
281 static int subsym_structacc PARAMS ((char *, char *));
282 static float math_ceil PARAMS ((float, float));
283 static float math_cvi PARAMS ((float, float));
284 static float math_floor PARAMS ((float, float));
285 static float math_fmod PARAMS ((float, float));
286 static float math_int PARAMS ((float, float));
287 static float math_round PARAMS ((float, float));
288 static float math_sgn PARAMS ((float, float));
289 static float math_trunc PARAMS ((float, float));
290 static float math_acos PARAMS ((float, float));
291 static float math_asin PARAMS ((float, float));
292 static float math_atan PARAMS ((float, float));
293 static float math_atan2 PARAMS ((float, float));
294 static float math_cosh PARAMS ((float, float));
295 static float math_cos PARAMS ((float, float));
296 static float math_cvf PARAMS ((float, float));
297 static float math_exp PARAMS ((float, float));
298 static float math_fabs PARAMS ((float, float));
299 static float math_ldexp PARAMS ((float, float));
300 static float math_log10 PARAMS ((float, float));
301 static float math_log PARAMS ((float, float));
302 static float math_max PARAMS ((float, float));
303 static float math_min PARAMS ((float, float));
304 static float math_pow PARAMS ((float, float));
305 static float math_sin PARAMS ((float, float));
306 static float math_sinh PARAMS ((float, float));
307 static float math_sqrt PARAMS ((float, float));
308 static float math_tan PARAMS ((float, float));
309 static float math_tanh PARAMS ((float, float));
310 static int is_accumulator PARAMS ((struct opstruct *));
311 static int get_operands PARAMS ((struct opstruct operands[], char *));
312 static int is_immediate PARAMS ((struct opstruct *));
313 static int is_absolute PARAMS ((struct opstruct *));
314 static int is_indirect PARAMS ((struct opstruct *));
315 static int is_dual PARAMS ((struct opstruct *));
316 static int is_mmreg PARAMS ((struct opstruct *));
317 static int is_type PARAMS ((struct opstruct *, enum optype));
318 static int operands_match PARAMS ((tic54x_insn *, struct opstruct *, int, const enum optype *, int, int));
319 static int encode_dmad PARAMS ((tic54x_insn *, struct opstruct *, int));
320 static int encode_address PARAMS ((tic54x_insn *, struct opstruct *));
321 static int encode_indirect PARAMS ((tic54x_insn *, struct opstruct *));
322 static int encode_integer PARAMS ((tic54x_insn *, struct opstruct *, int, int, int, unsigned short));
323 static int encode_condition PARAMS ((tic54x_insn *, struct opstruct *));
324 static int encode_cc3 PARAMS ((tic54x_insn *, struct opstruct *));
325 static int encode_arx PARAMS ((tic54x_insn *, struct opstruct *));
326 static int encode_cc2 PARAMS ((tic54x_insn *, struct opstruct *));
327 static int encode_operand PARAMS ((tic54x_insn *, enum optype, struct opstruct *));
328 static void emit_insn PARAMS ((tic54x_insn *));
329 static int build_insn PARAMS ((tic54x_insn *));
330 static int optimize_insn PARAMS ((tic54x_insn *));
331 static int tic54x_parse_insn PARAMS ((tic54x_insn *, char *));
332 static int next_line_shows_parallel PARAMS ((char *));
333 static int tic54x_parse_parallel_insn_firstline PARAMS ((tic54x_insn *, char *));
334 static int tic54x_parse_parallel_insn_lastline PARAMS ((tic54x_insn *, char *));
335 static char * subsym_get_arg PARAMS ((char *, char *, char **, int));
336 static void subsym_create_or_replace PARAMS ((char *, char *));
337 static char * subsym_lookup PARAMS ((char *, int));
338 static char * subsym_substitute PARAMS ((char *, int));
341 void
342 md_show_usage (stream)
343 FILE *stream;
345 fprintf (stream, _("C54x-specific command line options:\n"));
346 fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n"));
347 fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n"));
348 fprintf (stream, _("-merrors-to-file <filename>\n"));
349 fprintf (stream, _("-me <filename> Redirect errors to a file\n"));
352 /* Output a single character (upper octect is zero). */
354 static void
355 tic54x_emit_char (c)
356 char c;
358 expressionS exp;
360 exp.X_op = O_constant;
361 exp.X_add_number = c;
362 emit_expr (&exp, 2);
365 /* Walk backwards in the frag chain. */
367 static fragS *
368 frag_prev (frag, seg)
369 fragS *frag;
370 segT seg;
372 segment_info_type *seginfo = seg_info (seg);
373 fragS *fragp;
375 for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
376 if (fragp->fr_next == frag)
377 return fragp;
379 return NULL;
382 static fragS *
383 bit_offset_frag (frag, seg)
384 fragS *frag;
385 segT seg;
387 while (frag != NULL)
389 if (frag->fr_fix == 0
390 && frag->fr_opcode == NULL
391 && frag->tc_frag_data == 0)
392 frag = frag_prev (frag, seg);
393 else
394 return frag;
396 return NULL;
399 /* Return the number of bits allocated in the most recent word, or zero if
400 none. .field/.space/.bes may leave words partially allocated. */
402 static int
403 frag_bit_offset (frag, seg)
404 fragS *frag;
405 segT seg;
407 frag = bit_offset_frag (frag, seg);
409 if (frag)
410 return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
412 return 0;
415 /* Read an expression from a C string; returns a pointer past the end of the
416 expression. */
418 static char *
419 parse_expression (str, exp)
420 char *str;
421 expressionS * exp;
423 char *s;
424 char *tmp;
426 tmp = input_line_pointer; /* Save line pointer. */
427 input_line_pointer = str;
428 expression (exp);
429 s = input_line_pointer;
430 input_line_pointer = tmp; /* Restore line pointer. */
431 return s; /* Return pointer to where parsing stopped. */
434 /* .asg "character-string"|character-string, symbol
436 .eval is the only pseudo-op allowed to perform arithmetic on substitution
437 symbols. all other use of symbols defined with .asg are currently
438 unsupported. */
440 static void
441 tic54x_asg (x)
442 int x ATTRIBUTE_UNUSED;
444 int c;
445 char *name;
446 char *str;
447 char *tmp;
448 int quoted = *input_line_pointer == '"';
450 ILLEGAL_WITHIN_STRUCT ();
452 if (quoted)
454 int len;
455 str = demand_copy_C_string (&len);
456 c = *input_line_pointer;
458 else
460 str = input_line_pointer;
461 while ((c = *input_line_pointer) != ',')
463 if (is_end_of_line[(int) *input_line_pointer])
464 break;
465 ++input_line_pointer;
467 *input_line_pointer = 0;
469 if (c != ',')
471 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
472 ignore_rest_of_line ();
473 return;
476 name = ++input_line_pointer;
477 c = get_symbol_end (); /* Get terminator. */
478 if (!ISALPHA (*name))
480 as_bad ("symbols assigned with .asg must begin with a letter");
481 ignore_rest_of_line ();
482 return;
485 tmp = xmalloc (strlen (str) + 1);
486 strcpy (tmp, str);
487 str = tmp;
488 tmp = xmalloc (strlen (name) + 1);
489 strcpy (tmp, name);
490 name = tmp;
491 subsym_create_or_replace (name, str);
492 *input_line_pointer = c;
493 demand_empty_rest_of_line ();
496 /* .eval expression, symbol
497 There's something screwy about this. The other assembler sometimes does and
498 sometimes doesn't substitute symbols defined with .eval.
499 We'll put the symbols into the subsym table as well as the normal symbol
500 table, since that's what works best. */
502 static void
503 tic54x_eval (x)
504 int x ATTRIBUTE_UNUSED;
506 char c;
507 int value;
508 char *name;
509 symbolS *symbolP;
510 char valuestr[32], *tmp;
511 int quoted;
513 ILLEGAL_WITHIN_STRUCT ();
515 SKIP_WHITESPACE ();
517 quoted = *input_line_pointer == '"';
518 if (quoted)
519 ++input_line_pointer;
520 value = get_absolute_expression ();
521 if (quoted)
523 if (*input_line_pointer != '"')
525 as_bad (_("Unterminated string after absolute expression"));
526 ignore_rest_of_line ();
527 return;
529 ++input_line_pointer;
531 if (*input_line_pointer++ != ',')
533 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
534 ignore_rest_of_line ();
535 return;
537 name = input_line_pointer;
538 c = get_symbol_end (); /* Get terminator. */
539 tmp = xmalloc (strlen (name) + 1);
540 name = strcpy (tmp, name);
541 *input_line_pointer = c;
543 if (!ISALPHA (*name))
545 as_bad (_("symbols assigned with .eval must begin with a letter"));
546 ignore_rest_of_line ();
547 return;
549 symbolP = symbol_new (name, absolute_section,
550 (valueT) value, &zero_address_frag);
551 SF_SET_LOCAL (symbolP);
552 symbol_table_insert (symbolP);
554 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
555 But since there's not written rule as to when, don't even bother trying
556 to match their behavior. */
557 sprintf (valuestr, "%d", value);
558 tmp = xmalloc (strlen (valuestr) + 1);
559 strcpy (tmp, valuestr);
560 subsym_create_or_replace (name, tmp);
562 demand_empty_rest_of_line ();
565 /* .bss symbol, size [, [blocking flag] [, alignment flag]
567 alignment is to a longword boundary; blocking is to 128-word boundary.
569 1) if there is a hole in memory, this directive should attempt to fill it
570 (not yet implemented).
572 2) if the blocking flag is not set, allocate at the current SPC
573 otherwise, check to see if the current SPC plus the space to be
574 allocated crosses the page boundary (128 words).
575 if there's not enough space, create a hole and align with the next page
576 boundary.
577 (not yet implemented). */
579 static void
580 tic54x_bss (x)
581 int x ATTRIBUTE_UNUSED;
583 char c;
584 char *name;
585 char *p;
586 int words;
587 segT current_seg;
588 subsegT current_subseg;
589 symbolS *symbolP;
590 int block = 0;
591 int align = 0;
593 ILLEGAL_WITHIN_STRUCT ();
595 current_seg = now_seg; /* Save current seg. */
596 current_subseg = now_subseg; /* Save current subseg. */
598 name = input_line_pointer;
599 c = get_symbol_end (); /* Get terminator. */
600 if (c != ',')
602 as_bad (".bss size argument missing\n");
603 ignore_rest_of_line ();
604 return;
607 ++input_line_pointer;
608 words = get_absolute_expression ();
609 if (words < 0)
611 as_bad (".bss size %d < 0!", words);
612 ignore_rest_of_line ();
613 return;
616 if (*input_line_pointer == ',')
618 /* The blocking flag may be missing. */
619 ++input_line_pointer;
620 if (*input_line_pointer != ',')
621 block = get_absolute_expression ();
622 else
623 block = 0;
625 if (*input_line_pointer == ',')
627 ++input_line_pointer;
628 align = get_absolute_expression ();
630 else
631 align = 0;
633 else
634 block = align = 0;
636 subseg_set (bss_section, 0);
637 symbolP = symbol_find_or_make (name);
639 if (S_GET_SEGMENT (symbolP) == bss_section)
640 symbolP->sy_frag->fr_symbol = (symbolS *) NULL;
642 symbol_set_frag (symbolP, frag_now);
643 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
644 (offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
645 *p = 0; /* Fill char. */
647 S_SET_SEGMENT (symbolP, bss_section);
649 /* The symbol may already have been created with a preceding
650 ".globl" directive -- be careful not to step on storage class
651 in that case. Otherwise, set it to static. */
652 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
653 S_SET_STORAGE_CLASS (symbolP, C_STAT);
655 if (align)
657 /* s_align eats end of line; restore it */
658 s_align_bytes (4);
659 --input_line_pointer;
662 if (block)
663 bss_section->flags |= SEC_TIC54X_BLOCK;
665 subseg_set (current_seg, current_subseg); /* Restore current seg. */
666 demand_empty_rest_of_line ();
669 static void
670 stag_add_field_symbols (stag, path, base_offset, rootsym, root_stag_name)
671 struct stag *stag;
672 const char *path;
673 bfd_vma base_offset;
674 symbolS *rootsym;
675 const char *root_stag_name;
677 char prefix[strlen (path) + 2];
678 struct stag_field *field = stag->field;
680 /* Construct a symbol for every field contained within this structure
681 including fields within structure fields. */
682 strcpy (prefix, path);
683 if (*path)
684 strcat (prefix, ".");
686 while (field != NULL)
688 int len = strlen (prefix) + strlen (field->name) + 2;
689 char *name = xmalloc (len);
690 strcpy (name, prefix);
691 strcat (name, field->name);
693 if (rootsym == NULL)
695 symbolS *sym;
696 sym = symbol_new (name, absolute_section,
697 (field->stag ? field->offset :
698 (valueT) (base_offset + field->offset)),
699 &zero_address_frag);
700 SF_SET_LOCAL (sym);
701 symbol_table_insert (sym);
703 else
705 char *replacement = xmalloc (strlen (name)
706 + strlen (stag->name) + 2);
707 strcpy (replacement, S_GET_NAME (rootsym));
708 strcat (replacement, "+");
709 strcat (replacement, root_stag_name);
710 strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
711 hash_insert (subsym_hash[0], name, replacement);
714 /* Recurse if the field is a structure.
715 Note the field offset is relative to the outermost struct. */
716 if (field->stag != NULL)
717 stag_add_field_symbols (field->stag, name,
718 field->offset,
719 rootsym, root_stag_name);
720 field = field->next;
724 /* Keep track of stag fields so that when structures are nested we can add the
725 complete dereferencing symbols to the symbol table. */
727 static void
728 stag_add_field (parent, name, offset, stag)
729 struct stag *parent;
730 const char *name;
731 bfd_vma offset;
732 struct stag *stag;
734 struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
736 memset (sfield, 0, sizeof (*sfield));
737 sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
738 sfield->offset = offset;
739 sfield->bitfield_offset = parent->current_bitfield_offset;
740 sfield->stag = stag;
741 if (parent->field == NULL)
742 parent->field = sfield;
743 else
745 struct stag_field *sf = parent->field;
746 while (sf->next != NULL)
747 sf = sf->next;
748 sf->next = sfield;
750 /* Only create a symbol for this field if the parent has no name. */
751 if (!strncmp (".fake", parent->name, 5))
753 symbolS *sym = symbol_new (name, absolute_section,
754 (valueT) offset, &zero_address_frag);
755 SF_SET_LOCAL (sym);
756 symbol_table_insert (sym);
760 /* [STAG] .struct [OFFSET]
761 Start defining structure offsets (symbols in absolute section). */
763 static void
764 tic54x_struct (arg)
765 int arg;
767 int start_offset = 0;
768 int is_union = arg;
770 if (!current_stag)
772 /* Starting a new struct, switch to absolute section. */
773 stag_saved_seg = now_seg;
774 stag_saved_subseg = now_subseg;
775 subseg_set (absolute_section, 0);
777 /* Align the current pointer. */
778 else if (current_stag->current_bitfield_offset != 0)
780 ++abs_section_offset;
781 current_stag->current_bitfield_offset = 0;
784 /* Offset expression is only meaningful for global .structs. */
785 if (!is_union)
787 /* Offset is ignored in inner structs. */
788 SKIP_WHITESPACE ();
789 if (!is_end_of_line[(int) *input_line_pointer])
790 start_offset = get_absolute_expression ();
791 else
792 start_offset = 0;
795 if (current_stag)
797 /* Nesting, link to outer one. */
798 current_stag->inner = (struct stag *) xmalloc (sizeof (struct stag));
799 memset (current_stag->inner, 0, sizeof (struct stag));
800 current_stag->inner->outer = current_stag;
801 current_stag = current_stag->inner;
802 if (start_offset)
803 as_warn (_("Offset on nested structures is ignored"));
804 start_offset = abs_section_offset;
806 else
808 current_stag = (struct stag *) xmalloc (sizeof (struct stag));
809 memset (current_stag, 0, sizeof (struct stag));
810 abs_section_offset = start_offset;
812 current_stag->is_union = is_union;
814 if (line_label == NULL)
816 static int struct_count = 0;
817 char fake[] = ".fake_stagNNNNNNN";
818 sprintf (fake, ".fake_stag%d", struct_count++);
819 current_stag->sym = symbol_new (fake, absolute_section,
820 (valueT) abs_section_offset,
821 &zero_address_frag);
823 else
825 char label[strlen (S_GET_NAME (line_label)) + 1];
826 strcpy (label, S_GET_NAME (line_label));
827 current_stag->sym = symbol_new (label, absolute_section,
828 (valueT) abs_section_offset,
829 &zero_address_frag);
831 current_stag->name = S_GET_NAME (current_stag->sym);
832 SF_SET_LOCAL (current_stag->sym);
833 /* Nested .structs don't go into the symbol table. */
834 if (current_stag->outer == NULL)
835 symbol_table_insert (current_stag->sym);
837 line_label = NULL;
840 /* [LABEL] .endstruct
841 finish defining structure offsets; optional LABEL's value will be the size
842 of the structure. */
844 static void
845 tic54x_endstruct (is_union)
846 int is_union;
848 int size;
849 const char *path =
850 !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
852 if (!current_stag || current_stag->is_union != is_union)
854 as_bad (_(".end%s without preceding .%s"),
855 is_union ? "union" : "struct",
856 is_union ? "union" : "struct");
857 ignore_rest_of_line ();
858 return;
861 /* Align end of structures. */
862 if (current_stag->current_bitfield_offset)
864 ++abs_section_offset;
865 current_stag->current_bitfield_offset = 0;
868 if (current_stag->is_union)
869 size = current_stag->size;
870 else
871 size = abs_section_offset - S_GET_VALUE (current_stag->sym);
872 if (line_label != NULL)
874 S_SET_VALUE (line_label, size);
875 symbol_table_insert (line_label);
876 line_label = NULL;
879 /* Union size has already been calculated. */
880 if (!current_stag->is_union)
881 current_stag->size = size;
882 /* Nested .structs don't get put in the stag table. */
883 if (current_stag->outer == NULL)
885 hash_insert (stag_hash, current_stag->name, current_stag);
886 stag_add_field_symbols (current_stag, path,
887 S_GET_VALUE (current_stag->sym),
888 NULL, NULL);
890 current_stag = current_stag->outer;
892 /* If this is a nested .struct/.union, add it as a field to the enclosing
893 one. otherwise, restore the section we were in. */
894 if (current_stag != NULL)
896 stag_add_field (current_stag, current_stag->inner->name,
897 S_GET_VALUE (current_stag->inner->sym),
898 current_stag->inner);
900 else
901 subseg_set (stag_saved_seg, stag_saved_subseg);
904 /* [LABEL] .tag STAG
905 Reference a structure within a structure, as a sized field with an optional
906 label.
907 If used outside of a .struct/.endstruct, overlays the given structure
908 format on the existing allocated space. */
910 static void
911 tic54x_tag (ignore)
912 int ignore ATTRIBUTE_UNUSED;
914 char *name = input_line_pointer;
915 int c = get_symbol_end ();
916 struct stag *stag = (struct stag *) hash_find (stag_hash, name);
918 if (!stag)
920 if (*name)
921 as_bad (_("Unrecognized struct/union tag '%s'"), name);
922 else
923 as_bad (_(".tag requires a structure tag"));
924 ignore_rest_of_line ();
925 return;
927 if (line_label == NULL)
929 as_bad (_("Label required for .tag"));
930 ignore_rest_of_line ();
931 return;
933 else
935 char label[strlen (S_GET_NAME (line_label)) + 1];
937 strcpy (label, S_GET_NAME (line_label));
938 if (current_stag != NULL)
939 stag_add_field (current_stag, label,
940 abs_section_offset - S_GET_VALUE (current_stag->sym),
941 stag);
942 else
944 symbolS *sym = symbol_find (label);
946 if (!sym)
948 as_bad (_(".tag target '%s' undefined"), label);
949 ignore_rest_of_line ();
950 return;
952 stag_add_field_symbols (stag, S_GET_NAME (sym),
953 S_GET_VALUE (stag->sym), sym, stag->name);
957 /* Bump by the struct size, but only if we're within a .struct section. */
958 if (current_stag != NULL && !current_stag->is_union)
959 abs_section_offset += stag->size;
961 *input_line_pointer = c;
962 demand_empty_rest_of_line ();
963 line_label = NULL;
966 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
967 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
968 and .word. */
970 static void
971 tic54x_struct_field (type)
972 int type;
974 int size;
975 int count = 1;
976 int new_bitfield_offset = 0;
977 int field_align = current_stag->current_bitfield_offset != 0;
978 int longword_align = 0;
980 SKIP_WHITESPACE ();
981 if (!is_end_of_line[(int) *input_line_pointer])
982 count = get_absolute_expression ();
984 switch (type)
986 case 'b':
987 case 'B':
988 case 'c':
989 case 'C':
990 case 'h':
991 case 'H':
992 case 'i':
993 case 'I':
994 case 's':
995 case 'S':
996 case 'w':
997 case 'W':
998 case '*': /* String. */
999 size = 1;
1000 break;
1001 case 'f':
1002 case 'l':
1003 case 'L':
1004 longword_align = 1;
1005 size = 2;
1006 break;
1007 case '.': /* Bitfield. */
1008 size = 0;
1009 if (count < 1 || count > 32)
1011 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
1012 ignore_rest_of_line ();
1013 return;
1015 if (current_stag->current_bitfield_offset + count > 16)
1017 /* Set the appropriate size and new field offset. */
1018 if (count == 32)
1020 size = 2;
1021 count = 1;
1023 else if (count > 16)
1025 size = 1;
1026 count = 1;
1027 new_bitfield_offset = count - 16;
1029 else
1030 new_bitfield_offset = count;
1032 else
1034 field_align = 0;
1035 new_bitfield_offset = current_stag->current_bitfield_offset + count;
1037 break;
1038 default:
1039 as_bad (_("Unrecognized field type '%c'"), type);
1040 ignore_rest_of_line ();
1041 return;
1044 if (field_align)
1046 /* Align to the actual starting position of the field. */
1047 current_stag->current_bitfield_offset = 0;
1048 ++abs_section_offset;
1050 /* Align to longword boundary. */
1051 if (longword_align && (abs_section_offset & 0x1))
1052 ++abs_section_offset;
1054 if (line_label == NULL)
1056 static int fieldno = 0;
1057 char fake[] = ".fake_fieldNNNNN";
1059 sprintf (fake, ".fake_field%d", fieldno++);
1060 stag_add_field (current_stag, fake,
1061 abs_section_offset - S_GET_VALUE (current_stag->sym),
1062 NULL);
1064 else
1066 char label[strlen (S_GET_NAME (line_label) + 1)];
1068 strcpy (label, S_GET_NAME (line_label));
1069 stag_add_field (current_stag, label,
1070 abs_section_offset - S_GET_VALUE (current_stag->sym),
1071 NULL);
1074 if (current_stag->is_union)
1076 /* Note we treat the element as if it were an array of COUNT. */
1077 if (current_stag->size < (unsigned) size * count)
1078 current_stag->size = size * count;
1080 else
1082 abs_section_offset += (unsigned) size * count;
1083 current_stag->current_bitfield_offset = new_bitfield_offset;
1085 line_label = NULL;
1088 /* Handle .byte, .word. .int, .long and all variants. */
1090 static void
1091 tic54x_cons (type)
1092 int type;
1094 unsigned int c;
1095 int octets;
1097 /* If we're within a .struct construct, don't actually allocate space. */
1098 if (current_stag != NULL)
1100 tic54x_struct_field (type);
1101 return;
1104 #ifdef md_flush_pending_output
1105 md_flush_pending_output ();
1106 #endif
1108 generate_lineno_debug ();
1110 /* Align long words to long word boundaries (4 octets). */
1111 if (type == 'l' || type == 'L')
1113 frag_align (2, 0, 2);
1114 /* If there's a label, assign it to the first allocated word. */
1115 if (line_label != NULL)
1117 symbol_set_frag (line_label, frag_now);
1118 S_SET_VALUE (line_label, frag_now_fix ());
1122 switch (type)
1124 case 'l':
1125 case 'L':
1126 case 'x':
1127 octets = 4;
1128 break;
1129 case 'b':
1130 case 'B':
1131 case 'c':
1132 case 'C':
1133 octets = 1;
1134 break;
1135 default:
1136 octets = 2;
1137 break;
1142 if (*input_line_pointer == '"')
1144 input_line_pointer++;
1145 while (is_a_char (c = next_char_of_string ()))
1146 tic54x_emit_char (c);
1147 know (input_line_pointer[-1] == '\"');
1149 else
1151 expressionS exp;
1153 input_line_pointer = parse_expression (input_line_pointer, &exp);
1154 if (exp.X_op == O_constant)
1156 offsetT value = exp.X_add_number;
1157 /* Truncate overflows. */
1158 switch (octets)
1160 case 1:
1161 if ((value > 0 && value > 0xFF)
1162 || (value < 0 && value < - 0x100))
1163 as_warn ("Overflow in expression, truncated to 8 bits");
1164 break;
1165 case 2:
1166 if ((value > 0 && value > 0xFFFF)
1167 || (value < 0 && value < - 0x10000))
1168 as_warn ("Overflow in expression, truncated to 16 bits");
1169 break;
1172 if (exp.X_op != O_constant && octets < 2)
1174 /* Disallow .byte with a non constant expression that will
1175 require relocation. */
1176 as_bad (_("Relocatable values require at least WORD storage"));
1177 ignore_rest_of_line ();
1178 return;
1181 if (exp.X_op != O_constant
1182 && amode == c_mode
1183 && octets == 4)
1185 /* FIXME -- at one point TI tools used to output REL16
1186 relocations, but I don't think the latest tools do at all
1187 The current tools output extended relocations regardless of
1188 the addressing mode (I actually think that ".c_mode" is
1189 totally ignored in the latest tools). */
1190 amode = far_mode;
1191 emitting_long = 1;
1192 emit_expr (&exp, 4);
1193 emitting_long = 0;
1194 amode = c_mode;
1196 else
1198 emitting_long = octets == 4;
1199 emit_expr (&exp, (octets == 1) ? 2 : octets);
1200 emitting_long = 0;
1204 while (*input_line_pointer++ == ',');
1206 input_line_pointer--; /* Put terminator back into stream. */
1207 demand_empty_rest_of_line ();
1210 /* .global <symbol>[,...,<symbolN>]
1211 .def <symbol>[,...,<symbolN>]
1212 .ref <symbol>[,...,<symbolN>]
1214 These all identify global symbols.
1216 .def means the symbol is defined in the current module and can be accessed
1217 by other files. The symbol should be placed in the symbol table.
1219 .ref means the symbol is used in the current module but defined in another
1220 module. The linker is to resolve this symbol's definition at link time.
1222 .global should act as a .ref or .def, as needed.
1224 global, def and ref all have symbol storage classes of C_EXT.
1226 I can't identify any difference in how the "other" c54x assembler treats
1227 these, so we ignore the type here. */
1229 void
1230 tic54x_global (type)
1231 int type;
1233 char *name;
1234 int c;
1235 symbolS *symbolP;
1237 if (type == 'r')
1238 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1240 ILLEGAL_WITHIN_STRUCT ();
1244 name = input_line_pointer;
1245 c = get_symbol_end ();
1246 symbolP = symbol_find_or_make (name);
1248 *input_line_pointer = c;
1249 S_SET_STORAGE_CLASS (symbolP, C_EXT);
1250 if (c == ',')
1252 input_line_pointer++;
1253 if (is_end_of_line[(int) *input_line_pointer])
1254 c = *input_line_pointer;
1257 while (c == ',');
1259 demand_empty_rest_of_line ();
1262 /* Remove the symbol from the local label hash lookup. */
1264 static void
1265 tic54x_remove_local_label (key, value)
1266 const char *key;
1267 PTR value ATTRIBUTE_UNUSED;
1269 PTR *elem = hash_delete (local_label_hash[macro_level], key);
1270 free (elem);
1273 /* Reset all local labels. */
1275 static void
1276 tic54x_clear_local_labels (ignored)
1277 int ignored ATTRIBUTE_UNUSED;
1279 hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
1282 /* .text
1283 .data
1284 .sect "section name"
1286 Initialized section
1287 make sure local labels get cleared when changing sections
1289 ARG is 't' for text, 'd' for data, or '*' for a named section
1291 For compatibility, '*' sections are SEC_CODE if instructions are
1292 encountered, or SEC_DATA if not.
1295 static void
1296 tic54x_sect (arg)
1297 int arg;
1299 ILLEGAL_WITHIN_STRUCT ();
1301 /* Local labels are cleared when changing sections. */
1302 tic54x_clear_local_labels (0);
1304 if (arg == 't')
1305 s_text (0);
1306 else if (arg == 'd')
1307 s_data (0);
1308 else
1310 char *name = NULL;
1311 int len;
1313 /* If there are quotes, remove them. */
1314 if (*input_line_pointer == '"')
1316 name = demand_copy_C_string (&len);
1317 demand_empty_rest_of_line ();
1318 name = strcpy (xmalloc (len + 10), name);
1320 else
1322 int c;
1323 name = input_line_pointer;
1324 c = get_symbol_end ();
1325 len = strlen(name);
1326 name = strcpy (xmalloc (len + 10), name);
1327 *input_line_pointer = c;
1328 demand_empty_rest_of_line ();
1330 /* Make sure all named initialized sections flagged properly. If we
1331 encounter instructions, we'll flag it with SEC_CODE as well. */
1332 strcat (name, ",\"w\"\n");
1333 input_scrub_insert_line (name);
1334 obj_coff_section (0);
1336 /* If there was a line label, make sure that it gets assigned the proper
1337 section. This is for compatibility, even though the actual behavior
1338 is not explicitly defined. For consistency, we make .sect behave
1339 like .usect, since that is probably what people expect. */
1340 if (line_label != NULL)
1342 S_SET_SEGMENT (line_label, now_seg);
1343 symbol_set_frag (line_label, frag_now);
1344 S_SET_VALUE (line_label, frag_now_fix ());
1345 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1346 S_SET_STORAGE_CLASS (line_label, C_LABEL);
1351 /* [symbol] .space space_in_bits
1352 [symbol] .bes space_in_bits
1353 BES puts the symbol at the *last* word allocated
1355 cribbed from s_space. */
1357 static void
1358 tic54x_space (arg)
1359 int arg;
1361 expressionS exp;
1362 char *p = 0;
1363 int octets = 0;
1364 long words;
1365 int bits_per_byte = (OCTETS_PER_BYTE * 8);
1366 int bit_offset = 0;
1367 symbolS *label = line_label;
1368 int bes = arg;
1370 ILLEGAL_WITHIN_STRUCT ();
1372 #ifdef md_flush_pending_output
1373 md_flush_pending_output ();
1374 #endif
1376 /* Read the bit count. */
1377 expression (&exp);
1379 /* Some expressions are unresolvable until later in the assembly pass;
1380 postpone until relaxation/fixup. we also have to postpone if a previous
1381 partial allocation has not been completed yet. */
1382 if (exp.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
1384 struct bit_info *bi = xmalloc (sizeof (struct bit_info));
1385 char *p;
1387 bi->seg = now_seg;
1388 bi->type = bes;
1389 bi->sym = label;
1390 p = frag_var (rs_machine_dependent,
1391 65536 * 2, 1, (relax_substateT) 0,
1392 make_expr_symbol (&exp), (offsetT) 0,
1393 (char *) bi);
1394 if (p)
1395 *p = 0;
1397 return;
1400 /* Reduce the required size by any bit offsets currently left over
1401 from a previous .space/.bes/.field directive. */
1402 bit_offset = frag_now->tc_frag_data;
1403 if (bit_offset != 0 && bit_offset < 16)
1405 int spare_bits = bits_per_byte - bit_offset;
1407 if (spare_bits >= exp.X_add_number)
1409 /* Don't have to do anything; sufficient bits have already been
1410 allocated; just point the label to the right place. */
1411 if (label != NULL)
1413 symbol_set_frag (label, frag_now);
1414 S_SET_VALUE (label, frag_now_fix () - 1);
1415 label = NULL;
1417 frag_now->tc_frag_data += exp.X_add_number;
1418 goto getout;
1420 exp.X_add_number -= spare_bits;
1421 /* Set the label to point to the first word allocated, which in this
1422 case is the previous word, which was only partially filled. */
1423 if (!bes && label != NULL)
1425 symbol_set_frag (label, frag_now);
1426 S_SET_VALUE (label, frag_now_fix () - 1);
1427 label = NULL;
1430 /* Convert bits to bytes/words and octets, rounding up. */
1431 words = ((exp.X_add_number + bits_per_byte - 1) / bits_per_byte);
1432 /* How many do we have left over? */
1433 bit_offset = exp.X_add_number % bits_per_byte;
1434 octets = words * OCTETS_PER_BYTE;
1435 if (octets < 0)
1437 as_warn (_(".space/.bes repeat count is negative, ignored"));
1438 goto getout;
1440 else if (octets == 0)
1442 as_warn (_(".space/.bes repeat count is zero, ignored"));
1443 goto getout;
1446 /* If we are in the absolute section, just bump the offset. */
1447 if (now_seg == absolute_section)
1449 abs_section_offset += words;
1450 if (bes && label != NULL)
1451 S_SET_VALUE (label, abs_section_offset - 1);
1452 frag_now->tc_frag_data = bit_offset;
1453 goto getout;
1456 if (!need_pass_2)
1457 p = frag_var (rs_fill, 1, 1,
1458 (relax_substateT) 0, (symbolS *) 0,
1459 (offsetT) octets, (char *) 0);
1461 /* Make note of how many bits of this word we've allocated so far. */
1462 frag_now->tc_frag_data = bit_offset;
1464 /* .bes puts label at *last* word allocated. */
1465 if (bes && label != NULL)
1467 symbol_set_frag (label, frag_now);
1468 S_SET_VALUE (label, frag_now_fix () - 1);
1471 if (p)
1472 *p = 0;
1474 getout:
1476 demand_empty_rest_of_line ();
1479 /* [symbol] .usect "section-name", size-in-words
1480 [, [blocking-flag] [, alignment-flag]]
1482 Uninitialized section.
1483 Non-zero blocking means that if the section would cross a page (128-word)
1484 boundary, it will be page-aligned.
1485 Non-zero alignment aligns on a longword boundary.
1487 Has no effect on the current section. */
1489 static void
1490 tic54x_usect (x)
1491 int x ATTRIBUTE_UNUSED;
1493 char c;
1494 char *name;
1495 char *section_name;
1496 char *p;
1497 segT seg;
1498 int size, blocking_flag, alignment_flag;
1499 segT current_seg;
1500 subsegT current_subseg;
1501 flagword flags;
1503 ILLEGAL_WITHIN_STRUCT ();
1505 current_seg = now_seg; /* Save current seg. */
1506 current_subseg = now_subseg; /* Save current subseg. */
1508 if (*input_line_pointer == '"')
1509 input_line_pointer++;
1510 section_name = input_line_pointer;
1511 c = get_symbol_end (); /* Get terminator. */
1512 input_line_pointer++; /* Skip null symbol terminator. */
1513 name = xmalloc (input_line_pointer - section_name + 1);
1514 strcpy (name, section_name);
1516 if (*input_line_pointer == ',')
1517 ++input_line_pointer;
1518 else if (c != ',')
1520 as_bad (_("Missing size argument"));
1521 ignore_rest_of_line ();
1522 return;
1525 size = get_absolute_expression ();
1527 /* Read a possibly present third argument (blocking flag). */
1528 if (*input_line_pointer == ',')
1530 ++input_line_pointer;
1531 if (*input_line_pointer != ',')
1532 blocking_flag = get_absolute_expression ();
1533 else
1534 blocking_flag = 0;
1536 /* Read a possibly present fourth argument (alignment flag). */
1537 if (*input_line_pointer == ',')
1539 ++input_line_pointer;
1540 alignment_flag = get_absolute_expression ();
1542 else
1543 alignment_flag = 0;
1545 else
1546 blocking_flag = alignment_flag = 0;
1548 seg = subseg_new (name, 0);
1549 flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
1551 if (alignment_flag)
1553 /* s_align eats end of line; restore it. */
1554 s_align_bytes (4);
1555 --input_line_pointer;
1558 if (line_label != NULL)
1560 S_SET_SEGMENT (line_label, seg);
1561 symbol_set_frag (line_label, frag_now);
1562 S_SET_VALUE (line_label, frag_now_fix ());
1563 /* Set scl to label, since that's what TI does. */
1564 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1565 S_SET_STORAGE_CLASS (line_label, C_LABEL);
1568 seg_info (seg)->bss = 1; /* Uninitialized data. */
1570 p = frag_var (rs_fill, 1, 1,
1571 (relax_substateT) 0, (symbolS *) line_label,
1572 size * OCTETS_PER_BYTE, (char *) 0);
1573 *p = 0;
1575 if (blocking_flag)
1576 flags |= SEC_TIC54X_BLOCK;
1578 if (!bfd_set_section_flags (stdoutput, seg, flags))
1579 as_warn ("Error setting flags for \"%s\": %s", name,
1580 bfd_errmsg (bfd_get_error ()));
1582 subseg_set (current_seg, current_subseg); /* Restore current seg. */
1583 demand_empty_rest_of_line ();
1586 static enum cpu_version
1587 lookup_version (ver)
1588 const char *ver;
1590 enum cpu_version version = VNONE;
1592 if (ver[0] == '5' && ver[1] == '4')
1594 if (strlen (ver) == 3
1595 && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
1596 || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
1597 version = ver[2] - '0';
1598 else if (strlen (ver) == 5
1599 && TOUPPER (ver[3]) == 'L'
1600 && TOUPPER (ver[4]) == 'P'
1601 && (ver[2] == '5' || ver[2] == '6'))
1602 version = ver[2] - '0' + 10;
1605 return version;
1608 static void
1609 set_cpu (version)
1610 enum cpu_version version;
1612 cpu = version;
1613 if (version == V545LP || version == V546LP)
1615 symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
1616 (valueT) 1, &zero_address_frag);
1617 SF_SET_LOCAL (symbolP);
1618 symbol_table_insert (symbolP);
1622 /* .version cpu-version
1623 cpu-version may be one of the following:
1628 545LP
1629 546LP
1633 This is for compatibility only. It currently has no affect on assembly. */
1634 static int cpu_needs_set = 1;
1636 static void
1637 tic54x_version (x)
1638 int x ATTRIBUTE_UNUSED;
1640 enum cpu_version version = VNONE;
1641 enum cpu_version old_version = cpu;
1642 int c;
1643 char *ver;
1645 ILLEGAL_WITHIN_STRUCT ();
1647 SKIP_WHITESPACE ();
1648 ver = input_line_pointer;
1649 while (!is_end_of_line[(int) *input_line_pointer])
1650 ++input_line_pointer;
1651 c = *input_line_pointer;
1652 *input_line_pointer = 0;
1654 version = lookup_version (ver);
1656 if (cpu != VNONE && cpu != version)
1657 as_warn (_("CPU version has already been set"));
1659 if (version == VNONE)
1661 as_bad (_("Unrecognized version '%s'"), ver);
1662 ignore_rest_of_line ();
1663 return;
1665 else if (assembly_begun && version != old_version)
1667 as_bad (_("Changing of CPU version on the fly not supported"));
1668 ignore_rest_of_line ();
1669 return;
1672 set_cpu (version);
1674 *input_line_pointer = c;
1675 demand_empty_rest_of_line ();
1678 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1680 static void
1681 tic54x_float_cons (type)
1682 int type;
1684 if (current_stag != 0)
1685 tic54x_struct_field ('f');
1687 #ifdef md_flush_pending_output
1688 md_flush_pending_output ();
1689 #endif
1691 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1692 if (type != 'x')
1694 frag_align (2, 0, 2);
1695 /* If there's a label, assign it to the first allocated word. */
1696 if (line_label != NULL)
1698 symbol_set_frag (line_label, frag_now);
1699 S_SET_VALUE (line_label, frag_now_fix ());
1703 float_cons ('f');
1706 /* The argument is capitalized if it should be zero-terminated
1707 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1708 Code copied from stringer, and slightly modified so that strings are packed
1709 and encoded into the correct octets. */
1711 static void
1712 tic54x_stringer (type)
1713 int type;
1715 unsigned int c;
1716 char *start;
1717 int append_zero = type == 'S' || type == 'P';
1718 int packed = type == 'p' || type == 'P';
1719 int last_char = -1; /* Packed strings need two bytes at a time to encode. */
1721 if (current_stag != NULL)
1723 tic54x_struct_field ('*');
1724 return;
1727 #ifdef md_flush_pending_output
1728 md_flush_pending_output ();
1729 #endif
1731 c = ','; /* Do loop. */
1732 while (c == ',')
1734 SKIP_WHITESPACE ();
1735 switch (*input_line_pointer)
1737 default:
1739 unsigned short value = get_absolute_expression ();
1740 FRAG_APPEND_1_CHAR ( value & 0xFF);
1741 FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
1742 break;
1744 case '\"':
1745 ++input_line_pointer; /* -> 1st char of string. */
1746 start = input_line_pointer;
1747 while (is_a_char (c = next_char_of_string ()))
1749 if (!packed)
1751 FRAG_APPEND_1_CHAR (c);
1752 FRAG_APPEND_1_CHAR (0);
1754 else
1756 /* Packed strings are filled MS octet first. */
1757 if (last_char == -1)
1758 last_char = c;
1759 else
1761 FRAG_APPEND_1_CHAR (c);
1762 FRAG_APPEND_1_CHAR (last_char);
1763 last_char = -1;
1767 if (append_zero)
1769 if (packed && last_char != -1)
1771 FRAG_APPEND_1_CHAR (0);
1772 FRAG_APPEND_1_CHAR (last_char);
1773 last_char = -1;
1775 else
1777 FRAG_APPEND_1_CHAR (0);
1778 FRAG_APPEND_1_CHAR (0);
1781 know (input_line_pointer[-1] == '\"');
1782 break;
1784 SKIP_WHITESPACE ();
1785 c = *input_line_pointer;
1786 if (!is_end_of_line[c])
1787 ++input_line_pointer;
1790 /* Finish up any leftover packed string. */
1791 if (packed && last_char != -1)
1793 FRAG_APPEND_1_CHAR (0);
1794 FRAG_APPEND_1_CHAR (last_char);
1796 demand_empty_rest_of_line ();
1799 static void
1800 tic54x_p2align (arg)
1801 int arg ATTRIBUTE_UNUSED;
1803 as_bad (_("p2align not supported on this target"));
1806 static void
1807 tic54x_align_words (arg)
1808 int arg;
1810 /* Only ".align" with no argument is allowed within .struct/.union. */
1811 int count = arg;
1813 if (!is_end_of_line[(int) *input_line_pointer])
1815 if (arg == 2)
1816 as_warn (_("Argument to .even ignored"));
1817 else
1818 count = get_absolute_expression ();
1821 if (current_stag != NULL && arg == 128)
1823 if (current_stag->current_bitfield_offset != 0)
1825 current_stag->current_bitfield_offset = 0;
1826 ++abs_section_offset;
1828 demand_empty_rest_of_line ();
1829 return;
1832 ILLEGAL_WITHIN_STRUCT ();
1834 s_align_bytes (count << 1);
1837 /* Initialize multiple-bit fields withing a single word of memory. */
1839 static void
1840 tic54x_field (ignore)
1841 int ignore ATTRIBUTE_UNUSED;
1843 expressionS exp;
1844 int size = 16;
1845 char *p;
1846 valueT value;
1847 symbolS *label = line_label;
1849 if (current_stag != NULL)
1851 tic54x_struct_field ('.');
1852 return;
1855 input_line_pointer = parse_expression (input_line_pointer, &exp);
1857 if (*input_line_pointer == ',')
1859 ++input_line_pointer;
1860 size = get_absolute_expression ();
1861 if (size < 1 || size > 32)
1863 as_bad (_("Invalid field size, must be from 1 to 32"));
1864 ignore_rest_of_line ();
1865 return;
1869 /* Truncate values to the field width. */
1870 if (exp.X_op != O_constant)
1872 /* If the expression value is relocatable, the field size *must*
1873 be 16. */
1874 if (size != 16)
1876 as_bad (_("field size must be 16 when value is relocatable"));
1877 ignore_rest_of_line ();
1878 return;
1881 frag_now->tc_frag_data = 0;
1882 emit_expr (&exp, 2);
1884 else
1886 unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
1888 value = exp.X_add_number;
1889 exp.X_add_number &= fmask;
1890 if (value != (valueT) exp.X_add_number)
1891 as_warn (_("field value truncated"));
1892 value = exp.X_add_number;
1893 /* Bits are stored MS first. */
1894 while (size >= 16)
1896 frag_now->tc_frag_data = 0;
1897 p = frag_more (2);
1898 md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
1899 size -= 16;
1901 if (size > 0)
1903 int bit_offset = frag_bit_offset (frag_now, now_seg);
1905 fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
1906 if (bit_offset == -1)
1908 struct bit_info *bi = xmalloc (sizeof (struct bit_info));
1909 /* We don't know the previous offset at this time, so store the
1910 info we need and figure it out later. */
1911 expressionS size_exp;
1913 size_exp.X_op = O_constant;
1914 size_exp.X_add_number = size;
1915 bi->seg = now_seg;
1916 bi->type = TYPE_FIELD;
1917 bi->value = value;
1918 p = frag_var (rs_machine_dependent,
1919 4, 1, (relax_substateT) 0,
1920 make_expr_symbol (&size_exp), (offsetT) 0,
1921 (char *) bi);
1922 goto getout;
1924 else if (bit_offset == 0 || bit_offset + size > 16)
1926 /* Align a new field. */
1927 p = frag_more (2);
1928 frag_now->tc_frag_data = 0;
1929 alloc_frag = frag_now;
1931 else
1933 /* Put the new value entirely within the existing one. */
1934 p = alloc_frag == frag_now ?
1935 frag_now->fr_literal + frag_now_fix_octets () - 2 :
1936 alloc_frag->fr_literal;
1937 if (label != NULL)
1939 symbol_set_frag (label, alloc_frag);
1940 if (alloc_frag == frag_now)
1941 S_SET_VALUE (label, frag_now_fix () - 1);
1942 label = NULL;
1945 value <<= 16 - alloc_frag->tc_frag_data - size;
1947 /* OR in existing value. */
1948 if (alloc_frag->tc_frag_data)
1949 value |= ((unsigned short) p[1] << 8) | p[0];
1950 md_number_to_chars (p, value, 2);
1951 alloc_frag->tc_frag_data += size;
1952 if (alloc_frag->tc_frag_data == 16)
1953 alloc_frag->tc_frag_data = 0;
1956 getout:
1957 demand_empty_rest_of_line ();
1960 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1961 available yet. seg_info ()->bss is the next best thing. */
1963 static int
1964 tic54x_initialized_section (seg)
1965 segT seg;
1967 return !seg_info (seg)->bss;
1970 /* .clink ["section name"]
1972 Marks the section as conditionally linked (link only if contents are
1973 referenced elsewhere.
1974 Without a name, refers to the current initialized section.
1975 Name is required for uninitialized sections. */
1977 static void
1978 tic54x_clink (ignored)
1979 int ignored ATTRIBUTE_UNUSED;
1981 segT seg = now_seg;
1983 ILLEGAL_WITHIN_STRUCT ();
1985 if (*input_line_pointer == '\"')
1987 char *section_name = ++input_line_pointer;
1988 char *name;
1990 while (is_a_char (next_char_of_string ()))
1992 know (input_line_pointer[-1] == '\"');
1993 input_line_pointer[-1] = 0;
1994 name = xmalloc (input_line_pointer - section_name + 1);
1995 strcpy (name, section_name);
1997 seg = bfd_get_section_by_name (stdoutput, name);
1998 if (seg == NULL)
2000 as_bad (_("Unrecognized section '%s'"), section_name);
2001 ignore_rest_of_line ();
2002 return;
2005 else
2007 if (!tic54x_initialized_section (seg))
2009 as_bad (_("Current section is unitialized, "
2010 "section name required for .clink"));
2011 ignore_rest_of_line ();
2012 return;
2016 seg->flags |= SEC_TIC54X_CLINK;
2018 demand_empty_rest_of_line ();
2021 /* Change the default include directory to be the current source file's
2022 directory, instead of the current working directory. If DOT is non-zero,
2023 set to "." instead. */
2025 static void
2026 tic54x_set_default_include (dot)
2027 int dot;
2029 char *dir = ".";
2030 char *tmp = NULL;
2032 if (!dot)
2034 char *curfile;
2035 unsigned lineno;
2037 as_where (&curfile, &lineno);
2038 dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
2039 tmp = strrchr (dir, '/');
2041 if (tmp != NULL)
2043 int len;
2045 *tmp = '\0';
2046 len = strlen (dir);
2047 if (include_dir_count == 0)
2049 include_dirs = (char **) xmalloc (sizeof (*include_dirs));
2050 include_dir_count = 1;
2052 include_dirs[0] = dir;
2053 if (len > include_dir_maxlen)
2054 include_dir_maxlen = len;
2056 else if (include_dirs != NULL)
2057 include_dirs[0] = ".";
2060 /* .include "filename" | filename
2061 .copy "filename" | filename
2063 FIXME 'include' file should be omitted from any output listing,
2064 'copy' should be included in any output listing
2065 FIXME -- prevent any included files from changing listing (compat only)
2066 FIXME -- need to include source file directory in search path; what's a
2067 good way to do this?
2069 Entering/exiting included/copied file clears all local labels. */
2071 static void
2072 tic54x_include (ignored)
2073 int ignored ATTRIBUTE_UNUSED;
2075 char newblock[] = " .newblock\n";
2076 char *filename;
2077 char *input;
2078 int len, c = -1;
2080 ILLEGAL_WITHIN_STRUCT ();
2082 SKIP_WHITESPACE ();
2084 if (*input_line_pointer == '"')
2086 filename = demand_copy_C_string (&len);
2087 demand_empty_rest_of_line ();
2089 else
2091 filename = input_line_pointer;
2092 while (!is_end_of_line[(int) *input_line_pointer])
2093 ++input_line_pointer;
2094 c = *input_line_pointer;
2095 *input_line_pointer = '\0';
2096 filename = strcpy (xmalloc (strlen (filename) + 1), filename);
2097 *input_line_pointer = c;
2098 demand_empty_rest_of_line ();
2100 /* Insert a partial line with the filename (for the sake of s_include)
2101 and a .newblock.
2102 The included file will be inserted before the newblock, so that the
2103 newblock is executed after the included file is processed. */
2104 input = xmalloc (sizeof (newblock) + strlen (filename) + 4);
2105 sprintf (input, "\"%s\"\n%s", filename, newblock);
2106 input_scrub_insert_line (input);
2108 tic54x_clear_local_labels (0);
2110 tic54x_set_default_include (0);
2112 s_include (0);
2115 static void
2116 tic54x_message (type)
2117 int type;
2119 char *msg;
2120 char c;
2121 int len;
2123 ILLEGAL_WITHIN_STRUCT ();
2125 if (*input_line_pointer == '"')
2126 msg = demand_copy_C_string (&len);
2127 else
2129 msg = input_line_pointer;
2130 while (!is_end_of_line[(int) *input_line_pointer])
2131 ++input_line_pointer;
2132 c = *input_line_pointer;
2133 *input_line_pointer = 0;
2134 msg = strcpy (xmalloc (strlen (msg) + 1), msg);
2135 *input_line_pointer = c;
2138 switch (type)
2140 case 'm':
2141 as_tsktsk ("%s", msg);
2142 break;
2143 case 'w':
2144 as_warn ("%s", msg);
2145 break;
2146 case 'e':
2147 as_bad ("%s", msg);
2148 break;
2151 demand_empty_rest_of_line ();
2154 /* .label <symbol>
2155 Define a special symbol that refers to the loadtime address rather than the
2156 runtime address within the current section.
2158 This symbol gets a special storage class so that when it is resolved, it is
2159 resolved relative to the load address (lma) of the section rather than the
2160 run address (vma). */
2162 static void
2163 tic54x_label (ignored)
2164 int ignored ATTRIBUTE_UNUSED;
2166 char *name = input_line_pointer;
2167 symbolS *symbolP;
2168 int c;
2170 ILLEGAL_WITHIN_STRUCT ();
2172 c = get_symbol_end ();
2173 symbolP = colon (name);
2174 S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
2176 *input_line_pointer = c;
2177 demand_empty_rest_of_line ();
2180 /* .mmregs
2181 Install all memory-mapped register names into the symbol table as
2182 absolute local symbols. */
2184 static void
2185 tic54x_mmregs (ignored)
2186 int ignored ATTRIBUTE_UNUSED;
2188 symbol *sym;
2190 ILLEGAL_WITHIN_STRUCT ();
2192 for (sym = (symbol *) mmregs; sym->name; sym++)
2194 symbolS *symbolP = symbol_new (sym->name, absolute_section,
2195 (valueT) sym->value, &zero_address_frag);
2196 SF_SET_LOCAL (symbolP);
2197 symbol_table_insert (symbolP);
2201 /* .loop [count]
2202 Count defaults to 1024. */
2204 static void
2205 tic54x_loop (count)
2206 int count;
2208 ILLEGAL_WITHIN_STRUCT ();
2210 SKIP_WHITESPACE ();
2211 if (!is_end_of_line[(int) *input_line_pointer])
2212 count = get_absolute_expression ();
2214 do_repeat (count, "LOOP", "ENDLOOP");
2217 /* Normally, endloop gets eaten by the preceding loop. */
2219 static void
2220 tic54x_endloop (ignore)
2221 int ignore ATTRIBUTE_UNUSED;
2223 as_bad (_("ENDLOOP without corresponding LOOP"));
2224 ignore_rest_of_line ();
2227 /* .break [condition]. */
2229 static void
2230 tic54x_break (ignore)
2231 int ignore ATTRIBUTE_UNUSED;
2233 int cond = 1;
2235 ILLEGAL_WITHIN_STRUCT ();
2237 SKIP_WHITESPACE ();
2238 if (!is_end_of_line[(int) *input_line_pointer])
2239 cond = get_absolute_expression ();
2241 if (cond)
2242 end_repeat (substitution_line ? 1 : 0);
2245 static void
2246 set_address_mode (mode)
2247 int mode;
2249 amode = mode;
2250 if (mode == far_mode)
2252 symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
2253 (valueT) 1, &zero_address_frag);
2254 SF_SET_LOCAL (symbolP);
2255 symbol_table_insert (symbolP);
2259 static int address_mode_needs_set = 1;
2261 static void
2262 tic54x_address_mode (mode)
2263 int mode;
2265 if (assembly_begun && amode != (unsigned) mode)
2267 as_bad (_("Mixing of normal and extended addressing not supported"));
2268 ignore_rest_of_line ();
2269 return;
2271 if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549)
2273 as_bad (_("Extended addressing not supported on the specified CPU"));
2274 ignore_rest_of_line ();
2275 return;
2278 set_address_mode (mode);
2279 demand_empty_rest_of_line ();
2282 /* .sblock "section"|section [,...,"section"|section]
2283 Designate initialized sections for blocking. */
2285 static void
2286 tic54x_sblock (ignore)
2287 int ignore ATTRIBUTE_UNUSED;
2289 int c = ',';
2291 ILLEGAL_WITHIN_STRUCT ();
2293 while (c == ',')
2295 segT seg;
2296 char *name;
2298 if (*input_line_pointer == '"')
2300 int len;
2302 name = demand_copy_C_string (&len);
2304 else
2306 char *section_name = input_line_pointer;
2308 c = get_symbol_end ();
2309 name = xmalloc (strlen (section_name) + 1);
2310 strcpy (name, section_name);
2311 *input_line_pointer = c;
2314 seg = bfd_get_section_by_name (stdoutput, name);
2315 if (seg == NULL)
2317 as_bad (_("Unrecognized section '%s'"), name);
2318 ignore_rest_of_line ();
2319 return;
2321 else if (!tic54x_initialized_section (seg))
2323 as_bad (_(".sblock may be used for initialized sections only"));
2324 ignore_rest_of_line ();
2325 return;
2327 seg->flags |= SEC_TIC54X_BLOCK;
2329 c = *input_line_pointer;
2330 if (!is_end_of_line[(int) c])
2331 ++input_line_pointer;
2334 demand_empty_rest_of_line ();
2337 /* symbol .set value
2338 symbol .equ value
2340 value must be defined externals; no forward-referencing allowed
2341 symbols assigned with .set/.equ may not be redefined. */
2343 static void
2344 tic54x_set (ignore)
2345 int ignore ATTRIBUTE_UNUSED;
2347 symbolS *symbolP;
2348 char *name;
2350 ILLEGAL_WITHIN_STRUCT ();
2352 if (!line_label)
2354 as_bad (_("Symbol missing for .set/.equ"));
2355 ignore_rest_of_line ();
2356 return;
2358 name = xstrdup (S_GET_NAME (line_label));
2359 line_label = NULL;
2360 if ((symbolP = symbol_find (name)) == NULL
2361 && (symbolP = md_undefined_symbol (name)) == NULL)
2363 symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
2364 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2366 free (name);
2367 S_SET_DATA_TYPE (symbolP, T_INT);
2368 S_SET_SEGMENT (symbolP, absolute_section);
2369 symbol_table_insert (symbolP);
2370 pseudo_set (symbolP);
2371 demand_empty_rest_of_line ();
2374 /* .fclist
2375 .fcnolist
2376 List false conditional blocks. */
2378 static void
2379 tic54x_fclist (show)
2380 int show;
2382 if (show)
2383 listing &= ~LISTING_NOCOND;
2384 else
2385 listing |= LISTING_NOCOND;
2386 demand_empty_rest_of_line ();
2389 static void
2390 tic54x_sslist (show)
2391 int show;
2393 ILLEGAL_WITHIN_STRUCT ();
2395 listing_sslist = show;
2398 /* .var SYM[,...,SYMN]
2399 Define a substitution string to be local to a macro. */
2401 static void
2402 tic54x_var (ignore)
2403 int ignore ATTRIBUTE_UNUSED;
2405 static char empty[] = "";
2406 char *name;
2407 int c;
2409 ILLEGAL_WITHIN_STRUCT ();
2411 if (macro_level == 0)
2413 as_bad (_(".var may only be used within a macro definition"));
2414 ignore_rest_of_line ();
2415 return;
2419 if (!ISALPHA (*input_line_pointer))
2421 as_bad (_("Substitution symbols must begin with a letter"));
2422 ignore_rest_of_line ();
2423 return;
2425 name = input_line_pointer;
2426 c = get_symbol_end ();
2427 /* .var symbols start out with a null string. */
2428 name = strcpy (xmalloc (strlen (name) + 1), name);
2429 hash_insert (subsym_hash[macro_level], name, empty);
2430 *input_line_pointer = c;
2431 if (c == ',')
2433 ++input_line_pointer;
2434 if (is_end_of_line[(int) *input_line_pointer])
2435 c = *input_line_pointer;
2438 while (c == ',');
2440 demand_empty_rest_of_line ();
2443 /* .mlib <macro library filename>
2445 Macro libraries are archived (standard AR-format) text macro definitions
2446 Expand the file and include it.
2448 FIXME need to try the source file directory as well. */
2450 static void
2451 tic54x_mlib (ignore)
2452 int ignore ATTRIBUTE_UNUSED;
2454 char *filename;
2455 char *path;
2456 int len, i;
2457 bfd *abfd, *mbfd;
2459 ILLEGAL_WITHIN_STRUCT ();
2461 /* Parse the filename. */
2462 if (*input_line_pointer == '"')
2464 if ((filename = demand_copy_C_string (&len)) == NULL)
2465 return;
2467 else
2469 SKIP_WHITESPACE ();
2470 len = 0;
2471 while (!is_end_of_line[(int) *input_line_pointer]
2472 && !ISSPACE (*input_line_pointer))
2474 obstack_1grow (&notes, *input_line_pointer);
2475 ++input_line_pointer;
2476 ++len;
2478 obstack_1grow (&notes, '\0');
2479 filename = obstack_finish (&notes);
2481 demand_empty_rest_of_line ();
2483 tic54x_set_default_include (0);
2484 path = xmalloc ((unsigned long) len + include_dir_maxlen + 5);
2486 for (i = 0; i < include_dir_count; i++)
2488 FILE *try;
2490 strcpy (path, include_dirs[i]);
2491 strcat (path, "/");
2492 strcat (path, filename);
2493 if ((try = fopen (path, "r")) != NULL)
2495 fclose (try);
2496 break;
2500 if (i >= include_dir_count)
2502 free (path);
2503 path = filename;
2506 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2507 happens all over the place, and since the assembler doesn't usually keep
2508 running for a very long time, it really doesn't matter. */
2509 register_dependency (path);
2511 /* Expand all archive entries to temporary files and include them. */
2512 abfd = bfd_openr (path, NULL);
2513 if (!abfd)
2515 as_bad (_("can't open macro library file '%s' for reading: %s"),
2516 path, bfd_errmsg (bfd_get_error ()));
2517 ignore_rest_of_line ();
2518 return;
2520 if (!bfd_check_format (abfd, bfd_archive))
2522 as_bad (_("File '%s' not in macro archive format"), path);
2523 ignore_rest_of_line ();
2524 return;
2527 /* Open each BFD as binary (it should be straight ASCII text). */
2528 for (mbfd = bfd_openr_next_archived_file (abfd, NULL);
2529 mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd))
2531 /* Get a size at least as big as the archive member. */
2532 bfd_size_type size = bfd_get_size (mbfd);
2533 char *buf = xmalloc (size);
2534 char *fname = tmpnam (NULL);
2535 FILE *ftmp;
2537 /* We're not sure how big it is, but it will be smaller than "size". */
2538 bfd_bread (buf, size, mbfd);
2540 /* Write to a temporary file, then use s_include to include it
2541 a bit of a hack. */
2542 ftmp = fopen (fname, "w+b");
2543 fwrite ((void *) buf, size, 1, ftmp);
2544 if (buf[size - 1] != '\n')
2545 fwrite ("\n", 1, 1, ftmp);
2546 fclose (ftmp);
2547 free (buf);
2548 input_scrub_insert_file (fname);
2549 unlink (fname);
2553 const pseudo_typeS md_pseudo_table[] =
2555 { "algebraic", s_ignore , 0 },
2556 { "align" , tic54x_align_words , 128 },
2557 { "ascii" , tic54x_stringer , 'p' },
2558 { "asciz" , tic54x_stringer , 'P' },
2559 { "even" , tic54x_align_words , 2 },
2560 { "asg" , tic54x_asg , 0 },
2561 { "eval" , tic54x_eval , 0 },
2562 { "bss" , tic54x_bss , 0 },
2563 { "byte" , tic54x_cons , 'b' },
2564 { "ubyte" , tic54x_cons , 'B' },
2565 { "char" , tic54x_cons , 'c' },
2566 { "uchar" , tic54x_cons , 'C' },
2567 { "clink" , tic54x_clink , 0 },
2568 { "c_mode" , tic54x_address_mode , c_mode },
2569 { "copy" , tic54x_include , 'c' },
2570 { "include" , tic54x_include , 'i' },
2571 { "data" , tic54x_sect , 'd' },
2572 { "double" , tic54x_float_cons , 'd' },
2573 { "ldouble" , tic54x_float_cons , 'l' },
2574 { "drlist" , s_ignore , 0 },
2575 { "drnolist" , s_ignore , 0 },
2576 { "emsg" , tic54x_message , 'e' },
2577 { "mmsg" , tic54x_message , 'm' },
2578 { "wmsg" , tic54x_message , 'w' },
2579 { "far_mode" , tic54x_address_mode , far_mode },
2580 { "fclist" , tic54x_fclist , 1 },
2581 { "fcnolist" , tic54x_fclist , 0 },
2582 { "field" , tic54x_field , -1 },
2583 { "float" , tic54x_float_cons , 'f' },
2584 { "xfloat" , tic54x_float_cons , 'x' },
2585 { "global" , tic54x_global , 'g' },
2586 { "def" , tic54x_global , 'd' },
2587 { "ref" , tic54x_global , 'r' },
2588 { "half" , tic54x_cons , 'h' },
2589 { "uhalf" , tic54x_cons , 'H' },
2590 { "short" , tic54x_cons , 's' },
2591 { "ushort" , tic54x_cons , 'S' },
2592 { "if" , s_if , (int) O_ne },
2593 { "elseif" , s_elseif , (int) O_ne },
2594 { "else" , s_else , 0 },
2595 { "endif" , s_endif , 0 },
2596 { "int" , tic54x_cons , 'i' },
2597 { "uint" , tic54x_cons , 'I' },
2598 { "word" , tic54x_cons , 'w' },
2599 { "uword" , tic54x_cons , 'W' },
2600 { "label" , tic54x_label , 0 }, /* Loadtime
2601 address. */
2602 { "length" , s_ignore , 0 },
2603 { "width" , s_ignore , 0 },
2604 { "long" , tic54x_cons , 'l' },
2605 { "ulong" , tic54x_cons , 'L' },
2606 { "xlong" , tic54x_cons , 'x' },
2607 { "loop" , tic54x_loop , 1024 },
2608 { "break" , tic54x_break , 0 },
2609 { "endloop" , tic54x_endloop , 0 },
2610 { "mlib" , tic54x_mlib , 0 },
2611 { "mlist" , s_ignore , 0 },
2612 { "mnolist" , s_ignore , 0 },
2613 { "mmregs" , tic54x_mmregs , 0 },
2614 { "newblock" , tic54x_clear_local_labels, 0 },
2615 { "option" , s_ignore , 0 },
2616 { "p2align" , tic54x_p2align , 0 },
2617 { "sblock" , tic54x_sblock , 0 },
2618 { "sect" , tic54x_sect , '*' },
2619 { "set" , tic54x_set , 0 },
2620 { "equ" , tic54x_set , 0 },
2621 { "space" , tic54x_space , 0 },
2622 { "bes" , tic54x_space , 1 },
2623 { "sslist" , tic54x_sslist , 1 },
2624 { "ssnolist" , tic54x_sslist , 0 },
2625 { "string" , tic54x_stringer , 's' },
2626 { "pstring" , tic54x_stringer , 'p' },
2627 { "struct" , tic54x_struct , 0 },
2628 { "tag" , tic54x_tag , 0 },
2629 { "endstruct", tic54x_endstruct , 0 },
2630 { "tab" , s_ignore , 0 },
2631 { "text" , tic54x_sect , 't' },
2632 { "union" , tic54x_struct , 1 },
2633 { "endunion" , tic54x_endstruct , 1 },
2634 { "usect" , tic54x_usect , 0 },
2635 { "var" , tic54x_var , 0 },
2636 { "version" , tic54x_version , 0 },
2637 {0 , 0 , 0 }
2641 md_parse_option (c, arg)
2642 int c;
2643 char *arg;
2645 switch (c)
2647 default:
2648 return 0;
2649 case OPTION_COFF_VERSION:
2651 int version = atoi (arg);
2653 if (version != 0 && version != 1 && version != 2)
2654 as_fatal (_("Bad COFF version '%s'"), arg);
2655 /* FIXME -- not yet implemented. */
2656 break;
2658 case OPTION_CPU_VERSION:
2660 cpu = lookup_version (arg);
2661 cpu_needs_set = 1;
2662 if (cpu == VNONE)
2663 as_fatal (_("Bad CPU version '%s'"), arg);
2664 break;
2666 case OPTION_ADDRESS_MODE:
2667 amode = far_mode;
2668 address_mode_needs_set = 1;
2669 break;
2670 case OPTION_STDERR_TO_FILE:
2672 char *filename = arg;
2673 FILE *fp = fopen (filename, "w+");
2675 if (fp == NULL)
2676 as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2677 fclose (fp);
2678 if ((fp = freopen (filename, "w+", stderr)) == NULL)
2679 as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2680 break;
2684 return 1;
2687 /* Create a "local" substitution string hash table for a new macro level
2688 Some docs imply that macros have to use .newblock in order to be able
2689 to re-use a local label. We effectively do an automatic .newblock by
2690 deleting the local label hash between macro invocations. */
2692 void
2693 tic54x_macro_start ()
2695 ++macro_level;
2696 subsym_hash[macro_level] = hash_new ();
2697 local_label_hash[macro_level] = hash_new ();
2700 void
2701 tic54x_macro_info (macro)
2702 const macro_entry *macro;
2704 const formal_entry *entry;
2706 /* Put the formal args into the substitution symbol table. */
2707 for (entry = macro->formals; entry; entry = entry->next)
2709 char *name = strncpy (xmalloc (entry->name.len + 1),
2710 entry->name.ptr, entry->name.len);
2711 char *value = strncpy (xmalloc (entry->actual.len + 1),
2712 entry->actual.ptr, entry->actual.len);
2714 name[entry->name.len] = '\0';
2715 value[entry->actual.len] = '\0';
2716 hash_insert (subsym_hash[macro_level], name, value);
2720 /* Get rid of this macro's .var's, arguments, and local labels. */
2722 void
2723 tic54x_macro_end ()
2725 hash_die (subsym_hash[macro_level]);
2726 subsym_hash[macro_level] = NULL;
2727 hash_die (local_label_hash[macro_level]);
2728 local_label_hash[macro_level] = NULL;
2729 --macro_level;
2732 static int
2733 subsym_symlen (a, ignore)
2734 char *a;
2735 char *ignore ATTRIBUTE_UNUSED;
2737 return strlen (a);
2740 /* Compare symbol A to string B. */
2742 static int
2743 subsym_symcmp (a, b)
2744 char *a;
2745 char *b;
2747 return strcmp (a, b);
2750 /* Return the index of the first occurrence of B in A, or zero if none
2751 assumes b is an integer char value as a string. Index is one-based. */
2753 static int
2754 subsym_firstch (a, b)
2755 char *a;
2756 char *b;
2758 int val = atoi (b);
2759 char *tmp = strchr (a, val);
2761 return tmp ? tmp - a + 1 : 0;
2764 /* Similar to firstch, but returns index of last occurrence of B in A. */
2766 static int
2767 subsym_lastch (a, b)
2768 char *a;
2769 char *b;
2771 int val = atoi (b);
2772 char *tmp = strrchr (a, val);
2774 return tmp ? tmp - a + 1 : 0;
2777 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2778 symbol table). */
2780 static int
2781 subsym_isdefed (a, ignore)
2782 char *a;
2783 char *ignore ATTRIBUTE_UNUSED;
2785 symbolS *symbolP = symbol_find (a);
2787 return symbolP != NULL;
2790 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2791 A, or zero if B is a null string. Both arguments *must* be substitution
2792 symbols, unsubstituted. */
2794 static int
2795 subsym_ismember (sym, list)
2796 char *sym;
2797 char *list;
2799 char *elem, *ptr, *listv;
2801 if (!list)
2802 return 0;
2804 listv = subsym_lookup (list, macro_level);
2805 if (!listv)
2807 as_bad (_("Undefined substitution symbol '%s'"), list);
2808 ignore_rest_of_line ();
2809 return 0;
2812 ptr = elem = xmalloc (strlen (listv) + 1);
2813 strcpy (elem, listv);
2814 while (*ptr && *ptr != ',')
2815 ++ptr;
2816 *ptr++ = 0;
2818 subsym_create_or_replace (sym, elem);
2820 /* Reassign the list. */
2821 subsym_create_or_replace (list, ptr);
2823 /* Assume this value, docs aren't clear. */
2824 return *list != 0;
2827 /* Return zero if not a constant; otherwise:
2828 1 if binary
2829 2 if octal
2830 3 if hexadecimal
2831 4 if character
2832 5 if decimal. */
2834 static int
2835 subsym_iscons (a, ignore)
2836 char *a;
2837 char *ignore ATTRIBUTE_UNUSED;
2839 expressionS exp;
2841 parse_expression (a, &exp);
2843 if (exp.X_op == O_constant)
2845 int len = strlen (a);
2847 switch (TOUPPER (a[len - 1]))
2849 case 'B':
2850 return 1;
2851 case 'Q':
2852 return 2;
2853 case 'H':
2854 return 3;
2855 case '\'':
2856 return 4;
2857 default:
2858 break;
2860 /* No suffix; either octal, hex, or decimal. */
2861 if (*a == '0' && len > 1)
2863 if (TOUPPER (a[1]) == 'X')
2864 return 3;
2865 return 2;
2867 return 5;
2870 return 0;
2873 /* Return 1 if A is a valid symbol name. Expects string input. */
2875 static int
2876 subsym_isname (a, ignore)
2877 char *a;
2878 char *ignore ATTRIBUTE_UNUSED;
2880 if (!is_name_beginner (*a))
2881 return 0;
2882 while (*a)
2884 if (!is_part_of_name (*a))
2885 return 0;
2886 ++a;
2888 return 1;
2891 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2892 been seen; if so, recognize any memory-mapped register.
2893 Note this does not recognize "A" or "B" accumulators. */
2895 static int
2896 subsym_isreg (a, ignore)
2897 char *a;
2898 char *ignore ATTRIBUTE_UNUSED;
2900 if (hash_find (reg_hash, a))
2901 return 1;
2902 if (hash_find (mmreg_hash, a))
2903 return 1;
2904 return 0;
2907 /* Return the structure size, given the stag. */
2909 static int
2910 subsym_structsz (name, ignore)
2911 char *name;
2912 char *ignore ATTRIBUTE_UNUSED;
2914 struct stag *stag = (struct stag *) hash_find (stag_hash, name);
2916 if (stag)
2917 return stag->size;
2919 return 0;
2922 /* If anybody actually uses this, they can fix it :)
2923 FIXME I'm not sure what the "reference point" of a structure is. It might
2924 be either the initial offset given .struct, or it may be the offset of the
2925 structure within another structure, or it might be something else
2926 altogether. since the TI assembler doesn't seem to ever do anything but
2927 return zero, we punt and return zero. */
2929 static int
2930 subsym_structacc (stag_name, ignore)
2931 char *stag_name ATTRIBUTE_UNUSED;
2932 char *ignore ATTRIBUTE_UNUSED;
2934 return 0;
2937 static float
2938 math_ceil (arg1, ignore)
2939 float arg1;
2940 float ignore ATTRIBUTE_UNUSED;
2942 return (float) ceil (arg1);
2945 static float
2946 math_cvi (arg1, ignore)
2947 float arg1;
2948 float ignore ATTRIBUTE_UNUSED;
2950 return (int) arg1;
2953 static float
2954 math_floor (arg1, ignore)
2955 float arg1;
2956 float ignore ATTRIBUTE_UNUSED;
2958 return (float) floor (arg1);
2961 static float
2962 math_fmod (arg1, arg2)
2963 float arg1;
2964 float arg2;
2966 return (int) arg1 % (int) arg2;
2969 static float
2970 math_int (arg1, ignore)
2971 float arg1;
2972 float ignore ATTRIBUTE_UNUSED;
2974 return ((float) ((int) arg1)) == arg1;
2977 static float
2978 math_round (arg1, ignore)
2979 float arg1;
2980 float ignore ATTRIBUTE_UNUSED;
2982 return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
2985 static float
2986 math_sgn (arg1, ignore)
2987 float arg1;
2988 float ignore ATTRIBUTE_UNUSED;
2990 return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
2993 static float
2994 math_trunc (arg1, ignore)
2995 float arg1;
2996 float ignore ATTRIBUTE_UNUSED;
2998 return (int) arg1;
3001 static float
3002 math_acos (arg1, ignore)
3003 float arg1;
3004 float ignore ATTRIBUTE_UNUSED;
3006 return (float) acos (arg1);
3009 static float
3010 math_asin (arg1, ignore)
3011 float arg1;
3012 float ignore ATTRIBUTE_UNUSED;
3014 return (float) asin (arg1);
3017 static float
3018 math_atan (arg1, ignore)
3019 float arg1;
3020 float ignore ATTRIBUTE_UNUSED;
3022 return (float) atan (arg1);
3025 static float
3026 math_atan2 (arg1, arg2)
3027 float arg1;
3028 float arg2;
3030 return (float) atan2 (arg1, arg2);
3033 static float
3034 math_cosh (arg1, ignore)
3035 float arg1;
3036 float ignore ATTRIBUTE_UNUSED;
3038 return (float) cosh (arg1);
3041 static float
3042 math_cos (arg1, ignore)
3043 float arg1;
3044 float ignore ATTRIBUTE_UNUSED;
3046 return (float) cos (arg1);
3049 static float
3050 math_cvf (arg1, ignore)
3051 float arg1;
3052 float ignore ATTRIBUTE_UNUSED;
3054 return (float) arg1;
3057 static float
3058 math_exp (arg1, ignore)
3059 float arg1;
3060 float ignore ATTRIBUTE_UNUSED;
3062 return (float) exp (arg1);
3065 static float
3066 math_fabs (arg1, ignore)
3067 float arg1;
3068 float ignore ATTRIBUTE_UNUSED;
3070 return (float) fabs (arg1);
3073 /* expr1 * 2^expr2. */
3075 static float
3076 math_ldexp (arg1, arg2)
3077 float arg1;
3078 float arg2;
3080 return arg1 * (float) pow (2.0, arg2);
3083 static float
3084 math_log10 (arg1, ignore)
3085 float arg1;
3086 float ignore ATTRIBUTE_UNUSED;
3088 return (float) log10 (arg1);
3091 static float
3092 math_log (arg1, ignore)
3093 float arg1;
3094 float ignore ATTRIBUTE_UNUSED;
3096 return (float) log (arg1);
3099 static float
3100 math_max (arg1, arg2)
3101 float arg1;
3102 float arg2;
3104 return (arg1 > arg2) ? arg1 : arg2;
3107 static float
3108 math_min (arg1, arg2)
3109 float arg1;
3110 float arg2;
3112 return (arg1 < arg2) ? arg1 : arg2;
3115 static float
3116 math_pow (arg1, arg2)
3117 float arg1;
3118 float arg2;
3120 return (float) pow (arg1, arg2);
3123 static float
3124 math_sin (arg1, ignore)
3125 float arg1;
3126 float ignore ATTRIBUTE_UNUSED;
3128 return (float) sin (arg1);
3131 static float
3132 math_sinh (arg1, ignore)
3133 float arg1;
3134 float ignore ATTRIBUTE_UNUSED;
3136 return (float) sinh (arg1);
3139 static float
3140 math_sqrt (arg1, ignore)
3141 float arg1;
3142 float ignore ATTRIBUTE_UNUSED;
3144 return (float) sqrt (arg1);
3147 static float
3148 math_tan (arg1, ignore)
3149 float arg1;
3150 float ignore ATTRIBUTE_UNUSED;
3152 return (float) tan (arg1);
3155 static float
3156 math_tanh (arg1, ignore)
3157 float arg1;
3158 float ignore ATTRIBUTE_UNUSED;
3160 return (float) tanh (arg1);
3163 /* Built-in substitution symbol functions and math functions. */
3164 typedef struct
3166 char *name;
3167 int (*proc) PARAMS ((char *, char *));
3168 int nargs;
3169 } subsym_proc_entry;
3171 static const subsym_proc_entry subsym_procs[] =
3173 /* Assembler built-in string substitution functions. */
3174 { "$symlen", subsym_symlen, 1, },
3175 { "$symcmp", subsym_symcmp, 2, },
3176 { "$firstch", subsym_firstch, 2, },
3177 { "$lastch", subsym_lastch, 2, },
3178 { "$isdefed", subsym_isdefed, 1, },
3179 { "$ismember", subsym_ismember, 2, },
3180 { "$iscons", subsym_iscons, 1, },
3181 { "$isname", subsym_isname, 1, },
3182 { "$isreg", subsym_isreg, 1, },
3183 { "$structsz", subsym_structsz, 1, },
3184 { "$structacc", subsym_structacc, 1, },
3185 { NULL, NULL, 0 },
3188 typedef struct
3190 char *name;
3191 float (*proc) PARAMS ((float, float));
3192 int nargs;
3193 int int_return;
3194 } math_proc_entry;
3196 static const math_proc_entry math_procs[] =
3198 /* Integer-returning built-in math functions. */
3199 { "$cvi", math_cvi, 1, 1 },
3200 { "$int", math_int, 1, 1 },
3201 { "$sgn", math_sgn, 1, 1 },
3203 /* Float-returning built-in math functions. */
3204 { "$acos", math_acos, 1, 0 },
3205 { "$asin", math_asin, 1, 0 },
3206 { "$atan", math_atan, 1, 0 },
3207 { "$atan2", math_atan2, 2, 0 },
3208 { "$ceil", math_ceil, 1, 0 },
3209 { "$cosh", math_cosh, 1, 0 },
3210 { "$cos", math_cos, 1, 0 },
3211 { "$cvf", math_cvf, 1, 0 },
3212 { "$exp", math_exp, 1, 0 },
3213 { "$fabs", math_fabs, 1, 0 },
3214 { "$floor", math_floor, 1, 0 },
3215 { "$fmod", math_fmod, 2, 0 },
3216 { "$ldexp", math_ldexp, 2, 0 },
3217 { "$log10", math_log10, 1, 0 },
3218 { "$log", math_log, 1, 0 },
3219 { "$max", math_max, 2, 0 },
3220 { "$min", math_min, 2, 0 },
3221 { "$pow", math_pow, 2, 0 },
3222 { "$round", math_round, 1, 0 },
3223 { "$sin", math_sin, 1, 0 },
3224 { "$sinh", math_sinh, 1, 0 },
3225 { "$sqrt", math_sqrt, 1, 0 },
3226 { "$tan", math_tan, 1, 0 },
3227 { "$tanh", math_tanh, 1, 0 },
3228 { "$trunc", math_trunc, 1, 0 },
3229 { NULL, NULL, 0, 0 },
3232 void
3233 md_begin ()
3235 template *tm;
3236 symbol *sym;
3237 const subsym_proc_entry *subsym_proc;
3238 const math_proc_entry *math_proc;
3239 const char *hash_err;
3240 char **symname;
3241 char *TIC54X_DIR = getenv ("TIC54X_DIR");
3242 char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
3244 local_label_id = 0;
3246 /* Look for A_DIR and add it to the include list. */
3247 if (A_DIR != NULL)
3249 char *tmp = xstrdup (A_DIR);
3253 char *next = strchr (tmp, ';');
3255 if (next)
3256 *next++ = '\0';
3257 add_include_dir (tmp);
3258 tmp = next;
3260 while (tmp != NULL);
3263 op_hash = hash_new ();
3264 for (tm = (template *) tic54x_optab; tm->name; tm++)
3266 if (hash_find (op_hash, tm->name))
3267 continue;
3268 hash_err = hash_insert (op_hash, tm->name, (char *) tm);
3269 if (hash_err)
3270 as_fatal ("Internal Error: Can't hash %s: %s",
3271 tm->name, hash_err);
3273 parop_hash = hash_new ();
3274 for (tm = (template *) tic54x_paroptab; tm->name; tm++)
3276 if (hash_find (parop_hash, tm->name))
3277 continue;
3278 hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
3279 if (hash_err)
3280 as_fatal ("Internal Error: Can't hash %s: %s",
3281 tm->name, hash_err);
3283 reg_hash = hash_new ();
3284 for (sym = (symbol *) regs; sym->name; sym++)
3286 /* Add basic registers to the symbol table. */
3287 symbolS *symbolP = symbol_new (sym->name, absolute_section,
3288 (valueT) sym->value, &zero_address_frag);
3289 SF_SET_LOCAL (symbolP);
3290 symbol_table_insert (symbolP);
3291 hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3293 for (sym = (symbol *) mmregs; sym->name; sym++)
3294 hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3295 mmreg_hash = hash_new ();
3296 for (sym = (symbol *) mmregs; sym->name; sym++)
3297 hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
3299 cc_hash = hash_new ();
3300 for (sym = (symbol *) condition_codes; sym->name; sym++)
3301 hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
3303 cc2_hash = hash_new ();
3304 for (sym = (symbol *) cc2_codes; sym->name; sym++)
3305 hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
3307 cc3_hash = hash_new ();
3308 for (sym = (symbol *) cc3_codes; sym->name; sym++)
3309 hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
3311 sbit_hash = hash_new ();
3312 for (sym = (symbol *) status_bits; sym->name; sym++)
3313 hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
3315 misc_symbol_hash = hash_new ();
3316 for (symname = (char **) misc_symbols; *symname; symname++)
3317 hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
3319 /* Only the base substitution table and local label table are initialized;
3320 the others (for local macro substitution) get instantiated as needed. */
3321 local_label_hash[0] = hash_new ();
3322 subsym_hash[0] = hash_new ();
3323 for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
3324 hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
3325 (char *) subsym_proc);
3327 math_hash = hash_new ();
3328 for (math_proc = math_procs; math_proc->name; math_proc++)
3330 /* Insert into the main subsym hash for recognition; insert into
3331 the math hash to actually store information. */
3332 hash_err = hash_insert (subsym_hash[0], math_proc->name,
3333 (char *) math_proc);
3334 hash_err = hash_insert (math_hash, math_proc->name,
3335 (char *) math_proc);
3337 subsym_recurse_hash = hash_new ();
3338 stag_hash = hash_new ();
3341 static int
3342 is_accumulator (operand)
3343 struct opstruct *operand;
3345 return strcasecmp (operand->buf, "a") == 0
3346 || strcasecmp (operand->buf, "b") == 0;
3349 /* Return the number of operands found, or -1 on error, copying the
3350 operands into the given array and the accompanying expressions into
3351 the next array. */
3353 static int
3354 get_operands (operands, line)
3355 struct opstruct operands[];
3356 char *line;
3358 char *lptr = line;
3359 int numexp = 0;
3360 int expecting_operand = 0;
3361 int i;
3363 while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
3365 int paren_not_balanced = 0;
3366 char *op_start, *op_end;
3368 while (*lptr && ISSPACE (*lptr))
3369 ++lptr;
3370 op_start = lptr;
3371 while (paren_not_balanced || *lptr != ',')
3373 if (*lptr == '\0')
3375 if (paren_not_balanced)
3377 as_bad ("Unbalanced parenthesis in operand %d", numexp);
3378 return -1;
3380 else
3381 break;
3383 if (*lptr == '(')
3384 ++paren_not_balanced;
3385 else if (*lptr == ')')
3386 --paren_not_balanced;
3387 ++lptr;
3389 op_end = lptr;
3390 if (op_end != op_start)
3392 int len = op_end - op_start;
3394 strncpy (operands[numexp].buf, op_start, len);
3395 operands[numexp].buf[len] = 0;
3396 /* Trim trailing spaces; while the preprocessor gets rid of most,
3397 there are weird usage patterns that can introduce them
3398 (i.e. using strings for macro args). */
3399 while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
3400 operands[numexp].buf[--len] = 0;
3401 lptr = op_end;
3402 ++numexp;
3404 else
3406 if (expecting_operand || *lptr == ',')
3408 as_bad ("Expecting operand after ','");
3409 return -1;
3412 if (*lptr == ',')
3414 if (*++lptr == '\0')
3416 as_bad ("Expecting operand after ','");
3417 return -1;
3419 expecting_operand = 1;
3423 while (*lptr && ISSPACE (*lptr++))
3425 if (!is_end_of_line[(int) *lptr])
3427 as_bad ("Extra junk on line");
3428 return -1;
3431 /* OK, now parse them into expressions. */
3432 for (i = 0; i < numexp; i++)
3434 memset (&operands[i].exp, 0, sizeof (operands[i].exp));
3435 if (operands[i].buf[0] == '#')
3437 /* Immediate. */
3438 parse_expression (operands[i].buf + 1, &operands[i].exp);
3440 else if (operands[i].buf[0] == '@')
3442 /* Direct notation. */
3443 parse_expression (operands[i].buf + 1, &operands[i].exp);
3445 else if (operands[i].buf[0] == '*')
3447 /* Indirect. */
3448 char *paren = strchr (operands[i].buf, '(');
3450 /* Allow immediate syntax in the inner expression. */
3451 if (paren && paren[1] == '#')
3452 *++paren = '(';
3454 /* Pull out the lk expression or SP offset, if present. */
3455 if (paren != NULL)
3457 int len = strlen (paren);
3458 char *end = paren + len;
3459 int c;
3461 while (end[-1] != ')')
3462 if (--end <= paren)
3464 as_bad (_("Badly formed address expression"));
3465 return -1;
3467 c = *end;
3468 *end = '\0';
3469 parse_expression (paren, &operands[i].exp);
3470 *end = c;
3472 else
3473 operands[i].exp.X_op = O_absent;
3475 else
3476 parse_expression (operands[i].buf, &operands[i].exp);
3479 return numexp;
3482 /* Predicates for different operand types. */
3484 static int
3485 is_immediate (operand)
3486 struct opstruct *operand;
3488 return *operand->buf == '#';
3491 /* This is distinguished from immediate because some numbers must be constants
3492 and must *not* have the '#' prefix. */
3494 static int
3495 is_absolute (operand)
3496 struct opstruct *operand;
3498 return operand->exp.X_op == O_constant && !is_immediate (operand);
3501 /* Is this an indirect operand? */
3503 static int
3504 is_indirect (operand)
3505 struct opstruct *operand;
3507 return operand->buf[0] == '*';
3510 /* Is this a valid dual-memory operand? */
3512 static int
3513 is_dual (operand)
3514 struct opstruct *operand;
3516 if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
3518 char *tmp = operand->buf + 3;
3519 int arf;
3520 int valid_mod;
3522 arf = *tmp++ - '0';
3523 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3524 valid_mod = *tmp == '\0' ||
3525 strcasecmp (tmp, "-") == 0 ||
3526 strcasecmp (tmp, "+") == 0 ||
3527 strcasecmp (tmp, "+0%") == 0;
3528 return arf >= 2 && arf <= 5 && valid_mod;
3530 return 0;
3533 static int
3534 is_mmreg (operand)
3535 struct opstruct *operand;
3537 return (is_absolute (operand)
3538 || is_immediate (operand)
3539 || hash_find (mmreg_hash, operand->buf) != 0);
3542 static int
3543 is_type (operand, type)
3544 struct opstruct *operand;
3545 enum optype type;
3547 switch (type)
3549 case OP_None:
3550 return operand->buf[0] == 0;
3551 case OP_Xmem:
3552 case OP_Ymem:
3553 return is_dual (operand);
3554 case OP_Sind:
3555 return is_indirect (operand);
3556 case OP_xpmad_ms7:
3557 /* This one *must* be immediate. */
3558 return is_immediate (operand);
3559 case OP_xpmad:
3560 case OP_pmad:
3561 case OP_PA:
3562 case OP_dmad:
3563 case OP_Lmem:
3564 case OP_MMR:
3565 return 1;
3566 case OP_Smem:
3567 /* Address may be a numeric, indirect, or an expression. */
3568 return !is_immediate (operand);
3569 case OP_MMRY:
3570 case OP_MMRX:
3571 return is_mmreg (operand);
3572 case OP_SRC:
3573 case OP_SRC1:
3574 case OP_RND:
3575 case OP_DST:
3576 return is_accumulator (operand);
3577 case OP_B:
3578 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
3579 case OP_A:
3580 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
3581 case OP_ARX:
3582 return strncasecmp ("ar", operand->buf, 2) == 0
3583 && ISDIGIT (operand->buf[2]);
3584 case OP_SBIT:
3585 return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
3586 case OP_CC:
3587 return hash_find (cc_hash, operand->buf) != 0;
3588 case OP_CC2:
3589 return hash_find (cc2_hash, operand->buf) != 0;
3590 case OP_CC3:
3591 return hash_find (cc3_hash, operand->buf) != 0
3592 || is_immediate (operand) || is_absolute (operand);
3593 case OP_16:
3594 return (is_immediate (operand) || is_absolute (operand))
3595 && operand->exp.X_add_number == 16;
3596 case OP_N:
3597 /* Allow st0 or st1 instead of a numeric. */
3598 return is_absolute (operand) || is_immediate (operand) ||
3599 strcasecmp ("st0", operand->buf) == 0 ||
3600 strcasecmp ("st1", operand->buf) == 0;
3601 case OP_12:
3602 case OP_123:
3603 return is_absolute (operand) || is_immediate (operand);
3604 case OP_SHFT:
3605 return (is_immediate (operand) || is_absolute (operand))
3606 && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
3607 case OP_SHIFT:
3608 /* Let this one catch out-of-range values. */
3609 return (is_immediate (operand) || is_absolute (operand))
3610 && operand->exp.X_add_number != 16;
3611 case OP_BITC:
3612 case OP_031:
3613 case OP_k8:
3614 return is_absolute (operand) || is_immediate (operand);
3615 case OP_k8u:
3616 return is_immediate (operand)
3617 && operand->exp.X_op == O_constant
3618 && operand->exp.X_add_number >= 0
3619 && operand->exp.X_add_number < 256;
3620 case OP_lk:
3621 case OP_lku:
3622 /* Allow anything; assumes opcodes are ordered with Smem operands
3623 versions first. */
3624 return 1;
3625 case OP_k5:
3626 case OP_k3:
3627 case OP_k9:
3628 /* Just make sure it's an integer; check range later. */
3629 return is_immediate (operand);
3630 case OP_T:
3631 return strcasecmp ("t", operand->buf) == 0 ||
3632 strcasecmp ("treg", operand->buf) == 0;
3633 case OP_TS:
3634 return strcasecmp ("ts", operand->buf) == 0;
3635 case OP_ASM:
3636 return strcasecmp ("asm", operand->buf) == 0;
3637 case OP_TRN:
3638 return strcasecmp ("trn", operand->buf) == 0;
3639 case OP_DP:
3640 return strcasecmp ("dp", operand->buf) == 0;
3641 case OP_ARP:
3642 return strcasecmp ("arp", operand->buf) == 0;
3643 default:
3644 return 0;
3648 static int
3649 operands_match (insn, operands, opcount, refoptype, minops, maxops)
3650 tic54x_insn *insn;
3651 struct opstruct *operands;
3652 int opcount;
3653 const enum optype *refoptype;
3654 int minops;
3655 int maxops;
3657 int op = 0, refop = 0;
3659 if (opcount == 0 && minops == 0)
3660 return 1;
3662 while (op <= maxops && refop <= maxops)
3664 while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
3666 /* Skip an optional template operand if it doesn't agree
3667 with the current operand. */
3668 if (refoptype[refop] & OPT)
3670 ++refop;
3671 --maxops;
3672 if (refop > maxops)
3673 return 0;
3675 else
3676 return 0;
3679 /* Save the actual operand type for later use. */
3680 operands[op].type = OPTYPE (refoptype[refop]);
3681 ++refop;
3682 ++op;
3683 /* Have we matched them all yet? */
3684 if (op == opcount)
3686 while (op < maxops)
3688 /* If a later operand is *not* optional, no match. */
3689 if ((refoptype[refop] & OPT) == 0)
3690 return 0;
3691 /* Flag any implicit default OP_DST operands so we know to add
3692 them explicitly when encoding the operand later. */
3693 if (OPTYPE (refoptype[refop]) == OP_DST)
3694 insn->using_default_dst = 1;
3695 ++refop;
3696 ++op;
3699 return 1;
3703 return 0;
3706 /* 16-bit direct memory address
3707 Explicit dmad operands are always in last word of insn (usually second
3708 word, but bumped to third if lk addressing is used)
3710 We allow *(dmad) notation because the TI assembler allows it.
3712 XPC_CODE:
3713 0 for 16-bit addresses
3714 1 for full 23-bit addresses
3715 2 for the upper 7 bits of a 23-bit address (LDX). */
3717 static int
3718 encode_dmad (insn, operand, xpc_code)
3719 tic54x_insn *insn;
3720 struct opstruct *operand;
3721 int xpc_code;
3723 int op = 1 + insn->is_lkaddr;
3725 /* Only allow *(dmad) expressions; all others are invalid. */
3726 if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
3728 as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
3729 return 0;
3732 insn->opcode[op].addr_expr = operand->exp;
3734 if (insn->opcode[op].addr_expr.X_op == O_constant)
3736 valueT value = insn->opcode[op].addr_expr.X_add_number;
3738 if (xpc_code == 1)
3740 insn->opcode[0].word &= 0xFF80;
3741 insn->opcode[0].word |= (value >> 16) & 0x7F;
3742 insn->opcode[1].word = value & 0xFFFF;
3744 else if (xpc_code == 2)
3745 insn->opcode[op].word = (value >> 16) & 0xFFFF;
3746 else
3747 insn->opcode[op].word = value;
3749 else
3751 /* Do the fixup later; just store the expression. */
3752 insn->opcode[op].word = 0;
3753 insn->opcode[op].r_nchars = 2;
3755 if (amode == c_mode)
3756 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3757 else if (xpc_code == 1)
3759 /* This relocation spans two words, so adjust accordingly. */
3760 insn->opcode[0].addr_expr = operand->exp;
3761 insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
3762 insn->opcode[0].r_nchars = 4;
3763 insn->opcode[0].unresolved = 1;
3764 /* It's really 2 words, but we want to stop encoding after the
3765 first, since we must encode both words at once. */
3766 insn->words = 1;
3768 else if (xpc_code == 2)
3769 insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
3770 else
3771 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3773 insn->opcode[op].unresolved = 1;
3776 return 1;
3779 /* 7-bit direct address encoding. */
3781 static int
3782 encode_address (insn, operand)
3783 tic54x_insn *insn;
3784 struct opstruct *operand;
3786 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3787 insn->opcode[0].addr_expr = operand->exp;
3789 if (operand->exp.X_op == O_constant)
3790 insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
3791 else
3793 if (operand->exp.X_op == O_register)
3794 as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
3795 /* Do the fixup later; just store the expression. */
3796 insn->opcode[0].r_nchars = 1;
3797 insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
3798 insn->opcode[0].unresolved = 1;
3801 return 1;
3804 static int
3805 encode_indirect (insn, operand)
3806 tic54x_insn *insn;
3807 struct opstruct *operand;
3809 int arf;
3810 int mod;
3812 if (insn->is_lkaddr)
3814 /* lk addresses always go in the second insn word. */
3815 mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
3816 (operand->buf[1] == '(') ? 15 :
3817 (strchr (operand->buf, '%') != NULL) ? 14 : 13);
3818 arf = ((mod == 12) ? operand->buf[3] - '0' :
3819 (mod == 15) ? 0 : operand->buf[4] - '0');
3821 insn->opcode[1].addr_expr = operand->exp;
3823 if (operand->exp.X_op == O_constant)
3824 insn->opcode[1].word = operand->exp.X_add_number;
3825 else
3827 insn->opcode[1].word = 0;
3828 insn->opcode[1].r_nchars = 2;
3829 insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
3830 insn->opcode[1].unresolved = 1;
3833 else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
3835 /* Stack offsets look the same as 7-bit direct addressing. */
3836 return encode_address (insn, operand);
3838 else
3840 arf = (TOUPPER (operand->buf[1]) == 'A' ?
3841 operand->buf[3] : operand->buf[4]) - '0';
3843 if (operand->buf[1] == '+')
3845 mod = 3; /* *+ARx */
3846 if (insn->tm->flags & FL_SMR)
3847 as_warn (_("Address mode *+ARx is write-only. "
3848 "Results of reading are undefined."));
3850 else if (operand->buf[4] == '\0')
3851 mod = 0; /* *ARx */
3852 else if (operand->buf[5] == '\0')
3853 mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3854 else if (operand->buf[6] == '\0')
3856 if (operand->buf[5] == '0')
3857 mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3858 else
3859 mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3861 else if (TOUPPER (operand->buf[6]) == 'B')
3862 mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3863 else if (TOUPPER (operand->buf[6]) == '%')
3864 mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3865 else
3867 as_bad (_("Unrecognized indirect address format \"%s\""),
3868 operand->buf);
3869 return 0;
3873 insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
3875 return 1;
3878 static int
3879 encode_integer (insn, operand, which, min, max, mask)
3880 tic54x_insn *insn;
3881 struct opstruct *operand;
3882 int which;
3883 int min;
3884 int max;
3885 unsigned short mask;
3887 long parse, integer;
3889 insn->opcode[which].addr_expr = operand->exp;
3891 if (operand->exp.X_op == O_constant)
3893 parse = operand->exp.X_add_number;
3894 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3895 instead of negative. */
3896 if ((parse & 0x8000) && min == -32768 && max == 32767)
3897 integer = (short) parse;
3898 else
3899 integer = parse;
3901 if (integer >= min && integer <= max)
3903 insn->opcode[which].word |= (integer & mask);
3904 return 1;
3906 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3907 operand->buf, min, max);
3909 else
3911 if (insn->opcode[which].addr_expr.X_op == O_constant)
3913 insn->opcode[which].word |=
3914 insn->opcode[which].addr_expr.X_add_number & mask;
3916 else
3918 /* Do the fixup later; just store the expression. */
3919 bfd_reloc_code_real_type rtype =
3920 (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
3921 mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
3922 mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
3923 int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
3925 if (rtype == BFD_RELOC_8)
3926 as_bad (_("Error in relocation handling"));
3928 insn->opcode[which].r_nchars = size;
3929 insn->opcode[which].r_type = rtype;
3930 insn->opcode[which].unresolved = 1;
3933 return 1;
3936 return 0;
3939 static int
3940 encode_condition (insn, operand)
3941 tic54x_insn *insn;
3942 struct opstruct *operand;
3944 symbol *cc = (symbol *) hash_find (cc_hash, operand->buf);
3945 if (!cc)
3947 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3948 return 0;
3950 #define CC_GROUP 0x40
3951 #define CC_ACC 0x08
3952 #define CATG_A1 0x07
3953 #define CATG_B1 0x30
3954 #define CATG_A2 0x30
3955 #define CATG_B2 0x0C
3956 #define CATG_C2 0x03
3957 /* Disallow group 1 conditions mixed with group 2 conditions
3958 if group 1, allow only one category A and one category B
3959 if group 2, allow only one each of category A, B, and C. */
3960 if (((insn->opcode[0].word & 0xFF) != 0))
3962 if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
3964 as_bad (_("Condition \"%s\" does not match preceding group"),
3965 operand->buf);
3966 return 0;
3968 if (insn->opcode[0].word & CC_GROUP)
3970 if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
3972 as_bad (_("Condition \"%s\" uses a different accumulator from "
3973 "a preceding condition"),
3974 operand->buf);
3975 return 0;
3977 if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
3979 as_bad (_("Only one comparison conditional allowed"));
3980 return 0;
3982 if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
3984 as_bad (_("Only one overflow conditional allowed"));
3985 return 0;
3988 else if ( ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
3989 || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
3990 || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
3992 as_bad (_("Duplicate %s conditional"), operand->buf);
3993 return 0;
3997 insn->opcode[0].word |= cc->value;
3998 return 1;
4001 static int
4002 encode_cc3 (insn, operand)
4003 tic54x_insn *insn;
4004 struct opstruct *operand;
4006 symbol *cc3 = (symbol *) hash_find (cc3_hash, operand->buf);
4007 int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
4009 if ((value & 0x0300) != value)
4011 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
4012 return 0;
4014 insn->opcode[0].word |= value;
4015 return 1;
4018 static int
4019 encode_arx (insn, operand)
4020 tic54x_insn *insn;
4021 struct opstruct *operand;
4023 int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
4025 if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
4027 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
4028 return 0;
4030 insn->opcode[0].word |= arf;
4031 return 1;
4034 static int
4035 encode_cc2 (insn, operand)
4036 tic54x_insn *insn;
4037 struct opstruct *operand;
4039 symbol *cc2 = (symbol *) hash_find (cc2_hash, operand->buf);
4041 if (!cc2)
4043 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
4044 return 0;
4046 insn->opcode[0].word |= cc2->value;
4047 return 1;
4050 static int
4051 encode_operand (insn, type, operand)
4052 tic54x_insn *insn;
4053 enum optype type;
4054 struct opstruct *operand;
4056 int ext = (insn->tm->flags & FL_EXT) != 0;
4058 if (type == OP_MMR && operand->exp.X_op != O_constant)
4060 /* Disallow long-constant addressing for memory-mapped addressing. */
4061 if (insn->is_lkaddr)
4063 as_bad (_("lk addressing modes are invalid for memory-mapped "
4064 "register addressing"));
4065 return 0;
4067 type = OP_Smem;
4068 /* Warn about *+ARx when used with MMR operands. */
4069 if (strncasecmp (operand->buf, "*+ar", 4) == 0)
4071 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
4072 "register addressing. Resulting behavior is "
4073 "undefined."));
4077 switch (type)
4079 case OP_None:
4080 return 1;
4081 case OP_dmad:
4082 /* 16-bit immediate value. */
4083 return encode_dmad (insn, operand, 0);
4084 case OP_SRC:
4085 if (TOUPPER (*operand->buf) == 'B')
4087 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
4088 if (insn->using_default_dst)
4089 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
4091 return 1;
4092 case OP_RND:
4093 /* Make sure this agrees with the OP_DST operand. */
4094 if (!((TOUPPER (operand->buf[0]) == 'B') ^
4095 ((insn->opcode[0].word & (1 << 8)) != 0)))
4097 as_bad (_("Destination accumulator for each part of this parallel "
4098 "instruction must be different"));
4099 return 0;
4101 return 1;
4102 case OP_SRC1:
4103 case OP_DST:
4104 if (TOUPPER (operand->buf[0]) == 'B')
4105 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
4106 return 1;
4107 case OP_Xmem:
4108 case OP_Ymem:
4110 int mod = (operand->buf[4] == '\0' ? 0 : /* *arx */
4111 operand->buf[4] == '-' ? 1 : /* *arx- */
4112 operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
4113 int arf = operand->buf[3] - '0' - 2;
4114 int code = (mod << 2) | arf;
4115 insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
4116 return 1;
4118 case OP_Lmem:
4119 case OP_Smem:
4120 if (!is_indirect (operand))
4121 return encode_address (insn, operand);
4122 /* Fall through. */
4123 case OP_Sind:
4124 return encode_indirect (insn, operand);
4125 case OP_xpmad_ms7:
4126 return encode_dmad (insn, operand, 2);
4127 case OP_xpmad:
4128 return encode_dmad (insn, operand, 1);
4129 case OP_PA:
4130 case OP_pmad:
4131 return encode_dmad (insn, operand, 0);
4132 case OP_ARX:
4133 return encode_arx (insn, operand);
4134 case OP_MMRX:
4135 case OP_MMRY:
4136 case OP_MMR:
4138 int value = operand->exp.X_add_number;
4140 if (type == OP_MMR)
4141 insn->opcode[0].word |= value;
4142 else
4144 if (value < 16 || value > 24)
4146 as_bad (_("Memory mapped register \"%s\" out of range"),
4147 operand->buf);
4148 return 0;
4150 if (type == OP_MMRX)
4151 insn->opcode[0].word |= (value - 16) << 4;
4152 else
4153 insn->opcode[0].word |= (value - 16);
4155 return 1;
4157 case OP_B:
4158 case OP_A:
4159 return 1;
4160 case OP_SHFT:
4161 return encode_integer (insn, operand, ext + insn->is_lkaddr,
4162 0, 15, 0xF);
4163 case OP_SHIFT:
4164 return encode_integer (insn, operand, ext + insn->is_lkaddr,
4165 -16, 15, 0x1F);
4166 case OP_lk:
4167 return encode_integer (insn, operand, 1 + insn->is_lkaddr,
4168 -32768, 32767, 0xFFFF);
4169 case OP_CC:
4170 return encode_condition (insn, operand);
4171 case OP_CC2:
4172 return encode_cc2 (insn, operand);
4173 case OP_CC3:
4174 return encode_cc3 (insn, operand);
4175 case OP_BITC:
4176 return encode_integer (insn, operand, 0, 0, 15, 0xF);
4177 case OP_k8:
4178 return encode_integer (insn, operand, 0, -128, 127, 0xFF);
4179 case OP_123:
4181 int value = operand->exp.X_add_number;
4182 int code;
4183 if (value < 1 || value > 3)
4185 as_bad (_("Invalid operand (use 1, 2, or 3)"));
4186 return 0;
4188 code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
4189 insn->opcode[0].word |= (code << 8);
4190 return 1;
4192 case OP_031:
4193 return encode_integer (insn, operand, 0, 0, 31, 0x1F);
4194 case OP_k8u:
4195 return encode_integer (insn, operand, 0, 0, 255, 0xFF);
4196 case OP_lku:
4197 return encode_integer (insn, operand, 1 + insn->is_lkaddr,
4198 0, 65535, 0xFFFF);
4199 case OP_SBIT:
4201 symbol *sbit = (symbol *) hash_find (sbit_hash, operand->buf);
4202 int value = is_absolute (operand) ?
4203 operand->exp.X_add_number : (sbit ? sbit->value : -1);
4204 int reg = 0;
4206 if (insn->opcount == 1)
4208 if (!sbit)
4210 as_bad (_("A status register or status bit name is required"));
4211 return 0;
4213 /* Guess the register based on the status bit; "ovb" is the last
4214 status bit defined for st0. */
4215 if (sbit > (symbol *) hash_find (sbit_hash, "ovb"))
4216 reg = 1;
4218 if (value == -1)
4220 as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
4221 return 0;
4223 insn->opcode[0].word |= value;
4224 insn->opcode[0].word |= (reg << 9);
4225 return 1;
4227 case OP_N:
4228 if (strcasecmp (operand->buf, "st0") == 0
4229 || strcasecmp (operand->buf, "st1") == 0)
4231 insn->opcode[0].word |=
4232 ((unsigned short) (operand->buf[2] - '0')) << 9;
4233 return 1;
4235 else if (operand->exp.X_op == O_constant
4236 && (operand->exp.X_add_number == 0
4237 || operand->exp.X_add_number == 1))
4239 insn->opcode[0].word |=
4240 ((unsigned short) (operand->exp.X_add_number)) << 9;
4241 return 1;
4243 as_bad (_("Invalid status register \"%s\""), operand->buf);
4244 return 0;
4245 case OP_k5:
4246 return encode_integer (insn, operand, 0, -16, 15, 0x1F);
4247 case OP_k3:
4248 return encode_integer (insn, operand, 0, 0, 7, 0x7);
4249 case OP_k9:
4250 return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
4251 case OP_12:
4252 if (operand->exp.X_add_number != 1
4253 && operand->exp.X_add_number != 2)
4255 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
4256 return 0;
4258 insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
4259 return 1;
4260 case OP_16:
4261 case OP_T:
4262 case OP_TS:
4263 case OP_ASM:
4264 case OP_TRN:
4265 case OP_DP:
4266 case OP_ARP:
4267 /* No encoding necessary. */
4268 return 1;
4269 default:
4270 return 0;
4273 return 1;
4276 static void
4277 emit_insn (insn)
4278 tic54x_insn *insn;
4280 int i;
4281 flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
4282 flagword flags = oldflags | SEC_CODE;
4284 if (! bfd_set_section_flags (stdoutput, now_seg, flags))
4285 as_warn (_("error setting flags for \"%s\": %s"),
4286 bfd_section_name (stdoutput, now_seg),
4287 bfd_errmsg (bfd_get_error ()));
4289 for (i = 0; i < insn->words; i++)
4291 int size = (insn->opcode[i].unresolved
4292 && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
4293 char *p = frag_more (size);
4295 if (size == 2)
4296 md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
4297 else
4298 md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
4300 if (insn->opcode[i].unresolved)
4301 fix_new_exp (frag_now, p - frag_now->fr_literal,
4302 insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
4303 FALSE, insn->opcode[i].r_type);
4307 /* Convert the operand strings into appropriate opcode values
4308 return the total number of words used by the instruction. */
4310 static int
4311 build_insn (insn)
4312 tic54x_insn *insn;
4314 int i;
4316 /* Only non-parallel instructions support lk addressing. */
4317 if (!(insn->tm->flags & FL_PAR))
4319 for (i = 0; i < insn->opcount; i++)
4321 if ((OPTYPE (insn->operands[i].type) == OP_Smem
4322 || OPTYPE (insn->operands[i].type) == OP_Lmem
4323 || OPTYPE (insn->operands[i].type) == OP_Sind)
4324 && strchr (insn->operands[i].buf, '(')
4325 /* Don't mistake stack-relative addressing for lk addressing. */
4326 && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
4328 insn->is_lkaddr = 1;
4329 insn->lkoperand = i;
4330 break;
4334 insn->words = insn->tm->words + insn->is_lkaddr;
4336 insn->opcode[0].word = insn->tm->opcode;
4337 if (insn->tm->flags & FL_EXT)
4338 insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
4340 for (i = 0; i < insn->opcount; i++)
4342 enum optype type = insn->operands[i].type;
4344 if (!encode_operand (insn, type, &insn->operands[i]))
4345 return 0;
4347 if (insn->tm->flags & FL_PAR)
4348 for (i = 0; i < insn->paropcount; i++)
4350 enum optype partype = insn->paroperands[i].type;
4352 if (!encode_operand (insn, partype, &insn->paroperands[i]))
4353 return 0;
4356 emit_insn (insn);
4358 return insn->words;
4361 static int
4362 optimize_insn (insn)
4363 tic54x_insn *insn;
4365 /* Optimize some instructions, helping out the brain-dead programmer. */
4366 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4367 if (strcasecmp (insn->tm->name, "add") == 0)
4369 if (insn->opcount > 1
4370 && is_accumulator (&insn->operands[insn->opcount - 2])
4371 && is_accumulator (&insn->operands[insn->opcount - 1])
4372 && strcasecmp (insn->operands[insn->opcount - 2].buf,
4373 insn->operands[insn->opcount - 1].buf) == 0)
4375 --insn->opcount;
4376 insn->using_default_dst = 1;
4377 return 1;
4380 /* Try to collapse if Xmem and shift count is zero. */
4381 if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4382 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
4383 && is_zero (insn->operands[1]))
4384 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4385 || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4386 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4387 && is_type (&insn->operands[1], OP_SHIFT)
4388 && is_zero (insn->operands[1]) && insn->opcount == 3))
4390 insn->operands[1] = insn->operands[2];
4391 insn->opcount = 2;
4392 return 1;
4395 else if (strcasecmp (insn->tm->name, "ld") == 0)
4397 if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
4399 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4400 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4401 && is_zero (insn->operands[1])
4402 && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
4403 || (insn->operands[0].exp.X_op == O_constant
4404 && insn->operands[0].exp.X_add_number <= 255
4405 && insn->operands[0].exp.X_add_number >= 0)))
4407 insn->operands[1] = insn->operands[2];
4408 insn->opcount = 2;
4409 return 1;
4413 else if (strcasecmp (insn->tm->name, "sth") == 0
4414 || strcasecmp (insn->tm->name, "stl") == 0)
4416 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4417 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4418 && is_zero (insn->operands[1]))
4420 insn->operands[1] = insn->operands[2];
4421 insn->opcount = 2;
4422 return 1;
4425 else if (strcasecmp (insn->tm->name, "sub") == 0)
4427 if (insn->opcount > 1
4428 && is_accumulator (&insn->operands[insn->opcount - 2])
4429 && is_accumulator (&insn->operands[insn->opcount - 1])
4430 && strcasecmp (insn->operands[insn->opcount - 2].buf,
4431 insn->operands[insn->opcount - 1].buf) == 0)
4433 --insn->opcount;
4434 insn->using_default_dst = 1;
4435 return 1;
4438 if ( ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4439 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
4440 || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4441 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
4442 && is_zero (insn->operands[1])
4443 && insn->opcount == 3)
4445 insn->operands[1] = insn->operands[2];
4446 insn->opcount = 2;
4447 return 1;
4450 return 0;
4453 /* Find a matching template if possible, and get the operand strings. */
4455 static int
4456 tic54x_parse_insn (insn, line)
4457 tic54x_insn *insn;
4458 char *line;
4460 insn->tm = (template *) hash_find (op_hash, insn->mnemonic);
4461 if (!insn->tm)
4463 as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
4464 return 0;
4467 insn->opcount = get_operands (insn->operands, line);
4468 if (insn->opcount < 0)
4469 return 0;
4471 /* Check each variation of operands for this mnemonic. */
4472 while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
4474 if (insn->opcount >= insn->tm->minops
4475 && insn->opcount <= insn->tm->maxops
4476 && operands_match (insn, &insn->operands[0], insn->opcount,
4477 insn->tm->operand_types,
4478 insn->tm->minops, insn->tm->maxops))
4480 /* SUCCESS! now try some optimizations. */
4481 if (optimize_insn (insn))
4483 insn->tm = (template *) hash_find (op_hash,
4484 insn->mnemonic);
4485 continue;
4488 return 1;
4490 ++(insn->tm);
4492 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4493 line, insn->mnemonic);
4494 return 0;
4497 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4498 won't be able to see the next line. */
4499 static int parallel_on_next_line_hint = 0;
4501 /* See if this is part of a parallel instruction
4502 Look for a subsequent line starting with "||". */
4504 static int
4505 next_line_shows_parallel (next_line)
4506 char *next_line;
4508 /* Look for the second half. */
4509 while (ISSPACE (*next_line))
4510 ++next_line;
4512 return (next_line[0] == PARALLEL_SEPARATOR
4513 && next_line[1] == PARALLEL_SEPARATOR);
4516 static int
4517 tic54x_parse_parallel_insn_firstline (insn, line)
4518 tic54x_insn *insn;
4519 char *line;
4521 insn->tm = (template *) hash_find (parop_hash, insn->mnemonic);
4522 if (!insn->tm)
4524 as_bad (_("Unrecognized parallel instruction \"%s\""),
4525 insn->mnemonic);
4526 return 0;
4529 while (insn->tm->name && strcasecmp (insn->tm->name,
4530 insn->mnemonic) == 0)
4532 insn->opcount = get_operands (insn->operands, line);
4533 if (insn->opcount < 0)
4534 return 0;
4535 if (insn->opcount == 2
4536 && operands_match (insn, &insn->operands[0], insn->opcount,
4537 insn->tm->operand_types, 2, 2))
4539 return 1;
4541 ++(insn->tm);
4543 /* Didn't find a matching parallel; try for a normal insn. */
4544 return 0;
4547 /* Parse the second line of a two-line parallel instruction. */
4549 static int
4550 tic54x_parse_parallel_insn_lastline (insn, line)
4551 tic54x_insn *insn;
4552 char *line;
4554 int valid_mnemonic = 0;
4556 insn->paropcount = get_operands (insn->paroperands, line);
4557 while (insn->tm->name && strcasecmp (insn->tm->name,
4558 insn->mnemonic) == 0)
4560 if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
4562 valid_mnemonic = 1;
4564 if (insn->paropcount >= insn->tm->minops
4565 && insn->paropcount <= insn->tm->maxops
4566 && operands_match (insn, insn->paroperands,
4567 insn->paropcount,
4568 insn->tm->paroperand_types,
4569 insn->tm->minops, insn->tm->maxops))
4570 return 1;
4572 ++(insn->tm);
4574 if (valid_mnemonic)
4575 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4576 insn->parmnemonic);
4577 else
4578 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4579 insn->mnemonic, insn->parmnemonic);
4581 return 0;
4584 /* If quotes found, return copy of line up to closing quote;
4585 otherwise up until terminator.
4586 If it's a string, pass as-is; otherwise attempt substitution symbol
4587 replacement on the value. */
4589 static char *
4590 subsym_get_arg (line, terminators, str, nosub)
4591 char *line;
4592 char *terminators;
4593 char **str;
4594 int nosub;
4596 char *ptr = line;
4597 char *endp;
4598 int is_string = *line == '"';
4599 int is_char = ISDIGIT (*line);
4601 if (is_char)
4603 while (ISDIGIT (*ptr))
4604 ++ptr;
4605 endp = ptr;
4606 *str = xmalloc (ptr - line + 1);
4607 strncpy (*str, line, ptr - line);
4608 (*str)[ptr - line] = 0;
4610 else if (is_string)
4612 char *savedp = input_line_pointer;
4613 int len;
4615 input_line_pointer = ptr;
4616 *str = demand_copy_C_string (&len);
4617 endp = input_line_pointer;
4618 input_line_pointer = savedp;
4620 /* Do forced substitutions if requested. */
4621 if (!nosub && **str == ':')
4622 *str = subsym_substitute (*str, 1);
4624 else
4626 char *term = terminators;
4627 char *value = NULL;
4629 while (*ptr && *ptr != *term)
4631 if (!*term)
4633 term = terminators;
4634 ++ptr;
4636 else
4637 ++term;
4639 endp = ptr;
4640 *str = xmalloc (ptr - line + 1);
4641 strncpy (*str, line, ptr - line);
4642 (*str)[ptr - line] = 0;
4643 /* Do simple substitution, if available. */
4644 if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
4645 *str = value;
4648 return endp;
4651 /* Replace the given substitution string.
4652 We start at the innermost macro level, so that existing locals remain local
4653 Note: we're treating macro args identically to .var's; I don't know if
4654 that's compatible w/TI's assembler. */
4656 static void
4657 subsym_create_or_replace (name, value)
4658 char *name;
4659 char *value;
4661 int i;
4663 for (i = macro_level; i > 0; i--)
4665 if (hash_find (subsym_hash[i], name))
4667 hash_replace (subsym_hash[i], name, value);
4668 return;
4671 if (hash_find (subsym_hash[0], name))
4672 hash_replace (subsym_hash[0], name, value);
4673 else
4674 hash_insert (subsym_hash[0], name, value);
4677 /* Look up the substitution string replacement for the given symbol.
4678 Start with the innermost macro substitution table given and work
4679 outwards. */
4681 static char *
4682 subsym_lookup (name, nest_level)
4683 char *name;
4684 int nest_level;
4686 char *value = hash_find (subsym_hash[nest_level], name);
4688 if (value || nest_level == 0)
4689 return value;
4691 return subsym_lookup (name, nest_level - 1);
4694 /* Do substitution-symbol replacement on the given line (recursively).
4695 return the argument if no substitution was done
4697 Also look for built-in functions ($func (arg)) and local labels.
4699 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4701 static char *
4702 subsym_substitute (line, forced)
4703 char * line;
4704 int forced;
4706 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4707 replace it in the input. */
4708 char *replacement; /* current replacement for LINE. */
4709 char *head; /* Start of line. */
4710 char *ptr; /* Current examination point. */
4711 int changed = 0; /* Did we make a substitution? */
4712 int eval_line = 0; /* Is this line a .eval/.asg statement? */
4713 int eval_symbol = 0; /* Are we in the middle of the symbol for
4714 .eval/.asg? */
4715 char *eval_end = NULL;
4716 int recurse = 1;
4717 int line_conditional = 0;
4718 char *tmp;
4720 /* Work with a copy of the input line. */
4721 replacement = xmalloc (strlen (line) + 1);
4722 strcpy (replacement, line);
4724 ptr = head = replacement;
4726 /* Flag lines where we might need to replace a single '=' with two;
4727 GAS uses single '=' to assign macro args values, and possibly other
4728 places, so limit what we replace. */
4729 if (strstr (line, ".if")
4730 || strstr (line, ".elseif")
4731 || strstr (line, ".break"))
4732 line_conditional = 1;
4734 /* Watch out for .eval, so that we avoid doing substitution on the
4735 symbol being assigned a value. */
4736 if (strstr (line, ".eval") || strstr (line, ".asg"))
4737 eval_line = 1;
4739 /* If it's a macro definition, don't do substitution on the argument
4740 names. */
4741 if (strstr (line, ".macro"))
4742 return line;
4744 while (!is_end_of_line[(int) *ptr])
4746 int current_char = *ptr;
4748 /* Need to update this since LINE may have been modified. */
4749 if (eval_line)
4750 eval_end = strrchr (ptr, ',');
4752 /* Replace triple double quotes with bounding quote/escapes. */
4753 if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
4755 ptr[1] = '\\';
4756 tmp = strstr (ptr + 2, "\"\"\"");
4757 if (tmp)
4758 tmp[0] = '\\';
4759 changed = 1;
4762 /* Replace a single '=' with a '==';
4763 for compatibility with older code only. */
4764 if (line_conditional && current_char == '=')
4766 if (ptr[1] == '=')
4768 ptr += 2;
4769 continue;
4771 *ptr++ = '\0';
4772 tmp = xmalloc (strlen (head) + 2 + strlen (ptr) + 1);
4773 sprintf (tmp, "%s==%s", head, ptr);
4774 /* Continue examining after the '=='. */
4775 ptr = tmp + strlen (head) + 2;
4776 free (replacement);
4777 head = replacement = tmp;
4778 changed = 1;
4781 /* Flag when we've reached the symbol part of .eval/.asg. */
4782 if (eval_line && ptr >= eval_end)
4783 eval_symbol = 1;
4785 /* For each apparent symbol, see if it's a substitution symbol, and if
4786 so, replace it in the input. */
4787 if ((forced && current_char == ':')
4788 || (!forced && is_name_beginner (current_char)))
4790 char *name; /* Symbol to be replaced. */
4791 char *savedp = input_line_pointer;
4792 int c;
4793 char *value = NULL;
4794 char *tail; /* Rest of line after symbol. */
4796 /* Skip the colon. */
4797 if (forced)
4798 ++ptr;
4800 name = input_line_pointer = ptr;
4801 c = get_symbol_end ();
4802 /* '?' is not normally part of a symbol, but it IS part of a local
4803 label. */
4804 if (c == '?')
4806 *input_line_pointer++ = c;
4807 c = *input_line_pointer;
4808 *input_line_pointer = '\0';
4810 /* Avoid infinite recursion; if a symbol shows up a second time for
4811 substitution, leave it as is. */
4812 if (hash_find (subsym_recurse_hash, name) == NULL)
4813 value = subsym_lookup (name, macro_level);
4814 else
4815 as_warn (_("%s symbol recursion stopped at "
4816 "second appearance of '%s'"),
4817 forced ? "Forced substitution" : "Substitution", name);
4818 ptr = tail = input_line_pointer;
4819 input_line_pointer = savedp;
4821 /* Check for local labels; replace them with the appropriate
4822 substitution. */
4823 if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
4824 || name[strlen (name) - 1] == '?')
4826 /* Use an existing identifier for that label if, available, or
4827 create a new, unique identifier. */
4828 value = hash_find (local_label_hash[macro_level], name);
4829 if (value == NULL)
4831 char digit[11];
4832 char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
4834 value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
4835 name);
4836 if (*value != '$')
4837 value[strlen (value) - 1] = '\0';
4838 sprintf (digit, ".%d", local_label_id++);
4839 strcat (value, digit);
4840 hash_insert (local_label_hash[macro_level], namecopy, value);
4842 /* Indicate where to continue looking for substitutions. */
4843 ptr = tail;
4845 /* Check for built-in subsym and math functions. */
4846 else if (value != NULL && *name == '$')
4848 subsym_proc_entry *entry = (subsym_proc_entry *) value;
4849 math_proc_entry *math_entry = hash_find (math_hash, name);
4850 char *arg1, *arg2 = NULL;
4852 *ptr = c;
4853 if (entry == NULL)
4855 as_bad (_("Unrecognized substitution symbol function"));
4856 break;
4858 else if (*ptr != '(')
4860 as_bad (_("Missing '(' after substitution symbol function"));
4861 break;
4863 ++ptr;
4864 if (math_entry != NULL)
4866 float arg1, arg2 = 0;
4867 volatile float fresult;
4869 arg1 = (float) strtod (ptr, &ptr);
4870 if (math_entry->nargs == 2)
4872 if (*ptr++ != ',')
4874 as_bad (_("Expecting second argument"));
4875 break;
4877 arg2 = (float) strtod (ptr, &ptr);
4879 fresult = (*math_entry->proc) (arg1, arg2);
4880 value = xmalloc (128);
4881 if (math_entry->int_return)
4882 sprintf (value, "%d", (int) fresult);
4883 else
4884 sprintf (value, "%f", fresult);
4885 if (*ptr++ != ')')
4887 as_bad (_("Extra junk in function call, expecting ')'"));
4888 break;
4890 /* Don't bother recursing; the replacement isn't a
4891 symbol. */
4892 recurse = 0;
4894 else
4896 int val;
4897 int arg_type[2] = { *ptr == '"' , 0 };
4898 int ismember = !strcmp (entry->name, "$ismember");
4900 /* Parse one or two args, which must be a substitution
4901 symbol, string or a character-string constant. */
4902 /* For all functions, a string or substitution symbol may be
4903 used, with the following exceptions:
4904 firstch/lastch: 2nd arg must be character constant
4905 ismember: both args must be substitution symbols. */
4906 ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
4907 if (!arg1)
4908 break;
4909 if (entry->nargs == 2)
4911 if (*ptr++ != ',')
4913 as_bad (_("Function expects two arguments"));
4914 break;
4916 /* Character constants are converted to numerics
4917 by the preprocessor. */
4918 arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
4919 ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
4921 /* Args checking. */
4922 if ((!strcmp (entry->name, "$firstch")
4923 || !strcmp (entry->name, "$lastch"))
4924 && arg_type[1] != 2)
4926 as_bad (_("Expecting character constant argument"));
4927 break;
4929 if (ismember
4930 && (arg_type[0] != 0 || arg_type[1] != 0))
4932 as_bad (_("Both arguments must be substitution symbols"));
4933 break;
4935 if (*ptr++ != ')')
4937 as_bad (_("Extra junk in function call, expecting ')'"));
4938 break;
4940 val = (*entry->proc) (arg1, arg2);
4941 value = xmalloc (64);
4942 sprintf (value, "%d", val);
4944 /* Fix things up to replace the entire expression, not just the
4945 function name. */
4946 tail = ptr;
4947 c = *tail;
4950 if (value != NULL && !eval_symbol)
4952 /* Replace the symbol with its string replacement and
4953 continue. Recursively replace VALUE until either no
4954 substitutions are performed, or a substitution that has been
4955 previously made is encountered again.
4957 put the symbol into the recursion hash table so we only
4958 try to replace a symbol once. */
4959 if (recurse)
4961 hash_insert (subsym_recurse_hash, name, name);
4962 value = subsym_substitute (value, macro_level > 0);
4963 hash_delete (subsym_recurse_hash, name);
4966 /* Temporarily zero-terminate where the symbol started. */
4967 *name = 0;
4968 if (forced)
4970 if (c == '(')
4972 /* Subscripted substitution symbol -- use just the
4973 indicated portion of the string; the description
4974 kinda indicates that forced substitution is not
4975 supposed to be recursive, but I'm not sure. */
4976 unsigned beg, len = 1; /* default to a single char */
4977 char *newval = strcpy (xmalloc (strlen (value) + 1),
4978 value);
4980 savedp = input_line_pointer;
4981 input_line_pointer = tail + 1;
4982 beg = get_absolute_expression ();
4983 if (beg < 1)
4985 as_bad (_("Invalid subscript (use 1 to %d)"),
4986 (int) strlen (value));
4987 break;
4989 if (*input_line_pointer == ',')
4991 ++input_line_pointer;
4992 len = get_absolute_expression ();
4993 if (beg + len > strlen (value))
4995 as_bad (_("Invalid length (use 0 to %d"),
4996 (int) strlen (value) - beg);
4997 break;
5000 newval += beg - 1;
5001 newval[len] = 0;
5002 tail = input_line_pointer;
5003 if (*tail++ != ')')
5005 as_bad (_("Missing ')' in subscripted substitution "
5006 "symbol expression"));
5007 break;
5009 c = *tail;
5010 input_line_pointer = savedp;
5012 value = newval;
5014 name[-1] = 0;
5016 tmp = xmalloc (strlen (head) + strlen (value) +
5017 strlen (tail + 1) + 2);
5018 strcpy (tmp, head);
5019 strcat (tmp, value);
5020 /* Make sure forced substitutions are properly terminated. */
5021 if (forced)
5023 if (c != ':')
5025 as_bad (_("Missing forced substitution terminator ':'"));
5026 break;
5028 ++tail;
5030 else
5031 /* Restore the character after the symbol end. */
5032 *tail = c;
5033 strcat (tmp, tail);
5034 /* Continue examining after the replacement value. */
5035 ptr = tmp + strlen (head) + strlen (value);
5036 free (replacement);
5037 head = replacement = tmp;
5038 changed = 1;
5040 else
5041 *ptr = c;
5043 else
5045 ++ptr;
5049 if (changed)
5050 return replacement;
5051 else
5052 return line;
5055 /* We use this to handle substitution symbols
5056 hijack input_line_pointer, replacing it with our substituted string.
5058 .sslist should enable listing the line after replacements are made...
5060 returns the new buffer limit. */
5062 void
5063 tic54x_start_line_hook ()
5065 char *line, *endp;
5066 char *replacement = NULL;
5068 /* Work with a copy of the input line, including EOL char. */
5069 endp = input_line_pointer;
5070 while (!is_end_of_line[(int) *endp++])
5072 line = xmalloc (endp - input_line_pointer + 1);
5073 strncpy (line, input_line_pointer, endp - input_line_pointer + 1);
5074 line[endp - input_line_pointer] = 0;
5076 /* Scan ahead for parallel insns. */
5077 parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
5079 /* If within a macro, first process forced replacements. */
5080 if (macro_level > 0)
5081 replacement = subsym_substitute (line, 1);
5082 else
5083 replacement = line;
5084 replacement = subsym_substitute (replacement, 0);
5086 if (replacement != line)
5088 char *tmp = replacement;
5089 char *comment = strchr (replacement, ';');
5090 char endc = replacement[strlen (replacement) - 1];
5092 /* Clean up the replacement; we'd prefer to have this done by the
5093 standard preprocessing equipment (maybe do_scrub_chars?)
5094 but for now, do a quick-and-dirty. */
5095 if (comment != NULL)
5097 comment[0] = endc;
5098 comment[1] = 0;
5099 --comment;
5101 else
5102 comment = replacement + strlen (replacement) - 1;
5104 /* Trim trailing whitespace. */
5105 while (ISSPACE (*comment))
5107 comment[0] = endc;
5108 comment[1] = 0;
5109 --comment;
5112 /* Compact leading whitespace. */
5113 while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
5114 ++tmp;
5116 input_line_pointer = endp;
5117 input_scrub_insert_line (tmp);
5118 free (replacement);
5119 free (line);
5120 /* Keep track of whether we've done a substitution. */
5121 substitution_line = 1;
5123 else
5125 /* No change. */
5126 free (line);
5127 substitution_line = 0;
5131 /* This is the guts of the machine-dependent assembler. STR points to a
5132 machine dependent instruction. This function is supposed to emit
5133 the frags/bytes it assembles to. */
5134 void
5135 md_assemble (line)
5136 char *line;
5138 static int repeat_slot = 0;
5139 static int delay_slots = 0; /* How many delay slots left to fill? */
5140 static int is_parallel = 0;
5141 static tic54x_insn insn;
5142 char *lptr;
5143 char *savedp = input_line_pointer;
5144 int c;
5146 input_line_pointer = line;
5147 c = get_symbol_end ();
5149 if (cpu == VNONE)
5150 cpu = V542;
5151 if (address_mode_needs_set)
5153 set_address_mode (amode);
5154 address_mode_needs_set = 0;
5156 if (cpu_needs_set)
5158 set_cpu (cpu);
5159 cpu_needs_set = 0;
5161 assembly_begun = 1;
5163 if (is_parallel)
5165 is_parallel = 0;
5167 strcpy (insn.parmnemonic, line);
5168 lptr = input_line_pointer;
5169 *lptr = c;
5170 input_line_pointer = savedp;
5172 if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
5174 int words = build_insn (&insn);
5176 if (delay_slots != 0)
5178 if (words > delay_slots)
5180 as_bad (_("Instruction does not fit in available delay "
5181 "slots (%d-word insn, %d slots left)"),
5182 words, delay_slots);
5183 delay_slots = 0;
5184 return;
5186 delay_slots -= words;
5189 return;
5192 memset (&insn, 0, sizeof (insn));
5193 strcpy (insn.mnemonic, line);
5194 lptr = input_line_pointer;
5195 *lptr = c;
5196 input_line_pointer = savedp;
5198 /* See if this line is part of a parallel instruction; if so, either this
5199 line or the next line will have the "||" specifier preceding the
5200 mnemonic, and we look for it in the parallel insn hash table. */
5201 if (strstr (line, "||") != NULL || parallel_on_next_line_hint)
5203 char *tmp = strstr (line, "||");
5204 if (tmp != NULL)
5205 *tmp = '\0';
5207 if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
5209 is_parallel = 1;
5210 /* If the parallel part is on the same line, process it now,
5211 otherwise let the assembler pick up the next line for us. */
5212 if (tmp != NULL)
5214 while (ISSPACE (tmp[2]))
5215 ++tmp;
5216 md_assemble (tmp + 2);
5219 else
5221 as_bad (_("Unrecognized parallel instruction '%s'"), line);
5223 return;
5226 if (tic54x_parse_insn (&insn, lptr))
5228 int words;
5230 if ((insn.tm->flags & FL_LP)
5231 && cpu != V545LP && cpu != V546LP)
5233 as_bad (_("Instruction '%s' requires an LP cpu version"),
5234 insn.tm->name);
5235 return;
5237 if ((insn.tm->flags & FL_FAR)
5238 && amode != far_mode)
5240 as_bad (_("Instruction '%s' requires far mode addressing"),
5241 insn.tm->name);
5242 return;
5245 words = build_insn (&insn);
5247 /* Is this instruction in a delay slot? */
5248 if (delay_slots)
5250 if (words > delay_slots)
5252 as_warn (_("Instruction does not fit in available delay "
5253 "slots (%d-word insn, %d slots left). "
5254 "Resulting behavior is undefined."),
5255 words, delay_slots);
5256 delay_slots = 0;
5257 return;
5259 /* Branches in delay slots are not allowed. */
5260 if (insn.tm->flags & FL_BMASK)
5262 as_warn (_("Instructions which cause PC discontinuity are not "
5263 "allowed in a delay slot. "
5264 "Resulting behavior is undefined."));
5266 delay_slots -= words;
5269 /* Is this instruction the target of a repeat? */
5270 if (repeat_slot)
5272 if (insn.tm->flags & FL_NR)
5273 as_warn (_("'%s' is not repeatable. "
5274 "Resulting behavior is undefined."),
5275 insn.tm->name);
5276 else if (insn.is_lkaddr)
5277 as_warn (_("Instructions using long offset modifiers or absolute "
5278 "addresses are not repeatable. "
5279 "Resulting behavior is undefined."));
5280 repeat_slot = 0;
5283 /* Make sure we check the target of a repeat instruction. */
5284 if (insn.tm->flags & B_REPEAT)
5286 repeat_slot = 1;
5287 /* FIXME -- warn if repeat_slot == 1 at EOF. */
5289 /* Make sure we check our delay slots for validity. */
5290 if (insn.tm->flags & FL_DELAY)
5292 delay_slots = 2;
5293 /* FIXME -- warn if delay_slots != 0 at EOF. */
5298 /* Do a final adjustment on the symbol table; in this case, make sure we have
5299 a ".file" symbol. */
5301 void
5302 tic54x_adjust_symtab ()
5304 if (symbol_rootP == NULL
5305 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
5307 char *filename;
5308 unsigned lineno;
5309 as_where (&filename, &lineno);
5310 c_dot_file_symbol (filename, 0);
5314 /* In order to get gas to ignore any | chars at the start of a line,
5315 this function returns true if a | is found in a line.
5316 This lets us process parallel instructions, which span two lines. */
5319 tic54x_unrecognized_line (int c)
5321 return c == PARALLEL_SEPARATOR;
5324 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
5325 Encode their names so that only we see them and can map them to the
5326 appropriate places.
5327 FIXME -- obviously this isn't done yet. These locals still show up in the
5328 symbol table. */
5329 void
5330 tic54x_define_label (sym)
5331 symbolS *sym;
5333 /* Just in case we need this later; note that this is not necessarily the
5334 same thing as line_label...
5335 When aligning or assigning labels to fields, sometimes the label is
5336 assigned other than the address at which the label appears.
5337 FIXME -- is this really needed? I think all the proper label assignment
5338 is done in tic54x_cons. */
5339 last_label_seen = sym;
5342 /* Try to parse something that normal parsing failed at. */
5344 symbolS *
5345 tic54x_undefined_symbol (name)
5346 char *name;
5348 symbol *sym;
5350 /* Not sure how to handle predefined symbols. */
5351 if ((sym = (symbol *) hash_find (cc_hash, name)) != NULL ||
5352 (sym = (symbol *) hash_find (cc2_hash, name)) != NULL ||
5353 (sym = (symbol *) hash_find (cc3_hash, name)) != NULL ||
5354 (sym = (symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
5355 (sym = (symbol *) hash_find (sbit_hash, name)) != NULL)
5357 return symbol_new (name, reg_section,
5358 (valueT) sym->value,
5359 &zero_address_frag);
5362 if ((sym = (symbol *) hash_find (reg_hash, name)) != NULL ||
5363 (sym = (symbol *) hash_find (mmreg_hash, name)) != NULL ||
5364 !strcasecmp (name, "a") || !strcasecmp (name, "b"))
5366 return symbol_new (name, reg_section,
5367 (valueT) sym ? sym->value : 0,
5368 &zero_address_frag);
5371 return NULL;
5374 /* Parse a name in an expression before the expression parser takes a stab at
5375 it. */
5378 tic54x_parse_name (name, exp)
5379 char *name ATTRIBUTE_UNUSED;
5380 expressionS *exp ATTRIBUTE_UNUSED;
5382 return 0;
5385 char *
5386 md_atof (type, literalP, sizeP)
5387 int type;
5388 char *literalP;
5389 int *sizeP;
5391 #define MAX_LITTLENUMS 2
5392 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5393 LITTLENUM_TYPE *word;
5394 /* Only one precision on the c54x. */
5395 int prec = 2;
5396 char *t = atof_ieee (input_line_pointer, type, words);
5397 if (t)
5398 input_line_pointer = t;
5399 *sizeP = 4;
5401 /* Target data is little-endian, but floats are stored
5402 big-"word"ian. ugh. */
5403 for (word = words; prec--;)
5405 md_number_to_chars (literalP, (long) (*word++), sizeof (LITTLENUM_TYPE));
5406 literalP += sizeof (LITTLENUM_TYPE);
5409 return 0;
5412 arelent *
5413 tc_gen_reloc (section, fixP)
5414 asection *section;
5415 fixS *fixP;
5417 arelent *rel;
5418 bfd_reloc_code_real_type code = fixP->fx_r_type;
5419 asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
5421 rel = (arelent *) xmalloc (sizeof (arelent));
5422 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5423 *rel->sym_ptr_ptr = sym;
5424 /* We assume that all rel->address are host byte offsets. */
5425 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5426 rel->address /= OCTETS_PER_BYTE;
5427 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
5428 if (!strcmp (sym->name, section->name))
5429 rel->howto += HOWTO_BANK;
5431 if (!rel->howto)
5433 const char *name = S_GET_NAME (fixP->fx_addsy);
5434 if (name == NULL)
5435 name = "<unknown>";
5436 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5437 name, bfd_get_reloc_code_name (code));
5438 return NULL;
5440 return rel;
5443 /* Handle cons expressions. */
5445 void
5446 tic54x_cons_fix_new (frag, where, octets, exp)
5447 fragS *frag;
5448 int where;
5449 int octets;
5450 expressionS *exp;
5452 bfd_reloc_code_real_type r;
5454 switch (octets)
5456 default:
5457 as_bad (_("Unsupported relocation size %d"), octets);
5458 r = BFD_RELOC_TIC54X_16_OF_23;
5459 break;
5460 case 2:
5461 r = BFD_RELOC_TIC54X_16_OF_23;
5462 break;
5463 case 4:
5464 /* TI assembler always uses this, regardless of addressing mode. */
5465 if (emitting_long)
5466 r = BFD_RELOC_TIC54X_23;
5467 else
5468 /* We never want to directly generate this; this is provided for
5469 stabs support only. */
5470 r = BFD_RELOC_32;
5471 break;
5473 fix_new_exp (frag, where, octets, exp, 0, r);
5476 /* Attempt to simplify or even eliminate a fixup.
5477 To indicate that a fixup has been eliminated, set fixP->fx_done.
5479 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5481 void
5482 md_apply_fix (fixP, valP, seg)
5483 fixS *fixP;
5484 valueT * valP;
5485 segT seg ATTRIBUTE_UNUSED;
5487 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5488 valueT val = * valP;
5490 switch (fixP->fx_r_type)
5492 default:
5493 as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
5494 return;
5495 case BFD_RELOC_TIC54X_MS7_OF_23:
5496 val = (val >> 16) & 0x7F;
5497 /* Fall through. */
5498 case BFD_RELOC_TIC54X_16_OF_23:
5499 case BFD_RELOC_16:
5500 bfd_put_16 (stdoutput, val, buf);
5501 /* Indicate what we're actually writing, so that we don't get warnings
5502 about exceeding available space. */
5503 *valP = val & 0xFFFF;
5504 break;
5505 case BFD_RELOC_TIC54X_PARTLS7:
5506 bfd_put_16 (stdoutput,
5507 (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
5508 buf);
5509 /* Indicate what we're actually writing, so that we don't get warnings
5510 about exceeding available space. */
5511 *valP = val & 0x7F;
5512 break;
5513 case BFD_RELOC_TIC54X_PARTMS9:
5514 /* TI assembler doesn't shift its encoding for relocatable files, and is
5515 thus incompatible with this implementation's relocatable files. */
5516 bfd_put_16 (stdoutput,
5517 (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
5518 buf);
5519 break;
5520 case BFD_RELOC_32:
5521 case BFD_RELOC_TIC54X_23:
5522 bfd_put_32 (stdoutput,
5523 (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
5524 buf);
5525 break;
5528 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
5529 fixP->fx_done = 1;
5532 /* This is our chance to record section alignment
5533 don't need to do anything here, since BFD does the proper encoding. */
5535 valueT
5536 md_section_align (segment, section_size)
5537 segT segment ATTRIBUTE_UNUSED;
5538 valueT section_size;
5540 return section_size;
5543 long
5544 md_pcrel_from (fixP)
5545 fixS *fixP ATTRIBUTE_UNUSED;
5547 return 0;
5550 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5551 first. */
5553 void
5554 tic54x_number_to_chars (buf, val, n)
5555 char *buf;
5556 valueT val;
5557 int n;
5559 if (n != 4)
5560 number_to_chars_littleendian (buf, val, n);
5561 else
5563 number_to_chars_littleendian (buf , val >> 16 , 2);
5564 number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
5569 tic54x_estimate_size_before_relax (frag, seg)
5570 fragS *frag ATTRIBUTE_UNUSED;
5571 segT seg ATTRIBUTE_UNUSED;
5573 return 0;
5576 /* We use this to handle bit allocations which we couldn't handle before due
5577 to symbols being in different frags. return number of octets added. */
5580 tic54x_relax_frag (frag, stretch)
5581 fragS *frag;
5582 long stretch ATTRIBUTE_UNUSED;
5584 symbolS *sym = frag->fr_symbol;
5585 int growth = 0;
5586 int i;
5588 if (sym != NULL)
5590 struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
5591 int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
5592 int size = S_GET_VALUE (sym);
5593 fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
5594 int available = 16 - bit_offset;
5596 if (symbol_get_frag (sym) != &zero_address_frag
5597 || S_IS_COMMON (sym)
5598 || !S_IS_DEFINED (sym))
5599 as_bad_where (frag->fr_file, frag->fr_line,
5600 _("non-absolute value used with .space/.bes"));
5602 if (size < 0)
5604 as_warn (_("negative value ignored in %s"),
5605 bi->type == TYPE_SPACE ? ".space" :
5606 bi->type == TYPE_BES ? ".bes" : ".field");
5607 growth = 0;
5608 frag->tc_frag_data = frag->fr_fix = 0;
5609 return 0;
5612 if (bi->type == TYPE_FIELD)
5614 /* Bit fields of 16 or larger will have already been handled. */
5615 if (bit_offset != 0 && available >= size)
5617 char *p = prev_frag->fr_literal;
5619 valueT value = bi->value;
5620 value <<= available - size;
5621 value |= ((unsigned short) p[1] << 8) | p[0];
5622 md_number_to_chars (p, value, 2);
5623 if ((prev_frag->tc_frag_data += size) == 16)
5624 prev_frag->tc_frag_data = 0;
5625 if (bi->sym)
5626 symbol_set_frag (bi->sym, prev_frag);
5627 /* This frag is no longer used. */
5628 growth = -frag->fr_fix;
5629 frag->fr_fix = 0;
5630 frag->tc_frag_data = 0;
5632 else
5634 char *p = frag->fr_literal;
5636 valueT value = bi->value << (16 - size);
5637 md_number_to_chars (p, value, 2);
5638 if ((frag->tc_frag_data = size) == 16)
5639 frag->tc_frag_data = 0;
5640 growth = 0;
5643 else
5645 if (bit_offset != 0 && bit_offset < 16)
5647 if (available >= size)
5649 if ((prev_frag->tc_frag_data += size) == 16)
5650 prev_frag->tc_frag_data = 0;
5651 if (bi->sym)
5652 symbol_set_frag (bi->sym, prev_frag);
5653 /* This frag is no longer used. */
5654 growth = -frag->fr_fix;
5655 frag->fr_fix = 0;
5656 frag->tc_frag_data = 0;
5657 goto getout;
5659 if (bi->type == TYPE_SPACE && bi->sym)
5660 symbol_set_frag (bi->sym, prev_frag);
5661 size -= available;
5663 growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
5664 for (i = 0; i < growth; i++)
5665 frag->fr_literal[i] = 0;
5666 frag->fr_fix = growth;
5667 frag->tc_frag_data = size % 16;
5668 /* Make sure any BES label points to the LAST word allocated. */
5669 if (bi->type == TYPE_BES && bi->sym)
5670 S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
5672 getout:
5673 frag->fr_symbol = 0;
5674 frag->fr_opcode = 0;
5675 free ((void *) bi);
5677 return growth;
5680 void
5681 tic54x_convert_frag (abfd, seg, frag)
5682 bfd *abfd ATTRIBUTE_UNUSED;
5683 segT seg ATTRIBUTE_UNUSED;
5684 fragS *frag;
5686 /* Offset is in bytes. */
5687 frag->fr_offset = (frag->fr_next->fr_address
5688 - frag->fr_address
5689 - frag->fr_fix) / frag->fr_var;
5690 if (frag->fr_offset < 0)
5692 as_bad_where (frag->fr_file, frag->fr_line,
5693 _("attempt to .space/.bes backwards? (%ld)"),
5694 (long) frag->fr_offset);
5696 frag->fr_type = rs_space;
5699 /* We need to avoid having labels defined for certain directives/pseudo-ops
5700 since once the label is defined, it's in the symbol table for good. TI
5701 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5702 I guess, except I've never seen a definition of MRI syntax).
5704 C is the character that used to be at *REST, which points to the end of the
5705 label.
5707 Don't allow labels to start with '.' */
5710 tic54x_start_label (c, rest)
5711 int c;
5712 char *rest;
5714 /* If within .struct/.union, no auto line labels, please. */
5715 if (current_stag != NULL)
5716 return 0;
5718 /* Disallow labels starting with "." */
5719 if (c != ':')
5721 char *label = rest;
5723 while (!is_end_of_line[(int) label[-1]])
5724 --label;
5725 if (*label == '.')
5727 as_bad (_("Invalid label '%s'"), label);
5728 return 0;
5732 if (is_end_of_line[(int) c])
5733 return 1;
5735 if (ISSPACE (c))
5736 while (ISSPACE (c = *++rest))
5738 if (c == '.')
5740 /* Don't let colon () define a label for any of these... */
5741 return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
5742 && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
5743 && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
5744 && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
5745 && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
5746 && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
5749 return 1;