1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright (C) 2004-2017 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 struct hash_control
*crx_inst_hash
;
67 /* CRX registers hash table. */
68 static struct hash_control
*reg_hash
;
69 /* CRX coprocessor registers hash table. */
70 static struct hash_control
*copreg_hash
;
71 /* Current instruction we're assembling. */
72 const inst
*instruction
;
74 /* Global variables. */
76 /* Array to hold an instruction encoding. */
77 long output_opcode
[2];
79 /* Nonzero means a relocatable symbol. */
82 /* A copy of the original instruction (used in error messages). */
83 char ins_parse
[MAX_INST_LEN
];
85 /* The current processed argument number. */
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 (reg
);
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
*) 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
*) 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
+ 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. */
530 const char *hashret
= NULL
;
533 /* Set up a hash table for the instructions. */
534 if ((crx_inst_hash
= hash_new ()) == NULL
)
535 as_fatal (_("Virtual memory exhausted"));
537 while (crx_instruction
[i
].mnemonic
!= NULL
)
539 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
541 hashret
= hash_insert (crx_inst_hash
, mnemonic
,
542 (void *) &crx_instruction
[i
]);
544 if (hashret
!= NULL
&& *hashret
!= '\0')
545 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction
[i
].mnemonic
,
546 *hashret
== 0 ? _("(unknown reason)") : hashret
);
548 /* Insert unique names into hash table. The CRX instruction set
549 has many identical opcode names that have different opcodes based
550 on the operands. This hash table then provides a quick index to
551 the first opcode with a particular name in the opcode table. */
556 while (crx_instruction
[i
].mnemonic
!= NULL
557 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
560 /* Initialize reg_hash hash table. */
561 if ((reg_hash
= hash_new ()) == NULL
)
562 as_fatal (_("Virtual memory exhausted"));
565 const reg_entry
*regtab
;
567 for (regtab
= crx_regtab
;
568 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
570 hashret
= hash_insert (reg_hash
, regtab
->name
, (void *) regtab
);
572 as_fatal (_("Internal error: Can't hash %s: %s"),
578 /* Initialize copreg_hash hash table. */
579 if ((copreg_hash
= hash_new ()) == NULL
)
580 as_fatal (_("Virtual memory exhausted"));
583 const reg_entry
*copregtab
;
585 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
588 hashret
= hash_insert (copreg_hash
, copregtab
->name
,
591 as_fatal (_("Internal error: Can't hash %s: %s"),
596 /* Set linkrelax here to avoid fixups in most sections. */
600 /* Process constants (immediate/absolute)
601 and labels (jump targets/Memory locations). */
604 process_label_constant (char *str
, ins
* crx_ins
)
606 char *saved_input_line_pointer
;
607 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
609 saved_input_line_pointer
= input_line_pointer
;
610 input_line_pointer
= str
;
612 expression (&crx_ins
->exp
);
614 switch (crx_ins
->exp
.X_op
)
618 /* Missing or bad expr becomes absolute 0. */
619 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
621 crx_ins
->exp
.X_op
= O_constant
;
622 crx_ins
->exp
.X_add_number
= 0;
623 crx_ins
->exp
.X_add_symbol
= (symbolS
*) 0;
624 crx_ins
->exp
.X_op_symbol
= (symbolS
*) 0;
628 cur_arg
->X_op
= O_constant
;
629 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
635 cur_arg
->X_op
= O_symbol
;
636 crx_ins
->rtype
= BFD_RELOC_NONE
;
639 switch (cur_arg
->type
)
642 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
643 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
644 else if (IS_INSN_TYPE (CSTBIT_INS
)
645 || IS_INSN_TYPE (STOR_IMM_INS
))
646 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
648 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
652 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
656 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
657 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
658 else if (IS_INSN_TYPE (BRANCH_INS
))
659 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
660 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
661 || IS_INSN_TYPE (CSTBIT_INS
))
662 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
663 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
664 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
665 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
666 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
670 if (IS_INSN_TYPE (ARITH_INS
))
671 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
672 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
673 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
681 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
685 input_line_pointer
= saved_input_line_pointer
;
689 /* Get the values of the scale to be encoded -
690 used for the scaled index mode of addressing. */
693 exponent2scale (int val
)
697 /* If 'val' is 0, the following 'for' will be an endless loop. */
701 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
707 /* Parsing different types of operands
708 -> constants Immediate/Absolute/Relative numbers
709 -> Labels Relocatable symbols
710 -> (rbase) Register base
711 -> disp(rbase) Register relative
712 -> disp(rbase)+ Post-increment mode
713 -> disp(rbase,ridx,scl) Register index mode */
716 set_operand (char *operand
, ins
* crx_ins
)
718 char *operandS
; /* Pointer to start of sub-operand. */
719 char *operandE
; /* Pointer to end of sub-operand. */
723 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
725 /* Initialize pointers. */
726 operandS
= operandE
= operand
;
728 switch (cur_arg
->type
)
730 case arg_sc
: /* Case *+0x18. */
731 case arg_ic
: /* Case $0x18. */
734 case arg_c
: /* Case 0x18. */
736 process_label_constant (operandS
, crx_ins
);
738 if (cur_arg
->type
!= arg_ic
)
739 cur_arg
->type
= arg_c
;
742 case arg_icr
: /* Case $0x18(r1). */
744 case arg_cr
: /* Case 0x18(r1). */
745 /* Set displacement constant. */
746 while (*operandE
!= '(')
749 process_label_constant (operandS
, crx_ins
);
752 case arg_rbase
: /* Case (r1). */
754 /* Set register base. */
755 while (*operandE
!= ')')
758 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
759 as_bad (_("Illegal register `%s' in instruction `%s'"),
760 operandS
, ins_parse
);
762 if (cur_arg
->type
!= arg_rbase
)
763 cur_arg
->type
= arg_cr
;
767 /* Set displacement constant. */
768 while (*operandE
!= '(')
771 process_label_constant (operandS
, crx_ins
);
772 operandS
= ++operandE
;
774 /* Set register base. */
775 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
778 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
779 as_bad (_("Illegal register `%s' in instruction `%s'"),
780 operandS
, ins_parse
);
782 /* Skip leading white space. */
783 while (ISSPACE (*operandE
))
787 /* Set register index. */
788 while ((*operandE
!= ')') && (*operandE
!= ','))
793 if ((cur_arg
->i_r
= get_register (operandS
)) == nullregister
)
794 as_bad (_("Illegal register `%s' in instruction `%s'"),
795 operandS
, ins_parse
);
797 /* Skip leading white space. */
798 while (ISSPACE (*operandE
))
807 while (*operandE
!= ')')
811 /* Preprocess the scale string. */
812 input_save
= input_line_pointer
;
813 input_line_pointer
= operandS
;
815 input_line_pointer
= input_save
;
817 scale_val
= scale
.X_add_number
;
819 /* Check if the scale value is legal. */
820 if (scale_val
!= 1 && scale_val
!= 2
821 && scale_val
!= 4 && scale_val
!= 8)
822 as_bad (_("Illegal Scale - `%d'"), scale_val
);
824 cur_arg
->scale
= exponent2scale (scale_val
);
833 /* Parse a single operand.
834 operand - Current operand to parse.
835 crx_ins - Current assembled instruction. */
838 parse_operand (char *operand
, ins
* crx_ins
)
841 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
843 /* Initialize the type to NULL before parsing. */
844 cur_arg
->type
= nullargs
;
846 /* Check whether this is a general processor register. */
847 if ((ret_val
= get_register (operand
)) != nullregister
)
849 cur_arg
->type
= arg_r
;
850 cur_arg
->r
= ret_val
;
851 cur_arg
->X_op
= O_register
;
855 /* Check whether this is a core [special] coprocessor register. */
856 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
858 cur_arg
->type
= arg_copr
;
860 cur_arg
->type
= arg_copsr
;
861 cur_arg
->cr
= ret_val
;
862 cur_arg
->X_op
= O_register
;
866 /* Deal with special characters. */
870 if (strchr (operand
, '(') != NULL
)
871 cur_arg
->type
= arg_icr
;
873 cur_arg
->type
= arg_ic
;
878 cur_arg
->type
= arg_sc
;
883 cur_arg
->type
= arg_rbase
;
891 if (strchr (operand
, '(') != NULL
)
893 if (strchr (operand
, ',') != NULL
894 && (strchr (operand
, ',') > strchr (operand
, '(')))
895 cur_arg
->type
= arg_idxr
;
897 cur_arg
->type
= arg_cr
;
900 cur_arg
->type
= arg_c
;
903 /* Parse an operand according to its type. */
905 cur_arg
->constant
= 0;
906 set_operand (operand
, crx_ins
);
909 /* Parse the various operands. Each operand is then analyzed to fillup
910 the fields in the crx_ins data structure. */
913 parse_operands (ins
* crx_ins
, char *operands
)
915 char *operandS
; /* Operands string. */
916 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
917 int allocated
= 0; /* Indicates a new operands string was allocated. */
918 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
919 int op_num
= 0; /* Current operand number we are parsing. */
920 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
921 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
923 /* Preprocess the list of registers, if necessary. */
924 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
925 preprocess_reglist (operands
, &allocated
) : operands
;
927 while (*operandT
!= '\0')
929 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
932 operand
[op_num
++] = strdup (operandH
);
937 if (*operandT
== ' ')
938 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
940 if (*operandT
== '(')
942 else if (*operandT
== '[')
945 if (*operandT
== ')')
950 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
952 else if (*operandT
== ']')
957 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
960 if (bracket_flag
== 1 && *operandT
== ')')
962 else if (sq_bracket_flag
== 1 && *operandT
== ']')
968 /* Adding the last operand. */
969 operand
[op_num
++] = strdup (operandH
);
970 crx_ins
->nargs
= op_num
;
972 /* Verifying correct syntax of operands (all brackets should be closed). */
973 if (bracket_flag
|| sq_bracket_flag
)
974 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
976 /* Now we parse each operand separately. */
977 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
979 cur_arg_num
= op_num
;
980 parse_operand (operand
[op_num
], crx_ins
);
981 free (operand
[op_num
]);
988 /* Get the trap index in dispatch table, given its name.
989 This routine is used by assembling the 'excp' instruction. */
992 gettrap (const char *s
)
994 const trap_entry
*trap
;
996 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
997 if (strcasecmp (trap
->name
, s
) == 0)
1000 as_bad (_("Unknown exception: `%s'"), s
);
1004 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1005 sub-group within load/stor instruction groups.
1006 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1007 advance the instruction pointer to the start of that sub-group (that is, up
1008 to the first instruction of that type).
1009 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1012 handle_LoadStor (const char *operands
)
1014 /* Post-Increment instructions precede Store-Immediate instructions in
1015 CRX instruction table, hence they are handled before.
1016 This synchronization should be kept. */
1018 /* Assuming Post-Increment insn has the following format :
1019 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1020 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1021 if (strstr (operands
, ")+") != NULL
)
1023 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1028 /* Assuming Store-Immediate insn has the following format :
1029 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1030 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1031 if (strstr (operands
, "$") != NULL
)
1032 while (! IS_INSN_TYPE (STOR_IMM_INS
))
1036 /* Top level module where instruction parsing starts.
1037 crx_ins - data structure holds some information.
1038 operands - holds the operands part of the whole instruction. */
1041 parse_insn (ins
*insn
, char *operands
)
1045 /* Handle instructions with no operands. */
1046 for (i
= 0; no_op_insn
[i
] != NULL
; i
++)
1048 if (streq (no_op_insn
[i
], instruction
->mnemonic
))
1055 /* Handle 'excp'/'cinv' instructions. */
1056 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1059 insn
->arg
[0].type
= arg_ic
;
1060 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1061 gettrap (operands
) : get_cinv_parameters (operands
);
1062 insn
->arg
[0].X_op
= O_constant
;
1066 /* Handle load/stor unique instructions before parsing. */
1067 if (IS_INSN_TYPE (LD_STOR_INS
))
1068 handle_LoadStor (operands
);
1070 if (operands
!= NULL
)
1071 parse_operands (insn
, operands
);
1074 /* Cinv instruction requires special handling. */
1077 get_cinv_parameters (const char *operand
)
1079 const char *p
= operand
;
1080 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1084 if (*p
== ',' || *p
== ' ')
1096 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1099 return ((b_used
? 8 : 0)
1102 + (u_used
? 1 : 0));
1105 /* Retrieve the opcode image of a given register.
1106 If the register is illegal for the current instruction,
1110 getreg_image (reg r
)
1112 const reg_entry
*rreg
;
1114 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1116 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num
== 1))
1117 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num
== 0)) )
1120 /* Check whether the register is in registers table. */
1122 rreg
= &crx_regtab
[r
];
1123 /* Check whether the register is in coprocessor registers table. */
1124 else if (r
< (int) MAX_COPREG
)
1125 rreg
= &crx_copregtab
[r
-MAX_REG
];
1126 /* Register not found. */
1129 as_bad (_("Unknown register: `%d'"), r
);
1133 reg_name
= rreg
->name
;
1135 /* Issue a error message when register is illegal. */
1137 as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1138 reg_name, ins_parse); \
1144 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1149 case CRX_CFG_REGTYPE
:
1162 case CRX_CS_REGTYPE
:
1173 /* Routine used to represent integer X using NBITS bits. */
1176 getconstant (long x
, int nbits
)
1178 return x
& ((((1U << (nbits
- 1)) - 1) << 1) | 1);
1181 /* Print a constant value to 'output_opcode':
1182 ARG holds the operand's type and value.
1183 SHIFT represents the location of the operand to be print into.
1184 NBITS determines the size (in bits) of the constant. */
1187 print_constant (int nbits
, int shift
, argument
*arg
)
1189 unsigned long mask
= 0;
1191 long constant
= getconstant (arg
->constant
, nbits
);
1199 /* mask the upper part of the constant, that is, the bits
1200 going to the lowest byte of output_opcode[0].
1201 The upper part of output_opcode[1] is always filled,
1202 therefore it is always masked with 0xFFFF. */
1203 mask
= (1 << (nbits
- 16)) - 1;
1204 /* Divide the constant between two consecutive words :
1206 +---------+---------+---------+---------+
1207 | | X X X X | X X X X | |
1208 +---------+---------+---------+---------+
1209 output_opcode[0] output_opcode[1] */
1211 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1212 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1217 /* Special case - in arg_cr, the SHIFT represents the location
1218 of the REGISTER, not the constant, which is itself not shifted. */
1219 if (arg
->type
== arg_cr
)
1221 CRX_PRINT (0, constant
, 0);
1225 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1226 always filling the upper part of output_opcode[1]. If we mistakenly
1227 write it to output_opcode[0], the constant prefix (that is, 'match')
1230 +---------+---------+---------+---------+
1231 | 'match' | | X X X X | |
1232 +---------+---------+---------+---------+
1233 output_opcode[0] output_opcode[1] */
1235 if ((instruction
->size
> 2) && (shift
== WORD_SHIFT
))
1236 CRX_PRINT (1, constant
, WORD_SHIFT
);
1238 CRX_PRINT (0, constant
, shift
);
1242 CRX_PRINT (0, constant
, shift
);
1247 /* Print an operand to 'output_opcode', which later on will be
1248 printed to the object file:
1249 ARG holds the operand's type, size and value.
1250 SHIFT represents the printing location of operand.
1251 NBITS determines the size (in bits) of a constant operand. */
1254 print_operand (int nbits
, int shift
, argument
*arg
)
1259 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1263 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1264 as_bad (_("Illegal co-processor register in instruction `%s'"),
1266 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1270 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1271 as_bad (_("Illegal co-processor special register in instruction `%s'"),
1273 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1278 +--------------------------------+
1279 | r_base | r_idx | scl| disp |
1280 +--------------------------------+ */
1281 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1282 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1283 CRX_PRINT (0, arg
->scale
, 6);
1287 print_constant (nbits
, shift
, arg
);
1291 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1295 /* case base_cst4. */
1296 if (instruction
->flags
& DISPU4MAP
)
1297 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
1299 /* rbase_disps<NN> and other such cases. */
1300 print_constant (nbits
, shift
, arg
);
1301 /* Add the register argument to the output_opcode. */
1302 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1310 /* Retrieve the number of operands for the current assembled instruction. */
1313 get_number_of_operands (void)
1317 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1322 /* Verify that the number NUM can be represented in BITS bits (that is,
1323 within its permitted range), based on the instruction's FLAGS.
1324 If UPDATE is nonzero, update the value of NUM if necessary.
1325 Return OP_LEGAL upon success, actual error type upon failure. */
1328 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1331 op_err retval
= OP_LEGAL
;
1333 uint32_t upper_64kb
= 0xffff0000;
1334 uint32_t value
= *num
;
1336 /* Verify operand value is even. */
1337 if (flags
& OP_EVEN
)
1343 if (flags
& OP_UPPER_64KB
)
1345 /* Check if value is to be mapped to upper 64 KB memory area. */
1346 if ((value
& upper_64kb
) == upper_64kb
)
1348 value
-= upper_64kb
;
1353 return OP_NOT_UPPER_64KB
;
1356 if (flags
& OP_SHIFT
)
1358 /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1359 sign. However, right shift of a signed type with a negative
1360 value is implementation defined. See ISO C 6.5.7. So we use
1361 an unsigned type and sign extend afterwards. */
1363 value
= (value
^ 0x40000000) - 0x40000000;
1367 else if (flags
& OP_SHIFT_DEC
)
1369 value
= (value
>> 1) - 1;
1376 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1377 if (value
== 0x7e || value
== 0x7f)
1378 return OP_OUT_OF_RANGE
;
1381 if (flags
& OP_DISPU4
)
1385 uint32_t mul
= (instruction
->flags
& DISPUB4
? 1
1386 : instruction
->flags
& DISPUW4
? 2
1387 : instruction
->flags
& DISPUD4
? 4
1390 for (bin
= 0; bin
< cst4_maps
; bin
++)
1392 if (value
== mul
* bin
)
1401 retval
= OP_ILLEGAL_DISPU4
;
1403 else if (flags
& OP_CST4
)
1407 for (bin
= 0; bin
< cst4_maps
; bin
++)
1409 if (value
== (uint32_t) cst4_map
[bin
])
1418 retval
= OP_ILLEGAL_CST4
;
1420 else if (flags
& OP_SIGNED
)
1423 max
= max
<< (bits
- 1);
1425 max
= ((max
- 1) << 1) | 1;
1427 retval
= OP_OUT_OF_RANGE
;
1429 else if (flags
& OP_UNSIGNED
)
1432 max
= max
<< (bits
- 1);
1433 max
= ((max
- 1) << 1) | 1;
1435 retval
= OP_OUT_OF_RANGE
;
1440 /* Assemble a single instruction:
1441 INSN is already parsed (that is, all operand values and types are set).
1442 For instruction to be assembled, we need to find an appropriate template in
1443 the instruction table, meeting the following conditions:
1444 1: Has the same number of operands.
1445 2: Has the same operand types.
1446 3: Each operand size is sufficient to represent the instruction's values.
1447 Returns 1 upon success, 0 upon failure. */
1450 assemble_insn (char *mnemonic
, ins
*insn
)
1452 /* Type of each operand in the current template. */
1453 argtype cur_type
[MAX_OPERANDS
];
1454 /* Size (in bits) of each operand in the current template. */
1455 unsigned int cur_size
[MAX_OPERANDS
];
1456 /* Flags of each operand in the current template. */
1457 unsigned int cur_flags
[MAX_OPERANDS
];
1458 /* Instruction type to match. */
1459 unsigned int ins_type
;
1460 /* Boolean flag to mark whether a match was found. */
1463 /* Nonzero if an instruction with same number of operands was found. */
1464 int found_same_number_of_operands
= 0;
1465 /* Nonzero if an instruction with same argument types was found. */
1466 int found_same_argument_types
= 0;
1467 /* Nonzero if a constant was found within the required range. */
1468 int found_const_within_range
= 0;
1469 /* Argument number of an operand with invalid type. */
1470 int invalid_optype
= -1;
1471 /* Argument number of an operand with invalid constant value. */
1472 int invalid_const
= -1;
1473 /* Operand error (used for issuing various constant error messages). */
1474 op_err op_error
, const_err
= OP_LEGAL
;
1476 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1477 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1478 for (i = 0; i < insn->nargs; i++) \
1479 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1481 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1482 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1483 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1485 /* Instruction has no operands -> only copy the constant opcode. */
1486 if (insn
->nargs
== 0)
1488 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1492 /* In some case, same mnemonic can appear with different instruction types.
1493 For example, 'storb' is supported with 3 different types :
1494 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1495 We assume that when reaching this point, the instruction type was
1496 pre-determined. We need to make sure that the type stays the same
1497 during a search for matching instruction. */
1498 ins_type
= CRX_INS_TYPE(instruction
->flags
);
1500 while (/* Check that match is still not found. */
1502 /* Check we didn't get to end of table. */
1503 && instruction
->mnemonic
!= NULL
1504 /* Check that the actual mnemonic is still available. */
1505 && IS_INSN_MNEMONIC (mnemonic
)
1506 /* Check that the instruction type wasn't changed. */
1507 && IS_INSN_TYPE(ins_type
))
1509 /* Check whether number of arguments is legal. */
1510 if (get_number_of_operands () != insn
->nargs
)
1512 found_same_number_of_operands
= 1;
1514 /* Initialize arrays with data of each operand in current template. */
1519 /* Check for type compatibility. */
1520 for (i
= 0; i
< insn
->nargs
; i
++)
1522 if (cur_type
[i
] != insn
->arg
[i
].type
)
1524 if (invalid_optype
== -1)
1525 invalid_optype
= i
+ 1;
1529 found_same_argument_types
= 1;
1531 for (i
= 0; i
< insn
->nargs
; i
++)
1533 /* Reverse the operand indices for certain opcodes:
1536 Other index -->> stays the same. */
1537 int j
= instruction
->flags
& REVERSE_MATCH
?
1542 /* Only check range - don't update the constant's value, since the
1543 current instruction may not be the last we try to match.
1544 The constant's value will be updated later, right before printing
1545 it to the object file. */
1546 if ((insn
->arg
[j
].X_op
== O_constant
)
1547 && (op_error
= check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1550 if (invalid_const
== -1)
1552 invalid_const
= j
+ 1;
1553 const_err
= op_error
;
1557 /* For symbols, we make sure the relocation size (which was already
1558 determined) is sufficient. */
1559 else if ((insn
->arg
[j
].X_op
== O_symbol
)
1560 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
1564 found_const_within_range
= 1;
1566 /* If we got till here -> Full match is found. */
1570 /* Try again with next instruction. */
1577 /* We haven't found a match - instruction can't be assembled. */
1578 if (!found_same_number_of_operands
)
1579 as_bad (_("Incorrect number of operands"));
1580 else if (!found_same_argument_types
)
1581 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
1582 else if (!found_const_within_range
)
1586 case OP_OUT_OF_RANGE
:
1587 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1590 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
1592 case OP_ILLEGAL_DISPU4
:
1593 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const
);
1595 case OP_ILLEGAL_CST4
:
1596 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1598 case OP_NOT_UPPER_64KB
:
1599 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1603 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
1611 /* Full match - print the encoding to output file. */
1613 /* Make further checking (such that couldn't be made earlier).
1614 Warn the user if necessary. */
1615 warn_if_needed (insn
);
1617 /* Check whether we need to adjust the instruction pointer. */
1618 if (adjust_if_needed (insn
))
1619 /* If instruction pointer was adjusted, we need to update
1620 the size of the current template operands. */
1623 for (i
= 0; i
< insn
->nargs
; i
++)
1625 int j
= instruction
->flags
& REVERSE_MATCH
?
1630 /* This time, update constant value before printing it. */
1631 if ((insn
->arg
[j
].X_op
== O_constant
)
1632 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1633 cur_flags
[j
], 1) != OP_LEGAL
))
1634 as_fatal (_("Illegal operand (arg %d)"), j
+1);
1637 /* First, copy the instruction's opcode. */
1638 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1640 for (i
= 0; i
< insn
->nargs
; i
++)
1643 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1651 /* Bunch of error checking.
1652 The checks are made after a matching instruction was found. */
1655 warn_if_needed (ins
*insn
)
1657 /* If the post-increment address mode is used and the load/store
1658 source register is the same as rbase, the result of the
1659 instruction is undefined. */
1660 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1662 /* Enough to verify that one of the arguments is a simple reg. */
1663 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
1664 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
1665 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1669 /* Some instruction assume the stack pointer as rptr operand.
1670 Issue an error when the register to be loaded is also SP. */
1671 if (instruction
->flags
& NO_SP
)
1673 if (getreg_image (insn
->arg
[0].r
) == getreg_image (sp
))
1674 as_bad (_("`%s' has undefined result"), ins_parse
);
1677 /* If the rptr register is specified as one of the registers to be loaded,
1678 the final contents of rptr are undefined. Thus, we issue an error. */
1679 if (instruction
->flags
& NO_RPTR
)
1681 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
1682 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1683 getreg_image (insn
->arg
[0].r
));
1687 /* In some cases, we need to adjust the instruction pointer although a
1688 match was already found. Here, we gather all these cases.
1689 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1692 adjust_if_needed (ins
*insn
)
1696 /* Special check for 'addub $0, r0' instruction -
1697 The opcode '0000 0000 0000 0000' is not allowed. */
1698 if (IS_INSN_MNEMONIC ("addub"))
1700 if ((instruction
->operands
[0].op_type
== cst4
)
1701 && instruction
->operands
[1].op_type
== regr
)
1703 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
1711 /* Optimization: Omit a zero displacement in bit operations,
1712 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1713 if (IS_INSN_TYPE (CSTBIT_INS
))
1715 if ((instruction
->operands
[1].op_type
== rbase_disps12
)
1716 && (insn
->arg
[1].X_op
== O_constant
)
1717 && (insn
->arg
[1].constant
== 0))
1727 /* Set the appropriate bit for register 'r' in 'mask'.
1728 This indicates that this register is loaded or stored by
1732 mask_reg (int r
, unsigned short int *mask
)
1734 if ((reg
)r
> (reg
)sp
)
1736 as_bad (_("Invalid register in register list"));
1743 /* Preprocess register list - create a 16-bit mask with one bit for each
1744 of the 16 general purpose registers. If a bit is set, it indicates
1745 that this register is loaded or stored by the instruction. */
1748 preprocess_reglist (char *param
, int *allocated
)
1750 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
1751 char *regP
; /* Pointer to 'reg_name' string. */
1752 int reg_counter
= 0; /* Count number of parsed registers. */
1753 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
1754 char *new_param
; /* New created operands string. */
1755 char *paramP
= param
; /* Pointer to original operands string. */
1756 char maskstring
[10]; /* Array to print the mask as a string. */
1757 int hi_found
= 0, lo_found
= 0; /* Boolean flags for hi/lo registers. */
1761 /* If 'param' is already in form of a number, no need to preprocess. */
1762 if (strchr (paramP
, '{') == NULL
)
1765 /* Verifying correct syntax of operand. */
1766 if (strchr (paramP
, '}') == NULL
)
1767 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1769 while (*paramP
++ != '{');
1771 new_param
= XCNEWVEC (char, MAX_INST_LEN
);
1773 strncpy (new_param
, param
, paramP
- param
- 1);
1775 while (*paramP
!= '}')
1778 memset (®_name
, '\0', sizeof (reg_name
));
1780 while (ISALNUM (*paramP
))
1783 strncpy (reg_name
, regP
, paramP
- regP
);
1785 /* Coprocessor register c<N>. */
1786 if (IS_INSN_TYPE (COP_REG_INS
))
1788 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1789 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_C_REGTYPE
))
1790 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name
);
1791 mask_reg (getreg_image (cr
- c0
), &mask
);
1793 /* Coprocessor Special register cs<N>. */
1794 else if (IS_INSN_TYPE (COPS_REG_INS
))
1796 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1797 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_CS_REGTYPE
))
1798 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1800 mask_reg (getreg_image (cr
- cs0
), &mask
);
1802 /* User register u<N>. */
1803 else if (instruction
->flags
& USER_REG
)
1805 if (streq(reg_name
, "uhi"))
1810 else if (streq(reg_name
, "ulo"))
1815 else if (((r
= get_register (reg_name
)) == nullregister
)
1816 || (crx_regtab
[r
].type
!= CRX_U_REGTYPE
))
1817 as_fatal (_("Illegal register `%s' in user register list"), reg_name
);
1819 mask_reg (getreg_image (r
- u0
), &mask
);
1821 /* General purpose register r<N>. */
1824 if (streq(reg_name
, "hi"))
1829 else if (streq(reg_name
, "lo"))
1834 else if (((r
= get_register (reg_name
)) == nullregister
)
1835 || (crx_regtab
[r
].type
!= CRX_R_REGTYPE
))
1836 as_fatal (_("Illegal register `%s' in register list"), reg_name
);
1838 mask_reg (getreg_image (r
- r0
), &mask
);
1841 if (++reg_counter
> MAX_REGS_IN_MASK16
)
1842 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1843 MAX_REGS_IN_MASK16
);
1846 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1850 if (*++paramP
!= '\0')
1851 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1854 switch (hi_found
+ lo_found
)
1857 /* At least one register should be specified. */
1859 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1864 /* HI can't be specified without LO (and vise-versa). */
1865 as_bad (_("HI/LO registers should be specified together"));
1869 /* HI/LO registers mustn't be masked with additional registers. */
1871 as_bad (_("HI/LO registers should be specified without additional registers"));
1877 sprintf (maskstring
, "$0x%x", mask
);
1878 strcat (new_param
, maskstring
);
1882 /* Print the instruction.
1883 Handle also cases where the instruction is relaxable/relocatable. */
1886 print_insn (ins
*insn
)
1888 unsigned int i
, j
, insn_size
;
1890 unsigned short words
[4];
1893 /* Arrange the insn encodings in a WORD size array. */
1894 for (i
= 0, j
= 0; i
< 2; i
++)
1896 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
1897 words
[j
++] = output_opcode
[i
] & 0xFFFF;
1900 /* Handle relaxation. */
1901 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
1905 /* Write the maximal instruction size supported. */
1906 insn_size
= INSN_MAX_SIZE
;
1909 if (IS_INSN_TYPE (BRANCH_INS
))
1912 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1915 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1920 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1922 insn
->exp
.X_add_symbol
,
1923 insn
->exp
.X_add_number
,
1928 insn_size
= instruction
->size
;
1929 this_frag
= frag_more (insn_size
* 2);
1931 /* Handle relocation. */
1932 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
1934 reloc_howto_type
*reloc_howto
;
1937 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1942 size
= bfd_get_reloc_size (reloc_howto
);
1944 if (size
< 1 || size
> 4)
1947 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1948 size
, &insn
->exp
, reloc_howto
->pc_relative
,
1953 /* Verify a 2-byte code alignment. */
1954 addr_mod
= frag_now_fix () & 1;
1955 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
1956 as_bad (_("instruction address is not a multiple of 2"));
1957 frag_now
->insn_addr
= addr_mod
;
1958 frag_now
->has_code
= 1;
1960 /* Write the instruction encoding to frag. */
1961 for (i
= 0; i
< insn_size
; i
++)
1963 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
1968 /* This is the guts of the machine-dependent assembler. OP points to a
1969 machine dependent instruction. This function is supposed to emit
1970 the frags/bytes it assembles to. */
1973 md_assemble (char *op
)
1979 /* Reset global variables for a new instruction. */
1982 /* Strip the mnemonic. */
1983 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
1988 /* Find the instruction. */
1989 instruction
= (const inst
*) hash_find (crx_inst_hash
, op
);
1990 if (instruction
== NULL
)
1992 as_bad (_("Unknown opcode: `%s'"), op
);
1997 /* Tie dwarf2 debug info to the address at the start of the insn. */
1998 dwarf2_emit_insn (0);
2000 /* Parse the instruction's operands. */
2001 parse_insn (&crx_ins
, param
);
2003 /* Assemble the instruction - return upon failure. */
2004 if (assemble_insn (op
, &crx_ins
) == 0)
2010 /* Print the instruction. */
2012 print_insn (&crx_ins
);