1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2    Copyright (C) 2004-2020 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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
23    MA 02110-1301, USA.  */
24 
25 #include "as.h"
26 #include "bfd_stdint.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "opcode/crx.h"
30 #include "elf/crx.h"
31 
32 /* Word is considered here as a 16-bit unsigned short int.  */
33 #define WORD_SHIFT  16
34 
35 /* Register is 4-bit size.  */
36 #define REG_SIZE   4
37 
38 /* Maximum size of a single instruction (in words).  */
39 #define INSN_MAX_SIZE   3
40 
41 /* Maximum bits which may be set in a `mask16' operand.  */
42 #define MAX_REGS_IN_MASK16  8
43 
44 /* Utility macros for string comparison.  */
45 #define streq(a, b)           (strcmp (a, b) == 0)
46 #define strneq(a, b, c)       (strncmp (a, b, c) == 0)
47 
48 /* Assign a number NUM, shifted by SHIFT bytes, into a location
49    pointed by index BYTE of array 'output_opcode'.  */
50 #define CRX_PRINT(BYTE, NUM, SHIFT)   output_opcode[BYTE] |= (NUM) << (SHIFT)
51 
52 /* Operand errors.  */
53 typedef enum
54   {
55     OP_LEGAL = 0,	/* Legal operand.  */
56     OP_OUT_OF_RANGE,	/* Operand not within permitted range.  */
57     OP_NOT_EVEN,	/* Operand is Odd number, should be even.  */
58     OP_ILLEGAL_DISPU4,	/* Operand is not within DISPU4 range.  */
59     OP_ILLEGAL_CST4,	/* Operand is not within CST4 range.  */
60     OP_NOT_UPPER_64KB	/* Operand is not within the upper 64KB
61 			   (0xFFFF0000-0xFFFFFFFF).  */
62   }
63 op_err;
64 
65 /* Opcode mnemonics hash table.  */
66 static htab_t crx_inst_hash;
67 /* CRX registers hash table.  */
68 static htab_t reg_hash;
69 /* CRX coprocessor registers hash table.  */
70 static htab_t copreg_hash;
71 /* Current instruction we're assembling.  */
72 static const inst *instruction;
73 
74 /* Global variables.  */
75 
76 /* Array to hold an instruction encoding.  */
77 static long output_opcode[2];
78 
79 /* Nonzero means a relocatable symbol.  */
80 static int relocatable;
81 
82 /* A copy of the original instruction (used in error messages).  */
83 static char ins_parse[MAX_INST_LEN];
84 
85 /* The current processed argument number.  */
86 static int cur_arg_num;
87 
88 /* Generic assembler global variables which must be defined by all targets.  */
89 
90 /* Characters which always start a comment.  */
91 const char comment_chars[] = "#";
92 
93 /* Characters which start a comment at the beginning of a line.  */
94 const char line_comment_chars[] = "#";
95 
96 /* This array holds machine specific line separator characters.  */
97 const char line_separator_chars[] = ";";
98 
99 /* Chars that can be used to separate mant from exp in floating point nums.  */
100 const char EXP_CHARS[] = "eE";
101 
102 /* Chars that mean this number is a floating point constant as in 0f12.456  */
103 const char FLT_CHARS[] = "f'";
104 
105 /* Target-specific multicharacter options, not const-declared at usage.  */
106 const char *md_shortopts = "";
107 struct option md_longopts[] =
108 {
109   {NULL, no_argument, NULL, 0}
110 };
111 size_t md_longopts_size = sizeof (md_longopts);
112 
113 /* This table describes all the machine specific pseudo-ops
114    the assembler has to support.  The fields are:
115    *** Pseudo-op name without dot.
116    *** Function to call to execute this pseudo-op.
117    *** Integer arg to pass to the function.  */
118 
119 const pseudo_typeS md_pseudo_table[] =
120 {
121   /* In CRX machine, align is in bytes (not a ptwo boundary).  */
122   {"align", s_align_bytes, 0},
123   {0, 0, 0}
124 };
125 
126 /* CRX relaxation table.  */
127 const relax_typeS md_relax_table[] =
128 {
129   /* bCC  */
130   {0xfa, -0x100, 2, 1},			/*  8 */
131   {0xfffe, -0x10000, 4, 2},		/* 16 */
132   {0xfffffffe, -0xfffffffe, 6, 0},	/* 32 */
133 
134   /* bal  */
135   {0xfffe, -0x10000, 4, 4},		/* 16 */
136   {0xfffffffe, -0xfffffffe, 6, 0},	/* 32 */
137 
138   /* cmpbr/bcop  */
139   {0xfe, -0x100, 4, 6},			/*  8 */
140   {0xfffffe, -0x1000000, 6, 0}		/* 24 */
141 };
142 
143 static int     get_cinv_parameters	(const char *);
144 static char *  preprocess_reglist	(char *, int *);
145 static void    warn_if_needed		(ins *);
146 static int     adjust_if_needed		(ins *);
147 
148 /* Return the bit size for a given operand.  */
149 
150 static int
get_opbits(operand_type op)151 get_opbits (operand_type op)
152 {
153   if (op < MAX_OPRD)
154     return crx_optab[op].bit_size;
155   else
156     return 0;
157 }
158 
159 /* Return the argument type of a given operand.  */
160 
161 static argtype
get_optype(operand_type op)162 get_optype (operand_type op)
163 {
164   if (op < MAX_OPRD)
165     return crx_optab[op].arg_type;
166   else
167     return nullargs;
168 }
169 
170 /* Return the flags of a given operand.  */
171 
172 static int
get_opflags(operand_type op)173 get_opflags (operand_type op)
174 {
175   if (op < MAX_OPRD)
176     return crx_optab[op].flags;
177   else
178     return 0;
179 }
180 
181 /* Get the core processor register 'reg_name'.  */
182 
183 static reg
get_register(char * reg_name)184 get_register (char *reg_name)
185 {
186   const reg_entry *rreg;
187 
188   rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
189 
190   if (rreg != NULL)
191     return rreg->value.reg_val;
192   else
193     return nullregister;
194 }
195 
196 /* Get the coprocessor register 'copreg_name'.  */
197 
198 static copreg
get_copregister(char * copreg_name)199 get_copregister (char *copreg_name)
200 {
201   const reg_entry *coreg;
202 
203   coreg = (const reg_entry *) str_hash_find (copreg_hash, copreg_name);
204 
205   if (coreg != NULL)
206     return coreg->value.copreg_val;
207   else
208     return nullcopregister;
209 }
210 
211 /* Round up a section size to the appropriate boundary.  */
212 
213 valueT
md_section_align(segT seg,valueT val)214 md_section_align (segT seg, valueT val)
215 {
216   /* Round .text section to a multiple of 2.  */
217   if (seg == text_section)
218     return (val + 1) & ~1;
219   return val;
220 }
221 
222 /* Parse an operand that is machine-specific (remove '*').  */
223 
224 void
md_operand(expressionS * exp)225 md_operand (expressionS * exp)
226 {
227   char c = *input_line_pointer;
228 
229   switch (c)
230     {
231     case '*':
232       input_line_pointer++;
233       expression (exp);
234       break;
235     default:
236       break;
237     }
238 }
239 
240 /* Reset global variables before parsing a new instruction.  */
241 
242 static void
reset_vars(char * op)243 reset_vars (char *op)
244 {
245   cur_arg_num = relocatable = 0;
246   memset (& output_opcode, '\0', sizeof (output_opcode));
247 
248   /* Save a copy of the original OP (used in error messages).  */
249   strncpy (ins_parse, op, sizeof ins_parse - 1);
250   ins_parse [sizeof ins_parse - 1] = 0;
251 }
252 
253 /* This macro decides whether a particular reloc is an entry in a
254    switch table.  It is used when relaxing, because the linker needs
255    to know about all such entries so that it can adjust them if
256    necessary.  */
257 
258 #define SWITCH_TABLE(fix)				  \
259   (   (fix)->fx_addsy != NULL				  \
260    && (fix)->fx_subsy != NULL				  \
261    && S_GET_SEGMENT ((fix)->fx_addsy) ==		  \
262       S_GET_SEGMENT ((fix)->fx_subsy)			  \
263    && S_GET_SEGMENT (fix->fx_addsy) != undefined_section  \
264    && (   (fix)->fx_r_type == BFD_RELOC_CRX_NUM8	  \
265        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16	  \
266        || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
267 
268 /* See whether we need to force a relocation into the output file.
269    This is used to force out switch and PC relative relocations when
270    relaxing.  */
271 
272 int
crx_force_relocation(fixS * fix)273 crx_force_relocation (fixS *fix)
274 {
275   if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
276     return 1;
277 
278   return 0;
279 }
280 
281 /* Generate a relocation entry for a fixup.  */
282 
283 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixP)284 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
285 {
286   arelent * reloc;
287 
288   reloc = XNEW (arelent);
289   reloc->sym_ptr_ptr  = XNEW (asymbol *);
290   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
291   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
292   reloc->addend = fixP->fx_offset;
293 
294   if (fixP->fx_subsy != NULL)
295     {
296       if (SWITCH_TABLE (fixP))
297 	{
298 	  /* Keep the current difference in the addend.  */
299 	  reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
300 			   - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
301 
302 	  switch (fixP->fx_r_type)
303 	    {
304 	    case BFD_RELOC_CRX_NUM8:
305 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
306 	      break;
307 	    case BFD_RELOC_CRX_NUM16:
308 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
309 	      break;
310 	    case BFD_RELOC_CRX_NUM32:
311 	      fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
312 	      break;
313 	    default:
314 	      abort ();
315 	      break;
316 	    }
317 	}
318       else
319 	{
320 	  /* We only resolve difference expressions in the same section.  */
321 	  as_bad_where (fixP->fx_file, fixP->fx_line,
322 			_("can't resolve `%s' {%s section} - `%s' {%s section}"),
323 			fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
324 			segment_name (fixP->fx_addsy
325 				      ? S_GET_SEGMENT (fixP->fx_addsy)
326 				      : absolute_section),
327 			S_GET_NAME (fixP->fx_subsy),
328 			segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
329 	}
330     }
331 
332   gas_assert ((int) fixP->fx_r_type > 0);
333   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
334 
335   if (reloc->howto == (reloc_howto_type *) NULL)
336     {
337       as_bad_where (fixP->fx_file, fixP->fx_line,
338 		    _("internal error: reloc %d (`%s') not supported by object file format"),
339 		    fixP->fx_r_type,
340 		    bfd_get_reloc_code_name (fixP->fx_r_type));
341       return NULL;
342     }
343   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
344 
345   return reloc;
346 }
347 
348 /* Prepare machine-dependent frags for relaxation.  */
349 
350 int
md_estimate_size_before_relax(fragS * fragp,asection * seg)351 md_estimate_size_before_relax (fragS *fragp, asection *seg)
352 {
353   /* If symbol is undefined or located in a different section,
354      select the largest supported relocation.  */
355   relax_substateT subtype;
356   relax_substateT rlx_state[] = {0, 2,
357 				 3, 4,
358 				 5, 6};
359 
360   for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
361     {
362       if (fragp->fr_subtype == rlx_state[subtype]
363 	  && (!S_IS_DEFINED (fragp->fr_symbol)
364 	      || seg != S_GET_SEGMENT (fragp->fr_symbol)))
365 	{
366 	  fragp->fr_subtype = rlx_state[subtype + 1];
367 	  break;
368 	}
369     }
370 
371   if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
372     abort ();
373 
374   return md_relax_table[fragp->fr_subtype].rlx_length;
375 }
376 
377 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,fragS * fragP)378 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
379 {
380   /* 'opcode' points to the start of the instruction, whether
381      we need to change the instruction's fixed encoding.  */
382   char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
383   bfd_reloc_code_real_type reloc;
384 
385   subseg_change (sec, 0);
386 
387   switch (fragP->fr_subtype)
388     {
389     case 0:
390       reloc = BFD_RELOC_CRX_REL8;
391       break;
392     case 1:
393       *opcode = 0x7e;
394       reloc = BFD_RELOC_CRX_REL16;
395       break;
396     case 2:
397       *opcode = 0x7f;
398       reloc = BFD_RELOC_CRX_REL32;
399       break;
400     case 3:
401       reloc = BFD_RELOC_CRX_REL16;
402       break;
403     case 4:
404       *++opcode = 0x31;
405       reloc = BFD_RELOC_CRX_REL32;
406       break;
407     case 5:
408       reloc = BFD_RELOC_CRX_REL8_CMP;
409       break;
410     case 6:
411       *++opcode = 0x31;
412       reloc = BFD_RELOC_CRX_REL24;
413       break;
414     default:
415       abort ();
416       break;
417     }
418 
419     fix_new (fragP, fragP->fr_fix,
420 	     bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
421 	     fragP->fr_symbol, fragP->fr_offset, 1, reloc);
422     fragP->fr_var = 0;
423     fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
424 }
425 
426 /* Process machine-dependent command line options.  Called once for
427    each option on the command line that the machine-independent part of
428    GAS does not understand.  */
429 
430 int
md_parse_option(int c ATTRIBUTE_UNUSED,const char * arg ATTRIBUTE_UNUSED)431 md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
432 {
433   return 0;
434 }
435 
436 /* Machine-dependent usage-output.  */
437 
438 void
md_show_usage(FILE * stream ATTRIBUTE_UNUSED)439 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
440 {
441   return;
442 }
443 
444 const char *
md_atof(int type,char * litP,int * sizeP)445 md_atof (int type, char *litP, int *sizeP)
446 {
447   return ieee_md_atof (type, litP, sizeP, target_big_endian);
448 }
449 
450 /* Apply a fixS (fixup of an instruction or data that we didn't have
451    enough info to complete immediately) to the data in a frag.
452    Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
453    relaxation of debug sections, this function is called only when
454    fixuping relocations of debug sections.  */
455 
456 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg)457 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
458 {
459   valueT val = * valP;
460   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
461   fixP->fx_offset = 0;
462 
463   switch (fixP->fx_r_type)
464     {
465     case BFD_RELOC_CRX_NUM8:
466       bfd_put_8 (stdoutput, (unsigned char) val, buf);
467       break;
468     case BFD_RELOC_CRX_NUM16:
469       bfd_put_16 (stdoutput, val, buf);
470       break;
471     case BFD_RELOC_CRX_NUM32:
472       bfd_put_32 (stdoutput, val, buf);
473       break;
474     default:
475       /* We shouldn't ever get here because linkrelax is nonzero.  */
476       abort ();
477       break;
478     }
479 
480   fixP->fx_done = 0;
481 
482   if (fixP->fx_addsy == NULL
483       && fixP->fx_pcrel == 0)
484     fixP->fx_done = 1;
485 
486   if (fixP->fx_pcrel == 1
487       && fixP->fx_addsy != NULL
488       && S_GET_SEGMENT (fixP->fx_addsy) == seg)
489     fixP->fx_done = 1;
490 }
491 
492 /* The location from which a PC relative jump should be calculated,
493    given a PC relative reloc.  */
494 
495 long
md_pcrel_from(fixS * fixp)496 md_pcrel_from (fixS *fixp)
497 {
498   return fixp->fx_frag->fr_address + fixp->fx_where;
499 }
500 
501 /* This function is called once, at assembler startup time.  This should
502    set up all the tables, etc that the MD part of the assembler needs.  */
503 
504 void
md_begin(void)505 md_begin (void)
506 {
507   int i = 0;
508 
509   /* Set up a hash table for the instructions.  */
510   crx_inst_hash = str_htab_create ();
511 
512   while (crx_instruction[i].mnemonic != NULL)
513     {
514       const char *mnemonic = crx_instruction[i].mnemonic;
515 
516       if (str_hash_insert (crx_inst_hash, mnemonic, &crx_instruction[i], 0))
517 	as_fatal (_("duplicate %s"), mnemonic);
518 
519       /* Insert unique names into hash table.  The CRX instruction set
520 	 has many identical opcode names that have different opcodes based
521 	 on the operands.  This hash table then provides a quick index to
522 	 the first opcode with a particular name in the opcode table.  */
523       do
524 	{
525 	  ++i;
526 	}
527       while (crx_instruction[i].mnemonic != NULL
528 	     && streq (crx_instruction[i].mnemonic, mnemonic));
529     }
530 
531   /* Initialize reg_hash hash table.  */
532   reg_hash = str_htab_create ();
533   {
534     const reg_entry *regtab;
535 
536     for (regtab = crx_regtab;
537 	 regtab < (crx_regtab + NUMREGS); regtab++)
538       if (str_hash_insert (reg_hash, regtab->name, regtab, 0) != NULL)
539 	as_fatal (_("duplicate %s"), regtab->name);
540   }
541 
542   /* Initialize copreg_hash hash table.  */
543   copreg_hash = str_htab_create ();
544   {
545     const reg_entry *copregtab;
546 
547     for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
548 	 copregtab++)
549       if (str_hash_insert (copreg_hash, copregtab->name, copregtab, 0) != NULL)
550 	as_fatal (_("duplicate %s"), copregtab->name);
551   }
552   /*  Set linkrelax here to avoid fixups in most sections.  */
553   linkrelax = 1;
554 }
555 
556 /* Process constants (immediate/absolute)
557    and labels (jump targets/Memory locations).  */
558 
559 static void
process_label_constant(char * str,ins * crx_ins)560 process_label_constant (char *str, ins * crx_ins)
561 {
562   char *saved_input_line_pointer;
563   argument *cur_arg = &crx_ins->arg[cur_arg_num];  /* Current argument.  */
564 
565   saved_input_line_pointer = input_line_pointer;
566   input_line_pointer = str;
567 
568   expression (&crx_ins->exp);
569 
570   switch (crx_ins->exp.X_op)
571     {
572     case O_big:
573     case O_absent:
574       /* Missing or bad expr becomes absolute 0.  */
575       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
576 	      str);
577       crx_ins->exp.X_op = O_constant;
578       crx_ins->exp.X_add_number = 0;
579       crx_ins->exp.X_add_symbol = (symbolS *) 0;
580       crx_ins->exp.X_op_symbol = (symbolS *) 0;
581       /* Fall through.  */
582 
583     case O_constant:
584       cur_arg->X_op = O_constant;
585       cur_arg->constant = crx_ins->exp.X_add_number;
586       break;
587 
588     case O_symbol:
589     case O_subtract:
590     case O_add:
591       cur_arg->X_op = O_symbol;
592       crx_ins->rtype = BFD_RELOC_NONE;
593       relocatable = 1;
594 
595       switch (cur_arg->type)
596 	{
597 	case arg_cr:
598 	  if (IS_INSN_TYPE (LD_STOR_INS_INC))
599 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
600 	  else if (IS_INSN_TYPE (CSTBIT_INS)
601 		   || IS_INSN_TYPE (STOR_IMM_INS))
602 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
603 	  else
604 	    crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
605 	  break;
606 
607 	case arg_idxr:
608 	  crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
609 	  break;
610 
611 	case arg_c:
612 	  if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
613 	    crx_ins->rtype = BFD_RELOC_CRX_REL16;
614 	  else if (IS_INSN_TYPE (BRANCH_INS))
615 	    crx_ins->rtype = BFD_RELOC_CRX_REL8;
616 	  else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
617 		   || IS_INSN_TYPE (CSTBIT_INS))
618 	    crx_ins->rtype = BFD_RELOC_CRX_ABS32;
619 	  else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
620 	    crx_ins->rtype = BFD_RELOC_CRX_REL4;
621 	  else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
622 	    crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
623 	  break;
624 
625 	case arg_ic:
626 	  if (IS_INSN_TYPE (ARITH_INS))
627 	    crx_ins->rtype = BFD_RELOC_CRX_IMM32;
628 	  else if (IS_INSN_TYPE (ARITH_BYTE_INS))
629 	    crx_ins->rtype = BFD_RELOC_CRX_IMM16;
630 	  break;
631 	default:
632 	  break;
633 	}
634       break;
635 
636     default:
637       cur_arg->X_op = crx_ins->exp.X_op;
638       break;
639     }
640 
641   input_line_pointer = saved_input_line_pointer;
642   return;
643 }
644 
645 /* Get the values of the scale to be encoded -
646    used for the scaled index mode of addressing.  */
647 
648 static int
exponent2scale(int val)649 exponent2scale (int val)
650 {
651   int exponent;
652 
653   /* If 'val' is 0, the following 'for' will be an endless loop.  */
654   if (val == 0)
655     return 0;
656 
657   for (exponent = 0; (val != 1); val >>= 1, exponent++)
658     ;
659 
660   return exponent;
661 }
662 
663 /* Parsing different types of operands
664    -> constants		    Immediate/Absolute/Relative numbers
665    -> Labels		    Relocatable symbols
666    -> (rbase)		    Register base
667    -> disp(rbase)	    Register relative
668    -> disp(rbase)+	    Post-increment mode
669    -> disp(rbase,ridx,scl)  Register index mode  */
670 
671 static void
set_operand(char * operand,ins * crx_ins)672 set_operand (char *operand, ins * crx_ins)
673 {
674   char *operandS; /* Pointer to start of sub-operand.  */
675   char *operandE; /* Pointer to end of sub-operand.  */
676   expressionS scale;
677   int scale_val;
678   char *input_save, c;
679   argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
680 
681   /* Initialize pointers.  */
682   operandS = operandE = operand;
683 
684   switch (cur_arg->type)
685     {
686     case arg_sc:    /* Case *+0x18.  */
687     case arg_ic:    /* Case $0x18.  */
688       operandS++;
689       /* Fall through.  */
690     case arg_c:	    /* Case 0x18.  */
691       /* Set constant.  */
692       process_label_constant (operandS, crx_ins);
693 
694       if (cur_arg->type != arg_ic)
695 	cur_arg->type = arg_c;
696       break;
697 
698     case arg_icr:   /* Case $0x18(r1).  */
699       operandS++;
700     case arg_cr:    /* Case 0x18(r1).   */
701       /* Set displacement constant.  */
702       while (*operandE != '(')
703 	operandE++;
704       *operandE = '\0';
705       process_label_constant (operandS, crx_ins);
706       operandS = operandE;
707       /* Fall through.  */
708     case arg_rbase: /* Case (r1).  */
709       operandS++;
710       /* Set register base.  */
711       while (*operandE != ')')
712 	operandE++;
713       *operandE = '\0';
714       if ((cur_arg->r = get_register (operandS)) == nullregister)
715 	as_bad (_("Illegal register `%s' in instruction `%s'"),
716 		operandS, ins_parse);
717 
718       if (cur_arg->type != arg_rbase)
719 	cur_arg->type = arg_cr;
720       break;
721 
722     case arg_idxr:
723       /* Set displacement constant.  */
724       while (*operandE != '(')
725 	operandE++;
726       *operandE = '\0';
727       process_label_constant (operandS, crx_ins);
728       operandS = ++operandE;
729 
730       /* Set register base.  */
731       while ((*operandE != ',') && (! ISSPACE (*operandE)))
732 	operandE++;
733       *operandE++ = '\0';
734       if ((cur_arg->r = get_register (operandS)) == nullregister)
735 	as_bad (_("Illegal register `%s' in instruction `%s'"),
736 		operandS, ins_parse);
737 
738       /* Skip leading white space.  */
739       while (ISSPACE (*operandE))
740 	operandE++;
741       operandS = operandE;
742 
743       /* Set register index.  */
744       while ((*operandE != ')') && (*operandE != ','))
745 	operandE++;
746       c = *operandE;
747       *operandE++ = '\0';
748 
749       if ((cur_arg->i_r = get_register (operandS)) == nullregister)
750 	as_bad (_("Illegal register `%s' in instruction `%s'"),
751 		operandS, ins_parse);
752 
753       /* Skip leading white space.  */
754       while (ISSPACE (*operandE))
755 	operandE++;
756       operandS = operandE;
757 
758       /* Set the scale.  */
759       if (c == ')')
760 	cur_arg->scale = 0;
761       else
762 	{
763 	  while (*operandE != ')')
764 	    operandE++;
765 	  *operandE = '\0';
766 
767 	  /* Preprocess the scale string.  */
768 	  input_save = input_line_pointer;
769 	  input_line_pointer = operandS;
770 	  expression (&scale);
771 	  input_line_pointer = input_save;
772 
773 	  scale_val = scale.X_add_number;
774 
775 	  /* Check if the scale value is legal.  */
776 	  if (scale_val != 1 && scale_val != 2
777 	      && scale_val != 4 && scale_val != 8)
778 	    as_bad (_("Illegal Scale - `%d'"), scale_val);
779 
780 	  cur_arg->scale = exponent2scale (scale_val);
781 	}
782       break;
783 
784     default:
785       break;
786     }
787 }
788 
789 /* Parse a single operand.
790    operand - Current operand to parse.
791    crx_ins - Current assembled instruction.  */
792 
793 static void
parse_operand(char * operand,ins * crx_ins)794 parse_operand (char *operand, ins * crx_ins)
795 {
796   int ret_val;
797   argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument.  */
798 
799   /* Initialize the type to NULL before parsing.  */
800   cur_arg->type = nullargs;
801 
802   /* Check whether this is a general processor register.  */
803   if ((ret_val = get_register (operand)) != nullregister)
804     {
805       cur_arg->type = arg_r;
806       cur_arg->r = ret_val;
807       cur_arg->X_op = O_register;
808       return;
809     }
810 
811   /* Check whether this is a core [special] coprocessor register.  */
812   if ((ret_val = get_copregister (operand)) != nullcopregister)
813     {
814       cur_arg->type = arg_copr;
815       if (ret_val >= cs0)
816 	cur_arg->type = arg_copsr;
817       cur_arg->cr = ret_val;
818       cur_arg->X_op = O_register;
819       return;
820     }
821 
822   /* Deal with special characters.  */
823   switch (operand[0])
824     {
825     case '$':
826       if (strchr (operand, '(') != NULL)
827 	cur_arg->type = arg_icr;
828       else
829 	cur_arg->type = arg_ic;
830       goto set_params;
831       break;
832 
833     case '*':
834       cur_arg->type = arg_sc;
835       goto set_params;
836       break;
837 
838     case '(':
839       cur_arg->type = arg_rbase;
840       goto set_params;
841       break;
842 
843     default:
844       break;
845     }
846 
847   if (strchr (operand, '(') != NULL)
848     {
849       if (strchr (operand, ',') != NULL
850 	  && (strchr (operand, ',') > strchr (operand, '(')))
851 	cur_arg->type = arg_idxr;
852       else
853 	cur_arg->type = arg_cr;
854     }
855   else
856     cur_arg->type = arg_c;
857   goto set_params;
858 
859   /* Parse an operand according to its type.  */
860  set_params:
861   cur_arg->constant = 0;
862   set_operand (operand, crx_ins);
863 }
864 
865 /* Parse the various operands. Each operand is then analyzed to fillup
866    the fields in the crx_ins data structure.  */
867 
868 static void
parse_operands(ins * crx_ins,char * operands)869 parse_operands (ins * crx_ins, char *operands)
870 {
871   char *operandS;	       /* Operands string.  */
872   char *operandH, *operandT;   /* Single operand head/tail pointers.  */
873   int allocated = 0;	       /* Indicates a new operands string was allocated.  */
874   char *operand[MAX_OPERANDS]; /* Separating the operands.  */
875   int op_num = 0;	       /* Current operand number we are parsing.  */
876   int bracket_flag = 0;	       /* Indicates a bracket '(' was found.  */
877   int sq_bracket_flag = 0;     /* Indicates a square bracket '[' was found.  */
878 
879   /* Preprocess the list of registers, if necessary.  */
880   operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
881     preprocess_reglist (operands, &allocated) : operands;
882 
883   while (*operandT != '\0')
884     {
885       if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
886 	{
887 	  *operandT++ = '\0';
888 	  operand[op_num++] = strdup (operandH);
889 	  operandH = operandT;
890 	  continue;
891 	}
892 
893       if (*operandT == ' ')
894 	as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
895 
896       if (*operandT == '(')
897 	bracket_flag = 1;
898       else if (*operandT == '[')
899 	sq_bracket_flag = 1;
900 
901       if (*operandT == ')')
902 	{
903 	  if (bracket_flag)
904 	    bracket_flag = 0;
905 	  else
906 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
907 	}
908       else if (*operandT == ']')
909 	{
910 	  if (sq_bracket_flag)
911 	    sq_bracket_flag = 0;
912 	  else
913 	    as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
914 	}
915 
916       if (bracket_flag == 1 && *operandT == ')')
917 	bracket_flag = 0;
918       else if (sq_bracket_flag == 1 && *operandT == ']')
919 	sq_bracket_flag = 0;
920 
921       operandT++;
922     }
923 
924   /* Adding the last operand.  */
925   operand[op_num++] = strdup (operandH);
926   crx_ins->nargs = op_num;
927 
928   /* Verifying correct syntax of operands (all brackets should be closed).  */
929   if (bracket_flag || sq_bracket_flag)
930     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
931 
932   /* Now we parse each operand separately.  */
933   for (op_num = 0; op_num < crx_ins->nargs; op_num++)
934     {
935       cur_arg_num = op_num;
936       parse_operand (operand[op_num], crx_ins);
937       free (operand[op_num]);
938     }
939 
940   if (allocated)
941     free (operandS);
942 }
943 
944 /* Get the trap index in dispatch table, given its name.
945    This routine is used by assembling the 'excp' instruction.  */
946 
947 static int
gettrap(const char * s)948 gettrap (const char *s)
949 {
950   const trap_entry *trap;
951 
952   for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
953     if (strcasecmp (trap->name, s) == 0)
954       return trap->entry;
955 
956   as_bad (_("Unknown exception: `%s'"), s);
957   return 0;
958 }
959 
960 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
961    sub-group within load/stor instruction groups.
962    Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
963    advance the instruction pointer to the start of that sub-group (that is, up
964    to the first instruction of that type).
965    Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS.  */
966 
967 static void
handle_LoadStor(const char * operands)968 handle_LoadStor (const char *operands)
969 {
970   /* Post-Increment instructions precede Store-Immediate instructions in
971      CRX instruction table, hence they are handled before.
972      This synchronization should be kept.  */
973 
974   /* Assuming Post-Increment insn has the following format :
975      'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
976      LD_STOR_INS_INC are the only store insns containing a plus sign (+).  */
977   if (strstr (operands, ")+") != NULL)
978     {
979       while (! IS_INSN_TYPE (LD_STOR_INS_INC))
980 	instruction++;
981       return;
982     }
983 
984   /* Assuming Store-Immediate insn has the following format :
985      'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
986      STOR_IMM_INS are the only store insns containing a dollar sign ($).  */
987   if (strstr (operands, "$") != NULL)
988     while (! IS_INSN_TYPE (STOR_IMM_INS))
989       instruction++;
990 }
991 
992 /* Top level module where instruction parsing starts.
993    crx_ins - data structure holds some information.
994    operands - holds the operands part of the whole instruction.  */
995 
996 static void
parse_insn(ins * insn,char * operands)997 parse_insn (ins *insn, char *operands)
998 {
999   int i;
1000 
1001   /* Handle instructions with no operands.  */
1002   for (i = 0; crx_no_op_insn[i] != NULL; i++)
1003   {
1004     if (streq (crx_no_op_insn[i], instruction->mnemonic))
1005     {
1006       insn->nargs = 0;
1007       return;
1008     }
1009   }
1010 
1011   /* Handle 'excp'/'cinv' instructions.  */
1012   if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1013     {
1014       insn->nargs = 1;
1015       insn->arg[0].type = arg_ic;
1016       insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1017 	gettrap (operands) : get_cinv_parameters (operands);
1018       insn->arg[0].X_op = O_constant;
1019       return;
1020     }
1021 
1022   /* Handle load/stor unique instructions before parsing.  */
1023   if (IS_INSN_TYPE (LD_STOR_INS))
1024     handle_LoadStor (operands);
1025 
1026   if (operands != NULL)
1027     parse_operands (insn, operands);
1028 }
1029 
1030 /* Cinv instruction requires special handling.  */
1031 
1032 static int
get_cinv_parameters(const char * operand)1033 get_cinv_parameters (const char *operand)
1034 {
1035   const char *p = operand;
1036   int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1037 
1038   while (*++p != ']')
1039     {
1040       if (*p == ',' || *p == ' ')
1041 	continue;
1042 
1043       if (*p == 'd')
1044 	d_used = 1;
1045       else if (*p == 'i')
1046 	i_used = 1;
1047       else if (*p == 'u')
1048 	u_used = 1;
1049       else if (*p == 'b')
1050 	b_used = 1;
1051       else
1052 	as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1053     }
1054 
1055   return ((b_used ? 8 : 0)
1056 	+ (d_used ? 4 : 0)
1057 	+ (i_used ? 2 : 0)
1058 	+ (u_used ? 1 : 0));
1059 }
1060 
1061 /* Retrieve the opcode image of a given register.
1062    If the register is illegal for the current instruction,
1063    issue an error.  */
1064 
1065 static int
getreg_image(int r)1066 getreg_image (int r)
1067 {
1068   const reg_entry *rreg;
1069   char *reg_name;
1070   int is_procreg = 0; /* Nonzero means argument should be processor reg.  */
1071 
1072   if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1073       || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1074     is_procreg = 1;
1075 
1076   /* Check whether the register is in registers table.  */
1077   if (r < MAX_REG)
1078     rreg = &crx_regtab[r];
1079   /* Check whether the register is in coprocessor registers table.  */
1080   else if (r < (int) MAX_COPREG)
1081     rreg = &crx_copregtab[r-MAX_REG];
1082   /* Register not found.  */
1083   else
1084     {
1085       as_bad (_("Unknown register: `%d'"), r);
1086       return 0;
1087     }
1088 
1089   reg_name = rreg->name;
1090 
1091 /* Issue a error message when register is illegal.  */
1092 #define IMAGE_ERR \
1093   as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1094 	  reg_name, ins_parse);
1095 
1096   switch (rreg->type)
1097   {
1098     case CRX_U_REGTYPE:
1099       if (is_procreg || (instruction->flags & USER_REG))
1100 	return rreg->image;
1101       else
1102 	IMAGE_ERR;
1103       break;
1104 
1105     case CRX_CFG_REGTYPE:
1106       if (is_procreg)
1107 	return rreg->image;
1108       else
1109 	IMAGE_ERR;
1110       break;
1111 
1112     case CRX_R_REGTYPE:
1113       if (! is_procreg)
1114 	return rreg->image;
1115       else
1116 	IMAGE_ERR;
1117       break;
1118 
1119     case CRX_C_REGTYPE:
1120     case CRX_CS_REGTYPE:
1121       return rreg->image;
1122       break;
1123 
1124     default:
1125       IMAGE_ERR;
1126       break;
1127   }
1128 
1129   return 0;
1130 }
1131 
1132 /* Routine used to represent integer X using NBITS bits.  */
1133 
1134 static long
getconstant(long x,int nbits)1135 getconstant (long x, int nbits)
1136 {
1137   return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
1138 }
1139 
1140 /* Print a constant value to 'output_opcode':
1141    ARG holds the operand's type and value.
1142    SHIFT represents the location of the operand to be print into.
1143    NBITS determines the size (in bits) of the constant.  */
1144 
1145 static void
print_constant(int nbits,int shift,argument * arg)1146 print_constant (int nbits, int shift, argument *arg)
1147 {
1148   unsigned long mask = 0;
1149   unsigned long constant = getconstant (arg->constant, nbits);
1150 
1151   switch (nbits)
1152   {
1153     case 32:
1154     case 28:
1155     case 24:
1156     case 22:
1157       /* mask the upper part of the constant, that is, the bits
1158 	 going to the lowest byte of output_opcode[0].
1159 	 The upper part of output_opcode[1] is always filled,
1160 	 therefore it is always masked with 0xFFFF.  */
1161       mask = (1 << (nbits - 16)) - 1;
1162       /* Divide the constant between two consecutive words :
1163 		 0	   1	     2	       3
1164 	    +---------+---------+---------+---------+
1165 	    |	      | X X X X | X X X X |	    |
1166 	    +---------+---------+---------+---------+
1167 	      output_opcode[0]    output_opcode[1]     */
1168 
1169       CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1170       CRX_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1171       break;
1172 
1173     case 16:
1174     case 12:
1175       /* Special case - in arg_cr, the SHIFT represents the location
1176 	 of the REGISTER, not the constant, which is itself not shifted.  */
1177       if (arg->type == arg_cr)
1178 	{
1179 	  CRX_PRINT (0, constant,  0);
1180 	  break;
1181 	}
1182 
1183       /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1184 	 always filling the upper part of output_opcode[1]. If we mistakenly
1185 	 write it to output_opcode[0], the constant prefix (that is, 'match')
1186 	 will be overridden.
1187 		 0	   1	     2	       3
1188 	    +---------+---------+---------+---------+
1189 	    | 'match' |         | X X X X |	    |
1190 	    +---------+---------+---------+---------+
1191 	      output_opcode[0]    output_opcode[1]     */
1192 
1193       if ((instruction->size > 2) && (shift == WORD_SHIFT))
1194 	CRX_PRINT (1, constant, WORD_SHIFT);
1195       else
1196 	CRX_PRINT (0, constant, shift);
1197       break;
1198 
1199     default:
1200       CRX_PRINT (0, constant,  shift);
1201       break;
1202   }
1203 }
1204 
1205 /* Print an operand to 'output_opcode', which later on will be
1206    printed to the object file:
1207    ARG holds the operand's type, size and value.
1208    SHIFT represents the printing location of operand.
1209    NBITS determines the size (in bits) of a constant operand.  */
1210 
1211 static void
print_operand(int nbits,int shift,argument * arg)1212 print_operand (int nbits, int shift, argument *arg)
1213 {
1214   switch (arg->type)
1215     {
1216     case arg_r:
1217       CRX_PRINT (0, getreg_image (arg->r), shift);
1218       break;
1219 
1220     case arg_copr:
1221       if (arg->cr < c0 || arg->cr > c15)
1222 	as_bad (_("Illegal co-processor register in instruction `%s'"),
1223 		ins_parse);
1224       CRX_PRINT (0, getreg_image (arg->cr), shift);
1225       break;
1226 
1227     case arg_copsr:
1228       if (arg->cr < cs0 || arg->cr > cs15)
1229 	as_bad (_("Illegal co-processor special register in instruction `%s'"),
1230 		ins_parse);
1231       CRX_PRINT (0, getreg_image (arg->cr), shift);
1232       break;
1233 
1234     case arg_idxr:
1235       /*    16      12	      8    6         0
1236 	    +--------------------------------+
1237 	    | r_base | r_idx  | scl|  disp   |
1238 	    +--------------------------------+	  */
1239       CRX_PRINT (0, getreg_image (arg->r), 12);
1240       CRX_PRINT (0, getreg_image (arg->i_r), 8);
1241       CRX_PRINT (0, arg->scale, 6);
1242       /* Fall through.  */
1243     case arg_ic:
1244     case arg_c:
1245       print_constant (nbits, shift, arg);
1246       break;
1247 
1248     case arg_rbase:
1249       CRX_PRINT (0, getreg_image (arg->r), shift);
1250       break;
1251 
1252     case arg_cr:
1253       /* case base_cst4.  */
1254       if (instruction->flags & DISPU4MAP)
1255 	print_constant (nbits, shift + REG_SIZE, arg);
1256       else
1257 	/* rbase_disps<NN> and other such cases.  */
1258 	print_constant (nbits, shift, arg);
1259       /* Add the register argument to the output_opcode.  */
1260       CRX_PRINT (0, getreg_image (arg->r), shift);
1261       break;
1262 
1263     default:
1264       break;
1265     }
1266 }
1267 
1268 /* Retrieve the number of operands for the current assembled instruction.  */
1269 
1270 static int
get_number_of_operands(void)1271 get_number_of_operands (void)
1272 {
1273   int i;
1274 
1275   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1276     ;
1277   return i;
1278 }
1279 
1280 /* Verify that the number NUM can be represented in BITS bits (that is,
1281    within its permitted range), based on the instruction's FLAGS.
1282    If UPDATE is nonzero, update the value of NUM if necessary.
1283    Return OP_LEGAL upon success, actual error type upon failure.  */
1284 
1285 static op_err
check_range(long * num,int bits,int unsigned flags,int update)1286 check_range (long *num, int bits, int unsigned flags, int update)
1287 {
1288   uint32_t max;
1289   op_err retval = OP_LEGAL;
1290   int bin;
1291   uint32_t upper_64kb = 0xffff0000;
1292   uint32_t value = *num;
1293 
1294   /* Verify operand value is even.  */
1295   if (flags & OP_EVEN)
1296     {
1297       if (value % 2)
1298 	return OP_NOT_EVEN;
1299     }
1300 
1301   if (flags & OP_UPPER_64KB)
1302     {
1303       /* Check if value is to be mapped to upper 64 KB memory area.  */
1304       if ((value & upper_64kb) == upper_64kb)
1305 	{
1306 	  value -= upper_64kb;
1307 	  if (update)
1308 	    *num = value;
1309 	}
1310       else
1311 	return OP_NOT_UPPER_64KB;
1312     }
1313 
1314   if (flags & OP_SHIFT)
1315     {
1316       /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1317 	 sign.  However, right shift of a signed type with a negative
1318 	 value is implementation defined.  See ISO C 6.5.7.  So we use
1319 	 an unsigned type and sign extend afterwards.  */
1320       value >>= 1;
1321       value = (value ^ 0x40000000) - 0x40000000;
1322       if (update)
1323 	*num = value;
1324     }
1325   else if (flags & OP_SHIFT_DEC)
1326     {
1327       value = (value >> 1) - 1;
1328       if (update)
1329 	*num = value;
1330     }
1331 
1332   if (flags & OP_ESC)
1333     {
1334       /* 0x7e and 0x7f are reserved escape sequences of dispe9.  */
1335       if (value == 0x7e || value == 0x7f)
1336 	return OP_OUT_OF_RANGE;
1337     }
1338 
1339   if (flags & OP_DISPU4)
1340     {
1341       int is_dispu4 = 0;
1342 
1343       uint32_t mul = (instruction->flags & DISPUB4 ? 1
1344 		      : instruction->flags & DISPUW4 ? 2
1345 		      : instruction->flags & DISPUD4 ? 4
1346 		      : 0);
1347 
1348       for (bin = 0; bin < crx_cst4_maps; bin++)
1349 	{
1350 	  if (value == mul * bin)
1351 	    {
1352 	      is_dispu4 = 1;
1353 	      if (update)
1354 		*num = bin;
1355 	      break;
1356 	    }
1357 	}
1358       if (!is_dispu4)
1359 	retval = OP_ILLEGAL_DISPU4;
1360     }
1361   else if (flags & OP_CST4)
1362     {
1363       int is_cst4 = 0;
1364 
1365       for (bin = 0; bin < crx_cst4_maps; bin++)
1366 	{
1367 	  if (value == (uint32_t) crx_cst4_map[bin])
1368 	    {
1369 	      is_cst4 = 1;
1370 	      if (update)
1371 		*num = bin;
1372 	      break;
1373 	    }
1374 	}
1375       if (!is_cst4)
1376 	retval = OP_ILLEGAL_CST4;
1377     }
1378   else if (flags & OP_SIGNED)
1379     {
1380       max = 1;
1381       max = max << (bits - 1);
1382       value += max;
1383       max = ((max - 1) << 1) | 1;
1384       if (value > max)
1385 	retval = OP_OUT_OF_RANGE;
1386     }
1387   else if (flags & OP_UNSIGNED)
1388     {
1389       max = 1;
1390       max = max << (bits - 1);
1391       max = ((max - 1) << 1) | 1;
1392       if (value > max)
1393 	retval = OP_OUT_OF_RANGE;
1394     }
1395   return retval;
1396 }
1397 
1398 /* Assemble a single instruction:
1399    INSN is already parsed (that is, all operand values and types are set).
1400    For instruction to be assembled, we need to find an appropriate template in
1401    the instruction table, meeting the following conditions:
1402     1: Has the same number of operands.
1403     2: Has the same operand types.
1404     3: Each operand size is sufficient to represent the instruction's values.
1405    Returns 1 upon success, 0 upon failure.  */
1406 
1407 static int
assemble_insn(char * mnemonic,ins * insn)1408 assemble_insn (char *mnemonic, ins *insn)
1409 {
1410   /* Type of each operand in the current template.  */
1411   argtype cur_type[MAX_OPERANDS];
1412   /* Size (in bits) of each operand in the current template.  */
1413   unsigned int cur_size[MAX_OPERANDS];
1414   /* Flags of each operand in the current template.  */
1415   unsigned int cur_flags[MAX_OPERANDS];
1416   /* Instruction type to match.  */
1417   unsigned int ins_type;
1418   /* Boolean flag to mark whether a match was found.  */
1419   int match = 0;
1420   int i;
1421   /* Nonzero if an instruction with same number of operands was found.  */
1422   int found_same_number_of_operands = 0;
1423   /* Nonzero if an instruction with same argument types was found.  */
1424   int found_same_argument_types = 0;
1425   /* Nonzero if a constant was found within the required range.  */
1426   int found_const_within_range  = 0;
1427   /* Argument number of an operand with invalid type.  */
1428   int invalid_optype = -1;
1429   /* Argument number of an operand with invalid constant value.  */
1430   int invalid_const  = -1;
1431   /* Operand error (used for issuing various constant error messages).  */
1432   op_err op_error, const_err = OP_LEGAL;
1433 
1434   /* Retrieve data (based on FUNC) for each operand of a given instruction.  */
1435 #define GET_CURRENT_DATA(FUNC, ARRAY)			\
1436   for (i = 0; i < insn->nargs; i++)			\
1437     ARRAY[i] = FUNC (instruction->operands[i].op_type)
1438 
1439 #define GET_CURRENT_TYPE    GET_CURRENT_DATA(get_optype, cur_type)
1440 #define GET_CURRENT_SIZE    GET_CURRENT_DATA(get_opbits, cur_size)
1441 #define GET_CURRENT_FLAGS   GET_CURRENT_DATA(get_opflags, cur_flags)
1442 
1443   /* Instruction has no operands -> only copy the constant opcode.   */
1444   if (insn->nargs == 0)
1445     {
1446       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1447       return 1;
1448     }
1449 
1450   /* In some case, same mnemonic can appear with different instruction types.
1451      For example, 'storb' is supported with 3 different types :
1452      LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1453      We assume that when reaching this point, the instruction type was
1454      pre-determined. We need to make sure that the type stays the same
1455      during a search for matching instruction.  */
1456   ins_type = CRX_INS_TYPE(instruction->flags);
1457 
1458   while (/* Check that match is still not found.  */
1459 	 match != 1
1460 	 /* Check we didn't get to end of table.  */
1461 	 && instruction->mnemonic != NULL
1462 	 /* Check that the actual mnemonic is still available.  */
1463 	 && IS_INSN_MNEMONIC (mnemonic)
1464 	 /* Check that the instruction type wasn't changed.  */
1465 	 && IS_INSN_TYPE(ins_type))
1466     {
1467       /* Check whether number of arguments is legal.  */
1468       if (get_number_of_operands () != insn->nargs)
1469 	goto next_insn;
1470       found_same_number_of_operands = 1;
1471 
1472       /* Initialize arrays with data of each operand in current template.  */
1473       GET_CURRENT_TYPE;
1474       GET_CURRENT_SIZE;
1475       GET_CURRENT_FLAGS;
1476 
1477       /* Check for type compatibility.  */
1478       for (i = 0; i < insn->nargs; i++)
1479 	{
1480 	  if (cur_type[i] != insn->arg[i].type)
1481 	    {
1482 	      if (invalid_optype == -1)
1483 		invalid_optype = i + 1;
1484 	      goto next_insn;
1485 	    }
1486 	}
1487       found_same_argument_types = 1;
1488 
1489       for (i = 0; i < insn->nargs; i++)
1490 	{
1491 	  /* Reverse the operand indices for certain opcodes:
1492 	     Index 0	  -->> 1
1493 	     Index 1	  -->> 0
1494 	     Other index  -->> stays the same.  */
1495 	  int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
1496 
1497 	  /* Only check range - don't update the constant's value, since the
1498 	     current instruction may not be the last we try to match.
1499 	     The constant's value will be updated later, right before printing
1500 	     it to the object file.  */
1501 	  if ((insn->arg[j].X_op == O_constant)
1502 	      && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1503 					  cur_flags[j], 0)))
1504 	    {
1505 	      if (invalid_const == -1)
1506 		{
1507 		  invalid_const = j + 1;
1508 		  const_err = op_error;
1509 		}
1510 	      goto next_insn;
1511 	    }
1512 	  /* For symbols, we make sure the relocation size (which was already
1513 	     determined) is sufficient.  */
1514 	  else if ((insn->arg[j].X_op == O_symbol)
1515 		   && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1516 		       > cur_size[j]))
1517 	    goto next_insn;
1518 	}
1519       found_const_within_range = 1;
1520 
1521       /* If we got till here -> Full match is found.  */
1522       match = 1;
1523       break;
1524 
1525       /* Try again with next instruction.  */
1526     next_insn:
1527       instruction++;
1528     }
1529 
1530   if (!match)
1531     {
1532       /* We haven't found a match - instruction can't be assembled.  */
1533       if (!found_same_number_of_operands)
1534 	as_bad (_("Incorrect number of operands"));
1535       else if (!found_same_argument_types)
1536 	as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1537       else if (!found_const_within_range)
1538 	{
1539 	  switch (const_err)
1540 	    {
1541 	    case OP_OUT_OF_RANGE:
1542 	      as_bad (_("Operand out of range (arg %d)"), invalid_const);
1543 	      break;
1544 	    case OP_NOT_EVEN:
1545 	      as_bad (_("Operand has odd displacement (arg %d)"),
1546 		      invalid_const);
1547 	      break;
1548 	    case OP_ILLEGAL_DISPU4:
1549 	      as_bad (_("Invalid DISPU4 operand value (arg %d)"),
1550 		      invalid_const);
1551 	      break;
1552 	    case OP_ILLEGAL_CST4:
1553 	      as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1554 	      break;
1555 	    case OP_NOT_UPPER_64KB:
1556 	      as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1557 		      invalid_const);
1558 	      break;
1559 	    default:
1560 	      as_bad (_("Illegal operand (arg %d)"), invalid_const);
1561 	      break;
1562 	    }
1563 	}
1564 
1565       return 0;
1566     }
1567   else
1568     /* Full match - print the encoding to output file.  */
1569     {
1570       /* Make further checking (such that couldn't be made earlier).
1571 	 Warn the user if necessary.  */
1572       warn_if_needed (insn);
1573 
1574       /* Check whether we need to adjust the instruction pointer.  */
1575       if (adjust_if_needed (insn))
1576 	/* If instruction pointer was adjusted, we need to update
1577 	   the size of the current template operands.  */
1578 	GET_CURRENT_SIZE;
1579 
1580       for (i = 0; i < insn->nargs; i++)
1581 	{
1582 	  int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
1583 
1584 	  /* This time, update constant value before printing it.  */
1585 	  if ((insn->arg[j].X_op == O_constant)
1586 	      && (check_range (&insn->arg[j].constant, cur_size[j],
1587 			       cur_flags[j], 1) != OP_LEGAL))
1588 	    as_fatal (_("Illegal operand (arg %d)"), j+1);
1589 	}
1590 
1591       /* First, copy the instruction's opcode.  */
1592       output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1593 
1594       for (i = 0; i < insn->nargs; i++)
1595 	{
1596 	  cur_arg_num = i;
1597 	  print_operand (cur_size[i], instruction->operands[i].shift,
1598 			 &insn->arg[i]);
1599 	}
1600     }
1601 
1602   return 1;
1603 }
1604 
1605 /* Bunch of error checking.
1606    The checks are made after a matching instruction was found.  */
1607 
1608 void
warn_if_needed(ins * insn)1609 warn_if_needed (ins *insn)
1610 {
1611   /* If the post-increment address mode is used and the load/store
1612      source register is the same as rbase, the result of the
1613      instruction is undefined.  */
1614   if (IS_INSN_TYPE (LD_STOR_INS_INC))
1615     {
1616       /* Enough to verify that one of the arguments is a simple reg.  */
1617       if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1618 	if (insn->arg[0].r == insn->arg[1].r)
1619 	  as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1620 		   insn->arg[0].r);
1621     }
1622 
1623   /* Some instruction assume the stack pointer as rptr operand.
1624      Issue an error when the register to be loaded is also SP.  */
1625   if (instruction->flags & NO_SP)
1626     {
1627       if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1628 	as_bad (_("`%s' has undefined result"), ins_parse);
1629     }
1630 
1631   /* If the rptr register is specified as one of the registers to be loaded,
1632      the final contents of rptr are undefined. Thus, we issue an error.  */
1633   if (instruction->flags & NO_RPTR)
1634     {
1635       if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1636 	as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1637 	 getreg_image (insn->arg[0].r));
1638     }
1639 }
1640 
1641 /* In some cases, we need to adjust the instruction pointer although a
1642    match was already found. Here, we gather all these cases.
1643    Returns 1 if instruction pointer was adjusted, otherwise 0.  */
1644 
1645 int
adjust_if_needed(ins * insn)1646 adjust_if_needed (ins *insn)
1647 {
1648   int ret_value = 0;
1649 
1650   /* Special check for 'addub $0, r0' instruction -
1651      The opcode '0000 0000 0000 0000' is not allowed.  */
1652   if (IS_INSN_MNEMONIC ("addub"))
1653     {
1654       if ((instruction->operands[0].op_type == cst4)
1655 	  && instruction->operands[1].op_type == regr)
1656 	{
1657 	  if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1658 	    {
1659 	      instruction++;
1660 	      ret_value = 1;
1661 	    }
1662 	}
1663     }
1664 
1665   /* Optimization: Omit a zero displacement in bit operations,
1666      saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)').  */
1667   if (IS_INSN_TYPE (CSTBIT_INS))
1668     {
1669       if ((instruction->operands[1].op_type == rbase_disps12)
1670 	  && (insn->arg[1].X_op == O_constant)
1671 	  && (insn->arg[1].constant == 0))
1672 	{
1673 	  instruction--;
1674 	  ret_value = 1;
1675 	}
1676     }
1677 
1678   return ret_value;
1679 }
1680 
1681 /* Set the appropriate bit for register 'r' in 'mask'.
1682    This indicates that this register is loaded or stored by
1683    the instruction.  */
1684 
1685 static void
mask_reg(int r,unsigned short int * mask)1686 mask_reg (int r, unsigned short int *mask)
1687 {
1688   if ((reg)r > (reg)sp)
1689     {
1690       as_bad (_("Invalid register in register list"));
1691       return;
1692     }
1693 
1694   *mask |= (1 << r);
1695 }
1696 
1697 /* Preprocess register list - create a 16-bit mask with one bit for each
1698    of the 16 general purpose registers. If a bit is set, it indicates
1699    that this register is loaded or stored by the instruction.  */
1700 
1701 static char *
preprocess_reglist(char * param,int * allocated)1702 preprocess_reglist (char *param, int *allocated)
1703 {
1704   char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name.  */
1705   char *regP;			  /* Pointer to 'reg_name' string.  */
1706   int reg_counter = 0;		  /* Count number of parsed registers.  */
1707   unsigned short int mask = 0;	  /* Mask for 16 general purpose registers.  */
1708   char *new_param;		  /* New created operands string.  */
1709   char *paramP = param;		  /* Pointer to original operands string.  */
1710   char maskstring[10];		  /* Array to print the mask as a string.  */
1711   int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers.  */
1712   reg r;
1713   copreg cr;
1714 
1715   /* If 'param' is already in form of a number, no need to preprocess.  */
1716   if (strchr (paramP, '{') == NULL)
1717     return param;
1718 
1719   /* Verifying correct syntax of operand.  */
1720   if (strchr (paramP, '}') == NULL)
1721     as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1722 
1723   while (*paramP++ != '{');
1724 
1725   new_param = XCNEWVEC (char, MAX_INST_LEN);
1726   *allocated = 1;
1727   strncpy (new_param, param, paramP - param - 1);
1728 
1729   while (*paramP != '}')
1730     {
1731       regP = paramP;
1732       memset (&reg_name, '\0', sizeof (reg_name));
1733 
1734       while (ISALNUM (*paramP))
1735 	paramP++;
1736 
1737       strncpy (reg_name, regP, paramP - regP);
1738 
1739       /* Coprocessor register c<N>.  */
1740       if (IS_INSN_TYPE (COP_REG_INS))
1741 	{
1742 	  if (((cr = get_copregister (reg_name)) == nullcopregister)
1743 	      || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1744 	    as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1745 	  mask_reg (getreg_image (cr - c0), &mask);
1746 	}
1747       /* Coprocessor Special register cs<N>.  */
1748       else if (IS_INSN_TYPE (COPS_REG_INS))
1749 	{
1750 	  if (((cr = get_copregister (reg_name)) == nullcopregister)
1751 	      || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1752 	    as_fatal (_("Illegal register `%s' in cop-special-register list"),
1753 		      reg_name);
1754 	  mask_reg (getreg_image (cr - cs0), &mask);
1755 	}
1756       /* User register u<N>.  */
1757       else if (instruction->flags & USER_REG)
1758 	{
1759 	  if (streq(reg_name, "uhi"))
1760 	    {
1761 	      hi_found = 1;
1762 	      goto next_inst;
1763 	    }
1764 	  else if (streq(reg_name, "ulo"))
1765 	    {
1766 	      lo_found = 1;
1767 	      goto next_inst;
1768 	    }
1769 	  else if (((r = get_register (reg_name)) == nullregister)
1770 		   || (crx_regtab[r].type != CRX_U_REGTYPE))
1771 	    as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1772 
1773 	  mask_reg (getreg_image (r - u0), &mask);
1774 	}
1775       /* General purpose register r<N>.  */
1776       else
1777 	{
1778 	  if (streq(reg_name, "hi"))
1779 	    {
1780 	      hi_found = 1;
1781 	      goto next_inst;
1782 	    }
1783 	  else if (streq(reg_name, "lo"))
1784 	    {
1785 	      lo_found = 1;
1786 	      goto next_inst;
1787 	    }
1788 	  else if (((r = get_register (reg_name)) == nullregister)
1789 		   || (crx_regtab[r].type != CRX_R_REGTYPE))
1790 	    as_fatal (_("Illegal register `%s' in register list"), reg_name);
1791 
1792 	  mask_reg (getreg_image (r - r0), &mask);
1793 	}
1794 
1795       if (++reg_counter > MAX_REGS_IN_MASK16)
1796 	as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1797 		MAX_REGS_IN_MASK16);
1798 
1799     next_inst:
1800       while (!ISALNUM (*paramP) && *paramP != '}')
1801 	paramP++;
1802     }
1803 
1804   if (*++paramP != '\0')
1805     as_warn (_("rest of line ignored; first ignored character is `%c'"),
1806 	     *paramP);
1807 
1808   switch (hi_found + lo_found)
1809     {
1810     case 0:
1811       /* At least one register should be specified.  */
1812       if (mask == 0)
1813 	as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1814 		ins_parse);
1815       break;
1816 
1817     case 1:
1818       /* HI can't be specified without LO (and vise-versa).  */
1819       as_bad (_("HI/LO registers should be specified together"));
1820       break;
1821 
1822     case 2:
1823       /* HI/LO registers mustn't be masked with additional registers.  */
1824       if (mask != 0)
1825 	as_bad (_("HI/LO registers should be specified without additional registers"));
1826 
1827     default:
1828       break;
1829     }
1830 
1831   sprintf (maskstring, "$0x%x", mask);
1832   strcat (new_param, maskstring);
1833   return new_param;
1834 }
1835 
1836 /* Print the instruction.
1837    Handle also cases where the instruction is relaxable/relocatable.  */
1838 
1839 static void
print_insn(ins * insn)1840 print_insn (ins *insn)
1841 {
1842   unsigned int i, j, insn_size;
1843   char *this_frag;
1844   unsigned short words[4];
1845   int addr_mod;
1846 
1847   /* Arrange the insn encodings in a WORD size array.  */
1848   for (i = 0, j = 0; i < 2; i++)
1849     {
1850       words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1851       words[j++] = output_opcode[i] & 0xFFFF;
1852     }
1853 
1854   /* Handle relaxation.  */
1855   if ((instruction->flags & RELAXABLE) && relocatable)
1856     {
1857       int relax_subtype;
1858 
1859       /* Write the maximal instruction size supported.  */
1860       insn_size = INSN_MAX_SIZE;
1861 
1862       /* bCC  */
1863       if (IS_INSN_TYPE (BRANCH_INS))
1864 	relax_subtype = 0;
1865       /* bal  */
1866       else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1867 	relax_subtype = 3;
1868       /* cmpbr/bcop  */
1869       else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1870 	relax_subtype = 5;
1871       else
1872 	abort ();
1873 
1874       this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1875 			    4, relax_subtype,
1876 			    insn->exp.X_add_symbol,
1877 			    insn->exp.X_add_number,
1878 			    0);
1879     }
1880   else
1881     {
1882       insn_size = instruction->size;
1883       this_frag = frag_more (insn_size * 2);
1884 
1885       /* Handle relocation.  */
1886       if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1887 	{
1888 	  reloc_howto_type *reloc_howto;
1889 	  int size;
1890 
1891 	  reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1892 
1893 	  if (!reloc_howto)
1894 	    abort ();
1895 
1896 	  size = bfd_get_reloc_size (reloc_howto);
1897 
1898 	  if (size < 1 || size > 4)
1899 	    abort ();
1900 
1901 	  fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1902 		       size, &insn->exp, reloc_howto->pc_relative,
1903 		       insn->rtype);
1904 	}
1905     }
1906 
1907   /* Verify a 2-byte code alignment.  */
1908   addr_mod = frag_now_fix () & 1;
1909   if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1910     as_bad (_("instruction address is not a multiple of 2"));
1911   frag_now->insn_addr = addr_mod;
1912   frag_now->has_code = 1;
1913 
1914   /* Write the instruction encoding to frag.  */
1915   for (i = 0; i < insn_size; i++)
1916     {
1917       md_number_to_chars (this_frag, (valueT) words[i], 2);
1918       this_frag += 2;
1919     }
1920 }
1921 
1922 /* This is the guts of the machine-dependent assembler.  OP points to a
1923    machine dependent instruction.  This function is supposed to emit
1924    the frags/bytes it assembles to.  */
1925 
1926 void
md_assemble(char * op)1927 md_assemble (char *op)
1928 {
1929   ins crx_ins;
1930   char *param;
1931   char c;
1932 
1933   /* Reset global variables for a new instruction.  */
1934   reset_vars (op);
1935 
1936   /* Strip the mnemonic.  */
1937   for (param = op; *param != 0 && !ISSPACE (*param); param++)
1938     ;
1939   c = *param;
1940   *param++ = '\0';
1941 
1942   /* Find the instruction.  */
1943   instruction = (const inst *) str_hash_find (crx_inst_hash, op);
1944   if (instruction == NULL)
1945     {
1946       as_bad (_("Unknown opcode: `%s'"), op);
1947       param[-1] = c;
1948       return;
1949     }
1950 
1951   /* Tie dwarf2 debug info to the address at the start of the insn.  */
1952   dwarf2_emit_insn (0);
1953 
1954   /* Parse the instruction's operands.  */
1955   parse_insn (&crx_ins, param);
1956 
1957   /* Assemble the instruction - return upon failure.  */
1958   if (assemble_insn (op, &crx_ins) == 0)
1959     {
1960       param[-1] = c;
1961       return;
1962     }
1963 
1964   /* Print the instruction.  */
1965   param[-1] = c;
1966   print_insn (&crx_ins);
1967 }
1968