Add CRX insns: pushx, popx
[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 /* 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_constant:
883       crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
884       constant_val = crx_ins->exp.X_add_number;
885       if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
886            && number == 2)
887         {
888           /* This variable causes a warning (is to be handles by string
889              type implementation).  */
890           LONGLONG temp64 = 0;
891
892           char ptr[20];
893           char temp_str[30];
894           unsigned int jump_value = 0;
895           int BR_MASK = 0, BR_SIZE = 0;
896           temp_str[0] = '\0';
897           if (signflag)
898             {
899               temp_str[0] = '-';
900               temp_str[1] = '\0';
901             }
902           strncat (temp_str, str, strlen (str));
903           temp64 = strtol (temp_str, (char **) &ptr,0);
904           /* This is not accurate :
905              Actually overflow is allowed here (see comment below).
906              Originally the call was to 'strtoll', which isn't
907              identified by MSVC.  */
908           if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
909             as_bad (_("Overflow in displacement in Instruction `%s'"),
910                     ins_parse);
911
912           /* If br *+x
913              It will be returned as '0' padded with 'x' uptill 64 bits
914              If br *-x
915              It will be returned as sign extended form
916
917              Then search for validity of representation
918              Check whether upper 38 bits are all zeroes or all ones
919              If not report error.  */
920           if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
921                 || ((temp64 & UPPER31_MASK) == 0x0)))
922             as_bad (_("Overflow in displacement in Instruction `%s'"),
923                     ins_parse);
924
925           if (temp64 % 2 != 0)
926             as_bad (_("Odd Offset in displacement in Instruction `%s'"),
927                     ins_parse);
928
929           /* Determine the branch size.  */
930           jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
931           if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
932               || ((jump_value & 0xFFFFFF00) == 0x0))
933             {
934               BR_MASK = 0xFF;
935               BR_SIZE = 8;
936             }
937           else
938             if (((jump_value & 0xFF000000) == 0xFF000000)
939                 || ((jump_value & 0xFF000000) == 0x0))
940             {
941               BR_MASK = 0xFFFFFF;
942               BR_SIZE = 24;
943             }
944           jump_value = jump_value >> 1;
945           crx_ins->arg[number].constant = jump_value & BR_MASK;
946           crx_ins->arg[number].size = BR_SIZE;
947           size_was_set = 1;
948           crx_ins->arg[number].signflag = signflag;
949           input_line_pointer = save;
950           return crx_ins->exp.X_op;
951         }
952
953       if (IS_INSN_TYPE (BRANCH_INS)
954           || IS_INSN_MNEMONIC ("bal")
955           || IS_INSN_TYPE (DCR_BRANCH_INS))
956         {
957           LONGLONG temp64 = 0;
958           char ptr[20];
959           char temp_str[30];
960           unsigned int jump_value = 0;
961           int BR_MASK = 0, BR_SIZE = 0;
962
963           temp_str[0] = '\0';
964           if (signflag)
965             {
966               temp_str[0] = '-';
967               temp_str[1] = '\0';
968             }
969           strncat (temp_str, str, strlen (str));
970           temp64 = strtol (temp_str, (char **) &ptr,0);
971           /* This is not accurate :
972              Actually overflow is allowed here (see comment below).
973              Originally the call was to 'strtoll', which isn't
974              identified by MSVC.  */
975           if ((temp64 == LONG_MAX) || (temp64 == LONG_MIN))
976             as_bad (_("Overflow in displacement in Instruction `%s'"),
977                     ins_parse);
978
979           /* If br *+x
980              It will be returned as '0' padded with 'x' uptill 64 bits
981              If br *-x
982              It will be returned as sign extended form
983
984              Then search for validity of representation
985              Check whether upper 31 bits are all zeroes or all ones
986              If not report error.  */
987           if (!(((temp64 & UPPER31_MASK) == UPPER31_MASK)
988                 || ((temp64 & UPPER31_MASK) == 0x0)))
989             as_bad (_("Overflow in displacement in Instruction `%s'"),
990                     ins_parse);
991
992           if (temp64 % 2 != 0)
993             as_bad (_("Odd Offset in displacement in Instruction `%s'"),
994             ins_parse);
995
996           /* Determine the branch size.  */
997           jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
998           if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
999               && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
1000                   || ((jump_value & 0xFFFFFF00) == 0x0)))
1001             {
1002               BR_MASK = 0xFF;
1003               BR_SIZE = 8;
1004             }
1005           else
1006             if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
1007                 || ((jump_value & 0xFFFF0000) == 0x0))
1008             {
1009               BR_MASK = 0xFFFF;
1010               BR_SIZE = 16;
1011             }
1012           else
1013             {
1014               BR_MASK = 0xFFFFFFFF;
1015               BR_SIZE = 32;
1016             }
1017           jump_value = jump_value >> 1;
1018           crx_ins->arg[number].constant = jump_value & BR_MASK;
1019           crx_ins->arg[number].size = BR_SIZE;
1020           size_was_set = 1;
1021           crx_ins->arg[number].signflag = signflag;
1022           input_line_pointer = save;
1023           return crx_ins->exp.X_op;
1024         }
1025       /* Fix for movd $0xF12344, r0 -- signflag has to be set.  */
1026       if (constant_val < 0 && signflag != 1
1027           && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
1028           && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
1029           && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
1030         {
1031           crx_ins->arg[number].constant =
1032             ~(crx_ins->arg[number].constant) + 1;
1033           signflag = 1;
1034         }
1035       /* For load/store instruction when the value is in the offset part.  */
1036       if (constant_val < 0 && signflag != 1
1037           && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
1038               || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
1039         {
1040           if (crx_ins->arg[number].type == arg_cr
1041               || crx_ins->arg[number].type == arg_icr)
1042             {
1043               crx_ins->arg[number].constant =
1044                 ~(crx_ins->arg[number].constant) + 1;
1045               signflag = 1;
1046             }
1047         }
1048       if (signflag)
1049         {
1050           /* Signflag in never set in case of load store instructions
1051              Mapping in case of only the arithinsn case.  */
1052           if ((crx_ins->arg[number].constant != 1
1053                && crx_ins->arg[number].constant != 4)
1054              || (!IS_INSN_TYPE (ARITH_INS)
1055                  && !IS_INSN_TYPE (ARITH_BYTE_INS)
1056                  && !IS_INSN_TYPE (CMPBR_INS)))
1057             {
1058               /* Counting the number of bits required to represent
1059                  the constant.  */
1060               cnt = 0;
1061               temp = crx_ins->arg[number].constant - 1;
1062               while (temp > 0)
1063                 {
1064                   temp >>= 1;
1065                   cnt++;
1066                 }
1067               crx_ins->arg[number].size = cnt + 1;
1068               crx_ins->arg[number].constant =
1069                 ~(crx_ins->arg[number].constant) + 1;
1070               if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
1071                 {
1072                   char ptr[30];
1073                   LONGLONG temp64;
1074
1075                   /* Tomer - Originally the call was to 'strtoull', which isn't
1076                      identified by MSVC. Instead we check for overflow.  */
1077                   temp64 = strtoul (str, (char **) &ptr, 0);
1078                   if (cnt < 4)
1079                     crx_ins->arg[number].size = 5;
1080
1081                   if (IS_INSN_TYPE (ARITH_INS))
1082                     {
1083                       if (crx_ins->arg[number].size > 32
1084                           /* Tomer - check for overflow.  */
1085                           || (temp64 == ULONG_MAX))
1086                         {
1087                           if (crx_ins->arg[number].size > 32)
1088                             as_bad (_("In Instruction `%s': Immediate size is \
1089                                     %lu bits cannot be accomodated"),
1090                                     ins_parse, cnt + 1);
1091
1092                           /* Tomer - check for overflow.  */
1093                           if (temp64 == ULONG_MAX)
1094                             as_bad (_("Value given more than 32 bits in \
1095                                     Instruction `%s'"), ins_parse);
1096                         }
1097                     }
1098                   if (IS_INSN_TYPE (ARITH_BYTE_INS))
1099                     {
1100                       if (crx_ins->arg[number].size > 16
1101                           || !((temp64 & 0xFFFF0000) == 0xFFFF0000
1102                                || (temp64 & 0xFFFF0000) == 0x0))
1103                         {
1104                           if (crx_ins->arg[number].size > 16)
1105                             as_bad (_("In Instruction `%s': Immediate size is \
1106                                     %lu bits cannot be accomodated"),
1107                                     ins_parse, cnt + 1);
1108
1109                           if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
1110                                 || (temp64 & 0xFFFF0000) == 0x0))
1111                             as_bad (_("Value given more than 16 bits in \
1112                                     Instruction `%s'"), ins_parse);
1113                         }
1114                     }
1115                 }
1116               if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
1117                   && !post_inc_mode)
1118                 {
1119                   /* Cases handled ---
1120                      dispub4/dispuw4/dispud4 and for load store dispubwd4
1121                      is applicable only.  */
1122                   if (crx_ins->arg[number].size <= 4)
1123                     crx_ins->arg[number].size = 5;
1124                 }
1125               /* Argument number is checked to distinguish between
1126                  immediate and displacement in cmpbranch and bcopcond.  */
1127               if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1128                    && number == 2)
1129                 {
1130                   if (crx_ins->arg[number].size != 32)
1131                     crx_ins->arg[number].constant =
1132                       crx_ins->arg[number].constant >> 1;
1133                 }
1134
1135               mask_const (&crx_ins->arg[number].constant,
1136                           (int) crx_ins->arg[number].size);
1137             }
1138         }
1139       else
1140         {
1141           /* Argument number is checked to distinguish between
1142              immediate and displacement in cmpbranch and bcopcond.  */
1143           if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1144                   && number == 2)
1145                 || IS_INSN_TYPE (BRANCH_NEQ_INS))
1146             {
1147               if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1148                 {
1149                   if (crx_ins->arg[number].constant == 0)
1150                     as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
1151                 }
1152
1153               if (crx_ins->arg[number].constant % 2 != 0)
1154                 as_bad (_("Instruction `%s' has odd offset"), ins_parse);
1155
1156               if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1157                 {
1158                   if (crx_ins->arg[number].constant > 32
1159                       || crx_ins->arg[number].constant < 2)
1160                       as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1161                               ins_parse, crx_ins->arg[number].constant);
1162
1163                   crx_ins->arg[number].constant -= 2;
1164                 }
1165
1166               crx_ins->arg[number].constant =
1167                 crx_ins->arg[number].constant >> 1;
1168               get_number_of_bits (crx_ins, number);
1169             }
1170
1171           /* Compare branch argument number zero to be compared -
1172              mapped to cst4.  */
1173           if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
1174             {
1175               for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
1176                 {
1177                   if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
1178                     {
1179                       crx_ins->arg[number].constant = cst4_op->binary;
1180                       is_cst4 = 1;
1181                       break;
1182                     }
1183                 }
1184               if (!is_cst4)
1185                 as_bad (_("Instruction `%s' has invalid imm value as an \
1186                           operand"), ins_parse);
1187             }
1188         }
1189       break;
1190
1191     case O_symbol:
1192     case O_subtract:
1193       crx_ins->arg[number].constant = 0;
1194       relocatable = 1;
1195
1196       switch (crx_ins->arg[number].type)
1197         {
1198         case arg_cr:
1199           /* Have to consider various cases here --load/stor++[bwd] rbase, reg.  */
1200           if (IS_INSN_TYPE (LD_STOR_INS_INC))
1201             crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
1202           else if (IS_INSN_TYPE (CSTBIT_INS)
1203                    || IS_INSN_TYPE (STOR_IMM_INS))
1204             /* 'stor[bwd] imm' and '[stc]bit[bwd]'.  */
1205             crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
1206           else
1207             /* General load store instruction.  */
1208             crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
1209             break;
1210         case arg_icr:
1211           /* Index Mode 22 bits relocation.  */
1212             crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
1213           break;
1214         case arg_c:
1215           /* Absolute types.  */
1216           /* Case for jumps...dx  types.  */
1217           /* For bal.  */
1218           if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
1219             crx_ins->rtype = BFD_RELOC_CRX_REL16;
1220           else if (IS_INSN_TYPE (BRANCH_INS))
1221             {
1222               crx_ins->rtype = BFD_RELOC_CRX_REL8;
1223
1224               /* Overriding the above by the br_type_flag set above.  */
1225               switch (br_type_flag)
1226                 {
1227                 default:
1228                   break;
1229                 case 8:
1230                   crx_ins->rtype = BFD_RELOC_CRX_REL8;
1231                   break;
1232                 case 16:
1233                   crx_ins->rtype = BFD_RELOC_CRX_REL16;
1234                   break;
1235                 case 32:
1236                   crx_ins->rtype = BFD_RELOC_CRX_REL32;
1237                   break;
1238                 }
1239             }
1240           else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
1241                    || IS_INSN_TYPE (CSTBIT_INS))
1242             crx_ins->rtype = BFD_RELOC_CRX_ABS32;
1243           else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1244             crx_ins->rtype = BFD_RELOC_CRX_REL4;
1245           else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1246             {
1247               if (cmp_br_type_flag == 24)
1248                 crx_ins->rtype = BFD_RELOC_CRX_REL24;
1249               else
1250                 crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
1251             }
1252           break;
1253         case arg_ic:
1254         case arg_dc:
1255           if (IS_INSN_TYPE (ARITH_INS))
1256             crx_ins->rtype = BFD_RELOC_CRX_IMM32;
1257           else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1258             crx_ins->rtype = BFD_RELOC_CRX_IMM16;
1259           break;
1260         default:
1261           break;
1262       }
1263       crx_ins->arg[number].size = (bfd_reloc_type_lookup (stdoutput, crx_ins->rtype))->bitsize;
1264       break;
1265
1266     default:
1267       break;
1268     }
1269
1270   input_line_pointer = save;
1271   crx_ins->arg[number].signflag = signflag;
1272   return crx_ins->exp.X_op;
1273 }
1274
1275 /* Get the values of the scale to be encoded -
1276    used for the scaled index mode of addressing.  */
1277
1278 static int
1279 exponent2scale (int val)
1280 {
1281   int exponent;
1282
1283   /* If 'val' is 0, the following 'for' will be an endless loop.  */
1284   if (val == 0)
1285     return 0;
1286
1287   for (exponent = 0; (val != 1); val >>= 1, exponent++)
1288     ;
1289
1290   return exponent;
1291 }
1292
1293 /* This is used to set the index mode parameters. Used to set the attributes of
1294    an indexmode type of operand. op_num is the operand number.  */
1295
1296 static void
1297 set_indexmode_parameters (char *operand, ins * crx_ins, int op_num)
1298 {
1299   char address_str[30];
1300   char scale_str[MAX_OPERANDS];
1301   int scale_cnt = 0;
1302   char reg_name[MAX_REGNAME_LEN];
1303   char regindex_name[MAX_REGNAME_LEN];
1304   int i = 0;
1305   int reg_counter = 0, addr_cnt = 0, temp_int_val = 0;
1306
1307   switch (crx_ins->arg[op_num].type)
1308     {
1309     case arg_icr:
1310       while (operand[i] != '(')
1311         {
1312           address_str[addr_cnt++] = operand[i];
1313           i++;
1314         }
1315       address_str[addr_cnt] = '\0';
1316       process_label_constant (address_str, crx_ins, op_num);
1317       i++;
1318       reg_counter = 0;
1319       while (operand[i] != ',' && operand[i] != ' ')
1320         {
1321           reg_name[reg_counter++] = operand[i];
1322           i++;
1323         }
1324       reg_name[reg_counter] = '\0';
1325       if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1326         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1327                 reg_name, ins_parse);
1328
1329       i++;
1330       while (operand[i] == ' ')
1331         i++;
1332
1333       reg_counter = 0;
1334       while (operand[i] != ')' && operand[i] != ',')
1335         {
1336           regindex_name[reg_counter++] = operand[i];
1337           i++;
1338         }
1339       regindex_name[reg_counter] = '\0';
1340       reg_counter = 0;
1341       if ((crx_ins->arg[op_num].i_r = get_register (regindex_name))
1342             == nullregister)
1343         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1344                 regindex_name, ins_parse);
1345
1346       /* Setting the scale parameters.  */
1347       while (operand[i] == ' ')
1348         i++;
1349
1350       if (operand[i] == ')')
1351         crx_ins->arg[op_num].scale = 0;
1352       else
1353         {
1354           if (operand[i] == ',')
1355             i++;
1356
1357           while (operand[i] != ' ' && operand[i] != ')')
1358             {
1359               scale_str[scale_cnt++] = operand[i];
1360               i++;
1361             }
1362
1363           scale_str[scale_cnt] = '\0';
1364           /* Preprocess the scale string.  */
1365           if (strstr (scale_str, "0x") != NULL
1366               || strstr (scale_str, "0X") != NULL)
1367             {
1368               sscanf (scale_str, "%x", &temp_int_val);
1369               memset (&scale_str, '\0', sizeof (scale_str));
1370               sprintf (scale_str, "%d", temp_int_val);
1371             }
1372           /* Preprocess over.  */
1373           temp_int_val = atoi (scale_str);
1374
1375           if (temp_int_val != 1 && temp_int_val != 2
1376               && temp_int_val != 4 && temp_int_val != 8)
1377             as_bad (_("Illegal Scale - `%s'"), scale_str);
1378
1379           crx_ins->arg[op_num].scale = exponent2scale (temp_int_val);
1380         }
1381       break;
1382     default:
1383       break;
1384     }
1385 }
1386
1387 /* Parsing the operands of types
1388    - constants
1389    - rbase -> (register)
1390    - offset(rbase)
1391    - offset(rbase)+ - post increment mode.  */
1392
1393 static void
1394 set_cons_rparams (char *operand, ins * crx_ins, int op_num)
1395 {
1396   int i = 0, reg_count = 0;
1397   char reg_name[MAX_REGNAME_LEN];
1398   int change_flag = 0;
1399
1400   if (crx_ins->arg[op_num].type == arg_dc)
1401     change_flag = 1;
1402
1403   switch (crx_ins->arg[op_num].type)
1404     {
1405     case arg_sc: /* Case *+347.  */
1406     case arg_dc: /* Case $18.  */
1407       i++;
1408     case arg_c:/* Case where its a simple constant.  */
1409       process_label_constant (operand + i, crx_ins, op_num);
1410       crx_ins->arg[op_num].type = arg_c;
1411       break;
1412     case arg_dcr: /* Case $9(r13).  */
1413       operand++;
1414     case arg_cr: /* Case 9(r13.   */
1415       while (operand[i] != '(')
1416         i++;
1417       operand[i] = '\0';
1418       process_label_constant (operand, crx_ins, op_num);
1419       operand[i] = '(';
1420       i++;
1421       reg_count = 0;
1422       while (operand[i] != ')')
1423         {
1424           reg_name[reg_count] = operand[i];
1425           i++;
1426           reg_count++;
1427         }
1428       reg_name[reg_count] = '\0';
1429       if ((crx_ins->arg[op_num].r = get_register (reg_name)) == nullregister)
1430         as_bad (_("Illegal register `%s' in Instruction `%s'"),
1431                 reg_name, ins_parse);
1432
1433       crx_ins->arg[op_num].type = arg_cr;
1434       /* Post increment is represented in assembly as offset (register)+.  */
1435       if (strstr (operand + i, "+") != NULL)
1436         /* There is a plus after the ')'.  */
1437         post_inc_mode = 1;
1438       break;
1439     default:
1440       break;
1441     }
1442   if (change_flag == 1)
1443     crx_ins->arg[op_num].type = arg_ic;
1444 }
1445
1446 /* This is used to get the operand attributes -
1447    operand  - current operand to be used
1448    number - operand number
1449    crx_ins - current assembled instruction.  */
1450
1451 static void
1452 get_operandtype (char *operand, int number, ins * crx_ins)
1453 {
1454   int ret_val;
1455   char temp_operand[30];
1456
1457   switch (operand[0])
1458     {
1459     /* When it is a register.  */
1460     case 'r':
1461     case 'c':
1462     case 'i':
1463     case 'u':
1464     case 's':
1465     case 'p':
1466     case 'l':
1467     case 'h':
1468       /* Check whether this is a general processor register.  */
1469       ret_val = get_register (operand);
1470       if (ret_val != nullregister)
1471         {
1472           crx_ins->arg[number].type = arg_r;
1473           crx_ins->arg[number].r = ret_val;
1474           crx_ins->arg[number].size = REG_SIZE;
1475         }
1476       else
1477         {
1478           /* Check whether this is a core [special] coprocessor register.  */
1479           ret_val = get_copregister (operand);
1480           if (ret_val != nullcopregister)
1481             {
1482               crx_ins->arg[number].type = arg_copr;
1483               if (ret_val >= cs0)
1484                 crx_ins->arg[number].type = arg_copsr;
1485               crx_ins->arg[number].cr = ret_val;
1486               crx_ins->arg[number].size = REG_SIZE;
1487             }
1488           else
1489             {
1490               if (strchr (operand, '(') != NULL)
1491                 {
1492                   if (strchr (operand, ',') != NULL
1493                       && (strchr (operand, ',') > strchr (operand, '(')))
1494                     {
1495                       crx_ins->arg[number].type = arg_icr;
1496                       crx_ins->arg[number].constant = 0;
1497                       set_indexmode_parameters (operand, crx_ins, number);
1498                       get_number_of_bits (crx_ins, number);
1499                       return;
1500                     }
1501                   else
1502                     crx_ins->arg[number].type = arg_cr;
1503                 }
1504               else
1505                 crx_ins->arg[number].type = arg_c;
1506               crx_ins->arg[number].constant = 0;
1507               set_cons_rparams (operand, crx_ins, number);
1508               get_number_of_bits (crx_ins, number);
1509             }
1510         }
1511       break;
1512     case '$':
1513       if (strchr (operand, '(') != NULL)
1514         crx_ins->arg[number].type = arg_dcr;
1515       else
1516         crx_ins->arg[number].type = arg_dc;
1517       crx_ins->arg[number].constant = 0;
1518       set_cons_rparams (operand, crx_ins, number);
1519       get_number_of_bits (crx_ins, number);
1520       break;
1521
1522     case '(':
1523       /* Augmenting a zero in front of an operand -- won't work for tbit/sbit.  */
1524       strcpy (temp_operand, "0");
1525       strcat (temp_operand, operand);
1526       if (strchr (temp_operand, ',') != NULL
1527           && (strchr (temp_operand, ',') > strchr (temp_operand, '(')))
1528         {
1529           crx_ins->arg[number].type = arg_icr;
1530           crx_ins->arg[number].constant = 0;
1531           set_indexmode_parameters (temp_operand, crx_ins, number);
1532           get_number_of_bits (crx_ins, number);
1533           return;
1534         }
1535       else
1536         {
1537           crx_ins->arg[number].type = arg_cr;
1538           crx_ins->arg[number].constant = 0;
1539           set_cons_rparams (operand, crx_ins, number);
1540           get_number_of_bits (crx_ins, number);
1541           if ((! strneq (instruction->mnemonic, "load", 4))
1542               && (! strneq (instruction->mnemonic, "stor", 4)))
1543             {
1544               crx_ins->arg[number].type = arg_rbase;
1545               crx_ins->arg[number].size = REG_SIZE;
1546             }
1547           return;
1548         }
1549       break;
1550     case '*':
1551       crx_ins->arg[number].type = arg_sc;
1552       crx_ins->arg[number].constant = 0;
1553       set_cons_rparams (operand, crx_ins, number);
1554       get_number_of_bits (crx_ins, number);
1555       break;
1556     case '+':
1557     case '-':
1558     case '0':
1559     case '1':
1560     case '2':
1561     case '3':
1562     case '4':
1563     case '5':
1564     case '6':
1565     case '7':
1566     case '8':
1567     case '9':
1568       if (strchr (operand, '(') != NULL)
1569         {
1570           if (strchr (operand, ',') != NULL
1571               && (strchr (operand, ',') > strchr (operand, '(')))
1572             {
1573               crx_ins->arg[number].type = arg_icr;
1574               crx_ins->arg[number].constant = 0;
1575               set_indexmode_parameters (operand, crx_ins, number);
1576               get_number_of_bits (crx_ins, number);
1577               return;
1578             }
1579           else
1580             crx_ins->arg[number].type = arg_cr;
1581         }
1582       else
1583         crx_ins->arg[number].type = arg_c;
1584       crx_ins->arg[number].constant = 0;
1585       set_cons_rparams (operand, crx_ins, number);
1586       get_number_of_bits (crx_ins, number);
1587       break;
1588     default:
1589       if (strchr (operand, '(') != NULL)
1590         {
1591           if (strchr (operand, ',') != NULL
1592               && (strchr (operand, ',') > strchr (operand, '(')))
1593             {
1594               crx_ins->arg[number].type = arg_icr;
1595               crx_ins->arg[number].constant = 0;
1596               set_indexmode_parameters (operand, crx_ins, number);
1597               get_number_of_bits (crx_ins, number);
1598               return;
1599             }
1600           else
1601             crx_ins->arg[number].type = arg_cr;
1602         }
1603       else
1604         crx_ins->arg[number].type = arg_c;
1605       crx_ins->arg[number].constant = 0;
1606       set_cons_rparams (operand, crx_ins, number);
1607       get_number_of_bits (crx_ins, number);
1608       break;
1609     }
1610 }
1611
1612 /* Operands are parsed over here, separated into various operands. Each operand
1613    is then analyzed to fillup the fields in the crx_ins data structure.  */
1614
1615 static void
1616 parse_operands (ins * crx_ins, char *operands)
1617 {
1618   char *operandS;              /* Operands string.  */
1619   char *operandH, *operandT;   /* Single operand head/tail pointers.  */
1620   int allocated = 0;           /* Indicates a new operands string was allocated.  */
1621   char *operand[MAX_OPERANDS]; /* Separating the operands.  */
1622   int op_num = 0;              /* Current operand number we are parsing.  */
1623   int bracket_flag = 0;        /* Indicates a bracket '(' was found.  */
1624   int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
1625
1626   /* Preprocess the list of registers, if necessary.  */
1627   operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
1628     preprocess_reglist (operands, &allocated) : operands;
1629
1630   while (*operandT != '\0')
1631     {
1632       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1633         {
1634           *operandT++ = '\0';
1635           operand[op_num++] = strdup (operandH);
1636           operandH = operandT;
1637           continue;
1638         }
1639
1640       if (*operandT == ' ')
1641         as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1642
1643       if (*operandT == '(')
1644         bracket_flag = 1;
1645       else if (*operandT == '[')
1646         sq_bracket_flag = 1;
1647
1648       if (*operandT == ')')
1649         {
1650           if (bracket_flag)
1651             bracket_flag = 0;
1652           else
1653             as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1654         }
1655       else if (*operandT == ']')
1656         {
1657           if (sq_bracket_flag)
1658             sq_bracket_flag = 0;
1659           else
1660             as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1661         }
1662
1663       if (bracket_flag == 1 && *operandT == ')')
1664         bracket_flag = 0;
1665       else if (sq_bracket_flag == 1 && *operandT == ']')
1666         sq_bracket_flag = 0;
1667
1668       operandT++;
1669     }
1670
1671   /* Adding the last operand.  */
1672   operand[op_num++] = strdup (operandH);
1673   crx_ins->nargs = op_num;
1674
1675   /* Verifying correct syntax of operands (all brackets should be closed).  */
1676   if (bracket_flag || sq_bracket_flag)
1677     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1678
1679   /* Now to recongnize the operand types.  */
1680   for (op_num = 0; op_num < crx_ins->nargs; op_num++)
1681     {
1682       get_operandtype (operand[op_num], op_num, crx_ins);
1683       free (operand[op_num]);
1684     }
1685
1686   if (allocated)
1687     free (operandS);
1688 }
1689
1690 /* Get the trap index in dispatch table, given its name.
1691    This routine is used by assembling the 'excp' instruction.  */
1692
1693 static int
1694 gettrap (char *s)
1695 {
1696   const trap_entry *trap;
1697
1698   for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
1699     if (streq (trap->name, s))
1700       return trap->entry;
1701
1702   as_bad (_("Unknown exception: `%s'"), s);
1703   return 0;
1704 }
1705
1706 /* Post-Increment instructions are a sub-group within load/stor instruction
1707    groups. Therefore, when parsing a Post-Increment insn, we have to advance
1708    the instruction pointer to the start of that sub-group.  */
1709
1710 static void
1711 handle_pi_insn (char *operands)
1712 {
1713   /* Assuming Post-Increment insn has the following format :
1714      'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').  */
1715   if (strstr (operands, ")+") != NULL)
1716     while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1717       instruction++;
1718 }
1719
1720 /* Top level module where instruction parsing starts.
1721    crx_ins - data structure holds some information.
1722    operands - holds the operands part of the whole instruction.  */
1723
1724 static void
1725 parse_insn (ins *insn, char *operands)
1726 {
1727   /* Handle 'excp'/'cinv' */
1728   if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1729     {
1730       insn->nargs = 1;
1731       insn->arg[0].type = arg_ic;
1732       insn->arg[0].size = 4;
1733       insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1734         gettrap (operands) : get_cinv_parameters (operands);
1735       return;
1736     }
1737
1738   /* Handle load/stor post-increment instructions.  */
1739   if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS))
1740     handle_pi_insn (operands);
1741
1742   if (operands != NULL)
1743     parse_operands (insn, operands);
1744 }
1745
1746 /* Cinv instruction requires special handling.  */
1747
1748 static int
1749 get_cinv_parameters (char * operand)
1750 {
1751   char *p = operand;
1752   int d_used = 0, i_used = 0, u_used = 0;
1753
1754   while (*++p != ']')
1755     {
1756       if (*p == ',' || *p == ' ')
1757         continue;
1758
1759       if (*p == 'd')
1760         d_used = 1;
1761       else if (*p == 'i')
1762         i_used = 1;
1763       else if (*p == 'u')
1764         u_used = 1;
1765       else
1766         as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1767     }
1768
1769   return ((d_used ? 4 : 0)
1770         + (i_used ? 2 : 0)
1771         + (u_used ? 1 : 0));
1772 }
1773
1774 /* Retrieve the opcode image of a given register.
1775    If the register is illegal for the current instruction,
1776    issue an error.  */
1777
1778 static int
1779 getreg_image (reg r)
1780 {
1781   const reg_entry *reg;
1782   char *reg_name;
1783   int special_register_flag = 0;
1784   int movpr_flag = 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1785
1786   if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1787     movpr_flag = 1;
1788
1789   if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number == 1))
1790       || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number == 0)) )
1791     special_register_flag = 1;
1792
1793   /* Check whether the register is in registers table.  */
1794   if (r < MAX_REG)
1795     reg = &crx_regtab[r];
1796   /* Check whether the register is in coprocessor registers table.  */
1797   else if (r < MAX_COPREG)
1798     reg = &crx_copregtab[r-MAX_REG];
1799   /* Register not found.  */
1800   else
1801     {
1802       as_bad (_("Unknown register: `%d'"), r);
1803       return 0;
1804     }
1805
1806   reg_name = reg->name;
1807
1808 /* Issue a error message when register is illegal.  */
1809 #define IMAGE_ERR \
1810   as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1811             reg_name, ins_parse);                            \
1812   break;
1813
1814   switch (reg->type)
1815   {
1816     case CRX_U_REGTYPE:
1817     case CRX_CFG_REGTYPE:
1818     case CRX_MTPR_REGTYPE:
1819       if (movpr_flag && special_register_flag)
1820         return reg->image;
1821       else
1822         IMAGE_ERR;
1823
1824     case CRX_R_REGTYPE:
1825     case CRX_C_REGTYPE:
1826     case CRX_CS_REGTYPE:
1827       if (!(movpr_flag && special_register_flag))
1828         return reg->image;
1829       else
1830         IMAGE_ERR;
1831
1832     default:
1833       IMAGE_ERR;
1834   }
1835
1836   return 0;
1837 }
1838
1839 /* Routine used to get the binary-string equivalent of a integer constant
1840    which currently require currbits to represent itself to be extended to
1841    nbits.  */
1842
1843 static unsigned long int
1844 getconstant (unsigned long int x, int nbits)
1845 {
1846   int cnt = 0;
1847   unsigned long int temp = x;
1848
1849   while (temp > 0)
1850     {
1851       temp >>= 1;
1852       cnt++;
1853     }
1854
1855   /* Escape sequence to next 16bit immediate.  */
1856   if (cnt > nbits)
1857     as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1858             x, cnt, ins_parse);
1859   else
1860     {
1861       if (signflag)
1862         x |= SET_BITS_MASK (cnt, nbits - cnt);
1863       else
1864         x &= CLEAR_BITS_MASK (cnt, nbits - cnt);
1865     }
1866
1867   /* The following expression avoids overflow if
1868      'nbits' is the number of bits in 'bfd_vma'.  */
1869   return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1870 }
1871
1872 /* Print a constant value to 'output_opcode':
1873    ARG holds the operand's type and value.
1874    SHIFT represents the location of the operand to be print into.
1875    NBITS determines the size (in bits) of the constant.  */
1876
1877 static void
1878 print_constant (int nbits, int shift, argument *arg)
1879 {
1880   unsigned long mask = 0;
1881
1882   long constant = getconstant (arg->constant, nbits);
1883
1884   switch (nbits)
1885   {
1886     case 32:
1887     case 28:
1888     case 24:
1889     case 22:
1890       /* mask the upper part of the constant, that is, the bits
1891          going to the lowest byte of output_opcode[0].
1892          The upper part of output_opcode[1] is always filled,
1893          therefore it is always masked with 0xFFFF.  */
1894       mask = (1 << (nbits - 16)) - 1;
1895       /* Divide the constant between two consecutive words :
1896                  0         1         2         3
1897             +---------+---------+---------+---------+
1898             |         | X X X X | X X X X |         |
1899             +---------+---------+---------+---------+
1900               output_opcode[0]    output_opcode[1]     */
1901
1902       CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1903       CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1904       break;
1905
1906     case 16:
1907     case 12:
1908       /* Special case - in arg_cr, the SHIFT represents the location
1909          of the REGISTER, not the constant, which is itself not shifted.  */
1910       if (arg->type == arg_cr)
1911         {
1912           CRX_PRINT (0, constant,  0);
1913           break;
1914         }
1915
1916       /* When instruction size is 3, a 16-bit constant is always
1917          filling the upper part of output_opcode[1].  */
1918       if (instruction->size > 2)
1919         CRX_PRINT (1, constant, WORD_SHIFT);
1920       else
1921         CRX_PRINT (0, constant, shift);
1922       break;
1923
1924     default:
1925       CRX_PRINT (0, constant,  shift);
1926       break;
1927   }
1928 }
1929
1930 /* Print an operand to 'output_opcode', which later on will be
1931    printed to the object file:
1932    ARG holds the operand's type, size and value.
1933    SHIFT represents the printing location of operand.
1934    NBITS determines the size (in bits) of a constant operand.  */
1935
1936 static void
1937 print_operand (int nbits, int shift, argument *arg)
1938 {
1939   switch (arg->type)
1940     {
1941     case arg_r:
1942       CRX_PRINT (0, getreg_image (arg->r), shift);
1943       break;
1944
1945     case arg_copr:
1946       if (arg->cr < c0 || arg->cr > c15)
1947         as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1948                 ins_parse);
1949       CRX_PRINT (0, getreg_image (arg->cr), shift);
1950       break;
1951
1952     case arg_copsr:
1953       if (arg->cr < cs0 || arg->cr > cs15)
1954         as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1955                 ins_parse);
1956       CRX_PRINT (0, getreg_image (arg->cr), shift);
1957       break;
1958
1959     case arg_ic:
1960       print_constant (nbits, shift, arg);
1961       break;
1962
1963     case arg_icr:
1964       /*    16      12        8    6         0
1965             +--------------------------------+
1966             |  reg   | r_base | scl|  disp   |
1967             +--------------------------------+    */
1968       CRX_PRINT (0, getreg_image (arg->r), 12);
1969       CRX_PRINT (0, getreg_image (arg->i_r), 8);
1970       CRX_PRINT (0, arg->scale, 6);
1971       print_constant (nbits, shift, arg);
1972       break;
1973
1974     case arg_rbase:
1975       CRX_PRINT (0, getreg_image (arg->r), shift);
1976       break;
1977
1978     case arg_cr:
1979       /* case base_cst4.  */
1980       if ((instruction->flags & CST4MAP) && cst4flag)
1981         output_opcode[0] |= (getconstant (arg->constant, nbits)
1982                              << (shift + REG_SIZE));
1983       else
1984         /* rbase_dispu<NN> and other such cases.  */
1985         print_constant (nbits, shift, arg);
1986       /* Add the register argument to the output_opcode.  */
1987       CRX_PRINT (0, getreg_image (arg->r), shift);
1988       break;
1989
1990     case arg_c:
1991       print_constant (nbits, shift, arg);
1992       break;
1993
1994     default:
1995       break;
1996     }
1997 }
1998
1999 /* Retrieve the number of operands for the current assembled instruction.  */
2000
2001 static int
2002 get_number_of_operands (void)
2003 {
2004   int i;
2005
2006   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
2007     ;
2008   return i;
2009 }
2010
2011 /* Assemble a single instruction :
2012    Instruction has been parsed and all operand values set appropriately.
2013    Algorithm for assembling -
2014    For instruction to be assembled:
2015     Step 1: Find instruction in the array crx_instruction with same mnemonic.
2016     Step 2: Find instruction with same operand types.
2017     Step 3: If (size_of_operands) match then done, else increment the
2018             array_index and goto Step3.
2019     Step 4: Cannot assemble
2020    Returns 1 upon success, 0 upon failure.  */
2021
2022 static int
2023 assemble_insn (char *mnemonic, ins *insn)
2024 {
2025   /* Argument type of each operand in the instruction we are looking for.  */
2026   argtype atyp[MAX_OPERANDS];
2027   /* Argument type of each operand in the current instruction.  */
2028   argtype atyp_act[MAX_OPERANDS];
2029   /* Size (in bits) of each operand in the instruction we are looking for.  */
2030   int bits[MAX_OPERANDS];
2031   /* Size (in bits) of each operand in the current instruction.  */
2032   int bits_act[MAX_OPERANDS];
2033   /* Location (in bits) of each operand in the current instruction.  */
2034   int shift_act[MAX_OPERANDS];
2035   int match = 0;
2036   int done_flag = 0;
2037   int cst4maptype = 0;
2038   int changed_already = 0;
2039   unsigned int temp_value = 0;
2040   int instrtype, i;
2041   /* A pointer to the argument's constant value.  */
2042   unsigned long int *cons;
2043   /* Pointer to loop over all cst4_map entries.  */
2044   const cst4_entry *cst4_op;
2045
2046   /* Instruction has no operands -> copy only the constant opcode.   */
2047   if (insn->nargs == 0)
2048     {
2049       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2050       return 1;
2051     }
2052
2053   /* Find instruction with same number of operands.  */
2054   while (get_number_of_operands () != insn->nargs
2055          && IS_INSN_MNEMONIC (mnemonic))
2056     instruction++;
2057
2058   if (!IS_INSN_MNEMONIC (mnemonic))
2059     return 0;
2060
2061   /* Initialize argument type and size of each given operand.  */
2062   for (i = 0; i < insn->nargs; i++)
2063     {
2064       atyp[i] = insn->arg[i].type;
2065       bits[i] = insn->arg[i].size;
2066     }
2067
2068   /* Initialize argument type and size of each operand in current inst.  */
2069   GET_ACTUAL_TYPE;
2070   GET_ACTUAL_SIZE;
2071
2072   while (match != 1
2073          /* Check we didn't get to end of table.  */
2074          && instruction->mnemonic != NULL
2075          /* Check that the actual mnemonic is still available.  */
2076          && IS_INSN_MNEMONIC (mnemonic))
2077     {
2078       /* Check for argement type compatibility.  */
2079       for (i = 0; i < insn->nargs; i++)
2080         {
2081           if (atyp_act[i] == atyp[i])
2082             done_flag = 1;
2083           else
2084             {
2085               done_flag = 0;
2086               break;
2087             }
2088         }
2089       if (done_flag)
2090         {
2091           /* Check for post inc mode of the current instruction.  */
2092           if (post_inc_mode == 1 || IS_INSN_TYPE (LD_STOR_INS_INC))
2093             done_flag = (post_inc_mode == IS_INSN_TYPE (LD_STOR_INS_INC));
2094         }
2095
2096       if (done_flag == 0)
2097         {
2098           /* Try again with next instruction.  */
2099           instruction++;
2100           GET_ACTUAL_TYPE;
2101           GET_ACTUAL_SIZE;
2102           continue;
2103         }
2104       else
2105         {
2106           /* Check for size compatibility.  */
2107           for (i = 0; i < insn->nargs; i++)
2108             {
2109               if (bits[i] > bits_act[i])
2110                 {
2111                   /* Actual size is too small - try again.  */
2112                   done_flag = 0;
2113                   instruction++;
2114                   GET_ACTUAL_TYPE;
2115                   GET_ACTUAL_SIZE;
2116                   break;
2117                 }
2118             }
2119
2120         }
2121
2122       if (done_flag == 1)
2123         {
2124           /* Full match is found.  */
2125           match = 1;
2126           break;
2127         }
2128     }
2129
2130   if (match == 0)
2131     /* We haven't found a match - instruction can't be assembled.  */
2132     return 0;
2133   else
2134     /* Full match - print the final image.  */
2135     {
2136       /* Handle positive constants.  */
2137       if (!signflag)
2138         {
2139           if (IS_INSN_TYPE (LD_STOR_INS) && !relocatable)
2140             {
2141               /* Get the map type of the instruction.  */
2142               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2143               cons = &insn->arg[instrtype].constant;
2144               cst4maptype = instruction->flags & CST4MAP;
2145
2146               switch (cst4maptype)
2147                 {
2148                 case DISPUB4:
2149                   /* 14 and 15 are reserved escape sequences of dispub4.  */
2150                   if (*cons == 14 || *cons == 15)
2151                     {
2152                       instruction++;
2153                       GET_ACTUAL_SIZE;
2154                     }
2155                   break;
2156
2157                 case DISPUW4:
2158                   /* Mapping has to be done.  */
2159                   if (*cons <= 15 && *cons % 2 != 0)
2160                     {
2161                       instruction++;
2162                       GET_ACTUAL_SIZE;
2163                     }
2164                   else if (*cons > 15 && *cons < 27 && *cons % 2 == 0)
2165                     {
2166                       instruction--;
2167                       GET_ACTUAL_SIZE;
2168                     }
2169                   if (*cons < 27 && *cons % 2 == 0)
2170                     *cons /= 2;
2171                   break;
2172
2173                 case DISPUD4:
2174                   /* Mapping has to be done.  */
2175                   if (*cons <= 15 && *cons % 4 != 0)
2176                     {
2177                       instruction++;
2178                       GET_ACTUAL_SIZE;
2179                     }
2180                   else if (*cons > 15 && *cons < 53 && *cons % 4 == 0)
2181                     {
2182                       instruction--;
2183                       GET_ACTUAL_SIZE;
2184                     }
2185                   if (*cons < 53 && *cons % 4 == 0)
2186                     *cons /= 4;
2187                   break;
2188                 default:
2189                   break;
2190               }
2191             }
2192           if ((IS_INSN_TYPE (ARITH_BYTE_INS) || IS_INSN_TYPE (ARITH_INS))
2193                && !relocatable)
2194             {
2195               /* Check whether a cst4 mapping has to be done.  */
2196               if ((instruction->operands[0].op_type == cst4
2197                     || instruction->operands[0].op_type == i16)
2198                   && (instruction->operands[1].op_type == regr))
2199                 {
2200                   /* 'const' equals reserved escape sequences -->>
2201                      represent as i16.  */
2202                   if (insn->arg[0].constant == ESC_16
2203                       || insn->arg[0].constant == ESC_32)
2204                     {
2205                       instruction++;
2206                       GET_ACTUAL_SIZE;
2207                     }
2208                   else
2209                     {
2210                       /* Loop over cst4_map entries.  */
2211                       for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps);
2212                            cst4_op++)
2213                         {
2214                           /* 'const' equals a binary, which is already mapped
2215                              by a different value -->> represent as i16.  */
2216                           if (insn->arg[0].constant == (unsigned int)cst4_op->binary
2217                               && cst4_op->binary != cst4_op->value)
2218                             {
2219                               instruction++;
2220                               GET_ACTUAL_SIZE;
2221                             }
2222                           /* 'const' equals a value bigger than 16 -->> map to
2223                              its binary and represent as cst4.  */
2224                           else if (insn->arg[0].constant == (unsigned int)cst4_op->value
2225                                    && insn->arg[0].constant >= 16)
2226                             {
2227                               instruction--;
2228                               insn->arg[0].constant = cst4_op->binary;
2229                               GET_ACTUAL_SIZE;
2230                             }
2231                         }
2232                     }
2233                 }
2234               /* Special check for 'addub 0, r0' instruction -
2235                  The opcode '0000 0000 0000 0000' is not allowed.  */
2236               if (IS_INSN_MNEMONIC ("addub"))
2237                 {
2238                   if ((instruction->operands[0].op_type == cst4)
2239                       && instruction->operands[1].op_type == regr)
2240                     {
2241                       if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
2242                         instruction++;
2243                     }
2244                 }
2245             }
2246           if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
2247               || IS_INSN_TYPE (LD_STOR_INS_INC))
2248             {
2249               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2250               if (instruction->operands[instrtype].op_type == rbase)
2251                 instruction++;
2252             }
2253           /* Error checking in case of post-increment instruction.  */
2254           if (IS_INSN_TYPE (LD_STOR_INS_INC))
2255             {
2256               if (!((strneq (instruction->mnemonic, "stor", 4))
2257                     && (insn->arg[0].type != arg_r)))
2258                 if (insn->arg[0].r == insn->arg[1].r)
2259                   as_bad (_("Invalid instruction : `%s' Source and Destination register \
2260                           same in Post INC mode"), ins_parse);
2261             }
2262           if (IS_INSN_TYPE (CSTBIT_INS) && !relocatable)
2263             {
2264               if (instruction->operands[1].op_type == rbase_dispu12)
2265                 {
2266                   if (insn->arg[1].constant == 0)
2267                     {
2268                       instruction--;
2269                       GET_ACTUAL_SIZE;
2270                     }
2271                 }
2272             }
2273           if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS)
2274                || IS_INSN_TYPE (STOR_IMM_INS)
2275                || IS_INSN_TYPE (LD_STOR_INS_INC)) & !relocatable)
2276             {
2277               instrtype = instruction->flags & REVERSE_MATCH ? 0 : 1;
2278               changed_already = 0;
2279               /* Convert 32 bits accesses to 16 bits accesses.  */
2280               if (instruction->operands[instrtype].op_type == abs32)
2281                 {
2282                   if ((insn->arg[instrtype].constant & 0xFFFF0000) == 0xFFFF0000)
2283                     {
2284                       instruction--;
2285                       insn->arg[instrtype].constant =
2286                         insn->arg[instrtype].constant & 0xFFFF;
2287                       insn->arg[instrtype].size = 16;
2288                       changed_already = 1;
2289                       GET_ACTUAL_SIZE;
2290                     }
2291                 }
2292               /* Convert 16 bits accesses to 32 bits accesses.  */
2293               if (instruction->operands[instrtype].op_type == abs16
2294                   && changed_already != 1)
2295                 {
2296                   instruction++;
2297                   insn->arg[instrtype].constant =
2298                     insn->arg[instrtype].constant & 0xFFFF;
2299                   insn->arg[instrtype].size = 32;
2300                   GET_ACTUAL_SIZE;
2301                 }
2302               changed_already = 0;
2303             }
2304           if (IS_INSN_TYPE (BRANCH_INS) && !relocatable)
2305             {
2306               /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
2307               if (insn->arg[0].constant == 0x7e || insn->arg[0].constant == 0x7f)
2308                 {
2309                   instruction++;
2310                   GET_ACTUAL_SIZE;
2311                 }
2312             }
2313         }
2314
2315       for (i = 0; i < insn->nargs; i++)
2316         {
2317           if (instruction->operands[i].op_type == cst4
2318               || instruction->operands[i].op_type == rbase_cst4)
2319             cst4flag = 1;
2320         }
2321
2322       /* First, copy the instruction's opcode.  */
2323       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2324
2325       /* Swap the argument values in case bcop instructions.  */
2326       if (IS_INSN_TYPE (COP_BRANCH_INS))
2327         {
2328           temp_value = insn->arg[0].constant;
2329           insn->arg[0].constant = insn->arg[1].constant;
2330           insn->arg[1].constant = temp_value;
2331         }
2332
2333       for (i = 0; i < insn->nargs; i++)
2334         {
2335           shift_act[i] = instruction->operands[i].shift;
2336           signflag = insn->arg[i].signflag;
2337           processing_arg_number = i;
2338           print_operand (bits_act[i], shift_act[i], &insn->arg[i]);
2339         }
2340     }
2341
2342   return 1;
2343 }
2344
2345 /* Set the appropriate bit for register 'r' in 'mask'.
2346    This indicates that this register is loaded or stored by
2347    the instruction.  */
2348
2349 static void
2350 mask_reg (int r, unsigned short int *mask)
2351 {
2352   if ((reg)r > (reg)sp)
2353     {
2354       as_bad (_("Invalid Register in Register List"));
2355       return;
2356     }
2357
2358   *mask |= (1 << r);
2359 }
2360
2361 /* Preprocess register list - create a 16-bit mask with one bit for each
2362    of the 16 general purpose registers. If a bit is set, it indicates
2363    that this register is loaded or stored by the instruction.  */
2364
2365 static char *
2366 preprocess_reglist (char *param, int *allocated)
2367 {
2368   char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
2369   char *regP;                     /* Pointer to 'reg_name' string.  */
2370   int reg_counter = 0;            /* Count number of parsed registers.  */
2371   unsigned short int mask = 0;    /* Mask for 16 general purpose registers.  */
2372   char *new_param;                /* New created operands string.  */
2373   char *paramP = param;           /* Pointer to original opearands string.  */
2374   char maskstring[10];            /* Array to print the mask as a string.  */
2375   reg r;
2376   copreg cr;
2377
2378   /* If 'param' is already in form of a number, no need to preprocess.  */
2379   if (strchr (paramP, '{') == NULL)
2380     return param;
2381
2382   /* Verifying correct syntax of operand.  */
2383   if (strchr (paramP, '}') == NULL)
2384     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
2385
2386   while (*paramP++ != '{');
2387
2388   new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
2389   *allocated = 1;
2390   strncpy (new_param, param, paramP - param - 1);
2391
2392   while (*paramP != '}')
2393     {
2394       regP = paramP;
2395       memset (&reg_name, '\0', sizeof (reg_name));
2396
2397       while (ISALNUM (*paramP))
2398         paramP++;
2399
2400       strncpy (reg_name, regP, paramP - regP);
2401
2402       if (IS_INSN_TYPE (COP_REG_INS))
2403         {
2404           if ((cr = get_copregister (reg_name)) == nullcopregister)
2405             as_bad (_("Illegal register `%s' in cop-register list"), reg_name);
2406           mask_reg (getreg_image (cr - c0), &mask);
2407         }
2408       else
2409         {
2410           if ((r = get_register (reg_name)) == nullregister)
2411             as_bad (_("Illegal register `%s' in register list"), reg_name);
2412           mask_reg (getreg_image (r), &mask);
2413         }
2414
2415       if (++reg_counter > MAX_REGS_IN_MASK16)
2416         as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2417                 MAX_REGS_IN_MASK16);
2418
2419       while (!ISALNUM (*paramP) && *paramP != '}')
2420           paramP++;
2421     }
2422
2423   if (*++paramP != '\0')
2424     as_warn (_("rest of line ignored; first ignored character is `%c'"),
2425              *paramP);
2426
2427   if (mask == 0)
2428     as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2429             ins_parse);
2430
2431   sprintf (maskstring, "$0x%x", mask);
2432   strcat (new_param, maskstring);
2433   return new_param;
2434 }
2435
2436 /* Print the instruction.
2437    Handle also cases where the instruction is relaxable/relocatable.  */
2438
2439 void
2440 print_insn (ins *insn)
2441 {
2442   unsigned int i, j, insn_size;
2443   char *this_frag;
2444   unsigned short words[4];
2445
2446   /* Arrange the insn encodings in a WORD size array.  */
2447   for (i = 0, j = 0; i < 2; i++)
2448     {
2449       words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2450       words[j++] = output_opcode[i] & 0xFFFF;
2451     }
2452
2453   /* Handle relaxtion.  */
2454   if ((instruction->flags & RELAXABLE) && relocatable)
2455     {
2456       int relax_subtype;
2457
2458       /* Write the maximal instruction size supported.  */
2459       insn_size = INSN_MAX_SIZE;
2460
2461       /* bCC  */
2462       if (IS_INSN_TYPE (BRANCH_INS))
2463         relax_subtype = 0;
2464       /* bal  */
2465       else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
2466         relax_subtype = 3;
2467       /* cmpbr  */
2468       else if (IS_INSN_TYPE (CMPBR_INS))
2469         relax_subtype = 5;
2470       else
2471         abort ();
2472
2473       this_frag = frag_var (rs_machine_dependent, insn_size * 2,
2474                             4, relax_subtype,
2475                             insn->exp.X_add_symbol,
2476                             insn->exp.X_add_number,
2477                             0);
2478     }
2479   else
2480     {
2481       insn_size = instruction->size;
2482       this_frag = frag_more (insn_size * 2);
2483
2484       /* Handle relocation.  */
2485       if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2486         {
2487           reloc_howto_type *reloc_howto;
2488           int size;
2489
2490           reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2491
2492           if (!reloc_howto)
2493             abort ();
2494
2495           size = bfd_get_reloc_size (reloc_howto);
2496
2497           if (size < 1 || size > 4)
2498             abort ();
2499
2500           fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2501                        size, &insn->exp, reloc_howto->pc_relative,
2502                        insn->rtype);
2503         }
2504     }
2505
2506   /* Write the instruction encoding to frag.  */
2507   for (i = 0; i < insn_size; i++)
2508     {
2509       md_number_to_chars (this_frag, (valueT) words[i], 2);
2510       this_frag += 2;
2511     }
2512 }
2513
2514 /* This is the guts of the machine-dependent assembler.  OP points to a
2515    machine dependent instruction.  This function is supposed to emit
2516    the frags/bytes it assembles to.  */
2517
2518 void
2519 md_assemble (char *op)
2520 {
2521   ins crx_ins;
2522   char *param;
2523   char c;
2524
2525   /* Reset global variables for a new instruction.  */
2526   reset_vars (op, &crx_ins);
2527
2528   /* Strip the mnemonic.  */
2529   for (param = op; *param != 0 && !ISSPACE (*param); param++)
2530     ;
2531   c = *param;
2532   *param++ = '\0';
2533
2534   /* Find the instruction.  */
2535   instruction = (const inst *) hash_find (crx_inst_hash, op);
2536   if (instruction == NULL)
2537     {
2538       as_bad (_("Unknown opcode: `%s'"), op);
2539       return;
2540     }
2541
2542   /* Tie dwarf2 debug info to the address at the start of the insn.  */
2543   dwarf2_emit_insn (0);
2544
2545   if (NO_OPERANDS_INST (op))
2546     /* Handle instructions with no operands.  */
2547     crx_ins.nargs = 0;
2548   else
2549     /* Parse the instruction's operands.  */
2550     parse_insn (&crx_ins, param);
2551
2552   /* Assemble the instruction.  */
2553   if (assemble_insn (op, &crx_ins) == 0)
2554     {
2555       as_bad (_("Illegal operands in instruction : `%s'"), ins_parse);
2556       return;
2557     }
2558
2559   /* Print the instruction.  */
2560   print_insn (&crx_ins);
2561 }