1 /* tc-cr16.c -- Assembler code for the CR16 CPU core.
2 Copyright (C) 2007-2021 Free Software Foundation, Inc.
4 Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the
20 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "safe-ctype.h"
25 #include "dwarf2dbg.h"
26 #include "opcode/cr16.h"
36 /* Word is considered here as a 16-bit unsigned short int. */
39 /* Register is 2-byte size. */
42 /* Maximum size of a single instruction (in words). */
43 #define INSN_MAX_SIZE 3
45 /* Maximum bits which may be set in a `mask16' operand. */
46 #define MAX_REGS_IN_MASK16 8
48 /* Assign a number NUM, shifted by SHIFT bytes, into a location
49 pointed by index BYTE of array 'output_opcode'. */
50 #define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT)
55 OP_LEGAL
= 0, /* Legal operand. */
56 OP_OUT_OF_RANGE
, /* Operand not within permitted range. */
57 OP_NOT_EVEN
/* Operand is Odd number, should be even. */
61 /* Opcode mnemonics hash table. */
62 static htab_t cr16_inst_hash
;
63 /* CR16 registers hash table. */
64 static htab_t reg_hash
;
65 /* CR16 register pair hash table. */
66 static htab_t regp_hash
;
67 /* CR16 processor registers hash table. */
68 static htab_t preg_hash
;
69 /* CR16 processor registers 32 bit hash table. */
70 static htab_t pregp_hash
;
71 /* Current instruction we're assembling. */
72 const inst
*instruction
;
75 static int code_label
= 0;
77 /* Global variables. */
79 /* Array to hold an instruction encoding. */
80 long output_opcode
[2];
82 /* Nonzero means a relocatable symbol. */
85 /* A copy of the original instruction (used in error messages). */
86 char ins_parse
[MAX_INST_LEN
];
88 /* The current processed argument number. */
91 /* Generic assembler global variables which must be defined by all targets. */
93 /* Characters which always start a comment. */
94 const char comment_chars
[] = "#";
96 /* Characters which start a comment at the beginning of a line. */
97 const char line_comment_chars
[] = "#";
99 /* This array holds machine specific line separator characters. */
100 const char line_separator_chars
[] = ";";
102 /* Chars that can be used to separate mant from exp in floating point nums. */
103 const char EXP_CHARS
[] = "eE";
105 /* Chars that mean this number is a floating point constant as in 0f12.456 */
106 const char FLT_CHARS
[] = "f'";
109 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
110 symbolS
* GOT_symbol
;
113 /* Target-specific multicharacter options, not const-declared at usage. */
114 const char *md_shortopts
= "";
115 struct option md_longopts
[] =
117 {NULL
, no_argument
, NULL
, 0}
119 size_t md_longopts_size
= sizeof (md_longopts
);
127 #ifdef md_flush_pending_output
128 md_flush_pending_output ();
131 if (is_it_end_of_statement ())
133 demand_empty_rest_of_line ();
137 #ifdef TC_ADDRESS_BYTES
139 nbytes
= TC_ADDRESS_BYTES ();
143 md_cons_align (nbytes
);
149 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
150 char *hold
= input_line_pointer
;
154 if (*input_line_pointer
== ':')
163 if (*input_line_pointer
!= ':')
165 input_line_pointer
= hold
;
168 if (exp
.X_op
== O_absent
)
170 as_warn (_("using a bit field width of zero"));
171 exp
.X_add_number
= 0;
172 exp
.X_op
= O_constant
;
175 if (exp
.X_op
!= O_constant
)
177 *input_line_pointer
= '\0';
178 as_bad (_("field width \"%s\" too complex for a bitfield"),
180 *input_line_pointer
= ':';
181 demand_empty_rest_of_line ();
185 if ((width
= exp
.X_add_number
) >
186 (unsigned int)(BITS_PER_CHAR
* nbytes
))
188 as_warn (ngettext ("field width %lu too big to fit in %d"
189 " byte: truncated to %d bits",
190 "field width %lu too big to fit in %d"
191 " bytes: truncated to %d bits",
193 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
194 width
= BITS_PER_CHAR
* nbytes
;
197 if (width
> bits_available
)
199 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
200 input_line_pointer
= hold
;
201 exp
.X_add_number
= value
;
206 hold
= ++input_line_pointer
;
209 if (exp
.X_op
!= O_constant
)
211 char cache
= *input_line_pointer
;
213 *input_line_pointer
= '\0';
214 as_bad (_("field value \"%s\" too complex for a bitfield"),
216 *input_line_pointer
= cache
;
217 demand_empty_rest_of_line ();
221 value
|= ((~(-(1 << width
)) & exp
.X_add_number
)
222 << ((BITS_PER_CHAR
* nbytes
) - bits_available
));
224 if ((bits_available
-= width
) == 0
225 || is_it_end_of_statement ()
226 || *input_line_pointer
!= ',')
229 hold
= ++input_line_pointer
;
233 exp
.X_add_number
= value
;
234 exp
.X_op
= O_constant
;
238 if ((*(input_line_pointer
) == '@') && (*(input_line_pointer
+1) == 'c'))
240 emit_expr (&exp
, (unsigned int) nbytes
);
242 if ((*(input_line_pointer
) == '@') && (*(input_line_pointer
+1) == 'c'))
244 input_line_pointer
+=3;
248 while ((*input_line_pointer
++ == ','));
250 /* Put terminator back into stream. */
251 input_line_pointer
--;
253 demand_empty_rest_of_line ();
256 /* This table describes all the machine specific pseudo-ops
257 the assembler has to support. The fields are:
258 *** Pseudo-op name without dot.
259 *** Function to call to execute this pseudo-op.
260 *** Integer arg to pass to the function. */
262 const pseudo_typeS md_pseudo_table
[] =
264 /* In CR16 machine, align is in bytes (not a ptwo boundary). */
265 {"align", s_align_bytes
, 0},
266 {"long", l_cons
, 4 },
267 {"4byte", l_cons
, 4 },
271 /* CR16 relaxation table. */
272 const relax_typeS md_relax_table
[] =
275 {0x7f, -0x80, 2, 1}, /* 8 */
276 {0xfffe, -0x10000, 4, 2}, /* 16 */
277 {0xfffffe, -0x1000000, 6, 0}, /* 24 */
280 /* Return the bit size for a given operand. */
283 get_opbits (operand_type op
)
286 return cr16_optab
[op
].bit_size
;
291 /* Return the argument type of a given operand. */
294 get_optype (operand_type op
)
297 return cr16_optab
[op
].arg_type
;
302 /* Return the flags of a given operand. */
305 get_opflags (operand_type op
)
308 return cr16_optab
[op
].flags
;
313 /* Get the cc code. */
316 get_cc (char *cc_name
)
320 for (i
= 0; i
< cr16_num_cc
; i
++)
321 if (strcmp (cc_name
, cr16_b_cond_tab
[i
]) == 0)
327 /* Get the core processor register 'reg_name'. */
330 get_register (char *reg_name
)
332 const reg_entry
*rreg
;
334 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
337 return rreg
->value
.reg_val
;
341 /* Get the core processor register-pair 'reg_name'. */
344 get_register_pair (char *reg_name
)
346 const reg_entry
*rreg
;
347 char tmp_rp
[16]="\0";
349 /* Add '(' and ')' to the reg pair, if it's not present. */
350 if (reg_name
[0] != '(')
353 strcat (tmp_rp
, reg_name
);
355 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, tmp_rp
);
358 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, reg_name
);
361 return rreg
->value
.reg_val
;
366 /* Get the index register 'reg_name'. */
369 get_index_register (char *reg_name
)
371 const reg_entry
*rreg
;
373 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
376 && ((rreg
->value
.reg_val
== 12) || (rreg
->value
.reg_val
== 13)))
377 return rreg
->value
.reg_val
;
381 /* Get the core processor index register-pair 'reg_name'. */
384 get_index_register_pair (char *reg_name
)
386 const reg_entry
*rreg
;
388 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, reg_name
);
392 if ((rreg
->value
.reg_val
!= 1) || (rreg
->value
.reg_val
!= 7)
393 || (rreg
->value
.reg_val
!= 9) || (rreg
->value
.reg_val
> 10))
394 return rreg
->value
.reg_val
;
396 as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg
->value
.reg_val
);
402 /* Get the processor register 'preg_name'. */
405 get_pregister (char *preg_name
)
407 const reg_entry
*prreg
;
409 prreg
= (const reg_entry
*) str_hash_find (preg_hash
, preg_name
);
412 return prreg
->value
.preg_val
;
414 return nullpregister
;
417 /* Get the processor register 'preg_name 32 bit'. */
420 get_pregisterp (char *preg_name
)
422 const reg_entry
*prreg
;
424 prreg
= (const reg_entry
*) str_hash_find (pregp_hash
, preg_name
);
427 return prreg
->value
.preg_val
;
429 return nullpregister
;
433 /* Round up a section size to the appropriate boundary. */
436 md_section_align (segT seg
, valueT val
)
438 /* Round .text section to a multiple of 2. */
439 if (seg
== text_section
)
440 return (val
+ 1) & ~1;
444 /* Parse an operand that is machine-specific (remove '*'). */
447 md_operand (expressionS
* exp
)
449 char c
= *input_line_pointer
;
454 input_line_pointer
++;
462 /* Reset global variables before parsing a new instruction. */
465 reset_vars (char *op
)
467 cur_arg_num
= relocatable
= 0;
468 memset (& output_opcode
, '\0', sizeof (output_opcode
));
470 /* Save a copy of the original OP (used in error messages). */
471 strncpy (ins_parse
, op
, sizeof ins_parse
- 1);
472 ins_parse
[sizeof ins_parse
- 1] = 0;
475 /* This macro decides whether a particular reloc is an entry in a
476 switch table. It is used when relaxing, because the linker needs
477 to know about all such entries so that it can adjust them if
480 #define SWITCH_TABLE(fix) \
481 ((fix)->fx_addsy != NULL \
482 && (fix)->fx_subsy != NULL \
483 && ((fix)->fx_r_type == BFD_RELOC_CR16_NUM8 \
484 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16 \
485 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32 \
486 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a) \
487 && S_GET_SEGMENT ((fix)->fx_addsy) != undefined_section \
488 && S_GET_SEGMENT ((fix)->fx_addsy) == S_GET_SEGMENT ((fix)->fx_subsy))
490 /* See whether we need to force a relocation into the output file.
491 This is used to force out switch and PC relative relocations when
495 cr16_force_relocation (fixS
*fix
)
497 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
503 /* Record a fixup for a cons expression. */
506 cr16_cons_fix_new (fragS
*frag
, int offset
, int len
, expressionS
*exp
,
507 bfd_reloc_code_real_type rtype
)
511 default: rtype
= BFD_RELOC_NONE
; break;
512 case 1: rtype
= BFD_RELOC_CR16_NUM8
; break;
513 case 2: rtype
= BFD_RELOC_CR16_NUM16
; break;
517 rtype
= BFD_RELOC_CR16_NUM32a
;
521 rtype
= BFD_RELOC_CR16_NUM32
;
525 fix_new_exp (frag
, offset
, len
, exp
, 0, rtype
);
528 /* Generate a relocation entry for a fixup. */
531 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
535 /* If symbols are local and resolved, then no relocation needed. */
536 if ( ((fixP
->fx_addsy
)
537 && (S_GET_SEGMENT (fixP
->fx_addsy
) == absolute_section
))
539 && (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)))
542 reloc
= XNEW (arelent
);
543 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
544 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
545 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
546 reloc
->addend
= fixP
->fx_offset
;
548 if (fixP
->fx_subsy
!= NULL
)
550 if (SWITCH_TABLE (fixP
))
552 /* Keep the current difference in the addend. */
553 reloc
->addend
= (S_GET_VALUE (fixP
->fx_addsy
)
554 - S_GET_VALUE (fixP
->fx_subsy
) + fixP
->fx_offset
);
556 switch (fixP
->fx_r_type
)
558 case BFD_RELOC_CR16_NUM8
:
559 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH8
;
561 case BFD_RELOC_CR16_NUM16
:
562 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH16
;
564 case BFD_RELOC_CR16_NUM32
:
565 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH32
;
567 case BFD_RELOC_CR16_NUM32a
:
568 fixP
->fx_r_type
= BFD_RELOC_CR16_NUM32a
;
577 /* We only resolve difference expressions in the same section. */
578 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
579 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
580 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "0",
581 segment_name (fixP
->fx_addsy
582 ? S_GET_SEGMENT (fixP
->fx_addsy
)
584 S_GET_NAME (fixP
->fx_subsy
),
585 segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)));
589 if ((fixP
->fx_r_type
== BFD_RELOC_CR16_GOT_REGREL20
)
591 && fixP
->fx_addsy
== GOT_symbol
)
593 reloc
->addend
= fixP
->fx_offset
= reloc
->address
;
595 else if ((fixP
->fx_r_type
== BFD_RELOC_CR16_GOTC_REGREL20
)
597 && fixP
->fx_addsy
== GOT_symbol
)
599 reloc
->addend
= fixP
->fx_offset
= reloc
->address
;
603 gas_assert ((int) fixP
->fx_r_type
> 0);
604 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
606 if (reloc
->howto
== NULL
)
608 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
609 _("internal error: reloc %d (`%s') not supported by object file format"),
611 bfd_get_reloc_code_name (fixP
->fx_r_type
));
614 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
619 /* Prepare machine-dependent frags for relaxation. */
622 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
624 /* If symbol is undefined or located in a different section,
625 select the largest supported relocation. */
626 relax_substateT subtype
;
627 relax_substateT rlx_state
[] = {0, 2};
629 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
631 if (fragp
->fr_subtype
== rlx_state
[subtype
]
632 && (!S_IS_DEFINED (fragp
->fr_symbol
)
633 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
635 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
640 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
643 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
647 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
649 /* 'opcode' points to the start of the instruction, whether
650 we need to change the instruction's fixed encoding. */
651 char *opcode
= &fragP
->fr_literal
[0] + fragP
->fr_fix
;
652 bfd_reloc_code_real_type reloc
;
654 subseg_change (sec
, 0);
656 switch (fragP
->fr_subtype
)
659 reloc
= BFD_RELOC_CR16_DISP8
;
662 /* If the subtype is not changed due to :m operand qualifier,
663 then no need to update the opcode value. */
664 if ((int)opcode
[1] != 0x18)
666 opcode
[0] = (opcode
[0] & 0xf0);
669 reloc
= BFD_RELOC_CR16_DISP16
;
672 /* If the subtype is not changed due to :l operand qualifier,
673 then no need to update the opcode value. */
674 if ((int)opcode
[1] != 0)
676 opcode
[2] = opcode
[0];
677 opcode
[0] = opcode
[1];
680 reloc
= BFD_RELOC_CR16_DISP24
;
686 fix_new (fragP
, fragP
->fr_fix
,
687 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
688 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
690 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
694 md_undefined_symbol (char *name
)
696 if (*name
== '_' && *(name
+ 1) == 'G'
697 && strcmp (name
, "_GLOBAL_OFFSET_TABLE_") == 0)
701 if (symbol_find (name
))
702 as_bad (_("GOT already in symbol table"));
703 GOT_symbol
= symbol_new (name
, undefined_section
,
704 &zero_address_frag
, 0);
711 /* Process machine-dependent command line options. Called once for
712 each option on the command line that the machine-independent part of
713 GAS does not understand. */
716 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
721 /* Machine-dependent usage-output. */
724 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
730 md_atof (int type
, char *litP
, int *sizeP
)
732 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
735 /* Apply a fixS (fixup of an instruction or data that we didn't have
736 enough info to complete immediately) to the data in a frag.
737 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
738 relaxation of debug sections, this function is called only when
739 fixuping relocations of debug sections. */
742 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
746 if (fixP
->fx_addsy
== NULL
747 && fixP
->fx_pcrel
== 0)
749 else if (fixP
->fx_pcrel
== 1
750 && fixP
->fx_addsy
!= NULL
751 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
756 if (fixP
->fx_addsy
!= NULL
&& !fixP
->fx_pcrel
)
758 val
= fixP
->fx_offset
;
764 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
768 switch (fixP
->fx_r_type
)
770 case BFD_RELOC_CR16_NUM8
:
771 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
773 case BFD_RELOC_CR16_NUM16
:
774 bfd_put_16 (stdoutput
, val
, buf
);
776 case BFD_RELOC_CR16_NUM32
:
777 bfd_put_32 (stdoutput
, val
, buf
);
779 case BFD_RELOC_CR16_NUM32a
:
780 bfd_put_32 (stdoutput
, val
, buf
);
783 /* We shouldn't ever get here because linkrelax is nonzero. */
790 fixP
->fx_offset
= * valP
;
793 /* The location from which a PC relative jump should be calculated,
794 given a PC relative reloc. */
797 md_pcrel_from (fixS
*fixp
)
799 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
803 initialise_reg_hash_table (htab_t
*hash_table
,
804 const reg_entry
*register_table
,
805 const unsigned int num_entries
)
807 const reg_entry
*rreg
;
809 *hash_table
= str_htab_create ();
811 for (rreg
= register_table
;
812 rreg
< (register_table
+ num_entries
);
814 if (str_hash_insert (*hash_table
, rreg
->name
, rreg
, 0) != NULL
)
815 as_fatal (_("duplicate %s"), rreg
->name
);
818 /* This function is called once, at assembler startup time. This should
819 set up all the tables, etc that the MD part of the assembler needs. */
826 /* Set up a hash table for the instructions. */
827 cr16_inst_hash
= str_htab_create ();
829 while (cr16_instruction
[i
].mnemonic
!= NULL
)
831 const char *mnemonic
= cr16_instruction
[i
].mnemonic
;
833 if (str_hash_insert (cr16_inst_hash
, mnemonic
, cr16_instruction
+ i
, 0))
834 as_fatal (_("duplicate %s"), mnemonic
);
836 /* Insert unique names into hash table. The CR16 instruction set
837 has many identical opcode names that have different opcodes based
838 on the operands. This hash table then provides a quick index to
839 the first opcode with a particular name in the opcode table. */
844 while (cr16_instruction
[i
].mnemonic
!= NULL
845 && streq (cr16_instruction
[i
].mnemonic
, mnemonic
));
848 /* Initialize reg_hash hash table. */
849 initialise_reg_hash_table (& reg_hash
, cr16_regtab
, NUMREGS
);
850 /* Initialize regp_hash hash table. */
851 initialise_reg_hash_table (& regp_hash
, cr16_regptab
, NUMREGPS
);
852 /* Initialize preg_hash hash table. */
853 initialise_reg_hash_table (& preg_hash
, cr16_pregtab
, NUMPREGS
);
854 /* Initialize pregp_hash hash table. */
855 initialise_reg_hash_table (& pregp_hash
, cr16_pregptab
, NUMPREGPS
);
857 /* Set linkrelax here to avoid fixups in most sections. */
861 /* Process constants (immediate/absolute)
862 and labels (jump targets/Memory locations). */
865 process_label_constant (char *str
, ins
* cr16_ins
)
867 char *saved_input_line_pointer
;
868 int symbol_with_at
= 0;
869 int symbol_with_s
= 0;
870 int symbol_with_m
= 0;
871 int symbol_with_l
= 0;
872 int symbol_with_at_got
= 0;
873 int symbol_with_at_gotc
= 0;
874 argument
*cur_arg
= cr16_ins
->arg
+ cur_arg_num
; /* Current argument. */
876 saved_input_line_pointer
= input_line_pointer
;
877 input_line_pointer
= str
;
879 expression (&cr16_ins
->exp
);
881 switch (cr16_ins
->exp
.X_op
)
885 /* Missing or bad expr becomes absolute 0. */
886 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
888 cr16_ins
->exp
.X_op
= O_constant
;
889 cr16_ins
->exp
.X_add_number
= 0;
890 cr16_ins
->exp
.X_add_symbol
= NULL
;
891 cr16_ins
->exp
.X_op_symbol
= NULL
;
895 cur_arg
->X_op
= O_constant
;
896 cur_arg
->constant
= cr16_ins
->exp
.X_add_number
;
902 cur_arg
->X_op
= O_symbol
;
903 cur_arg
->constant
= cr16_ins
->exp
.X_add_number
;
904 cr16_ins
->exp
.X_add_number
= 0;
905 cr16_ins
->rtype
= BFD_RELOC_NONE
;
908 if (strneq (input_line_pointer
, "@c", 2))
911 if (strneq (input_line_pointer
, "@l", 2)
912 || strneq (input_line_pointer
, ":l", 2))
915 if (strneq (input_line_pointer
, "@m", 2)
916 || strneq (input_line_pointer
, ":m", 2))
919 if (strneq (input_line_pointer
, "@s", 2)
920 || strneq (input_line_pointer
, ":s", 2))
923 if (strneq (input_line_pointer
, "@cGOT", 5)
924 || strneq (input_line_pointer
, "@cgot", 5))
926 if (GOT_symbol
== NULL
)
927 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
929 symbol_with_at_gotc
= 1;
931 else if (strneq (input_line_pointer
, "@GOT", 4)
932 || strneq (input_line_pointer
, "@got", 4))
934 if ((strneq (input_line_pointer
, "+", 1))
935 || (strneq (input_line_pointer
, "-", 1)))
936 as_warn (_("GOT bad expression with %s."), input_line_pointer
);
938 if (GOT_symbol
== NULL
)
939 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
941 symbol_with_at_got
= 1;
944 switch (cur_arg
->type
)
947 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
949 if (symbol_with_at_got
)
950 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
951 else if (symbol_with_at_gotc
)
952 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
953 else if (cur_arg
->size
== 20)
954 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
956 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20a
;
961 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
963 if (symbol_with_at_got
)
964 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
965 else if (symbol_with_at_gotc
)
966 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
968 switch (instruction
->size
)
971 switch (cur_arg
->size
)
974 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL0
;
977 if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
978 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL4
;
980 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL4a
;
986 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL16
;
989 if (cur_arg
->size
== 20)
990 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
992 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20a
;
1001 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
1003 if (symbol_with_at_got
)
1004 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1005 else if (symbol_with_at_gotc
)
1006 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1008 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
1013 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
1015 if (symbol_with_at_got
)
1016 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1017 else if (symbol_with_at_gotc
)
1018 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1020 switch (instruction
->size
)
1022 case 1: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL0
; break;
1023 case 2: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL14
; break;
1024 case 3: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
; break;
1032 if (IS_INSN_MNEMONIC ("bal"))
1033 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP24
;
1034 else if (IS_INSN_TYPE (BRANCH_INS
))
1037 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP24
;
1038 else if (symbol_with_m
)
1039 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP16
;
1041 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP8
;
1043 else if (IS_INSN_TYPE (STOR_IMM_INS
) || IS_INSN_TYPE (LD_STOR_INS
)
1044 || IS_INSN_TYPE (CSTBIT_INS
))
1047 as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num
+ 1, str
);
1048 if (symbol_with_at_got
)
1049 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1050 else if (symbol_with_at_gotc
)
1051 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1052 else if (symbol_with_m
)
1053 cr16_ins
->rtype
= BFD_RELOC_CR16_ABS20
;
1054 else /* Default to (symbol_with_l) */
1055 cr16_ins
->rtype
= BFD_RELOC_CR16_ABS24
;
1057 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1058 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP4
;
1062 if (IS_INSN_TYPE (ARITH_INS
))
1064 if (symbol_with_at_got
)
1065 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1066 else if (symbol_with_at_gotc
)
1067 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1068 else if (symbol_with_s
)
1069 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM4
;
1070 else if (symbol_with_m
)
1071 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM20
;
1072 else if (symbol_with_at
)
1073 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM32a
;
1074 else /* Default to (symbol_with_l) */
1075 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM32
;
1077 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1079 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM16
;
1088 cur_arg
->X_op
= cr16_ins
->exp
.X_op
;
1092 input_line_pointer
= saved_input_line_pointer
;
1096 /* Retrieve the opcode image of a given register.
1097 If the register is illegal for the current instruction,
1101 getreg_image (reg r
)
1103 const reg_entry
*rreg
;
1105 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1107 /* Check whether the register is in registers table. */
1109 rreg
= cr16_regtab
+ r
;
1110 else /* Register not found. */
1112 as_bad (_("Unknown register: `%d'"), r
);
1116 reg_name
= rreg
->name
;
1118 /* Issue a error message when register is illegal. */
1120 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1121 reg_name, ins_parse);
1125 case CR16_R_REGTYPE
:
1132 case CR16_P_REGTYPE
:
1144 /* Parsing different types of operands
1145 -> constants Immediate/Absolute/Relative numbers
1146 -> Labels Relocatable symbols
1147 -> (reg pair base) Register pair base
1148 -> (rbase) Register base
1149 -> disp(rbase) Register relative
1150 -> [rinx]disp(reg pair) Register index with reg pair mode
1151 -> disp(rbase,ridx,scl) Register index mode. */
1154 set_operand (char *operand
, ins
* cr16_ins
)
1156 char *operandS
; /* Pointer to start of sub-operand. */
1157 char *operandE
; /* Pointer to end of sub-operand. */
1159 argument
*cur_arg
= &cr16_ins
->arg
[cur_arg_num
]; /* Current argument. */
1161 /* Initialize pointers. */
1162 operandS
= operandE
= operand
;
1164 switch (cur_arg
->type
)
1166 case arg_ic
: /* Case $0x18. */
1169 case arg_c
: /* Case 0x18. */
1171 process_label_constant (operandS
, cr16_ins
);
1173 if (cur_arg
->type
!= arg_ic
)
1174 cur_arg
->type
= arg_c
;
1177 case arg_icr
: /* Case $0x18(r1). */
1179 case arg_cr
: /* Case 0x18(r1). */
1180 /* Set displacement constant. */
1181 while (*operandE
!= '(')
1184 process_label_constant (operandS
, cr16_ins
);
1185 operandS
= operandE
;
1187 case arg_rbase
: /* Case (r1) or (r1,r0). */
1189 /* Set register base. */
1190 while (*operandE
!= ')')
1193 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
1194 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1195 operandS
, ins_parse
);
1197 /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1198 if ((cur_arg
->type
!= arg_rbase
)
1199 && ((getreg_image (cur_arg
->r
) == 12)
1200 || (getreg_image (cur_arg
->r
) == 13)
1201 || (getreg_image (cur_arg
->r
) == 14)
1202 || (getreg_image (cur_arg
->r
) == 15)))
1204 cur_arg
->type
= arg_crp
;
1205 cur_arg
->rp
= cur_arg
->r
;
1209 case arg_crp
: /* Case 0x18(r1,r0). */
1210 /* Set displacement constant. */
1211 while (*operandE
!= '(')
1214 process_label_constant (operandS
, cr16_ins
);
1215 operandS
= operandE
;
1217 /* Set register pair base. */
1218 while (*operandE
!= ')')
1221 if ((cur_arg
->rp
= get_register_pair (operandS
)) == nullregister
)
1222 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1223 operandS
, ins_parse
);
1227 /* Set register pair base. */
1228 if ((strchr (operandS
,'(') != NULL
))
1230 while ((*operandE
!= '(') && (! ISSPACE (*operandE
)))
1232 if ((cur_arg
->rp
= get_index_register_pair (operandE
)) == nullregister
)
1233 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1234 operandS
, ins_parse
);
1236 cur_arg
->type
= arg_idxrp
;
1241 operandE
= operandS
;
1242 /* Set displacement constant. */
1243 while (*operandE
!= ']')
1245 process_label_constant (++operandE
, cr16_ins
);
1247 operandE
= operandS
;
1249 /* Set index register . */
1250 operandS
= strchr (operandE
,'[');
1251 if (operandS
!= NULL
)
1252 { /* Eliminate '[', detach from rest of operand. */
1255 operandE
= strchr (operandS
, ']');
1257 if (operandE
== NULL
)
1258 as_bad (_("unmatched '['"));
1260 { /* Eliminate ']' and make sure it was the last thing
1263 if (*(operandE
+ 1) != '\0')
1264 as_bad (_("garbage after index spec ignored"));
1268 if ((cur_arg
->i_r
= get_index_register (operandS
)) == nullregister
)
1269 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1270 operandS
, ins_parse
);
1280 /* Parse a single operand.
1281 operand - Current operand to parse.
1282 cr16_ins - Current assembled instruction. */
1285 parse_operand (char *operand
, ins
* cr16_ins
)
1288 argument
*cur_arg
= cr16_ins
->arg
+ cur_arg_num
; /* Current argument. */
1290 /* Initialize the type to NULL before parsing. */
1291 cur_arg
->type
= nullargs
;
1293 /* Check whether this is a condition code . */
1294 if ((IS_INSN_MNEMONIC ("b")) && ((ret_val
= get_cc (operand
)) != -1))
1296 cur_arg
->type
= arg_cc
;
1297 cur_arg
->cc
= ret_val
;
1298 cur_arg
->X_op
= O_register
;
1302 /* Check whether this is a general processor register. */
1303 if ((ret_val
= get_register (operand
)) != nullregister
)
1305 cur_arg
->type
= arg_r
;
1306 cur_arg
->r
= ret_val
;
1311 /* Check whether this is a general processor register pair. */
1312 if ((operand
[0] == '(')
1313 && ((ret_val
= get_register_pair (operand
)) != nullregister
))
1315 cur_arg
->type
= arg_rp
;
1316 cur_arg
->rp
= ret_val
;
1317 cur_arg
->X_op
= O_register
;
1321 /* Check whether the operand is a processor register.
1322 For "lprd" and "sprd" instruction, only 32 bit
1323 processor registers used. */
1324 if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
1325 && ((ret_val
= get_pregister (operand
)) != nullpregister
))
1327 cur_arg
->type
= arg_pr
;
1328 cur_arg
->pr
= ret_val
;
1329 cur_arg
->X_op
= O_register
;
1333 /* Check whether this is a processor register - 32 bit. */
1334 if ((ret_val
= get_pregisterp (operand
)) != nullpregister
)
1336 cur_arg
->type
= arg_prp
;
1337 cur_arg
->prp
= ret_val
;
1338 cur_arg
->X_op
= O_register
;
1342 /* Deal with special characters. */
1346 if (strchr (operand
, '(') != NULL
)
1347 cur_arg
->type
= arg_icr
;
1349 cur_arg
->type
= arg_ic
;
1354 cur_arg
->type
= arg_rbase
;
1359 cur_arg
->type
= arg_idxr
;
1367 if (strchr (operand
, '(') != NULL
)
1369 if (strchr (operand
, ',') != NULL
1370 && (strchr (operand
, ',') > strchr (operand
, '(')))
1371 cur_arg
->type
= arg_crp
;
1373 cur_arg
->type
= arg_cr
;
1376 cur_arg
->type
= arg_c
;
1378 /* Parse an operand according to its type. */
1380 cur_arg
->constant
= 0;
1381 set_operand (operand
, cr16_ins
);
1384 /* Parse the various operands. Each operand is then analyzed to fillup
1385 the fields in the cr16_ins data structure. */
1388 parse_operands (ins
* cr16_ins
, char *operands
)
1390 char *operandS
; /* Operands string. */
1391 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
1392 int allocated
= 0; /* Indicates a new operands string was allocated.*/
1393 char *operand
[MAX_OPERANDS
];/* Separating the operands. */
1394 int op_num
= 0; /* Current operand number we are parsing. */
1395 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
1396 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
1398 /* Preprocess the list of registers, if necessary. */
1399 operandS
= operandH
= operandT
= operands
;
1401 while (*operandT
!= '\0')
1403 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
1406 operand
[op_num
++] = strdup (operandH
);
1407 operandH
= operandT
;
1411 if (*operandT
== ' ')
1412 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
1414 if (*operandT
== '(')
1416 else if (*operandT
== '[')
1417 sq_bracket_flag
= 1;
1419 if (*operandT
== ')')
1424 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1426 else if (*operandT
== ']')
1428 if (sq_bracket_flag
)
1429 sq_bracket_flag
= 0;
1431 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1434 if (bracket_flag
== 1 && *operandT
== ')')
1436 else if (sq_bracket_flag
== 1 && *operandT
== ']')
1437 sq_bracket_flag
= 0;
1442 /* Adding the last operand. */
1443 operand
[op_num
++] = strdup (operandH
);
1444 cr16_ins
->nargs
= op_num
;
1446 /* Verifying correct syntax of operands (all brackets should be closed). */
1447 if (bracket_flag
|| sq_bracket_flag
)
1448 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1450 /* Now we parse each operand separately. */
1451 for (op_num
= 0; op_num
< cr16_ins
->nargs
; op_num
++)
1453 cur_arg_num
= op_num
;
1454 parse_operand (operand
[op_num
], cr16_ins
);
1455 free (operand
[op_num
]);
1462 /* Get the trap index in dispatch table, given its name.
1463 This routine is used by assembling the 'excp' instruction. */
1468 const trap_entry
*trap
;
1470 for (trap
= cr16_traps
; trap
< (cr16_traps
+ NUMTRAPS
); trap
++)
1471 if (strcasecmp (trap
->name
, s
) == 0)
1474 /* To make compatible with CR16 4.1 tools, the below 3-lines of
1475 * code added. Refer: Development Tracker item #123 */
1476 for (trap
= cr16_traps
; trap
< (cr16_traps
+ NUMTRAPS
); trap
++)
1477 if (trap
->entry
== (unsigned int) atoi (s
))
1480 as_bad (_("Unknown exception: `%s'"), s
);
1484 /* Top level module where instruction parsing starts.
1485 cr16_ins - data structure holds some information.
1486 operands - holds the operands part of the whole instruction. */
1489 parse_insn (ins
*insn
, char *operands
)
1493 /* Handle instructions with no operands. */
1494 for (i
= 0; cr16_no_op_insn
[i
] != NULL
; i
++)
1496 if (streq (cr16_no_op_insn
[i
], instruction
->mnemonic
))
1503 /* Handle 'excp' instructions. */
1504 if (IS_INSN_MNEMONIC ("excp"))
1507 insn
->arg
[0].type
= arg_ic
;
1508 insn
->arg
[0].constant
= gettrap (operands
);
1509 insn
->arg
[0].X_op
= O_constant
;
1513 if (operands
!= NULL
)
1514 parse_operands (insn
, operands
);
1517 /* bCC instruction requires special handling. */
1519 get_b_cc (char * op
)
1523 if (op
[1] == 0 || (op
[2] != 0 && op
[3] != 0))
1526 for (i
= 0; i
< cr16_num_cc
; i
++)
1527 if (streq (op
+ 1, cr16_b_cond_tab
[i
]))
1528 return (char *) cr16_b_cond_tab
[i
];
1533 /* bCC instruction requires special handling. */
1535 is_bcc_insn (char * op
)
1537 if (!(streq (op
, "bal") || streq (op
, "beq0b") || streq (op
, "bnq0b")
1538 || streq (op
, "beq0w") || streq (op
, "bnq0w")))
1539 if ((op
[0] == 'b') && (get_b_cc (op
) != NULL
))
1544 /* Cinv instruction requires special handling. */
1547 check_cinv_options (char * operand
)
1562 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1567 /* Retrieve the opcode image of a given register pair.
1568 If the register is illegal for the current instruction,
1572 getregp_image (reg r
)
1574 const reg_entry
*rreg
;
1577 /* Check whether the register is in registers table. */
1579 rreg
= cr16_regptab
+ r
;
1580 /* Register not found. */
1583 as_bad (_("Unknown register pair: `%d'"), r
);
1587 reg_name
= rreg
->name
;
1589 /* Issue a error message when register pair is illegal. */
1590 #define RPAIR_IMAGE_ERR \
1591 as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1592 reg_name, ins_parse); \
1597 case CR16_RP_REGTYPE
:
1606 /* Retrieve the opcode image of a given index register pair.
1607 If the register is illegal for the current instruction,
1611 getidxregp_image (reg r
)
1613 const reg_entry
*rreg
;
1616 /* Check whether the register is in registers table. */
1618 rreg
= cr16_regptab
+ r
;
1619 /* Register not found. */
1622 as_bad (_("Unknown register pair: `%d'"), r
);
1626 reg_name
= rreg
->name
;
1628 /* Issue a error message when register pair is illegal. */
1629 #define IDX_RPAIR_IMAGE_ERR \
1630 as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1631 reg_name, ins_parse); \
1633 if (rreg->type == CR16_RP_REGTYPE)
1635 switch (rreg
->image
)
1637 case 0: return 0; break;
1638 case 2: return 1; break;
1639 case 4: return 2; break;
1640 case 6: return 3; break;
1641 case 8: return 4; break;
1642 case 10: return 5; break;
1643 case 3: return 6; break;
1644 case 5: return 7; break;
1650 IDX_RPAIR_IMAGE_ERR
;
1654 /* Retrieve the opcode image of a given processor register.
1655 If the register is illegal for the current instruction,
1658 getprocreg_image (int r
)
1660 const reg_entry
*rreg
;
1663 /* Check whether the register is in registers table. */
1664 if (r
>= MAX_REG
&& r
< MAX_PREG
)
1665 rreg
= &cr16_pregtab
[r
- MAX_REG
];
1666 /* Register not found. */
1669 as_bad (_("Unknown processor register : `%d'"), r
);
1673 reg_name
= rreg
->name
;
1675 /* Issue a error message when register pair is illegal. */
1676 #define PROCREG_IMAGE_ERR \
1677 as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1678 reg_name, ins_parse); \
1683 case CR16_P_REGTYPE
:
1692 /* Retrieve the opcode image of a given processor register.
1693 If the register is illegal for the current instruction,
1696 getprocregp_image (int r
)
1698 const reg_entry
*rreg
;
1700 int pregptab_disp
= 0;
1702 /* Check whether the register is in registers table. */
1703 if (r
>= MAX_REG
&& r
< MAX_PREG
)
1708 case 4: pregptab_disp
= 1; break;
1709 case 6: pregptab_disp
= 2; break;
1713 pregptab_disp
= 3; break;
1715 pregptab_disp
= 4; break;
1717 pregptab_disp
= 5; break;
1720 rreg
= &cr16_pregptab
[r
- pregptab_disp
];
1722 /* Register not found. */
1725 as_bad (_("Unknown processor register (32 bit) : `%d'"), r
);
1729 reg_name
= rreg
->name
;
1731 /* Issue a error message when register pair is illegal. */
1732 #define PROCREGP_IMAGE_ERR \
1733 as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"), \
1734 reg_name, ins_parse); \
1739 case CR16_P_REGTYPE
:
1748 /* Routine used to represent integer X using NBITS bits. */
1751 getconstant (long x
, int nbits
)
1753 if ((unsigned) nbits
>= sizeof (x
) * CHAR_BIT
)
1755 return x
& ((1UL << nbits
) - 1);
1758 /* Print a constant value to 'output_opcode':
1759 ARG holds the operand's type and value.
1760 SHIFT represents the location of the operand to be print into.
1761 NBITS determines the size (in bits) of the constant. */
1764 print_constant (int nbits
, int shift
, argument
*arg
)
1766 unsigned long mask
= 0;
1767 unsigned long constant
= getconstant (arg
->constant
, nbits
);
1773 /* mask the upper part of the constant, that is, the bits
1774 going to the lowest byte of output_opcode[0].
1775 The upper part of output_opcode[1] is always filled,
1776 therefore it is always masked with 0xFFFF. */
1777 mask
= (1 << (nbits
- 16)) - 1;
1778 /* Divide the constant between two consecutive words :
1780 +---------+---------+---------+---------+
1781 | | X X X X | x X x X | |
1782 +---------+---------+---------+---------+
1783 output_opcode[0] output_opcode[1] */
1785 CR16_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1786 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1790 if ((nbits
== 21) && (IS_INSN_TYPE (LD_STOR_INS
)))
1796 /* mask the upper part of the constant, that is, the bits
1797 going to the lowest byte of output_opcode[0].
1798 The upper part of output_opcode[1] is always filled,
1799 therefore it is always masked with 0xFFFF. */
1800 mask
= (1 << (nbits
- 16)) - 1;
1801 /* Divide the constant between two consecutive words :
1803 +---------+---------+---------+---------+
1804 | | X X X X | - X - X | |
1805 +---------+---------+---------+---------+
1806 output_opcode[0] output_opcode[1] */
1808 if (instruction
->size
> 2 && shift
== WORD_SHIFT
)
1810 if (arg
->type
== arg_idxrp
)
1812 CR16_PRINT (0, ((constant
>> WORD_SHIFT
) & mask
) << 8, 0);
1813 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1818 ((((constant
>> WORD_SHIFT
) & mask
& 0xf) << 8)
1819 | (((constant
>> WORD_SHIFT
) & mask
& 0xf0) >> 4)),
1821 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1825 CR16_PRINT (0, constant
, shift
);
1829 if (arg
->type
== arg_idxrp
)
1831 if (instruction
->size
== 2)
1833 CR16_PRINT (0, (constant
) & 0xf, shift
); /* 0-3 bits. */
1834 CR16_PRINT (0, (constant
>> 4) & 0x3, shift
+ 20); /* 4-5 bits. */
1835 CR16_PRINT (0, (constant
>> 6) & 0x3, shift
+ 14); /* 6-7 bits. */
1836 CR16_PRINT (0, (constant
>> 8) & 0x3f, shift
+ 8); /* 8-13 bits. */
1839 CR16_PRINT (0, constant
, shift
);
1845 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1846 always filling the upper part of output_opcode[1]. If we mistakenly
1847 write it to output_opcode[0], the constant prefix (that is, 'match')
1850 +---------+---------+---------+---------+
1851 | 'match' | | X X X X | |
1852 +---------+---------+---------+---------+
1853 output_opcode[0] output_opcode[1] */
1855 if (instruction
->size
> 2 && shift
== WORD_SHIFT
)
1856 CR16_PRINT (1, constant
, WORD_SHIFT
);
1858 CR16_PRINT (0, constant
, shift
);
1862 CR16_PRINT (0, (constant
/ 2) & 0xf, shift
);
1863 CR16_PRINT (0, (constant
/ 2) >> 4, shift
+ 8);
1867 CR16_PRINT (0, constant
, shift
);
1872 /* Print an operand to 'output_opcode', which later on will be
1873 printed to the object file:
1874 ARG holds the operand's type, size and value.
1875 SHIFT represents the printing location of operand.
1876 NBITS determines the size (in bits) of a constant operand. */
1879 print_operand (int nbits
, int shift
, argument
*arg
)
1884 CR16_PRINT (0, arg
->cc
, shift
);
1888 CR16_PRINT (0, getreg_image (arg
->r
), shift
);
1892 CR16_PRINT (0, getregp_image (arg
->rp
), shift
);
1896 CR16_PRINT (0, getprocreg_image (arg
->pr
), shift
);
1900 CR16_PRINT (0, getprocregp_image (arg
->prp
), shift
);
1905 +-----------------------------+
1906 | r_index | disp | rp_base |
1907 +-----------------------------+ */
1909 if (instruction
->size
== 3)
1911 CR16_PRINT (0, getidxregp_image (arg
->rp
), 0);
1912 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1, 3);
1916 CR16_PRINT (0, getidxregp_image (arg
->rp
), 16);
1917 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1, 19);
1919 print_constant (nbits
, shift
, arg
);
1923 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1,
1924 (IS_INSN_TYPE (CSTBIT_INS
)
1925 && instruction
->mnemonic
[4] == 'b') ? 23 : 24);
1926 print_constant (nbits
, shift
, arg
);
1931 print_constant (nbits
, shift
, arg
);
1935 CR16_PRINT (0, getreg_image (arg
->r
), shift
);
1939 print_constant (nbits
, shift
, arg
);
1940 /* Add the register argument to the output_opcode. */
1941 CR16_PRINT (0, getreg_image (arg
->r
), shift
- 16);
1945 print_constant (nbits
, shift
, arg
);
1946 if ((IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
1947 && instruction
->size
== 1)
1948 CR16_PRINT (0, getregp_image (arg
->rp
), 16);
1949 else if (instruction
->size
> 1)
1950 CR16_PRINT (0, getregp_image (arg
->rp
), (shift
+ 16) & 31);
1952 CR16_PRINT (0, getregp_image (arg
->rp
), shift
);
1960 /* Retrieve the number of operands for the current assembled instruction. */
1963 get_number_of_operands (void)
1967 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1972 /* Verify that the number NUM can be represented in BITS bits (that is,
1973 within its permitted range), based on the instruction's FLAGS.
1974 If UPDATE is nonzero, update the value of NUM if necessary.
1975 Return OP_LEGAL upon success, actual error type upon failure. */
1978 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1981 op_err retval
= OP_LEGAL
;
1982 int32_t value
= *num
;
1984 /* Verify operand value is even. */
1985 if (flags
& OP_EVEN
)
1998 if (flags
& OP_SHIFT
)
2004 else if (flags
& OP_SHIFT_DEC
)
2006 value
= (value
>> 1) - 1;
2011 if (flags
& OP_ABS20
)
2013 if (value
> 0xEFFFF)
2014 return OP_OUT_OF_RANGE
;
2019 if (value
== 0xB || value
== 0x9)
2020 return OP_OUT_OF_RANGE
;
2021 else if (value
== -1)
2029 if (flags
& OP_ESC1
)
2032 return OP_OUT_OF_RANGE
;
2038 retval
= OP_OUT_OF_RANGE
;
2042 if (flags
& OP_SIGNED
)
2044 max
= (1U << (bits
- 1)) - 1;
2045 min
= - (1U << (bits
- 1));
2046 if (value
> max
|| value
< min
)
2047 retval
= OP_OUT_OF_RANGE
;
2049 else if (flags
& OP_UNSIGNED
)
2051 max
= (1U << (bits
- 1) << 1) - 1;
2052 if ((uint32_t) value
> (uint32_t) max
)
2053 retval
= OP_OUT_OF_RANGE
;
2055 else if (flags
& OP_NEG
)
2057 min
= - ((1U << (bits
- 1)) - 1);
2059 retval
= OP_OUT_OF_RANGE
;
2064 /* Bunch of error checking.
2065 The checks are made after a matching instruction was found. */
2068 warn_if_needed (ins
*insn
)
2070 /* If the post-increment address mode is used and the load/store
2071 source register is the same as rbase, the result of the
2072 instruction is undefined. */
2073 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
2075 /* Enough to verify that one of the arguments is a simple reg. */
2076 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
2077 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
2078 as_bad (_("Same src/dest register is used (`r%d'), "
2079 "result is undefined"), insn
->arg
[0].r
);
2082 if (IS_INSN_MNEMONIC ("pop")
2083 || IS_INSN_MNEMONIC ("push")
2084 || IS_INSN_MNEMONIC ("popret"))
2086 unsigned int count
= insn
->arg
[0].constant
, reg_val
;
2088 /* Check if count operand caused to save/retrieve the RA twice
2089 to generate warning message. */
2090 if (insn
->nargs
> 2)
2092 reg_val
= getreg_image (insn
->arg
[1].r
);
2094 if ( ((reg_val
== 9) && (count
> 7))
2095 || ((reg_val
== 10) && (count
> 6))
2096 || ((reg_val
== 11) && (count
> 5))
2097 || ((reg_val
== 12) && (count
> 4))
2098 || ((reg_val
== 13) && (count
> 2))
2099 || ((reg_val
== 14) && (count
> 0)))
2100 as_warn (_("RA register is saved twice."));
2102 /* Check if the third operand is "RA" or "ra" */
2103 if (!(((insn
->arg
[2].r
) == ra
) || ((insn
->arg
[2].r
) == RA
)))
2104 as_bad (_("`%s' Illegal use of registers."), ins_parse
);
2107 if (insn
->nargs
> 1)
2109 reg_val
= getreg_image (insn
->arg
[1].r
);
2111 /* If register is a register pair ie r12/r13/r14 in operand1, then
2112 the count constant should be validated. */
2113 if (((reg_val
== 11) && (count
> 7))
2114 || ((reg_val
== 12) && (count
> 6))
2115 || ((reg_val
== 13) && (count
> 4))
2116 || ((reg_val
== 14) && (count
> 2))
2117 || ((reg_val
== 15) && (count
> 0)))
2118 as_bad (_("`%s' Illegal count-register combination."), ins_parse
);
2122 /* Check if the operand is "RA" or "ra" */
2123 if (!(((insn
->arg
[0].r
) == ra
) || ((insn
->arg
[0].r
) == RA
)))
2124 as_bad (_("`%s' Illegal use of register."), ins_parse
);
2128 /* Some instruction assume the stack pointer as rptr operand.
2129 Issue an error when the register to be loaded is also SP. */
2130 if (instruction
->flags
& NO_SP
)
2132 if (getreg_image (insn
->arg
[1].r
) == getreg_image (sp
))
2133 as_bad (_("`%s' has undefined result"), ins_parse
);
2136 /* If the rptr register is specified as one of the registers to be loaded,
2137 the final contents of rptr are undefined. Thus, we issue an error. */
2138 if (instruction
->flags
& NO_RPTR
)
2140 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
2141 as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2142 getreg_image (insn
->arg
[0].r
));
2146 /* In some cases, we need to adjust the instruction pointer although a
2147 match was already found. Here, we gather all these cases.
2148 Returns 1 if instruction pointer was adjusted, otherwise 0. */
2151 adjust_if_needed (ins
*insn ATTRIBUTE_UNUSED
)
2155 if ((IS_INSN_TYPE (CSTBIT_INS
)) || (IS_INSN_TYPE (LD_STOR_INS
)))
2157 if ((instruction
->operands
[0].op_type
== abs24
)
2158 && ((insn
->arg
[0].constant
) > 0xF00000))
2160 insn
->arg
[0].constant
&= 0xFFFFF;
2169 /* Assemble a single instruction:
2170 INSN is already parsed (that is, all operand values and types are set).
2171 For instruction to be assembled, we need to find an appropriate template in
2172 the instruction table, meeting the following conditions:
2173 1: Has the same number of operands.
2174 2: Has the same operand types.
2175 3: Each operand size is sufficient to represent the instruction's values.
2176 Returns 1 upon success, 0 upon failure. */
2179 assemble_insn (const char *mnemonic
, ins
*insn
)
2181 /* Type of each operand in the current template. */
2182 argtype cur_type
[MAX_OPERANDS
];
2183 /* Size (in bits) of each operand in the current template. */
2184 unsigned int cur_size
[MAX_OPERANDS
];
2185 /* Flags of each operand in the current template. */
2186 unsigned int cur_flags
[MAX_OPERANDS
];
2187 /* Instruction type to match. */
2188 unsigned int ins_type
;
2189 /* Boolean flag to mark whether a match was found. */
2192 /* Nonzero if an instruction with same number of operands was found. */
2193 int found_same_number_of_operands
= 0;
2194 /* Nonzero if an instruction with same argument types was found. */
2195 int found_same_argument_types
= 0;
2196 /* Nonzero if a constant was found within the required range. */
2197 int found_const_within_range
= 0;
2198 /* Argument number of an operand with invalid type. */
2199 int invalid_optype
= -1;
2200 /* Argument number of an operand with invalid constant value. */
2201 int invalid_const
= -1;
2202 /* Operand error (used for issuing various constant error messages). */
2203 op_err op_error
, const_err
= OP_LEGAL
;
2205 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
2206 #define GET_CURRENT_DATA(FUNC, ARRAY) \
2207 for (i = 0; i < insn->nargs; i++) \
2208 ARRAY[i] = FUNC (instruction->operands[i].op_type)
2210 #define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type)
2211 #define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size)
2212 #define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags)
2214 /* Instruction has no operands -> only copy the constant opcode. */
2215 if (insn
->nargs
== 0)
2217 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2221 /* In some case, same mnemonic can appear with different instruction types.
2222 For example, 'storb' is supported with 3 different types :
2223 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2224 We assume that when reaching this point, the instruction type was
2225 pre-determined. We need to make sure that the type stays the same
2226 during a search for matching instruction. */
2227 ins_type
= CR16_INS_TYPE (instruction
->flags
);
2229 while (/* Check that match is still not found. */
2231 /* Check we didn't get to end of table. */
2232 && instruction
->mnemonic
!= NULL
2233 /* Check that the actual mnemonic is still available. */
2234 && IS_INSN_MNEMONIC (mnemonic
)
2235 /* Check that the instruction type wasn't changed. */
2236 && IS_INSN_TYPE (ins_type
))
2238 /* Check whether number of arguments is legal. */
2239 if (get_number_of_operands () != insn
->nargs
)
2241 found_same_number_of_operands
= 1;
2243 /* Initialize arrays with data of each operand in current template. */
2248 /* Check for type compatibility. */
2249 for (i
= 0; i
< insn
->nargs
; i
++)
2251 if (cur_type
[i
] != insn
->arg
[i
].type
)
2253 if (invalid_optype
== -1)
2254 invalid_optype
= i
+ 1;
2258 found_same_argument_types
= 1;
2260 for (i
= 0; i
< insn
->nargs
; i
++)
2262 /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2263 then goto next instruction. */
2264 if (IS_INSN_MNEMONIC ("bal") && (i
== 0)
2265 && (instruction
->size
== 2) && (insn
->arg
[i
].rp
!= 14))
2268 /* If 'storb' instruction with 'sp' reg and 16-bit disp of
2269 * reg-pair, leads to undefined trap, so this should use
2270 * 20-bit disp of reg-pair. */
2271 if (IS_INSN_MNEMONIC ("storb") && (instruction
->size
== 2)
2272 && (insn
->arg
[i
].r
== 15) && (insn
->arg
[i
+ 1].type
== arg_crp
))
2275 /* Only check range - don't update the constant's value, since the
2276 current instruction may not be the last we try to match.
2277 The constant's value will be updated later, right before printing
2278 it to the object file. */
2279 if ((insn
->arg
[i
].X_op
== O_constant
)
2280 && (op_error
= check_range (&insn
->arg
[i
].constant
, cur_size
[i
],
2283 if (invalid_const
== -1)
2285 invalid_const
= i
+ 1;
2286 const_err
= op_error
;
2290 /* For symbols, we make sure the relocation size (which was already
2291 determined) is sufficient. */
2292 else if ((insn
->arg
[i
].X_op
== O_symbol
)
2293 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
2297 found_const_within_range
= 1;
2299 /* If we got till here -> Full match is found. */
2303 /* Try again with next instruction. */
2310 /* We haven't found a match - instruction can't be assembled. */
2311 if (!found_same_number_of_operands
)
2312 as_bad (_("Incorrect number of operands"));
2313 else if (!found_same_argument_types
)
2314 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
2315 else if (!found_const_within_range
)
2319 case OP_OUT_OF_RANGE
:
2320 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
2323 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
2326 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
2334 /* Full match - print the encoding to output file. */
2336 /* Make further checking (such that couldn't be made earlier).
2337 Warn the user if necessary. */
2338 warn_if_needed (insn
);
2340 /* Check whether we need to adjust the instruction pointer. */
2341 if (adjust_if_needed (insn
))
2342 /* If instruction pointer was adjusted, we need to update
2343 the size of the current template operands. */
2346 for (i
= 0; i
< insn
->nargs
; i
++)
2348 int j
= instruction
->flags
& REVERSE_MATCH
?
2353 /* This time, update constant value before printing it. */
2354 if ((insn
->arg
[j
].X_op
== O_constant
)
2355 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
2356 cur_flags
[j
], 1) != OP_LEGAL
))
2357 as_fatal (_("Illegal operand (arg %d)"), j
+1);
2360 /* First, copy the instruction's opcode. */
2361 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2363 for (i
= 0; i
< insn
->nargs
; i
++)
2365 /* For BAL (ra),disp17 instruction only. And also set the
2366 DISP24a relocation type. */
2367 if (IS_INSN_MNEMONIC ("bal") && (instruction
->size
== 2) && i
== 0)
2369 insn
->rtype
= BFD_RELOC_CR16_DISP24a
;
2373 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
2381 /* Print the instruction.
2382 Handle also cases where the instruction is relaxable/relocatable. */
2385 print_insn (ins
*insn
)
2387 unsigned int i
, j
, insn_size
;
2389 unsigned short words
[4];
2392 /* Arrange the insn encodings in a WORD size array. */
2393 for (i
= 0, j
= 0; i
< 2; i
++)
2395 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
2396 words
[j
++] = output_opcode
[i
] & 0xFFFF;
2399 /* Handle relocation. */
2400 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
2403 /* Write the maximal instruction size supported. */
2404 insn_size
= INSN_MAX_SIZE
;
2406 if (IS_INSN_TYPE (BRANCH_INS
))
2408 switch (insn
->rtype
)
2410 case BFD_RELOC_CR16_DISP24
:
2413 case BFD_RELOC_CR16_DISP16
:
2424 this_frag
= frag_var (rs_machine_dependent
, insn_size
*2,
2426 insn
->exp
.X_add_symbol
,
2432 insn_size
= instruction
->size
;
2433 this_frag
= frag_more (insn_size
* 2);
2435 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
2437 reloc_howto_type
*reloc_howto
;
2440 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
2445 size
= bfd_get_reloc_size (reloc_howto
);
2447 if (size
< 1 || size
> 4)
2450 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
2451 size
, &insn
->exp
, reloc_howto
->pc_relative
,
2456 /* Verify a 2-byte code alignment. */
2457 addr_mod
= frag_now_fix () & 1;
2458 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
2459 as_bad (_("instruction address is not a multiple of 2"));
2460 frag_now
->insn_addr
= addr_mod
;
2461 frag_now
->has_code
= 1;
2463 /* Write the instruction encoding to frag. */
2464 for (i
= 0; i
< insn_size
; i
++)
2466 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
2471 /* Actually assemble an instruction. */
2474 cr16_assemble (const char *op
, char *param
)
2478 /* Find the instruction. */
2479 instruction
= (const inst
*) str_hash_find (cr16_inst_hash
, op
);
2480 if (instruction
== NULL
)
2482 as_bad (_("Unknown opcode: `%s'"), op
);
2486 /* Tie dwarf2 debug info to the address at the start of the insn. */
2487 dwarf2_emit_insn (0);
2489 /* Parse the instruction's operands. */
2490 parse_insn (&cr16_ins
, param
);
2492 /* Assemble the instruction - return upon failure. */
2493 if (assemble_insn (op
, &cr16_ins
) == 0)
2496 /* Print the instruction. */
2497 print_insn (&cr16_ins
);
2500 /* This is the guts of the machine-dependent assembler. OP points to a
2501 machine dependent instruction. This function is supposed to emit
2502 the frags/bytes it assembles to. */
2505 md_assemble (char *op
)
2508 char *param
, param1
[32];
2510 /* Reset global variables for a new instruction. */
2513 /* Strip the mnemonic. */
2514 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
2518 /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
2519 if (is_bcc_insn (op
))
2521 strcpy (param1
, get_b_cc (op
));
2522 strcat (param1
,",");
2523 strcat (param1
, param
);
2524 param
= (char *) ¶m1
;
2525 cr16_assemble ("b", param
);
2529 /* Checking the cinv options and adjust the mnemonic by removing the
2530 extra white spaces. */
2531 if (streq ("cinv", op
))
2533 /* Validate the cinv options. */
2534 unsigned int op_len
, param_len
;
2535 check_cinv_options (param
);
2536 op_len
= strlen (op
);
2537 param_len
= strlen (param
) + 1;
2538 memmove (op
+ op_len
, param
, param_len
);
2541 /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2542 lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
2543 as CR16 core doesn't support lsh[b/w] right shift operations. */
2544 if ((streq ("lshb", op
) || streq ("lshw", op
) || streq ("lshd", op
))
2545 && (param
[0] == '$'))
2547 strcpy (param1
, param
);
2548 /* Find the instruction. */
2549 instruction
= (const inst
*) str_hash_find (cr16_inst_hash
, op
);
2550 parse_operands (&cr16_ins
, param1
);
2551 if (((&cr16_ins
)->arg
[0].type
== arg_ic
)
2552 && ((&cr16_ins
)->arg
[0].constant
>= 0))
2554 if (streq ("lshb", op
))
2555 cr16_assemble ("ashub", param
);
2556 else if (streq ("lshd", op
))
2557 cr16_assemble ("ashud", param
);
2559 cr16_assemble ("ashuw", param
);
2564 cr16_assemble (op
, param
);