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