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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 38 julius
/* tc-crx.c -- Assembler code for the CRX CPU core.
2
   Copyright 2004, 2007 Free Software Foundation, Inc.
3
 
4
   Contributed by Tomer Levi, NSC, Israel.
5
   Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
6
   Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
7
 
8
   This file is part of GAS, the GNU Assembler.
9
 
10
   GAS is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3, or (at your option)
13
   any later version.
14
 
15
   GAS is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with GAS; see the file COPYING.  If not, write to the
22
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
#include "as.h"
26
#include "safe-ctype.h"
27
#include "dwarf2dbg.h"
28
#include "opcode/crx.h"
29
#include "elf/crx.h"
30
 
31
/* Word is considered here as a 16-bit unsigned short int.  */
32
#define WORD_SHIFT  16
33
 
34
/* Register is 4-bit size.  */
35
#define REG_SIZE   4
36
 
37
/* Maximum size of a single instruction (in words).  */
38
#define INSN_MAX_SIZE   3
39
 
40
/* Maximum bits which may be set in a `mask16' operand.  */
41
#define MAX_REGS_IN_MASK16  8
42
 
43
/* Utility macros for string comparison.  */
44
#define streq(a, b)           (strcmp (a, b) == 0)
45
#define strneq(a, b, c)       (strncmp (a, b, c) == 0)
46
 
47
/* Assign a number NUM, shifted by SHIFT bytes, into a location
48
   pointed by index BYTE of array 'output_opcode'.  */
49
#define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)
50
 
51
/* Operand errors.  */
52
typedef enum
53
  {
54
    OP_LEGAL = 0,        /* Legal operand.  */
55
    OP_OUT_OF_RANGE,    /* Operand not within permitted range.  */
56
    OP_NOT_EVEN,        /* Operand is Odd number, should be even.  */
57
    OP_ILLEGAL_DISPU4,  /* Operand is not within DISPU4 range.  */
58
    OP_ILLEGAL_CST4,    /* Operand is not within CST4 range.  */
59
    OP_NOT_UPPER_64KB   /* Operand is not within the upper 64KB
60
                           (0xFFFF0000-0xFFFFFFFF).  */
61
  }
62
op_err;
63
 
64
/* Opcode mnemonics hash table.  */
65
static struct hash_control *crx_inst_hash;
66
/* CRX registers hash table.  */
67
static struct hash_control *reg_hash;
68
/* CRX coprocessor registers hash table.  */
69
static struct hash_control *copreg_hash;
70
/* Current instruction we're assembling.  */
71
const inst *instruction;
72
 
73
/* Global variables.  */
74
 
75
/* Array to hold an instruction encoding.  */
76
long output_opcode[2];
77
 
78
/* Nonzero means a relocatable symbol.  */
79
int relocatable;
80
 
81
/* A copy of the original instruction (used in error messages).  */
82
char ins_parse[MAX_INST_LEN];
83
 
84
/* The current processed argument number.  */
85
int cur_arg_num;
86
 
87
/* Generic assembler global variables which must be defined by all targets.  */
88
 
89
/* Characters which always start a comment.  */
90
const char comment_chars[] = "#";
91
 
92
/* Characters which start a comment at the beginning of a line.  */
93
const char line_comment_chars[] = "#";
94
 
95
/* This array holds machine specific line separator characters.  */
96
const char line_separator_chars[] = ";";
97
 
98
/* Chars that can be used to separate mant from exp in floating point nums.  */
99
const char EXP_CHARS[] = "eE";
100
 
101
/* Chars that mean this number is a floating point constant as in 0f12.456  */
102
const char FLT_CHARS[] = "f'";
103
 
104
/* Target-specific multicharacter options, not const-declared at usage.  */
105
const char *md_shortopts = "";
106
struct option md_longopts[] =
107
{
108
  {NULL, no_argument, NULL, 0}
109
};
110
size_t md_longopts_size = sizeof (md_longopts);
111
 
112
/* This table describes all the machine specific pseudo-ops
113
   the assembler has to support.  The fields are:
114
   *** Pseudo-op name without dot.
115
   *** Function to call to execute this pseudo-op.
116
   *** Integer arg to pass to the function.  */
117
 
118
const pseudo_typeS md_pseudo_table[] =
119
{
120
  /* In CRX machine, align is in bytes (not a ptwo boundary).  */
121
  {"align", s_align_bytes, 0},
122
  {0, 0, 0}
123
};
124
 
125
/* CRX relaxation table.  */
126
const relax_typeS md_relax_table[] =
127
{
128
  /* bCC  */
129
  {0xfa, -0x100, 2, 1},                 /*  8 */
130
  {0xfffe, -0x10000, 4, 2},             /* 16 */
131
  {0xfffffffe, -0xfffffffe, 6, 0},       /* 32 */
132
 
133
  /* bal  */
134
  {0xfffe, -0x10000, 4, 4},             /* 16 */
135
  {0xfffffffe, -0xfffffffe, 6, 0},       /* 32 */
136
 
137
  /* cmpbr/bcop  */
138
  {0xfe, -0x100, 4, 6},                 /*  8 */
139
  {0xfffffe, -0x1000000, 6, 0}           /* 24 */
140
};
141
 
142
static void    reset_vars               (char *);
143
static reg     get_register             (char *);
144
static copreg  get_copregister          (char *);
145
static argtype get_optype               (operand_type);
146
static int     get_opbits               (operand_type);
147
static int     get_opflags              (operand_type);
148
static int     get_number_of_operands   (void);
149
static void    parse_operand            (char *, ins *);
150
static int     gettrap                  (char *);
151
static void    handle_LoadStor          (char *);
152
static int     get_cinv_parameters      (char *);
153
static long    getconstant              (long, int);
154
static op_err  check_range              (long *, int, unsigned int, int);
155
static int     getreg_image             (reg);
156
static void    parse_operands           (ins *, char *);
157
static void    parse_insn               (ins *, char *);
158
static void    print_operand            (int, int, argument *);
159
static void    print_constant           (int, int, argument *);
160
static int     exponent2scale           (int);
161
static void    mask_reg                 (int, unsigned short *);
162
static void    process_label_constant   (char *, ins *);
163
static void    set_operand              (char *, ins *);
164
static char *  preprocess_reglist       (char *, int *);
165
static int     assemble_insn            (char *, ins *);
166
static void    print_insn               (ins *);
167
static void    warn_if_needed           (ins *);
168
static int     adjust_if_needed         (ins *);
169
 
170
/* Return the bit size for a given operand.  */
171
 
172
static int
173
get_opbits (operand_type op)
174
{
175
  if (op < MAX_OPRD)
176
    return crx_optab[op].bit_size;
177
  else
178
    return 0;
179
}
180
 
181
/* Return the argument type of a given operand.  */
182
 
183
static argtype
184
get_optype (operand_type op)
185
{
186
  if (op < MAX_OPRD)
187
    return crx_optab[op].arg_type;
188
  else
189
    return nullargs;
190
}
191
 
192
/* Return the flags of a given operand.  */
193
 
194
static int
195
get_opflags (operand_type op)
196
{
197
  if (op < MAX_OPRD)
198
    return crx_optab[op].flags;
199
  else
200
    return 0;
201
}
202
 
203
/* Get the core processor register 'reg_name'.  */
204
 
205
static reg
206
get_register (char *reg_name)
207
{
208
  const reg_entry *reg;
209
 
210
  reg = (const reg_entry *) hash_find (reg_hash, reg_name);
211
 
212
  if (reg != NULL)
213
    return reg->value.reg_val;
214
  else
215
    return nullregister;
216
}
217
 
218
/* Get the coprocessor register 'copreg_name'.  */
219
 
220
static copreg
221
get_copregister (char *copreg_name)
222
{
223
  const reg_entry *copreg;
224
 
225
  copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
226
 
227
  if (copreg != NULL)
228
    return copreg->value.copreg_val;
229
  else
230
    return nullcopregister;
231
}
232
 
233
/* Round up a section size to the appropriate boundary.  */
234
 
235
valueT
236
md_section_align (segT seg, valueT val)
237
{
238
  /* Round .text section to a multiple of 2.  */
239
  if (seg == text_section)
240
    return (val + 1) & ~1;
241
  return val;
242
}
243
 
244
/* Parse an operand that is machine-specific (remove '*').  */
245
 
246
void
247
md_operand (expressionS * exp)
248
{
249
  char c = *input_line_pointer;
250
 
251
  switch (c)
252
    {
253
    case '*':
254
      input_line_pointer++;
255
      expression (exp);
256
      break;
257
    default:
258
      break;
259
    }
260
}
261
 
262
/* Reset global variables before parsing a new instruction.  */
263
 
264
static void
265
reset_vars (char *op)
266
{
267
  cur_arg_num = relocatable = 0;
268
  memset (& output_opcode, '\0', sizeof (output_opcode));
269
 
270
  /* Save a copy of the original OP (used in error messages).  */
271
  strncpy (ins_parse, op, sizeof ins_parse - 1);
272
  ins_parse [sizeof ins_parse - 1] = 0;
273
}
274
 
275
/* This macro decides whether a particular reloc is an entry in a
276
   switch table.  It is used when relaxing, because the linker needs
277
   to know about all such entries so that it can adjust them if
278
   necessary.  */
279
 
280
#define SWITCH_TABLE(fix)                                 \
281
  (   (fix)->fx_addsy != NULL                             \
282
   && (fix)->fx_subsy != NULL                             \
283
   && S_GET_SEGMENT ((fix)->fx_addsy) ==                  \
284
      S_GET_SEGMENT ((fix)->fx_subsy)                     \
285
   && S_GET_SEGMENT (fix->fx_addsy) != undefined_section  \
286
   && (   (fix)->fx_r_type == BFD_RELOC_CRX_NUM8          \
287
       || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16         \
288
       || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
289
 
290
/* See whether we need to force a relocation into the output file.
291
   This is used to force out switch and PC relative relocations when
292
   relaxing.  */
293
 
294
int
295
crx_force_relocation (fixS *fix)
296
{
297
  if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
298
    return 1;
299
 
300
  return 0;
301
}
302
 
303
/* Generate a relocation entry for a fixup.  */
304
 
305
arelent *
306
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
307
{
308
  arelent * reloc;
309
 
310
  reloc = xmalloc (sizeof (arelent));
311
  reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
312
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
313
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
314
  reloc->addend = fixP->fx_offset;
315
 
316
  if (fixP->fx_subsy != NULL)
317
    {
318
      if (SWITCH_TABLE (fixP))
319
        {
320
          /* Keep the current difference in the addend.  */
321
          reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
322
                           - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
323
 
324
          switch (fixP->fx_r_type)
325
            {
326
            case BFD_RELOC_CRX_NUM8:
327
              fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
328
              break;
329
            case BFD_RELOC_CRX_NUM16:
330
              fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
331
              break;
332
            case BFD_RELOC_CRX_NUM32:
333
              fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
334
              break;
335
            default:
336
              abort ();
337
              break;
338
            }
339
        }
340
      else
341
        {
342
          /* We only resolve difference expressions in the same section.  */
343
          as_bad_where (fixP->fx_file, fixP->fx_line,
344
                        _("can't resolve `%s' {%s section} - `%s' {%s section}"),
345
                        fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
346
                        segment_name (fixP->fx_addsy
347
                                      ? S_GET_SEGMENT (fixP->fx_addsy)
348
                                      : absolute_section),
349
                        S_GET_NAME (fixP->fx_subsy),
350
                        segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
351
        }
352
    }
353
 
354
  assert ((int) fixP->fx_r_type > 0);
355
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
356
 
357
  if (reloc->howto == (reloc_howto_type *) NULL)
358
    {
359
      as_bad_where (fixP->fx_file, fixP->fx_line,
360
                    _("internal error: reloc %d (`%s') not supported by object file format"),
361
                    fixP->fx_r_type,
362
                    bfd_get_reloc_code_name (fixP->fx_r_type));
363
      return NULL;
364
    }
365
  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
366
 
367
  return reloc;
368
}
369
 
370
/* Prepare machine-dependent frags for relaxation.  */
371
 
372
int
373
md_estimate_size_before_relax (fragS *fragp, asection *seg)
374
{
375
  /* If symbol is undefined or located in a different section,
376
     select the largest supported relocation.  */
377
  relax_substateT subtype;
378
  relax_substateT rlx_state[] = {0, 2,
379
                                 3, 4,
380
                                 5, 6};
381
 
382
  for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
383
    {
384
      if (fragp->fr_subtype == rlx_state[subtype]
385
          && (!S_IS_DEFINED (fragp->fr_symbol)
386
              || seg != S_GET_SEGMENT (fragp->fr_symbol)))
387
        {
388
          fragp->fr_subtype = rlx_state[subtype + 1];
389
          break;
390
        }
391
    }
392
 
393
  if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
394
    abort ();
395
 
396
  return md_relax_table[fragp->fr_subtype].rlx_length;
397
}
398
 
399
void
400
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
401
{
402
  /* 'opcode' points to the start of the instruction, whether
403
     we need to change the instruction's fixed encoding.  */
404
  char *opcode = fragP->fr_literal + fragP->fr_fix;
405
  bfd_reloc_code_real_type reloc;
406
 
407
  subseg_change (sec, 0);
408
 
409
  switch (fragP->fr_subtype)
410
    {
411
    case 0:
412
      reloc = BFD_RELOC_CRX_REL8;
413
      break;
414
    case 1:
415
      *opcode = 0x7e;
416
      reloc = BFD_RELOC_CRX_REL16;
417
      break;
418
    case 2:
419
      *opcode = 0x7f;
420
      reloc = BFD_RELOC_CRX_REL32;
421
      break;
422
    case 3:
423
      reloc = BFD_RELOC_CRX_REL16;
424
      break;
425
    case 4:
426
      *++opcode = 0x31;
427
      reloc = BFD_RELOC_CRX_REL32;
428
      break;
429
    case 5:
430
      reloc = BFD_RELOC_CRX_REL8_CMP;
431
      break;
432
    case 6:
433
      *++opcode = 0x31;
434
      reloc = BFD_RELOC_CRX_REL24;
435
      break;
436
    default:
437
      abort ();
438
      break;
439
    }
440
 
441
    fix_new (fragP, fragP->fr_fix,
442
             bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
443
             fragP->fr_symbol, fragP->fr_offset, 1, reloc);
444
    fragP->fr_var = 0;
445
    fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
446
}
447
 
448
/* Process machine-dependent command line options.  Called once for
449
   each option on the command line that the machine-independent part of
450
   GAS does not understand.  */
451
 
452
int
453
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
454
{
455
  return 0;
456
}
457
 
458
/* Machine-dependent usage-output.  */
459
 
460
void
461
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
462
{
463
  return;
464
}
465
 
466
char *
467
md_atof (int type, char *litP, int *sizeP)
468
{
469
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
470
}
471
 
472
/* Apply a fixS (fixup of an instruction or data that we didn't have
473
   enough info to complete immediately) to the data in a frag.
474
   Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
475
   relaxation of debug sections, this function is called only when
476
   fixuping relocations of debug sections.  */
477
 
478
void
479
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
480
{
481
  valueT val = * valP;
482
  char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
483
  fixP->fx_offset = 0;
484
 
485
  switch (fixP->fx_r_type)
486
    {
487
    case BFD_RELOC_CRX_NUM8:
488
      bfd_put_8 (stdoutput, (unsigned char) val, buf);
489
      break;
490
    case BFD_RELOC_CRX_NUM16:
491
      bfd_put_16 (stdoutput, val, buf);
492
      break;
493
    case BFD_RELOC_CRX_NUM32:
494
      bfd_put_32 (stdoutput, val, buf);
495
      break;
496
    default:
497
      /* We shouldn't ever get here because linkrelax is nonzero.  */
498
      abort ();
499
      break;
500
    }
501
 
502
  fixP->fx_done = 0;
503
 
504
  if (fixP->fx_addsy == NULL
505
      && fixP->fx_pcrel == 0)
506
    fixP->fx_done = 1;
507
 
508
  if (fixP->fx_pcrel == 1
509
      && fixP->fx_addsy != NULL
510
      && S_GET_SEGMENT (fixP->fx_addsy) == seg)
511
    fixP->fx_done = 1;
512
}
513
 
514
/* The location from which a PC relative jump should be calculated,
515
   given a PC relative reloc.  */
516
 
517
long
518
md_pcrel_from (fixS *fixp)
519
{
520
  return fixp->fx_frag->fr_address + fixp->fx_where;
521
}
522
 
523
/* This function is called once, at assembler startup time.  This should
524
   set up all the tables, etc that the MD part of the assembler needs.  */
525
 
526
void
527
md_begin (void)
528
{
529
  const char *hashret = NULL;
530
  int i = 0;
531
 
532
  /* Set up a hash table for the instructions.  */
533
  if ((crx_inst_hash = hash_new ()) == NULL)
534
    as_fatal (_("Virtual memory exhausted"));
535
 
536
  while (crx_instruction[i].mnemonic != NULL)
537
    {
538
      const char *mnemonic = crx_instruction[i].mnemonic;
539
 
540
      hashret = hash_insert (crx_inst_hash, mnemonic,
541
        (PTR) &crx_instruction[i]);
542
 
543
      if (hashret != NULL && *hashret != '\0')
544
        as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
545
                  *hashret == 0 ? _("(unknown reason)") : hashret);
546
 
547
      /* Insert unique names into hash table.  The CRX instruction set
548
         has many identical opcode names that have different opcodes based
549
         on the operands.  This hash table then provides a quick index to
550
         the first opcode with a particular name in the opcode table.  */
551
      do
552
        {
553
          ++i;
554
        }
555
      while (crx_instruction[i].mnemonic != NULL
556
             && streq (crx_instruction[i].mnemonic, mnemonic));
557
    }
558
 
559
  /* Initialize reg_hash hash table.  */
560
  if ((reg_hash = hash_new ()) == NULL)
561
    as_fatal (_("Virtual memory exhausted"));
562
 
563
  {
564
    const reg_entry *regtab;
565
 
566
    for (regtab = crx_regtab;
567
         regtab < (crx_regtab + NUMREGS); regtab++)
568
      {
569
        hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
570
        if (hashret)
571
          as_fatal (_("Internal Error:  Can't hash %s: %s"),
572
                    regtab->name,
573
                    hashret);
574
      }
575
  }
576
 
577
  /* Initialize copreg_hash hash table.  */
578
  if ((copreg_hash = hash_new ()) == NULL)
579
    as_fatal (_("Virtual memory exhausted"));
580
 
581
  {
582
    const reg_entry *copregtab;
583
 
584
    for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
585
         copregtab++)
586
      {
587
        hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
588
        if (hashret)
589
          as_fatal (_("Internal Error:  Can't hash %s: %s"),
590
                    copregtab->name,
591
                    hashret);
592
      }
593
  }
594
  /*  Set linkrelax here to avoid fixups in most sections.  */
595
  linkrelax = 1;
596
}
597
 
598
/* Process constants (immediate/absolute)
599
   and labels (jump targets/Memory locations).  */
600
 
601
static void
602
process_label_constant (char *str, ins * crx_ins)
603
{
604
  char *saved_input_line_pointer;
605
  argument *cur_arg = &crx_ins->arg[cur_arg_num];  /* Current argument.  */
606
 
607
  saved_input_line_pointer = input_line_pointer;
608
  input_line_pointer = str;
609
 
610
  expression (&crx_ins->exp);
611
 
612
  switch (crx_ins->exp.X_op)
613
    {
614
    case O_big:
615
    case O_absent:
616
      /* Missing or bad expr becomes absolute 0.  */
617
      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
618
              str);
619
      crx_ins->exp.X_op = O_constant;
620
      crx_ins->exp.X_add_number = 0;
621
      crx_ins->exp.X_add_symbol = (symbolS *) 0;
622
      crx_ins->exp.X_op_symbol = (symbolS *) 0;
623
      /* Fall through.  */
624
 
625
    case O_constant:
626
      cur_arg->X_op = O_constant;
627
      cur_arg->constant = crx_ins->exp.X_add_number;
628
      break;
629
 
630
    case O_symbol:
631
    case O_subtract:
632
    case O_add:
633
      cur_arg->X_op = O_symbol;
634
      crx_ins->rtype = BFD_RELOC_NONE;
635
      relocatable = 1;
636
 
637
      switch (cur_arg->type)
638
        {
639
        case arg_cr:
640
          if (IS_INSN_TYPE (LD_STOR_INS_INC))
641
            crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
642
          else if (IS_INSN_TYPE (CSTBIT_INS)
643
                   || IS_INSN_TYPE (STOR_IMM_INS))
644
            crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
645
          else
646
            crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
647
          break;
648
 
649
        case arg_idxr:
650
            crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
651
          break;
652
 
653
        case arg_c:
654
          if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
655
            crx_ins->rtype = BFD_RELOC_CRX_REL16;
656
          else if (IS_INSN_TYPE (BRANCH_INS))
657
            crx_ins->rtype = BFD_RELOC_CRX_REL8;
658
          else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
659
                   || IS_INSN_TYPE (CSTBIT_INS))
660
            crx_ins->rtype = BFD_RELOC_CRX_ABS32;
661
          else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
662
            crx_ins->rtype = BFD_RELOC_CRX_REL4;
663
          else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
664
            crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
665
          break;
666
 
667
        case arg_ic:
668
          if (IS_INSN_TYPE (ARITH_INS))
669
            crx_ins->rtype = BFD_RELOC_CRX_IMM32;
670
          else if (IS_INSN_TYPE (ARITH_BYTE_INS))
671
            crx_ins->rtype = BFD_RELOC_CRX_IMM16;
672
          break;
673
        default:
674
          break;
675
      }
676
      break;
677
 
678
    default:
679
      cur_arg->X_op = crx_ins->exp.X_op;
680
      break;
681
    }
682
 
683
  input_line_pointer = saved_input_line_pointer;
684
  return;
685
}
686
 
687
/* Get the values of the scale to be encoded -
688
   used for the scaled index mode of addressing.  */
689
 
690
static int
691
exponent2scale (int val)
692
{
693
  int exponent;
694
 
695
  /* If 'val' is 0, the following 'for' will be an endless loop.  */
696
  if (val == 0)
697
    return 0;
698
 
699
  for (exponent = 0; (val != 1); val >>= 1, exponent++)
700
    ;
701
 
702
  return exponent;
703
}
704
 
705
/* Parsing different types of operands
706
   -> constants             Immediate/Absolute/Relative numbers
707
   -> Labels                Relocatable symbols
708
   -> (rbase)               Register base
709
   -> disp(rbase)           Register relative
710
   -> disp(rbase)+          Post-increment mode
711
   -> disp(rbase,ridx,scl)  Register index mode  */
712
 
713
static void
714
set_operand (char *operand, ins * crx_ins)
715
{
716
  char *operandS; /* Pointer to start of sub-opearand.  */
717
  char *operandE; /* Pointer to end of sub-opearand.  */
718
  expressionS scale;
719
  int scale_val;
720
  char *input_save, c;
721
  argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
722
 
723
  /* Initialize pointers.  */
724
  operandS = operandE = operand;
725
 
726
  switch (cur_arg->type)
727
    {
728
    case arg_sc:    /* Case *+0x18.  */
729
    case arg_ic:    /* Case $0x18.  */
730
      operandS++;
731
    case arg_c:     /* Case 0x18.  */
732
      /* Set constant.  */
733
      process_label_constant (operandS, crx_ins);
734
 
735
      if (cur_arg->type != arg_ic)
736
        cur_arg->type = arg_c;
737
      break;
738
 
739
    case arg_icr:   /* Case $0x18(r1).  */
740
      operandS++;
741
    case arg_cr:    /* Case 0x18(r1).   */
742
      /* Set displacement constant.  */
743
      while (*operandE != '(')
744
        operandE++;
745
      *operandE = '\0';
746
      process_label_constant (operandS, crx_ins);
747
      operandS = operandE;
748
    case arg_rbase: /* Case (r1).  */
749
      operandS++;
750
      /* Set register base.  */
751
      while (*operandE != ')')
752
        operandE++;
753
      *operandE = '\0';
754
      if ((cur_arg->r = get_register (operandS)) == nullregister)
755
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
756
                operandS, ins_parse);
757
 
758
      if (cur_arg->type != arg_rbase)
759
        cur_arg->type = arg_cr;
760
      break;
761
 
762
    case arg_idxr:
763
      /* Set displacement constant.  */
764
      while (*operandE != '(')
765
        operandE++;
766
      *operandE = '\0';
767
      process_label_constant (operandS, crx_ins);
768
      operandS = ++operandE;
769
 
770
      /* Set register base.  */
771
      while ((*operandE != ',') && (! ISSPACE (*operandE)))
772
        operandE++;
773
      *operandE++ = '\0';
774
      if ((cur_arg->r = get_register (operandS)) == nullregister)
775
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
776
                operandS, ins_parse);
777
 
778
      /* Skip leading white space.  */
779
      while (ISSPACE (*operandE))
780
        operandE++;
781
      operandS = operandE;
782
 
783
      /* Set register index.  */
784
      while ((*operandE != ')') && (*operandE != ','))
785
        operandE++;
786
      c = *operandE;
787
      *operandE++ = '\0';
788
 
789
      if ((cur_arg->i_r = get_register (operandS)) == nullregister)
790
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
791
                operandS, ins_parse);
792
 
793
      /* Skip leading white space.  */
794
      while (ISSPACE (*operandE))
795
        operandE++;
796
      operandS = operandE;
797
 
798
      /* Set the scale.  */
799
      if (c == ')')
800
        cur_arg->scale = 0;
801
      else
802
        {
803
          while (*operandE != ')')
804
            operandE++;
805
          *operandE = '\0';
806
 
807
          /* Preprocess the scale string.  */
808
          input_save = input_line_pointer;
809
          input_line_pointer = operandS;
810
          expression (&scale);
811
          input_line_pointer = input_save;
812
 
813
          scale_val = scale.X_add_number;
814
 
815
          /* Check if the scale value is legal.  */
816
          if (scale_val != 1 && scale_val != 2
817
              && scale_val != 4 && scale_val != 8)
818
            as_bad (_("Illegal Scale - `%d'"), scale_val);
819
 
820
          cur_arg->scale = exponent2scale (scale_val);
821
        }
822
      break;
823
 
824
    default:
825
      break;
826
    }
827
}
828
 
829
/* Parse a single operand.
830
   operand - Current operand to parse.
831
   crx_ins - Current assembled instruction.  */
832
 
833
static void
834
parse_operand (char *operand, ins * crx_ins)
835
{
836
  int ret_val;
837
  argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
838
 
839
  /* Initialize the type to NULL before parsing.  */
840
  cur_arg->type = nullargs;
841
 
842
  /* Check whether this is a general processor register.  */
843
  if ((ret_val = get_register (operand)) != nullregister)
844
    {
845
      cur_arg->type = arg_r;
846
      cur_arg->r = ret_val;
847
      cur_arg->X_op = O_register;
848
      return;
849
    }
850
 
851
  /* Check whether this is a core [special] coprocessor register.  */
852
  if ((ret_val = get_copregister (operand)) != nullcopregister)
853
    {
854
      cur_arg->type = arg_copr;
855
      if (ret_val >= cs0)
856
        cur_arg->type = arg_copsr;
857
      cur_arg->cr = ret_val;
858
      cur_arg->X_op = O_register;
859
      return;
860
    }
861
 
862
  /* Deal with special characters.  */
863
  switch (operand[0])
864
    {
865
    case '$':
866
      if (strchr (operand, '(') != NULL)
867
        cur_arg->type = arg_icr;
868
      else
869
        cur_arg->type = arg_ic;
870
      goto set_params;
871
      break;
872
 
873
    case '*':
874
      cur_arg->type = arg_sc;
875
      goto set_params;
876
      break;
877
 
878
    case '(':
879
      cur_arg->type = arg_rbase;
880
      goto set_params;
881
      break;
882
 
883
    default:
884
        break;
885
    }
886
 
887
  if (strchr (operand, '(') != NULL)
888
    {
889
      if (strchr (operand, ',') != NULL
890
          && (strchr (operand, ',') > strchr (operand, '(')))
891
            cur_arg->type = arg_idxr;
892
      else
893
        cur_arg->type = arg_cr;
894
    }
895
  else
896
    cur_arg->type = arg_c;
897
  goto set_params;
898
 
899
/* Parse an operand according to its type.  */
900
set_params:
901
  cur_arg->constant = 0;
902
  set_operand (operand, crx_ins);
903
}
904
 
905
/* Parse the various operands. Each operand is then analyzed to fillup
906
   the fields in the crx_ins data structure.  */
907
 
908
static void
909
parse_operands (ins * crx_ins, char *operands)
910
{
911
  char *operandS;              /* Operands string.  */
912
  char *operandH, *operandT;   /* Single operand head/tail pointers.  */
913
  int allocated = 0;            /* Indicates a new operands string was allocated.  */
914
  char *operand[MAX_OPERANDS]; /* Separating the operands.  */
915
  int op_num = 0;               /* Current operand number we are parsing.  */
916
  int bracket_flag = 0;         /* Indicates a bracket '(' was found.  */
917
  int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
918
 
919
  /* Preprocess the list of registers, if necessary.  */
920
  operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
921
    preprocess_reglist (operands, &allocated) : operands;
922
 
923
  while (*operandT != '\0')
924
    {
925
      if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
926
        {
927
          *operandT++ = '\0';
928
          operand[op_num++] = strdup (operandH);
929
          operandH = operandT;
930
          continue;
931
        }
932
 
933
      if (*operandT == ' ')
934
        as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
935
 
936
      if (*operandT == '(')
937
        bracket_flag = 1;
938
      else if (*operandT == '[')
939
        sq_bracket_flag = 1;
940
 
941
      if (*operandT == ')')
942
        {
943
          if (bracket_flag)
944
            bracket_flag = 0;
945
          else
946
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
947
        }
948
      else if (*operandT == ']')
949
        {
950
          if (sq_bracket_flag)
951
            sq_bracket_flag = 0;
952
          else
953
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
954
        }
955
 
956
      if (bracket_flag == 1 && *operandT == ')')
957
        bracket_flag = 0;
958
      else if (sq_bracket_flag == 1 && *operandT == ']')
959
        sq_bracket_flag = 0;
960
 
961
      operandT++;
962
    }
963
 
964
  /* Adding the last operand.  */
965
  operand[op_num++] = strdup (operandH);
966
  crx_ins->nargs = op_num;
967
 
968
  /* Verifying correct syntax of operands (all brackets should be closed).  */
969
  if (bracket_flag || sq_bracket_flag)
970
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
971
 
972
  /* Now we parse each operand separately.  */
973
  for (op_num = 0; op_num < crx_ins->nargs; op_num++)
974
    {
975
      cur_arg_num = op_num;
976
      parse_operand (operand[op_num], crx_ins);
977
      free (operand[op_num]);
978
    }
979
 
980
  if (allocated)
981
    free (operandS);
982
}
983
 
984
/* Get the trap index in dispatch table, given its name.
985
   This routine is used by assembling the 'excp' instruction.  */
986
 
987
static int
988
gettrap (char *s)
989
{
990
  const trap_entry *trap;
991
 
992
  for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
993
    if (strcasecmp (trap->name, s) == 0)
994
      return trap->entry;
995
 
996
  as_bad (_("Unknown exception: `%s'"), s);
997
  return 0;
998
}
999
 
1000
/* Post-Increment instructions, as well as Store-Immediate instructions, are a
1001
   sub-group within load/stor instruction groups.
1002
   Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1003
   advance the instruction pointer to the start of that sub-group (that is, up
1004
   to the first instruction of that type).
1005
   Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS.  */
1006
 
1007
static void
1008
handle_LoadStor (char *operands)
1009
{
1010
  /* Post-Increment instructions precede Store-Immediate instructions in
1011
     CRX instruction table, hence they are handled before.
1012
     This synchronization should be kept.  */
1013
 
1014
  /* Assuming Post-Increment insn has the following format :
1015
     'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1016
     LD_STOR_INS_INC are the only store insns containing a plus sign (+).  */
1017
  if (strstr (operands, ")+") != NULL)
1018
    {
1019
      while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1020
        instruction++;
1021
      return;
1022
    }
1023
 
1024
  /* Assuming Store-Immediate insn has the following format :
1025
     'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1026
     STOR_IMM_INS are the only store insns containing a dollar sign ($).  */
1027
  if (strstr (operands, "$") != NULL)
1028
    while (! IS_INSN_TYPE (STOR_IMM_INS))
1029
      instruction++;
1030
}
1031
 
1032
/* Top level module where instruction parsing starts.
1033
   crx_ins - data structure holds some information.
1034
   operands - holds the operands part of the whole instruction.  */
1035
 
1036
static void
1037
parse_insn (ins *insn, char *operands)
1038
{
1039
  int i;
1040
 
1041
  /* Handle instructions with no operands.  */
1042
  for (i = 0; no_op_insn[i] != NULL; i++)
1043
  {
1044
    if (streq (no_op_insn[i], instruction->mnemonic))
1045
    {
1046
      insn->nargs = 0;
1047
      return;
1048
    }
1049
  }
1050
 
1051
  /* Handle 'excp'/'cinv' instructions.  */
1052
  if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1053
    {
1054
      insn->nargs = 1;
1055
      insn->arg[0].type = arg_ic;
1056
      insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1057
        gettrap (operands) : get_cinv_parameters (operands);
1058
      insn->arg[0].X_op = O_constant;
1059
      return;
1060
    }
1061
 
1062
  /* Handle load/stor unique instructions before parsing.  */
1063
  if (IS_INSN_TYPE (LD_STOR_INS))
1064
    handle_LoadStor (operands);
1065
 
1066
  if (operands != NULL)
1067
    parse_operands (insn, operands);
1068
}
1069
 
1070
/* Cinv instruction requires special handling.  */
1071
 
1072
static int
1073
get_cinv_parameters (char * operand)
1074
{
1075
  char *p = operand;
1076
  int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1077
 
1078
  while (*++p != ']')
1079
    {
1080
      if (*p == ',' || *p == ' ')
1081
        continue;
1082
 
1083
      if (*p == 'd')
1084
        d_used = 1;
1085
      else if (*p == 'i')
1086
        i_used = 1;
1087
      else if (*p == 'u')
1088
        u_used = 1;
1089
      else if (*p == 'b')
1090
        b_used = 1;
1091
      else
1092
        as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1093
    }
1094
 
1095
  return ((b_used ? 8 : 0)
1096
        + (d_used ? 4 : 0)
1097
        + (i_used ? 2 : 0)
1098
        + (u_used ? 1 : 0));
1099
}
1100
 
1101
/* Retrieve the opcode image of a given register.
1102
   If the register is illegal for the current instruction,
1103
   issue an error.  */
1104
 
1105
static int
1106
getreg_image (reg r)
1107
{
1108
  const reg_entry *reg;
1109
  char *reg_name;
1110
  int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
1111
 
1112
  if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1113
      || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1114
    is_procreg = 1;
1115
 
1116
  /* Check whether the register is in registers table.  */
1117
  if (r < MAX_REG)
1118
    reg = &crx_regtab[r];
1119
  /* Check whether the register is in coprocessor registers table.  */
1120
  else if (r < MAX_COPREG)
1121
    reg = &crx_copregtab[r-MAX_REG];
1122
  /* Register not found.  */
1123
  else
1124
    {
1125
      as_bad (_("Unknown register: `%d'"), r);
1126
      return 0;
1127
    }
1128
 
1129
  reg_name = reg->name;
1130
 
1131
/* Issue a error message when register is illegal.  */
1132
#define IMAGE_ERR \
1133
  as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1134
            reg_name, ins_parse);                            \
1135
  break;
1136
 
1137
  switch (reg->type)
1138
  {
1139
    case CRX_U_REGTYPE:
1140
      if (is_procreg || (instruction->flags & USER_REG))
1141
        return reg->image;
1142
      else
1143
        IMAGE_ERR;
1144
 
1145
    case CRX_CFG_REGTYPE:
1146
      if (is_procreg)
1147
        return reg->image;
1148
      else
1149
        IMAGE_ERR;
1150
 
1151
    case CRX_R_REGTYPE:
1152
      if (! is_procreg)
1153
        return reg->image;
1154
      else
1155
        IMAGE_ERR;
1156
 
1157
    case CRX_C_REGTYPE:
1158
    case CRX_CS_REGTYPE:
1159
      return reg->image;
1160
      break;
1161
 
1162
    default:
1163
      IMAGE_ERR;
1164
  }
1165
 
1166
  return 0;
1167
}
1168
 
1169
/* Routine used to represent integer X using NBITS bits.  */
1170
 
1171
static long
1172
getconstant (long x, int nbits)
1173
{
1174
  /* The following expression avoids overflow if
1175
     'nbits' is the number of bits in 'bfd_vma'.  */
1176
  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1177
}
1178
 
1179
/* Print a constant value to 'output_opcode':
1180
   ARG holds the operand's type and value.
1181
   SHIFT represents the location of the operand to be print into.
1182
   NBITS determines the size (in bits) of the constant.  */
1183
 
1184
static void
1185
print_constant (int nbits, int shift, argument *arg)
1186
{
1187
  unsigned long mask = 0;
1188
 
1189
  long constant = getconstant (arg->constant, nbits);
1190
 
1191
  switch (nbits)
1192
  {
1193
    case 32:
1194
    case 28:
1195
    case 24:
1196
    case 22:
1197
      /* mask the upper part of the constant, that is, the bits
1198
         going to the lowest byte of output_opcode[0].
1199
         The upper part of output_opcode[1] is always filled,
1200
         therefore it is always masked with 0xFFFF.  */
1201
      mask = (1 << (nbits - 16)) - 1;
1202
      /* Divide the constant between two consecutive words :
1203
 
1204
            +---------+---------+---------+---------+
1205
            |         | X X X X | X X X X |         |
1206
            +---------+---------+---------+---------+
1207
              output_opcode[0]    output_opcode[1]     */
1208
 
1209
      CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1210
      CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1211
      break;
1212
 
1213
    case 16:
1214
    case 12:
1215
      /* Special case - in arg_cr, the SHIFT represents the location
1216
         of the REGISTER, not the constant, which is itself not shifted.  */
1217
      if (arg->type == arg_cr)
1218
        {
1219
          CRX_PRINT (0, constant,  0);
1220
          break;
1221
        }
1222
 
1223
      /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1224
         always filling the upper part of output_opcode[1]. If we mistakenly
1225
         write it to output_opcode[0], the constant prefix (that is, 'match')
1226
         will be overridden.
1227
 
1228
            +---------+---------+---------+---------+
1229
            | 'match' |         | X X X X |         |
1230
            +---------+---------+---------+---------+
1231
              output_opcode[0]    output_opcode[1]     */
1232
 
1233
      if ((instruction->size > 2) && (shift == WORD_SHIFT))
1234
        CRX_PRINT (1, constant, WORD_SHIFT);
1235
      else
1236
        CRX_PRINT (0, constant, shift);
1237
      break;
1238
 
1239
    default:
1240
      CRX_PRINT (0, constant,  shift);
1241
      break;
1242
  }
1243
}
1244
 
1245
/* Print an operand to 'output_opcode', which later on will be
1246
   printed to the object file:
1247
   ARG holds the operand's type, size and value.
1248
   SHIFT represents the printing location of operand.
1249
   NBITS determines the size (in bits) of a constant operand.  */
1250
 
1251
static void
1252
print_operand (int nbits, int shift, argument *arg)
1253
{
1254
  switch (arg->type)
1255
    {
1256
    case arg_r:
1257
      CRX_PRINT (0, getreg_image (arg->r), shift);
1258
      break;
1259
 
1260
    case arg_copr:
1261
      if (arg->cr < c0 || arg->cr > c15)
1262
        as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1263
                ins_parse);
1264
      CRX_PRINT (0, getreg_image (arg->cr), shift);
1265
      break;
1266
 
1267
    case arg_copsr:
1268
      if (arg->cr < cs0 || arg->cr > cs15)
1269
        as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1270
                ins_parse);
1271
      CRX_PRINT (0, getreg_image (arg->cr), shift);
1272
      break;
1273
 
1274
    case arg_idxr:
1275
      /*    16      12        8    6         0
1276
            +--------------------------------+
1277
            | r_base | r_idx  | scl|  disp   |
1278
            +--------------------------------+    */
1279
      CRX_PRINT (0, getreg_image (arg->r), 12);
1280
      CRX_PRINT (0, getreg_image (arg->i_r), 8);
1281
      CRX_PRINT (0, arg->scale, 6);
1282
    case arg_ic:
1283
    case arg_c:
1284
      print_constant (nbits, shift, arg);
1285
      break;
1286
 
1287
    case arg_rbase:
1288
      CRX_PRINT (0, getreg_image (arg->r), shift);
1289
      break;
1290
 
1291
    case arg_cr:
1292
      /* case base_cst4.  */
1293
      if (instruction->flags & DISPU4MAP)
1294
        print_constant (nbits, shift + REG_SIZE, arg);
1295
      else
1296
        /* rbase_disps<NN> and other such cases.  */
1297
        print_constant (nbits, shift, arg);
1298
      /* Add the register argument to the output_opcode.  */
1299
      CRX_PRINT (0, getreg_image (arg->r), shift);
1300
      break;
1301
 
1302
    default:
1303
      break;
1304
    }
1305
}
1306
 
1307
/* Retrieve the number of operands for the current assembled instruction.  */
1308
 
1309
static int
1310
get_number_of_operands (void)
1311
{
1312
  int i;
1313
 
1314
  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1315
    ;
1316
  return i;
1317
}
1318
 
1319
/* Verify that the number NUM can be represented in BITS bits (that is,
1320
   within its permitted range), based on the instruction's FLAGS.
1321
   If UPDATE is nonzero, update the value of NUM if necessary.
1322
   Return OP_LEGAL upon success, actual error type upon failure.  */
1323
 
1324
static op_err
1325
check_range (long *num, int bits, int unsigned flags, int update)
1326
{
1327
  long min, max;
1328
  int retval = OP_LEGAL;
1329
  int bin;
1330
  long upper_64kb = 0xFFFF0000;
1331
  long value = *num;
1332
 
1333
  /* For hosts witah longs bigger than 32-bits make sure that the top
1334
     bits of a 32-bit negative value read in by the parser are set,
1335
     so that the correct comparisons are made.  */
1336
  if (value & 0x80000000)
1337
    value |= (-1L << 31);
1338
 
1339
  /* Verify operand value is even.  */
1340
  if (flags & OP_EVEN)
1341
    {
1342
      if (value % 2)
1343
        return OP_NOT_EVEN;
1344
    }
1345
 
1346
  if (flags & OP_UPPER_64KB)
1347
    {
1348
      /* Check if value is to be mapped to upper 64 KB memory area.  */
1349
      if ((value & upper_64kb) == upper_64kb)
1350
        {
1351
          value -= upper_64kb;
1352
          if (update)
1353
            *num = value;
1354
        }
1355
      else
1356
        return OP_NOT_UPPER_64KB;
1357
    }
1358
 
1359
  if (flags & OP_SHIFT)
1360
    {
1361
      value >>= 1;
1362
      if (update)
1363
        *num = value;
1364
    }
1365
  else if (flags & OP_SHIFT_DEC)
1366
    {
1367
      value = (value >> 1) - 1;
1368
      if (update)
1369
        *num = value;
1370
    }
1371
 
1372
  if (flags & OP_ESC)
1373
    {
1374
      /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
1375
      if (value == 0x7e || value == 0x7f)
1376
        return OP_OUT_OF_RANGE;
1377
    }
1378
 
1379
  if (flags & OP_DISPU4)
1380
    {
1381
      int is_dispu4 = 0;
1382
 
1383
      int mul = (instruction->flags & DISPUB4) ? 1
1384
                : (instruction->flags & DISPUW4) ? 2
1385
                : (instruction->flags & DISPUD4) ? 4 : 0;
1386
 
1387
      for (bin = 0; bin < cst4_maps; bin++)
1388
        {
1389
          if (value == (mul * bin))
1390
            {
1391
              is_dispu4 = 1;
1392
              if (update)
1393
                *num = bin;
1394
              break;
1395
            }
1396
        }
1397
      if (!is_dispu4)
1398
        retval = OP_ILLEGAL_DISPU4;
1399
    }
1400
  else if (flags & OP_CST4)
1401
    {
1402
      int is_cst4 = 0;
1403
 
1404
      for (bin = 0; bin < cst4_maps; bin++)
1405
        {
1406
          if (value == cst4_map[bin])
1407
            {
1408
              is_cst4 = 1;
1409
              if (update)
1410
                *num = bin;
1411
              break;
1412
            }
1413
        }
1414
      if (!is_cst4)
1415
        retval = OP_ILLEGAL_CST4;
1416
    }
1417
  else if (flags & OP_SIGNED)
1418
    {
1419
      max = (1 << (bits - 1)) - 1;
1420
      min = - (1 << (bits - 1));
1421
      if ((value > max) || (value < min))
1422
        retval = OP_OUT_OF_RANGE;
1423
    }
1424
  else if (flags & OP_UNSIGNED)
1425
    {
1426
      max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1427
      min = 0;
1428
      if (((unsigned long) value > (unsigned long) max)
1429
            || ((unsigned long) value < (unsigned long) min))
1430
        retval = OP_OUT_OF_RANGE;
1431
    }
1432
  return retval;
1433
}
1434
 
1435
/* Assemble a single instruction:
1436
   INSN is already parsed (that is, all operand values and types are set).
1437
   For instruction to be assembled, we need to find an appropriate template in
1438
   the instruction table, meeting the following conditions:
1439
    1: Has the same number of operands.
1440
    2: Has the same operand types.
1441
    3: Each operand size is sufficient to represent the instruction's values.
1442
   Returns 1 upon success, 0 upon failure.  */
1443
 
1444
static int
1445
assemble_insn (char *mnemonic, ins *insn)
1446
{
1447
  /* Type of each operand in the current template.  */
1448
  argtype cur_type[MAX_OPERANDS];
1449
  /* Size (in bits) of each operand in the current template.  */
1450
  unsigned int cur_size[MAX_OPERANDS];
1451
  /* Flags of each operand in the current template.  */
1452
  unsigned int cur_flags[MAX_OPERANDS];
1453
  /* Instruction type to match.  */
1454
  unsigned int ins_type;
1455
  /* Boolean flag to mark whether a match was found.  */
1456
  int match = 0;
1457
  int i;
1458
  /* Nonzero if an instruction with same number of operands was found.  */
1459
  int found_same_number_of_operands = 0;
1460
  /* Nonzero if an instruction with same argument types was found.  */
1461
  int found_same_argument_types = 0;
1462
  /* Nonzero if a constant was found within the required range.  */
1463
  int found_const_within_range  = 0;
1464
  /* Argument number of an operand with invalid type.  */
1465
  int invalid_optype = -1;
1466
  /* Argument number of an operand with invalid constant value.  */
1467
  int invalid_const  = -1;
1468
  /* Operand error (used for issuing various constant error messages).  */
1469
  op_err op_error, const_err = OP_LEGAL;
1470
 
1471
/* Retrieve data (based on FUNC) for each operand of a given instruction.  */
1472
#define GET_CURRENT_DATA(FUNC, ARRAY)                             \
1473
  for (i = 0; i < insn->nargs; i++)                                \
1474
    ARRAY[i] = FUNC (instruction->operands[i].op_type)
1475
 
1476
#define GET_CURRENT_TYPE    GET_CURRENT_DATA(get_optype, cur_type)
1477
#define GET_CURRENT_SIZE    GET_CURRENT_DATA(get_opbits, cur_size)
1478
#define GET_CURRENT_FLAGS   GET_CURRENT_DATA(get_opflags, cur_flags)
1479
 
1480
  /* Instruction has no operands -> only copy the constant opcode.   */
1481
  if (insn->nargs == 0)
1482
    {
1483
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1484
      return 1;
1485
    }
1486
 
1487
  /* In some case, same mnemonic can appear with different instruction types.
1488
     For example, 'storb' is supported with 3 different types :
1489
     LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1490
     We assume that when reaching this point, the instruction type was
1491
     pre-determined. We need to make sure that the type stays the same
1492
     during a search for matching instruction.  */
1493
  ins_type = CRX_INS_TYPE(instruction->flags);
1494
 
1495
  while (/* Check that match is still not found.  */
1496
         match != 1
1497
         /* Check we didn't get to end of table.  */
1498
         && instruction->mnemonic != NULL
1499
         /* Check that the actual mnemonic is still available.  */
1500
         && IS_INSN_MNEMONIC (mnemonic)
1501
         /* Check that the instruction type wasn't changed.  */
1502
         && IS_INSN_TYPE(ins_type))
1503
    {
1504
      /* Check whether number of arguments is legal.  */
1505
      if (get_number_of_operands () != insn->nargs)
1506
        goto next_insn;
1507
      found_same_number_of_operands = 1;
1508
 
1509
      /* Initialize arrays with data of each operand in current template.  */
1510
      GET_CURRENT_TYPE;
1511
      GET_CURRENT_SIZE;
1512
      GET_CURRENT_FLAGS;
1513
 
1514
      /* Check for type compatibility.  */
1515
      for (i = 0; i < insn->nargs; i++)
1516
        {
1517
          if (cur_type[i] != insn->arg[i].type)
1518
            {
1519
              if (invalid_optype == -1)
1520
                invalid_optype = i + 1;
1521
              goto next_insn;
1522
            }
1523
        }
1524
      found_same_argument_types = 1;
1525
 
1526
      for (i = 0; i < insn->nargs; i++)
1527
        {
1528
          /* Reverse the operand indices for certain opcodes:
1529
             Index 0      -->> 1
1530
             Index 1      -->> 0
1531
             Other index  -->> stays the same.  */
1532
          int j = instruction->flags & REVERSE_MATCH ?
1533
                  i == 0 ? 1 :
1534
                  i == 1 ? 0 : i :
1535
                  i;
1536
 
1537
          /* Only check range - don't update the constant's value, since the
1538
             current instruction may not be the last we try to match.
1539
             The constant's value will be updated later, right before printing
1540
             it to the object file.  */
1541
          if ((insn->arg[j].X_op == O_constant)
1542
               && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1543
                                           cur_flags[j], 0)))
1544
            {
1545
              if (invalid_const == -1)
1546
              {
1547
                invalid_const = j + 1;
1548
                const_err = op_error;
1549
              }
1550
              goto next_insn;
1551
            }
1552
          /* For symbols, we make sure the relocation size (which was already
1553
             determined) is sufficient.  */
1554
          else if ((insn->arg[j].X_op == O_symbol)
1555
                    && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1556
                         > cur_size[j]))
1557
                  goto next_insn;
1558
        }
1559
      found_const_within_range = 1;
1560
 
1561
      /* If we got till here -> Full match is found.  */
1562
      match = 1;
1563
      break;
1564
 
1565
/* Try again with next instruction.  */
1566
next_insn:
1567
      instruction++;
1568
    }
1569
 
1570
  if (!match)
1571
    {
1572
      /* We haven't found a match - instruction can't be assembled.  */
1573
      if (!found_same_number_of_operands)
1574
        as_bad (_("Incorrect number of operands"));
1575
      else if (!found_same_argument_types)
1576
        as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1577
      else if (!found_const_within_range)
1578
      {
1579
        switch (const_err)
1580
        {
1581
        case OP_OUT_OF_RANGE:
1582
          as_bad (_("Operand out of range (arg %d)"), invalid_const);
1583
          break;
1584
        case OP_NOT_EVEN:
1585
          as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1586
          break;
1587
        case OP_ILLEGAL_DISPU4:
1588
          as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1589
          break;
1590
        case OP_ILLEGAL_CST4:
1591
          as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1592
          break;
1593
        case OP_NOT_UPPER_64KB:
1594
          as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1595
                    invalid_const);
1596
          break;
1597
        default:
1598
          as_bad (_("Illegal operand (arg %d)"), invalid_const);
1599
          break;
1600
        }
1601
      }
1602
 
1603
      return 0;
1604
    }
1605
  else
1606
    /* Full match - print the encoding to output file.  */
1607
    {
1608
      /* Make further checkings (such that couldn't be made earlier).
1609
         Warn the user if necessary.  */
1610
      warn_if_needed (insn);
1611
 
1612
      /* Check whether we need to adjust the instruction pointer.  */
1613
      if (adjust_if_needed (insn))
1614
        /* If instruction pointer was adjusted, we need to update
1615
           the size of the current template operands.  */
1616
        GET_CURRENT_SIZE;
1617
 
1618
      for (i = 0; i < insn->nargs; i++)
1619
        {
1620
          int j = instruction->flags & REVERSE_MATCH ?
1621
                  i == 0 ? 1 :
1622
                  i == 1 ? 0 : i :
1623
                  i;
1624
 
1625
          /* This time, update constant value before printing it.  */
1626
          if ((insn->arg[j].X_op == O_constant)
1627
               && (check_range (&insn->arg[j].constant, cur_size[j],
1628
                                cur_flags[j], 1) != OP_LEGAL))
1629
              as_fatal (_("Illegal operand (arg %d)"), j+1);
1630
        }
1631
 
1632
      /* First, copy the instruction's opcode.  */
1633
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1634
 
1635
      for (i = 0; i < insn->nargs; i++)
1636
        {
1637
          cur_arg_num = i;
1638
          print_operand (cur_size[i], instruction->operands[i].shift,
1639
                         &insn->arg[i]);
1640
        }
1641
    }
1642
 
1643
  return 1;
1644
}
1645
 
1646
/* Bunch of error checkings.
1647
   The checks are made after a matching instruction was found.  */
1648
 
1649
void
1650
warn_if_needed (ins *insn)
1651
{
1652
  /* If the post-increment address mode is used and the load/store
1653
     source register is the same as rbase, the result of the
1654
     instruction is undefined.  */
1655
  if (IS_INSN_TYPE (LD_STOR_INS_INC))
1656
    {
1657
      /* Enough to verify that one of the arguments is a simple reg.  */
1658
      if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1659
        if (insn->arg[0].r == insn->arg[1].r)
1660
          as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1661
                   insn->arg[0].r);
1662
    }
1663
 
1664
  /* Some instruction assume the stack pointer as rptr operand.
1665
     Issue an error when the register to be loaded is also SP.  */
1666
  if (instruction->flags & NO_SP)
1667
    {
1668
      if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1669
        as_bad (_("`%s' has undefined result"), ins_parse);
1670
    }
1671
 
1672
  /* If the rptr register is specified as one of the registers to be loaded,
1673
     the final contents of rptr are undefined. Thus, we issue an error.  */
1674
  if (instruction->flags & NO_RPTR)
1675
    {
1676
      if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1677
        as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1678
         getreg_image (insn->arg[0].r));
1679
    }
1680
}
1681
 
1682
/* In some cases, we need to adjust the instruction pointer although a
1683
   match was already found. Here, we gather all these cases.
1684
   Returns 1 if instruction pointer was adjusted, otherwise 0.  */
1685
 
1686
int
1687
adjust_if_needed (ins *insn)
1688
{
1689
  int ret_value = 0;
1690
 
1691
  /* Special check for 'addub $0, r0' instruction -
1692
     The opcode '0000 0000 0000 0000' is not allowed.  */
1693
  if (IS_INSN_MNEMONIC ("addub"))
1694
    {
1695
      if ((instruction->operands[0].op_type == cst4)
1696
          && instruction->operands[1].op_type == regr)
1697
        {
1698
          if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1699
            {
1700
              instruction++;
1701
              ret_value = 1;
1702
            }
1703
        }
1704
    }
1705
 
1706
  /* Optimization: Omit a zero displacement in bit operations,
1707
     saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)').  */
1708
  if (IS_INSN_TYPE (CSTBIT_INS))
1709
    {
1710
      if ((instruction->operands[1].op_type == rbase_disps12)
1711
           && (insn->arg[1].X_op == O_constant)
1712
           && (insn->arg[1].constant == 0))
1713
            {
1714
              instruction--;
1715
              ret_value = 1;
1716
            }
1717
    }
1718
 
1719
  return ret_value;
1720
}
1721
 
1722
/* Set the appropriate bit for register 'r' in 'mask'.
1723
   This indicates that this register is loaded or stored by
1724
   the instruction.  */
1725
 
1726
static void
1727
mask_reg (int r, unsigned short int *mask)
1728
{
1729
  if ((reg)r > (reg)sp)
1730
    {
1731
      as_bad (_("Invalid Register in Register List"));
1732
      return;
1733
    }
1734
 
1735
  *mask |= (1 << r);
1736
}
1737
 
1738
/* Preprocess register list - create a 16-bit mask with one bit for each
1739
   of the 16 general purpose registers. If a bit is set, it indicates
1740
   that this register is loaded or stored by the instruction.  */
1741
 
1742
static char *
1743
preprocess_reglist (char *param, int *allocated)
1744
{
1745
  char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
1746
  char *regP;                     /* Pointer to 'reg_name' string.  */
1747
  int reg_counter = 0;             /* Count number of parsed registers.  */
1748
  unsigned short int mask = 0;     /* Mask for 16 general purpose registers.  */
1749
  char *new_param;                /* New created operands string.  */
1750
  char *paramP = param;           /* Pointer to original opearands string.  */
1751
  char maskstring[10];            /* Array to print the mask as a string.  */
1752
  int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers.  */
1753
  reg r;
1754
  copreg cr;
1755
 
1756
  /* If 'param' is already in form of a number, no need to preprocess.  */
1757
  if (strchr (paramP, '{') == NULL)
1758
    return param;
1759
 
1760
  /* Verifying correct syntax of operand.  */
1761
  if (strchr (paramP, '}') == NULL)
1762
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1763
 
1764
  while (*paramP++ != '{');
1765
 
1766
  new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1767
  *allocated = 1;
1768
  strncpy (new_param, param, paramP - param - 1);
1769
 
1770
  while (*paramP != '}')
1771
    {
1772
      regP = paramP;
1773
      memset (&reg_name, '\0', sizeof (reg_name));
1774
 
1775
      while (ISALNUM (*paramP))
1776
        paramP++;
1777
 
1778
      strncpy (reg_name, regP, paramP - regP);
1779
 
1780
      /* Coprocessor register c<N>.  */
1781
      if (IS_INSN_TYPE (COP_REG_INS))
1782
        {
1783
          if (((cr = get_copregister (reg_name)) == nullcopregister)
1784
              || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1785
            as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1786
          mask_reg (getreg_image (cr - c0), &mask);
1787
        }
1788
      /* Coprocessor Special register cs<N>.  */
1789
      else if (IS_INSN_TYPE (COPS_REG_INS))
1790
        {
1791
          if (((cr = get_copregister (reg_name)) == nullcopregister)
1792
              || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1793
            as_fatal (_("Illegal register `%s' in cop-special-register list"),
1794
                      reg_name);
1795
          mask_reg (getreg_image (cr - cs0), &mask);
1796
        }
1797
      /* User register u<N>.  */
1798
      else if (instruction->flags & USER_REG)
1799
        {
1800
          if (streq(reg_name, "uhi"))
1801
            {
1802
              hi_found = 1;
1803
              goto next_inst;
1804
            }
1805
          else if (streq(reg_name, "ulo"))
1806
            {
1807
              lo_found = 1;
1808
              goto next_inst;
1809
            }
1810
          else if (((r = get_register (reg_name)) == nullregister)
1811
              || (crx_regtab[r].type != CRX_U_REGTYPE))
1812
            as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1813
 
1814
          mask_reg (getreg_image (r - u0), &mask);
1815
        }
1816
      /* General purpose register r<N>.  */
1817
      else
1818
        {
1819
          if (streq(reg_name, "hi"))
1820
            {
1821
              hi_found = 1;
1822
              goto next_inst;
1823
            }
1824
          else if (streq(reg_name, "lo"))
1825
            {
1826
              lo_found = 1;
1827
              goto next_inst;
1828
            }
1829
          else if (((r = get_register (reg_name)) == nullregister)
1830
              || (crx_regtab[r].type != CRX_R_REGTYPE))
1831
            as_fatal (_("Illegal register `%s' in register list"), reg_name);
1832
 
1833
          mask_reg (getreg_image (r - r0), &mask);
1834
        }
1835
 
1836
      if (++reg_counter > MAX_REGS_IN_MASK16)
1837
        as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1838
                MAX_REGS_IN_MASK16);
1839
 
1840
next_inst:
1841
      while (!ISALNUM (*paramP) && *paramP != '}')
1842
          paramP++;
1843
    }
1844
 
1845
  if (*++paramP != '\0')
1846
    as_warn (_("rest of line ignored; first ignored character is `%c'"),
1847
             *paramP);
1848
 
1849
  switch (hi_found + lo_found)
1850
    {
1851
    case 0:
1852
      /* At least one register should be specified.  */
1853
      if (mask == 0)
1854
        as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1855
                ins_parse);
1856
      break;
1857
 
1858
    case 1:
1859
      /* HI can't be specified without LO (and vise-versa).  */
1860
      as_bad (_("HI/LO registers should be specified together"));
1861
      break;
1862
 
1863
    case 2:
1864
      /* HI/LO registers mustn't be masked with additional registers.  */
1865
      if (mask != 0)
1866
        as_bad (_("HI/LO registers should be specified without additional registers"));
1867
 
1868
    default:
1869
      break;
1870
    }
1871
 
1872
  sprintf (maskstring, "$0x%x", mask);
1873
  strcat (new_param, maskstring);
1874
  return new_param;
1875
}
1876
 
1877
/* Print the instruction.
1878
   Handle also cases where the instruction is relaxable/relocatable.  */
1879
 
1880
void
1881
print_insn (ins *insn)
1882
{
1883
  unsigned int i, j, insn_size;
1884
  char *this_frag;
1885
  unsigned short words[4];
1886
  int addr_mod;
1887
 
1888
  /* Arrange the insn encodings in a WORD size array.  */
1889
  for (i = 0, j = 0; i < 2; i++)
1890
    {
1891
      words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1892
      words[j++] = output_opcode[i] & 0xFFFF;
1893
    }
1894
 
1895
  /* Handle relaxtion.  */
1896
  if ((instruction->flags & RELAXABLE) && relocatable)
1897
    {
1898
      int relax_subtype;
1899
 
1900
      /* Write the maximal instruction size supported.  */
1901
      insn_size = INSN_MAX_SIZE;
1902
 
1903
      /* bCC  */
1904
      if (IS_INSN_TYPE (BRANCH_INS))
1905
        relax_subtype = 0;
1906
      /* bal  */
1907
      else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1908
        relax_subtype = 3;
1909
      /* cmpbr/bcop  */
1910
      else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1911
        relax_subtype = 5;
1912
      else
1913
        abort ();
1914
 
1915
      this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1916
                            4, relax_subtype,
1917
                            insn->exp.X_add_symbol,
1918
                            insn->exp.X_add_number,
1919
                            0);
1920
    }
1921
  else
1922
    {
1923
      insn_size = instruction->size;
1924
      this_frag = frag_more (insn_size * 2);
1925
 
1926
      /* Handle relocation.  */
1927
      if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1928
        {
1929
          reloc_howto_type *reloc_howto;
1930
          int size;
1931
 
1932
          reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1933
 
1934
          if (!reloc_howto)
1935
            abort ();
1936
 
1937
          size = bfd_get_reloc_size (reloc_howto);
1938
 
1939
          if (size < 1 || size > 4)
1940
            abort ();
1941
 
1942
          fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1943
                       size, &insn->exp, reloc_howto->pc_relative,
1944
                       insn->rtype);
1945
        }
1946
    }
1947
 
1948
  /* Verify a 2-byte code alignment.  */
1949
  addr_mod = frag_now_fix () & 1;
1950
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1951
    as_bad (_("instruction address is not a multiple of 2"));
1952
  frag_now->insn_addr = addr_mod;
1953
  frag_now->has_code = 1;
1954
 
1955
  /* Write the instruction encoding to frag.  */
1956
  for (i = 0; i < insn_size; i++)
1957
    {
1958
      md_number_to_chars (this_frag, (valueT) words[i], 2);
1959
      this_frag += 2;
1960
    }
1961
}
1962
 
1963
/* This is the guts of the machine-dependent assembler.  OP points to a
1964
   machine dependent instruction.  This function is supposed to emit
1965
   the frags/bytes it assembles to.  */
1966
 
1967
void
1968
md_assemble (char *op)
1969
{
1970
  ins crx_ins;
1971
  char *param;
1972
  char c;
1973
 
1974
  /* Reset global variables for a new instruction.  */
1975
  reset_vars (op);
1976
 
1977
  /* Strip the mnemonic.  */
1978
  for (param = op; *param != 0 && !ISSPACE (*param); param++)
1979
    ;
1980
  c = *param;
1981
  *param++ = '\0';
1982
 
1983
  /* Find the instruction.  */
1984
  instruction = (const inst *) hash_find (crx_inst_hash, op);
1985
  if (instruction == NULL)
1986
    {
1987
      as_bad (_("Unknown opcode: `%s'"), op);
1988
      return;
1989
    }
1990
 
1991
  /* Tie dwarf2 debug info to the address at the start of the insn.  */
1992
  dwarf2_emit_insn (0);
1993
 
1994
  /* Parse the instruction's operands.  */
1995
  parse_insn (&crx_ins, param);
1996
 
1997
  /* Assemble the instruction - return upon failure.  */
1998
  if (assemble_insn (op, &crx_ins) == 0)
1999
    return;
2000
 
2001
  /* Print the instruction.  */
2002
  print_insn (&crx_ins);
2003
}

powered by: WebSVN 2.1.0

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