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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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