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)
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 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},
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_subtract (fixP
);
321 free (reloc
->sym_ptr_ptr
);
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"),
335 bfd_get_reloc_code_name (fixP
->fx_r_type
));
338 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
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,
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];
366 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
369 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
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
)
385 reloc
= BFD_RELOC_CRX_REL8
;
389 reloc
= BFD_RELOC_CRX_REL16
;
393 reloc
= BFD_RELOC_CRX_REL32
;
396 reloc
= BFD_RELOC_CRX_REL16
;
400 reloc
= BFD_RELOC_CRX_REL32
;
403 reloc
= BFD_RELOC_CRX_REL8_CMP
;
407 reloc
= BFD_RELOC_CRX_REL24
;
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
);
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
)
431 /* Machine-dependent usage-output. */
434 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
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. */
452 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
455 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
458 switch (fixP
->fx_r_type
)
460 case BFD_RELOC_CRX_NUM8
:
461 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
463 case BFD_RELOC_CRX_NUM16
:
464 bfd_put_16 (stdoutput
, val
, buf
);
466 case BFD_RELOC_CRX_NUM32
:
467 bfd_put_32 (stdoutput
, val
, buf
);
470 /* We shouldn't ever get here because linkrelax is nonzero. */
477 if (fixP
->fx_addsy
== NULL
478 && fixP
->fx_pcrel
== 0)
481 if (fixP
->fx_pcrel
== 1
482 && fixP
->fx_addsy
!= NULL
483 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
487 /* The location from which a PC relative jump should be calculated,
488 given a PC relative reloc. */
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. */
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. */
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
);
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. */
551 /* Process constants (immediate/absolute)
552 and labels (jump targets/Memory locations). */
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
)
569 /* Missing or bad expr becomes absolute 0. */
570 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
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;
579 cur_arg
->X_op
= O_constant
;
580 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
586 cur_arg
->X_op
= O_symbol
;
587 crx_ins
->rtype
= BFD_RELOC_NONE
;
590 switch (cur_arg
->type
)
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
;
599 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
603 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
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
;
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
;
632 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
636 input_line_pointer
= saved_input_line_pointer
;
640 /* Get the values of the scale to be encoded -
641 used for the scaled index mode of addressing. */
644 exponent2scale (int val
)
648 /* If 'val' is 0, the following 'for' will be an endless loop. */
652 for (exponent
= 0; (val
!= 1); val
>>= 1, 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 */
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. */
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. */
685 case arg_c
: /* Case 0x18. */
687 process_label_constant (operandS
, crx_ins
);
689 if (cur_arg
->type
!= arg_ic
)
690 cur_arg
->type
= arg_c
;
693 case arg_icr
: /* Case $0x18(r1). */
695 case arg_cr
: /* Case 0x18(r1). */
696 /* Set displacement constant. */
697 while (*operandE
!= '(')
700 process_label_constant (operandS
, crx_ins
);
703 case arg_rbase
: /* Case (r1). */
705 /* Set register base. */
706 while (*operandE
!= ')')
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
;
718 /* Set displacement constant. */
719 while (*operandE
!= '(')
722 process_label_constant (operandS
, crx_ins
);
723 operandS
= ++operandE
;
725 /* Set register base. */
726 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
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
))
738 /* Set register index. */
739 while ((*operandE
!= ')') && (*operandE
!= ','))
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
))
758 while (*operandE
!= ')')
762 /* Preprocess the scale string. */
763 input_save
= input_line_pointer
;
764 input_line_pointer
= operandS
;
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
);
784 /* Parse a single operand.
785 operand - Current operand to parse.
786 crx_ins - Current assembled instruction. */
789 parse_operand (char *operand
, ins
* crx_ins
)
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
;
806 /* Check whether this is a core [special] coprocessor register. */
807 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
809 cur_arg
->type
= arg_copr
;
811 cur_arg
->type
= arg_copsr
;
812 cur_arg
->cr
= ret_val
;
813 cur_arg
->X_op
= O_register
;
817 /* Deal with special characters. */
821 if (strchr (operand
, '(') != NULL
)
822 cur_arg
->type
= arg_icr
;
824 cur_arg
->type
= arg_ic
;
829 cur_arg
->type
= arg_sc
;
834 cur_arg
->type
= arg_rbase
;
842 if (strchr (operand
, '(') != NULL
)
844 if (strchr (operand
, ',') != NULL
845 && (strchr (operand
, ',') > strchr (operand
, '(')))
846 cur_arg
->type
= arg_idxr
;
848 cur_arg
->type
= arg_cr
;
851 cur_arg
->type
= arg_c
;
854 /* Parse an operand according to its type. */
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. */
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)
883 operand
[op_num
++] = strdup (operandH
);
888 if (*operandT
== ' ')
889 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
891 if (*operandT
== '(')
893 else if (*operandT
== '[')
896 if (*operandT
== ')')
901 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
903 else if (*operandT
== ']')
908 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
911 if (bracket_flag
== 1 && *operandT
== ')')
913 else if (sq_bracket_flag
== 1 && *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
]);
939 /* Get the trap index in dispatch table, given its name.
940 This routine is used by assembling the 'excp' instruction. */
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)
951 as_bad (_("Unknown exception: `%s'"), s
);
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. */
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
))
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
))
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. */
992 parse_insn (ins
*insn
, char *operands
)
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
))
1006 /* Handle 'excp'/'cinv' instructions. */
1007 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
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
;
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. */
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;
1035 if (*p
== ',' || *p
== ' ')
1047 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1050 return ((b_used
? 8 : 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,
1061 getreg_image (int r
)
1063 const reg_entry
*rreg
;
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)) )
1071 /* Check whether the register is in registers table. */
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. */
1080 as_bad (_("Unknown register: `%d'"), r
);
1084 reg_name
= rreg
->name
;
1086 /* Issue a error message when register is illegal. */
1088 as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1089 reg_name, ins_parse);
1094 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1100 case CRX_CFG_REGTYPE
:
1115 case CRX_CS_REGTYPE
:
1127 /* Routine used to represent integer X using NBITS bits. */
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. */
1141 print_constant (int nbits
, int shift
, argument
*arg
)
1143 unsigned long mask
= 0;
1144 unsigned long constant
= getconstant (arg
->constant
, nbits
);
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 :
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
);
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);
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')
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
);
1191 CRX_PRINT (0, constant
, shift
);
1195 CRX_PRINT (0, constant
, shift
);
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. */
1207 print_operand (int nbits
, int shift
, argument
*arg
)
1212 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1216 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1217 as_bad (_("Illegal co-processor register in instruction `%s'"),
1219 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1223 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1224 as_bad (_("Illegal co-processor special register in instruction `%s'"),
1226 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
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);
1240 print_constant (nbits
, shift
, arg
);
1244 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1248 /* case base_cst4. */
1249 if (instruction
->flags
& DISPU4MAP
)
1250 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
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
);
1263 /* Retrieve the number of operands for the current assembled instruction. */
1266 get_number_of_operands (void)
1270 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; 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. */
1281 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1284 op_err retval
= OP_LEGAL
;
1286 uint32_t upper_64kb
= 0xffff0000;
1287 uint32_t value
= *num
;
1289 /* Verify operand value is even. */
1290 if (flags
& OP_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
;
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. */
1316 value
= (value
^ 0x40000000) - 0x40000000;
1320 else if (flags
& OP_SHIFT_DEC
)
1322 value
= (value
>> 1) - 1;
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
)
1338 uint32_t mul
= (instruction
->flags
& DISPUB4
? 1
1339 : instruction
->flags
& DISPUW4
? 2
1340 : instruction
->flags
& DISPUD4
? 4
1343 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1345 if (value
== mul
* bin
)
1354 retval
= OP_ILLEGAL_DISPU4
;
1356 else if (flags
& OP_CST4
)
1360 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1362 if (value
== (uint32_t) crx_cst4_map
[bin
])
1371 retval
= OP_ILLEGAL_CST4
;
1373 else if (flags
& OP_SIGNED
)
1376 max
= max
<< (bits
- 1);
1378 max
= ((max
- 1) << 1) | 1;
1380 retval
= OP_OUT_OF_RANGE
;
1382 else if (flags
& OP_UNSIGNED
)
1385 max
= max
<< (bits
- 1);
1386 max
= ((max
- 1) << 1) | 1;
1388 retval
= OP_OUT_OF_RANGE
;
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. */
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. */
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
);
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. */
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
)
1465 found_same_number_of_operands
= 1;
1467 /* Initialize arrays with data of each operand in current template. */
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;
1482 found_same_argument_types
= 1;
1484 for (i
= 0; i
< insn
->nargs
; i
++)
1486 /* Reverse the operand indices for certain opcodes:
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
],
1500 if (invalid_const
== -1)
1502 invalid_const
= j
+ 1;
1503 const_err
= op_error
;
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
1514 found_const_within_range
= 1;
1516 /* If we got till here -> Full match is found. */
1520 /* Try again with next instruction. */
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
)
1536 case OP_OUT_OF_RANGE
:
1537 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1540 as_bad (_("Operand has odd displacement (arg %d)"),
1543 case OP_ILLEGAL_DISPU4
:
1544 as_bad (_("Invalid DISPU4 operand value (arg %d)"),
1547 case OP_ILLEGAL_CST4
:
1548 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1550 case OP_NOT_UPPER_64KB
:
1551 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1555 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
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. */
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
++)
1592 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1600 /* Bunch of error checking.
1601 The checks are made after a matching instruction was found. */
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"),
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
)
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
)
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))
1676 /* Set the appropriate bit for register 'r' in 'mask'.
1677 This indicates that this register is loaded or stored by
1681 mask_reg (int r
, unsigned short int *mask
)
1683 if ((reg
)r
> (reg
)sp
)
1685 as_bad (_("Invalid register in register list"));
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. */
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. */
1710 /* If 'param' is already in form of a number, no need to preprocess. */
1711 if (strchr (paramP
, '{') == NULL
)
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
);
1722 strncpy (new_param
, param
, paramP
- param
- 1);
1724 while (*paramP
!= '}')
1727 memset (®_name
, '\0', sizeof (reg_name
));
1729 while (ISALNUM (*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"),
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"))
1759 else if (streq(reg_name
, "ulo"))
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>. */
1773 if (streq(reg_name
, "hi"))
1778 else if (streq(reg_name
, "lo"))
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
);
1795 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1799 if (*++paramP
!= '\0')
1800 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1803 switch (hi_found
+ lo_found
)
1806 /* At least one register should be specified. */
1808 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1813 /* HI can't be specified without LO (and vise-versa). */
1814 as_bad (_("HI/LO registers should be specified together"));
1818 /* HI/LO registers mustn't be masked with additional registers. */
1820 as_bad (_("HI/LO registers should be specified without additional registers"));
1826 sprintf (maskstring
, "$0x%x", mask
);
1827 strcat (new_param
, maskstring
);
1831 /* Print the instruction.
1832 Handle also cases where the instruction is relaxable/relocatable. */
1835 print_insn (ins
*insn
)
1837 unsigned int i
, j
, insn_size
;
1839 unsigned short words
[4];
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
)
1854 /* Write the maximal instruction size supported. */
1855 insn_size
= INSN_MAX_SIZE
;
1858 if (IS_INSN_TYPE (BRANCH_INS
))
1861 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1864 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1869 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1871 insn
->exp
.X_add_symbol
,
1872 insn
->exp
.X_add_number
,
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
;
1886 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1891 size
= bfd_get_reloc_size (reloc_howto
);
1893 if (size
< 1 || size
> 4)
1896 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1897 size
, &insn
->exp
, reloc_howto
->pc_relative
,
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);
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. */
1922 md_assemble (char *op
)
1928 /* Reset global variables for a new instruction. */
1931 /* Strip the mnemonic. */
1932 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
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
);
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)
1959 /* Print the instruction. */
1961 print_insn (&crx_ins
);