1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright (C) 2004-2021 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)
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. */
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "opcode/crx.h"
32 /* Word is considered here as a 16-bit unsigned short int. */
35 /* Register is 4-bit size. */
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)
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). */
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 struct option md_longopts
[] =
108 {NULL
, no_argument
, NULL
, 0}
110 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},
125 /* CRX relaxation table. */
126 const relax_typeS md_relax_table
[] =
129 {0xfa, -0x100, 2, 1}, /* 8 */
130 {0xfffe, -0x10000, 4, 2}, /* 16 */
131 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
134 {0xfffe, -0x10000, 4, 4}, /* 16 */
135 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
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. */
150 get_opbits (operand_type op
)
153 return crx_optab
[op
].bit_size
;
158 /* Return the argument type of a given operand. */
161 get_optype (operand_type op
)
164 return crx_optab
[op
].arg_type
;
169 /* Return the flags of a given operand. */
172 get_opflags (operand_type op
)
175 return crx_optab
[op
].flags
;
180 /* Get the core processor register 'reg_name'. */
183 get_register (char *reg_name
)
185 const reg_entry
*rreg
;
187 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
190 return rreg
->value
.reg_val
;
195 /* Get the coprocessor register 'copreg_name'. */
198 get_copregister (char *copreg_name
)
200 const reg_entry
*coreg
;
202 coreg
= (const reg_entry
*) str_hash_find (copreg_hash
, copreg_name
);
205 return coreg
->value
.copreg_val
;
207 return nullcopregister
;
210 /* Round up a section size to the appropriate boundary. */
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;
221 /* Parse an operand that is machine-specific (remove '*'). */
224 md_operand (expressionS
* exp
)
226 char c
= *input_line_pointer
;
231 input_line_pointer
++;
239 /* Reset global variables before parsing a new instruction. */
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
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
272 crx_force_relocation (fixS
*fix
)
274 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
280 /* Generate a relocation entry for a fixup. */
283 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
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
;
306 case BFD_RELOC_CRX_NUM16
:
307 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH16
;
309 case BFD_RELOC_CRX_NUM32
:
310 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH32
;
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
)
326 S_GET_NAME (fixP
->fx_subsy
),
327 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
331 gas_assert ((int) fixP
->fx_r_type
> 0);
332 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
334 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
336 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
337 _("internal error: reloc %d (`%s') not supported by object file format"),
339 bfd_get_reloc_code_name (fixP
->fx_r_type
));
342 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
347 /* Prepare machine-dependent frags for relaxation. */
350 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
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,
359 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
361 if (fragp
->fr_subtype
== rlx_state
[subtype
]
362 && (!S_IS_DEFINED (fragp
->fr_symbol
)
363 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
365 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
370 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
373 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
377 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
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
;
384 subseg_change (sec
, 0);
386 switch (fragP
->fr_subtype
)
389 reloc
= BFD_RELOC_CRX_REL8
;
393 reloc
= BFD_RELOC_CRX_REL16
;
397 reloc
= BFD_RELOC_CRX_REL32
;
400 reloc
= BFD_RELOC_CRX_REL16
;
404 reloc
= BFD_RELOC_CRX_REL32
;
407 reloc
= BFD_RELOC_CRX_REL8_CMP
;
411 reloc
= BFD_RELOC_CRX_REL24
;
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
);
422 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
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. */
430 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
435 /* Machine-dependent usage-output. */
438 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
444 md_atof (int type
, char *litP
, int *sizeP
)
446 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
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. */
456 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
459 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
462 switch (fixP
->fx_r_type
)
464 case BFD_RELOC_CRX_NUM8
:
465 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
467 case BFD_RELOC_CRX_NUM16
:
468 bfd_put_16 (stdoutput
, val
, buf
);
470 case BFD_RELOC_CRX_NUM32
:
471 bfd_put_32 (stdoutput
, val
, buf
);
474 /* We shouldn't ever get here because linkrelax is nonzero. */
481 if (fixP
->fx_addsy
== NULL
482 && fixP
->fx_pcrel
== 0)
485 if (fixP
->fx_pcrel
== 1
486 && fixP
->fx_addsy
!= NULL
487 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
491 /* The location from which a PC relative jump should be calculated,
492 given a PC relative reloc. */
495 md_pcrel_from (fixS
*fixp
)
497 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
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. */
508 /* Set up a hash table for the instructions. */
509 crx_inst_hash
= str_htab_create ();
511 while (crx_instruction
[i
].mnemonic
!= NULL
)
513 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
515 if (str_hash_insert (crx_inst_hash
, mnemonic
, &crx_instruction
[i
], 0))
516 as_fatal (_("duplicate %s"), mnemonic
);
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. */
526 while (crx_instruction
[i
].mnemonic
!= NULL
527 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
530 /* Initialize reg_hash hash table. */
531 reg_hash
= str_htab_create ();
533 const reg_entry
*regtab
;
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
);
541 /* Initialize copreg_hash hash table. */
542 copreg_hash
= str_htab_create ();
544 const reg_entry
*copregtab
;
546 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
548 if (str_hash_insert (copreg_hash
, copregtab
->name
, copregtab
, 0) != NULL
)
549 as_fatal (_("duplicate %s"), copregtab
->name
);
551 /* Set linkrelax here to avoid fixups in most sections. */
555 /* Process constants (immediate/absolute)
556 and labels (jump targets/Memory locations). */
559 process_label_constant (char *str
, ins
* crx_ins
)
561 char *saved_input_line_pointer
;
562 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
564 saved_input_line_pointer
= input_line_pointer
;
565 input_line_pointer
= str
;
567 expression (&crx_ins
->exp
);
569 switch (crx_ins
->exp
.X_op
)
573 /* Missing or bad expr becomes absolute 0. */
574 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
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;
583 cur_arg
->X_op
= O_constant
;
584 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
590 cur_arg
->X_op
= O_symbol
;
591 crx_ins
->rtype
= BFD_RELOC_NONE
;
594 switch (cur_arg
->type
)
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
;
603 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
607 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
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
;
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
;
636 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
640 input_line_pointer
= saved_input_line_pointer
;
644 /* Get the values of the scale to be encoded -
645 used for the scaled index mode of addressing. */
648 exponent2scale (int val
)
652 /* If 'val' is 0, the following 'for' will be an endless loop. */
656 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
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 */
671 set_operand (char *operand
, ins
* crx_ins
)
673 char *operandS
; /* Pointer to start of sub-operand. */
674 char *operandE
; /* Pointer to end of sub-operand. */
678 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
680 /* Initialize pointers. */
681 operandS
= operandE
= operand
;
683 switch (cur_arg
->type
)
685 case arg_sc
: /* Case *+0x18. */
686 case arg_ic
: /* Case $0x18. */
689 case arg_c
: /* Case 0x18. */
691 process_label_constant (operandS
, crx_ins
);
693 if (cur_arg
->type
!= arg_ic
)
694 cur_arg
->type
= arg_c
;
697 case arg_icr
: /* Case $0x18(r1). */
699 case arg_cr
: /* Case 0x18(r1). */
700 /* Set displacement constant. */
701 while (*operandE
!= '(')
704 process_label_constant (operandS
, crx_ins
);
707 case arg_rbase
: /* Case (r1). */
709 /* Set register base. */
710 while (*operandE
!= ')')
713 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
714 as_bad (_("Illegal register `%s' in instruction `%s'"),
715 operandS
, ins_parse
);
717 if (cur_arg
->type
!= arg_rbase
)
718 cur_arg
->type
= arg_cr
;
722 /* Set displacement constant. */
723 while (*operandE
!= '(')
726 process_label_constant (operandS
, crx_ins
);
727 operandS
= ++operandE
;
729 /* Set register base. */
730 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
733 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
734 as_bad (_("Illegal register `%s' in instruction `%s'"),
735 operandS
, ins_parse
);
737 /* Skip leading white space. */
738 while (ISSPACE (*operandE
))
742 /* Set register index. */
743 while ((*operandE
!= ')') && (*operandE
!= ','))
748 if ((cur_arg
->i_r
= get_register (operandS
)) == nullregister
)
749 as_bad (_("Illegal register `%s' in instruction `%s'"),
750 operandS
, ins_parse
);
752 /* Skip leading white space. */
753 while (ISSPACE (*operandE
))
762 while (*operandE
!= ')')
766 /* Preprocess the scale string. */
767 input_save
= input_line_pointer
;
768 input_line_pointer
= operandS
;
770 input_line_pointer
= input_save
;
772 scale_val
= scale
.X_add_number
;
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
);
779 cur_arg
->scale
= exponent2scale (scale_val
);
788 /* Parse a single operand.
789 operand - Current operand to parse.
790 crx_ins - Current assembled instruction. */
793 parse_operand (char *operand
, ins
* crx_ins
)
796 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
798 /* Initialize the type to NULL before parsing. */
799 cur_arg
->type
= nullargs
;
801 /* Check whether this is a general processor register. */
802 if ((ret_val
= get_register (operand
)) != nullregister
)
804 cur_arg
->type
= arg_r
;
805 cur_arg
->r
= ret_val
;
806 cur_arg
->X_op
= O_register
;
810 /* Check whether this is a core [special] coprocessor register. */
811 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
813 cur_arg
->type
= arg_copr
;
815 cur_arg
->type
= arg_copsr
;
816 cur_arg
->cr
= ret_val
;
817 cur_arg
->X_op
= O_register
;
821 /* Deal with special characters. */
825 if (strchr (operand
, '(') != NULL
)
826 cur_arg
->type
= arg_icr
;
828 cur_arg
->type
= arg_ic
;
833 cur_arg
->type
= arg_sc
;
838 cur_arg
->type
= arg_rbase
;
846 if (strchr (operand
, '(') != NULL
)
848 if (strchr (operand
, ',') != NULL
849 && (strchr (operand
, ',') > strchr (operand
, '(')))
850 cur_arg
->type
= arg_idxr
;
852 cur_arg
->type
= arg_cr
;
855 cur_arg
->type
= arg_c
;
858 /* Parse an operand according to its type. */
860 cur_arg
->constant
= 0;
861 set_operand (operand
, crx_ins
);
864 /* Parse the various operands. Each operand is then analyzed to fillup
865 the fields in the crx_ins data structure. */
868 parse_operands (ins
* crx_ins
, char *operands
)
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. */
878 /* Preprocess the list of registers, if necessary. */
879 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
880 preprocess_reglist (operands
, &allocated
) : operands
;
882 while (*operandT
!= '\0')
884 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
887 operand
[op_num
++] = strdup (operandH
);
892 if (*operandT
== ' ')
893 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
895 if (*operandT
== '(')
897 else if (*operandT
== '[')
900 if (*operandT
== ')')
905 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
907 else if (*operandT
== ']')
912 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
915 if (bracket_flag
== 1 && *operandT
== ')')
917 else if (sq_bracket_flag
== 1 && *operandT
== ']')
923 /* Adding the last operand. */
924 operand
[op_num
++] = strdup (operandH
);
925 crx_ins
->nargs
= op_num
;
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
);
931 /* Now we parse each operand separately. */
932 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
934 cur_arg_num
= op_num
;
935 parse_operand (operand
[op_num
], crx_ins
);
936 free (operand
[op_num
]);
943 /* Get the trap index in dispatch table, given its name.
944 This routine is used by assembling the 'excp' instruction. */
947 gettrap (const char *s
)
949 const trap_entry
*trap
;
951 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
952 if (strcasecmp (trap
->name
, s
) == 0)
955 as_bad (_("Unknown exception: `%s'"), s
);
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. */
967 handle_LoadStor (const char *operands
)
969 /* Post-Increment instructions precede Store-Immediate instructions in
970 CRX instruction table, hence they are handled before.
971 This synchronization should be kept. */
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
)
978 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
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
))
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. */
996 parse_insn (ins
*insn
, char *operands
)
1000 /* Handle instructions with no operands. */
1001 for (i
= 0; crx_no_op_insn
[i
] != NULL
; i
++)
1003 if (streq (crx_no_op_insn
[i
], instruction
->mnemonic
))
1010 /* Handle 'excp'/'cinv' instructions. */
1011 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
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
;
1021 /* Handle load/stor unique instructions before parsing. */
1022 if (IS_INSN_TYPE (LD_STOR_INS
))
1023 handle_LoadStor (operands
);
1025 if (operands
!= NULL
)
1026 parse_operands (insn
, operands
);
1029 /* Cinv instruction requires special handling. */
1032 get_cinv_parameters (const char *operand
)
1034 const char *p
= operand
;
1035 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1039 if (*p
== ',' || *p
== ' ')
1051 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1054 return ((b_used
? 8 : 0)
1057 + (u_used
? 1 : 0));
1060 /* Retrieve the opcode image of a given register.
1061 If the register is illegal for the current instruction,
1065 getreg_image (int r
)
1067 const reg_entry
*rreg
;
1069 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1071 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num
== 1))
1072 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num
== 0)) )
1075 /* Check whether the register is in registers table. */
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. */
1084 as_bad (_("Unknown register: `%d'"), r
);
1088 reg_name
= rreg
->name
;
1090 /* Issue a error message when register is illegal. */
1092 as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1093 reg_name, ins_parse);
1098 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1104 case CRX_CFG_REGTYPE
:
1119 case CRX_CS_REGTYPE
:
1131 /* Routine used to represent integer X using NBITS bits. */
1134 getconstant (long x
, int nbits
)
1136 return x
& ((((1U << (nbits
- 1)) - 1) << 1) | 1);
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. */
1145 print_constant (int nbits
, int shift
, argument
*arg
)
1147 unsigned long mask
= 0;
1148 unsigned long constant
= getconstant (arg
->constant
, nbits
);
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 :
1163 +---------+---------+---------+---------+
1164 | | X X X X | X X X X | |
1165 +---------+---------+---------+---------+
1166 output_opcode[0] output_opcode[1] */
1168 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1169 CRX_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
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
)
1178 CRX_PRINT (0, constant
, 0);
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')
1187 +---------+---------+---------+---------+
1188 | 'match' | | X X X X | |
1189 +---------+---------+---------+---------+
1190 output_opcode[0] output_opcode[1] */
1192 if ((instruction
->size
> 2) && (shift
== WORD_SHIFT
))
1193 CRX_PRINT (1, constant
, WORD_SHIFT
);
1195 CRX_PRINT (0, constant
, shift
);
1199 CRX_PRINT (0, constant
, shift
);
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. */
1211 print_operand (int nbits
, int shift
, argument
*arg
)
1216 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1220 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1221 as_bad (_("Illegal co-processor register in instruction `%s'"),
1223 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1227 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1228 as_bad (_("Illegal co-processor special register in instruction `%s'"),
1230 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
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);
1244 print_constant (nbits
, shift
, arg
);
1248 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1252 /* case base_cst4. */
1253 if (instruction
->flags
& DISPU4MAP
)
1254 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
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
);
1267 /* Retrieve the number of operands for the current assembled instruction. */
1270 get_number_of_operands (void)
1274 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
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. */
1285 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1288 op_err retval
= OP_LEGAL
;
1290 uint32_t upper_64kb
= 0xffff0000;
1291 uint32_t value
= *num
;
1293 /* Verify operand value is even. */
1294 if (flags
& OP_EVEN
)
1300 if (flags
& OP_UPPER_64KB
)
1302 /* Check if value is to be mapped to upper 64 KB memory area. */
1303 if ((value
& upper_64kb
) == upper_64kb
)
1305 value
-= upper_64kb
;
1310 return OP_NOT_UPPER_64KB
;
1313 if (flags
& OP_SHIFT
)
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. */
1320 value
= (value
^ 0x40000000) - 0x40000000;
1324 else if (flags
& OP_SHIFT_DEC
)
1326 value
= (value
>> 1) - 1;
1333 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1334 if (value
== 0x7e || value
== 0x7f)
1335 return OP_OUT_OF_RANGE
;
1338 if (flags
& OP_DISPU4
)
1342 uint32_t mul
= (instruction
->flags
& DISPUB4
? 1
1343 : instruction
->flags
& DISPUW4
? 2
1344 : instruction
->flags
& DISPUD4
? 4
1347 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1349 if (value
== mul
* bin
)
1358 retval
= OP_ILLEGAL_DISPU4
;
1360 else if (flags
& OP_CST4
)
1364 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1366 if (value
== (uint32_t) crx_cst4_map
[bin
])
1375 retval
= OP_ILLEGAL_CST4
;
1377 else if (flags
& OP_SIGNED
)
1380 max
= max
<< (bits
- 1);
1382 max
= ((max
- 1) << 1) | 1;
1384 retval
= OP_OUT_OF_RANGE
;
1386 else if (flags
& OP_UNSIGNED
)
1389 max
= max
<< (bits
- 1);
1390 max
= ((max
- 1) << 1) | 1;
1392 retval
= OP_OUT_OF_RANGE
;
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. */
1407 assemble_insn (char *mnemonic
, ins
*insn
)
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. */
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
;
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)
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)
1442 /* Instruction has no operands -> only copy the constant opcode. */
1443 if (insn
->nargs
== 0)
1445 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
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
);
1457 while (/* Check that match is still not found. */
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
))
1466 /* Check whether number of arguments is legal. */
1467 if (get_number_of_operands () != insn
->nargs
)
1469 found_same_number_of_operands
= 1;
1471 /* Initialize arrays with data of each operand in current template. */
1476 /* Check for type compatibility. */
1477 for (i
= 0; i
< insn
->nargs
; i
++)
1479 if (cur_type
[i
] != insn
->arg
[i
].type
)
1481 if (invalid_optype
== -1)
1482 invalid_optype
= i
+ 1;
1486 found_same_argument_types
= 1;
1488 for (i
= 0; i
< insn
->nargs
; i
++)
1490 /* Reverse the operand indices for certain opcodes:
1493 Other index -->> stays the same. */
1494 int j
= (instruction
->flags
& REVERSE_MATCH
) && i
<= 1 ? 1 - i
: i
;
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
],
1504 if (invalid_const
== -1)
1506 invalid_const
= j
+ 1;
1507 const_err
= op_error
;
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
1518 found_const_within_range
= 1;
1520 /* If we got till here -> Full match is found. */
1524 /* Try again with next instruction. */
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
)
1540 case OP_OUT_OF_RANGE
:
1541 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1544 as_bad (_("Operand has odd displacement (arg %d)"),
1547 case OP_ILLEGAL_DISPU4
:
1548 as_bad (_("Invalid DISPU4 operand value (arg %d)"),
1551 case OP_ILLEGAL_CST4
:
1552 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1554 case OP_NOT_UPPER_64KB
:
1555 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1559 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
1567 /* Full match - print the encoding to output file. */
1569 /* Make further checking (such that couldn't be made earlier).
1570 Warn the user if necessary. */
1571 warn_if_needed (insn
);
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. */
1579 for (i
= 0; i
< insn
->nargs
; i
++)
1581 int j
= (instruction
->flags
& REVERSE_MATCH
) && i
<= 1 ? 1 - i
: i
;
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);
1590 /* First, copy the instruction's opcode. */
1591 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1593 for (i
= 0; i
< insn
->nargs
; i
++)
1596 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1604 /* Bunch of error checking.
1605 The checks are made after a matching instruction was found. */
1608 warn_if_needed (ins
*insn
)
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
))
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"),
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
)
1626 if (getreg_image (insn
->arg
[0].r
) == getreg_image (sp
))
1627 as_bad (_("`%s' has undefined result"), ins_parse
);
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
)
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
));
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. */
1645 adjust_if_needed (ins
*insn
)
1649 /* Special check for 'addub $0, r0' instruction -
1650 The opcode '0000 0000 0000 0000' is not allowed. */
1651 if (IS_INSN_MNEMONIC ("addub"))
1653 if ((instruction
->operands
[0].op_type
== cst4
)
1654 && instruction
->operands
[1].op_type
== regr
)
1656 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
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
))
1668 if ((instruction
->operands
[1].op_type
== rbase_disps12
)
1669 && (insn
->arg
[1].X_op
== O_constant
)
1670 && (insn
->arg
[1].constant
== 0))
1680 /* Set the appropriate bit for register 'r' in 'mask'.
1681 This indicates that this register is loaded or stored by
1685 mask_reg (int r
, unsigned short int *mask
)
1687 if ((reg
)r
> (reg
)sp
)
1689 as_bad (_("Invalid register in register list"));
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. */
1701 preprocess_reglist (char *param
, int *allocated
)
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. */
1714 /* If 'param' is already in form of a number, no need to preprocess. */
1715 if (strchr (paramP
, '{') == NULL
)
1718 /* Verifying correct syntax of operand. */
1719 if (strchr (paramP
, '}') == NULL
)
1720 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1722 while (*paramP
++ != '{');
1724 new_param
= XCNEWVEC (char, MAX_INST_LEN
);
1726 strncpy (new_param
, param
, paramP
- param
- 1);
1728 while (*paramP
!= '}')
1731 memset (®_name
, '\0', sizeof (reg_name
));
1733 while (ISALNUM (*paramP
))
1736 strncpy (reg_name
, regP
, paramP
- regP
);
1738 /* Coprocessor register c<N>. */
1739 if (IS_INSN_TYPE (COP_REG_INS
))
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
);
1746 /* Coprocessor Special register cs<N>. */
1747 else if (IS_INSN_TYPE (COPS_REG_INS
))
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"),
1753 mask_reg (getreg_image (cr
- cs0
), &mask
);
1755 /* User register u<N>. */
1756 else if (instruction
->flags
& USER_REG
)
1758 if (streq(reg_name
, "uhi"))
1763 else if (streq(reg_name
, "ulo"))
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
);
1772 mask_reg (getreg_image (r
- u0
), &mask
);
1774 /* General purpose register r<N>. */
1777 if (streq(reg_name
, "hi"))
1782 else if (streq(reg_name
, "lo"))
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
);
1791 mask_reg (getreg_image (r
- r0
), &mask
);
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
);
1799 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1803 if (*++paramP
!= '\0')
1804 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1807 switch (hi_found
+ lo_found
)
1810 /* At least one register should be specified. */
1812 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1817 /* HI can't be specified without LO (and vise-versa). */
1818 as_bad (_("HI/LO registers should be specified together"));
1822 /* HI/LO registers mustn't be masked with additional registers. */
1824 as_bad (_("HI/LO registers should be specified without additional registers"));
1830 sprintf (maskstring
, "$0x%x", mask
);
1831 strcat (new_param
, maskstring
);
1835 /* Print the instruction.
1836 Handle also cases where the instruction is relaxable/relocatable. */
1839 print_insn (ins
*insn
)
1841 unsigned int i
, j
, insn_size
;
1843 unsigned short words
[4];
1846 /* Arrange the insn encodings in a WORD size array. */
1847 for (i
= 0, j
= 0; i
< 2; i
++)
1849 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
1850 words
[j
++] = output_opcode
[i
] & 0xFFFF;
1853 /* Handle relaxation. */
1854 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
1858 /* Write the maximal instruction size supported. */
1859 insn_size
= INSN_MAX_SIZE
;
1862 if (IS_INSN_TYPE (BRANCH_INS
))
1865 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1868 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1873 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1875 insn
->exp
.X_add_symbol
,
1876 insn
->exp
.X_add_number
,
1881 insn_size
= instruction
->size
;
1882 this_frag
= frag_more (insn_size
* 2);
1884 /* Handle relocation. */
1885 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
1887 reloc_howto_type
*reloc_howto
;
1890 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1895 size
= bfd_get_reloc_size (reloc_howto
);
1897 if (size
< 1 || size
> 4)
1900 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1901 size
, &insn
->exp
, reloc_howto
->pc_relative
,
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;
1913 /* Write the instruction encoding to frag. */
1914 for (i
= 0; i
< insn_size
; i
++)
1916 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
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. */
1926 md_assemble (char *op
)
1932 /* Reset global variables for a new instruction. */
1935 /* Strip the mnemonic. */
1936 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
1941 /* Find the instruction. */
1942 instruction
= (const inst
*) str_hash_find (crx_inst_hash
, op
);
1943 if (instruction
== NULL
)
1945 as_bad (_("Unknown opcode: `%s'"), op
);
1950 /* Tie dwarf2 debug info to the address at the start of the insn. */
1951 dwarf2_emit_insn (0);
1953 /* Parse the instruction's operands. */
1954 parse_insn (&crx_ins
, param
);
1956 /* Assemble the instruction - return upon failure. */
1957 if (assemble_insn (op
, &crx_ins
) == 0)
1963 /* Print the instruction. */
1965 print_insn (&crx_ins
);