Remove strneq macro and use startswith.
[binutils-gdb.git] / gas / config / tc-crx.c
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
438 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
439 {
440 return;
441 }
442
443 const char *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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 }