OSDN Git Service

4bd3d18321300b12b0d86316c03cfc84dd64c2a3
[pf3gnuchains/pf3gnuchains3x.git] / gas / config / tc-crx.c
1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2    Copyright 2004 Free Software Foundation, Inc.
3
4    Contributed by Tomer Levi, NSC, Israel.
5    Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
6    Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
7
8    This file is part of GAS, the GNU Assembler.
9
10    GAS is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2, or (at your option)
13    any later version.
14
15    GAS is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with GAS; see the file COPYING.  If not, write to the
22    Free Software Foundation, 59 Temple Place - Suite 330, Boston,
23    MA 02111-1307, USA.  */
24
25 #include "as.h"
26 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
28 #include "opcode/crx.h"
29 #include "elf/crx.h"
30
31 #include <limits.h>
32
33 /* Word is considered here as a 16-bit unsigned short int.  */
34 #define WORD_SIZE   16
35 #define WORD_SHIFT  16
36
37 /* Register is 4-bit size.  */
38 #define REG_SIZE   4
39
40 /* Maximum size of a single instruction (in words).  */
41 #define INSN_MAX_SIZE   3
42
43 /* Maximum bits which may be set in a `mask16' operand.  */
44 #define MAX_REGS_IN_MASK16  8
45
46 /* Escape to 16-bit immediate.  */
47 #define ESC_16  0xE
48 /* Escape to 32-bit immediate.  */
49 #define ESC_32  0xF
50
51 /* Utility macros for string comparison.  */
52 #define streq(a, b)           (strcmp (a, b) == 0)
53 #define strneq(a, b, c)       (strncmp (a, b, c) == 0)
54
55 /* A mask to set n_bits starting from offset offs.  */
56 #define SET_BITS_MASK(offs,n_bits)    ((((1 << (n_bits)) - 1) << (offs)))
57 /* A mask to clear n_bits starting from offset offs.  */
58 #define CLEAR_BITS_MASK(offs,n_bits)  (~(((1 << (n_bits)) - 1) << (offs)))
59
60 /* Get the argument type for each operand of a given instruction.  */
61 #define GET_ACTUAL_TYPE                                           \
62   for (i = 0; i < insn->nargs; i++)                               \
63     atyp_act[i] = getarg_type (instruction->operands[i].op_type)
64
65 /* Get the size (in bits) for each operand of a given instruction.  */
66 #define GET_ACTUAL_SIZE                                           \
67   for (i = 0; i < insn->nargs; i++)                               \
68     bits_act[i] = getbits (instruction->operands[i].op_type)
69
70 /* Non-zero if OP is instruction with no operands.  */
71 #define NO_OPERANDS_INST(OP)                      \
72   (streq (OP, "di") || streq (OP, "nop")          \
73    || streq (OP, "retx") || streq (OP, "ei")      \
74    || streq (OP, "wait") || streq (OP, "eiwait"))
75
76 /* Print a number NUM, shifted by SHIFT bytes, into a location
77    pointed by index BYTE of array 'output_opcode'.  */
78 #define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM << SHIFT)
79
80 /* Opcode mnemonics hash table.  */
81 static struct hash_control *crx_inst_hash;
82 /* CRX registers hash table.  */
83 static struct hash_control *reg_hash;
84 /* CRX coprocessor registers hash table.  */
85 static struct hash_control *copreg_hash;
86 /* Current instruction we're assembling.  */
87 const inst *instruction;
88
89 /* Initialize global variables.  */
90 long output_opcode[2];
91 /* Nonzero means a relocatable symbol.  */
92 int relocatable;
93 /* Nonzero means a constant's bit-size was already set.  */
94 int size_was_set;
95 /* Nonzero means a negative constant.  */
96 int signflag;
97 /* Nonzero means a CST4 instruction.  */
98 int cst4flag;
99 /* A copy of the original instruction (used in error messages).  */
100 char ins_parse[MAX_INST_LEN];
101 /* Nonzero means instruction is represented in post increment mode.  */
102 int post_inc_mode;
103 /* Holds the current processed argument number.  */
104 int processing_arg_number;
105
106 /* Generic assembler global variables which must be defined by all targets.  */
107
108 /* Characters which always start a comment.  */
109 const char comment_chars[] = "#";
110
111 /* Characters which start a comment at the beginning of a line.  */
112 const char line_comment_chars[] = "#";
113
114 /* This array holds machine specific line separator characters.  */
115 const char line_separator_chars[] = ";";
116
117 /* Chars that can be used to separate mant from exp in floating point nums.  */
118 const char EXP_CHARS[] = "eE";
119
120 /* Chars that mean this number is a floating point constant as in 0f12.456  */
121 const char FLT_CHARS[] = "f'";
122
123 /* Target-specific multicharacter options, not const-declared at usage.  */
124 const char *md_shortopts = "";
125 struct option md_longopts[] =
126 {
127   {NULL, no_argument, NULL, 0}
128 };
129 size_t md_longopts_size = sizeof (md_longopts);
130
131 /* This table describes all the machine specific pseudo-ops
132    the assembler has to support.  The fields are:
133    *** Pseudo-op name without dot.
134    *** Function to call to execute this pseudo-op.
135    *** Integer arg to pass to the function.  */
136
137 const pseudo_typeS md_pseudo_table[] =
138 {
139   /* In CRX machine, align is in bytes (not a ptwo boundary).  */
140   {"align", s_align_bytes, 0},
141   {0, 0, 0}
142 };
143
144 const relax_typeS md_relax_table[] =
145 {
146   /* bCC  */
147   {0xfa, -0x100, 2, 1},                 /*  8 */
148   {0xfffe, -0x10000, 4, 2},             /* 16 */
149   {0xfffffffe, -0xfffffffe, 6, 0},      /* 32 */
150
151   /* bal  */
152   {0xfffe, -0x10000, 4, 4},             /* 16 */
153   {0xfffffffe, -0xfffffffe, 6, 0},      /* 32 */
154
155   /* cmpbr  */
156   {0xfe, -0x100, 4, 6},                 /*  8 */
157   {0xfffffe, -0x1000000, 6, 0}          /* 24 */
158 };
159
160 static void    reset_vars               (char *, ins *);
161 static reg     get_register             (char *);
162 static copreg  get_copregister          (char *);
163 static void    get_number_of_bits       (ins *, int);
164 static argtype getarg_type              (operand_type);
165 static int     getbits                  (operand_type);
166 static int     get_number_of_operands   (void);
167 static void    get_operandtype          (char *, int, ins *);
168 static int     gettrap                  (char *);
169 static void    handle_pi_insn           (char *);
170 static int     get_cinv_parameters      (char *);
171 static unsigned long getconstant        (unsigned long, int);
172 static int     getreg_image             (reg);
173 static void    parse_operands           (ins *, char *);
174 static void    parse_insn               (ins *, char *);
175 static void    print_operand            (int, int, argument *);
176 static void    print_constant           (int, int, argument *);
177 static int     exponent2scale           (int);
178 static void    mask_const               (unsigned long *, int);
179 static void    mask_reg                 (int, unsigned short *);
180 static int     process_label_constant   (char *, ins *, int);
181 static void    set_indexmode_parameters (char *, ins *, int);
182 static void    set_cons_rparams         (char *, ins *, int);
183 static char *  preprocess_reglist       (char *, int *);
184 static int     assemble_insn            (char *, ins *);
185 static void    print_insn               (ins *);
186
187 /* Return the bit size for a given operand.  */
188
189 static int
190 getbits (operand_type op)
191 {
192   if (op < MAX_OPRD)
193     return crx_optab[op].bit_size;
194   else
195     return 0;
196 }
197
198 /* Return the argument type of a given operand.  */
199
200 static argtype
201 getarg_type (operand_type op)
202 {
203   if (op < MAX_OPRD)
204     return crx_optab[op].arg_type;
205   else
206     return nullargs;
207 }
208
209 /* Get the core processor register 'reg_name'.  */
210
211 static reg
212 get_register (char *reg_name)
213 {
214   const reg_entry *reg;
215
216   reg = (const reg_entry *) hash_find (reg_hash, reg_name);
217
218   if (reg != NULL)
219     return reg->value.reg_val;
220   else
221     return nullregister;
222 }
223
224 /* Get the coprocessor register 'copreg_name'.  */
225
226 static copreg
227 get_copregister (char *copreg_name)
228 {
229   const reg_entry *copreg;
230
231   copreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
232
233   if (copreg != NULL)
234     return copreg->value.copreg_val;
235   else
236     return nullcopregister;
237 }
238
239 /* Mask a constant to the number of bits it is to be mapped to.  */
240
241 static void
242 mask_const (unsigned long int *t, int size)
243 {
244   *t &= (((LONGLONG)1 << size) - 1);
245 }
246
247 /* Round up a section size to the appropriate boundary.  */
248
249 valueT
250 md_section_align (segT seg, valueT val)
251 {
252   /* Round .text section to a multiple of 2.  */
253   if (seg == text_section)
254     return (val + 1) & ~1;
255   return val;
256 }
257
258 /* Parse an operand that is machine-specific (remove '*').  */
259
260 void
261 md_operand (expressionS * exp)
262 {
263   char c = *input_line_pointer;
264
265   switch (c)
266     {
267     case '*':
268       input_line_pointer++;
269       expression (exp);
270       break;
271     default:
272       break;
273     }
274 }
275
276 /* Reset global variables before parsing a new instruction.  */
277
278 static void
279 reset_vars (char *op, ins *crx_ins)
280 {
281   unsigned int i;
282
283   processing_arg_number = relocatable = size_was_set
284     = signflag = post_inc_mode = cst4flag = 0;
285   memset (& output_opcode, '\0', sizeof (output_opcode));
286
287   /* Memset the 'signflag' field in every argument.  */
288   for (i = 0; i < MAX_OPERANDS; i++)
289     crx_ins->arg[i].signflag = 0;
290
291   /* Save a copy of the original OP (used in error messages).  */
292   strcpy (ins_parse, op);
293 }
294
295 /* This macro decides whether a particular reloc is an entry in a
296    switch table.  It is used when relaxing, because the linker needs
297    to know about all such entries so that it can adjust them if
298    necessary.  */
299
300 #define SWITCH_TABLE(fix)                                 \
301   (   (fix)->fx_addsy != NULL                             \
302    && (fix)->fx_subsy != NULL                             \
303    && S_GET_SEGMENT ((fix)->fx_addsy) ==                  \
304       S_GET_SEGMENT ((fix)->fx_subsy)                     \
305    && S_GET_SEGMENT (fix->fx_addsy) != undefined_section  \
306    && (   (fix)->fx_r_type == BFD_RELOC_CRX_NUM8          \
307        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16         \
308        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
309
310 /* See whether we need to force a relocation into the output file.
311    This is used to force out switch and PC relative relocations when
312    relaxing.  */
313
314 int
315 crx_force_relocation (fixS *fix)
316 {
317   if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
318     return 1;
319
320   return 0;
321 }
322
323 /* Generate a relocation entry for a fixup.  */
324
325 arelent *
326 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
327 {
328   arelent * reloc;
329
330   reloc = xmalloc (sizeof (arelent));
331   reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
332   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
333   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
334   reloc->addend = fixP->fx_offset;
335
336   if (fixP->fx_subsy != NULL)
337     {
338       if (SWITCH_TABLE (fixP))
339         {
340           /* Keep the current difference in the addend.  */
341           reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
342                            - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
343
344           switch (fixP->fx_r_type)
345             {
346             case BFD_RELOC_CRX_NUM8:
347               fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
348               break;
349             case BFD_RELOC_CRX_NUM16:
350               fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
351               break;
352             case BFD_RELOC_CRX_NUM32:
353               fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
354               break;
355             default:
356               abort ();
357               break;
358             }
359         }
360       else
361         {
362           /* We only resolve difference expressions in the same section.  */
363           as_bad_where (fixP->fx_file, fixP->fx_line,
364                         _("can't resolve `%s' {%s section} - `%s' {%s section}"),
365                         fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
366                         segment_name (fixP->fx_addsy
367                                       ? S_GET_SEGMENT (fixP->fx_addsy)
368                                       : absolute_section),
369                         S_GET_NAME (fixP->fx_subsy),
370                         segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
371         }
372     }
373
374   assert ((int) fixP->fx_r_type > 0);
375   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
376
377   if (reloc->howto == (reloc_howto_type *) NULL)
378     {
379       as_bad_where (fixP->fx_file, fixP->fx_line,
380                     _("internal error: reloc %d (`%s') not supported by object file format"),
381                     fixP->fx_r_type,
382                     bfd_get_reloc_code_name (fixP->fx_r_type));
383       return NULL;
384     }
385   assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
386
387   return reloc;
388 }
389
390 /* Prepare machine-dependent frags for relaxation.  */
391
392 int
393 md_estimate_size_before_relax (fragS *fragp, asection *seg)
394 {
395   /* If symbol is undefined or located in a different section,
396      select the largest supported relocation.  */
397   relax_substateT subtype;
398   relax_substateT rlx_state[] = {0, 2,
399                                  3, 4,
400                                  5, 6};
401
402   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
403     {
404       if (fragp->fr_subtype == rlx_state[subtype]
405           && (!S_IS_DEFINED (fragp->fr_symbol)
406               || seg != S_GET_SEGMENT (fragp->fr_symbol)))
407         {
408           fragp->fr_subtype = rlx_state[subtype + 1];
409           break;
410         }
411     }
412
413   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
414     abort ();
415
416   return md_relax_table[fragp->fr_subtype].rlx_length;
417 }
418
419 void
420 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
421 {
422   /* 'opcode' points to the start of the instruction, whether
423      we need to change the instruction's fixed encoding.  */
424   char *opcode = fragP->fr_literal + fragP->fr_fix;
425   bfd_reloc_code_real_type reloc;
426
427   subseg_change (sec, 0);
428
429   switch (fragP->fr_subtype)
430     {
431     case 0:
432       reloc = BFD_RELOC_CRX_REL8;
433       break;
434     case 1:
435       *opcode = 0x7e;
436       reloc = BFD_RELOC_CRX_REL16;
437       break;
438     case 2:
439       *opcode = 0x7f;
440       reloc = BFD_RELOC_CRX_REL32;
441       break;
442     case 3:
443       reloc = BFD_RELOC_CRX_REL16;
444       break;
445     case 4:
446       *++opcode = 0x31;
447       reloc = BFD_RELOC_CRX_REL32;
448       break;
449     case 5:
450       reloc = BFD_RELOC_CRX_REL8_CMP;
451       break;
452     case 6:
453       *++opcode = 0x31;
454       reloc = BFD_RELOC_CRX_REL24;
455       break;
456     default:
457       abort ();
458       break;
459     }
460
461     fix_new (fragP, fragP->fr_fix,
462              bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
463              fragP->fr_symbol, fragP->fr_offset, 1, reloc);
464     fragP->fr_var = 0;
465     fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
466 }
467
468 /* Process machine-dependent command line options.  Called once for
469    each option on the command line that the machine-independent part of
470    GAS does not understand.  */
471
472 int
473 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
474 {
475   return 0;
476 }
477
478 /* Machine-dependent usage-output.  */
479
480 void
481 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
482 {
483   return;
484 }
485
486 /* Turn a string in input_line_pointer into a floating point constant
487    of type TYPE, and store the appropriate bytes in *LITP.  The number
488    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
489    returned, or NULL on OK.  */
490
491 char *
492 md_atof (int type, char *litP, int *sizeP)
493 {
494   int prec;
495   LITTLENUM_TYPE words[4];
496   char *t;
497   int i;
498
499   switch (type)
500     {
501     case 'f':
502       prec = 2;
503       break;
504
505     case 'd':
506       prec = 4;
507       break;
508
509     default:
510       *sizeP = 0;
511       return _("bad call to md_atof");
512     }
513
514   t = atof_ieee (input_line_pointer, type, words);
515   if (t)
516     input_line_pointer = t;
517
518   *sizeP = prec * 2;
519
520   if (! target_big_endian)
521     {
522       for (i = prec - 1; i >= 0; i--)
523         {
524           md_number_to_chars (litP, (valueT) words[i], 2);
525           litP += 2;
526         }
527     }
528   else
529     {
530       for (i = 0; i < prec; i++)
531         {
532           md_number_to_chars (litP, (valueT) words[i], 2);
533           litP += 2;
534         }
535     }
536
537   return NULL;
538 }
539
540 /* Apply a fixS (fixup of an instruction or data that we didn't have
541    enough info to complete immediately) to the data in a frag.
542    Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
543    relaxation of debug sections, this function is called only when
544    fixuping relocations of debug sections.  */
545
546 void
547 md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
548 {
549   valueT val = * valP;
550   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
551   fixP->fx_offset = 0;
552
553   switch (fixP->fx_r_type)
554     {
555     case BFD_RELOC_CRX_NUM8:
556       bfd_put_8 (stdoutput, (unsigned char) val, buf);
557       break;
558     case BFD_RELOC_CRX_NUM16:
559       bfd_put_16 (stdoutput, val, buf);
560       break;
561     case BFD_RELOC_CRX_NUM32:
562       bfd_put_32 (stdoutput, val, buf);
563       break;
564     default:
565       /* We shouldn't ever get here because linkrelax is nonzero.  */
566       abort ();
567       break;
568     }
569
570   fixP->fx_done = 0;
571
572   if (fixP->fx_addsy == NULL
573       && fixP->fx_pcrel == 0)
574     fixP->fx_done = 1;
575
576   if (fixP->fx_pcrel == 1
577       && fixP->fx_addsy != NULL
578       && S_GET_SEGMENT (fixP->fx_addsy) == seg)
579     fixP->fx_done = 1;
580 }
581
582 /* The location from which a PC relative jump should be calculated,
583    given a PC relative reloc.  */
584
585 long
586 md_pcrel_from (fixS *fixp)
587 {
588   return fixp->fx_frag->fr_address + fixp->fx_where;
589 }
590
591 /* This function is called once, at assembler startup time.  This should
592    set up all the tables, etc that the MD part of the assembler needs.  */
593
594 void
595 md_begin (void)
596 {
597   const char *hashret = NULL;
598   int i = 0;
599
600   /* Set up a hash table for the instructions.  */
601   crx_inst_hash = hash_new ();
602   if (crx_inst_hash == NULL)
603     as_fatal (_("Virtual memory exhausted"));
604
605   while (crx_instruction[i].mnemonic != NULL)
606     {
607       const char *mnemonic = crx_instruction[i].mnemonic;
608
609       hashret = hash_insert (crx_inst_hash, mnemonic,
610         (PTR) &crx_instruction[i]);
611
612       if (hashret != NULL && *hashret != '\0')
613         as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
614                   *hashret == 0 ? _("(unknown reason)") : hashret);
615
616       /* Insert unique names into hash table.  The CRX instruction set
617          has many identical opcode names that have different opcodes based
618          on the operands.  This hash table then provides a quick index to
619          the first opcode with a particular name in the opcode table.  */
620       do
621         {
622           ++i;
623         }
624       while (crx_instruction[i].mnemonic != NULL
625              && streq (crx_instruction[i].mnemonic, mnemonic));
626     }
627
628   /* Initialize reg_hash hash table.  */
629   reg_hash = hash_new ();
630
631   {
632     const reg_entry *regtab;
633
634     for (regtab = crx_regtab;
635          regtab < (crx_regtab + NUMREGS); regtab++)
636       {
637         hashret = hash_insert (reg_hash, regtab->name, (PTR) regtab);
638         if (hashret)
639           as_fatal (_("Internal Error:  Can't hash %s: %s"),
640                     regtab->name,
641                     hashret);
642       }
643   }
644
645   /* Initialize copreg_hash hash table.  */
646   copreg_hash = hash_new ();
647
648   {
649     const reg_entry *copregtab;
650
651     for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
652          copregtab++)
653       {
654         hashret = hash_insert (copreg_hash, copregtab->name, (PTR) copregtab);
655         if (hashret)
656           as_fatal (_("Internal Error:  Can't hash %s: %s"),
657                     copregtab->name,
658                     hashret);
659       }
660   }
661   /*  Set linkrelax here to avoid fixups in most sections.  */
662   linkrelax = 1;
663 }
664
665 /* Get the number of bits corresponding to a constant -
666    here we check for possible overflow cases.  */
667
668 static void
669 get_number_of_bits (ins * crx_ins, int op_num)
670 {
671   int cnt_bits = 0;
672   unsigned long int temp = crx_ins->arg[op_num].constant;
673   const cst4_entry *cst4_op;
674
675   /* If the constant's size was already set - nothing to do.  */
676   if (size_was_set)
677     return;
678
679   /* Already dealt with negative numbers in process_label_constants.  */
680   while (temp > 0)
681     {
682       temp >>= 1;
683       cnt_bits++;
684     }
685
686   if (IS_INSN_TYPE (ARITH_INS) && !relocatable && !signflag)
687     {
688       if (cnt_bits == 16)
689         {
690           crx_ins->arg[op_num].size = 17;
691           return;
692         }
693     }
694   /* If a signed +ve is represented in 6 bits then we have to represent
695      it in 22 bits in case of the index mode of addressing.  */
696   if (IS_INSN_TYPE (LD_STOR_INS)
697       || IS_INSN_TYPE (LD_STOR_INS_INC)
698       || IS_INSN_TYPE (STOR_IMM_INS)
699       || IS_INSN_TYPE (CSTBIT_INS))
700     {
701       if (!signflag && crx_ins->arg[op_num].type == arg_icr)
702         {
703           if (cnt_bits == 6)
704             {
705               crx_ins->arg[op_num].size = 7;
706               return;
707             }
708           if (cnt_bits == 22)
709             as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
710         }
711     }
712   /* If a signed +ve is represnted in 16 bits in case of load/stor disp16
713      then change it to 17 bits.
714      If a signed +ve is represnted in 12 bits in post increment instruction
715      increase it to 13 bits.  */
716   if (IS_INSN_TYPE (LD_STOR_INS))
717     {
718       if (!signflag && crx_ins->arg[op_num].type == arg_cr)
719         {
720           if (cnt_bits == 16)
721             {
722               crx_ins->arg[op_num].size = 17;
723               return;
724             }
725           if (cnt_bits == 32)
726             as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
727         }
728     }
729
730   if (IS_INSN_TYPE (CSTBIT_INS)
731       || IS_INSN_TYPE (LD_STOR_INS_INC)
732       || IS_INSN_TYPE (STOR_IMM_INS))
733     {
734       if (!signflag && crx_ins->arg[op_num].type == arg_cr)
735         {
736           if (cnt_bits == 12)
737             {
738               crx_ins->arg[op_num].size = 13;
739               if (IS_INSN_TYPE (LD_STOR_INS_INC))
740                 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
741               return;
742             }
743           if (IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS))
744             {
745               if (cnt_bits == 28)
746                 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse);
747             }
748
749         }
750     }
751
752   /* Handle negative cst4 mapping for arithmetic/cmp&br operations.  */
753   if (signflag && !relocatable
754       && ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
755       || ((IS_INSN_TYPE (CMPBR_INS) && op_num == 0))))
756     {
757       for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
758         {
759           if (crx_ins->arg[op_num].constant == (unsigned int)(-cst4_op->value))
760             {
761               crx_ins->arg[op_num].size = 4;
762               crx_ins->arg[op_num].constant = cst4_op->binary;
763               crx_ins->arg[op_num].signflag = 0;
764               return;
765             }
766         }
767     }
768   /* Because of the cst4 mapping -- -1 and -4 already handled above
769      as well as for relocatable cases.  */
770   if (signflag && IS_INSN_TYPE (ARITH_BYTE_INS))
771     {
772       if (!relocatable)
773         {
774           if (crx_ins->arg[op_num].constant <= 0xffff)
775             crx_ins->arg[op_num].size = 16;
776           else
777             /* Setting to 18 so that there is no match.  */
778             crx_ins->arg[op_num].size = 18;
779         }
780       else
781         crx_ins->arg[op_num].size = 16;
782       return;
783     }
784
785   if (signflag && IS_INSN_TYPE (ARITH_INS))
786     {
787       /* For all immediates which can be expressed in less than 16 bits.  */
788       if (crx_ins->arg[op_num].constant <= 0xffff && !relocatable)
789         {
790           crx_ins->arg[op_num].size = 16;
791           return;
792         }
793       /* Either it is relocatable or not representable in 16 bits.  */
794       if (crx_ins->arg[op_num].constant < 0xffffffff || relocatable)
795         {
796           crx_ins->arg[op_num].size = 32;
797           return;
798         }
799       crx_ins->arg[op_num].size = 33;
800       return;
801     }
802   if (signflag && !relocatable)
803     return;
804
805   if (!relocatable)
806     crx_ins->arg[op_num].size = cnt_bits;
807
808   /* Checking for Error Conditions.  */
809   if (IS_INSN_TYPE (ARITH_INS) && !signflag)
810     {
811       if (cnt_bits > 32)
812         as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
813                 cnt_bits, ins_parse);
814     }
815   else if (IS_INSN_TYPE (ARITH_BYTE_INS) && !signflag)
816     {
817       if (cnt_bits > 16)
818         as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
819                 cnt_bits, ins_parse);
820     }
821 }
822
823 /* Handle the constants -immediate/absolute values and
824    Labels (jump targets/Memory locations).  */
825
826 static int
827 process_label_constant (char *str, ins * crx_ins, int number)
828 {
829   char *save;
830   unsigned long int temp, cnt;
831   const cst4_entry *cst4_op;
832   int is_cst4=0;
833   int constant_val = 0;
834   int cmp_br_type_flag = 0, i;
835   int br_type_flag = 0;
836   save = input_line_pointer;
837   signflag = 0;
838
839   if (str[0] == '-')
840     {
841       signflag = 1;
842       str++;
843     }
844   else if (str[0] == '+')
845     str++;
846
847   /* Preprocessing for cmpbr instruction and getting the size flag.  */
848   if (strstr (str, ":s") != NULL && (IS_INSN_TYPE (CMPBR_INS)
849       || IS_INSN_TYPE (COP_BRANCH_INS)))
850     cmp_br_type_flag = 8;
851
852   if (strstr (str, ":l") != NULL && (IS_INSN_TYPE (CMPBR_INS)
853       || IS_INSN_TYPE (COP_BRANCH_INS)))
854     cmp_br_type_flag = 24;
855
856   /* Branch instruction preprocessing.  */
857   if (IS_INSN_TYPE (BRANCH_INS))
858     {
859       if (strstr (str, ":s") != NULL)
860         br_type_flag = 8;
861       else if (strstr (str, ":m") != NULL)
862         br_type_flag = 16;
863       else if (strstr (str, ":l") != NULL)
864         br_type_flag = 32;
865     }
866   /* Making the label cleared for processing removing :lms etc from labels.  */
867   if (cmp_br_type_flag != 0 || br_type_flag != 0)
868     {
869       i = 0;
870       while (str[i] != ':')
871         {
872           i++;
873         }
874       str[i] = '\0';
875     }
876   input_line_pointer = str;
877
878   expression (&crx_ins->exp);
879
880   switch (crx_ins->exp.X_op)
881     {
882     case O_big:
883     case O_absent:
884       /* Missing or bad expr becomes absolute 0.  */
885       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
886               str);
887       crx_ins->exp.X_op = O_constant;
888       crx_ins->exp.X_add_number = 0;
889       crx_ins->exp.X_add_symbol = (symbolS *) 0;
890       crx_ins->exp.X_op_symbol = (symbolS *) 0;
891       break;
892
893     case O_constant:
894       crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
895       constant_val = crx_ins->exp.X_add_number;
896       if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
897            && number == 2)
898         {
899           LONGLONG temp64 = 0;
900           char ptr;
901           char temp_str[30];
902           unsigned int jump_value = 0;
903           int BR_MASK = 0, BR_SIZE = 0;
904           temp_str[0] = '\0';
905           if (signflag)
906             {
907               temp_str[0] = '-';
908               temp_str[1] = '\0';
909             }
910           strncat (temp_str, str, strlen (str));
911           temp64 = strtoll (temp_str, (char **) &ptr,0);
912
913           if (temp64 % 2 != 0)
914             as_bad (_("Odd Offset in displacement in Instruction `%s'"),
915                     ins_parse);
916
917           /* Determine the branch size.  */
918           jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
919           if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
920               || ((jump_value & 0xFFFFFF00) == 0x0))
921             {
922               BR_MASK = 0xFF;
923               BR_SIZE = 8;
924             }
925           else
926             if (((jump_value & 0xFF000000) == 0xFF000000)
927                 || ((jump_value & 0xFF000000) == 0x0))
928             {
929               BR_MASK = 0xFFFFFF;
930               BR_SIZE = 24;
931             }
932           jump_value = jump_value >> 1;
933           crx_ins->arg[number].constant = jump_value & BR_MASK;
934           crx_ins->arg[number].size = BR_SIZE;
935           size_was_set = 1;
936           crx_ins->arg[number].signflag = signflag;
937           input_line_pointer = save;
938           return crx_ins->exp.X_op;
939         }
940
941       if (IS_INSN_TYPE (BRANCH_INS)
942           || IS_INSN_MNEMONIC ("bal")
943           || IS_INSN_TYPE (DCR_BRANCH_INS))
944         {
945           LONGLONG temp64 = 0;
946           char ptr;
947           char temp_str[30];
948           unsigned int jump_value = 0;
949           int BR_MASK = 0, BR_SIZE = 0;
950
951           temp_str[0] = '\0';
952           if (signflag)
953             {
954               temp_str[0] = '-';
955               temp_str[1] = '\0';
956             }
957           strncat (temp_str, str, strlen (str));
958           temp64 = strtoll (temp_str, (char **) &ptr,0);
959
960           if (temp64 % 2 != 0)
961             as_bad (_("Odd Offset in displacement in Instruction `%s'"),
962             ins_parse);
963
964           /* Determine the branch size.  */
965           jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
966           if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
967               && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
968                   || ((jump_value & 0xFFFFFF00) == 0x0)))
969             {
970               BR_MASK = 0xFF;
971               BR_SIZE = 8;
972             }
973           else if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
974                    || ((jump_value & 0xFFFF0000) == 0x0))
975             {
976               BR_MASK = 0xFFFF;
977               BR_SIZE = 16;
978             }
979           else
980             {
981               BR_MASK = 0xFFFFFFFF;
982               BR_SIZE = 32;
983             }
984           jump_value = jump_value >> 1;
985           crx_ins->arg[number].constant = jump_value & BR_MASK;
986           crx_ins->arg[number].size = BR_SIZE;
987           size_was_set = 1;
988           crx_ins->arg[number].signflag = signflag;
989           input_line_pointer = save;
990           return crx_ins->exp.X_op;
991         }
992       /* Fix for movd $0xF12344, r0 -- signflag has to be set.  */
993       if (constant_val < 0 && signflag != 1
994           && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
995           && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
996           && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
997         {
998           crx_ins->arg[number].constant =
999             ~(crx_ins->arg[number].constant) + 1;
1000           signflag = 1;
1001         }
1002       /* For load/store instruction when the value is in the offset part.  */
1003       if (constant_val < 0 && signflag != 1
1004           && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
1005               || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
1006         {
1007           if (crx_ins->arg[number].type == arg_cr
1008               || crx_ins->arg[number].type == arg_icr)
1009             {
1010               crx_ins->arg[number].constant =
1011                 ~(crx_ins->arg[number].constant) + 1;
1012               signflag = 1;
1013             }
1014         }
1015       if (signflag)
1016         {
1017           /* Signflag in never set in case of load store instructions
1018              Mapping in case of only the arithinsn case.  */
1019           if ((crx_ins->arg[number].constant != 1
1020                && crx_ins->arg[number].constant != 4)
1021              || (!IS_INSN_TYPE (ARITH_INS)
1022                  && !IS_INSN_TYPE (ARITH_BYTE_INS)
1023                  && !IS_INSN_TYPE (CMPBR_INS)))
1024             {
1025               /* Counting the number of bits required to represent
1026                  the constant.  */
1027               cnt = 0;
1028               temp = crx_ins->arg[number].constant - 1;
1029               while (temp > 0)
1030                 {
1031                   temp >>= 1;
1032                   cnt++;
1033                 }
1034               crx_ins->arg[number].size = cnt + 1;
1035               crx_ins->arg[number].constant =
1036                 ~(crx_ins->arg[number].constant) + 1;
1037               if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1038                 {
1039                   char ptr;
1040                   LONGLONG temp64;
1041
1042                   temp64 = strtoull (str, (char **) &ptr, 0);
1043                   if (cnt < 4)
1044                     crx_ins->arg[number].size = 5;
1045
1046                   if (IS_INSN_TYPE (ARITH_INS))
1047                     {
1048                       if (crx_ins->arg[number].size > 32
1049                           || (temp64 > ULONG_MAX))
1050                         {
1051                           if (crx_ins->arg[number].size > 32)
1052                             as_bad (_("In Instruction `%s': Immediate size is \
1053                                     %lu bits cannot be accomodated"),
1054                                     ins_parse, cnt + 1);
1055
1056                           if (temp64 > ULONG_MAX)
1057                             as_bad (_("Value given more than 32 bits in \
1058                                     Instruction `%s'"), ins_parse);
1059                         }
1060                     }
1061                   if (IS_INSN_TYPE (ARITH_BYTE_INS))
1062                     {
1063                       if (crx_ins->arg[number].size > 16
1064                           || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1065                                || (temp64 & 0xFFFF0000) == 0x0))
1066                         {
1067                           if (crx_ins->arg[number].size > 16)
1068                             as_bad (_("In Instruction `%s': Immediate size is \
1069                                     %lu bits cannot be accomodated"),
1070                                     ins_parse, cnt + 1);
1071
1072                           if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1073                                 || (temp64 & 0xFFFF0000) == 0x0))
1074                             as_bad (_("Value given more than 16 bits in \
1075                                     Instruction `%s'"), ins_parse);
1076                         }
1077                     }
1078                 }
1079               if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
1080                   && !post_inc_mode)
1081                 {
1082                   /* Cases handled ---
1083                      dispub4/dispuw4/dispud4 and for load store dispubwd4
1084                      is applicable only.  */
1085                   if (crx_ins->arg[number].size <= 4)
1086                     crx_ins->arg[number].size = 5;
1087                 }
1088               /* Argument number is checked to distinguish between
1089                  immediate and displacement in cmpbranch and bcopcond.  */
1090               if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1091                    && number == 2)
1092                 {
1093                   if (crx_ins->arg[number].size != 32)
1094                     crx_ins->arg[number].constant =
1095                       crx_ins->arg[number].constant >> 1;
1096                 }
1097
1098               mask_const (&crx_ins->arg[number].constant,
1099                           (int) crx_ins->arg[number].size);
1100             }
1101         }
1102       else
1103         {
1104           /* Argument number is checked to distinguish between
1105              immediate and displacement in cmpbranch and bcopcond.  */
1106           if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1107                   && number == 2)
1108                 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1109             {
1110               if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1111                 {
1112                   if (crx_ins->arg[number].constant == 0)
1113                     as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1114                 }
1115
1116               if (crx_ins->arg[number].constant % 2 != 0)
1117                 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1118
1119               if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1120                 {
1121                   if (crx_ins->arg[number].constant > 32
1122                       || crx_ins->arg[number].constant < 2)
1123                       as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1124                               ins_parse, crx_ins->arg[number].constant);
1125
1126                   crx_ins->arg[number].constant -= 2;
1127                 }
1128
1129               crx_ins->arg[number].constant =
1130                 crx_ins->arg[number].constant >> 1;
1131               get_number_of_bits (crx_ins, number);
1132             }
1133
1134           /* Compare branch argument number zero to be compared -
1135              mapped to cst4.  */
1136           if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
1137             {
1138               for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1139                 {
1140                   if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
1141                     {
1142                       crx_ins->arg[number].constant = cst4_op->binary;
1143                       is_cst4 = 1;
1144                       break;
1145                     }
1146                 }
1147               if (!is_cst4)
1148                 as_bad (_("Instruction `%s' has invalid imm value as an \
1149                           operand"), ins_parse);
1150             }
1151         }
1152       break;
1153
1154     case O_symbol:
1155     case O_subtract:
1156       crx_ins->arg[number].constant = 0;
1157       crx_ins->rtype = BFD_RELOC_NONE;
1158       relocatable = 1;
1159
1160       switch (crx_ins->arg[number].type)
1161         {
1162         case arg_cr:
1163           /* Have to consider various cases here --load/stor++[bwd] rbase, reg.  */
1164           if (IS_INSN_TYPE (LD_STOR_INS_INC))
1165             crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1166           else if (IS_INSN_TYPE (CSTBIT_INS)
1167                    || IS_INSN_TYPE (STOR_IMM_INS))
1168             /* 'stor[bwd] imm' and '[stc]bit[bwd]'.  */
1169             crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1170           else
1171             /* General load store instruction.  */
1172             crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1173             break;
1174         case arg_icr:
1175           /* Index Mode 22 bits relocation.  */
1176             crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1177           break;
1178         case arg_c:
1179           /* Absolute types.  */
1180           /* Case for jumps...dx  types.  */
1181           /* For bal.  */
1182           if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1183             crx_ins->rtype = BFD_RELOC_CRX_REL16;
1184           else if (IS_INSN_TYPE (BRANCH_INS))
1185             {
1186               crx_ins->rtype = BFD_RELOC_CRX_REL8;
1187
1188               /* Overriding the above by the br_type_flag set above.  */
1189               switch (br_type_flag)
1190                 {
1191                 default:
1192                   break;
1193                 case 8:
1194                   crx_ins->rtype = BFD_RELOC_CRX_REL8;
1195                   break;
1196                 case 16:
1197                   crx_ins->rtype = BFD_RELOC_CRX_REL16;
1198                   break;
1199                 case 32:
1200                   crx_ins->rtype = BFD_RELOC_CRX_REL32;
1201                   break;
1202                 }
1203             }
1204           else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1205                    || IS_INSN_TYPE (CSTBIT_INS))
1206             crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1207           else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1208             crx_ins->rtype = BFD_RELOC_CRX_REL4;
1209           else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1210             {
1211               if (cmp_br_type_flag == 24)
1212                 crx_ins->rtype = BFD_RELOC_CRX_REL24;
1213               else
1214                 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1215             }
1216           break;
1217         case arg_ic:
1218         case arg_dc:
1219           if (IS_INSN_TYPE (ARITH_INS))
1220             crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1221           else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1222             crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1223           break;
1224         default:
1225           break;
1226       }
1227       crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1228       break;
1229
1230     default:
1231       break;
1232     }
1233
1234   input_line_pointer = save;
1235   crx_ins->arg[number].signflag = signflag;
1236   return crx_ins->exp.X_op;
1237 }
1238
1239 /* Get the values of the scale to be encoded -
1240    used for the scaled index mode of addressing.  */
1241
1242 static int
1243 exponent2scale (int val)
1244 {
1245   int exponent;
1246
1247   /* If 'val' is 0, the following 'for' will be an endless loop.  */
1248   if (val == 0)
1249     return 0;
1250
1251   for (exponent = 0; (val != 1); val >>= 1, exponent++)
1252     ;
1253
1254   return exponent;
1255 }
1256
1257 /* This is used to set the index mode parameters. Used to set the attributes of
1258    an indexmode type of operand. op_num is the operand number.  */
1259
1260 static void
1261 set_indexmode_parameters (char *operand, ins * crx_ins, int op_num)
1262 {
1263   char address_str[30];
1264   char scale_str[MAX_OPERANDS];
1265   int scale_cnt = 0;
1266   char reg_name[MAX_REGNAME_LEN];
1267   char regindex_name[MAX_REGNAME_LEN];
1268   int i = 0;
1269   int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
1270
1271   switch (crx_ins->arg[op_num].type)
1272     {
1273     case arg_icr:
1274       while (operand[i] != '(')
1275         {
1276           address_str[addr_cnt++] = operand[i];
1277           i++;
1278         }
1279       address_str[addr_cnt] = '\0';
1280       process_label_constant (address_str, crx_ins, op_num);
1281       i++;
1282       reg_counter = 0;
1283       while (operand[i] != ',' && operand[i] != ' ')
1284         {
1285           reg_name[reg_counter++] = operand[i];
1286           i++;
1287         }
1288       reg_name[reg_counter] = '\0';
1289       if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1290         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1291                 reg_name, ins_parse);
1292
1293       i++;
1294       while (operand[i] == ' ')
1295         i++;
1296
1297       reg_counter = 0;
1298       while (operand[i] != ')' && operand[i] != ',')
1299         {
1300           regindex_name[reg_counter++] = operand[i];
1301           i++;
1302         }
1303       regindex_name[reg_counter] = '\0';
1304       reg_counter = 0;
1305       if ((crx_ins->arg[op_num].i_r = get_register (regindex_name))
1306             == nullregister)
1307         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1308                 regindex_name, ins_parse);
1309
1310       /* Setting the scale parameters.  */
1311       while (operand[i] == ' ')
1312         i++;
1313
1314       if (operand[i] == ')')
1315         crx_ins->arg[op_num].scale = 0;
1316       else
1317         {
1318           if (operand[i] == ',')
1319             i++;
1320
1321           while (operand[i] != ' ' && operand[i] != ')')
1322             {
1323               scale_str[scale_cnt++] = operand[i];
1324               i++;
1325             }
1326
1327           scale_str[scale_cnt] = '\0';
1328           /* Preprocess the scale string.  */
1329           if (strstr (scale_str, "0x") != NULL
1330               || strstr (scale_str, "0X") != NULL)
1331             {
1332               sscanf (scale_str, "%x", &temp_int_val);
1333               memset (&scale_str, '\0', sizeof (scale_str));
1334               sprintf (scale_str, "%d", temp_int_val);
1335             }
1336           /* Preprocess over.  */
1337           temp_int_val = atoi (scale_str);
1338
1339           if (temp_int_val != 1 && temp_int_val != 2
1340               && temp_int_val != 4 && temp_int_val != 8)
1341             as_bad (_("Illegal Scale - `%s'"), scale_str);
1342
1343           crx_ins->arg[op_num].scale = exponent2scale (temp_int_val);
1344         }
1345       break;
1346     default:
1347       break;
1348     }
1349 }
1350
1351 /* Parsing the operands of types
1352    - constants
1353    - rbase -> (register)
1354    - offset(rbase)
1355    - offset(rbase)+ - post increment mode.  */
1356
1357 static void
1358 set_cons_rparams (char *operand, ins * crx_ins, int op_num)
1359 {
1360   int i = 0, reg_count = 0;
1361   char reg_name[MAX_REGNAME_LEN];
1362   int change_flag = 0;
1363
1364   if (crx_ins->arg[op_num].type == arg_dc)
1365     change_flag = 1;
1366
1367   switch (crx_ins->arg[op_num].type)
1368     {
1369     case arg_sc: /* Case *+347.  */
1370     case arg_dc: /* Case $18.  */
1371       i++;
1372     case arg_c:/* Case where its a simple constant.  */
1373       process_label_constant (operand + i, crx_ins, op_num);
1374       crx_ins->arg[op_num].type = arg_c;
1375       break;
1376     case arg_dcr: /* Case $9(r13).  */
1377       operand++;
1378     case arg_cr: /* Case 9(r13.   */
1379       while (operand[i] != '(')
1380         i++;
1381       operand[i] = '\0';
1382       process_label_constant (operand, crx_ins, op_num);
1383       operand[i] = '(';
1384       i++;
1385       reg_count = 0;
1386       while (operand[i] != ')')
1387         {
1388           reg_name[reg_count] = operand[i];
1389           i++;
1390           reg_count++;
1391         }
1392       reg_name[reg_count] = '\0';
1393       if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1394         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1395                 reg_name, ins_parse);
1396
1397       crx_ins->arg[op_num].type = arg_cr;
1398       /* Post increment is represented in assembly as offset (register)+.  */
1399       if (strstr (operand + i, "+") != NULL)
1400         /* There is a plus after the ')'.  */
1401         post_inc_mode = 1;
1402       break;
1403     default:
1404       break;
1405     }
1406   if (change_flag == 1)
1407     crx_ins->arg[op_num].type = arg_ic;
1408 }
1409
1410 /* This is used to get the operand attributes -
1411    operand  - current operand to be used
1412    number - operand number
1413    crx_ins - current assembled instruction.  */
1414
1415 static void
1416 get_operandtype (char *operand, int number, ins * crx_ins)
1417 {
1418   int ret_val;
1419   char temp_operand[30];
1420
1421   switch (operand[0])
1422     {
1423     /* When it is a register.  */
1424     case 'r':
1425     case 'c':
1426     case 'i':
1427     case 'u':
1428     case 's':
1429     case 'p':
1430     case 'l':
1431     case 'h':
1432       /* Check whether this is a general processor register.  */
1433       ret_val = get_register (operand);
1434       if (ret_val != nullregister)
1435         {
1436           crx_ins->arg[number].type = arg_r;
1437           crx_ins->arg[number].r = ret_val;
1438           crx_ins->arg[number].size = REG_SIZE;
1439         }
1440       else
1441         {
1442           /* Check whether this is a core [special] coprocessor register.  */
1443           ret_val = get_copregister (operand);
1444           if (ret_val != nullcopregister)
1445             {
1446               crx_ins->arg[number].type = arg_copr;
1447               if (ret_val >= cs0)
1448                 crx_ins->arg[number].type = arg_copsr;
1449               crx_ins->arg[number].cr = ret_val;
1450               crx_ins->arg[number].size = REG_SIZE;
1451             }
1452           else
1453             {
1454               if (strchr (operand, '(') != NULL)
1455                 {
1456                   if (strchr (operand, ',') != NULL
1457                       && (strchr (operand, ',') > strchr (operand, '(')))
1458                     {
1459                       crx_ins->arg[number].type = arg_icr;
1460                       crx_ins->arg[number].constant = 0;
1461                       set_indexmode_parameters (operand, crx_ins, number);
1462                       get_number_of_bits (crx_ins, number);
1463                       return;
1464                     }
1465                   else
1466                     crx_ins->arg[number].type = arg_cr;
1467                 }
1468               else
1469                 crx_ins->arg[number].type = arg_c;
1470               crx_ins->arg[number].constant = 0;
1471               set_cons_rparams (operand, crx_ins, number);
1472               get_number_of_bits (crx_ins, number);
1473             }
1474         }
1475       break;
1476     case '$':
1477       if (strchr (operand, '(') != NULL)
1478         crx_ins->arg[number].type = arg_dcr;
1479       else
1480         crx_ins->arg[number].type = arg_dc;
1481       crx_ins->arg[number].constant = 0;
1482       set_cons_rparams (operand, crx_ins, number);
1483       get_number_of_bits (crx_ins, number);
1484       break;
1485
1486     case '(':
1487       /* Augmenting a zero in front of an operand -- won't work for tbit/sbit.  */
1488       strcpy (temp_operand, "0");
1489       strcat (temp_operand, operand);
1490       if (strchr (temp_operand, ',') != NULL
1491           && (strchr (temp_operand, ',') > strchr (temp_operand, '(')))
1492         {
1493           crx_ins->arg[number].type = arg_icr;
1494           crx_ins->arg[number].constant = 0;
1495           set_indexmode_parameters (temp_operand, crx_ins, number);
1496           get_number_of_bits (crx_ins, number);
1497           return;
1498         }
1499       else
1500         {
1501           crx_ins->arg[number].type = arg_cr;
1502           crx_ins->arg[number].constant = 0;
1503           set_cons_rparams (temp_operand, crx_ins, number);
1504           get_number_of_bits (crx_ins, number);
1505           if ((! strneq (instruction->mnemonic, "load", 4))
1506               && (! strneq (instruction->mnemonic, "stor", 4)))
1507             {
1508               crx_ins->arg[number].type = arg_rbase;
1509               crx_ins->arg[number].size = REG_SIZE;
1510             }
1511           return;
1512         }
1513       break;
1514     case '*':
1515       crx_ins->arg[number].type = arg_sc;
1516       crx_ins->arg[number].constant = 0;
1517       set_cons_rparams (operand, crx_ins, number);
1518       get_number_of_bits (crx_ins, number);
1519       break;
1520     case '+':
1521     case '-':
1522     case '0':
1523     case '1':
1524     case '2':
1525     case '3':
1526     case '4':
1527     case '5':
1528     case '6':
1529     case '7':
1530     case '8':
1531     case '9':
1532       if (strchr (operand, '(') != NULL)
1533         {
1534           if (strchr (operand, ',') != NULL
1535               && (strchr (operand, ',') > strchr (operand, '(')))
1536             {
1537               crx_ins->arg[number].type = arg_icr;
1538               crx_ins->arg[number].constant = 0;
1539               set_indexmode_parameters (operand, crx_ins, number);
1540               get_number_of_bits (crx_ins, number);
1541               return;
1542             }
1543           else
1544             crx_ins->arg[number].type = arg_cr;
1545         }
1546       else
1547         crx_ins->arg[number].type = arg_c;
1548       crx_ins->arg[number].constant = 0;
1549       set_cons_rparams (operand, crx_ins, number);
1550       get_number_of_bits (crx_ins, number);
1551       break;
1552     default:
1553       if (strchr (operand, '(') != NULL)
1554         {
1555           if (strchr (operand, ',') != NULL
1556               && (strchr (operand, ',') > strchr (operand, '(')))
1557             {
1558               crx_ins->arg[number].type = arg_icr;
1559               crx_ins->arg[number].constant = 0;
1560               set_indexmode_parameters (operand, crx_ins, number);
1561               get_number_of_bits (crx_ins, number);
1562               return;
1563             }
1564           else
1565             crx_ins->arg[number].type = arg_cr;
1566         }
1567       else
1568         crx_ins->arg[number].type = arg_c;
1569       crx_ins->arg[number].constant = 0;
1570       set_cons_rparams (operand, crx_ins, number);
1571       get_number_of_bits (crx_ins, number);
1572       break;
1573     }
1574 }
1575
1576 /* Operands are parsed over here, separated into various operands. Each operand
1577    is then analyzed to fillup the fields in the crx_ins data structure.  */
1578
1579 static void
1580 parse_operands (ins * crx_ins, char *operands)
1581 {
1582   char *operandS;              /* Operands string.  */
1583   char *operandH, *operandT;   /* Single operand head/tail pointers.  */
1584   int allocated = 0;           /* Indicates a new operands string was allocated.  */
1585   char *operand[MAX_OPERANDS]; /* Separating the operands.  */
1586   int op_num = 0;              /* Current operand number we are parsing.  */
1587   int bracket_flag = 0;        /* Indicates a bracket '(' was found.  */
1588   int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
1589
1590   /* Preprocess the list of registers, if necessary.  */
1591   operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1592     preprocess_reglist (operands, &allocated) : operands;
1593
1594   while (*operandT != '\0')
1595     {
1596       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1597         {
1598           *operandT++ = '\0';
1599           operand[op_num++] = strdup (operandH);
1600           operandH = operandT;
1601           continue;
1602         }
1603
1604       if (*operandT == ' ')
1605         as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1606
1607       if (*operandT == '(')
1608         bracket_flag = 1;
1609       else if (*operandT == '[')
1610         sq_bracket_flag = 1;
1611
1612       if (*operandT == ')')
1613         {
1614           if (bracket_flag)
1615             bracket_flag = 0;
1616           else
1617             as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1618         }
1619       else if (*operandT == ']')
1620         {
1621           if (sq_bracket_flag)
1622             sq_bracket_flag = 0;
1623           else
1624             as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1625         }
1626
1627       if (bracket_flag == 1 && *operandT == ')')
1628         bracket_flag = 0;
1629       else if (sq_bracket_flag == 1 && *operandT == ']')
1630         sq_bracket_flag = 0;
1631
1632       operandT++;
1633     }
1634
1635   /* Adding the last operand.  */
1636   operand[op_num++] = strdup (operandH);
1637   crx_ins->nargs = op_num;
1638
1639   /* Verifying correct syntax of operands (all brackets should be closed).  */
1640   if (bracket_flag || sq_bracket_flag)
1641     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1642
1643   /* Now to recongnize the operand types.  */
1644   for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1645     {
1646       get_operandtype (operand[op_num], op_num, crx_ins);
1647       free (operand[op_num]);
1648     }
1649
1650   if (allocated)
1651     free (operandS);
1652 }
1653
1654 /* Get the trap index in dispatch table, given its name.
1655    This routine is used by assembling the 'excp' instruction.  */
1656
1657 static int
1658 gettrap (char *s)
1659 {
1660   const trap_entry *trap;
1661
1662   for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1663     if (strcasecmp (trap->name, s) == 0)
1664       return trap->entry;
1665
1666   as_bad (_("Unknown exception: `%s'"), s);
1667   return 0;
1668 }
1669
1670 /* Post-Increment instructions are a sub-group within load/stor instruction
1671    groups. Therefore, when parsing a Post-Increment insn, we have to advance
1672    the instruction pointer to the start of that sub-group.  */
1673
1674 static void
1675 handle_pi_insn (char *operands)
1676 {
1677   /* Assuming Post-Increment insn has the following format :
1678      'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').  */
1679   if (strstr (operands, ")+") != NULL)
1680     while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1681       instruction++;
1682 }
1683
1684 /* Top level module where instruction parsing starts.
1685    crx_ins - data structure holds some information.
1686    operands - holds the operands part of the whole instruction.  */
1687
1688 static void
1689 parse_insn (ins *insn, char *operands)
1690 {
1691   /* Handle 'excp'/'cinv' */
1692   if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1693     {
1694       insn->nargs = 1;
1695       insn->arg[0].type = arg_ic;
1696       insn->arg[0].size = 4;
1697       insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1698         gettrap (operands) : get_cinv_parameters (operands);
1699       return;
1700     }
1701
1702   /* Handle load/stor post-increment instructions.  */
1703   if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS))
1704     handle_pi_insn (operands);
1705
1706   if (operands != NULL)
1707     parse_operands (insn, operands);
1708 }
1709
1710 /* Cinv instruction requires special handling.  */
1711
1712 static int
1713 get_cinv_parameters (char * operand)
1714 {
1715   char *p = operand;
1716   int d_used = 0, i_used = 0, u_used = 0;
1717
1718   while (*++p != ']')
1719     {
1720       if (*p == ',' || *p == ' ')
1721         continue;
1722
1723       if (*p == 'd')
1724         d_used = 1;
1725       else if (*p == 'i')
1726         i_used = 1;
1727       else if (*p == 'u')
1728         u_used = 1;
1729       else
1730         as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1731     }
1732
1733   return ((d_used ? 4 : 0)
1734         + (i_used ? 2 : 0)
1735         + (u_used ? 1 : 0));
1736 }
1737
1738 /* Retrieve the opcode image of a given register.
1739    If the register is illegal for the current instruction,
1740    issue an error.  */
1741
1742 static int
1743 getreg_image (reg r)
1744 {
1745   const reg_entry *reg;
1746   char *reg_name;
1747   int special_register_flag = 0;
1748   int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1749
1750   if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1751     movpr_flag = 1;
1752
1753   if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1754       || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1755     special_register_flag = 1;
1756
1757   /* Check whether the register is in registers table.  */
1758   if (r < MAX_REG)
1759     reg = &crx_regtab[r];
1760   /* Check whether the register is in coprocessor registers table.  */
1761   else if (r < MAX_COPREG)
1762     reg = &crx_copregtab[r-MAX_REG];
1763   /* Register not found.  */
1764   else
1765     {
1766       as_bad (_("Unknown register: `%d'"), r);
1767       return 0;
1768     }
1769
1770   reg_name = reg->name;
1771
1772 /* Issue a error message when register is illegal.  */
1773 #define IMAGE_ERR \
1774   as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1775             reg_name, ins_parse);                            \
1776   break;
1777
1778   switch (reg->type)
1779   {
1780     case CRX_U_REGTYPE:
1781     case CRX_CFG_REGTYPE:
1782     case CRX_MTPR_REGTYPE:
1783       if (movpr_flag && special_register_flag)
1784         return reg->image;
1785       else
1786         IMAGE_ERR;
1787
1788     case CRX_R_REGTYPE:
1789     case CRX_C_REGTYPE:
1790     case CRX_CS_REGTYPE:
1791       if (!(movpr_flag && special_register_flag))
1792         return reg->image;
1793       else
1794         IMAGE_ERR;
1795
1796     default:
1797       IMAGE_ERR;
1798   }
1799
1800   return 0;
1801 }
1802
1803 /* Routine used to get the binary-string equivalent of a integer constant
1804    which currently require currbits to represent itself to be extended to
1805    nbits.  */
1806
1807 static unsigned long int
1808 getconstant (unsigned long int x, int nbits)
1809 {
1810   int cnt = 0;
1811   unsigned long int temp = x;
1812
1813   while (temp > 0)
1814     {
1815       temp >>= 1;
1816       cnt++;
1817     }
1818
1819   /* Escape sequence to next 16bit immediate.  */
1820   if (cnt > nbits)
1821     as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1822             x, cnt, ins_parse);
1823   else
1824     {
1825       if (signflag)
1826         x |= SET_BITS_MASK (cnt, nbits - cnt);
1827       else
1828         x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1829     }
1830
1831   /* The following expression avoids overflow if
1832      'nbits' is the number of bits in 'bfd_vma'.  */
1833   return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1834 }
1835
1836 /* Print a constant value to 'output_opcode':
1837    ARG holds the operand's type and value.
1838    SHIFT represents the location of the operand to be print into.
1839    NBITS determines the size (in bits) of the constant.  */
1840
1841 static void
1842 print_constant (int nbits, int shift, argument *arg)
1843 {
1844   unsigned long mask = 0;
1845
1846   long constant = getconstant (arg->constant, nbits);
1847
1848   switch (nbits)
1849   {
1850     case 32:
1851     case 28:
1852     case 24:
1853     case 22:
1854       /* mask the upper part of the constant, that is, the bits
1855          going to the lowest byte of output_opcode[0].
1856          The upper part of output_opcode[1] is always filled,
1857          therefore it is always masked with 0xFFFF.  */
1858       mask = (1 << (nbits - 16)) - 1;
1859       /* Divide the constant between two consecutive words :
1860                  0         1         2         3
1861             +---------+---------+---------+---------+
1862             |         | X X X X | X X X X |         |
1863             +---------+---------+---------+---------+
1864               output_opcode[0]    output_opcode[1]     */
1865
1866       CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1867       CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1868       break;
1869
1870     case 16:
1871     case 12:
1872       /* Special case - in arg_cr, the SHIFT represents the location
1873          of the REGISTER, not the constant, which is itself not shifted.  */
1874       if (arg->type == arg_cr)
1875         {
1876           CRX_PRINT (0, constant,  0);
1877           break;
1878         }
1879
1880       /* When instruction size is 3, a 16-bit constant is always
1881          filling the upper part of output_opcode[1].  */
1882       if (instruction->size > 2)
1883         CRX_PRINT (1, constant, WORD_SHIFT);
1884       else
1885         CRX_PRINT (0, constant, shift);
1886       break;
1887
1888     default:
1889       CRX_PRINT (0, constant,  shift);
1890       break;
1891   }
1892 }
1893
1894 /* Print an operand to 'output_opcode', which later on will be
1895    printed to the object file:
1896    ARG holds the operand's type, size and value.
1897    SHIFT represents the printing location of operand.
1898    NBITS determines the size (in bits) of a constant operand.  */
1899
1900 static void
1901 print_operand (int nbits, int shift, argument *arg)
1902 {
1903   switch (arg->type)
1904     {
1905     case arg_r:
1906       CRX_PRINT (0, getreg_image (arg->r), shift);
1907       break;
1908
1909     case arg_copr:
1910       if (arg->cr < c0 || arg->cr > c15)
1911         as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1912                 ins_parse);
1913       CRX_PRINT (0, getreg_image (arg->cr), shift);
1914       break;
1915
1916     case arg_copsr:
1917       if (arg->cr < cs0 || arg->cr > cs15)
1918         as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1919                 ins_parse);
1920       CRX_PRINT (0, getreg_image (arg->cr), shift);
1921       break;
1922
1923     case arg_ic:
1924       print_constant (nbits, shift, arg);
1925       break;
1926
1927     case arg_icr:
1928       /*    16      12        8    6         0
1929             +--------------------------------+
1930             |  reg   | r_base | scl|  disp   |
1931             +--------------------------------+    */
1932       CRX_PRINT (0, getreg_image (arg->r), 12);
1933       CRX_PRINT (0, getreg_image (arg->i_r), 8);
1934       CRX_PRINT (0, arg->scale, 6);
1935       print_constant (nbits, shift, arg);
1936       break;
1937
1938     case arg_rbase:
1939       CRX_PRINT (0, getreg_image (arg->r), shift);
1940       break;
1941
1942     case arg_cr:
1943       /* case base_cst4.  */
1944       if ((instruction->flags & CST4MAP) && cst4flag)
1945         output_opcode[0] |= (getconstant (arg->constant, nbits)
1946                              << (shift + REG_SIZE));
1947       else
1948         /* rbase_dispu<NN> and other such cases.  */
1949         print_constant (nbits, shift, arg);
1950       /* Add the register argument to the output_opcode.  */
1951       CRX_PRINT (0, getreg_image (arg->r), shift);
1952       break;
1953
1954     case arg_c:
1955       print_constant (nbits, shift, arg);
1956       break;
1957
1958     default:
1959       break;
1960     }
1961 }
1962
1963 /* Retrieve the number of operands for the current assembled instruction.  */
1964
1965 static int
1966 get_number_of_operands (void)
1967 {
1968   int i;
1969
1970   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1971     ;
1972   return i;
1973 }
1974
1975 /* Assemble a single instruction :
1976    Instruction has been parsed and all operand values set appropriately.
1977    Algorithm for assembling -
1978    For instruction to be assembled:
1979     Step 1: Find instruction in the array crx_instruction with same mnemonic.
1980     Step 2: Find instruction with same operand types.
1981     Step 3: If (size_of_operands) match then done, else increment the
1982             array_index and goto Step3.
1983     Step 4: Cannot assemble
1984    Returns 1 upon success, 0 upon failure.  */
1985
1986 static int
1987 assemble_insn (char *mnemonic, ins *insn)
1988 {
1989   /* Argument type of each operand in the instruction we are looking for.  */
1990   argtype atyp[MAX_OPERANDS];
1991   /* Argument type of each operand in the current instruction.  */
1992   argtype atyp_act[MAX_OPERANDS];
1993   /* Size (in bits) of each operand in the instruction we are looking for.  */
1994   int bits[MAX_OPERANDS];
1995   /* Size (in bits) of each operand in the current instruction.  */
1996   int bits_act[MAX_OPERANDS];
1997   /* Location (in bits) of each operand in the current instruction.  */
1998   int shift_act[MAX_OPERANDS];
1999   int match = 0;
2000   int done_flag = 0;
2001   int cst4maptype = 0;
2002   int changed_already = 0;
2003   unsigned int temp_value = 0;
2004   int instrtype, i;
2005   /* A pointer to the argument's constant value.  */
2006   unsigned long int *cons;
2007   /* Pointer to loop over all cst4_map entries.  */
2008   const cst4_entry *cst4_op;
2009
2010   /* Instruction has no operands -> copy only the constant opcode.   */
2011   if (insn->nargs == 0)
2012     {
2013       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2014       return 1;
2015     }
2016
2017   /* Find instruction with same number of operands.  */
2018   while (get_number_of_operands () != insn->nargs
2019          && IS_INSN_MNEMONIC (mnemonic))
2020     instruction++;
2021
2022   if (!IS_INSN_MNEMONIC (mnemonic))
2023     return 0;
2024
2025   /* Initialize argument type and size of each given operand.  */
2026   for (i = 0; i < insn->nargs; i++)
2027     {
2028       atyp[i] = insn->arg[i].type;
2029       bits[i] = insn->arg[i].size;
2030     }
2031
2032   /* Initialize argument type and size of each operand in current inst.  */
2033   GET_ACTUAL_TYPE;
2034   GET_ACTUAL_SIZE;
2035
2036   while (match != 1
2037          /* Check we didn't get to end of table.  */
2038          && instruction->mnemonic != NULL
2039          /* Check that the actual mnemonic is still available.  */
2040          && IS_INSN_MNEMONIC (mnemonic))
2041     {
2042       /* Check for argement type compatibility.  */
2043       for (i = 0; i < insn->nargs; i++)
2044         {
2045           if (atyp_act[i] == atyp[i])
2046             done_flag = 1;
2047           else
2048             {
2049               done_flag = 0;
2050               break;
2051             }
2052         }
2053       if (done_flag)
2054         {
2055           /* Check for post inc mode of the current instruction.  */
2056           if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2057             done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2058         }
2059
2060       if (done_flag == 0)
2061         {
2062           /* Try again with next instruction.  */
2063           instruction++;
2064           GET_ACTUAL_TYPE;
2065           GET_ACTUAL_SIZE;
2066           continue;
2067         }
2068       else
2069         {
2070           /* Check for size compatibility.  */
2071           for (i = 0; i < insn->nargs; i++)
2072             {
2073               if (bits[i] > bits_act[i])
2074                 {
2075                   /* Actual size is too small - try again.  */
2076                   done_flag = 0;
2077                   instruction++;
2078                   GET_ACTUAL_TYPE;
2079                   GET_ACTUAL_SIZE;
2080                   break;
2081                 }
2082             }
2083
2084         }
2085
2086       if (done_flag == 1)
2087         {
2088           /* Full match is found.  */
2089           match = 1;
2090           break;
2091         }
2092     }
2093
2094   if (match == 0)
2095     /* We haven't found a match - instruction can't be assembled.  */
2096     return 0;
2097   else
2098     /* Full match - print the final image.  */
2099     {
2100       /* Handle positive constants.  */
2101       if (!signflag)
2102         {
2103           if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2104             {
2105               /* Get the map type of the instruction.  */
2106               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2107               cons = &insn->arg[instrtype].constant;
2108               cst4maptype = instruction->flags & CST4MAP;
2109
2110               switch (cst4maptype)
2111                 {
2112                 case DISPUB4:
2113                   /* 14 and 15 are reserved escape sequences of dispub4.  */
2114                   if (*cons == 14 || *cons == 15)
2115                     {
2116                       instruction++;
2117                       GET_ACTUAL_SIZE;
2118                     }
2119                   break;
2120
2121                 case DISPUW4:
2122                   /* Mapping has to be done.  */
2123                   if (*cons <= 15 && *cons % 2 != 0)
2124                     {
2125                       instruction++;
2126                       GET_ACTUAL_SIZE;
2127                     }
2128                   else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2129                     {
2130                       instruction--;
2131                       GET_ACTUAL_SIZE;
2132                     }
2133                   if (*cons < 27 && *cons % 2 == 0)
2134                     *cons /= 2;
2135                   break;
2136
2137                 case DISPUD4:
2138                   /* Mapping has to be done.  */
2139                   if (*cons <= 15 && *cons % 4 != 0)
2140                     {
2141                       instruction++;
2142                       GET_ACTUAL_SIZE;
2143                     }
2144                   else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2145                     {
2146                       instruction--;
2147                       GET_ACTUAL_SIZE;
2148                     }
2149                   if (*cons < 53 && *cons % 4 == 0)
2150                     *cons /= 4;
2151                   break;
2152                 default:
2153                   break;
2154               }
2155             }
2156           if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2157                && !relocatable)
2158             {
2159               /* Check whether a cst4 mapping has to be done.  */
2160               if ((instruction->operands[0].op_type == cst4
2161                     || instruction->operands[0].op_type == i16)
2162                   && (instruction->operands[1].op_type == regr))
2163                 {
2164                   /* 'const' equals reserved escape sequences -->>
2165                      represent as i16.  */
2166                   if (insn->arg[0].constant == ESC_16
2167                       || insn->arg[0].constant == ESC_32)
2168                     {
2169                       instruction++;
2170                       GET_ACTUAL_SIZE;
2171                     }
2172                   else
2173                     {
2174                       /* Loop over cst4_map entries.  */
2175                       for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2176                            cst4_op++)
2177                         {
2178                           /* 'const' equals a binary, which is already mapped
2179                              by a different value -->> represent as i16.  */
2180                           if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2181                               && cst4_op->binary != cst4_op->value)
2182                             {
2183                               instruction++;
2184                               GET_ACTUAL_SIZE;
2185                             }
2186                           /* 'const' equals a value bigger than 16 -->> map to
2187                              its binary and represent as cst4.  */
2188                           else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2189                                    && insn->arg[0].constant >= 16)
2190                             {
2191                               instruction--;
2192                               insn->arg[0].constant = cst4_op->binary;
2193                               GET_ACTUAL_SIZE;
2194                             }
2195                         }
2196                     }
2197                 }
2198               /* Special check for 'addub 0, r0' instruction -
2199                  The opcode '0000 0000 0000 0000' is not allowed.  */
2200               if (IS_INSN_MNEMONIC ("addub"))
2201                 {
2202                   if ((instruction->operands[0].op_type == cst4)
2203                       && instruction->operands[1].op_type == regr)
2204                     {
2205                       if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2206                         instruction++;
2207                     }
2208                 }
2209             }
2210           if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2211               || IS_INSN_TYPE (LD_STOR_INS_INC))
2212             {
2213               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2214               if (instruction->operands[instrtype].op_type == rbase)
2215                 instruction++;
2216             }
2217           /* Error checking in case of post-increment instruction.  */
2218           if (IS_INSN_TYPE (LD_STOR_INS_INC))
2219             {
2220               if (!((strneq (instruction->mnemonic, "stor", 4))
2221                     && (insn->arg[0].type != arg_r)))
2222                 if (insn->arg[0].r == insn->arg[1].r)
2223                   as_bad (_("Invalid instruction : `%s' Source and Destination register \
2224                           same in Post INC mode"), ins_parse);
2225             }
2226           if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2227             {
2228               if (instruction->operands[1].op_type == rbase_dispu12)
2229                 {
2230                   if (insn->arg[1].constant == 0)
2231                     {
2232                       instruction--;
2233                       GET_ACTUAL_SIZE;
2234                     }
2235                 }
2236             }
2237           if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2238                || IS_INSN_TYPE (STOR_IMM_INS)
2239                || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2240             {
2241               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2242               changed_already = 0;
2243               /* Convert 32 bits accesses to 16 bits accesses.  */
2244               if (instruction->operands[instrtype].op_type == abs32)
2245                 {
2246                   if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2247                     {
2248                       instruction--;
2249                       insn->arg[instrtype].constant =
2250                         insn->arg[instrtype].constant & 0xFFFF;
2251                       insn->arg[instrtype].size = 16;
2252                       changed_already = 1;
2253                       GET_ACTUAL_SIZE;
2254                     }
2255                 }
2256               /* Convert 16 bits accesses to 32 bits accesses.  */
2257               if (instruction->operands[instrtype].op_type == abs16
2258                   && changed_already != 1)
2259                 {
2260                   instruction++;
2261                   insn->arg[instrtype].constant =
2262                     insn->arg[instrtype].constant & 0xFFFF;
2263                   insn->arg[instrtype].size = 32;
2264                   GET_ACTUAL_SIZE;
2265                 }
2266               changed_already = 0;
2267             }
2268           if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2269             {
2270               /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
2271               if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2272                 {
2273                   instruction++;
2274                   GET_ACTUAL_SIZE;
2275                 }
2276             }
2277         }
2278
2279       for (i = 0; i < insn->nargs; i++)
2280         {
2281           if (instruction->operands[i].op_type == cst4
2282               || instruction->operands[i].op_type == rbase_cst4)
2283             cst4flag = 1;
2284         }
2285
2286       /* First, copy the instruction's opcode.  */
2287       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2288
2289       /* Swap the argument values in case bcop instructions.  */
2290       if (IS_INSN_TYPE (COP_BRANCH_INS))
2291         {
2292           temp_value = insn->arg[0].constant;
2293           insn->arg[0].constant = insn->arg[1].constant;
2294           insn->arg[1].constant = temp_value;
2295         }
2296
2297       for (i = 0; i < insn->nargs; i++)
2298         {
2299           shift_act[i] = instruction->operands[i].shift;
2300           signflag = insn->arg[i].signflag;
2301           processing_arg_number = i;
2302           print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2303         }
2304     }
2305
2306   return 1;
2307 }
2308
2309 /* Set the appropriate bit for register 'r' in 'mask'.
2310    This indicates that this register is loaded or stored by
2311    the instruction.  */
2312
2313 static void
2314 mask_reg (int r, unsigned short int *mask)
2315 {
2316   if ((reg)r > (reg)sp)
2317     {
2318       as_bad (_("Invalid Register in Register List"));
2319       return;
2320     }
2321
2322   *mask |= (1 << r);
2323 }
2324
2325 /* Preprocess register list - create a 16-bit mask with one bit for each
2326    of the 16 general purpose registers. If a bit is set, it indicates
2327    that this register is loaded or stored by the instruction.  */
2328
2329 static char *
2330 preprocess_reglist (char *param, int *allocated)
2331 {
2332   char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
2333   char *regP;                     /* Pointer to 'reg_name' string.  */
2334   int reg_counter = 0;            /* Count number of parsed registers.  */
2335   unsigned short int mask = 0;    /* Mask for 16 general purpose registers.  */
2336   char *new_param;                /* New created operands string.  */
2337   char *paramP = param;           /* Pointer to original opearands string.  */
2338   char maskstring[10];            /* Array to print the mask as a string.  */
2339   reg r;
2340   copreg cr;
2341
2342   /* If 'param' is already in form of a number, no need to preprocess.  */
2343   if (strchr (paramP, '{') == NULL)
2344     return param;
2345
2346   /* Verifying correct syntax of operand.  */
2347   if (strchr (paramP, '}') == NULL)
2348     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2349
2350   while (*paramP++ != '{');
2351
2352   new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2353   *allocated = 1;
2354   strncpy (new_param, param, paramP - param - 1);
2355
2356   while (*paramP != '}')
2357     {
2358       regP = paramP;
2359       memset (&reg_name, '\0', sizeof (reg_name));
2360
2361       while (ISALNUM (*paramP))
2362         paramP++;
2363
2364       strncpy (reg_name, regP, paramP - regP);
2365
2366       if (IS_INSN_TYPE (COP_REG_INS))
2367         {
2368           if ((cr = get_copregister (reg_name)) == nullcopregister)
2369             as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2370           mask_reg (getreg_image (cr - c0), &mask);
2371         }
2372       else
2373         {
2374           if ((r = get_register (reg_name)) == nullregister)
2375             as_bad (_("Illegal register `%s' in register list"), reg_name);
2376           mask_reg (getreg_image (r), &mask);
2377         }
2378
2379       if (++reg_counter > MAX_REGS_IN_MASK16)
2380         as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2381                 MAX_REGS_IN_MASK16);
2382
2383       while (!ISALNUM (*paramP) && *paramP != '}')
2384           paramP++;
2385     }
2386
2387   if (*++paramP != '\0')
2388     as_warn (_("rest of line ignored; first ignored character is `%c'"),
2389              *paramP);
2390
2391   if (mask == 0)
2392     as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2393             ins_parse);
2394
2395   sprintf (maskstring, "$0x%x", mask);
2396   strcat (new_param, maskstring);
2397   return new_param;
2398 }
2399
2400 /* Print the instruction.
2401    Handle also cases where the instruction is relaxable/relocatable.  */
2402
2403 void
2404 print_insn (ins *insn)
2405 {
2406   unsigned int i, j, insn_size;
2407   char *this_frag;
2408   unsigned short words[4];
2409
2410   /* Arrange the insn encodings in a WORD size array.  */
2411   for (i = 0, j = 0; i < 2; i++)
2412     {
2413       words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2414       words[j++] = output_opcode[i] & 0xFFFF;
2415     }
2416
2417   /* Handle relaxtion.  */
2418   if ((instruction->flags & RELAXABLE) && relocatable)
2419     {
2420       int relax_subtype;
2421
2422       /* Write the maximal instruction size supported.  */
2423       insn_size = INSN_MAX_SIZE;
2424
2425       /* bCC  */
2426       if (IS_INSN_TYPE (BRANCH_INS))
2427         relax_subtype = 0;
2428       /* bal  */
2429       else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2430         relax_subtype = 3;
2431       /* cmpbr  */
2432       else if (IS_INSN_TYPE (CMPBR_INS))
2433         relax_subtype = 5;
2434       else
2435         abort ();
2436
2437       this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2438                             4, relax_subtype,
2439                             insn->exp.X_add_symbol,
2440                             insn->exp.X_add_number,
2441                             0);
2442     }
2443   else
2444     {
2445       insn_size = instruction->size;
2446       this_frag = frag_more (insn_size * 2);
2447
2448       /* Handle relocation.  */
2449       if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2450         {
2451           reloc_howto_type *reloc_howto;
2452           int size;
2453
2454           reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2455
2456           if (!reloc_howto)
2457             abort ();
2458
2459           size = bfd_get_reloc_size (reloc_howto);
2460
2461           if (size < 1 || size > 4)
2462             abort ();
2463
2464           fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2465                        size, &insn->exp, reloc_howto->pc_relative,
2466                        insn->rtype);
2467         }
2468     }
2469
2470   /* Write the instruction encoding to frag.  */
2471   for (i = 0; i < insn_size; i++)
2472     {
2473       md_number_to_chars (this_frag, (valueT) words[i], 2);
2474       this_frag += 2;
2475     }
2476 }
2477
2478 /* This is the guts of the machine-dependent assembler.  OP points to a
2479    machine dependent instruction.  This function is supposed to emit
2480    the frags/bytes it assembles to.  */
2481
2482 void
2483 md_assemble (char *op)
2484 {
2485   ins crx_ins;
2486   char *param;
2487   char c;
2488
2489   /* Reset global variables for a new instruction.  */
2490   reset_vars (op, &crx_ins);
2491
2492   /* Strip the mnemonic.  */
2493   for (param = op; *param != 0 && !ISSPACE (*param); param++)
2494     ;
2495   c = *param;
2496   *param++ = '\0';
2497
2498   /* Find the instruction.  */
2499   instruction = (const inst *) hash_find (crx_inst_hash, op);
2500   if (instruction == NULL)
2501     {
2502       as_bad (_("Unknown opcode: `%s'"), op);
2503       return;
2504     }
2505
2506   /* Tie dwarf2 debug info to the address at the start of the insn.  */
2507   dwarf2_emit_insn (0);
2508
2509   if (NO_OPERANDS_INST (op))
2510     /* Handle instructions with no operands.  */
2511     crx_ins.nargs = 0;
2512   else
2513     /* Parse the instruction's operands.  */
2514     parse_insn (&crx_ins, param);
2515
2516   /* Assemble the instruction.  */
2517   if (assemble_insn (op, &crx_ins) == 0)
2518     {
2519       as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2520       return;
2521     }
2522
2523   /* Print the instruction.  */
2524   print_insn (&crx_ins);
2525 }