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