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