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