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 241

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

powered by: WebSVN 2.1.0

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