OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [tc-tic54x.c] - Blame information for rev 832

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.