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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [config/] [tc-crx.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 205 julius
/* tc-crx.c -- Assembler code for the CRX CPU core.
2
   Copyright 2004, 2005, 2006, 2007, 2008, 2009 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
  gas_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
  gas_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
                             (void *) &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, (void *) 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,
588
                               (void *) copregtab);
589
        if (hashret)
590
          as_fatal (_("Internal Error:  Can't hash %s: %s"),
591
                    copregtab->name,
592
                    hashret);
593
      }
594
  }
595
  /*  Set linkrelax here to avoid fixups in most sections.  */
596
  linkrelax = 1;
597
}
598
 
599
/* Process constants (immediate/absolute)
600
   and labels (jump targets/Memory locations).  */
601
 
602
static void
603
process_label_constant (char *str, ins * crx_ins)
604
{
605
  char *saved_input_line_pointer;
606
  argument *cur_arg = &crx_ins->arg[cur_arg_num];  /* Current argument.  */
607
 
608
  saved_input_line_pointer = input_line_pointer;
609
  input_line_pointer = str;
610
 
611
  expression (&crx_ins->exp);
612
 
613
  switch (crx_ins->exp.X_op)
614
    {
615
    case O_big:
616
    case O_absent:
617
      /* Missing or bad expr becomes absolute 0.  */
618
      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
619
              str);
620
      crx_ins->exp.X_op = O_constant;
621
      crx_ins->exp.X_add_number = 0;
622
      crx_ins->exp.X_add_symbol = (symbolS *) 0;
623
      crx_ins->exp.X_op_symbol = (symbolS *) 0;
624
      /* Fall through.  */
625
 
626
    case O_constant:
627
      cur_arg->X_op = O_constant;
628
      cur_arg->constant = crx_ins->exp.X_add_number;
629
      break;
630
 
631
    case O_symbol:
632
    case O_subtract:
633
    case O_add:
634
      cur_arg->X_op = O_symbol;
635
      crx_ins->rtype = BFD_RELOC_NONE;
636
      relocatable = 1;
637
 
638
      switch (cur_arg->type)
639
        {
640
        case arg_cr:
641
          if (IS_INSN_TYPE (LD_STOR_INS_INC))
642
            crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
643
          else if (IS_INSN_TYPE (CSTBIT_INS)
644
                   || IS_INSN_TYPE (STOR_IMM_INS))
645
            crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
646
          else
647
            crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
648
          break;
649
 
650
        case arg_idxr:
651
            crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
652
          break;
653
 
654
        case arg_c:
655
          if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
656
            crx_ins->rtype = BFD_RELOC_CRX_REL16;
657
          else if (IS_INSN_TYPE (BRANCH_INS))
658
            crx_ins->rtype = BFD_RELOC_CRX_REL8;
659
          else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
660
                   || IS_INSN_TYPE (CSTBIT_INS))
661
            crx_ins->rtype = BFD_RELOC_CRX_ABS32;
662
          else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
663
            crx_ins->rtype = BFD_RELOC_CRX_REL4;
664
          else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
665
            crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
666
          break;
667
 
668
        case arg_ic:
669
          if (IS_INSN_TYPE (ARITH_INS))
670
            crx_ins->rtype = BFD_RELOC_CRX_IMM32;
671
          else if (IS_INSN_TYPE (ARITH_BYTE_INS))
672
            crx_ins->rtype = BFD_RELOC_CRX_IMM16;
673
          break;
674
        default:
675
          break;
676
      }
677
      break;
678
 
679
    default:
680
      cur_arg->X_op = crx_ins->exp.X_op;
681
      break;
682
    }
683
 
684
  input_line_pointer = saved_input_line_pointer;
685
  return;
686
}
687
 
688
/* Get the values of the scale to be encoded -
689
   used for the scaled index mode of addressing.  */
690
 
691
static int
692
exponent2scale (int val)
693
{
694
  int exponent;
695
 
696
  /* If 'val' is 0, the following 'for' will be an endless loop.  */
697
  if (val == 0)
698
    return 0;
699
 
700
  for (exponent = 0; (val != 1); val >>= 1, exponent++)
701
    ;
702
 
703
  return exponent;
704
}
705
 
706
/* Parsing different types of operands
707
   -> constants             Immediate/Absolute/Relative numbers
708
   -> Labels                Relocatable symbols
709
   -> (rbase)               Register base
710
   -> disp(rbase)           Register relative
711
   -> disp(rbase)+          Post-increment mode
712
   -> disp(rbase,ridx,scl)  Register index mode  */
713
 
714
static void
715
set_operand (char *operand, ins * crx_ins)
716
{
717
  char *operandS; /* Pointer to start of sub-opearand.  */
718
  char *operandE; /* Pointer to end of sub-opearand.  */
719
  expressionS scale;
720
  int scale_val;
721
  char *input_save, c;
722
  argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
723
 
724
  /* Initialize pointers.  */
725
  operandS = operandE = operand;
726
 
727
  switch (cur_arg->type)
728
    {
729
    case arg_sc:    /* Case *+0x18.  */
730
    case arg_ic:    /* Case $0x18.  */
731
      operandS++;
732
    case arg_c:     /* Case 0x18.  */
733
      /* Set constant.  */
734
      process_label_constant (operandS, crx_ins);
735
 
736
      if (cur_arg->type != arg_ic)
737
        cur_arg->type = arg_c;
738
      break;
739
 
740
    case arg_icr:   /* Case $0x18(r1).  */
741
      operandS++;
742
    case arg_cr:    /* Case 0x18(r1).   */
743
      /* Set displacement constant.  */
744
      while (*operandE != '(')
745
        operandE++;
746
      *operandE = '\0';
747
      process_label_constant (operandS, crx_ins);
748
      operandS = operandE;
749
    case arg_rbase: /* Case (r1).  */
750
      operandS++;
751
      /* Set register base.  */
752
      while (*operandE != ')')
753
        operandE++;
754
      *operandE = '\0';
755
      if ((cur_arg->r = get_register (operandS)) == nullregister)
756
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
757
                operandS, ins_parse);
758
 
759
      if (cur_arg->type != arg_rbase)
760
        cur_arg->type = arg_cr;
761
      break;
762
 
763
    case arg_idxr:
764
      /* Set displacement constant.  */
765
      while (*operandE != '(')
766
        operandE++;
767
      *operandE = '\0';
768
      process_label_constant (operandS, crx_ins);
769
      operandS = ++operandE;
770
 
771
      /* Set register base.  */
772
      while ((*operandE != ',') && (! ISSPACE (*operandE)))
773
        operandE++;
774
      *operandE++ = '\0';
775
      if ((cur_arg->r = get_register (operandS)) == nullregister)
776
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
777
                operandS, ins_parse);
778
 
779
      /* Skip leading white space.  */
780
      while (ISSPACE (*operandE))
781
        operandE++;
782
      operandS = operandE;
783
 
784
      /* Set register index.  */
785
      while ((*operandE != ')') && (*operandE != ','))
786
        operandE++;
787
      c = *operandE;
788
      *operandE++ = '\0';
789
 
790
      if ((cur_arg->i_r = get_register (operandS)) == nullregister)
791
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
792
                operandS, ins_parse);
793
 
794
      /* Skip leading white space.  */
795
      while (ISSPACE (*operandE))
796
        operandE++;
797
      operandS = operandE;
798
 
799
      /* Set the scale.  */
800
      if (c == ')')
801
        cur_arg->scale = 0;
802
      else
803
        {
804
          while (*operandE != ')')
805
            operandE++;
806
          *operandE = '\0';
807
 
808
          /* Preprocess the scale string.  */
809
          input_save = input_line_pointer;
810
          input_line_pointer = operandS;
811
          expression (&scale);
812
          input_line_pointer = input_save;
813
 
814
          scale_val = scale.X_add_number;
815
 
816
          /* Check if the scale value is legal.  */
817
          if (scale_val != 1 && scale_val != 2
818
              && scale_val != 4 && scale_val != 8)
819
            as_bad (_("Illegal Scale - `%d'"), scale_val);
820
 
821
          cur_arg->scale = exponent2scale (scale_val);
822
        }
823
      break;
824
 
825
    default:
826
      break;
827
    }
828
}
829
 
830
/* Parse a single operand.
831
   operand - Current operand to parse.
832
   crx_ins - Current assembled instruction.  */
833
 
834
static void
835
parse_operand (char *operand, ins * crx_ins)
836
{
837
  int ret_val;
838
  argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
839
 
840
  /* Initialize the type to NULL before parsing.  */
841
  cur_arg->type = nullargs;
842
 
843
  /* Check whether this is a general processor register.  */
844
  if ((ret_val = get_register (operand)) != nullregister)
845
    {
846
      cur_arg->type = arg_r;
847
      cur_arg->r = ret_val;
848
      cur_arg->X_op = O_register;
849
      return;
850
    }
851
 
852
  /* Check whether this is a core [special] coprocessor register.  */
853
  if ((ret_val = get_copregister (operand)) != nullcopregister)
854
    {
855
      cur_arg->type = arg_copr;
856
      if (ret_val >= cs0)
857
        cur_arg->type = arg_copsr;
858
      cur_arg->cr = ret_val;
859
      cur_arg->X_op = O_register;
860
      return;
861
    }
862
 
863
  /* Deal with special characters.  */
864
  switch (operand[0])
865
    {
866
    case '$':
867
      if (strchr (operand, '(') != NULL)
868
        cur_arg->type = arg_icr;
869
      else
870
        cur_arg->type = arg_ic;
871
      goto set_params;
872
      break;
873
 
874
    case '*':
875
      cur_arg->type = arg_sc;
876
      goto set_params;
877
      break;
878
 
879
    case '(':
880
      cur_arg->type = arg_rbase;
881
      goto set_params;
882
      break;
883
 
884
    default:
885
        break;
886
    }
887
 
888
  if (strchr (operand, '(') != NULL)
889
    {
890
      if (strchr (operand, ',') != NULL
891
          && (strchr (operand, ',') > strchr (operand, '(')))
892
            cur_arg->type = arg_idxr;
893
      else
894
        cur_arg->type = arg_cr;
895
    }
896
  else
897
    cur_arg->type = arg_c;
898
  goto set_params;
899
 
900
/* Parse an operand according to its type.  */
901
set_params:
902
  cur_arg->constant = 0;
903
  set_operand (operand, crx_ins);
904
}
905
 
906
/* Parse the various operands. Each operand is then analyzed to fillup
907
   the fields in the crx_ins data structure.  */
908
 
909
static void
910
parse_operands (ins * crx_ins, char *operands)
911
{
912
  char *operandS;              /* Operands string.  */
913
  char *operandH, *operandT;   /* Single operand head/tail pointers.  */
914
  int allocated = 0;            /* Indicates a new operands string was allocated.  */
915
  char *operand[MAX_OPERANDS]; /* Separating the operands.  */
916
  int op_num = 0;               /* Current operand number we are parsing.  */
917
  int bracket_flag = 0;         /* Indicates a bracket '(' was found.  */
918
  int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
919
 
920
  /* Preprocess the list of registers, if necessary.  */
921
  operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
922
    preprocess_reglist (operands, &allocated) : operands;
923
 
924
  while (*operandT != '\0')
925
    {
926
      if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
927
        {
928
          *operandT++ = '\0';
929
          operand[op_num++] = strdup (operandH);
930
          operandH = operandT;
931
          continue;
932
        }
933
 
934
      if (*operandT == ' ')
935
        as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
936
 
937
      if (*operandT == '(')
938
        bracket_flag = 1;
939
      else if (*operandT == '[')
940
        sq_bracket_flag = 1;
941
 
942
      if (*operandT == ')')
943
        {
944
          if (bracket_flag)
945
            bracket_flag = 0;
946
          else
947
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
948
        }
949
      else if (*operandT == ']')
950
        {
951
          if (sq_bracket_flag)
952
            sq_bracket_flag = 0;
953
          else
954
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
955
        }
956
 
957
      if (bracket_flag == 1 && *operandT == ')')
958
        bracket_flag = 0;
959
      else if (sq_bracket_flag == 1 && *operandT == ']')
960
        sq_bracket_flag = 0;
961
 
962
      operandT++;
963
    }
964
 
965
  /* Adding the last operand.  */
966
  operand[op_num++] = strdup (operandH);
967
  crx_ins->nargs = op_num;
968
 
969
  /* Verifying correct syntax of operands (all brackets should be closed).  */
970
  if (bracket_flag || sq_bracket_flag)
971
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
972
 
973
  /* Now we parse each operand separately.  */
974
  for (op_num = 0; op_num < crx_ins->nargs; op_num++)
975
    {
976
      cur_arg_num = op_num;
977
      parse_operand (operand[op_num], crx_ins);
978
      free (operand[op_num]);
979
    }
980
 
981
  if (allocated)
982
    free (operandS);
983
}
984
 
985
/* Get the trap index in dispatch table, given its name.
986
   This routine is used by assembling the 'excp' instruction.  */
987
 
988
static int
989
gettrap (char *s)
990
{
991
  const trap_entry *trap;
992
 
993
  for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
994
    if (strcasecmp (trap->name, s) == 0)
995
      return trap->entry;
996
 
997
  as_bad (_("Unknown exception: `%s'"), s);
998
  return 0;
999
}
1000
 
1001
/* Post-Increment instructions, as well as Store-Immediate instructions, are a
1002
   sub-group within load/stor instruction groups.
1003
   Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1004
   advance the instruction pointer to the start of that sub-group (that is, up
1005
   to the first instruction of that type).
1006
   Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS.  */
1007
 
1008
static void
1009
handle_LoadStor (char *operands)
1010
{
1011
  /* Post-Increment instructions precede Store-Immediate instructions in
1012
     CRX instruction table, hence they are handled before.
1013
     This synchronization should be kept.  */
1014
 
1015
  /* Assuming Post-Increment insn has the following format :
1016
     'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1017
     LD_STOR_INS_INC are the only store insns containing a plus sign (+).  */
1018
  if (strstr (operands, ")+") != NULL)
1019
    {
1020
      while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1021
        instruction++;
1022
      return;
1023
    }
1024
 
1025
  /* Assuming Store-Immediate insn has the following format :
1026
     'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1027
     STOR_IMM_INS are the only store insns containing a dollar sign ($).  */
1028
  if (strstr (operands, "$") != NULL)
1029
    while (! IS_INSN_TYPE (STOR_IMM_INS))
1030
      instruction++;
1031
}
1032
 
1033
/* Top level module where instruction parsing starts.
1034
   crx_ins - data structure holds some information.
1035
   operands - holds the operands part of the whole instruction.  */
1036
 
1037
static void
1038
parse_insn (ins *insn, char *operands)
1039
{
1040
  int i;
1041
 
1042
  /* Handle instructions with no operands.  */
1043
  for (i = 0; no_op_insn[i] != NULL; i++)
1044
  {
1045
    if (streq (no_op_insn[i], instruction->mnemonic))
1046
    {
1047
      insn->nargs = 0;
1048
      return;
1049
    }
1050
  }
1051
 
1052
  /* Handle 'excp'/'cinv' instructions.  */
1053
  if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1054
    {
1055
      insn->nargs = 1;
1056
      insn->arg[0].type = arg_ic;
1057
      insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1058
        gettrap (operands) : get_cinv_parameters (operands);
1059
      insn->arg[0].X_op = O_constant;
1060
      return;
1061
    }
1062
 
1063
  /* Handle load/stor unique instructions before parsing.  */
1064
  if (IS_INSN_TYPE (LD_STOR_INS))
1065
    handle_LoadStor (operands);
1066
 
1067
  if (operands != NULL)
1068
    parse_operands (insn, operands);
1069
}
1070
 
1071
/* Cinv instruction requires special handling.  */
1072
 
1073
static int
1074
get_cinv_parameters (char * operand)
1075
{
1076
  char *p = operand;
1077
  int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1078
 
1079
  while (*++p != ']')
1080
    {
1081
      if (*p == ',' || *p == ' ')
1082
        continue;
1083
 
1084
      if (*p == 'd')
1085
        d_used = 1;
1086
      else if (*p == 'i')
1087
        i_used = 1;
1088
      else if (*p == 'u')
1089
        u_used = 1;
1090
      else if (*p == 'b')
1091
        b_used = 1;
1092
      else
1093
        as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1094
    }
1095
 
1096
  return ((b_used ? 8 : 0)
1097
        + (d_used ? 4 : 0)
1098
        + (i_used ? 2 : 0)
1099
        + (u_used ? 1 : 0));
1100
}
1101
 
1102
/* Retrieve the opcode image of a given register.
1103
   If the register is illegal for the current instruction,
1104
   issue an error.  */
1105
 
1106
static int
1107
getreg_image (reg r)
1108
{
1109
  const reg_entry *reg;
1110
  char *reg_name;
1111
  int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
1112
 
1113
  if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1114
      || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1115
    is_procreg = 1;
1116
 
1117
  /* Check whether the register is in registers table.  */
1118
  if (r < MAX_REG)
1119
    reg = &crx_regtab[r];
1120
  /* Check whether the register is in coprocessor registers table.  */
1121
  else if (r < MAX_COPREG)
1122
    reg = &crx_copregtab[r-MAX_REG];
1123
  /* Register not found.  */
1124
  else
1125
    {
1126
      as_bad (_("Unknown register: `%d'"), r);
1127
      return 0;
1128
    }
1129
 
1130
  reg_name = reg->name;
1131
 
1132
/* Issue a error message when register is illegal.  */
1133
#define IMAGE_ERR \
1134
  as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1135
            reg_name, ins_parse);                            \
1136
  break;
1137
 
1138
  switch (reg->type)
1139
  {
1140
    case CRX_U_REGTYPE:
1141
      if (is_procreg || (instruction->flags & USER_REG))
1142
        return reg->image;
1143
      else
1144
        IMAGE_ERR;
1145
 
1146
    case CRX_CFG_REGTYPE:
1147
      if (is_procreg)
1148
        return reg->image;
1149
      else
1150
        IMAGE_ERR;
1151
 
1152
    case CRX_R_REGTYPE:
1153
      if (! is_procreg)
1154
        return reg->image;
1155
      else
1156
        IMAGE_ERR;
1157
 
1158
    case CRX_C_REGTYPE:
1159
    case CRX_CS_REGTYPE:
1160
      return reg->image;
1161
      break;
1162
 
1163
    default:
1164
      IMAGE_ERR;
1165
  }
1166
 
1167
  return 0;
1168
}
1169
 
1170
/* Routine used to represent integer X using NBITS bits.  */
1171
 
1172
static long
1173
getconstant (long x, int nbits)
1174
{
1175
  /* The following expression avoids overflow if
1176
     'nbits' is the number of bits in 'bfd_vma'.  */
1177
  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1178
}
1179
 
1180
/* Print a constant value to 'output_opcode':
1181
   ARG holds the operand's type and value.
1182
   SHIFT represents the location of the operand to be print into.
1183
   NBITS determines the size (in bits) of the constant.  */
1184
 
1185
static void
1186
print_constant (int nbits, int shift, argument *arg)
1187
{
1188
  unsigned long mask = 0;
1189
 
1190
  long constant = getconstant (arg->constant, nbits);
1191
 
1192
  switch (nbits)
1193
  {
1194
    case 32:
1195
    case 28:
1196
    case 24:
1197
    case 22:
1198
      /* mask the upper part of the constant, that is, the bits
1199
         going to the lowest byte of output_opcode[0].
1200
         The upper part of output_opcode[1] is always filled,
1201
         therefore it is always masked with 0xFFFF.  */
1202
      mask = (1 << (nbits - 16)) - 1;
1203
      /* Divide the constant between two consecutive words :
1204
 
1205
            +---------+---------+---------+---------+
1206
            |         | X X X X | X X X X |         |
1207
            +---------+---------+---------+---------+
1208
              output_opcode[0]    output_opcode[1]     */
1209
 
1210
      CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1211
      CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1212
      break;
1213
 
1214
    case 16:
1215
    case 12:
1216
      /* Special case - in arg_cr, the SHIFT represents the location
1217
         of the REGISTER, not the constant, which is itself not shifted.  */
1218
      if (arg->type == arg_cr)
1219
        {
1220
          CRX_PRINT (0, constant,  0);
1221
          break;
1222
        }
1223
 
1224
      /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1225
         always filling the upper part of output_opcode[1]. If we mistakenly
1226
         write it to output_opcode[0], the constant prefix (that is, 'match')
1227
         will be overridden.
1228
 
1229
            +---------+---------+---------+---------+
1230
            | 'match' |         | X X X X |         |
1231
            +---------+---------+---------+---------+
1232
              output_opcode[0]    output_opcode[1]     */
1233
 
1234
      if ((instruction->size > 2) && (shift == WORD_SHIFT))
1235
        CRX_PRINT (1, constant, WORD_SHIFT);
1236
      else
1237
        CRX_PRINT (0, constant, shift);
1238
      break;
1239
 
1240
    default:
1241
      CRX_PRINT (0, constant,  shift);
1242
      break;
1243
  }
1244
}
1245
 
1246
/* Print an operand to 'output_opcode', which later on will be
1247
   printed to the object file:
1248
   ARG holds the operand's type, size and value.
1249
   SHIFT represents the printing location of operand.
1250
   NBITS determines the size (in bits) of a constant operand.  */
1251
 
1252
static void
1253
print_operand (int nbits, int shift, argument *arg)
1254
{
1255
  switch (arg->type)
1256
    {
1257
    case arg_r:
1258
      CRX_PRINT (0, getreg_image (arg->r), shift);
1259
      break;
1260
 
1261
    case arg_copr:
1262
      if (arg->cr < c0 || arg->cr > c15)
1263
        as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1264
                ins_parse);
1265
      CRX_PRINT (0, getreg_image (arg->cr), shift);
1266
      break;
1267
 
1268
    case arg_copsr:
1269
      if (arg->cr < cs0 || arg->cr > cs15)
1270
        as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1271
                ins_parse);
1272
      CRX_PRINT (0, getreg_image (arg->cr), shift);
1273
      break;
1274
 
1275
    case arg_idxr:
1276
      /*    16      12        8    6         0
1277
            +--------------------------------+
1278
            | r_base | r_idx  | scl|  disp   |
1279
            +--------------------------------+    */
1280
      CRX_PRINT (0, getreg_image (arg->r), 12);
1281
      CRX_PRINT (0, getreg_image (arg->i_r), 8);
1282
      CRX_PRINT (0, arg->scale, 6);
1283
    case arg_ic:
1284
    case arg_c:
1285
      print_constant (nbits, shift, arg);
1286
      break;
1287
 
1288
    case arg_rbase:
1289
      CRX_PRINT (0, getreg_image (arg->r), shift);
1290
      break;
1291
 
1292
    case arg_cr:
1293
      /* case base_cst4.  */
1294
      if (instruction->flags & DISPU4MAP)
1295
        print_constant (nbits, shift + REG_SIZE, arg);
1296
      else
1297
        /* rbase_disps<NN> and other such cases.  */
1298
        print_constant (nbits, shift, arg);
1299
      /* Add the register argument to the output_opcode.  */
1300
      CRX_PRINT (0, getreg_image (arg->r), shift);
1301
      break;
1302
 
1303
    default:
1304
      break;
1305
    }
1306
}
1307
 
1308
/* Retrieve the number of operands for the current assembled instruction.  */
1309
 
1310
static int
1311
get_number_of_operands (void)
1312
{
1313
  int i;
1314
 
1315
  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1316
    ;
1317
  return i;
1318
}
1319
 
1320
/* Verify that the number NUM can be represented in BITS bits (that is,
1321
   within its permitted range), based on the instruction's FLAGS.
1322
   If UPDATE is nonzero, update the value of NUM if necessary.
1323
   Return OP_LEGAL upon success, actual error type upon failure.  */
1324
 
1325
static op_err
1326
check_range (long *num, int bits, int unsigned flags, int update)
1327
{
1328
  long min, max;
1329
  int retval = OP_LEGAL;
1330
  int bin;
1331
  long upper_64kb = 0xFFFF0000;
1332
  long value = *num;
1333
 
1334
  /* For hosts witah longs bigger than 32-bits make sure that the top
1335
     bits of a 32-bit negative value read in by the parser are set,
1336
     so that the correct comparisons are made.  */
1337
  if (value & 0x80000000)
1338
    value |= (-1L << 31);
1339
 
1340
  /* Verify operand value is even.  */
1341
  if (flags & OP_EVEN)
1342
    {
1343
      if (value % 2)
1344
        return OP_NOT_EVEN;
1345
    }
1346
 
1347
  if (flags & OP_UPPER_64KB)
1348
    {
1349
      /* Check if value is to be mapped to upper 64 KB memory area.  */
1350
      if ((value & upper_64kb) == upper_64kb)
1351
        {
1352
          value -= upper_64kb;
1353
          if (update)
1354
            *num = value;
1355
        }
1356
      else
1357
        return OP_NOT_UPPER_64KB;
1358
    }
1359
 
1360
  if (flags & OP_SHIFT)
1361
    {
1362
      value >>= 1;
1363
      if (update)
1364
        *num = value;
1365
    }
1366
  else if (flags & OP_SHIFT_DEC)
1367
    {
1368
      value = (value >> 1) - 1;
1369
      if (update)
1370
        *num = value;
1371
    }
1372
 
1373
  if (flags & OP_ESC)
1374
    {
1375
      /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
1376
      if (value == 0x7e || value == 0x7f)
1377
        return OP_OUT_OF_RANGE;
1378
    }
1379
 
1380
  if (flags & OP_DISPU4)
1381
    {
1382
      int is_dispu4 = 0;
1383
 
1384
      int mul = (instruction->flags & DISPUB4) ? 1
1385
                : (instruction->flags & DISPUW4) ? 2
1386
                : (instruction->flags & DISPUD4) ? 4 : 0;
1387
 
1388
      for (bin = 0; bin < cst4_maps; bin++)
1389
        {
1390
          if (value == (mul * bin))
1391
            {
1392
              is_dispu4 = 1;
1393
              if (update)
1394
                *num = bin;
1395
              break;
1396
            }
1397
        }
1398
      if (!is_dispu4)
1399
        retval = OP_ILLEGAL_DISPU4;
1400
    }
1401
  else if (flags & OP_CST4)
1402
    {
1403
      int is_cst4 = 0;
1404
 
1405
      for (bin = 0; bin < cst4_maps; bin++)
1406
        {
1407
          if (value == cst4_map[bin])
1408
            {
1409
              is_cst4 = 1;
1410
              if (update)
1411
                *num = bin;
1412
              break;
1413
            }
1414
        }
1415
      if (!is_cst4)
1416
        retval = OP_ILLEGAL_CST4;
1417
    }
1418
  else if (flags & OP_SIGNED)
1419
    {
1420
      max = (1 << (bits - 1)) - 1;
1421
      min = - (1 << (bits - 1));
1422
      if ((value > max) || (value < min))
1423
        retval = OP_OUT_OF_RANGE;
1424
    }
1425
  else if (flags & OP_UNSIGNED)
1426
    {
1427
      max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1428
      min = 0;
1429
      if (((unsigned long) value > (unsigned long) max)
1430
            || ((unsigned long) value < (unsigned long) min))
1431
        retval = OP_OUT_OF_RANGE;
1432
    }
1433
  return retval;
1434
}
1435
 
1436
/* Assemble a single instruction:
1437
   INSN is already parsed (that is, all operand values and types are set).
1438
   For instruction to be assembled, we need to find an appropriate template in
1439
   the instruction table, meeting the following conditions:
1440
    1: Has the same number of operands.
1441
    2: Has the same operand types.
1442
    3: Each operand size is sufficient to represent the instruction's values.
1443
   Returns 1 upon success, 0 upon failure.  */
1444
 
1445
static int
1446
assemble_insn (char *mnemonic, ins *insn)
1447
{
1448
  /* Type of each operand in the current template.  */
1449
  argtype cur_type[MAX_OPERANDS];
1450
  /* Size (in bits) of each operand in the current template.  */
1451
  unsigned int cur_size[MAX_OPERANDS];
1452
  /* Flags of each operand in the current template.  */
1453
  unsigned int cur_flags[MAX_OPERANDS];
1454
  /* Instruction type to match.  */
1455
  unsigned int ins_type;
1456
  /* Boolean flag to mark whether a match was found.  */
1457
  int match = 0;
1458
  int i;
1459
  /* Nonzero if an instruction with same number of operands was found.  */
1460
  int found_same_number_of_operands = 0;
1461
  /* Nonzero if an instruction with same argument types was found.  */
1462
  int found_same_argument_types = 0;
1463
  /* Nonzero if a constant was found within the required range.  */
1464
  int found_const_within_range  = 0;
1465
  /* Argument number of an operand with invalid type.  */
1466
  int invalid_optype = -1;
1467
  /* Argument number of an operand with invalid constant value.  */
1468
  int invalid_const  = -1;
1469
  /* Operand error (used for issuing various constant error messages).  */
1470
  op_err op_error, const_err = OP_LEGAL;
1471
 
1472
/* Retrieve data (based on FUNC) for each operand of a given instruction.  */
1473
#define GET_CURRENT_DATA(FUNC, ARRAY)                             \
1474
  for (i = 0; i < insn->nargs; i++)                                \
1475
    ARRAY[i] = FUNC (instruction->operands[i].op_type)
1476
 
1477
#define GET_CURRENT_TYPE    GET_CURRENT_DATA(get_optype, cur_type)
1478
#define GET_CURRENT_SIZE    GET_CURRENT_DATA(get_opbits, cur_size)
1479
#define GET_CURRENT_FLAGS   GET_CURRENT_DATA(get_opflags, cur_flags)
1480
 
1481
  /* Instruction has no operands -> only copy the constant opcode.   */
1482
  if (insn->nargs == 0)
1483
    {
1484
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1485
      return 1;
1486
    }
1487
 
1488
  /* In some case, same mnemonic can appear with different instruction types.
1489
     For example, 'storb' is supported with 3 different types :
1490
     LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1491
     We assume that when reaching this point, the instruction type was
1492
     pre-determined. We need to make sure that the type stays the same
1493
     during a search for matching instruction.  */
1494
  ins_type = CRX_INS_TYPE(instruction->flags);
1495
 
1496
  while (/* Check that match is still not found.  */
1497
         match != 1
1498
         /* Check we didn't get to end of table.  */
1499
         && instruction->mnemonic != NULL
1500
         /* Check that the actual mnemonic is still available.  */
1501
         && IS_INSN_MNEMONIC (mnemonic)
1502
         /* Check that the instruction type wasn't changed.  */
1503
         && IS_INSN_TYPE(ins_type))
1504
    {
1505
      /* Check whether number of arguments is legal.  */
1506
      if (get_number_of_operands () != insn->nargs)
1507
        goto next_insn;
1508
      found_same_number_of_operands = 1;
1509
 
1510
      /* Initialize arrays with data of each operand in current template.  */
1511
      GET_CURRENT_TYPE;
1512
      GET_CURRENT_SIZE;
1513
      GET_CURRENT_FLAGS;
1514
 
1515
      /* Check for type compatibility.  */
1516
      for (i = 0; i < insn->nargs; i++)
1517
        {
1518
          if (cur_type[i] != insn->arg[i].type)
1519
            {
1520
              if (invalid_optype == -1)
1521
                invalid_optype = i + 1;
1522
              goto next_insn;
1523
            }
1524
        }
1525
      found_same_argument_types = 1;
1526
 
1527
      for (i = 0; i < insn->nargs; i++)
1528
        {
1529
          /* Reverse the operand indices for certain opcodes:
1530
             Index 0      -->> 1
1531
             Index 1      -->> 0
1532
             Other index  -->> stays the same.  */
1533
          int j = instruction->flags & REVERSE_MATCH ?
1534
                  i == 0 ? 1 :
1535
                  i == 1 ? 0 : i :
1536
                  i;
1537
 
1538
          /* Only check range - don't update the constant's value, since the
1539
             current instruction may not be the last we try to match.
1540
             The constant's value will be updated later, right before printing
1541
             it to the object file.  */
1542
          if ((insn->arg[j].X_op == O_constant)
1543
               && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1544
                                           cur_flags[j], 0)))
1545
            {
1546
              if (invalid_const == -1)
1547
              {
1548
                invalid_const = j + 1;
1549
                const_err = op_error;
1550
              }
1551
              goto next_insn;
1552
            }
1553
          /* For symbols, we make sure the relocation size (which was already
1554
             determined) is sufficient.  */
1555
          else if ((insn->arg[j].X_op == O_symbol)
1556
                    && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1557
                         > cur_size[j]))
1558
                  goto next_insn;
1559
        }
1560
      found_const_within_range = 1;
1561
 
1562
      /* If we got till here -> Full match is found.  */
1563
      match = 1;
1564
      break;
1565
 
1566
/* Try again with next instruction.  */
1567
next_insn:
1568
      instruction++;
1569
    }
1570
 
1571
  if (!match)
1572
    {
1573
      /* We haven't found a match - instruction can't be assembled.  */
1574
      if (!found_same_number_of_operands)
1575
        as_bad (_("Incorrect number of operands"));
1576
      else if (!found_same_argument_types)
1577
        as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1578
      else if (!found_const_within_range)
1579
      {
1580
        switch (const_err)
1581
        {
1582
        case OP_OUT_OF_RANGE:
1583
          as_bad (_("Operand out of range (arg %d)"), invalid_const);
1584
          break;
1585
        case OP_NOT_EVEN:
1586
          as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1587
          break;
1588
        case OP_ILLEGAL_DISPU4:
1589
          as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1590
          break;
1591
        case OP_ILLEGAL_CST4:
1592
          as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1593
          break;
1594
        case OP_NOT_UPPER_64KB:
1595
          as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1596
                    invalid_const);
1597
          break;
1598
        default:
1599
          as_bad (_("Illegal operand (arg %d)"), invalid_const);
1600
          break;
1601
        }
1602
      }
1603
 
1604
      return 0;
1605
    }
1606
  else
1607
    /* Full match - print the encoding to output file.  */
1608
    {
1609
      /* Make further checkings (such that couldn't be made earlier).
1610
         Warn the user if necessary.  */
1611
      warn_if_needed (insn);
1612
 
1613
      /* Check whether we need to adjust the instruction pointer.  */
1614
      if (adjust_if_needed (insn))
1615
        /* If instruction pointer was adjusted, we need to update
1616
           the size of the current template operands.  */
1617
        GET_CURRENT_SIZE;
1618
 
1619
      for (i = 0; i < insn->nargs; i++)
1620
        {
1621
          int j = instruction->flags & REVERSE_MATCH ?
1622
                  i == 0 ? 1 :
1623
                  i == 1 ? 0 : i :
1624
                  i;
1625
 
1626
          /* This time, update constant value before printing it.  */
1627
          if ((insn->arg[j].X_op == O_constant)
1628
               && (check_range (&insn->arg[j].constant, cur_size[j],
1629
                                cur_flags[j], 1) != OP_LEGAL))
1630
              as_fatal (_("Illegal operand (arg %d)"), j+1);
1631
        }
1632
 
1633
      /* First, copy the instruction's opcode.  */
1634
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1635
 
1636
      for (i = 0; i < insn->nargs; i++)
1637
        {
1638
          cur_arg_num = i;
1639
          print_operand (cur_size[i], instruction->operands[i].shift,
1640
                         &insn->arg[i]);
1641
        }
1642
    }
1643
 
1644
  return 1;
1645
}
1646
 
1647
/* Bunch of error checkings.
1648
   The checks are made after a matching instruction was found.  */
1649
 
1650
void
1651
warn_if_needed (ins *insn)
1652
{
1653
  /* If the post-increment address mode is used and the load/store
1654
     source register is the same as rbase, the result of the
1655
     instruction is undefined.  */
1656
  if (IS_INSN_TYPE (LD_STOR_INS_INC))
1657
    {
1658
      /* Enough to verify that one of the arguments is a simple reg.  */
1659
      if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1660
        if (insn->arg[0].r == insn->arg[1].r)
1661
          as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1662
                   insn->arg[0].r);
1663
    }
1664
 
1665
  /* Some instruction assume the stack pointer as rptr operand.
1666
     Issue an error when the register to be loaded is also SP.  */
1667
  if (instruction->flags & NO_SP)
1668
    {
1669
      if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1670
        as_bad (_("`%s' has undefined result"), ins_parse);
1671
    }
1672
 
1673
  /* If the rptr register is specified as one of the registers to be loaded,
1674
     the final contents of rptr are undefined. Thus, we issue an error.  */
1675
  if (instruction->flags & NO_RPTR)
1676
    {
1677
      if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1678
        as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1679
         getreg_image (insn->arg[0].r));
1680
    }
1681
}
1682
 
1683
/* In some cases, we need to adjust the instruction pointer although a
1684
   match was already found. Here, we gather all these cases.
1685
   Returns 1 if instruction pointer was adjusted, otherwise 0.  */
1686
 
1687
int
1688
adjust_if_needed (ins *insn)
1689
{
1690
  int ret_value = 0;
1691
 
1692
  /* Special check for 'addub $0, r0' instruction -
1693
     The opcode '0000 0000 0000 0000' is not allowed.  */
1694
  if (IS_INSN_MNEMONIC ("addub"))
1695
    {
1696
      if ((instruction->operands[0].op_type == cst4)
1697
          && instruction->operands[1].op_type == regr)
1698
        {
1699
          if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1700
            {
1701
              instruction++;
1702
              ret_value = 1;
1703
            }
1704
        }
1705
    }
1706
 
1707
  /* Optimization: Omit a zero displacement in bit operations,
1708
     saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)').  */
1709
  if (IS_INSN_TYPE (CSTBIT_INS))
1710
    {
1711
      if ((instruction->operands[1].op_type == rbase_disps12)
1712
           && (insn->arg[1].X_op == O_constant)
1713
           && (insn->arg[1].constant == 0))
1714
            {
1715
              instruction--;
1716
              ret_value = 1;
1717
            }
1718
    }
1719
 
1720
  return ret_value;
1721
}
1722
 
1723
/* Set the appropriate bit for register 'r' in 'mask'.
1724
   This indicates that this register is loaded or stored by
1725
   the instruction.  */
1726
 
1727
static void
1728
mask_reg (int r, unsigned short int *mask)
1729
{
1730
  if ((reg)r > (reg)sp)
1731
    {
1732
      as_bad (_("Invalid Register in Register List"));
1733
      return;
1734
    }
1735
 
1736
  *mask |= (1 << r);
1737
}
1738
 
1739
/* Preprocess register list - create a 16-bit mask with one bit for each
1740
   of the 16 general purpose registers. If a bit is set, it indicates
1741
   that this register is loaded or stored by the instruction.  */
1742
 
1743
static char *
1744
preprocess_reglist (char *param, int *allocated)
1745
{
1746
  char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
1747
  char *regP;                     /* Pointer to 'reg_name' string.  */
1748
  int reg_counter = 0;             /* Count number of parsed registers.  */
1749
  unsigned short int mask = 0;     /* Mask for 16 general purpose registers.  */
1750
  char *new_param;                /* New created operands string.  */
1751
  char *paramP = param;           /* Pointer to original opearands string.  */
1752
  char maskstring[10];            /* Array to print the mask as a string.  */
1753
  int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers.  */
1754
  reg r;
1755
  copreg cr;
1756
 
1757
  /* If 'param' is already in form of a number, no need to preprocess.  */
1758
  if (strchr (paramP, '{') == NULL)
1759
    return param;
1760
 
1761
  /* Verifying correct syntax of operand.  */
1762
  if (strchr (paramP, '}') == NULL)
1763
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1764
 
1765
  while (*paramP++ != '{');
1766
 
1767
  new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1768
  *allocated = 1;
1769
  strncpy (new_param, param, paramP - param - 1);
1770
 
1771
  while (*paramP != '}')
1772
    {
1773
      regP = paramP;
1774
      memset (&reg_name, '\0', sizeof (reg_name));
1775
 
1776
      while (ISALNUM (*paramP))
1777
        paramP++;
1778
 
1779
      strncpy (reg_name, regP, paramP - regP);
1780
 
1781
      /* Coprocessor register c<N>.  */
1782
      if (IS_INSN_TYPE (COP_REG_INS))
1783
        {
1784
          if (((cr = get_copregister (reg_name)) == nullcopregister)
1785
              || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1786
            as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1787
          mask_reg (getreg_image (cr - c0), &mask);
1788
        }
1789
      /* Coprocessor Special register cs<N>.  */
1790
      else if (IS_INSN_TYPE (COPS_REG_INS))
1791
        {
1792
          if (((cr = get_copregister (reg_name)) == nullcopregister)
1793
              || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1794
            as_fatal (_("Illegal register `%s' in cop-special-register list"),
1795
                      reg_name);
1796
          mask_reg (getreg_image (cr - cs0), &mask);
1797
        }
1798
      /* User register u<N>.  */
1799
      else if (instruction->flags & USER_REG)
1800
        {
1801
          if (streq(reg_name, "uhi"))
1802
            {
1803
              hi_found = 1;
1804
              goto next_inst;
1805
            }
1806
          else if (streq(reg_name, "ulo"))
1807
            {
1808
              lo_found = 1;
1809
              goto next_inst;
1810
            }
1811
          else if (((r = get_register (reg_name)) == nullregister)
1812
              || (crx_regtab[r].type != CRX_U_REGTYPE))
1813
            as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1814
 
1815
          mask_reg (getreg_image (r - u0), &mask);
1816
        }
1817
      /* General purpose register r<N>.  */
1818
      else
1819
        {
1820
          if (streq(reg_name, "hi"))
1821
            {
1822
              hi_found = 1;
1823
              goto next_inst;
1824
            }
1825
          else if (streq(reg_name, "lo"))
1826
            {
1827
              lo_found = 1;
1828
              goto next_inst;
1829
            }
1830
          else if (((r = get_register (reg_name)) == nullregister)
1831
              || (crx_regtab[r].type != CRX_R_REGTYPE))
1832
            as_fatal (_("Illegal register `%s' in register list"), reg_name);
1833
 
1834
          mask_reg (getreg_image (r - r0), &mask);
1835
        }
1836
 
1837
      if (++reg_counter > MAX_REGS_IN_MASK16)
1838
        as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1839
                MAX_REGS_IN_MASK16);
1840
 
1841
next_inst:
1842
      while (!ISALNUM (*paramP) && *paramP != '}')
1843
          paramP++;
1844
    }
1845
 
1846
  if (*++paramP != '\0')
1847
    as_warn (_("rest of line ignored; first ignored character is `%c'"),
1848
             *paramP);
1849
 
1850
  switch (hi_found + lo_found)
1851
    {
1852
    case 0:
1853
      /* At least one register should be specified.  */
1854
      if (mask == 0)
1855
        as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1856
                ins_parse);
1857
      break;
1858
 
1859
    case 1:
1860
      /* HI can't be specified without LO (and vise-versa).  */
1861
      as_bad (_("HI/LO registers should be specified together"));
1862
      break;
1863
 
1864
    case 2:
1865
      /* HI/LO registers mustn't be masked with additional registers.  */
1866
      if (mask != 0)
1867
        as_bad (_("HI/LO registers should be specified without additional registers"));
1868
 
1869
    default:
1870
      break;
1871
    }
1872
 
1873
  sprintf (maskstring, "$0x%x", mask);
1874
  strcat (new_param, maskstring);
1875
  return new_param;
1876
}
1877
 
1878
/* Print the instruction.
1879
   Handle also cases where the instruction is relaxable/relocatable.  */
1880
 
1881
void
1882
print_insn (ins *insn)
1883
{
1884
  unsigned int i, j, insn_size;
1885
  char *this_frag;
1886
  unsigned short words[4];
1887
  int addr_mod;
1888
 
1889
  /* Arrange the insn encodings in a WORD size array.  */
1890
  for (i = 0, j = 0; i < 2; i++)
1891
    {
1892
      words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1893
      words[j++] = output_opcode[i] & 0xFFFF;
1894
    }
1895
 
1896
  /* Handle relaxtion.  */
1897
  if ((instruction->flags & RELAXABLE) && relocatable)
1898
    {
1899
      int relax_subtype;
1900
 
1901
      /* Write the maximal instruction size supported.  */
1902
      insn_size = INSN_MAX_SIZE;
1903
 
1904
      /* bCC  */
1905
      if (IS_INSN_TYPE (BRANCH_INS))
1906
        relax_subtype = 0;
1907
      /* bal  */
1908
      else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1909
        relax_subtype = 3;
1910
      /* cmpbr/bcop  */
1911
      else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1912
        relax_subtype = 5;
1913
      else
1914
        abort ();
1915
 
1916
      this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1917
                            4, relax_subtype,
1918
                            insn->exp.X_add_symbol,
1919
                            insn->exp.X_add_number,
1920
                            0);
1921
    }
1922
  else
1923
    {
1924
      insn_size = instruction->size;
1925
      this_frag = frag_more (insn_size * 2);
1926
 
1927
      /* Handle relocation.  */
1928
      if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1929
        {
1930
          reloc_howto_type *reloc_howto;
1931
          int size;
1932
 
1933
          reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1934
 
1935
          if (!reloc_howto)
1936
            abort ();
1937
 
1938
          size = bfd_get_reloc_size (reloc_howto);
1939
 
1940
          if (size < 1 || size > 4)
1941
            abort ();
1942
 
1943
          fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1944
                       size, &insn->exp, reloc_howto->pc_relative,
1945
                       insn->rtype);
1946
        }
1947
    }
1948
 
1949
  /* Verify a 2-byte code alignment.  */
1950
  addr_mod = frag_now_fix () & 1;
1951
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1952
    as_bad (_("instruction address is not a multiple of 2"));
1953
  frag_now->insn_addr = addr_mod;
1954
  frag_now->has_code = 1;
1955
 
1956
  /* Write the instruction encoding to frag.  */
1957
  for (i = 0; i < insn_size; i++)
1958
    {
1959
      md_number_to_chars (this_frag, (valueT) words[i], 2);
1960
      this_frag += 2;
1961
    }
1962
}
1963
 
1964
/* This is the guts of the machine-dependent assembler.  OP points to a
1965
   machine dependent instruction.  This function is supposed to emit
1966
   the frags/bytes it assembles to.  */
1967
 
1968
void
1969
md_assemble (char *op)
1970
{
1971
  ins crx_ins;
1972
  char *param;
1973
  char c;
1974
 
1975
  /* Reset global variables for a new instruction.  */
1976
  reset_vars (op);
1977
 
1978
  /* Strip the mnemonic.  */
1979
  for (param = op; *param != 0 && !ISSPACE (*param); param++)
1980
    ;
1981
  c = *param;
1982
  *param++ = '\0';
1983
 
1984
  /* Find the instruction.  */
1985
  instruction = (const inst *) hash_find (crx_inst_hash, op);
1986
  if (instruction == NULL)
1987
    {
1988
      as_bad (_("Unknown opcode: `%s'"), op);
1989
      return;
1990
    }
1991
 
1992
  /* Tie dwarf2 debug info to the address at the start of the insn.  */
1993
  dwarf2_emit_insn (0);
1994
 
1995
  /* Parse the instruction's operands.  */
1996
  parse_insn (&crx_ins, param);
1997
 
1998
  /* Assemble the instruction - return upon failure.  */
1999
  if (assemble_insn (op, &crx_ins) == 0)
2000
    return;
2001
 
2002
  /* Print the instruction.  */
2003
  print_insn (&crx_ins);
2004
}

powered by: WebSVN 2.1.0

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