]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-cr16.c
Fix illegal memory access when bfd_get_section_contents is called with a NULL section...
[thirdparty/binutils-gdb.git] / gas / config / tc-cr16.c
CommitLineData
3d3d428f 1/* tc-cr16.c -- Assembler code for the CR16 CPU core.
fd67aa11 2 Copyright (C) 2007-2024 Free Software Foundation, Inc.
3d3d428f
NC
3
4 Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
5
6 This file is part of GAS, the GNU Assembler.
7
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
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
3d3d428f
NC
11 any later version.
12
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.
17
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. */
22
23#include "as.h"
24#include "safe-ctype.h"
25#include "dwarf2dbg.h"
26#include "opcode/cr16.h"
27#include "elf/cr16.h"
28
c9302810 29#include <limits.h>
c9302810
AM
30#ifndef CHAR_BIT
31#define CHAR_BIT 8
32#endif
3d3d428f
NC
33
34/* Word is considered here as a 16-bit unsigned short int. */
35#define WORD_SHIFT 16
36
37/* Register is 2-byte size. */
38#define REG_SIZE 2
39
40/* Maximum size of a single instruction (in words). */
41#define INSN_MAX_SIZE 3
42
43/* Maximum bits which may be set in a `mask16' operand. */
44#define MAX_REGS_IN_MASK16 8
45
46/* Assign a number NUM, shifted by SHIFT bytes, into a location
47 pointed by index BYTE of array 'output_opcode'. */
c9302810 48#define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT)
3d3d428f
NC
49
50/* Operand errors. */
51typedef enum
52 {
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. */
56 }
57op_err;
58
59/* Opcode mnemonics hash table. */
629310ab 60static htab_t cr16_inst_hash;
3d3d428f 61/* CR16 registers hash table. */
629310ab 62static htab_t reg_hash;
3d3d428f 63/* CR16 register pair hash table. */
629310ab 64static htab_t regp_hash;
3d3d428f 65/* CR16 processor registers hash table. */
629310ab 66static htab_t preg_hash;
3d3d428f 67/* CR16 processor registers 32 bit hash table. */
629310ab 68static htab_t pregp_hash;
3d3d428f
NC
69/* Current instruction we're assembling. */
70const inst *instruction;
71
72
73static int code_label = 0;
74
75/* Global variables. */
76
77/* Array to hold an instruction encoding. */
78long output_opcode[2];
79
80/* Nonzero means a relocatable symbol. */
81int relocatable;
82
83/* A copy of the original instruction (used in error messages). */
84char ins_parse[MAX_INST_LEN];
85
86/* The current processed argument number. */
87int cur_arg_num;
88
89/* Generic assembler global variables which must be defined by all targets. */
90
91/* Characters which always start a comment. */
92const char comment_chars[] = "#";
93
94/* Characters which start a comment at the beginning of a line. */
95const char line_comment_chars[] = "#";
96
97/* This array holds machine specific line separator characters. */
98const char line_separator_chars[] = ";";
99
100/* Chars that can be used to separate mant from exp in floating point nums. */
101const char EXP_CHARS[] = "eE";
102
103/* Chars that mean this number is a floating point constant as in 0f12.456 */
104const char FLT_CHARS[] = "f'";
105
0b9e228a
SR
106#ifdef OBJ_ELF
107/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
108symbolS * GOT_symbol;
109#endif
110
3d3d428f
NC
111/* Target-specific multicharacter options, not const-declared at usage. */
112const char *md_shortopts = "";
113struct option md_longopts[] =
114{
115 {NULL, no_argument, NULL, 0}
116};
117size_t md_longopts_size = sizeof (md_longopts);
118
119static void
120l_cons (int nbytes)
121{
122 int c;
123 expressionS exp;
124
125#ifdef md_flush_pending_output
c9302810 126 md_flush_pending_output ();
3d3d428f
NC
127#endif
128
129 if (is_it_end_of_statement ())
130 {
131 demand_empty_rest_of_line ();
132 return;
133 }
134
135#ifdef TC_ADDRESS_BYTES
136 if (nbytes == 0)
137 nbytes = TC_ADDRESS_BYTES ();
138#endif
139
140#ifdef md_cons_align
141 md_cons_align (nbytes);
142#endif
143
144 c = 0;
145 do
146 {
147 unsigned int bits_available = BITS_PER_CHAR * nbytes;
148 char *hold = input_line_pointer;
149
150 expression (&exp);
151
152 if (*input_line_pointer == ':')
c9302810
AM
153 {
154 /* Bitfields. */
155 long value = 0;
156
157 for (;;)
158 {
159 unsigned long width;
160
161 if (*input_line_pointer != ':')
162 {
163 input_line_pointer = hold;
164 break;
165 }
166 if (exp.X_op == O_absent)
167 {
168 as_warn (_("using a bit field width of zero"));
169 exp.X_add_number = 0;
170 exp.X_op = O_constant;
171 }
172
173 if (exp.X_op != O_constant)
174 {
175 *input_line_pointer = '\0';
176 as_bad (_("field width \"%s\" too complex for a bitfield"),
177 hold);
178 *input_line_pointer = ':';
179 demand_empty_rest_of_line ();
180 return;
181 }
182
183 if ((width = exp.X_add_number) >
184 (unsigned int)(BITS_PER_CHAR * nbytes))
185 {
992a06ee
AM
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",
190 nbytes),
191 width, nbytes, (BITS_PER_CHAR * nbytes));
c9302810
AM
192 width = BITS_PER_CHAR * nbytes;
193 }
194
195 if (width > bits_available)
196 {
197 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
198 input_line_pointer = hold;
199 exp.X_add_number = value;
200 break;
201 }
202
203 /* Skip ':'. */
204 hold = ++input_line_pointer;
205
206 expression (&exp);
207 if (exp.X_op != O_constant)
208 {
209 char cache = *input_line_pointer;
210
211 *input_line_pointer = '\0';
212 as_bad (_("field value \"%s\" too complex for a bitfield"),
213 hold);
214 *input_line_pointer = cache;
215 demand_empty_rest_of_line ();
216 return;
217 }
218
219 value |= ((~(-(1 << width)) & exp.X_add_number)
220 << ((BITS_PER_CHAR * nbytes) - bits_available));
221
222 if ((bits_available -= width) == 0
223 || is_it_end_of_statement ()
224 || *input_line_pointer != ',')
225 break;
226
227 hold = ++input_line_pointer;
228 expression (&exp);
229 }
230
231 exp.X_add_number = value;
232 exp.X_op = O_constant;
233 exp.X_unsigned = 1;
234 }
3d3d428f
NC
235
236 if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
c9302810 237 code_label = 1;
3d3d428f
NC
238 emit_expr (&exp, (unsigned int) nbytes);
239 ++c;
240 if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
c9302810
AM
241 {
242 input_line_pointer +=3;
243 break;
244 }
3d3d428f
NC
245 }
246 while ((*input_line_pointer++ == ','));
247
248 /* Put terminator back into stream. */
249 input_line_pointer--;
250
251 demand_empty_rest_of_line ();
252}
253
3d3d428f
NC
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. */
259
260const pseudo_typeS md_pseudo_table[] =
261{
262 /* In CR16 machine, align is in bytes (not a ptwo boundary). */
263 {"align", s_align_bytes, 0},
264 {"long", l_cons, 4 },
0b9e228a 265 {"4byte", l_cons, 4 },
3d3d428f
NC
266 {0, 0, 0}
267};
268
269/* CR16 relaxation table. */
270const relax_typeS md_relax_table[] =
271{
272 /* bCC */
e9deb29d 273 {0x7f, -0x80, 2, 1}, /* 8 */
3d3d428f
NC
274 {0xfffe, -0x10000, 4, 2}, /* 16 */
275 {0xfffffe, -0x1000000, 6, 0}, /* 24 */
276};
277
278/* Return the bit size for a given operand. */
279
280static int
281get_opbits (operand_type op)
282{
283 if (op < MAX_OPRD)
284 return cr16_optab[op].bit_size;
285
286 return 0;
287}
288
289/* Return the argument type of a given operand. */
290
291static argtype
292get_optype (operand_type op)
293{
294 if (op < MAX_OPRD)
295 return cr16_optab[op].arg_type;
296 else
297 return nullargs;
298}
299
300/* Return the flags of a given operand. */
301
302static int
303get_opflags (operand_type op)
304{
305 if (op < MAX_OPRD)
306 return cr16_optab[op].flags;
307
308 return 0;
309}
310
311/* Get the cc code. */
312
313static int
314get_cc (char *cc_name)
315{
316 unsigned int i;
317
318 for (i = 0; i < cr16_num_cc; i++)
319 if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
320 return i;
321
322 return -1;
323}
324
325/* Get the core processor register 'reg_name'. */
326
327static reg
328get_register (char *reg_name)
329{
91d6fa6a 330 const reg_entry *rreg;
3d3d428f 331
629310ab 332 rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
3d3d428f 333
91d6fa6a
NC
334 if (rreg != NULL)
335 return rreg->value.reg_val;
3d3d428f
NC
336
337 return nullregister;
338}
339/* Get the core processor register-pair 'reg_name'. */
340
341static reg
342get_register_pair (char *reg_name)
343{
91d6fa6a 344 const reg_entry *rreg;
3d3d428f
NC
345 char tmp_rp[16]="\0";
346
33eaf5de 347 /* Add '(' and ')' to the reg pair, if it's not present. */
3739860c 348 if (reg_name[0] != '(')
3d3d428f
NC
349 {
350 tmp_rp[0] = '(';
351 strcat (tmp_rp, reg_name);
352 strcat (tmp_rp,")");
629310ab 353 rreg = (const reg_entry *) str_hash_find (regp_hash, tmp_rp);
3d3d428f
NC
354 }
355 else
629310ab 356 rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
3d3d428f 357
91d6fa6a
NC
358 if (rreg != NULL)
359 return rreg->value.reg_val;
3d3d428f
NC
360
361 return nullregister;
3739860c 362}
3d3d428f
NC
363
364/* Get the index register 'reg_name'. */
365
366static reg
367get_index_register (char *reg_name)
368{
91d6fa6a 369 const reg_entry *rreg;
3d3d428f 370
629310ab 371 rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
3d3d428f 372
91d6fa6a
NC
373 if ((rreg != NULL)
374 && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13)))
375 return rreg->value.reg_val;
3d3d428f
NC
376
377 return nullregister;
378}
379/* Get the core processor index register-pair 'reg_name'. */
380
381static reg
382get_index_register_pair (char *reg_name)
383{
91d6fa6a 384 const reg_entry *rreg;
3d3d428f 385
629310ab 386 rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
3d3d428f 387
91d6fa6a 388 if (rreg != NULL)
3d3d428f 389 {
91d6fa6a 390 if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7)
c9302810
AM
391 || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10))
392 return rreg->value.reg_val;
3d3d428f 393
91d6fa6a 394 as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val);
3d3d428f
NC
395 }
396
397 return nullregister;
398}
399
400/* Get the processor register 'preg_name'. */
401
402static preg
403get_pregister (char *preg_name)
404{
91d6fa6a 405 const reg_entry *prreg;
3d3d428f 406
629310ab 407 prreg = (const reg_entry *) str_hash_find (preg_hash, preg_name);
3d3d428f 408
91d6fa6a
NC
409 if (prreg != NULL)
410 return prreg->value.preg_val;
3d3d428f
NC
411
412 return nullpregister;
413}
414
415/* Get the processor register 'preg_name 32 bit'. */
416
417static preg
418get_pregisterp (char *preg_name)
419{
91d6fa6a 420 const reg_entry *prreg;
3d3d428f 421
629310ab 422 prreg = (const reg_entry *) str_hash_find (pregp_hash, preg_name);
3d3d428f 423
91d6fa6a
NC
424 if (prreg != NULL)
425 return prreg->value.preg_val;
3d3d428f
NC
426
427 return nullpregister;
428}
429
430
431/* Round up a section size to the appropriate boundary. */
432
433valueT
434md_section_align (segT seg, valueT val)
435{
436 /* Round .text section to a multiple of 2. */
437 if (seg == text_section)
438 return (val + 1) & ~1;
439 return val;
440}
441
442/* Parse an operand that is machine-specific (remove '*'). */
443
444void
445md_operand (expressionS * exp)
446{
447 char c = *input_line_pointer;
448
449 switch (c)
450 {
451 case '*':
452 input_line_pointer++;
453 expression (exp);
454 break;
455 default:
456 break;
457 }
458}
459
460/* Reset global variables before parsing a new instruction. */
461
462static void
463reset_vars (char *op)
464{
465 cur_arg_num = relocatable = 0;
466 memset (& output_opcode, '\0', sizeof (output_opcode));
467
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;
471}
472
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
476 necessary. */
477
c9302810
AM
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))
3d3d428f
NC
487
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
490 relaxing. */
491
492int
493cr16_force_relocation (fixS *fix)
494{
7fac7ff4 495 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
3d3d428f
NC
496 return 1;
497
498 return 0;
499}
500
501/* Record a fixup for a cons expression. */
502
503void
62ebcb5c
AM
504cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
505 bfd_reloc_code_real_type rtype)
3d3d428f 506{
3d3d428f
NC
507 switch (len)
508 {
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;
512 case 4:
513 if (code_label)
c9302810
AM
514 {
515 rtype = BFD_RELOC_CR16_NUM32a;
516 code_label = 0;
517 }
3d3d428f 518 else
c9302810 519 rtype = BFD_RELOC_CR16_NUM32;
3d3d428f
NC
520 break;
521 }
522
523 fix_new_exp (frag, offset, len, exp, 0, rtype);
524}
525
526/* Generate a relocation entry for a fixup. */
527
528arelent *
529tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
530{
531 arelent * reloc;
532
7859b21d 533 /* If symbols are local and resolved, then no relocation needed. */
3739860c 534 if ( ((fixP->fx_addsy)
c9302810 535 && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
3739860c 536 || ((fixP->fx_subsy)
7859b21d 537 && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)))
c9302810 538 return NULL;
7859b21d 539
add39d23
TS
540 reloc = XNEW (arelent);
541 reloc->sym_ptr_ptr = XNEW (asymbol *);
3d3d428f
NC
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;
545
546 if (fixP->fx_subsy != NULL)
547 {
548 if (SWITCH_TABLE (fixP))
0b9e228a 549 {
c9302810
AM
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);
553
554 switch (fixP->fx_r_type)
555 {
556 case BFD_RELOC_CR16_NUM8:
557 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
558 break;
559 case BFD_RELOC_CR16_NUM16:
560 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
561 break;
562 case BFD_RELOC_CR16_NUM32:
563 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
564 break;
565 case BFD_RELOC_CR16_NUM32a:
566 fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
567 break;
568 default:
569 abort ();
570 break;
571 }
0b9e228a 572 }
c9302810 573 else
0b9e228a 574 {
c9302810 575 /* We only resolve difference expressions in the same section. */
4bf09429
AM
576 as_bad_subtract (fixP);
577 free (reloc->sym_ptr_ptr);
578 free (reloc);
579 return NULL;
0b9e228a 580 }
c9302810
AM
581 }
582#ifdef OBJ_ELF
583 if ((fixP->fx_r_type == BFD_RELOC_CR16_GOT_REGREL20)
584 && GOT_symbol
585 && fixP->fx_addsy == GOT_symbol)
586 {
587 reloc->addend = fixP->fx_offset = reloc->address;
588 }
589 else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20)
590 && GOT_symbol
591 && fixP->fx_addsy == GOT_symbol)
592 {
593 reloc->addend = fixP->fx_offset = reloc->address;
594 }
0b9e228a 595#endif
3d3d428f 596
9c2799c2 597 gas_assert ((int) fixP->fx_r_type > 0);
3d3d428f
NC
598 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
599
600 if (reloc->howto == NULL)
601 {
602 as_bad_where (fixP->fx_file, fixP->fx_line,
c9302810
AM
603 _("internal error: reloc %d (`%s') not supported by object file format"),
604 fixP->fx_r_type,
605 bfd_get_reloc_code_name (fixP->fx_r_type));
3d3d428f
NC
606 return NULL;
607 }
9c2799c2 608 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
3d3d428f
NC
609
610 return reloc;
611}
612
613/* Prepare machine-dependent frags for relaxation. */
614
615int
616md_estimate_size_before_relax (fragS *fragp, asection *seg)
617{
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};
622
623 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
624 {
625 if (fragp->fr_subtype == rlx_state[subtype]
c9302810
AM
626 && (!S_IS_DEFINED (fragp->fr_symbol)
627 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
628 {
629 fragp->fr_subtype = rlx_state[subtype + 1];
630 break;
631 }
3d3d428f
NC
632 }
633
634 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
635 abort ();
636
637 return md_relax_table[fragp->fr_subtype].rlx_length;
638}
639
640void
641md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
642{
643 /* 'opcode' points to the start of the instruction, whether
644 we need to change the instruction's fixed encoding. */
6c115e16 645 char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
7fac7ff4 646 bfd_reloc_code_real_type reloc;
3d3d428f
NC
647
648 subseg_change (sec, 0);
649
7fac7ff4
NC
650 switch (fragP->fr_subtype)
651 {
652 case 0:
653 reloc = BFD_RELOC_CR16_DISP8;
654 break;
655 case 1:
656 /* If the subtype is not changed due to :m operand qualifier,
c9302810 657 then no need to update the opcode value. */
7fac7ff4 658 if ((int)opcode[1] != 0x18)
c9302810
AM
659 {
660 opcode[0] = (opcode[0] & 0xf0);
661 opcode[1] = 0x18;
662 }
7fac7ff4
NC
663 reloc = BFD_RELOC_CR16_DISP16;
664 break;
665 case 2:
666 /* If the subtype is not changed due to :l operand qualifier,
c9302810 667 then no need to update the opcode value. */
7fac7ff4 668 if ((int)opcode[1] != 0)
c9302810
AM
669 {
670 opcode[2] = opcode[0];
671 opcode[0] = opcode[1];
672 opcode[1] = 0x0;
673 }
7fac7ff4
NC
674 reloc = BFD_RELOC_CR16_DISP24;
675 break;
676 default:
677 abort();
678 }
679
3d3d428f 680 fix_new (fragP, fragP->fr_fix,
c9302810
AM
681 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
682 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
3d3d428f
NC
683 fragP->fr_var = 0;
684 fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
685}
686
0b9e228a
SR
687symbolS *
688md_undefined_symbol (char *name)
689{
690 if (*name == '_' && *(name + 1) == 'G'
691 && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
e01e1cee
AM
692 {
693 if (!GOT_symbol)
694 {
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);
699 }
700 return GOT_symbol;
701 }
0b9e228a
SR
702 return 0;
703}
704
3d3d428f
NC
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. */
708
709int
17b9d67d 710md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
3d3d428f
NC
711{
712 return 0;
713}
714
715/* Machine-dependent usage-output. */
716
717void
718md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
719{
720 return;
721}
722
6d4af3c2 723const char *
3d3d428f
NC
724md_atof (int type, char *litP, int *sizeP)
725{
499ac353 726 return ieee_md_atof (type, litP, sizeP, target_big_endian);
3d3d428f
NC
727}
728
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. */
734
735void
736md_apply_fix (fixS *fixP, valueT *valP, segT seg)
737{
738 valueT val = * valP;
3d3d428f
NC
739
740 if (fixP->fx_addsy == NULL
741 && fixP->fx_pcrel == 0)
742 fixP->fx_done = 1;
7859b21d 743 else if (fixP->fx_pcrel == 1
3d3d428f
NC
744 && fixP->fx_addsy != NULL
745 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
746 fixP->fx_done = 1;
7859b21d
SR
747 else
748 fixP->fx_done = 0;
749
750 if (fixP->fx_addsy != NULL && !fixP->fx_pcrel)
751 {
752 val = fixP->fx_offset;
753 fixP->fx_done = 1;
754 }
755
756 if (fixP->fx_done)
757 {
758 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
759
760 fixP->fx_offset = 0;
761
762 switch (fixP->fx_r_type)
763 {
764 case BFD_RELOC_CR16_NUM8:
765 bfd_put_8 (stdoutput, (unsigned char) val, buf);
766 break;
767 case BFD_RELOC_CR16_NUM16:
768 bfd_put_16 (stdoutput, val, buf);
769 break;
770 case BFD_RELOC_CR16_NUM32:
771 bfd_put_32 (stdoutput, val, buf);
772 break;
773 case BFD_RELOC_CR16_NUM32a:
774 bfd_put_32 (stdoutput, val, buf);
775 break;
776 default:
777 /* We shouldn't ever get here because linkrelax is nonzero. */
778 abort ();
779 break;
780 }
781 fixP->fx_done = 0;
782 }
783 else
784 fixP->fx_offset = * valP;
3d3d428f
NC
785}
786
787/* The location from which a PC relative jump should be calculated,
788 given a PC relative reloc. */
789
790long
791md_pcrel_from (fixS *fixp)
792{
793 return fixp->fx_frag->fr_address + fixp->fx_where;
794}
795
796static void
fe0e921f
AM
797initialise_reg_hash_table (htab_t *hash_table,
798 const reg_entry *register_table,
799 const unsigned int num_entries)
3d3d428f 800{
fe0e921f
AM
801 const reg_entry *rreg;
802
803 *hash_table = str_htab_create ();
3d3d428f 804
91d6fa6a
NC
805 for (rreg = register_table;
806 rreg < (register_table + num_entries);
807 rreg++)
fe0e921f
AM
808 if (str_hash_insert (*hash_table, rreg->name, rreg, 0) != NULL)
809 as_fatal (_("duplicate %s"), rreg->name);
3d3d428f
NC
810}
811
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. */
814
815void
816md_begin (void)
817{
818 int i = 0;
819
820 /* Set up a hash table for the instructions. */
f16c3d4f 821 cr16_inst_hash = str_htab_create ();
3d3d428f
NC
822
823 while (cr16_instruction[i].mnemonic != NULL)
824 {
3d3d428f
NC
825 const char *mnemonic = cr16_instruction[i].mnemonic;
826
fe0e921f
AM
827 if (str_hash_insert (cr16_inst_hash, mnemonic, cr16_instruction + i, 0))
828 as_fatal (_("duplicate %s"), mnemonic);
829
3d3d428f 830 /* Insert unique names into hash table. The CR16 instruction set
c9302810
AM
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. */
3d3d428f 834 do
c9302810
AM
835 {
836 ++i;
837 }
3d3d428f 838 while (cr16_instruction[i].mnemonic != NULL
c9302810 839 && streq (cr16_instruction[i].mnemonic, mnemonic));
3d3d428f
NC
840 }
841
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);
850
851 /* Set linkrelax here to avoid fixups in most sections. */
852 linkrelax = 1;
853}
854
855/* Process constants (immediate/absolute)
856 and labels (jump targets/Memory locations). */
857
858static void
859process_label_constant (char *str, ins * cr16_ins)
860{
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;
0b9e228a
SR
866 int symbol_with_at_got = 0;
867 int symbol_with_at_gotc = 0;
3d3d428f
NC
868 argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
869
870 saved_input_line_pointer = input_line_pointer;
871 input_line_pointer = str;
872
873 expression (&cr16_ins->exp);
874
875 switch (cr16_ins->exp.X_op)
876 {
877 case O_big:
878 case O_absent:
879 /* Missing or bad expr becomes absolute 0. */
880 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
c9302810 881 str);
3d3d428f
NC
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;
886 /* Fall through. */
887
888 case O_constant:
889 cur_arg->X_op = O_constant;
890 cur_arg->constant = cr16_ins->exp.X_add_number;
891 break;
892
893 case O_symbol:
894 case O_subtract:
895 case O_add:
896 cur_arg->X_op = O_symbol;
0b9e228a
SR
897 cur_arg->constant = cr16_ins->exp.X_add_number;
898 cr16_ins->exp.X_add_number = 0;
3d3d428f
NC
899 cr16_ins->rtype = BFD_RELOC_NONE;
900 relocatable = 1;
901
e9b095a5 902 if (startswith (input_line_pointer, "@c"))
c9302810 903 symbol_with_at = 1;
3d3d428f 904
e9b095a5
ML
905 if (startswith (input_line_pointer, "@l")
906 || startswith (input_line_pointer, ":l"))
c9302810 907 symbol_with_l = 1;
3d3d428f 908
e9b095a5
ML
909 if (startswith (input_line_pointer, "@m")
910 || startswith (input_line_pointer, ":m"))
c9302810 911 symbol_with_m = 1;
3d3d428f 912
e9b095a5
ML
913 if (startswith (input_line_pointer, "@s")
914 || startswith (input_line_pointer, ":s"))
c9302810 915 symbol_with_s = 1;
3d3d428f 916
e9b095a5
ML
917 if (startswith (input_line_pointer, "@cGOT")
918 || startswith (input_line_pointer, "@cgot"))
0b9e228a
SR
919 {
920 if (GOT_symbol == NULL)
c9302810 921 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
0b9e228a 922
c9302810 923 symbol_with_at_gotc = 1;
0b9e228a 924 }
e9b095a5
ML
925 else if (startswith (input_line_pointer, "@GOT")
926 || startswith (input_line_pointer, "@got"))
0b9e228a 927 {
e9b095a5
ML
928 if ((startswith (input_line_pointer, "+"))
929 || (startswith (input_line_pointer, "-")))
c9302810 930 as_warn (_("GOT bad expression with %s."), input_line_pointer);
0b9e228a
SR
931
932 if (GOT_symbol == NULL)
c9302810 933 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
0b9e228a 934
c9302810 935 symbol_with_at_got = 1;
0b9e228a
SR
936 }
937
3d3d428f 938 switch (cur_arg->type)
c9302810
AM
939 {
940 case arg_cr:
941 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
942 {
0b9e228a 943 if (symbol_with_at_got)
c9302810 944 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
0b9e228a 945 else if (symbol_with_at_gotc)
c9302810 946 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
0b9e228a 947 else if (cur_arg->size == 20)
c9302810
AM
948 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
949 else
950 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
0b9e228a 951 }
c9302810
AM
952 break;
953
954 case arg_crp:
955 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
956 {
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;
961 } else {
962 switch (instruction->size)
963 {
964 case 1:
965 switch (cur_arg->size)
966 {
967 case 0:
968 cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
969 break;
970 case 4:
971 if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
972 cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
973 else
974 cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
975 break;
976 default: break;
977 }
978 break;
979 case 2:
980 cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
981 break;
982 case 3:
983 if (cur_arg->size == 20)
984 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
985 else
986 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
987 break;
988 default:
989 break;
990 }
991 }
992 break;
7fac7ff4 993
c9302810
AM
994 case arg_idxr:
995 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
0b9e228a
SR
996 {
997 if (symbol_with_at_got)
c9302810 998 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
0b9e228a 999 else if (symbol_with_at_gotc)
c9302810 1000 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
0b9e228a 1001 else
c9302810 1002 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
0b9e228a 1003 }
c9302810
AM
1004 break;
1005
1006 case arg_idxrp:
1007 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
1008 {
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;
1013 else {
1014 switch (instruction->size)
1015 {
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;
1019 default: break;
1020 }
1021 }
1022 }
1023 break;
7fac7ff4 1024
c9302810
AM
1025 case arg_c:
1026 if (IS_INSN_MNEMONIC ("bal"))
1027 cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1028 else if (IS_INSN_TYPE (BRANCH_INS))
0b9e228a 1029 {
c9302810
AM
1030 if (symbol_with_l)
1031 cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1032 else if (symbol_with_m)
1033 cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
1034 else
1035 cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
0b9e228a 1036 }
c9302810
AM
1037 else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
1038 || IS_INSN_TYPE (CSTBIT_INS))
1039 {
0b9e228a 1040 if (symbol_with_s)
c9302810 1041 as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
0b9e228a 1042 if (symbol_with_at_got)
c9302810 1043 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
0b9e228a 1044 else if (symbol_with_at_gotc)
c9302810 1045 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
0b9e228a 1046 else if (symbol_with_m)
c9302810
AM
1047 cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
1048 else /* Default to (symbol_with_l) */
1049 cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
1050 }
1051 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1052 cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
1053 break;
1054
1055 case arg_ic:
1056 if (IS_INSN_TYPE (ARITH_INS))
1057 {
0b9e228a 1058 if (symbol_with_at_got)
c9302810 1059 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
0b9e228a 1060 else if (symbol_with_at_gotc)
c9302810 1061 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
0b9e228a 1062 else if (symbol_with_s)
c9302810
AM
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;
1070 }
1071 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1072 {
1073 cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
1074 }
1075 break;
1076 default:
1077 break;
1078 }
3d3d428f
NC
1079 break;
1080
1081 default:
1082 cur_arg->X_op = cr16_ins->exp.X_op;
1083 break;
1084 }
1085
1086 input_line_pointer = saved_input_line_pointer;
1087 return;
1088}
1089
1090/* Retrieve the opcode image of a given register.
1091 If the register is illegal for the current instruction,
1092 issue an error. */
1093
1094static int
1095getreg_image (reg r)
1096{
91d6fa6a 1097 const reg_entry *rreg;
3d3d428f
NC
1098 char *reg_name;
1099 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1100
1101 /* Check whether the register is in registers table. */
1102 if (r < MAX_REG)
91d6fa6a 1103 rreg = cr16_regtab + r;
3d3d428f
NC
1104 else /* Register not found. */
1105 {
1106 as_bad (_("Unknown register: `%d'"), r);
1107 return 0;
1108 }
1109
91d6fa6a 1110 reg_name = rreg->name;
3d3d428f 1111
c9302810
AM
1112 /* Issue a error message when register is illegal. */
1113#define IMAGE_ERR \
1114 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
5a6312e8 1115 reg_name, ins_parse);
3d3d428f 1116
91d6fa6a 1117 switch (rreg->type)
3d3d428f
NC
1118 {
1119 case CR16_R_REGTYPE:
1120 if (! is_procreg)
c9302810 1121 return rreg->image;
3d3d428f 1122 else
c9302810 1123 IMAGE_ERR;
5a6312e8 1124 break;
3d3d428f
NC
1125
1126 case CR16_P_REGTYPE:
91d6fa6a 1127 return rreg->image;
3d3d428f
NC
1128 break;
1129
1130 default:
1131 IMAGE_ERR;
5a6312e8 1132 break;
3d3d428f
NC
1133 }
1134
1135 return 0;
1136}
1137
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. */
1146
1147static void
1148set_operand (char *operand, ins * cr16_ins)
1149{
33eaf5de
NC
1150 char *operandS; /* Pointer to start of sub-operand. */
1151 char *operandE; /* Pointer to end of sub-operand. */
3d3d428f
NC
1152
1153 argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument. */
1154
1155 /* Initialize pointers. */
1156 operandS = operandE = operand;
1157
1158 switch (cur_arg->type)
1159 {
1160 case arg_ic: /* Case $0x18. */
1161 operandS++;
1a0670f3 1162 /* Fall through. */
3d3d428f
NC
1163 case arg_c: /* Case 0x18. */
1164 /* Set constant. */
1165 process_label_constant (operandS, cr16_ins);
1166
1167 if (cur_arg->type != arg_ic)
c9302810 1168 cur_arg->type = arg_c;
3d3d428f
NC
1169 break;
1170
1171 case arg_icr: /* Case $0x18(r1). */
1172 operandS++;
1173 case arg_cr: /* Case 0x18(r1). */
1174 /* Set displacement constant. */
1175 while (*operandE != '(')
c9302810 1176 operandE++;
3d3d428f
NC
1177 *operandE = '\0';
1178 process_label_constant (operandS, cr16_ins);
1179 operandS = operandE;
1a0670f3 1180 /* Fall through. */
3d3d428f
NC
1181 case arg_rbase: /* Case (r1) or (r1,r0). */
1182 operandS++;
1183 /* Set register base. */
1184 while (*operandE != ')')
c9302810 1185 operandE++;
3d3d428f
NC
1186 *operandE = '\0';
1187 if ((cur_arg->r = get_register (operandS)) == nullregister)
c9302810
AM
1188 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1189 operandS, ins_parse);
3d3d428f
NC
1190
1191 /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1192 if ((cur_arg->type != arg_rbase)
c9302810
AM
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)))
1197 {
1198 cur_arg->type = arg_crp;
1199 cur_arg->rp = cur_arg->r;
1200 }
3d3d428f
NC
1201 break;
1202
1203 case arg_crp: /* Case 0x18(r1,r0). */
1204 /* Set displacement constant. */
1205 while (*operandE != '(')
c9302810 1206 operandE++;
3d3d428f
NC
1207 *operandE = '\0';
1208 process_label_constant (operandS, cr16_ins);
1209 operandS = operandE;
1210 operandS++;
1211 /* Set register pair base. */
1212 while (*operandE != ')')
c9302810 1213 operandE++;
3d3d428f
NC
1214 *operandE = '\0';
1215 if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
c9302810
AM
1216 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1217 operandS, ins_parse);
3d3d428f
NC
1218 break;
1219
1220 case arg_idxr:
1221 /* Set register pair base. */
1222 if ((strchr (operandS,'(') != NULL))
c9302810
AM
1223 {
1224 while ((*operandE != '(') && (! ISSPACE (*operandE)))
1225 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);
1229 *operandE++ = '\0';
1230 cur_arg->type = arg_idxrp;
1231 }
3d3d428f 1232 else
c9302810 1233 cur_arg->rp = -1;
3d3d428f 1234
c9302810 1235 operandE = operandS;
3d3d428f
NC
1236 /* Set displacement constant. */
1237 while (*operandE != ']')
c9302810 1238 operandE++;
3d3d428f
NC
1239 process_label_constant (++operandE, cr16_ins);
1240 *operandE++ = '\0';
1241 operandE = operandS;
1242
1243 /* Set index register . */
1244 operandS = strchr (operandE,'[');
1245 if (operandS != NULL)
c9302810
AM
1246 { /* Eliminate '[', detach from rest of operand. */
1247 *operandS++ = '\0';
1248
1249 operandE = strchr (operandS, ']');
1250
1251 if (operandE == NULL)
1252 as_bad (_("unmatched '['"));
1253 else
1254 { /* Eliminate ']' and make sure it was the last thing
1255 in the string. */
1256 *operandE = '\0';
1257 if (*(operandE + 1) != '\0')
1258 as_bad (_("garbage after index spec ignored"));
1259 }
1260 }
3d3d428f
NC
1261
1262 if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
c9302810
AM
1263 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1264 operandS, ins_parse);
3d3d428f
NC
1265 *operandE = '\0';
1266 *operandS = '\0';
1267 break;
1268
1269 default:
1270 break;
1271 }
1272}
1273
1274/* Parse a single operand.
1275 operand - Current operand to parse.
1276 cr16_ins - Current assembled instruction. */
1277
1278static void
1279parse_operand (char *operand, ins * cr16_ins)
1280{
1281 int ret_val;
1282 argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
1283
1284 /* Initialize the type to NULL before parsing. */
1285 cur_arg->type = nullargs;
1286
1287 /* Check whether this is a condition code . */
1288 if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
1289 {
1290 cur_arg->type = arg_cc;
1291 cur_arg->cc = ret_val;
1292 cur_arg->X_op = O_register;
1293 return;
1294 }
1295
1296 /* Check whether this is a general processor register. */
1297 if ((ret_val = get_register (operand)) != nullregister)
1298 {
1299 cur_arg->type = arg_r;
1300 cur_arg->r = ret_val;
1301 cur_arg->X_op = 0;
1302 return;
1303 }
1304
1305 /* Check whether this is a general processor register pair. */
1306 if ((operand[0] == '(')
1307 && ((ret_val = get_register_pair (operand)) != nullregister))
1308 {
1309 cur_arg->type = arg_rp;
1310 cur_arg->rp = ret_val;
1311 cur_arg->X_op = O_register;
1312 return;
1313 }
1314
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))
1320 {
1321 cur_arg->type = arg_pr;
1322 cur_arg->pr = ret_val;
1323 cur_arg->X_op = O_register;
1324 return;
1325 }
1326
1327 /* Check whether this is a processor register - 32 bit. */
1328 if ((ret_val = get_pregisterp (operand)) != nullpregister)
1329 {
1330 cur_arg->type = arg_prp;
1331 cur_arg->prp = ret_val;
1332 cur_arg->X_op = O_register;
1333 return;
1334 }
1335
1336 /* Deal with special characters. */
1337 switch (operand[0])
1338 {
1339 case '$':
1340 if (strchr (operand, '(') != NULL)
c9302810 1341 cur_arg->type = arg_icr;
3d3d428f 1342 else
c9302810 1343 cur_arg->type = arg_ic;
3d3d428f
NC
1344 goto set_params;
1345 break;
1346
1347 case '(':
1348 cur_arg->type = arg_rbase;
1349 goto set_params;
1350 break;
1351
1352 case '[':
1353 cur_arg->type = arg_idxr;
1354 goto set_params;
1355 break;
1356
1357 default:
1358 break;
1359 }
1360
1361 if (strchr (operand, '(') != NULL)
1362 {
1363 if (strchr (operand, ',') != NULL
c9302810
AM
1364 && (strchr (operand, ',') > strchr (operand, '(')))
1365 cur_arg->type = arg_crp;
3d3d428f 1366 else
c9302810 1367 cur_arg->type = arg_cr;
3d3d428f
NC
1368 }
1369 else
1370 cur_arg->type = arg_c;
1371
c9302810 1372 /* Parse an operand according to its type. */
3d3d428f
NC
1373 set_params:
1374 cur_arg->constant = 0;
1375 set_operand (operand, cr16_ins);
1376}
1377
1378/* Parse the various operands. Each operand is then analyzed to fillup
1379 the fields in the cr16_ins data structure. */
1380
1381static void
1382parse_operands (ins * cr16_ins, char *operands)
1383{
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. */
1391
1392 /* Preprocess the list of registers, if necessary. */
1393 operandS = operandH = operandT = operands;
1394
1395 while (*operandT != '\0')
1396 {
1397 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
c9302810
AM
1398 {
1399 *operandT++ = '\0';
1400 operand[op_num++] = strdup (operandH);
1401 operandH = operandT;
1402 continue;
1403 }
3d3d428f
NC
1404
1405 if (*operandT == ' ')
c9302810 1406 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
3d3d428f
NC
1407
1408 if (*operandT == '(')
c9302810 1409 bracket_flag = 1;
3d3d428f 1410 else if (*operandT == '[')
c9302810 1411 sq_bracket_flag = 1;
3d3d428f
NC
1412
1413 if (*operandT == ')')
c9302810
AM
1414 {
1415 if (bracket_flag)
1416 bracket_flag = 0;
1417 else
1418 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1419 }
3d3d428f 1420 else if (*operandT == ']')
c9302810
AM
1421 {
1422 if (sq_bracket_flag)
1423 sq_bracket_flag = 0;
1424 else
1425 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1426 }
3d3d428f
NC
1427
1428 if (bracket_flag == 1 && *operandT == ')')
c9302810 1429 bracket_flag = 0;
3d3d428f 1430 else if (sq_bracket_flag == 1 && *operandT == ']')
c9302810 1431 sq_bracket_flag = 0;
3d3d428f
NC
1432
1433 operandT++;
1434 }
1435
1436 /* Adding the last operand. */
1437 operand[op_num++] = strdup (operandH);
1438 cr16_ins->nargs = op_num;
1439
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);
1443
1444 /* Now we parse each operand separately. */
1445 for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
1446 {
1447 cur_arg_num = op_num;
1448 parse_operand (operand[op_num], cr16_ins);
1449 free (operand[op_num]);
1450 }
1451
1452 if (allocated)
1453 free (operandS);
1454}
1455
1456/* Get the trap index in dispatch table, given its name.
1457 This routine is used by assembling the 'excp' instruction. */
1458
1459static int
1460gettrap (char *s)
1461{
1462 const trap_entry *trap;
1463
1464 for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1465 if (strcasecmp (trap->name, s) == 0)
1466 return trap->entry;
1467
2b0f3761 1468 /* To make compatible with CR16 4.1 tools, the below 3-lines of
3d3d428f
NC
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))
1472 return trap->entry;
1473
1474 as_bad (_("Unknown exception: `%s'"), s);
1475 return 0;
1476}
1477
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. */
1481
1482static void
1483parse_insn (ins *insn, char *operands)
1484{
1485 int i;
1486
1487 /* Handle instructions with no operands. */
1488 for (i = 0; cr16_no_op_insn[i] != NULL; i++)
1489 {
1490 if (streq (cr16_no_op_insn[i], instruction->mnemonic))
1491 {
1492 insn->nargs = 0;
1493 return;
1494 }
1495 }
1496
1497 /* Handle 'excp' instructions. */
1498 if (IS_INSN_MNEMONIC ("excp"))
1499 {
1500 insn->nargs = 1;
1501 insn->arg[0].type = arg_ic;
1502 insn->arg[0].constant = gettrap (operands);
1503 insn->arg[0].X_op = O_constant;
1504 return;
1505 }
1506
1507 if (operands != NULL)
1508 parse_operands (insn, operands);
1509}
1510
1511/* bCC instruction requires special handling. */
1512static char *
1513get_b_cc (char * op)
1514{
1515 unsigned int i;
3d3d428f 1516
d3e0badd
AM
1517 if (op[1] == 0 || (op[2] != 0 && op[3] != 0))
1518 return NULL;
3d3d428f
NC
1519
1520 for (i = 0; i < cr16_num_cc ; i++)
d3e0badd 1521 if (streq (op + 1, cr16_b_cond_tab[i]))
3d3d428f
NC
1522 return (char *) cr16_b_cond_tab[i];
1523
1524 return NULL;
1525}
1526
1527/* bCC instruction requires special handling. */
1528static int
1529is_bcc_insn (char * op)
1530{
1531 if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
c9302810 1532 || streq (op, "beq0w") || streq (op, "bnq0w")))
3d3d428f
NC
1533 if ((op[0] == 'b') && (get_b_cc (op) != NULL))
1534 return 1;
1535 return 0;
1536}
1537
1538/* Cinv instruction requires special handling. */
1539
fd596c16 1540static void
3d3d428f
NC
1541check_cinv_options (char * operand)
1542{
1543 char *p = operand;
3d3d428f
NC
1544
1545 while (*++p != ']')
1546 {
fd596c16
NC
1547 switch (*p)
1548 {
1549 case ',':
1550 case ' ':
1551 case 'i':
1552 case 'u':
1553 case 'd':
1554 break;
1555 default:
1556 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1557 }
3d3d428f 1558 }
3d3d428f
NC
1559}
1560
1561/* Retrieve the opcode image of a given register pair.
1562 If the register is illegal for the current instruction,
1563 issue an error. */
1564
1565static int
1566getregp_image (reg r)
1567{
91d6fa6a 1568 const reg_entry *rreg;
3d3d428f
NC
1569 char *reg_name;
1570
1571 /* Check whether the register is in registers table. */
1572 if (r < MAX_REG)
91d6fa6a 1573 rreg = cr16_regptab + r;
3d3d428f
NC
1574 /* Register not found. */
1575 else
1576 {
1577 as_bad (_("Unknown register pair: `%d'"), r);
1578 return 0;
1579 }
1580
91d6fa6a 1581 reg_name = rreg->name;
3d3d428f 1582
c9302810
AM
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); \
3d3d428f
NC
1587 break;
1588
91d6fa6a 1589 switch (rreg->type)
3d3d428f
NC
1590 {
1591 case CR16_RP_REGTYPE:
91d6fa6a 1592 return rreg->image;
3d3d428f
NC
1593 default:
1594 RPAIR_IMAGE_ERR;
1595 }
1596
1597 return 0;
1598}
1599
1600/* Retrieve the opcode image of a given index register pair.
1601 If the register is illegal for the current instruction,
1602 issue an error. */
1603
1604static int
1605getidxregp_image (reg r)
1606{
91d6fa6a 1607 const reg_entry *rreg;
3d3d428f
NC
1608 char *reg_name;
1609
1610 /* Check whether the register is in registers table. */
1611 if (r < MAX_REG)
91d6fa6a 1612 rreg = cr16_regptab + r;
3d3d428f
NC
1613 /* Register not found. */
1614 else
1615 {
1616 as_bad (_("Unknown register pair: `%d'"), r);
1617 return 0;
1618 }
1619
91d6fa6a 1620 reg_name = rreg->name;
3d3d428f 1621
c9302810
AM
1622 /* Issue a error message when register pair is illegal. */
1623#define IDX_RPAIR_IMAGE_ERR \
3d3d428f 1624 as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
c9302810 1625 reg_name, ins_parse); \
3d3d428f 1626
91d6fa6a 1627 if (rreg->type == CR16_RP_REGTYPE)
3d3d428f 1628 {
91d6fa6a 1629 switch (rreg->image)
c9302810
AM
1630 {
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;
1639 default:
1640 break;
1641 }
3d3d428f
NC
1642 }
1643
1644 IDX_RPAIR_IMAGE_ERR;
1645 return 0;
1646}
1647
33eaf5de 1648/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1649 If the register is illegal for the current instruction,
1650 issue an error. */
1651static int
249c2423 1652getprocreg_image (int r)
3d3d428f 1653{
91d6fa6a 1654 const reg_entry *rreg;
3d3d428f
NC
1655 char *reg_name;
1656
1657 /* Check whether the register is in registers table. */
d86fff44 1658 if (r >= MAX_REG && r < MAX_PREG)
91d6fa6a 1659 rreg = &cr16_pregtab[r - MAX_REG];
3d3d428f
NC
1660 /* Register not found. */
1661 else
1662 {
1663 as_bad (_("Unknown processor register : `%d'"), r);
1664 return 0;
1665 }
1666
91d6fa6a 1667 reg_name = rreg->name;
3d3d428f 1668
c9302810
AM
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); \
3d3d428f
NC
1673 break;
1674
91d6fa6a 1675 switch (rreg->type)
3d3d428f
NC
1676 {
1677 case CR16_P_REGTYPE:
91d6fa6a 1678 return rreg->image;
3d3d428f
NC
1679 default:
1680 PROCREG_IMAGE_ERR;
1681 }
1682
1683 return 0;
1684}
1685
33eaf5de 1686/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1687 If the register is illegal for the current instruction,
1688 issue an error. */
1689static int
249c2423 1690getprocregp_image (int r)
3d3d428f 1691{
91d6fa6a 1692 const reg_entry *rreg;
3d3d428f
NC
1693 char *reg_name;
1694 int pregptab_disp = 0;
1695
1696 /* Check whether the register is in registers table. */
d86fff44 1697 if (r >= MAX_REG && r < MAX_PREG)
3d3d428f
NC
1698 {
1699 r = r - MAX_REG;
1700 switch (r)
c9302810
AM
1701 {
1702 case 4: pregptab_disp = 1; break;
1703 case 6: pregptab_disp = 2; break;
1704 case 8:
1705 case 9:
1706 case 10:
1707 pregptab_disp = 3; break;
1708 case 12:
1709 pregptab_disp = 4; break;
1710 case 14:
1711 pregptab_disp = 5; break;
1712 default: break;
1713 }
91d6fa6a 1714 rreg = &cr16_pregptab[r - pregptab_disp];
3d3d428f
NC
1715 }
1716 /* Register not found. */
1717 else
1718 {
1719 as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
1720 return 0;
1721 }
1722
91d6fa6a 1723 reg_name = rreg->name;
3d3d428f 1724
c9302810
AM
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); \
3d3d428f
NC
1729 break;
1730
91d6fa6a 1731 switch (rreg->type)
3d3d428f
NC
1732 {
1733 case CR16_P_REGTYPE:
91d6fa6a 1734 return rreg->image;
3d3d428f
NC
1735 default:
1736 PROCREGP_IMAGE_ERR;
1737 }
1738
1739 return 0;
1740}
1741
1742/* Routine used to represent integer X using NBITS bits. */
1743
1744static long
1745getconstant (long x, int nbits)
1746{
c9302810
AM
1747 if ((unsigned) nbits >= sizeof (x) * CHAR_BIT)
1748 return x;
1749 return x & ((1UL << nbits) - 1);
3d3d428f
NC
1750}
1751
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. */
1756
1757static void
1758print_constant (int nbits, int shift, argument *arg)
1759{
1760 unsigned long mask = 0;
c9302810 1761 unsigned long constant = getconstant (arg->constant, nbits);
3d3d428f
NC
1762
1763 switch (nbits)
1764 {
1765 case 32:
1766 case 28:
1767 /* mask the upper part of the constant, that is, the bits
c9302810
AM
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. */
3d3d428f
NC
1771 mask = (1 << (nbits - 16)) - 1;
1772 /* Divide the constant between two consecutive words :
c9302810
AM
1773 0 1 2 3
1774 +---------+---------+---------+---------+
1775 | | X X X X | x X x X | |
1776 +---------+---------+---------+---------+
1777 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1778
1779 CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
c9302810 1780 CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
3d3d428f
NC
1781 break;
1782
1783 case 21:
1a0670f3
AM
1784 if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
1785 nbits = 20;
1786 /* Fall through. */
3d3d428f
NC
1787 case 24:
1788 case 22:
1789 case 20:
1790 /* mask the upper part of the constant, that is, the bits
c9302810
AM
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. */
3d3d428f
NC
1794 mask = (1 << (nbits - 16)) - 1;
1795 /* Divide the constant between two consecutive words :
c9302810
AM
1796 0 1 2 3
1797 +---------+---------+---------+---------+
1798 | | X X X X | - X - X | |
1799 +---------+---------+---------+---------+
1800 output_opcode[0] output_opcode[1] */
1801
1802 if (instruction->size > 2 && shift == WORD_SHIFT)
1803 {
1804 if (arg->type == arg_idxrp)
1805 {
1806 CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
1807 CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1808 }
1809 else
1810 {
1811 CR16_PRINT (0,
1812 ((((constant >> WORD_SHIFT) & mask & 0xf) << 8)
1813 | (((constant >> WORD_SHIFT) & mask & 0xf0) >> 4)),
1814 0);
1815 CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1816 }
1817 }
3d3d428f 1818 else
c9302810 1819 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1820 break;
1821
1822 case 14:
1823 if (arg->type == arg_idxrp)
c9302810
AM
1824 {
1825 if (instruction->size == 2)
1826 {
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. */
1831 }
1832 else
1833 CR16_PRINT (0, constant, shift);
1834 }
3d3d428f
NC
1835 break;
1836
1837 case 16:
1838 case 12:
1839 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
c9302810
AM
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')
1842 will be overridden.
1843 0 1 2 3
1844 +---------+---------+---------+---------+
1845 | 'match' | | X X X X | |
1846 +---------+---------+---------+---------+
1847 output_opcode[0] output_opcode[1] */
1848
1849 if (instruction->size > 2 && shift == WORD_SHIFT)
1850 CR16_PRINT (1, constant, WORD_SHIFT);
3d3d428f 1851 else
c9302810 1852 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1853 break;
1854
1855 case 8:
c9302810
AM
1856 CR16_PRINT (0, (constant / 2) & 0xf, shift);
1857 CR16_PRINT (0, (constant / 2) >> 4, shift + 8);
3d3d428f
NC
1858 break;
1859
1860 default:
c9302810 1861 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1862 break;
1863 }
1864}
1865
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. */
1871
1872static void
1873print_operand (int nbits, int shift, argument *arg)
1874{
1875 switch (arg->type)
1876 {
1877 case arg_cc:
1878 CR16_PRINT (0, arg->cc, shift);
1879 break;
1880
1881 case arg_r:
1882 CR16_PRINT (0, getreg_image (arg->r), shift);
1883 break;
1884
1885 case arg_rp:
1886 CR16_PRINT (0, getregp_image (arg->rp), shift);
1887 break;
1888
1889 case arg_pr:
1890 CR16_PRINT (0, getprocreg_image (arg->pr), shift);
1891 break;
1892
1893 case arg_prp:
1894 CR16_PRINT (0, getprocregp_image (arg->prp), shift);
1895 break;
1896
1897 case arg_idxrp:
1898 /* 16 12 8 6 0
c9302810
AM
1899 +-----------------------------+
1900 | r_index | disp | rp_base |
1901 +-----------------------------+ */
3d3d428f
NC
1902
1903 if (instruction->size == 3)
c9302810
AM
1904 {
1905 CR16_PRINT (0, getidxregp_image (arg->rp), 0);
1906 CR16_PRINT (0, getreg_image (arg->i_r) & 1, 3);
1907 }
3d3d428f 1908 else
c9302810
AM
1909 {
1910 CR16_PRINT (0, getidxregp_image (arg->rp), 16);
1911 CR16_PRINT (0, getreg_image (arg->i_r) & 1, 19);
1912 }
3d3d428f
NC
1913 print_constant (nbits, shift, arg);
1914 break;
1915
1916 case arg_idxr:
c9302810
AM
1917 CR16_PRINT (0, getreg_image (arg->i_r) & 1,
1918 (IS_INSN_TYPE (CSTBIT_INS)
1919 && instruction->mnemonic[4] == 'b') ? 23 : 24);
3d3d428f
NC
1920 print_constant (nbits, shift, arg);
1921 break;
1922
1923 case arg_ic:
1924 case arg_c:
1925 print_constant (nbits, shift, arg);
1926 break;
1927
1928 case arg_rbase:
1929 CR16_PRINT (0, getreg_image (arg->r), shift);
1930 break;
1931
1932 case arg_cr:
c9302810 1933 print_constant (nbits, shift, arg);
3d3d428f 1934 /* Add the register argument to the output_opcode. */
c9302810 1935 CR16_PRINT (0, getreg_image (arg->r), shift - 16);
3d3d428f
NC
1936 break;
1937
1938 case arg_crp:
c9302810
AM
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);
3d3d428f 1945 else
c9302810 1946 CR16_PRINT (0, getregp_image (arg->rp), shift);
3d3d428f
NC
1947 break;
1948
1949 default:
1950 break;
1951 }
1952}
1953
1954/* Retrieve the number of operands for the current assembled instruction. */
1955
1956static int
1957get_number_of_operands (void)
1958{
1959 int i;
1960
1961 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1962 ;
1963 return i;
1964}
1965
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. */
1970
1971static op_err
1972check_range (long *num, int bits, int unsigned flags, int update)
1973{
c9302810 1974 int32_t min, max;
6610dc6d 1975 op_err retval = OP_LEGAL;
c9302810 1976 int32_t value = *num;
3d3d428f
NC
1977
1978 /* Verify operand value is even. */
1979 if (flags & OP_EVEN)
1980 {
1981 if (value % 2)
c9302810 1982 return OP_NOT_EVEN;
3d3d428f
NC
1983 }
1984
1985 if (flags & OP_DEC)
1986 {
1987 value -= 1;
1988 if (update)
c9302810 1989 *num = value;
3d3d428f
NC
1990 }
1991
1992 if (flags & OP_SHIFT)
1993 {
1994 value >>= 1;
1995 if (update)
c9302810 1996 *num = value;
3d3d428f
NC
1997 }
1998 else if (flags & OP_SHIFT_DEC)
1999 {
2000 value = (value >> 1) - 1;
2001 if (update)
c9302810 2002 *num = value;
3d3d428f
NC
2003 }
2004
2005 if (flags & OP_ABS20)
2006 {
2007 if (value > 0xEFFFF)
c9302810 2008 return OP_OUT_OF_RANGE;
3d3d428f
NC
2009 }
2010
2011 if (flags & OP_ESC)
2012 {
2013 if (value == 0xB || value == 0x9)
c9302810 2014 return OP_OUT_OF_RANGE;
3d3d428f 2015 else if (value == -1)
c9302810
AM
2016 {
2017 if (update)
2018 *num = 9;
2019 return retval;
2020 }
3d3d428f
NC
2021 }
2022
2023 if (flags & OP_ESC1)
2024 {
2025 if (value > 13)
c9302810
AM
2026 return OP_OUT_OF_RANGE;
2027 }
2028
2029 if (bits == 0)
2030 {
2031 if (value != 0)
2032 retval = OP_OUT_OF_RANGE;
2033 return retval;
2034 }
2035
2036 if (flags & OP_SIGNED)
2037 {
2038 max = (1U << (bits - 1)) - 1;
2039 min = - (1U << (bits - 1));
2040 if (value > max || value < min)
2041 retval = OP_OUT_OF_RANGE;
2042 }
2043 else if (flags & OP_UNSIGNED)
2044 {
2045 max = (1U << (bits - 1) << 1) - 1;
2046 if ((uint32_t) value > (uint32_t) max)
2047 retval = OP_OUT_OF_RANGE;
2048 }
2049 else if (flags & OP_NEG)
2050 {
2051 min = - ((1U << (bits - 1)) - 1);
2052 if (value < min)
2053 retval = OP_OUT_OF_RANGE;
2054 }
2055 return retval;
3d3d428f
NC
2056}
2057
33eaf5de 2058/* Bunch of error checking.
3d3d428f
NC
2059 The checks are made after a matching instruction was found. */
2060
2061static void
2062warn_if_needed (ins *insn)
2063{
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))
2068 {
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))
c9302810
AM
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);
3d3d428f
NC
2074 }
2075
2076 if (IS_INSN_MNEMONIC ("pop")
2077 || IS_INSN_MNEMONIC ("push")
2078 || IS_INSN_MNEMONIC ("popret"))
2079 {
2080 unsigned int count = insn->arg[0].constant, reg_val;
2081
33eaf5de 2082 /* Check if count operand caused to save/retrieve the RA twice
c9302810
AM
2083 to generate warning message. */
2084 if (insn->nargs > 2)
2085 {
2086 reg_val = getreg_image (insn->arg[1].r);
2087
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."));
2095
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);
2099 }
3d3d428f
NC
2100
2101 if (insn->nargs > 1)
c9302810
AM
2102 {
2103 reg_val = getreg_image (insn->arg[1].r);
2104
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);
2113 }
2114 else
2115 {
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);
2119 }
3d3d428f
NC
2120 }
2121
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)
2125 {
2126 if (getreg_image (insn->arg[1].r) == getreg_image (sp))
c9302810 2127 as_bad (_("`%s' has undefined result"), ins_parse);
3d3d428f
NC
2128 }
2129
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)
2133 {
2134 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
c9302810
AM
2135 as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2136 getreg_image (insn->arg[0].r));
3d3d428f
NC
2137 }
2138}
2139
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. */
2143
2144static int
2145adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
2146{
2147 int ret_value = 0;
2148
2149 if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
2150 {
2151 if ((instruction->operands[0].op_type == abs24)
c9302810
AM
2152 && ((insn->arg[0].constant) > 0xF00000))
2153 {
2154 insn->arg[0].constant &= 0xFFFFF;
2155 instruction--;
2156 ret_value = 1;
2157 }
3d3d428f
NC
2158 }
2159
2160 return ret_value;
2161}
2162
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. */
2171
2172static int
9202e88a 2173assemble_insn (const char *mnemonic, ins *insn)
3d3d428f
NC
2174{
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. */
2184 int match = 0;
2185 int i;
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;
2198
c9302810
AM
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++) \
3d3d428f
NC
2202 ARRAY[i] = FUNC (instruction->operands[i].op_type)
2203
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)
2207
2208 /* Instruction has no operands -> only copy the constant opcode. */
2209 if (insn->nargs == 0)
2210 {
2211 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2212 return 1;
2213 }
2214
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);
2222
2223 while (/* Check that match is still not found. */
c9302810
AM
2224 match != 1
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))
3d3d428f
NC
2231 {
2232 /* Check whether number of arguments is legal. */
2233 if (get_number_of_operands () != insn->nargs)
c9302810 2234 goto next_insn;
3d3d428f
NC
2235 found_same_number_of_operands = 1;
2236
2237 /* Initialize arrays with data of each operand in current template. */
2238 GET_CURRENT_TYPE;
2239 GET_CURRENT_SIZE;
2240 GET_CURRENT_FLAGS;
2241
2242 /* Check for type compatibility. */
2243 for (i = 0; i < insn->nargs; i++)
c9302810
AM
2244 {
2245 if (cur_type[i] != insn->arg[i].type)
2246 {
2247 if (invalid_optype == -1)
2248 invalid_optype = i + 1;
2249 goto next_insn;
2250 }
2251 }
3d3d428f
NC
2252 found_same_argument_types = 1;
2253
2254 for (i = 0; i < insn->nargs; i++)
c9302810
AM
2255 {
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))
2260 goto next_insn;
2261
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))
2267 goto next_insn;
2268
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],
2275 cur_flags[i], 0)))
2276 {
2277 if (invalid_const == -1)
2278 {
2279 invalid_const = i + 1;
2280 const_err = op_error;
2281 }
2282 goto next_insn;
2283 }
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
2288 > cur_size[i]))
2289 goto next_insn;
2290 }
3d3d428f
NC
2291 found_const_within_range = 1;
2292
2293 /* If we got till here -> Full match is found. */
2294 match = 1;
2295 break;
2296
dc1e8a47
AM
2297 /* Try again with next instruction. */
2298 next_insn:
3d3d428f
NC
2299 instruction++;
2300 }
2301
2302 if (!match)
2303 {
2304 /* We haven't found a match - instruction can't be assembled. */
2305 if (!found_same_number_of_operands)
c9302810 2306 as_bad (_("Incorrect number of operands"));
3d3d428f 2307 else if (!found_same_argument_types)
c9302810 2308 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
3d3d428f 2309 else if (!found_const_within_range)
c9302810
AM
2310 {
2311 switch (const_err)
2312 {
2313 case OP_OUT_OF_RANGE:
2314 as_bad (_("Operand out of range (arg %d)"), invalid_const);
2315 break;
2316 case OP_NOT_EVEN:
2317 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
2318 break;
2319 default:
2320 as_bad (_("Illegal operand (arg %d)"), invalid_const);
2321 break;
2322 }
2323 }
2324
2325 return 0;
3d3d428f
NC
2326 }
2327 else
2328 /* Full match - print the encoding to output file. */
2329 {
33eaf5de 2330 /* Make further checking (such that couldn't be made earlier).
c9302810 2331 Warn the user if necessary. */
3d3d428f
NC
2332 warn_if_needed (insn);
2333
2334 /* Check whether we need to adjust the instruction pointer. */
2335 if (adjust_if_needed (insn))
c9302810
AM
2336 /* If instruction pointer was adjusted, we need to update
2337 the size of the current template operands. */
2338 GET_CURRENT_SIZE;
3d3d428f
NC
2339
2340 for (i = 0; i < insn->nargs; i++)
c9302810
AM
2341 {
2342 int j = instruction->flags & REVERSE_MATCH ?
2343 i == 0 ? 1 :
2344 i == 1 ? 0 : i :
2345 i;
2346
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);
2352 }
3d3d428f
NC
2353
2354 /* First, copy the instruction's opcode. */
2355 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2356
2357 for (i = 0; i < insn->nargs; i++)
c9302810
AM
2358 {
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)
2362 {
2363 insn->rtype = BFD_RELOC_CR16_DISP24a;
2364 continue;
2365 }
2366 cur_arg_num = i;
2367 print_operand (cur_size[i], instruction->operands[i].shift,
2368 &insn->arg[i]);
2369 }
3d3d428f
NC
2370 }
2371
2372 return 1;
2373}
2374
2375/* Print the instruction.
2376 Handle also cases where the instruction is relaxable/relocatable. */
2377
2378static void
2379print_insn (ins *insn)
2380{
2381 unsigned int i, j, insn_size;
2382 char *this_frag;
2383 unsigned short words[4];
2384 int addr_mod;
2385
2386 /* Arrange the insn encodings in a WORD size array. */
2387 for (i = 0, j = 0; i < 2; i++)
2388 {
2389 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2390 words[j++] = output_opcode[i] & 0xFFFF;
2391 }
2392
c9302810
AM
2393 /* Handle relocation. */
2394 if ((instruction->flags & RELAXABLE) && relocatable)
2395 {
2396 int relax_subtype;
2397 /* Write the maximal instruction size supported. */
2398 insn_size = INSN_MAX_SIZE;
2399
2400 if (IS_INSN_TYPE (BRANCH_INS))
2401 {
2402 switch (insn->rtype)
2403 {
2404 case BFD_RELOC_CR16_DISP24:
2405 relax_subtype = 2;
2406 break;
2407 case BFD_RELOC_CR16_DISP16:
2408 relax_subtype = 1;
2409 break;
2410 default:
2411 relax_subtype = 0;
2412 break;
2413 }
2414 }
2415 else
2416 abort ();
2417
2418 this_frag = frag_var (rs_machine_dependent, insn_size *2,
2419 4, relax_subtype,
2420 insn->exp.X_add_symbol,
2421 0,
2422 0);
2423 }
2424 else
2425 {
2426 insn_size = instruction->size;
2427 this_frag = frag_more (insn_size * 2);
2428
2429 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2430 {
2431 reloc_howto_type *reloc_howto;
2432 int size;
2433
2434 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2435
2436 if (!reloc_howto)
2437 abort ();
2438
2439 size = bfd_get_reloc_size (reloc_howto);
2440
2441 if (size < 1 || size > 4)
2442 abort ();
2443
2444 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2445 size, &insn->exp, reloc_howto->pc_relative,
2446 insn->rtype);
2447 }
2448 }
3d3d428f
NC
2449
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;
2456
2457 /* Write the instruction encoding to frag. */
2458 for (i = 0; i < insn_size; i++)
2459 {
2460 md_number_to_chars (this_frag, (valueT) words[i], 2);
2461 this_frag += 2;
2462 }
2463}
2464
9202e88a
TS
2465/* Actually assemble an instruction. */
2466
2467static void
2468cr16_assemble (const char *op, char *param)
2469{
2470 ins cr16_ins;
2471
2472 /* Find the instruction. */
629310ab 2473 instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
9202e88a
TS
2474 if (instruction == NULL)
2475 {
2476 as_bad (_("Unknown opcode: `%s'"), op);
2477 return;
2478 }
2479
2480 /* Tie dwarf2 debug info to the address at the start of the insn. */
2481 dwarf2_emit_insn (0);
2482
2483 /* Parse the instruction's operands. */
2484 parse_insn (&cr16_ins, param);
2485
2486 /* Assemble the instruction - return upon failure. */
2487 if (assemble_insn (op, &cr16_ins) == 0)
2488 return;
2489
2490 /* Print the instruction. */
2491 print_insn (&cr16_ins);
2492}
2493
3d3d428f
NC
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. */
2497
2498void
2499md_assemble (char *op)
2500{
2501 ins cr16_ins;
2502 char *param, param1[32];
3d3d428f
NC
2503
2504 /* Reset global variables for a new instruction. */
2505 reset_vars (op);
2506
2507 /* Strip the mnemonic. */
2508 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2509 ;
3d3d428f
NC
2510 *param++ = '\0';
2511
33eaf5de 2512 /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
3d3d428f
NC
2513 if (is_bcc_insn (op))
2514 {
2515 strcpy (param1, get_b_cc (op));
3d3d428f
NC
2516 strcat (param1,",");
2517 strcat (param1, param);
2518 param = (char *) &param1;
9202e88a
TS
2519 cr16_assemble ("b", param);
2520 return;
3d3d428f
NC
2521 }
2522
2523 /* Checking the cinv options and adjust the mnemonic by removing the
2524 extra white spaces. */
2525 if (streq ("cinv", op))
2526 {
c9302810 2527 /* Validate the cinv options. */
9fcc3457 2528 unsigned int op_len, param_len;
3d3d428f 2529 check_cinv_options (param);
9fcc3457
L
2530 op_len = strlen (op);
2531 param_len = strlen (param) + 1;
2532 memmove (op + op_len, param, param_len);
3d3d428f
NC
2533 }
2534
2535 /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2536 lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
33eaf5de 2537 as CR16 core doesn't support lsh[b/w] right shift operations. */
3d3d428f
NC
2538 if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
2539 && (param [0] == '$'))
2540 {
2541 strcpy (param1, param);
2542 /* Find the instruction. */
629310ab 2543 instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
c9302810 2544 parse_operands (&cr16_ins, param1);
3d3d428f 2545 if (((&cr16_ins)->arg[0].type == arg_ic)
c9302810
AM
2546 && ((&cr16_ins)->arg[0].constant >= 0))
2547 {
2548 if (streq ("lshb", op))
2549 cr16_assemble ("ashub", param);
2550 else if (streq ("lshd", op))
2551 cr16_assemble ("ashud", param);
2552 else
2553 cr16_assemble ("ashuw", param);
2554 return;
2555 }
3d3d428f
NC
2556 }
2557
9202e88a 2558 cr16_assemble (op, param);
3d3d428f 2559}