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