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