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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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