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