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