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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [tc-arc.c] - Blame information for rev 307

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

Line No. Rev Author Line
1 38 julius
/* tc-arc.c -- Assembler for the ARC
2
   Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007  Free Software Foundation, Inc.
4
   Contributed by Doug Evans (dje@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
#include "as.h"
24
#include "struc-symbol.h"
25
#include "safe-ctype.h"
26
#include "subsegs.h"
27
#include "opcode/arc.h"
28
#include "../opcodes/arc-ext.h"
29
#include "elf/arc.h"
30
#include "dwarf2dbg.h"
31
 
32
const struct suffix_classes
33
{
34
  char *name;
35
  int  len;
36
} suffixclass[] =
37
{
38
  { "SUFFIX_COND|SUFFIX_FLAG",23 },
39
  { "SUFFIX_FLAG", 11 },
40
  { "SUFFIX_COND", 11 },
41
  { "SUFFIX_NONE", 11 }
42
};
43
 
44
#define MAXSUFFIXCLASS (sizeof (suffixclass) / sizeof (struct suffix_classes))
45
 
46
const struct syntax_classes
47
{
48
  char *name;
49
  int  len;
50
  int  class;
51
} syntaxclass[] =
52
{
53
  { "SYNTAX_3OP|OP1_MUST_BE_IMM", 26, SYNTAX_3OP|OP1_MUST_BE_IMM|SYNTAX_VALID },
54
  { "OP1_MUST_BE_IMM|SYNTAX_3OP", 26, OP1_MUST_BE_IMM|SYNTAX_3OP|SYNTAX_VALID },
55
  { "SYNTAX_2OP|OP1_IMM_IMPLIED", 26, SYNTAX_2OP|OP1_IMM_IMPLIED|SYNTAX_VALID },
56
  { "OP1_IMM_IMPLIED|SYNTAX_2OP", 26, OP1_IMM_IMPLIED|SYNTAX_2OP|SYNTAX_VALID },
57
  { "SYNTAX_3OP",                 10, SYNTAX_3OP|SYNTAX_VALID },
58
  { "SYNTAX_2OP",                 10, SYNTAX_2OP|SYNTAX_VALID }
59
};
60
 
61
#define MAXSYNTAXCLASS (sizeof (syntaxclass) / sizeof (struct syntax_classes))
62
 
63
/* This array holds the chars that always start a comment.  If the
64
   pre-processor is disabled, these aren't very useful.  */
65
const char comment_chars[] = "#;";
66
 
67
/* This array holds the chars that only start a comment at the beginning of
68
   a line.  If the line seems to have the form '# 123 filename'
69
   .line and .file directives will appear in the pre-processed output */
70
/* Note that input_file.c hand checks for '#' at the beginning of the
71
   first line of the input file.  This is because the compiler outputs
72
   #NO_APP at the beginning of its output.  */
73
/* Also note that comments started like this one will always
74
   work if '/' isn't otherwise defined.  */
75
const char line_comment_chars[] = "#";
76
 
77
const char line_separator_chars[] = "";
78
 
79
/* Chars that can be used to separate mant from exp in floating point nums.  */
80
const char EXP_CHARS[] = "eE";
81
 
82
/* Chars that mean this number is a floating point constant
83
   As in 0f12.456 or 0d1.2345e12.  */
84
const char FLT_CHARS[] = "rRsSfFdD";
85
 
86
/* Byte order.  */
87
extern int target_big_endian;
88
const char *arc_target_format = DEFAULT_TARGET_FORMAT;
89
static int byte_order = DEFAULT_BYTE_ORDER;
90
 
91
static segT arcext_section;
92
 
93
/* One of bfd_mach_arc_n.  */
94
static int arc_mach_type = bfd_mach_arc_6;
95
 
96
/* Non-zero if the cpu type has been explicitly specified.  */
97
static int mach_type_specified_p = 0;
98
 
99
/* Non-zero if opcode tables have been initialized.
100
   A .option command must appear before any instructions.  */
101
static int cpu_tables_init_p = 0;
102
 
103
static struct hash_control *arc_suffix_hash = NULL;
104
 
105
const char *md_shortopts = "";
106
 
107
enum options
108
{
109
  OPTION_EB = OPTION_MD_BASE,
110
  OPTION_EL,
111
  OPTION_ARC5,
112
  OPTION_ARC6,
113
  OPTION_ARC7,
114
  OPTION_ARC8,
115
  OPTION_ARC
116
};
117
 
118
struct option md_longopts[] =
119
{
120
  { "EB", no_argument, NULL, OPTION_EB },
121
  { "EL", no_argument, NULL, OPTION_EL },
122
  { "marc5", no_argument, NULL, OPTION_ARC5 },
123
  { "pre-v6", no_argument, NULL, OPTION_ARC5 },
124
  { "marc6", no_argument, NULL, OPTION_ARC6 },
125
  { "marc7", no_argument, NULL, OPTION_ARC7 },
126
  { "marc8", no_argument, NULL, OPTION_ARC8 },
127
  { "marc", no_argument, NULL, OPTION_ARC },
128
  { NULL, no_argument, NULL, 0 }
129
};
130
size_t md_longopts_size = sizeof (md_longopts);
131
 
132
#define IS_SYMBOL_OPERAND(o) \
133
 ((o) == 'b' || (o) == 'c' || (o) == 's' || (o) == 'o' || (o) == 'O')
134
 
135
struct arc_operand_value *get_ext_suffix (char *s);
136
 
137
/* Invocation line includes a switch not recognized by the base assembler.
138
   See if it's a processor-specific option.  */
139
 
140
int
141
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
142
{
143
  switch (c)
144
    {
145
    case OPTION_ARC5:
146
      arc_mach_type = bfd_mach_arc_5;
147
      break;
148
    case OPTION_ARC:
149
    case OPTION_ARC6:
150
      arc_mach_type = bfd_mach_arc_6;
151
      break;
152
    case OPTION_ARC7:
153
      arc_mach_type = bfd_mach_arc_7;
154
      break;
155
    case OPTION_ARC8:
156
      arc_mach_type = bfd_mach_arc_8;
157
      break;
158
    case OPTION_EB:
159
      byte_order = BIG_ENDIAN;
160
      arc_target_format = "elf32-bigarc";
161
      break;
162
    case OPTION_EL:
163
      byte_order = LITTLE_ENDIAN;
164
      arc_target_format = "elf32-littlearc";
165
      break;
166
    default:
167
      return 0;
168
    }
169
  return 1;
170
}
171
 
172
void
173
md_show_usage (FILE *stream)
174
{
175
  fprintf (stream, "\
176
ARC Options:\n\
177
  -marc[5|6|7|8]          select processor variant (default arc%d)\n\
178
  -EB                     assemble code for a big endian cpu\n\
179
  -EL                     assemble code for a little endian cpu\n", arc_mach_type + 5);
180
}
181
 
182
/* This function is called once, at assembler startup time.  It should
183
   set up all the tables, etc. that the MD part of the assembler will need.
184
   Opcode selection is deferred until later because we might see a .option
185
   command.  */
186
 
187
void
188
md_begin (void)
189
{
190
  /* The endianness can be chosen "at the factory".  */
191
  target_big_endian = byte_order == BIG_ENDIAN;
192
 
193
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
194
    as_warn (_("could not set architecture and machine"));
195
 
196
  /* This call is necessary because we need to initialize `arc_operand_map'
197
     which may be needed before we see the first insn.  */
198
  arc_opcode_init_tables (arc_get_opcode_mach (arc_mach_type,
199
                                               target_big_endian));
200
}
201
 
202
/* Initialize the various opcode and operand tables.
203
   MACH is one of bfd_mach_arc_xxx.  */
204
 
205
static void
206
init_opcode_tables (int mach)
207
{
208
  int i;
209
  char *last;
210
 
211
  if ((arc_suffix_hash = hash_new ()) == NULL)
212
    as_fatal (_("virtual memory exhausted"));
213
 
214
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
215
    as_warn (_("could not set architecture and machine"));
216
 
217
  /* This initializes a few things in arc-opc.c that we need.
218
     This must be called before the various arc_xxx_supported fns.  */
219
  arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
220
 
221
  /* Only put the first entry of each equivalently named suffix in the
222
     table.  */
223
  last = "";
224
  for (i = 0; i < arc_suffixes_count; i++)
225
    {
226
      if (strcmp (arc_suffixes[i].name, last) != 0)
227
        hash_insert (arc_suffix_hash, arc_suffixes[i].name, (void *) (arc_suffixes + i));
228
      last = arc_suffixes[i].name;
229
    }
230
 
231
  /* Since registers don't have a prefix, we put them in the symbol table so
232
     they can't be used as symbols.  This also simplifies argument parsing as
233
     we can let gas parse registers for us.  The recorded register number is
234
     the address of the register's entry in arc_reg_names.
235
 
236
     If the register name is already in the table, then the existing
237
     definition is assumed to be from an .ExtCoreRegister pseudo-op.  */
238
 
239
  for (i = 0; i < arc_reg_names_count; i++)
240
    {
241
      if (symbol_find (arc_reg_names[i].name))
242
        continue;
243
      /* Use symbol_create here instead of symbol_new so we don't try to
244
         output registers into the object file's symbol table.  */
245
      symbol_table_insert (symbol_create (arc_reg_names[i].name,
246
                                          reg_section,
247
                                          (valueT) &arc_reg_names[i],
248
                                          &zero_address_frag));
249
    }
250
 
251
  /* Tell `.option' it's too late.  */
252
  cpu_tables_init_p = 1;
253
}
254
 
255
/* Insert an operand value into an instruction.
256
   If REG is non-NULL, it is a register number and ignore VAL.  */
257
 
258
static arc_insn
259
arc_insert_operand (arc_insn insn,
260
                    const struct arc_operand *operand,
261
                    int mods,
262
                    const struct arc_operand_value *reg,
263
                    offsetT val,
264
                    char *file,
265
                    unsigned int line)
266
{
267
  if (operand->bits != 32)
268
    {
269
      long min, max;
270
      offsetT test;
271
 
272
      if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
273
        {
274
          if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
275
            max = (1 << operand->bits) - 1;
276
          else
277
            max = (1 << (operand->bits - 1)) - 1;
278
          min = - (1 << (operand->bits - 1));
279
        }
280
      else
281
        {
282
          max = (1 << operand->bits) - 1;
283
          min = 0;
284
        }
285
 
286
      if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
287
        test = - val;
288
      else
289
        test = val;
290
 
291
      if (test < (offsetT) min || test > (offsetT) max)
292
        as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
293
    }
294
 
295
  if (operand->insert)
296
    {
297
      const char *errmsg;
298
 
299
      errmsg = NULL;
300
      insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
301
      if (errmsg != (const char *) NULL)
302
        as_warn (errmsg);
303
    }
304
  else
305
    insn |= (((long) val & ((1 << operand->bits) - 1))
306
             << operand->shift);
307
 
308
  return insn;
309
}
310
 
311
/* We need to keep a list of fixups.  We can't simply generate them as
312
   we go, because that would require us to first create the frag, and
313
   that would screw up references to ``.''.  */
314
 
315
struct arc_fixup
316
{
317
  /* index into `arc_operands'  */
318
  int opindex;
319
  expressionS exp;
320
};
321
 
322
#define MAX_FIXUPS 5
323
 
324
#define MAX_SUFFIXES 5
325
 
326
/* Compute the reloc type of an expression.
327
   The possibly modified expression is stored in EXPNEW.
328
 
329
   This is used to convert the expressions generated by the %-op's into
330
   the appropriate operand type.  It is called for both data in instructions
331
   (operands) and data outside instructions (variables, debugging info, etc.).
332
 
333
   Currently supported %-ops:
334
 
335
   %st(symbol): represented as "symbol >> 2"
336
                "st" is short for STatus as in the status register (pc)
337
 
338
   DEFAULT_TYPE is the type to use if no special processing is required.
339
 
340
   DATA_P is non-zero for data or limm values, zero for insn operands.
341
   Remember that the opcode "insertion fns" cannot be used on data, they're
342
   only for inserting operands into insns.  They also can't be used for limm
343
   values as the insertion routines don't handle limm values.  When called for
344
   insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED).  When
345
   called for data or limm values we use real reloc types.  */
346
 
347
static int
348
get_arc_exp_reloc_type (int data_p,
349
                        int default_type,
350
                        expressionS *exp,
351
                        expressionS *expnew)
352
{
353
  /* If the expression is "symbol >> 2" we must change it to just "symbol",
354
     as fix_new_exp can't handle it.  Similarly for (symbol - symbol) >> 2.
355
     That's ok though.  What's really going on here is that we're using
356
     ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26.  */
357
 
358
  if (exp->X_op == O_right_shift
359
      && exp->X_op_symbol != NULL
360
      && exp->X_op_symbol->sy_value.X_op == O_constant
361
      && exp->X_op_symbol->sy_value.X_add_number == 2
362
      && exp->X_add_number == 0)
363
    {
364
      if (exp->X_add_symbol != NULL
365
          && (exp->X_add_symbol->sy_value.X_op == O_constant
366
              || exp->X_add_symbol->sy_value.X_op == O_symbol))
367
        {
368
          *expnew = *exp;
369
          expnew->X_op = O_symbol;
370
          expnew->X_op_symbol = NULL;
371
          return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
372
        }
373
      else if (exp->X_add_symbol != NULL
374
               && exp->X_add_symbol->sy_value.X_op == O_subtract)
375
        {
376
          *expnew = exp->X_add_symbol->sy_value;
377
          return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
378
        }
379
    }
380
 
381
  *expnew = *exp;
382
  return default_type;
383
}
384
 
385
static int
386
arc_set_ext_seg (void)
387
{
388
  if (!arcext_section)
389
    {
390
      arcext_section = subseg_new (".arcextmap", 0);
391
      bfd_set_section_flags (stdoutput, arcext_section,
392
                             SEC_READONLY | SEC_HAS_CONTENTS);
393
    }
394
  else
395
    subseg_set (arcext_section, 0);
396
  return 1;
397
}
398
 
399
static void
400
arc_extoper (int opertype)
401
{
402
  char *name;
403
  char *mode;
404
  char c;
405
  char *p;
406
  int imode = 0;
407
  int number;
408
  struct arc_ext_operand_value *ext_oper;
409
  symbolS *symbolP;
410
 
411
  segT old_sec;
412
  int old_subsec;
413
 
414
  name = input_line_pointer;
415
  c = get_symbol_end ();
416
  name = xstrdup (name);
417
 
418
  p = name;
419
  while (*p)
420
    {
421
      *p = TOLOWER (*p);
422
      p++;
423
    }
424
 
425
  /* just after name is now '\0'  */
426
  p = input_line_pointer;
427
  *p = c;
428
  SKIP_WHITESPACE ();
429
 
430
  if (*input_line_pointer != ',')
431
    {
432
      as_bad (_("expected comma after operand name"));
433
      ignore_rest_of_line ();
434
      free (name);
435
      return;
436
    }
437
 
438
  input_line_pointer++;         /* skip ','  */
439
  number = get_absolute_expression ();
440
 
441
  if (number < 0)
442
    {
443
      as_bad (_("negative operand number %d"), number);
444
      ignore_rest_of_line ();
445
      free (name);
446
      return;
447
    }
448
 
449
  if (opertype)
450
    {
451
      SKIP_WHITESPACE ();
452
 
453
      if (*input_line_pointer != ',')
454
        {
455
          as_bad (_("expected comma after register-number"));
456
          ignore_rest_of_line ();
457
          free (name);
458
          return;
459
        }
460
 
461
      input_line_pointer++;             /* skip ','  */
462
      mode = input_line_pointer;
463
 
464
      if (!strncmp (mode, "r|w", 3))
465
        {
466
          imode = 0;
467
          input_line_pointer += 3;
468
        }
469
      else
470
        {
471
          if (!strncmp (mode, "r", 1))
472
            {
473
              imode = ARC_REGISTER_READONLY;
474
              input_line_pointer += 1;
475
            }
476
          else
477
            {
478
              if (strncmp (mode, "w", 1))
479
                {
480
                  as_bad (_("invalid mode"));
481
                  ignore_rest_of_line ();
482
                  free (name);
483
                  return;
484
                }
485
              else
486
                {
487
                  imode = ARC_REGISTER_WRITEONLY;
488
                  input_line_pointer += 1;
489
                }
490
            }
491
        }
492
      SKIP_WHITESPACE ();
493
      if (1 == opertype)
494
        {
495
          if (*input_line_pointer != ',')
496
            {
497
              as_bad (_("expected comma after register-mode"));
498
              ignore_rest_of_line ();
499
              free (name);
500
              return;
501
            }
502
 
503
          input_line_pointer++;         /* skip ','  */
504
 
505
          if (!strncmp (input_line_pointer, "cannot_shortcut", 15))
506
            {
507
              imode |= arc_get_noshortcut_flag ();
508
              input_line_pointer += 15;
509
            }
510
          else
511
            {
512
              if (strncmp (input_line_pointer, "can_shortcut", 12))
513
                {
514
                  as_bad (_("shortcut designator invalid"));
515
                  ignore_rest_of_line ();
516
                  free (name);
517
                  return;
518
                }
519
              else
520
                {
521
                  input_line_pointer += 12;
522
                }
523
            }
524
        }
525
    }
526
 
527
  if ((opertype == 1) && number > 60)
528
    {
529
      as_bad (_("core register value (%d) too large"), number);
530
      ignore_rest_of_line ();
531
      free (name);
532
      return;
533
    }
534
 
535
  if ((opertype == 0) && number > 31)
536
    {
537
      as_bad (_("condition code value (%d) too large"), number);
538
      ignore_rest_of_line ();
539
      free (name);
540
      return;
541
    }
542
 
543
  ext_oper = xmalloc (sizeof (struct arc_ext_operand_value));
544
 
545
  if (opertype)
546
    {
547
      /* If the symbol already exists, point it at the new definition.  */
548
      if ((symbolP = symbol_find (name)))
549
        {
550
          if (S_GET_SEGMENT (symbolP) == reg_section)
551
            S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
552
          else
553
            {
554
              as_bad (_("attempt to override symbol: %s"), name);
555
              ignore_rest_of_line ();
556
              free (name);
557
              free (ext_oper);
558
              return;
559
            }
560
        }
561
      else
562
        {
563
          /* If its not there, add it.  */
564
          symbol_table_insert (symbol_create (name, reg_section,
565
                                              (valueT) &ext_oper->operand,
566
                                              &zero_address_frag));
567
        }
568
    }
569
 
570
  ext_oper->operand.name  = name;
571
  ext_oper->operand.value = number;
572
  ext_oper->operand.type  = arc_operand_type (opertype);
573
  ext_oper->operand.flags = imode;
574
 
575
  ext_oper->next = arc_ext_operands;
576
  arc_ext_operands = ext_oper;
577
 
578
  /* OK, now that we know what this operand is, put a description in
579
     the arc extension section of the output file.  */
580
 
581
  old_sec    = now_seg;
582
  old_subsec = now_subseg;
583
 
584
  arc_set_ext_seg ();
585
 
586
  switch (opertype)
587
    {
588
    case 0:
589
      p = frag_more (1);
590
      *p = 3 + strlen (name) + 1;
591
      p = frag_more (1);
592
      *p = EXT_COND_CODE;
593
      p = frag_more (1);
594
      *p = number;
595
      p = frag_more (strlen (name) + 1);
596
      strcpy (p, name);
597
      break;
598
    case 1:
599
      p = frag_more (1);
600
      *p = 3 + strlen (name) + 1;
601
      p = frag_more (1);
602
      *p = EXT_CORE_REGISTER;
603
      p = frag_more (1);
604
      *p = number;
605
      p = frag_more (strlen (name) + 1);
606
      strcpy (p, name);
607
      break;
608
    case 2:
609
      p = frag_more (1);
610
      *p = 6 + strlen (name) + 1;
611
      p = frag_more (1);
612
      *p = EXT_AUX_REGISTER;
613
      p = frag_more (1);
614
      *p = number >> 24 & 0xff;
615
      p = frag_more (1);
616
      *p = number >> 16 & 0xff;
617
      p = frag_more (1);
618
      *p = number >>  8 & 0xff;
619
      p = frag_more (1);
620
      *p = number       & 0xff;
621
      p = frag_more (strlen (name) + 1);
622
      strcpy (p, name);
623
      break;
624
    default:
625
      as_bad (_("invalid opertype"));
626
      ignore_rest_of_line ();
627
      free (name);
628
      return;
629
      break;
630
    }
631
 
632
  subseg_set (old_sec, old_subsec);
633
 
634
  /* Enter all registers into the symbol table.  */
635
 
636
  demand_empty_rest_of_line ();
637
}
638
 
639
static void
640
arc_extinst (int ignore ATTRIBUTE_UNUSED)
641
{
642
  char syntax[129];
643
  char *name;
644
  char *p;
645
  char c;
646
  int suffixcode = -1;
647
  int opcode, subopcode;
648
  int i;
649
  int class = 0;
650
  int name_len;
651
  struct arc_opcode *ext_op;
652
 
653
  segT old_sec;
654
  int old_subsec;
655
 
656
  name = input_line_pointer;
657
  c = get_symbol_end ();
658
  name = xstrdup (name);
659
  strcpy (syntax, name);
660
  name_len = strlen (name);
661
 
662
  /* just after name is now '\0'  */
663
  p = input_line_pointer;
664
  *p = c;
665
 
666
  SKIP_WHITESPACE ();
667
 
668
  if (*input_line_pointer != ',')
669
    {
670
      as_bad (_("expected comma after operand name"));
671
      ignore_rest_of_line ();
672
      return;
673
    }
674
 
675
  input_line_pointer++;         /* skip ','  */
676
  opcode = get_absolute_expression ();
677
 
678
  SKIP_WHITESPACE ();
679
 
680
  if (*input_line_pointer != ',')
681
    {
682
      as_bad (_("expected comma after opcode"));
683
      ignore_rest_of_line ();
684
      return;
685
    }
686
 
687
  input_line_pointer++;         /* skip ','  */
688
  subopcode = get_absolute_expression ();
689
 
690
  if (subopcode < 0)
691
    {
692
      as_bad (_("negative subopcode %d"), subopcode);
693
      ignore_rest_of_line ();
694
      return;
695
    }
696
 
697
  if (subopcode)
698
    {
699
      if (3 != opcode)
700
        {
701
          as_bad (_("subcode value found when opcode not equal 0x03"));
702
          ignore_rest_of_line ();
703
          return;
704
        }
705
      else
706
        {
707
          if (subopcode < 0x09 || subopcode == 0x3f)
708
            {
709
              as_bad (_("invalid subopcode %d"), subopcode);
710
              ignore_rest_of_line ();
711
              return;
712
            }
713
        }
714
    }
715
 
716
  SKIP_WHITESPACE ();
717
 
718
  if (*input_line_pointer != ',')
719
    {
720
      as_bad (_("expected comma after subopcode"));
721
      ignore_rest_of_line ();
722
      return;
723
    }
724
 
725
  input_line_pointer++;         /* skip ','  */
726
 
727
  for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
728
    {
729
      if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
730
        {
731
          suffixcode = i;
732
          input_line_pointer += suffixclass[i].len;
733
          break;
734
        }
735
    }
736
 
737
  if (-1 == suffixcode)
738
    {
739
      as_bad (_("invalid suffix class"));
740
      ignore_rest_of_line ();
741
      return;
742
    }
743
 
744
  SKIP_WHITESPACE ();
745
 
746
  if (*input_line_pointer != ',')
747
    {
748
      as_bad (_("expected comma after suffix class"));
749
      ignore_rest_of_line ();
750
      return;
751
    }
752
 
753
  input_line_pointer++;         /* skip ','  */
754
 
755
  for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
756
    {
757
      if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
758
        {
759
          class = syntaxclass[i].class;
760
          input_line_pointer += syntaxclass[i].len;
761
          break;
762
        }
763
    }
764
 
765
  if (0 == (SYNTAX_VALID & class))
766
    {
767
      as_bad (_("invalid syntax class"));
768
      ignore_rest_of_line ();
769
      return;
770
    }
771
 
772
  if ((0x3 == opcode) & (class & SYNTAX_3OP))
773
    {
774
      as_bad (_("opcode 0x3 and SYNTAX_3OP invalid"));
775
      ignore_rest_of_line ();
776
      return;
777
    }
778
 
779
  switch (suffixcode)
780
    {
781
    case 0:
782
      strcat (syntax, "%.q%.f ");
783
      break;
784
    case 1:
785
      strcat (syntax, "%.f ");
786
      break;
787
    case 2:
788
      strcat (syntax, "%.q ");
789
      break;
790
    case 3:
791
      strcat (syntax, " ");
792
      break;
793
    default:
794
      as_bad (_("unknown suffix class"));
795
      ignore_rest_of_line ();
796
      return;
797
      break;
798
    };
799
 
800
  strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
801
  if (suffixcode < 2)
802
    strcat (syntax, "%F");
803
  strcat (syntax, "%S%L");
804
 
805
  ext_op = xmalloc (sizeof (struct arc_opcode));
806
  ext_op->syntax = xstrdup (syntax);
807
 
808
  ext_op->mask  = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
809
  ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
810
  ext_op->flags = class;
811
  ext_op->next_asm = arc_ext_opcodes;
812
  ext_op->next_dis = arc_ext_opcodes;
813
  arc_ext_opcodes = ext_op;
814
 
815
  /* OK, now that we know what this inst is, put a description in the
816
     arc extension section of the output file.  */
817
 
818
  old_sec    = now_seg;
819
  old_subsec = now_subseg;
820
 
821
  arc_set_ext_seg ();
822
 
823
  p = frag_more (1);
824
  *p = 5 + name_len + 1;
825
  p = frag_more (1);
826
  *p = EXT_INSTRUCTION;
827
  p = frag_more (1);
828
  *p = opcode;
829
  p = frag_more (1);
830
  *p = subopcode;
831
  p = frag_more (1);
832
  *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
833
  p = frag_more (name_len);
834
  strncpy (p, syntax, name_len);
835
  p = frag_more (1);
836
  *p = '\0';
837
 
838
  subseg_set (old_sec, old_subsec);
839
 
840
  demand_empty_rest_of_line ();
841
}
842
 
843
static void
844
arc_common (int localScope)
845
{
846
  char *name;
847
  char c;
848
  char *p;
849
  int align, size;
850
  symbolS *symbolP;
851
 
852
  name = input_line_pointer;
853
  c = get_symbol_end ();
854
  /* just after name is now '\0'  */
855
  p = input_line_pointer;
856
  *p = c;
857
  SKIP_WHITESPACE ();
858
 
859
  if (*input_line_pointer != ',')
860
    {
861
      as_bad (_("expected comma after symbol name"));
862
      ignore_rest_of_line ();
863
      return;
864
    }
865
 
866
  input_line_pointer++;         /* skip ','  */
867
  size = get_absolute_expression ();
868
 
869
  if (size < 0)
870
    {
871
      as_bad (_("negative symbol length"));
872
      ignore_rest_of_line ();
873
      return;
874
    }
875
 
876
  *p = 0;
877
  symbolP = symbol_find_or_make (name);
878
  *p = c;
879
 
880
  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
881
    {
882
      as_bad (_("ignoring attempt to re-define symbol"));
883
      ignore_rest_of_line ();
884
      return;
885
    }
886
  if (((int) S_GET_VALUE (symbolP) != 0) \
887
      && ((int) S_GET_VALUE (symbolP) != size))
888
    {
889
      as_warn (_("length of symbol \"%s\" already %ld, ignoring %d"),
890
               S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
891
    }
892
  assert (symbolP->sy_frag == &zero_address_frag);
893
 
894
  /* Now parse the alignment field.  This field is optional for
895
     local and global symbols. Default alignment is zero.  */
896
  if (*input_line_pointer == ',')
897
    {
898
      input_line_pointer++;
899
      align = get_absolute_expression ();
900
      if (align < 0)
901
        {
902
          align = 0;
903
          as_warn (_("assuming symbol alignment of zero"));
904
        }
905
    }
906
  else
907
    align = 0;
908
 
909
  if (localScope != 0)
910
    {
911
      segT old_sec;
912
      int old_subsec;
913
      char *pfrag;
914
 
915
      old_sec    = now_seg;
916
      old_subsec = now_subseg;
917
      record_alignment (bss_section, align);
918
      subseg_set (bss_section, 0);  /* ??? subseg_set (bss_section, 1); ???  */
919
 
920
      if (align)
921
        /* Do alignment.  */
922
        frag_align (align, 0, 0);
923
 
924
      /* Detach from old frag.  */
925
      if (S_GET_SEGMENT (symbolP) == bss_section)
926
        symbolP->sy_frag->fr_symbol = NULL;
927
 
928
      symbolP->sy_frag = frag_now;
929
      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
930
                        (offsetT) size, (char *) 0);
931
      *pfrag = 0;
932
 
933
      S_SET_SIZE       (symbolP, size);
934
      S_SET_SEGMENT    (symbolP, bss_section);
935
      S_CLEAR_EXTERNAL (symbolP);
936
      symbolP->local = 1;
937
      subseg_set (old_sec, old_subsec);
938
    }
939
  else
940
    {
941
      S_SET_VALUE    (symbolP, (valueT) size);
942
      S_SET_ALIGN    (symbolP, align);
943
      S_SET_EXTERNAL (symbolP);
944
      S_SET_SEGMENT  (symbolP, bfd_com_section_ptr);
945
    }
946
 
947
  symbolP->bsym->flags |= BSF_OBJECT;
948
 
949
  demand_empty_rest_of_line ();
950
}
951
 
952
/* Select the cpu we're assembling for.  */
953
 
954
static void
955
arc_option (int ignore ATTRIBUTE_UNUSED)
956
{
957
  extern int arc_get_mach (char *);
958
  int mach;
959
  char c;
960
  char *cpu;
961
 
962
  cpu = input_line_pointer;
963
  c = get_symbol_end ();
964
  mach = arc_get_mach (cpu);
965
  *input_line_pointer = c;
966
 
967
  /* If an instruction has already been seen, it's too late.  */
968
  if (cpu_tables_init_p)
969
    {
970
      as_bad (_("\".option\" directive must appear before any instructions"));
971
      ignore_rest_of_line ();
972
      return;
973
    }
974
 
975
  if (mach == -1)
976
    goto bad_cpu;
977
 
978
  if (mach_type_specified_p && mach != arc_mach_type)
979
    {
980
      as_bad (_("\".option\" directive conflicts with initial definition"));
981
      ignore_rest_of_line ();
982
      return;
983
    }
984
  else
985
    {
986
      /* The cpu may have been selected on the command line.  */
987
      if (mach != arc_mach_type)
988
        as_warn (_("\".option\" directive overrides command-line (default) value"));
989
      arc_mach_type = mach;
990
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
991
        as_fatal (_("could not set architecture and machine"));
992
      mach_type_specified_p = 1;
993
    }
994
  demand_empty_rest_of_line ();
995
  return;
996
 
997
 bad_cpu:
998
  as_bad (_("invalid identifier for \".option\""));
999
  ignore_rest_of_line ();
1000
}
1001
 
1002
char *
1003
md_atof (int type, char *litP, int *sizeP)
1004
{
1005
  return ieee_md_atof (type, litP, sizeP, TRUE);
1006
}
1007
 
1008
/* Write a value out to the object file, using the appropriate
1009
   endianness.  */
1010
 
1011
void
1012
md_number_to_chars (char *buf, valueT val, int n)
1013
{
1014
  if (target_big_endian)
1015
    number_to_chars_bigendian (buf, val, n);
1016
  else
1017
    number_to_chars_littleendian (buf, val, n);
1018
}
1019
 
1020
/* Round up a section size to the appropriate boundary.  */
1021
 
1022
valueT
1023
md_section_align (segT segment, valueT size)
1024
{
1025
  int align = bfd_get_section_alignment (stdoutput, segment);
1026
 
1027
  return ((size + (1 << align) - 1) & (-1 << align));
1028
}
1029
 
1030
/* We don't have any form of relaxing.  */
1031
 
1032
int
1033
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1034
                               asection *seg ATTRIBUTE_UNUSED)
1035
{
1036
  as_fatal (_("relaxation not supported\n"));
1037
  return 1;
1038
}
1039
 
1040
/* Convert a machine dependent frag.  We never generate these.  */
1041
 
1042
void
1043
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1044
                 asection *sec ATTRIBUTE_UNUSED,
1045
                 fragS *fragp ATTRIBUTE_UNUSED)
1046
{
1047
  abort ();
1048
}
1049
 
1050
static void
1051
arc_code_symbol (expressionS *expressionP)
1052
{
1053
  if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
1054
    {
1055
      expressionS two;
1056
 
1057
      expressionP->X_op = O_right_shift;
1058
      expressionP->X_add_symbol->sy_value.X_op = O_constant;
1059
      two.X_op = O_constant;
1060
      two.X_add_symbol = two.X_op_symbol = NULL;
1061
      two.X_add_number = 2;
1062
      expressionP->X_op_symbol = make_expr_symbol (&two);
1063
    }
1064
  /* Allow %st(sym1-sym2)  */
1065
  else if (expressionP->X_op == O_subtract
1066
           && expressionP->X_add_symbol != NULL
1067
           && expressionP->X_op_symbol != NULL
1068
           && expressionP->X_add_number == 0)
1069
    {
1070
      expressionS two;
1071
 
1072
      expressionP->X_add_symbol = make_expr_symbol (expressionP);
1073
      expressionP->X_op = O_right_shift;
1074
      two.X_op = O_constant;
1075
      two.X_add_symbol = two.X_op_symbol = NULL;
1076
      two.X_add_number = 2;
1077
      expressionP->X_op_symbol = make_expr_symbol (&two);
1078
    }
1079
  else
1080
    as_bad (_("expression too complex code symbol"));
1081
}
1082
 
1083
/* Parse an operand that is machine-specific.
1084
 
1085
   The ARC has a special %-op to adjust addresses so they're usable in
1086
   branches.  The "st" is short for the STatus register.
1087
   ??? Later expand this to take a flags value too.
1088
 
1089
   ??? We can't create new expression types so we map the %-op's onto the
1090
   existing syntax.  This means that the user could use the chosen syntax
1091
   to achieve the same effect.  */
1092
 
1093
void
1094
md_operand (expressionS *expressionP)
1095
{
1096
  char *p = input_line_pointer;
1097
 
1098
  if (*p != '%')
1099
    return;
1100
 
1101
  if (strncmp (p, "%st(", 4) == 0)
1102
    {
1103
      input_line_pointer += 4;
1104
      expression (expressionP);
1105
      if (*input_line_pointer != ')')
1106
        {
1107
          as_bad (_("missing ')' in %%-op"));
1108
          return;
1109
        }
1110
      ++input_line_pointer;
1111
      arc_code_symbol (expressionP);
1112
    }
1113
  else
1114
    {
1115
      /* It could be a register.  */
1116
      int i, l;
1117
      struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1118
      p++;
1119
 
1120
      while (ext_oper)
1121
        {
1122
          l = strlen (ext_oper->operand.name);
1123
          if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1124
            {
1125
              input_line_pointer += l + 1;
1126
              expressionP->X_op = O_register;
1127
              expressionP->X_add_number = (offsetT) &ext_oper->operand;
1128
              return;
1129
            }
1130
          ext_oper = ext_oper->next;
1131
        }
1132
      for (i = 0; i < arc_reg_names_count; i++)
1133
        {
1134
          l = strlen (arc_reg_names[i].name);
1135
          if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1136
            {
1137
              input_line_pointer += l + 1;
1138
              expressionP->X_op = O_register;
1139
              expressionP->X_add_number = (offsetT) &arc_reg_names[i];
1140
              break;
1141
            }
1142
        }
1143
    }
1144
}
1145
 
1146
/* We have no need to default values of symbols.
1147
   We could catch register names here, but that is handled by inserting
1148
   them all in the symbol table to begin with.  */
1149
 
1150
symbolS *
1151
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1152
{
1153
  return 0;
1154
}
1155
 
1156
/* Functions concerning expressions.  */
1157
 
1158
/* Parse a .byte, .word, etc. expression.
1159
 
1160
   Values for the status register are specified with %st(label).
1161
   `label' will be right shifted by 2.  */
1162
 
1163
void
1164
arc_parse_cons_expression (expressionS *exp,
1165
                           unsigned int nbytes ATTRIBUTE_UNUSED)
1166
{
1167
  char *p = input_line_pointer;
1168
  int code_symbol_fix = 0;
1169
 
1170
  for (; ! is_end_of_line[(unsigned char) *p]; p++)
1171
    if (*p == '@' && !strncmp (p, "@h30", 4))
1172
      {
1173
        code_symbol_fix = 1;
1174
        strcpy (p, ";   ");
1175
      }
1176
  expression_and_evaluate (exp);
1177
  if (code_symbol_fix)
1178
    {
1179
      arc_code_symbol (exp);
1180
      input_line_pointer = p;
1181
    }
1182
}
1183
 
1184
/* Record a fixup for a cons expression.  */
1185
 
1186
void
1187
arc_cons_fix_new (fragS *frag,
1188
                  int where,
1189
                  int nbytes,
1190
                  expressionS *exp)
1191
{
1192
  if (nbytes == 4)
1193
    {
1194
      int reloc_type;
1195
      expressionS exptmp;
1196
 
1197
      /* This may be a special ARC reloc (eg: %st()).  */
1198
      reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1199
      fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
1200
    }
1201
  else
1202
    {
1203
      fix_new_exp (frag, where, nbytes, exp, 0,
1204
                   nbytes == 2 ? BFD_RELOC_16
1205
                   : nbytes == 8 ? BFD_RELOC_64
1206
                   : BFD_RELOC_32);
1207
    }
1208
}
1209
 
1210
/* Functions concerning relocs.  */
1211
 
1212
/* The location from which a PC relative jump should be calculated,
1213
   given a PC relative reloc.  */
1214
 
1215
long
1216
md_pcrel_from (fixS *fixP)
1217
{
1218
  /* Return the address of the delay slot.  */
1219
  return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1220
}
1221
 
1222
/* Apply a fixup to the object code.  This is called for all the
1223
   fixups we generated by the call to fix_new_exp, above.  In the call
1224
   above we used a reloc code which was the largest legal reloc code
1225
   plus the operand index.  Here we undo that to recover the operand
1226
   index.  At this point all symbol values should be fully resolved,
1227
   and we attempt to completely resolve the reloc.  If we can not do
1228
   that, we determine the correct reloc code and put it back in the fixup.  */
1229
 
1230
void
1231
md_apply_fix (fixS *fixP, valueT * valP, segT seg)
1232
{
1233
  valueT value = * valP;
1234
 
1235
  if (fixP->fx_addsy == (symbolS *) NULL)
1236
    fixP->fx_done = 1;
1237
 
1238
  else if (fixP->fx_pcrel)
1239
    {
1240
      /* Hack around bfd_install_relocation brain damage.  */
1241
      if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
1242
        value += md_pcrel_from (fixP);
1243
    }
1244
 
1245
  /* We can't actually support subtracting a symbol.  */
1246
  if (fixP->fx_subsy != NULL)
1247
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1248
 
1249
  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1250
    {
1251
      int opindex;
1252
      const struct arc_operand *operand;
1253
      char *where;
1254
      arc_insn insn;
1255
 
1256
      opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1257
 
1258
      operand = &arc_operands[opindex];
1259
 
1260
      /* Fetch the instruction, insert the fully resolved operand
1261
         value, and stuff the instruction back again.  */
1262
      where = fixP->fx_frag->fr_literal + fixP->fx_where;
1263
      if (target_big_endian)
1264
        insn = bfd_getb32 ((unsigned char *) where);
1265
      else
1266
        insn = bfd_getl32 ((unsigned char *) where);
1267
      insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1268
                                 fixP->fx_file, fixP->fx_line);
1269
      if (target_big_endian)
1270
        bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1271
      else
1272
        bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1273
 
1274
      if (fixP->fx_done)
1275
        /* Nothing else to do here.  */
1276
        return;
1277
 
1278
      /* Determine a BFD reloc value based on the operand information.
1279
         We are only prepared to turn a few of the operands into relocs.
1280
         !!! Note that we can't handle limm values here.  Since we're using
1281
         implicit addends the addend must be inserted into the instruction,
1282
         however, the opcode insertion routines currently do nothing with
1283
         limm values.  */
1284
      if (operand->fmt == 'B')
1285
        {
1286
          assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1287
                  && operand->bits == 20
1288
                  && operand->shift == 7);
1289
          fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1290
        }
1291
      else if (operand->fmt == 'J')
1292
        {
1293
          assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1294
                  && operand->bits == 24
1295
                  && operand->shift == 32);
1296
          fixP->fx_r_type = BFD_RELOC_ARC_B26;
1297
        }
1298
      else if (operand->fmt == 'L')
1299
        {
1300
          assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1301
                  && operand->bits == 32
1302
                  && operand->shift == 32);
1303
          fixP->fx_r_type = BFD_RELOC_32;
1304
        }
1305
      else
1306
        {
1307
          as_bad_where (fixP->fx_file, fixP->fx_line,
1308
                        _("unresolved expression that must be resolved"));
1309
          fixP->fx_done = 1;
1310
          return;
1311
        }
1312
    }
1313
  else
1314
    {
1315
      switch (fixP->fx_r_type)
1316
        {
1317
        case BFD_RELOC_8:
1318
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1319
                              value, 1);
1320
          break;
1321
        case BFD_RELOC_16:
1322
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1323
                              value, 2);
1324
          break;
1325
        case BFD_RELOC_32:
1326
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1327
                              value, 4);
1328
          break;
1329
        case BFD_RELOC_ARC_B26:
1330
          /* If !fixP->fx_done then `value' is an implicit addend.
1331
             We must shift it right by 2 in this case as well because the
1332
             linker performs the relocation and then adds this in (as opposed
1333
             to adding this in and then shifting right by 2).  */
1334
          value >>= 2;
1335
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1336
                              value, 4);
1337
          break;
1338
        default:
1339
          abort ();
1340
        }
1341
    }
1342
}
1343
 
1344
/* Translate internal representation of relocation info to BFD target
1345
   format.  */
1346
 
1347
arelent *
1348
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1349
              fixS *fixP)
1350
{
1351
  arelent *reloc;
1352
 
1353
  reloc = xmalloc (sizeof (arelent));
1354
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1355
 
1356
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1357
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1358
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1359
  if (reloc->howto == (reloc_howto_type *) NULL)
1360
    {
1361
      as_bad_where (fixP->fx_file, fixP->fx_line,
1362
                    _("internal error: can't export reloc type %d (`%s')"),
1363
                    fixP->fx_r_type,
1364
                    bfd_get_reloc_code_name (fixP->fx_r_type));
1365
      return NULL;
1366
    }
1367
 
1368
  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1369
 
1370
  /* Set addend to account for PC being advanced one insn before the
1371
     target address is computed.  */
1372
 
1373
  reloc->addend = (fixP->fx_pcrel ? -4 : 0);
1374
 
1375
  return reloc;
1376
}
1377
 
1378
const pseudo_typeS md_pseudo_table[] =
1379
{
1380
  { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
1381
  { "comm", arc_common, 0 },
1382
  { "common", arc_common, 0 },
1383
  { "lcomm", arc_common, 1 },
1384
  { "lcommon", arc_common, 1 },
1385
  { "2byte", cons, 2 },
1386
  { "half", cons, 2 },
1387
  { "short", cons, 2 },
1388
  { "3byte", cons, 3 },
1389
  { "4byte", cons, 4 },
1390
  { "word", cons, 4 },
1391
  { "option", arc_option, 0 },
1392
  { "cpu", arc_option, 0 },
1393
  { "block", s_space, 0 },
1394
  { "extcondcode", arc_extoper, 0 },
1395
  { "extcoreregister", arc_extoper, 1 },
1396
  { "extauxregister", arc_extoper, 2 },
1397
  { "extinstruction", arc_extinst, 0 },
1398
  { NULL, 0, 0 },
1399
};
1400
 
1401
/* This routine is called for each instruction to be assembled.  */
1402
 
1403
void
1404
md_assemble (char *str)
1405
{
1406
  const struct arc_opcode *opcode;
1407
  const struct arc_opcode *std_opcode;
1408
  struct arc_opcode *ext_opcode;
1409
  char *start;
1410
  const char *last_errmsg = 0;
1411
  arc_insn insn;
1412
  static int init_tables_p = 0;
1413
 
1414
  /* Opcode table initialization is deferred until here because we have to
1415
     wait for a possible .option command.  */
1416
  if (!init_tables_p)
1417
    {
1418
      init_opcode_tables (arc_mach_type);
1419
      init_tables_p = 1;
1420
    }
1421
 
1422
  /* Skip leading white space.  */
1423
  while (ISSPACE (*str))
1424
    str++;
1425
 
1426
  /* The instructions are stored in lists hashed by the first letter (though
1427
     we needn't care how they're hashed).  Get the first in the list.  */
1428
 
1429
  ext_opcode = arc_ext_opcodes;
1430
  std_opcode = arc_opcode_lookup_asm (str);
1431
 
1432
  /* Keep looking until we find a match.  */
1433
  start = str;
1434
  for (opcode = (ext_opcode ? ext_opcode : std_opcode);
1435
       opcode != NULL;
1436
       opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1437
                 ? ARC_OPCODE_NEXT_ASM (opcode)
1438
                 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
1439
    {
1440
      int past_opcode_p, fc, num_suffixes;
1441
      int fix_up_at = 0;
1442
      char *syn;
1443
      struct arc_fixup fixups[MAX_FIXUPS];
1444
      /* Used as a sanity check.  If we need a limm reloc, make sure we ask
1445
         for an extra 4 bytes from frag_more.  */
1446
      int limm_reloc_p;
1447
      int ext_suffix_p;
1448
      const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
1449
 
1450
      /* Is this opcode supported by the selected cpu?  */
1451
      if (! arc_opcode_supported (opcode))
1452
        continue;
1453
 
1454
      /* Scan the syntax string.  If it doesn't match, try the next one.  */
1455
      arc_opcode_init_insert ();
1456
      insn = opcode->value;
1457
      fc = 0;
1458
      past_opcode_p = 0;
1459
      num_suffixes = 0;
1460
      limm_reloc_p = 0;
1461
      ext_suffix_p = 0;
1462
 
1463
      /* We don't check for (*str != '\0') here because we want to parse
1464
         any trailing fake arguments in the syntax string.  */
1465
      for (str = start, syn = opcode->syntax; *syn != '\0';)
1466
        {
1467
          int mods;
1468
          const struct arc_operand *operand;
1469
 
1470
          /* Non operand chars must match exactly.  */
1471
          if (*syn != '%' || *++syn == '%')
1472
            {
1473
             if (*str == *syn)
1474
                {
1475
                  if (*syn == ' ')
1476
                    past_opcode_p = 1;
1477
                  ++syn;
1478
                  ++str;
1479
                }
1480
              else
1481
                break;
1482
              continue;
1483
            }
1484
 
1485
          /* We have an operand.  Pick out any modifiers.  */
1486
          mods = 0;
1487
          while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
1488
            {
1489
              mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
1490
              ++syn;
1491
            }
1492
          operand = arc_operands + arc_operand_map[(int) *syn];
1493
          if (operand->fmt == 0)
1494
            as_fatal (_("unknown syntax format character `%c'"), *syn);
1495
 
1496
          if (operand->flags & ARC_OPERAND_FAKE)
1497
            {
1498
              const char *errmsg = NULL;
1499
              if (operand->insert)
1500
                {
1501
                  insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1502
                  if (errmsg != (const char *) NULL)
1503
                    {
1504
                      last_errmsg = errmsg;
1505
                      if (operand->flags & ARC_OPERAND_ERROR)
1506
                        {
1507
                          as_bad (errmsg);
1508
                          return;
1509
                        }
1510
                      else if (operand->flags & ARC_OPERAND_WARN)
1511
                        as_warn (errmsg);
1512
                      break;
1513
                    }
1514
                  if (limm_reloc_p
1515
                      && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
1516
                      && (operand->flags &
1517
                          (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1518
                    {
1519
                      fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
1520
                    }
1521
                }
1522
              ++syn;
1523
            }
1524
          /* Are we finished with suffixes?  */
1525
          else if (!past_opcode_p)
1526
            {
1527
              int found;
1528
              char c;
1529
              char *s, *t;
1530
              const struct arc_operand_value *suf, *suffix_end;
1531
              const struct arc_operand_value *suffix = NULL;
1532
 
1533
              if (!(operand->flags & ARC_OPERAND_SUFFIX))
1534
                abort ();
1535
 
1536
              /* If we're at a space in the input string, we want to skip the
1537
                 remaining suffixes.  There may be some fake ones though, so
1538
                 just go on to try the next one.  */
1539
              if (*str == ' ')
1540
                {
1541
                  ++syn;
1542
                  continue;
1543
                }
1544
 
1545
              s = str;
1546
              if (mods & ARC_MOD_DOT)
1547
                {
1548
                  if (*s != '.')
1549
                    break;
1550
                  ++s;
1551
                }
1552
              else
1553
                {
1554
                  /* This can happen in "b.nd foo" and we're currently looking
1555
                     for "%q" (ie: a condition code suffix).  */
1556
                  if (*s == '.')
1557
                    {
1558
                      ++syn;
1559
                      continue;
1560
                    }
1561
                }
1562
 
1563
              /* Pick the suffix out and look it up via the hash table.  */
1564
              for (t = s; *t && ISALNUM (*t); ++t)
1565
                continue;
1566
              c = *t;
1567
              *t = '\0';
1568
              if ((suf = get_ext_suffix (s)))
1569
                ext_suffix_p = 1;
1570
              else
1571
                suf = hash_find (arc_suffix_hash, s);
1572
              if (!suf)
1573
                {
1574
                  /* This can happen in "blle foo" and we're currently using
1575
                     the template "b%q%.n %j".  The "bl" insn occurs later in
1576
                     the table so "lle" isn't an illegal suffix.  */
1577
                  *t = c;
1578
                  break;
1579
                }
1580
 
1581
              /* Is it the right type?  Note that the same character is used
1582
                 several times, so we have to examine all of them.  This is
1583
                 relatively efficient as equivalent entries are kept
1584
                 together.  If it's not the right type, don't increment `str'
1585
                 so we try the next one in the series.  */
1586
              found = 0;
1587
              if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
1588
                {
1589
                  /* Insert the suffix's value into the insn.  */
1590
                  *t = c;
1591
                  if (operand->insert)
1592
                    insn = (*operand->insert) (insn, operand,
1593
                                               mods, NULL, suf->value,
1594
                                               NULL);
1595
                  else
1596
                    insn |= suf->value << operand->shift;
1597
                  suffix = suf;
1598
                  str = t;
1599
                  found = 1;
1600
                }
1601
              else
1602
                {
1603
                  *t = c;
1604
                  suffix_end = arc_suffixes + arc_suffixes_count;
1605
                  for (suffix = suf;
1606
                       suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
1607
                       ++suffix)
1608
                    {
1609
                      if (arc_operands[suffix->type].fmt == *syn)
1610
                        {
1611
                          /* Insert the suffix's value into the insn.  */
1612
                          if (operand->insert)
1613
                            insn = (*operand->insert) (insn, operand,
1614
                                                       mods, NULL, suffix->value,
1615
                                                       NULL);
1616
                          else
1617
                            insn |= suffix->value << operand->shift;
1618
 
1619
                          str = t;
1620
                          found = 1;
1621
                          break;
1622
                        }
1623
                    }
1624
                }
1625
              ++syn;
1626
              if (!found)
1627
                /* Wrong type.  Just go on to try next insn entry.  */
1628
                ;
1629
              else
1630
                {
1631
                  if (num_suffixes == MAX_SUFFIXES)
1632
                    as_bad (_("too many suffixes"));
1633
                  else
1634
                    insn_suffixes[num_suffixes++] = suffix;
1635
                }
1636
            }
1637
          else
1638
            /* This is either a register or an expression of some kind.  */
1639
            {
1640
              char *hold;
1641
              const struct arc_operand_value *reg = NULL;
1642
              long value = 0;
1643
              expressionS exp;
1644
 
1645
              if (operand->flags & ARC_OPERAND_SUFFIX)
1646
                abort ();
1647
 
1648
              /* Is there anything left to parse?
1649
                 We don't check for this at the top because we want to parse
1650
                 any trailing fake arguments in the syntax string.  */
1651
              if (is_end_of_line[(unsigned char) *str])
1652
                break;
1653
 
1654
              /* Parse the operand.  */
1655
              hold = input_line_pointer;
1656
              input_line_pointer = str;
1657
              expression (&exp);
1658
              str = input_line_pointer;
1659
              input_line_pointer = hold;
1660
 
1661
              if (exp.X_op == O_illegal)
1662
                as_bad (_("illegal operand"));
1663
              else if (exp.X_op == O_absent)
1664
                as_bad (_("missing operand"));
1665
              else if (exp.X_op == O_constant)
1666
                value = exp.X_add_number;
1667
              else if (exp.X_op == O_register)
1668
                reg = (struct arc_operand_value *) exp.X_add_number;
1669
#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
1670
              else if (IS_REG_DEST_OPERAND (*syn))
1671
                as_bad (_("symbol as destination register"));
1672
              else
1673
                {
1674
                  if (!strncmp (str, "@h30", 4))
1675
                    {
1676
                      arc_code_symbol (&exp);
1677
                      str += 4;
1678
                    }
1679
                  /* We need to generate a fixup for this expression.  */
1680
                  if (fc >= MAX_FIXUPS)
1681
                    as_fatal (_("too many fixups"));
1682
                  fixups[fc].exp = exp;
1683
                  /* We don't support shimm relocs. break here to force
1684
                     the assembler to output a limm.  */
1685
#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
1686
                  if (IS_REG_SHIMM_OFFSET (*syn))
1687
                    break;
1688
                  /* If this is a register constant (IE: one whose
1689
                     register value gets stored as 61-63) then this
1690
                     must be a limm.  */
1691
                  /* ??? This bit could use some cleaning up.
1692
                     Referencing the format chars like this goes
1693
                     against style.  */
1694
                  if (IS_SYMBOL_OPERAND (*syn))
1695
                    {
1696
                      const char *junk;
1697
                      limm_reloc_p = 1;
1698
                      /* Save this, we don't yet know what reloc to use.  */
1699
                      fix_up_at = fc;
1700
                      /* Tell insert_reg we need a limm.  This is
1701
                         needed because the value at this point is
1702
                         zero, a shimm.  */
1703
                      /* ??? We need a cleaner interface than this.  */
1704
                      (*arc_operands[arc_operand_map['Q']].insert)
1705
                        (insn, operand, mods, reg, 0L, &junk);
1706
                    }
1707
                  else
1708
                    fixups[fc].opindex = arc_operand_map[(int) *syn];
1709
                  ++fc;
1710
                  value = 0;
1711
                }
1712
 
1713
              /* Insert the register or expression into the instruction.  */
1714
              if (operand->insert)
1715
                {
1716
                  const char *errmsg = NULL;
1717
                  insn = (*operand->insert) (insn, operand, mods,
1718
                                             reg, (long) value, &errmsg);
1719
                  if (errmsg != (const char *) NULL)
1720
                    {
1721
                      last_errmsg = errmsg;
1722
                      if (operand->flags & ARC_OPERAND_ERROR)
1723
                        {
1724
                          as_bad (errmsg);
1725
                          return;
1726
                        }
1727
                      else if (operand->flags & ARC_OPERAND_WARN)
1728
                        as_warn (errmsg);
1729
                      break;
1730
                    }
1731
                }
1732
              else
1733
                insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
1734
 
1735
              ++syn;
1736
            }
1737
        }
1738
 
1739
      /* If we're at the end of the syntax string, we're done.  */
1740
      /* FIXME: try to move this to a separate function.  */
1741
      if (*syn == '\0')
1742
        {
1743
          int i;
1744
          char *f;
1745
          long limm, limm_p;
1746
 
1747
          /* For the moment we assume a valid `str' can only contain blanks
1748
             now.  IE: We needn't try again with a longer version of the
1749
             insn and it is assumed that longer versions of insns appear
1750
             before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1751
 
1752
          while (ISSPACE (*str))
1753
            ++str;
1754
 
1755
          if (!is_end_of_line[(unsigned char) *str])
1756
            as_bad (_("junk at end of line: `%s'"), str);
1757
 
1758
          /* Is there a limm value?  */
1759
          limm_p = arc_opcode_limm_p (&limm);
1760
 
1761
          /* Perform various error and warning tests.  */
1762
 
1763
          {
1764
            static int in_delay_slot_p = 0;
1765
            static int prev_insn_needs_cc_nop_p = 0;
1766
            /* delay slot type seen */
1767
            int delay_slot_type = ARC_DELAY_NONE;
1768
            /* conditional execution flag seen */
1769
            int conditional = 0;
1770
            /* 1 if condition codes are being set */
1771
            int cc_set_p = 0;
1772
            /* 1 if conditional branch, including `b' "branch always" */
1773
            int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
1774
 
1775
            for (i = 0; i < num_suffixes; ++i)
1776
              {
1777
                switch (arc_operands[insn_suffixes[i]->type].fmt)
1778
                  {
1779
                  case 'n':
1780
                    delay_slot_type = insn_suffixes[i]->value;
1781
                    break;
1782
                  case 'q':
1783
                    conditional = insn_suffixes[i]->value;
1784
                    break;
1785
                  case 'f':
1786
                    cc_set_p = 1;
1787
                    break;
1788
                  }
1789
              }
1790
 
1791
            /* Putting an insn with a limm value in a delay slot is supposed to
1792
               be legal, but let's warn the user anyway.  Ditto for 8 byte
1793
               jumps with delay slots.  */
1794
            if (in_delay_slot_p && limm_p)
1795
              as_warn (_("8 byte instruction in delay slot"));
1796
            if (delay_slot_type != ARC_DELAY_NONE
1797
                && limm_p && arc_insn_not_jl (insn)) /* except for jl  addr */
1798
              as_warn (_("8 byte jump instruction with delay slot"));
1799
            in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
1800
 
1801
            /* Warn when a conditional branch immediately follows a set of
1802
               the condition codes.  Note that this needn't be done if the
1803
               insn that sets the condition codes uses a limm.  */
1804
            if (cond_branch_p && conditional != 0 /* 0 = "always" */
1805
                && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1806
              as_warn (_("conditional branch follows set of flags"));
1807
            prev_insn_needs_cc_nop_p =
1808
              /* FIXME: ??? not required:
1809
                 (delay_slot_type != ARC_DELAY_NONE) &&  */
1810
              cc_set_p && !limm_p;
1811
          }
1812
 
1813
          /* Write out the instruction.
1814
             It is important to fetch enough space in one call to `frag_more'.
1815
             We use (f - frag_now->fr_literal) to compute where we are and we
1816
             don't want frag_now to change between calls.  */
1817
          if (limm_p)
1818
            {
1819
              f = frag_more (8);
1820
              md_number_to_chars (f, insn, 4);
1821
              md_number_to_chars (f + 4, limm, 4);
1822
              dwarf2_emit_insn (8);
1823
            }
1824
          else if (limm_reloc_p)
1825
            /* We need a limm reloc, but the tables think we don't.  */
1826
            abort ();
1827
          else
1828
            {
1829
              f = frag_more (4);
1830
              md_number_to_chars (f, insn, 4);
1831
              dwarf2_emit_insn (4);
1832
            }
1833
 
1834
          /* Create any fixups.  */
1835
          for (i = 0; i < fc; ++i)
1836
            {
1837
              int op_type, reloc_type;
1838
              expressionS exptmp;
1839
              const struct arc_operand *operand;
1840
 
1841
              /* Create a fixup for this operand.
1842
                 At this point we do not use a bfd_reloc_code_real_type for
1843
                 operands residing in the insn, but instead just use the
1844
                 operand index.  This lets us easily handle fixups for any
1845
                 operand type, although that is admittedly not a very exciting
1846
                 feature.  We pick a BFD reloc type in md_apply_fix.
1847
 
1848
                 Limm values (4 byte immediate "constants") must be treated
1849
                 normally because they're not part of the actual insn word
1850
                 and thus the insertion routines don't handle them.  */
1851
 
1852
              if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
1853
                {
1854
                  /* Modify the fixup addend as required by the cpu.  */
1855
                  fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
1856
                  op_type = fixups[i].opindex;
1857
                  /* FIXME: can we add this data to the operand table?  */
1858
                  if (op_type == arc_operand_map['L']
1859
                      || op_type == arc_operand_map['s']
1860
                      || op_type == arc_operand_map['o']
1861
                      || op_type == arc_operand_map['O'])
1862
                    reloc_type = BFD_RELOC_32;
1863
                  else if (op_type == arc_operand_map['J'])
1864
                    reloc_type = BFD_RELOC_ARC_B26;
1865
                  else
1866
                    abort ();
1867
                  reloc_type = get_arc_exp_reloc_type (1, reloc_type,
1868
                                                       &fixups[i].exp,
1869
                                                       &exptmp);
1870
                }
1871
              else
1872
                {
1873
                  op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
1874
                                                    &fixups[i].exp, &exptmp);
1875
                  reloc_type = op_type + (int) BFD_RELOC_UNUSED;
1876
                }
1877
              operand = &arc_operands[op_type];
1878
              fix_new_exp (frag_now,
1879
                           ((f - frag_now->fr_literal)
1880
                            + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
1881
                           &exptmp,
1882
                           (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
1883
                           (bfd_reloc_code_real_type) reloc_type);
1884
            }
1885
          return;
1886
        }
1887
    }
1888
 
1889
  if (NULL == last_errmsg)
1890
    as_bad (_("bad instruction `%s'"), start);
1891
  else
1892
    as_bad (last_errmsg);
1893
}

powered by: WebSVN 2.1.0

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