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