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