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, 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
26 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
28 #include "opcode/crx.h"
31 /* Word is considered here as a 16-bit unsigned short int. */
34 /* Register is 4-bit size. */
37 /* Maximum size of a single instruction (in words). */
38 #define INSN_MAX_SIZE 3
40 /* Maximum bits which may be set in a `mask16' operand. */
41 #define MAX_REGS_IN_MASK16 8
43 /* Utility macros for string comparison. */
44 #define streq(a, b) (strcmp (a, b) == 0)
45 #define strneq(a, b, c) (strncmp (a, b, c) == 0)
47 /* Assign a number NUM, shifted by SHIFT bytes, into a location
48 pointed by index BYTE of array 'output_opcode'. */
49 #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
54 OP_LEGAL
= 0, /* Legal operand. */
55 OP_OUT_OF_RANGE
, /* Operand not within permitted range. */
56 OP_NOT_EVEN
, /* Operand is Odd number, should be even. */
57 OP_ILLEGAL_DISPU4
, /* Operand is not within DISPU4 range. */
58 OP_ILLEGAL_CST4
, /* Operand is not within CST4 range. */
59 OP_NOT_UPPER_64KB
/* Operand is not within the upper 64KB
60 (0xFFFF0000-0xFFFFFFFF). */
64 /* Opcode mnemonics hash table. */
65 static struct hash_control
*crx_inst_hash
;
66 /* CRX registers hash table. */
67 static struct hash_control
*reg_hash
;
68 /* CRX coprocessor registers hash table. */
69 static struct hash_control
*copreg_hash
;
70 /* Current instruction we're assembling. */
71 const inst
*instruction
;
73 /* Global variables. */
75 /* Array to hold an instruction encoding. */
76 long output_opcode
[2];
78 /* Nonzero means a relocatable symbol. */
81 /* A copy of the original instruction (used in error messages). */
82 char ins_parse
[MAX_INST_LEN
];
84 /* The current processed argument number. */
87 /* Generic assembler global variables which must be defined by all targets. */
89 /* Characters which always start a comment. */
90 const char comment_chars
[] = "#";
92 /* Characters which start a comment at the beginning of a line. */
93 const char line_comment_chars
[] = "#";
95 /* This array holds machine specific line separator characters. */
96 const char line_separator_chars
[] = ";";
98 /* Chars that can be used to separate mant from exp in floating point nums. */
99 const char EXP_CHARS
[] = "eE";
101 /* Chars that mean this number is a floating point constant as in 0f12.456 */
102 const char FLT_CHARS
[] = "f'";
104 /* Target-specific multicharacter options, not const-declared at usage. */
105 const char *md_shortopts
= "";
106 struct option md_longopts
[] =
108 {NULL
, no_argument
, NULL
, 0}
110 size_t md_longopts_size
= sizeof (md_longopts
);
112 /* This table describes all the machine specific pseudo-ops
113 the assembler has to support. The fields are:
114 *** Pseudo-op name without dot.
115 *** Function to call to execute this pseudo-op.
116 *** Integer arg to pass to the function. */
118 const pseudo_typeS md_pseudo_table
[] =
120 /* In CRX machine, align is in bytes (not a ptwo boundary). */
121 {"align", s_align_bytes
, 0},
125 /* CRX relaxation table. */
126 const relax_typeS md_relax_table
[] =
129 {0xfa, -0x100, 2, 1}, /* 8 */
130 {0xfffe, -0x10000, 4, 2}, /* 16 */
131 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
134 {0xfffe, -0x10000, 4, 4}, /* 16 */
135 {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
138 {0xfe, -0x100, 4, 6}, /* 8 */
139 {0xfffffe, -0x1000000, 6, 0} /* 24 */
142 static void reset_vars (char *);
143 static reg
get_register (char *);
144 static copreg
get_copregister (char *);
145 static argtype
get_optype (operand_type
);
146 static int get_opbits (operand_type
);
147 static int get_opflags (operand_type
);
148 static int get_number_of_operands (void);
149 static void parse_operand (char *, ins
*);
150 static int gettrap (char *);
151 static void handle_LoadStor (char *);
152 static int get_cinv_parameters (char *);
153 static long getconstant (long, int);
154 static op_err
check_range (long *, int, unsigned int, int);
155 static int getreg_image (reg
);
156 static void parse_operands (ins
*, char *);
157 static void parse_insn (ins
*, char *);
158 static void print_operand (int, int, argument
*);
159 static void print_constant (int, int, argument
*);
160 static int exponent2scale (int);
161 static void mask_reg (int, unsigned short *);
162 static void process_label_constant (char *, ins
*);
163 static void set_operand (char *, ins
*);
164 static char * preprocess_reglist (char *, int *);
165 static int assemble_insn (char *, ins
*);
166 static void print_insn (ins
*);
167 static void warn_if_needed (ins
*);
168 static int adjust_if_needed (ins
*);
170 /* Return the bit size for a given operand. */
173 get_opbits (operand_type op
)
176 return crx_optab
[op
].bit_size
;
181 /* Return the argument type of a given operand. */
184 get_optype (operand_type op
)
187 return crx_optab
[op
].arg_type
;
192 /* Return the flags of a given operand. */
195 get_opflags (operand_type op
)
198 return crx_optab
[op
].flags
;
203 /* Get the core processor register 'reg_name'. */
206 get_register (char *reg_name
)
208 const reg_entry
*reg
;
210 reg
= (const reg_entry
*) hash_find (reg_hash
, reg_name
);
213 return reg
->value
.reg_val
;
218 /* Get the coprocessor register 'copreg_name'. */
221 get_copregister (char *copreg_name
)
223 const reg_entry
*copreg
;
225 copreg
= (const reg_entry
*) hash_find (copreg_hash
, copreg_name
);
228 return copreg
->value
.copreg_val
;
230 return nullcopregister
;
233 /* Round up a section size to the appropriate boundary. */
236 md_section_align (segT seg
, valueT val
)
238 /* Round .text section to a multiple of 2. */
239 if (seg
== text_section
)
240 return (val
+ 1) & ~1;
244 /* Parse an operand that is machine-specific (remove '*'). */
247 md_operand (expressionS
* exp
)
249 char c
= *input_line_pointer
;
254 input_line_pointer
++;
262 /* Reset global variables before parsing a new instruction. */
265 reset_vars (char *op
)
267 cur_arg_num
= relocatable
= 0;
268 memset (& output_opcode
, '\0', sizeof (output_opcode
));
270 /* Save a copy of the original OP (used in error messages). */
271 strncpy (ins_parse
, op
, sizeof ins_parse
- 1);
272 ins_parse
[sizeof ins_parse
- 1] = 0;
275 /* This macro decides whether a particular reloc is an entry in a
276 switch table. It is used when relaxing, because the linker needs
277 to know about all such entries so that it can adjust them if
280 #define SWITCH_TABLE(fix) \
281 ( (fix)->fx_addsy != NULL \
282 && (fix)->fx_subsy != NULL \
283 && S_GET_SEGMENT ((fix)->fx_addsy) == \
284 S_GET_SEGMENT ((fix)->fx_subsy) \
285 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
286 && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
287 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
288 || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
290 /* See whether we need to force a relocation into the output file.
291 This is used to force out switch and PC relative relocations when
295 crx_force_relocation (fixS
*fix
)
297 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
303 /* Generate a relocation entry for a fixup. */
306 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
310 reloc
= xmalloc (sizeof (arelent
));
311 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
312 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
313 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
314 reloc
->addend
= fixP
->fx_offset
;
316 if (fixP
->fx_subsy
!= NULL
)
318 if (SWITCH_TABLE (fixP
))
320 /* Keep the current difference in the addend. */
321 reloc
->addend
= (S_GET_VALUE (fixP
->fx_addsy
)
322 - S_GET_VALUE (fixP
->fx_subsy
) + fixP
->fx_offset
);
324 switch (fixP
->fx_r_type
)
326 case BFD_RELOC_CRX_NUM8
:
327 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH8
;
329 case BFD_RELOC_CRX_NUM16
:
330 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH16
;
332 case BFD_RELOC_CRX_NUM32
:
333 fixP
->fx_r_type
= BFD_RELOC_CRX_SWITCH32
;
342 /* We only resolve difference expressions in the same section. */
343 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
344 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
345 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "0",
346 segment_name (fixP
->fx_addsy
347 ? S_GET_SEGMENT (fixP
->fx_addsy
)
349 S_GET_NAME (fixP
->fx_subsy
),
350 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
354 assert ((int) fixP
->fx_r_type
> 0);
355 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
357 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
359 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
360 _("internal error: reloc %d (`%s') not supported by object file format"),
362 bfd_get_reloc_code_name (fixP
->fx_r_type
));
365 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
370 /* Prepare machine-dependent frags for relaxation. */
373 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
375 /* If symbol is undefined or located in a different section,
376 select the largest supported relocation. */
377 relax_substateT subtype
;
378 relax_substateT rlx_state
[] = {0, 2,
382 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
384 if (fragp
->fr_subtype
== rlx_state
[subtype
]
385 && (!S_IS_DEFINED (fragp
->fr_symbol
)
386 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
388 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
393 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
396 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
400 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
402 /* 'opcode' points to the start of the instruction, whether
403 we need to change the instruction's fixed encoding. */
404 char *opcode
= fragP
->fr_literal
+ fragP
->fr_fix
;
405 bfd_reloc_code_real_type reloc
;
407 subseg_change (sec
, 0);
409 switch (fragP
->fr_subtype
)
412 reloc
= BFD_RELOC_CRX_REL8
;
416 reloc
= BFD_RELOC_CRX_REL16
;
420 reloc
= BFD_RELOC_CRX_REL32
;
423 reloc
= BFD_RELOC_CRX_REL16
;
427 reloc
= BFD_RELOC_CRX_REL32
;
430 reloc
= BFD_RELOC_CRX_REL8_CMP
;
434 reloc
= BFD_RELOC_CRX_REL24
;
441 fix_new (fragP
, fragP
->fr_fix
,
442 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
443 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
445 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
448 /* Process machine-dependent command line options. Called once for
449 each option on the command line that the machine-independent part of
450 GAS does not understand. */
453 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
458 /* Machine-dependent usage-output. */
461 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
466 /* Turn a string in input_line_pointer into a floating point constant
467 of type TYPE, and store the appropriate bytes in *LITP. The number
468 of LITTLENUMS emitted is stored in *SIZEP. An error message is
469 returned, or NULL on OK. */
472 md_atof (int type
, char *litP
, int *sizeP
)
475 LITTLENUM_TYPE words
[4];
491 return _("bad call to md_atof");
494 t
= atof_ieee (input_line_pointer
, type
, words
);
496 input_line_pointer
= t
;
500 if (! target_big_endian
)
502 for (i
= prec
- 1; i
>= 0; i
--)
504 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
510 for (i
= 0; i
< prec
; i
++)
512 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
520 /* Apply a fixS (fixup of an instruction or data that we didn't have
521 enough info to complete immediately) to the data in a frag.
522 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
523 relaxation of debug sections, this function is called only when
524 fixuping relocations of debug sections. */
527 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
530 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
533 switch (fixP
->fx_r_type
)
535 case BFD_RELOC_CRX_NUM8
:
536 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
538 case BFD_RELOC_CRX_NUM16
:
539 bfd_put_16 (stdoutput
, val
, buf
);
541 case BFD_RELOC_CRX_NUM32
:
542 bfd_put_32 (stdoutput
, val
, buf
);
545 /* We shouldn't ever get here because linkrelax is nonzero. */
552 if (fixP
->fx_addsy
== NULL
553 && fixP
->fx_pcrel
== 0)
556 if (fixP
->fx_pcrel
== 1
557 && fixP
->fx_addsy
!= NULL
558 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
562 /* The location from which a PC relative jump should be calculated,
563 given a PC relative reloc. */
566 md_pcrel_from (fixS
*fixp
)
568 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
571 /* This function is called once, at assembler startup time. This should
572 set up all the tables, etc that the MD part of the assembler needs. */
577 const char *hashret
= NULL
;
580 /* Set up a hash table for the instructions. */
581 if ((crx_inst_hash
= hash_new ()) == NULL
)
582 as_fatal (_("Virtual memory exhausted"));
584 while (crx_instruction
[i
].mnemonic
!= NULL
)
586 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
588 hashret
= hash_insert (crx_inst_hash
, mnemonic
,
589 (PTR
) &crx_instruction
[i
]);
591 if (hashret
!= NULL
&& *hashret
!= '\0')
592 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction
[i
].mnemonic
,
593 *hashret
== 0 ? _("(unknown reason)") : hashret
);
595 /* Insert unique names into hash table. The CRX instruction set
596 has many identical opcode names that have different opcodes based
597 on the operands. This hash table then provides a quick index to
598 the first opcode with a particular name in the opcode table. */
603 while (crx_instruction
[i
].mnemonic
!= NULL
604 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
607 /* Initialize reg_hash hash table. */
608 if ((reg_hash
= hash_new ()) == NULL
)
609 as_fatal (_("Virtual memory exhausted"));
612 const reg_entry
*regtab
;
614 for (regtab
= crx_regtab
;
615 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
617 hashret
= hash_insert (reg_hash
, regtab
->name
, (PTR
) regtab
);
619 as_fatal (_("Internal Error: Can't hash %s: %s"),
625 /* Initialize copreg_hash hash table. */
626 if ((copreg_hash
= hash_new ()) == NULL
)
627 as_fatal (_("Virtual memory exhausted"));
630 const reg_entry
*copregtab
;
632 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
635 hashret
= hash_insert (copreg_hash
, copregtab
->name
, (PTR
) copregtab
);
637 as_fatal (_("Internal Error: Can't hash %s: %s"),
642 /* Set linkrelax here to avoid fixups in most sections. */
646 /* Process constants (immediate/absolute)
647 and labels (jump targets/Memory locations). */
650 process_label_constant (char *str
, ins
* crx_ins
)
652 char *saved_input_line_pointer
;
653 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
655 saved_input_line_pointer
= input_line_pointer
;
656 input_line_pointer
= str
;
658 expression (&crx_ins
->exp
);
660 switch (crx_ins
->exp
.X_op
)
664 /* Missing or bad expr becomes absolute 0. */
665 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
667 crx_ins
->exp
.X_op
= O_constant
;
668 crx_ins
->exp
.X_add_number
= 0;
669 crx_ins
->exp
.X_add_symbol
= (symbolS
*) 0;
670 crx_ins
->exp
.X_op_symbol
= (symbolS
*) 0;
674 cur_arg
->X_op
= O_constant
;
675 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
681 cur_arg
->X_op
= O_symbol
;
682 crx_ins
->rtype
= BFD_RELOC_NONE
;
685 switch (cur_arg
->type
)
688 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
689 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
690 else if (IS_INSN_TYPE (CSTBIT_INS
)
691 || IS_INSN_TYPE (STOR_IMM_INS
))
692 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
694 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
698 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
702 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
703 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
704 else if (IS_INSN_TYPE (BRANCH_INS
))
705 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
706 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
707 || IS_INSN_TYPE (CSTBIT_INS
))
708 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
709 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
710 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
711 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
712 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
716 if (IS_INSN_TYPE (ARITH_INS
))
717 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
718 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
719 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
727 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
731 input_line_pointer
= saved_input_line_pointer
;
735 /* Get the values of the scale to be encoded -
736 used for the scaled index mode of addressing. */
739 exponent2scale (int val
)
743 /* If 'val' is 0, the following 'for' will be an endless loop. */
747 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
753 /* Parsing different types of operands
754 -> constants Immediate/Absolute/Relative numbers
755 -> Labels Relocatable symbols
756 -> (rbase) Register base
757 -> disp(rbase) Register relative
758 -> disp(rbase)+ Post-increment mode
759 -> disp(rbase,ridx,scl) Register index mode */
762 set_operand (char *operand
, ins
* crx_ins
)
764 char *operandS
; /* Pointer to start of sub-opearand. */
765 char *operandE
; /* Pointer to end of sub-opearand. */
769 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
771 /* Initialize pointers. */
772 operandS
= operandE
= operand
;
774 switch (cur_arg
->type
)
776 case arg_sc
: /* Case *+0x18. */
777 case arg_ic
: /* Case $0x18. */
779 case arg_c
: /* Case 0x18. */
781 process_label_constant (operandS
, crx_ins
);
783 if (cur_arg
->type
!= arg_ic
)
784 cur_arg
->type
= arg_c
;
787 case arg_icr
: /* Case $0x18(r1). */
789 case arg_cr
: /* Case 0x18(r1). */
790 /* Set displacement constant. */
791 while (*operandE
!= '(')
794 process_label_constant (operandS
, crx_ins
);
796 case arg_rbase
: /* Case (r1). */
798 /* Set register base. */
799 while (*operandE
!= ')')
802 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
803 as_bad (_("Illegal register `%s' in Instruction `%s'"),
804 operandS
, ins_parse
);
806 if (cur_arg
->type
!= arg_rbase
)
807 cur_arg
->type
= arg_cr
;
811 /* Set displacement constant. */
812 while (*operandE
!= '(')
815 process_label_constant (operandS
, crx_ins
);
816 operandS
= ++operandE
;
818 /* Set register base. */
819 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
822 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
823 as_bad (_("Illegal register `%s' in Instruction `%s'"),
824 operandS
, ins_parse
);
826 /* Skip leading white space. */
827 while (ISSPACE (*operandE
))
831 /* Set register index. */
832 while ((*operandE
!= ')') && (*operandE
!= ','))
837 if ((cur_arg
->i_r
= get_register (operandS
)) == nullregister
)
838 as_bad (_("Illegal register `%s' in Instruction `%s'"),
839 operandS
, ins_parse
);
841 /* Skip leading white space. */
842 while (ISSPACE (*operandE
))
851 while (*operandE
!= ')')
855 /* Preprocess the scale string. */
856 input_save
= input_line_pointer
;
857 input_line_pointer
= operandS
;
859 input_line_pointer
= input_save
;
861 scale_val
= scale
.X_add_number
;
863 /* Check if the scale value is legal. */
864 if (scale_val
!= 1 && scale_val
!= 2
865 && scale_val
!= 4 && scale_val
!= 8)
866 as_bad (_("Illegal Scale - `%d'"), scale_val
);
868 cur_arg
->scale
= exponent2scale (scale_val
);
877 /* Parse a single operand.
878 operand - Current operand to parse.
879 crx_ins - Current assembled instruction. */
882 parse_operand (char *operand
, ins
* crx_ins
)
885 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
887 /* Initialize the type to NULL before parsing. */
888 cur_arg
->type
= nullargs
;
890 /* Check whether this is a general processor register. */
891 if ((ret_val
= get_register (operand
)) != nullregister
)
893 cur_arg
->type
= arg_r
;
894 cur_arg
->r
= ret_val
;
895 cur_arg
->X_op
= O_register
;
899 /* Check whether this is a core [special] coprocessor register. */
900 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
902 cur_arg
->type
= arg_copr
;
904 cur_arg
->type
= arg_copsr
;
905 cur_arg
->cr
= ret_val
;
906 cur_arg
->X_op
= O_register
;
910 /* Deal with special characters. */
914 if (strchr (operand
, '(') != NULL
)
915 cur_arg
->type
= arg_icr
;
917 cur_arg
->type
= arg_ic
;
922 cur_arg
->type
= arg_sc
;
927 cur_arg
->type
= arg_rbase
;
935 if (strchr (operand
, '(') != NULL
)
937 if (strchr (operand
, ',') != NULL
938 && (strchr (operand
, ',') > strchr (operand
, '(')))
939 cur_arg
->type
= arg_idxr
;
941 cur_arg
->type
= arg_cr
;
944 cur_arg
->type
= arg_c
;
947 /* Parse an operand according to its type. */
949 cur_arg
->constant
= 0;
950 set_operand (operand
, crx_ins
);
953 /* Parse the various operands. Each operand is then analyzed to fillup
954 the fields in the crx_ins data structure. */
957 parse_operands (ins
* crx_ins
, char *operands
)
959 char *operandS
; /* Operands string. */
960 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
961 int allocated
= 0; /* Indicates a new operands string was allocated. */
962 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
963 int op_num
= 0; /* Current operand number we are parsing. */
964 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
965 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
967 /* Preprocess the list of registers, if necessary. */
968 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
969 preprocess_reglist (operands
, &allocated
) : operands
;
971 while (*operandT
!= '\0')
973 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
976 operand
[op_num
++] = strdup (operandH
);
981 if (*operandT
== ' ')
982 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
984 if (*operandT
== '(')
986 else if (*operandT
== '[')
989 if (*operandT
== ')')
994 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
996 else if (*operandT
== ']')
1001 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1004 if (bracket_flag
== 1 && *operandT
== ')')
1006 else if (sq_bracket_flag
== 1 && *operandT
== ']')
1007 sq_bracket_flag
= 0;
1012 /* Adding the last operand. */
1013 operand
[op_num
++] = strdup (operandH
);
1014 crx_ins
->nargs
= op_num
;
1016 /* Verifying correct syntax of operands (all brackets should be closed). */
1017 if (bracket_flag
|| sq_bracket_flag
)
1018 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1020 /* Now we parse each operand separately. */
1021 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
1023 cur_arg_num
= op_num
;
1024 parse_operand (operand
[op_num
], crx_ins
);
1025 free (operand
[op_num
]);
1032 /* Get the trap index in dispatch table, given its name.
1033 This routine is used by assembling the 'excp' instruction. */
1038 const trap_entry
*trap
;
1040 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
1041 if (strcasecmp (trap
->name
, s
) == 0)
1044 as_bad (_("Unknown exception: `%s'"), s
);
1048 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1049 sub-group within load/stor instruction groups.
1050 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1051 advance the instruction pointer to the start of that sub-group (that is, up
1052 to the first instruction of that type).
1053 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1056 handle_LoadStor (char *operands
)
1058 /* Post-Increment instructions precede Store-Immediate instructions in
1059 CRX instruction table, hence they are handled before.
1060 This synchronization should be kept. */
1062 /* Assuming Post-Increment insn has the following format :
1063 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1064 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1065 if (strstr (operands
, ")+") != NULL
)
1067 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1072 /* Assuming Store-Immediate insn has the following format :
1073 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1074 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1075 if (strstr (operands
, "$") != NULL
)
1076 while (! IS_INSN_TYPE (STOR_IMM_INS
))
1080 /* Top level module where instruction parsing starts.
1081 crx_ins - data structure holds some information.
1082 operands - holds the operands part of the whole instruction. */
1085 parse_insn (ins
*insn
, char *operands
)
1089 /* Handle instructions with no operands. */
1090 for (i
= 0; no_op_insn
[i
] != NULL
; i
++)
1092 if (streq (no_op_insn
[i
], instruction
->mnemonic
))
1099 /* Handle 'excp'/'cinv' instructions. */
1100 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1103 insn
->arg
[0].type
= arg_ic
;
1104 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1105 gettrap (operands
) : get_cinv_parameters (operands
);
1106 insn
->arg
[0].X_op
= O_constant
;
1110 /* Handle load/stor unique instructions before parsing. */
1111 if (IS_INSN_TYPE (LD_STOR_INS
))
1112 handle_LoadStor (operands
);
1114 if (operands
!= NULL
)
1115 parse_operands (insn
, operands
);
1118 /* Cinv instruction requires special handling. */
1121 get_cinv_parameters (char * operand
)
1124 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1128 if (*p
== ',' || *p
== ' ')
1140 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1143 return ((b_used
? 8 : 0)
1146 + (u_used
? 1 : 0));
1149 /* Retrieve the opcode image of a given register.
1150 If the register is illegal for the current instruction,
1154 getreg_image (reg r
)
1156 const reg_entry
*reg
;
1158 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1160 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num
== 1))
1161 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num
== 0)) )
1164 /* Check whether the register is in registers table. */
1166 reg
= &crx_regtab
[r
];
1167 /* Check whether the register is in coprocessor registers table. */
1168 else if (r
< MAX_COPREG
)
1169 reg
= &crx_copregtab
[r
-MAX_REG
];
1170 /* Register not found. */
1173 as_bad (_("Unknown register: `%d'"), r
);
1177 reg_name
= reg
->name
;
1179 /* Issue a error message when register is illegal. */
1181 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1182 reg_name, ins_parse); \
1188 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1193 case CRX_CFG_REGTYPE
:
1206 case CRX_CS_REGTYPE
:
1217 /* Routine used to represent integer X using NBITS bits. */
1220 getconstant (long x
, int nbits
)
1222 /* The following expression avoids overflow if
1223 'nbits' is the number of bits in 'bfd_vma'. */
1224 return (x
& ((((1 << (nbits
- 1)) - 1) << 1) | 1));
1227 /* Print a constant value to 'output_opcode':
1228 ARG holds the operand's type and value.
1229 SHIFT represents the location of the operand to be print into.
1230 NBITS determines the size (in bits) of the constant. */
1233 print_constant (int nbits
, int shift
, argument
*arg
)
1235 unsigned long mask
= 0;
1237 long constant
= getconstant (arg
->constant
, nbits
);
1245 /* mask the upper part of the constant, that is, the bits
1246 going to the lowest byte of output_opcode[0].
1247 The upper part of output_opcode[1] is always filled,
1248 therefore it is always masked with 0xFFFF. */
1249 mask
= (1 << (nbits
- 16)) - 1;
1250 /* Divide the constant between two consecutive words :
1252 +---------+---------+---------+---------+
1253 | | X X X X | X X X X | |
1254 +---------+---------+---------+---------+
1255 output_opcode[0] output_opcode[1] */
1257 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1258 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1263 /* Special case - in arg_cr, the SHIFT represents the location
1264 of the REGISTER, not the constant, which is itself not shifted. */
1265 if (arg
->type
== arg_cr
)
1267 CRX_PRINT (0, constant
, 0);
1271 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1272 always filling the upper part of output_opcode[1]. If we mistakenly
1273 write it to output_opcode[0], the constant prefix (that is, 'match')
1276 +---------+---------+---------+---------+
1277 | 'match' | | X X X X | |
1278 +---------+---------+---------+---------+
1279 output_opcode[0] output_opcode[1] */
1281 if ((instruction
->size
> 2) && (shift
== WORD_SHIFT
))
1282 CRX_PRINT (1, constant
, WORD_SHIFT
);
1284 CRX_PRINT (0, constant
, shift
);
1288 CRX_PRINT (0, constant
, shift
);
1293 /* Print an operand to 'output_opcode', which later on will be
1294 printed to the object file:
1295 ARG holds the operand's type, size and value.
1296 SHIFT represents the printing location of operand.
1297 NBITS determines the size (in bits) of a constant operand. */
1300 print_operand (int nbits
, int shift
, argument
*arg
)
1305 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1309 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1310 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1312 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1316 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1317 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1319 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1324 +--------------------------------+
1325 | r_base | r_idx | scl| disp |
1326 +--------------------------------+ */
1327 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1328 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1329 CRX_PRINT (0, arg
->scale
, 6);
1332 print_constant (nbits
, shift
, arg
);
1336 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1340 /* case base_cst4. */
1341 if (instruction
->flags
& DISPU4MAP
)
1342 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
1344 /* rbase_disps<NN> and other such cases. */
1345 print_constant (nbits
, shift
, arg
);
1346 /* Add the register argument to the output_opcode. */
1347 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1355 /* Retrieve the number of operands for the current assembled instruction. */
1358 get_number_of_operands (void)
1362 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1367 /* Verify that the number NUM can be represented in BITS bits (that is,
1368 within its permitted range), based on the instruction's FLAGS.
1369 If UPDATE is nonzero, update the value of NUM if necessary.
1370 Return OP_LEGAL upon success, actual error type upon failure. */
1373 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1376 int retval
= OP_LEGAL
;
1378 long upper_64kb
= 0xFFFF0000;
1381 /* For hosts witah longs bigger than 32-bits make sure that the top
1382 bits of a 32-bit negative value read in by the parser are set,
1383 so that the correct comparisons are made. */
1384 if (value
& 0x80000000)
1385 value
|= (-1L << 31);
1387 /* Verify operand value is even. */
1388 if (flags
& OP_EVEN
)
1394 if (flags
& OP_UPPER_64KB
)
1396 /* Check if value is to be mapped to upper 64 KB memory area. */
1397 if ((value
& upper_64kb
) == upper_64kb
)
1399 value
-= upper_64kb
;
1404 return OP_NOT_UPPER_64KB
;
1407 if (flags
& OP_SHIFT
)
1413 else if (flags
& OP_SHIFT_DEC
)
1415 value
= (value
>> 1) - 1;
1422 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1423 if (value
== 0x7e || value
== 0x7f)
1424 return OP_OUT_OF_RANGE
;
1427 if (flags
& OP_DISPU4
)
1431 int mul
= (instruction
->flags
& DISPUB4
) ? 1
1432 : (instruction
->flags
& DISPUW4
) ? 2
1433 : (instruction
->flags
& DISPUD4
) ? 4 : 0;
1435 for (bin
= 0; bin
< cst4_maps
; bin
++)
1437 if (value
== (mul
* bin
))
1446 retval
= OP_ILLEGAL_DISPU4
;
1448 else if (flags
& OP_CST4
)
1452 for (bin
= 0; bin
< cst4_maps
; bin
++)
1454 if (value
== cst4_map
[bin
])
1463 retval
= OP_ILLEGAL_CST4
;
1465 else if (flags
& OP_SIGNED
)
1467 max
= (1 << (bits
- 1)) - 1;
1468 min
= - (1 << (bits
- 1));
1469 if ((value
> max
) || (value
< min
))
1470 retval
= OP_OUT_OF_RANGE
;
1472 else if (flags
& OP_UNSIGNED
)
1474 max
= ((((1 << (bits
- 1)) - 1) << 1) | 1);
1476 if (((unsigned long) value
> (unsigned long) max
)
1477 || ((unsigned long) value
< (unsigned long) min
))
1478 retval
= OP_OUT_OF_RANGE
;
1483 /* Assemble a single instruction:
1484 INSN is already parsed (that is, all operand values and types are set).
1485 For instruction to be assembled, we need to find an appropriate template in
1486 the instruction table, meeting the following conditions:
1487 1: Has the same number of operands.
1488 2: Has the same operand types.
1489 3: Each operand size is sufficient to represent the instruction's values.
1490 Returns 1 upon success, 0 upon failure. */
1493 assemble_insn (char *mnemonic
, ins
*insn
)
1495 /* Type of each operand in the current template. */
1496 argtype cur_type
[MAX_OPERANDS
];
1497 /* Size (in bits) of each operand in the current template. */
1498 unsigned int cur_size
[MAX_OPERANDS
];
1499 /* Flags of each operand in the current template. */
1500 unsigned int cur_flags
[MAX_OPERANDS
];
1501 /* Instruction type to match. */
1502 unsigned int ins_type
;
1503 /* Boolean flag to mark whether a match was found. */
1506 /* Nonzero if an instruction with same number of operands was found. */
1507 int found_same_number_of_operands
= 0;
1508 /* Nonzero if an instruction with same argument types was found. */
1509 int found_same_argument_types
= 0;
1510 /* Nonzero if a constant was found within the required range. */
1511 int found_const_within_range
= 0;
1512 /* Argument number of an operand with invalid type. */
1513 int invalid_optype
= -1;
1514 /* Argument number of an operand with invalid constant value. */
1515 int invalid_const
= -1;
1516 /* Operand error (used for issuing various constant error messages). */
1517 op_err op_error
, const_err
= OP_LEGAL
;
1519 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1520 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1521 for (i = 0; i < insn->nargs; i++) \
1522 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1524 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1525 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1526 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1528 /* Instruction has no operands -> only copy the constant opcode. */
1529 if (insn
->nargs
== 0)
1531 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1535 /* In some case, same mnemonic can appear with different instruction types.
1536 For example, 'storb' is supported with 3 different types :
1537 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1538 We assume that when reaching this point, the instruction type was
1539 pre-determined. We need to make sure that the type stays the same
1540 during a search for matching instruction. */
1541 ins_type
= CRX_INS_TYPE(instruction
->flags
);
1543 while (/* Check that match is still not found. */
1545 /* Check we didn't get to end of table. */
1546 && instruction
->mnemonic
!= NULL
1547 /* Check that the actual mnemonic is still available. */
1548 && IS_INSN_MNEMONIC (mnemonic
)
1549 /* Check that the instruction type wasn't changed. */
1550 && IS_INSN_TYPE(ins_type
))
1552 /* Check whether number of arguments is legal. */
1553 if (get_number_of_operands () != insn
->nargs
)
1555 found_same_number_of_operands
= 1;
1557 /* Initialize arrays with data of each operand in current template. */
1562 /* Check for type compatibility. */
1563 for (i
= 0; i
< insn
->nargs
; i
++)
1565 if (cur_type
[i
] != insn
->arg
[i
].type
)
1567 if (invalid_optype
== -1)
1568 invalid_optype
= i
+ 1;
1572 found_same_argument_types
= 1;
1574 for (i
= 0; i
< insn
->nargs
; i
++)
1576 /* Reverse the operand indices for certain opcodes:
1579 Other index -->> stays the same. */
1580 int j
= instruction
->flags
& REVERSE_MATCH
?
1585 /* Only check range - don't update the constant's value, since the
1586 current instruction may not be the last we try to match.
1587 The constant's value will be updated later, right before printing
1588 it to the object file. */
1589 if ((insn
->arg
[j
].X_op
== O_constant
)
1590 && (op_error
= check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1593 if (invalid_const
== -1)
1595 invalid_const
= j
+ 1;
1596 const_err
= op_error
;
1600 /* For symbols, we make sure the relocation size (which was already
1601 determined) is sufficient. */
1602 else if ((insn
->arg
[j
].X_op
== O_symbol
)
1603 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
1607 found_const_within_range
= 1;
1609 /* If we got till here -> Full match is found. */
1613 /* Try again with next instruction. */
1620 /* We haven't found a match - instruction can't be assembled. */
1621 if (!found_same_number_of_operands
)
1622 as_bad (_("Incorrect number of operands"));
1623 else if (!found_same_argument_types
)
1624 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
1625 else if (!found_const_within_range
)
1629 case OP_OUT_OF_RANGE
:
1630 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1633 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
1635 case OP_ILLEGAL_DISPU4
:
1636 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const
);
1638 case OP_ILLEGAL_CST4
:
1639 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1641 case OP_NOT_UPPER_64KB
:
1642 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1646 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
1654 /* Full match - print the encoding to output file. */
1656 /* Make further checkings (such that couldn't be made earlier).
1657 Warn the user if necessary. */
1658 warn_if_needed (insn
);
1660 /* Check whether we need to adjust the instruction pointer. */
1661 if (adjust_if_needed (insn
))
1662 /* If instruction pointer was adjusted, we need to update
1663 the size of the current template operands. */
1666 for (i
= 0; i
< insn
->nargs
; i
++)
1668 int j
= instruction
->flags
& REVERSE_MATCH
?
1673 /* This time, update constant value before printing it. */
1674 if ((insn
->arg
[j
].X_op
== O_constant
)
1675 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1676 cur_flags
[j
], 1) != OP_LEGAL
))
1677 as_fatal (_("Illegal operand (arg %d)"), j
+1);
1680 /* First, copy the instruction's opcode. */
1681 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1683 for (i
= 0; i
< insn
->nargs
; i
++)
1686 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1694 /* Bunch of error checkings.
1695 The checks are made after a matching instruction was found. */
1698 warn_if_needed (ins
*insn
)
1700 /* If the post-increment address mode is used and the load/store
1701 source register is the same as rbase, the result of the
1702 instruction is undefined. */
1703 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1705 /* Enough to verify that one of the arguments is a simple reg. */
1706 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
1707 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
1708 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1712 /* Some instruction assume the stack pointer as rptr operand.
1713 Issue an error when the register to be loaded is also SP. */
1714 if (instruction
->flags
& NO_SP
)
1716 if (getreg_image (insn
->arg
[0].r
) == getreg_image (sp
))
1717 as_bad (_("`%s' has undefined result"), ins_parse
);
1720 /* If the rptr register is specified as one of the registers to be loaded,
1721 the final contents of rptr are undefined. Thus, we issue an error. */
1722 if (instruction
->flags
& NO_RPTR
)
1724 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
1725 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1726 getreg_image (insn
->arg
[0].r
));
1730 /* In some cases, we need to adjust the instruction pointer although a
1731 match was already found. Here, we gather all these cases.
1732 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1735 adjust_if_needed (ins
*insn
)
1739 /* Special check for 'addub $0, r0' instruction -
1740 The opcode '0000 0000 0000 0000' is not allowed. */
1741 if (IS_INSN_MNEMONIC ("addub"))
1743 if ((instruction
->operands
[0].op_type
== cst4
)
1744 && instruction
->operands
[1].op_type
== regr
)
1746 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
1754 /* Optimization: Omit a zero displacement in bit operations,
1755 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1756 if (IS_INSN_TYPE (CSTBIT_INS
))
1758 if ((instruction
->operands
[1].op_type
== rbase_disps12
)
1759 && (insn
->arg
[1].X_op
== O_constant
)
1760 && (insn
->arg
[1].constant
== 0))
1770 /* Set the appropriate bit for register 'r' in 'mask'.
1771 This indicates that this register is loaded or stored by
1775 mask_reg (int r
, unsigned short int *mask
)
1777 if ((reg
)r
> (reg
)sp
)
1779 as_bad (_("Invalid Register in Register List"));
1786 /* Preprocess register list - create a 16-bit mask with one bit for each
1787 of the 16 general purpose registers. If a bit is set, it indicates
1788 that this register is loaded or stored by the instruction. */
1791 preprocess_reglist (char *param
, int *allocated
)
1793 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
1794 char *regP
; /* Pointer to 'reg_name' string. */
1795 int reg_counter
= 0; /* Count number of parsed registers. */
1796 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
1797 char *new_param
; /* New created operands string. */
1798 char *paramP
= param
; /* Pointer to original opearands string. */
1799 char maskstring
[10]; /* Array to print the mask as a string. */
1800 int hi_found
= 0, lo_found
= 0; /* Boolean flags for hi/lo registers. */
1804 /* If 'param' is already in form of a number, no need to preprocess. */
1805 if (strchr (paramP
, '{') == NULL
)
1808 /* Verifying correct syntax of operand. */
1809 if (strchr (paramP
, '}') == NULL
)
1810 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1812 while (*paramP
++ != '{');
1814 new_param
= (char *)xcalloc (MAX_INST_LEN
, sizeof (char));
1816 strncpy (new_param
, param
, paramP
- param
- 1);
1818 while (*paramP
!= '}')
1821 memset (®_name
, '\0', sizeof (reg_name
));
1823 while (ISALNUM (*paramP
))
1826 strncpy (reg_name
, regP
, paramP
- regP
);
1828 /* Coprocessor register c<N>. */
1829 if (IS_INSN_TYPE (COP_REG_INS
))
1831 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1832 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_C_REGTYPE
))
1833 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name
);
1834 mask_reg (getreg_image (cr
- c0
), &mask
);
1836 /* Coprocessor Special register cs<N>. */
1837 else if (IS_INSN_TYPE (COPS_REG_INS
))
1839 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1840 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_CS_REGTYPE
))
1841 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1843 mask_reg (getreg_image (cr
- cs0
), &mask
);
1845 /* User register u<N>. */
1846 else if (instruction
->flags
& USER_REG
)
1848 if (streq(reg_name
, "uhi"))
1853 else if (streq(reg_name
, "ulo"))
1858 else if (((r
= get_register (reg_name
)) == nullregister
)
1859 || (crx_regtab
[r
].type
!= CRX_U_REGTYPE
))
1860 as_fatal (_("Illegal register `%s' in user register list"), reg_name
);
1862 mask_reg (getreg_image (r
- u0
), &mask
);
1864 /* General purpose register r<N>. */
1867 if (streq(reg_name
, "hi"))
1872 else if (streq(reg_name
, "lo"))
1877 else if (((r
= get_register (reg_name
)) == nullregister
)
1878 || (crx_regtab
[r
].type
!= CRX_R_REGTYPE
))
1879 as_fatal (_("Illegal register `%s' in register list"), reg_name
);
1881 mask_reg (getreg_image (r
- r0
), &mask
);
1884 if (++reg_counter
> MAX_REGS_IN_MASK16
)
1885 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1886 MAX_REGS_IN_MASK16
);
1889 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1893 if (*++paramP
!= '\0')
1894 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1897 switch (hi_found
+ lo_found
)
1900 /* At least one register should be specified. */
1902 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1907 /* HI can't be specified without LO (and vise-versa). */
1908 as_bad (_("HI/LO registers should be specified together"));
1912 /* HI/LO registers mustn't be masked with additional registers. */
1914 as_bad (_("HI/LO registers should be specified without additional registers"));
1920 sprintf (maskstring
, "$0x%x", mask
);
1921 strcat (new_param
, maskstring
);
1925 /* Print the instruction.
1926 Handle also cases where the instruction is relaxable/relocatable. */
1929 print_insn (ins
*insn
)
1931 unsigned int i
, j
, insn_size
;
1933 unsigned short words
[4];
1936 /* Arrange the insn encodings in a WORD size array. */
1937 for (i
= 0, j
= 0; i
< 2; i
++)
1939 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
1940 words
[j
++] = output_opcode
[i
] & 0xFFFF;
1943 /* Handle relaxtion. */
1944 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
1948 /* Write the maximal instruction size supported. */
1949 insn_size
= INSN_MAX_SIZE
;
1952 if (IS_INSN_TYPE (BRANCH_INS
))
1955 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1958 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1963 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1965 insn
->exp
.X_add_symbol
,
1966 insn
->exp
.X_add_number
,
1971 insn_size
= instruction
->size
;
1972 this_frag
= frag_more (insn_size
* 2);
1974 /* Handle relocation. */
1975 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
1977 reloc_howto_type
*reloc_howto
;
1980 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1985 size
= bfd_get_reloc_size (reloc_howto
);
1987 if (size
< 1 || size
> 4)
1990 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1991 size
, &insn
->exp
, reloc_howto
->pc_relative
,
1996 /* Verify a 2-byte code alignment. */
1997 addr_mod
= frag_now_fix () & 1;
1998 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
1999 as_bad (_("instruction address is not a multiple of 2"));
2000 frag_now
->insn_addr
= addr_mod
;
2001 frag_now
->has_code
= 1;
2003 /* Write the instruction encoding to frag. */
2004 for (i
= 0; i
< insn_size
; i
++)
2006 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
2011 /* This is the guts of the machine-dependent assembler. OP points to a
2012 machine dependent instruction. This function is supposed to emit
2013 the frags/bytes it assembles to. */
2016 md_assemble (char *op
)
2022 /* Reset global variables for a new instruction. */
2025 /* Strip the mnemonic. */
2026 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
2031 /* Find the instruction. */
2032 instruction
= (const inst
*) hash_find (crx_inst_hash
, op
);
2033 if (instruction
== NULL
)
2035 as_bad (_("Unknown opcode: `%s'"), op
);
2039 /* Tie dwarf2 debug info to the address at the start of the insn. */
2040 dwarf2_emit_insn (0);
2042 /* Parse the instruction's operands. */
2043 parse_insn (&crx_ins
, param
);
2045 /* Assemble the instruction - return upon failure. */
2046 if (assemble_insn (op
, &crx_ins
) == 0)
2049 /* Print the instruction. */
2050 print_insn (&crx_ins
);