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