1 /* tc-cr16.c -- Assembler code for the CR16 CPU core.
2 Copyright (C) 2007-2023 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"
34 /* Word is considered here as a 16-bit unsigned short int. */
37 /* Register is 2-byte size. */
40 /* Maximum size of a single instruction (in words). */
41 #define INSN_MAX_SIZE 3
43 /* Maximum bits which may be set in a `mask16' operand. */
44 #define MAX_REGS_IN_MASK16 8
46 /* Assign a number NUM, shifted by SHIFT bytes, into a location
47 pointed by index BYTE of array 'output_opcode'. */
48 #define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT)
53 OP_LEGAL
= 0, /* Legal operand. */
54 OP_OUT_OF_RANGE
, /* Operand not within permitted range. */
55 OP_NOT_EVEN
/* Operand is Odd number, should be even. */
59 /* Opcode mnemonics hash table. */
60 static htab_t cr16_inst_hash
;
61 /* CR16 registers hash table. */
62 static htab_t reg_hash
;
63 /* CR16 register pair hash table. */
64 static htab_t regp_hash
;
65 /* CR16 processor registers hash table. */
66 static htab_t preg_hash
;
67 /* CR16 processor registers 32 bit hash table. */
68 static htab_t pregp_hash
;
69 /* Current instruction we're assembling. */
70 const inst
*instruction
;
73 static int code_label
= 0;
75 /* Global variables. */
77 /* Array to hold an instruction encoding. */
78 long output_opcode
[2];
80 /* Nonzero means a relocatable symbol. */
83 /* A copy of the original instruction (used in error messages). */
84 char ins_parse
[MAX_INST_LEN
];
86 /* The current processed argument number. */
89 /* Generic assembler global variables which must be defined by all targets. */
91 /* Characters which always start a comment. */
92 const char comment_chars
[] = "#";
94 /* Characters which start a comment at the beginning of a line. */
95 const char line_comment_chars
[] = "#";
97 /* This array holds machine specific line separator characters. */
98 const char line_separator_chars
[] = ";";
100 /* Chars that can be used to separate mant from exp in floating point nums. */
101 const char EXP_CHARS
[] = "eE";
103 /* Chars that mean this number is a floating point constant as in 0f12.456 */
104 const char FLT_CHARS
[] = "f'";
107 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
108 symbolS
* GOT_symbol
;
111 /* Target-specific multicharacter options, not const-declared at usage. */
112 const char *md_shortopts
= "";
113 struct option md_longopts
[] =
115 {NULL
, no_argument
, NULL
, 0}
117 size_t md_longopts_size
= sizeof (md_longopts
);
125 #ifdef md_flush_pending_output
126 md_flush_pending_output ();
129 if (is_it_end_of_statement ())
131 demand_empty_rest_of_line ();
135 #ifdef TC_ADDRESS_BYTES
137 nbytes
= TC_ADDRESS_BYTES ();
141 md_cons_align (nbytes
);
147 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
148 char *hold
= input_line_pointer
;
152 if (*input_line_pointer
== ':')
161 if (*input_line_pointer
!= ':')
163 input_line_pointer
= hold
;
166 if (exp
.X_op
== O_absent
)
168 as_warn (_("using a bit field width of zero"));
169 exp
.X_add_number
= 0;
170 exp
.X_op
= O_constant
;
173 if (exp
.X_op
!= O_constant
)
175 *input_line_pointer
= '\0';
176 as_bad (_("field width \"%s\" too complex for a bitfield"),
178 *input_line_pointer
= ':';
179 demand_empty_rest_of_line ();
183 if ((width
= exp
.X_add_number
) >
184 (unsigned int)(BITS_PER_CHAR
* nbytes
))
186 as_warn (ngettext ("field width %lu too big to fit in %d"
187 " byte: truncated to %d bits",
188 "field width %lu too big to fit in %d"
189 " bytes: truncated to %d bits",
191 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
192 width
= BITS_PER_CHAR
* nbytes
;
195 if (width
> bits_available
)
197 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
198 input_line_pointer
= hold
;
199 exp
.X_add_number
= value
;
204 hold
= ++input_line_pointer
;
207 if (exp
.X_op
!= O_constant
)
209 char cache
= *input_line_pointer
;
211 *input_line_pointer
= '\0';
212 as_bad (_("field value \"%s\" too complex for a bitfield"),
214 *input_line_pointer
= cache
;
215 demand_empty_rest_of_line ();
219 value
|= ((~(-(1 << width
)) & exp
.X_add_number
)
220 << ((BITS_PER_CHAR
* nbytes
) - bits_available
));
222 if ((bits_available
-= width
) == 0
223 || is_it_end_of_statement ()
224 || *input_line_pointer
!= ',')
227 hold
= ++input_line_pointer
;
231 exp
.X_add_number
= value
;
232 exp
.X_op
= O_constant
;
236 if ((*(input_line_pointer
) == '@') && (*(input_line_pointer
+1) == 'c'))
238 emit_expr (&exp
, (unsigned int) nbytes
);
240 if ((*(input_line_pointer
) == '@') && (*(input_line_pointer
+1) == 'c'))
242 input_line_pointer
+=3;
246 while ((*input_line_pointer
++ == ','));
248 /* Put terminator back into stream. */
249 input_line_pointer
--;
251 demand_empty_rest_of_line ();
254 /* This table describes all the machine specific pseudo-ops
255 the assembler has to support. The fields are:
256 *** Pseudo-op name without dot.
257 *** Function to call to execute this pseudo-op.
258 *** Integer arg to pass to the function. */
260 const pseudo_typeS md_pseudo_table
[] =
262 /* In CR16 machine, align is in bytes (not a ptwo boundary). */
263 {"align", s_align_bytes
, 0},
264 {"long", l_cons
, 4 },
265 {"4byte", l_cons
, 4 },
269 /* CR16 relaxation table. */
270 const relax_typeS md_relax_table
[] =
273 {0x7f, -0x80, 2, 1}, /* 8 */
274 {0xfffe, -0x10000, 4, 2}, /* 16 */
275 {0xfffffe, -0x1000000, 6, 0}, /* 24 */
278 /* Return the bit size for a given operand. */
281 get_opbits (operand_type op
)
284 return cr16_optab
[op
].bit_size
;
289 /* Return the argument type of a given operand. */
292 get_optype (operand_type op
)
295 return cr16_optab
[op
].arg_type
;
300 /* Return the flags of a given operand. */
303 get_opflags (operand_type op
)
306 return cr16_optab
[op
].flags
;
311 /* Get the cc code. */
314 get_cc (char *cc_name
)
318 for (i
= 0; i
< cr16_num_cc
; i
++)
319 if (strcmp (cc_name
, cr16_b_cond_tab
[i
]) == 0)
325 /* Get the core processor register 'reg_name'. */
328 get_register (char *reg_name
)
330 const reg_entry
*rreg
;
332 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
335 return rreg
->value
.reg_val
;
339 /* Get the core processor register-pair 'reg_name'. */
342 get_register_pair (char *reg_name
)
344 const reg_entry
*rreg
;
345 char tmp_rp
[16]="\0";
347 /* Add '(' and ')' to the reg pair, if it's not present. */
348 if (reg_name
[0] != '(')
351 strcat (tmp_rp
, reg_name
);
353 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, tmp_rp
);
356 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, reg_name
);
359 return rreg
->value
.reg_val
;
364 /* Get the index register 'reg_name'. */
367 get_index_register (char *reg_name
)
369 const reg_entry
*rreg
;
371 rreg
= (const reg_entry
*) str_hash_find (reg_hash
, reg_name
);
374 && ((rreg
->value
.reg_val
== 12) || (rreg
->value
.reg_val
== 13)))
375 return rreg
->value
.reg_val
;
379 /* Get the core processor index register-pair 'reg_name'. */
382 get_index_register_pair (char *reg_name
)
384 const reg_entry
*rreg
;
386 rreg
= (const reg_entry
*) str_hash_find (regp_hash
, reg_name
);
390 if ((rreg
->value
.reg_val
!= 1) || (rreg
->value
.reg_val
!= 7)
391 || (rreg
->value
.reg_val
!= 9) || (rreg
->value
.reg_val
> 10))
392 return rreg
->value
.reg_val
;
394 as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg
->value
.reg_val
);
400 /* Get the processor register 'preg_name'. */
403 get_pregister (char *preg_name
)
405 const reg_entry
*prreg
;
407 prreg
= (const reg_entry
*) str_hash_find (preg_hash
, preg_name
);
410 return prreg
->value
.preg_val
;
412 return nullpregister
;
415 /* Get the processor register 'preg_name 32 bit'. */
418 get_pregisterp (char *preg_name
)
420 const reg_entry
*prreg
;
422 prreg
= (const reg_entry
*) str_hash_find (pregp_hash
, preg_name
);
425 return prreg
->value
.preg_val
;
427 return nullpregister
;
431 /* Round up a section size to the appropriate boundary. */
434 md_section_align (segT seg
, valueT val
)
436 /* Round .text section to a multiple of 2. */
437 if (seg
== text_section
)
438 return (val
+ 1) & ~1;
442 /* Parse an operand that is machine-specific (remove '*'). */
445 md_operand (expressionS
* exp
)
447 char c
= *input_line_pointer
;
452 input_line_pointer
++;
460 /* Reset global variables before parsing a new instruction. */
463 reset_vars (char *op
)
465 cur_arg_num
= relocatable
= 0;
466 memset (& output_opcode
, '\0', sizeof (output_opcode
));
468 /* Save a copy of the original OP (used in error messages). */
469 strncpy (ins_parse
, op
, sizeof ins_parse
- 1);
470 ins_parse
[sizeof ins_parse
- 1] = 0;
473 /* This macro decides whether a particular reloc is an entry in a
474 switch table. It is used when relaxing, because the linker needs
475 to know about all such entries so that it can adjust them if
478 #define SWITCH_TABLE(fix) \
479 ((fix)->fx_addsy != NULL \
480 && (fix)->fx_subsy != NULL \
481 && ((fix)->fx_r_type == BFD_RELOC_CR16_NUM8 \
482 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16 \
483 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32 \
484 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a) \
485 && S_GET_SEGMENT ((fix)->fx_addsy) != undefined_section \
486 && S_GET_SEGMENT ((fix)->fx_addsy) == S_GET_SEGMENT ((fix)->fx_subsy))
488 /* See whether we need to force a relocation into the output file.
489 This is used to force out switch and PC relative relocations when
493 cr16_force_relocation (fixS
*fix
)
495 if (generic_force_reloc (fix
) || SWITCH_TABLE (fix
))
501 /* Record a fixup for a cons expression. */
504 cr16_cons_fix_new (fragS
*frag
, int offset
, int len
, expressionS
*exp
,
505 bfd_reloc_code_real_type rtype
)
509 default: rtype
= BFD_RELOC_NONE
; break;
510 case 1: rtype
= BFD_RELOC_CR16_NUM8
; break;
511 case 2: rtype
= BFD_RELOC_CR16_NUM16
; break;
515 rtype
= BFD_RELOC_CR16_NUM32a
;
519 rtype
= BFD_RELOC_CR16_NUM32
;
523 fix_new_exp (frag
, offset
, len
, exp
, 0, rtype
);
526 /* Generate a relocation entry for a fixup. */
529 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
* fixP
)
533 /* If symbols are local and resolved, then no relocation needed. */
534 if ( ((fixP
->fx_addsy
)
535 && (S_GET_SEGMENT (fixP
->fx_addsy
) == absolute_section
))
537 && (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)))
540 reloc
= XNEW (arelent
);
541 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
542 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
543 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
544 reloc
->addend
= fixP
->fx_offset
;
546 if (fixP
->fx_subsy
!= NULL
)
548 if (SWITCH_TABLE (fixP
))
550 /* Keep the current difference in the addend. */
551 reloc
->addend
= (S_GET_VALUE (fixP
->fx_addsy
)
552 - S_GET_VALUE (fixP
->fx_subsy
) + fixP
->fx_offset
);
554 switch (fixP
->fx_r_type
)
556 case BFD_RELOC_CR16_NUM8
:
557 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH8
;
559 case BFD_RELOC_CR16_NUM16
:
560 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH16
;
562 case BFD_RELOC_CR16_NUM32
:
563 fixP
->fx_r_type
= BFD_RELOC_CR16_SWITCH32
;
565 case BFD_RELOC_CR16_NUM32a
:
566 fixP
->fx_r_type
= BFD_RELOC_CR16_NUM32a
;
575 /* We only resolve difference expressions in the same section. */
576 as_bad_subtract (fixP
);
577 free (reloc
->sym_ptr_ptr
);
583 if ((fixP
->fx_r_type
== BFD_RELOC_CR16_GOT_REGREL20
)
585 && fixP
->fx_addsy
== GOT_symbol
)
587 reloc
->addend
= fixP
->fx_offset
= reloc
->address
;
589 else if ((fixP
->fx_r_type
== BFD_RELOC_CR16_GOTC_REGREL20
)
591 && fixP
->fx_addsy
== GOT_symbol
)
593 reloc
->addend
= fixP
->fx_offset
= reloc
->address
;
597 gas_assert ((int) fixP
->fx_r_type
> 0);
598 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
600 if (reloc
->howto
== NULL
)
602 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
603 _("internal error: reloc %d (`%s') not supported by object file format"),
605 bfd_get_reloc_code_name (fixP
->fx_r_type
));
608 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
613 /* Prepare machine-dependent frags for relaxation. */
616 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
618 /* If symbol is undefined or located in a different section,
619 select the largest supported relocation. */
620 relax_substateT subtype
;
621 relax_substateT rlx_state
[] = {0, 2};
623 for (subtype
= 0; subtype
< ARRAY_SIZE (rlx_state
); subtype
+= 2)
625 if (fragp
->fr_subtype
== rlx_state
[subtype
]
626 && (!S_IS_DEFINED (fragp
->fr_symbol
)
627 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
629 fragp
->fr_subtype
= rlx_state
[subtype
+ 1];
634 if (fragp
->fr_subtype
>= ARRAY_SIZE (md_relax_table
))
637 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
641 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
, fragS
*fragP
)
643 /* 'opcode' points to the start of the instruction, whether
644 we need to change the instruction's fixed encoding. */
645 char *opcode
= &fragP
->fr_literal
[0] + fragP
->fr_fix
;
646 bfd_reloc_code_real_type reloc
;
648 subseg_change (sec
, 0);
650 switch (fragP
->fr_subtype
)
653 reloc
= BFD_RELOC_CR16_DISP8
;
656 /* If the subtype is not changed due to :m operand qualifier,
657 then no need to update the opcode value. */
658 if ((int)opcode
[1] != 0x18)
660 opcode
[0] = (opcode
[0] & 0xf0);
663 reloc
= BFD_RELOC_CR16_DISP16
;
666 /* If the subtype is not changed due to :l operand qualifier,
667 then no need to update the opcode value. */
668 if ((int)opcode
[1] != 0)
670 opcode
[2] = opcode
[0];
671 opcode
[0] = opcode
[1];
674 reloc
= BFD_RELOC_CR16_DISP24
;
680 fix_new (fragP
, fragP
->fr_fix
,
681 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput
, reloc
)),
682 fragP
->fr_symbol
, fragP
->fr_offset
, 1, reloc
);
684 fragP
->fr_fix
+= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
688 md_undefined_symbol (char *name
)
690 if (*name
== '_' && *(name
+ 1) == 'G'
691 && strcmp (name
, "_GLOBAL_OFFSET_TABLE_") == 0)
695 if (symbol_find (name
))
696 as_bad (_("GOT already in symbol table"));
697 GOT_symbol
= symbol_new (name
, undefined_section
,
698 &zero_address_frag
, 0);
705 /* Process machine-dependent command line options. Called once for
706 each option on the command line that the machine-independent part of
707 GAS does not understand. */
710 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
715 /* Machine-dependent usage-output. */
718 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
724 md_atof (int type
, char *litP
, int *sizeP
)
726 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
729 /* Apply a fixS (fixup of an instruction or data that we didn't have
730 enough info to complete immediately) to the data in a frag.
731 Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
732 relaxation of debug sections, this function is called only when
733 fixuping relocations of debug sections. */
736 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
740 if (fixP
->fx_addsy
== NULL
741 && fixP
->fx_pcrel
== 0)
743 else if (fixP
->fx_pcrel
== 1
744 && fixP
->fx_addsy
!= NULL
745 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
750 if (fixP
->fx_addsy
!= NULL
&& !fixP
->fx_pcrel
)
752 val
= fixP
->fx_offset
;
758 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
762 switch (fixP
->fx_r_type
)
764 case BFD_RELOC_CR16_NUM8
:
765 bfd_put_8 (stdoutput
, (unsigned char) val
, buf
);
767 case BFD_RELOC_CR16_NUM16
:
768 bfd_put_16 (stdoutput
, val
, buf
);
770 case BFD_RELOC_CR16_NUM32
:
771 bfd_put_32 (stdoutput
, val
, buf
);
773 case BFD_RELOC_CR16_NUM32a
:
774 bfd_put_32 (stdoutput
, val
, buf
);
777 /* We shouldn't ever get here because linkrelax is nonzero. */
784 fixP
->fx_offset
= * valP
;
787 /* The location from which a PC relative jump should be calculated,
788 given a PC relative reloc. */
791 md_pcrel_from (fixS
*fixp
)
793 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
797 initialise_reg_hash_table (htab_t
*hash_table
,
798 const reg_entry
*register_table
,
799 const unsigned int num_entries
)
801 const reg_entry
*rreg
;
803 *hash_table
= str_htab_create ();
805 for (rreg
= register_table
;
806 rreg
< (register_table
+ num_entries
);
808 if (str_hash_insert (*hash_table
, rreg
->name
, rreg
, 0) != NULL
)
809 as_fatal (_("duplicate %s"), rreg
->name
);
812 /* This function is called once, at assembler startup time. This should
813 set up all the tables, etc that the MD part of the assembler needs. */
820 /* Set up a hash table for the instructions. */
821 cr16_inst_hash
= str_htab_create ();
823 while (cr16_instruction
[i
].mnemonic
!= NULL
)
825 const char *mnemonic
= cr16_instruction
[i
].mnemonic
;
827 if (str_hash_insert (cr16_inst_hash
, mnemonic
, cr16_instruction
+ i
, 0))
828 as_fatal (_("duplicate %s"), mnemonic
);
830 /* Insert unique names into hash table. The CR16 instruction set
831 has many identical opcode names that have different opcodes based
832 on the operands. This hash table then provides a quick index to
833 the first opcode with a particular name in the opcode table. */
838 while (cr16_instruction
[i
].mnemonic
!= NULL
839 && streq (cr16_instruction
[i
].mnemonic
, mnemonic
));
842 /* Initialize reg_hash hash table. */
843 initialise_reg_hash_table (& reg_hash
, cr16_regtab
, NUMREGS
);
844 /* Initialize regp_hash hash table. */
845 initialise_reg_hash_table (& regp_hash
, cr16_regptab
, NUMREGPS
);
846 /* Initialize preg_hash hash table. */
847 initialise_reg_hash_table (& preg_hash
, cr16_pregtab
, NUMPREGS
);
848 /* Initialize pregp_hash hash table. */
849 initialise_reg_hash_table (& pregp_hash
, cr16_pregptab
, NUMPREGPS
);
851 /* Set linkrelax here to avoid fixups in most sections. */
855 /* Process constants (immediate/absolute)
856 and labels (jump targets/Memory locations). */
859 process_label_constant (char *str
, ins
* cr16_ins
)
861 char *saved_input_line_pointer
;
862 int symbol_with_at
= 0;
863 int symbol_with_s
= 0;
864 int symbol_with_m
= 0;
865 int symbol_with_l
= 0;
866 int symbol_with_at_got
= 0;
867 int symbol_with_at_gotc
= 0;
868 argument
*cur_arg
= cr16_ins
->arg
+ cur_arg_num
; /* Current argument. */
870 saved_input_line_pointer
= input_line_pointer
;
871 input_line_pointer
= str
;
873 expression (&cr16_ins
->exp
);
875 switch (cr16_ins
->exp
.X_op
)
879 /* Missing or bad expr becomes absolute 0. */
880 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
882 cr16_ins
->exp
.X_op
= O_constant
;
883 cr16_ins
->exp
.X_add_number
= 0;
884 cr16_ins
->exp
.X_add_symbol
= NULL
;
885 cr16_ins
->exp
.X_op_symbol
= NULL
;
889 cur_arg
->X_op
= O_constant
;
890 cur_arg
->constant
= cr16_ins
->exp
.X_add_number
;
896 cur_arg
->X_op
= O_symbol
;
897 cur_arg
->constant
= cr16_ins
->exp
.X_add_number
;
898 cr16_ins
->exp
.X_add_number
= 0;
899 cr16_ins
->rtype
= BFD_RELOC_NONE
;
902 if (startswith (input_line_pointer
, "@c"))
905 if (startswith (input_line_pointer
, "@l")
906 || startswith (input_line_pointer
, ":l"))
909 if (startswith (input_line_pointer
, "@m")
910 || startswith (input_line_pointer
, ":m"))
913 if (startswith (input_line_pointer
, "@s")
914 || startswith (input_line_pointer
, ":s"))
917 if (startswith (input_line_pointer
, "@cGOT")
918 || startswith (input_line_pointer
, "@cgot"))
920 if (GOT_symbol
== NULL
)
921 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
923 symbol_with_at_gotc
= 1;
925 else if (startswith (input_line_pointer
, "@GOT")
926 || startswith (input_line_pointer
, "@got"))
928 if ((startswith (input_line_pointer
, "+"))
929 || (startswith (input_line_pointer
, "-")))
930 as_warn (_("GOT bad expression with %s."), input_line_pointer
);
932 if (GOT_symbol
== NULL
)
933 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
935 symbol_with_at_got
= 1;
938 switch (cur_arg
->type
)
941 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
943 if (symbol_with_at_got
)
944 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
945 else if (symbol_with_at_gotc
)
946 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
947 else if (cur_arg
->size
== 20)
948 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
950 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20a
;
955 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
957 if (symbol_with_at_got
)
958 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
959 else if (symbol_with_at_gotc
)
960 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
962 switch (instruction
->size
)
965 switch (cur_arg
->size
)
968 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL0
;
971 if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
972 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL4
;
974 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL4a
;
980 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL16
;
983 if (cur_arg
->size
== 20)
984 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
986 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20a
;
995 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
997 if (symbol_with_at_got
)
998 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
999 else if (symbol_with_at_gotc
)
1000 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1002 cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
;
1007 if (IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
1009 if (symbol_with_at_got
)
1010 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1011 else if (symbol_with_at_gotc
)
1012 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1014 switch (instruction
->size
)
1016 case 1: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL0
; break;
1017 case 2: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL14
; break;
1018 case 3: cr16_ins
->rtype
= BFD_RELOC_CR16_REGREL20
; break;
1026 if (IS_INSN_MNEMONIC ("bal"))
1027 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP24
;
1028 else if (IS_INSN_TYPE (BRANCH_INS
))
1031 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP24
;
1032 else if (symbol_with_m
)
1033 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP16
;
1035 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP8
;
1037 else if (IS_INSN_TYPE (STOR_IMM_INS
) || IS_INSN_TYPE (LD_STOR_INS
)
1038 || IS_INSN_TYPE (CSTBIT_INS
))
1041 as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num
+ 1, str
);
1042 if (symbol_with_at_got
)
1043 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1044 else if (symbol_with_at_gotc
)
1045 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1046 else if (symbol_with_m
)
1047 cr16_ins
->rtype
= BFD_RELOC_CR16_ABS20
;
1048 else /* Default to (symbol_with_l) */
1049 cr16_ins
->rtype
= BFD_RELOC_CR16_ABS24
;
1051 else if (IS_INSN_TYPE (BRANCH_NEQ_INS
))
1052 cr16_ins
->rtype
= BFD_RELOC_CR16_DISP4
;
1056 if (IS_INSN_TYPE (ARITH_INS
))
1058 if (symbol_with_at_got
)
1059 cr16_ins
->rtype
= BFD_RELOC_CR16_GOT_REGREL20
;
1060 else if (symbol_with_at_gotc
)
1061 cr16_ins
->rtype
= BFD_RELOC_CR16_GOTC_REGREL20
;
1062 else if (symbol_with_s
)
1063 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM4
;
1064 else if (symbol_with_m
)
1065 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM20
;
1066 else if (symbol_with_at
)
1067 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM32a
;
1068 else /* Default to (symbol_with_l) */
1069 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM32
;
1071 else if (IS_INSN_TYPE (ARITH_BYTE_INS
))
1073 cr16_ins
->rtype
= BFD_RELOC_CR16_IMM16
;
1082 cur_arg
->X_op
= cr16_ins
->exp
.X_op
;
1086 input_line_pointer
= saved_input_line_pointer
;
1090 /* Retrieve the opcode image of a given register.
1091 If the register is illegal for the current instruction,
1095 getreg_image (reg r
)
1097 const reg_entry
*rreg
;
1099 int is_procreg
= 0; /* Nonzero means argument should be processor reg. */
1101 /* Check whether the register is in registers table. */
1103 rreg
= cr16_regtab
+ r
;
1104 else /* Register not found. */
1106 as_bad (_("Unknown register: `%d'"), r
);
1110 reg_name
= rreg
->name
;
1112 /* Issue a error message when register is illegal. */
1114 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1115 reg_name, ins_parse);
1119 case CR16_R_REGTYPE
:
1126 case CR16_P_REGTYPE
:
1138 /* Parsing different types of operands
1139 -> constants Immediate/Absolute/Relative numbers
1140 -> Labels Relocatable symbols
1141 -> (reg pair base) Register pair base
1142 -> (rbase) Register base
1143 -> disp(rbase) Register relative
1144 -> [rinx]disp(reg pair) Register index with reg pair mode
1145 -> disp(rbase,ridx,scl) Register index mode. */
1148 set_operand (char *operand
, ins
* cr16_ins
)
1150 char *operandS
; /* Pointer to start of sub-operand. */
1151 char *operandE
; /* Pointer to end of sub-operand. */
1153 argument
*cur_arg
= &cr16_ins
->arg
[cur_arg_num
]; /* Current argument. */
1155 /* Initialize pointers. */
1156 operandS
= operandE
= operand
;
1158 switch (cur_arg
->type
)
1160 case arg_ic
: /* Case $0x18. */
1163 case arg_c
: /* Case 0x18. */
1165 process_label_constant (operandS
, cr16_ins
);
1167 if (cur_arg
->type
!= arg_ic
)
1168 cur_arg
->type
= arg_c
;
1171 case arg_icr
: /* Case $0x18(r1). */
1173 case arg_cr
: /* Case 0x18(r1). */
1174 /* Set displacement constant. */
1175 while (*operandE
!= '(')
1178 process_label_constant (operandS
, cr16_ins
);
1179 operandS
= operandE
;
1181 case arg_rbase
: /* Case (r1) or (r1,r0). */
1183 /* Set register base. */
1184 while (*operandE
!= ')')
1187 if ((cur_arg
->r
= get_register (operandS
)) == nullregister
)
1188 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1189 operandS
, ins_parse
);
1191 /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1192 if ((cur_arg
->type
!= arg_rbase
)
1193 && ((getreg_image (cur_arg
->r
) == 12)
1194 || (getreg_image (cur_arg
->r
) == 13)
1195 || (getreg_image (cur_arg
->r
) == 14)
1196 || (getreg_image (cur_arg
->r
) == 15)))
1198 cur_arg
->type
= arg_crp
;
1199 cur_arg
->rp
= cur_arg
->r
;
1203 case arg_crp
: /* Case 0x18(r1,r0). */
1204 /* Set displacement constant. */
1205 while (*operandE
!= '(')
1208 process_label_constant (operandS
, cr16_ins
);
1209 operandS
= operandE
;
1211 /* Set register pair base. */
1212 while (*operandE
!= ')')
1215 if ((cur_arg
->rp
= get_register_pair (operandS
)) == nullregister
)
1216 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1217 operandS
, ins_parse
);
1221 /* Set register pair base. */
1222 if ((strchr (operandS
,'(') != NULL
))
1224 while ((*operandE
!= '(') && (! ISSPACE (*operandE
)))
1226 if ((cur_arg
->rp
= get_index_register_pair (operandE
)) == nullregister
)
1227 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1228 operandS
, ins_parse
);
1230 cur_arg
->type
= arg_idxrp
;
1235 operandE
= operandS
;
1236 /* Set displacement constant. */
1237 while (*operandE
!= ']')
1239 process_label_constant (++operandE
, cr16_ins
);
1241 operandE
= operandS
;
1243 /* Set index register . */
1244 operandS
= strchr (operandE
,'[');
1245 if (operandS
!= NULL
)
1246 { /* Eliminate '[', detach from rest of operand. */
1249 operandE
= strchr (operandS
, ']');
1251 if (operandE
== NULL
)
1252 as_bad (_("unmatched '['"));
1254 { /* Eliminate ']' and make sure it was the last thing
1257 if (*(operandE
+ 1) != '\0')
1258 as_bad (_("garbage after index spec ignored"));
1262 if ((cur_arg
->i_r
= get_index_register (operandS
)) == nullregister
)
1263 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1264 operandS
, ins_parse
);
1274 /* Parse a single operand.
1275 operand - Current operand to parse.
1276 cr16_ins - Current assembled instruction. */
1279 parse_operand (char *operand
, ins
* cr16_ins
)
1282 argument
*cur_arg
= cr16_ins
->arg
+ cur_arg_num
; /* Current argument. */
1284 /* Initialize the type to NULL before parsing. */
1285 cur_arg
->type
= nullargs
;
1287 /* Check whether this is a condition code . */
1288 if ((IS_INSN_MNEMONIC ("b")) && ((ret_val
= get_cc (operand
)) != -1))
1290 cur_arg
->type
= arg_cc
;
1291 cur_arg
->cc
= ret_val
;
1292 cur_arg
->X_op
= O_register
;
1296 /* Check whether this is a general processor register. */
1297 if ((ret_val
= get_register (operand
)) != nullregister
)
1299 cur_arg
->type
= arg_r
;
1300 cur_arg
->r
= ret_val
;
1305 /* Check whether this is a general processor register pair. */
1306 if ((operand
[0] == '(')
1307 && ((ret_val
= get_register_pair (operand
)) != nullregister
))
1309 cur_arg
->type
= arg_rp
;
1310 cur_arg
->rp
= ret_val
;
1311 cur_arg
->X_op
= O_register
;
1315 /* Check whether the operand is a processor register.
1316 For "lprd" and "sprd" instruction, only 32 bit
1317 processor registers used. */
1318 if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
1319 && ((ret_val
= get_pregister (operand
)) != nullpregister
))
1321 cur_arg
->type
= arg_pr
;
1322 cur_arg
->pr
= ret_val
;
1323 cur_arg
->X_op
= O_register
;
1327 /* Check whether this is a processor register - 32 bit. */
1328 if ((ret_val
= get_pregisterp (operand
)) != nullpregister
)
1330 cur_arg
->type
= arg_prp
;
1331 cur_arg
->prp
= ret_val
;
1332 cur_arg
->X_op
= O_register
;
1336 /* Deal with special characters. */
1340 if (strchr (operand
, '(') != NULL
)
1341 cur_arg
->type
= arg_icr
;
1343 cur_arg
->type
= arg_ic
;
1348 cur_arg
->type
= arg_rbase
;
1353 cur_arg
->type
= arg_idxr
;
1361 if (strchr (operand
, '(') != NULL
)
1363 if (strchr (operand
, ',') != NULL
1364 && (strchr (operand
, ',') > strchr (operand
, '(')))
1365 cur_arg
->type
= arg_crp
;
1367 cur_arg
->type
= arg_cr
;
1370 cur_arg
->type
= arg_c
;
1372 /* Parse an operand according to its type. */
1374 cur_arg
->constant
= 0;
1375 set_operand (operand
, cr16_ins
);
1378 /* Parse the various operands. Each operand is then analyzed to fillup
1379 the fields in the cr16_ins data structure. */
1382 parse_operands (ins
* cr16_ins
, char *operands
)
1384 char *operandS
; /* Operands string. */
1385 char *operandH
, *operandT
; /* Single operand head/tail pointers. */
1386 int allocated
= 0; /* Indicates a new operands string was allocated.*/
1387 char *operand
[MAX_OPERANDS
];/* Separating the operands. */
1388 int op_num
= 0; /* Current operand number we are parsing. */
1389 int bracket_flag
= 0; /* Indicates a bracket '(' was found. */
1390 int sq_bracket_flag
= 0; /* Indicates a square bracket '[' was found. */
1392 /* Preprocess the list of registers, if necessary. */
1393 operandS
= operandH
= operandT
= operands
;
1395 while (*operandT
!= '\0')
1397 if (*operandT
== ',' && bracket_flag
!= 1 && sq_bracket_flag
!= 1)
1400 operand
[op_num
++] = strdup (operandH
);
1401 operandH
= operandT
;
1405 if (*operandT
== ' ')
1406 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse
);
1408 if (*operandT
== '(')
1410 else if (*operandT
== '[')
1411 sq_bracket_flag
= 1;
1413 if (*operandT
== ')')
1418 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1420 else if (*operandT
== ']')
1422 if (sq_bracket_flag
)
1423 sq_bracket_flag
= 0;
1425 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1428 if (bracket_flag
== 1 && *operandT
== ')')
1430 else if (sq_bracket_flag
== 1 && *operandT
== ']')
1431 sq_bracket_flag
= 0;
1436 /* Adding the last operand. */
1437 operand
[op_num
++] = strdup (operandH
);
1438 cr16_ins
->nargs
= op_num
;
1440 /* Verifying correct syntax of operands (all brackets should be closed). */
1441 if (bracket_flag
|| sq_bracket_flag
)
1442 as_fatal (_("Missing matching brackets : `%s'"), ins_parse
);
1444 /* Now we parse each operand separately. */
1445 for (op_num
= 0; op_num
< cr16_ins
->nargs
; op_num
++)
1447 cur_arg_num
= op_num
;
1448 parse_operand (operand
[op_num
], cr16_ins
);
1449 free (operand
[op_num
]);
1456 /* Get the trap index in dispatch table, given its name.
1457 This routine is used by assembling the 'excp' instruction. */
1462 const trap_entry
*trap
;
1464 for (trap
= cr16_traps
; trap
< (cr16_traps
+ NUMTRAPS
); trap
++)
1465 if (strcasecmp (trap
->name
, s
) == 0)
1468 /* To make compatible with CR16 4.1 tools, the below 3-lines of
1469 * code added. Refer: Development Tracker item #123 */
1470 for (trap
= cr16_traps
; trap
< (cr16_traps
+ NUMTRAPS
); trap
++)
1471 if (trap
->entry
== (unsigned int) atoi (s
))
1474 as_bad (_("Unknown exception: `%s'"), s
);
1478 /* Top level module where instruction parsing starts.
1479 cr16_ins - data structure holds some information.
1480 operands - holds the operands part of the whole instruction. */
1483 parse_insn (ins
*insn
, char *operands
)
1487 /* Handle instructions with no operands. */
1488 for (i
= 0; cr16_no_op_insn
[i
] != NULL
; i
++)
1490 if (streq (cr16_no_op_insn
[i
], instruction
->mnemonic
))
1497 /* Handle 'excp' instructions. */
1498 if (IS_INSN_MNEMONIC ("excp"))
1501 insn
->arg
[0].type
= arg_ic
;
1502 insn
->arg
[0].constant
= gettrap (operands
);
1503 insn
->arg
[0].X_op
= O_constant
;
1507 if (operands
!= NULL
)
1508 parse_operands (insn
, operands
);
1511 /* bCC instruction requires special handling. */
1513 get_b_cc (char * op
)
1517 if (op
[1] == 0 || (op
[2] != 0 && op
[3] != 0))
1520 for (i
= 0; i
< cr16_num_cc
; i
++)
1521 if (streq (op
+ 1, cr16_b_cond_tab
[i
]))
1522 return (char *) cr16_b_cond_tab
[i
];
1527 /* bCC instruction requires special handling. */
1529 is_bcc_insn (char * op
)
1531 if (!(streq (op
, "bal") || streq (op
, "beq0b") || streq (op
, "bnq0b")
1532 || streq (op
, "beq0w") || streq (op
, "bnq0w")))
1533 if ((op
[0] == 'b') && (get_b_cc (op
) != NULL
))
1538 /* Cinv instruction requires special handling. */
1541 check_cinv_options (char * operand
)
1556 as_bad (_("Illegal `cinv' parameter: `%c'"), *p
);
1561 /* Retrieve the opcode image of a given register pair.
1562 If the register is illegal for the current instruction,
1566 getregp_image (reg r
)
1568 const reg_entry
*rreg
;
1571 /* Check whether the register is in registers table. */
1573 rreg
= cr16_regptab
+ r
;
1574 /* Register not found. */
1577 as_bad (_("Unknown register pair: `%d'"), r
);
1581 reg_name
= rreg
->name
;
1583 /* Issue a error message when register pair is illegal. */
1584 #define RPAIR_IMAGE_ERR \
1585 as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1586 reg_name, ins_parse); \
1591 case CR16_RP_REGTYPE
:
1600 /* Retrieve the opcode image of a given index register pair.
1601 If the register is illegal for the current instruction,
1605 getidxregp_image (reg r
)
1607 const reg_entry
*rreg
;
1610 /* Check whether the register is in registers table. */
1612 rreg
= cr16_regptab
+ r
;
1613 /* Register not found. */
1616 as_bad (_("Unknown register pair: `%d'"), r
);
1620 reg_name
= rreg
->name
;
1622 /* Issue a error message when register pair is illegal. */
1623 #define IDX_RPAIR_IMAGE_ERR \
1624 as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1625 reg_name, ins_parse); \
1627 if (rreg->type == CR16_RP_REGTYPE)
1629 switch (rreg
->image
)
1631 case 0: return 0; break;
1632 case 2: return 1; break;
1633 case 4: return 2; break;
1634 case 6: return 3; break;
1635 case 8: return 4; break;
1636 case 10: return 5; break;
1637 case 3: return 6; break;
1638 case 5: return 7; break;
1644 IDX_RPAIR_IMAGE_ERR
;
1648 /* Retrieve the opcode image of a given processor register.
1649 If the register is illegal for the current instruction,
1652 getprocreg_image (int r
)
1654 const reg_entry
*rreg
;
1657 /* Check whether the register is in registers table. */
1658 if (r
>= MAX_REG
&& r
< MAX_PREG
)
1659 rreg
= &cr16_pregtab
[r
- MAX_REG
];
1660 /* Register not found. */
1663 as_bad (_("Unknown processor register : `%d'"), r
);
1667 reg_name
= rreg
->name
;
1669 /* Issue a error message when register pair is illegal. */
1670 #define PROCREG_IMAGE_ERR \
1671 as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1672 reg_name, ins_parse); \
1677 case CR16_P_REGTYPE
:
1686 /* Retrieve the opcode image of a given processor register.
1687 If the register is illegal for the current instruction,
1690 getprocregp_image (int r
)
1692 const reg_entry
*rreg
;
1694 int pregptab_disp
= 0;
1696 /* Check whether the register is in registers table. */
1697 if (r
>= MAX_REG
&& r
< MAX_PREG
)
1702 case 4: pregptab_disp
= 1; break;
1703 case 6: pregptab_disp
= 2; break;
1707 pregptab_disp
= 3; break;
1709 pregptab_disp
= 4; break;
1711 pregptab_disp
= 5; break;
1714 rreg
= &cr16_pregptab
[r
- pregptab_disp
];
1716 /* Register not found. */
1719 as_bad (_("Unknown processor register (32 bit) : `%d'"), r
);
1723 reg_name
= rreg
->name
;
1725 /* Issue a error message when register pair is illegal. */
1726 #define PROCREGP_IMAGE_ERR \
1727 as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"), \
1728 reg_name, ins_parse); \
1733 case CR16_P_REGTYPE
:
1742 /* Routine used to represent integer X using NBITS bits. */
1745 getconstant (long x
, int nbits
)
1747 if ((unsigned) nbits
>= sizeof (x
) * CHAR_BIT
)
1749 return x
& ((1UL << nbits
) - 1);
1752 /* Print a constant value to 'output_opcode':
1753 ARG holds the operand's type and value.
1754 SHIFT represents the location of the operand to be print into.
1755 NBITS determines the size (in bits) of the constant. */
1758 print_constant (int nbits
, int shift
, argument
*arg
)
1760 unsigned long mask
= 0;
1761 unsigned long constant
= getconstant (arg
->constant
, nbits
);
1767 /* mask the upper part of the constant, that is, the bits
1768 going to the lowest byte of output_opcode[0].
1769 The upper part of output_opcode[1] is always filled,
1770 therefore it is always masked with 0xFFFF. */
1771 mask
= (1 << (nbits
- 16)) - 1;
1772 /* Divide the constant between two consecutive words :
1774 +---------+---------+---------+---------+
1775 | | X X X X | x X x X | |
1776 +---------+---------+---------+---------+
1777 output_opcode[0] output_opcode[1] */
1779 CR16_PRINT (0, (constant
>> WORD_SHIFT
) & mask
, 0);
1780 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1784 if ((nbits
== 21) && (IS_INSN_TYPE (LD_STOR_INS
)))
1790 /* mask the upper part of the constant, that is, the bits
1791 going to the lowest byte of output_opcode[0].
1792 The upper part of output_opcode[1] is always filled,
1793 therefore it is always masked with 0xFFFF. */
1794 mask
= (1 << (nbits
- 16)) - 1;
1795 /* Divide the constant between two consecutive words :
1797 +---------+---------+---------+---------+
1798 | | X X X X | - X - X | |
1799 +---------+---------+---------+---------+
1800 output_opcode[0] output_opcode[1] */
1802 if (instruction
->size
> 2 && shift
== WORD_SHIFT
)
1804 if (arg
->type
== arg_idxrp
)
1806 CR16_PRINT (0, ((constant
>> WORD_SHIFT
) & mask
) << 8, 0);
1807 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1812 ((((constant
>> WORD_SHIFT
) & mask
& 0xf) << 8)
1813 | (((constant
>> WORD_SHIFT
) & mask
& 0xf0) >> 4)),
1815 CR16_PRINT (1, constant
& 0xFFFF, WORD_SHIFT
);
1819 CR16_PRINT (0, constant
, shift
);
1823 if (arg
->type
== arg_idxrp
)
1825 if (instruction
->size
== 2)
1827 CR16_PRINT (0, (constant
) & 0xf, shift
); /* 0-3 bits. */
1828 CR16_PRINT (0, (constant
>> 4) & 0x3, shift
+ 20); /* 4-5 bits. */
1829 CR16_PRINT (0, (constant
>> 6) & 0x3, shift
+ 14); /* 6-7 bits. */
1830 CR16_PRINT (0, (constant
>> 8) & 0x3f, shift
+ 8); /* 8-13 bits. */
1833 CR16_PRINT (0, constant
, shift
);
1839 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1840 always filling the upper part of output_opcode[1]. If we mistakenly
1841 write it to output_opcode[0], the constant prefix (that is, 'match')
1844 +---------+---------+---------+---------+
1845 | 'match' | | X X X X | |
1846 +---------+---------+---------+---------+
1847 output_opcode[0] output_opcode[1] */
1849 if (instruction
->size
> 2 && shift
== WORD_SHIFT
)
1850 CR16_PRINT (1, constant
, WORD_SHIFT
);
1852 CR16_PRINT (0, constant
, shift
);
1856 CR16_PRINT (0, (constant
/ 2) & 0xf, shift
);
1857 CR16_PRINT (0, (constant
/ 2) >> 4, shift
+ 8);
1861 CR16_PRINT (0, constant
, shift
);
1866 /* Print an operand to 'output_opcode', which later on will be
1867 printed to the object file:
1868 ARG holds the operand's type, size and value.
1869 SHIFT represents the printing location of operand.
1870 NBITS determines the size (in bits) of a constant operand. */
1873 print_operand (int nbits
, int shift
, argument
*arg
)
1878 CR16_PRINT (0, arg
->cc
, shift
);
1882 CR16_PRINT (0, getreg_image (arg
->r
), shift
);
1886 CR16_PRINT (0, getregp_image (arg
->rp
), shift
);
1890 CR16_PRINT (0, getprocreg_image (arg
->pr
), shift
);
1894 CR16_PRINT (0, getprocregp_image (arg
->prp
), shift
);
1899 +-----------------------------+
1900 | r_index | disp | rp_base |
1901 +-----------------------------+ */
1903 if (instruction
->size
== 3)
1905 CR16_PRINT (0, getidxregp_image (arg
->rp
), 0);
1906 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1, 3);
1910 CR16_PRINT (0, getidxregp_image (arg
->rp
), 16);
1911 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1, 19);
1913 print_constant (nbits
, shift
, arg
);
1917 CR16_PRINT (0, getreg_image (arg
->i_r
) & 1,
1918 (IS_INSN_TYPE (CSTBIT_INS
)
1919 && instruction
->mnemonic
[4] == 'b') ? 23 : 24);
1920 print_constant (nbits
, shift
, arg
);
1925 print_constant (nbits
, shift
, arg
);
1929 CR16_PRINT (0, getreg_image (arg
->r
), shift
);
1933 print_constant (nbits
, shift
, arg
);
1934 /* Add the register argument to the output_opcode. */
1935 CR16_PRINT (0, getreg_image (arg
->r
), shift
- 16);
1939 print_constant (nbits
, shift
, arg
);
1940 if ((IS_INSN_TYPE (LD_STOR_INS
) || IS_INSN_TYPE (CSTBIT_INS
))
1941 && instruction
->size
== 1)
1942 CR16_PRINT (0, getregp_image (arg
->rp
), 16);
1943 else if (instruction
->size
> 1)
1944 CR16_PRINT (0, getregp_image (arg
->rp
), (shift
+ 16) & 31);
1946 CR16_PRINT (0, getregp_image (arg
->rp
), shift
);
1954 /* Retrieve the number of operands for the current assembled instruction. */
1957 get_number_of_operands (void)
1961 for (i
= 0; instruction
->operands
[i
].op_type
&& i
< MAX_OPERANDS
; i
++)
1966 /* Verify that the number NUM can be represented in BITS bits (that is,
1967 within its permitted range), based on the instruction's FLAGS.
1968 If UPDATE is nonzero, update the value of NUM if necessary.
1969 Return OP_LEGAL upon success, actual error type upon failure. */
1972 check_range (long *num
, int bits
, int unsigned flags
, int update
)
1975 op_err retval
= OP_LEGAL
;
1976 int32_t value
= *num
;
1978 /* Verify operand value is even. */
1979 if (flags
& OP_EVEN
)
1992 if (flags
& OP_SHIFT
)
1998 else if (flags
& OP_SHIFT_DEC
)
2000 value
= (value
>> 1) - 1;
2005 if (flags
& OP_ABS20
)
2007 if (value
> 0xEFFFF)
2008 return OP_OUT_OF_RANGE
;
2013 if (value
== 0xB || value
== 0x9)
2014 return OP_OUT_OF_RANGE
;
2015 else if (value
== -1)
2023 if (flags
& OP_ESC1
)
2026 return OP_OUT_OF_RANGE
;
2032 retval
= OP_OUT_OF_RANGE
;
2036 if (flags
& OP_SIGNED
)
2038 max
= (1U << (bits
- 1)) - 1;
2039 min
= - (1U << (bits
- 1));
2040 if (value
> max
|| value
< min
)
2041 retval
= OP_OUT_OF_RANGE
;
2043 else if (flags
& OP_UNSIGNED
)
2045 max
= (1U << (bits
- 1) << 1) - 1;
2046 if ((uint32_t) value
> (uint32_t) max
)
2047 retval
= OP_OUT_OF_RANGE
;
2049 else if (flags
& OP_NEG
)
2051 min
= - ((1U << (bits
- 1)) - 1);
2053 retval
= OP_OUT_OF_RANGE
;
2058 /* Bunch of error checking.
2059 The checks are made after a matching instruction was found. */
2062 warn_if_needed (ins
*insn
)
2064 /* If the post-increment address mode is used and the load/store
2065 source register is the same as rbase, the result of the
2066 instruction is undefined. */
2067 if (IS_INSN_TYPE (LD_STOR_INS_INC
))
2069 /* Enough to verify that one of the arguments is a simple reg. */
2070 if ((insn
->arg
[0].type
== arg_r
) || (insn
->arg
[1].type
== arg_r
))
2071 if (insn
->arg
[0].r
== insn
->arg
[1].r
)
2072 as_bad (_("Same src/dest register is used (`r%d'), "
2073 "result is undefined"), insn
->arg
[0].r
);
2076 if (IS_INSN_MNEMONIC ("pop")
2077 || IS_INSN_MNEMONIC ("push")
2078 || IS_INSN_MNEMONIC ("popret"))
2080 unsigned int count
= insn
->arg
[0].constant
, reg_val
;
2082 /* Check if count operand caused to save/retrieve the RA twice
2083 to generate warning message. */
2084 if (insn
->nargs
> 2)
2086 reg_val
= getreg_image (insn
->arg
[1].r
);
2088 if ( ((reg_val
== 9) && (count
> 7))
2089 || ((reg_val
== 10) && (count
> 6))
2090 || ((reg_val
== 11) && (count
> 5))
2091 || ((reg_val
== 12) && (count
> 4))
2092 || ((reg_val
== 13) && (count
> 2))
2093 || ((reg_val
== 14) && (count
> 0)))
2094 as_warn (_("RA register is saved twice."));
2096 /* Check if the third operand is "RA" or "ra" */
2097 if (!(((insn
->arg
[2].r
) == ra
) || ((insn
->arg
[2].r
) == RA
)))
2098 as_bad (_("`%s' Illegal use of registers."), ins_parse
);
2101 if (insn
->nargs
> 1)
2103 reg_val
= getreg_image (insn
->arg
[1].r
);
2105 /* If register is a register pair ie r12/r13/r14 in operand1, then
2106 the count constant should be validated. */
2107 if (((reg_val
== 11) && (count
> 7))
2108 || ((reg_val
== 12) && (count
> 6))
2109 || ((reg_val
== 13) && (count
> 4))
2110 || ((reg_val
== 14) && (count
> 2))
2111 || ((reg_val
== 15) && (count
> 0)))
2112 as_bad (_("`%s' Illegal count-register combination."), ins_parse
);
2116 /* Check if the operand is "RA" or "ra" */
2117 if (!(((insn
->arg
[0].r
) == ra
) || ((insn
->arg
[0].r
) == RA
)))
2118 as_bad (_("`%s' Illegal use of register."), ins_parse
);
2122 /* Some instruction assume the stack pointer as rptr operand.
2123 Issue an error when the register to be loaded is also SP. */
2124 if (instruction
->flags
& NO_SP
)
2126 if (getreg_image (insn
->arg
[1].r
) == getreg_image (sp
))
2127 as_bad (_("`%s' has undefined result"), ins_parse
);
2130 /* If the rptr register is specified as one of the registers to be loaded,
2131 the final contents of rptr are undefined. Thus, we issue an error. */
2132 if (instruction
->flags
& NO_RPTR
)
2134 if ((1 << getreg_image (insn
->arg
[0].r
)) & insn
->arg
[1].constant
)
2135 as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2136 getreg_image (insn
->arg
[0].r
));
2140 /* In some cases, we need to adjust the instruction pointer although a
2141 match was already found. Here, we gather all these cases.
2142 Returns 1 if instruction pointer was adjusted, otherwise 0. */
2145 adjust_if_needed (ins
*insn ATTRIBUTE_UNUSED
)
2149 if ((IS_INSN_TYPE (CSTBIT_INS
)) || (IS_INSN_TYPE (LD_STOR_INS
)))
2151 if ((instruction
->operands
[0].op_type
== abs24
)
2152 && ((insn
->arg
[0].constant
) > 0xF00000))
2154 insn
->arg
[0].constant
&= 0xFFFFF;
2163 /* Assemble a single instruction:
2164 INSN is already parsed (that is, all operand values and types are set).
2165 For instruction to be assembled, we need to find an appropriate template in
2166 the instruction table, meeting the following conditions:
2167 1: Has the same number of operands.
2168 2: Has the same operand types.
2169 3: Each operand size is sufficient to represent the instruction's values.
2170 Returns 1 upon success, 0 upon failure. */
2173 assemble_insn (const char *mnemonic
, ins
*insn
)
2175 /* Type of each operand in the current template. */
2176 argtype cur_type
[MAX_OPERANDS
];
2177 /* Size (in bits) of each operand in the current template. */
2178 unsigned int cur_size
[MAX_OPERANDS
];
2179 /* Flags of each operand in the current template. */
2180 unsigned int cur_flags
[MAX_OPERANDS
];
2181 /* Instruction type to match. */
2182 unsigned int ins_type
;
2183 /* Boolean flag to mark whether a match was found. */
2186 /* Nonzero if an instruction with same number of operands was found. */
2187 int found_same_number_of_operands
= 0;
2188 /* Nonzero if an instruction with same argument types was found. */
2189 int found_same_argument_types
= 0;
2190 /* Nonzero if a constant was found within the required range. */
2191 int found_const_within_range
= 0;
2192 /* Argument number of an operand with invalid type. */
2193 int invalid_optype
= -1;
2194 /* Argument number of an operand with invalid constant value. */
2195 int invalid_const
= -1;
2196 /* Operand error (used for issuing various constant error messages). */
2197 op_err op_error
, const_err
= OP_LEGAL
;
2199 /* Retrieve data (based on FUNC) for each operand of a given instruction. */
2200 #define GET_CURRENT_DATA(FUNC, ARRAY) \
2201 for (i = 0; i < insn->nargs; i++) \
2202 ARRAY[i] = FUNC (instruction->operands[i].op_type)
2204 #define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type)
2205 #define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size)
2206 #define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags)
2208 /* Instruction has no operands -> only copy the constant opcode. */
2209 if (insn
->nargs
== 0)
2211 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2215 /* In some case, same mnemonic can appear with different instruction types.
2216 For example, 'storb' is supported with 3 different types :
2217 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2218 We assume that when reaching this point, the instruction type was
2219 pre-determined. We need to make sure that the type stays the same
2220 during a search for matching instruction. */
2221 ins_type
= CR16_INS_TYPE (instruction
->flags
);
2223 while (/* Check that match is still not found. */
2225 /* Check we didn't get to end of table. */
2226 && instruction
->mnemonic
!= NULL
2227 /* Check that the actual mnemonic is still available. */
2228 && IS_INSN_MNEMONIC (mnemonic
)
2229 /* Check that the instruction type wasn't changed. */
2230 && IS_INSN_TYPE (ins_type
))
2232 /* Check whether number of arguments is legal. */
2233 if (get_number_of_operands () != insn
->nargs
)
2235 found_same_number_of_operands
= 1;
2237 /* Initialize arrays with data of each operand in current template. */
2242 /* Check for type compatibility. */
2243 for (i
= 0; i
< insn
->nargs
; i
++)
2245 if (cur_type
[i
] != insn
->arg
[i
].type
)
2247 if (invalid_optype
== -1)
2248 invalid_optype
= i
+ 1;
2252 found_same_argument_types
= 1;
2254 for (i
= 0; i
< insn
->nargs
; i
++)
2256 /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2257 then goto next instruction. */
2258 if (IS_INSN_MNEMONIC ("bal") && (i
== 0)
2259 && (instruction
->size
== 2) && (insn
->arg
[i
].rp
!= 14))
2262 /* If 'storb' instruction with 'sp' reg and 16-bit disp of
2263 * reg-pair, leads to undefined trap, so this should use
2264 * 20-bit disp of reg-pair. */
2265 if (IS_INSN_MNEMONIC ("storb") && (instruction
->size
== 2)
2266 && (insn
->arg
[i
].r
== 15) && (insn
->arg
[i
+ 1].type
== arg_crp
))
2269 /* Only check range - don't update the constant's value, since the
2270 current instruction may not be the last we try to match.
2271 The constant's value will be updated later, right before printing
2272 it to the object file. */
2273 if ((insn
->arg
[i
].X_op
== O_constant
)
2274 && (op_error
= check_range (&insn
->arg
[i
].constant
, cur_size
[i
],
2277 if (invalid_const
== -1)
2279 invalid_const
= i
+ 1;
2280 const_err
= op_error
;
2284 /* For symbols, we make sure the relocation size (which was already
2285 determined) is sufficient. */
2286 else if ((insn
->arg
[i
].X_op
== O_symbol
)
2287 && ((bfd_reloc_type_lookup (stdoutput
, insn
->rtype
))->bitsize
2291 found_const_within_range
= 1;
2293 /* If we got till here -> Full match is found. */
2297 /* Try again with next instruction. */
2304 /* We haven't found a match - instruction can't be assembled. */
2305 if (!found_same_number_of_operands
)
2306 as_bad (_("Incorrect number of operands"));
2307 else if (!found_same_argument_types
)
2308 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype
);
2309 else if (!found_const_within_range
)
2313 case OP_OUT_OF_RANGE
:
2314 as_bad (_("Operand out of range (arg %d)"), invalid_const
);
2317 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const
);
2320 as_bad (_("Illegal operand (arg %d)"), invalid_const
);
2328 /* Full match - print the encoding to output file. */
2330 /* Make further checking (such that couldn't be made earlier).
2331 Warn the user if necessary. */
2332 warn_if_needed (insn
);
2334 /* Check whether we need to adjust the instruction pointer. */
2335 if (adjust_if_needed (insn
))
2336 /* If instruction pointer was adjusted, we need to update
2337 the size of the current template operands. */
2340 for (i
= 0; i
< insn
->nargs
; i
++)
2342 int j
= instruction
->flags
& REVERSE_MATCH
?
2347 /* This time, update constant value before printing it. */
2348 if ((insn
->arg
[j
].X_op
== O_constant
)
2349 && (check_range (&insn
->arg
[j
].constant
, cur_size
[j
],
2350 cur_flags
[j
], 1) != OP_LEGAL
))
2351 as_fatal (_("Illegal operand (arg %d)"), j
+1);
2354 /* First, copy the instruction's opcode. */
2355 output_opcode
[0] = BIN (instruction
->match
, instruction
->match_bits
);
2357 for (i
= 0; i
< insn
->nargs
; i
++)
2359 /* For BAL (ra),disp17 instruction only. And also set the
2360 DISP24a relocation type. */
2361 if (IS_INSN_MNEMONIC ("bal") && (instruction
->size
== 2) && i
== 0)
2363 insn
->rtype
= BFD_RELOC_CR16_DISP24a
;
2367 print_operand (cur_size
[i
], instruction
->operands
[i
].shift
,
2375 /* Print the instruction.
2376 Handle also cases where the instruction is relaxable/relocatable. */
2379 print_insn (ins
*insn
)
2381 unsigned int i
, j
, insn_size
;
2383 unsigned short words
[4];
2386 /* Arrange the insn encodings in a WORD size array. */
2387 for (i
= 0, j
= 0; i
< 2; i
++)
2389 words
[j
++] = (output_opcode
[i
] >> 16) & 0xFFFF;
2390 words
[j
++] = output_opcode
[i
] & 0xFFFF;
2393 /* Handle relocation. */
2394 if ((instruction
->flags
& RELAXABLE
) && relocatable
)
2397 /* Write the maximal instruction size supported. */
2398 insn_size
= INSN_MAX_SIZE
;
2400 if (IS_INSN_TYPE (BRANCH_INS
))
2402 switch (insn
->rtype
)
2404 case BFD_RELOC_CR16_DISP24
:
2407 case BFD_RELOC_CR16_DISP16
:
2418 this_frag
= frag_var (rs_machine_dependent
, insn_size
*2,
2420 insn
->exp
.X_add_symbol
,
2426 insn_size
= instruction
->size
;
2427 this_frag
= frag_more (insn_size
* 2);
2429 if ((relocatable
) && (insn
->rtype
!= BFD_RELOC_NONE
))
2431 reloc_howto_type
*reloc_howto
;
2434 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, insn
->rtype
);
2439 size
= bfd_get_reloc_size (reloc_howto
);
2441 if (size
< 1 || size
> 4)
2444 fix_new_exp (frag_now
, this_frag
- frag_now
->fr_literal
,
2445 size
, &insn
->exp
, reloc_howto
->pc_relative
,
2450 /* Verify a 2-byte code alignment. */
2451 addr_mod
= frag_now_fix () & 1;
2452 if (frag_now
->has_code
&& frag_now
->insn_addr
!= addr_mod
)
2453 as_bad (_("instruction address is not a multiple of 2"));
2454 frag_now
->insn_addr
= addr_mod
;
2455 frag_now
->has_code
= 1;
2457 /* Write the instruction encoding to frag. */
2458 for (i
= 0; i
< insn_size
; i
++)
2460 md_number_to_chars (this_frag
, (valueT
) words
[i
], 2);
2465 /* Actually assemble an instruction. */
2468 cr16_assemble (const char *op
, char *param
)
2472 /* Find the instruction. */
2473 instruction
= (const inst
*) str_hash_find (cr16_inst_hash
, op
);
2474 if (instruction
== NULL
)
2476 as_bad (_("Unknown opcode: `%s'"), op
);
2480 /* Tie dwarf2 debug info to the address at the start of the insn. */
2481 dwarf2_emit_insn (0);
2483 /* Parse the instruction's operands. */
2484 parse_insn (&cr16_ins
, param
);
2486 /* Assemble the instruction - return upon failure. */
2487 if (assemble_insn (op
, &cr16_ins
) == 0)
2490 /* Print the instruction. */
2491 print_insn (&cr16_ins
);
2494 /* This is the guts of the machine-dependent assembler. OP points to a
2495 machine dependent instruction. This function is supposed to emit
2496 the frags/bytes it assembles to. */
2499 md_assemble (char *op
)
2502 char *param
, param1
[32];
2504 /* Reset global variables for a new instruction. */
2507 /* Strip the mnemonic. */
2508 for (param
= op
; *param
!= 0 && !ISSPACE (*param
); param
++)
2512 /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
2513 if (is_bcc_insn (op
))
2515 strcpy (param1
, get_b_cc (op
));
2516 strcat (param1
,",");
2517 strcat (param1
, param
);
2518 param
= (char *) ¶m1
;
2519 cr16_assemble ("b", param
);
2523 /* Checking the cinv options and adjust the mnemonic by removing the
2524 extra white spaces. */
2525 if (streq ("cinv", op
))
2527 /* Validate the cinv options. */
2528 unsigned int op_len
, param_len
;
2529 check_cinv_options (param
);
2530 op_len
= strlen (op
);
2531 param_len
= strlen (param
) + 1;
2532 memmove (op
+ op_len
, param
, param_len
);
2535 /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2536 lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
2537 as CR16 core doesn't support lsh[b/w] right shift operations. */
2538 if ((streq ("lshb", op
) || streq ("lshw", op
) || streq ("lshd", op
))
2539 && (param
[0] == '$'))
2541 strcpy (param1
, param
);
2542 /* Find the instruction. */
2543 instruction
= (const inst
*) str_hash_find (cr16_inst_hash
, op
);
2544 parse_operands (&cr16_ins
, param1
);
2545 if (((&cr16_ins
)->arg
[0].type
== arg_ic
)
2546 && ((&cr16_ins
)->arg
[0].constant
>= 0))
2548 if (streq ("lshb", op
))
2549 cr16_assemble ("ashub", param
);
2550 else if (streq ("lshd", op
))
2551 cr16_assemble ("ashud", param
);
2553 cr16_assemble ("ashuw", param
);
2558 cr16_assemble (op
, param
);