1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright 2004 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 2, 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, 59 Temple Place - Suite 330, Boston,
23 MA 02111-1307, USA. */
26 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
28 #include "opcode/crx.h"
31 /* Include <limits.h> do define ULONG_MAX, LONG_MAX, LONG_MIN. */
34 /* Word is considered here as a 16-bit unsigned short int. */
38 /* Register is 4-bit size. */
41 /* Maximum size of a single instruction (in words). */
42 #define INSN_MAX_SIZE 3
44 /* Maximum bits which may be set in a `mask16' operand. */
45 #define MAX_REGS_IN_MASK16 8
47 /* Escape to 16-bit immediate. */
49 /* Escape to 32-bit immediate. */
52 /* Utility macros for string comparison. */
53 #define streq(a, b) (strcmp (a, b) == 0)
54 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
56 /* A mask to set n_bits starting from offset offs. */
57 #define SET_BITS_MASK(offs,n_bits) ((((1 << (n_bits)) - 1) << (offs)))
58 /* A mask to clear n_bits starting from offset offs. */
59 #define CLEAR_BITS_MASK(offs,n_bits) (~(((1 << (n_bits)) - 1) << (offs)))
61 /* Get the argument type for each operand of a given instruction. */
62 #define GET_ACTUAL_TYPE \
63 for (i = 0; i < insn->nargs; i++) \
64 atyp_act[i] = getarg_type (instruction->operands[i].op_type)
66 /* Get the size (in bits) for each operand of a given instruction. */
67 #define GET_ACTUAL_SIZE \
68 for (i = 0; i < insn->nargs; i++) \
69 bits_act[i] = getbits (instruction->operands[i].op_type)
71 /* Non-zero if OP is instruction with no operands. */
72 #define NO_OPERANDS_INST(OP) \
73 (streq (OP, "di") || streq (OP, "nop") \
74 || streq (OP, "retx") || streq (OP, "ei") \
75 || streq (OP, "wait") || streq (OP, "eiwait"))
77 /* Print a number NUM, shifted by SHIFT bytes, into a location
78 pointed by index BYTE of array 'output_opcode'. */
79 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
81 /* Opcode mnemonics hash table. */
82 static struct hash_control
*crx_inst_hash
;
83 /* CRX registers hash table. */
84 static struct hash_control
*reg_hash
;
85 /* CRX coprocessor registers hash table. */
86 static struct hash_control
*copreg_hash
;
87 /* Current instruction we're assembling. */
88 const inst
*instruction
;
90 /* Initialize global variables. */
91 long output_opcode
[2];
92 /* Nonzero means a relocatable symbol. */
94 /* Nonzero means a constant's bit-size was already set. */
96 /* Nonzero means a negative constant. */
98 /* Nonzero means a CST4 instruction. */
100 /* A copy of the original instruction (used in error messages). */
101 char ins_parse
[MAX_INST_LEN
];
102 /* Nonzero means instruction is represented in post increment mode. */
104 /* Holds the current processed argument number. */
105 int processing_arg_number
;
107 /* Generic assembler global variables which must be defined by all targets. */
109 /* Characters which always start a comment. */
110 const char comment_chars
[] = "#";
112 /* Characters which start a comment at the beginning of a line. */
113 const char line_comment_chars
[] = "#";
115 /* This array holds machine specific line separator characters. */
116 const char line_separator_chars
[] = ";";
118 /* Chars that can be used to separate mant from exp in floating point nums. */
119 const char EXP_CHARS
[] = "eE";
121 /* Chars that mean this number is a floating point constant as in 0f12.456 */
122 const char FLT_CHARS
[] = "f'";
124 /* Target-specific multicharacter options, not const-declared at usage. */
125 const char *md_shortopts
= "";
126 struct option md_longopts
[] = {
127 {NULL
, no_argument
, NULL
, 0}
129 size_t md_longopts_size
= sizeof (md_longopts
);
131 /* This table describes all the machine specific pseudo-ops
132 the assembler has to support. The fields are:
133 *** Pseudo-op name without dot.
134 *** Function to call to execute this pseudo-op.
135 *** Integer arg to pass to the function. */
137 const pseudo_typeS md_pseudo_table
[] =
139 /* In CRX machine, align is in bytes (not a ptwo boundary). */
140 {"align", s_align_bytes
, 0},
144 const relax_typeS md_relax_table
[] =
147 {0xfa, -0x100, 2, 1}, /* 8 */
148 {0xfffe, -0x10000, 4, 2}, /* 16 */
149 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
152 {0xfffe, -0x10000, 4, 4}, /* 16 */
153 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
156 {0xfe, -0x100, 4, 6}, /* 8 */
157 {0xfffffe, -0x1000000, 6, 0} /* 24 */
160 static void reset_vars (char *, ins
*);
161 static reg
get_register (char *);
162 static copreg
get_copregister (char *);
163 static void get_number_of_bits (ins
*, int);
164 static argtype
getarg_type (operand_type
);
165 static int getbits (operand_type
);
166 static int get_number_of_operands (void);
167 static void get_operandtype (char *, int, ins
*);
168 static int gettrap (char *);
169 static void handle_pi_insn (char *);
170 static int get_cinv_parameters (char *);
171 static unsigned long getconstant (unsigned long, int);
172 static int getreg_image (reg
);
173 static void parse_operands (ins
*, char *);
174 static void parse_insn (ins
*, char *);
175 static void print_operand (int, int, argument
*);
176 static void print_constant (int, int, argument
*);
177 static int exponent2scale (int);
178 static void mask_const (unsigned long *, int);
179 static void mask_reg (int, unsigned short *);
180 static int process_label_constant (char *, ins
*, int);
181 static void set_indexmode_parameters (char *, ins
*, int);
182 static void set_cons_rparams (char *, ins
*, int);
183 static char * preprocess_reglist (char *, int *);
184 static int assemble_insn (char *, ins
*);
185 static void print_insn (ins
*);
187 /* Return the bit size for a given operand. */
190 getbits (operand_type op
)
193 return crx_optab
[op
].bit_size
;
198 /* Return the argument type of a given operand. */
201 getarg_type (operand_type op
)
204 return crx_optab
[op
].arg_type
;
209 /* Get the core processor register 'reg_name'. */
212 get_register (char *reg_name
)
214 const reg_entry
*reg
;
216 reg
= (const reg_entry
*) hash_find (reg_hash
, reg_name
);
219 return reg
->value
.reg_val
;
224 /* Get the coprocessor register 'copreg_name'. */
227 get_copregister (char *copreg_name
)
229 const reg_entry
*copreg
;
231 copreg
= (const reg_entry
*) hash_find (copreg_hash
, copreg_name
);
234 return copreg
->value
.copreg_val
;
236 return nullcopregister
;
239 /* Mask a constant to the number of bits it is to be mapped to. */
242 mask_const (unsigned long int *t
, int size
)
244 *t
&= (((LONGLONG
)1 << size
) - 1);
247 /* Round up a section size to the appropriate boundary. */
250 md_section_align (segT seg
, valueT val
)
252 /* Round .text section to a multiple of 2. */
253 if (seg
== text_section
)
254 return (val
+ 1) & ~1;
258 /* Parse an operand that is machine-specific (remove '*'). */
261 md_operand (expressionS
* exp
)
263 char c
= *input_line_pointer
;
268 input_line_pointer
++;
276 /* Reset global variables before parsing a new instruction. */
279 reset_vars (char *op
, ins
*crx_ins
)
283 processing_arg_number
= relocatable
= size_was_set
284 = signflag
= post_inc_mode
= cst4flag
= 0;
285 memset (&output_opcode
, '\0', sizeof (output_opcode
));
287 /* Memset the 'signflag' field in every argument. */
288 for (i
= 0; i
< MAX_OPERANDS
; i
++)
289 crx_ins
->arg
[i
].signflag
= 0;
291 /* Save a copy of the original OP (used in error messages). */
292 strcpy (ins_parse
, op
);
295 /* Generate a relocation entry for a fixup. */
298 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
302 reloc
= xmalloc (sizeof (arelent
));
303 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
304 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
305 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
306 reloc
->addend
= fixP
->fx_offset
;
308 if (fixP
->fx_subsy
!= NULL
)
309 /* We don't resolve difference expressions. */
310 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
311 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
312 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "0",
313 segment_name (fixP
->fx_addsy
314 ? S_GET_SEGMENT (fixP
->fx_addsy
)
316 S_GET_NAME (fixP
->fx_subsy
),
317 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
319 assert ((int) fixP
->fx_r_type
> 0);
320 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
322 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
324 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
325 _("internal error: reloc %d (`%s') not supported by object file format"),
327 bfd_get_reloc_code_name (fixP
->fx_r_type
));
330 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
335 /* Prepare machine-dependent frags for relaxation. */
338 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
340 /* If symbol is undefined or located in a different section,
341 select the largest supported relocation. */
342 relax_substateT subtype
;
343 relax_substateT rlx_state
[] = {0, 2,
347 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
349 if (fragp
->fr_subtype
== rlx_state
[subtype
]
350 && (!S_IS_DEFINED (fragp
->fr_symbol
)
351 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
353 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
358 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
361 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
365 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
367 /* 'opcode' points to the start of the instruction, whether
368 we need to change the instruction's fixed encoding. */
369 char *opcode
= fragP
->fr_literal
+ fragP
->fr_fix
;
370 bfd_reloc_code_real_type reloc
;
372 subseg_change (sec
, 0);
374 switch (fragP
->fr_subtype
)
377 reloc
= BFD_RELOC_CRX_REL8
;
381 reloc
= BFD_RELOC_CRX_REL16
;
385 reloc
= BFD_RELOC_CRX_REL32
;
388 reloc
= BFD_RELOC_CRX_REL16
;
392 reloc
= BFD_RELOC_CRX_REL32
;
395 reloc
= BFD_RELOC_CRX_REL8_CMP
;
399 reloc
= BFD_RELOC_CRX_REL24
;
406 fix_new (fragP
, fragP
->fr_fix
,
407 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
408 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
410 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
413 /* Process machine-dependent command line options. Called once for
414 each option on the command line that the machine-independent part of
415 GAS does not understand. */
418 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
423 /* Machine-dependent usage-output. */
426 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
431 /* Turn a string in input_line_pointer into a floating point constant
432 of type TYPE, and store the appropriate bytes in *LITP. The number
433 of LITTLENUMS emitted is stored in *SIZEP. An error message is
434 returned, or NULL on OK. */
437 md_atof (int type
, char *litP
, int *sizeP
)
440 LITTLENUM_TYPE words
[4];
456 return _("bad call to md_atof");
459 t
= atof_ieee (input_line_pointer
, type
, words
);
461 input_line_pointer
= t
;
465 if (! target_big_endian
)
467 for (i
= prec
- 1; i
>= 0; i
--)
469 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
475 for (i
= 0; i
< prec
; i
++)
477 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
485 /* Apply a fixS (fixup of an instruction or data that we didn't have
486 enough info to complete immediately) to the data in a frag.
487 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
488 relaxation of debug sections, this function is called only when
489 fixuping relocations of debug sections. */
492 md_apply_fix3 (fixS
*fixP
, valueT
*valP
, segT seg
)
495 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
498 switch (fixP
->fx_r_type
)
500 case BFD_RELOC_CRX_NUM8
:
501 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
503 case BFD_RELOC_CRX_NUM16
:
504 bfd_put_16 (stdoutput
, val
, buf
);
506 case BFD_RELOC_CRX_NUM32
:
507 bfd_put_32 (stdoutput
, val
, buf
);
510 /* We shouldn't ever get here because linkrelax is nonzero. */
517 if (fixP
->fx_addsy
== NULL
518 && fixP
->fx_pcrel
== 0)
521 if (fixP
->fx_pcrel
== 1
522 && fixP
->fx_addsy
!= NULL
523 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
527 /* The location from which a PC relative jump should be calculated,
528 given a PC relative reloc. */
531 md_pcrel_from (fixS
*fixp
)
533 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
536 /* This function is called once, at assembler startup time. This should
537 set up all the tables, etc that the MD part of the assembler needs. */
542 const char *hashret
= NULL
;
545 /* Set up a hash table for the instructions. */
546 crx_inst_hash
= hash_new ();
547 if (crx_inst_hash
== NULL
)
548 as_fatal (_("Virtual memory exhausted"));
550 while (crx_instruction
[i
].mnemonic
!= NULL
)
552 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
554 hashret
= hash_insert (crx_inst_hash
, mnemonic
,
555 (PTR
) &crx_instruction
[i
]);
557 if (hashret
!= NULL
&& *hashret
!= '\0')
558 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction
[i
].mnemonic
,
559 *hashret
== 0 ? _("(unknown reason)") : hashret
);
561 /* Insert unique names into hash table. The CRX instruction set
562 has many identical opcode names that have different opcodes based
563 on the operands. This hash table then provides a quick index to
564 the first opcode with a particular name in the opcode table. */
569 while (crx_instruction
[i
].mnemonic
!= NULL
570 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
573 /* Initialize reg_hash hash table. */
574 reg_hash
= hash_new ();
577 const reg_entry
*regtab
;
579 for (regtab
= crx_regtab
;
580 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
582 hashret
= hash_insert (reg_hash
, regtab
->name
, (PTR
) regtab
);
584 as_fatal (_("Internal Error: Can't hash %s: %s"),
590 /* Initialize copreg_hash hash table. */
591 copreg_hash
= hash_new ();
594 const reg_entry
*copregtab
;
596 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
599 hashret
= hash_insert (copreg_hash
, copregtab
->name
, (PTR
) copregtab
);
601 as_fatal (_("Internal Error: Can't hash %s: %s"),
606 /* Set linkrelax here to avoid fixups in most sections. */
610 /* Get the number of bits corresponding to a constant -
611 here we check for possible overflow cases. */
614 get_number_of_bits (ins
* crx_ins
, int op_num
)
617 unsigned long int temp
= crx_ins
->arg
[op_num
].constant
;
618 const cst4_entry
*cst4_op
;
620 /* If the constant's size was already set - nothing to do. */
624 /* Already dealt with negative numbers in process_label_constants. */
631 if (IS_INSN_TYPE (ARITH_INS
) && !relocatable
&& !signflag
)
635 crx_ins
->arg
[op_num
].size
= 17;
639 /* If a signed +ve is represented in 6 bits then we have to represent
640 it in 22 bits in case of the index mode of addressing. */
641 if (IS_INSN_TYPE (LD_STOR_INS
)
642 || IS_INSN_TYPE (LD_STOR_INS_INC
)
643 || IS_INSN_TYPE (STOR_IMM_INS
)
644 || IS_INSN_TYPE (CSTBIT_INS
))
646 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_icr
)
650 crx_ins
->arg
[op_num
].size
= 7;
654 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
657 /* If a signed +ve is represnted in 16 bits in case of load/stor disp16
658 then change it to 17 bits.
659 If a signed +ve is represnted in 12 bits in post increment instruction
660 increase it to 13 bits. */
661 if (IS_INSN_TYPE (LD_STOR_INS
))
663 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_cr
)
667 crx_ins
->arg
[op_num
].size
= 17;
671 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
675 if (IS_INSN_TYPE (CSTBIT_INS
)
676 || IS_INSN_TYPE (LD_STOR_INS_INC
)
677 || IS_INSN_TYPE (STOR_IMM_INS
))
679 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_cr
)
683 crx_ins
->arg
[op_num
].size
= 13;
684 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
685 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
688 if (IS_INSN_TYPE (CSTBIT_INS
) || IS_INSN_TYPE (STOR_IMM_INS
))
691 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
697 /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
698 if (signflag
&& !relocatable
699 && ((IS_INSN_TYPE (ARITH_INS
) || IS_INSN_TYPE (ARITH_BYTE_INS
))
700 || ((IS_INSN_TYPE (CMPBR_INS
) && op_num
== 0))))
702 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
); cst4_op
++)
704 if (crx_ins
->arg
[op_num
].constant
== (unsigned int)(-cst4_op
->value
))
706 crx_ins
->arg
[op_num
].size
= 4;
707 crx_ins
->arg
[op_num
].constant
= cst4_op
->binary
;
708 crx_ins
->arg
[op_num
].signflag
= 0;
713 /* Because of the cst4 mapping -- -1 and -4 already handled above
714 as well as for relocatable cases. */
715 if (signflag
&& IS_INSN_TYPE (ARITH_BYTE_INS
))
719 if (crx_ins
->arg
[op_num
].constant
<= 0xffff)
720 crx_ins
->arg
[op_num
].size
= 16;
722 /* Setting to 18 so that there is no match. */
723 crx_ins
->arg
[op_num
].size
= 18;
726 crx_ins
->arg
[op_num
].size
= 16;
730 if (signflag
&& IS_INSN_TYPE (ARITH_INS
))
732 /* For all immediates which can be expressed in less than 16 bits. */
733 if (crx_ins
->arg
[op_num
].constant
<= 0xffff && !relocatable
)
735 crx_ins
->arg
[op_num
].size
= 16;
738 /* Either it is relocatable or not representable in 16 bits. */
739 if (crx_ins
->arg
[op_num
].constant
< 0xffffffff || relocatable
)
741 crx_ins
->arg
[op_num
].size
= 32;
744 crx_ins
->arg
[op_num
].size
= 33;
747 if (signflag
&& !relocatable
)
751 crx_ins
->arg
[op_num
].size
= cnt_bits
;
753 /* Checking for Error Conditions. */
754 if (IS_INSN_TYPE (ARITH_INS
) && !signflag
)
757 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
758 cnt_bits
, ins_parse
);
760 else if (IS_INSN_TYPE (ARITH_BYTE_INS
) && !signflag
)
763 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
764 cnt_bits
, ins_parse
);
768 /* Handle the constants -immediate/absolute values and
769 Labels (jump targets/Memory locations). */
772 process_label_constant (char *str
, ins
* crx_ins
, int number
)
775 unsigned long int temp
, cnt
;
776 const cst4_entry
*cst4_op
;
778 int constant_val
= 0;
779 int cmp_br_type_flag
= 0, i
;
780 int br_type_flag
= 0;
781 save
= input_line_pointer
;
789 else if (str
[0] == '+')
792 /* Preprocessing for cmpbr instruction and getting the size flag. */
793 if (strstr (str
, ":s") != NULL
&& (IS_INSN_TYPE (CMPBR_INS
)
794 || IS_INSN_TYPE (COP_BRANCH_INS
)))
795 cmp_br_type_flag
= 8;
797 if (strstr (str
, ":l") != NULL
&& (IS_INSN_TYPE (CMPBR_INS
)
798 || IS_INSN_TYPE (COP_BRANCH_INS
)))
799 cmp_br_type_flag
= 24;
801 /* Branch instruction preprocessing. */
802 if (IS_INSN_TYPE (BRANCH_INS
))
804 if (strstr (str
, ":s") != NULL
)
806 else if (strstr (str
, ":m") != NULL
)
808 else if (strstr (str
, ":l") != NULL
)
811 /* Making the label cleared for processing removing :lms etc from labels. */
812 if (cmp_br_type_flag
!= 0 || br_type_flag
!= 0)
815 while (str
[i
] != ':')
821 input_line_pointer
= str
;
823 expression (&crx_ins
->exp
);
825 switch (crx_ins
->exp
.X_op
)
828 crx_ins
->arg
[number
].constant
= crx_ins
->exp
.X_add_number
;
829 constant_val
= crx_ins
->exp
.X_add_number
;
830 if ((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
833 /* This variable causes a warning (is to be handles by string
834 type implementation). */
839 unsigned int jump_value
= 0;
840 int BR_MASK
= 0, BR_SIZE
= 0;
847 strncat (temp_str
, str
, strlen (str
));
848 temp64
= strtol (temp_str
, (char **) &ptr
,0);
849 /* This is not accurate :
850 Actually overflow is allowed here (see comment below).
851 Originally the call was to 'strtoll', which isn't
852 identified by MSVC. */
853 if ((temp64
== LONG_MAX
) || (temp64
== LONG_MIN
))
854 as_bad (_("Overflow in displacement in Instruction `%s'"),
858 It will be returned as '0' padded with 'x' uptill 64 bits
860 It will be returned as sign extended form
862 Then search for validity of representation
863 Check whether upper 38 bits are all zeroes or all ones
864 If not report error. */
865 if (!(((temp64
& UPPER31_MASK
) == UPPER31_MASK
)
866 || ((temp64
& UPPER31_MASK
) == 0x0)))
867 as_bad (_("Overflow in displacement in Instruction `%s'"),
871 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
874 /* Determine the branch size. */
875 jump_value
= (unsigned int)temp64
& 0xFFFFFFFF;
876 if (((jump_value
& 0xFFFFFF00) == 0xFFFFFF00)
877 || ((jump_value
& 0xFFFFFF00) == 0x0))
883 if (((jump_value
& 0xFF000000) == 0xFF000000)
884 || ((jump_value
& 0xFF000000) == 0x0))
889 jump_value
= jump_value
>> 1;
890 crx_ins
->arg
[number
].constant
= jump_value
& BR_MASK
;
891 crx_ins
->arg
[number
].size
= BR_SIZE
;
893 crx_ins
->arg
[number
].signflag
= signflag
;
894 input_line_pointer
= save
;
895 return crx_ins
->exp
.X_op
;
898 if (IS_INSN_TYPE (BRANCH_INS
)
899 || IS_INSN_MNEMONIC ("bal")
900 || IS_INSN_TYPE (DCR_BRANCH_INS
))
905 unsigned int jump_value
= 0;
906 int BR_MASK
= 0, BR_SIZE
= 0;
914 strncat (temp_str
, str
, strlen (str
));
915 temp64
= strtol (temp_str
, (char **) &ptr
,0);
916 /* This is not accurate :
917 Actually overflow is allowed here (see comment below).
918 Originally the call was to 'strtoll', which isn't
919 identified by MSVC. */
920 if ((temp64
== LONG_MAX
) || (temp64
== LONG_MIN
))
921 as_bad (_("Overflow in displacement in Instruction `%s'"),
925 It will be returned as '0' padded with 'x' uptill 64 bits
927 It will be returned as sign extended form
929 Then search for validity of representation
930 Check whether upper 31 bits are all zeroes or all ones
931 If not report error. */
932 if (!(((temp64
& UPPER31_MASK
) == UPPER31_MASK
)
933 || ((temp64
& UPPER31_MASK
) == 0x0)))
934 as_bad (_("Overflow in displacement in Instruction `%s'"),
938 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
941 /* Determine the branch size. */
942 jump_value
= (unsigned int)temp64
& 0xFFFFFFFF;
943 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS
)
944 && (((jump_value
& 0xFFFFFF00) == 0xFFFFFF00)
945 || ((jump_value
& 0xFFFFFF00) == 0x0)))
951 if (((jump_value
& 0xFFFF0000) == 0xFFFF0000)
952 || ((jump_value
& 0xFFFF0000) == 0x0))
959 BR_MASK
= 0xFFFFFFFF;
962 jump_value
= jump_value
>> 1;
963 crx_ins
->arg
[number
].constant
= jump_value
& BR_MASK
;
964 crx_ins
->arg
[number
].size
= BR_SIZE
;
966 crx_ins
->arg
[number
].signflag
= signflag
;
967 input_line_pointer
= save
;
968 return crx_ins
->exp
.X_op
;
970 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
971 if (constant_val
< 0 && signflag
!= 1
972 && !IS_INSN_TYPE (LD_STOR_INS
) && !IS_INSN_TYPE (LD_STOR_INS_INC
)
973 && !IS_INSN_TYPE (CSTBIT_INS
) && !IS_INSN_TYPE (STOR_IMM_INS
)
974 && !IS_INSN_TYPE (BRANCH_INS
) && !IS_INSN_MNEMONIC ("bal"))
976 crx_ins
->arg
[number
].constant
=
977 ~(crx_ins
->arg
[number
].constant
) + 1;
980 /* For load/store instruction when the value is in the offset part. */
981 if (constant_val
< 0 && signflag
!= 1
982 && (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (LD_STOR_INS_INC
)
983 || IS_INSN_TYPE (CSTBIT_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)))
985 if (crx_ins
->arg
[number
].type
== arg_cr
986 || crx_ins
->arg
[number
].type
== arg_icr
)
988 crx_ins
->arg
[number
].constant
=
989 ~(crx_ins
->arg
[number
].constant
) + 1;
995 /* Signflag in never set in case of load store instructions
996 Mapping in case of only the arithinsn case. */
997 if ((crx_ins
->arg
[number
].constant
!= 1
998 && crx_ins
->arg
[number
].constant
!= 4)
999 || (!IS_INSN_TYPE (ARITH_INS
)
1000 && !IS_INSN_TYPE (ARITH_BYTE_INS
)
1001 && !IS_INSN_TYPE (CMPBR_INS
)))
1003 /* Counting the number of bits required to represent
1006 temp
= crx_ins
->arg
[number
].constant
- 1;
1012 crx_ins
->arg
[number
].size
= cnt
+ 1;
1013 crx_ins
->arg
[number
].constant
=
1014 ~(crx_ins
->arg
[number
].constant
) + 1;
1015 if (IS_INSN_TYPE (ARITH_INS
) || IS_INSN_TYPE (ARITH_BYTE_INS
))
1020 /* Tomer - Originally the call was to 'strtoull', which isn't
1021 identified by MSVC. Instead we check for overflow. */
1022 temp64
= strtoul (str
, (char **) &ptr
, 0);
1024 crx_ins
->arg
[number
].size
= 5;
1026 if (IS_INSN_TYPE (ARITH_INS
))
1028 if (crx_ins
->arg
[number
].size
> 32
1029 /* Tomer - check for overflow. */
1030 || (temp64
== ULONG_MAX
))
1032 if (crx_ins
->arg
[number
].size
> 32)
1033 as_bad (_("In Instruction `%s': Immediate size is \
1034 %lu bits cannot be accomodated"),
1035 ins_parse
, cnt
+ 1);
1037 /* Tomer - check for overflow. */
1038 if (temp64
== ULONG_MAX
)
1039 as_bad (_("Value given more than 32 bits in \
1040 Instruction `%s'"), ins_parse
);
1043 if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1045 if (crx_ins
->arg
[number
].size
> 16
1046 || !((temp64
& 0xFFFF0000) == 0xFFFF0000
1047 || (temp64
& 0xFFFF0000) == 0x0))
1049 if (crx_ins
->arg
[number
].size
> 16)
1050 as_bad (_("In Instruction `%s': Immediate size is \
1051 %lu bits cannot be accomodated"),
1052 ins_parse
, cnt
+ 1);
1054 if (!((temp64
& 0xFFFF0000) == 0xFFFF0000
1055 || (temp64
& 0xFFFF0000) == 0x0))
1056 as_bad (_("Value given more than 16 bits in \
1057 Instruction `%s'"), ins_parse
);
1061 if (IS_INSN_TYPE (LD_STOR_INS
) && crx_ins
->arg
[number
].type
== arg_cr
1064 /* Cases handled ---
1065 dispub4/dispuw4/dispud4 and for load store dispubwd4
1066 is applicable only. */
1067 if (crx_ins
->arg
[number
].size
<= 4)
1068 crx_ins
->arg
[number
].size
= 5;
1070 /* Argument number is checked to distinguish between
1071 immediate and displacement in cmpbranch and bcopcond. */
1072 if ((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1075 if (crx_ins
->arg
[number
].size
!= 32)
1076 crx_ins
->arg
[number
].constant
=
1077 crx_ins
->arg
[number
].constant
>> 1;
1080 mask_const (&crx_ins
->arg
[number
].constant
,
1081 (int) crx_ins
->arg
[number
].size
);
1086 /* Argument number is checked to distinguish between
1087 immediate and displacement in cmpbranch and bcopcond. */
1088 if (((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1090 || IS_INSN_TYPE (BRANCH_NEQ_INS
))
1092 if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1094 if (crx_ins
->arg
[number
].constant
== 0)
1095 as_bad (_("Instruction `%s' has Zero offset"), ins_parse
);
1098 if (crx_ins
->arg
[number
].constant
% 2 != 0)
1099 as_bad (_("Instruction `%s' has odd offset"), ins_parse
);
1101 if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1103 if (crx_ins
->arg
[number
].constant
> 32
1104 || crx_ins
->arg
[number
].constant
< 2)
1105 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1106 ins_parse
, crx_ins
->arg
[number
].constant
);
1108 crx_ins
->arg
[number
].constant
-= 2;
1111 crx_ins
->arg
[number
].constant
=
1112 crx_ins
->arg
[number
].constant
>> 1;
1113 get_number_of_bits (crx_ins
, number
);
1116 /* Compare branch argument number zero to be compared -
1118 if (IS_INSN_TYPE (CMPBR_INS
) && number
== 0)
1120 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
); cst4_op
++)
1122 if (crx_ins
->arg
[number
].constant
== (unsigned int)cst4_op
->value
)
1124 crx_ins
->arg
[number
].constant
= cst4_op
->binary
;
1130 as_bad (_("Instruction `%s' has invalid imm value as an \
1131 operand"), ins_parse
);
1138 crx_ins
->arg
[number
].constant
= 0;
1141 switch (crx_ins
->arg
[number
].type
)
1144 /* Have to consider various cases here --load/stor++[bwd] rbase, reg. */
1145 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1146 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
1147 else if (IS_INSN_TYPE (CSTBIT_INS
)
1148 || IS_INSN_TYPE (STOR_IMM_INS
))
1149 /* 'stor[bwd] imm' and '[stc]bit[bwd]'. */
1150 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
1152 /* General load store instruction. */
1153 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
1156 /* Index Mode 22 bits relocation. */
1157 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
1160 /* Absolute types. */
1161 /* Case for jumps...dx types. */
1163 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
1164 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
1165 else if (IS_INSN_TYPE (BRANCH_INS
))
1167 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
1169 /* Overriding the above by the br_type_flag set above. */
1170 switch (br_type_flag
)
1175 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
1178 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
1181 crx_ins
->rtype
= BFD_RELOC_CRX_REL32
;
1185 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
1186 || IS_INSN_TYPE (CSTBIT_INS
))
1187 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
1188 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1189 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
1190 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1192 if (cmp_br_type_flag
== 24)
1193 crx_ins
->rtype
= BFD_RELOC_CRX_REL24
;
1195 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
1200 if (IS_INSN_TYPE (ARITH_INS
))
1201 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
1202 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1203 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
1208 crx_ins
->arg
[number
].size
= (bfd_reloc_type_lookup (stdoutput
, crx_ins
->rtype
))->bitsize
;
1215 input_line_pointer
= save
;
1216 crx_ins
->arg
[number
].signflag
= signflag
;
1217 return crx_ins
->exp
.X_op
;
1220 /* Get the values of the scale to be encoded -
1221 used for the scaled index mode of addressing. */
1224 exponent2scale (int val
)
1228 /* If 'val' is 0, the following 'for' will be an endless loop. */
1232 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
1238 /* This is used to set the index mode parameters. Used to set the attributes of
1239 an indexmode type of operand. op_num is the operand number. */
1242 set_indexmode_parameters (char *operand
, ins
* crx_ins
, int op_num
)
1244 char address_str
[30];
1245 char scale_str
[MAX_OPERANDS
];
1247 char reg_name
[MAX_REGNAME_LEN
];
1248 char regindex_name
[MAX_REGNAME_LEN
];
1250 int reg_counter
= 0, addr_cnt
= 0, temp_int_val
= 0;
1252 switch (crx_ins
->arg
[op_num
].type
)
1255 while (operand
[i
] != '(')
1257 address_str
[addr_cnt
++] = operand
[i
];
1260 address_str
[addr_cnt
] = '\0';
1261 process_label_constant (address_str
, crx_ins
, op_num
);
1264 while (operand
[i
] != ',' && operand
[i
] != ' ')
1266 reg_name
[reg_counter
++] = operand
[i
];
1269 reg_name
[reg_counter
] = '\0';
1270 if ((crx_ins
->arg
[op_num
].r
= get_register (reg_name
)) == nullregister
)
1271 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1272 reg_name
, ins_parse
);
1275 while (operand
[i
] == ' ')
1279 while (operand
[i
] != ')' && operand
[i
] != ',')
1281 regindex_name
[reg_counter
++] = operand
[i
];
1284 regindex_name
[reg_counter
] = '\0';
1286 if ((crx_ins
->arg
[op_num
].i_r
= get_register (regindex_name
))
1288 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1289 regindex_name
, ins_parse
);
1291 /* Setting the scale parameters. */
1292 while (operand
[i
] == ' ')
1295 if (operand
[i
] == ')')
1296 crx_ins
->arg
[op_num
].scale
= 0;
1299 if (operand
[i
] == ',')
1302 while (operand
[i
] != ' ' && operand
[i
] != ')')
1304 scale_str
[scale_cnt
++] = operand
[i
];
1308 scale_str
[scale_cnt
] = '\0';
1309 /* Preprocess the scale string. */
1310 if (strstr (scale_str
, "0x") != NULL
1311 || strstr (scale_str
, "0X") != NULL
)
1313 sscanf (scale_str
, "%x", &temp_int_val
);
1314 memset (&scale_str
, '\0', sizeof (scale_str
));
1315 sprintf (scale_str
, "%d", temp_int_val
);
1317 /* Preprocess over. */
1318 temp_int_val
= atoi (scale_str
);
1320 if (temp_int_val
!= 1 && temp_int_val
!= 2
1321 && temp_int_val
!= 4 && temp_int_val
!= 8)
1322 as_bad (_("Illegal Scale - `%s'"), scale_str
);
1324 crx_ins
->arg
[op_num
].scale
= exponent2scale (temp_int_val
);
1332 /* Parsing the operands of types
1334 - rbase -> (register)
1336 - offset(rbase)+ - post increment mode. */
1339 set_cons_rparams (char *operand
, ins
* crx_ins
, int op_num
)
1341 int i
= 0, reg_count
= 0;
1342 char reg_name
[MAX_REGNAME_LEN
];
1343 int change_flag
= 0;
1345 if (crx_ins
->arg
[op_num
].type
== arg_dc
)
1348 switch (crx_ins
->arg
[op_num
].type
)
1350 case arg_sc
: /* Case *+347. */
1351 case arg_dc
: /* Case $18. */
1353 case arg_c
:/* Case where its a simple constant. */
1354 process_label_constant (operand
+ i
, crx_ins
, op_num
);
1355 crx_ins
->arg
[op_num
].type
= arg_c
;
1357 case arg_dcr
: /* Case $9(r13). */
1359 case arg_cr
: /* Case 9(r13. */
1360 while (operand
[i
] != '(')
1363 process_label_constant (operand
, crx_ins
, op_num
);
1367 while (operand
[i
] != ')')
1369 reg_name
[reg_count
] = operand
[i
];
1373 reg_name
[reg_count
] = '\0';
1374 if ((crx_ins
->arg
[op_num
].r
= get_register (reg_name
)) == nullregister
)
1375 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1376 reg_name
, ins_parse
);
1378 crx_ins
->arg
[op_num
].type
= arg_cr
;
1379 /* Post increment is represented in assembly as offset (register)+. */
1380 if (strstr (operand
+ i
, "+") != NULL
)
1381 /* There is a plus after the ')'. */
1387 if (change_flag
== 1)
1388 crx_ins
->arg
[op_num
].type
= arg_ic
;
1391 /* This is used to get the operand attributes -
1392 operand - current operand to be used
1393 number - operand number
1394 crx_ins - current assembled instruction. */
1397 get_operandtype (char *operand
, int number
, ins
* crx_ins
)
1400 char temp_operand
[30];
1404 /* When it is a register. */
1413 /* Check whether this is a general processor register. */
1414 ret_val
= get_register (operand
);
1415 if (ret_val
!= nullregister
)
1417 crx_ins
->arg
[number
].type
= arg_r
;
1418 crx_ins
->arg
[number
].r
= ret_val
;
1419 crx_ins
->arg
[number
].size
= REG_SIZE
;
1423 /* Check whether this is a core [special] coprocessor register. */
1424 ret_val
= get_copregister (operand
);
1425 if (ret_val
!= nullcopregister
)
1427 crx_ins
->arg
[number
].type
= arg_copr
;
1429 crx_ins
->arg
[number
].type
= arg_copsr
;
1430 crx_ins
->arg
[number
].cr
= ret_val
;
1431 crx_ins
->arg
[number
].size
= REG_SIZE
;
1435 if (strchr (operand
, '(') != NULL
)
1437 if (strchr (operand
, ',') != NULL
1438 && (strchr (operand
, ',') > strchr (operand
, '(')))
1440 crx_ins
->arg
[number
].type
= arg_icr
;
1441 crx_ins
->arg
[number
].constant
= 0;
1442 set_indexmode_parameters (operand
, crx_ins
, number
);
1443 get_number_of_bits (crx_ins
, number
);
1447 crx_ins
->arg
[number
].type
= arg_cr
;
1450 crx_ins
->arg
[number
].type
= arg_c
;
1451 crx_ins
->arg
[number
].constant
= 0;
1452 set_cons_rparams (operand
, crx_ins
, number
);
1453 get_number_of_bits (crx_ins
, number
);
1458 if (strchr (operand
, '(') != NULL
)
1459 crx_ins
->arg
[number
].type
= arg_dcr
;
1461 crx_ins
->arg
[number
].type
= arg_dc
;
1462 crx_ins
->arg
[number
].constant
= 0;
1463 set_cons_rparams (operand
, crx_ins
, number
);
1464 get_number_of_bits (crx_ins
, number
);
1468 /* Augmenting a zero in front of an operand -- won't work for tbit/sbit. */
1469 strcpy (temp_operand
, "0");
1470 strcat (temp_operand
, operand
);
1471 if (strchr (temp_operand
, ',') != NULL
1472 && (strchr (temp_operand
, ',') > strchr (temp_operand
, '(')))
1474 crx_ins
->arg
[number
].type
= arg_icr
;
1475 crx_ins
->arg
[number
].constant
= 0;
1476 set_indexmode_parameters (temp_operand
, crx_ins
, number
);
1477 get_number_of_bits (crx_ins
, number
);
1482 crx_ins
->arg
[number
].type
= arg_cr
;
1483 crx_ins
->arg
[number
].constant
= 0;
1484 set_cons_rparams (operand
, crx_ins
, number
);
1485 get_number_of_bits (crx_ins
, number
);
1486 if ((! strneq (instruction
->mnemonic
, "load", 4))
1487 && (! strneq (instruction
->mnemonic
, "stor", 4)))
1489 crx_ins
->arg
[number
].type
= arg_rbase
;
1490 crx_ins
->arg
[number
].size
= REG_SIZE
;
1496 crx_ins
->arg
[number
].type
= arg_sc
;
1497 crx_ins
->arg
[number
].constant
= 0;
1498 set_cons_rparams (operand
, crx_ins
, number
);
1499 get_number_of_bits (crx_ins
, number
);
1513 if (strchr (operand
, '(') != NULL
)
1515 if (strchr (operand
, ',') != NULL
1516 && (strchr (operand
, ',') > strchr (operand
, '(')))
1518 crx_ins
->arg
[number
].type
= arg_icr
;
1519 crx_ins
->arg
[number
].constant
= 0;
1520 set_indexmode_parameters (operand
, crx_ins
, number
);
1521 get_number_of_bits (crx_ins
, number
);
1525 crx_ins
->arg
[number
].type
= arg_cr
;
1528 crx_ins
->arg
[number
].type
= arg_c
;
1529 crx_ins
->arg
[number
].constant
= 0;
1530 set_cons_rparams (operand
, crx_ins
, number
);
1531 get_number_of_bits (crx_ins
, number
);
1534 if (strchr (operand
, '(') != NULL
)
1536 if (strchr (operand
, ',') != NULL
1537 && (strchr (operand
, ',') > strchr (operand
, '(')))
1539 crx_ins
->arg
[number
].type
= arg_icr
;
1540 crx_ins
->arg
[number
].constant
= 0;
1541 set_indexmode_parameters (operand
, crx_ins
, number
);
1542 get_number_of_bits (crx_ins
, number
);
1546 crx_ins
->arg
[number
].type
= arg_cr
;
1549 crx_ins
->arg
[number
].type
= arg_c
;
1550 crx_ins
->arg
[number
].constant
= 0;
1551 set_cons_rparams (operand
, crx_ins
, number
);
1552 get_number_of_bits (crx_ins
, number
);
1557 /* Operands are parsed over here, separated into various operands. Each operand
1558 is then analyzed to fillup the fields in the crx_ins data structure. */
1561 parse_operands (ins
* crx_ins
, char *operands
)
1563 char *operandS
; /* Operands string. */
1564 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
1565 int allocated
= 0; /* Indicates a new operands string was allocated. */
1566 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
1567 int op_num
= 0; /* Current operand number we are parsing. */
1568 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
1569 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
1571 /* Preprocess the list of registers, if necessary. */
1572 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
1573 preprocess_reglist (operands
, &allocated
) : operands
;
1575 while (*operandT
!= '\0')
1577 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
1580 operand
[op_num
++] = strdup (operandH
);
1581 operandH
= operandT
;
1585 if (*operandT
== ' ')
1586 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
1588 if (*operandT
== '(')
1590 else if (*operandT
== '[')
1591 sq_bracket_flag
= 1;
1593 if (*operandT
== ')')
1598 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1600 else if (*operandT
== ']')
1602 if (sq_bracket_flag
)
1603 sq_bracket_flag
= 0;
1605 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1608 if (bracket_flag
== 1 && *operandT
== ')')
1610 else if (sq_bracket_flag
== 1 && *operandT
== ']')
1611 sq_bracket_flag
= 0;
1616 /* Adding the last operand. */
1617 operand
[op_num
++] = strdup (operandH
);
1618 crx_ins
->nargs
= op_num
;
1620 /* Verifying correct syntax of operands (all brackets should be closed). */
1621 if (bracket_flag
|| sq_bracket_flag
)
1622 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1624 /* Now to recongnize the operand types. */
1625 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
1627 get_operandtype (operand
[op_num
], op_num
, crx_ins
);
1628 free (operand
[op_num
]);
1635 /* Get the trap index in dispatch table, given its name.
1636 This routine is used by assembling the 'excp' instruction. */
1641 const trap_entry
*trap
;
1643 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
1644 if (streq (trap
->name
, s
))
1647 as_bad (_("Unknown exception: `%s'"), s
);
1651 /* Post-Increment instructions are a sub-group within load/stor instruction
1652 groups. Therefore, when parsing a Post-Increment insn, we have to advance
1653 the instruction pointer to the start of that sub-group. */
1656 handle_pi_insn (char *operands
)
1658 /* Assuming Post-Increment insn has the following format :
1659 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6'). */
1660 if (strstr (operands
, ")+") != NULL
)
1661 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1665 /* Top level module where instruction parsing starts.
1666 crx_ins - data structure holds some information.
1667 operands - holds the operands part of the whole instruction. */
1670 parse_insn (ins
*insn
, char *operands
)
1672 /* Handle 'excp'/'cinv' */
1673 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1676 insn
->arg
[0].type
= arg_ic
;
1677 insn
->arg
[0].size
= 4;
1678 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1679 gettrap (operands
) : get_cinv_parameters (operands
);
1683 /* Handle load/stor post-increment instructions. */
1684 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
))
1685 handle_pi_insn (operands
);
1687 if (operands
!= NULL
)
1688 parse_operands (insn
, operands
);
1691 /* Cinv instruction requires special handling. */
1694 get_cinv_parameters (char * operand
)
1697 int d_used
= 0, i_used
= 0, u_used
= 0;
1701 if (*p
== ',' || *p
== ' ')
1711 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1714 return ((d_used
? 4 : 0)
1716 + (u_used
? 1 : 0));
1719 /* Retrieve the opcode image of a given register.
1720 If the register is illegal for the current instruction,
1724 getreg_image (reg r
)
1726 const reg_entry
*reg
;
1728 int special_register_flag
= 0;
1729 int movpr_flag
= 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1731 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1734 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number
== 1))
1735 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number
== 0)) )
1736 special_register_flag
= 1;
1738 /* Check whether the register is in registers table. */
1740 reg
= &crx_regtab
[r
];
1741 /* Check whether the register is in coprocessor registers table. */
1742 else if (r
< MAX_COPREG
)
1743 reg
= &crx_copregtab
[r
-MAX_REG
];
1744 /* Register not found. */
1747 as_bad (_("Unknown register: `%d'"), r
);
1751 reg_name
= reg
->name
;
1753 /* Issue a error message when register is illegal. */
1755 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1756 reg_name, ins_parse); \
1762 case CRX_CFG_REGTYPE
:
1763 case CRX_MTPR_REGTYPE
:
1764 if (movpr_flag
&& special_register_flag
)
1771 case CRX_CS_REGTYPE
:
1772 if (!(movpr_flag
&& special_register_flag
))
1784 /* Routine used to get the binary-string equivalent of a integer constant
1785 which currently require currbits to represent itself to be extended to
1788 static unsigned long int
1789 getconstant (unsigned long int x
, int nbits
)
1792 unsigned long int temp
= x
;
1800 /* Escape sequence to next 16bit immediate. */
1802 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1807 x
|= SET_BITS_MASK (cnt
, nbits
- cnt
);
1809 x
&= CLEAR_BITS_MASK (cnt
, nbits
- cnt
);
1812 /* The following expression avoids overflow if
1813 'nbits' is the number of bits in 'bfd_vma'. */
1814 return (x
& ((((1 << (nbits
- 1)) - 1) << 1) | 1));
1817 /* Print a constant value to 'output_opcode':
1818 ARG holds the operand's type and value.
1819 SHIFT represents the location of the operand to be print into.
1820 NBITS determines the size (in bits) of the constant. */
1823 print_constant (int nbits
, int shift
, argument
*arg
)
1825 unsigned long mask
= 0;
1827 long constant
= getconstant (arg
->constant
, nbits
);
1835 /* mask the upper part of the constant, that is, the bits
1836 going to the lowest byte of output_opcode[0].
1837 The upper part of output_opcode[1] is always filled,
1838 therefore it is always masked with 0xFFFF. */
1839 mask
= (1 << (nbits
- 16)) - 1;
1840 /* Divide the constant between two consecutive words :
1842 +---------+---------+---------+---------+
1843 | | X X X X | X X X X | |
1844 +---------+---------+---------+---------+
1845 output_opcode[0] output_opcode[1] */
1847 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1848 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1853 /* Special case - in arg_cr, the SHIFT represents the location
1854 of the REGISTER, not the constant, which is itself not shifted. */
1855 if (arg
->type
== arg_cr
)
1857 CRX_PRINT (0, constant
, 0);
1861 /* When instruction size is 3, a 16-bit constant is always
1862 filling the upper part of output_opcode[1]. */
1863 if (instruction
->size
> 2)
1864 CRX_PRINT (1, constant
, WORD_SHIFT
);
1866 CRX_PRINT (0, constant
, shift
);
1870 CRX_PRINT (0, constant
, shift
);
1875 /* Print an operand to 'output_opcode', which later on will be
1876 printed to the object file:
1877 ARG holds the operand's type, size and value.
1878 SHIFT represents the printing location of operand.
1879 NBITS determines the size (in bits) of a constant operand. */
1882 print_operand (int nbits
, int shift
, argument
*arg
)
1887 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1891 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1892 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1894 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1898 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1899 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1901 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1905 print_constant (nbits
, shift
, arg
);
1910 +--------------------------------+
1911 | reg | r_base | scl| disp |
1912 +--------------------------------+ */
1913 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1914 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1915 CRX_PRINT (0, arg
->scale
, 6);
1916 print_constant (nbits
, shift
, arg
);
1920 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1924 /* case base_cst4. */
1925 if ((instruction
->flags
& CST4MAP
) && cst4flag
)
1926 output_opcode
[0] |= (getconstant (arg
->constant
, nbits
)
1927 << (shift
+ REG_SIZE
));
1929 /* rbase_dispu<NN> and other such cases. */
1930 print_constant (nbits
, shift
, arg
);
1931 /* Add the register argument to the output_opcode. */
1932 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1936 print_constant (nbits
, shift
, arg
);
1944 /* Retrieve the number of operands for the current assembled instruction. */
1947 get_number_of_operands (void)
1951 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1956 /* Assemble a single instruction :
1957 Instruction has been parsed and all operand values set appropriately.
1958 Algorithm for assembling -
1959 For instruction to be assembled:
1960 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1961 Step 2: Find instruction with same operand types.
1962 Step 3: If (size_of_operands) match then done, else increment the
1963 array_index and goto Step3.
1964 Step 4: Cannot assemble
1965 Returns 1 upon success, 0 upon failure. */
1968 assemble_insn (char *mnemonic
, ins
*insn
)
1970 /* Argument type of each operand in the instruction we are looking for. */
1971 argtype atyp
[MAX_OPERANDS
];
1972 /* Argument type of each operand in the current instruction. */
1973 argtype atyp_act
[MAX_OPERANDS
];
1974 /* Size (in bits) of each operand in the instruction we are looking for. */
1975 int bits
[MAX_OPERANDS
];
1976 /* Size (in bits) of each operand in the current instruction. */
1977 int bits_act
[MAX_OPERANDS
];
1978 /* Location (in bits) of each operand in the current instruction. */
1979 int shift_act
[MAX_OPERANDS
];
1982 int cst4maptype
= 0;
1983 int changed_already
= 0;
1984 unsigned int temp_value
= 0;
1986 /* A pointer to the argument's constant value. */
1987 unsigned long int *cons
;
1988 /* Pointer to loop over all cst4_map entries. */
1989 const cst4_entry
*cst4_op
;
1991 /* Instruction has no operands -> copy only the constant opcode. */
1992 if (insn
->nargs
== 0)
1994 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1998 /* Find instruction with same number of operands. */
1999 while (get_number_of_operands () != insn
->nargs
2000 && IS_INSN_MNEMONIC (mnemonic
))
2003 if (!IS_INSN_MNEMONIC (mnemonic
))
2006 /* Initialize argument type and size of each given operand. */
2007 for (i
= 0; i
< insn
->nargs
; i
++)
2009 atyp
[i
] = insn
->arg
[i
].type
;
2010 bits
[i
] = insn
->arg
[i
].size
;
2013 /* Initialize argument type and size of each operand in current inst. */
2018 /* Check we didn't get to end of table. */
2019 && instruction
->mnemonic
!= NULL
2020 /* Check that the actual mnemonic is still available. */
2021 && IS_INSN_MNEMONIC (mnemonic
))
2023 /* Check for argement type compatibility. */
2024 for (i
= 0; i
< insn
->nargs
; i
++)
2026 if (atyp_act
[i
] == atyp
[i
])
2036 /* Check for post inc mode of the current instruction. */
2037 if (post_inc_mode
== 1 || IS_INSN_TYPE (LD_STOR_INS_INC
))
2038 done_flag
= (post_inc_mode
== IS_INSN_TYPE (LD_STOR_INS_INC
));
2043 /* Try again with next instruction. */
2051 /* Check for size compatibility. */
2052 for (i
= 0; i
< insn
->nargs
; i
++)
2054 if (bits
[i
] > bits_act
[i
])
2056 /* Actual size is too small - try again. */
2069 /* Full match is found. */
2076 /* We haven't found a match - instruction can't be assembled. */
2079 /* Full match - print the final image. */
2081 /* Handle positive constants. */
2084 if (IS_INSN_TYPE (LD_STOR_INS
) && !relocatable
)
2086 /* Get the map type of the instruction. */
2087 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2088 cons
= &insn
->arg
[instrtype
].constant
;
2089 cst4maptype
= instruction
->flags
& CST4MAP
;
2091 switch (cst4maptype
)
2094 /* 14 and 15 are reserved escape sequences of dispub4. */
2095 if (*cons
== 14 || *cons
== 15)
2103 /* Mapping has to be done. */
2104 if (*cons
<= 15 && *cons
% 2 != 0)
2109 else if (*cons
> 15 && *cons
< 27 && *cons
% 2 == 0)
2114 if (*cons
< 27 && *cons
% 2 == 0)
2119 /* Mapping has to be done. */
2120 if (*cons
<= 15 && *cons
% 4 != 0)
2125 else if (*cons
> 15 && *cons
< 53 && *cons
% 4 == 0)
2130 if (*cons
< 53 && *cons
% 4 == 0)
2137 if ((IS_INSN_TYPE (ARITH_BYTE_INS
) || IS_INSN_TYPE (ARITH_INS
))
2140 /* Check whether a cst4 mapping has to be done. */
2141 if ((instruction
->operands
[0].op_type
== cst4
2142 || instruction
->operands
[0].op_type
== i16
)
2143 && (instruction
->operands
[1].op_type
== regr
))
2145 /* 'const' equals reserved escape sequences -->>
2146 represent as i16. */
2147 if (insn
->arg
[0].constant
== ESC_16
2148 || insn
->arg
[0].constant
== ESC_32
)
2155 /* Loop over cst4_map entries. */
2156 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
);
2159 /* 'const' equals a binary, which is already mapped
2160 by a different value -->> represent as i16. */
2161 if (insn
->arg
[0].constant
== (unsigned int)cst4_op
->binary
2162 && cst4_op
->binary
!= cst4_op
->value
)
2167 /* 'const' equals a value bigger than 16 -->> map to
2168 its binary and represent as cst4. */
2169 else if (insn
->arg
[0].constant
== (unsigned int)cst4_op
->value
2170 && insn
->arg
[0].constant
>= 16)
2173 insn
->arg
[0].constant
= cst4_op
->binary
;
2179 /* Special check for 'addub 0, r0' instruction -
2180 The opcode '0000 0000 0000 0000' is not allowed. */
2181 if (IS_INSN_MNEMONIC ("addub"))
2183 if ((instruction
->operands
[0].op_type
== cst4
)
2184 && instruction
->operands
[1].op_type
== regr
)
2186 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
2191 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
2192 || IS_INSN_TYPE (LD_STOR_INS_INC
))
2194 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2195 if (instruction
->operands
[instrtype
].op_type
== rbase
)
2198 /* Error checking in case of post-increment instruction. */
2199 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
2201 if (!((strneq (instruction
->mnemonic
, "stor", 4))
2202 && (insn
->arg
[0].type
!= arg_r
)))
2203 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
2204 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2205 same in Post INC mode"), ins_parse
);
2207 if (IS_INSN_TYPE (CSTBIT_INS
) && !relocatable
)
2209 if (instruction
->operands
[1].op_type
== rbase_dispu12
)
2211 if (insn
->arg
[1].constant
== 0)
2218 if ((IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
)
2219 || IS_INSN_TYPE (STOR_IMM_INS
)
2220 || IS_INSN_TYPE (LD_STOR_INS_INC
)) & !relocatable
)
2222 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2223 changed_already
= 0;
2224 /* Convert 32 bits accesses to 16 bits accesses. */
2225 if (instruction
->operands
[instrtype
].op_type
== abs32
)
2227 if ((insn
->arg
[instrtype
].constant
& 0xFFFF0000) == 0xFFFF0000)
2230 insn
->arg
[instrtype
].constant
=
2231 insn
->arg
[instrtype
].constant
& 0xFFFF;
2232 insn
->arg
[instrtype
].size
= 16;
2233 changed_already
= 1;
2237 /* Convert 16 bits accesses to 32 bits accesses. */
2238 if (instruction
->operands
[instrtype
].op_type
== abs16
2239 && changed_already
!= 1)
2242 insn
->arg
[instrtype
].constant
=
2243 insn
->arg
[instrtype
].constant
& 0xFFFF;
2244 insn
->arg
[instrtype
].size
= 32;
2247 changed_already
= 0;
2249 if (IS_INSN_TYPE (BRANCH_INS
) && !relocatable
)
2251 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2252 if (insn
->arg
[0].constant
== 0x7e || insn
->arg
[0].constant
== 0x7f)
2260 for (i
= 0; i
< insn
->nargs
; i
++)
2262 if (instruction
->operands
[i
].op_type
== cst4
2263 || instruction
->operands
[i
].op_type
== rbase_cst4
)
2267 /* First, copy the instruction's opcode. */
2268 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2270 /* Swap the argument values in case bcop instructions. */
2271 if (IS_INSN_TYPE (COP_BRANCH_INS
))
2273 temp_value
= insn
->arg
[0].constant
;
2274 insn
->arg
[0].constant
= insn
->arg
[1].constant
;
2275 insn
->arg
[1].constant
= temp_value
;
2278 for (i
= 0; i
< insn
->nargs
; i
++)
2280 shift_act
[i
] = instruction
->operands
[i
].shift
;
2281 signflag
= insn
->arg
[i
].signflag
;
2282 processing_arg_number
= i
;
2283 print_operand (bits_act
[i
], shift_act
[i
], &insn
->arg
[i
]);
2290 /* Set the appropriate bit for register 'r' in 'mask'.
2291 This indicates that this register is loaded or stored by
2295 mask_reg (int r
, unsigned short int *mask
)
2297 if ((reg
)r
> (reg
)sp
)
2299 as_bad (_("Invalid Register in Register List"));
2306 /* Preprocess register list - create a 16-bit mask with one bit for each
2307 of the 16 general purpose registers. If a bit is set, it indicates
2308 that this register is loaded or stored by the instruction. */
2311 preprocess_reglist (char *param
, int *allocated
)
2313 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
2314 char *regP
; /* Pointer to 'reg_name' string. */
2315 int reg_counter
= 0; /* Count number of parsed registers. */
2316 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
2317 char *new_param
; /* New created operands string. */
2318 char *paramP
= param
; /* Pointer to original opearands string. */
2319 char maskstring
[10]; /* Array to print the mask as a string. */
2323 /* If 'param' is already in form of a number, no need to preprocess. */
2324 if (strchr (paramP
, '{') == NULL
)
2327 /* Verifying correct syntax of operand. */
2328 if (strchr (paramP
, '}') == NULL
)
2329 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
2331 while (*paramP
++ != '{');
2333 new_param
= (char *)xcalloc (MAX_INST_LEN
, sizeof (char));
2335 strncpy (new_param
, param
, paramP
- param
- 1);
2337 while (*paramP
!= '}')
2340 memset (®_name
, '\0', sizeof (reg_name
));
2342 while (ISALNUM (*paramP
))
2345 strncpy (reg_name
, regP
, paramP
- regP
);
2347 if (IS_INSN_TYPE (COP_REG_INS
))
2349 if ((cr
= get_copregister (reg_name
)) == nullcopregister
)
2350 as_bad (_("Illegal register `%s' in cop-register list"), reg_name
);
2351 mask_reg (getreg_image (cr
- c0
), &mask
);
2355 if ((r
= get_register (reg_name
)) == nullregister
)
2356 as_bad (_("Illegal register `%s' in register list"), reg_name
);
2357 mask_reg (getreg_image (r
), &mask
);
2360 if (++reg_counter
> MAX_REGS_IN_MASK16
)
2361 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2362 MAX_REGS_IN_MASK16
);
2364 while (!ISALNUM (*paramP
) && *paramP
!= '}')
2368 if (*++paramP
!= '\0')
2369 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2373 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2376 sprintf (maskstring
, "$0x%x", mask
);
2377 strcat (new_param
, maskstring
);
2381 /* Print the instruction.
2382 Handle also cases where the instruction is relaxable/relocatable. */
2385 print_insn (ins
*insn
)
2387 unsigned int i
, j
, insn_size
;
2389 unsigned short words
[4];
2391 /* Arrange the insn encodings in a WORD size array. */
2392 for (i
= 0, j
= 0; i
< 2; i
++)
2394 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
2395 words
[j
++] = output_opcode
[i
] & 0xFFFF;
2398 /* Handle relaxtion. */
2399 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
2403 /* Write the maximal instruction size supported. */
2404 insn_size
= INSN_MAX_SIZE
;
2407 if (IS_INSN_TYPE (BRANCH_INS
))
2410 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
2413 else if (IS_INSN_TYPE (CMPBR_INS
))
2418 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
2420 insn
->exp
.X_add_symbol
,
2421 insn
->exp
.X_add_number
,
2426 insn_size
= instruction
->size
;
2427 this_frag
= frag_more (insn_size
* 2);
2429 /* Handle relocation. */
2430 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
2432 reloc_howto_type
*reloc_howto
;
2435 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
2440 size
= bfd_get_reloc_size (reloc_howto
);
2442 if (size
< 1 || size
> 4)
2445 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
2446 size
, &insn
->exp
, reloc_howto
->pc_relative
,
2451 /* Write the instruction encoding to frag. */
2452 for (i
= 0; i
< insn_size
; i
++)
2454 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
2459 /* This is the guts of the machine-dependent assembler. OP points to a
2460 machine dependent instruction. This function is supposed to emit
2461 the frags/bytes it assembles to. */
2464 md_assemble (char *op
)
2470 /* Reset global variables for a new instruction. */
2471 reset_vars (op
, &crx_ins
);
2473 /* Strip the mnemonic. */
2474 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
2479 /* Find the instruction. */
2480 instruction
= (const inst
*) hash_find (crx_inst_hash
, op
);
2481 if (instruction
== NULL
)
2483 as_bad (_("Unknown opcode: `%s'"), op
);
2487 /* Tie dwarf2 debug info to the address at the start of the insn. */
2488 dwarf2_emit_insn (0);
2490 if (NO_OPERANDS_INST (op
))
2491 /* Handle instructions with no operands. */
2494 /* Parse the instruction's operands. */
2495 parse_insn (&crx_ins
, param
);
2497 /* Assemble the instruction. */
2498 if (assemble_insn (op
, &crx_ins
) == 0)
2500 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse
);
2504 /* Print the instruction. */
2505 print_insn (&crx_ins
);