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