]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-cr16.c
PR26430, ASAN: nacl_modify_segment_map elf-nacl.c:164
[thirdparty/binutils-gdb.git] / gas / config / tc-cr16.c
CommitLineData
3d3d428f 1/* tc-cr16.c -- Assembler code for the CR16 CPU core.
b3adc24a 2 Copyright (C) 2007-2020 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
29
30/* Word is considered here as a 16-bit unsigned short int. */
31#define WORD_SHIFT 16
32
33/* Register is 2-byte size. */
34#define REG_SIZE 2
35
36/* Maximum size of a single instruction (in words). */
37#define INSN_MAX_SIZE 3
38
39/* Maximum bits which may be set in a `mask16' operand. */
40#define MAX_REGS_IN_MASK16 8
41
42/* Assign a number NUM, shifted by SHIFT bytes, into a location
43 pointed by index BYTE of array 'output_opcode'. */
44#define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
45
46/* Operand errors. */
47typedef enum
48 {
49 OP_LEGAL = 0, /* Legal operand. */
50 OP_OUT_OF_RANGE, /* Operand not within permitted range. */
51 OP_NOT_EVEN /* Operand is Odd number, should be even. */
52 }
53op_err;
54
55/* Opcode mnemonics hash table. */
629310ab 56static htab_t cr16_inst_hash;
3d3d428f 57/* CR16 registers hash table. */
629310ab 58static htab_t reg_hash;
3d3d428f 59/* CR16 register pair hash table. */
629310ab 60static htab_t regp_hash;
3d3d428f 61/* CR16 processor registers hash table. */
629310ab 62static htab_t preg_hash;
3d3d428f 63/* CR16 processor registers 32 bit hash table. */
629310ab 64static htab_t pregp_hash;
3d3d428f
NC
65/* Current instruction we're assembling. */
66const inst *instruction;
67
68
69static int code_label = 0;
70
71/* Global variables. */
72
73/* Array to hold an instruction encoding. */
74long output_opcode[2];
75
76/* Nonzero means a relocatable symbol. */
77int relocatable;
78
79/* A copy of the original instruction (used in error messages). */
80char ins_parse[MAX_INST_LEN];
81
82/* The current processed argument number. */
83int cur_arg_num;
84
85/* Generic assembler global variables which must be defined by all targets. */
86
87/* Characters which always start a comment. */
88const char comment_chars[] = "#";
89
90/* Characters which start a comment at the beginning of a line. */
91const char line_comment_chars[] = "#";
92
93/* This array holds machine specific line separator characters. */
94const char line_separator_chars[] = ";";
95
96/* Chars that can be used to separate mant from exp in floating point nums. */
97const char EXP_CHARS[] = "eE";
98
99/* Chars that mean this number is a floating point constant as in 0f12.456 */
100const char FLT_CHARS[] = "f'";
101
0b9e228a
SR
102#ifdef OBJ_ELF
103/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
104symbolS * GOT_symbol;
105#endif
106
3d3d428f
NC
107/* Target-specific multicharacter options, not const-declared at usage. */
108const char *md_shortopts = "";
109struct option md_longopts[] =
110{
111 {NULL, no_argument, NULL, 0}
112};
113size_t md_longopts_size = sizeof (md_longopts);
114
115static void
116l_cons (int nbytes)
117{
118 int c;
119 expressionS exp;
120
121#ifdef md_flush_pending_output
122 md_flush_pending_output ();
123#endif
124
125 if (is_it_end_of_statement ())
126 {
127 demand_empty_rest_of_line ();
128 return;
129 }
130
131#ifdef TC_ADDRESS_BYTES
132 if (nbytes == 0)
133 nbytes = TC_ADDRESS_BYTES ();
134#endif
135
136#ifdef md_cons_align
137 md_cons_align (nbytes);
138#endif
139
140 c = 0;
141 do
142 {
143 unsigned int bits_available = BITS_PER_CHAR * nbytes;
144 char *hold = input_line_pointer;
145
146 expression (&exp);
147
148 if (*input_line_pointer == ':')
7fac7ff4
NC
149 {
150 /* Bitfields. */
151 long value = 0;
152
153 for (;;)
154 {
155 unsigned long width;
156
157 if (*input_line_pointer != ':')
158 {
159 input_line_pointer = hold;
160 break;
161 }
162 if (exp.X_op == O_absent)
163 {
164 as_warn (_("using a bit field width of zero"));
165 exp.X_add_number = 0;
166 exp.X_op = O_constant;
167 }
168
169 if (exp.X_op != O_constant)
170 {
171 *input_line_pointer = '\0';
172 as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
173 *input_line_pointer = ':';
174 demand_empty_rest_of_line ();
175 return;
176 }
177
178 if ((width = exp.X_add_number) >
179 (unsigned int)(BITS_PER_CHAR * nbytes))
180 {
992a06ee
AM
181 as_warn (ngettext ("field width %lu too big to fit in %d"
182 " byte: truncated to %d bits",
183 "field width %lu too big to fit in %d"
184 " bytes: truncated to %d bits",
185 nbytes),
186 width, nbytes, (BITS_PER_CHAR * nbytes));
7fac7ff4
NC
187 width = BITS_PER_CHAR * nbytes;
188 } /* Too big. */
189
190
191 if (width > bits_available)
192 {
193 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
194 input_line_pointer = hold;
195 exp.X_add_number = value;
196 break;
197 }
198
199 /* Skip ':'. */
200 hold = ++input_line_pointer;
201
202 expression (&exp);
203 if (exp.X_op != O_constant)
204 {
205 char cache = *input_line_pointer;
206
207 *input_line_pointer = '\0';
208 as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
209 *input_line_pointer = cache;
210 demand_empty_rest_of_line ();
211 return;
212 }
213
8d3842cd 214 value |= ((~(-(1 << width)) & exp.X_add_number)
7fac7ff4
NC
215 << ((BITS_PER_CHAR * nbytes) - bits_available));
216
217 if ((bits_available -= width) == 0
218 || is_it_end_of_statement ()
219 || *input_line_pointer != ',')
220 break;
221
222 hold = ++input_line_pointer;
223 expression (&exp);
224 }
225
226 exp.X_add_number = value;
227 exp.X_op = O_constant;
228 exp.X_unsigned = 1;
229 }
3d3d428f
NC
230
231 if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
7fac7ff4 232 code_label = 1;
3d3d428f
NC
233 emit_expr (&exp, (unsigned int) nbytes);
234 ++c;
235 if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
7fac7ff4
NC
236 {
237 input_line_pointer +=3;
238 break;
239 }
3d3d428f
NC
240 }
241 while ((*input_line_pointer++ == ','));
242
243 /* Put terminator back into stream. */
244 input_line_pointer--;
245
246 demand_empty_rest_of_line ();
247}
248
3d3d428f
NC
249/* This table describes all the machine specific pseudo-ops
250 the assembler has to support. The fields are:
251 *** Pseudo-op name without dot.
252 *** Function to call to execute this pseudo-op.
253 *** Integer arg to pass to the function. */
254
255const pseudo_typeS md_pseudo_table[] =
256{
257 /* In CR16 machine, align is in bytes (not a ptwo boundary). */
258 {"align", s_align_bytes, 0},
259 {"long", l_cons, 4 },
0b9e228a 260 {"4byte", l_cons, 4 },
3d3d428f
NC
261 {0, 0, 0}
262};
263
264/* CR16 relaxation table. */
265const relax_typeS md_relax_table[] =
266{
267 /* bCC */
e9deb29d 268 {0x7f, -0x80, 2, 1}, /* 8 */
3d3d428f
NC
269 {0xfffe, -0x10000, 4, 2}, /* 16 */
270 {0xfffffe, -0x1000000, 6, 0}, /* 24 */
271};
272
273/* Return the bit size for a given operand. */
274
275static int
276get_opbits (operand_type op)
277{
278 if (op < MAX_OPRD)
279 return cr16_optab[op].bit_size;
280
281 return 0;
282}
283
284/* Return the argument type of a given operand. */
285
286static argtype
287get_optype (operand_type op)
288{
289 if (op < MAX_OPRD)
290 return cr16_optab[op].arg_type;
291 else
292 return nullargs;
293}
294
295/* Return the flags of a given operand. */
296
297static int
298get_opflags (operand_type op)
299{
300 if (op < MAX_OPRD)
301 return cr16_optab[op].flags;
302
303 return 0;
304}
305
306/* Get the cc code. */
307
308static int
309get_cc (char *cc_name)
310{
311 unsigned int i;
312
313 for (i = 0; i < cr16_num_cc; i++)
314 if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
315 return i;
316
317 return -1;
318}
319
320/* Get the core processor register 'reg_name'. */
321
322static reg
323get_register (char *reg_name)
324{
91d6fa6a 325 const reg_entry *rreg;
3d3d428f 326
629310ab 327 rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
3d3d428f 328
91d6fa6a
NC
329 if (rreg != NULL)
330 return rreg->value.reg_val;
3d3d428f
NC
331
332 return nullregister;
333}
334/* Get the core processor register-pair 'reg_name'. */
335
336static reg
337get_register_pair (char *reg_name)
338{
91d6fa6a 339 const reg_entry *rreg;
3d3d428f
NC
340 char tmp_rp[16]="\0";
341
33eaf5de 342 /* Add '(' and ')' to the reg pair, if it's not present. */
3739860c 343 if (reg_name[0] != '(')
3d3d428f
NC
344 {
345 tmp_rp[0] = '(';
346 strcat (tmp_rp, reg_name);
347 strcat (tmp_rp,")");
629310ab 348 rreg = (const reg_entry *) str_hash_find (regp_hash, tmp_rp);
3d3d428f
NC
349 }
350 else
629310ab 351 rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
3d3d428f 352
91d6fa6a
NC
353 if (rreg != NULL)
354 return rreg->value.reg_val;
3d3d428f
NC
355
356 return nullregister;
3739860c 357}
3d3d428f
NC
358
359/* Get the index register 'reg_name'. */
360
361static reg
362get_index_register (char *reg_name)
363{
91d6fa6a 364 const reg_entry *rreg;
3d3d428f 365
629310ab 366 rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
3d3d428f 367
91d6fa6a
NC
368 if ((rreg != NULL)
369 && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13)))
370 return rreg->value.reg_val;
3d3d428f
NC
371
372 return nullregister;
373}
374/* Get the core processor index register-pair 'reg_name'. */
375
376static reg
377get_index_register_pair (char *reg_name)
378{
91d6fa6a 379 const reg_entry *rreg;
3d3d428f 380
629310ab 381 rreg = (const reg_entry *) str_hash_find (regp_hash, reg_name);
3d3d428f 382
91d6fa6a 383 if (rreg != NULL)
3d3d428f 384 {
91d6fa6a
NC
385 if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7)
386 || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10))
387 return rreg->value.reg_val;
3d3d428f 388
91d6fa6a 389 as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val);
3d3d428f
NC
390 }
391
392 return nullregister;
393}
394
395/* Get the processor register 'preg_name'. */
396
397static preg
398get_pregister (char *preg_name)
399{
91d6fa6a 400 const reg_entry *prreg;
3d3d428f 401
629310ab 402 prreg = (const reg_entry *) str_hash_find (preg_hash, preg_name);
3d3d428f 403
91d6fa6a
NC
404 if (prreg != NULL)
405 return prreg->value.preg_val;
3d3d428f
NC
406
407 return nullpregister;
408}
409
410/* Get the processor register 'preg_name 32 bit'. */
411
412static preg
413get_pregisterp (char *preg_name)
414{
91d6fa6a 415 const reg_entry *prreg;
3d3d428f 416
629310ab 417 prreg = (const reg_entry *) str_hash_find (pregp_hash, preg_name);
3d3d428f 418
91d6fa6a
NC
419 if (prreg != NULL)
420 return prreg->value.preg_val;
3d3d428f
NC
421
422 return nullpregister;
423}
424
425
426/* Round up a section size to the appropriate boundary. */
427
428valueT
429md_section_align (segT seg, valueT val)
430{
431 /* Round .text section to a multiple of 2. */
432 if (seg == text_section)
433 return (val + 1) & ~1;
434 return val;
435}
436
437/* Parse an operand that is machine-specific (remove '*'). */
438
439void
440md_operand (expressionS * exp)
441{
442 char c = *input_line_pointer;
443
444 switch (c)
445 {
446 case '*':
447 input_line_pointer++;
448 expression (exp);
449 break;
450 default:
451 break;
452 }
453}
454
455/* Reset global variables before parsing a new instruction. */
456
457static void
458reset_vars (char *op)
459{
460 cur_arg_num = relocatable = 0;
461 memset (& output_opcode, '\0', sizeof (output_opcode));
462
463 /* Save a copy of the original OP (used in error messages). */
464 strncpy (ins_parse, op, sizeof ins_parse - 1);
465 ins_parse [sizeof ins_parse - 1] = 0;
466}
467
468/* This macro decides whether a particular reloc is an entry in a
469 switch table. It is used when relaxing, because the linker needs
470 to know about all such entries so that it can adjust them if
471 necessary. */
472
473#define SWITCH_TABLE(fix) \
474 ( (fix)->fx_addsy != NULL \
475 && (fix)->fx_subsy != NULL \
476 && S_GET_SEGMENT ((fix)->fx_addsy) == \
477 S_GET_SEGMENT ((fix)->fx_subsy) \
478 && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
479 && ( (fix)->fx_r_type == BFD_RELOC_CR16_NUM8 \
480 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16 \
481 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32 \
482 || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a))
483
484/* See whether we need to force a relocation into the output file.
485 This is used to force out switch and PC relative relocations when
486 relaxing. */
487
488int
489cr16_force_relocation (fixS *fix)
490{
7fac7ff4 491 if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
3d3d428f
NC
492 return 1;
493
494 return 0;
495}
496
497/* Record a fixup for a cons expression. */
498
499void
62ebcb5c
AM
500cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
501 bfd_reloc_code_real_type rtype)
3d3d428f 502{
3d3d428f
NC
503 switch (len)
504 {
505 default: rtype = BFD_RELOC_NONE; break;
506 case 1: rtype = BFD_RELOC_CR16_NUM8 ; break;
507 case 2: rtype = BFD_RELOC_CR16_NUM16; break;
508 case 4:
509 if (code_label)
7fac7ff4
NC
510 {
511 rtype = BFD_RELOC_CR16_NUM32a;
512 code_label = 0;
513 }
3d3d428f 514 else
7fac7ff4 515 rtype = BFD_RELOC_CR16_NUM32;
3d3d428f
NC
516 break;
517 }
518
519 fix_new_exp (frag, offset, len, exp, 0, rtype);
520}
521
522/* Generate a relocation entry for a fixup. */
523
524arelent *
525tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
526{
527 arelent * reloc;
528
7859b21d 529 /* If symbols are local and resolved, then no relocation needed. */
3739860c 530 if ( ((fixP->fx_addsy)
7859b21d 531 && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
3739860c 532 || ((fixP->fx_subsy)
7859b21d
SR
533 && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)))
534 return NULL;
535
add39d23
TS
536 reloc = XNEW (arelent);
537 reloc->sym_ptr_ptr = XNEW (asymbol *);
3d3d428f
NC
538 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
539 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
540 reloc->addend = fixP->fx_offset;
541
542 if (fixP->fx_subsy != NULL)
543 {
544 if (SWITCH_TABLE (fixP))
545 {
546 /* Keep the current difference in the addend. */
547 reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
548 - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
549
550 switch (fixP->fx_r_type)
551 {
7fac7ff4
NC
552 case BFD_RELOC_CR16_NUM8:
553 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
554 break;
555 case BFD_RELOC_CR16_NUM16:
556 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
557 break;
558 case BFD_RELOC_CR16_NUM32:
559 fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
560 break;
561 case BFD_RELOC_CR16_NUM32a:
562 fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
563 break;
564 default:
565 abort ();
566 break;
3d3d428f
NC
567 }
568 }
569 else
570 {
571 /* We only resolve difference expressions in the same section. */
572 as_bad_where (fixP->fx_file, fixP->fx_line,
573 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
574 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
575 segment_name (fixP->fx_addsy
576 ? S_GET_SEGMENT (fixP->fx_addsy)
577 : absolute_section),
578 S_GET_NAME (fixP->fx_subsy),
579 segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
580 }
581 }
0b9e228a
SR
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 {
0b9e228a
SR
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 {
0b9e228a
SR
593 reloc->addend = fixP->fx_offset = reloc->address;
594 }
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,
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));
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]
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 }
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,
657 then no need to update the opcode value. */
658 if ((int)opcode[1] != 0x18)
659 {
660 opcode[0] = (opcode[0] & 0xf0);
661 opcode[1] = 0x18;
662 }
663 reloc = BFD_RELOC_CR16_DISP16;
664 break;
665 case 2:
666 /* If the subtype is not changed due to :l operand qualifier,
667 then no need to update the opcode value. */
668 if ((int)opcode[1] != 0)
669 {
670 opcode[2] = opcode[0];
671 opcode[0] = opcode[1];
672 opcode[1] = 0x0;
673 }
674 reloc = BFD_RELOC_CR16_DISP24;
675 break;
676 default:
677 abort();
678 }
679
3d3d428f
NC
680 fix_new (fragP, fragP->fr_fix,
681 bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
682 fragP->fr_symbol, fragP->fr_offset, 1, reloc);
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
NC
830 /* Insert unique names into hash table. The CR16 instruction set
831 has many identical opcode names that have different opcodes based
832 on the operands. This hash table then provides a quick index to
833 the first opcode with a particular name in the opcode table. */
834 do
835 {
836 ++i;
837 }
838 while (cr16_instruction[i].mnemonic != NULL
839 && streq (cr16_instruction[i].mnemonic, mnemonic));
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"),
7fac7ff4 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
902 if (strneq (input_line_pointer, "@c", 2))
7fac7ff4 903 symbol_with_at = 1;
3d3d428f
NC
904
905 if (strneq (input_line_pointer, "@l", 2)
7fac7ff4
NC
906 || strneq (input_line_pointer, ":l", 2))
907 symbol_with_l = 1;
3d3d428f
NC
908
909 if (strneq (input_line_pointer, "@m", 2)
7fac7ff4
NC
910 || strneq (input_line_pointer, ":m", 2))
911 symbol_with_m = 1;
3d3d428f
NC
912
913 if (strneq (input_line_pointer, "@s", 2)
7fac7ff4
NC
914 || strneq (input_line_pointer, ":s", 2))
915 symbol_with_s = 1;
3d3d428f 916
0b9e228a
SR
917 if (strneq (input_line_pointer, "@cGOT", 5)
918 || strneq (input_line_pointer, "@cgot", 5))
919 {
920 if (GOT_symbol == NULL)
921 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
922
923 symbol_with_at_gotc = 1;
924 }
925 else if (strneq (input_line_pointer, "@GOT", 4)
926 || strneq (input_line_pointer, "@got", 4))
927 {
3739860c 928 if ((strneq (input_line_pointer, "+", 1))
0b9e228a
SR
929 || (strneq (input_line_pointer, "-", 1)))
930 as_warn (_("GOT bad expression with %s."), input_line_pointer);
931
932 if (GOT_symbol == NULL)
933 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
934
935 symbol_with_at_got = 1;
936 }
937
3d3d428f
NC
938 switch (cur_arg->type)
939 {
7fac7ff4
NC
940 case arg_cr:
941 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
942 {
0b9e228a
SR
943 if (symbol_with_at_got)
944 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
945 else if (symbol_with_at_gotc)
946 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
947 else if (cur_arg->size == 20)
7fac7ff4
NC
948 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
949 else
950 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
951 }
952 break;
953
954 case arg_crp:
955 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
0b9e228a
SR
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 {
7fac7ff4
NC
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 }
0b9e228a 991 }
7fac7ff4
NC
992 break;
993
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)
998 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
999 else if (symbol_with_at_gotc)
1000 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1001 else
1002 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
1003 }
7fac7ff4
NC
1004 break;
1005
1006 case arg_idxrp:
1007 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
0b9e228a
SR
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 {
7fac7ff4
NC
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 }
0b9e228a
SR
1021 }
1022 }
7fac7ff4
NC
1023 break;
1024
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))
1029 {
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;
1036 }
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)
7fac7ff4 1041 as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
0b9e228a
SR
1042 if (symbol_with_at_got)
1043 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1044 else if (symbol_with_at_gotc)
1045 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1046 else if (symbol_with_m)
7fac7ff4
NC
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;
3d3d428f
NC
1053 break;
1054
1055 case arg_ic:
1056 if (IS_INSN_TYPE (ARITH_INS))
1057 {
0b9e228a
SR
1058 if (symbol_with_at_got)
1059 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1060 else if (symbol_with_at_gotc)
1061 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1062 else if (symbol_with_s)
3d3d428f
NC
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))
7fac7ff4
NC
1072 {
1073 cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
1074 }
3d3d428f
NC
1075 break;
1076 default:
1077 break;
7fac7ff4 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
NC
1111
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)
91d6fa6a 1121 return rreg->image;
3d3d428f 1122 else
7fac7ff4 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)
1168 cur_arg->type = arg_c;
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 != '(')
1176 operandE++;
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 != ')')
1185 operandE++;
1186 *operandE = '\0';
1187 if ((cur_arg->r = get_register (operandS)) == nullregister)
1188 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1189 operandS, ins_parse);
1190
1191 /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1192 if ((cur_arg->type != arg_rbase)
7fac7ff4
NC
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)))
3d3d428f
NC
1197 {
1198 cur_arg->type = arg_crp;
1199 cur_arg->rp = cur_arg->r;
1200 }
1201 break;
1202
1203 case arg_crp: /* Case 0x18(r1,r0). */
1204 /* Set displacement constant. */
1205 while (*operandE != '(')
1206 operandE++;
1207 *operandE = '\0';
1208 process_label_constant (operandS, cr16_ins);
1209 operandS = operandE;
1210 operandS++;
1211 /* Set register pair base. */
1212 while (*operandE != ')')
1213 operandE++;
1214 *operandE = '\0';
1215 if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
1216 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1217 operandS, ins_parse);
1218 break;
1219
1220 case arg_idxr:
1221 /* Set register pair base. */
1222 if ((strchr (operandS,'(') != NULL))
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 }
1232 else
7fac7ff4 1233 cur_arg->rp = -1;
3d3d428f
NC
1234
1235 operandE = operandS;
1236 /* Set displacement constant. */
1237 while (*operandE != ']')
1238 operandE++;
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)
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 }
1261
1262 if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
1263 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1264 operandS, ins_parse);
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)
7fac7ff4 1341 cur_arg->type = arg_icr;
3d3d428f 1342 else
7fac7ff4 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
1364 && (strchr (operand, ',') > strchr (operand, '(')))
1365 cur_arg->type = arg_crp;
1366 else
1367 cur_arg->type = arg_cr;
1368 }
1369 else
1370 cur_arg->type = arg_c;
1371
1372/* Parse an operand according to its type. */
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)
1398 {
1399 *operandT++ = '\0';
1400 operand[op_num++] = strdup (operandH);
1401 operandH = operandT;
1402 continue;
1403 }
1404
1405 if (*operandT == ' ')
1406 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1407
1408 if (*operandT == '(')
1409 bracket_flag = 1;
1410 else if (*operandT == '[')
1411 sq_bracket_flag = 1;
1412
1413 if (*operandT == ')')
1414 {
1415 if (bracket_flag)
1416 bracket_flag = 0;
1417 else
1418 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1419 }
1420 else if (*operandT == ']')
1421 {
1422 if (sq_bracket_flag)
1423 sq_bracket_flag = 0;
1424 else
1425 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1426 }
1427
1428 if (bracket_flag == 1 && *operandT == ')')
1429 bracket_flag = 0;
1430 else if (sq_bracket_flag == 1 && *operandT == ']')
1431 sq_bracket_flag = 0;
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;
1516 char op1[5];
1517
1518 for (i = 1; i < strlen (op); i++)
1519 op1[i-1] = op[i];
1520
1521 op1[i-1] = '\0';
1522
1523 for (i = 0; i < cr16_num_cc ; i++)
1524 if (streq (op1, cr16_b_cond_tab[i]))
1525 return (char *) cr16_b_cond_tab[i];
1526
1527 return NULL;
1528}
1529
1530/* bCC instruction requires special handling. */
1531static int
1532is_bcc_insn (char * op)
1533{
1534 if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
7fac7ff4 1535 || streq (op, "beq0w") || streq (op, "bnq0w")))
3d3d428f
NC
1536 if ((op[0] == 'b') && (get_b_cc (op) != NULL))
1537 return 1;
1538 return 0;
1539}
1540
1541/* Cinv instruction requires special handling. */
1542
fd596c16 1543static void
3d3d428f
NC
1544check_cinv_options (char * operand)
1545{
1546 char *p = operand;
3d3d428f
NC
1547
1548 while (*++p != ']')
1549 {
fd596c16
NC
1550 switch (*p)
1551 {
1552 case ',':
1553 case ' ':
1554 case 'i':
1555 case 'u':
1556 case 'd':
1557 break;
1558 default:
1559 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1560 }
3d3d428f 1561 }
3d3d428f
NC
1562}
1563
1564/* Retrieve the opcode image of a given register pair.
1565 If the register is illegal for the current instruction,
1566 issue an error. */
1567
1568static int
1569getregp_image (reg r)
1570{
91d6fa6a 1571 const reg_entry *rreg;
3d3d428f
NC
1572 char *reg_name;
1573
1574 /* Check whether the register is in registers table. */
1575 if (r < MAX_REG)
91d6fa6a 1576 rreg = cr16_regptab + r;
3d3d428f
NC
1577 /* Register not found. */
1578 else
1579 {
1580 as_bad (_("Unknown register pair: `%d'"), r);
1581 return 0;
1582 }
1583
91d6fa6a 1584 reg_name = rreg->name;
3d3d428f
NC
1585
1586/* Issue a error message when register pair is illegal. */
1587#define RPAIR_IMAGE_ERR \
1588 as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1589 reg_name, ins_parse); \
1590 break;
1591
91d6fa6a 1592 switch (rreg->type)
3d3d428f
NC
1593 {
1594 case CR16_RP_REGTYPE:
91d6fa6a 1595 return rreg->image;
3d3d428f
NC
1596 default:
1597 RPAIR_IMAGE_ERR;
1598 }
1599
1600 return 0;
1601}
1602
1603/* Retrieve the opcode image of a given index register pair.
1604 If the register is illegal for the current instruction,
1605 issue an error. */
1606
1607static int
1608getidxregp_image (reg r)
1609{
91d6fa6a 1610 const reg_entry *rreg;
3d3d428f
NC
1611 char *reg_name;
1612
1613 /* Check whether the register is in registers table. */
1614 if (r < MAX_REG)
91d6fa6a 1615 rreg = cr16_regptab + r;
3d3d428f
NC
1616 /* Register not found. */
1617 else
1618 {
1619 as_bad (_("Unknown register pair: `%d'"), r);
1620 return 0;
1621 }
1622
91d6fa6a 1623 reg_name = rreg->name;
3d3d428f
NC
1624
1625/* Issue a error message when register pair is illegal. */
1626#define IDX_RPAIR_IMAGE_ERR \
1627 as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1628 reg_name, ins_parse); \
1629
91d6fa6a 1630 if (rreg->type == CR16_RP_REGTYPE)
3d3d428f 1631 {
91d6fa6a 1632 switch (rreg->image)
7fac7ff4
NC
1633 {
1634 case 0: return 0; break;
1635 case 2: return 1; break;
1636 case 4: return 2; break;
1637 case 6: return 3; break;
1638 case 8: return 4; break;
1639 case 10: return 5; break;
1640 case 3: return 6; break;
1641 case 5: return 7; break;
1642 default:
1643 break;
1644 }
3d3d428f
NC
1645 }
1646
1647 IDX_RPAIR_IMAGE_ERR;
1648 return 0;
1649}
1650
33eaf5de 1651/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1652 If the register is illegal for the current instruction,
1653 issue an error. */
1654static int
249c2423 1655getprocreg_image (int r)
3d3d428f 1656{
91d6fa6a 1657 const reg_entry *rreg;
3d3d428f
NC
1658 char *reg_name;
1659
1660 /* Check whether the register is in registers table. */
d86fff44 1661 if (r >= MAX_REG && r < MAX_PREG)
91d6fa6a 1662 rreg = &cr16_pregtab[r - MAX_REG];
3d3d428f
NC
1663 /* Register not found. */
1664 else
1665 {
1666 as_bad (_("Unknown processor register : `%d'"), r);
1667 return 0;
1668 }
1669
91d6fa6a 1670 reg_name = rreg->name;
3d3d428f
NC
1671
1672/* Issue a error message when register pair is illegal. */
1673#define PROCREG_IMAGE_ERR \
1674 as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1675 reg_name, ins_parse); \
1676 break;
1677
91d6fa6a 1678 switch (rreg->type)
3d3d428f
NC
1679 {
1680 case CR16_P_REGTYPE:
91d6fa6a 1681 return rreg->image;
3d3d428f
NC
1682 default:
1683 PROCREG_IMAGE_ERR;
1684 }
1685
1686 return 0;
1687}
1688
33eaf5de 1689/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1690 If the register is illegal for the current instruction,
1691 issue an error. */
1692static int
249c2423 1693getprocregp_image (int r)
3d3d428f 1694{
91d6fa6a 1695 const reg_entry *rreg;
3d3d428f
NC
1696 char *reg_name;
1697 int pregptab_disp = 0;
1698
1699 /* Check whether the register is in registers table. */
d86fff44 1700 if (r >= MAX_REG && r < MAX_PREG)
3d3d428f
NC
1701 {
1702 r = r - MAX_REG;
1703 switch (r)
1704 {
7fac7ff4
NC
1705 case 4: pregptab_disp = 1; break;
1706 case 6: pregptab_disp = 2; break;
1707 case 8:
1708 case 9:
1709 case 10:
1710 pregptab_disp = 3; break;
1711 case 12:
1712 pregptab_disp = 4; break;
1713 case 14:
1714 pregptab_disp = 5; break;
1715 default: break;
3d3d428f 1716 }
91d6fa6a 1717 rreg = &cr16_pregptab[r - pregptab_disp];
3d3d428f
NC
1718 }
1719 /* Register not found. */
1720 else
1721 {
1722 as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
1723 return 0;
1724 }
1725
91d6fa6a 1726 reg_name = rreg->name;
3d3d428f
NC
1727
1728/* Issue a error message when register pair is illegal. */
1729#define PROCREGP_IMAGE_ERR \
1730 as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"),\
1731 reg_name, ins_parse); \
1732 break;
1733
91d6fa6a 1734 switch (rreg->type)
3d3d428f
NC
1735 {
1736 case CR16_P_REGTYPE:
91d6fa6a 1737 return rreg->image;
3d3d428f
NC
1738 default:
1739 PROCREGP_IMAGE_ERR;
1740 }
1741
1742 return 0;
1743}
1744
1745/* Routine used to represent integer X using NBITS bits. */
1746
1747static long
1748getconstant (long x, int nbits)
1749{
1750 /* The following expression avoids overflow if
1751 'nbits' is the number of bits in 'bfd_vma'. */
1752 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1753}
1754
1755/* Print a constant value to 'output_opcode':
1756 ARG holds the operand's type and value.
1757 SHIFT represents the location of the operand to be print into.
1758 NBITS determines the size (in bits) of the constant. */
1759
1760static void
1761print_constant (int nbits, int shift, argument *arg)
1762{
1763 unsigned long mask = 0;
1764
1765 long constant = getconstant (arg->constant, nbits);
1766
1767 switch (nbits)
1768 {
1769 case 32:
1770 case 28:
1771 /* mask the upper part of the constant, that is, the bits
7fac7ff4
NC
1772 going to the lowest byte of output_opcode[0].
1773 The upper part of output_opcode[1] is always filled,
1774 therefore it is always masked with 0xFFFF. */
3d3d428f
NC
1775 mask = (1 << (nbits - 16)) - 1;
1776 /* Divide the constant between two consecutive words :
7fac7ff4
NC
1777 0 1 2 3
1778 +---------+---------+---------+---------+
1779 | | X X X X | x X x X | |
1780 +---------+---------+---------+---------+
1781 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1782
1783 CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1784 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1785 break;
1786
1787 case 21:
1a0670f3
AM
1788 if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
1789 nbits = 20;
1790 /* Fall through. */
3d3d428f
NC
1791 case 24:
1792 case 22:
1793 case 20:
1794 /* mask the upper part of the constant, that is, the bits
7fac7ff4
NC
1795 going to the lowest byte of output_opcode[0].
1796 The upper part of output_opcode[1] is always filled,
1797 therefore it is always masked with 0xFFFF. */
3d3d428f
NC
1798 mask = (1 << (nbits - 16)) - 1;
1799 /* Divide the constant between two consecutive words :
7fac7ff4
NC
1800 0 1 2 3
1801 +---------+---------+---------+---------+
1802 | | X X X X | - X - X | |
1803 +---------+---------+---------+---------+
1804 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1805
1806 if ((instruction->size > 2) && (shift == WORD_SHIFT))
7fac7ff4
NC
1807 {
1808 if (arg->type == arg_idxrp)
1809 {
1810 CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
1811 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1812 }
1813 else
1814 {
1815 CR16_PRINT (0, (((((constant >> WORD_SHIFT) & mask) << 8) & 0x0f00) | ((((constant >> WORD_SHIFT) & mask) >> 4) & 0xf)),0);
1816 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1817 }
1818 }
3d3d428f 1819 else
7fac7ff4 1820 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1821 break;
1822
1823 case 14:
1824 if (arg->type == arg_idxrp)
7fac7ff4
NC
1825 {
1826 if (instruction->size == 2)
1827 {
1828 CR16_PRINT (0, ((constant) & 0xf), shift); /* 0-3 bits. */
1829 CR16_PRINT (0, ((constant >> 4) & 0x3), (shift + 20)); /* 4-5 bits. */
1830 CR16_PRINT (0, ((constant >> 6) & 0x3), (shift + 14)); /* 6-7 bits. */
1831 CR16_PRINT (0, ((constant >> 8) & 0x3f), (shift + 8)); /* 8-13 bits. */
1832 }
1833 else
1834 CR16_PRINT (0, constant, shift);
1835 }
3d3d428f
NC
1836 break;
1837
1838 case 16:
1839 case 12:
1840 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
7fac7ff4
NC
1841 always filling the upper part of output_opcode[1]. If we mistakenly
1842 write it to output_opcode[0], the constant prefix (that is, 'match')
33eaf5de 1843 will be overridden.
7fac7ff4
NC
1844 0 1 2 3
1845 +---------+---------+---------+---------+
1846 | 'match' | | X X X X | |
1847 +---------+---------+---------+---------+
1848 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1849
1850 if ((instruction->size > 2) && (shift == WORD_SHIFT))
7fac7ff4 1851 CR16_PRINT (1, constant, WORD_SHIFT);
3d3d428f 1852 else
7fac7ff4 1853 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1854 break;
1855
1856 case 8:
7fac7ff4
NC
1857 CR16_PRINT (0, ((constant / 2) & 0xf), shift);
1858 CR16_PRINT (0, ((constant / 2) >> 4), (shift + 8));
3d3d428f
NC
1859 break;
1860
1861 default:
1862 CR16_PRINT (0, constant, shift);
1863 break;
1864 }
1865}
1866
1867/* Print an operand to 'output_opcode', which later on will be
1868 printed to the object file:
1869 ARG holds the operand's type, size and value.
1870 SHIFT represents the printing location of operand.
1871 NBITS determines the size (in bits) of a constant operand. */
1872
1873static void
1874print_operand (int nbits, int shift, argument *arg)
1875{
1876 switch (arg->type)
1877 {
1878 case arg_cc:
1879 CR16_PRINT (0, arg->cc, shift);
1880 break;
1881
1882 case arg_r:
1883 CR16_PRINT (0, getreg_image (arg->r), shift);
1884 break;
1885
1886 case arg_rp:
1887 CR16_PRINT (0, getregp_image (arg->rp), shift);
1888 break;
1889
1890 case arg_pr:
1891 CR16_PRINT (0, getprocreg_image (arg->pr), shift);
1892 break;
1893
1894 case arg_prp:
1895 CR16_PRINT (0, getprocregp_image (arg->prp), shift);
1896 break;
1897
1898 case arg_idxrp:
1899 /* 16 12 8 6 0
1900 +-----------------------------+
1901 | r_index | disp | rp_base |
1902 +-----------------------------+ */
1903
1904 if (instruction->size == 3)
7fac7ff4
NC
1905 {
1906 CR16_PRINT (0, getidxregp_image (arg->rp), 0);
1907 if (getreg_image (arg->i_r) == 12)
1908 CR16_PRINT (0, 0, 3);
1909 else
1910 CR16_PRINT (0, 1, 3);
1911 }
3d3d428f 1912 else
7fac7ff4
NC
1913 {
1914 CR16_PRINT (0, getidxregp_image (arg->rp), 16);
1915 if (getreg_image (arg->i_r) == 12)
1916 CR16_PRINT (0, 0, 19);
1917 else
1918 CR16_PRINT (0, 1, 19);
1919 }
3d3d428f
NC
1920 print_constant (nbits, shift, arg);
1921 break;
1922
1923 case arg_idxr:
1924 if (getreg_image (arg->i_r) == 12)
7fac7ff4
NC
1925 if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1926 || IS_INSN_MNEMONIC ("tbitb"))
1927 CR16_PRINT (0, 0, 23);
1928 else CR16_PRINT (0, 0, 24);
3d3d428f 1929 else
7fac7ff4
NC
1930 if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1931 || IS_INSN_MNEMONIC ("tbitb"))
1932 CR16_PRINT (0, 1, 23);
1933 else CR16_PRINT (0, 1, 24);
3d3d428f
NC
1934
1935 print_constant (nbits, shift, arg);
1936 break;
1937
1938 case arg_ic:
1939 case arg_c:
1940 print_constant (nbits, shift, arg);
1941 break;
1942
1943 case arg_rbase:
1944 CR16_PRINT (0, getreg_image (arg->r), shift);
1945 break;
1946
1947 case arg_cr:
1948 print_constant (nbits, shift , arg);
1949 /* Add the register argument to the output_opcode. */
1950 CR16_PRINT (0, getreg_image (arg->r), (shift+16));
1951 break;
1952
1953 case arg_crp:
1954 print_constant (nbits, shift , arg);
1955 if (instruction->size > 1)
7fac7ff4 1956 CR16_PRINT (0, getregp_image (arg->rp), (shift + 16));
3d3d428f 1957 else if (IS_INSN_TYPE (LD_STOR_INS) || (IS_INSN_TYPE (CSTBIT_INS)))
7fac7ff4
NC
1958 {
1959 if (instruction->size == 2)
1960 CR16_PRINT (0, getregp_image (arg->rp), (shift - 8));
1961 else if (instruction->size == 1)
1962 CR16_PRINT (0, getregp_image (arg->rp), 16);
1963 }
3d3d428f 1964 else
7fac7ff4 1965 CR16_PRINT (0, getregp_image (arg->rp), shift);
3d3d428f
NC
1966 break;
1967
1968 default:
1969 break;
1970 }
1971}
1972
1973/* Retrieve the number of operands for the current assembled instruction. */
1974
1975static int
1976get_number_of_operands (void)
1977{
1978 int i;
1979
1980 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1981 ;
1982 return i;
1983}
1984
1985/* Verify that the number NUM can be represented in BITS bits (that is,
1986 within its permitted range), based on the instruction's FLAGS.
1987 If UPDATE is nonzero, update the value of NUM if necessary.
1988 Return OP_LEGAL upon success, actual error type upon failure. */
1989
1990static op_err
1991check_range (long *num, int bits, int unsigned flags, int update)
1992{
1993 long min, max;
6610dc6d 1994 op_err retval = OP_LEGAL;
3d3d428f
NC
1995 long value = *num;
1996
1997 if (bits == 0 && value > 0) return OP_OUT_OF_RANGE;
1998
33eaf5de 1999 /* For hosts with longs bigger than 32-bits make sure that the top
3d3d428f
NC
2000 bits of a 32-bit negative value read in by the parser are set,
2001 so that the correct comparisons are made. */
2002 if (value & 0x80000000)
69c9e028 2003 value |= (-1UL << 31);
3d3d428f
NC
2004
2005
2006 /* Verify operand value is even. */
2007 if (flags & OP_EVEN)
2008 {
2009 if (value % 2)
2010 return OP_NOT_EVEN;
2011 }
2012
2013 if (flags & OP_DEC)
2014 {
2015 value -= 1;
2016 if (update)
2017 *num = value;
2018 }
2019
2020 if (flags & OP_SHIFT)
2021 {
2022 value >>= 1;
2023 if (update)
2024 *num = value;
2025 }
2026 else if (flags & OP_SHIFT_DEC)
2027 {
2028 value = (value >> 1) - 1;
2029 if (update)
2030 *num = value;
2031 }
2032
2033 if (flags & OP_ABS20)
2034 {
2035 if (value > 0xEFFFF)
2036 return OP_OUT_OF_RANGE;
2037 }
2038
2039 if (flags & OP_ESC)
2040 {
2041 if (value == 0xB || value == 0x9)
2042 return OP_OUT_OF_RANGE;
2043 else if (value == -1)
7fac7ff4
NC
2044 {
2045 if (update)
2046 *num = 9;
2047 return retval;
2048 }
3d3d428f
NC
2049 }
2050
2051 if (flags & OP_ESC1)
2052 {
2053 if (value > 13)
2054 return OP_OUT_OF_RANGE;
2055 }
2056
2057 if (flags & OP_SIGNED)
2058 {
2059 max = (1 << (bits - 1)) - 1;
2060 min = - (1 << (bits - 1));
2061 if ((value > max) || (value < min))
2062 retval = OP_OUT_OF_RANGE;
2063 }
2064 else if (flags & OP_UNSIGNED)
2065 {
2066 max = ((((1 << (bits - 1)) - 1) << 1) | 1);
2067 min = 0;
2068 if (((unsigned long) value > (unsigned long) max)
2069 || ((unsigned long) value < (unsigned long) min))
2070 retval = OP_OUT_OF_RANGE;
2071 }
2072 else if (flags & OP_NEG)
2073 {
2074 max = - 1;
7fac7ff4 2075 min = - ((1 << (bits - 1)) - 1);
3d3d428f
NC
2076 if ((value > max) || (value < min))
2077 retval = OP_OUT_OF_RANGE;
2078 }
2079 return retval;
2080}
2081
33eaf5de 2082/* Bunch of error checking.
3d3d428f
NC
2083 The checks are made after a matching instruction was found. */
2084
2085static void
2086warn_if_needed (ins *insn)
2087{
2088 /* If the post-increment address mode is used and the load/store
2089 source register is the same as rbase, the result of the
2090 instruction is undefined. */
2091 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2092 {
2093 /* Enough to verify that one of the arguments is a simple reg. */
2094 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
2095 if (insn->arg[0].r == insn->arg[1].r)
2096 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"), insn->arg[0].r);
2097 }
2098
2099 if (IS_INSN_MNEMONIC ("pop")
2100 || IS_INSN_MNEMONIC ("push")
2101 || IS_INSN_MNEMONIC ("popret"))
2102 {
2103 unsigned int count = insn->arg[0].constant, reg_val;
2104
33eaf5de 2105 /* Check if count operand caused to save/retrieve the RA twice
7fac7ff4 2106 to generate warning message. */
3d3d428f
NC
2107 if (insn->nargs > 2)
2108 {
2109 reg_val = getreg_image (insn->arg[1].r);
2110
2111 if ( ((reg_val == 9) && (count > 7))
7fac7ff4
NC
2112 || ((reg_val == 10) && (count > 6))
2113 || ((reg_val == 11) && (count > 5))
2114 || ((reg_val == 12) && (count > 4))
2115 || ((reg_val == 13) && (count > 2))
2116 || ((reg_val == 14) && (count > 0)))
3d3d428f
NC
2117 as_warn (_("RA register is saved twice."));
2118
2119 /* Check if the third operand is "RA" or "ra" */
2120 if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
2121 as_bad (_("`%s' Illegal use of registers."), ins_parse);
2122 }
2123
2124 if (insn->nargs > 1)
2125 {
2126 reg_val = getreg_image (insn->arg[1].r);
2127
2128 /* If register is a register pair ie r12/r13/r14 in operand1, then
2129 the count constant should be validated. */
2130 if (((reg_val == 11) && (count > 7))
7fac7ff4
NC
2131 || ((reg_val == 12) && (count > 6))
2132 || ((reg_val == 13) && (count > 4))
2133 || ((reg_val == 14) && (count > 2))
2134 || ((reg_val == 15) && (count > 0)))
3d3d428f
NC
2135 as_bad (_("`%s' Illegal count-register combination."), ins_parse);
2136 }
2137 else
2138 {
2139 /* Check if the operand is "RA" or "ra" */
2140 if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
2141 as_bad (_("`%s' Illegal use of register."), ins_parse);
2142 }
2143 }
2144
2145 /* Some instruction assume the stack pointer as rptr operand.
2146 Issue an error when the register to be loaded is also SP. */
2147 if (instruction->flags & NO_SP)
2148 {
2149 if (getreg_image (insn->arg[1].r) == getreg_image (sp))
2150 as_bad (_("`%s' has undefined result"), ins_parse);
2151 }
2152
2153 /* If the rptr register is specified as one of the registers to be loaded,
2154 the final contents of rptr are undefined. Thus, we issue an error. */
2155 if (instruction->flags & NO_RPTR)
2156 {
2157 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
2158 as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2159 getreg_image (insn->arg[0].r));
2160 }
2161}
2162
2163/* In some cases, we need to adjust the instruction pointer although a
2164 match was already found. Here, we gather all these cases.
2165 Returns 1 if instruction pointer was adjusted, otherwise 0. */
2166
2167static int
2168adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
2169{
2170 int ret_value = 0;
2171
2172 if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
2173 {
2174 if ((instruction->operands[0].op_type == abs24)
2175 && ((insn->arg[0].constant) > 0xF00000))
2176 {
2177 insn->arg[0].constant &= 0xFFFFF;
2178 instruction--;
2179 ret_value = 1;
2180 }
2181 }
2182
2183 return ret_value;
2184}
2185
2186/* Assemble a single instruction:
2187 INSN is already parsed (that is, all operand values and types are set).
2188 For instruction to be assembled, we need to find an appropriate template in
2189 the instruction table, meeting the following conditions:
2190 1: Has the same number of operands.
2191 2: Has the same operand types.
2192 3: Each operand size is sufficient to represent the instruction's values.
2193 Returns 1 upon success, 0 upon failure. */
2194
2195static int
9202e88a 2196assemble_insn (const char *mnemonic, ins *insn)
3d3d428f
NC
2197{
2198 /* Type of each operand in the current template. */
2199 argtype cur_type[MAX_OPERANDS];
2200 /* Size (in bits) of each operand in the current template. */
2201 unsigned int cur_size[MAX_OPERANDS];
2202 /* Flags of each operand in the current template. */
2203 unsigned int cur_flags[MAX_OPERANDS];
2204 /* Instruction type to match. */
2205 unsigned int ins_type;
2206 /* Boolean flag to mark whether a match was found. */
2207 int match = 0;
2208 int i;
2209 /* Nonzero if an instruction with same number of operands was found. */
2210 int found_same_number_of_operands = 0;
2211 /* Nonzero if an instruction with same argument types was found. */
2212 int found_same_argument_types = 0;
2213 /* Nonzero if a constant was found within the required range. */
2214 int found_const_within_range = 0;
2215 /* Argument number of an operand with invalid type. */
2216 int invalid_optype = -1;
2217 /* Argument number of an operand with invalid constant value. */
2218 int invalid_const = -1;
2219 /* Operand error (used for issuing various constant error messages). */
2220 op_err op_error, const_err = OP_LEGAL;
2221
2222/* Retrieve data (based on FUNC) for each operand of a given instruction. */
2223#define GET_CURRENT_DATA(FUNC, ARRAY) \
2224 for (i = 0; i < insn->nargs; i++) \
2225 ARRAY[i] = FUNC (instruction->operands[i].op_type)
2226
2227#define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type)
2228#define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size)
2229#define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags)
2230
2231 /* Instruction has no operands -> only copy the constant opcode. */
2232 if (insn->nargs == 0)
2233 {
2234 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2235 return 1;
2236 }
2237
2238 /* In some case, same mnemonic can appear with different instruction types.
2239 For example, 'storb' is supported with 3 different types :
2240 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2241 We assume that when reaching this point, the instruction type was
2242 pre-determined. We need to make sure that the type stays the same
2243 during a search for matching instruction. */
2244 ins_type = CR16_INS_TYPE (instruction->flags);
2245
2246 while (/* Check that match is still not found. */
2247 match != 1
2248 /* Check we didn't get to end of table. */
2249 && instruction->mnemonic != NULL
2250 /* Check that the actual mnemonic is still available. */
2251 && IS_INSN_MNEMONIC (mnemonic)
2252 /* Check that the instruction type wasn't changed. */
2253 && IS_INSN_TYPE (ins_type))
2254 {
2255 /* Check whether number of arguments is legal. */
2256 if (get_number_of_operands () != insn->nargs)
2257 goto next_insn;
2258 found_same_number_of_operands = 1;
2259
2260 /* Initialize arrays with data of each operand in current template. */
2261 GET_CURRENT_TYPE;
2262 GET_CURRENT_SIZE;
2263 GET_CURRENT_FLAGS;
2264
2265 /* Check for type compatibility. */
2266 for (i = 0; i < insn->nargs; i++)
2267 {
2268 if (cur_type[i] != insn->arg[i].type)
2269 {
2270 if (invalid_optype == -1)
2271 invalid_optype = i + 1;
2272 goto next_insn;
2273 }
2274 }
2275 found_same_argument_types = 1;
2276
2277 for (i = 0; i < insn->nargs; i++)
2278 {
2279 /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2280 then goto next instruction. */
2281 if (IS_INSN_MNEMONIC ("bal") && (i == 0)
7fac7ff4 2282 && (instruction->size == 2) && (insn->arg[i].rp != 14))
3d3d428f
NC
2283 goto next_insn;
2284
2285 /* If 'storb' instruction with 'sp' reg and 16-bit disp of
33eaf5de 2286 * reg-pair, leads to undefined trap, so this should use
3d3d428f
NC
2287 * 20-bit disp of reg-pair. */
2288 if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
7fac7ff4 2289 && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
3d3d428f
NC
2290 goto next_insn;
2291
2292 /* Only check range - don't update the constant's value, since the
2293 current instruction may not be the last we try to match.
2294 The constant's value will be updated later, right before printing
2295 it to the object file. */
2296 if ((insn->arg[i].X_op == O_constant)
2297 && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
2298 cur_flags[i], 0)))
2299 {
2300 if (invalid_const == -1)
2301 {
2302 invalid_const = i + 1;
2303 const_err = op_error;
2304 }
2305 goto next_insn;
2306 }
2307 /* For symbols, we make sure the relocation size (which was already
2308 determined) is sufficient. */
2309 else if ((insn->arg[i].X_op == O_symbol)
2310 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
7fac7ff4 2311 > cur_size[i]))
3d3d428f
NC
2312 goto next_insn;
2313 }
2314 found_const_within_range = 1;
2315
2316 /* If we got till here -> Full match is found. */
2317 match = 1;
2318 break;
2319
dc1e8a47
AM
2320 /* Try again with next instruction. */
2321 next_insn:
3d3d428f
NC
2322 instruction++;
2323 }
2324
2325 if (!match)
2326 {
2327 /* We haven't found a match - instruction can't be assembled. */
2328 if (!found_same_number_of_operands)
2329 as_bad (_("Incorrect number of operands"));
2330 else if (!found_same_argument_types)
2331 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
2332 else if (!found_const_within_range)
2333 {
2334 switch (const_err)
2335 {
7fac7ff4
NC
2336 case OP_OUT_OF_RANGE:
2337 as_bad (_("Operand out of range (arg %d)"), invalid_const);
2338 break;
2339 case OP_NOT_EVEN:
2340 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
2341 break;
2342 default:
2343 as_bad (_("Illegal operand (arg %d)"), invalid_const);
2344 break;
3d3d428f
NC
2345 }
2346 }
2347
2348 return 0;
2349 }
2350 else
2351 /* Full match - print the encoding to output file. */
2352 {
33eaf5de 2353 /* Make further checking (such that couldn't be made earlier).
3d3d428f
NC
2354 Warn the user if necessary. */
2355 warn_if_needed (insn);
2356
2357 /* Check whether we need to adjust the instruction pointer. */
2358 if (adjust_if_needed (insn))
2359 /* If instruction pointer was adjusted, we need to update
2360 the size of the current template operands. */
2361 GET_CURRENT_SIZE;
2362
2363 for (i = 0; i < insn->nargs; i++)
2364 {
2365 int j = instruction->flags & REVERSE_MATCH ?
2366 i == 0 ? 1 :
2367 i == 1 ? 0 : i :
2368 i;
2369
2370 /* This time, update constant value before printing it. */
2371 if ((insn->arg[j].X_op == O_constant)
2372 && (check_range (&insn->arg[j].constant, cur_size[j],
2373 cur_flags[j], 1) != OP_LEGAL))
2374 as_fatal (_("Illegal operand (arg %d)"), j+1);
2375 }
2376
2377 /* First, copy the instruction's opcode. */
2378 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2379
2380 for (i = 0; i < insn->nargs; i++)
2381 {
2b0f3761 2382 /* For BAL (ra),disp17 instruction only. And also set the
3d3d428f
NC
2383 DISP24a relocation type. */
2384 if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
2385 {
2386 insn->rtype = BFD_RELOC_CR16_DISP24a;
2387 continue;
2388 }
2389 cur_arg_num = i;
2390 print_operand (cur_size[i], instruction->operands[i].shift,
2391 &insn->arg[i]);
2392 }
2393 }
2394
2395 return 1;
2396}
2397
2398/* Print the instruction.
2399 Handle also cases where the instruction is relaxable/relocatable. */
2400
2401static void
2402print_insn (ins *insn)
2403{
2404 unsigned int i, j, insn_size;
2405 char *this_frag;
2406 unsigned short words[4];
2407 int addr_mod;
2408
2409 /* Arrange the insn encodings in a WORD size array. */
2410 for (i = 0, j = 0; i < 2; i++)
2411 {
2412 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2413 words[j++] = output_opcode[i] & 0xFFFF;
2414 }
2415
3d3d428f 2416 /* Handle relocation. */
7fac7ff4
NC
2417 if ((instruction->flags & RELAXABLE) && relocatable)
2418 {
2419 int relax_subtype;
2420 /* Write the maximal instruction size supported. */
2421 insn_size = INSN_MAX_SIZE;
2422
2423 if (IS_INSN_TYPE (BRANCH_INS))
2424 {
2425 switch (insn->rtype)
2426 {
2427 case BFD_RELOC_CR16_DISP24:
2428 relax_subtype = 2;
2429 break;
2430 case BFD_RELOC_CR16_DISP16:
2431 relax_subtype = 1;
2432 break;
2433 default:
2434 relax_subtype = 0;
2435 break;
2436 }
2437 }
2438 else
2439 abort ();
2440
2441 this_frag = frag_var (rs_machine_dependent, insn_size *2,
2442 4, relax_subtype,
2443 insn->exp.X_add_symbol,
0b9e228a 2444 0,
7fac7ff4
NC
2445 0);
2446 }
2447 else
3d3d428f 2448 {
7fac7ff4
NC
2449 insn_size = instruction->size;
2450 this_frag = frag_more (insn_size * 2);
3d3d428f 2451
7fac7ff4
NC
2452 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2453 {
2454 reloc_howto_type *reloc_howto;
2455 int size;
3d3d428f 2456
7fac7ff4 2457 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
3739860c 2458
7fac7ff4
NC
2459 if (!reloc_howto)
2460 abort ();
3d3d428f 2461
7fac7ff4 2462 size = bfd_get_reloc_size (reloc_howto);
3d3d428f 2463
7fac7ff4
NC
2464 if (size < 1 || size > 4)
2465 abort ();
3d3d428f 2466
7fac7ff4
NC
2467 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2468 size, &insn->exp, reloc_howto->pc_relative,
2469 insn->rtype);
2470 }
3d3d428f
NC
2471 }
2472
2473 /* Verify a 2-byte code alignment. */
2474 addr_mod = frag_now_fix () & 1;
2475 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
2476 as_bad (_("instruction address is not a multiple of 2"));
2477 frag_now->insn_addr = addr_mod;
2478 frag_now->has_code = 1;
2479
2480 /* Write the instruction encoding to frag. */
2481 for (i = 0; i < insn_size; i++)
2482 {
2483 md_number_to_chars (this_frag, (valueT) words[i], 2);
2484 this_frag += 2;
2485 }
2486}
2487
9202e88a
TS
2488/* Actually assemble an instruction. */
2489
2490static void
2491cr16_assemble (const char *op, char *param)
2492{
2493 ins cr16_ins;
2494
2495 /* Find the instruction. */
629310ab 2496 instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
9202e88a
TS
2497 if (instruction == NULL)
2498 {
2499 as_bad (_("Unknown opcode: `%s'"), op);
2500 return;
2501 }
2502
2503 /* Tie dwarf2 debug info to the address at the start of the insn. */
2504 dwarf2_emit_insn (0);
2505
2506 /* Parse the instruction's operands. */
2507 parse_insn (&cr16_ins, param);
2508
2509 /* Assemble the instruction - return upon failure. */
2510 if (assemble_insn (op, &cr16_ins) == 0)
2511 return;
2512
2513 /* Print the instruction. */
2514 print_insn (&cr16_ins);
2515}
2516
3d3d428f
NC
2517/* This is the guts of the machine-dependent assembler. OP points to a
2518 machine dependent instruction. This function is supposed to emit
2519 the frags/bytes it assembles to. */
2520
2521void
2522md_assemble (char *op)
2523{
2524 ins cr16_ins;
2525 char *param, param1[32];
3d3d428f
NC
2526
2527 /* Reset global variables for a new instruction. */
2528 reset_vars (op);
2529
2530 /* Strip the mnemonic. */
2531 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2532 ;
3d3d428f
NC
2533 *param++ = '\0';
2534
33eaf5de 2535 /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
3d3d428f
NC
2536 if (is_bcc_insn (op))
2537 {
2538 strcpy (param1, get_b_cc (op));
3d3d428f
NC
2539 strcat (param1,",");
2540 strcat (param1, param);
2541 param = (char *) &param1;
9202e88a
TS
2542 cr16_assemble ("b", param);
2543 return;
3d3d428f
NC
2544 }
2545
2546 /* Checking the cinv options and adjust the mnemonic by removing the
2547 extra white spaces. */
2548 if (streq ("cinv", op))
2549 {
2550 /* Validate the cinv options. */
9fcc3457 2551 unsigned int op_len, param_len;
3d3d428f 2552 check_cinv_options (param);
9fcc3457
L
2553 op_len = strlen (op);
2554 param_len = strlen (param) + 1;
2555 memmove (op + op_len, param, param_len);
3d3d428f
NC
2556 }
2557
2558 /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2559 lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
33eaf5de 2560 as CR16 core doesn't support lsh[b/w] right shift operations. */
3d3d428f
NC
2561 if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
2562 && (param [0] == '$'))
2563 {
2564 strcpy (param1, param);
2565 /* Find the instruction. */
629310ab 2566 instruction = (const inst *) str_hash_find (cr16_inst_hash, op);
3d3d428f
NC
2567 parse_operands (&cr16_ins, param1);
2568 if (((&cr16_ins)->arg[0].type == arg_ic)
7fac7ff4 2569 && ((&cr16_ins)->arg[0].constant >= 0))
3d3d428f
NC
2570 {
2571 if (streq ("lshb", op))
9202e88a 2572 cr16_assemble ("ashub", param);
3d3d428f 2573 else if (streq ("lshd", op))
9202e88a 2574 cr16_assemble ("ashud", param);
7fac7ff4 2575 else
9202e88a
TS
2576 cr16_assemble ("ashuw", param);
2577 return;
3d3d428f
NC
2578 }
2579 }
2580
9202e88a 2581 cr16_assemble (op, param);
3d3d428f 2582}