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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [tc-cr16.c] - Blame information for rev 156

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* tc-cr16.c -- Assembler code for the CR16 CPU core.
2
   Copyright 2007 Free Software Foundation, Inc.
3
 
4
   Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the
20
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "as.h"
24
#include "safe-ctype.h"
25
#include "dwarf2dbg.h"
26
#include "opcode/cr16.h"
27
#include "elf/cr16.h"
28
 
29
 
30
/* Word is considered here as a 16-bit unsigned short int.  */
31
#define WORD_SHIFT  16
32
 
33
/* Register is 2-byte size.  */
34
#define REG_SIZE   2
35
 
36
/* Maximum size of a single instruction (in words).  */
37
#define INSN_MAX_SIZE   3
38
 
39
/* Maximum bits which may be set in a `mask16' operand.  */
40
#define MAX_REGS_IN_MASK16  8
41
 
42
/* Assign a number NUM, shifted by SHIFT bytes, into a location
43
   pointed by index BYTE of array 'output_opcode'.  */
44
#define CR16_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)
45
 
46
/* Operand errors.  */
47
typedef enum
48
  {
49
    OP_LEGAL = 0,       /* Legal operand.  */
50
    OP_OUT_OF_RANGE,    /* Operand not within permitted range.  */
51
    OP_NOT_EVEN         /* Operand is Odd number, should be even.  */
52
  }
53
op_err;
54
 
55
/* Opcode mnemonics hash table.  */
56
static struct hash_control *cr16_inst_hash;
57
/* CR16 registers hash table.  */
58
static struct hash_control *reg_hash;
59
/* CR16 register pair hash table.  */
60
static struct hash_control *regp_hash;
61
/* CR16 processor registers hash table.  */
62
static struct hash_control *preg_hash;
63
/* CR16 processor registers 32 bit hash table.  */
64
static struct hash_control *pregp_hash;
65
/* Current instruction we're assembling.  */
66
const inst *instruction;
67
 
68
 
69
static int code_label = 0;
70
 
71
/* Global variables.  */
72
 
73
/* Array to hold an instruction encoding.  */
74
long output_opcode[2];
75
 
76
/* Nonzero means a relocatable symbol.  */
77
int relocatable;
78
 
79
/* A copy of the original instruction (used in error messages).  */
80
char ins_parse[MAX_INST_LEN];
81
 
82
/* The current processed argument number.  */
83
int cur_arg_num;
84
 
85
/* Generic assembler global variables which must be defined by all targets.  */
86
 
87
/* Characters which always start a comment.  */
88
const char comment_chars[] = "#";
89
 
90
/* Characters which start a comment at the beginning of a line.  */
91
const char line_comment_chars[] = "#";
92
 
93
/* This array holds machine specific line separator characters.  */
94
const char line_separator_chars[] = ";";
95
 
96
/* Chars that can be used to separate mant from exp in floating point nums.  */
97
const char EXP_CHARS[] = "eE";
98
 
99
/* Chars that mean this number is a floating point constant as in 0f12.456  */
100
const char FLT_CHARS[] = "f'";
101
 
102
/* Target-specific multicharacter options, not const-declared at usage.  */
103
const char *md_shortopts = "";
104
struct option md_longopts[] =
105
{
106
  {NULL, no_argument, NULL, 0}
107
};
108
size_t md_longopts_size = sizeof (md_longopts);
109
 
110
static void
111
l_cons (int nbytes)
112
{
113
  int c;
114
  expressionS exp;
115
 
116
#ifdef md_flush_pending_output
117
    md_flush_pending_output ();
118
#endif
119
 
120
  if (is_it_end_of_statement ())
121
    {
122
      demand_empty_rest_of_line ();
123
      return;
124
    }
125
 
126
#ifdef TC_ADDRESS_BYTES
127
  if (nbytes == 0)
128
    nbytes = TC_ADDRESS_BYTES ();
129
#endif
130
 
131
#ifdef md_cons_align
132
  md_cons_align (nbytes);
133
#endif
134
 
135
  c = 0;
136
  do
137
    {
138
      unsigned int bits_available = BITS_PER_CHAR * nbytes;
139
      char *hold = input_line_pointer;
140
 
141
      expression (&exp);
142
 
143
      if (*input_line_pointer == ':')
144
        {
145
          /* Bitfields.  */
146
          long value = 0;
147
 
148
          for (;;)
149
            {
150
              unsigned long width;
151
 
152
              if (*input_line_pointer != ':')
153
                {
154
                  input_line_pointer = hold;
155
                  break;
156
                }
157
              if (exp.X_op == O_absent)
158
                {
159
                  as_warn (_("using a bit field width of zero"));
160
                  exp.X_add_number = 0;
161
                  exp.X_op = O_constant;
162
                }
163
 
164
              if (exp.X_op != O_constant)
165
                {
166
                  *input_line_pointer = '\0';
167
                  as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
168
                  *input_line_pointer = ':';
169
                  demand_empty_rest_of_line ();
170
                  return;
171
                }
172
 
173
              if ((width = exp.X_add_number) >
174
                  (unsigned int)(BITS_PER_CHAR * nbytes))
175
                {
176
                  as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), width, nbytes, (BITS_PER_CHAR * nbytes));
177
                  width = BITS_PER_CHAR * nbytes;
178
                }                   /* Too big.  */
179
 
180
 
181
              if (width > bits_available)
182
                {
183
                  /* FIXME-SOMEDAY: backing up and reparsing is wasteful.  */
184
                  input_line_pointer = hold;
185
                  exp.X_add_number = value;
186
                  break;
187
                }
188
 
189
              /* Skip ':'.  */
190
              hold = ++input_line_pointer;
191
 
192
              expression (&exp);
193
              if (exp.X_op != O_constant)
194
                {
195
                  char cache = *input_line_pointer;
196
 
197
                  *input_line_pointer = '\0';
198
                  as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
199
                  *input_line_pointer = cache;
200
                  demand_empty_rest_of_line ();
201
                  return;
202
                }
203
 
204
              value |= ((~(-1 << width) & exp.X_add_number)
205
                        << ((BITS_PER_CHAR * nbytes) - bits_available));
206
 
207
              if ((bits_available -= width) == 0
208
                  || is_it_end_of_statement ()
209
                  || *input_line_pointer != ',')
210
                break;
211
 
212
              hold = ++input_line_pointer;
213
              expression (&exp);
214
            }
215
 
216
          exp.X_add_number = value;
217
          exp.X_op = O_constant;
218
          exp.X_unsigned = 1;
219
        }
220
 
221
      if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
222
        code_label = 1;
223
      emit_expr (&exp, (unsigned int) nbytes);
224
      ++c;
225
      if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
226
        {
227
          input_line_pointer +=3;
228
          break;
229
        }
230
    }
231
  while ((*input_line_pointer++ == ','));
232
 
233
  /* Put terminator back into stream.  */
234
  input_line_pointer--;
235
 
236
  demand_empty_rest_of_line ();
237
}
238
 
239
 
240
/* This table describes all the machine specific pseudo-ops
241
   the assembler has to support.  The fields are:
242
   *** Pseudo-op name without dot.
243
   *** Function to call to execute this pseudo-op.
244
   *** Integer arg to pass to the function.  */
245
 
246
const pseudo_typeS md_pseudo_table[] =
247
{
248
  /* In CR16 machine, align is in bytes (not a ptwo boundary).  */
249
  {"align", s_align_bytes, 0},
250
  {"long", l_cons,  4 },
251
  {0, 0, 0}
252
};
253
 
254
/* CR16 relaxation table.  */
255
const relax_typeS md_relax_table[] =
256
{
257
  /* bCC  */
258
  {0x7f, -0x80, 2, 1},                  /*  8 */
259
  {0xfffe, -0x10000, 4, 2},             /* 16 */
260
  {0xfffffe, -0x1000000, 6, 0},         /* 24 */
261
};
262
 
263
/* Return the bit size for a given operand.  */
264
 
265
static int
266
get_opbits (operand_type op)
267
{
268
  if (op < MAX_OPRD)
269
    return cr16_optab[op].bit_size;
270
 
271
  return 0;
272
}
273
 
274
/* Return the argument type of a given operand.  */
275
 
276
static argtype
277
get_optype (operand_type op)
278
{
279
  if (op < MAX_OPRD)
280
    return cr16_optab[op].arg_type;
281
  else
282
    return nullargs;
283
}
284
 
285
/* Return the flags of a given operand.  */
286
 
287
static int
288
get_opflags (operand_type op)
289
{
290
  if (op < MAX_OPRD)
291
    return cr16_optab[op].flags;
292
 
293
  return 0;
294
}
295
 
296
/* Get the cc code.  */
297
 
298
static int
299
get_cc (char *cc_name)
300
{
301
   unsigned int i;
302
 
303
   for (i = 0; i < cr16_num_cc; i++)
304
     if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
305
       return i;
306
 
307
   return -1;
308
}
309
 
310
/* Get the core processor register 'reg_name'.  */
311
 
312
static reg
313
get_register (char *reg_name)
314
{
315
  const reg_entry *reg;
316
 
317
  reg = (const reg_entry *) hash_find (reg_hash, reg_name);
318
 
319
  if (reg != NULL)
320
    return reg->value.reg_val;
321
 
322
  return nullregister;
323
}
324
/* Get the core processor register-pair 'reg_name'.  */
325
 
326
static reg
327
get_register_pair (char *reg_name)
328
{
329
  const reg_entry *reg;
330
  char tmp_rp[16]="\0";
331
 
332
  /* Add '(' and ')' to the reg pair, if its not present.  */
333
  if (reg_name[0] != '(')
334
    {
335
      tmp_rp[0] = '(';
336
      strcat (tmp_rp, reg_name);
337
      strcat (tmp_rp,")");
338
      reg = (const reg_entry *) hash_find (regp_hash, tmp_rp);
339
    }
340
  else
341
    reg = (const reg_entry *) hash_find (regp_hash, reg_name);
342
 
343
  if (reg != NULL)
344
    return reg->value.reg_val;
345
 
346
  return nullregister;
347
}
348
 
349
/* Get the index register 'reg_name'.  */
350
 
351
static reg
352
get_index_register (char *reg_name)
353
{
354
  const reg_entry *reg;
355
 
356
  reg = (const reg_entry *) hash_find (reg_hash, reg_name);
357
 
358
  if ((reg != NULL)
359
      && ((reg->value.reg_val == 12) || (reg->value.reg_val == 13)))
360
    return reg->value.reg_val;
361
 
362
  return nullregister;
363
}
364
/* Get the core processor index register-pair 'reg_name'.  */
365
 
366
static reg
367
get_index_register_pair (char *reg_name)
368
{
369
  const reg_entry *reg;
370
 
371
  reg = (const reg_entry *) hash_find (regp_hash, reg_name);
372
 
373
  if (reg != NULL)
374
    {
375
      if ((reg->value.reg_val != 1) || (reg->value.reg_val != 7)
376
          || (reg->value.reg_val != 9) || (reg->value.reg_val > 10))
377
        return reg->value.reg_val;
378
 
379
      as_bad (_("Unknown register pair - index relative mode: `%d'"), reg->value.reg_val);
380
    }
381
 
382
  return nullregister;
383
}
384
 
385
/* Get the processor register 'preg_name'.  */
386
 
387
static preg
388
get_pregister (char *preg_name)
389
{
390
  const reg_entry *preg;
391
 
392
  preg = (const reg_entry *) hash_find (preg_hash, preg_name);
393
 
394
  if (preg != NULL)
395
    return preg->value.preg_val;
396
 
397
  return nullpregister;
398
}
399
 
400
/* Get the processor register 'preg_name 32 bit'.  */
401
 
402
static preg
403
get_pregisterp (char *preg_name)
404
{
405
  const reg_entry *preg;
406
 
407
  preg = (const reg_entry *) hash_find (pregp_hash, preg_name);
408
 
409
  if (preg != NULL)
410
    return preg->value.preg_val;
411
 
412
  return nullpregister;
413
}
414
 
415
 
416
/* Round up a section size to the appropriate boundary.  */
417
 
418
valueT
419
md_section_align (segT seg, valueT val)
420
{
421
  /* Round .text section to a multiple of 2.  */
422
  if (seg == text_section)
423
    return (val + 1) & ~1;
424
  return val;
425
}
426
 
427
/* Parse an operand that is machine-specific (remove '*').  */
428
 
429
void
430
md_operand (expressionS * exp)
431
{
432
  char c = *input_line_pointer;
433
 
434
  switch (c)
435
    {
436
    case '*':
437
      input_line_pointer++;
438
      expression (exp);
439
      break;
440
    default:
441
      break;
442
    }
443
}
444
 
445
/* Reset global variables before parsing a new instruction.  */
446
 
447
static void
448
reset_vars (char *op)
449
{
450
  cur_arg_num = relocatable = 0;
451
  memset (& output_opcode, '\0', sizeof (output_opcode));
452
 
453
  /* Save a copy of the original OP (used in error messages).  */
454
  strncpy (ins_parse, op, sizeof ins_parse - 1);
455
  ins_parse [sizeof ins_parse - 1] = 0;
456
}
457
 
458
/* This macro decides whether a particular reloc is an entry in a
459
   switch table.  It is used when relaxing, because the linker needs
460
   to know about all such entries so that it can adjust them if
461
   necessary.  */
462
 
463
#define SWITCH_TABLE(fix)                                  \
464
  (   (fix)->fx_addsy != NULL                              \
465
   && (fix)->fx_subsy != NULL                              \
466
   && S_GET_SEGMENT ((fix)->fx_addsy) ==                   \
467
      S_GET_SEGMENT ((fix)->fx_subsy)                      \
468
   && S_GET_SEGMENT (fix->fx_addsy) != undefined_section   \
469
   && (   (fix)->fx_r_type == BFD_RELOC_CR16_NUM8          \
470
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16         \
471
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32         \
472
       || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a))
473
 
474
/* See whether we need to force a relocation into the output file.
475
   This is used to force out switch and PC relative relocations when
476
   relaxing.  */
477
 
478
int
479
cr16_force_relocation (fixS *fix)
480
{
481
  if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
482
    return 1;
483
 
484
  return 0;
485
}
486
 
487
/* Record a fixup for a cons expression.  */
488
 
489
void
490
cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp)
491
{
492
  int rtype;
493
  switch (len)
494
    {
495
    default: rtype = BFD_RELOC_NONE; break;
496
    case 1: rtype = BFD_RELOC_CR16_NUM8 ; break;
497
    case 2: rtype = BFD_RELOC_CR16_NUM16; break;
498
    case 4:
499
      if (code_label)
500
        {
501
          rtype = BFD_RELOC_CR16_NUM32a;
502
          code_label = 0;
503
        }
504
      else
505
        rtype = BFD_RELOC_CR16_NUM32;
506
      break;
507
    }
508
 
509
  fix_new_exp (frag, offset, len, exp, 0, rtype);
510
}
511
 
512
/* Generate a relocation entry for a fixup.  */
513
 
514
arelent *
515
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
516
{
517
  arelent * reloc;
518
 
519
  reloc = xmalloc (sizeof (arelent));
520
  reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
521
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
522
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
523
  reloc->addend = fixP->fx_offset;
524
 
525
  if (fixP->fx_subsy != NULL)
526
    {
527
      if (SWITCH_TABLE (fixP))
528
        {
529
          /* Keep the current difference in the addend.  */
530
          reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
531
                           - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
532
 
533
          switch (fixP->fx_r_type)
534
            {
535
            case BFD_RELOC_CR16_NUM8:
536
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
537
              break;
538
            case BFD_RELOC_CR16_NUM16:
539
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
540
              break;
541
            case BFD_RELOC_CR16_NUM32:
542
              fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
543
              break;
544
            case BFD_RELOC_CR16_NUM32a:
545
              fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
546
              break;
547
            default:
548
              abort ();
549
              break;
550
            }
551
        }
552
      else
553
        {
554
          /* We only resolve difference expressions in the same section.  */
555
          as_bad_where (fixP->fx_file, fixP->fx_line,
556
                        _("can't resolve `%s' {%s section} - `%s' {%s section}"),
557
                        fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
558
                        segment_name (fixP->fx_addsy
559
                                      ? S_GET_SEGMENT (fixP->fx_addsy)
560
                                      : absolute_section),
561
                        S_GET_NAME (fixP->fx_subsy),
562
                        segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
563
        }
564
    }
565
 
566
  assert ((int) fixP->fx_r_type > 0);
567
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
568
 
569
  if (reloc->howto == NULL)
570
    {
571
      as_bad_where (fixP->fx_file, fixP->fx_line,
572
                    _("internal error: reloc %d (`%s') not supported by object file format"),
573
                    fixP->fx_r_type,
574
                    bfd_get_reloc_code_name (fixP->fx_r_type));
575
      return NULL;
576
    }
577
  assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
578
 
579
  return reloc;
580
}
581
 
582
/* Prepare machine-dependent frags for relaxation.  */
583
 
584
int
585
md_estimate_size_before_relax (fragS *fragp, asection *seg)
586
{
587
  /* If symbol is undefined or located in a different section,
588
     select the largest supported relocation.  */
589
  relax_substateT subtype;
590
  relax_substateT rlx_state[] = {0, 2};
591
 
592
  for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
593
    {
594
      if (fragp->fr_subtype == rlx_state[subtype]
595
          && (!S_IS_DEFINED (fragp->fr_symbol)
596
              || seg != S_GET_SEGMENT (fragp->fr_symbol)))
597
        {
598
          fragp->fr_subtype = rlx_state[subtype + 1];
599
          break;
600
        }
601
    }
602
 
603
  if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
604
    abort ();
605
 
606
  return md_relax_table[fragp->fr_subtype].rlx_length;
607
}
608
 
609
void
610
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
611
{
612
  /* 'opcode' points to the start of the instruction, whether
613
     we need to change the instruction's fixed encoding.  */
614
  char *opcode = fragP->fr_literal + fragP->fr_fix;
615
  bfd_reloc_code_real_type reloc;
616
 
617
  subseg_change (sec, 0);
618
 
619
  switch (fragP->fr_subtype)
620
    {
621
    case 0:
622
      reloc = BFD_RELOC_CR16_DISP8;
623
      break;
624
    case 1:
625
      /* If the subtype is not changed due to :m operand qualifier,
626
         then no need to update the opcode value.  */
627
      if ((int)opcode[1] != 0x18)
628
        {
629
          opcode[0] = (opcode[0] & 0xf0);
630
          opcode[1] = 0x18;
631
        }
632
      reloc = BFD_RELOC_CR16_DISP16;
633
      break;
634
    case 2:
635
      /* If the subtype is not changed due to :l operand qualifier,
636
         then no need to update the opcode value.  */
637
      if ((int)opcode[1] != 0)
638
        {
639
          opcode[2] = opcode[0];
640
          opcode[0] = opcode[1];
641
          opcode[1] = 0x0;
642
        }
643
      reloc = BFD_RELOC_CR16_DISP24;
644
      break;
645
    default:
646
      abort();
647
    }
648
 
649
  fix_new (fragP, fragP->fr_fix,
650
           bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
651
           fragP->fr_symbol, fragP->fr_offset, 1, reloc);
652
  fragP->fr_var = 0;
653
  fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
654
}
655
 
656
/* Process machine-dependent command line options.  Called once for
657
   each option on the command line that the machine-independent part of
658
   GAS does not understand.  */
659
 
660
int
661
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
662
{
663
  return 0;
664
}
665
 
666
/* Machine-dependent usage-output.  */
667
 
668
void
669
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
670
{
671
  return;
672
}
673
 
674
char *
675
md_atof (int type, char *litP, int *sizeP)
676
{
677
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
678
}
679
 
680
/* Apply a fixS (fixup of an instruction or data that we didn't have
681
   enough info to complete immediately) to the data in a frag.
682
   Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
683
   relaxation of debug sections, this function is called only when
684
   fixuping relocations of debug sections.  */
685
 
686
void
687
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
688
{
689
  valueT val = * valP;
690
  char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
691
  fixP->fx_offset = 0;
692
 
693
  switch (fixP->fx_r_type)
694
    {
695
      case BFD_RELOC_CR16_NUM8:
696
        bfd_put_8 (stdoutput, (unsigned char) val, buf);
697
        break;
698
      case BFD_RELOC_CR16_NUM16:
699
        bfd_put_16 (stdoutput, val, buf);
700
        break;
701
      case BFD_RELOC_CR16_NUM32:
702
        bfd_put_32 (stdoutput, val, buf);
703
        break;
704
      case BFD_RELOC_CR16_NUM32a:
705
        bfd_put_32 (stdoutput, val, buf);
706
        break;
707
      default:
708
        /* We shouldn't ever get here because linkrelax is nonzero.  */
709
        abort ();
710
        break;
711
    }
712
 
713
  fixP->fx_done = 0;
714
 
715
  if (fixP->fx_addsy == NULL
716
      && fixP->fx_pcrel == 0)
717
    fixP->fx_done = 1;
718
 
719
  if (fixP->fx_pcrel == 1
720
      && fixP->fx_addsy != NULL
721
      && S_GET_SEGMENT (fixP->fx_addsy) == seg)
722
    fixP->fx_done = 1;
723
}
724
 
725
/* The location from which a PC relative jump should be calculated,
726
   given a PC relative reloc.  */
727
 
728
long
729
md_pcrel_from (fixS *fixp)
730
{
731
  return fixp->fx_frag->fr_address + fixp->fx_where;
732
}
733
 
734
static void
735
initialise_reg_hash_table (struct hash_control ** hash_table,
736
                           const reg_entry * register_table,
737
                           const unsigned int num_entries)
738
{
739
  const reg_entry * reg;
740
  const char *hashret;
741
 
742
  if ((* hash_table = hash_new ()) == NULL)
743
    as_fatal (_("Virtual memory exhausted"));
744
 
745
  for (reg = register_table;
746
       reg < (register_table + num_entries);
747
       reg++)
748
    {
749
      hashret = hash_insert (* hash_table, reg->name, (char *) reg);
750
      if (hashret)
751
        as_fatal (_("Internal Error:  Can't hash %s: %s"),
752
                  reg->name, hashret);
753
    }
754
}
755
 
756
/* This function is called once, at assembler startup time.  This should
757
   set up all the tables, etc that the MD part of the assembler needs.  */
758
 
759
void
760
md_begin (void)
761
{
762
  int i = 0;
763
 
764
  /* Set up a hash table for the instructions.  */
765
  if ((cr16_inst_hash = hash_new ()) == NULL)
766
    as_fatal (_("Virtual memory exhausted"));
767
 
768
  while (cr16_instruction[i].mnemonic != NULL)
769
    {
770
      const char *hashret;
771
      const char *mnemonic = cr16_instruction[i].mnemonic;
772
 
773
      hashret = hash_insert (cr16_inst_hash, mnemonic,
774
                             (char *)(cr16_instruction + i));
775
 
776
      if (hashret != NULL && *hashret != '\0')
777
        as_fatal (_("Can't hash `%s': %s\n"), cr16_instruction[i].mnemonic,
778
                  *hashret == 0 ? _("(unknown reason)") : hashret);
779
 
780
      /* Insert unique names into hash table.  The CR16 instruction set
781
         has many identical opcode names that have different opcodes based
782
         on the operands.  This hash table then provides a quick index to
783
         the first opcode with a particular name in the opcode table.  */
784
      do
785
        {
786
          ++i;
787
        }
788
      while (cr16_instruction[i].mnemonic != NULL
789
             && streq (cr16_instruction[i].mnemonic, mnemonic));
790
    }
791
 
792
  /* Initialize reg_hash hash table.  */
793
  initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS);
794
  /* Initialize regp_hash hash table.  */
795
  initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS);
796
  /* Initialize preg_hash hash table.  */
797
  initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS);
798
  /* Initialize pregp_hash hash table.  */
799
  initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS);
800
 
801
  /*  Set linkrelax here to avoid fixups in most sections.  */
802
  linkrelax = 1;
803
}
804
 
805
/* Process constants (immediate/absolute)
806
   and labels (jump targets/Memory locations).  */
807
 
808
static void
809
process_label_constant (char *str, ins * cr16_ins)
810
{
811
  char *saved_input_line_pointer;
812
  int symbol_with_at = 0;
813
  int symbol_with_s = 0;
814
  int symbol_with_m = 0;
815
  int symbol_with_l = 0;
816
  argument *cur_arg = cr16_ins->arg + cur_arg_num;  /* Current argument.  */
817
 
818
  saved_input_line_pointer = input_line_pointer;
819
  input_line_pointer = str;
820
 
821
  expression (&cr16_ins->exp);
822
 
823
  switch (cr16_ins->exp.X_op)
824
    {
825
    case O_big:
826
    case O_absent:
827
      /* Missing or bad expr becomes absolute 0.  */
828
      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
829
              str);
830
      cr16_ins->exp.X_op = O_constant;
831
      cr16_ins->exp.X_add_number = 0;
832
      cr16_ins->exp.X_add_symbol = NULL;
833
      cr16_ins->exp.X_op_symbol = NULL;
834
      /* Fall through.  */
835
 
836
    case O_constant:
837
      cur_arg->X_op = O_constant;
838
      cur_arg->constant = cr16_ins->exp.X_add_number;
839
      break;
840
 
841
    case O_symbol:
842
    case O_subtract:
843
    case O_add:
844
      cur_arg->X_op = O_symbol;
845
      cr16_ins->rtype = BFD_RELOC_NONE;
846
      relocatable = 1;
847
 
848
      if (strneq (input_line_pointer, "@c", 2))
849
        symbol_with_at = 1;
850
 
851
      if (strneq (input_line_pointer, "@l", 2)
852
          || strneq (input_line_pointer, ":l", 2))
853
        symbol_with_l = 1;
854
 
855
      if (strneq (input_line_pointer, "@m", 2)
856
          || strneq (input_line_pointer, ":m", 2))
857
        symbol_with_m = 1;
858
 
859
      if (strneq (input_line_pointer, "@s", 2)
860
          || strneq (input_line_pointer, ":s", 2))
861
        symbol_with_s = 1;
862
 
863
      switch (cur_arg->type)
864
        {
865
        case arg_cr:
866
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
867
            {
868
              if (cur_arg->size == 20)
869
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
870
              else
871
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
872
            }
873
          break;
874
 
875
        case arg_crp:
876
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
877
            switch (instruction->size)
878
              {
879
              case 1:
880
                switch (cur_arg->size)
881
                  {
882
                  case 0:
883
                    cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
884
                    break;
885
                  case 4:
886
                    if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
887
                      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
888
                    else
889
                      cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
890
                    break;
891
                  default: break;
892
                  }
893
                break;
894
              case 2:
895
                cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
896
                break;
897
              case 3:
898
                if (cur_arg->size == 20)
899
                  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
900
                else
901
                  cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
902
                break;
903
              default:
904
                break;
905
              }
906
          break;
907
 
908
        case arg_idxr:
909
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
910
            cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
911
          break;
912
 
913
        case arg_idxrp:
914
          if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
915
            switch (instruction->size)
916
              {
917
              case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break;
918
              case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break;
919
              case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break;
920
              default: break;
921
              }
922
          break;
923
 
924
        case arg_c:
925
          if (IS_INSN_MNEMONIC ("bal"))
926
            cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
927
          else if (IS_INSN_TYPE (BRANCH_INS))
928
            {
929
              if (symbol_with_l)
930
                cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
931
              else if (symbol_with_m)
932
                cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
933
              else
934
                cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
935
            }
936
          else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
937
                   || IS_INSN_TYPE (CSTBIT_INS))
938
            {
939
              if (symbol_with_s)
940
                as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
941
              if (symbol_with_m)
942
                cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
943
              else /* Default to (symbol_with_l) */
944
                cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
945
            }
946
          else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
947
            cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
948
          break;
949
 
950
        case arg_ic:
951
          if (IS_INSN_TYPE (ARITH_INS))
952
            {
953
              if (symbol_with_s)
954
                cr16_ins->rtype = BFD_RELOC_CR16_IMM4;
955
              else if (symbol_with_m)
956
                cr16_ins->rtype = BFD_RELOC_CR16_IMM20;
957
              else if (symbol_with_at)
958
                cr16_ins->rtype = BFD_RELOC_CR16_IMM32a;
959
              else /* Default to (symbol_with_l) */
960
                cr16_ins->rtype = BFD_RELOC_CR16_IMM32;
961
            }
962
          else if (IS_INSN_TYPE (ARITH_BYTE_INS))
963
            {
964
              cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
965
            }
966
          break;
967
        default:
968
          break;
969
        }
970
      break;
971
 
972
    default:
973
      cur_arg->X_op = cr16_ins->exp.X_op;
974
      break;
975
    }
976
 
977
  input_line_pointer = saved_input_line_pointer;
978
  return;
979
}
980
 
981
/* Retrieve the opcode image of a given register.
982
   If the register is illegal for the current instruction,
983
   issue an error.  */
984
 
985
static int
986
getreg_image (reg r)
987
{
988
  const reg_entry *reg;
989
  char *reg_name;
990
  int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
991
 
992
  /* Check whether the register is in registers table.  */
993
  if (r < MAX_REG)
994
    reg = cr16_regtab + r;
995
  else /* Register not found.  */
996
    {
997
      as_bad (_("Unknown register: `%d'"), r);
998
      return 0;
999
    }
1000
 
1001
  reg_name = reg->name;
1002
 
1003
/* Issue a error message when register is illegal.  */
1004
#define IMAGE_ERR \
1005
  as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1006
            reg_name, ins_parse);                            \
1007
  break;
1008
 
1009
  switch (reg->type)
1010
    {
1011
    case CR16_R_REGTYPE:
1012
      if (! is_procreg)
1013
        return reg->image;
1014
      else
1015
        IMAGE_ERR;
1016
 
1017
    case CR16_P_REGTYPE:
1018
      return reg->image;
1019
      break;
1020
 
1021
    default:
1022
      IMAGE_ERR;
1023
    }
1024
 
1025
  return 0;
1026
}
1027
 
1028
/* Parsing different types of operands
1029
   -> constants             Immediate/Absolute/Relative numbers
1030
   -> Labels                Relocatable symbols
1031
   -> (reg pair base)       Register pair base
1032
   -> (rbase)               Register base
1033
   -> disp(rbase)           Register relative
1034
   -> [rinx]disp(reg pair)  Register index with reg pair mode
1035
   -> disp(rbase,ridx,scl)  Register index mode.  */
1036
 
1037
static void
1038
set_operand (char *operand, ins * cr16_ins)
1039
{
1040
  char *operandS; /* Pointer to start of sub-opearand.  */
1041
  char *operandE; /* Pointer to end of sub-opearand.  */
1042
 
1043
  argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument.  */
1044
 
1045
  /* Initialize pointers.  */
1046
  operandS = operandE = operand;
1047
 
1048
  switch (cur_arg->type)
1049
    {
1050
    case arg_ic:    /* Case $0x18.  */
1051
      operandS++;
1052
    case arg_c:     /* Case 0x18.  */
1053
      /* Set constant.  */
1054
      process_label_constant (operandS, cr16_ins);
1055
 
1056
      if (cur_arg->type != arg_ic)
1057
        cur_arg->type = arg_c;
1058
      break;
1059
 
1060
    case arg_icr:   /* Case $0x18(r1).  */
1061
      operandS++;
1062
    case arg_cr:    /* Case 0x18(r1).   */
1063
      /* Set displacement constant.  */
1064
      while (*operandE != '(')
1065
        operandE++;
1066
      *operandE = '\0';
1067
      process_label_constant (operandS, cr16_ins);
1068
      operandS = operandE;
1069
    case arg_rbase: /* Case (r1) or (r1,r0).  */
1070
      operandS++;
1071
      /* Set register base.  */
1072
      while (*operandE != ')')
1073
        operandE++;
1074
      *operandE = '\0';
1075
      if ((cur_arg->r = get_register (operandS)) == nullregister)
1076
         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1077
              operandS, ins_parse);
1078
 
1079
      /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1080
      if ((cur_arg->type != arg_rbase)
1081
          && ((getreg_image (cur_arg->r) == 12)
1082
              || (getreg_image (cur_arg->r) == 13)
1083
              || (getreg_image (cur_arg->r) == 14)
1084
              || (getreg_image (cur_arg->r) == 15)))
1085
         {
1086
           cur_arg->type = arg_crp;
1087
           cur_arg->rp = cur_arg->r;
1088
         }
1089
      break;
1090
 
1091
    case arg_crp:    /* Case 0x18(r1,r0).   */
1092
      /* Set displacement constant.  */
1093
      while (*operandE != '(')
1094
        operandE++;
1095
      *operandE = '\0';
1096
      process_label_constant (operandS, cr16_ins);
1097
      operandS = operandE;
1098
      operandS++;
1099
      /* Set register pair base.  */
1100
      while (*operandE != ')')
1101
        operandE++;
1102
      *operandE = '\0';
1103
      if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
1104
         as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1105
              operandS, ins_parse);
1106
      break;
1107
 
1108
    case arg_idxr:
1109
      /* Set register pair base.  */
1110
      if ((strchr (operandS,'(') != NULL))
1111
        {
1112
         while ((*operandE != '(') && (! ISSPACE (*operandE)))
1113
           operandE++;
1114
         if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister)
1115
              as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1116
                            operandS, ins_parse);
1117
         *operandE++ = '\0';
1118
         cur_arg->type = arg_idxrp;
1119
        }
1120
      else
1121
        cur_arg->rp = -1;
1122
 
1123
       operandE = operandS;
1124
      /* Set displacement constant.  */
1125
      while (*operandE != ']')
1126
        operandE++;
1127
      process_label_constant (++operandE, cr16_ins);
1128
      *operandE++ = '\0';
1129
      operandE = operandS;
1130
 
1131
      /* Set index register .  */
1132
      operandS = strchr (operandE,'[');
1133
      if (operandS != NULL)
1134
        { /* Eliminate '[', detach from rest of operand.  */
1135
          *operandS++ = '\0';
1136
 
1137
          operandE = strchr (operandS, ']');
1138
 
1139
          if (operandE == NULL)
1140
            as_bad (_("unmatched '['"));
1141
          else
1142
            { /* Eliminate ']' and make sure it was the last thing
1143
                 in the string.  */
1144
              *operandE = '\0';
1145
              if (*(operandE + 1) != '\0')
1146
                as_bad (_("garbage after index spec ignored"));
1147
            }
1148
        }
1149
 
1150
      if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
1151
        as_bad (_("Illegal register `%s' in Instruction `%s'"),
1152
                operandS, ins_parse);
1153
      *operandE = '\0';
1154
      *operandS = '\0';
1155
      break;
1156
 
1157
    default:
1158
      break;
1159
    }
1160
}
1161
 
1162
/* Parse a single operand.
1163
   operand - Current operand to parse.
1164
   cr16_ins - Current assembled instruction.  */
1165
 
1166
static void
1167
parse_operand (char *operand, ins * cr16_ins)
1168
{
1169
  int ret_val;
1170
  argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument.  */
1171
 
1172
  /* Initialize the type to NULL before parsing.  */
1173
  cur_arg->type = nullargs;
1174
 
1175
  /* Check whether this is a condition code .  */
1176
  if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
1177
    {
1178
      cur_arg->type = arg_cc;
1179
      cur_arg->cc = ret_val;
1180
      cur_arg->X_op = O_register;
1181
      return;
1182
    }
1183
 
1184
  /* Check whether this is a general processor register.  */
1185
  if ((ret_val = get_register (operand)) != nullregister)
1186
    {
1187
      cur_arg->type = arg_r;
1188
      cur_arg->r = ret_val;
1189
      cur_arg->X_op = 0;
1190
      return;
1191
    }
1192
 
1193
  /* Check whether this is a general processor register pair.  */
1194
  if ((operand[0] == '(')
1195
      && ((ret_val = get_register_pair (operand)) != nullregister))
1196
    {
1197
      cur_arg->type = arg_rp;
1198
      cur_arg->rp = ret_val;
1199
      cur_arg->X_op = O_register;
1200
      return;
1201
    }
1202
 
1203
  /* Check whether the operand is a processor register.
1204
     For "lprd" and "sprd" instruction, only 32 bit
1205
     processor registers used.  */
1206
  if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
1207
      && ((ret_val = get_pregister (operand)) != nullpregister))
1208
    {
1209
      cur_arg->type = arg_pr;
1210
      cur_arg->pr = ret_val;
1211
      cur_arg->X_op = O_register;
1212
      return;
1213
    }
1214
 
1215
  /* Check whether this is a processor register - 32 bit.  */
1216
  if ((ret_val = get_pregisterp (operand)) != nullpregister)
1217
    {
1218
      cur_arg->type = arg_prp;
1219
      cur_arg->prp = ret_val;
1220
      cur_arg->X_op = O_register;
1221
      return;
1222
    }
1223
 
1224
  /* Deal with special characters.  */
1225
  switch (operand[0])
1226
    {
1227
    case '$':
1228
      if (strchr (operand, '(') != NULL)
1229
        cur_arg->type = arg_icr;
1230
      else
1231
        cur_arg->type = arg_ic;
1232
      goto set_params;
1233
      break;
1234
 
1235
    case '(':
1236
      cur_arg->type = arg_rbase;
1237
      goto set_params;
1238
      break;
1239
 
1240
    case '[':
1241
      cur_arg->type = arg_idxr;
1242
      goto set_params;
1243
      break;
1244
 
1245
    default:
1246
      break;
1247
    }
1248
 
1249
  if (strchr (operand, '(') != NULL)
1250
    {
1251
      if (strchr (operand, ',') != NULL
1252
          && (strchr (operand, ',') > strchr (operand, '(')))
1253
        cur_arg->type = arg_crp;
1254
      else
1255
        cur_arg->type = arg_cr;
1256
    }
1257
  else
1258
    cur_arg->type = arg_c;
1259
 
1260
/* Parse an operand according to its type.  */
1261
 set_params:
1262
  cur_arg->constant = 0;
1263
  set_operand (operand, cr16_ins);
1264
}
1265
 
1266
/* Parse the various operands. Each operand is then analyzed to fillup
1267
   the fields in the cr16_ins data structure.  */
1268
 
1269
static void
1270
parse_operands (ins * cr16_ins, char *operands)
1271
{
1272
  char *operandS;            /* Operands string.  */
1273
  char *operandH, *operandT; /* Single operand head/tail pointers.  */
1274
  int allocated = 0;         /* Indicates a new operands string was allocated.*/
1275
  char *operand[MAX_OPERANDS];/* Separating the operands.  */
1276
  int op_num = 0;             /* Current operand number we are parsing.  */
1277
  int bracket_flag = 0;       /* Indicates a bracket '(' was found.  */
1278
  int sq_bracket_flag = 0;    /* Indicates a square bracket '[' was found.  */
1279
 
1280
  /* Preprocess the list of registers, if necessary.  */
1281
  operandS = operandH = operandT = operands;
1282
 
1283
  while (*operandT != '\0')
1284
    {
1285
      if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1286
        {
1287
          *operandT++ = '\0';
1288
          operand[op_num++] = strdup (operandH);
1289
          operandH = operandT;
1290
          continue;
1291
        }
1292
 
1293
      if (*operandT == ' ')
1294
        as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1295
 
1296
      if (*operandT == '(')
1297
        bracket_flag = 1;
1298
      else if (*operandT == '[')
1299
        sq_bracket_flag = 1;
1300
 
1301
      if (*operandT == ')')
1302
        {
1303
          if (bracket_flag)
1304
            bracket_flag = 0;
1305
          else
1306
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1307
        }
1308
      else if (*operandT == ']')
1309
        {
1310
          if (sq_bracket_flag)
1311
            sq_bracket_flag = 0;
1312
          else
1313
            as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1314
        }
1315
 
1316
      if (bracket_flag == 1 && *operandT == ')')
1317
        bracket_flag = 0;
1318
      else if (sq_bracket_flag == 1 && *operandT == ']')
1319
        sq_bracket_flag = 0;
1320
 
1321
      operandT++;
1322
    }
1323
 
1324
  /* Adding the last operand.  */
1325
  operand[op_num++] = strdup (operandH);
1326
  cr16_ins->nargs = op_num;
1327
 
1328
  /* Verifying correct syntax of operands (all brackets should be closed).  */
1329
  if (bracket_flag || sq_bracket_flag)
1330
    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1331
 
1332
  /* Now we parse each operand separately.  */
1333
  for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
1334
    {
1335
      cur_arg_num = op_num;
1336
      parse_operand (operand[op_num], cr16_ins);
1337
      free (operand[op_num]);
1338
    }
1339
 
1340
  if (allocated)
1341
    free (operandS);
1342
}
1343
 
1344
/* Get the trap index in dispatch table, given its name.
1345
   This routine is used by assembling the 'excp' instruction.  */
1346
 
1347
static int
1348
gettrap (char *s)
1349
{
1350
  const trap_entry *trap;
1351
 
1352
  for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1353
    if (strcasecmp (trap->name, s) == 0)
1354
      return trap->entry;
1355
 
1356
  /* To make compatable with CR16 4.1 tools, the below 3-lines of
1357
   * code added. Refer: Development Tracker item #123 */
1358
  for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1359
    if (trap->entry  == (unsigned int) atoi (s))
1360
      return trap->entry;
1361
 
1362
  as_bad (_("Unknown exception: `%s'"), s);
1363
  return 0;
1364
}
1365
 
1366
/* Top level module where instruction parsing starts.
1367
   cr16_ins - data structure holds some information.
1368
   operands - holds the operands part of the whole instruction.  */
1369
 
1370
static void
1371
parse_insn (ins *insn, char *operands)
1372
{
1373
  int i;
1374
 
1375
  /* Handle instructions with no operands.  */
1376
  for (i = 0; cr16_no_op_insn[i] != NULL; i++)
1377
  {
1378
    if (streq (cr16_no_op_insn[i], instruction->mnemonic))
1379
    {
1380
      insn->nargs = 0;
1381
      return;
1382
    }
1383
  }
1384
 
1385
  /* Handle 'excp' instructions.  */
1386
  if (IS_INSN_MNEMONIC ("excp"))
1387
    {
1388
      insn->nargs = 1;
1389
      insn->arg[0].type = arg_ic;
1390
      insn->arg[0].constant = gettrap (operands);
1391
      insn->arg[0].X_op = O_constant;
1392
      return;
1393
    }
1394
 
1395
  if (operands != NULL)
1396
    parse_operands (insn, operands);
1397
}
1398
 
1399
/* bCC instruction requires special handling.  */
1400
static char *
1401
get_b_cc (char * op)
1402
{
1403
  unsigned int i;
1404
  char op1[5];
1405
 
1406
  for (i = 1; i < strlen (op); i++)
1407
     op1[i-1] = op[i];
1408
 
1409
  op1[i-1] = '\0';
1410
 
1411
  for (i = 0; i < cr16_num_cc ; i++)
1412
    if (streq (op1, cr16_b_cond_tab[i]))
1413
      return (char *) cr16_b_cond_tab[i];
1414
 
1415
   return NULL;
1416
}
1417
 
1418
/* bCC instruction requires special handling.  */
1419
static int
1420
is_bcc_insn (char * op)
1421
{
1422
  if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
1423
        || streq (op, "beq0w") || streq (op, "bnq0w")))
1424
    if ((op[0] == 'b') && (get_b_cc (op) != NULL))
1425
      return 1;
1426
  return 0;
1427
}
1428
 
1429
/* Cinv instruction requires special handling.  */
1430
 
1431
static int
1432
check_cinv_options (char * operand)
1433
{
1434
  char *p = operand;
1435
  int i_used = 0, u_used = 0, d_used = 0;
1436
 
1437
  while (*++p != ']')
1438
    {
1439
      if (*p == ',' || *p == ' ')
1440
        continue;
1441
 
1442
      else if (*p == 'i')
1443
        i_used = 1;
1444
      else if (*p == 'u')
1445
        u_used = 1;
1446
      else if (*p == 'd')
1447
        d_used = 1;
1448
      else
1449
        as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1450
    }
1451
 
1452
  return 0;
1453
}
1454
 
1455
/* Retrieve the opcode image of a given register pair.
1456
   If the register is illegal for the current instruction,
1457
   issue an error.  */
1458
 
1459
static int
1460
getregp_image (reg r)
1461
{
1462
  const reg_entry *reg;
1463
  char *reg_name;
1464
 
1465
  /* Check whether the register is in registers table.  */
1466
  if (r < MAX_REG)
1467
    reg = cr16_regptab + r;
1468
  /* Register not found.  */
1469
  else
1470
    {
1471
      as_bad (_("Unknown register pair: `%d'"), r);
1472
      return 0;
1473
    }
1474
 
1475
  reg_name = reg->name;
1476
 
1477
/* Issue a error message when register  pair is illegal.  */
1478
#define RPAIR_IMAGE_ERR \
1479
  as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1480
            reg_name, ins_parse);                                 \
1481
  break;
1482
 
1483
  switch (reg->type)
1484
    {
1485
    case CR16_RP_REGTYPE:
1486
      return reg->image;
1487
    default:
1488
      RPAIR_IMAGE_ERR;
1489
    }
1490
 
1491
  return 0;
1492
}
1493
 
1494
/* Retrieve the opcode image of a given index register pair.
1495
   If the register is illegal for the current instruction,
1496
   issue an error.  */
1497
 
1498
static int
1499
getidxregp_image (reg r)
1500
{
1501
  const reg_entry *reg;
1502
  char *reg_name;
1503
 
1504
  /* Check whether the register is in registers table.  */
1505
  if (r < MAX_REG)
1506
    reg = cr16_regptab + r;
1507
  /* Register not found.  */
1508
  else
1509
    {
1510
      as_bad (_("Unknown register pair: `%d'"), r);
1511
      return 0;
1512
    }
1513
 
1514
  reg_name = reg->name;
1515
 
1516
/* Issue a error message when register  pair is illegal.  */
1517
#define IDX_RPAIR_IMAGE_ERR \
1518
  as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1519
            reg_name, ins_parse);                                       \
1520
 
1521
  if (reg->type == CR16_RP_REGTYPE)
1522
    {
1523
      switch (reg->image)
1524
        {
1525
        case 0:  return 0; break;
1526
        case 2:  return 1; break;
1527
        case 4:  return 2; break;
1528
        case 6:  return 3; break;
1529
        case 8:  return 4; break;
1530
        case 10: return 5; break;
1531
        case 3:  return 6; break;
1532
        case 5:  return 7; break;
1533
        default:
1534
          break;
1535
        }
1536
    }
1537
 
1538
  IDX_RPAIR_IMAGE_ERR;
1539
  return 0;
1540
}
1541
 
1542
/* Retrieve the opcode image of a given processort register.
1543
   If the register is illegal for the current instruction,
1544
   issue an error.  */
1545
static int
1546
getprocreg_image (reg r)
1547
{
1548
  const reg_entry *reg;
1549
  char *reg_name;
1550
 
1551
  /* Check whether the register is in registers table.  */
1552
  if (r < MAX_PREG)
1553
    reg = &cr16_pregtab[r - MAX_REG];
1554
  /* Register not found.  */
1555
  else
1556
    {
1557
      as_bad (_("Unknown processor register : `%d'"), r);
1558
      return 0;
1559
    }
1560
 
1561
  reg_name = reg->name;
1562
 
1563
/* Issue a error message when register  pair is illegal.  */
1564
#define PROCREG_IMAGE_ERR \
1565
  as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1566
            reg_name, ins_parse);                                      \
1567
  break;
1568
 
1569
  switch (reg->type)
1570
    {
1571
    case CR16_P_REGTYPE:
1572
      return reg->image;
1573
    default:
1574
      PROCREG_IMAGE_ERR;
1575
    }
1576
 
1577
  return 0;
1578
}
1579
 
1580
/* Retrieve the opcode image of a given processort register.
1581
   If the register is illegal for the current instruction,
1582
   issue an error.  */
1583
static int
1584
getprocregp_image (reg r)
1585
{
1586
  const reg_entry *reg;
1587
  char *reg_name;
1588
  int pregptab_disp = 0;
1589
 
1590
  /* Check whether the register is in registers table.  */
1591
  if (r < MAX_PREG)
1592
    {
1593
      r = r - MAX_REG;
1594
      switch (r)
1595
        {
1596
        case 4: pregptab_disp = 1;  break;
1597
        case 6: pregptab_disp = 2;  break;
1598
        case 8:
1599
        case 9:
1600
        case 10:
1601
          pregptab_disp = 3;  break;
1602
        case 12:
1603
          pregptab_disp = 4;  break;
1604
        case 14:
1605
          pregptab_disp = 5;  break;
1606
        default: break;
1607
        }
1608
      reg = &cr16_pregptab[r - pregptab_disp];
1609
    }
1610
  /* Register not found.  */
1611
  else
1612
    {
1613
      as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
1614
      return 0;
1615
    }
1616
 
1617
  reg_name = reg->name;
1618
 
1619
/* Issue a error message when register  pair is illegal.  */
1620
#define PROCREGP_IMAGE_ERR \
1621
  as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"),\
1622
            reg_name, ins_parse);                                              \
1623
  break;
1624
 
1625
  switch (reg->type)
1626
    {
1627
    case CR16_P_REGTYPE:
1628
      return reg->image;
1629
    default:
1630
      PROCREGP_IMAGE_ERR;
1631
    }
1632
 
1633
  return 0;
1634
}
1635
 
1636
/* Routine used to represent integer X using NBITS bits.  */
1637
 
1638
static long
1639
getconstant (long x, int nbits)
1640
{
1641
  /* The following expression avoids overflow if
1642
     'nbits' is the number of bits in 'bfd_vma'.  */
1643
  return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1644
}
1645
 
1646
/* Print a constant value to 'output_opcode':
1647
   ARG holds the operand's type and value.
1648
   SHIFT represents the location of the operand to be print into.
1649
   NBITS determines the size (in bits) of the constant.  */
1650
 
1651
static void
1652
print_constant (int nbits, int shift, argument *arg)
1653
{
1654
  unsigned long mask = 0;
1655
 
1656
  long constant = getconstant (arg->constant, nbits);
1657
 
1658
  switch (nbits)
1659
    {
1660
    case 32:
1661
    case 28:
1662
      /* mask the upper part of the constant, that is, the bits
1663
         going to the lowest byte of output_opcode[0].
1664
         The upper part of output_opcode[1] is always filled,
1665
         therefore it is always masked with 0xFFFF.  */
1666
      mask = (1 << (nbits - 16)) - 1;
1667
      /* Divide the constant between two consecutive words :
1668
 
1669
         +---------+---------+---------+---------+
1670
         |         | X X X X | x X x X |         |
1671
         +---------+---------+---------+---------+
1672
         output_opcode[0]    output_opcode[1]     */
1673
 
1674
      CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1675
      CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1676
      break;
1677
 
1678
    case 21:
1679
      if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS))) nbits = 20;
1680
    case 24:
1681
    case 22:
1682
    case 20:
1683
      /* mask the upper part of the constant, that is, the bits
1684
         going to the lowest byte of output_opcode[0].
1685
         The upper part of output_opcode[1] is always filled,
1686
         therefore it is always masked with 0xFFFF.  */
1687
      mask = (1 << (nbits - 16)) - 1;
1688
      /* Divide the constant between two consecutive words :
1689
 
1690
         +---------+---------+---------+---------+
1691
         |         | X X X X | - X - X |         |
1692
         +---------+---------+---------+---------+
1693
         output_opcode[0]    output_opcode[1]     */
1694
 
1695
      if ((instruction->size > 2) && (shift == WORD_SHIFT))
1696
        {
1697
          if (arg->type == arg_idxrp)
1698
            {
1699
              CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
1700
              CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1701
            }
1702
          else
1703
            {
1704
              CR16_PRINT (0, (((((constant >> WORD_SHIFT) & mask) << 8) & 0x0f00) | ((((constant >> WORD_SHIFT) & mask) >> 4) & 0xf)),0);
1705
              CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1706
            }
1707
        }
1708
      else
1709
        CR16_PRINT (0, constant, shift);
1710
      break;
1711
 
1712
    case 14:
1713
      if (arg->type == arg_idxrp)
1714
        {
1715
          if (instruction->size == 2)
1716
            {
1717
              CR16_PRINT (0, ((constant)      & 0xf), shift);        /* 0-3 bits.  */
1718
              CR16_PRINT (0, ((constant >> 4) & 0x3), (shift + 20)); /* 4-5 bits.  */
1719
              CR16_PRINT (0, ((constant >> 6) & 0x3), (shift + 14)); /* 6-7 bits.  */
1720
              CR16_PRINT (0, ((constant >> 8) & 0x3f), (shift + 8)); /* 8-13 bits.  */
1721
            }
1722
          else
1723
            CR16_PRINT (0, constant, shift);
1724
        }
1725
      break;
1726
 
1727
    case 16:
1728
    case 12:
1729
      /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1730
         always filling the upper part of output_opcode[1]. If we mistakenly
1731
         write it to output_opcode[0], the constant prefix (that is, 'match')
1732
         will be overriden.
1733
 
1734
         +---------+---------+---------+---------+
1735
         | 'match' |         | X X X X |         |
1736
         +---------+---------+---------+---------+
1737
         output_opcode[0]    output_opcode[1]     */
1738
 
1739
      if ((instruction->size > 2) && (shift == WORD_SHIFT))
1740
        CR16_PRINT (1, constant, WORD_SHIFT);
1741
      else
1742
        CR16_PRINT (0, constant, shift);
1743
      break;
1744
 
1745
    case 8:
1746
      CR16_PRINT (0, ((constant / 2) & 0xf), shift);
1747
      CR16_PRINT (0, ((constant / 2) >> 4), (shift + 8));
1748
      break;
1749
 
1750
    default:
1751
      CR16_PRINT (0, constant,  shift);
1752
      break;
1753
    }
1754
}
1755
 
1756
/* Print an operand to 'output_opcode', which later on will be
1757
   printed to the object file:
1758
   ARG holds the operand's type, size and value.
1759
   SHIFT represents the printing location of operand.
1760
   NBITS determines the size (in bits) of a constant operand.  */
1761
 
1762
static void
1763
print_operand (int nbits, int shift, argument *arg)
1764
{
1765
  switch (arg->type)
1766
    {
1767
    case arg_cc:
1768
      CR16_PRINT (0, arg->cc, shift);
1769
      break;
1770
 
1771
    case arg_r:
1772
      CR16_PRINT (0, getreg_image (arg->r), shift);
1773
      break;
1774
 
1775
    case arg_rp:
1776
      CR16_PRINT (0, getregp_image (arg->rp), shift);
1777
      break;
1778
 
1779
    case arg_pr:
1780
      CR16_PRINT (0, getprocreg_image (arg->pr), shift);
1781
      break;
1782
 
1783
    case arg_prp:
1784
      CR16_PRINT (0, getprocregp_image (arg->prp), shift);
1785
      break;
1786
 
1787
    case arg_idxrp:
1788
      /*    16      12      8    6      0
1789
            +-----------------------------+
1790
            | r_index | disp  | rp_base   |
1791
            +-----------------------------+          */
1792
 
1793
      if (instruction->size == 3)
1794
        {
1795
          CR16_PRINT (0, getidxregp_image (arg->rp), 0);
1796
          if (getreg_image (arg->i_r) == 12)
1797
            CR16_PRINT (0, 0, 3);
1798
          else
1799
            CR16_PRINT (0, 1, 3);
1800
        }
1801
      else
1802
        {
1803
          CR16_PRINT (0, getidxregp_image (arg->rp), 16);
1804
          if (getreg_image (arg->i_r) == 12)
1805
            CR16_PRINT (0, 0, 19);
1806
          else
1807
            CR16_PRINT (0, 1, 19);
1808
        }
1809
      print_constant (nbits, shift, arg);
1810
      break;
1811
 
1812
    case arg_idxr:
1813
      if (getreg_image (arg->i_r) == 12)
1814
        if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1815
            || IS_INSN_MNEMONIC ("tbitb"))
1816
          CR16_PRINT (0, 0, 23);
1817
        else CR16_PRINT (0, 0, 24);
1818
      else
1819
        if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1820
            || IS_INSN_MNEMONIC ("tbitb"))
1821
          CR16_PRINT (0, 1, 23);
1822
        else CR16_PRINT (0, 1, 24);
1823
 
1824
      print_constant (nbits, shift, arg);
1825
      break;
1826
 
1827
    case arg_ic:
1828
    case arg_c:
1829
      print_constant (nbits, shift, arg);
1830
      break;
1831
 
1832
    case arg_rbase:
1833
      CR16_PRINT (0, getreg_image (arg->r), shift);
1834
      break;
1835
 
1836
    case arg_cr:
1837
      print_constant (nbits, shift , arg);
1838
      /* Add the register argument to the output_opcode.  */
1839
      CR16_PRINT (0, getreg_image (arg->r), (shift+16));
1840
      break;
1841
 
1842
    case arg_crp:
1843
      print_constant (nbits, shift , arg);
1844
      if (instruction->size > 1)
1845
        CR16_PRINT (0, getregp_image (arg->rp), (shift + 16));
1846
      else if (IS_INSN_TYPE (LD_STOR_INS) || (IS_INSN_TYPE (CSTBIT_INS)))
1847
        {
1848
          if (instruction->size == 2)
1849
            CR16_PRINT (0, getregp_image (arg->rp), (shift - 8));
1850
          else if (instruction->size == 1)
1851
            CR16_PRINT (0, getregp_image (arg->rp), 16);
1852
        }
1853
      else
1854
        CR16_PRINT (0, getregp_image (arg->rp), shift);
1855
      break;
1856
 
1857
    default:
1858
      break;
1859
    }
1860
}
1861
 
1862
/* Retrieve the number of operands for the current assembled instruction.  */
1863
 
1864
static int
1865
get_number_of_operands (void)
1866
{
1867
  int i;
1868
 
1869
  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1870
    ;
1871
  return i;
1872
}
1873
 
1874
/* Verify that the number NUM can be represented in BITS bits (that is,
1875
   within its permitted range), based on the instruction's FLAGS.
1876
   If UPDATE is nonzero, update the value of NUM if necessary.
1877
   Return OP_LEGAL upon success, actual error type upon failure.  */
1878
 
1879
static op_err
1880
check_range (long *num, int bits, int unsigned flags, int update)
1881
{
1882
  long min, max;
1883
  int retval = OP_LEGAL;
1884
  long value = *num;
1885
 
1886
  if (bits == 0 && value > 0) return OP_OUT_OF_RANGE;
1887
 
1888
  /* For hosts witah longs bigger than 32-bits make sure that the top
1889
     bits of a 32-bit negative value read in by the parser are set,
1890
     so that the correct comparisons are made.  */
1891
  if (value & 0x80000000)
1892
    value |= (-1L << 31);
1893
 
1894
 
1895
  /* Verify operand value is even.  */
1896
  if (flags & OP_EVEN)
1897
    {
1898
      if (value % 2)
1899
        return OP_NOT_EVEN;
1900
    }
1901
 
1902
  if (flags & OP_DEC)
1903
    {
1904
      value -= 1;
1905
      if (update)
1906
        *num = value;
1907
    }
1908
 
1909
  if (flags & OP_SHIFT)
1910
    {
1911
      value >>= 1;
1912
      if (update)
1913
        *num = value;
1914
    }
1915
  else if (flags & OP_SHIFT_DEC)
1916
    {
1917
      value = (value >> 1) - 1;
1918
      if (update)
1919
        *num = value;
1920
    }
1921
 
1922
  if (flags & OP_ABS20)
1923
    {
1924
      if (value > 0xEFFFF)
1925
        return OP_OUT_OF_RANGE;
1926
    }
1927
 
1928
  if (flags & OP_ESC)
1929
    {
1930
      if (value == 0xB || value == 0x9)
1931
        return OP_OUT_OF_RANGE;
1932
      else if (value == -1)
1933
        {
1934
          if (update)
1935
            *num = 9;
1936
          return retval;
1937
        }
1938
    }
1939
 
1940
  if (flags & OP_ESC1)
1941
    {
1942
      if (value > 13)
1943
        return OP_OUT_OF_RANGE;
1944
    }
1945
 
1946
   if (flags & OP_SIGNED)
1947
     {
1948
       max = (1 << (bits - 1)) - 1;
1949
       min = - (1 << (bits - 1));
1950
       if ((value > max) || (value < min))
1951
         retval = OP_OUT_OF_RANGE;
1952
     }
1953
   else if (flags & OP_UNSIGNED)
1954
     {
1955
       max = ((((1 << (bits - 1)) - 1) << 1) | 1);
1956
       min = 0;
1957
       if (((unsigned long) value > (unsigned long) max)
1958
            || ((unsigned long) value < (unsigned long) min))
1959
         retval = OP_OUT_OF_RANGE;
1960
     }
1961
   else if (flags & OP_NEG)
1962
     {
1963
       max = - 1;
1964
       min = - ((1 << (bits - 1)) - 1);
1965
       if ((value > max) || (value < min))
1966
         retval = OP_OUT_OF_RANGE;
1967
     }
1968
   return retval;
1969
}
1970
 
1971
/* Bunch of error checkings.
1972
   The checks are made after a matching instruction was found.  */
1973
 
1974
static void
1975
warn_if_needed (ins *insn)
1976
{
1977
  /* If the post-increment address mode is used and the load/store
1978
     source register is the same as rbase, the result of the
1979
     instruction is undefined.  */
1980
  if (IS_INSN_TYPE (LD_STOR_INS_INC))
1981
    {
1982
      /* Enough to verify that one of the arguments is a simple reg.  */
1983
      if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1984
        if (insn->arg[0].r == insn->arg[1].r)
1985
          as_bad (_("Same src/dest register is used (`r%d'), result is undefined"), insn->arg[0].r);
1986
    }
1987
 
1988
  if (IS_INSN_MNEMONIC ("pop")
1989
      || IS_INSN_MNEMONIC ("push")
1990
      || IS_INSN_MNEMONIC ("popret"))
1991
    {
1992
      unsigned int count = insn->arg[0].constant, reg_val;
1993
 
1994
      /* Check if count operand caused to save/retrive the RA twice
1995
         to generate warning message.  */
1996
     if (insn->nargs > 2)
1997
       {
1998
         reg_val = getreg_image (insn->arg[1].r);
1999
 
2000
         if (   ((reg_val == 9) &&  (count > 7))
2001
             || ((reg_val == 10) && (count > 6))
2002
             || ((reg_val == 11) && (count > 5))
2003
             || ((reg_val == 12) && (count > 4))
2004
             || ((reg_val == 13) && (count > 2))
2005
             || ((reg_val == 14) && (count > 0)))
2006
           as_warn (_("RA register is saved twice."));
2007
 
2008
         /* Check if the third operand is "RA" or "ra" */
2009
         if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
2010
           as_bad (_("`%s' Illegal use of registers."), ins_parse);
2011
       }
2012
 
2013
      if (insn->nargs > 1)
2014
       {
2015
         reg_val = getreg_image (insn->arg[1].r);
2016
 
2017
         /* If register is a register pair ie r12/r13/r14 in operand1, then
2018
            the count constant should be validated.  */
2019
         if (((reg_val == 11) && (count > 7))
2020
             || ((reg_val == 12) && (count > 6))
2021
             || ((reg_val == 13) && (count > 4))
2022
             || ((reg_val == 14) && (count > 2))
2023
             || ((reg_val == 15) && (count > 0)))
2024
           as_bad (_("`%s' Illegal count-register combination."), ins_parse);
2025
       }
2026
     else
2027
       {
2028
         /* Check if the operand is "RA" or "ra" */
2029
         if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
2030
           as_bad (_("`%s' Illegal use of register."), ins_parse);
2031
       }
2032
    }
2033
 
2034
  /* Some instruction assume the stack pointer as rptr operand.
2035
     Issue an error when the register to be loaded is also SP.  */
2036
  if (instruction->flags & NO_SP)
2037
    {
2038
      if (getreg_image (insn->arg[1].r) == getreg_image (sp))
2039
        as_bad (_("`%s' has undefined result"), ins_parse);
2040
    }
2041
 
2042
  /* If the rptr register is specified as one of the registers to be loaded,
2043
     the final contents of rptr are undefined. Thus, we issue an error.  */
2044
  if (instruction->flags & NO_RPTR)
2045
    {
2046
      if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
2047
        as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2048
                  getreg_image (insn->arg[0].r));
2049
    }
2050
}
2051
 
2052
/* In some cases, we need to adjust the instruction pointer although a
2053
   match was already found. Here, we gather all these cases.
2054
   Returns 1 if instruction pointer was adjusted, otherwise 0.  */
2055
 
2056
static int
2057
adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
2058
{
2059
  int ret_value = 0;
2060
 
2061
  if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
2062
    {
2063
      if ((instruction->operands[0].op_type == abs24)
2064
           && ((insn->arg[0].constant) > 0xF00000))
2065
        {
2066
          insn->arg[0].constant &= 0xFFFFF;
2067
          instruction--;
2068
          ret_value = 1;
2069
        }
2070
    }
2071
 
2072
  return ret_value;
2073
}
2074
 
2075
/* Assemble a single instruction:
2076
   INSN is already parsed (that is, all operand values and types are set).
2077
   For instruction to be assembled, we need to find an appropriate template in
2078
   the instruction table, meeting the following conditions:
2079
    1: Has the same number of operands.
2080
    2: Has the same operand types.
2081
    3: Each operand size is sufficient to represent the instruction's values.
2082
   Returns 1 upon success, 0 upon failure.  */
2083
 
2084
static int
2085
assemble_insn (char *mnemonic, ins *insn)
2086
{
2087
  /* Type of each operand in the current template.  */
2088
  argtype cur_type[MAX_OPERANDS];
2089
  /* Size (in bits) of each operand in the current template.  */
2090
  unsigned int cur_size[MAX_OPERANDS];
2091
  /* Flags of each operand in the current template.  */
2092
  unsigned int cur_flags[MAX_OPERANDS];
2093
  /* Instruction type to match.  */
2094
  unsigned int ins_type;
2095
  /* Boolean flag to mark whether a match was found.  */
2096
  int match = 0;
2097
  int i;
2098
  /* Nonzero if an instruction with same number of operands was found.  */
2099
  int found_same_number_of_operands = 0;
2100
  /* Nonzero if an instruction with same argument types was found.  */
2101
  int found_same_argument_types = 0;
2102
  /* Nonzero if a constant was found within the required range.  */
2103
  int found_const_within_range  = 0;
2104
  /* Argument number of an operand with invalid type.  */
2105
  int invalid_optype = -1;
2106
  /* Argument number of an operand with invalid constant value.  */
2107
  int invalid_const  = -1;
2108
  /* Operand error (used for issuing various constant error messages).  */
2109
  op_err op_error, const_err = OP_LEGAL;
2110
 
2111
/* Retrieve data (based on FUNC) for each operand of a given instruction.  */
2112
#define GET_CURRENT_DATA(FUNC, ARRAY)                           \
2113
  for (i = 0; i < insn->nargs; i++)                             \
2114
    ARRAY[i] = FUNC (instruction->operands[i].op_type)
2115
 
2116
#define GET_CURRENT_TYPE    GET_CURRENT_DATA (get_optype, cur_type)
2117
#define GET_CURRENT_SIZE    GET_CURRENT_DATA (get_opbits, cur_size)
2118
#define GET_CURRENT_FLAGS   GET_CURRENT_DATA (get_opflags, cur_flags)
2119
 
2120
  /* Instruction has no operands -> only copy the constant opcode.   */
2121
  if (insn->nargs == 0)
2122
    {
2123
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2124
      return 1;
2125
    }
2126
 
2127
  /* In some case, same mnemonic can appear with different instruction types.
2128
     For example, 'storb' is supported with 3 different types :
2129
     LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2130
     We assume that when reaching this point, the instruction type was
2131
     pre-determined. We need to make sure that the type stays the same
2132
     during a search for matching instruction.  */
2133
  ins_type = CR16_INS_TYPE (instruction->flags);
2134
 
2135
  while (/* Check that match is still not found.  */
2136
         match != 1
2137
         /* Check we didn't get to end of table.  */
2138
         && instruction->mnemonic != NULL
2139
         /* Check that the actual mnemonic is still available.  */
2140
         && IS_INSN_MNEMONIC (mnemonic)
2141
         /* Check that the instruction type wasn't changed.  */
2142
         && IS_INSN_TYPE (ins_type))
2143
    {
2144
      /* Check whether number of arguments is legal.  */
2145
      if (get_number_of_operands () != insn->nargs)
2146
        goto next_insn;
2147
      found_same_number_of_operands = 1;
2148
 
2149
      /* Initialize arrays with data of each operand in current template.  */
2150
      GET_CURRENT_TYPE;
2151
      GET_CURRENT_SIZE;
2152
      GET_CURRENT_FLAGS;
2153
 
2154
      /* Check for type compatibility.  */
2155
      for (i = 0; i < insn->nargs; i++)
2156
        {
2157
          if (cur_type[i] != insn->arg[i].type)
2158
            {
2159
              if (invalid_optype == -1)
2160
                invalid_optype = i + 1;
2161
              goto next_insn;
2162
            }
2163
        }
2164
      found_same_argument_types = 1;
2165
 
2166
      for (i = 0; i < insn->nargs; i++)
2167
        {
2168
          /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2169
             then goto next instruction.  */
2170
          if (IS_INSN_MNEMONIC ("bal") && (i == 0)
2171
              && (instruction->size == 2) && (insn->arg[i].rp != 14))
2172
            goto next_insn;
2173
 
2174
          /* If 'storb' instruction with 'sp' reg and 16-bit disp of
2175
           * reg-pair, leads to undifined trap, so this should use
2176
           * 20-bit disp of reg-pair.  */
2177
          if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
2178
              && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
2179
            goto next_insn;
2180
 
2181
          /* Only check range - don't update the constant's value, since the
2182
             current instruction may not be the last we try to match.
2183
             The constant's value will be updated later, right before printing
2184
             it to the object file.  */
2185
          if ((insn->arg[i].X_op == O_constant)
2186
              && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
2187
                                          cur_flags[i], 0)))
2188
            {
2189
              if (invalid_const == -1)
2190
                {
2191
                  invalid_const = i + 1;
2192
                  const_err = op_error;
2193
                }
2194
              goto next_insn;
2195
            }
2196
          /* For symbols, we make sure the relocation size (which was already
2197
             determined) is sufficient.  */
2198
          else if ((insn->arg[i].X_op == O_symbol)
2199
                   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
2200
                       > cur_size[i]))
2201
                  goto next_insn;
2202
        }
2203
      found_const_within_range = 1;
2204
 
2205
      /* If we got till here -> Full match is found.  */
2206
      match = 1;
2207
      break;
2208
 
2209
/* Try again with next instruction.  */
2210
next_insn:
2211
      instruction++;
2212
    }
2213
 
2214
  if (!match)
2215
    {
2216
      /* We haven't found a match - instruction can't be assembled.  */
2217
      if (!found_same_number_of_operands)
2218
        as_bad (_("Incorrect number of operands"));
2219
      else if (!found_same_argument_types)
2220
        as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
2221
      else if (!found_const_within_range)
2222
        {
2223
          switch (const_err)
2224
            {
2225
            case OP_OUT_OF_RANGE:
2226
              as_bad (_("Operand out of range (arg %d)"), invalid_const);
2227
              break;
2228
            case OP_NOT_EVEN:
2229
              as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
2230
              break;
2231
            default:
2232
              as_bad (_("Illegal operand (arg %d)"), invalid_const);
2233
              break;
2234
            }
2235
        }
2236
 
2237
       return 0;
2238
    }
2239
  else
2240
    /* Full match - print the encoding to output file.  */
2241
    {
2242
      /* Make further checkings (such that couldn't be made earlier).
2243
         Warn the user if necessary.  */
2244
      warn_if_needed (insn);
2245
 
2246
      /* Check whether we need to adjust the instruction pointer.  */
2247
      if (adjust_if_needed (insn))
2248
        /* If instruction pointer was adjusted, we need to update
2249
           the size of the current template operands.  */
2250
        GET_CURRENT_SIZE;
2251
 
2252
      for (i = 0; i < insn->nargs; i++)
2253
        {
2254
          int j = instruction->flags & REVERSE_MATCH ?
2255
                  i == 0 ? 1 :
2256
                  i == 1 ? 0 : i :
2257
                  i;
2258
 
2259
          /* This time, update constant value before printing it.  */
2260
            if ((insn->arg[j].X_op == O_constant)
2261
               && (check_range (&insn->arg[j].constant, cur_size[j],
2262
                                cur_flags[j], 1) != OP_LEGAL))
2263
              as_fatal (_("Illegal operand (arg %d)"), j+1);
2264
        }
2265
 
2266
      /* First, copy the instruction's opcode.  */
2267
      output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2268
 
2269
      for (i = 0; i < insn->nargs; i++)
2270
        {
2271
         /* For BAL (ra),disp17 instuction only. And also set the
2272
            DISP24a relocation type.  */
2273
         if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
2274
           {
2275
             insn->rtype = BFD_RELOC_CR16_DISP24a;
2276
             continue;
2277
           }
2278
          cur_arg_num = i;
2279
          print_operand (cur_size[i], instruction->operands[i].shift,
2280
                         &insn->arg[i]);
2281
        }
2282
    }
2283
 
2284
  return 1;
2285
}
2286
 
2287
/* Print the instruction.
2288
   Handle also cases where the instruction is relaxable/relocatable.  */
2289
 
2290
static void
2291
print_insn (ins *insn)
2292
{
2293
  unsigned int i, j, insn_size;
2294
  char *this_frag;
2295
  unsigned short words[4];
2296
  int addr_mod;
2297
 
2298
  /* Arrange the insn encodings in a WORD size array.  */
2299
  for (i = 0, j = 0; i < 2; i++)
2300
    {
2301
      words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2302
      words[j++] = output_opcode[i] & 0xFFFF;
2303
    }
2304
 
2305
    /* Handle relocation.  */
2306
    if ((instruction->flags & RELAXABLE) && relocatable)
2307
      {
2308
        int relax_subtype;
2309
        /* Write the maximal instruction size supported.  */
2310
        insn_size = INSN_MAX_SIZE;
2311
 
2312
        if (IS_INSN_TYPE (BRANCH_INS))
2313
          {
2314
            switch (insn->rtype)
2315
              {
2316
              case BFD_RELOC_CR16_DISP24:
2317
                relax_subtype = 2;
2318
                break;
2319
              case BFD_RELOC_CR16_DISP16:
2320
                relax_subtype = 1;
2321
                break;
2322
              default:
2323
                relax_subtype = 0;
2324
                break;
2325
              }
2326
          }
2327
        else
2328
          abort ();
2329
 
2330
        this_frag = frag_var (rs_machine_dependent, insn_size *2,
2331
                              4, relax_subtype,
2332
                              insn->exp.X_add_symbol,
2333
                              insn->exp.X_add_number,
2334
                              0);
2335
      }
2336
    else
2337
      {
2338
        insn_size = instruction->size;
2339
        this_frag = frag_more (insn_size * 2);
2340
 
2341
        if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2342
          {
2343
             reloc_howto_type *reloc_howto;
2344
             int size;
2345
 
2346
             reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2347
 
2348
             if (!reloc_howto)
2349
               abort ();
2350
 
2351
             size = bfd_get_reloc_size (reloc_howto);
2352
 
2353
             if (size < 1 || size > 4)
2354
               abort ();
2355
 
2356
             fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2357
                          size, &insn->exp, reloc_howto->pc_relative,
2358
                          insn->rtype);
2359
          }
2360
      }
2361
 
2362
  /* Verify a 2-byte code alignment.  */
2363
  addr_mod = frag_now_fix () & 1;
2364
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
2365
    as_bad (_("instruction address is not a multiple of 2"));
2366
  frag_now->insn_addr = addr_mod;
2367
  frag_now->has_code = 1;
2368
 
2369
  /* Write the instruction encoding to frag.  */
2370
  for (i = 0; i < insn_size; i++)
2371
    {
2372
      md_number_to_chars (this_frag, (valueT) words[i], 2);
2373
      this_frag += 2;
2374
    }
2375
}
2376
 
2377
/* This is the guts of the machine-dependent assembler.  OP points to a
2378
   machine dependent instruction.  This function is supposed to emit
2379
   the frags/bytes it assembles to.  */
2380
 
2381
void
2382
md_assemble (char *op)
2383
{
2384
  ins cr16_ins;
2385
  char *param, param1[32];
2386
  char c;
2387
 
2388
  /* Reset global variables for a new instruction.  */
2389
  reset_vars (op);
2390
 
2391
  /* Strip the mnemonic.  */
2392
  for (param = op; *param != 0 && !ISSPACE (*param); param++)
2393
    ;
2394
  c = *param;
2395
  *param++ = '\0';
2396
 
2397
  /* bCC instuctions and adjust the mnemonic by adding extra white spaces.  */
2398
  if (is_bcc_insn (op))
2399
    {
2400
      strcpy (param1, get_b_cc (op));
2401
      op = "b";
2402
      strcat (param1,",");
2403
      strcat (param1, param);
2404
      param = (char *) &param1;
2405
    }
2406
 
2407
  /* Checking the cinv options and adjust the mnemonic by removing the
2408
     extra white spaces.  */
2409
  if (streq ("cinv", op))
2410
    {
2411
     /* Validate the cinv options.  */
2412
      check_cinv_options (param);
2413
      strcat (op, param);
2414
    }
2415
 
2416
  /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2417
     lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
2418
     as CR16 core doesn't support lsh[b/w] right shift operaions.  */
2419
  if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
2420
      && (param [0] == '$'))
2421
    {
2422
      strcpy (param1, param);
2423
      /* Find the instruction.  */
2424
      instruction = (const inst *) hash_find (cr16_inst_hash, op);
2425
       parse_operands (&cr16_ins, param1);
2426
      if (((&cr16_ins)->arg[0].type == arg_ic)
2427
          && ((&cr16_ins)->arg[0].constant >= 0))
2428
        {
2429
           if (streq ("lshb", op))
2430
             op = "ashub";
2431
           else if (streq ("lshd", op))
2432
             op = "ashud";
2433
           else
2434
             op = "ashuw";
2435
        }
2436
    }
2437
 
2438
  /* Find the instruction.  */
2439
  instruction = (const inst *) hash_find (cr16_inst_hash, op);
2440
  if (instruction == NULL)
2441
    {
2442
      as_bad (_("Unknown opcode: `%s'"), op);
2443
      return;
2444
    }
2445
 
2446
  /* Tie dwarf2 debug info to the address at the start of the insn.  */
2447
  dwarf2_emit_insn (0);
2448
 
2449
  /* Parse the instruction's operands.  */
2450
  parse_insn (&cr16_ins, param);
2451
 
2452
  /* Assemble the instruction - return upon failure.  */
2453
  if (assemble_insn (op, &cr16_ins) == 0)
2454
    return;
2455
 
2456
  /* Print the instruction.  */
2457
  print_insn (&cr16_ins);
2458
}

powered by: WebSVN 2.1.0

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