1 /* tc-crx.c -- Assembler code for the CRX CPU core.
2 Copyright 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Tomer Levi, NSC, Israel.
5 Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
6 Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the
22 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
26 #include "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
*rreg
;
210 rreg
= (const reg_entry
*) hash_find (reg_hash
, reg_name
);
213 return rreg
->value
.reg_val
;
218 /* Get the coprocessor register 'copreg_name'. */
221 get_copregister (char *copreg_name
)
223 const reg_entry
*coreg
;
225 coreg
= (const reg_entry
*) hash_find (copreg_hash
, copreg_name
);
228 return coreg
->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 gas_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 gas_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
)
467 md_atof (int type
, char *litP
, int *sizeP
)
469 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
472 /* Apply a fixS (fixup of an instruction or data that we didn't have
473 enough info to complete immediately) to the data in a frag.
474 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
475 relaxation of debug sections, this function is called only when
476 fixuping relocations of debug sections. */
479 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
482 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
485 switch (fixP
->fx_r_type
)
487 case BFD_RELOC_CRX_NUM8
:
488 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
490 case BFD_RELOC_CRX_NUM16
:
491 bfd_put_16 (stdoutput
, val
, buf
);
493 case BFD_RELOC_CRX_NUM32
:
494 bfd_put_32 (stdoutput
, val
, buf
);
497 /* We shouldn't ever get here because linkrelax is nonzero. */
504 if (fixP
->fx_addsy
== NULL
505 && fixP
->fx_pcrel
== 0)
508 if (fixP
->fx_pcrel
== 1
509 && fixP
->fx_addsy
!= NULL
510 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
514 /* The location from which a PC relative jump should be calculated,
515 given a PC relative reloc. */
518 md_pcrel_from (fixS
*fixp
)
520 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
523 /* This function is called once, at assembler startup time. This should
524 set up all the tables, etc that the MD part of the assembler needs. */
529 const char *hashret
= NULL
;
532 /* Set up a hash table for the instructions. */
533 if ((crx_inst_hash
= hash_new ()) == NULL
)
534 as_fatal (_("Virtual memory exhausted"));
536 while (crx_instruction
[i
].mnemonic
!= NULL
)
538 const char *mnemonic
= crx_instruction
[i
].mnemonic
;
540 hashret
= hash_insert (crx_inst_hash
, mnemonic
,
541 (void *) &crx_instruction
[i
]);
543 if (hashret
!= NULL
&& *hashret
!= '\0')
544 as_fatal (_("Can't hash `%s': %s\n"), crx_instruction
[i
].mnemonic
,
545 *hashret
== 0 ? _("(unknown reason)") : hashret
);
547 /* Insert unique names into hash table. The CRX instruction set
548 has many identical opcode names that have different opcodes based
549 on the operands. This hash table then provides a quick index to
550 the first opcode with a particular name in the opcode table. */
555 while (crx_instruction
[i
].mnemonic
!= NULL
556 && streq (crx_instruction
[i
].mnemonic
, mnemonic
));
559 /* Initialize reg_hash hash table. */
560 if ((reg_hash
= hash_new ()) == NULL
)
561 as_fatal (_("Virtual memory exhausted"));
564 const reg_entry
*regtab
;
566 for (regtab
= crx_regtab
;
567 regtab
< (crx_regtab
+ NUMREGS
); regtab
++)
569 hashret
= hash_insert (reg_hash
, regtab
->name
, (void *) regtab
);
571 as_fatal (_("Internal Error: Can't hash %s: %s"),
577 /* Initialize copreg_hash hash table. */
578 if ((copreg_hash
= hash_new ()) == NULL
)
579 as_fatal (_("Virtual memory exhausted"));
582 const reg_entry
*copregtab
;
584 for (copregtab
= crx_copregtab
; copregtab
< (crx_copregtab
+ NUMCOPREGS
);
587 hashret
= hash_insert (copreg_hash
, copregtab
->name
,
590 as_fatal (_("Internal Error: Can't hash %s: %s"),
595 /* Set linkrelax here to avoid fixups in most sections. */
599 /* Process constants (immediate/absolute)
600 and labels (jump targets/Memory locations). */
603 process_label_constant (char *str
, ins
* crx_ins
)
605 char *saved_input_line_pointer
;
606 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
608 saved_input_line_pointer
= input_line_pointer
;
609 input_line_pointer
= str
;
611 expression (&crx_ins
->exp
);
613 switch (crx_ins
->exp
.X_op
)
617 /* Missing or bad expr becomes absolute 0. */
618 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
620 crx_ins
->exp
.X_op
= O_constant
;
621 crx_ins
->exp
.X_add_number
= 0;
622 crx_ins
->exp
.X_add_symbol
= (symbolS
*) 0;
623 crx_ins
->exp
.X_op_symbol
= (symbolS
*) 0;
627 cur_arg
->X_op
= O_constant
;
628 cur_arg
->constant
= crx_ins
->exp
.X_add_number
;
634 cur_arg
->X_op
= O_symbol
;
635 crx_ins
->rtype
= BFD_RELOC_NONE
;
638 switch (cur_arg
->type
)
641 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
642 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL12
;
643 else if (IS_INSN_TYPE (CSTBIT_INS
)
644 || IS_INSN_TYPE (STOR_IMM_INS
))
645 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL28
;
647 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL32
;
651 crx_ins
->rtype
= BFD_RELOC_CRX_REGREL22
;
655 if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS
))
656 crx_ins
->rtype
= BFD_RELOC_CRX_REL16
;
657 else if (IS_INSN_TYPE (BRANCH_INS
))
658 crx_ins
->rtype
= BFD_RELOC_CRX_REL8
;
659 else if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (STOR_IMM_INS
)
660 || IS_INSN_TYPE (CSTBIT_INS
))
661 crx_ins
->rtype
= BFD_RELOC_CRX_ABS32
;
662 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
663 crx_ins
->rtype
= BFD_RELOC_CRX_REL4
;
664 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
665 crx_ins
->rtype
= BFD_RELOC_CRX_REL8_CMP
;
669 if (IS_INSN_TYPE (ARITH_INS
))
670 crx_ins
->rtype
= BFD_RELOC_CRX_IMM32
;
671 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
672 crx_ins
->rtype
= BFD_RELOC_CRX_IMM16
;
680 cur_arg
->X_op
= crx_ins
->exp
.X_op
;
684 input_line_pointer
= saved_input_line_pointer
;
688 /* Get the values of the scale to be encoded -
689 used for the scaled index mode of addressing. */
692 exponent2scale (int val
)
696 /* If 'val' is 0, the following 'for' will be an endless loop. */
700 for (exponent
= 0; (val
!= 1); val
>>= 1, exponent
++)
706 /* Parsing different types of operands
707 -> constants Immediate/Absolute/Relative numbers
708 -> Labels Relocatable symbols
709 -> (rbase) Register base
710 -> disp(rbase) Register relative
711 -> disp(rbase)+ Post-increment mode
712 -> disp(rbase,ridx,scl) Register index mode */
715 set_operand (char *operand
, ins
* crx_ins
)
717 char *operandS
; /* Pointer to start of sub-opearand. */
718 char *operandE
; /* Pointer to end of sub-opearand. */
722 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
724 /* Initialize pointers. */
725 operandS
= operandE
= operand
;
727 switch (cur_arg
->type
)
729 case arg_sc
: /* Case *+0x18. */
730 case arg_ic
: /* Case $0x18. */
732 case arg_c
: /* Case 0x18. */
734 process_label_constant (operandS
, crx_ins
);
736 if (cur_arg
->type
!= arg_ic
)
737 cur_arg
->type
= arg_c
;
740 case arg_icr
: /* Case $0x18(r1). */
742 case arg_cr
: /* Case 0x18(r1). */
743 /* Set displacement constant. */
744 while (*operandE
!= '(')
747 process_label_constant (operandS
, crx_ins
);
749 case arg_rbase
: /* Case (r1). */
751 /* Set register base. */
752 while (*operandE
!= ')')
755 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
756 as_bad (_("Illegal register `%s' in Instruction `%s'"),
757 operandS
, ins_parse
);
759 if (cur_arg
->type
!= arg_rbase
)
760 cur_arg
->type
= arg_cr
;
764 /* Set displacement constant. */
765 while (*operandE
!= '(')
768 process_label_constant (operandS
, crx_ins
);
769 operandS
= ++operandE
;
771 /* Set register base. */
772 while ((*operandE
!= ',') && (! ISSPACE (*operandE
)))
775 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
776 as_bad (_("Illegal register `%s' in Instruction `%s'"),
777 operandS
, ins_parse
);
779 /* Skip leading white space. */
780 while (ISSPACE (*operandE
))
784 /* Set register index. */
785 while ((*operandE
!= ')') && (*operandE
!= ','))
790 if ((cur_arg
->i_r
= get_register (operandS
)) == nullregister
)
791 as_bad (_("Illegal register `%s' in Instruction `%s'"),
792 operandS
, ins_parse
);
794 /* Skip leading white space. */
795 while (ISSPACE (*operandE
))
804 while (*operandE
!= ')')
808 /* Preprocess the scale string. */
809 input_save
= input_line_pointer
;
810 input_line_pointer
= operandS
;
812 input_line_pointer
= input_save
;
814 scale_val
= scale
.X_add_number
;
816 /* Check if the scale value is legal. */
817 if (scale_val
!= 1 && scale_val
!= 2
818 && scale_val
!= 4 && scale_val
!= 8)
819 as_bad (_("Illegal Scale - `%d'"), scale_val
);
821 cur_arg
->scale
= exponent2scale (scale_val
);
830 /* Parse a single operand.
831 operand - Current operand to parse.
832 crx_ins - Current assembled instruction. */
835 parse_operand (char *operand
, ins
* crx_ins
)
838 argument
*cur_arg
= &crx_ins
->arg
[cur_arg_num
]; /* Current argument. */
840 /* Initialize the type to NULL before parsing. */
841 cur_arg
->type
= nullargs
;
843 /* Check whether this is a general processor register. */
844 if ((ret_val
= get_register (operand
)) != nullregister
)
846 cur_arg
->type
= arg_r
;
847 cur_arg
->r
= ret_val
;
848 cur_arg
->X_op
= O_register
;
852 /* Check whether this is a core [special] coprocessor register. */
853 if ((ret_val
= get_copregister (operand
)) != nullcopregister
)
855 cur_arg
->type
= arg_copr
;
857 cur_arg
->type
= arg_copsr
;
858 cur_arg
->cr
= ret_val
;
859 cur_arg
->X_op
= O_register
;
863 /* Deal with special characters. */
867 if (strchr (operand
, '(') != NULL
)
868 cur_arg
->type
= arg_icr
;
870 cur_arg
->type
= arg_ic
;
875 cur_arg
->type
= arg_sc
;
880 cur_arg
->type
= arg_rbase
;
888 if (strchr (operand
, '(') != NULL
)
890 if (strchr (operand
, ',') != NULL
891 && (strchr (operand
, ',') > strchr (operand
, '(')))
892 cur_arg
->type
= arg_idxr
;
894 cur_arg
->type
= arg_cr
;
897 cur_arg
->type
= arg_c
;
900 /* Parse an operand according to its type. */
902 cur_arg
->constant
= 0;
903 set_operand (operand
, crx_ins
);
906 /* Parse the various operands. Each operand is then analyzed to fillup
907 the fields in the crx_ins data structure. */
910 parse_operands (ins
* crx_ins
, char *operands
)
912 char *operandS
; /* Operands string. */
913 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
914 int allocated
= 0; /* Indicates a new operands string was allocated. */
915 char *operand
[MAX_OPERANDS
]; /* Separating the operands. */
916 int op_num
= 0; /* Current operand number we are parsing. */
917 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
918 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
920 /* Preprocess the list of registers, if necessary. */
921 operandS
= operandH
= operandT
= (INST_HAS_REG_LIST
) ?
922 preprocess_reglist (operands
, &allocated
) : operands
;
924 while (*operandT
!= '\0')
926 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
929 operand
[op_num
++] = strdup (operandH
);
934 if (*operandT
== ' ')
935 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
937 if (*operandT
== '(')
939 else if (*operandT
== '[')
942 if (*operandT
== ')')
947 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
949 else if (*operandT
== ']')
954 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
957 if (bracket_flag
== 1 && *operandT
== ')')
959 else if (sq_bracket_flag
== 1 && *operandT
== ']')
965 /* Adding the last operand. */
966 operand
[op_num
++] = strdup (operandH
);
967 crx_ins
->nargs
= op_num
;
969 /* Verifying correct syntax of operands (all brackets should be closed). */
970 if (bracket_flag
|| sq_bracket_flag
)
971 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
973 /* Now we parse each operand separately. */
974 for (op_num
= 0; op_num
< crx_ins
->nargs
; op_num
++)
976 cur_arg_num
= op_num
;
977 parse_operand (operand
[op_num
], crx_ins
);
978 free (operand
[op_num
]);
985 /* Get the trap index in dispatch table, given its name.
986 This routine is used by assembling the 'excp' instruction. */
991 const trap_entry
*trap
;
993 for (trap
= crx_traps
; trap
< (crx_traps
+ NUMTRAPS
); trap
++)
994 if (strcasecmp (trap
->name
, s
) == 0)
997 as_bad (_("Unknown exception: `%s'"), s
);
1001 /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1002 sub-group within load/stor instruction groups.
1003 Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1004 advance the instruction pointer to the start of that sub-group (that is, up
1005 to the first instruction of that type).
1006 Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1009 handle_LoadStor (char *operands
)
1011 /* Post-Increment instructions precede Store-Immediate instructions in
1012 CRX instruction table, hence they are handled before.
1013 This synchronization should be kept. */
1015 /* Assuming Post-Increment insn has the following format :
1016 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1017 LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1018 if (strstr (operands
, ")+") != NULL
)
1020 while (! IS_INSN_TYPE (LD_STOR_INS_INC
))
1025 /* Assuming Store-Immediate insn has the following format :
1026 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1027 STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1028 if (strstr (operands
, "$") != NULL
)
1029 while (! IS_INSN_TYPE (STOR_IMM_INS
))
1033 /* Top level module where instruction parsing starts.
1034 crx_ins - data structure holds some information.
1035 operands - holds the operands part of the whole instruction. */
1038 parse_insn (ins
*insn
, char *operands
)
1042 /* Handle instructions with no operands. */
1043 for (i
= 0; no_op_insn
[i
] != NULL
; i
++)
1045 if (streq (no_op_insn
[i
], instruction
->mnemonic
))
1052 /* Handle 'excp'/'cinv' instructions. */
1053 if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1056 insn
->arg
[0].type
= arg_ic
;
1057 insn
->arg
[0].constant
= IS_INSN_MNEMONIC ("excp") ?
1058 gettrap (operands
) : get_cinv_parameters (operands
);
1059 insn
->arg
[0].X_op
= O_constant
;
1063 /* Handle load/stor unique instructions before parsing. */
1064 if (IS_INSN_TYPE (LD_STOR_INS
))
1065 handle_LoadStor (operands
);
1067 if (operands
!= NULL
)
1068 parse_operands (insn
, operands
);
1071 /* Cinv instruction requires special handling. */
1074 get_cinv_parameters (char * operand
)
1077 int d_used
= 0, i_used
= 0, u_used
= 0, b_used
= 0;
1081 if (*p
== ',' || *p
== ' ')
1093 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1096 return ((b_used
? 8 : 0)
1099 + (u_used
? 1 : 0));
1102 /* Retrieve the opcode image of a given register.
1103 If the register is illegal for the current instruction,
1107 getreg_image (reg r
)
1109 const reg_entry
*rreg
;
1111 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1113 if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num
== 1))
1114 || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num
== 0)) )
1117 /* Check whether the register is in registers table. */
1119 rreg
= &crx_regtab
[r
];
1120 /* Check whether the register is in coprocessor registers table. */
1121 else if (r
< MAX_COPREG
)
1122 rreg
= &crx_copregtab
[r
-MAX_REG
];
1123 /* Register not found. */
1126 as_bad (_("Unknown register: `%d'"), r
);
1130 reg_name
= rreg
->name
;
1132 /* Issue a error message when register is illegal. */
1134 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1135 reg_name, ins_parse); \
1141 if (is_procreg
|| (instruction
->flags
& USER_REG
))
1146 case CRX_CFG_REGTYPE
:
1159 case CRX_CS_REGTYPE
:
1170 /* Routine used to represent integer X using NBITS bits. */
1173 getconstant (long x
, int nbits
)
1175 /* The following expression avoids overflow if
1176 'nbits' is the number of bits in 'bfd_vma'. */
1177 return (x
& ((((1 << (nbits
- 1)) - 1) << 1) | 1));
1180 /* Print a constant value to 'output_opcode':
1181 ARG holds the operand's type and value.
1182 SHIFT represents the location of the operand to be print into.
1183 NBITS determines the size (in bits) of the constant. */
1186 print_constant (int nbits
, int shift
, argument
*arg
)
1188 unsigned long mask
= 0;
1190 long constant
= getconstant (arg
->constant
, nbits
);
1198 /* mask the upper part of the constant, that is, the bits
1199 going to the lowest byte of output_opcode[0].
1200 The upper part of output_opcode[1] is always filled,
1201 therefore it is always masked with 0xFFFF. */
1202 mask
= (1 << (nbits
- 16)) - 1;
1203 /* Divide the constant between two consecutive words :
1205 +---------+---------+---------+---------+
1206 | | X X X X | X X X X | |
1207 +---------+---------+---------+---------+
1208 output_opcode[0] output_opcode[1] */
1210 CRX_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1211 CRX_PRINT (1, (constant
& 0xFFFF), WORD_SHIFT
);
1216 /* Special case - in arg_cr, the SHIFT represents the location
1217 of the REGISTER, not the constant, which is itself not shifted. */
1218 if (arg
->type
== arg_cr
)
1220 CRX_PRINT (0, constant
, 0);
1224 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1225 always filling the upper part of output_opcode[1]. If we mistakenly
1226 write it to output_opcode[0], the constant prefix (that is, 'match')
1229 +---------+---------+---------+---------+
1230 | 'match' | | X X X X | |
1231 +---------+---------+---------+---------+
1232 output_opcode[0] output_opcode[1] */
1234 if ((instruction
->size
> 2) && (shift
== WORD_SHIFT
))
1235 CRX_PRINT (1, constant
, WORD_SHIFT
);
1237 CRX_PRINT (0, constant
, shift
);
1241 CRX_PRINT (0, constant
, shift
);
1246 /* Print an operand to 'output_opcode', which later on will be
1247 printed to the object file:
1248 ARG holds the operand's type, size and value.
1249 SHIFT represents the printing location of operand.
1250 NBITS determines the size (in bits) of a constant operand. */
1253 print_operand (int nbits
, int shift
, argument
*arg
)
1258 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1262 if (arg
->cr
< c0
|| arg
->cr
> c15
)
1263 as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1265 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1269 if (arg
->cr
< cs0
|| arg
->cr
> cs15
)
1270 as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1272 CRX_PRINT (0, getreg_image (arg
->cr
), shift
);
1277 +--------------------------------+
1278 | r_base | r_idx | scl| disp |
1279 +--------------------------------+ */
1280 CRX_PRINT (0, getreg_image (arg
->r
), 12);
1281 CRX_PRINT (0, getreg_image (arg
->i_r
), 8);
1282 CRX_PRINT (0, arg
->scale
, 6);
1285 print_constant (nbits
, shift
, arg
);
1289 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1293 /* case base_cst4. */
1294 if (instruction
->flags
& DISPU4MAP
)
1295 print_constant (nbits
, shift
+ REG_SIZE
, arg
);
1297 /* rbase_disps<NN> and other such cases. */
1298 print_constant (nbits
, shift
, arg
);
1299 /* Add the register argument to the output_opcode. */
1300 CRX_PRINT (0, getreg_image (arg
->r
), shift
);
1308 /* Retrieve the number of operands for the current assembled instruction. */
1311 get_number_of_operands (void)
1315 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1320 /* Verify that the number NUM can be represented in BITS bits (that is,
1321 within its permitted range), based on the instruction's FLAGS.
1322 If UPDATE is nonzero, update the value of NUM if necessary.
1323 Return OP_LEGAL upon success, actual error type upon failure. */
1326 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1329 int retval
= OP_LEGAL
;
1331 long upper_64kb
= 0xFFFF0000;
1334 /* For hosts witah longs bigger than 32-bits make sure that the top
1335 bits of a 32-bit negative value read in by the parser are set,
1336 so that the correct comparisons are made. */
1337 if (value
& 0x80000000)
1338 value
|= (-1L << 31);
1340 /* Verify operand value is even. */
1341 if (flags
& OP_EVEN
)
1347 if (flags
& OP_UPPER_64KB
)
1349 /* Check if value is to be mapped to upper 64 KB memory area. */
1350 if ((value
& upper_64kb
) == upper_64kb
)
1352 value
-= upper_64kb
;
1357 return OP_NOT_UPPER_64KB
;
1360 if (flags
& OP_SHIFT
)
1366 else if (flags
& OP_SHIFT_DEC
)
1368 value
= (value
>> 1) - 1;
1375 /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1376 if (value
== 0x7e || value
== 0x7f)
1377 return OP_OUT_OF_RANGE
;
1380 if (flags
& OP_DISPU4
)
1384 int mul
= (instruction
->flags
& DISPUB4
) ? 1
1385 : (instruction
->flags
& DISPUW4
) ? 2
1386 : (instruction
->flags
& DISPUD4
) ? 4 : 0;
1388 for (bin
= 0; bin
< cst4_maps
; bin
++)
1390 if (value
== (mul
* bin
))
1399 retval
= OP_ILLEGAL_DISPU4
;
1401 else if (flags
& OP_CST4
)
1405 for (bin
= 0; bin
< cst4_maps
; bin
++)
1407 if (value
== cst4_map
[bin
])
1416 retval
= OP_ILLEGAL_CST4
;
1418 else if (flags
& OP_SIGNED
)
1420 max
= (1 << (bits
- 1)) - 1;
1421 min
= - (1 << (bits
- 1));
1422 if ((value
> max
) || (value
< min
))
1423 retval
= OP_OUT_OF_RANGE
;
1425 else if (flags
& OP_UNSIGNED
)
1427 max
= ((((1 << (bits
- 1)) - 1) << 1) | 1);
1429 if (((unsigned long) value
> (unsigned long) max
)
1430 || ((unsigned long) value
< (unsigned long) min
))
1431 retval
= OP_OUT_OF_RANGE
;
1436 /* Assemble a single instruction:
1437 INSN is already parsed (that is, all operand values and types are set).
1438 For instruction to be assembled, we need to find an appropriate template in
1439 the instruction table, meeting the following conditions:
1440 1: Has the same number of operands.
1441 2: Has the same operand types.
1442 3: Each operand size is sufficient to represent the instruction's values.
1443 Returns 1 upon success, 0 upon failure. */
1446 assemble_insn (char *mnemonic
, ins
*insn
)
1448 /* Type of each operand in the current template. */
1449 argtype cur_type
[MAX_OPERANDS
];
1450 /* Size (in bits) of each operand in the current template. */
1451 unsigned int cur_size
[MAX_OPERANDS
];
1452 /* Flags of each operand in the current template. */
1453 unsigned int cur_flags
[MAX_OPERANDS
];
1454 /* Instruction type to match. */
1455 unsigned int ins_type
;
1456 /* Boolean flag to mark whether a match was found. */
1459 /* Nonzero if an instruction with same number of operands was found. */
1460 int found_same_number_of_operands
= 0;
1461 /* Nonzero if an instruction with same argument types was found. */
1462 int found_same_argument_types
= 0;
1463 /* Nonzero if a constant was found within the required range. */
1464 int found_const_within_range
= 0;
1465 /* Argument number of an operand with invalid type. */
1466 int invalid_optype
= -1;
1467 /* Argument number of an operand with invalid constant value. */
1468 int invalid_const
= -1;
1469 /* Operand error (used for issuing various constant error messages). */
1470 op_err op_error
, const_err
= OP_LEGAL
;
1472 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1473 #define GET_CURRENT_DATA(FUNC, ARRAY) \
1474 for (i = 0; i < insn->nargs; i++) \
1475 ARRAY[i] = FUNC (instruction->operands[i].op_type)
1477 #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1478 #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1479 #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1481 /* Instruction has no operands -> only copy the constant opcode. */
1482 if (insn
->nargs
== 0)
1484 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1488 /* In some case, same mnemonic can appear with different instruction types.
1489 For example, 'storb' is supported with 3 different types :
1490 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1491 We assume that when reaching this point, the instruction type was
1492 pre-determined. We need to make sure that the type stays the same
1493 during a search for matching instruction. */
1494 ins_type
= CRX_INS_TYPE(instruction
->flags
);
1496 while (/* Check that match is still not found. */
1498 /* Check we didn't get to end of table. */
1499 && instruction
->mnemonic
!= NULL
1500 /* Check that the actual mnemonic is still available. */
1501 && IS_INSN_MNEMONIC (mnemonic
)
1502 /* Check that the instruction type wasn't changed. */
1503 && IS_INSN_TYPE(ins_type
))
1505 /* Check whether number of arguments is legal. */
1506 if (get_number_of_operands () != insn
->nargs
)
1508 found_same_number_of_operands
= 1;
1510 /* Initialize arrays with data of each operand in current template. */
1515 /* Check for type compatibility. */
1516 for (i
= 0; i
< insn
->nargs
; i
++)
1518 if (cur_type
[i
] != insn
->arg
[i
].type
)
1520 if (invalid_optype
== -1)
1521 invalid_optype
= i
+ 1;
1525 found_same_argument_types
= 1;
1527 for (i
= 0; i
< insn
->nargs
; i
++)
1529 /* Reverse the operand indices for certain opcodes:
1532 Other index -->> stays the same. */
1533 int j
= instruction
->flags
& REVERSE_MATCH
?
1538 /* Only check range - don't update the constant's value, since the
1539 current instruction may not be the last we try to match.
1540 The constant's value will be updated later, right before printing
1541 it to the object file. */
1542 if ((insn
->arg
[j
].X_op
== O_constant
)
1543 && (op_error
= check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1546 if (invalid_const
== -1)
1548 invalid_const
= j
+ 1;
1549 const_err
= op_error
;
1553 /* For symbols, we make sure the relocation size (which was already
1554 determined) is sufficient. */
1555 else if ((insn
->arg
[j
].X_op
== O_symbol
)
1556 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
1560 found_const_within_range
= 1;
1562 /* If we got till here -> Full match is found. */
1566 /* Try again with next instruction. */
1573 /* We haven't found a match - instruction can't be assembled. */
1574 if (!found_same_number_of_operands
)
1575 as_bad (_("Incorrect number of operands"));
1576 else if (!found_same_argument_types
)
1577 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
1578 else if (!found_const_within_range
)
1582 case OP_OUT_OF_RANGE
:
1583 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
1586 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
1588 case OP_ILLEGAL_DISPU4
:
1589 as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const
);
1591 case OP_ILLEGAL_CST4
:
1592 as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const
);
1594 case OP_NOT_UPPER_64KB
:
1595 as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1599 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
1607 /* Full match - print the encoding to output file. */
1609 /* Make further checkings (such that couldn't be made earlier).
1610 Warn the user if necessary. */
1611 warn_if_needed (insn
);
1613 /* Check whether we need to adjust the instruction pointer. */
1614 if (adjust_if_needed (insn
))
1615 /* If instruction pointer was adjusted, we need to update
1616 the size of the current template operands. */
1619 for (i
= 0; i
< insn
->nargs
; i
++)
1621 int j
= instruction
->flags
& REVERSE_MATCH
?
1626 /* This time, update constant value before printing it. */
1627 if ((insn
->arg
[j
].X_op
== O_constant
)
1628 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
1629 cur_flags
[j
], 1) != OP_LEGAL
))
1630 as_fatal (_("Illegal operand (arg %d)"), j
+1);
1633 /* First, copy the instruction's opcode. */
1634 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
1636 for (i
= 0; i
< insn
->nargs
; i
++)
1639 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
1647 /* Bunch of error checkings.
1648 The checks are made after a matching instruction was found. */
1651 warn_if_needed (ins
*insn
)
1653 /* If the post-increment address mode is used and the load/store
1654 source register is the same as rbase, the result of the
1655 instruction is undefined. */
1656 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
1658 /* Enough to verify that one of the arguments is a simple reg. */
1659 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
1660 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
1661 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1665 /* Some instruction assume the stack pointer as rptr operand.
1666 Issue an error when the register to be loaded is also SP. */
1667 if (instruction
->flags
& NO_SP
)
1669 if (getreg_image (insn
->arg
[0].r
) == getreg_image (sp
))
1670 as_bad (_("`%s' has undefined result"), ins_parse
);
1673 /* If the rptr register is specified as one of the registers to be loaded,
1674 the final contents of rptr are undefined. Thus, we issue an error. */
1675 if (instruction
->flags
& NO_RPTR
)
1677 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
1678 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1679 getreg_image (insn
->arg
[0].r
));
1683 /* In some cases, we need to adjust the instruction pointer although a
1684 match was already found. Here, we gather all these cases.
1685 Returns 1 if instruction pointer was adjusted, otherwise 0. */
1688 adjust_if_needed (ins
*insn
)
1692 /* Special check for 'addub $0, r0' instruction -
1693 The opcode '0000 0000 0000 0000' is not allowed. */
1694 if (IS_INSN_MNEMONIC ("addub"))
1696 if ((instruction
->operands
[0].op_type
== cst4
)
1697 && instruction
->operands
[1].op_type
== regr
)
1699 if (insn
->arg
[0].constant
== 0 && insn
->arg
[1].r
== r0
)
1707 /* Optimization: Omit a zero displacement in bit operations,
1708 saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1709 if (IS_INSN_TYPE (CSTBIT_INS
))
1711 if ((instruction
->operands
[1].op_type
== rbase_disps12
)
1712 && (insn
->arg
[1].X_op
== O_constant
)
1713 && (insn
->arg
[1].constant
== 0))
1723 /* Set the appropriate bit for register 'r' in 'mask'.
1724 This indicates that this register is loaded or stored by
1728 mask_reg (int r
, unsigned short int *mask
)
1730 if ((reg
)r
> (reg
)sp
)
1732 as_bad (_("Invalid Register in Register List"));
1739 /* Preprocess register list - create a 16-bit mask with one bit for each
1740 of the 16 general purpose registers. If a bit is set, it indicates
1741 that this register is loaded or stored by the instruction. */
1744 preprocess_reglist (char *param
, int *allocated
)
1746 char reg_name
[MAX_REGNAME_LEN
]; /* Current parsed register name. */
1747 char *regP
; /* Pointer to 'reg_name' string. */
1748 int reg_counter
= 0; /* Count number of parsed registers. */
1749 unsigned short int mask
= 0; /* Mask for 16 general purpose registers. */
1750 char *new_param
; /* New created operands string. */
1751 char *paramP
= param
; /* Pointer to original opearands string. */
1752 char maskstring
[10]; /* Array to print the mask as a string. */
1753 int hi_found
= 0, lo_found
= 0; /* Boolean flags for hi/lo registers. */
1757 /* If 'param' is already in form of a number, no need to preprocess. */
1758 if (strchr (paramP
, '{') == NULL
)
1761 /* Verifying correct syntax of operand. */
1762 if (strchr (paramP
, '}') == NULL
)
1763 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1765 while (*paramP
++ != '{');
1767 new_param
= (char *)xcalloc (MAX_INST_LEN
, sizeof (char));
1769 strncpy (new_param
, param
, paramP
- param
- 1);
1771 while (*paramP
!= '}')
1774 memset (®_name
, '\0', sizeof (reg_name
));
1776 while (ISALNUM (*paramP
))
1779 strncpy (reg_name
, regP
, paramP
- regP
);
1781 /* Coprocessor register c<N>. */
1782 if (IS_INSN_TYPE (COP_REG_INS
))
1784 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1785 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_C_REGTYPE
))
1786 as_fatal (_("Illegal register `%s' in cop-register list"), reg_name
);
1787 mask_reg (getreg_image (cr
- c0
), &mask
);
1789 /* Coprocessor Special register cs<N>. */
1790 else if (IS_INSN_TYPE (COPS_REG_INS
))
1792 if (((cr
= get_copregister (reg_name
)) == nullcopregister
)
1793 || (crx_copregtab
[cr
-MAX_REG
].type
!= CRX_CS_REGTYPE
))
1794 as_fatal (_("Illegal register `%s' in cop-special-register list"),
1796 mask_reg (getreg_image (cr
- cs0
), &mask
);
1798 /* User register u<N>. */
1799 else if (instruction
->flags
& USER_REG
)
1801 if (streq(reg_name
, "uhi"))
1806 else if (streq(reg_name
, "ulo"))
1811 else if (((r
= get_register (reg_name
)) == nullregister
)
1812 || (crx_regtab
[r
].type
!= CRX_U_REGTYPE
))
1813 as_fatal (_("Illegal register `%s' in user register list"), reg_name
);
1815 mask_reg (getreg_image (r
- u0
), &mask
);
1817 /* General purpose register r<N>. */
1820 if (streq(reg_name
, "hi"))
1825 else if (streq(reg_name
, "lo"))
1830 else if (((r
= get_register (reg_name
)) == nullregister
)
1831 || (crx_regtab
[r
].type
!= CRX_R_REGTYPE
))
1832 as_fatal (_("Illegal register `%s' in register list"), reg_name
);
1834 mask_reg (getreg_image (r
- r0
), &mask
);
1837 if (++reg_counter
> MAX_REGS_IN_MASK16
)
1838 as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1839 MAX_REGS_IN_MASK16
);
1842 while (!ISALNUM (*paramP
) && *paramP
!= '}')
1846 if (*++paramP
!= '\0')
1847 as_warn (_("rest of line ignored; first ignored character is `%c'"),
1850 switch (hi_found
+ lo_found
)
1853 /* At least one register should be specified. */
1855 as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1860 /* HI can't be specified without LO (and vise-versa). */
1861 as_bad (_("HI/LO registers should be specified together"));
1865 /* HI/LO registers mustn't be masked with additional registers. */
1867 as_bad (_("HI/LO registers should be specified without additional registers"));
1873 sprintf (maskstring
, "$0x%x", mask
);
1874 strcat (new_param
, maskstring
);
1878 /* Print the instruction.
1879 Handle also cases where the instruction is relaxable/relocatable. */
1882 print_insn (ins
*insn
)
1884 unsigned int i
, j
, insn_size
;
1886 unsigned short words
[4];
1889 /* Arrange the insn encodings in a WORD size array. */
1890 for (i
= 0, j
= 0; i
< 2; i
++)
1892 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
1893 words
[j
++] = output_opcode
[i
] & 0xFFFF;
1896 /* Handle relaxtion. */
1897 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
1901 /* Write the maximal instruction size supported. */
1902 insn_size
= INSN_MAX_SIZE
;
1905 if (IS_INSN_TYPE (BRANCH_INS
))
1908 else if (IS_INSN_TYPE (DCR_BRANCH_INS
) || IS_INSN_MNEMONIC ("bal"))
1911 else if (IS_INSN_TYPE (CMPBR_INS
) || IS_INSN_TYPE (COP_BRANCH_INS
))
1916 this_frag
= frag_var (rs_machine_dependent
, insn_size
* 2,
1918 insn
->exp
.X_add_symbol
,
1919 insn
->exp
.X_add_number
,
1924 insn_size
= instruction
->size
;
1925 this_frag
= frag_more (insn_size
* 2);
1927 /* Handle relocation. */
1928 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
1930 reloc_howto_type
*reloc_howto
;
1933 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
1938 size
= bfd_get_reloc_size (reloc_howto
);
1940 if (size
< 1 || size
> 4)
1943 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
1944 size
, &insn
->exp
, reloc_howto
->pc_relative
,
1949 /* Verify a 2-byte code alignment. */
1950 addr_mod
= frag_now_fix () & 1;
1951 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
1952 as_bad (_("instruction address is not a multiple of 2"));
1953 frag_now
->insn_addr
= addr_mod
;
1954 frag_now
->has_code
= 1;
1956 /* Write the instruction encoding to frag. */
1957 for (i
= 0; i
< insn_size
; i
++)
1959 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
1964 /* This is the guts of the machine-dependent assembler. OP points to a
1965 machine dependent instruction. This function is supposed to emit
1966 the frags/bytes it assembles to. */
1969 md_assemble (char *op
)
1975 /* Reset global variables for a new instruction. */
1978 /* Strip the mnemonic. */
1979 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
1984 /* Find the instruction. */
1985 instruction
= (const inst
*) hash_find (crx_inst_hash
, op
);
1986 if (instruction
== NULL
)
1988 as_bad (_("Unknown opcode: `%s'"), op
);
1992 /* Tie dwarf2 debug info to the address at the start of the insn. */
1993 dwarf2_emit_insn (0);
1995 /* Parse the instruction's operands. */
1996 parse_insn (&crx_ins
, param
);
1998 /* Assemble the instruction - return upon failure. */
1999 if (assemble_insn (op
, &crx_ins
) == 0)
2002 /* Print the instruction. */
2003 print_insn (&crx_ins
);