]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-tic54x.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-tic54x.c
1 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
3 Contributed by Timothy Wall (twall@cygnus.com)
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 /* Texas Instruments TMS320C54X machine specific gas.
23 Written by Timothy Wall (twall@alum.mit.edu).
24
25 Valuable things to do:
26 Pipeline conflict warnings
27 We encode/decode "ld #_label, dp" differently in relocatable files
28 This means we're not compatible with TI output containing those
29 expressions. We store the upper nine bits; TI stores the lower nine
30 bits. How they recover the original upper nine bits is beyond me.
31
32 Tests to add to expect testsuite:
33 '=' and '==' with .if, .elseif, and .break
34
35 Incompatibilities (mostly trivial):
36 We don't allow '''
37 We fill text section with zeroes instead of "nop"s
38 We don't convert '' or "" to a single instance
39 We don't convert '' to '\0'
40 We don't allow strings with .byte/.half/.short/.long
41 Probably details of the subsym stuff are different
42 TI sets labels to be data type 4 (T_INT); GAS uses T_NULL.
43
44 COFF1 limits section names to 8 characters.
45 Some of the default behavior changed from COFF1 to COFF2. */
46
47 #include "as.h"
48 #include <limits.h>
49 #include "safe-ctype.h"
50 #include "sb.h"
51 #include "macro.h"
52 #include "subsegs.h"
53 #include "opcode/tic54x.h"
54 #include "obj-coff.h"
55 #include <math.h>
56
57
58 static struct stag
59 {
60 symbolS *sym; /* Symbol for this stag; value is offset. */
61 const char *name; /* Shortcut to symbol name. */
62 bfd_vma size; /* Size of struct/union. */
63 int current_bitfield_offset; /* Temporary for tracking fields. */
64 int is_union;
65 struct stag_field /* List of fields. */
66 {
67 const char *name;
68 bfd_vma offset; /* Of start of this field. */
69 int bitfield_offset; /* Of start of this field. */
70 struct stag *stag; /* If field is struct/union. */
71 struct stag_field *next;
72 } *field;
73 /* For nesting; used only in stag construction. */
74 struct stag *inner; /* Enclosed .struct. */
75 struct stag *outer; /* Enclosing .struct. */
76 } *current_stag = NULL;
77
78 #define MAX_LINE 256 /* Lines longer than this are truncated by TI's asm. */
79
80 typedef struct _tic54x_insn
81 {
82 const insn_template *tm; /* Opcode template. */
83
84 char mnemonic[MAX_LINE]; /* Opcode name/mnemonic. */
85 char parmnemonic[MAX_LINE]; /* 2nd mnemonic of parallel insn. */
86
87 int opcount;
88 struct opstruct
89 {
90 char buf[MAX_LINE];
91 enum optype type;
92 expressionS exp;
93 } operands[MAX_OPERANDS];
94
95 int paropcount;
96 struct opstruct paroperands[MAX_OPERANDS];
97
98 int is_lkaddr;
99 int lkoperand;
100 int words; /* Size of insn in 16-bit words. */
101 int using_default_dst; /* Do we need to explicitly set an
102 omitted OP_DST operand? */
103 struct
104 {
105 unsigned short word; /* Final encoded opcode data. */
106 int unresolved;
107 int r_nchars; /* Relocation size. */
108 bfd_reloc_code_real_type r_type; /* Relocation type. */
109 expressionS addr_expr; /* Storage for unresolved expressions. */
110 } opcode[3];
111 } tic54x_insn;
112
113 enum cpu_version
114 {
115 VNONE = 0, V541 = 1, V542 = 2, V543 = 3, V545 = 5, V548 = 8, V549 = 9,
116 V545LP = 15, V546LP = 16
117 };
118
119 enum address_mode
120 {
121 c_mode, /* 16-bit addresses. */
122 far_mode /* >16-bit addresses. */
123 };
124
125 static segT stag_saved_seg;
126 static subsegT stag_saved_subseg;
127
128 const char comment_chars[] = ";";
129 const char line_comment_chars[] = ";*#"; /* At column zero only. */
130 const char line_separator_chars[] = ""; /* Not permitted. */
131
132 int emitting_long = 0;
133
134 /* Characters which indicate that this is a floating point constant. */
135 const char FLT_CHARS[] = "fF";
136
137 /* Characters that can be used to separate mantissa from exp in FP
138 nums. */
139 const char EXP_CHARS[] = "eE";
140
141 const char *md_shortopts = "";
142
143 #define OPTION_ADDRESS_MODE (OPTION_MD_BASE)
144 #define OPTION_CPU_VERSION (OPTION_ADDRESS_MODE + 1)
145 #define OPTION_COFF_VERSION (OPTION_CPU_VERSION + 1)
146 #define OPTION_STDERR_TO_FILE (OPTION_COFF_VERSION + 1)
147
148 struct option md_longopts[] =
149 {
150 { "mfar-mode", no_argument, NULL, OPTION_ADDRESS_MODE },
151 { "mf", no_argument, NULL, OPTION_ADDRESS_MODE },
152 { "mcpu", required_argument, NULL, OPTION_CPU_VERSION },
153 { "merrors-to-file", required_argument, NULL, OPTION_STDERR_TO_FILE },
154 { "me", required_argument, NULL, OPTION_STDERR_TO_FILE },
155 { NULL, no_argument, NULL, 0},
156 };
157
158 size_t md_longopts_size = sizeof (md_longopts);
159
160 static int assembly_begun = 0;
161 /* Addressing mode is not entirely implemented; the latest rev of the Other
162 assembler doesn't seem to make any distinction whatsoever; all relocations
163 are stored as extended relocations. Older versions used REL16 vs RELEXT16,
164 but now it seems all relocations are RELEXT16. We use all RELEXT16.
165
166 The cpu version is kind of a waste of time as well. There is one
167 instruction (RND) for LP devices only, and several for devices with
168 extended addressing only. We include it for compatibility. */
169 static enum address_mode amode = c_mode;
170 static enum cpu_version cpu = VNONE;
171
172 /* Include string substitutions in listing? */
173 static int listing_sslist = 0;
174
175 /* Did we do subsym substitutions on the line? */
176 static int substitution_line = 0;
177
178 /* Last label seen. */
179 static symbolS *last_label_seen = NULL;
180
181 /* This ensures that all new labels are unique. */
182 static int local_label_id;
183
184 static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. */
185 static struct hash_control *math_hash; /* Built-in math functions. */
186 /* Allow maximum levels of macro nesting; level 0 is the main substitution
187 symbol table. The other assembler only does 32 levels, so there! */
188 static struct hash_control *subsym_hash[100];
189
190 /* Keep track of local labels so we can substitute them before GAS sees them
191 since macros use their own 'namespace' for local labels, use a separate hash
192
193 We do our own local label handling 'cuz it's subtly different from the
194 stock GAS handling.
195
196 We use our own macro nesting counter, since GAS overloads it when expanding
197 other things (like conditionals and repeat loops). */
198 static int macro_level = 0;
199 static struct hash_control *local_label_hash[100];
200 /* Keep track of struct/union tags. */
201 static struct hash_control *stag_hash;
202 static struct hash_control *op_hash;
203 static struct hash_control *parop_hash;
204 static struct hash_control *reg_hash;
205 static struct hash_control *mmreg_hash;
206 static struct hash_control *cc_hash;
207 static struct hash_control *cc2_hash;
208 static struct hash_control *cc3_hash;
209 static struct hash_control *sbit_hash;
210 static struct hash_control *misc_symbol_hash;
211
212 /* Only word (et al.), align, or conditionals are allowed within
213 .struct/.union. */
214 #define ILLEGAL_WITHIN_STRUCT() \
215 do \
216 if (current_stag != NULL) \
217 { \
218 as_bad (_("pseudo-op illegal within .struct/.union")); \
219 return; \
220 } \
221 while (0)
222
223
224 static void subsym_create_or_replace (char *, char *);
225 static char *subsym_lookup (char *, int);
226 static char *subsym_substitute (char *, int);
227
228
229 void
230 md_show_usage (FILE *stream)
231 {
232 fprintf (stream, _("C54x-specific command line options:\n"));
233 fprintf (stream, _("-mfar-mode | -mf Use extended addressing\n"));
234 fprintf (stream, _("-mcpu=<CPU version> Specify the CPU version\n"));
235 fprintf (stream, _("-merrors-to-file <filename>\n"));
236 fprintf (stream, _("-me <filename> Redirect errors to a file\n"));
237 }
238
239 /* Output a single character (upper octet is zero). */
240
241 static void
242 tic54x_emit_char (char c)
243 {
244 expressionS expn;
245
246 expn.X_op = O_constant;
247 expn.X_add_number = c;
248 emit_expr (&expn, 2);
249 }
250
251 /* Walk backwards in the frag chain. */
252
253 static fragS *
254 frag_prev (fragS *frag, segT seg)
255 {
256 segment_info_type *seginfo = seg_info (seg);
257 fragS *fragp;
258
259 for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
260 if (fragp->fr_next == frag)
261 return fragp;
262
263 return NULL;
264 }
265
266 static fragS *
267 bit_offset_frag (fragS *frag, segT seg)
268 {
269 while (frag != NULL)
270 {
271 if (frag->fr_fix == 0
272 && frag->fr_opcode == NULL
273 && frag->tc_frag_data == 0)
274 frag = frag_prev (frag, seg);
275 else
276 return frag;
277 }
278 return NULL;
279 }
280
281 /* Return the number of bits allocated in the most recent word, or zero if
282 none. .field/.space/.bes may leave words partially allocated. */
283
284 static int
285 frag_bit_offset (fragS *frag, segT seg)
286 {
287 frag = bit_offset_frag (frag, seg);
288
289 if (frag)
290 return frag->fr_opcode != NULL ? -1 : frag->tc_frag_data;
291
292 return 0;
293 }
294
295 /* Read an expression from a C string; returns a pointer past the end of the
296 expression. */
297
298 static char *
299 parse_expression (char *str, expressionS *expn)
300 {
301 char *s;
302 char *tmp;
303
304 tmp = input_line_pointer; /* Save line pointer. */
305 input_line_pointer = str;
306 expression (expn);
307 s = input_line_pointer;
308 input_line_pointer = tmp; /* Restore line pointer. */
309 return s; /* Return pointer to where parsing stopped. */
310 }
311
312 /* .asg "character-string"|character-string, symbol
313
314 .eval is the only pseudo-op allowed to perform arithmetic on substitution
315 symbols. all other use of symbols defined with .asg are currently
316 unsupported. */
317
318 static void
319 tic54x_asg (int x ATTRIBUTE_UNUSED)
320 {
321 int c;
322 char *name;
323 char *str;
324 int quoted = *input_line_pointer == '"';
325
326 ILLEGAL_WITHIN_STRUCT ();
327
328 if (quoted)
329 {
330 int len;
331 str = demand_copy_C_string (&len);
332 c = *input_line_pointer;
333 }
334 else
335 {
336 str = input_line_pointer;
337 while ((c = *input_line_pointer) != ',')
338 {
339 if (is_end_of_line[(int) *input_line_pointer])
340 break;
341 ++input_line_pointer;
342 }
343 *input_line_pointer = 0;
344 }
345 if (c != ',')
346 {
347 as_bad (_("Comma and symbol expected for '.asg STRING, SYMBOL'"));
348 ignore_rest_of_line ();
349 return;
350 }
351
352 ++input_line_pointer;
353 c = get_symbol_name (&name); /* Get terminator. */
354 if (!ISALPHA (*name))
355 {
356 as_bad (_("symbols assigned with .asg must begin with a letter"));
357 ignore_rest_of_line ();
358 return;
359 }
360
361 str = xstrdup (str);
362 name = xstrdup (name);
363 subsym_create_or_replace (name, str);
364 (void) restore_line_pointer (c);
365 demand_empty_rest_of_line ();
366 }
367
368 /* .eval expression, symbol
369 There's something screwy about this. The other assembler sometimes does and
370 sometimes doesn't substitute symbols defined with .eval.
371 We'll put the symbols into the subsym table as well as the normal symbol
372 table, since that's what works best. */
373
374 static void
375 tic54x_eval (int x ATTRIBUTE_UNUSED)
376 {
377 char c;
378 int value;
379 char *name;
380 symbolS *symbolP;
381 char valuestr[32], *tmp;
382 int quoted;
383
384 ILLEGAL_WITHIN_STRUCT ();
385
386 SKIP_WHITESPACE ();
387
388 quoted = *input_line_pointer == '"';
389 if (quoted)
390 ++input_line_pointer;
391 value = get_absolute_expression ();
392 if (quoted)
393 {
394 if (*input_line_pointer != '"')
395 {
396 as_bad (_("Unterminated string after absolute expression"));
397 ignore_rest_of_line ();
398 return;
399 }
400 ++input_line_pointer;
401 }
402 if (*input_line_pointer++ != ',')
403 {
404 as_bad (_("Comma and symbol expected for '.eval EXPR, SYMBOL'"));
405 ignore_rest_of_line ();
406 return;
407 }
408 c = get_symbol_name (&name); /* Get terminator. */
409 name = xstrdup (name);
410 (void) restore_line_pointer (c);
411
412 if (!ISALPHA (*name))
413 {
414 as_bad (_("symbols assigned with .eval must begin with a letter"));
415 ignore_rest_of_line ();
416 return;
417 }
418 symbolP = symbol_new (name, absolute_section,
419 (valueT) value, &zero_address_frag);
420 SF_SET_LOCAL (symbolP);
421 symbol_table_insert (symbolP);
422
423 /* The "other" assembler sometimes doesn't put .eval's in the subsym table
424 But since there's not written rule as to when, don't even bother trying
425 to match their behavior. */
426 sprintf (valuestr, "%d", value);
427 tmp = xstrdup (valuestr);
428 subsym_create_or_replace (name, tmp);
429
430 demand_empty_rest_of_line ();
431 }
432
433 /* .bss symbol, size [, [blocking flag] [, alignment flag]
434
435 alignment is to a longword boundary; blocking is to 128-word boundary.
436
437 1) if there is a hole in memory, this directive should attempt to fill it
438 (not yet implemented).
439
440 2) if the blocking flag is not set, allocate at the current SPC
441 otherwise, check to see if the current SPC plus the space to be
442 allocated crosses the page boundary (128 words).
443 if there's not enough space, create a hole and align with the next page
444 boundary.
445 (not yet implemented). */
446
447 static void
448 tic54x_bss (int x ATTRIBUTE_UNUSED)
449 {
450 char c;
451 char *name;
452 char *p;
453 int words;
454 segT current_seg;
455 subsegT current_subseg;
456 symbolS *symbolP;
457 int block = 0;
458 int align = 0;
459
460 ILLEGAL_WITHIN_STRUCT ();
461
462 current_seg = now_seg; /* Save current seg. */
463 current_subseg = now_subseg; /* Save current subseg. */
464
465 c = get_symbol_name (&name); /* Get terminator. */
466 if (c == '"')
467 c = * ++ input_line_pointer;
468 if (c != ',')
469 {
470 as_bad (_(".bss size argument missing\n"));
471 ignore_rest_of_line ();
472 return;
473 }
474
475 ++input_line_pointer;
476 words = get_absolute_expression ();
477 if (words < 0)
478 {
479 as_bad (_(".bss size %d < 0!"), words);
480 ignore_rest_of_line ();
481 return;
482 }
483
484 if (*input_line_pointer == ',')
485 {
486 /* The blocking flag may be missing. */
487 ++input_line_pointer;
488 if (*input_line_pointer != ',')
489 block = get_absolute_expression ();
490 else
491 block = 0;
492
493 if (*input_line_pointer == ',')
494 {
495 ++input_line_pointer;
496 align = get_absolute_expression ();
497 }
498 else
499 align = 0;
500 }
501 else
502 block = align = 0;
503
504 subseg_set (bss_section, 0);
505 symbolP = symbol_find_or_make (name);
506
507 if (S_GET_SEGMENT (symbolP) == bss_section)
508 symbol_get_frag (symbolP)->fr_symbol = (symbolS *) NULL;
509
510 symbol_set_frag (symbolP, frag_now);
511 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
512 (offsetT) (words * OCTETS_PER_BYTE), (char *) 0);
513 *p = 0; /* Fill char. */
514
515 S_SET_SEGMENT (symbolP, bss_section);
516
517 /* The symbol may already have been created with a preceding
518 ".globl" directive -- be careful not to step on storage class
519 in that case. Otherwise, set it to static. */
520 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
521 S_SET_STORAGE_CLASS (symbolP, C_STAT);
522
523 if (align)
524 {
525 /* s_align eats end of line; restore it */
526 s_align_bytes (4);
527 --input_line_pointer;
528 }
529
530 if (block)
531 bss_section->flags |= SEC_TIC54X_BLOCK;
532
533 subseg_set (current_seg, current_subseg); /* Restore current seg. */
534 demand_empty_rest_of_line ();
535 }
536
537 static void
538 stag_add_field_symbols (struct stag *stag,
539 const char *path,
540 bfd_vma base_offset,
541 symbolS *rootsym,
542 const char *root_stag_name)
543 {
544 char * prefix;
545 struct stag_field *field = stag->field;
546
547 /* Construct a symbol for every field contained within this structure
548 including fields within structure fields. */
549 prefix = concat (path, *path ? "." : "", NULL);
550
551 while (field != NULL)
552 {
553 char *name = concat (prefix, field->name, NULL);
554
555 if (rootsym == NULL)
556 {
557 symbolS *sym;
558 sym = symbol_new (name, absolute_section,
559 (field->stag ? field->offset :
560 (valueT) (base_offset + field->offset)),
561 &zero_address_frag);
562 SF_SET_LOCAL (sym);
563 symbol_table_insert (sym);
564 }
565 else
566 {
567 char *replacement;
568
569 replacement = concat (S_GET_NAME (rootsym), "+", root_stag_name,
570 name + strlen (S_GET_NAME (rootsym)), NULL);
571 hash_insert (subsym_hash[0], name, replacement);
572 }
573
574 /* Recurse if the field is a structure.
575 Note the field offset is relative to the outermost struct. */
576 if (field->stag != NULL)
577 stag_add_field_symbols (field->stag, name,
578 field->offset,
579 rootsym, root_stag_name);
580 field = field->next;
581 free (name);
582 }
583 free (prefix);
584 }
585
586 /* Keep track of stag fields so that when structures are nested we can add the
587 complete dereferencing symbols to the symbol table. */
588
589 static void
590 stag_add_field (struct stag *parent,
591 const char *name,
592 bfd_vma offset,
593 struct stag *stag)
594 {
595 struct stag_field *sfield = XCNEW (struct stag_field);
596
597 sfield->name = xstrdup (name);
598 sfield->offset = offset;
599 sfield->bitfield_offset = parent->current_bitfield_offset;
600 sfield->stag = stag;
601 if (parent->field == NULL)
602 parent->field = sfield;
603 else
604 {
605 struct stag_field *sf = parent->field;
606 while (sf->next != NULL)
607 sf = sf->next;
608 sf->next = sfield;
609 }
610 /* Only create a symbol for this field if the parent has no name. */
611 if (!strncmp (".fake", parent->name, 5))
612 {
613 symbolS *sym = symbol_new (name, absolute_section,
614 (valueT) offset, &zero_address_frag);
615 SF_SET_LOCAL (sym);
616 symbol_table_insert (sym);
617 }
618 }
619
620 /* [STAG] .struct [OFFSET]
621 Start defining structure offsets (symbols in absolute section). */
622
623 static void
624 tic54x_struct (int arg)
625 {
626 int start_offset = 0;
627 int is_union = arg;
628
629 if (!current_stag)
630 {
631 /* Starting a new struct, switch to absolute section. */
632 stag_saved_seg = now_seg;
633 stag_saved_subseg = now_subseg;
634 subseg_set (absolute_section, 0);
635 }
636 /* Align the current pointer. */
637 else if (current_stag->current_bitfield_offset != 0)
638 {
639 ++abs_section_offset;
640 current_stag->current_bitfield_offset = 0;
641 }
642
643 /* Offset expression is only meaningful for global .structs. */
644 if (!is_union)
645 {
646 /* Offset is ignored in inner structs. */
647 SKIP_WHITESPACE ();
648 if (!is_end_of_line[(int) *input_line_pointer])
649 start_offset = get_absolute_expression ();
650 else
651 start_offset = 0;
652 }
653
654 if (current_stag)
655 {
656 /* Nesting, link to outer one. */
657 current_stag->inner = XCNEW (struct stag);
658 current_stag->inner->outer = current_stag;
659 current_stag = current_stag->inner;
660 if (start_offset)
661 as_warn (_("Offset on nested structures is ignored"));
662 start_offset = abs_section_offset;
663 }
664 else
665 {
666 current_stag = XCNEW (struct stag);
667 abs_section_offset = start_offset;
668 }
669 current_stag->is_union = is_union;
670
671 if (line_label == NULL)
672 {
673 static int struct_count = 0;
674 char fake[] = ".fake_stagNNNNNNN";
675 sprintf (fake, ".fake_stag%d", struct_count++);
676 current_stag->sym = symbol_new (fake, absolute_section,
677 (valueT) abs_section_offset,
678 &zero_address_frag);
679 }
680 else
681 {
682 char * label = xstrdup (S_GET_NAME (line_label));
683 current_stag->sym = symbol_new (label,
684 absolute_section,
685 (valueT) abs_section_offset,
686 &zero_address_frag);
687 free (label);
688 }
689 current_stag->name = S_GET_NAME (current_stag->sym);
690 SF_SET_LOCAL (current_stag->sym);
691 /* Nested .structs don't go into the symbol table. */
692 if (current_stag->outer == NULL)
693 symbol_table_insert (current_stag->sym);
694
695 line_label = NULL;
696 }
697
698 /* [LABEL] .endstruct
699 finish defining structure offsets; optional LABEL's value will be the size
700 of the structure. */
701
702 static void
703 tic54x_endstruct (int is_union)
704 {
705 int size;
706 const char *path =
707 !strncmp (current_stag->name, ".fake", 5) ? "" : current_stag->name;
708
709 if (!current_stag || current_stag->is_union != is_union)
710 {
711 as_bad (_(".end%s without preceding .%s"),
712 is_union ? "union" : "struct",
713 is_union ? "union" : "struct");
714 ignore_rest_of_line ();
715 return;
716 }
717
718 /* Align end of structures. */
719 if (current_stag->current_bitfield_offset)
720 {
721 ++abs_section_offset;
722 current_stag->current_bitfield_offset = 0;
723 }
724
725 if (current_stag->is_union)
726 size = current_stag->size;
727 else
728 size = abs_section_offset - S_GET_VALUE (current_stag->sym);
729 if (line_label != NULL)
730 {
731 S_SET_VALUE (line_label, size);
732 symbol_table_insert (line_label);
733 line_label = NULL;
734 }
735
736 /* Union size has already been calculated. */
737 if (!current_stag->is_union)
738 current_stag->size = size;
739 /* Nested .structs don't get put in the stag table. */
740 if (current_stag->outer == NULL)
741 {
742 hash_insert (stag_hash, current_stag->name, current_stag);
743 stag_add_field_symbols (current_stag, path,
744 S_GET_VALUE (current_stag->sym),
745 NULL, NULL);
746 }
747 current_stag = current_stag->outer;
748
749 /* If this is a nested .struct/.union, add it as a field to the enclosing
750 one. otherwise, restore the section we were in. */
751 if (current_stag != NULL)
752 {
753 stag_add_field (current_stag, current_stag->inner->name,
754 S_GET_VALUE (current_stag->inner->sym),
755 current_stag->inner);
756 }
757 else
758 subseg_set (stag_saved_seg, stag_saved_subseg);
759 }
760
761 /* [LABEL] .tag STAG
762 Reference a structure within a structure, as a sized field with an optional
763 label.
764 If used outside of a .struct/.endstruct, overlays the given structure
765 format on the existing allocated space. */
766
767 static void
768 tic54x_tag (int ignore ATTRIBUTE_UNUSED)
769 {
770 char *name;
771 int c = get_symbol_name (&name);
772 struct stag *stag = (struct stag *) hash_find (stag_hash, name);
773
774 if (!stag)
775 {
776 if (*name)
777 as_bad (_("Unrecognized struct/union tag '%s'"), name);
778 else
779 as_bad (_(".tag requires a structure tag"));
780 ignore_rest_of_line ();
781 return;
782 }
783 if (line_label == NULL)
784 {
785 as_bad (_("Label required for .tag"));
786 ignore_rest_of_line ();
787 return;
788 }
789 else
790 {
791 char * label;
792
793 label = xstrdup (S_GET_NAME (line_label));
794 if (current_stag != NULL)
795 stag_add_field (current_stag, label,
796 abs_section_offset - S_GET_VALUE (current_stag->sym),
797 stag);
798 else
799 {
800 symbolS *sym = symbol_find (label);
801
802 if (!sym)
803 {
804 as_bad (_(".tag target '%s' undefined"), label);
805 ignore_rest_of_line ();
806 free (label);
807 return;
808 }
809 stag_add_field_symbols (stag, S_GET_NAME (sym),
810 S_GET_VALUE (stag->sym), sym, stag->name);
811 }
812 free (label);
813 }
814
815 /* Bump by the struct size, but only if we're within a .struct section. */
816 if (current_stag != NULL && !current_stag->is_union)
817 abs_section_offset += stag->size;
818
819 (void) restore_line_pointer (c);
820 demand_empty_rest_of_line ();
821 line_label = NULL;
822 }
823
824 /* Handle all .byte, .char, .double, .field, .float, .half, .int, .long,
825 .short, .string, .ubyte, .uchar, .uhalf, .uint, .ulong, .ushort, .uword,
826 and .word. */
827
828 static void
829 tic54x_struct_field (int type)
830 {
831 int size;
832 int count = 1;
833 int new_bitfield_offset = 0;
834 int field_align = current_stag->current_bitfield_offset != 0;
835 int longword_align = 0;
836
837 SKIP_WHITESPACE ();
838 if (!is_end_of_line[(int) *input_line_pointer])
839 count = get_absolute_expression ();
840
841 switch (type)
842 {
843 case 'b':
844 case 'B':
845 case 'c':
846 case 'C':
847 case 'h':
848 case 'H':
849 case 'i':
850 case 'I':
851 case 's':
852 case 'S':
853 case 'w':
854 case 'W':
855 case '*': /* String. */
856 size = 1;
857 break;
858 case 'f':
859 case 'l':
860 case 'L':
861 longword_align = 1;
862 size = 2;
863 break;
864 case '.': /* Bitfield. */
865 size = 0;
866 if (count < 1 || count > 32)
867 {
868 as_bad (_(".field count '%d' out of range (1 <= X <= 32)"), count);
869 ignore_rest_of_line ();
870 return;
871 }
872 if (current_stag->current_bitfield_offset + count > 16)
873 {
874 /* Set the appropriate size and new field offset. */
875 if (count == 32)
876 {
877 size = 2;
878 count = 1;
879 }
880 else if (count > 16)
881 {
882 size = 1;
883 count = 1;
884 new_bitfield_offset = count - 16;
885 }
886 else
887 new_bitfield_offset = count;
888 }
889 else
890 {
891 field_align = 0;
892 new_bitfield_offset = current_stag->current_bitfield_offset + count;
893 }
894 break;
895 default:
896 as_bad (_("Unrecognized field type '%c'"), type);
897 ignore_rest_of_line ();
898 return;
899 }
900
901 if (field_align)
902 {
903 /* Align to the actual starting position of the field. */
904 current_stag->current_bitfield_offset = 0;
905 ++abs_section_offset;
906 }
907 /* Align to longword boundary. */
908 if (longword_align && (abs_section_offset & 0x1))
909 ++abs_section_offset;
910
911 if (line_label == NULL)
912 {
913 static int fieldno = 0;
914 char fake[] = ".fake_fieldNNNNN";
915
916 sprintf (fake, ".fake_field%d", fieldno++);
917 stag_add_field (current_stag, fake,
918 abs_section_offset - S_GET_VALUE (current_stag->sym),
919 NULL);
920 }
921 else
922 {
923 char * label;
924
925 label = xstrdup (S_GET_NAME (line_label));
926 stag_add_field (current_stag, label,
927 abs_section_offset - S_GET_VALUE (current_stag->sym),
928 NULL);
929 free (label);
930 }
931
932 if (current_stag->is_union)
933 {
934 /* Note we treat the element as if it were an array of COUNT. */
935 if (current_stag->size < (unsigned) size * count)
936 current_stag->size = size * count;
937 }
938 else
939 {
940 abs_section_offset += (unsigned) size * count;
941 current_stag->current_bitfield_offset = new_bitfield_offset;
942 }
943 line_label = NULL;
944 }
945
946 /* Handle .byte, .word. .int, .long and all variants. */
947
948 static void
949 tic54x_cons (int type)
950 {
951 unsigned int c;
952 int octets;
953
954 /* If we're within a .struct construct, don't actually allocate space. */
955 if (current_stag != NULL)
956 {
957 tic54x_struct_field (type);
958 return;
959 }
960
961 #ifdef md_flush_pending_output
962 md_flush_pending_output ();
963 #endif
964
965 generate_lineno_debug ();
966
967 /* Align long words to long word boundaries (4 octets). */
968 if (type == 'l' || type == 'L')
969 {
970 frag_align (2, 0, 2);
971 /* If there's a label, assign it to the first allocated word. */
972 if (line_label != NULL)
973 {
974 symbol_set_frag (line_label, frag_now);
975 S_SET_VALUE (line_label, frag_now_fix ());
976 }
977 }
978
979 switch (type)
980 {
981 case 'l':
982 case 'L':
983 case 'x':
984 octets = 4;
985 break;
986 case 'b':
987 case 'B':
988 case 'c':
989 case 'C':
990 octets = 1;
991 break;
992 default:
993 octets = 2;
994 break;
995 }
996
997 do
998 {
999 if (*input_line_pointer == '"')
1000 {
1001 input_line_pointer++;
1002 while (is_a_char (c = next_char_of_string ()))
1003 tic54x_emit_char (c);
1004 know (input_line_pointer[-1] == '\"');
1005 }
1006 else
1007 {
1008 expressionS expn;
1009
1010 input_line_pointer = parse_expression (input_line_pointer, &expn);
1011 if (expn.X_op == O_constant)
1012 {
1013 offsetT value = expn.X_add_number;
1014 /* Truncate overflows. */
1015 switch (octets)
1016 {
1017 case 1:
1018 if ((value > 0 && value > 0xFF)
1019 || (value < 0 && value < - 0x100))
1020 as_warn (_("Overflow in expression, truncated to 8 bits"));
1021 break;
1022 case 2:
1023 if ((value > 0 && value > 0xFFFF)
1024 || (value < 0 && value < - 0x10000))
1025 as_warn (_("Overflow in expression, truncated to 16 bits"));
1026 break;
1027 }
1028 }
1029 if (expn.X_op != O_constant && octets < 2)
1030 {
1031 /* Disallow .byte with a non constant expression that will
1032 require relocation. */
1033 as_bad (_("Relocatable values require at least WORD storage"));
1034 ignore_rest_of_line ();
1035 return;
1036 }
1037
1038 if (expn.X_op != O_constant
1039 && amode == c_mode
1040 && octets == 4)
1041 {
1042 /* FIXME -- at one point TI tools used to output REL16
1043 relocations, but I don't think the latest tools do at all
1044 The current tools output extended relocations regardless of
1045 the addressing mode (I actually think that ".c_mode" is
1046 totally ignored in the latest tools). */
1047 amode = far_mode;
1048 emitting_long = 1;
1049 emit_expr (&expn, 4);
1050 emitting_long = 0;
1051 amode = c_mode;
1052 }
1053 else
1054 {
1055 emitting_long = octets == 4;
1056 emit_expr (&expn, (octets == 1) ? 2 : octets);
1057 emitting_long = 0;
1058 }
1059 }
1060 }
1061 while (*input_line_pointer++ == ',');
1062
1063 input_line_pointer--; /* Put terminator back into stream. */
1064 demand_empty_rest_of_line ();
1065 }
1066
1067 /* .global <symbol>[,...,<symbolN>]
1068 .def <symbol>[,...,<symbolN>]
1069 .ref <symbol>[,...,<symbolN>]
1070
1071 These all identify global symbols.
1072
1073 .def means the symbol is defined in the current module and can be accessed
1074 by other files. The symbol should be placed in the symbol table.
1075
1076 .ref means the symbol is used in the current module but defined in another
1077 module. The linker is to resolve this symbol's definition at link time.
1078
1079 .global should act as a .ref or .def, as needed.
1080
1081 global, def and ref all have symbol storage classes of C_EXT.
1082
1083 I can't identify any difference in how the "other" c54x assembler treats
1084 these, so we ignore the type here. */
1085
1086 void
1087 tic54x_global (int type)
1088 {
1089 char *name;
1090 int c;
1091 symbolS *symbolP;
1092
1093 if (type == 'r')
1094 as_warn (_("Use of .def/.ref is deprecated. Use .global instead"));
1095
1096 ILLEGAL_WITHIN_STRUCT ();
1097
1098 do
1099 {
1100 c = get_symbol_name (&name);
1101 symbolP = symbol_find_or_make (name);
1102 c = restore_line_pointer (c);
1103
1104 S_SET_STORAGE_CLASS (symbolP, C_EXT);
1105 if (c == ',')
1106 {
1107 input_line_pointer++;
1108 if (is_end_of_line[(int) *input_line_pointer])
1109 c = *input_line_pointer;
1110 }
1111 }
1112 while (c == ',');
1113
1114 demand_empty_rest_of_line ();
1115 }
1116
1117 /* Remove the symbol from the local label hash lookup. */
1118
1119 static void
1120 tic54x_remove_local_label (const char *key, void *value ATTRIBUTE_UNUSED)
1121 {
1122 void *elem = hash_delete (local_label_hash[macro_level], key, FALSE);
1123 free (elem);
1124 }
1125
1126 /* Reset all local labels. */
1127
1128 static void
1129 tic54x_clear_local_labels (int ignored ATTRIBUTE_UNUSED)
1130 {
1131 hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);
1132 }
1133
1134 /* .text
1135 .data
1136 .sect "section name"
1137
1138 Initialized section
1139 make sure local labels get cleared when changing sections
1140
1141 ARG is 't' for text, 'd' for data, or '*' for a named section
1142
1143 For compatibility, '*' sections are SEC_CODE if instructions are
1144 encountered, or SEC_DATA if not.
1145 */
1146
1147 static void
1148 tic54x_sect (int arg)
1149 {
1150 ILLEGAL_WITHIN_STRUCT ();
1151
1152 /* Local labels are cleared when changing sections. */
1153 tic54x_clear_local_labels (0);
1154
1155 if (arg == 't')
1156 s_text (0);
1157 else if (arg == 'd')
1158 s_data (0);
1159 else
1160 {
1161 char *name = NULL;
1162 int len;
1163 /* Make sure all named initialized sections flagged properly. If we
1164 encounter instructions, we'll flag it with SEC_CODE as well. */
1165 const char *flags = ",\"w\"\n";
1166
1167 /* If there are quotes, remove them. */
1168 if (*input_line_pointer == '"')
1169 {
1170 name = demand_copy_C_string (&len);
1171 demand_empty_rest_of_line ();
1172 name = concat (name, flags, (char *) NULL);
1173 }
1174 else
1175 {
1176 int c;
1177
1178 c = get_symbol_name (&name);
1179 name = concat (name, flags, (char *) NULL);
1180 (void) restore_line_pointer (c);
1181 demand_empty_rest_of_line ();
1182 }
1183
1184 input_scrub_insert_line (name);
1185 obj_coff_section (0);
1186
1187 /* If there was a line label, make sure that it gets assigned the proper
1188 section. This is for compatibility, even though the actual behavior
1189 is not explicitly defined. For consistency, we make .sect behave
1190 like .usect, since that is probably what people expect. */
1191 if (line_label != NULL)
1192 {
1193 S_SET_SEGMENT (line_label, now_seg);
1194 symbol_set_frag (line_label, frag_now);
1195 S_SET_VALUE (line_label, frag_now_fix ());
1196 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1197 S_SET_STORAGE_CLASS (line_label, C_LABEL);
1198 }
1199 }
1200 }
1201
1202 /* [symbol] .space space_in_bits
1203 [symbol] .bes space_in_bits
1204 BES puts the symbol at the *last* word allocated
1205
1206 cribbed from s_space. */
1207
1208 static void
1209 tic54x_space (int arg)
1210 {
1211 expressionS expn;
1212 char *p = 0;
1213 int octets = 0;
1214 long words;
1215 int bits_per_byte = (OCTETS_PER_BYTE * 8);
1216 int bit_offset = 0;
1217 symbolS *label = line_label;
1218 int bes = arg;
1219
1220 ILLEGAL_WITHIN_STRUCT ();
1221
1222 #ifdef md_flush_pending_output
1223 md_flush_pending_output ();
1224 #endif
1225
1226 /* Read the bit count. */
1227 expression (&expn);
1228
1229 /* Some expressions are unresolvable until later in the assembly pass;
1230 postpone until relaxation/fixup. we also have to postpone if a previous
1231 partial allocation has not been completed yet. */
1232 if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
1233 {
1234 struct bit_info *bi = XNEW (struct bit_info);
1235
1236 bi->seg = now_seg;
1237 bi->type = bes;
1238 bi->sym = label;
1239 p = frag_var (rs_machine_dependent,
1240 65536 * 2, 1, (relax_substateT) 0,
1241 make_expr_symbol (&expn), (offsetT) 0,
1242 (char *) bi);
1243 if (p)
1244 *p = 0;
1245
1246 return;
1247 }
1248
1249 /* Reduce the required size by any bit offsets currently left over
1250 from a previous .space/.bes/.field directive. */
1251 bit_offset = frag_now->tc_frag_data;
1252 if (bit_offset != 0 && bit_offset < 16)
1253 {
1254 int spare_bits = bits_per_byte - bit_offset;
1255
1256 if (spare_bits >= expn.X_add_number)
1257 {
1258 /* Don't have to do anything; sufficient bits have already been
1259 allocated; just point the label to the right place. */
1260 if (label != NULL)
1261 {
1262 symbol_set_frag (label, frag_now);
1263 S_SET_VALUE (label, frag_now_fix () - 1);
1264 label = NULL;
1265 }
1266 frag_now->tc_frag_data += expn.X_add_number;
1267 goto getout;
1268 }
1269 expn.X_add_number -= spare_bits;
1270 /* Set the label to point to the first word allocated, which in this
1271 case is the previous word, which was only partially filled. */
1272 if (!bes && label != NULL)
1273 {
1274 symbol_set_frag (label, frag_now);
1275 S_SET_VALUE (label, frag_now_fix () - 1);
1276 label = NULL;
1277 }
1278 }
1279 /* Convert bits to bytes/words and octets, rounding up. */
1280 words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
1281 /* How many do we have left over? */
1282 bit_offset = expn.X_add_number % bits_per_byte;
1283 octets = words * OCTETS_PER_BYTE;
1284 if (octets < 0)
1285 {
1286 as_warn (_(".space/.bes repeat count is negative, ignored"));
1287 goto getout;
1288 }
1289 else if (octets == 0)
1290 {
1291 as_warn (_(".space/.bes repeat count is zero, ignored"));
1292 goto getout;
1293 }
1294
1295 /* If we are in the absolute section, just bump the offset. */
1296 if (now_seg == absolute_section)
1297 {
1298 abs_section_offset += words;
1299 if (bes && label != NULL)
1300 S_SET_VALUE (label, abs_section_offset - 1);
1301 frag_now->tc_frag_data = bit_offset;
1302 goto getout;
1303 }
1304
1305 if (!need_pass_2)
1306 p = frag_var (rs_fill, 1, 1,
1307 (relax_substateT) 0, (symbolS *) 0,
1308 (offsetT) octets, (char *) 0);
1309
1310 /* Make note of how many bits of this word we've allocated so far. */
1311 frag_now->tc_frag_data = bit_offset;
1312
1313 /* .bes puts label at *last* word allocated. */
1314 if (bes && label != NULL)
1315 {
1316 symbol_set_frag (label, frag_now);
1317 S_SET_VALUE (label, frag_now_fix () - 1);
1318 }
1319
1320 if (p)
1321 *p = 0;
1322
1323 getout:
1324
1325 demand_empty_rest_of_line ();
1326 }
1327
1328 /* [symbol] .usect "section-name", size-in-words
1329 [, [blocking-flag] [, alignment-flag]]
1330
1331 Uninitialized section.
1332 Non-zero blocking means that if the section would cross a page (128-word)
1333 boundary, it will be page-aligned.
1334 Non-zero alignment aligns on a longword boundary.
1335
1336 Has no effect on the current section. */
1337
1338 static void
1339 tic54x_usect (int x ATTRIBUTE_UNUSED)
1340 {
1341 char c;
1342 char *name;
1343 char *section_name;
1344 char *p;
1345 segT seg;
1346 int size, blocking_flag, alignment_flag;
1347 segT current_seg;
1348 subsegT current_subseg;
1349 flagword flags;
1350
1351 ILLEGAL_WITHIN_STRUCT ();
1352
1353 current_seg = now_seg; /* Save current seg. */
1354 current_subseg = now_subseg; /* Save current subseg. */
1355
1356 c = get_symbol_name (&section_name); /* Get terminator. */
1357 name = xstrdup (section_name);
1358 c = restore_line_pointer (c);
1359
1360 if (c == ',')
1361 ++input_line_pointer;
1362 else
1363 {
1364 as_bad (_("Missing size argument"));
1365 ignore_rest_of_line ();
1366 return;
1367 }
1368
1369 size = get_absolute_expression ();
1370
1371 /* Read a possibly present third argument (blocking flag). */
1372 if (*input_line_pointer == ',')
1373 {
1374 ++input_line_pointer;
1375 if (*input_line_pointer != ',')
1376 blocking_flag = get_absolute_expression ();
1377 else
1378 blocking_flag = 0;
1379
1380 /* Read a possibly present fourth argument (alignment flag). */
1381 if (*input_line_pointer == ',')
1382 {
1383 ++input_line_pointer;
1384 alignment_flag = get_absolute_expression ();
1385 }
1386 else
1387 alignment_flag = 0;
1388 }
1389 else
1390 blocking_flag = alignment_flag = 0;
1391
1392 seg = subseg_new (name, 0);
1393 flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC;
1394
1395 if (alignment_flag)
1396 {
1397 /* s_align eats end of line; restore it. */
1398 s_align_bytes (4);
1399 --input_line_pointer;
1400 }
1401
1402 if (line_label != NULL)
1403 {
1404 S_SET_SEGMENT (line_label, seg);
1405 symbol_set_frag (line_label, frag_now);
1406 S_SET_VALUE (line_label, frag_now_fix ());
1407 /* Set scl to label, since that's what TI does. */
1408 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1409 S_SET_STORAGE_CLASS (line_label, C_LABEL);
1410 }
1411
1412 seg_info (seg)->bss = 1; /* Uninitialized data. */
1413
1414 p = frag_var (rs_fill, 1, 1,
1415 (relax_substateT) 0, (symbolS *) line_label,
1416 size * OCTETS_PER_BYTE, (char *) 0);
1417 *p = 0;
1418
1419 if (blocking_flag)
1420 flags |= SEC_TIC54X_BLOCK;
1421
1422 if (!bfd_set_section_flags (stdoutput, seg, flags))
1423 as_warn (_("Error setting flags for \"%s\": %s"), name,
1424 bfd_errmsg (bfd_get_error ()));
1425
1426 subseg_set (current_seg, current_subseg); /* Restore current seg. */
1427 demand_empty_rest_of_line ();
1428 }
1429
1430 static enum cpu_version
1431 lookup_version (const char *ver)
1432 {
1433 enum cpu_version version = VNONE;
1434
1435 if (ver[0] == '5' && ver[1] == '4')
1436 {
1437 if (strlen (ver) == 3
1438 && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3'
1439 || ver[2] == '5' || ver[2] == '8' || ver[2] == '9'))
1440 version = ver[2] - '0';
1441 else if (strlen (ver) == 5
1442 && TOUPPER (ver[3]) == 'L'
1443 && TOUPPER (ver[4]) == 'P'
1444 && (ver[2] == '5' || ver[2] == '6'))
1445 version = ver[2] - '0' + 10;
1446 }
1447
1448 return version;
1449 }
1450
1451 static void
1452 set_cpu (enum cpu_version version)
1453 {
1454 cpu = version;
1455 if (version == V545LP || version == V546LP)
1456 {
1457 symbolS *symbolP = symbol_new ("__allow_lp", absolute_section,
1458 (valueT) 1, &zero_address_frag);
1459 SF_SET_LOCAL (symbolP);
1460 symbol_table_insert (symbolP);
1461 }
1462 }
1463
1464 /* .version cpu-version
1465 cpu-version may be one of the following:
1466 541
1467 542
1468 543
1469 545
1470 545LP
1471 546LP
1472 548
1473 549
1474
1475 This is for compatibility only. It currently has no affect on assembly. */
1476 static int cpu_needs_set = 1;
1477
1478 static void
1479 tic54x_version (int x ATTRIBUTE_UNUSED)
1480 {
1481 enum cpu_version version = VNONE;
1482 enum cpu_version old_version = cpu;
1483 int c;
1484 char *ver;
1485
1486 ILLEGAL_WITHIN_STRUCT ();
1487
1488 SKIP_WHITESPACE ();
1489 ver = input_line_pointer;
1490 while (!is_end_of_line[(int) *input_line_pointer])
1491 ++input_line_pointer;
1492 c = *input_line_pointer;
1493 *input_line_pointer = 0;
1494
1495 version = lookup_version (ver);
1496
1497 if (cpu != VNONE && cpu != version)
1498 as_warn (_("CPU version has already been set"));
1499
1500 if (version == VNONE)
1501 {
1502 as_bad (_("Unrecognized version '%s'"), ver);
1503 ignore_rest_of_line ();
1504 return;
1505 }
1506 else if (assembly_begun && version != old_version)
1507 {
1508 as_bad (_("Changing of CPU version on the fly not supported"));
1509 ignore_rest_of_line ();
1510 return;
1511 }
1512
1513 set_cpu (version);
1514
1515 *input_line_pointer = c;
1516 demand_empty_rest_of_line ();
1517 }
1518
1519 /* 'f' = float, 'x' = xfloat, 'd' = double, 'l' = ldouble. */
1520
1521 static void
1522 tic54x_float_cons (int type)
1523 {
1524 if (current_stag != 0)
1525 tic54x_struct_field ('f');
1526
1527 #ifdef md_flush_pending_output
1528 md_flush_pending_output ();
1529 #endif
1530
1531 /* Align to long word boundary (4 octets) unless it's ".xfloat". */
1532 if (type != 'x')
1533 {
1534 frag_align (2, 0, 2);
1535 /* If there's a label, assign it to the first allocated word. */
1536 if (line_label != NULL)
1537 {
1538 symbol_set_frag (line_label, frag_now);
1539 S_SET_VALUE (line_label, frag_now_fix ());
1540 }
1541 }
1542
1543 float_cons ('f');
1544 }
1545
1546 /* The argument is capitalized if it should be zero-terminated
1547 's' is normal string with upper 8-bits zero-filled, 'p' is packed.
1548 Code copied from stringer, and slightly modified so that strings are packed
1549 and encoded into the correct octets. */
1550
1551 static void
1552 tic54x_stringer (int type)
1553 {
1554 unsigned int c;
1555 int append_zero = type == 'S' || type == 'P';
1556 int packed = type == 'p' || type == 'P';
1557 int last_char = -1; /* Packed strings need two bytes at a time to encode. */
1558
1559 if (current_stag != NULL)
1560 {
1561 tic54x_struct_field ('*');
1562 return;
1563 }
1564
1565 #ifdef md_flush_pending_output
1566 md_flush_pending_output ();
1567 #endif
1568
1569 c = ','; /* Do loop. */
1570 while (c == ',')
1571 {
1572 SKIP_WHITESPACE ();
1573 switch (*input_line_pointer)
1574 {
1575 default:
1576 {
1577 unsigned short value = get_absolute_expression ();
1578 FRAG_APPEND_1_CHAR ( value & 0xFF);
1579 FRAG_APPEND_1_CHAR ((value >> 8) & 0xFF);
1580 break;
1581 }
1582 case '\"':
1583 ++input_line_pointer; /* -> 1st char of string. */
1584 while (is_a_char (c = next_char_of_string ()))
1585 {
1586 if (!packed)
1587 {
1588 FRAG_APPEND_1_CHAR (c);
1589 FRAG_APPEND_1_CHAR (0);
1590 }
1591 else
1592 {
1593 /* Packed strings are filled MS octet first. */
1594 if (last_char == -1)
1595 last_char = c;
1596 else
1597 {
1598 FRAG_APPEND_1_CHAR (c);
1599 FRAG_APPEND_1_CHAR (last_char);
1600 last_char = -1;
1601 }
1602 }
1603 }
1604 if (append_zero)
1605 {
1606 if (packed && last_char != -1)
1607 {
1608 FRAG_APPEND_1_CHAR (0);
1609 FRAG_APPEND_1_CHAR (last_char);
1610 last_char = -1;
1611 }
1612 else
1613 {
1614 FRAG_APPEND_1_CHAR (0);
1615 FRAG_APPEND_1_CHAR (0);
1616 }
1617 }
1618 know (input_line_pointer[-1] == '\"');
1619 break;
1620 }
1621 SKIP_WHITESPACE ();
1622 c = *input_line_pointer;
1623 if (!is_end_of_line[c])
1624 ++input_line_pointer;
1625 }
1626
1627 /* Finish up any leftover packed string. */
1628 if (packed && last_char != -1)
1629 {
1630 FRAG_APPEND_1_CHAR (0);
1631 FRAG_APPEND_1_CHAR (last_char);
1632 }
1633 demand_empty_rest_of_line ();
1634 }
1635
1636 static void
1637 tic54x_p2align (int arg ATTRIBUTE_UNUSED)
1638 {
1639 as_bad (_("p2align not supported on this target"));
1640 }
1641
1642 static void
1643 tic54x_align_words (int arg)
1644 {
1645 /* Only ".align" with no argument is allowed within .struct/.union. */
1646 int count = arg;
1647
1648 if (!is_end_of_line[(int) *input_line_pointer])
1649 {
1650 if (arg == 2)
1651 as_warn (_("Argument to .even ignored"));
1652 else
1653 count = get_absolute_expression ();
1654 }
1655
1656 if (current_stag != NULL && arg == 128)
1657 {
1658 if (current_stag->current_bitfield_offset != 0)
1659 {
1660 current_stag->current_bitfield_offset = 0;
1661 ++abs_section_offset;
1662 }
1663 demand_empty_rest_of_line ();
1664 return;
1665 }
1666
1667 ILLEGAL_WITHIN_STRUCT ();
1668
1669 s_align_bytes (count << 1);
1670 }
1671
1672 /* Initialize multiple-bit fields within a single word of memory. */
1673
1674 static void
1675 tic54x_field (int ignore ATTRIBUTE_UNUSED)
1676 {
1677 expressionS expn;
1678 int size = 16;
1679 char *p;
1680 valueT value;
1681 symbolS *label = line_label;
1682
1683 if (current_stag != NULL)
1684 {
1685 tic54x_struct_field ('.');
1686 return;
1687 }
1688
1689 input_line_pointer = parse_expression (input_line_pointer, &expn);
1690
1691 if (*input_line_pointer == ',')
1692 {
1693 ++input_line_pointer;
1694 size = get_absolute_expression ();
1695 if (size < 1 || size > 32)
1696 {
1697 as_bad (_("Invalid field size, must be from 1 to 32"));
1698 ignore_rest_of_line ();
1699 return;
1700 }
1701 }
1702
1703 /* Truncate values to the field width. */
1704 if (expn.X_op != O_constant)
1705 {
1706 /* If the expression value is relocatable, the field size *must*
1707 be 16. */
1708 if (size != 16)
1709 {
1710 as_bad (_("field size must be 16 when value is relocatable"));
1711 ignore_rest_of_line ();
1712 return;
1713 }
1714
1715 frag_now->tc_frag_data = 0;
1716 emit_expr (&expn, 2);
1717 }
1718 else
1719 {
1720 unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
1721
1722 value = expn.X_add_number;
1723 expn.X_add_number &= fmask;
1724 if (value != (valueT) expn.X_add_number)
1725 as_warn (_("field value truncated"));
1726 value = expn.X_add_number;
1727 /* Bits are stored MS first. */
1728 while (size >= 16)
1729 {
1730 frag_now->tc_frag_data = 0;
1731 p = frag_more (2);
1732 md_number_to_chars (p, (value >> (size - 16)) & 0xFFFF, 2);
1733 size -= 16;
1734 }
1735 if (size > 0)
1736 {
1737 int bit_offset = frag_bit_offset (frag_now, now_seg);
1738
1739 fragS *alloc_frag = bit_offset_frag (frag_now, now_seg);
1740 if (bit_offset == -1)
1741 {
1742 struct bit_info *bi = XNEW (struct bit_info);
1743 /* We don't know the previous offset at this time, so store the
1744 info we need and figure it out later. */
1745 expressionS size_exp;
1746
1747 size_exp.X_op = O_constant;
1748 size_exp.X_add_number = size;
1749 bi->seg = now_seg;
1750 bi->type = TYPE_FIELD;
1751 bi->value = value;
1752 p = frag_var (rs_machine_dependent,
1753 4, 1, (relax_substateT) 0,
1754 make_expr_symbol (&size_exp), (offsetT) 0,
1755 (char *) bi);
1756 goto getout;
1757 }
1758 else if (bit_offset == 0 || bit_offset + size > 16)
1759 {
1760 /* Align a new field. */
1761 p = frag_more (2);
1762 frag_now->tc_frag_data = 0;
1763 alloc_frag = frag_now;
1764 }
1765 else
1766 {
1767 /* Put the new value entirely within the existing one. */
1768 p = alloc_frag == frag_now ?
1769 frag_now->fr_literal + frag_now_fix_octets () - 2 :
1770 alloc_frag->fr_literal;
1771 if (label != NULL)
1772 {
1773 symbol_set_frag (label, alloc_frag);
1774 if (alloc_frag == frag_now)
1775 S_SET_VALUE (label, frag_now_fix () - 1);
1776 label = NULL;
1777 }
1778 }
1779 value <<= 16 - alloc_frag->tc_frag_data - size;
1780
1781 /* OR in existing value. */
1782 if (alloc_frag->tc_frag_data)
1783 value |= ((unsigned short) p[1] << 8) | p[0];
1784 md_number_to_chars (p, value, 2);
1785 alloc_frag->tc_frag_data += size;
1786 if (alloc_frag->tc_frag_data == 16)
1787 alloc_frag->tc_frag_data = 0;
1788 }
1789 }
1790 getout:
1791 demand_empty_rest_of_line ();
1792 }
1793
1794 /* Ideally, we want to check SEC_LOAD and SEC_HAS_CONTENTS, but those aren't
1795 available yet. seg_info ()->bss is the next best thing. */
1796
1797 static int
1798 tic54x_initialized_section (segT seg)
1799 {
1800 return !seg_info (seg)->bss;
1801 }
1802
1803 /* .clink ["section name"]
1804
1805 Marks the section as conditionally linked (link only if contents are
1806 referenced elsewhere.
1807 Without a name, refers to the current initialized section.
1808 Name is required for uninitialized sections. */
1809
1810 static void
1811 tic54x_clink (int ignored ATTRIBUTE_UNUSED)
1812 {
1813 segT seg = now_seg;
1814
1815 ILLEGAL_WITHIN_STRUCT ();
1816
1817 if (*input_line_pointer == '\"')
1818 {
1819 char *section_name = ++input_line_pointer;
1820 char *name;
1821
1822 while (is_a_char (next_char_of_string ()))
1823 ;
1824 know (input_line_pointer[-1] == '\"');
1825 input_line_pointer[-1] = 0;
1826 name = xstrdup (section_name);
1827
1828 seg = bfd_get_section_by_name (stdoutput, name);
1829 if (seg == NULL)
1830 {
1831 as_bad (_("Unrecognized section '%s'"), section_name);
1832 ignore_rest_of_line ();
1833 return;
1834 }
1835 }
1836 else
1837 {
1838 if (!tic54x_initialized_section (seg))
1839 {
1840 as_bad (_("Current section is uninitialized, "
1841 "section name required for .clink"));
1842 ignore_rest_of_line ();
1843 return;
1844 }
1845 }
1846
1847 seg->flags |= SEC_TIC54X_CLINK;
1848
1849 demand_empty_rest_of_line ();
1850 }
1851
1852 /* Change the default include directory to be the current source file's
1853 directory, instead of the current working directory. If DOT is non-zero,
1854 set to "." instead. */
1855
1856 static void
1857 tic54x_set_default_include (void)
1858 {
1859 char *dir, *tmp = NULL;
1860 const char *curfile;
1861 unsigned lineno;
1862
1863 curfile = as_where (&lineno);
1864 dir = xstrdup (curfile);
1865 tmp = strrchr (dir, '/');
1866 if (tmp != NULL)
1867 {
1868 int len;
1869
1870 *tmp = '\0';
1871 len = strlen (dir);
1872 if (include_dir_count == 0)
1873 {
1874 include_dirs = XNEWVEC (const char *, 1);
1875 include_dir_count = 1;
1876 }
1877 include_dirs[0] = dir;
1878 if (len > include_dir_maxlen)
1879 include_dir_maxlen = len;
1880 }
1881 else if (include_dirs != NULL)
1882 include_dirs[0] = ".";
1883 }
1884
1885 /* .include "filename" | filename
1886 .copy "filename" | filename
1887
1888 FIXME 'include' file should be omitted from any output listing,
1889 'copy' should be included in any output listing
1890 FIXME -- prevent any included files from changing listing (compat only)
1891 FIXME -- need to include source file directory in search path; what's a
1892 good way to do this?
1893
1894 Entering/exiting included/copied file clears all local labels. */
1895
1896 static void
1897 tic54x_include (int ignored ATTRIBUTE_UNUSED)
1898 {
1899 char newblock[] = " .newblock\n";
1900 char *filename;
1901 char *input;
1902 int len, c = -1;
1903
1904 ILLEGAL_WITHIN_STRUCT ();
1905
1906 SKIP_WHITESPACE ();
1907
1908 if (*input_line_pointer == '"')
1909 {
1910 filename = demand_copy_C_string (&len);
1911 demand_empty_rest_of_line ();
1912 }
1913 else
1914 {
1915 filename = input_line_pointer;
1916 while (!is_end_of_line[(int) *input_line_pointer])
1917 ++input_line_pointer;
1918 c = *input_line_pointer;
1919 *input_line_pointer = '\0';
1920 filename = xstrdup (filename);
1921 *input_line_pointer = c;
1922 demand_empty_rest_of_line ();
1923 }
1924 /* Insert a partial line with the filename (for the sake of s_include)
1925 and a .newblock.
1926 The included file will be inserted before the newblock, so that the
1927 newblock is executed after the included file is processed. */
1928 input = concat ("\"", filename, "\"\n", newblock, (char *) NULL);
1929 input_scrub_insert_line (input);
1930
1931 tic54x_clear_local_labels (0);
1932
1933 tic54x_set_default_include ();
1934
1935 s_include (0);
1936 }
1937
1938 static void
1939 tic54x_message (int type)
1940 {
1941 char *msg;
1942 char c;
1943 int len;
1944
1945 ILLEGAL_WITHIN_STRUCT ();
1946
1947 if (*input_line_pointer == '"')
1948 msg = demand_copy_C_string (&len);
1949 else
1950 {
1951 msg = input_line_pointer;
1952 while (!is_end_of_line[(int) *input_line_pointer])
1953 ++input_line_pointer;
1954 c = *input_line_pointer;
1955 *input_line_pointer = 0;
1956 msg = xstrdup (msg);
1957 *input_line_pointer = c;
1958 }
1959
1960 switch (type)
1961 {
1962 case 'm':
1963 as_tsktsk ("%s", msg);
1964 break;
1965 case 'w':
1966 as_warn ("%s", msg);
1967 break;
1968 case 'e':
1969 as_bad ("%s", msg);
1970 break;
1971 }
1972
1973 demand_empty_rest_of_line ();
1974 }
1975
1976 /* .label <symbol>
1977 Define a special symbol that refers to the loadtime address rather than the
1978 runtime address within the current section.
1979
1980 This symbol gets a special storage class so that when it is resolved, it is
1981 resolved relative to the load address (lma) of the section rather than the
1982 run address (vma). */
1983
1984 static void
1985 tic54x_label (int ignored ATTRIBUTE_UNUSED)
1986 {
1987 char *name;
1988 symbolS *symbolP;
1989 int c;
1990
1991 ILLEGAL_WITHIN_STRUCT ();
1992
1993 c = get_symbol_name (&name);
1994 symbolP = colon (name);
1995 S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
1996
1997 (void) restore_line_pointer (c);
1998 demand_empty_rest_of_line ();
1999 }
2000
2001 /* .mmregs
2002 Install all memory-mapped register names into the symbol table as
2003 absolute local symbols. */
2004
2005 static void
2006 tic54x_mmregs (int ignored ATTRIBUTE_UNUSED)
2007 {
2008 tic54x_symbol *sym;
2009
2010 ILLEGAL_WITHIN_STRUCT ();
2011
2012 for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
2013 {
2014 symbolS *symbolP = symbol_new (sym->name, absolute_section,
2015 (valueT) sym->value, &zero_address_frag);
2016 SF_SET_LOCAL (symbolP);
2017 symbol_table_insert (symbolP);
2018 }
2019 }
2020
2021 /* .loop [count]
2022 Count defaults to 1024. */
2023
2024 static void
2025 tic54x_loop (int count)
2026 {
2027 ILLEGAL_WITHIN_STRUCT ();
2028
2029 SKIP_WHITESPACE ();
2030 if (!is_end_of_line[(int) *input_line_pointer])
2031 count = get_absolute_expression ();
2032
2033 do_repeat ((size_t) count, "LOOP", "ENDLOOP");
2034 }
2035
2036 /* Normally, endloop gets eaten by the preceding loop. */
2037
2038 static void
2039 tic54x_endloop (int ignore ATTRIBUTE_UNUSED)
2040 {
2041 as_bad (_("ENDLOOP without corresponding LOOP"));
2042 ignore_rest_of_line ();
2043 }
2044
2045 /* .break [condition]. */
2046
2047 static void
2048 tic54x_break (int ignore ATTRIBUTE_UNUSED)
2049 {
2050 int cond = 1;
2051
2052 ILLEGAL_WITHIN_STRUCT ();
2053
2054 SKIP_WHITESPACE ();
2055 if (!is_end_of_line[(int) *input_line_pointer])
2056 cond = get_absolute_expression ();
2057
2058 if (cond)
2059 end_repeat (substitution_line ? 1 : 0);
2060 }
2061
2062 static void
2063 set_address_mode (int mode)
2064 {
2065 amode = mode;
2066 if (mode == far_mode)
2067 {
2068 symbolS *symbolP = symbol_new ("__allow_far", absolute_section,
2069 (valueT) 1, &zero_address_frag);
2070 SF_SET_LOCAL (symbolP);
2071 symbol_table_insert (symbolP);
2072 }
2073 }
2074
2075 static int address_mode_needs_set = 1;
2076
2077 static void
2078 tic54x_address_mode (int mode)
2079 {
2080 if (assembly_begun && amode != (unsigned) mode)
2081 {
2082 as_bad (_("Mixing of normal and extended addressing not supported"));
2083 ignore_rest_of_line ();
2084 return;
2085 }
2086 if (mode == far_mode && cpu != VNONE && cpu != V548 && cpu != V549)
2087 {
2088 as_bad (_("Extended addressing not supported on the specified CPU"));
2089 ignore_rest_of_line ();
2090 return;
2091 }
2092
2093 set_address_mode (mode);
2094 demand_empty_rest_of_line ();
2095 }
2096
2097 /* .sblock "section"|section [,...,"section"|section]
2098 Designate initialized sections for blocking. */
2099
2100 static void
2101 tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
2102 {
2103 int c = ',';
2104
2105 ILLEGAL_WITHIN_STRUCT ();
2106
2107 while (c == ',')
2108 {
2109 segT seg;
2110 char *name;
2111
2112 if (*input_line_pointer == '"')
2113 {
2114 int len;
2115
2116 name = demand_copy_C_string (&len);
2117 }
2118 else
2119 {
2120 char *section_name;
2121
2122 c = get_symbol_name (&section_name);
2123 name = xstrdup (section_name);
2124 (void) restore_line_pointer (c);
2125 }
2126
2127 seg = bfd_get_section_by_name (stdoutput, name);
2128 if (seg == NULL)
2129 {
2130 as_bad (_("Unrecognized section '%s'"), name);
2131 ignore_rest_of_line ();
2132 return;
2133 }
2134 else if (!tic54x_initialized_section (seg))
2135 {
2136 as_bad (_(".sblock may be used for initialized sections only"));
2137 ignore_rest_of_line ();
2138 return;
2139 }
2140 seg->flags |= SEC_TIC54X_BLOCK;
2141
2142 c = *input_line_pointer;
2143 if (!is_end_of_line[(int) c])
2144 ++input_line_pointer;
2145 }
2146
2147 demand_empty_rest_of_line ();
2148 }
2149
2150 /* symbol .set value
2151 symbol .equ value
2152
2153 value must be defined externals; no forward-referencing allowed
2154 symbols assigned with .set/.equ may not be redefined. */
2155
2156 static void
2157 tic54x_set (int ignore ATTRIBUTE_UNUSED)
2158 {
2159 symbolS *symbolP;
2160 char *name;
2161
2162 ILLEGAL_WITHIN_STRUCT ();
2163
2164 if (!line_label)
2165 {
2166 as_bad (_("Symbol missing for .set/.equ"));
2167 ignore_rest_of_line ();
2168 return;
2169 }
2170 name = xstrdup (S_GET_NAME (line_label));
2171 line_label = NULL;
2172 if ((symbolP = symbol_find (name)) == NULL
2173 && (symbolP = md_undefined_symbol (name)) == NULL)
2174 {
2175 symbolP = symbol_new (name, absolute_section, 0, &zero_address_frag);
2176 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2177 }
2178 free (name);
2179 S_SET_DATA_TYPE (symbolP, T_INT);
2180 S_SET_SEGMENT (symbolP, absolute_section);
2181 symbol_table_insert (symbolP);
2182 pseudo_set (symbolP);
2183 demand_empty_rest_of_line ();
2184 }
2185
2186 /* .fclist
2187 .fcnolist
2188 List false conditional blocks. */
2189
2190 static void
2191 tic54x_fclist (int show)
2192 {
2193 if (show)
2194 listing &= ~LISTING_NOCOND;
2195 else
2196 listing |= LISTING_NOCOND;
2197 demand_empty_rest_of_line ();
2198 }
2199
2200 static void
2201 tic54x_sslist (int show)
2202 {
2203 ILLEGAL_WITHIN_STRUCT ();
2204
2205 listing_sslist = show;
2206 }
2207
2208 /* .var SYM[,...,SYMN]
2209 Define a substitution string to be local to a macro. */
2210
2211 static void
2212 tic54x_var (int ignore ATTRIBUTE_UNUSED)
2213 {
2214 static char empty[] = "";
2215 char *name;
2216 int c;
2217
2218 ILLEGAL_WITHIN_STRUCT ();
2219
2220 if (macro_level == 0)
2221 {
2222 as_bad (_(".var may only be used within a macro definition"));
2223 ignore_rest_of_line ();
2224 return;
2225 }
2226 do
2227 {
2228 if (!ISALPHA (*input_line_pointer))
2229 {
2230 as_bad (_("Substitution symbols must begin with a letter"));
2231 ignore_rest_of_line ();
2232 return;
2233 }
2234 c = get_symbol_name (&name);
2235 /* .var symbols start out with a null string. */
2236 name = xstrdup (name);
2237 hash_insert (subsym_hash[macro_level], name, empty);
2238 c = restore_line_pointer (c);
2239 if (c == ',')
2240 {
2241 ++input_line_pointer;
2242 if (is_end_of_line[(int) *input_line_pointer])
2243 c = *input_line_pointer;
2244 }
2245 }
2246 while (c == ',');
2247
2248 demand_empty_rest_of_line ();
2249 }
2250
2251 /* .mlib <macro library filename>
2252
2253 Macro libraries are archived (standard AR-format) text macro definitions
2254 Expand the file and include it.
2255
2256 FIXME need to try the source file directory as well. */
2257
2258 static void
2259 tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
2260 {
2261 char *filename;
2262 char *path;
2263 int len, i;
2264 bfd *abfd, *mbfd;
2265
2266 ILLEGAL_WITHIN_STRUCT ();
2267
2268 /* Parse the filename. */
2269 if (*input_line_pointer == '"')
2270 {
2271 if ((filename = demand_copy_C_string (&len)) == NULL)
2272 return;
2273 }
2274 else
2275 {
2276 SKIP_WHITESPACE ();
2277 len = 0;
2278 while (!is_end_of_line[(int) *input_line_pointer]
2279 && !ISSPACE (*input_line_pointer))
2280 {
2281 obstack_1grow (&notes, *input_line_pointer);
2282 ++input_line_pointer;
2283 ++len;
2284 }
2285 obstack_1grow (&notes, '\0');
2286 filename = obstack_finish (&notes);
2287 }
2288 demand_empty_rest_of_line ();
2289
2290 tic54x_set_default_include ();
2291 path = XNEWVEC (char, (unsigned long) len + include_dir_maxlen + 5);
2292
2293 for (i = 0; i < include_dir_count; i++)
2294 {
2295 FILE *try;
2296
2297 strcpy (path, include_dirs[i]);
2298 strcat (path, "/");
2299 strcat (path, filename);
2300 if ((try = fopen (path, "r")) != NULL)
2301 {
2302 fclose (try);
2303 break;
2304 }
2305 }
2306
2307 if (i >= include_dir_count)
2308 {
2309 free (path);
2310 path = filename;
2311 }
2312
2313 /* FIXME: if path is found, malloc'd storage is not freed. Of course, this
2314 happens all over the place, and since the assembler doesn't usually keep
2315 running for a very long time, it really doesn't matter. */
2316 register_dependency (path);
2317
2318 /* Expand all archive entries to temporary files and include them. */
2319 abfd = bfd_openr (path, NULL);
2320 if (!abfd)
2321 {
2322 as_bad (_("can't open macro library file '%s' for reading: %s"),
2323 path, bfd_errmsg (bfd_get_error ()));
2324 ignore_rest_of_line ();
2325 return;
2326 }
2327 if (!bfd_check_format (abfd, bfd_archive))
2328 {
2329 as_bad (_("File '%s' not in macro archive format"), path);
2330 ignore_rest_of_line ();
2331 return;
2332 }
2333
2334 /* Open each BFD as binary (it should be straight ASCII text). */
2335 for (mbfd = bfd_openr_next_archived_file (abfd, NULL);
2336 mbfd != NULL; mbfd = bfd_openr_next_archived_file (abfd, mbfd))
2337 {
2338 /* Get a size at least as big as the archive member. */
2339 bfd_size_type size = bfd_get_size (mbfd);
2340 char *buf = XNEWVEC (char, size);
2341 char *fname = tmpnam (NULL);
2342 FILE *ftmp;
2343
2344 /* We're not sure how big it is, but it will be smaller than "size". */
2345 size = bfd_bread (buf, size, mbfd);
2346
2347 /* Write to a temporary file, then use s_include to include it
2348 a bit of a hack. */
2349 ftmp = fopen (fname, "w+b");
2350 fwrite ((void *) buf, size, 1, ftmp);
2351 if (size == 0 || buf[size - 1] != '\n')
2352 fwrite ("\n", 1, 1, ftmp);
2353 fclose (ftmp);
2354 free (buf);
2355 input_scrub_insert_file (fname);
2356 unlink (fname);
2357 }
2358 }
2359
2360 const pseudo_typeS md_pseudo_table[] =
2361 {
2362 { "algebraic", s_ignore , 0 },
2363 { "align" , tic54x_align_words , 128 },
2364 { "ascii" , tic54x_stringer , 'p' },
2365 { "asciz" , tic54x_stringer , 'P' },
2366 { "even" , tic54x_align_words , 2 },
2367 { "asg" , tic54x_asg , 0 },
2368 { "eval" , tic54x_eval , 0 },
2369 { "bss" , tic54x_bss , 0 },
2370 { "byte" , tic54x_cons , 'b' },
2371 { "ubyte" , tic54x_cons , 'B' },
2372 { "char" , tic54x_cons , 'c' },
2373 { "uchar" , tic54x_cons , 'C' },
2374 { "clink" , tic54x_clink , 0 },
2375 { "c_mode" , tic54x_address_mode , c_mode },
2376 { "copy" , tic54x_include , 'c' },
2377 { "include" , tic54x_include , 'i' },
2378 { "data" , tic54x_sect , 'd' },
2379 { "double" , tic54x_float_cons , 'd' },
2380 { "ldouble" , tic54x_float_cons , 'l' },
2381 { "drlist" , s_ignore , 0 },
2382 { "drnolist" , s_ignore , 0 },
2383 { "emsg" , tic54x_message , 'e' },
2384 { "mmsg" , tic54x_message , 'm' },
2385 { "wmsg" , tic54x_message , 'w' },
2386 { "far_mode" , tic54x_address_mode , far_mode },
2387 { "fclist" , tic54x_fclist , 1 },
2388 { "fcnolist" , tic54x_fclist , 0 },
2389 { "field" , tic54x_field , -1 },
2390 { "float" , tic54x_float_cons , 'f' },
2391 { "xfloat" , tic54x_float_cons , 'x' },
2392 { "global" , tic54x_global , 'g' },
2393 { "def" , tic54x_global , 'd' },
2394 { "ref" , tic54x_global , 'r' },
2395 { "half" , tic54x_cons , 'h' },
2396 { "uhalf" , tic54x_cons , 'H' },
2397 { "short" , tic54x_cons , 's' },
2398 { "ushort" , tic54x_cons , 'S' },
2399 { "if" , s_if , (int) O_ne },
2400 { "elseif" , s_elseif , (int) O_ne },
2401 { "else" , s_else , 0 },
2402 { "endif" , s_endif , 0 },
2403 { "int" , tic54x_cons , 'i' },
2404 { "uint" , tic54x_cons , 'I' },
2405 { "word" , tic54x_cons , 'w' },
2406 { "uword" , tic54x_cons , 'W' },
2407 { "label" , tic54x_label , 0 }, /* Loadtime
2408 address. */
2409 { "length" , s_ignore , 0 },
2410 { "width" , s_ignore , 0 },
2411 { "long" , tic54x_cons , 'l' },
2412 { "ulong" , tic54x_cons , 'L' },
2413 { "xlong" , tic54x_cons , 'x' },
2414 { "loop" , tic54x_loop , 1024 },
2415 { "break" , tic54x_break , 0 },
2416 { "endloop" , tic54x_endloop , 0 },
2417 { "mlib" , tic54x_mlib , 0 },
2418 { "mlist" , s_ignore , 0 },
2419 { "mnolist" , s_ignore , 0 },
2420 { "mmregs" , tic54x_mmregs , 0 },
2421 { "newblock" , tic54x_clear_local_labels, 0 },
2422 { "option" , s_ignore , 0 },
2423 { "p2align" , tic54x_p2align , 0 },
2424 { "sblock" , tic54x_sblock , 0 },
2425 { "sect" , tic54x_sect , '*' },
2426 { "set" , tic54x_set , 0 },
2427 { "equ" , tic54x_set , 0 },
2428 { "space" , tic54x_space , 0 },
2429 { "bes" , tic54x_space , 1 },
2430 { "sslist" , tic54x_sslist , 1 },
2431 { "ssnolist" , tic54x_sslist , 0 },
2432 { "string" , tic54x_stringer , 's' },
2433 { "pstring" , tic54x_stringer , 'p' },
2434 { "struct" , tic54x_struct , 0 },
2435 { "tag" , tic54x_tag , 0 },
2436 { "endstruct", tic54x_endstruct , 0 },
2437 { "tab" , s_ignore , 0 },
2438 { "text" , tic54x_sect , 't' },
2439 { "union" , tic54x_struct , 1 },
2440 { "endunion" , tic54x_endstruct , 1 },
2441 { "usect" , tic54x_usect , 0 },
2442 { "var" , tic54x_var , 0 },
2443 { "version" , tic54x_version , 0 },
2444 {0 , 0 , 0 }
2445 };
2446
2447 int
2448 md_parse_option (int c, const char *arg)
2449 {
2450 switch (c)
2451 {
2452 default:
2453 return 0;
2454 case OPTION_COFF_VERSION:
2455 {
2456 int version = atoi (arg);
2457
2458 if (version != 0 && version != 1 && version != 2)
2459 as_fatal (_("Bad COFF version '%s'"), arg);
2460 /* FIXME -- not yet implemented. */
2461 break;
2462 }
2463 case OPTION_CPU_VERSION:
2464 {
2465 cpu = lookup_version (arg);
2466 cpu_needs_set = 1;
2467 if (cpu == VNONE)
2468 as_fatal (_("Bad CPU version '%s'"), arg);
2469 break;
2470 }
2471 case OPTION_ADDRESS_MODE:
2472 amode = far_mode;
2473 address_mode_needs_set = 1;
2474 break;
2475 case OPTION_STDERR_TO_FILE:
2476 {
2477 const char *filename = arg;
2478 FILE *fp = fopen (filename, "w+");
2479
2480 if (fp == NULL)
2481 as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2482 fclose (fp);
2483 if ((fp = freopen (filename, "w+", stderr)) == NULL)
2484 as_fatal (_("Can't redirect stderr to the file '%s'"), filename);
2485 break;
2486 }
2487 }
2488
2489 return 1;
2490 }
2491
2492 /* Create a "local" substitution string hash table for a new macro level
2493 Some docs imply that macros have to use .newblock in order to be able
2494 to re-use a local label. We effectively do an automatic .newblock by
2495 deleting the local label hash between macro invocations. */
2496
2497 void
2498 tic54x_macro_start (void)
2499 {
2500 ++macro_level;
2501 subsym_hash[macro_level] = hash_new ();
2502 local_label_hash[macro_level] = hash_new ();
2503 }
2504
2505 void
2506 tic54x_macro_info (const macro_entry *macro)
2507 {
2508 const formal_entry *entry;
2509
2510 /* Put the formal args into the substitution symbol table. */
2511 for (entry = macro->formals; entry; entry = entry->next)
2512 {
2513 char *name = xstrndup (entry->name.ptr, entry->name.len);
2514 char *value = xstrndup (entry->actual.ptr, entry->actual.len);
2515
2516 name[entry->name.len] = '\0';
2517 value[entry->actual.len] = '\0';
2518 hash_insert (subsym_hash[macro_level], name, value);
2519 }
2520 }
2521
2522 /* Get rid of this macro's .var's, arguments, and local labels. */
2523
2524 void
2525 tic54x_macro_end (void)
2526 {
2527 hash_die (subsym_hash[macro_level]);
2528 subsym_hash[macro_level] = NULL;
2529 hash_die (local_label_hash[macro_level]);
2530 local_label_hash[macro_level] = NULL;
2531 --macro_level;
2532 }
2533
2534 static int
2535 subsym_symlen (char *a, char *ignore ATTRIBUTE_UNUSED)
2536 {
2537 return strlen (a);
2538 }
2539
2540 /* Compare symbol A to string B. */
2541
2542 static int
2543 subsym_symcmp (char *a, char *b)
2544 {
2545 return strcmp (a, b);
2546 }
2547
2548 /* Return the index of the first occurrence of B in A, or zero if none
2549 assumes b is an integer char value as a string. Index is one-based. */
2550
2551 static int
2552 subsym_firstch (char *a, char *b)
2553 {
2554 int val = atoi (b);
2555 char *tmp = strchr (a, val);
2556
2557 return tmp ? tmp - a + 1 : 0;
2558 }
2559
2560 /* Similar to firstch, but returns index of last occurrence of B in A. */
2561
2562 static int
2563 subsym_lastch (char *a, char *b)
2564 {
2565 int val = atoi (b);
2566 char *tmp = strrchr (a, val);
2567
2568 return tmp ? tmp - a + 1 : 0;
2569 }
2570
2571 /* Returns 1 if string A is defined in the symbol table (NOT the substitution
2572 symbol table). */
2573
2574 static int
2575 subsym_isdefed (char *a, char *ignore ATTRIBUTE_UNUSED)
2576 {
2577 symbolS *symbolP = symbol_find (a);
2578
2579 return symbolP != NULL;
2580 }
2581
2582 /* Assign first member of comma-separated list B (e.g. "1,2,3") to the symbol
2583 A, or zero if B is a null string. Both arguments *must* be substitution
2584 symbols, unsubstituted. */
2585
2586 static int
2587 subsym_ismember (char *sym, char *list)
2588 {
2589 char *elem, *ptr, *listv;
2590
2591 if (!list)
2592 return 0;
2593
2594 listv = subsym_lookup (list, macro_level);
2595 if (!listv)
2596 {
2597 as_bad (_("Undefined substitution symbol '%s'"), list);
2598 ignore_rest_of_line ();
2599 return 0;
2600 }
2601
2602 ptr = elem = xstrdup (listv);
2603 while (*ptr && *ptr != ',')
2604 ++ptr;
2605 *ptr++ = 0;
2606
2607 subsym_create_or_replace (sym, elem);
2608
2609 /* Reassign the list. */
2610 subsym_create_or_replace (list, ptr);
2611
2612 /* Assume this value, docs aren't clear. */
2613 return *list != 0;
2614 }
2615
2616 /* Return zero if not a constant; otherwise:
2617 1 if binary
2618 2 if octal
2619 3 if hexadecimal
2620 4 if character
2621 5 if decimal. */
2622
2623 static int
2624 subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
2625 {
2626 expressionS expn;
2627
2628 parse_expression (a, &expn);
2629
2630 if (expn.X_op == O_constant)
2631 {
2632 int len = strlen (a);
2633
2634 switch (TOUPPER (a[len - 1]))
2635 {
2636 case 'B':
2637 return 1;
2638 case 'Q':
2639 return 2;
2640 case 'H':
2641 return 3;
2642 case '\'':
2643 return 4;
2644 default:
2645 break;
2646 }
2647 /* No suffix; either octal, hex, or decimal. */
2648 if (*a == '0' && len > 1)
2649 {
2650 if (TOUPPER (a[1]) == 'X')
2651 return 3;
2652 return 2;
2653 }
2654 return 5;
2655 }
2656
2657 return 0;
2658 }
2659
2660 /* Return 1 if A is a valid symbol name. Expects string input. */
2661
2662 static int
2663 subsym_isname (char *a, char *ignore ATTRIBUTE_UNUSED)
2664 {
2665 if (!is_name_beginner (*a))
2666 return 0;
2667 while (*a)
2668 {
2669 if (!is_part_of_name (*a))
2670 return 0;
2671 ++a;
2672 }
2673 return 1;
2674 }
2675
2676 /* Return whether the string is a register; accepts ar0-7, unless .mmregs has
2677 been seen; if so, recognize any memory-mapped register.
2678 Note this does not recognize "A" or "B" accumulators. */
2679
2680 static int
2681 subsym_isreg (char *a, char *ignore ATTRIBUTE_UNUSED)
2682 {
2683 if (hash_find (reg_hash, a))
2684 return 1;
2685 if (hash_find (mmreg_hash, a))
2686 return 1;
2687 return 0;
2688 }
2689
2690 /* Return the structure size, given the stag. */
2691
2692 static int
2693 subsym_structsz (char *name, char *ignore ATTRIBUTE_UNUSED)
2694 {
2695 struct stag *stag = (struct stag *) hash_find (stag_hash, name);
2696
2697 if (stag)
2698 return stag->size;
2699
2700 return 0;
2701 }
2702
2703 /* If anybody actually uses this, they can fix it :)
2704 FIXME I'm not sure what the "reference point" of a structure is. It might
2705 be either the initial offset given .struct, or it may be the offset of the
2706 structure within another structure, or it might be something else
2707 altogether. since the TI assembler doesn't seem to ever do anything but
2708 return zero, we punt and return zero. */
2709
2710 static int
2711 subsym_structacc (char *stag_name ATTRIBUTE_UNUSED,
2712 char *ignore ATTRIBUTE_UNUSED)
2713 {
2714 return 0;
2715 }
2716
2717 static float
2718 math_ceil (float arg1, float ignore ATTRIBUTE_UNUSED)
2719 {
2720 return (float) ceil (arg1);
2721 }
2722
2723 static float
2724 math_cvi (float arg1, float ignore ATTRIBUTE_UNUSED)
2725 {
2726 return (int) arg1;
2727 }
2728
2729 static float
2730 math_floor (float arg1, float ignore ATTRIBUTE_UNUSED)
2731 {
2732 return (float) floor (arg1);
2733 }
2734
2735 static float
2736 math_fmod (float arg1, float arg2)
2737 {
2738 return (int) arg1 % (int) arg2;
2739 }
2740
2741 static float
2742 math_int (float arg1, float ignore ATTRIBUTE_UNUSED)
2743 {
2744 return ((float) ((int) arg1)) == arg1;
2745 }
2746
2747 static float
2748 math_round (float arg1, float ignore ATTRIBUTE_UNUSED)
2749 {
2750 return arg1 > 0 ? (int) (arg1 + 0.5) : (int) (arg1 - 0.5);
2751 }
2752
2753 static float
2754 math_sgn (float arg1, float ignore ATTRIBUTE_UNUSED)
2755 {
2756 return (arg1 < 0) ? -1 : (arg1 ? 1 : 0);
2757 }
2758
2759 static float
2760 math_trunc (float arg1, float ignore ATTRIBUTE_UNUSED)
2761 {
2762 return (int) arg1;
2763 }
2764
2765 static float
2766 math_acos (float arg1, float ignore ATTRIBUTE_UNUSED)
2767 {
2768 return (float) acos (arg1);
2769 }
2770
2771 static float
2772 math_asin (float arg1, float ignore ATTRIBUTE_UNUSED)
2773 {
2774 return (float) asin (arg1);
2775 }
2776
2777 static float
2778 math_atan (float arg1, float ignore ATTRIBUTE_UNUSED)
2779 {
2780 return (float) atan (arg1);
2781 }
2782
2783 static float
2784 math_atan2 (float arg1, float arg2)
2785 {
2786 return (float) atan2 (arg1, arg2);
2787 }
2788
2789 static float
2790 math_cosh (float arg1, float ignore ATTRIBUTE_UNUSED)
2791 {
2792 return (float) cosh (arg1);
2793 }
2794
2795 static float
2796 math_cos (float arg1, float ignore ATTRIBUTE_UNUSED)
2797 {
2798 return (float) cos (arg1);
2799 }
2800
2801 static float
2802 math_cvf (float arg1, float ignore ATTRIBUTE_UNUSED)
2803 {
2804 return (float) arg1;
2805 }
2806
2807 static float
2808 math_exp (float arg1, float ignore ATTRIBUTE_UNUSED)
2809 {
2810 return (float) exp (arg1);
2811 }
2812
2813 static float
2814 math_fabs (float arg1, float ignore ATTRIBUTE_UNUSED)
2815 {
2816 return (float) fabs (arg1);
2817 }
2818
2819 /* expr1 * 2^expr2. */
2820
2821 static float
2822 math_ldexp (float arg1, float arg2)
2823 {
2824 return arg1 * (float) pow (2.0, arg2);
2825 }
2826
2827 static float
2828 math_log10 (float arg1, float ignore ATTRIBUTE_UNUSED)
2829 {
2830 return (float) log10 (arg1);
2831 }
2832
2833 static float
2834 math_log (float arg1, float ignore ATTRIBUTE_UNUSED)
2835 {
2836 return (float) log (arg1);
2837 }
2838
2839 static float
2840 math_max (float arg1, float arg2)
2841 {
2842 return (arg1 > arg2) ? arg1 : arg2;
2843 }
2844
2845 static float
2846 math_min (float arg1, float arg2)
2847 {
2848 return (arg1 < arg2) ? arg1 : arg2;
2849 }
2850
2851 static float
2852 math_pow (float arg1, float arg2)
2853 {
2854 return (float) pow (arg1, arg2);
2855 }
2856
2857 static float
2858 math_sin (float arg1, float ignore ATTRIBUTE_UNUSED)
2859 {
2860 return (float) sin (arg1);
2861 }
2862
2863 static float
2864 math_sinh (float arg1, float ignore ATTRIBUTE_UNUSED)
2865 {
2866 return (float) sinh (arg1);
2867 }
2868
2869 static float
2870 math_sqrt (float arg1, float ignore ATTRIBUTE_UNUSED)
2871 {
2872 return (float) sqrt (arg1);
2873 }
2874
2875 static float
2876 math_tan (float arg1, float ignore ATTRIBUTE_UNUSED)
2877 {
2878 return (float) tan (arg1);
2879 }
2880
2881 static float
2882 math_tanh (float arg1, float ignore ATTRIBUTE_UNUSED)
2883 {
2884 return (float) tanh (arg1);
2885 }
2886
2887 /* Built-in substitution symbol functions and math functions. */
2888 typedef struct
2889 {
2890 const char *name;
2891 int (*proc) (char *, char *);
2892 int nargs;
2893 } subsym_proc_entry;
2894
2895 static const subsym_proc_entry subsym_procs[] =
2896 {
2897 /* Assembler built-in string substitution functions. */
2898 { "$symlen", subsym_symlen, 1, },
2899 { "$symcmp", subsym_symcmp, 2, },
2900 { "$firstch", subsym_firstch, 2, },
2901 { "$lastch", subsym_lastch, 2, },
2902 { "$isdefed", subsym_isdefed, 1, },
2903 { "$ismember", subsym_ismember, 2, },
2904 { "$iscons", subsym_iscons, 1, },
2905 { "$isname", subsym_isname, 1, },
2906 { "$isreg", subsym_isreg, 1, },
2907 { "$structsz", subsym_structsz, 1, },
2908 { "$structacc", subsym_structacc, 1, },
2909 { NULL, NULL, 0 },
2910 };
2911
2912 typedef struct
2913 {
2914 const char *name;
2915 float (*proc) (float, float);
2916 int nargs;
2917 int int_return;
2918 } math_proc_entry;
2919
2920 static const math_proc_entry math_procs[] =
2921 {
2922 /* Integer-returning built-in math functions. */
2923 { "$cvi", math_cvi, 1, 1 },
2924 { "$int", math_int, 1, 1 },
2925 { "$sgn", math_sgn, 1, 1 },
2926
2927 /* Float-returning built-in math functions. */
2928 { "$acos", math_acos, 1, 0 },
2929 { "$asin", math_asin, 1, 0 },
2930 { "$atan", math_atan, 1, 0 },
2931 { "$atan2", math_atan2, 2, 0 },
2932 { "$ceil", math_ceil, 1, 0 },
2933 { "$cosh", math_cosh, 1, 0 },
2934 { "$cos", math_cos, 1, 0 },
2935 { "$cvf", math_cvf, 1, 0 },
2936 { "$exp", math_exp, 1, 0 },
2937 { "$fabs", math_fabs, 1, 0 },
2938 { "$floor", math_floor, 1, 0 },
2939 { "$fmod", math_fmod, 2, 0 },
2940 { "$ldexp", math_ldexp, 2, 0 },
2941 { "$log10", math_log10, 1, 0 },
2942 { "$log", math_log, 1, 0 },
2943 { "$max", math_max, 2, 0 },
2944 { "$min", math_min, 2, 0 },
2945 { "$pow", math_pow, 2, 0 },
2946 { "$round", math_round, 1, 0 },
2947 { "$sin", math_sin, 1, 0 },
2948 { "$sinh", math_sinh, 1, 0 },
2949 { "$sqrt", math_sqrt, 1, 0 },
2950 { "$tan", math_tan, 1, 0 },
2951 { "$tanh", math_tanh, 1, 0 },
2952 { "$trunc", math_trunc, 1, 0 },
2953 { NULL, NULL, 0, 0 },
2954 };
2955
2956 void
2957 md_begin (void)
2958 {
2959 insn_template *tm;
2960 tic54x_symbol *sym;
2961 const subsym_proc_entry *subsym_proc;
2962 const math_proc_entry *math_proc;
2963 const char *hash_err;
2964 char **symname;
2965 char *TIC54X_DIR = getenv ("TIC54X_DIR");
2966 char *A_DIR = TIC54X_DIR ? TIC54X_DIR : getenv ("A_DIR");
2967
2968 local_label_id = 0;
2969
2970 /* Look for A_DIR and add it to the include list. */
2971 if (A_DIR != NULL)
2972 {
2973 char *tmp = xstrdup (A_DIR);
2974
2975 do
2976 {
2977 char *next = strchr (tmp, ';');
2978
2979 if (next)
2980 *next++ = '\0';
2981 add_include_dir (tmp);
2982 tmp = next;
2983 }
2984 while (tmp != NULL);
2985 }
2986
2987 op_hash = hash_new ();
2988 for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
2989 {
2990 if (hash_find (op_hash, tm->name))
2991 continue;
2992 hash_err = hash_insert (op_hash, tm->name, (char *) tm);
2993 if (hash_err)
2994 as_fatal ("Internal Error: Can't hash %s: %s",
2995 tm->name, hash_err);
2996 }
2997 parop_hash = hash_new ();
2998 for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
2999 {
3000 if (hash_find (parop_hash, tm->name))
3001 continue;
3002 hash_err = hash_insert (parop_hash, tm->name, (char *) tm);
3003 if (hash_err)
3004 as_fatal ("Internal Error: Can't hash %s: %s",
3005 tm->name, hash_err);
3006 }
3007 reg_hash = hash_new ();
3008 for (sym = (tic54x_symbol *) regs; sym->name; sym++)
3009 {
3010 /* Add basic registers to the symbol table. */
3011 symbolS *symbolP = symbol_new (sym->name, absolute_section,
3012 (valueT) sym->value, &zero_address_frag);
3013 SF_SET_LOCAL (symbolP);
3014 symbol_table_insert (symbolP);
3015 hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3016 }
3017 for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
3018 hash_err = hash_insert (reg_hash, sym->name, (char *) sym);
3019 mmreg_hash = hash_new ();
3020 for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
3021 hash_err = hash_insert (mmreg_hash, sym->name, (char *) sym);
3022
3023 cc_hash = hash_new ();
3024 for (sym = (tic54x_symbol *) condition_codes; sym->name; sym++)
3025 hash_err = hash_insert (cc_hash, sym->name, (char *) sym);
3026
3027 cc2_hash = hash_new ();
3028 for (sym = (tic54x_symbol *) cc2_codes; sym->name; sym++)
3029 hash_err = hash_insert (cc2_hash, sym->name, (char *) sym);
3030
3031 cc3_hash = hash_new ();
3032 for (sym = (tic54x_symbol *) cc3_codes; sym->name; sym++)
3033 hash_err = hash_insert (cc3_hash, sym->name, (char *) sym);
3034
3035 sbit_hash = hash_new ();
3036 for (sym = (tic54x_symbol *) status_bits; sym->name; sym++)
3037 hash_err = hash_insert (sbit_hash, sym->name, (char *) sym);
3038
3039 misc_symbol_hash = hash_new ();
3040 for (symname = (char **) misc_symbols; *symname; symname++)
3041 hash_err = hash_insert (misc_symbol_hash, *symname, *symname);
3042
3043 /* Only the base substitution table and local label table are initialized;
3044 the others (for local macro substitution) get instantiated as needed. */
3045 local_label_hash[0] = hash_new ();
3046 subsym_hash[0] = hash_new ();
3047 for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
3048 hash_err = hash_insert (subsym_hash[0], subsym_proc->name,
3049 (char *) subsym_proc);
3050
3051 math_hash = hash_new ();
3052 for (math_proc = math_procs; math_proc->name; math_proc++)
3053 {
3054 /* Insert into the main subsym hash for recognition; insert into
3055 the math hash to actually store information. */
3056 hash_err = hash_insert (subsym_hash[0], math_proc->name,
3057 (char *) math_proc);
3058 hash_err = hash_insert (math_hash, math_proc->name,
3059 (char *) math_proc);
3060 }
3061 subsym_recurse_hash = hash_new ();
3062 stag_hash = hash_new ();
3063 }
3064
3065 static int
3066 is_accumulator (struct opstruct *operand)
3067 {
3068 return strcasecmp (operand->buf, "a") == 0
3069 || strcasecmp (operand->buf, "b") == 0;
3070 }
3071
3072 /* Return the number of operands found, or -1 on error, copying the
3073 operands into the given array and the accompanying expressions into
3074 the next array. */
3075
3076 static int
3077 get_operands (struct opstruct operands[], char *line)
3078 {
3079 char *lptr = line;
3080 int numexp = 0;
3081 int expecting_operand = 0;
3082 int i;
3083
3084 while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr])
3085 {
3086 int paren_not_balanced = 0;
3087 char *op_start, *op_end;
3088
3089 while (*lptr && ISSPACE (*lptr))
3090 ++lptr;
3091 op_start = lptr;
3092 while (paren_not_balanced || *lptr != ',')
3093 {
3094 if (*lptr == '\0')
3095 {
3096 if (paren_not_balanced)
3097 {
3098 as_bad (_("Unbalanced parenthesis in operand %d"), numexp);
3099 return -1;
3100 }
3101 else
3102 break;
3103 }
3104 if (*lptr == '(')
3105 ++paren_not_balanced;
3106 else if (*lptr == ')')
3107 --paren_not_balanced;
3108 ++lptr;
3109 }
3110 op_end = lptr;
3111 if (op_end != op_start)
3112 {
3113 int len = op_end - op_start;
3114
3115 strncpy (operands[numexp].buf, op_start, len);
3116 operands[numexp].buf[len] = 0;
3117 /* Trim trailing spaces; while the preprocessor gets rid of most,
3118 there are weird usage patterns that can introduce them
3119 (i.e. using strings for macro args). */
3120 while (len > 0 && ISSPACE (operands[numexp].buf[len - 1]))
3121 operands[numexp].buf[--len] = 0;
3122 lptr = op_end;
3123 ++numexp;
3124 }
3125 else
3126 {
3127 if (expecting_operand || *lptr == ',')
3128 {
3129 as_bad (_("Expecting operand after ','"));
3130 return -1;
3131 }
3132 }
3133 if (*lptr == ',')
3134 {
3135 if (*++lptr == '\0')
3136 {
3137 as_bad (_("Expecting operand after ','"));
3138 return -1;
3139 }
3140 expecting_operand = 1;
3141 }
3142 }
3143
3144 while (*lptr && ISSPACE (*lptr++))
3145 ;
3146 if (!is_end_of_line[(int) *lptr])
3147 {
3148 as_bad (_("Extra junk on line"));
3149 return -1;
3150 }
3151
3152 /* OK, now parse them into expressions. */
3153 for (i = 0; i < numexp; i++)
3154 {
3155 memset (&operands[i].exp, 0, sizeof (operands[i].exp));
3156 if (operands[i].buf[0] == '#')
3157 {
3158 /* Immediate. */
3159 parse_expression (operands[i].buf + 1, &operands[i].exp);
3160 }
3161 else if (operands[i].buf[0] == '@')
3162 {
3163 /* Direct notation. */
3164 parse_expression (operands[i].buf + 1, &operands[i].exp);
3165 }
3166 else if (operands[i].buf[0] == '*')
3167 {
3168 /* Indirect. */
3169 char *paren = strchr (operands[i].buf, '(');
3170
3171 /* Allow immediate syntax in the inner expression. */
3172 if (paren && paren[1] == '#')
3173 *++paren = '(';
3174
3175 /* Pull out the lk expression or SP offset, if present. */
3176 if (paren != NULL)
3177 {
3178 int len = strlen (paren);
3179 char *end = paren + len;
3180 int c;
3181
3182 while (end[-1] != ')')
3183 if (--end <= paren)
3184 {
3185 as_bad (_("Badly formed address expression"));
3186 return -1;
3187 }
3188 c = *end;
3189 *end = '\0';
3190 parse_expression (paren, &operands[i].exp);
3191 *end = c;
3192 }
3193 else
3194 operands[i].exp.X_op = O_absent;
3195 }
3196 else
3197 parse_expression (operands[i].buf, &operands[i].exp);
3198 }
3199
3200 return numexp;
3201 }
3202
3203 /* Predicates for different operand types. */
3204
3205 static int
3206 is_immediate (struct opstruct *operand)
3207 {
3208 return *operand->buf == '#';
3209 }
3210
3211 /* This is distinguished from immediate because some numbers must be constants
3212 and must *not* have the '#' prefix. */
3213
3214 static int
3215 is_absolute (struct opstruct *operand)
3216 {
3217 return operand->exp.X_op == O_constant && !is_immediate (operand);
3218 }
3219
3220 /* Is this an indirect operand? */
3221
3222 static int
3223 is_indirect (struct opstruct *operand)
3224 {
3225 return operand->buf[0] == '*';
3226 }
3227
3228 /* Is this a valid dual-memory operand? */
3229
3230 static int
3231 is_dual (struct opstruct *operand)
3232 {
3233 if (is_indirect (operand) && strncasecmp (operand->buf, "*ar", 3) == 0)
3234 {
3235 char *tmp = operand->buf + 3;
3236 int arf;
3237 int valid_mod;
3238
3239 arf = *tmp++ - '0';
3240 /* Only allow *ARx, *ARx-, *ARx+, or *ARx+0%. */
3241 valid_mod = *tmp == '\0' ||
3242 strcasecmp (tmp, "-") == 0 ||
3243 strcasecmp (tmp, "+") == 0 ||
3244 strcasecmp (tmp, "+0%") == 0;
3245 return arf >= 2 && arf <= 5 && valid_mod;
3246 }
3247 return 0;
3248 }
3249
3250 static int
3251 is_mmreg (struct opstruct *operand)
3252 {
3253 return (is_absolute (operand)
3254 || is_immediate (operand)
3255 || hash_find (mmreg_hash, operand->buf) != 0);
3256 }
3257
3258 static int
3259 is_type (struct opstruct *operand, enum optype type)
3260 {
3261 switch (type)
3262 {
3263 case OP_None:
3264 return operand->buf[0] == 0;
3265 case OP_Xmem:
3266 case OP_Ymem:
3267 return is_dual (operand);
3268 case OP_Sind:
3269 return is_indirect (operand);
3270 case OP_xpmad_ms7:
3271 /* This one *must* be immediate. */
3272 return is_immediate (operand);
3273 case OP_xpmad:
3274 case OP_pmad:
3275 case OP_PA:
3276 case OP_dmad:
3277 case OP_Lmem:
3278 case OP_MMR:
3279 return 1;
3280 case OP_Smem:
3281 /* Address may be a numeric, indirect, or an expression. */
3282 return !is_immediate (operand);
3283 case OP_MMRY:
3284 case OP_MMRX:
3285 return is_mmreg (operand);
3286 case OP_SRC:
3287 case OP_SRC1:
3288 case OP_RND:
3289 case OP_DST:
3290 return is_accumulator (operand);
3291 case OP_B:
3292 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'B';
3293 case OP_A:
3294 return is_accumulator (operand) && TOUPPER (operand->buf[0]) == 'A';
3295 case OP_ARX:
3296 return strncasecmp ("ar", operand->buf, 2) == 0
3297 && ISDIGIT (operand->buf[2]);
3298 case OP_SBIT:
3299 return hash_find (sbit_hash, operand->buf) != 0 || is_absolute (operand);
3300 case OP_CC:
3301 return hash_find (cc_hash, operand->buf) != 0;
3302 case OP_CC2:
3303 return hash_find (cc2_hash, operand->buf) != 0;
3304 case OP_CC3:
3305 return hash_find (cc3_hash, operand->buf) != 0
3306 || is_immediate (operand) || is_absolute (operand);
3307 case OP_16:
3308 return (is_immediate (operand) || is_absolute (operand))
3309 && operand->exp.X_add_number == 16;
3310 case OP_N:
3311 /* Allow st0 or st1 instead of a numeric. */
3312 return is_absolute (operand) || is_immediate (operand) ||
3313 strcasecmp ("st0", operand->buf) == 0 ||
3314 strcasecmp ("st1", operand->buf) == 0;
3315 case OP_12:
3316 case OP_123:
3317 return is_absolute (operand) || is_immediate (operand);
3318 case OP_SHFT:
3319 return (is_immediate (operand) || is_absolute (operand))
3320 && operand->exp.X_add_number >= 0 && operand->exp.X_add_number < 16;
3321 case OP_SHIFT:
3322 /* Let this one catch out-of-range values. */
3323 return (is_immediate (operand) || is_absolute (operand))
3324 && operand->exp.X_add_number != 16;
3325 case OP_BITC:
3326 case OP_031:
3327 case OP_k8:
3328 return is_absolute (operand) || is_immediate (operand);
3329 case OP_k8u:
3330 return is_immediate (operand)
3331 && operand->exp.X_op == O_constant
3332 && operand->exp.X_add_number >= 0
3333 && operand->exp.X_add_number < 256;
3334 case OP_lk:
3335 case OP_lku:
3336 /* Allow anything; assumes opcodes are ordered with Smem operands
3337 versions first. */
3338 return 1;
3339 case OP_k5:
3340 case OP_k3:
3341 case OP_k9:
3342 /* Just make sure it's an integer; check range later. */
3343 return is_immediate (operand);
3344 case OP_T:
3345 return strcasecmp ("t", operand->buf) == 0 ||
3346 strcasecmp ("treg", operand->buf) == 0;
3347 case OP_TS:
3348 return strcasecmp ("ts", operand->buf) == 0;
3349 case OP_ASM:
3350 return strcasecmp ("asm", operand->buf) == 0;
3351 case OP_TRN:
3352 return strcasecmp ("trn", operand->buf) == 0;
3353 case OP_DP:
3354 return strcasecmp ("dp", operand->buf) == 0;
3355 case OP_ARP:
3356 return strcasecmp ("arp", operand->buf) == 0;
3357 default:
3358 return 0;
3359 }
3360 }
3361
3362 static int
3363 operands_match (tic54x_insn *insn,
3364 struct opstruct *operands,
3365 int opcount,
3366 const enum optype *refoptype,
3367 int minops,
3368 int maxops)
3369 {
3370 int op = 0, refop = 0;
3371
3372 if (opcount == 0 && minops == 0)
3373 return 1;
3374
3375 while (op <= maxops && refop <= maxops)
3376 {
3377 while (!is_type (&operands[op], OPTYPE (refoptype[refop])))
3378 {
3379 /* Skip an optional template operand if it doesn't agree
3380 with the current operand. */
3381 if (refoptype[refop] & OPT)
3382 {
3383 ++refop;
3384 --maxops;
3385 if (refop > maxops)
3386 return 0;
3387 }
3388 else
3389 return 0;
3390 }
3391
3392 /* Save the actual operand type for later use. */
3393 operands[op].type = OPTYPE (refoptype[refop]);
3394 ++refop;
3395 ++op;
3396 /* Have we matched them all yet? */
3397 if (op == opcount)
3398 {
3399 while (op < maxops)
3400 {
3401 /* If a later operand is *not* optional, no match. */
3402 if ((refoptype[refop] & OPT) == 0)
3403 return 0;
3404 /* Flag any implicit default OP_DST operands so we know to add
3405 them explicitly when encoding the operand later. */
3406 if (OPTYPE (refoptype[refop]) == OP_DST)
3407 insn->using_default_dst = 1;
3408 ++refop;
3409 ++op;
3410 }
3411
3412 return 1;
3413 }
3414 }
3415
3416 return 0;
3417 }
3418
3419 /* 16-bit direct memory address
3420 Explicit dmad operands are always in last word of insn (usually second
3421 word, but bumped to third if lk addressing is used)
3422
3423 We allow *(dmad) notation because the TI assembler allows it.
3424
3425 XPC_CODE:
3426 0 for 16-bit addresses
3427 1 for full 23-bit addresses
3428 2 for the upper 7 bits of a 23-bit address (LDX). */
3429
3430 static int
3431 encode_dmad (tic54x_insn *insn, struct opstruct *operand, int xpc_code)
3432 {
3433 int op = 1 + insn->is_lkaddr;
3434
3435 /* Only allow *(dmad) expressions; all others are invalid. */
3436 if (is_indirect (operand) && operand->buf[strlen (operand->buf) - 1] != ')')
3437 {
3438 as_bad (_("Invalid dmad syntax '%s'"), operand->buf);
3439 return 0;
3440 }
3441
3442 insn->opcode[op].addr_expr = operand->exp;
3443
3444 if (insn->opcode[op].addr_expr.X_op == O_constant)
3445 {
3446 valueT value = insn->opcode[op].addr_expr.X_add_number;
3447
3448 if (xpc_code == 1)
3449 {
3450 insn->opcode[0].word &= 0xFF80;
3451 insn->opcode[0].word |= (value >> 16) & 0x7F;
3452 insn->opcode[1].word = value & 0xFFFF;
3453 }
3454 else if (xpc_code == 2)
3455 insn->opcode[op].word = (value >> 16) & 0xFFFF;
3456 else
3457 insn->opcode[op].word = value;
3458 }
3459 else
3460 {
3461 /* Do the fixup later; just store the expression. */
3462 insn->opcode[op].word = 0;
3463 insn->opcode[op].r_nchars = 2;
3464
3465 if (amode == c_mode)
3466 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3467 else if (xpc_code == 1)
3468 {
3469 /* This relocation spans two words, so adjust accordingly. */
3470 insn->opcode[0].addr_expr = operand->exp;
3471 insn->opcode[0].r_type = BFD_RELOC_TIC54X_23;
3472 insn->opcode[0].r_nchars = 4;
3473 insn->opcode[0].unresolved = 1;
3474 /* It's really 2 words, but we want to stop encoding after the
3475 first, since we must encode both words at once. */
3476 insn->words = 1;
3477 }
3478 else if (xpc_code == 2)
3479 insn->opcode[op].r_type = BFD_RELOC_TIC54X_MS7_OF_23;
3480 else
3481 insn->opcode[op].r_type = BFD_RELOC_TIC54X_16_OF_23;
3482
3483 insn->opcode[op].unresolved = 1;
3484 }
3485
3486 return 1;
3487 }
3488
3489 /* 7-bit direct address encoding. */
3490
3491 static int
3492 encode_address (tic54x_insn *insn, struct opstruct *operand)
3493 {
3494 /* Assumes that dma addresses are *always* in word 0 of the opcode. */
3495 insn->opcode[0].addr_expr = operand->exp;
3496
3497 if (operand->exp.X_op == O_constant)
3498 insn->opcode[0].word |= (operand->exp.X_add_number & 0x7F);
3499 else
3500 {
3501 if (operand->exp.X_op == O_register)
3502 as_bad (_("Use the .mmregs directive to use memory-mapped register names such as '%s'"), operand->buf);
3503 /* Do the fixup later; just store the expression. */
3504 insn->opcode[0].r_nchars = 1;
3505 insn->opcode[0].r_type = BFD_RELOC_TIC54X_PARTLS7;
3506 insn->opcode[0].unresolved = 1;
3507 }
3508
3509 return 1;
3510 }
3511
3512 static int
3513 encode_indirect (tic54x_insn *insn, struct opstruct *operand)
3514 {
3515 int arf;
3516 int mod;
3517
3518 if (insn->is_lkaddr)
3519 {
3520 /* lk addresses always go in the second insn word. */
3521 mod = ((TOUPPER (operand->buf[1]) == 'A') ? 12 :
3522 (operand->buf[1] == '(') ? 15 :
3523 (strchr (operand->buf, '%') != NULL) ? 14 : 13);
3524 arf = ((mod == 12) ? operand->buf[3] - '0' :
3525 (mod == 15) ? 0 : operand->buf[4] - '0');
3526
3527 insn->opcode[1].addr_expr = operand->exp;
3528
3529 if (operand->exp.X_op == O_constant)
3530 insn->opcode[1].word = operand->exp.X_add_number;
3531 else
3532 {
3533 insn->opcode[1].word = 0;
3534 insn->opcode[1].r_nchars = 2;
3535 insn->opcode[1].r_type = BFD_RELOC_TIC54X_16_OF_23;
3536 insn->opcode[1].unresolved = 1;
3537 }
3538 }
3539 else if (strncasecmp (operand->buf, "*sp (", 4) == 0)
3540 {
3541 /* Stack offsets look the same as 7-bit direct addressing. */
3542 return encode_address (insn, operand);
3543 }
3544 else
3545 {
3546 arf = (TOUPPER (operand->buf[1]) == 'A' ?
3547 operand->buf[3] : operand->buf[4]) - '0';
3548
3549 if (operand->buf[1] == '+')
3550 {
3551 mod = 3; /* *+ARx */
3552 if (insn->tm->flags & FL_SMR)
3553 as_warn (_("Address mode *+ARx is write-only. "
3554 "Results of reading are undefined."));
3555 }
3556 else if (operand->buf[4] == '\0')
3557 mod = 0; /* *ARx */
3558 else if (operand->buf[5] == '\0')
3559 mod = (operand->buf[4] == '-' ? 1 : 2); /* *ARx+ / *ARx- */
3560 else if (operand->buf[6] == '\0')
3561 {
3562 if (operand->buf[5] == '0')
3563 mod = (operand->buf[4] == '-' ? 5 : 6); /* *ARx+0 / *ARx-0 */
3564 else
3565 mod = (operand->buf[4] == '-' ? 8 : 10);/* *ARx+% / *ARx-% */
3566 }
3567 else if (TOUPPER (operand->buf[6]) == 'B')
3568 mod = (operand->buf[4] == '-' ? 4 : 7); /* ARx+0B / *ARx-0B */
3569 else if (TOUPPER (operand->buf[6]) == '%')
3570 mod = (operand->buf[4] == '-' ? 9 : 11); /* ARx+0% / *ARx - 0% */
3571 else
3572 {
3573 as_bad (_("Unrecognized indirect address format \"%s\""),
3574 operand->buf);
3575 return 0;
3576 }
3577 }
3578
3579 insn->opcode[0].word |= 0x80 | (mod << 3) | arf;
3580
3581 return 1;
3582 }
3583
3584 static int
3585 encode_integer (tic54x_insn *insn,
3586 struct opstruct *operand,
3587 int which,
3588 int min,
3589 int max,
3590 unsigned short mask)
3591 {
3592 long parse, integer;
3593
3594 insn->opcode[which].addr_expr = operand->exp;
3595
3596 if (operand->exp.X_op == O_constant)
3597 {
3598 parse = operand->exp.X_add_number;
3599 /* Hack -- fixup for 16-bit hex quantities that get converted positive
3600 instead of negative. */
3601 if ((parse & 0x8000) && min == -32768 && max == 32767)
3602 integer = (short) parse;
3603 else
3604 integer = parse;
3605
3606 if (integer >= min && integer <= max)
3607 {
3608 insn->opcode[which].word |= (integer & mask);
3609 return 1;
3610 }
3611 as_bad (_("Operand '%s' out of range (%d <= x <= %d)"),
3612 operand->buf, min, max);
3613 }
3614 else
3615 {
3616 if (insn->opcode[which].addr_expr.X_op == O_constant)
3617 {
3618 insn->opcode[which].word |=
3619 insn->opcode[which].addr_expr.X_add_number & mask;
3620 }
3621 else
3622 {
3623 /* Do the fixup later; just store the expression. */
3624 bfd_reloc_code_real_type rtype =
3625 (mask == 0x1FF ? BFD_RELOC_TIC54X_PARTMS9 :
3626 mask == 0xFFFF ? BFD_RELOC_TIC54X_16_OF_23 :
3627 mask == 0x7F ? BFD_RELOC_TIC54X_PARTLS7 : BFD_RELOC_8);
3628 int size = (mask == 0x1FF || mask == 0xFFFF) ? 2 : 1;
3629
3630 if (rtype == BFD_RELOC_8)
3631 as_bad (_("Error in relocation handling"));
3632
3633 insn->opcode[which].r_nchars = size;
3634 insn->opcode[which].r_type = rtype;
3635 insn->opcode[which].unresolved = 1;
3636 }
3637
3638 return 1;
3639 }
3640
3641 return 0;
3642 }
3643
3644 static int
3645 encode_condition (tic54x_insn *insn, struct opstruct *operand)
3646 {
3647 tic54x_symbol *cc = (tic54x_symbol *) hash_find (cc_hash, operand->buf);
3648 if (!cc)
3649 {
3650 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3651 return 0;
3652 }
3653 #define CC_GROUP 0x40
3654 #define CC_ACC 0x08
3655 #define CATG_A1 0x07
3656 #define CATG_B1 0x30
3657 #define CATG_A2 0x30
3658 #define CATG_B2 0x0C
3659 #define CATG_C2 0x03
3660 /* Disallow group 1 conditions mixed with group 2 conditions
3661 if group 1, allow only one category A and one category B
3662 if group 2, allow only one each of category A, B, and C. */
3663 if (((insn->opcode[0].word & 0xFF) != 0))
3664 {
3665 if ((insn->opcode[0].word & CC_GROUP) != (cc->value & CC_GROUP))
3666 {
3667 as_bad (_("Condition \"%s\" does not match preceding group"),
3668 operand->buf);
3669 return 0;
3670 }
3671 if (insn->opcode[0].word & CC_GROUP)
3672 {
3673 if ((insn->opcode[0].word & CC_ACC) != (cc->value & CC_ACC))
3674 {
3675 as_bad (_("Condition \"%s\" uses a different accumulator from "
3676 "a preceding condition"),
3677 operand->buf);
3678 return 0;
3679 }
3680 if ((insn->opcode[0].word & CATG_A1) && (cc->value & CATG_A1))
3681 {
3682 as_bad (_("Only one comparison conditional allowed"));
3683 return 0;
3684 }
3685 if ((insn->opcode[0].word & CATG_B1) && (cc->value & CATG_B1))
3686 {
3687 as_bad (_("Only one overflow conditional allowed"));
3688 return 0;
3689 }
3690 }
3691 else if ( ((insn->opcode[0].word & CATG_A2) && (cc->value & CATG_A2))
3692 || ((insn->opcode[0].word & CATG_B2) && (cc->value & CATG_B2))
3693 || ((insn->opcode[0].word & CATG_C2) && (cc->value & CATG_C2)))
3694 {
3695 as_bad (_("Duplicate %s conditional"), operand->buf);
3696 return 0;
3697 }
3698 }
3699
3700 insn->opcode[0].word |= cc->value;
3701 return 1;
3702 }
3703
3704 static int
3705 encode_cc3 (tic54x_insn *insn, struct opstruct *operand)
3706 {
3707 tic54x_symbol *cc3 = (tic54x_symbol *) hash_find (cc3_hash, operand->buf);
3708 int value = cc3 ? cc3->value : operand->exp.X_add_number << 8;
3709
3710 if ((value & 0x0300) != value)
3711 {
3712 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3713 return 0;
3714 }
3715 insn->opcode[0].word |= value;
3716 return 1;
3717 }
3718
3719 static int
3720 encode_arx (tic54x_insn *insn, struct opstruct *operand)
3721 {
3722 int arf = strlen (operand->buf) >= 3 ? operand->buf[2] - '0' : -1;
3723
3724 if (strncasecmp ("ar", operand->buf, 2) || arf < 0 || arf > 7)
3725 {
3726 as_bad (_("Invalid auxiliary register (use AR0-AR7)"));
3727 return 0;
3728 }
3729 insn->opcode[0].word |= arf;
3730 return 1;
3731 }
3732
3733 static int
3734 encode_cc2 (tic54x_insn *insn, struct opstruct *operand)
3735 {
3736 tic54x_symbol *cc2 = (tic54x_symbol *) hash_find (cc2_hash, operand->buf);
3737
3738 if (!cc2)
3739 {
3740 as_bad (_("Unrecognized condition code \"%s\""), operand->buf);
3741 return 0;
3742 }
3743 insn->opcode[0].word |= cc2->value;
3744 return 1;
3745 }
3746
3747 static int
3748 encode_operand (tic54x_insn *insn, enum optype type, struct opstruct *operand)
3749 {
3750 int ext = (insn->tm->flags & FL_EXT) != 0;
3751
3752 if (type == OP_MMR && operand->exp.X_op != O_constant)
3753 {
3754 /* Disallow long-constant addressing for memory-mapped addressing. */
3755 if (insn->is_lkaddr)
3756 {
3757 as_bad (_("lk addressing modes are invalid for memory-mapped "
3758 "register addressing"));
3759 return 0;
3760 }
3761 type = OP_Smem;
3762 /* Warn about *+ARx when used with MMR operands. */
3763 if (strncasecmp (operand->buf, "*+ar", 4) == 0)
3764 {
3765 as_warn (_("Address mode *+ARx is not allowed in memory-mapped "
3766 "register addressing. Resulting behavior is "
3767 "undefined."));
3768 }
3769 }
3770
3771 switch (type)
3772 {
3773 case OP_None:
3774 return 1;
3775 case OP_dmad:
3776 /* 16-bit immediate value. */
3777 return encode_dmad (insn, operand, 0);
3778 case OP_SRC:
3779 if (TOUPPER (*operand->buf) == 'B')
3780 {
3781 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 9);
3782 if (insn->using_default_dst)
3783 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
3784 }
3785 return 1;
3786 case OP_RND:
3787 /* Make sure this agrees with the OP_DST operand. */
3788 if (!((TOUPPER (operand->buf[0]) == 'B') ^
3789 ((insn->opcode[0].word & (1 << 8)) != 0)))
3790 {
3791 as_bad (_("Destination accumulator for each part of this parallel "
3792 "instruction must be different"));
3793 return 0;
3794 }
3795 return 1;
3796 case OP_SRC1:
3797 case OP_DST:
3798 if (TOUPPER (operand->buf[0]) == 'B')
3799 insn->opcode[ext ? (1 + insn->is_lkaddr) : 0].word |= (1 << 8);
3800 return 1;
3801 case OP_Xmem:
3802 case OP_Ymem:
3803 {
3804 int mod = (operand->buf[4] == '\0' ? 0 : /* *arx */
3805 operand->buf[4] == '-' ? 1 : /* *arx- */
3806 operand->buf[5] == '\0' ? 2 : 3); /* *arx+, *arx+0% */
3807 int arf = operand->buf[3] - '0' - 2;
3808 int code = (mod << 2) | arf;
3809 insn->opcode[0].word |= (code << (type == OP_Xmem ? 4 : 0));
3810 return 1;
3811 }
3812 case OP_Lmem:
3813 case OP_Smem:
3814 if (!is_indirect (operand))
3815 return encode_address (insn, operand);
3816 /* Fall through. */
3817 case OP_Sind:
3818 return encode_indirect (insn, operand);
3819 case OP_xpmad_ms7:
3820 return encode_dmad (insn, operand, 2);
3821 case OP_xpmad:
3822 return encode_dmad (insn, operand, 1);
3823 case OP_PA:
3824 case OP_pmad:
3825 return encode_dmad (insn, operand, 0);
3826 case OP_ARX:
3827 return encode_arx (insn, operand);
3828 case OP_MMRX:
3829 case OP_MMRY:
3830 case OP_MMR:
3831 {
3832 int value = operand->exp.X_add_number;
3833
3834 if (type == OP_MMR)
3835 insn->opcode[0].word |= value;
3836 else
3837 {
3838 if (value < 16 || value > 24)
3839 {
3840 as_bad (_("Memory mapped register \"%s\" out of range"),
3841 operand->buf);
3842 return 0;
3843 }
3844 if (type == OP_MMRX)
3845 insn->opcode[0].word |= (value - 16) << 4;
3846 else
3847 insn->opcode[0].word |= (value - 16);
3848 }
3849 return 1;
3850 }
3851 case OP_B:
3852 case OP_A:
3853 return 1;
3854 case OP_SHFT:
3855 return encode_integer (insn, operand, ext + insn->is_lkaddr,
3856 0, 15, 0xF);
3857 case OP_SHIFT:
3858 return encode_integer (insn, operand, ext + insn->is_lkaddr,
3859 -16, 15, 0x1F);
3860 case OP_lk:
3861 return encode_integer (insn, operand, 1 + insn->is_lkaddr,
3862 -32768, 32767, 0xFFFF);
3863 case OP_CC:
3864 return encode_condition (insn, operand);
3865 case OP_CC2:
3866 return encode_cc2 (insn, operand);
3867 case OP_CC3:
3868 return encode_cc3 (insn, operand);
3869 case OP_BITC:
3870 return encode_integer (insn, operand, 0, 0, 15, 0xF);
3871 case OP_k8:
3872 return encode_integer (insn, operand, 0, -128, 127, 0xFF);
3873 case OP_123:
3874 {
3875 int value = operand->exp.X_add_number;
3876 int code;
3877 if (value < 1 || value > 3)
3878 {
3879 as_bad (_("Invalid operand (use 1, 2, or 3)"));
3880 return 0;
3881 }
3882 code = value == 1 ? 0 : value == 2 ? 0x2 : 0x1;
3883 insn->opcode[0].word |= (code << 8);
3884 return 1;
3885 }
3886 case OP_031:
3887 return encode_integer (insn, operand, 0, 0, 31, 0x1F);
3888 case OP_k8u:
3889 return encode_integer (insn, operand, 0, 0, 255, 0xFF);
3890 case OP_lku:
3891 return encode_integer (insn, operand, 1 + insn->is_lkaddr,
3892 0, 65535, 0xFFFF);
3893 case OP_SBIT:
3894 {
3895 tic54x_symbol *sbit = (tic54x_symbol *)
3896 hash_find (sbit_hash, operand->buf);
3897 int value = is_absolute (operand) ?
3898 operand->exp.X_add_number : (sbit ? sbit->value : -1);
3899 int reg = 0;
3900
3901 if (insn->opcount == 1)
3902 {
3903 if (!sbit)
3904 {
3905 as_bad (_("A status register or status bit name is required"));
3906 return 0;
3907 }
3908 /* Guess the register based on the status bit; "ovb" is the last
3909 status bit defined for st0. */
3910 if (sbit > (tic54x_symbol *) hash_find (sbit_hash, "ovb"))
3911 reg = 1;
3912 }
3913 if (value == -1)
3914 {
3915 as_bad (_("Unrecognized status bit \"%s\""), operand->buf);
3916 return 0;
3917 }
3918 insn->opcode[0].word |= value;
3919 insn->opcode[0].word |= (reg << 9);
3920 return 1;
3921 }
3922 case OP_N:
3923 if (strcasecmp (operand->buf, "st0") == 0
3924 || strcasecmp (operand->buf, "st1") == 0)
3925 {
3926 insn->opcode[0].word |=
3927 ((unsigned short) (operand->buf[2] - '0')) << 9;
3928 return 1;
3929 }
3930 else if (operand->exp.X_op == O_constant
3931 && (operand->exp.X_add_number == 0
3932 || operand->exp.X_add_number == 1))
3933 {
3934 insn->opcode[0].word |=
3935 ((unsigned short) (operand->exp.X_add_number)) << 9;
3936 return 1;
3937 }
3938 as_bad (_("Invalid status register \"%s\""), operand->buf);
3939 return 0;
3940 case OP_k5:
3941 return encode_integer (insn, operand, 0, -16, 15, 0x1F);
3942 case OP_k3:
3943 return encode_integer (insn, operand, 0, 0, 7, 0x7);
3944 case OP_k9:
3945 return encode_integer (insn, operand, 0, 0, 0x1FF, 0x1FF);
3946 case OP_12:
3947 if (operand->exp.X_add_number != 1
3948 && operand->exp.X_add_number != 2)
3949 {
3950 as_bad (_("Operand \"%s\" out of range (use 1 or 2)"), operand->buf);
3951 return 0;
3952 }
3953 insn->opcode[0].word |= (operand->exp.X_add_number - 1) << 9;
3954 return 1;
3955 case OP_16:
3956 case OP_T:
3957 case OP_TS:
3958 case OP_ASM:
3959 case OP_TRN:
3960 case OP_DP:
3961 case OP_ARP:
3962 /* No encoding necessary. */
3963 return 1;
3964 default:
3965 return 0;
3966 }
3967
3968 return 1;
3969 }
3970
3971 static void
3972 emit_insn (tic54x_insn *insn)
3973 {
3974 int i;
3975 flagword oldflags = bfd_get_section_flags (stdoutput, now_seg);
3976 flagword flags = oldflags | SEC_CODE;
3977
3978 if (! bfd_set_section_flags (stdoutput, now_seg, flags))
3979 as_warn (_("error setting flags for \"%s\": %s"),
3980 bfd_section_name (stdoutput, now_seg),
3981 bfd_errmsg (bfd_get_error ()));
3982
3983 for (i = 0; i < insn->words; i++)
3984 {
3985 int size = (insn->opcode[i].unresolved
3986 && insn->opcode[i].r_type == BFD_RELOC_TIC54X_23) ? 4 : 2;
3987 char *p = frag_more (size);
3988
3989 if (size == 2)
3990 md_number_to_chars (p, (valueT) insn->opcode[i].word, 2);
3991 else
3992 md_number_to_chars (p, (valueT) insn->opcode[i].word << 16, 4);
3993
3994 if (insn->opcode[i].unresolved)
3995 fix_new_exp (frag_now, p - frag_now->fr_literal,
3996 insn->opcode[i].r_nchars, &insn->opcode[i].addr_expr,
3997 FALSE, insn->opcode[i].r_type);
3998 }
3999 }
4000
4001 /* Convert the operand strings into appropriate opcode values
4002 return the total number of words used by the instruction. */
4003
4004 static int
4005 build_insn (tic54x_insn *insn)
4006 {
4007 int i;
4008
4009 /* Only non-parallel instructions support lk addressing. */
4010 if (!(insn->tm->flags & FL_PAR))
4011 {
4012 for (i = 0; i < insn->opcount; i++)
4013 {
4014 if ((OPTYPE (insn->operands[i].type) == OP_Smem
4015 || OPTYPE (insn->operands[i].type) == OP_Lmem
4016 || OPTYPE (insn->operands[i].type) == OP_Sind)
4017 && strchr (insn->operands[i].buf, '(')
4018 /* Don't mistake stack-relative addressing for lk addressing. */
4019 && strncasecmp (insn->operands[i].buf, "*sp (", 4) != 0)
4020 {
4021 insn->is_lkaddr = 1;
4022 insn->lkoperand = i;
4023 break;
4024 }
4025 }
4026 }
4027 insn->words = insn->tm->words + insn->is_lkaddr;
4028
4029 insn->opcode[0].word = insn->tm->opcode;
4030 if (insn->tm->flags & FL_EXT)
4031 insn->opcode[1 + insn->is_lkaddr].word = insn->tm->opcode2;
4032
4033 for (i = 0; i < insn->opcount; i++)
4034 {
4035 enum optype type = insn->operands[i].type;
4036
4037 if (!encode_operand (insn, type, &insn->operands[i]))
4038 return 0;
4039 }
4040 if (insn->tm->flags & FL_PAR)
4041 for (i = 0; i < insn->paropcount; i++)
4042 {
4043 enum optype partype = insn->paroperands[i].type;
4044
4045 if (!encode_operand (insn, partype, &insn->paroperands[i]))
4046 return 0;
4047 }
4048
4049 emit_insn (insn);
4050
4051 return insn->words;
4052 }
4053
4054 static int
4055 optimize_insn (tic54x_insn *insn)
4056 {
4057 /* Optimize some instructions, helping out the brain-dead programmer. */
4058 #define is_zero(op) ((op).exp.X_op == O_constant && (op).exp.X_add_number == 0)
4059 if (strcasecmp (insn->tm->name, "add") == 0)
4060 {
4061 if (insn->opcount > 1
4062 && is_accumulator (&insn->operands[insn->opcount - 2])
4063 && is_accumulator (&insn->operands[insn->opcount - 1])
4064 && strcasecmp (insn->operands[insn->opcount - 2].buf,
4065 insn->operands[insn->opcount - 1].buf) == 0)
4066 {
4067 --insn->opcount;
4068 insn->using_default_dst = 1;
4069 return 1;
4070 }
4071
4072 /* Try to collapse if Xmem and shift count is zero. */
4073 if ((OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4074 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT
4075 && is_zero (insn->operands[1]))
4076 /* Or if Smem, shift is zero or absent, and SRC == DST. */
4077 || (OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4078 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4079 && is_type (&insn->operands[1], OP_SHIFT)
4080 && is_zero (insn->operands[1]) && insn->opcount == 3))
4081 {
4082 insn->operands[1] = insn->operands[2];
4083 insn->opcount = 2;
4084 return 1;
4085 }
4086 }
4087 else if (strcasecmp (insn->tm->name, "ld") == 0)
4088 {
4089 if (insn->opcount == 3 && insn->operands[0].type != OP_SRC)
4090 {
4091 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4092 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4093 && is_zero (insn->operands[1])
4094 && (OPTYPE (insn->tm->operand_types[0]) != OP_lk
4095 || (insn->operands[0].exp.X_op == O_constant
4096 && insn->operands[0].exp.X_add_number <= 255
4097 && insn->operands[0].exp.X_add_number >= 0)))
4098 {
4099 insn->operands[1] = insn->operands[2];
4100 insn->opcount = 2;
4101 return 1;
4102 }
4103 }
4104 }
4105 else if (strcasecmp (insn->tm->name, "sth") == 0
4106 || strcasecmp (insn->tm->name, "stl") == 0)
4107 {
4108 if ((OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT
4109 || OPTYPE (insn->tm->operand_types[1]) == OP_SHFT)
4110 && is_zero (insn->operands[1]))
4111 {
4112 insn->operands[1] = insn->operands[2];
4113 insn->opcount = 2;
4114 return 1;
4115 }
4116 }
4117 else if (strcasecmp (insn->tm->name, "sub") == 0)
4118 {
4119 if (insn->opcount > 1
4120 && is_accumulator (&insn->operands[insn->opcount - 2])
4121 && is_accumulator (&insn->operands[insn->opcount - 1])
4122 && strcasecmp (insn->operands[insn->opcount - 2].buf,
4123 insn->operands[insn->opcount - 1].buf) == 0)
4124 {
4125 --insn->opcount;
4126 insn->using_default_dst = 1;
4127 return 1;
4128 }
4129
4130 if ( ((OPTYPE (insn->tm->operand_types[0]) == OP_Smem
4131 && OPTYPE (insn->tm->operand_types[1]) == OP_SHIFT)
4132 || (OPTYPE (insn->tm->operand_types[0]) == OP_Xmem
4133 && OPTYPE (insn->tm->operand_types[1]) == OP_SHFT))
4134 && is_zero (insn->operands[1])
4135 && insn->opcount == 3)
4136 {
4137 insn->operands[1] = insn->operands[2];
4138 insn->opcount = 2;
4139 return 1;
4140 }
4141 }
4142 return 0;
4143 }
4144
4145 /* Find a matching template if possible, and get the operand strings. */
4146
4147 static int
4148 tic54x_parse_insn (tic54x_insn *insn, char *line)
4149 {
4150 insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
4151 if (!insn->tm)
4152 {
4153 as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
4154 return 0;
4155 }
4156
4157 insn->opcount = get_operands (insn->operands, line);
4158 if (insn->opcount < 0)
4159 return 0;
4160
4161 /* Check each variation of operands for this mnemonic. */
4162 while (insn->tm->name && strcasecmp (insn->tm->name, insn->mnemonic) == 0)
4163 {
4164 if (insn->opcount >= insn->tm->minops
4165 && insn->opcount <= insn->tm->maxops
4166 && operands_match (insn, &insn->operands[0], insn->opcount,
4167 insn->tm->operand_types,
4168 insn->tm->minops, insn->tm->maxops))
4169 {
4170 /* SUCCESS! now try some optimizations. */
4171 if (optimize_insn (insn))
4172 {
4173 insn->tm = (insn_template *) hash_find (op_hash,
4174 insn->mnemonic);
4175 continue;
4176 }
4177
4178 return 1;
4179 }
4180 ++(insn->tm);
4181 }
4182 as_bad (_("Unrecognized operand list '%s' for instruction '%s'"),
4183 line, insn->mnemonic);
4184 return 0;
4185 }
4186
4187 /* We set this in start_line_hook, 'cause if we do a line replacement, we
4188 won't be able to see the next line. */
4189 static int parallel_on_next_line_hint = 0;
4190
4191 /* See if this is part of a parallel instruction
4192 Look for a subsequent line starting with "||". */
4193
4194 static int
4195 next_line_shows_parallel (char *next_line)
4196 {
4197 /* Look for the second half. */
4198 while (ISSPACE (*next_line))
4199 ++next_line;
4200
4201 return (next_line[0] == PARALLEL_SEPARATOR
4202 && next_line[1] == PARALLEL_SEPARATOR);
4203 }
4204
4205 static int
4206 tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
4207 {
4208 insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
4209 if (!insn->tm)
4210 {
4211 as_bad (_("Unrecognized parallel instruction \"%s\""),
4212 insn->mnemonic);
4213 return 0;
4214 }
4215
4216 while (insn->tm->name && strcasecmp (insn->tm->name,
4217 insn->mnemonic) == 0)
4218 {
4219 insn->opcount = get_operands (insn->operands, line);
4220 if (insn->opcount < 0)
4221 return 0;
4222 if (insn->opcount == 2
4223 && operands_match (insn, &insn->operands[0], insn->opcount,
4224 insn->tm->operand_types, 2, 2))
4225 {
4226 return 1;
4227 }
4228 ++(insn->tm);
4229 }
4230 /* Didn't find a matching parallel; try for a normal insn. */
4231 return 0;
4232 }
4233
4234 /* Parse the second line of a two-line parallel instruction. */
4235
4236 static int
4237 tic54x_parse_parallel_insn_lastline (tic54x_insn *insn, char *line)
4238 {
4239 int valid_mnemonic = 0;
4240
4241 insn->paropcount = get_operands (insn->paroperands, line);
4242 while (insn->tm->name && strcasecmp (insn->tm->name,
4243 insn->mnemonic) == 0)
4244 {
4245 if (strcasecmp (insn->tm->parname, insn->parmnemonic) == 0)
4246 {
4247 valid_mnemonic = 1;
4248
4249 if (insn->paropcount >= insn->tm->minops
4250 && insn->paropcount <= insn->tm->maxops
4251 && operands_match (insn, insn->paroperands,
4252 insn->paropcount,
4253 insn->tm->paroperand_types,
4254 insn->tm->minops, insn->tm->maxops))
4255 return 1;
4256 }
4257 ++(insn->tm);
4258 }
4259 if (valid_mnemonic)
4260 as_bad (_("Invalid operand (s) for parallel instruction \"%s\""),
4261 insn->parmnemonic);
4262 else
4263 as_bad (_("Unrecognized parallel instruction combination \"%s || %s\""),
4264 insn->mnemonic, insn->parmnemonic);
4265
4266 return 0;
4267 }
4268
4269 /* If quotes found, return copy of line up to closing quote;
4270 otherwise up until terminator.
4271 If it's a string, pass as-is; otherwise attempt substitution symbol
4272 replacement on the value. */
4273
4274 static char *
4275 subsym_get_arg (char *line, const char *terminators, char **str, int nosub)
4276 {
4277 char *ptr = line;
4278 char *endp;
4279 int is_string = *line == '"';
4280 int is_char = ISDIGIT (*line);
4281
4282 if (is_char)
4283 {
4284 while (ISDIGIT (*ptr))
4285 ++ptr;
4286 endp = ptr;
4287 *str = xmemdup0 (line, ptr - line);
4288 }
4289 else if (is_string)
4290 {
4291 char *savedp = input_line_pointer;
4292 int len;
4293
4294 input_line_pointer = ptr;
4295 *str = demand_copy_C_string (&len);
4296 endp = input_line_pointer;
4297 input_line_pointer = savedp;
4298
4299 /* Do forced substitutions if requested. */
4300 if (!nosub && **str == ':')
4301 *str = subsym_substitute (*str, 1);
4302 }
4303 else
4304 {
4305 const char *term = terminators;
4306 char *value = NULL;
4307
4308 while (*ptr && *ptr != *term)
4309 {
4310 if (!*term)
4311 {
4312 term = terminators;
4313 ++ptr;
4314 }
4315 else
4316 ++term;
4317 }
4318 endp = ptr;
4319 *str = xmemdup0 (line, ptr - line);
4320 /* Do simple substitution, if available. */
4321 if (!nosub && (value = subsym_lookup (*str, macro_level)) != NULL)
4322 *str = value;
4323 }
4324
4325 return endp;
4326 }
4327
4328 /* Replace the given substitution string.
4329 We start at the innermost macro level, so that existing locals remain local
4330 Note: we're treating macro args identically to .var's; I don't know if
4331 that's compatible w/TI's assembler. */
4332
4333 static void
4334 subsym_create_or_replace (char *name, char *value)
4335 {
4336 int i;
4337
4338 for (i = macro_level; i > 0; i--)
4339 {
4340 if (hash_find (subsym_hash[i], name))
4341 {
4342 hash_replace (subsym_hash[i], name, value);
4343 return;
4344 }
4345 }
4346 if (hash_find (subsym_hash[0], name))
4347 hash_replace (subsym_hash[0], name, value);
4348 else
4349 hash_insert (subsym_hash[0], name, value);
4350 }
4351
4352 /* Look up the substitution string replacement for the given symbol.
4353 Start with the innermost macro substitution table given and work
4354 outwards. */
4355
4356 static char *
4357 subsym_lookup (char *name, int nest_level)
4358 {
4359 char *value = hash_find (subsym_hash[nest_level], name);
4360
4361 if (value || nest_level == 0)
4362 return value;
4363
4364 return subsym_lookup (name, nest_level - 1);
4365 }
4366
4367 /* Do substitution-symbol replacement on the given line (recursively).
4368 return the argument if no substitution was done
4369
4370 Also look for built-in functions ($func (arg)) and local labels.
4371
4372 If FORCED is set, look for forced substitutions of the form ':SYMBOL:'. */
4373
4374 static char *
4375 subsym_substitute (char *line, int forced)
4376 {
4377 /* For each apparent symbol, see if it's a substitution symbol, and if so,
4378 replace it in the input. */
4379 char *replacement; /* current replacement for LINE. */
4380 char *head; /* Start of line. */
4381 char *ptr; /* Current examination point. */
4382 int changed = 0; /* Did we make a substitution? */
4383 int eval_line = 0; /* Is this line a .eval/.asg statement? */
4384 int eval_symbol = 0; /* Are we in the middle of the symbol for
4385 .eval/.asg? */
4386 char *eval_end = NULL;
4387 int recurse = 1;
4388 int line_conditional = 0;
4389 char *tmp;
4390
4391 /* Work with a copy of the input line. */
4392 replacement = xstrdup (line);
4393
4394 ptr = head = replacement;
4395
4396 /* Flag lines where we might need to replace a single '=' with two;
4397 GAS uses single '=' to assign macro args values, and possibly other
4398 places, so limit what we replace. */
4399 if (strstr (line, ".if")
4400 || strstr (line, ".elseif")
4401 || strstr (line, ".break"))
4402 line_conditional = 1;
4403
4404 /* Watch out for .eval, so that we avoid doing substitution on the
4405 symbol being assigned a value. */
4406 if (strstr (line, ".eval") || strstr (line, ".asg"))
4407 eval_line = 1;
4408
4409 /* If it's a macro definition, don't do substitution on the argument
4410 names. */
4411 if (strstr (line, ".macro"))
4412 return line;
4413
4414 while (!is_end_of_line[(int) *ptr])
4415 {
4416 int current_char = *ptr;
4417
4418 /* Need to update this since LINE may have been modified. */
4419 if (eval_line)
4420 eval_end = strrchr (ptr, ',');
4421
4422 /* Replace triple double quotes with bounding quote/escapes. */
4423 if (current_char == '"' && ptr[1] == '"' && ptr[2] == '"')
4424 {
4425 ptr[1] = '\\';
4426 tmp = strstr (ptr + 2, "\"\"\"");
4427 if (tmp)
4428 tmp[0] = '\\';
4429 changed = 1;
4430 }
4431
4432 /* Replace a single '=' with a '==';
4433 for compatibility with older code only. */
4434 if (line_conditional && current_char == '=')
4435 {
4436 if (ptr[1] == '=')
4437 {
4438 ptr += 2;
4439 continue;
4440 }
4441 *ptr++ = '\0';
4442 tmp = concat (head, "==", ptr, (char *) NULL);
4443 /* Continue examining after the '=='. */
4444 ptr = tmp + strlen (head) + 2;
4445 free (replacement);
4446 head = replacement = tmp;
4447 changed = 1;
4448 }
4449
4450 /* Flag when we've reached the symbol part of .eval/.asg. */
4451 if (eval_line && ptr >= eval_end)
4452 eval_symbol = 1;
4453
4454 /* For each apparent symbol, see if it's a substitution symbol, and if
4455 so, replace it in the input. */
4456 if ((forced && current_char == ':')
4457 || (!forced && is_name_beginner (current_char)))
4458 {
4459 char *name; /* Symbol to be replaced. */
4460 char *savedp = input_line_pointer;
4461 int c;
4462 char *value = NULL;
4463 char *tail; /* Rest of line after symbol. */
4464
4465 /* Skip the colon. */
4466 if (forced)
4467 ++ptr;
4468
4469 input_line_pointer = ptr;
4470 c = get_symbol_name (&name);
4471 /* '?' is not normally part of a symbol, but it IS part of a local
4472 label. */
4473 if (c == '?')
4474 {
4475 *input_line_pointer++ = c;
4476 c = *input_line_pointer;
4477 *input_line_pointer = '\0';
4478 }
4479 /* Avoid infinite recursion; if a symbol shows up a second time for
4480 substitution, leave it as is. */
4481 if (hash_find (subsym_recurse_hash, name) == NULL)
4482 value = subsym_lookup (name, macro_level);
4483 else
4484 as_warn (_("%s symbol recursion stopped at "
4485 "second appearance of '%s'"),
4486 forced ? "Forced substitution" : "Substitution", name);
4487 ptr = tail = input_line_pointer;
4488 input_line_pointer = savedp;
4489
4490 /* Check for local labels; replace them with the appropriate
4491 substitution. */
4492 if ((*name == '$' && ISDIGIT (name[1]) && name[2] == '\0')
4493 || name[strlen (name) - 1] == '?')
4494 {
4495 /* Use an existing identifier for that label if, available, or
4496 create a new, unique identifier. */
4497 value = hash_find (local_label_hash[macro_level], name);
4498 if (value == NULL)
4499 {
4500 char digit[11];
4501 char *namecopy = xstrdup (name);
4502
4503 value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
4504 name);
4505 if (*value != '$')
4506 value[strlen (value) - 1] = '\0';
4507 sprintf (digit, ".%d", local_label_id++);
4508 strcat (value, digit);
4509 hash_insert (local_label_hash[macro_level], namecopy, value);
4510 }
4511 /* Indicate where to continue looking for substitutions. */
4512 ptr = tail;
4513 }
4514 /* Check for built-in subsym and math functions. */
4515 else if (value != NULL && *name == '$')
4516 {
4517 subsym_proc_entry *entry = (subsym_proc_entry *) value;
4518 math_proc_entry *math_entry = hash_find (math_hash, name);
4519 char *arg1, *arg2 = NULL;
4520
4521 *ptr = c;
4522 if (entry == NULL)
4523 {
4524 as_bad (_("Unrecognized substitution symbol function"));
4525 break;
4526 }
4527 else if (*ptr != '(')
4528 {
4529 as_bad (_("Missing '(' after substitution symbol function"));
4530 break;
4531 }
4532 ++ptr;
4533 if (math_entry != NULL)
4534 {
4535 float farg1, farg2 = 0;
4536 volatile float fresult;
4537
4538 farg1 = (float) strtod (ptr, &ptr);
4539 if (math_entry->nargs == 2)
4540 {
4541 if (*ptr++ != ',')
4542 {
4543 as_bad (_("Expecting second argument"));
4544 break;
4545 }
4546 farg2 = (float) strtod (ptr, &ptr);
4547 }
4548 fresult = (*math_entry->proc) (farg1, farg2);
4549 value = XNEWVEC (char, 128);
4550 if (math_entry->int_return)
4551 sprintf (value, "%d", (int) fresult);
4552 else
4553 sprintf (value, "%f", fresult);
4554 if (*ptr++ != ')')
4555 {
4556 as_bad (_("Extra junk in function call, expecting ')'"));
4557 break;
4558 }
4559 /* Don't bother recursing; the replacement isn't a
4560 symbol. */
4561 recurse = 0;
4562 }
4563 else
4564 {
4565 int val;
4566 int arg_type[2] = { *ptr == '"' , 0 };
4567 int ismember = !strcmp (entry->name, "$ismember");
4568
4569 /* Parse one or two args, which must be a substitution
4570 symbol, string or a character-string constant. */
4571 /* For all functions, a string or substitution symbol may be
4572 used, with the following exceptions:
4573 firstch/lastch: 2nd arg must be character constant
4574 ismember: both args must be substitution symbols. */
4575 ptr = subsym_get_arg (ptr, ",)", &arg1, ismember);
4576 if (!arg1)
4577 break;
4578 if (entry->nargs == 2)
4579 {
4580 if (*ptr++ != ',')
4581 {
4582 as_bad (_("Function expects two arguments"));
4583 break;
4584 }
4585 /* Character constants are converted to numerics
4586 by the preprocessor. */
4587 arg_type[1] = (ISDIGIT (*ptr)) ? 2 : (*ptr == '"');
4588 ptr = subsym_get_arg (ptr, ")", &arg2, ismember);
4589 }
4590 /* Args checking. */
4591 if ((!strcmp (entry->name, "$firstch")
4592 || !strcmp (entry->name, "$lastch"))
4593 && arg_type[1] != 2)
4594 {
4595 as_bad (_("Expecting character constant argument"));
4596 break;
4597 }
4598 if (ismember
4599 && (arg_type[0] != 0 || arg_type[1] != 0))
4600 {
4601 as_bad (_("Both arguments must be substitution symbols"));
4602 break;
4603 }
4604 if (*ptr++ != ')')
4605 {
4606 as_bad (_("Extra junk in function call, expecting ')'"));
4607 break;
4608 }
4609 val = (*entry->proc) (arg1, arg2);
4610 value = XNEWVEC (char, 64);
4611 sprintf (value, "%d", val);
4612 }
4613 /* Fix things up to replace the entire expression, not just the
4614 function name. */
4615 tail = ptr;
4616 c = *tail;
4617 }
4618
4619 if (value != NULL && !eval_symbol)
4620 {
4621 /* Replace the symbol with its string replacement and
4622 continue. Recursively replace VALUE until either no
4623 substitutions are performed, or a substitution that has been
4624 previously made is encountered again.
4625
4626 Put the symbol into the recursion hash table so we only
4627 try to replace a symbol once. */
4628 if (recurse)
4629 {
4630 hash_insert (subsym_recurse_hash, name, name);
4631 value = subsym_substitute (value, macro_level > 0);
4632 hash_delete (subsym_recurse_hash, name, FALSE);
4633 }
4634
4635 /* Temporarily zero-terminate where the symbol started. */
4636 *name = 0;
4637 if (forced)
4638 {
4639 if (c == '(')
4640 {
4641 /* Subscripted substitution symbol -- use just the
4642 indicated portion of the string; the description
4643 kinda indicates that forced substitution is not
4644 supposed to be recursive, but I'm not sure. */
4645 unsigned beg, len = 1; /* default to a single char */
4646 char *newval = xstrdup (value);
4647
4648 savedp = input_line_pointer;
4649 input_line_pointer = tail + 1;
4650 beg = get_absolute_expression ();
4651 if (beg < 1)
4652 {
4653 as_bad (_("Invalid subscript (use 1 to %d)"),
4654 (int) strlen (value));
4655 break;
4656 }
4657 if (*input_line_pointer == ',')
4658 {
4659 ++input_line_pointer;
4660 len = get_absolute_expression ();
4661 if (beg + len > strlen (value))
4662 {
4663 as_bad (_("Invalid length (use 0 to %d)"),
4664 (int) strlen (value) - beg);
4665 break;
4666 }
4667 }
4668 newval += beg - 1;
4669 newval[len] = 0;
4670 tail = input_line_pointer;
4671 if (*tail++ != ')')
4672 {
4673 as_bad (_("Missing ')' in subscripted substitution "
4674 "symbol expression"));
4675 break;
4676 }
4677 c = *tail;
4678 input_line_pointer = savedp;
4679
4680 value = newval;
4681 }
4682 name[-1] = 0;
4683 }
4684 tmp = xmalloc (strlen (head) + strlen (value) +
4685 strlen (tail + 1) + 2);
4686 strcpy (tmp, head);
4687 strcat (tmp, value);
4688 /* Make sure forced substitutions are properly terminated. */
4689 if (forced)
4690 {
4691 if (c != ':')
4692 {
4693 as_bad (_("Missing forced substitution terminator ':'"));
4694 break;
4695 }
4696 ++tail;
4697 }
4698 else
4699 /* Restore the character after the symbol end. */
4700 *tail = c;
4701 strcat (tmp, tail);
4702 /* Continue examining after the replacement value. */
4703 ptr = tmp + strlen (head) + strlen (value);
4704 free (replacement);
4705 head = replacement = tmp;
4706 changed = 1;
4707 }
4708 else
4709 *ptr = c;
4710 }
4711 else
4712 {
4713 ++ptr;
4714 }
4715 }
4716
4717 if (changed)
4718 return replacement;
4719 else
4720 return line;
4721 }
4722
4723 /* We use this to handle substitution symbols
4724 hijack input_line_pointer, replacing it with our substituted string.
4725
4726 .sslist should enable listing the line after replacements are made...
4727
4728 returns the new buffer limit. */
4729
4730 void
4731 tic54x_start_line_hook (void)
4732 {
4733 char *line, *endp;
4734 char *replacement = NULL;
4735
4736 /* Work with a copy of the input line, including EOL char. */
4737 endp = input_line_pointer;
4738 while (!is_end_of_line[(int) *endp++])
4739 ;
4740 line = xmemdup0 (input_line_pointer, endp - input_line_pointer);
4741
4742 /* Scan ahead for parallel insns. */
4743 parallel_on_next_line_hint = next_line_shows_parallel (endp);
4744
4745 /* If within a macro, first process forced replacements. */
4746 if (macro_level > 0)
4747 replacement = subsym_substitute (line, 1);
4748 else
4749 replacement = line;
4750 replacement = subsym_substitute (replacement, 0);
4751
4752 if (replacement != line)
4753 {
4754 char *tmp = replacement;
4755 char *comment = strchr (replacement, ';');
4756 char endc = replacement[strlen (replacement) - 1];
4757
4758 /* Clean up the replacement; we'd prefer to have this done by the
4759 standard preprocessing equipment (maybe do_scrub_chars?)
4760 but for now, do a quick-and-dirty. */
4761 if (comment != NULL)
4762 {
4763 comment[0] = endc;
4764 comment[1] = 0;
4765 --comment;
4766 }
4767 else
4768 comment = replacement + strlen (replacement) - 1;
4769
4770 /* Trim trailing whitespace. */
4771 while (ISSPACE (*comment))
4772 {
4773 comment[0] = endc;
4774 comment[1] = 0;
4775 --comment;
4776 }
4777
4778 /* Compact leading whitespace. */
4779 while (ISSPACE (tmp[0]) && ISSPACE (tmp[1]))
4780 ++tmp;
4781
4782 input_line_pointer = endp;
4783 input_scrub_insert_line (tmp);
4784 free (replacement);
4785 free (line);
4786 /* Keep track of whether we've done a substitution. */
4787 substitution_line = 1;
4788 }
4789 else
4790 {
4791 /* No change. */
4792 free (line);
4793 substitution_line = 0;
4794 }
4795 }
4796
4797 /* This is the guts of the machine-dependent assembler. STR points to a
4798 machine dependent instruction. This function is supposed to emit
4799 the frags/bytes it assembles to. */
4800 void
4801 md_assemble (char *line)
4802 {
4803 static int repeat_slot = 0;
4804 static int delay_slots = 0; /* How many delay slots left to fill? */
4805 static int is_parallel = 0;
4806 static tic54x_insn insn;
4807 char *lptr;
4808 char *savedp = input_line_pointer;
4809 int c;
4810
4811 input_line_pointer = line;
4812 c = get_symbol_name (&line);
4813
4814 if (cpu == VNONE)
4815 cpu = V542;
4816 if (address_mode_needs_set)
4817 {
4818 set_address_mode (amode);
4819 address_mode_needs_set = 0;
4820 }
4821 if (cpu_needs_set)
4822 {
4823 set_cpu (cpu);
4824 cpu_needs_set = 0;
4825 }
4826 assembly_begun = 1;
4827
4828 if (is_parallel)
4829 {
4830 is_parallel = 0;
4831
4832 strcpy (insn.parmnemonic, line);
4833 lptr = input_line_pointer;
4834 *lptr = c;
4835 input_line_pointer = savedp;
4836
4837 if (tic54x_parse_parallel_insn_lastline (&insn, lptr))
4838 {
4839 int words = build_insn (&insn);
4840
4841 if (delay_slots != 0)
4842 {
4843 if (words > delay_slots)
4844 {
4845 as_bad (ngettext ("Instruction does not fit in available "
4846 "delay slots (%d-word insn, %d slot left)",
4847 "Instruction does not fit in available "
4848 "delay slots (%d-word insn, %d slots left)",
4849 delay_slots),
4850 words, delay_slots);
4851 delay_slots = 0;
4852 return;
4853 }
4854 delay_slots -= words;
4855 }
4856 }
4857 return;
4858 }
4859
4860 memset (&insn, 0, sizeof (insn));
4861 strcpy (insn.mnemonic, line);
4862 lptr = input_line_pointer;
4863 *lptr = c;
4864 input_line_pointer = savedp;
4865
4866 /* See if this line is part of a parallel instruction; if so, either this
4867 line or the next line will have the "||" specifier preceding the
4868 mnemonic, and we look for it in the parallel insn hash table. */
4869 if (strstr (line, "||") != NULL || parallel_on_next_line_hint)
4870 {
4871 char *tmp = strstr (line, "||");
4872 if (tmp != NULL)
4873 *tmp = '\0';
4874
4875 if (tic54x_parse_parallel_insn_firstline (&insn, lptr))
4876 {
4877 is_parallel = 1;
4878 /* If the parallel part is on the same line, process it now,
4879 otherwise let the assembler pick up the next line for us. */
4880 if (tmp != NULL)
4881 {
4882 while (ISSPACE (tmp[2]))
4883 ++tmp;
4884 md_assemble (tmp + 2);
4885 }
4886 }
4887 else
4888 {
4889 as_bad (_("Unrecognized parallel instruction '%s'"), line);
4890 }
4891 return;
4892 }
4893
4894 if (tic54x_parse_insn (&insn, lptr))
4895 {
4896 int words;
4897
4898 if ((insn.tm->flags & FL_LP)
4899 && cpu != V545LP && cpu != V546LP)
4900 {
4901 as_bad (_("Instruction '%s' requires an LP cpu version"),
4902 insn.tm->name);
4903 return;
4904 }
4905 if ((insn.tm->flags & FL_FAR)
4906 && amode != far_mode)
4907 {
4908 as_bad (_("Instruction '%s' requires far mode addressing"),
4909 insn.tm->name);
4910 return;
4911 }
4912
4913 words = build_insn (&insn);
4914
4915 /* Is this instruction in a delay slot? */
4916 if (delay_slots)
4917 {
4918 if (words > delay_slots)
4919 {
4920 as_warn (ngettext ("Instruction does not fit in available "
4921 "delay slots (%d-word insn, %d slot left). "
4922 "Resulting behavior is undefined.",
4923 "Instruction does not fit in available "
4924 "delay slots (%d-word insn, %d slots left). "
4925 "Resulting behavior is undefined.",
4926 delay_slots),
4927 words, delay_slots);
4928 delay_slots = 0;
4929 return;
4930 }
4931 /* Branches in delay slots are not allowed. */
4932 if (insn.tm->flags & FL_BMASK)
4933 {
4934 as_warn (_("Instructions which cause PC discontinuity are not "
4935 "allowed in a delay slot. "
4936 "Resulting behavior is undefined."));
4937 }
4938 delay_slots -= words;
4939 }
4940
4941 /* Is this instruction the target of a repeat? */
4942 if (repeat_slot)
4943 {
4944 if (insn.tm->flags & FL_NR)
4945 as_warn (_("'%s' is not repeatable. "
4946 "Resulting behavior is undefined."),
4947 insn.tm->name);
4948 else if (insn.is_lkaddr)
4949 as_warn (_("Instructions using long offset modifiers or absolute "
4950 "addresses are not repeatable. "
4951 "Resulting behavior is undefined."));
4952 repeat_slot = 0;
4953 }
4954
4955 /* Make sure we check the target of a repeat instruction. */
4956 if (insn.tm->flags & B_REPEAT)
4957 {
4958 repeat_slot = 1;
4959 /* FIXME -- warn if repeat_slot == 1 at EOF. */
4960 }
4961 /* Make sure we check our delay slots for validity. */
4962 if (insn.tm->flags & FL_DELAY)
4963 {
4964 delay_slots = 2;
4965 /* FIXME -- warn if delay_slots != 0 at EOF. */
4966 }
4967 }
4968 }
4969
4970 /* Do a final adjustment on the symbol table; in this case, make sure we have
4971 a ".file" symbol. */
4972
4973 void
4974 tic54x_adjust_symtab (void)
4975 {
4976 if (symbol_rootP == NULL
4977 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
4978 {
4979 unsigned lineno;
4980 const char * filename = as_where (&lineno);
4981 c_dot_file_symbol (filename, 0);
4982 }
4983 }
4984
4985 /* In order to get gas to ignore any | chars at the start of a line,
4986 this function returns true if a | is found in a line.
4987 This lets us process parallel instructions, which span two lines. */
4988
4989 int
4990 tic54x_unrecognized_line (int c)
4991 {
4992 return c == PARALLEL_SEPARATOR;
4993 }
4994
4995 /* Watch for local labels of the form $[0-9] and [_a-zA-Z][_a-zA-Z0-9]*?
4996 Encode their names so that only we see them and can map them to the
4997 appropriate places.
4998 FIXME -- obviously this isn't done yet. These locals still show up in the
4999 symbol table. */
5000 void
5001 tic54x_define_label (symbolS *sym)
5002 {
5003 /* Just in case we need this later; note that this is not necessarily the
5004 same thing as line_label...
5005 When aligning or assigning labels to fields, sometimes the label is
5006 assigned other than the address at which the label appears.
5007 FIXME -- is this really needed? I think all the proper label assignment
5008 is done in tic54x_cons. */
5009 last_label_seen = sym;
5010 }
5011
5012 /* Try to parse something that normal parsing failed at. */
5013
5014 symbolS *
5015 tic54x_undefined_symbol (char *name)
5016 {
5017 tic54x_symbol *sym;
5018
5019 /* Not sure how to handle predefined symbols. */
5020 if ((sym = (tic54x_symbol *) hash_find (cc_hash, name)) != NULL ||
5021 (sym = (tic54x_symbol *) hash_find (cc2_hash, name)) != NULL ||
5022 (sym = (tic54x_symbol *) hash_find (cc3_hash, name)) != NULL ||
5023 (sym = (tic54x_symbol *) hash_find (misc_symbol_hash, name)) != NULL ||
5024 (sym = (tic54x_symbol *) hash_find (sbit_hash, name)) != NULL)
5025 {
5026 return symbol_new (name, reg_section,
5027 (valueT) sym->value,
5028 &zero_address_frag);
5029 }
5030
5031 if ((sym = (tic54x_symbol *) hash_find (reg_hash, name)) != NULL ||
5032 (sym = (tic54x_symbol *) hash_find (mmreg_hash, name)) != NULL ||
5033 !strcasecmp (name, "a") || !strcasecmp (name, "b"))
5034 {
5035 return symbol_new (name, reg_section,
5036 (valueT) sym ? sym->value : 0,
5037 &zero_address_frag);
5038 }
5039
5040 return NULL;
5041 }
5042
5043 /* Parse a name in an expression before the expression parser takes a stab at
5044 it. */
5045
5046 int
5047 tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
5048 expressionS *expn ATTRIBUTE_UNUSED)
5049 {
5050 return 0;
5051 }
5052
5053 const char *
5054 md_atof (int type, char *literalP, int *sizeP)
5055 {
5056 /* Target data is little-endian, but floats are stored
5057 big-"word"ian. ugh. */
5058 return ieee_md_atof (type, literalP, sizeP, TRUE);
5059 }
5060
5061 arelent *
5062 tc_gen_reloc (asection *section, fixS *fixP)
5063 {
5064 arelent *rel;
5065 bfd_reloc_code_real_type code = fixP->fx_r_type;
5066 asymbol *sym = symbol_get_bfdsym (fixP->fx_addsy);
5067
5068 rel = XNEW (arelent);
5069 rel->sym_ptr_ptr = XNEW (asymbol *);
5070 *rel->sym_ptr_ptr = sym;
5071 /* We assume that all rel->address are host byte offsets. */
5072 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5073 rel->address /= OCTETS_PER_BYTE;
5074 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
5075 if (!strcmp (sym->name, section->name))
5076 rel->howto += HOWTO_BANK;
5077
5078 if (!rel->howto)
5079 {
5080 const char *name = S_GET_NAME (fixP->fx_addsy);
5081 if (name == NULL)
5082 name = "<unknown>";
5083 as_fatal ("Cannot generate relocation type for symbol %s, code %s",
5084 name, bfd_get_reloc_code_name (code));
5085 return NULL;
5086 }
5087 return rel;
5088 }
5089
5090 /* Handle cons expressions. */
5091
5092 void
5093 tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
5094 bfd_reloc_code_real_type r)
5095 {
5096 switch (octets)
5097 {
5098 default:
5099 as_bad (_("Unsupported relocation size %d"), octets);
5100 r = BFD_RELOC_TIC54X_16_OF_23;
5101 break;
5102 case 2:
5103 r = BFD_RELOC_TIC54X_16_OF_23;
5104 break;
5105 case 4:
5106 /* TI assembler always uses this, regardless of addressing mode. */
5107 if (emitting_long)
5108 r = BFD_RELOC_TIC54X_23;
5109 else
5110 /* We never want to directly generate this; this is provided for
5111 stabs support only. */
5112 r = BFD_RELOC_32;
5113 break;
5114 }
5115 fix_new_exp (frag, where, octets, expn, 0, r);
5116 }
5117
5118 /* Attempt to simplify or even eliminate a fixup.
5119 To indicate that a fixup has been eliminated, set fixP->fx_done.
5120
5121 If fixp->fx_addsy is non-NULL, we'll have to generate a reloc entry. */
5122
5123 void
5124 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
5125 {
5126 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5127 valueT val = * valP;
5128
5129 switch (fixP->fx_r_type)
5130 {
5131 default:
5132 as_fatal ("Bad relocation type: 0x%02x", fixP->fx_r_type);
5133 return;
5134 case BFD_RELOC_TIC54X_MS7_OF_23:
5135 val = (val >> 16) & 0x7F;
5136 /* Fall through. */
5137 case BFD_RELOC_TIC54X_16_OF_23:
5138 case BFD_RELOC_16:
5139 bfd_put_16 (stdoutput, val, buf);
5140 /* Indicate what we're actually writing, so that we don't get warnings
5141 about exceeding available space. */
5142 *valP = val & 0xFFFF;
5143 break;
5144 case BFD_RELOC_TIC54X_PARTLS7:
5145 bfd_put_16 (stdoutput,
5146 (bfd_get_16 (stdoutput, buf) & 0xFF80) | (val & 0x7F),
5147 buf);
5148 /* Indicate what we're actually writing, so that we don't get warnings
5149 about exceeding available space. */
5150 *valP = val & 0x7F;
5151 break;
5152 case BFD_RELOC_TIC54X_PARTMS9:
5153 /* TI assembler doesn't shift its encoding for relocatable files, and is
5154 thus incompatible with this implementation's relocatable files. */
5155 bfd_put_16 (stdoutput,
5156 (bfd_get_16 (stdoutput, buf) & 0xFE00) | (val >> 7),
5157 buf);
5158 break;
5159 case BFD_RELOC_32:
5160 case BFD_RELOC_TIC54X_23:
5161 bfd_put_32 (stdoutput,
5162 (bfd_get_32 (stdoutput, buf) & 0xFF800000) | val,
5163 buf);
5164 break;
5165 }
5166
5167 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
5168 fixP->fx_done = 1;
5169 }
5170
5171 /* This is our chance to record section alignment
5172 don't need to do anything here, since BFD does the proper encoding. */
5173
5174 valueT
5175 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT section_size)
5176 {
5177 return section_size;
5178 }
5179
5180 long
5181 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
5182 {
5183 return 0;
5184 }
5185
5186 /* Mostly little-endian, but longwords (4 octets) get MS word stored
5187 first. */
5188
5189 void
5190 tic54x_number_to_chars (char *buf, valueT val, int n)
5191 {
5192 if (n != 4)
5193 number_to_chars_littleendian (buf, val, n);
5194 else
5195 {
5196 number_to_chars_littleendian (buf , val >> 16 , 2);
5197 number_to_chars_littleendian (buf + 2, val & 0xFFFF, 2);
5198 }
5199 }
5200
5201 int
5202 tic54x_estimate_size_before_relax (fragS *frag ATTRIBUTE_UNUSED,
5203 segT seg ATTRIBUTE_UNUSED)
5204 {
5205 return 0;
5206 }
5207
5208 /* We use this to handle bit allocations which we couldn't handle before due
5209 to symbols being in different frags. return number of octets added. */
5210
5211 int
5212 tic54x_relax_frag (fragS *frag, long stretch ATTRIBUTE_UNUSED)
5213 {
5214 symbolS *sym = frag->fr_symbol;
5215 int growth = 0;
5216 int i;
5217
5218 if (sym != NULL)
5219 {
5220 struct bit_info *bi = (struct bit_info *) frag->fr_opcode;
5221 int bit_offset = frag_bit_offset (frag_prev (frag, bi->seg), bi->seg);
5222 int size = S_GET_VALUE (sym);
5223 fragS *prev_frag = bit_offset_frag (frag_prev (frag, bi->seg), bi->seg);
5224 int available = 16 - bit_offset;
5225
5226 if (symbol_get_frag (sym) != &zero_address_frag
5227 || S_IS_COMMON (sym)
5228 || !S_IS_DEFINED (sym))
5229 as_bad_where (frag->fr_file, frag->fr_line,
5230 _("non-absolute value used with .space/.bes"));
5231
5232 if (size < 0)
5233 {
5234 as_warn (_("negative value ignored in %s"),
5235 bi->type == TYPE_SPACE ? ".space" :
5236 bi->type == TYPE_BES ? ".bes" : ".field");
5237 growth = 0;
5238 frag->tc_frag_data = frag->fr_fix = 0;
5239 return 0;
5240 }
5241
5242 if (bi->type == TYPE_FIELD)
5243 {
5244 /* Bit fields of 16 or larger will have already been handled. */
5245 if (bit_offset != 0 && available >= size)
5246 {
5247 char *p = prev_frag->fr_literal;
5248
5249 valueT value = bi->value;
5250 value <<= available - size;
5251 value |= ((unsigned short) p[1] << 8) | p[0];
5252 md_number_to_chars (p, value, 2);
5253 if ((prev_frag->tc_frag_data += size) == 16)
5254 prev_frag->tc_frag_data = 0;
5255 if (bi->sym)
5256 symbol_set_frag (bi->sym, prev_frag);
5257 /* This frag is no longer used. */
5258 growth = -frag->fr_fix;
5259 frag->fr_fix = 0;
5260 frag->tc_frag_data = 0;
5261 }
5262 else
5263 {
5264 char *p = frag->fr_literal;
5265
5266 valueT value = bi->value << (16 - size);
5267 md_number_to_chars (p, value, 2);
5268 if ((frag->tc_frag_data = size) == 16)
5269 frag->tc_frag_data = 0;
5270 growth = 0;
5271 }
5272 }
5273 else
5274 {
5275 if (bit_offset != 0 && bit_offset < 16)
5276 {
5277 if (available >= size)
5278 {
5279 if ((prev_frag->tc_frag_data += size) == 16)
5280 prev_frag->tc_frag_data = 0;
5281 if (bi->sym)
5282 symbol_set_frag (bi->sym, prev_frag);
5283 /* This frag is no longer used. */
5284 growth = -frag->fr_fix;
5285 frag->fr_fix = 0;
5286 frag->tc_frag_data = 0;
5287 goto getout;
5288 }
5289 if (bi->type == TYPE_SPACE && bi->sym)
5290 symbol_set_frag (bi->sym, prev_frag);
5291 size -= available;
5292 }
5293 growth = (size + 15) / 16 * OCTETS_PER_BYTE - frag->fr_fix;
5294 for (i = 0; i < growth; i++)
5295 frag->fr_literal[i] = 0;
5296 frag->fr_fix = growth;
5297 frag->tc_frag_data = size % 16;
5298 /* Make sure any BES label points to the LAST word allocated. */
5299 if (bi->type == TYPE_BES && bi->sym)
5300 S_SET_VALUE (bi->sym, frag->fr_fix / OCTETS_PER_BYTE - 1);
5301 }
5302 getout:
5303 frag->fr_symbol = 0;
5304 frag->fr_opcode = 0;
5305 free ((void *) bi);
5306 }
5307 return growth;
5308 }
5309
5310 void
5311 tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
5312 segT seg ATTRIBUTE_UNUSED,
5313 fragS *frag)
5314 {
5315 /* Offset is in bytes. */
5316 frag->fr_offset = (frag->fr_next->fr_address
5317 - frag->fr_address
5318 - frag->fr_fix) / frag->fr_var;
5319 if (frag->fr_offset < 0)
5320 {
5321 as_bad_where (frag->fr_file, frag->fr_line,
5322 _("attempt to .space/.bes backwards? (%ld)"),
5323 (long) frag->fr_offset);
5324 }
5325 frag->fr_type = rs_space;
5326 }
5327
5328 /* We need to avoid having labels defined for certain directives/pseudo-ops
5329 since once the label is defined, it's in the symbol table for good. TI
5330 syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
5331 I guess, except I've never seen a definition of MRI syntax).
5332
5333 Don't allow labels to start with '.' */
5334
5335 int
5336 tic54x_start_label (int nul_char, int next_char)
5337 {
5338 char *rest;
5339
5340 /* If within .struct/.union, no auto line labels, please. */
5341 if (current_stag != NULL)
5342 return 0;
5343
5344 /* Disallow labels starting with "." */
5345 if (next_char != ':')
5346 {
5347 char *label = input_line_pointer;
5348
5349 while (!is_end_of_line[(int) label[-1]])
5350 --label;
5351 if (*label == '.')
5352 {
5353 as_bad (_("Invalid label '%s'"), label);
5354 return 0;
5355 }
5356 }
5357
5358 if (is_end_of_line[(int) next_char])
5359 return 1;
5360
5361 rest = input_line_pointer;
5362 if (nul_char == '"')
5363 ++rest;
5364 while (ISSPACE (next_char))
5365 next_char = *++rest;
5366 if (next_char != '.')
5367 return 1;
5368
5369 /* Don't let colon () define a label for any of these... */
5370 return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
5371 && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
5372 && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
5373 && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
5374 && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
5375 && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
5376 }