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"
33 /* Word is considered here as a 16-bit unsigned short int. */
37 /* Register is 4-bit size. */
40 /* Maximum size of a single instruction (in words). */
41 #define INSN_MAX_SIZE 3
43 /* Maximum bits which may be set in a `mask16' operand. */
44 #define MAX_REGS_IN_MASK16 8
46 /* Escape to 16-bit immediate. */
48 /* Escape to 32-bit immediate. */
51 /* Utility macros for string comparison. */
52 #define streq(a, b) (strcmp (a, b) == 0)
53 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
55 /* A mask to set n_bits starting from offset offs. */
56 #define SET_BITS_MASK(offs,n_bits) ((((1 << (n_bits)) - 1) << (offs)))
57 /* A mask to clear n_bits starting from offset offs. */
58 #define CLEAR_BITS_MASK(offs,n_bits) (~(((1 << (n_bits)) - 1) << (offs)))
60 /* Get the argument type for each operand of a given instruction. */
61 #define GET_ACTUAL_TYPE \
62 for (i = 0; i < insn->nargs; i++) \
63 atyp_act[i] = getarg_type (instruction->operands[i].op_type)
65 /* Get the size (in bits) for each operand of a given instruction. */
66 #define GET_ACTUAL_SIZE \
67 for (i = 0; i < insn->nargs; i++) \
68 bits_act[i] = getbits (instruction->operands[i].op_type)
70 /* Non-zero if OP is instruction with no operands. */
71 #define NO_OPERANDS_INST(OP) \
72 (streq (OP, "di") || streq (OP, "nop") \
73 || streq (OP, "retx") || streq (OP, "ei") \
74 || streq (OP, "wait") || streq (OP, "eiwait"))
76 /* Print a number NUM, shifted by SHIFT bytes, into a location
77 pointed by index BYTE of array 'output_opcode'. */
78 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
80 /* Opcode mnemonics hash table. */
81 static struct hash_control
*crx_inst_hash
;
82 /* CRX registers hash table. */
83 static struct hash_control
*reg_hash
;
84 /* CRX coprocessor registers hash table. */
85 static struct hash_control
*copreg_hash
;
86 /* Current instruction we're assembling. */
87 const inst
*instruction
;
89 /* Initialize global variables. */
90 long output_opcode
[2];
91 /* Nonzero means a relocatable symbol. */
93 /* Nonzero means a constant's bit-size was already set. */
95 /* Nonzero means a negative constant. */
97 /* Nonzero means a CST4 instruction. */
99 /* A copy of the original instruction (used in error messages). */
100 char ins_parse
[MAX_INST_LEN
];
101 /* Nonzero means instruction is represented in post increment mode. */
103 /* Holds the current processed argument number. */
104 int processing_arg_number
;
106 /* Generic assembler global variables which must be defined by all targets. */
108 /* Characters which always start a comment. */
109 const char comment_chars
[] = "#";
111 /* Characters which start a comment at the beginning of a line. */
112 const char line_comment_chars
[] = "#";
114 /* This array holds machine specific line separator characters. */
115 const char line_separator_chars
[] = ";";
117 /* Chars that can be used to separate mant from exp in floating point nums. */
118 const char EXP_CHARS
[] = "eE";
120 /* Chars that mean this number is a floating point constant as in 0f12.456 */
121 const char FLT_CHARS
[] = "f'";
123 /* Target-specific multicharacter options, not const-declared at usage. */
124 const char *md_shortopts
= "";
125 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_LoadStor (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 /* This macro decides whether a particular reloc is an entry in a
296 switch table. It is used when relaxing, because the linker needs
297 to know about all such entries so that it can adjust them if
300 #define SWITCH_TABLE(fix) \
301 ( (fix)->fx_addsy != NULL \
302 && (fix)->fx_subsy != NULL \
303 && S_GET_SEGMENT ((fix)->fx_addsy) == \
304 S_GET_SEGMENT ((fix)->fx_subsy) \
305 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
306 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
307 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
308 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
310 /* See whether we need to force a relocation into the output file.
311 This is used to force out switch and PC relative relocations when
315 crx_force_relocation (fixS
*fix
)
317 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
323 /* Generate a relocation entry for a fixup. */
326 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
330 reloc
= xmalloc (sizeof (arelent
));
331 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
332 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
333 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
334 reloc
->addend
= fixP
->fx_offset
;
336 if (fixP
->fx_subsy
!= NULL
)
338 if (SWITCH_TABLE (fixP
))
340 /* Keep the current difference in the addend. */
341 reloc
->addend
= (S_GET_VALUE (fixP
->fx_addsy
)
342 - S_GET_VALUE (fixP
->fx_subsy
) + fixP
->fx_offset
);
344 switch (fixP
->fx_r_type
)
346 case BFD_RELOC_CRX_NUM8
:
347 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH8
;
349 case BFD_RELOC_CRX_NUM16
:
350 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH16
;
352 case BFD_RELOC_CRX_NUM32
:
353 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH32
;
362 /* We only resolve difference expressions in the same section. */
363 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
364 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
365 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "0",
366 segment_name (fixP
->fx_addsy
367 ? S_GET_SEGMENT (fixP
->fx_addsy
)
369 S_GET_NAME (fixP
->fx_subsy
),
370 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
374 assert ((int) fixP
->fx_r_type
> 0);
375 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
377 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
379 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
380 _("internal error: reloc %d (`%s') not supported by object file format"),
382 bfd_get_reloc_code_name (fixP
->fx_r_type
));
385 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
390 /* Prepare machine-dependent frags for relaxation. */
393 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
395 /* If symbol is undefined or located in a different section,
396 select the largest supported relocation. */
397 relax_substateT subtype
;
398 relax_substateT rlx_state
[] = {0, 2,
402 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
404 if (fragp
->fr_subtype
== rlx_state
[subtype
]
405 && (!S_IS_DEFINED (fragp
->fr_symbol
)
406 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
408 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
413 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
416 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
420 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
422 /* 'opcode' points to the start of the instruction, whether
423 we need to change the instruction's fixed encoding. */
424 char *opcode
= fragP
->fr_literal
+ fragP
->fr_fix
;
425 bfd_reloc_code_real_type reloc
;
427 subseg_change (sec
, 0);
429 switch (fragP
->fr_subtype
)
432 reloc
= BFD_RELOC_CRX_REL8
;
436 reloc
= BFD_RELOC_CRX_REL16
;
440 reloc
= BFD_RELOC_CRX_REL32
;
443 reloc
= BFD_RELOC_CRX_REL16
;
447 reloc
= BFD_RELOC_CRX_REL32
;
450 reloc
= BFD_RELOC_CRX_REL8_CMP
;
454 reloc
= BFD_RELOC_CRX_REL24
;
461 fix_new (fragP
, fragP
->fr_fix
,
462 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
463 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
465 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
468 /* Process machine-dependent command line options. Called once for
469 each option on the command line that the machine-independent part of
470 GAS does not understand. */
473 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
478 /* Machine-dependent usage-output. */
481 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
486 /* Turn a string in input_line_pointer into a floating point constant
487 of type TYPE, and store the appropriate bytes in *LITP. The number
488 of LITTLENUMS emitted is stored in *SIZEP. An error message is
489 returned, or NULL on OK. */
492 md_atof (int type
, char *litP
, int *sizeP
)
495 LITTLENUM_TYPE words
[4];
511 return _("bad call to md_atof");
514 t
= atof_ieee (input_line_pointer
, type
, words
);
516 input_line_pointer
= t
;
520 if (! target_big_endian
)
522 for (i
= prec
- 1; i
>= 0; i
--)
524 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
530 for (i
= 0; i
< prec
; i
++)
532 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
540 /* Apply a fixS (fixup of an instruction or data that we didn't have
541 enough info to complete immediately) to the data in a frag.
542 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
543 relaxation of debug sections, this function is called only when
544 fixuping relocations of debug sections. */
547 md_apply_fix3 (fixS
*fixP
, valueT
*valP
, segT seg
)
550 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
553 switch (fixP
->fx_r_type
)
555 case BFD_RELOC_CRX_NUM8
:
556 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
558 case BFD_RELOC_CRX_NUM16
:
559 bfd_put_16 (stdoutput
, val
, buf
);
561 case BFD_RELOC_CRX_NUM32
:
562 bfd_put_32 (stdoutput
, val
, buf
);
565 /* We shouldn't ever get here because linkrelax is nonzero. */
572 if (fixP
->fx_addsy
== NULL
573 && fixP
->fx_pcrel
== 0)
576 if (fixP
->fx_pcrel
== 1
577 && fixP
->fx_addsy
!= NULL
578 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
582 /* The location from which a PC relative jump should be calculated,
583 given a PC relative reloc. */
586 md_pcrel_from (fixS
*fixp
)
588 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
591 /* This function is called once, at assembler startup time. This should
592 set up all the tables, etc that the MD part of the assembler needs. */
597 const char *hashret
= NULL
;
600 /* Set up a hash table for the instructions. */
601 crx_inst_hash
= hash_new ();
602 if (crx_inst_hash
== NULL
)
603 as_fatal (_("Virtual memory exhausted"));
605 while (crx_instruction
[i
].mnemonic
!= NULL
)
607 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
609 hashret
= hash_insert (crx_inst_hash
, mnemonic
,
610 (PTR
) &crx_instruction
[i
]);
612 if (hashret
!= NULL
&& *hashret
!= '\0')
613 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction
[i
].mnemonic
,
614 *hashret
== 0 ? _("(unknown reason)") : hashret
);
616 /* Insert unique names into hash table. The CRX instruction set
617 has many identical opcode names that have different opcodes based
618 on the operands. This hash table then provides a quick index to
619 the first opcode with a particular name in the opcode table. */
624 while (crx_instruction
[i
].mnemonic
!= NULL
625 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
628 /* Initialize reg_hash hash table. */
629 reg_hash
= hash_new ();
632 const reg_entry
*regtab
;
634 for (regtab
= crx_regtab
;
635 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
637 hashret
= hash_insert (reg_hash
, regtab
->name
, (PTR
) regtab
);
639 as_fatal (_("Internal Error: Can't hash %s: %s"),
645 /* Initialize copreg_hash hash table. */
646 copreg_hash
= hash_new ();
649 const reg_entry
*copregtab
;
651 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
654 hashret
= hash_insert (copreg_hash
, copregtab
->name
, (PTR
) copregtab
);
656 as_fatal (_("Internal Error: Can't hash %s: %s"),
661 /* Set linkrelax here to avoid fixups in most sections. */
665 /* Get the number of bits corresponding to a constant -
666 here we check for possible overflow cases. */
669 get_number_of_bits (ins
* crx_ins
, int op_num
)
672 unsigned long int temp
= crx_ins
->arg
[op_num
].constant
;
673 const cst4_entry
*cst4_op
;
675 /* If the constant's size was already set - nothing to do. */
679 /* Already dealt with negative numbers in process_label_constants. */
686 if (IS_INSN_TYPE (ARITH_INS
) && !relocatable
&& !signflag
)
690 crx_ins
->arg
[op_num
].size
= 17;
694 /* If a signed +ve is represented in 6 bits then we have to represent
695 it in 22 bits in case of the index mode of addressing. */
696 if (IS_INSN_TYPE (LD_STOR_INS
)
697 || IS_INSN_TYPE (LD_STOR_INS_INC
)
698 || IS_INSN_TYPE (STOR_IMM_INS
)
699 || IS_INSN_TYPE (CSTBIT_INS
))
701 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_icr
)
705 crx_ins
->arg
[op_num
].size
= 7;
709 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
712 /* If a signed +ve is represnted in 16 bits in case of load/stor disp16
713 then change it to 17 bits.
714 If a signed +ve is represnted in 12 bits in post increment instruction
715 increase it to 13 bits. */
716 if (IS_INSN_TYPE (LD_STOR_INS
))
718 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_cr
)
722 crx_ins
->arg
[op_num
].size
= 17;
726 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
730 if (IS_INSN_TYPE (CSTBIT_INS
)
731 || IS_INSN_TYPE (LD_STOR_INS_INC
)
732 || IS_INSN_TYPE (STOR_IMM_INS
))
734 if (!signflag
&& crx_ins
->arg
[op_num
].type
== arg_cr
)
738 crx_ins
->arg
[op_num
].size
= 13;
739 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
740 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
743 if (IS_INSN_TYPE (CSTBIT_INS
) || IS_INSN_TYPE (STOR_IMM_INS
))
746 as_bad (_("Offset out of range in Instruction `%s'"), ins_parse
);
752 /* Handle negative cst4 mapping for arithmetic/cmp&br operations. */
753 if (signflag
&& !relocatable
754 && ((IS_INSN_TYPE (ARITH_INS
) || IS_INSN_TYPE (ARITH_BYTE_INS
))
755 || ((IS_INSN_TYPE (CMPBR_INS
) && op_num
== 0))))
757 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
); cst4_op
++)
759 if (crx_ins
->arg
[op_num
].constant
== (unsigned int)(-cst4_op
->value
))
761 crx_ins
->arg
[op_num
].size
= 4;
762 crx_ins
->arg
[op_num
].constant
= cst4_op
->binary
;
763 crx_ins
->arg
[op_num
].signflag
= 0;
768 /* Because of the cst4 mapping -- -1 and -4 already handled above
769 as well as for relocatable cases. */
770 if (signflag
&& IS_INSN_TYPE (ARITH_BYTE_INS
))
774 if (crx_ins
->arg
[op_num
].constant
<= 0xffff)
775 crx_ins
->arg
[op_num
].size
= 16;
777 /* Setting to 18 so that there is no match. */
778 crx_ins
->arg
[op_num
].size
= 18;
781 crx_ins
->arg
[op_num
].size
= 16;
785 if (signflag
&& IS_INSN_TYPE (ARITH_INS
))
787 /* For all immediates which can be expressed in less than 16 bits. */
788 if (crx_ins
->arg
[op_num
].constant
<= 0xffff && !relocatable
)
790 crx_ins
->arg
[op_num
].size
= 16;
793 /* Either it is relocatable or not representable in 16 bits. */
794 if (crx_ins
->arg
[op_num
].constant
< 0xffffffff || relocatable
)
796 crx_ins
->arg
[op_num
].size
= 32;
799 crx_ins
->arg
[op_num
].size
= 33;
802 if (signflag
&& !relocatable
)
806 crx_ins
->arg
[op_num
].size
= cnt_bits
;
808 /* Checking for Error Conditions. */
809 if (IS_INSN_TYPE (ARITH_INS
) && !signflag
)
812 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
813 cnt_bits
, ins_parse
);
815 else if (IS_INSN_TYPE (ARITH_BYTE_INS
) && !signflag
)
818 as_bad (_("Cannot represent Immediate in %d bits in Instruction `%s'"),
819 cnt_bits
, ins_parse
);
823 /* Handle the constants -immediate/absolute values and
824 Labels (jump targets/Memory locations). */
827 process_label_constant (char *str
, ins
* crx_ins
, int number
)
830 unsigned long int temp
, cnt
;
831 const cst4_entry
*cst4_op
;
833 int constant_val
= 0;
834 int cmp_br_type_flag
= 0, i
;
835 int br_type_flag
= 0;
836 save
= input_line_pointer
;
844 else if (str
[0] == '+')
847 /* Preprocessing for cmpbr instruction and getting the size flag. */
848 if (strstr (str
, ":s") != NULL
&& (IS_INSN_TYPE (CMPBR_INS
)
849 || IS_INSN_TYPE (COP_BRANCH_INS
)))
850 cmp_br_type_flag
= 8;
852 if (strstr (str
, ":l") != NULL
&& (IS_INSN_TYPE (CMPBR_INS
)
853 || IS_INSN_TYPE (COP_BRANCH_INS
)))
854 cmp_br_type_flag
= 24;
856 /* Branch instruction preprocessing. */
857 if (IS_INSN_TYPE (BRANCH_INS
))
859 if (strstr (str
, ":s") != NULL
)
861 else if (strstr (str
, ":m") != NULL
)
863 else if (strstr (str
, ":l") != NULL
)
866 /* Making the label cleared for processing removing :lms etc from labels. */
867 if (cmp_br_type_flag
!= 0 || br_type_flag
!= 0)
870 while (str
[i
] != ':')
876 input_line_pointer
= str
;
878 expression (&crx_ins
->exp
);
880 switch (crx_ins
->exp
.X_op
)
884 /* Missing or bad expr becomes absolute 0. */
885 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
887 crx_ins
->exp
.X_op
= O_constant
;
888 crx_ins
->exp
.X_add_number
= 0;
889 crx_ins
->exp
.X_add_symbol
= (symbolS
*) 0;
890 crx_ins
->exp
.X_op_symbol
= (symbolS
*) 0;
894 crx_ins
->arg
[number
].constant
= crx_ins
->exp
.X_add_number
;
895 constant_val
= crx_ins
->exp
.X_add_number
;
896 if ((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
902 unsigned int jump_value
= 0;
903 int BR_MASK
= 0, BR_SIZE
= 0;
910 strncat (temp_str
, str
, strlen (str
));
911 temp64
= strtoll (temp_str
, (char **) &ptr
,0);
914 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
917 /* Determine the branch size. */
918 jump_value
= (unsigned int)temp64
& 0xFFFFFFFF;
919 if (((jump_value
& 0xFFFFFF00) == 0xFFFFFF00)
920 || ((jump_value
& 0xFFFFFF00) == 0x0))
926 if (((jump_value
& 0xFF000000) == 0xFF000000)
927 || ((jump_value
& 0xFF000000) == 0x0))
932 jump_value
= jump_value
>> 1;
933 crx_ins
->arg
[number
].constant
= jump_value
& BR_MASK
;
934 crx_ins
->arg
[number
].size
= BR_SIZE
;
936 crx_ins
->arg
[number
].signflag
= signflag
;
937 input_line_pointer
= save
;
938 return crx_ins
->exp
.X_op
;
941 if (IS_INSN_TYPE (BRANCH_INS
)
942 || IS_INSN_MNEMONIC ("bal")
943 || IS_INSN_TYPE (DCR_BRANCH_INS
))
948 unsigned int jump_value
= 0;
949 int BR_MASK
= 0, BR_SIZE
= 0;
957 strncat (temp_str
, str
, strlen (str
));
958 temp64
= strtoll (temp_str
, (char **) &ptr
,0);
961 as_bad (_("Odd Offset in displacement in Instruction `%s'"),
964 /* Determine the branch size. */
965 jump_value
= (unsigned int)temp64
& 0xFFFFFFFF;
966 if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS
)
967 && (((jump_value
& 0xFFFFFF00) == 0xFFFFFF00)
968 || ((jump_value
& 0xFFFFFF00) == 0x0)))
973 else if (((jump_value
& 0xFFFF0000) == 0xFFFF0000)
974 || ((jump_value
& 0xFFFF0000) == 0x0))
981 BR_MASK
= 0xFFFFFFFF;
984 jump_value
= jump_value
>> 1;
985 crx_ins
->arg
[number
].constant
= jump_value
& BR_MASK
;
986 crx_ins
->arg
[number
].size
= BR_SIZE
;
988 crx_ins
->arg
[number
].signflag
= signflag
;
989 input_line_pointer
= save
;
990 return crx_ins
->exp
.X_op
;
992 /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
993 if (constant_val
< 0 && signflag
!= 1
994 && !IS_INSN_TYPE (LD_STOR_INS
) && !IS_INSN_TYPE (LD_STOR_INS_INC
)
995 && !IS_INSN_TYPE (CSTBIT_INS
) && !IS_INSN_TYPE (STOR_IMM_INS
)
996 && !IS_INSN_TYPE (BRANCH_INS
) && !IS_INSN_MNEMONIC ("bal"))
998 crx_ins
->arg
[number
].constant
=
999 ~(crx_ins
->arg
[number
].constant
) + 1;
1002 /* For load/store instruction when the value is in the offset part. */
1003 if (constant_val
< 0 && signflag
!= 1
1004 && (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (LD_STOR_INS_INC
)
1005 || IS_INSN_TYPE (CSTBIT_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)))
1007 if (crx_ins
->arg
[number
].type
== arg_cr
1008 || crx_ins
->arg
[number
].type
== arg_icr
)
1010 crx_ins
->arg
[number
].constant
=
1011 ~(crx_ins
->arg
[number
].constant
) + 1;
1017 /* Signflag in never set in case of load store instructions
1018 Mapping in case of only the arithinsn case. */
1019 if ((crx_ins
->arg
[number
].constant
!= 1
1020 && crx_ins
->arg
[number
].constant
!= 4)
1021 || (!IS_INSN_TYPE (ARITH_INS
)
1022 && !IS_INSN_TYPE (ARITH_BYTE_INS
)
1023 && !IS_INSN_TYPE (CMPBR_INS
)))
1025 /* Counting the number of bits required to represent
1028 temp
= crx_ins
->arg
[number
].constant
- 1;
1034 crx_ins
->arg
[number
].size
= cnt
+ 1;
1035 crx_ins
->arg
[number
].constant
=
1036 ~(crx_ins
->arg
[number
].constant
) + 1;
1037 if (IS_INSN_TYPE (ARITH_INS
) || IS_INSN_TYPE (ARITH_BYTE_INS
))
1042 temp64
= strtoull (str
, (char **) &ptr
, 0);
1044 crx_ins
->arg
[number
].size
= 5;
1046 if (IS_INSN_TYPE (ARITH_INS
))
1048 if (crx_ins
->arg
[number
].size
> 32
1049 || (temp64
> ULONG_MAX
))
1051 if (crx_ins
->arg
[number
].size
> 32)
1052 as_bad (_("In Instruction `%s': Immediate size is \
1053 %lu bits cannot be accomodated"),
1054 ins_parse
, cnt
+ 1);
1056 if (temp64
> ULONG_MAX
)
1057 as_bad (_("Value given more than 32 bits in \
1058 Instruction `%s'"), ins_parse
);
1061 if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1063 if (crx_ins
->arg
[number
].size
> 16
1064 || !((temp64
& 0xFFFF0000) == 0xFFFF0000
1065 || (temp64
& 0xFFFF0000) == 0x0))
1067 if (crx_ins
->arg
[number
].size
> 16)
1068 as_bad (_("In Instruction `%s': Immediate size is \
1069 %lu bits cannot be accomodated"),
1070 ins_parse
, cnt
+ 1);
1072 if (!((temp64
& 0xFFFF0000) == 0xFFFF0000
1073 || (temp64
& 0xFFFF0000) == 0x0))
1074 as_bad (_("Value given more than 16 bits in \
1075 Instruction `%s'"), ins_parse
);
1079 if (IS_INSN_TYPE (LD_STOR_INS
) && crx_ins
->arg
[number
].type
== arg_cr
1082 /* Cases handled ---
1083 dispub4/dispuw4/dispud4 and for load store dispubwd4
1084 is applicable only. */
1085 if (crx_ins
->arg
[number
].size
<= 4)
1086 crx_ins
->arg
[number
].size
= 5;
1088 /* Argument number is checked to distinguish between
1089 immediate and displacement in cmpbranch and bcopcond. */
1090 if ((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1093 if (crx_ins
->arg
[number
].size
!= 32)
1094 crx_ins
->arg
[number
].constant
=
1095 crx_ins
->arg
[number
].constant
>> 1;
1098 mask_const (&crx_ins
->arg
[number
].constant
,
1099 (int) crx_ins
->arg
[number
].size
);
1104 /* Argument number is checked to distinguish between
1105 immediate and displacement in cmpbranch and bcopcond. */
1106 if (((IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1108 || IS_INSN_TYPE (BRANCH_NEQ_INS
))
1110 if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1112 if (crx_ins
->arg
[number
].constant
== 0)
1113 as_bad (_("Instruction `%s' has Zero offset"), ins_parse
);
1116 if (crx_ins
->arg
[number
].constant
% 2 != 0)
1117 as_bad (_("Instruction `%s' has odd offset"), ins_parse
);
1119 if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1121 if (crx_ins
->arg
[number
].constant
> 32
1122 || crx_ins
->arg
[number
].constant
< 2)
1123 as_bad (_("Instruction `%s' has illegal offset (%ld)"),
1124 ins_parse
, crx_ins
->arg
[number
].constant
);
1126 crx_ins
->arg
[number
].constant
-= 2;
1129 crx_ins
->arg
[number
].constant
=
1130 crx_ins
->arg
[number
].constant
>> 1;
1131 get_number_of_bits (crx_ins
, number
);
1134 /* Compare branch argument number zero to be compared -
1136 if (IS_INSN_TYPE (CMPBR_INS
) && number
== 0)
1138 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
); cst4_op
++)
1140 if (crx_ins
->arg
[number
].constant
== (unsigned int)cst4_op
->value
)
1142 crx_ins
->arg
[number
].constant
= cst4_op
->binary
;
1148 as_bad (_("Instruction `%s' has invalid imm value as an \
1149 operand"), ins_parse
);
1156 crx_ins
->arg
[number
].constant
= 0;
1157 crx_ins
->rtype
= BFD_RELOC_NONE
;
1160 switch (crx_ins
->arg
[number
].type
)
1163 /* Have to consider various cases here --load/stor++[bwd] rbase, reg. */
1164 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1165 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
1166 else if (IS_INSN_TYPE (CSTBIT_INS
)
1167 || IS_INSN_TYPE (STOR_IMM_INS
))
1168 /* 'stor[bwd] imm' and '[stc]bit[bwd]'. */
1169 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
1171 /* General load store instruction. */
1172 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
1175 /* Index Mode 22 bits relocation. */
1176 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
1179 /* Absolute types. */
1180 /* Case for jumps...dx types. */
1182 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
1183 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
1184 else if (IS_INSN_TYPE (BRANCH_INS
))
1186 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
1188 /* Overriding the above by the br_type_flag set above. */
1189 switch (br_type_flag
)
1194 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
1197 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
1200 crx_ins
->rtype
= BFD_RELOC_CRX_REL32
;
1204 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
1205 || IS_INSN_TYPE (CSTBIT_INS
))
1206 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
1207 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1208 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
1209 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1211 if (cmp_br_type_flag
== 24)
1212 crx_ins
->rtype
= BFD_RELOC_CRX_REL24
;
1214 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
1219 if (IS_INSN_TYPE (ARITH_INS
))
1220 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
1221 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1222 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
1227 crx_ins
->arg
[number
].size
= (bfd_reloc_type_lookup (stdoutput
, crx_ins
->rtype
))->bitsize
;
1234 input_line_pointer
= save
;
1235 crx_ins
->arg
[number
].signflag
= signflag
;
1236 return crx_ins
->exp
.X_op
;
1239 /* Get the values of the scale to be encoded -
1240 used for the scaled index mode of addressing. */
1243 exponent2scale (int val
)
1247 /* If 'val' is 0, the following 'for' will be an endless loop. */
1251 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
1257 /* This is used to set the index mode parameters. Used to set the attributes of
1258 an indexmode type of operand. op_num is the operand number. */
1261 set_indexmode_parameters (char *operand
, ins
* crx_ins
, int op_num
)
1263 char address_str
[30];
1264 char scale_str
[MAX_OPERANDS
];
1266 char reg_name
[MAX_REGNAME_LEN
];
1267 char regindex_name
[MAX_REGNAME_LEN
];
1269 int reg_counter
= 0, addr_cnt
= 0, temp_int_val
= 0;
1271 switch (crx_ins
->arg
[op_num
].type
)
1274 while (operand
[i
] != '(')
1276 address_str
[addr_cnt
++] = operand
[i
];
1279 address_str
[addr_cnt
] = '\0';
1280 process_label_constant (address_str
, crx_ins
, op_num
);
1283 while (operand
[i
] != ',' && operand
[i
] != ' ')
1285 reg_name
[reg_counter
++] = operand
[i
];
1288 reg_name
[reg_counter
] = '\0';
1289 if ((crx_ins
->arg
[op_num
].r
= get_register (reg_name
)) == nullregister
)
1290 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1291 reg_name
, ins_parse
);
1294 while (operand
[i
] == ' ')
1298 while (operand
[i
] != ')' && operand
[i
] != ',')
1300 regindex_name
[reg_counter
++] = operand
[i
];
1303 regindex_name
[reg_counter
] = '\0';
1305 if ((crx_ins
->arg
[op_num
].i_r
= get_register (regindex_name
))
1307 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1308 regindex_name
, ins_parse
);
1310 /* Setting the scale parameters. */
1311 while (operand
[i
] == ' ')
1314 if (operand
[i
] == ')')
1315 crx_ins
->arg
[op_num
].scale
= 0;
1318 if (operand
[i
] == ',')
1321 while (operand
[i
] != ' ' && operand
[i
] != ')')
1323 scale_str
[scale_cnt
++] = operand
[i
];
1327 scale_str
[scale_cnt
] = '\0';
1328 /* Preprocess the scale string. */
1329 if (strstr (scale_str
, "0x") != NULL
1330 || strstr (scale_str
, "0X") != NULL
)
1332 sscanf (scale_str
, "%x", &temp_int_val
);
1333 memset (&scale_str
, '\0', sizeof (scale_str
));
1334 sprintf (scale_str
, "%d", temp_int_val
);
1336 /* Preprocess over. */
1337 temp_int_val
= atoi (scale_str
);
1339 if (temp_int_val
!= 1 && temp_int_val
!= 2
1340 && temp_int_val
!= 4 && temp_int_val
!= 8)
1341 as_bad (_("Illegal Scale - `%s'"), scale_str
);
1343 crx_ins
->arg
[op_num
].scale
= exponent2scale (temp_int_val
);
1351 /* Parsing the operands of types
1353 - rbase -> (register)
1355 - offset(rbase)+ - post increment mode. */
1358 set_cons_rparams (char *operand
, ins
* crx_ins
, int op_num
)
1360 int i
= 0, reg_count
= 0;
1361 char reg_name
[MAX_REGNAME_LEN
];
1362 int change_flag
= 0;
1364 if (crx_ins
->arg
[op_num
].type
== arg_dc
)
1367 switch (crx_ins
->arg
[op_num
].type
)
1369 case arg_sc
: /* Case *+347. */
1370 case arg_dc
: /* Case $18. */
1372 case arg_c
:/* Case where its a simple constant. */
1373 process_label_constant (operand
+ i
, crx_ins
, op_num
);
1374 crx_ins
->arg
[op_num
].type
= arg_c
;
1376 case arg_dcr
: /* Case $9(r13). */
1378 case arg_cr
: /* Case 9(r13. */
1379 while (operand
[i
] != '(')
1382 process_label_constant (operand
, crx_ins
, op_num
);
1386 while (operand
[i
] != ')')
1388 reg_name
[reg_count
] = operand
[i
];
1392 reg_name
[reg_count
] = '\0';
1393 if ((crx_ins
->arg
[op_num
].r
= get_register (reg_name
)) == nullregister
)
1394 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1395 reg_name
, ins_parse
);
1397 crx_ins
->arg
[op_num
].type
= arg_cr
;
1398 /* Post increment is represented in assembly as offset (register)+. */
1399 if (strstr (operand
+ i
, "+") != NULL
)
1400 /* There is a plus after the ')'. */
1406 if (change_flag
== 1)
1407 crx_ins
->arg
[op_num
].type
= arg_ic
;
1410 /* This is used to get the operand attributes -
1411 operand - current operand to be used
1412 number - operand number
1413 crx_ins - current assembled instruction. */
1416 get_operandtype (char *operand
, int number
, ins
* crx_ins
)
1419 char temp_operand
[30];
1423 /* When it is a register. */
1432 /* Check whether this is a general processor register. */
1433 ret_val
= get_register (operand
);
1434 if (ret_val
!= nullregister
)
1436 crx_ins
->arg
[number
].type
= arg_r
;
1437 crx_ins
->arg
[number
].r
= ret_val
;
1438 crx_ins
->arg
[number
].size
= REG_SIZE
;
1442 /* Check whether this is a core [special] coprocessor register. */
1443 ret_val
= get_copregister (operand
);
1444 if (ret_val
!= nullcopregister
)
1446 crx_ins
->arg
[number
].type
= arg_copr
;
1448 crx_ins
->arg
[number
].type
= arg_copsr
;
1449 crx_ins
->arg
[number
].cr
= ret_val
;
1450 crx_ins
->arg
[number
].size
= REG_SIZE
;
1454 if (strchr (operand
, '(') != NULL
)
1456 if (strchr (operand
, ',') != NULL
1457 && (strchr (operand
, ',') > strchr (operand
, '(')))
1459 crx_ins
->arg
[number
].type
= arg_icr
;
1460 crx_ins
->arg
[number
].constant
= 0;
1461 set_indexmode_parameters (operand
, crx_ins
, number
);
1462 get_number_of_bits (crx_ins
, number
);
1466 crx_ins
->arg
[number
].type
= arg_cr
;
1469 crx_ins
->arg
[number
].type
= arg_c
;
1470 crx_ins
->arg
[number
].constant
= 0;
1471 set_cons_rparams (operand
, crx_ins
, number
);
1472 get_number_of_bits (crx_ins
, number
);
1477 if (strchr (operand
, '(') != NULL
)
1478 crx_ins
->arg
[number
].type
= arg_dcr
;
1480 crx_ins
->arg
[number
].type
= arg_dc
;
1481 crx_ins
->arg
[number
].constant
= 0;
1482 set_cons_rparams (operand
, crx_ins
, number
);
1483 get_number_of_bits (crx_ins
, number
);
1487 /* Augmenting a zero in front of an operand -- won't work for tbit/sbit. */
1488 strcpy (temp_operand
, "0");
1489 strcat (temp_operand
, operand
);
1490 if (strchr (temp_operand
, ',') != NULL
1491 && (strchr (temp_operand
, ',') > strchr (temp_operand
, '(')))
1493 crx_ins
->arg
[number
].type
= arg_icr
;
1494 crx_ins
->arg
[number
].constant
= 0;
1495 set_indexmode_parameters (temp_operand
, crx_ins
, number
);
1496 get_number_of_bits (crx_ins
, number
);
1501 crx_ins
->arg
[number
].type
= arg_cr
;
1502 crx_ins
->arg
[number
].constant
= 0;
1503 set_cons_rparams (temp_operand
, crx_ins
, number
);
1504 get_number_of_bits (crx_ins
, number
);
1505 if ((! strneq (instruction
->mnemonic
, "load", 4))
1506 && (! strneq (instruction
->mnemonic
, "stor", 4)))
1508 crx_ins
->arg
[number
].type
= arg_rbase
;
1509 crx_ins
->arg
[number
].size
= REG_SIZE
;
1515 crx_ins
->arg
[number
].type
= arg_sc
;
1516 crx_ins
->arg
[number
].constant
= 0;
1517 set_cons_rparams (operand
, crx_ins
, number
);
1518 get_number_of_bits (crx_ins
, number
);
1532 if (strchr (operand
, '(') != NULL
)
1534 if (strchr (operand
, ',') != NULL
1535 && (strchr (operand
, ',') > strchr (operand
, '(')))
1537 crx_ins
->arg
[number
].type
= arg_icr
;
1538 crx_ins
->arg
[number
].constant
= 0;
1539 set_indexmode_parameters (operand
, crx_ins
, number
);
1540 get_number_of_bits (crx_ins
, number
);
1544 crx_ins
->arg
[number
].type
= arg_cr
;
1547 crx_ins
->arg
[number
].type
= arg_c
;
1548 crx_ins
->arg
[number
].constant
= 0;
1549 set_cons_rparams (operand
, crx_ins
, number
);
1550 get_number_of_bits (crx_ins
, number
);
1553 if (strchr (operand
, '(') != NULL
)
1555 if (strchr (operand
, ',') != NULL
1556 && (strchr (operand
, ',') > strchr (operand
, '(')))
1558 crx_ins
->arg
[number
].type
= arg_icr
;
1559 crx_ins
->arg
[number
].constant
= 0;
1560 set_indexmode_parameters (operand
, crx_ins
, number
);
1561 get_number_of_bits (crx_ins
, number
);
1565 crx_ins
->arg
[number
].type
= arg_cr
;
1568 crx_ins
->arg
[number
].type
= arg_c
;
1569 crx_ins
->arg
[number
].constant
= 0;
1570 set_cons_rparams (operand
, crx_ins
, number
);
1571 get_number_of_bits (crx_ins
, number
);
1576 /* Operands are parsed over here, separated into various operands. Each operand
1577 is then analyzed to fillup the fields in the crx_ins data structure. */
1580 parse_operands (ins
* crx_ins
, char *operands
)
1582 char *operandS
; /* Operands string. */
1583 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
1584 int allocated
= 0; /* Indicates a new operands string was allocated. */
1585 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
1586 int op_num
= 0; /* Current operand number we are parsing. */
1587 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
1588 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
1590 /* Preprocess the list of registers, if necessary. */
1591 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
1592 preprocess_reglist (operands
, &allocated
) : operands
;
1594 while (*operandT
!= '\0')
1596 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
1599 operand
[op_num
++] = strdup (operandH
);
1600 operandH
= operandT
;
1604 if (*operandT
== ' ')
1605 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
1607 if (*operandT
== '(')
1609 else if (*operandT
== '[')
1610 sq_bracket_flag
= 1;
1612 if (*operandT
== ')')
1617 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1619 else if (*operandT
== ']')
1621 if (sq_bracket_flag
)
1622 sq_bracket_flag
= 0;
1624 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1627 if (bracket_flag
== 1 && *operandT
== ')')
1629 else if (sq_bracket_flag
== 1 && *operandT
== ']')
1630 sq_bracket_flag
= 0;
1635 /* Adding the last operand. */
1636 operand
[op_num
++] = strdup (operandH
);
1637 crx_ins
->nargs
= op_num
;
1639 /* Verifying correct syntax of operands (all brackets should be closed). */
1640 if (bracket_flag
|| sq_bracket_flag
)
1641 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1643 /* Now to recongnize the operand types. */
1644 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
1646 get_operandtype (operand
[op_num
], op_num
, crx_ins
);
1647 free (operand
[op_num
]);
1654 /* Get the trap index in dispatch table, given its name.
1655 This routine is used by assembling the 'excp' instruction. */
1660 const trap_entry
*trap
;
1662 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
1663 if (strcasecmp (trap
->name
, s
) == 0)
1666 as_bad (_("Unknown exception: `%s'"), s
);
1670 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1671 sub-group within load/stor instruction groups.
1672 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1673 advance the instruction pointer to the start of that sub-group (that is, up
1674 to the first instruction of that type).
1675 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1678 handle_LoadStor (char *operands
)
1680 /* Assuming Store-Immediate insn has the following format :
1681 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1682 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1683 if (strstr (operands
, "$") != NULL
)
1684 while (! IS_INSN_TYPE (STOR_IMM_INS
))
1687 /* Assuming Post-Increment insn has the following format :
1688 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1689 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1690 if (strstr (operands
, ")+") != NULL
)
1691 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1695 /* Top level module where instruction parsing starts.
1696 crx_ins - data structure holds some information.
1697 operands - holds the operands part of the whole instruction. */
1700 parse_insn (ins
*insn
, char *operands
)
1702 /* Handle 'excp'/'cinv' */
1703 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1706 insn
->arg
[0].type
= arg_ic
;
1707 insn
->arg
[0].size
= 4;
1708 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1709 gettrap (operands
) : get_cinv_parameters (operands
);
1713 /* Handle load/stor unique instructions before parsing. */
1714 if (IS_INSN_TYPE (LD_STOR_INS
))
1715 handle_LoadStor (operands
);
1717 if (operands
!= NULL
)
1718 parse_operands (insn
, operands
);
1721 /* Cinv instruction requires special handling. */
1724 get_cinv_parameters (char * operand
)
1727 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1731 if (*p
== ',' || *p
== ' ')
1743 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1746 return ((b_used
? 8 : 0)
1749 + (u_used
? 1 : 0));
1752 /* Retrieve the opcode image of a given register.
1753 If the register is illegal for the current instruction,
1757 getreg_image (reg r
)
1759 const reg_entry
*reg
;
1761 int special_register_flag
= 0;
1762 int movpr_flag
= 0; /* Nonzero means current mnemonic is 'mtpr'/'mfpr' */
1764 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
1767 if (((IS_INSN_MNEMONIC ("mtpr")) && (processing_arg_number
== 1))
1768 || ((IS_INSN_MNEMONIC ("mfpr")) && (processing_arg_number
== 0)) )
1769 special_register_flag
= 1;
1771 /* Check whether the register is in registers table. */
1773 reg
= &crx_regtab
[r
];
1774 /* Check whether the register is in coprocessor registers table. */
1775 else if (r
< MAX_COPREG
)
1776 reg
= &crx_copregtab
[r
-MAX_REG
];
1777 /* Register not found. */
1780 as_bad (_("Unknown register: `%d'"), r
);
1784 reg_name
= reg
->name
;
1786 /* Issue a error message when register is illegal. */
1788 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1789 reg_name, ins_parse); \
1795 case CRX_CFG_REGTYPE
:
1796 case CRX_MTPR_REGTYPE
:
1797 if (movpr_flag
&& special_register_flag
)
1804 case CRX_CS_REGTYPE
:
1805 if (!(movpr_flag
&& special_register_flag
))
1817 /* Routine used to get the binary-string equivalent of a integer constant
1818 which currently require currbits to represent itself to be extended to
1821 static unsigned long int
1822 getconstant (unsigned long int x
, int nbits
)
1825 unsigned long int temp
= x
;
1833 /* Escape sequence to next 16bit immediate. */
1835 as_bad (_("Value `%ld' truncated to fit `%d' bits in instruction `%s'"),
1840 x
|= SET_BITS_MASK (cnt
, nbits
- cnt
);
1842 x
&= CLEAR_BITS_MASK (cnt
, nbits
- cnt
);
1845 /* The following expression avoids overflow if
1846 'nbits' is the number of bits in 'bfd_vma'. */
1847 return (x
& ((((1 << (nbits
- 1)) - 1) << 1) | 1));
1850 /* Print a constant value to 'output_opcode':
1851 ARG holds the operand's type and value.
1852 SHIFT represents the location of the operand to be print into.
1853 NBITS determines the size (in bits) of the constant. */
1856 print_constant (int nbits
, int shift
, argument
*arg
)
1858 unsigned long mask
= 0;
1860 long constant
= getconstant (arg
->constant
, nbits
);
1868 /* mask the upper part of the constant, that is, the bits
1869 going to the lowest byte of output_opcode[0].
1870 The upper part of output_opcode[1] is always filled,
1871 therefore it is always masked with 0xFFFF. */
1872 mask
= (1 << (nbits
- 16)) - 1;
1873 /* Divide the constant between two consecutive words :
1875 +---------+---------+---------+---------+
1876 | | X X X X | X X X X | |
1877 +---------+---------+---------+---------+
1878 output_opcode[0] output_opcode[1] */
1880 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1881 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1886 /* Special case - in arg_cr, the SHIFT represents the location
1887 of the REGISTER, not the constant, which is itself not shifted. */
1888 if (arg
->type
== arg_cr
)
1890 CRX_PRINT (0, constant
, 0);
1894 /* When instruction size is 3, a 16-bit constant is always
1895 filling the upper part of output_opcode[1]. */
1896 if (instruction
->size
> 2)
1897 CRX_PRINT (1, constant
, WORD_SHIFT
);
1899 CRX_PRINT (0, constant
, shift
);
1903 CRX_PRINT (0, constant
, shift
);
1908 /* Print an operand to 'output_opcode', which later on will be
1909 printed to the object file:
1910 ARG holds the operand's type, size and value.
1911 SHIFT represents the printing location of operand.
1912 NBITS determines the size (in bits) of a constant operand. */
1915 print_operand (int nbits
, int shift
, argument
*arg
)
1920 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1924 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1925 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1927 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1931 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1932 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1934 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1938 print_constant (nbits
, shift
, arg
);
1943 +--------------------------------+
1944 | reg | r_base | scl| disp |
1945 +--------------------------------+ */
1946 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1947 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1948 CRX_PRINT (0, arg
->scale
, 6);
1949 print_constant (nbits
, shift
, arg
);
1953 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1957 /* case base_cst4. */
1958 if ((instruction
->flags
& CST4MAP
) && cst4flag
)
1959 output_opcode
[0] |= (getconstant (arg
->constant
, nbits
)
1960 << (shift
+ REG_SIZE
));
1962 /* rbase_dispu<NN> and other such cases. */
1963 print_constant (nbits
, shift
, arg
);
1964 /* Add the register argument to the output_opcode. */
1965 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1969 print_constant (nbits
, shift
, arg
);
1977 /* Retrieve the number of operands for the current assembled instruction. */
1980 get_number_of_operands (void)
1984 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1989 /* Assemble a single instruction :
1990 Instruction has been parsed and all operand values set appropriately.
1991 Algorithm for assembling -
1992 For instruction to be assembled:
1993 Step 1: Find instruction in the array crx_instruction with same mnemonic.
1994 Step 2: Find instruction with same operand types.
1995 Step 3: If (size_of_operands) match then done, else increment the
1996 array_index and goto Step3.
1997 Step 4: Cannot assemble
1998 Returns 1 upon success, 0 upon failure. */
2001 assemble_insn (char *mnemonic
, ins
*insn
)
2003 /* Argument type of each operand in the instruction we are looking for. */
2004 argtype atyp
[MAX_OPERANDS
];
2005 /* Argument type of each operand in the current instruction. */
2006 argtype atyp_act
[MAX_OPERANDS
];
2007 /* Size (in bits) of each operand in the instruction we are looking for. */
2008 int bits
[MAX_OPERANDS
];
2009 /* Size (in bits) of each operand in the current instruction. */
2010 int bits_act
[MAX_OPERANDS
];
2011 /* Location (in bits) of each operand in the current instruction. */
2012 int shift_act
[MAX_OPERANDS
];
2015 int cst4maptype
= 0;
2016 int changed_already
= 0;
2017 unsigned int temp_value
= 0;
2019 /* A pointer to the argument's constant value. */
2020 unsigned long int *cons
;
2021 /* Pointer to loop over all cst4_map entries. */
2022 const cst4_entry
*cst4_op
;
2024 /* Instruction has no operands -> copy only the constant opcode. */
2025 if (insn
->nargs
== 0)
2027 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2031 /* Find instruction with same number of operands. */
2032 while (get_number_of_operands () != insn
->nargs
2033 && IS_INSN_MNEMONIC (mnemonic
))
2036 if (!IS_INSN_MNEMONIC (mnemonic
))
2039 /* Initialize argument type and size of each given operand. */
2040 for (i
= 0; i
< insn
->nargs
; i
++)
2042 atyp
[i
] = insn
->arg
[i
].type
;
2043 bits
[i
] = insn
->arg
[i
].size
;
2046 /* Initialize argument type and size of each operand in current inst. */
2051 /* Check we didn't get to end of table. */
2052 && instruction
->mnemonic
!= NULL
2053 /* Check that the actual mnemonic is still available. */
2054 && IS_INSN_MNEMONIC (mnemonic
))
2056 /* Check for argement type compatibility. */
2057 for (i
= 0; i
< insn
->nargs
; i
++)
2059 if (atyp_act
[i
] == atyp
[i
])
2069 /* Check for post inc mode of the current instruction. */
2070 if (post_inc_mode
== 1 || IS_INSN_TYPE (LD_STOR_INS_INC
))
2071 done_flag
= (post_inc_mode
== IS_INSN_TYPE (LD_STOR_INS_INC
));
2076 for (i
= 0; i
< insn
->nargs
; i
++)
2078 if (((instruction
->operands
[i
].op_type
== us3
)
2079 || (instruction
->operands
[i
].op_type
== us4
)
2080 || (instruction
->operands
[i
].op_type
== us5
))
2081 && (insn
->arg
[i
].signflag
== 1))
2091 /* Try again with next instruction. */
2099 /* Check for size compatibility. */
2100 for (i
= 0; i
< insn
->nargs
; i
++)
2102 if (bits
[i
] > bits_act
[i
])
2104 /* Actual size is too small - try again. */
2117 /* Full match is found. */
2124 /* We haven't found a match - instruction can't be assembled. */
2127 /* Full match - print the final image. */
2129 /* Error checking for Co-Processor instructions :
2130 The internal coprocessor 0 can only accept the
2131 "mtcr" and "mfcr" instructions. */
2132 if (IS_INSN_TYPE (COP_REG_INS
) || IS_INSN_TYPE (COPS_REG_INS
)
2133 || IS_INSN_TYPE (COP_BRANCH_INS
))
2135 /* The coprocessor id is always the first argument. */
2136 if ((instruction
->operands
[0].op_type
== us4
)
2137 && (insn
->arg
[0].constant
== 0)
2138 && (! IS_INSN_MNEMONIC ("mtcr")
2139 && ! IS_INSN_MNEMONIC ("mfcr")))
2141 as_bad (_("Internal Coprocessor 0 doesn't support instruction `%s'"),
2145 /* Handle positive constants. */
2148 if (IS_INSN_TYPE (LD_STOR_INS
) && !relocatable
)
2150 /* Get the map type of the instruction. */
2151 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2152 cons
= &insn
->arg
[instrtype
].constant
;
2153 cst4maptype
= instruction
->flags
& CST4MAP
;
2155 switch (cst4maptype
)
2158 /* 14 and 15 are reserved escape sequences of dispub4. */
2159 if (*cons
== 14 || *cons
== 15)
2167 /* Mapping has to be done. */
2168 if (*cons
<= 15 && *cons
% 2 != 0)
2173 else if (*cons
> 15 && *cons
< 27 && *cons
% 2 == 0)
2178 if (*cons
< 27 && *cons
% 2 == 0)
2183 /* Mapping has to be done. */
2184 if (*cons
<= 15 && *cons
% 4 != 0)
2189 else if (*cons
> 15 && *cons
< 53 && *cons
% 4 == 0)
2194 if (*cons
< 53 && *cons
% 4 == 0)
2201 if ((IS_INSN_TYPE (ARITH_BYTE_INS
) || IS_INSN_TYPE (ARITH_INS
))
2204 /* Check whether a cst4 mapping has to be done. */
2205 if ((instruction
->operands
[0].op_type
== cst4
2206 || instruction
->operands
[0].op_type
== i16
)
2207 && (instruction
->operands
[1].op_type
== regr
))
2209 /* 'const' equals reserved escape sequences -->>
2210 represent as i16. */
2211 if (insn
->arg
[0].constant
== ESC_16
2212 || insn
->arg
[0].constant
== ESC_32
)
2219 /* Loop over cst4_map entries. */
2220 for (cst4_op
= cst4_map
; cst4_op
< (cst4_map
+ cst4_maps
);
2223 /* 'const' equals a binary, which is already mapped
2224 by a different value -->> represent as i16. */
2225 if (insn
->arg
[0].constant
== (unsigned int)cst4_op
->binary
2226 && cst4_op
->binary
!= cst4_op
->value
)
2231 /* 'const' equals a value bigger than 16 -->> map to
2232 its binary and represent as cst4. */
2233 else if (insn
->arg
[0].constant
== (unsigned int)cst4_op
->value
2234 && insn
->arg
[0].constant
>= 16)
2237 insn
->arg
[0].constant
= cst4_op
->binary
;
2243 /* Special check for 'addub 0, r0' instruction -
2244 The opcode '0000 0000 0000 0000' is not allowed. */
2245 if (IS_INSN_MNEMONIC ("addub"))
2247 if ((instruction
->operands
[0].op_type
== cst4
)
2248 && instruction
->operands
[1].op_type
== regr
)
2250 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
2255 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
2256 || IS_INSN_TYPE (LD_STOR_INS_INC
))
2258 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2259 if (instruction
->operands
[instrtype
].op_type
== rbase
)
2262 /* Error checking in case of post-increment instruction. */
2263 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
2265 if (!((strneq (instruction
->mnemonic
, "stor", 4))
2266 && (insn
->arg
[0].type
!= arg_r
)))
2267 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
2268 as_bad (_("Invalid instruction : `%s' Source and Destination register \
2269 same in Post INC mode"), ins_parse
);
2271 if (IS_INSN_TYPE (CSTBIT_INS
) && !relocatable
)
2273 if (instruction
->operands
[1].op_type
== rbase_dispu12
)
2275 if (insn
->arg
[1].constant
== 0)
2282 if ((IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
)
2283 || IS_INSN_TYPE (STOR_IMM_INS
)
2284 || IS_INSN_TYPE (LD_STOR_INS_INC
)) & !relocatable
)
2286 instrtype
= instruction
->flags
& REVERSE_MATCH
? 0 : 1;
2287 changed_already
= 0;
2288 /* Convert 32 bits accesses to 16 bits accesses. */
2289 if (instruction
->operands
[instrtype
].op_type
== abs32
)
2291 if ((insn
->arg
[instrtype
].constant
& 0xFFFF0000) == 0xFFFF0000)
2294 insn
->arg
[instrtype
].constant
=
2295 insn
->arg
[instrtype
].constant
& 0xFFFF;
2296 insn
->arg
[instrtype
].size
= 16;
2297 changed_already
= 1;
2301 /* Convert 16 bits accesses to 32 bits accesses. */
2302 if (instruction
->operands
[instrtype
].op_type
== abs16
2303 && changed_already
!= 1)
2306 insn
->arg
[instrtype
].constant
=
2307 insn
->arg
[instrtype
].constant
& 0xFFFF;
2308 insn
->arg
[instrtype
].size
= 32;
2311 changed_already
= 0;
2313 if (IS_INSN_TYPE (BRANCH_INS
) && !relocatable
)
2315 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
2316 if (insn
->arg
[0].constant
== 0x7e || insn
->arg
[0].constant
== 0x7f)
2324 for (i
= 0; i
< insn
->nargs
; i
++)
2326 if (instruction
->operands
[i
].op_type
== cst4
2327 || instruction
->operands
[i
].op_type
== rbase_cst4
)
2331 /* First, copy the instruction's opcode. */
2332 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2334 /* Swap the argument values in case bcop instructions. */
2335 if (IS_INSN_TYPE (COP_BRANCH_INS
))
2337 temp_value
= insn
->arg
[0].constant
;
2338 insn
->arg
[0].constant
= insn
->arg
[1].constant
;
2339 insn
->arg
[1].constant
= temp_value
;
2342 for (i
= 0; i
< insn
->nargs
; i
++)
2344 shift_act
[i
] = instruction
->operands
[i
].shift
;
2345 signflag
= insn
->arg
[i
].signflag
;
2346 processing_arg_number
= i
;
2347 print_operand (bits_act
[i
], shift_act
[i
], &insn
->arg
[i
]);
2354 /* Set the appropriate bit for register 'r' in 'mask'.
2355 This indicates that this register is loaded or stored by
2359 mask_reg (int r
, unsigned short int *mask
)
2361 if ((reg
)r
> (reg
)sp
)
2363 as_bad (_("Invalid Register in Register List"));
2370 /* Preprocess register list - create a 16-bit mask with one bit for each
2371 of the 16 general purpose registers. If a bit is set, it indicates
2372 that this register is loaded or stored by the instruction. */
2375 preprocess_reglist (char *param
, int *allocated
)
2377 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
2378 char *regP
; /* Pointer to 'reg_name' string. */
2379 int reg_counter
= 0; /* Count number of parsed registers. */
2380 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
2381 char *new_param
; /* New created operands string. */
2382 char *paramP
= param
; /* Pointer to original opearands string. */
2383 char maskstring
[10]; /* Array to print the mask as a string. */
2387 /* If 'param' is already in form of a number, no need to preprocess. */
2388 if (strchr (paramP
, '{') == NULL
)
2391 /* Verifying correct syntax of operand. */
2392 if (strchr (paramP
, '}') == NULL
)
2393 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
2395 while (*paramP
++ != '{');
2397 new_param
= (char *)xcalloc (MAX_INST_LEN
, sizeof (char));
2399 strncpy (new_param
, param
, paramP
- param
- 1);
2401 while (*paramP
!= '}')
2404 memset (®_name
, '\0', sizeof (reg_name
));
2406 while (ISALNUM (*paramP
))
2409 strncpy (reg_name
, regP
, paramP
- regP
);
2411 /* Coprocessor register c<N>. */
2412 if (IS_INSN_TYPE (COP_REG_INS
))
2414 if ((cr
= get_copregister (reg_name
)) == nullcopregister
)
2415 as_bad (_("Illegal register `%s' in cop-register list"), reg_name
);
2416 mask_reg (getreg_image (cr
- c0
), &mask
);
2418 /* Coprocessor Special register cs<N>. */
2419 else if (IS_INSN_TYPE (COPS_REG_INS
))
2421 if ((cr
= get_copregister (reg_name
)) == nullcopregister
)
2422 as_bad (_("Illegal register `%s' in cop-special-register list"),
2424 mask_reg (getreg_image (cr
- cs0
), &mask
);
2426 /* General purpose register r<N>. */
2429 if ((r
= get_register (reg_name
)) == nullregister
)
2430 as_bad (_("Illegal register `%s' in register list"), reg_name
);
2431 mask_reg (getreg_image (r
), &mask
);
2434 if (++reg_counter
> MAX_REGS_IN_MASK16
)
2435 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
2436 MAX_REGS_IN_MASK16
);
2438 while (!ISALNUM (*paramP
) && *paramP
!= '}')
2442 if (*++paramP
!= '\0')
2443 as_warn (_("rest of line ignored; first ignored character is `%c'"),
2447 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
2450 sprintf (maskstring
, "$0x%x", mask
);
2451 strcat (new_param
, maskstring
);
2455 /* Print the instruction.
2456 Handle also cases where the instruction is relaxable/relocatable. */
2459 print_insn (ins
*insn
)
2461 unsigned int i
, j
, insn_size
;
2463 unsigned short words
[4];
2465 /* Arrange the insn encodings in a WORD size array. */
2466 for (i
= 0, j
= 0; i
< 2; i
++)
2468 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
2469 words
[j
++] = output_opcode
[i
] & 0xFFFF;
2472 /* Handle relaxtion. */
2473 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
2477 /* Write the maximal instruction size supported. */
2478 insn_size
= INSN_MAX_SIZE
;
2481 if (IS_INSN_TYPE (BRANCH_INS
))
2484 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
2487 else if (IS_INSN_TYPE (CMPBR_INS
))
2492 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
2494 insn
->exp
.X_add_symbol
,
2495 insn
->exp
.X_add_number
,
2500 insn_size
= instruction
->size
;
2501 this_frag
= frag_more (insn_size
* 2);
2503 /* Handle relocation. */
2504 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
2506 reloc_howto_type
*reloc_howto
;
2509 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
2514 size
= bfd_get_reloc_size (reloc_howto
);
2516 if (size
< 1 || size
> 4)
2519 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
2520 size
, &insn
->exp
, reloc_howto
->pc_relative
,
2525 /* Write the instruction encoding to frag. */
2526 for (i
= 0; i
< insn_size
; i
++)
2528 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
2533 /* This is the guts of the machine-dependent assembler. OP points to a
2534 machine dependent instruction. This function is supposed to emit
2535 the frags/bytes it assembles to. */
2538 md_assemble (char *op
)
2544 /* Reset global variables for a new instruction. */
2545 reset_vars (op
, &crx_ins
);
2547 /* Strip the mnemonic. */
2548 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
2553 /* Find the instruction. */
2554 instruction
= (const inst
*) hash_find (crx_inst_hash
, op
);
2555 if (instruction
== NULL
)
2557 as_bad (_("Unknown opcode: `%s'"), op
);
2561 /* Tie dwarf2 debug info to the address at the start of the insn. */
2562 dwarf2_emit_insn (0);
2564 if (NO_OPERANDS_INST (op
))
2565 /* Handle instructions with no operands. */
2568 /* Parse the instruction's operands. */
2569 parse_insn (&crx_ins
, param
);
2571 /* Assemble the instruction. */
2572 if (assemble_insn (op
, &crx_ins
) == 0)
2574 as_bad (_("Illegal operands in instruction : `%s'"), ins_parse
);
2578 /* Print the instruction. */
2579 print_insn (&crx_ins
);