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