[gdb] Fix tsan warning: signal handler spoils errno
[binutils-gdb.git] / gas / config / tc-crx.c
blobfb128aae7b203673841a5d68f1ab0556c1234f85
1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright (C) 2004-2024 Free Software Foundation, Inc.
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.
8 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
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"
32 /* Word is considered here as a 16-bit unsigned short int. */
33 #define WORD_SHIFT 16
35 /* Register is 4-bit size. */
36 #define REG_SIZE 4
38 /* Maximum size of a single instruction (in words). */
39 #define INSN_MAX_SIZE 3
41 /* Maximum bits which may be set in a `mask16' operand. */
42 #define MAX_REGS_IN_MASK16 8
44 /* Utility macros for string comparison. */
45 #define streq(a, b) (strcmp (a, b) == 0)
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)
51 /* Operand errors. */
52 typedef enum
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). */
62 op_err;
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;
73 /* Global variables. */
75 /* Array to hold an instruction encoding. */
76 static long output_opcode[2];
78 /* Nonzero means a relocatable symbol. */
79 static int relocatable;
81 /* A copy of the original instruction (used in error messages). */
82 static char ins_parse[MAX_INST_LEN];
84 /* The current processed argument number. */
85 static int cur_arg_num;
87 /* Generic assembler global variables which must be defined by all targets. */
89 /* Characters which always start a comment. */
90 const char comment_chars[] = "#";
92 /* Characters which start a comment at the beginning of a line. */
93 const char line_comment_chars[] = "#";
95 /* This array holds machine specific line separator characters. */
96 const char line_separator_chars[] = ";";
98 /* Chars that can be used to separate mant from exp in floating point nums. */
99 const char EXP_CHARS[] = "eE";
101 /* Chars that mean this number is a floating point constant as in 0f12.456 */
102 const char FLT_CHARS[] = "f'";
104 /* Target-specific multicharacter options, not const-declared at usage. */
105 const char md_shortopts[] = "";
106 const struct option md_longopts[] =
108 {NULL, no_argument, NULL, 0}
110 const size_t md_longopts_size = sizeof (md_longopts);
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. */
118 const pseudo_typeS md_pseudo_table[] =
120 /* In CRX machine, align is in bytes (not a ptwo boundary). */
121 {"align", s_align_bytes, 0},
122 {0, 0, 0}
125 /* CRX relaxation table. */
126 const relax_typeS md_relax_table[] =
128 /* bCC */
129 {0xfa, -0x100, 2, 1}, /* 8 */
130 {0xfffe, -0x10000, 4, 2}, /* 16 */
131 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
133 /* bal */
134 {0xfffe, -0x10000, 4, 4}, /* 16 */
135 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
137 /* cmpbr/bcop */
138 {0xfe, -0x100, 4, 6}, /* 8 */
139 {0xfffffe, -0x1000000, 6, 0} /* 24 */
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 *);
147 /* Return the bit size for a given operand. */
149 static int
150 get_opbits (operand_type op)
152 if (op < MAX_OPRD)
153 return crx_optab[op].bit_size;
154 else
155 return 0;
158 /* Return the argument type of a given operand. */
160 static argtype
161 get_optype (operand_type op)
163 if (op < MAX_OPRD)
164 return crx_optab[op].arg_type;
165 else
166 return nullargs;
169 /* Return the flags of a given operand. */
171 static int
172 get_opflags (operand_type op)
174 if (op < MAX_OPRD)
175 return crx_optab[op].flags;
176 else
177 return 0;
180 /* Get the core processor register 'reg_name'. */
182 static reg
183 get_register (char *reg_name)
185 const reg_entry *rreg;
187 rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
189 if (rreg != NULL)
190 return rreg->value.reg_val;
191 else
192 return nullregister;
195 /* Get the coprocessor register 'copreg_name'. */
197 static copreg
198 get_copregister (char *copreg_name)
200 const reg_entry *coreg;
202 coreg = (const reg_entry *) str_hash_find (copreg_hash, copreg_name);
204 if (coreg != NULL)
205 return coreg->value.copreg_val;
206 else
207 return nullcopregister;
210 /* Round up a section size to the appropriate boundary. */
212 valueT
213 md_section_align (segT seg, valueT val)
215 /* Round .text section to a multiple of 2. */
216 if (seg == text_section)
217 return (val + 1) & ~1;
218 return val;
221 /* Parse an operand that is machine-specific (remove '*'). */
223 void
224 md_operand (expressionS * exp)
226 char c = *input_line_pointer;
228 switch (c)
230 case '*':
231 input_line_pointer++;
232 expression (exp);
233 break;
234 default:
235 break;
239 /* Reset global variables before parsing a new instruction. */
241 static void
242 reset_vars (char *op)
244 cur_arg_num = relocatable = 0;
245 memset (& output_opcode, '\0', sizeof (output_opcode));
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;
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. */
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))
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. */
272 crx_force_relocation (fixS *fix)
274 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
275 return 1;
277 return 0;
280 /* Generate a relocation entry for a fixup. */
282 arelent *
283 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
285 arelent * reloc;
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;
293 if (fixP->fx_subsy != NULL)
295 if (SWITCH_TABLE (fixP))
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);
301 switch (fixP->fx_r_type)
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;
317 else
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;
327 gas_assert ((int) fixP->fx_r_type > 0);
328 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
330 if (reloc->howto == (reloc_howto_type *) NULL)
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;
338 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
340 return reloc;
343 /* Prepare machine-dependent frags for relaxation. */
346 md_estimate_size_before_relax (fragS *fragp, asection *seg)
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};
355 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
357 if (fragp->fr_subtype == rlx_state[subtype]
358 && (!S_IS_DEFINED (fragp->fr_symbol)
359 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
361 fragp->fr_subtype = rlx_state[subtype + 1];
362 break;
366 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
367 abort ();
369 return md_relax_table[fragp->fr_subtype].rlx_length;
372 void
373 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
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;
380 subseg_change (sec, 0);
382 switch (fragP->fr_subtype)
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;
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;
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. */
426 md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
428 return 0;
431 /* Machine-dependent usage-output. */
433 void
434 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
436 return;
439 const char *
440 md_atof (int type, char *litP, int *sizeP)
442 return ieee_md_atof (type, litP, sizeP, target_big_endian);
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. */
451 void
452 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
454 valueT val = * valP;
455 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
456 fixP->fx_offset = 0;
458 switch (fixP->fx_r_type)
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;
475 fixP->fx_done = 0;
477 if (fixP->fx_addsy == NULL
478 && fixP->fx_pcrel == 0)
479 fixP->fx_done = 1;
481 if (fixP->fx_pcrel == 1
482 && fixP->fx_addsy != NULL
483 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
484 fixP->fx_done = 1;
487 /* The location from which a PC relative jump should be calculated,
488 given a PC relative reloc. */
490 long
491 md_pcrel_from (fixS *fixp)
493 return fixp->fx_frag->fr_address + fixp->fx_where;
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. */
499 void
500 md_begin (void)
502 int i = 0;
504 /* Set up a hash table for the instructions. */
505 crx_inst_hash = str_htab_create ();
507 while (crx_instruction[i].mnemonic != NULL)
509 const char *mnemonic = crx_instruction[i].mnemonic;
511 if (str_hash_insert (crx_inst_hash, mnemonic, &crx_instruction[i], 0))
512 as_fatal (_("duplicate %s"), mnemonic);
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. */
520 ++i;
522 while (crx_instruction[i].mnemonic != NULL
523 && streq (crx_instruction[i].mnemonic, mnemonic));
526 /* Initialize reg_hash hash table. */
527 reg_hash = str_htab_create ();
529 const reg_entry *regtab;
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);
537 /* Initialize copreg_hash hash table. */
538 copreg_hash = str_htab_create ();
540 const reg_entry *copregtab;
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);
547 /* Set linkrelax here to avoid fixups in most sections. */
548 linkrelax = 1;
551 /* Process constants (immediate/absolute)
552 and labels (jump targets/Memory locations). */
554 static void
555 process_label_constant (char *str, ins * crx_ins)
557 char *saved_input_line_pointer;
558 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
560 saved_input_line_pointer = input_line_pointer;
561 input_line_pointer = str;
563 expression (&crx_ins->exp);
565 switch (crx_ins->exp.X_op)
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. */
578 case O_constant:
579 cur_arg->X_op = O_constant;
580 cur_arg->constant = crx_ins->exp.X_add_number;
581 break;
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;
590 switch (cur_arg->type)
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;
602 case arg_idxr:
603 crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
604 break;
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;
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;
629 break;
631 default:
632 cur_arg->X_op = crx_ins->exp.X_op;
633 break;
636 input_line_pointer = saved_input_line_pointer;
637 return;
640 /* Get the values of the scale to be encoded -
641 used for the scaled index mode of addressing. */
643 static int
644 exponent2scale (int val)
646 int exponent;
648 /* If 'val' is 0, the following 'for' will be an endless loop. */
649 if (val == 0)
650 return 0;
652 for (exponent = 0; (val != 1); val >>= 1, exponent++)
655 return exponent;
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 */
666 static void
667 set_operand (char *operand, ins * crx_ins)
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. */
676 /* Initialize pointers. */
677 operandS = operandE = operand;
679 switch (cur_arg->type)
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);
689 if (cur_arg->type != arg_ic)
690 cur_arg->type = arg_c;
691 break;
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);
713 if (cur_arg->type != arg_rbase)
714 cur_arg->type = arg_cr;
715 break;
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;
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);
733 /* Skip leading white space. */
734 while (ISSPACE (*operandE))
735 operandE++;
736 operandS = operandE;
738 /* Set register index. */
739 while ((*operandE != ')') && (*operandE != ','))
740 operandE++;
741 c = *operandE;
742 *operandE++ = '\0';
744 if ((cur_arg->i_r = get_register (operandS)) == nullregister)
745 as_bad (_("Illegal register `%s' in instruction `%s'"),
746 operandS, ins_parse);
748 /* Skip leading white space. */
749 while (ISSPACE (*operandE))
750 operandE++;
751 operandS = operandE;
753 /* Set the scale. */
754 if (c == ')')
755 cur_arg->scale = 0;
756 else
758 while (*operandE != ')')
759 operandE++;
760 *operandE = '\0';
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;
768 scale_val = scale.X_add_number;
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);
775 cur_arg->scale = exponent2scale (scale_val);
777 break;
779 default:
780 break;
784 /* Parse a single operand.
785 operand - Current operand to parse.
786 crx_ins - Current assembled instruction. */
788 static void
789 parse_operand (char *operand, ins * crx_ins)
791 int ret_val;
792 argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
794 /* Initialize the type to NULL before parsing. */
795 cur_arg->type = nullargs;
797 /* Check whether this is a general processor register. */
798 if ((ret_val = get_register (operand)) != nullregister)
800 cur_arg->type = arg_r;
801 cur_arg->r = ret_val;
802 cur_arg->X_op = O_register;
803 return;
806 /* Check whether this is a core [special] coprocessor register. */
807 if ((ret_val = get_copregister (operand)) != nullcopregister)
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;
817 /* Deal with special characters. */
818 switch (operand[0])
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;
828 case '*':
829 cur_arg->type = arg_sc;
830 goto set_params;
831 break;
833 case '(':
834 cur_arg->type = arg_rbase;
835 goto set_params;
836 break;
838 default:
839 break;
842 if (strchr (operand, '(') != NULL)
844 if (strchr (operand, ',') != NULL
845 && (strchr (operand, ',') > strchr (operand, '(')))
846 cur_arg->type = arg_idxr;
847 else
848 cur_arg->type = arg_cr;
850 else
851 cur_arg->type = arg_c;
852 goto set_params;
854 /* Parse an operand according to its type. */
855 set_params:
856 cur_arg->constant = 0;
857 set_operand (operand, crx_ins);
860 /* Parse the various operands. Each operand is then analyzed to fillup
861 the fields in the crx_ins data structure. */
863 static void
864 parse_operands (ins * crx_ins, char *operands)
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. */
874 /* Preprocess the list of registers, if necessary. */
875 operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
876 preprocess_reglist (operands, &allocated) : operands;
878 while (*operandT != '\0')
880 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
882 *operandT++ = '\0';
883 operand[op_num++] = strdup (operandH);
884 operandH = operandT;
885 continue;
888 if (*operandT == ' ')
889 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
891 if (*operandT == '(')
892 bracket_flag = 1;
893 else if (*operandT == '[')
894 sq_bracket_flag = 1;
896 if (*operandT == ')')
898 if (bracket_flag)
899 bracket_flag = 0;
900 else
901 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
903 else if (*operandT == ']')
905 if (sq_bracket_flag)
906 sq_bracket_flag = 0;
907 else
908 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
911 if (bracket_flag == 1 && *operandT == ')')
912 bracket_flag = 0;
913 else if (sq_bracket_flag == 1 && *operandT == ']')
914 sq_bracket_flag = 0;
916 operandT++;
919 /* Adding the last operand. */
920 operand[op_num++] = strdup (operandH);
921 crx_ins->nargs = op_num;
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);
927 /* Now we parse each operand separately. */
928 for (op_num = 0; op_num < crx_ins->nargs; op_num++)
930 cur_arg_num = op_num;
931 parse_operand (operand[op_num], crx_ins);
932 free (operand[op_num]);
935 if (allocated)
936 free (operandS);
939 /* Get the trap index in dispatch table, given its name.
940 This routine is used by assembling the 'excp' instruction. */
942 static int
943 gettrap (const char *s)
945 const trap_entry *trap;
947 for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
948 if (strcasecmp (trap->name, s) == 0)
949 return trap->entry;
951 as_bad (_("Unknown exception: `%s'"), s);
952 return 0;
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. */
962 static void
963 handle_LoadStor (const char *operands)
965 /* Post-Increment instructions precede Store-Immediate instructions in
966 CRX instruction table, hence they are handled before.
967 This synchronization should be kept. */
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)
974 while (! IS_INSN_TYPE (LD_STOR_INS_INC))
975 instruction++;
976 return;
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++;
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. */
991 static void
992 parse_insn (ins *insn, char *operands)
994 int i;
996 /* Handle instructions with no operands. */
997 for (i = 0; crx_no_op_insn[i] != NULL; i++)
999 if (streq (crx_no_op_insn[i], instruction->mnemonic))
1001 insn->nargs = 0;
1002 return;
1006 /* Handle 'excp'/'cinv' instructions. */
1007 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
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;
1017 /* Handle load/stor unique instructions before parsing. */
1018 if (IS_INSN_TYPE (LD_STOR_INS))
1019 handle_LoadStor (operands);
1021 if (operands != NULL)
1022 parse_operands (insn, operands);
1025 /* Cinv instruction requires special handling. */
1027 static int
1028 get_cinv_parameters (const char *operand)
1030 const char *p = operand;
1031 int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1033 while (*++p != ']')
1035 if (*p == ',' || *p == ' ')
1036 continue;
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);
1050 return ((b_used ? 8 : 0)
1051 + (d_used ? 4 : 0)
1052 + (i_used ? 2 : 0)
1053 + (u_used ? 1 : 0));
1056 /* Retrieve the opcode image of a given register.
1057 If the register is illegal for the current instruction,
1058 issue an error. */
1060 static int
1061 getreg_image (int r)
1063 const reg_entry *rreg;
1064 char *reg_name;
1065 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1067 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1068 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1069 is_procreg = 1;
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
1080 as_bad (_("Unknown register: `%d'"), r);
1081 return 0;
1084 reg_name = rreg->name;
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);
1091 switch (rreg->type)
1093 case CRX_U_REGTYPE:
1094 if (is_procreg || (instruction->flags & USER_REG))
1095 return rreg->image;
1096 else
1097 IMAGE_ERR;
1098 break;
1100 case CRX_CFG_REGTYPE:
1101 if (is_procreg)
1102 return rreg->image;
1103 else
1104 IMAGE_ERR;
1105 break;
1107 case CRX_R_REGTYPE:
1108 if (! is_procreg)
1109 return rreg->image;
1110 else
1111 IMAGE_ERR;
1112 break;
1114 case CRX_C_REGTYPE:
1115 case CRX_CS_REGTYPE:
1116 return rreg->image;
1117 break;
1119 default:
1120 IMAGE_ERR;
1121 break;
1124 return 0;
1127 /* Routine used to represent integer X using NBITS bits. */
1129 static long
1130 getconstant (long x, int nbits)
1132 return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
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. */
1140 static void
1141 print_constant (int nbits, int shift, argument *arg)
1143 unsigned long mask = 0;
1144 unsigned long constant = getconstant (arg->constant, nbits);
1146 switch (nbits)
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] */
1164 CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1165 CRX_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1166 break;
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)
1174 CRX_PRINT (0, constant, 0);
1175 break;
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] */
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;
1194 default:
1195 CRX_PRINT (0, constant, shift);
1196 break;
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. */
1206 static void
1207 print_operand (int nbits, int shift, argument *arg)
1209 switch (arg->type)
1211 case arg_r:
1212 CRX_PRINT (0, getreg_image (arg->r), shift);
1213 break;
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;
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;
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;
1243 case arg_rbase:
1244 CRX_PRINT (0, getreg_image (arg->r), shift);
1245 break;
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;
1258 default:
1259 break;
1263 /* Retrieve the number of operands for the current assembled instruction. */
1265 static int
1266 get_number_of_operands (void)
1268 int i;
1270 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1272 return i;
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. */
1280 static op_err
1281 check_range (long *num, int bits, int unsigned flags, int update)
1283 uint32_t max;
1284 op_err retval = OP_LEGAL;
1285 int bin;
1286 uint32_t upper_64kb = 0xffff0000;
1287 uint32_t value = *num;
1289 /* Verify operand value is even. */
1290 if (flags & OP_EVEN)
1292 if (value % 2)
1293 return OP_NOT_EVEN;
1296 if (flags & OP_UPPER_64KB)
1298 /* Check if value is to be mapped to upper 64 KB memory area. */
1299 if ((value & upper_64kb) == upper_64kb)
1301 value -= upper_64kb;
1302 if (update)
1303 *num = value;
1305 else
1306 return OP_NOT_UPPER_64KB;
1309 if (flags & OP_SHIFT)
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;
1320 else if (flags & OP_SHIFT_DEC)
1322 value = (value >> 1) - 1;
1323 if (update)
1324 *num = value;
1327 if (flags & OP_ESC)
1329 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1330 if (value == 0x7e || value == 0x7f)
1331 return OP_OUT_OF_RANGE;
1334 if (flags & OP_DISPU4)
1336 int is_dispu4 = 0;
1338 uint32_t mul = (instruction->flags & DISPUB4 ? 1
1339 : instruction->flags & DISPUW4 ? 2
1340 : instruction->flags & DISPUD4 ? 4
1341 : 0);
1343 for (bin = 0; bin < crx_cst4_maps; bin++)
1345 if (value == mul * bin)
1347 is_dispu4 = 1;
1348 if (update)
1349 *num = bin;
1350 break;
1353 if (!is_dispu4)
1354 retval = OP_ILLEGAL_DISPU4;
1356 else if (flags & OP_CST4)
1358 int is_cst4 = 0;
1360 for (bin = 0; bin < crx_cst4_maps; bin++)
1362 if (value == (uint32_t) crx_cst4_map[bin])
1364 is_cst4 = 1;
1365 if (update)
1366 *num = bin;
1367 break;
1370 if (!is_cst4)
1371 retval = OP_ILLEGAL_CST4;
1373 else if (flags & OP_SIGNED)
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;
1382 else if (flags & OP_UNSIGNED)
1384 max = 1;
1385 max = max << (bits - 1);
1386 max = ((max - 1) << 1) | 1;
1387 if (value > max)
1388 retval = OP_OUT_OF_RANGE;
1390 return retval;
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. */
1402 static int
1403 assemble_insn (char *mnemonic, ins *insn)
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;
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)
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)
1438 /* Instruction has no operands -> only copy the constant opcode. */
1439 if (insn->nargs == 0)
1441 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1442 return 1;
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);
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))
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;
1467 /* Initialize arrays with data of each operand in current template. */
1468 GET_CURRENT_TYPE;
1469 GET_CURRENT_SIZE;
1470 GET_CURRENT_FLAGS;
1472 /* Check for type compatibility. */
1473 for (i = 0; i < insn->nargs; i++)
1475 if (cur_type[i] != insn->arg[i].type)
1477 if (invalid_optype == -1)
1478 invalid_optype = i + 1;
1479 goto next_insn;
1482 found_same_argument_types = 1;
1484 for (i = 0; i < insn->nargs; i++)
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;
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)))
1500 if (invalid_const == -1)
1502 invalid_const = j + 1;
1503 const_err = op_error;
1505 goto next_insn;
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;
1514 found_const_within_range = 1;
1516 /* If we got till here -> Full match is found. */
1517 match = 1;
1518 break;
1520 /* Try again with next instruction. */
1521 next_insn:
1522 instruction++;
1525 if (!match)
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)
1534 switch (const_err)
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;
1560 return 0;
1562 else
1563 /* Full match - print the encoding to output file. */
1565 /* Make further checking (such that couldn't be made earlier).
1566 Warn the user if necessary. */
1567 warn_if_needed (insn);
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;
1575 for (i = 0; i < insn->nargs; i++)
1577 int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
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);
1586 /* First, copy the instruction's opcode. */
1587 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1589 for (i = 0; i < insn->nargs; i++)
1591 cur_arg_num = i;
1592 print_operand (cur_size[i], instruction->operands[i].shift,
1593 &insn->arg[i]);
1597 return 1;
1600 /* Bunch of error checking.
1601 The checks are made after a matching instruction was found. */
1603 void
1604 warn_if_needed (ins *insn)
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))
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);
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)
1622 if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1623 as_bad (_("`%s' has undefined result"), ins_parse);
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)
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));
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. */
1641 adjust_if_needed (ins *insn)
1643 int ret_value = 0;
1645 /* Special check for 'addub $0, r0' instruction -
1646 The opcode '0000 0000 0000 0000' is not allowed. */
1647 if (IS_INSN_MNEMONIC ("addub"))
1649 if ((instruction->operands[0].op_type == cst4)
1650 && instruction->operands[1].op_type == regr)
1652 if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1654 instruction++;
1655 ret_value = 1;
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))
1664 if ((instruction->operands[1].op_type == rbase_disps12)
1665 && (insn->arg[1].X_op == O_constant)
1666 && (insn->arg[1].constant == 0))
1668 instruction--;
1669 ret_value = 1;
1673 return ret_value;
1676 /* Set the appropriate bit for register 'r' in 'mask'.
1677 This indicates that this register is loaded or stored by
1678 the instruction. */
1680 static void
1681 mask_reg (int r, unsigned short int *mask)
1683 if ((reg)r > (reg)sp)
1685 as_bad (_("Invalid register in register list"));
1686 return;
1689 *mask |= (1 << r);
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. */
1696 static char *
1697 preprocess_reglist (char *param, int *allocated)
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;
1710 /* If 'param' is already in form of a number, no need to preprocess. */
1711 if (strchr (paramP, '{') == NULL)
1712 return param;
1714 /* Verifying correct syntax of operand. */
1715 if (strchr (paramP, '}') == NULL)
1716 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1718 while (*paramP++ != '{');
1720 new_param = XCNEWVEC (char, MAX_INST_LEN);
1721 *allocated = 1;
1722 strncpy (new_param, param, paramP - param - 1);
1724 while (*paramP != '}')
1726 regP = paramP;
1727 memset (&reg_name, '\0', sizeof (reg_name));
1729 while (ISALNUM (*paramP))
1730 paramP++;
1732 strncpy (reg_name, regP, paramP - regP);
1734 /* Coprocessor register c<N>. */
1735 if (IS_INSN_TYPE (COP_REG_INS))
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);
1742 /* Coprocessor Special register cs<N>. */
1743 else if (IS_INSN_TYPE (COPS_REG_INS))
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);
1751 /* User register u<N>. */
1752 else if (instruction->flags & USER_REG)
1754 if (streq(reg_name, "uhi"))
1756 hi_found = 1;
1757 goto next_inst;
1759 else if (streq(reg_name, "ulo"))
1761 lo_found = 1;
1762 goto next_inst;
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);
1768 mask_reg (getreg_image (r - u0), &mask);
1770 /* General purpose register r<N>. */
1771 else
1773 if (streq(reg_name, "hi"))
1775 hi_found = 1;
1776 goto next_inst;
1778 else if (streq(reg_name, "lo"))
1780 lo_found = 1;
1781 goto next_inst;
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);
1787 mask_reg (getreg_image (r - r0), &mask);
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);
1794 next_inst:
1795 while (!ISALNUM (*paramP) && *paramP != '}')
1796 paramP++;
1799 if (*++paramP != '\0')
1800 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1801 *paramP);
1803 switch (hi_found + lo_found)
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;
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;
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"));
1822 default:
1823 break;
1826 sprintf (maskstring, "$0x%x", mask);
1827 strcat (new_param, maskstring);
1828 return new_param;
1831 /* Print the instruction.
1832 Handle also cases where the instruction is relaxable/relocatable. */
1834 static void
1835 print_insn (ins *insn)
1837 unsigned int i, j, insn_size;
1838 char *this_frag;
1839 unsigned short words[4];
1840 int addr_mod;
1842 /* Arrange the insn encodings in a WORD size array. */
1843 for (i = 0, j = 0; i < 2; i++)
1845 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1846 words[j++] = output_opcode[i] & 0xFFFF;
1849 /* Handle relaxation. */
1850 if ((instruction->flags & RELAXABLE) && relocatable)
1852 int relax_subtype;
1854 /* Write the maximal instruction size supported. */
1855 insn_size = INSN_MAX_SIZE;
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 ();
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,
1875 else
1877 insn_size = instruction->size;
1878 this_frag = frag_more (insn_size * 2);
1880 /* Handle relocation. */
1881 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1883 reloc_howto_type *reloc_howto;
1884 int size;
1886 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1888 if (!reloc_howto)
1889 abort ();
1891 size = bfd_get_reloc_size (reloc_howto);
1893 if (size < 1 || size > 4)
1894 abort ();
1896 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1897 size, &insn->exp, reloc_howto->pc_relative,
1898 insn->rtype);
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;
1909 /* Write the instruction encoding to frag. */
1910 for (i = 0; i < insn_size; i++)
1912 md_number_to_chars (this_frag, (valueT) words[i], 2);
1913 this_frag += 2;
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. */
1921 void
1922 md_assemble (char *op)
1924 ins crx_ins;
1925 char *param;
1926 char c;
1928 /* Reset global variables for a new instruction. */
1929 reset_vars (op);
1931 /* Strip the mnemonic. */
1932 for (param = op; *param != 0 && !ISSPACE (*param); param++)
1934 c = *param;
1935 *param++ = '\0';
1937 /* Find the instruction. */
1938 instruction = (const inst *) str_hash_find (crx_inst_hash, op);
1939 if (instruction == NULL)
1941 as_bad (_("Unknown opcode: `%s'"), op);
1942 param[-1] = c;
1943 return;
1946 /* Tie dwarf2 debug info to the address at the start of the insn. */
1947 dwarf2_emit_insn (0);
1949 /* Parse the instruction's operands. */
1950 parse_insn (&crx_ins, param);
1952 /* Assemble the instruction - return upon failure. */
1953 if (assemble_insn (op, &crx_ins) == 0)
1955 param[-1] = c;
1956 return;
1959 /* Print the instruction. */
1960 param[-1] = c;
1961 print_insn (&crx_ins);