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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-arc.c] - Blame information for rev 146

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

Line No. Rev Author Line
1 16 khays
/* tc-arc.c -- Assembler for the ARC
2
   Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007, 2009, 2011  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  s_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 ("%s", 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 = (struct arc_ext_operand_value *)
544
      xmalloc (sizeof (struct arc_ext_operand_value));
545
 
546
  if (opertype)
547
    {
548
      /* If the symbol already exists, point it at the new definition.  */
549
      if ((symbolP = symbol_find (name)))
550
        {
551
          if (S_GET_SEGMENT (symbolP) == reg_section)
552
            S_SET_VALUE (symbolP, (valueT) &ext_oper->operand);
553
          else
554
            {
555
              as_bad (_("attempt to override symbol: %s"), name);
556
              ignore_rest_of_line ();
557
              free (name);
558
              free (ext_oper);
559
              return;
560
            }
561
        }
562
      else
563
        {
564
          /* If its not there, add it.  */
565
          symbol_table_insert (symbol_create (name, reg_section,
566
                                              (valueT) &ext_oper->operand,
567
                                              &zero_address_frag));
568
        }
569
    }
570
 
571
  ext_oper->operand.name  = name;
572
  ext_oper->operand.value = number;
573
  ext_oper->operand.type  = arc_operand_type (opertype);
574
  ext_oper->operand.flags = imode;
575
 
576
  ext_oper->next = arc_ext_operands;
577
  arc_ext_operands = ext_oper;
578
 
579
  /* OK, now that we know what this operand is, put a description in
580
     the arc extension section of the output file.  */
581
 
582
  old_sec    = now_seg;
583
  old_subsec = now_subseg;
584
 
585
  arc_set_ext_seg ();
586
 
587
  switch (opertype)
588
    {
589
    case 0:
590
      p = frag_more (1);
591
      *p = 3 + strlen (name) + 1;
592
      p = frag_more (1);
593
      *p = EXT_COND_CODE;
594
      p = frag_more (1);
595
      *p = number;
596
      p = frag_more (strlen (name) + 1);
597
      strcpy (p, name);
598
      break;
599
    case 1:
600
      p = frag_more (1);
601
      *p = 3 + strlen (name) + 1;
602
      p = frag_more (1);
603
      *p = EXT_CORE_REGISTER;
604
      p = frag_more (1);
605
      *p = number;
606
      p = frag_more (strlen (name) + 1);
607
      strcpy (p, name);
608
      break;
609
    case 2:
610
      p = frag_more (1);
611
      *p = 6 + strlen (name) + 1;
612
      p = frag_more (1);
613
      *p = EXT_AUX_REGISTER;
614
      p = frag_more (1);
615
      *p = number >> 24 & 0xff;
616
      p = frag_more (1);
617
      *p = number >> 16 & 0xff;
618
      p = frag_more (1);
619
      *p = number >>  8 & 0xff;
620
      p = frag_more (1);
621
      *p = number       & 0xff;
622
      p = frag_more (strlen (name) + 1);
623
      strcpy (p, name);
624
      break;
625
    default:
626
      as_bad (_("invalid opertype"));
627
      ignore_rest_of_line ();
628
      free (name);
629
      return;
630
      break;
631
    }
632
 
633
  subseg_set (old_sec, old_subsec);
634
 
635
  /* Enter all registers into the symbol table.  */
636
 
637
  demand_empty_rest_of_line ();
638
}
639
 
640
static void
641
arc_extinst (int ignore ATTRIBUTE_UNUSED)
642
{
643
  char syntax[129];
644
  char *name;
645
  char *p;
646
  char c;
647
  int suffixcode = -1;
648
  int opcode, subopcode;
649
  int i;
650
  int s_class = 0;
651
  int name_len;
652
  struct arc_opcode *ext_op;
653
 
654
  segT old_sec;
655
  int old_subsec;
656
 
657
  name = input_line_pointer;
658
  c = get_symbol_end ();
659
  name = xstrdup (name);
660
  strcpy (syntax, name);
661
  name_len = strlen (name);
662
 
663
  /* just after name is now '\0'  */
664
  p = input_line_pointer;
665
  *p = c;
666
 
667
  SKIP_WHITESPACE ();
668
 
669
  if (*input_line_pointer != ',')
670
    {
671
      as_bad (_("expected comma after operand name"));
672
      ignore_rest_of_line ();
673
      return;
674
    }
675
 
676
  input_line_pointer++;         /* skip ','  */
677
  opcode = get_absolute_expression ();
678
 
679
  SKIP_WHITESPACE ();
680
 
681
  if (*input_line_pointer != ',')
682
    {
683
      as_bad (_("expected comma after opcode"));
684
      ignore_rest_of_line ();
685
      return;
686
    }
687
 
688
  input_line_pointer++;         /* skip ','  */
689
  subopcode = get_absolute_expression ();
690
 
691
  if (subopcode < 0)
692
    {
693
      as_bad (_("negative subopcode %d"), subopcode);
694
      ignore_rest_of_line ();
695
      return;
696
    }
697
 
698
  if (subopcode)
699
    {
700
      if (3 != opcode)
701
        {
702
          as_bad (_("subcode value found when opcode not equal 0x03"));
703
          ignore_rest_of_line ();
704
          return;
705
        }
706
      else
707
        {
708
          if (subopcode < 0x09 || subopcode == 0x3f)
709
            {
710
              as_bad (_("invalid subopcode %d"), subopcode);
711
              ignore_rest_of_line ();
712
              return;
713
            }
714
        }
715
    }
716
 
717
  SKIP_WHITESPACE ();
718
 
719
  if (*input_line_pointer != ',')
720
    {
721
      as_bad (_("expected comma after subopcode"));
722
      ignore_rest_of_line ();
723
      return;
724
    }
725
 
726
  input_line_pointer++;         /* skip ','  */
727
 
728
  for (i = 0; i < (int) MAXSUFFIXCLASS; i++)
729
    {
730
      if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len))
731
        {
732
          suffixcode = i;
733
          input_line_pointer += suffixclass[i].len;
734
          break;
735
        }
736
    }
737
 
738
  if (-1 == suffixcode)
739
    {
740
      as_bad (_("invalid suffix class"));
741
      ignore_rest_of_line ();
742
      return;
743
    }
744
 
745
  SKIP_WHITESPACE ();
746
 
747
  if (*input_line_pointer != ',')
748
    {
749
      as_bad (_("expected comma after suffix class"));
750
      ignore_rest_of_line ();
751
      return;
752
    }
753
 
754
  input_line_pointer++;         /* skip ','  */
755
 
756
  for (i = 0; i < (int) MAXSYNTAXCLASS; i++)
757
    {
758
      if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len))
759
        {
760
          s_class = syntaxclass[i].s_class;
761
          input_line_pointer += syntaxclass[i].len;
762
          break;
763
        }
764
    }
765
 
766
  if (0 == (SYNTAX_VALID & s_class))
767
    {
768
      as_bad (_("invalid syntax class"));
769
      ignore_rest_of_line ();
770
      return;
771
    }
772
 
773
  if ((0x3 == opcode) & (s_class & SYNTAX_3OP))
774
    {
775
      as_bad (_("opcode 0x3 and SYNTAX_3OP invalid"));
776
      ignore_rest_of_line ();
777
      return;
778
    }
779
 
780
  switch (suffixcode)
781
    {
782
    case 0:
783
      strcat (syntax, "%.q%.f ");
784
      break;
785
    case 1:
786
      strcat (syntax, "%.f ");
787
      break;
788
    case 2:
789
      strcat (syntax, "%.q ");
790
      break;
791
    case 3:
792
      strcat (syntax, " ");
793
      break;
794
    default:
795
      as_bad (_("unknown suffix class"));
796
      ignore_rest_of_line ();
797
      return;
798
      break;
799
    };
800
 
801
  strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((s_class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c")));
802
  if (suffixcode < 2)
803
    strcat (syntax, "%F");
804
  strcat (syntax, "%S%L");
805
 
806
  ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode));
807
  ext_op->syntax = xstrdup (syntax);
808
 
809
  ext_op->mask  = I (-1) | ((0x3 == opcode) ? C (-1) : 0);
810
  ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0);
811
  ext_op->flags = s_class;
812
  ext_op->next_asm = arc_ext_opcodes;
813
  ext_op->next_dis = arc_ext_opcodes;
814
  arc_ext_opcodes = ext_op;
815
 
816
  /* OK, now that we know what this inst is, put a description in the
817
     arc extension section of the output file.  */
818
 
819
  old_sec    = now_seg;
820
  old_subsec = now_subseg;
821
 
822
  arc_set_ext_seg ();
823
 
824
  p = frag_more (1);
825
  *p = 5 + name_len + 1;
826
  p = frag_more (1);
827
  *p = EXT_INSTRUCTION;
828
  p = frag_more (1);
829
  *p = opcode;
830
  p = frag_more (1);
831
  *p = subopcode;
832
  p = frag_more (1);
833
  *p = (s_class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0);
834
  p = frag_more (name_len);
835
  strncpy (p, syntax, name_len);
836
  p = frag_more (1);
837
  *p = '\0';
838
 
839
  subseg_set (old_sec, old_subsec);
840
 
841
  demand_empty_rest_of_line ();
842
}
843
 
844
static void
845
arc_common (int localScope)
846
{
847
  char *name;
848
  char c;
849
  char *p;
850
  int align, size;
851
  symbolS *symbolP;
852
 
853
  name = input_line_pointer;
854
  c = get_symbol_end ();
855
  /* just after name is now '\0'  */
856
  p = input_line_pointer;
857
  *p = c;
858
  SKIP_WHITESPACE ();
859
 
860
  if (*input_line_pointer != ',')
861
    {
862
      as_bad (_("expected comma after symbol name"));
863
      ignore_rest_of_line ();
864
      return;
865
    }
866
 
867
  input_line_pointer++;         /* skip ','  */
868
  size = get_absolute_expression ();
869
 
870
  if (size < 0)
871
    {
872
      as_bad (_("negative symbol length"));
873
      ignore_rest_of_line ();
874
      return;
875
    }
876
 
877
  *p = 0;
878
  symbolP = symbol_find_or_make (name);
879
  *p = c;
880
 
881
  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
882
    {
883
      as_bad (_("ignoring attempt to re-define symbol"));
884
      ignore_rest_of_line ();
885
      return;
886
    }
887
  if (((int) S_GET_VALUE (symbolP) != 0) \
888
      && ((int) S_GET_VALUE (symbolP) != size))
889
    {
890
      as_warn (_("length of symbol \"%s\" already %ld, ignoring %d"),
891
               S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
892
    }
893
  gas_assert (symbolP->sy_frag == &zero_address_frag);
894
 
895
  /* Now parse the alignment field.  This field is optional for
896
     local and global symbols. Default alignment is zero.  */
897
  if (*input_line_pointer == ',')
898
    {
899
      input_line_pointer++;
900
      align = get_absolute_expression ();
901
      if (align < 0)
902
        {
903
          align = 0;
904
          as_warn (_("assuming symbol alignment of zero"));
905
        }
906
    }
907
  else
908
    align = 0;
909
 
910
  if (localScope != 0)
911
    {
912
      segT old_sec;
913
      int old_subsec;
914
      char *pfrag;
915
 
916
      old_sec    = now_seg;
917
      old_subsec = now_subseg;
918
      record_alignment (bss_section, align);
919
      subseg_set (bss_section, 0);  /* ??? subseg_set (bss_section, 1); ???  */
920
 
921
      if (align)
922
        /* Do alignment.  */
923
        frag_align (align, 0, 0);
924
 
925
      /* Detach from old frag.  */
926
      if (S_GET_SEGMENT (symbolP) == bss_section)
927
        symbolP->sy_frag->fr_symbol = NULL;
928
 
929
      symbolP->sy_frag = frag_now;
930
      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
931
                        (offsetT) size, (char *) 0);
932
      *pfrag = 0;
933
 
934
      S_SET_SIZE       (symbolP, size);
935
      S_SET_SEGMENT    (symbolP, bss_section);
936
      S_CLEAR_EXTERNAL (symbolP);
937
      symbol_get_obj (symbolP)->local = 1;
938
      subseg_set (old_sec, old_subsec);
939
    }
940
  else
941
    {
942
      S_SET_VALUE    (symbolP, (valueT) size);
943
      S_SET_ALIGN    (symbolP, align);
944
      S_SET_EXTERNAL (symbolP);
945
      S_SET_SEGMENT  (symbolP, bfd_com_section_ptr);
946
    }
947
 
948
  symbolP->bsym->flags |= BSF_OBJECT;
949
 
950
  demand_empty_rest_of_line ();
951
}
952
 
953
/* Select the cpu we're assembling for.  */
954
 
955
static void
956
arc_option (int ignore ATTRIBUTE_UNUSED)
957
{
958
  extern int arc_get_mach (char *);
959
  int mach;
960
  char c;
961
  char *cpu;
962
 
963
  cpu = input_line_pointer;
964
  c = get_symbol_end ();
965
  mach = arc_get_mach (cpu);
966
  *input_line_pointer = c;
967
 
968
  /* If an instruction has already been seen, it's too late.  */
969
  if (cpu_tables_init_p)
970
    {
971
      as_bad (_("\".option\" directive must appear before any instructions"));
972
      ignore_rest_of_line ();
973
      return;
974
    }
975
 
976
  if (mach == -1)
977
    goto bad_cpu;
978
 
979
  if (mach_type_specified_p && mach != arc_mach_type)
980
    {
981
      as_bad (_("\".option\" directive conflicts with initial definition"));
982
      ignore_rest_of_line ();
983
      return;
984
    }
985
  else
986
    {
987
      /* The cpu may have been selected on the command line.  */
988
      if (mach != arc_mach_type)
989
        as_warn (_("\".option\" directive overrides command-line (default) value"));
990
      arc_mach_type = mach;
991
      if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
992
        as_fatal (_("could not set architecture and machine"));
993
      mach_type_specified_p = 1;
994
    }
995
  demand_empty_rest_of_line ();
996
  return;
997
 
998
 bad_cpu:
999
  as_bad (_("invalid identifier for \".option\""));
1000
  ignore_rest_of_line ();
1001
}
1002
 
1003
char *
1004
md_atof (int type, char *litP, int *sizeP)
1005
{
1006
  return ieee_md_atof (type, litP, sizeP, TRUE);
1007
}
1008
 
1009
/* Write a value out to the object file, using the appropriate
1010
   endianness.  */
1011
 
1012
void
1013
md_number_to_chars (char *buf, valueT val, int n)
1014
{
1015
  if (target_big_endian)
1016
    number_to_chars_bigendian (buf, val, n);
1017
  else
1018
    number_to_chars_littleendian (buf, val, n);
1019
}
1020
 
1021
/* Round up a section size to the appropriate boundary.  */
1022
 
1023
valueT
1024
md_section_align (segT segment, valueT size)
1025
{
1026
  int align = bfd_get_section_alignment (stdoutput, segment);
1027
 
1028
  return ((size + (1 << align) - 1) & (-1 << align));
1029
}
1030
 
1031
/* We don't have any form of relaxing.  */
1032
 
1033
int
1034
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1035
                               asection *seg ATTRIBUTE_UNUSED)
1036
{
1037
  as_fatal (_("relaxation not supported\n"));
1038
  return 1;
1039
}
1040
 
1041
/* Convert a machine dependent frag.  We never generate these.  */
1042
 
1043
void
1044
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1045
                 asection *sec ATTRIBUTE_UNUSED,
1046
                 fragS *fragp ATTRIBUTE_UNUSED)
1047
{
1048
  abort ();
1049
}
1050
 
1051
static void
1052
arc_code_symbol (expressionS *expressionP)
1053
{
1054
  if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
1055
    {
1056
      expressionS two;
1057
 
1058
      expressionP->X_op = O_right_shift;
1059
      expressionP->X_add_symbol->sy_value.X_op = O_constant;
1060
      two.X_op = O_constant;
1061
      two.X_add_symbol = two.X_op_symbol = NULL;
1062
      two.X_add_number = 2;
1063
      expressionP->X_op_symbol = make_expr_symbol (&two);
1064
    }
1065
  /* Allow %st(sym1-sym2)  */
1066
  else if (expressionP->X_op == O_subtract
1067
           && expressionP->X_add_symbol != NULL
1068
           && expressionP->X_op_symbol != NULL
1069
           && expressionP->X_add_number == 0)
1070
    {
1071
      expressionS two;
1072
 
1073
      expressionP->X_add_symbol = make_expr_symbol (expressionP);
1074
      expressionP->X_op = O_right_shift;
1075
      two.X_op = O_constant;
1076
      two.X_add_symbol = two.X_op_symbol = NULL;
1077
      two.X_add_number = 2;
1078
      expressionP->X_op_symbol = make_expr_symbol (&two);
1079
    }
1080
  else
1081
    as_bad (_("expression too complex code symbol"));
1082
}
1083
 
1084
/* Parse an operand that is machine-specific.
1085
 
1086
   The ARC has a special %-op to adjust addresses so they're usable in
1087
   branches.  The "st" is short for the STatus register.
1088
   ??? Later expand this to take a flags value too.
1089
 
1090
   ??? We can't create new expression types so we map the %-op's onto the
1091
   existing syntax.  This means that the user could use the chosen syntax
1092
   to achieve the same effect.  */
1093
 
1094
void
1095
md_operand (expressionS *expressionP)
1096
{
1097
  char *p = input_line_pointer;
1098
 
1099
  if (*p != '%')
1100
    return;
1101
 
1102
  if (strncmp (p, "%st(", 4) == 0)
1103
    {
1104
      input_line_pointer += 4;
1105
      expression (expressionP);
1106
      if (*input_line_pointer != ')')
1107
        {
1108
          as_bad (_("missing ')' in %%-op"));
1109
          return;
1110
        }
1111
      ++input_line_pointer;
1112
      arc_code_symbol (expressionP);
1113
    }
1114
  else
1115
    {
1116
      /* It could be a register.  */
1117
      int i, l;
1118
      struct arc_ext_operand_value *ext_oper = arc_ext_operands;
1119
      p++;
1120
 
1121
      while (ext_oper)
1122
        {
1123
          l = strlen (ext_oper->operand.name);
1124
          if (!strncmp (p, ext_oper->operand.name, l) && !ISALNUM (*(p + l)))
1125
            {
1126
              input_line_pointer += l + 1;
1127
              expressionP->X_op = O_register;
1128
              expressionP->X_add_number = (offsetT) &ext_oper->operand;
1129
              return;
1130
            }
1131
          ext_oper = ext_oper->next;
1132
        }
1133
      for (i = 0; i < arc_reg_names_count; i++)
1134
        {
1135
          l = strlen (arc_reg_names[i].name);
1136
          if (!strncmp (p, arc_reg_names[i].name, l) && !ISALNUM (*(p + l)))
1137
            {
1138
              input_line_pointer += l + 1;
1139
              expressionP->X_op = O_register;
1140
              expressionP->X_add_number = (offsetT) &arc_reg_names[i];
1141
              break;
1142
            }
1143
        }
1144
    }
1145
}
1146
 
1147
/* We have no need to default values of symbols.
1148
   We could catch register names here, but that is handled by inserting
1149
   them all in the symbol table to begin with.  */
1150
 
1151
symbolS *
1152
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1153
{
1154
  return 0;
1155
}
1156
 
1157
/* Functions concerning expressions.  */
1158
 
1159
/* Parse a .byte, .word, etc. expression.
1160
 
1161
   Values for the status register are specified with %st(label).
1162
   `label' will be right shifted by 2.  */
1163
 
1164
void
1165
arc_parse_cons_expression (expressionS *exp,
1166
                           unsigned int nbytes ATTRIBUTE_UNUSED)
1167
{
1168
  char *p = input_line_pointer;
1169
  int code_symbol_fix = 0;
1170
 
1171
  for (; ! is_end_of_line[(unsigned char) *p]; p++)
1172
    if (*p == '@' && !strncmp (p, "@h30", 4))
1173
      {
1174
        code_symbol_fix = 1;
1175
        strcpy (p, ";   ");
1176
      }
1177
  expression_and_evaluate (exp);
1178
  if (code_symbol_fix)
1179
    {
1180
      arc_code_symbol (exp);
1181
      input_line_pointer = p;
1182
    }
1183
}
1184
 
1185
/* Record a fixup for a cons expression.  */
1186
 
1187
void
1188
arc_cons_fix_new (fragS *frag,
1189
                  int where,
1190
                  int nbytes,
1191
                  expressionS *exp)
1192
{
1193
  if (nbytes == 4)
1194
    {
1195
      int reloc_type;
1196
      expressionS exptmp;
1197
 
1198
      /* This may be a special ARC reloc (eg: %st()).  */
1199
      reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
1200
      fix_new_exp (frag, where, nbytes, &exptmp, 0,
1201
                   (enum bfd_reloc_code_real) reloc_type);
1202
    }
1203
  else
1204
    {
1205
      fix_new_exp (frag, where, nbytes, exp, 0,
1206
                   nbytes == 2 ? BFD_RELOC_16
1207
                   : nbytes == 8 ? BFD_RELOC_64
1208
                   : BFD_RELOC_32);
1209
    }
1210
}
1211
 
1212
/* Functions concerning relocs.  */
1213
 
1214
/* The location from which a PC relative jump should be calculated,
1215
   given a PC relative reloc.  */
1216
 
1217
long
1218
md_pcrel_from (fixS *fixP)
1219
{
1220
  /* Return the address of the delay slot.  */
1221
  return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1222
}
1223
 
1224
/* Apply a fixup to the object code.  This is called for all the
1225
   fixups we generated by the call to fix_new_exp, above.  In the call
1226
   above we used a reloc code which was the largest legal reloc code
1227
   plus the operand index.  Here we undo that to recover the operand
1228
   index.  At this point all symbol values should be fully resolved,
1229
   and we attempt to completely resolve the reloc.  If we can not do
1230
   that, we determine the correct reloc code and put it back in the fixup.  */
1231
 
1232
void
1233
md_apply_fix (fixS *fixP, valueT * valP, segT seg)
1234
{
1235
  valueT value = * valP;
1236
 
1237
  if (fixP->fx_addsy == (symbolS *) NULL)
1238
    fixP->fx_done = 1;
1239
 
1240
  else if (fixP->fx_pcrel)
1241
    {
1242
      /* Hack around bfd_install_relocation brain damage.  */
1243
      if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
1244
        value += md_pcrel_from (fixP);
1245
    }
1246
 
1247
  /* We can't actually support subtracting a symbol.  */
1248
  if (fixP->fx_subsy != NULL)
1249
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1250
 
1251
  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1252
    {
1253
      int opindex;
1254
      const struct arc_operand *operand;
1255
      char *where;
1256
      arc_insn insn;
1257
 
1258
      opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1259
 
1260
      operand = &arc_operands[opindex];
1261
 
1262
      /* Fetch the instruction, insert the fully resolved operand
1263
         value, and stuff the instruction back again.  */
1264
      where = fixP->fx_frag->fr_literal + fixP->fx_where;
1265
      if (target_big_endian)
1266
        insn = bfd_getb32 ((unsigned char *) where);
1267
      else
1268
        insn = bfd_getl32 ((unsigned char *) where);
1269
      insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
1270
                                 fixP->fx_file, fixP->fx_line);
1271
      if (target_big_endian)
1272
        bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
1273
      else
1274
        bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1275
 
1276
      if (fixP->fx_done)
1277
        /* Nothing else to do here.  */
1278
        return;
1279
 
1280
      /* Determine a BFD reloc value based on the operand information.
1281
         We are only prepared to turn a few of the operands into relocs.
1282
         !!! Note that we can't handle limm values here.  Since we're using
1283
         implicit addends the addend must be inserted into the instruction,
1284
         however, the opcode insertion routines currently do nothing with
1285
         limm values.  */
1286
      if (operand->fmt == 'B')
1287
        {
1288
          gas_assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
1289
                  && operand->bits == 20
1290
                  && operand->shift == 7);
1291
          fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
1292
        }
1293
      else if (operand->fmt == 'J')
1294
        {
1295
          gas_assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
1296
                  && operand->bits == 24
1297
                  && operand->shift == 32);
1298
          fixP->fx_r_type = BFD_RELOC_ARC_B26;
1299
        }
1300
      else if (operand->fmt == 'L')
1301
        {
1302
          gas_assert ((operand->flags & ARC_OPERAND_LIMM) != 0
1303
                  && operand->bits == 32
1304
                  && operand->shift == 32);
1305
          fixP->fx_r_type = BFD_RELOC_32;
1306
        }
1307
      else
1308
        {
1309
          as_bad_where (fixP->fx_file, fixP->fx_line,
1310
                        _("unresolved expression that must be resolved"));
1311
          fixP->fx_done = 1;
1312
          return;
1313
        }
1314
    }
1315
  else
1316
    {
1317
      switch (fixP->fx_r_type)
1318
        {
1319
        case BFD_RELOC_8:
1320
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1321
                              value, 1);
1322
          break;
1323
        case BFD_RELOC_16:
1324
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1325
                              value, 2);
1326
          break;
1327
        case BFD_RELOC_32:
1328
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1329
                              value, 4);
1330
          break;
1331
        case BFD_RELOC_ARC_B26:
1332
          /* If !fixP->fx_done then `value' is an implicit addend.
1333
             We must shift it right by 2 in this case as well because the
1334
             linker performs the relocation and then adds this in (as opposed
1335
             to adding this in and then shifting right by 2).  */
1336
          value >>= 2;
1337
          md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1338
                              value, 4);
1339
          break;
1340
        default:
1341
          abort ();
1342
        }
1343
    }
1344
}
1345
 
1346
/* Translate internal representation of relocation info to BFD target
1347
   format.  */
1348
 
1349
arelent *
1350
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1351
              fixS *fixP)
1352
{
1353
  arelent *reloc;
1354
 
1355
  reloc = (arelent *) xmalloc (sizeof (arelent));
1356
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1357
 
1358
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1359
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1360
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1361
  if (reloc->howto == (reloc_howto_type *) NULL)
1362
    {
1363
      as_bad_where (fixP->fx_file, fixP->fx_line,
1364
                    _("internal error: can't export reloc type %d (`%s')"),
1365
                    fixP->fx_r_type,
1366
                    bfd_get_reloc_code_name (fixP->fx_r_type));
1367
      return NULL;
1368
    }
1369
 
1370
  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1371
 
1372
  /* Set addend to account for PC being advanced one insn before the
1373
     target address is computed.  */
1374
 
1375
  reloc->addend = (fixP->fx_pcrel ? -4 : 0);
1376
 
1377
  return reloc;
1378
}
1379
 
1380
const pseudo_typeS md_pseudo_table[] =
1381
{
1382
  { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0).  */
1383
  { "comm", arc_common, 0 },
1384
  { "common", arc_common, 0 },
1385
  { "lcomm", arc_common, 1 },
1386
  { "lcommon", arc_common, 1 },
1387
  { "2byte", cons, 2 },
1388
  { "half", cons, 2 },
1389
  { "short", cons, 2 },
1390
  { "3byte", cons, 3 },
1391
  { "4byte", cons, 4 },
1392
  { "word", cons, 4 },
1393
  { "option", arc_option, 0 },
1394
  { "cpu", arc_option, 0 },
1395
  { "block", s_space, 0 },
1396
  { "extcondcode", arc_extoper, 0 },
1397
  { "extcoreregister", arc_extoper, 1 },
1398
  { "extauxregister", arc_extoper, 2 },
1399
  { "extinstruction", arc_extinst, 0 },
1400
  { NULL, 0, 0 },
1401
};
1402
 
1403
/* This routine is called for each instruction to be assembled.  */
1404
 
1405
void
1406
md_assemble (char *str)
1407
{
1408
  const struct arc_opcode *opcode;
1409
  const struct arc_opcode *std_opcode;
1410
  struct arc_opcode *ext_opcode;
1411
  char *start;
1412
  const char *last_errmsg = 0;
1413
  arc_insn insn;
1414
  static int init_tables_p = 0;
1415
 
1416
  /* Opcode table initialization is deferred until here because we have to
1417
     wait for a possible .option command.  */
1418
  if (!init_tables_p)
1419
    {
1420
      init_opcode_tables (arc_mach_type);
1421
      init_tables_p = 1;
1422
    }
1423
 
1424
  /* Skip leading white space.  */
1425
  while (ISSPACE (*str))
1426
    str++;
1427
 
1428
  /* The instructions are stored in lists hashed by the first letter (though
1429
     we needn't care how they're hashed).  Get the first in the list.  */
1430
 
1431
  ext_opcode = arc_ext_opcodes;
1432
  std_opcode = arc_opcode_lookup_asm (str);
1433
 
1434
  /* Keep looking until we find a match.  */
1435
  start = str;
1436
  for (opcode = (ext_opcode ? ext_opcode : std_opcode);
1437
       opcode != NULL;
1438
       opcode = (ARC_OPCODE_NEXT_ASM (opcode)
1439
                 ? ARC_OPCODE_NEXT_ASM (opcode)
1440
                 : (ext_opcode ? ext_opcode = NULL, std_opcode : NULL)))
1441
    {
1442
      int past_opcode_p, fc, num_suffixes;
1443
      int fix_up_at = 0;
1444
      char *syn;
1445
      struct arc_fixup fixups[MAX_FIXUPS];
1446
      /* Used as a sanity check.  If we need a limm reloc, make sure we ask
1447
         for an extra 4 bytes from frag_more.  */
1448
      int limm_reloc_p;
1449
      int ext_suffix_p;
1450
      const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
1451
 
1452
      /* Is this opcode supported by the selected cpu?  */
1453
      if (! arc_opcode_supported (opcode))
1454
        continue;
1455
 
1456
      /* Scan the syntax string.  If it doesn't match, try the next one.  */
1457
      arc_opcode_init_insert ();
1458
      insn = opcode->value;
1459
      fc = 0;
1460
      past_opcode_p = 0;
1461
      num_suffixes = 0;
1462
      limm_reloc_p = 0;
1463
      ext_suffix_p = 0;
1464
 
1465
      /* We don't check for (*str != '\0') here because we want to parse
1466
         any trailing fake arguments in the syntax string.  */
1467
      for (str = start, syn = opcode->syntax; *syn != '\0';)
1468
        {
1469
          int mods;
1470
          const struct arc_operand *operand;
1471
 
1472
          /* Non operand chars must match exactly.  */
1473
          if (*syn != '%' || *++syn == '%')
1474
            {
1475
             if (*str == *syn)
1476
                {
1477
                  if (*syn == ' ')
1478
                    past_opcode_p = 1;
1479
                  ++syn;
1480
                  ++str;
1481
                }
1482
              else
1483
                break;
1484
              continue;
1485
            }
1486
 
1487
          /* We have an operand.  Pick out any modifiers.  */
1488
          mods = 0;
1489
          while (ARC_MOD_P (arc_operands[arc_operand_map[(int) *syn]].flags))
1490
            {
1491
              mods |= arc_operands[arc_operand_map[(int) *syn]].flags & ARC_MOD_BITS;
1492
              ++syn;
1493
            }
1494
          operand = arc_operands + arc_operand_map[(int) *syn];
1495
          if (operand->fmt == 0)
1496
            as_fatal (_("unknown syntax format character `%c'"), *syn);
1497
 
1498
          if (operand->flags & ARC_OPERAND_FAKE)
1499
            {
1500
              const char *errmsg = NULL;
1501
              if (operand->insert)
1502
                {
1503
                  insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
1504
                  if (errmsg != (const char *) NULL)
1505
                    {
1506
                      last_errmsg = errmsg;
1507
                      if (operand->flags & ARC_OPERAND_ERROR)
1508
                        {
1509
                          as_bad ("%s", errmsg);
1510
                          return;
1511
                        }
1512
                      else if (operand->flags & ARC_OPERAND_WARN)
1513
                        as_warn ("%s", errmsg);
1514
                      break;
1515
                    }
1516
                  if (limm_reloc_p
1517
                      && (operand->flags && operand->flags & ARC_OPERAND_LIMM)
1518
                      && (operand->flags &
1519
                          (ARC_OPERAND_ABSOLUTE_BRANCH | ARC_OPERAND_ADDRESS)))
1520
                    {
1521
                      fixups[fix_up_at].opindex = arc_operand_map[operand->fmt];
1522
                    }
1523
                }
1524
              ++syn;
1525
            }
1526
          /* Are we finished with suffixes?  */
1527
          else if (!past_opcode_p)
1528
            {
1529
              int found;
1530
              char c;
1531
              char *s, *t;
1532
              const struct arc_operand_value *suf, *suffix_end;
1533
              const struct arc_operand_value *suffix = NULL;
1534
 
1535
              if (!(operand->flags & ARC_OPERAND_SUFFIX))
1536
                abort ();
1537
 
1538
              /* If we're at a space in the input string, we want to skip the
1539
                 remaining suffixes.  There may be some fake ones though, so
1540
                 just go on to try the next one.  */
1541
              if (*str == ' ')
1542
                {
1543
                  ++syn;
1544
                  continue;
1545
                }
1546
 
1547
              s = str;
1548
              if (mods & ARC_MOD_DOT)
1549
                {
1550
                  if (*s != '.')
1551
                    break;
1552
                  ++s;
1553
                }
1554
              else
1555
                {
1556
                  /* This can happen in "b.nd foo" and we're currently looking
1557
                     for "%q" (ie: a condition code suffix).  */
1558
                  if (*s == '.')
1559
                    {
1560
                      ++syn;
1561
                      continue;
1562
                    }
1563
                }
1564
 
1565
              /* Pick the suffix out and look it up via the hash table.  */
1566
              for (t = s; *t && ISALNUM (*t); ++t)
1567
                continue;
1568
              c = *t;
1569
              *t = '\0';
1570
              if ((suf = get_ext_suffix (s)))
1571
                ext_suffix_p = 1;
1572
              else
1573
                suf = (const struct arc_operand_value *)
1574
                    hash_find (arc_suffix_hash, s);
1575
              if (!suf)
1576
                {
1577
                  /* This can happen in "blle foo" and we're currently using
1578
                     the template "b%q%.n %j".  The "bl" insn occurs later in
1579
                     the table so "lle" isn't an illegal suffix.  */
1580
                  *t = c;
1581
                  break;
1582
                }
1583
 
1584
              /* Is it the right type?  Note that the same character is used
1585
                 several times, so we have to examine all of them.  This is
1586
                 relatively efficient as equivalent entries are kept
1587
                 together.  If it's not the right type, don't increment `str'
1588
                 so we try the next one in the series.  */
1589
              found = 0;
1590
              if (ext_suffix_p && arc_operands[suf->type].fmt == *syn)
1591
                {
1592
                  /* Insert the suffix's value into the insn.  */
1593
                  *t = c;
1594
                  if (operand->insert)
1595
                    insn = (*operand->insert) (insn, operand,
1596
                                               mods, NULL, suf->value,
1597
                                               NULL);
1598
                  else
1599
                    insn |= suf->value << operand->shift;
1600
                  suffix = suf;
1601
                  str = t;
1602
                  found = 1;
1603
                }
1604
              else
1605
                {
1606
                  *t = c;
1607
                  suffix_end = arc_suffixes + arc_suffixes_count;
1608
                  for (suffix = suf;
1609
                       suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
1610
                       ++suffix)
1611
                    {
1612
                      if (arc_operands[suffix->type].fmt == *syn)
1613
                        {
1614
                          /* Insert the suffix's value into the insn.  */
1615
                          if (operand->insert)
1616
                            insn = (*operand->insert) (insn, operand,
1617
                                                       mods, NULL, suffix->value,
1618
                                                       NULL);
1619
                          else
1620
                            insn |= suffix->value << operand->shift;
1621
 
1622
                          str = t;
1623
                          found = 1;
1624
                          break;
1625
                        }
1626
                    }
1627
                }
1628
              ++syn;
1629
              if (!found)
1630
                /* Wrong type.  Just go on to try next insn entry.  */
1631
                ;
1632
              else
1633
                {
1634
                  if (num_suffixes == MAX_SUFFIXES)
1635
                    as_bad (_("too many suffixes"));
1636
                  else
1637
                    insn_suffixes[num_suffixes++] = suffix;
1638
                }
1639
            }
1640
          else
1641
            /* This is either a register or an expression of some kind.  */
1642
            {
1643
              char *hold;
1644
              const struct arc_operand_value *reg = NULL;
1645
              long value = 0;
1646
              expressionS exp;
1647
 
1648
              if (operand->flags & ARC_OPERAND_SUFFIX)
1649
                abort ();
1650
 
1651
              /* Is there anything left to parse?
1652
                 We don't check for this at the top because we want to parse
1653
                 any trailing fake arguments in the syntax string.  */
1654
              if (is_end_of_line[(unsigned char) *str])
1655
                break;
1656
 
1657
              /* Parse the operand.  */
1658
              hold = input_line_pointer;
1659
              input_line_pointer = str;
1660
              expression (&exp);
1661
              str = input_line_pointer;
1662
              input_line_pointer = hold;
1663
 
1664
              if (exp.X_op == O_illegal)
1665
                as_bad (_("illegal operand"));
1666
              else if (exp.X_op == O_absent)
1667
                as_bad (_("missing operand"));
1668
              else if (exp.X_op == O_constant)
1669
                value = exp.X_add_number;
1670
              else if (exp.X_op == O_register)
1671
                reg = (struct arc_operand_value *) exp.X_add_number;
1672
#define IS_REG_DEST_OPERAND(o) ((o) == 'a')
1673
              else if (IS_REG_DEST_OPERAND (*syn))
1674
                as_bad (_("symbol as destination register"));
1675
              else
1676
                {
1677
                  if (!strncmp (str, "@h30", 4))
1678
                    {
1679
                      arc_code_symbol (&exp);
1680
                      str += 4;
1681
                    }
1682
                  /* We need to generate a fixup for this expression.  */
1683
                  if (fc >= MAX_FIXUPS)
1684
                    as_fatal (_("too many fixups"));
1685
                  fixups[fc].exp = exp;
1686
                  /* We don't support shimm relocs. break here to force
1687
                     the assembler to output a limm.  */
1688
#define IS_REG_SHIMM_OFFSET(o) ((o) == 'd')
1689
                  if (IS_REG_SHIMM_OFFSET (*syn))
1690
                    break;
1691
                  /* If this is a register constant (IE: one whose
1692
                     register value gets stored as 61-63) then this
1693
                     must be a limm.  */
1694
                  /* ??? This bit could use some cleaning up.
1695
                     Referencing the format chars like this goes
1696
                     against style.  */
1697
                  if (IS_SYMBOL_OPERAND (*syn))
1698
                    {
1699
                      const char *junk;
1700
                      limm_reloc_p = 1;
1701
                      /* Save this, we don't yet know what reloc to use.  */
1702
                      fix_up_at = fc;
1703
                      /* Tell insert_reg we need a limm.  This is
1704
                         needed because the value at this point is
1705
                         zero, a shimm.  */
1706
                      /* ??? We need a cleaner interface than this.  */
1707
                      (*arc_operands[arc_operand_map['Q']].insert)
1708
                        (insn, operand, mods, reg, 0L, &junk);
1709
                    }
1710
                  else
1711
                    fixups[fc].opindex = arc_operand_map[(int) *syn];
1712
                  ++fc;
1713
                  value = 0;
1714
                }
1715
 
1716
              /* Insert the register or expression into the instruction.  */
1717
              if (operand->insert)
1718
                {
1719
                  const char *errmsg = NULL;
1720
                  insn = (*operand->insert) (insn, operand, mods,
1721
                                             reg, (long) value, &errmsg);
1722
                  if (errmsg != (const char *) NULL)
1723
                    {
1724
                      last_errmsg = errmsg;
1725
                      if (operand->flags & ARC_OPERAND_ERROR)
1726
                        {
1727
                          as_bad ("%s", errmsg);
1728
                          return;
1729
                        }
1730
                      else if (operand->flags & ARC_OPERAND_WARN)
1731
                        as_warn ("%s", errmsg);
1732
                      break;
1733
                    }
1734
                }
1735
              else
1736
                insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
1737
 
1738
              ++syn;
1739
            }
1740
        }
1741
 
1742
      /* If we're at the end of the syntax string, we're done.  */
1743
      /* FIXME: try to move this to a separate function.  */
1744
      if (*syn == '\0')
1745
        {
1746
          int i;
1747
          char *f;
1748
          long limm, limm_p;
1749
 
1750
          /* For the moment we assume a valid `str' can only contain blanks
1751
             now.  IE: We needn't try again with a longer version of the
1752
             insn and it is assumed that longer versions of insns appear
1753
             before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1754
 
1755
          while (ISSPACE (*str))
1756
            ++str;
1757
 
1758
          if (!is_end_of_line[(unsigned char) *str])
1759
            as_bad (_("junk at end of line: `%s'"), str);
1760
 
1761
          /* Is there a limm value?  */
1762
          limm_p = arc_opcode_limm_p (&limm);
1763
 
1764
          /* Perform various error and warning tests.  */
1765
 
1766
          {
1767
            static int in_delay_slot_p = 0;
1768
            static int prev_insn_needs_cc_nop_p = 0;
1769
            /* delay slot type seen */
1770
            int delay_slot_type = ARC_DELAY_NONE;
1771
            /* conditional execution flag seen */
1772
            int conditional = 0;
1773
            /* 1 if condition codes are being set */
1774
            int cc_set_p = 0;
1775
            /* 1 if conditional branch, including `b' "branch always" */
1776
            int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
1777
 
1778
            for (i = 0; i < num_suffixes; ++i)
1779
              {
1780
                switch (arc_operands[insn_suffixes[i]->type].fmt)
1781
                  {
1782
                  case 'n':
1783
                    delay_slot_type = insn_suffixes[i]->value;
1784
                    break;
1785
                  case 'q':
1786
                    conditional = insn_suffixes[i]->value;
1787
                    break;
1788
                  case 'f':
1789
                    cc_set_p = 1;
1790
                    break;
1791
                  }
1792
              }
1793
 
1794
            /* Putting an insn with a limm value in a delay slot is supposed to
1795
               be legal, but let's warn the user anyway.  Ditto for 8 byte
1796
               jumps with delay slots.  */
1797
            if (in_delay_slot_p && limm_p)
1798
              as_warn (_("8 byte instruction in delay slot"));
1799
            if (delay_slot_type != ARC_DELAY_NONE
1800
                && limm_p && arc_insn_not_jl (insn)) /* except for jl  addr */
1801
              as_warn (_("8 byte jump instruction with delay slot"));
1802
            in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
1803
 
1804
            /* Warn when a conditional branch immediately follows a set of
1805
               the condition codes.  Note that this needn't be done if the
1806
               insn that sets the condition codes uses a limm.  */
1807
            if (cond_branch_p && conditional != 0 /* 0 = "always" */
1808
                && prev_insn_needs_cc_nop_p && arc_mach_type == bfd_mach_arc_5)
1809
              as_warn (_("conditional branch follows set of flags"));
1810
            prev_insn_needs_cc_nop_p =
1811
              /* FIXME: ??? not required:
1812
                 (delay_slot_type != ARC_DELAY_NONE) &&  */
1813
              cc_set_p && !limm_p;
1814
          }
1815
 
1816
          /* Write out the instruction.
1817
             It is important to fetch enough space in one call to `frag_more'.
1818
             We use (f - frag_now->fr_literal) to compute where we are and we
1819
             don't want frag_now to change between calls.  */
1820
          if (limm_p)
1821
            {
1822
              f = frag_more (8);
1823
              md_number_to_chars (f, insn, 4);
1824
              md_number_to_chars (f + 4, limm, 4);
1825
              dwarf2_emit_insn (8);
1826
            }
1827
          else if (limm_reloc_p)
1828
            /* We need a limm reloc, but the tables think we don't.  */
1829
            abort ();
1830
          else
1831
            {
1832
              f = frag_more (4);
1833
              md_number_to_chars (f, insn, 4);
1834
              dwarf2_emit_insn (4);
1835
            }
1836
 
1837
          /* Create any fixups.  */
1838
          for (i = 0; i < fc; ++i)
1839
            {
1840
              int op_type, reloc_type;
1841
              expressionS exptmp;
1842
              const struct arc_operand *operand;
1843
 
1844
              /* Create a fixup for this operand.
1845
                 At this point we do not use a bfd_reloc_code_real_type for
1846
                 operands residing in the insn, but instead just use the
1847
                 operand index.  This lets us easily handle fixups for any
1848
                 operand type, although that is admittedly not a very exciting
1849
                 feature.  We pick a BFD reloc type in md_apply_fix.
1850
 
1851
                 Limm values (4 byte immediate "constants") must be treated
1852
                 normally because they're not part of the actual insn word
1853
                 and thus the insertion routines don't handle them.  */
1854
 
1855
              if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
1856
                {
1857
                  /* Modify the fixup addend as required by the cpu.  */
1858
                  fixups[i].exp.X_add_number += arc_limm_fixup_adjust (insn);
1859
                  op_type = fixups[i].opindex;
1860
                  /* FIXME: can we add this data to the operand table?  */
1861
                  if (op_type == arc_operand_map['L']
1862
                      || op_type == arc_operand_map['s']
1863
                      || op_type == arc_operand_map['o']
1864
                      || op_type == arc_operand_map['O'])
1865
                    reloc_type = BFD_RELOC_32;
1866
                  else if (op_type == arc_operand_map['J'])
1867
                    reloc_type = BFD_RELOC_ARC_B26;
1868
                  else
1869
                    abort ();
1870
                  reloc_type = get_arc_exp_reloc_type (1, reloc_type,
1871
                                                       &fixups[i].exp,
1872
                                                       &exptmp);
1873
                }
1874
              else
1875
                {
1876
                  op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
1877
                                                    &fixups[i].exp, &exptmp);
1878
                  reloc_type = op_type + (int) BFD_RELOC_UNUSED;
1879
                }
1880
              operand = &arc_operands[op_type];
1881
              fix_new_exp (frag_now,
1882
                           ((f - frag_now->fr_literal)
1883
                            + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
1884
                           &exptmp,
1885
                           (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
1886
                           (bfd_reloc_code_real_type) reloc_type);
1887
            }
1888
          return;
1889
        }
1890
    }
1891
 
1892
  if (NULL == last_errmsg)
1893
    as_bad (_("bad instruction `%s'"), start);
1894
  else
1895
    as_bad ("%s", last_errmsg);
1896
}

powered by: WebSVN 2.1.0

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