1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright (C) 2004-2020 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. */
26 #include "bfd_stdint.h"
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)
46 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
48 /* Assign a number NUM, shifted by SHIFT bytes, into a location
49 pointed by index BYTE of array 'output_opcode'. */
50 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
55 OP_LEGAL
= 0, /* Legal operand. */
56 OP_OUT_OF_RANGE
, /* Operand not within permitted range. */
57 OP_NOT_EVEN
, /* Operand is Odd number, should be even. */
58 OP_ILLEGAL_DISPU4
, /* Operand is not within DISPU4 range. */
59 OP_ILLEGAL_CST4
, /* Operand is not within CST4 range. */
60 OP_NOT_UPPER_64KB
/* Operand is not within the upper 64KB
61 (0xFFFF0000-0xFFFFFFFF). */
65 /* Opcode mnemonics hash table. */
66 static htab_t crx_inst_hash
;
67 /* CRX registers hash table. */
68 static htab_t reg_hash
;
69 /* CRX coprocessor registers hash table. */
70 static htab_t copreg_hash
;
71 /* Current instruction we're assembling. */
72 static const inst
*instruction
;
74 /* Global variables. */
76 /* Array to hold an instruction encoding. */
77 static long output_opcode
[2];
79 /* Nonzero means a relocatable symbol. */
80 static int relocatable
;
82 /* A copy of the original instruction (used in error messages). */
83 static char ins_parse
[MAX_INST_LEN
];
85 /* The current processed argument number. */
86 static int cur_arg_num
;
88 /* Generic assembler global variables which must be defined by all targets. */
90 /* Characters which always start a comment. */
91 const char comment_chars
[] = "#";
93 /* Characters which start a comment at the beginning of a line. */
94 const char line_comment_chars
[] = "#";
96 /* This array holds machine specific line separator characters. */
97 const char line_separator_chars
[] = ";";
99 /* Chars that can be used to separate mant from exp in floating point nums. */
100 const char EXP_CHARS
[] = "eE";
102 /* Chars that mean this number is a floating point constant as in 0f12.456 */
103 const char FLT_CHARS
[] = "f'";
105 /* Target-specific multicharacter options, not const-declared at usage. */
106 const char *md_shortopts
= "";
107 struct option md_longopts
[] =
109 {NULL
, no_argument
, NULL
, 0}
111 size_t md_longopts_size
= sizeof (md_longopts
);
113 /* This table describes all the machine specific pseudo-ops
114 the assembler has to support. The fields are:
115 *** Pseudo-op name without dot.
116 *** Function to call to execute this pseudo-op.
117 *** Integer arg to pass to the function. */
119 const pseudo_typeS md_pseudo_table
[] =
121 /* In CRX machine, align is in bytes (not a ptwo boundary). */
122 {"align", s_align_bytes
, 0},
126 /* CRX relaxation table. */
127 const relax_typeS md_relax_table
[] =
130 {0xfa, -0x100, 2, 1}, /* 8 */
131 {0xfffe, -0x10000, 4, 2}, /* 16 */
132 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
135 {0xfffe, -0x10000, 4, 4}, /* 16 */
136 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
139 {0xfe, -0x100, 4, 6}, /* 8 */
140 {0xfffffe, -0x1000000, 6, 0} /* 24 */
143 static void reset_vars (char *);
144 static reg
get_register (char *);
145 static copreg
get_copregister (char *);
146 static argtype
get_optype (operand_type
);
147 static int get_opbits (operand_type
);
148 static int get_opflags (operand_type
);
149 static int get_number_of_operands (void);
150 static void parse_operand (char *, ins
*);
151 static int gettrap (const char *);
152 static void handle_LoadStor (const char *);
153 static int get_cinv_parameters (const char *);
154 static long getconstant (long, int);
155 static op_err
check_range (long *, int, unsigned int, int);
156 static int getreg_image (int);
157 static void parse_operands (ins
*, char *);
158 static void parse_insn (ins
*, char *);
159 static void print_operand (int, int, argument
*);
160 static void print_constant (int, int, argument
*);
161 static int exponent2scale (int);
162 static void mask_reg (int, unsigned short *);
163 static void process_label_constant (char *, ins
*);
164 static void set_operand (char *, ins
*);
165 static char * preprocess_reglist (char *, int *);
166 static int assemble_insn (char *, ins
*);
167 static void print_insn (ins
*);
168 static void warn_if_needed (ins
*);
169 static int adjust_if_needed (ins
*);
171 /* Return the bit size for a given operand. */
174 get_opbits (operand_type op
)
177 return crx_optab
[op
].bit_size
;
182 /* Return the argument type of a given operand. */
185 get_optype (operand_type op
)
188 return crx_optab
[op
].arg_type
;
193 /* Return the flags of a given operand. */
196 get_opflags (operand_type op
)
199 return crx_optab
[op
].flags
;
204 /* Get the core processor register 'reg_name'. */
207 get_register (char *reg_name
)
209 const reg_entry
*rreg
;
211 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
214 return rreg
->value
.reg_val
;
219 /* Get the coprocessor register 'copreg_name'. */
222 get_copregister (char *copreg_name
)
224 const reg_entry
*coreg
;
226 coreg
= (const reg_entry
*) str_hash_find (copreg_hash
, copreg_name
);
229 return coreg
->value
.copreg_val
;
231 return nullcopregister
;
234 /* Round up a section size to the appropriate boundary. */
237 md_section_align (segT seg
, valueT val
)
239 /* Round .text section to a multiple of 2. */
240 if (seg
== text_section
)
241 return (val
+ 1) & ~1;
245 /* Parse an operand that is machine-specific (remove '*'). */
248 md_operand (expressionS
* exp
)
250 char c
= *input_line_pointer
;
255 input_line_pointer
++;
263 /* Reset global variables before parsing a new instruction. */
266 reset_vars (char *op
)
268 cur_arg_num
= relocatable
= 0;
269 memset (& output_opcode
, '\0', sizeof (output_opcode
));
271 /* Save a copy of the original OP (used in error messages). */
272 strncpy (ins_parse
, op
, sizeof ins_parse
- 1);
273 ins_parse
[sizeof ins_parse
- 1] = 0;
276 /* This macro decides whether a particular reloc is an entry in a
277 switch table. It is used when relaxing, because the linker needs
278 to know about all such entries so that it can adjust them if
281 #define SWITCH_TABLE(fix) \
282 ( (fix)->fx_addsy != NULL \
283 && (fix)->fx_subsy != NULL \
284 && S_GET_SEGMENT ((fix)->fx_addsy) == \
285 S_GET_SEGMENT ((fix)->fx_subsy) \
286 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
287 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
288 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
289 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
291 /* See whether we need to force a relocation into the output file.
292 This is used to force out switch and PC relative relocations when
296 crx_force_relocation (fixS
*fix
)
298 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
304 /* Generate a relocation entry for a fixup. */
307 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
311 reloc
= XNEW (arelent
);
312 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
313 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
314 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
315 reloc
->addend
= fixP
->fx_offset
;
317 if (fixP
->fx_subsy
!= NULL
)
319 if (SWITCH_TABLE (fixP
))
321 /* Keep the current difference in the addend. */
322 reloc
->addend
= (S_GET_VALUE (fixP
->fx_addsy
)
323 - S_GET_VALUE (fixP
->fx_subsy
) + fixP
->fx_offset
);
325 switch (fixP
->fx_r_type
)
327 case BFD_RELOC_CRX_NUM8
:
328 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH8
;
330 case BFD_RELOC_CRX_NUM16
:
331 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH16
;
333 case BFD_RELOC_CRX_NUM32
:
334 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH32
;
343 /* We only resolve difference expressions in the same section. */
344 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
345 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
346 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "0",
347 segment_name (fixP
->fx_addsy
348 ? S_GET_SEGMENT (fixP
->fx_addsy
)
350 S_GET_NAME (fixP
->fx_subsy
),
351 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
355 gas_assert ((int) fixP
->fx_r_type
> 0);
356 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
358 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
360 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
361 _("internal error: reloc %d (`%s') not supported by object file format"),
363 bfd_get_reloc_code_name (fixP
->fx_r_type
));
366 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
371 /* Prepare machine-dependent frags for relaxation. */
374 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
376 /* If symbol is undefined or located in a different section,
377 select the largest supported relocation. */
378 relax_substateT subtype
;
379 relax_substateT rlx_state
[] = {0, 2,
383 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
385 if (fragp
->fr_subtype
== rlx_state
[subtype
]
386 && (!S_IS_DEFINED (fragp
->fr_symbol
)
387 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
389 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
394 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
397 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
401 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
403 /* 'opcode' points to the start of the instruction, whether
404 we need to change the instruction's fixed encoding. */
405 char *opcode
= &fragP
->fr_literal
[0] + fragP
->fr_fix
;
406 bfd_reloc_code_real_type reloc
;
408 subseg_change (sec
, 0);
410 switch (fragP
->fr_subtype
)
413 reloc
= BFD_RELOC_CRX_REL8
;
417 reloc
= BFD_RELOC_CRX_REL16
;
421 reloc
= BFD_RELOC_CRX_REL32
;
424 reloc
= BFD_RELOC_CRX_REL16
;
428 reloc
= BFD_RELOC_CRX_REL32
;
431 reloc
= BFD_RELOC_CRX_REL8_CMP
;
435 reloc
= BFD_RELOC_CRX_REL24
;
442 fix_new (fragP
, fragP
->fr_fix
,
443 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
444 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
446 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
449 /* Process machine-dependent command line options. Called once for
450 each option on the command line that the machine-independent part of
451 GAS does not understand. */
454 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
459 /* Machine-dependent usage-output. */
462 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
468 md_atof (int type
, char *litP
, int *sizeP
)
470 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
473 /* Apply a fixS (fixup of an instruction or data that we didn't have
474 enough info to complete immediately) to the data in a frag.
475 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
476 relaxation of debug sections, this function is called only when
477 fixuping relocations of debug sections. */
480 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
483 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
486 switch (fixP
->fx_r_type
)
488 case BFD_RELOC_CRX_NUM8
:
489 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
491 case BFD_RELOC_CRX_NUM16
:
492 bfd_put_16 (stdoutput
, val
, buf
);
494 case BFD_RELOC_CRX_NUM32
:
495 bfd_put_32 (stdoutput
, val
, buf
);
498 /* We shouldn't ever get here because linkrelax is nonzero. */
505 if (fixP
->fx_addsy
== NULL
506 && fixP
->fx_pcrel
== 0)
509 if (fixP
->fx_pcrel
== 1
510 && fixP
->fx_addsy
!= NULL
511 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
515 /* The location from which a PC relative jump should be calculated,
516 given a PC relative reloc. */
519 md_pcrel_from (fixS
*fixp
)
521 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
524 /* This function is called once, at assembler startup time. This should
525 set up all the tables, etc that the MD part of the assembler needs. */
532 /* Set up a hash table for the instructions. */
533 if ((crx_inst_hash
= str_htab_create ()) == NULL
)
534 as_fatal (_("Virtual memory exhausted"));
536 while (crx_instruction
[i
].mnemonic
!= NULL
)
538 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
540 str_hash_insert (crx_inst_hash
, mnemonic
,
541 (void *) &crx_instruction
[i
]);
543 /* Insert unique names into hash table. The CRX instruction set
544 has many identical opcode names that have different opcodes based
545 on the operands. This hash table then provides a quick index to
546 the first opcode with a particular name in the opcode table. */
551 while (crx_instruction
[i
].mnemonic
!= NULL
552 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
555 /* Initialize reg_hash hash table. */
556 if ((reg_hash
= str_htab_create ()) == NULL
)
557 as_fatal (_("Virtual memory exhausted"));
560 const reg_entry
*regtab
;
562 for (regtab
= crx_regtab
;
563 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
564 str_hash_insert (reg_hash
, regtab
->name
, (void *) regtab
);
567 /* Initialize copreg_hash hash table. */
568 if ((copreg_hash
= str_htab_create ()) == NULL
)
569 as_fatal (_("Virtual memory exhausted"));
572 const reg_entry
*copregtab
;
574 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
576 str_hash_insert (copreg_hash
, copregtab
->name
,
579 /* Set linkrelax here to avoid fixups in most sections. */
583 /* Process constants (immediate/absolute)
584 and labels (jump targets/Memory locations). */
587 process_label_constant (char *str
, ins
* crx_ins
)
589 char *saved_input_line_pointer
;
590 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
592 saved_input_line_pointer
= input_line_pointer
;
593 input_line_pointer
= str
;
595 expression (&crx_ins
->exp
);
597 switch (crx_ins
->exp
.X_op
)
601 /* Missing or bad expr becomes absolute 0. */
602 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
604 crx_ins
->exp
.X_op
= O_constant
;
605 crx_ins
->exp
.X_add_number
= 0;
606 crx_ins
->exp
.X_add_symbol
= (symbolS
*) 0;
607 crx_ins
->exp
.X_op_symbol
= (symbolS
*) 0;
611 cur_arg
->X_op
= O_constant
;
612 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
618 cur_arg
->X_op
= O_symbol
;
619 crx_ins
->rtype
= BFD_RELOC_NONE
;
622 switch (cur_arg
->type
)
625 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
626 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
627 else if (IS_INSN_TYPE (CSTBIT_INS
)
628 || IS_INSN_TYPE (STOR_IMM_INS
))
629 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
631 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
635 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
639 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
640 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
641 else if (IS_INSN_TYPE (BRANCH_INS
))
642 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
643 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
644 || IS_INSN_TYPE (CSTBIT_INS
))
645 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
646 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
647 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
648 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
649 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
653 if (IS_INSN_TYPE (ARITH_INS
))
654 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
655 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
656 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
664 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
668 input_line_pointer
= saved_input_line_pointer
;
672 /* Get the values of the scale to be encoded -
673 used for the scaled index mode of addressing. */
676 exponent2scale (int val
)
680 /* If 'val' is 0, the following 'for' will be an endless loop. */
684 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
690 /* Parsing different types of operands
691 -> constants Immediate/Absolute/Relative numbers
692 -> Labels Relocatable symbols
693 -> (rbase) Register base
694 -> disp(rbase) Register relative
695 -> disp(rbase)+ Post-increment mode
696 -> disp(rbase,ridx,scl) Register index mode */
699 set_operand (char *operand
, ins
* crx_ins
)
701 char *operandS
; /* Pointer to start of sub-operand. */
702 char *operandE
; /* Pointer to end of sub-operand. */
706 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
708 /* Initialize pointers. */
709 operandS
= operandE
= operand
;
711 switch (cur_arg
->type
)
713 case arg_sc
: /* Case *+0x18. */
714 case arg_ic
: /* Case $0x18. */
717 case arg_c
: /* Case 0x18. */
719 process_label_constant (operandS
, crx_ins
);
721 if (cur_arg
->type
!= arg_ic
)
722 cur_arg
->type
= arg_c
;
725 case arg_icr
: /* Case $0x18(r1). */
727 case arg_cr
: /* Case 0x18(r1). */
728 /* Set displacement constant. */
729 while (*operandE
!= '(')
732 process_label_constant (operandS
, crx_ins
);
735 case arg_rbase
: /* Case (r1). */
737 /* Set register base. */
738 while (*operandE
!= ')')
741 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
742 as_bad (_("Illegal register `%s' in instruction `%s'"),
743 operandS
, ins_parse
);
745 if (cur_arg
->type
!= arg_rbase
)
746 cur_arg
->type
= arg_cr
;
750 /* Set displacement constant. */
751 while (*operandE
!= '(')
754 process_label_constant (operandS
, crx_ins
);
755 operandS
= ++operandE
;
757 /* Set register base. */
758 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
761 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
762 as_bad (_("Illegal register `%s' in instruction `%s'"),
763 operandS
, ins_parse
);
765 /* Skip leading white space. */
766 while (ISSPACE (*operandE
))
770 /* Set register index. */
771 while ((*operandE
!= ')') && (*operandE
!= ','))
776 if ((cur_arg
->i_r
= get_register (operandS
)) == nullregister
)
777 as_bad (_("Illegal register `%s' in instruction `%s'"),
778 operandS
, ins_parse
);
780 /* Skip leading white space. */
781 while (ISSPACE (*operandE
))
790 while (*operandE
!= ')')
794 /* Preprocess the scale string. */
795 input_save
= input_line_pointer
;
796 input_line_pointer
= operandS
;
798 input_line_pointer
= input_save
;
800 scale_val
= scale
.X_add_number
;
802 /* Check if the scale value is legal. */
803 if (scale_val
!= 1 && scale_val
!= 2
804 && scale_val
!= 4 && scale_val
!= 8)
805 as_bad (_("Illegal Scale - `%d'"), scale_val
);
807 cur_arg
->scale
= exponent2scale (scale_val
);
816 /* Parse a single operand.
817 operand - Current operand to parse.
818 crx_ins - Current assembled instruction. */
821 parse_operand (char *operand
, ins
* crx_ins
)
824 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
826 /* Initialize the type to NULL before parsing. */
827 cur_arg
->type
= nullargs
;
829 /* Check whether this is a general processor register. */
830 if ((ret_val
= get_register (operand
)) != nullregister
)
832 cur_arg
->type
= arg_r
;
833 cur_arg
->r
= ret_val
;
834 cur_arg
->X_op
= O_register
;
838 /* Check whether this is a core [special] coprocessor register. */
839 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
841 cur_arg
->type
= arg_copr
;
843 cur_arg
->type
= arg_copsr
;
844 cur_arg
->cr
= ret_val
;
845 cur_arg
->X_op
= O_register
;
849 /* Deal with special characters. */
853 if (strchr (operand
, '(') != NULL
)
854 cur_arg
->type
= arg_icr
;
856 cur_arg
->type
= arg_ic
;
861 cur_arg
->type
= arg_sc
;
866 cur_arg
->type
= arg_rbase
;
874 if (strchr (operand
, '(') != NULL
)
876 if (strchr (operand
, ',') != NULL
877 && (strchr (operand
, ',') > strchr (operand
, '(')))
878 cur_arg
->type
= arg_idxr
;
880 cur_arg
->type
= arg_cr
;
883 cur_arg
->type
= arg_c
;
886 /* Parse an operand according to its type. */
888 cur_arg
->constant
= 0;
889 set_operand (operand
, crx_ins
);
892 /* Parse the various operands. Each operand is then analyzed to fillup
893 the fields in the crx_ins data structure. */
896 parse_operands (ins
* crx_ins
, char *operands
)
898 char *operandS
; /* Operands string. */
899 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
900 int allocated
= 0; /* Indicates a new operands string was allocated. */
901 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
902 int op_num
= 0; /* Current operand number we are parsing. */
903 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
904 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
906 /* Preprocess the list of registers, if necessary. */
907 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
908 preprocess_reglist (operands
, &allocated
) : operands
;
910 while (*operandT
!= '\0')
912 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
915 operand
[op_num
++] = strdup (operandH
);
920 if (*operandT
== ' ')
921 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
923 if (*operandT
== '(')
925 else if (*operandT
== '[')
928 if (*operandT
== ')')
933 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
935 else if (*operandT
== ']')
940 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
943 if (bracket_flag
== 1 && *operandT
== ')')
945 else if (sq_bracket_flag
== 1 && *operandT
== ']')
951 /* Adding the last operand. */
952 operand
[op_num
++] = strdup (operandH
);
953 crx_ins
->nargs
= op_num
;
955 /* Verifying correct syntax of operands (all brackets should be closed). */
956 if (bracket_flag
|| sq_bracket_flag
)
957 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
959 /* Now we parse each operand separately. */
960 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
962 cur_arg_num
= op_num
;
963 parse_operand (operand
[op_num
], crx_ins
);
964 free (operand
[op_num
]);
971 /* Get the trap index in dispatch table, given its name.
972 This routine is used by assembling the 'excp' instruction. */
975 gettrap (const char *s
)
977 const trap_entry
*trap
;
979 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
980 if (strcasecmp (trap
->name
, s
) == 0)
983 as_bad (_("Unknown exception: `%s'"), s
);
987 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
988 sub-group within load/stor instruction groups.
989 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
990 advance the instruction pointer to the start of that sub-group (that is, up
991 to the first instruction of that type).
992 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
995 handle_LoadStor (const char *operands
)
997 /* Post-Increment instructions precede Store-Immediate instructions in
998 CRX instruction table, hence they are handled before.
999 This synchronization should be kept. */
1001 /* Assuming Post-Increment insn has the following format :
1002 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1003 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1004 if (strstr (operands
, ")+") != NULL
)
1006 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1011 /* Assuming Store-Immediate insn has the following format :
1012 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1013 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1014 if (strstr (operands
, "$") != NULL
)
1015 while (! IS_INSN_TYPE (STOR_IMM_INS
))
1019 /* Top level module where instruction parsing starts.
1020 crx_ins - data structure holds some information.
1021 operands - holds the operands part of the whole instruction. */
1024 parse_insn (ins
*insn
, char *operands
)
1028 /* Handle instructions with no operands. */
1029 for (i
= 0; crx_no_op_insn
[i
] != NULL
; i
++)
1031 if (streq (crx_no_op_insn
[i
], instruction
->mnemonic
))
1038 /* Handle 'excp'/'cinv' instructions. */
1039 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1042 insn
->arg
[0].type
= arg_ic
;
1043 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1044 gettrap (operands
) : get_cinv_parameters (operands
);
1045 insn
->arg
[0].X_op
= O_constant
;
1049 /* Handle load/stor unique instructions before parsing. */
1050 if (IS_INSN_TYPE (LD_STOR_INS
))
1051 handle_LoadStor (operands
);
1053 if (operands
!= NULL
)
1054 parse_operands (insn
, operands
);
1057 /* Cinv instruction requires special handling. */
1060 get_cinv_parameters (const char *operand
)
1062 const char *p
= operand
;
1063 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1067 if (*p
== ',' || *p
== ' ')
1079 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1082 return ((b_used
? 8 : 0)
1085 + (u_used
? 1 : 0));
1088 /* Retrieve the opcode image of a given register.
1089 If the register is illegal for the current instruction,
1093 getreg_image (int r
)
1095 const reg_entry
*rreg
;
1097 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1099 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num
== 1))
1100 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num
== 0)) )
1103 /* Check whether the register is in registers table. */
1105 rreg
= &crx_regtab
[r
];
1106 /* Check whether the register is in coprocessor registers table. */
1107 else if (r
< (int) MAX_COPREG
)
1108 rreg
= &crx_copregtab
[r
-MAX_REG
];
1109 /* Register not found. */
1112 as_bad (_("Unknown register: `%d'"), r
);
1116 reg_name
= rreg
->name
;
1118 /* Issue a error message when register is illegal. */
1120 as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1121 reg_name, ins_parse);
1126 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1132 case CRX_CFG_REGTYPE
:
1147 case CRX_CS_REGTYPE
:
1159 /* Routine used to represent integer X using NBITS bits. */
1162 getconstant (long x
, int nbits
)
1164 return x
& ((((1U << (nbits
- 1)) - 1) << 1) | 1);
1167 /* Print a constant value to 'output_opcode':
1168 ARG holds the operand's type and value.
1169 SHIFT represents the location of the operand to be print into.
1170 NBITS determines the size (in bits) of the constant. */
1173 print_constant (int nbits
, int shift
, argument
*arg
)
1175 unsigned long mask
= 0;
1177 long constant
= getconstant (arg
->constant
, nbits
);
1185 /* mask the upper part of the constant, that is, the bits
1186 going to the lowest byte of output_opcode[0].
1187 The upper part of output_opcode[1] is always filled,
1188 therefore it is always masked with 0xFFFF. */
1189 mask
= (1 << (nbits
- 16)) - 1;
1190 /* Divide the constant between two consecutive words :
1192 +---------+---------+---------+---------+
1193 | | X X X X | X X X X | |
1194 +---------+---------+---------+---------+
1195 output_opcode[0] output_opcode[1] */
1197 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1198 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1203 /* Special case - in arg_cr, the SHIFT represents the location
1204 of the REGISTER, not the constant, which is itself not shifted. */
1205 if (arg
->type
== arg_cr
)
1207 CRX_PRINT (0, constant
, 0);
1211 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1212 always filling the upper part of output_opcode[1]. If we mistakenly
1213 write it to output_opcode[0], the constant prefix (that is, 'match')
1216 +---------+---------+---------+---------+
1217 | 'match' | | X X X X | |
1218 +---------+---------+---------+---------+
1219 output_opcode[0] output_opcode[1] */
1221 if ((instruction
->size
> 2) && (shift
== WORD_SHIFT
))
1222 CRX_PRINT (1, constant
, WORD_SHIFT
);
1224 CRX_PRINT (0, constant
, shift
);
1228 CRX_PRINT (0, constant
, shift
);
1233 /* Print an operand to 'output_opcode', which later on will be
1234 printed to the object file:
1235 ARG holds the operand's type, size and value.
1236 SHIFT represents the printing location of operand.
1237 NBITS determines the size (in bits) of a constant operand. */
1240 print_operand (int nbits
, int shift
, argument
*arg
)
1245 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1249 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1250 as_bad (_("Illegal co-processor register in instruction `%s'"),
1252 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1256 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1257 as_bad (_("Illegal co-processor special register in instruction `%s'"),
1259 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1264 +--------------------------------+
1265 | r_base | r_idx | scl| disp |
1266 +--------------------------------+ */
1267 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1268 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1269 CRX_PRINT (0, arg
->scale
, 6);
1273 print_constant (nbits
, shift
, arg
);
1277 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1281 /* case base_cst4. */
1282 if (instruction
->flags
& DISPU4MAP
)
1283 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
1285 /* rbase_disps<NN> and other such cases. */
1286 print_constant (nbits
, shift
, arg
);
1287 /* Add the register argument to the output_opcode. */
1288 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1296 /* Retrieve the number of operands for the current assembled instruction. */
1299 get_number_of_operands (void)
1303 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1308 /* Verify that the number NUM can be represented in BITS bits (that is,
1309 within its permitted range), based on the instruction's FLAGS.
1310 If UPDATE is nonzero, update the value of NUM if necessary.
1311 Return OP_LEGAL upon success, actual error type upon failure. */
1314 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1317 op_err retval
= OP_LEGAL
;
1319 uint32_t upper_64kb
= 0xffff0000;
1320 uint32_t value
= *num
;
1322 /* Verify operand value is even. */
1323 if (flags
& OP_EVEN
)
1329 if (flags
& OP_UPPER_64KB
)
1331 /* Check if value is to be mapped to upper 64 KB memory area. */
1332 if ((value
& upper_64kb
) == upper_64kb
)
1334 value
-= upper_64kb
;
1339 return OP_NOT_UPPER_64KB
;
1342 if (flags
& OP_SHIFT
)
1344 /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1345 sign. However, right shift of a signed type with a negative
1346 value is implementation defined. See ISO C 6.5.7. So we use
1347 an unsigned type and sign extend afterwards. */
1349 value
= (value
^ 0x40000000) - 0x40000000;
1353 else if (flags
& OP_SHIFT_DEC
)
1355 value
= (value
>> 1) - 1;
1362 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1363 if (value
== 0x7e || value
== 0x7f)
1364 return OP_OUT_OF_RANGE
;
1367 if (flags
& OP_DISPU4
)
1371 uint32_t mul
= (instruction
->flags
& DISPUB4
? 1
1372 : instruction
->flags
& DISPUW4
? 2
1373 : instruction
->flags
& DISPUD4
? 4
1376 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1378 if (value
== mul
* bin
)
1387 retval
= OP_ILLEGAL_DISPU4
;
1389 else if (flags
& OP_CST4
)
1393 for (bin
= 0; bin
< crx_cst4_maps
; bin
++)
1395 if (value
== (uint32_t) crx_cst4_map
[bin
])
1404 retval
= OP_ILLEGAL_CST4
;
1406 else if (flags
& OP_SIGNED
)
1409 max
= max
<< (bits
- 1);
1411 max
= ((max
- 1) << 1) | 1;
1413 retval
= OP_OUT_OF_RANGE
;
1415 else if (flags
& OP_UNSIGNED
)
1418 max
= max
<< (bits
- 1);
1419 max
= ((max
- 1) << 1) | 1;
1421 retval
= OP_OUT_OF_RANGE
;
1426 /* Assemble a single instruction:
1427 INSN is already parsed (that is, all operand values and types are set).
1428 For instruction to be assembled, we need to find an appropriate template in
1429 the instruction table, meeting the following conditions:
1430 1: Has the same number of operands.
1431 2: Has the same operand types.
1432 3: Each operand size is sufficient to represent the instruction's values.
1433 Returns 1 upon success, 0 upon failure. */
1436 assemble_insn (char *mnemonic
, ins
*insn
)
1438 /* Type of each operand in the current template. */
1439 argtype cur_type
[MAX_OPERANDS
];
1440 /* Size (in bits) of each operand in the current template. */
1441 unsigned int cur_size
[MAX_OPERANDS
];
1442 /* Flags of each operand in the current template. */
1443 unsigned int cur_flags
[MAX_OPERANDS
];
1444 /* Instruction type to match. */
1445 unsigned int ins_type
;
1446 /* Boolean flag to mark whether a match was found. */
1449 /* Nonzero if an instruction with same number of operands was found. */
1450 int found_same_number_of_operands
= 0;
1451 /* Nonzero if an instruction with same argument types was found. */
1452 int found_same_argument_types
= 0;
1453 /* Nonzero if a constant was found within the required range. */
1454 int found_const_within_range
= 0;
1455 /* Argument number of an operand with invalid type. */
1456 int invalid_optype
= -1;
1457 /* Argument number of an operand with invalid constant value. */
1458 int invalid_const
= -1;
1459 /* Operand error (used for issuing various constant error messages). */
1460 op_err op_error
, const_err
= OP_LEGAL
;
1462 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1463 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1464 for (i = 0; i < insn->nargs; i++) \
1465 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1467 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1468 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1469 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1471 /* Instruction has no operands -> only copy the constant opcode. */
1472 if (insn
->nargs
== 0)
1474 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1478 /* In some case, same mnemonic can appear with different instruction types.
1479 For example, 'storb' is supported with 3 different types :
1480 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1481 We assume that when reaching this point, the instruction type was
1482 pre-determined. We need to make sure that the type stays the same
1483 during a search for matching instruction. */
1484 ins_type
= CRX_INS_TYPE(instruction
->flags
);
1486 while (/* Check that match is still not found. */
1488 /* Check we didn't get to end of table. */
1489 && instruction
->mnemonic
!= NULL
1490 /* Check that the actual mnemonic is still available. */
1491 && IS_INSN_MNEMONIC (mnemonic
)
1492 /* Check that the instruction type wasn't changed. */
1493 && IS_INSN_TYPE(ins_type
))
1495 /* Check whether number of arguments is legal. */
1496 if (get_number_of_operands () != insn
->nargs
)
1498 found_same_number_of_operands
= 1;
1500 /* Initialize arrays with data of each operand in current template. */
1505 /* Check for type compatibility. */
1506 for (i
= 0; i
< insn
->nargs
; i
++)
1508 if (cur_type
[i
] != insn
->arg
[i
].type
)
1510 if (invalid_optype
== -1)
1511 invalid_optype
= i
+ 1;
1515 found_same_argument_types
= 1;
1517 for (i
= 0; i
< insn
->nargs
; i
++)
1519 /* Reverse the operand indices for certain opcodes:
1522 Other index -->> stays the same. */
1523 int j
= instruction
->flags
& REVERSE_MATCH
?
1528 /* Only check range - don't update the constant's value, since the
1529 current instruction may not be the last we try to match.
1530 The constant's value will be updated later, right before printing
1531 it to the object file. */
1532 if ((insn
->arg
[j
].X_op
== O_constant
)
1533 && (op_error
= check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1536 if (invalid_const
== -1)
1538 invalid_const
= j
+ 1;
1539 const_err
= op_error
;
1543 /* For symbols, we make sure the relocation size (which was already
1544 determined) is sufficient. */
1545 else if ((insn
->arg
[j
].X_op
== O_symbol
)
1546 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
1550 found_const_within_range
= 1;
1552 /* If we got till here -> Full match is found. */
1556 /* Try again with next instruction. */
1563 /* We haven't found a match - instruction can't be assembled. */
1564 if (!found_same_number_of_operands
)
1565 as_bad (_("Incorrect number of operands"));
1566 else if (!found_same_argument_types
)
1567 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
1568 else if (!found_const_within_range
)
1572 case OP_OUT_OF_RANGE
:
1573 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1576 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
1578 case OP_ILLEGAL_DISPU4
:
1579 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const
);
1581 case OP_ILLEGAL_CST4
:
1582 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1584 case OP_NOT_UPPER_64KB
:
1585 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1589 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
1597 /* Full match - print the encoding to output file. */
1599 /* Make further checking (such that couldn't be made earlier).
1600 Warn the user if necessary. */
1601 warn_if_needed (insn
);
1603 /* Check whether we need to adjust the instruction pointer. */
1604 if (adjust_if_needed (insn
))
1605 /* If instruction pointer was adjusted, we need to update
1606 the size of the current template operands. */
1609 for (i
= 0; i
< insn
->nargs
; i
++)
1611 int j
= instruction
->flags
& REVERSE_MATCH
?
1616 /* This time, update constant value before printing it. */
1617 if ((insn
->arg
[j
].X_op
== O_constant
)
1618 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1619 cur_flags
[j
], 1) != OP_LEGAL
))
1620 as_fatal (_("Illegal operand (arg %d)"), j
+1);
1623 /* First, copy the instruction's opcode. */
1624 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1626 for (i
= 0; i
< insn
->nargs
; i
++)
1629 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1637 /* Bunch of error checking.
1638 The checks are made after a matching instruction was found. */
1641 warn_if_needed (ins
*insn
)
1643 /* If the post-increment address mode is used and the load/store
1644 source register is the same as rbase, the result of the
1645 instruction is undefined. */
1646 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1648 /* Enough to verify that one of the arguments is a simple reg. */
1649 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
1650 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
1651 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1655 /* Some instruction assume the stack pointer as rptr operand.
1656 Issue an error when the register to be loaded is also SP. */
1657 if (instruction
->flags
& NO_SP
)
1659 if (getreg_image (insn
->arg
[0].r
) == getreg_image (sp
))
1660 as_bad (_("`%s' has undefined result"), ins_parse
);
1663 /* If the rptr register is specified as one of the registers to be loaded,
1664 the final contents of rptr are undefined. Thus, we issue an error. */
1665 if (instruction
->flags
& NO_RPTR
)
1667 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
1668 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1669 getreg_image (insn
->arg
[0].r
));
1673 /* In some cases, we need to adjust the instruction pointer although a
1674 match was already found. Here, we gather all these cases.
1675 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1678 adjust_if_needed (ins
*insn
)
1682 /* Special check for 'addub $0, r0' instruction -
1683 The opcode '0000 0000 0000 0000' is not allowed. */
1684 if (IS_INSN_MNEMONIC ("addub"))
1686 if ((instruction
->operands
[0].op_type
== cst4
)
1687 && instruction
->operands
[1].op_type
== regr
)
1689 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
1697 /* Optimization: Omit a zero displacement in bit operations,
1698 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1699 if (IS_INSN_TYPE (CSTBIT_INS
))
1701 if ((instruction
->operands
[1].op_type
== rbase_disps12
)
1702 && (insn
->arg
[1].X_op
== O_constant
)
1703 && (insn
->arg
[1].constant
== 0))
1713 /* Set the appropriate bit for register 'r' in 'mask'.
1714 This indicates that this register is loaded or stored by
1718 mask_reg (int r
, unsigned short int *mask
)
1720 if ((reg
)r
> (reg
)sp
)
1722 as_bad (_("Invalid register in register list"));
1729 /* Preprocess register list - create a 16-bit mask with one bit for each
1730 of the 16 general purpose registers. If a bit is set, it indicates
1731 that this register is loaded or stored by the instruction. */
1734 preprocess_reglist (char *param
, int *allocated
)
1736 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
1737 char *regP
; /* Pointer to 'reg_name' string. */
1738 int reg_counter
= 0; /* Count number of parsed registers. */
1739 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
1740 char *new_param
; /* New created operands string. */
1741 char *paramP
= param
; /* Pointer to original operands string. */
1742 char maskstring
[10]; /* Array to print the mask as a string. */
1743 int hi_found
= 0, lo_found
= 0; /* Boolean flags for hi/lo registers. */
1747 /* If 'param' is already in form of a number, no need to preprocess. */
1748 if (strchr (paramP
, '{') == NULL
)
1751 /* Verifying correct syntax of operand. */
1752 if (strchr (paramP
, '}') == NULL
)
1753 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1755 while (*paramP
++ != '{');
1757 new_param
= XCNEWVEC (char, MAX_INST_LEN
);
1759 strncpy (new_param
, param
, paramP
- param
- 1);
1761 while (*paramP
!= '}')
1764 memset (®_name
, '\0', sizeof (reg_name
));
1766 while (ISALNUM (*paramP
))
1769 strncpy (reg_name
, regP
, paramP
- regP
);
1771 /* Coprocessor register c<N>. */
1772 if (IS_INSN_TYPE (COP_REG_INS
))
1774 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1775 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_C_REGTYPE
))
1776 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name
);
1777 mask_reg (getreg_image (cr
- c0
), &mask
);
1779 /* Coprocessor Special register cs<N>. */
1780 else if (IS_INSN_TYPE (COPS_REG_INS
))
1782 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1783 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_CS_REGTYPE
))
1784 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1786 mask_reg (getreg_image (cr
- cs0
), &mask
);
1788 /* User register u<N>. */
1789 else if (instruction
->flags
& USER_REG
)
1791 if (streq(reg_name
, "uhi"))
1796 else if (streq(reg_name
, "ulo"))
1801 else if (((r
= get_register (reg_name
)) == nullregister
)
1802 || (crx_regtab
[r
].type
!= CRX_U_REGTYPE
))
1803 as_fatal (_("Illegal register `%s' in user register list"), reg_name
);
1805 mask_reg (getreg_image (r
- u0
), &mask
);
1807 /* General purpose register r<N>. */
1810 if (streq(reg_name
, "hi"))
1815 else if (streq(reg_name
, "lo"))
1820 else if (((r
= get_register (reg_name
)) == nullregister
)
1821 || (crx_regtab
[r
].type
!= CRX_R_REGTYPE
))
1822 as_fatal (_("Illegal register `%s' in register list"), reg_name
);
1824 mask_reg (getreg_image (r
- r0
), &mask
);
1827 if (++reg_counter
> MAX_REGS_IN_MASK16
)
1828 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1829 MAX_REGS_IN_MASK16
);
1832 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1836 if (*++paramP
!= '\0')
1837 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1840 switch (hi_found
+ lo_found
)
1843 /* At least one register should be specified. */
1845 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1850 /* HI can't be specified without LO (and vise-versa). */
1851 as_bad (_("HI/LO registers should be specified together"));
1855 /* HI/LO registers mustn't be masked with additional registers. */
1857 as_bad (_("HI/LO registers should be specified without additional registers"));
1863 sprintf (maskstring
, "$0x%x", mask
);
1864 strcat (new_param
, maskstring
);
1868 /* Print the instruction.
1869 Handle also cases where the instruction is relaxable/relocatable. */
1872 print_insn (ins
*insn
)
1874 unsigned int i
, j
, insn_size
;
1876 unsigned short words
[4];
1879 /* Arrange the insn encodings in a WORD size array. */
1880 for (i
= 0, j
= 0; i
< 2; i
++)
1882 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
1883 words
[j
++] = output_opcode
[i
] & 0xFFFF;
1886 /* Handle relaxation. */
1887 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
1891 /* Write the maximal instruction size supported. */
1892 insn_size
= INSN_MAX_SIZE
;
1895 if (IS_INSN_TYPE (BRANCH_INS
))
1898 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1901 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1906 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1908 insn
->exp
.X_add_symbol
,
1909 insn
->exp
.X_add_number
,
1914 insn_size
= instruction
->size
;
1915 this_frag
= frag_more (insn_size
* 2);
1917 /* Handle relocation. */
1918 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
1920 reloc_howto_type
*reloc_howto
;
1923 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1928 size
= bfd_get_reloc_size (reloc_howto
);
1930 if (size
< 1 || size
> 4)
1933 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1934 size
, &insn
->exp
, reloc_howto
->pc_relative
,
1939 /* Verify a 2-byte code alignment. */
1940 addr_mod
= frag_now_fix () & 1;
1941 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
1942 as_bad (_("instruction address is not a multiple of 2"));
1943 frag_now
->insn_addr
= addr_mod
;
1944 frag_now
->has_code
= 1;
1946 /* Write the instruction encoding to frag. */
1947 for (i
= 0; i
< insn_size
; i
++)
1949 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
1954 /* This is the guts of the machine-dependent assembler. OP points to a
1955 machine dependent instruction. This function is supposed to emit
1956 the frags/bytes it assembles to. */
1959 md_assemble (char *op
)
1965 /* Reset global variables for a new instruction. */
1968 /* Strip the mnemonic. */
1969 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
1974 /* Find the instruction. */
1975 instruction
= (const inst
*) str_hash_find (crx_inst_hash
, op
);
1976 if (instruction
== NULL
)
1978 as_bad (_("Unknown opcode: `%s'"), op
);
1983 /* Tie dwarf2 debug info to the address at the start of the insn. */
1984 dwarf2_emit_insn (0);
1986 /* Parse the instruction's operands. */
1987 parse_insn (&crx_ins
, param
);
1989 /* Assemble the instruction - return upon failure. */
1990 if (assemble_insn (op
, &crx_ins
) == 0)
1996 /* Print the instruction. */
1998 print_insn (&crx_ins
);