x86: replace Reg8, Reg16, Reg32, and Reg64
[deliverable/binutils-gdb.git] / gas / config / tc-cr16.c
CommitLineData
3d3d428f 1/* tc-cr16.c -- Assembler code for the CR16 CPU core.
2571583a 2 Copyright (C) 2007-2017 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. */
56static struct hash_control *cr16_inst_hash;
57/* CR16 registers hash table. */
58static struct hash_control *reg_hash;
59/* CR16 register pair hash table. */
60static struct hash_control *regp_hash;
61/* CR16 processor registers hash table. */
62static struct hash_control *preg_hash;
63/* CR16 processor registers 32 bit hash table. */
64static struct hash_control *pregp_hash;
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
91d6fa6a 327 rreg = (const reg_entry *) 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,")");
91d6fa6a 348 rreg = (const reg_entry *) hash_find (regp_hash, tmp_rp);
3d3d428f
NC
349 }
350 else
91d6fa6a 351 rreg = (const reg_entry *) 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
91d6fa6a 366 rreg = (const reg_entry *) 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
91d6fa6a 381 rreg = (const reg_entry *) 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
91d6fa6a 402 prreg = (const reg_entry *) 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
91d6fa6a 417 prreg = (const reg_entry *) 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. */
7fac7ff4
NC
645 char *opcode = fragP->fr_literal + fragP->fr_fix;
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)
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 (valueT) 0, &zero_address_frag);
699 }
700 return GOT_symbol;
701 }
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
797initialise_reg_hash_table (struct hash_control ** hash_table,
7fac7ff4
NC
798 const reg_entry * register_table,
799 const unsigned int num_entries)
3d3d428f 800{
91d6fa6a 801 const reg_entry * rreg;
3d3d428f
NC
802 const char *hashret;
803
804 if ((* hash_table = hash_new ()) == NULL)
805 as_fatal (_("Virtual memory exhausted"));
806
91d6fa6a
NC
807 for (rreg = register_table;
808 rreg < (register_table + num_entries);
809 rreg++)
3d3d428f 810 {
91d6fa6a 811 hashret = hash_insert (* hash_table, rreg->name, (char *) rreg);
3d3d428f 812 if (hashret)
7fac7ff4 813 as_fatal (_("Internal Error: Can't hash %s: %s"),
91d6fa6a 814 rreg->name, hashret);
3d3d428f
NC
815 }
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. */
827 if ((cr16_inst_hash = hash_new ()) == NULL)
828 as_fatal (_("Virtual memory exhausted"));
829
830 while (cr16_instruction[i].mnemonic != NULL)
831 {
832 const char *hashret;
833 const char *mnemonic = cr16_instruction[i].mnemonic;
834
835 hashret = hash_insert (cr16_inst_hash, mnemonic,
7fac7ff4 836 (char *)(cr16_instruction + i));
3d3d428f
NC
837
838 if (hashret != NULL && *hashret != '\0')
839 as_fatal (_("Can't hash `%s': %s\n"), cr16_instruction[i].mnemonic,
840 *hashret == 0 ? _("(unknown reason)") : hashret);
841
842 /* Insert unique names into hash table. The CR16 instruction set
843 has many identical opcode names that have different opcodes based
844 on the operands. This hash table then provides a quick index to
845 the first opcode with a particular name in the opcode table. */
846 do
847 {
848 ++i;
849 }
850 while (cr16_instruction[i].mnemonic != NULL
851 && streq (cr16_instruction[i].mnemonic, mnemonic));
852 }
853
854 /* Initialize reg_hash hash table. */
855 initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS);
856 /* Initialize regp_hash hash table. */
857 initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS);
858 /* Initialize preg_hash hash table. */
859 initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS);
860 /* Initialize pregp_hash hash table. */
861 initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS);
862
863 /* Set linkrelax here to avoid fixups in most sections. */
864 linkrelax = 1;
865}
866
867/* Process constants (immediate/absolute)
868 and labels (jump targets/Memory locations). */
869
870static void
871process_label_constant (char *str, ins * cr16_ins)
872{
873 char *saved_input_line_pointer;
874 int symbol_with_at = 0;
875 int symbol_with_s = 0;
876 int symbol_with_m = 0;
877 int symbol_with_l = 0;
0b9e228a
SR
878 int symbol_with_at_got = 0;
879 int symbol_with_at_gotc = 0;
3d3d428f
NC
880 argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
881
882 saved_input_line_pointer = input_line_pointer;
883 input_line_pointer = str;
884
885 expression (&cr16_ins->exp);
886
887 switch (cr16_ins->exp.X_op)
888 {
889 case O_big:
890 case O_absent:
891 /* Missing or bad expr becomes absolute 0. */
892 as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
7fac7ff4 893 str);
3d3d428f
NC
894 cr16_ins->exp.X_op = O_constant;
895 cr16_ins->exp.X_add_number = 0;
896 cr16_ins->exp.X_add_symbol = NULL;
897 cr16_ins->exp.X_op_symbol = NULL;
898 /* Fall through. */
899
900 case O_constant:
901 cur_arg->X_op = O_constant;
902 cur_arg->constant = cr16_ins->exp.X_add_number;
903 break;
904
905 case O_symbol:
906 case O_subtract:
907 case O_add:
908 cur_arg->X_op = O_symbol;
0b9e228a
SR
909 cur_arg->constant = cr16_ins->exp.X_add_number;
910 cr16_ins->exp.X_add_number = 0;
3d3d428f
NC
911 cr16_ins->rtype = BFD_RELOC_NONE;
912 relocatable = 1;
913
914 if (strneq (input_line_pointer, "@c", 2))
7fac7ff4 915 symbol_with_at = 1;
3d3d428f
NC
916
917 if (strneq (input_line_pointer, "@l", 2)
7fac7ff4
NC
918 || strneq (input_line_pointer, ":l", 2))
919 symbol_with_l = 1;
3d3d428f
NC
920
921 if (strneq (input_line_pointer, "@m", 2)
7fac7ff4
NC
922 || strneq (input_line_pointer, ":m", 2))
923 symbol_with_m = 1;
3d3d428f
NC
924
925 if (strneq (input_line_pointer, "@s", 2)
7fac7ff4
NC
926 || strneq (input_line_pointer, ":s", 2))
927 symbol_with_s = 1;
3d3d428f 928
0b9e228a
SR
929 if (strneq (input_line_pointer, "@cGOT", 5)
930 || strneq (input_line_pointer, "@cgot", 5))
931 {
932 if (GOT_symbol == NULL)
933 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
934
935 symbol_with_at_gotc = 1;
936 }
937 else if (strneq (input_line_pointer, "@GOT", 4)
938 || strneq (input_line_pointer, "@got", 4))
939 {
3739860c 940 if ((strneq (input_line_pointer, "+", 1))
0b9e228a
SR
941 || (strneq (input_line_pointer, "-", 1)))
942 as_warn (_("GOT bad expression with %s."), input_line_pointer);
943
944 if (GOT_symbol == NULL)
945 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
946
947 symbol_with_at_got = 1;
948 }
949
3d3d428f
NC
950 switch (cur_arg->type)
951 {
7fac7ff4
NC
952 case arg_cr:
953 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
954 {
0b9e228a
SR
955 if (symbol_with_at_got)
956 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
957 else if (symbol_with_at_gotc)
958 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
959 else if (cur_arg->size == 20)
7fac7ff4
NC
960 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
961 else
962 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
963 }
964 break;
965
966 case arg_crp:
967 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
0b9e228a
SR
968 {
969 if (symbol_with_at_got)
970 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
971 else if (symbol_with_at_gotc)
972 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
973 } else {
7fac7ff4
NC
974 switch (instruction->size)
975 {
976 case 1:
977 switch (cur_arg->size)
978 {
979 case 0:
980 cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
981 break;
982 case 4:
983 if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
984 cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
985 else
986 cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
987 break;
988 default: break;
989 }
990 break;
991 case 2:
992 cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
993 break;
994 case 3:
995 if (cur_arg->size == 20)
996 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
997 else
998 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
999 break;
1000 default:
1001 break;
1002 }
0b9e228a 1003 }
7fac7ff4
NC
1004 break;
1005
1006 case arg_idxr:
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
1014 cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
1015 }
7fac7ff4
NC
1016 break;
1017
1018 case arg_idxrp:
1019 if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
0b9e228a
SR
1020 {
1021 if (symbol_with_at_got)
1022 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1023 else if (symbol_with_at_gotc)
1024 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1025 else {
7fac7ff4
NC
1026 switch (instruction->size)
1027 {
1028 case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break;
1029 case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break;
1030 case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break;
1031 default: break;
1032 }
0b9e228a
SR
1033 }
1034 }
7fac7ff4
NC
1035 break;
1036
1037 case arg_c:
1038 if (IS_INSN_MNEMONIC ("bal"))
1039 cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1040 else if (IS_INSN_TYPE (BRANCH_INS))
1041 {
1042 if (symbol_with_l)
1043 cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1044 else if (symbol_with_m)
1045 cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
1046 else
1047 cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
1048 }
1049 else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
1050 || IS_INSN_TYPE (CSTBIT_INS))
1051 {
0b9e228a 1052 if (symbol_with_s)
7fac7ff4 1053 as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
0b9e228a
SR
1054 if (symbol_with_at_got)
1055 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1056 else if (symbol_with_at_gotc)
1057 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1058 else if (symbol_with_m)
7fac7ff4
NC
1059 cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
1060 else /* Default to (symbol_with_l) */
1061 cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
1062 }
1063 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1064 cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
3d3d428f
NC
1065 break;
1066
1067 case arg_ic:
1068 if (IS_INSN_TYPE (ARITH_INS))
1069 {
0b9e228a
SR
1070 if (symbol_with_at_got)
1071 cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1072 else if (symbol_with_at_gotc)
1073 cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1074 else if (symbol_with_s)
3d3d428f
NC
1075 cr16_ins->rtype = BFD_RELOC_CR16_IMM4;
1076 else if (symbol_with_m)
1077 cr16_ins->rtype = BFD_RELOC_CR16_IMM20;
1078 else if (symbol_with_at)
1079 cr16_ins->rtype = BFD_RELOC_CR16_IMM32a;
1080 else /* Default to (symbol_with_l) */
1081 cr16_ins->rtype = BFD_RELOC_CR16_IMM32;
1082 }
1083 else if (IS_INSN_TYPE (ARITH_BYTE_INS))
7fac7ff4
NC
1084 {
1085 cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
1086 }
3d3d428f
NC
1087 break;
1088 default:
1089 break;
7fac7ff4 1090 }
3d3d428f
NC
1091 break;
1092
1093 default:
1094 cur_arg->X_op = cr16_ins->exp.X_op;
1095 break;
1096 }
1097
1098 input_line_pointer = saved_input_line_pointer;
1099 return;
1100}
1101
1102/* Retrieve the opcode image of a given register.
1103 If the register is illegal for the current instruction,
1104 issue an error. */
1105
1106static int
1107getreg_image (reg r)
1108{
91d6fa6a 1109 const reg_entry *rreg;
3d3d428f
NC
1110 char *reg_name;
1111 int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1112
1113 /* Check whether the register is in registers table. */
1114 if (r < MAX_REG)
91d6fa6a 1115 rreg = cr16_regtab + r;
3d3d428f
NC
1116 else /* Register not found. */
1117 {
1118 as_bad (_("Unknown register: `%d'"), r);
1119 return 0;
1120 }
1121
91d6fa6a 1122 reg_name = rreg->name;
3d3d428f
NC
1123
1124/* Issue a error message when register is illegal. */
1125#define IMAGE_ERR \
1126 as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1127 reg_name, ins_parse); \
1128 break;
1129
91d6fa6a 1130 switch (rreg->type)
3d3d428f
NC
1131 {
1132 case CR16_R_REGTYPE:
1133 if (! is_procreg)
91d6fa6a 1134 return rreg->image;
3d3d428f 1135 else
7fac7ff4 1136 IMAGE_ERR;
3d3d428f
NC
1137
1138 case CR16_P_REGTYPE:
91d6fa6a 1139 return rreg->image;
3d3d428f
NC
1140 break;
1141
1142 default:
1143 IMAGE_ERR;
1144 }
1145
1146 return 0;
1147}
1148
1149/* Parsing different types of operands
1150 -> constants Immediate/Absolute/Relative numbers
1151 -> Labels Relocatable symbols
1152 -> (reg pair base) Register pair base
1153 -> (rbase) Register base
1154 -> disp(rbase) Register relative
1155 -> [rinx]disp(reg pair) Register index with reg pair mode
1156 -> disp(rbase,ridx,scl) Register index mode. */
1157
1158static void
1159set_operand (char *operand, ins * cr16_ins)
1160{
33eaf5de
NC
1161 char *operandS; /* Pointer to start of sub-operand. */
1162 char *operandE; /* Pointer to end of sub-operand. */
3d3d428f
NC
1163
1164 argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument. */
1165
1166 /* Initialize pointers. */
1167 operandS = operandE = operand;
1168
1169 switch (cur_arg->type)
1170 {
1171 case arg_ic: /* Case $0x18. */
1172 operandS++;
1a0670f3 1173 /* Fall through. */
3d3d428f
NC
1174 case arg_c: /* Case 0x18. */
1175 /* Set constant. */
1176 process_label_constant (operandS, cr16_ins);
1177
1178 if (cur_arg->type != arg_ic)
1179 cur_arg->type = arg_c;
1180 break;
1181
1182 case arg_icr: /* Case $0x18(r1). */
1183 operandS++;
1184 case arg_cr: /* Case 0x18(r1). */
1185 /* Set displacement constant. */
1186 while (*operandE != '(')
1187 operandE++;
1188 *operandE = '\0';
1189 process_label_constant (operandS, cr16_ins);
1190 operandS = operandE;
1a0670f3 1191 /* Fall through. */
3d3d428f
NC
1192 case arg_rbase: /* Case (r1) or (r1,r0). */
1193 operandS++;
1194 /* Set register base. */
1195 while (*operandE != ')')
1196 operandE++;
1197 *operandE = '\0';
1198 if ((cur_arg->r = get_register (operandS)) == nullregister)
1199 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1200 operandS, ins_parse);
1201
1202 /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1203 if ((cur_arg->type != arg_rbase)
7fac7ff4
NC
1204 && ((getreg_image (cur_arg->r) == 12)
1205 || (getreg_image (cur_arg->r) == 13)
1206 || (getreg_image (cur_arg->r) == 14)
1207 || (getreg_image (cur_arg->r) == 15)))
3d3d428f
NC
1208 {
1209 cur_arg->type = arg_crp;
1210 cur_arg->rp = cur_arg->r;
1211 }
1212 break;
1213
1214 case arg_crp: /* Case 0x18(r1,r0). */
1215 /* Set displacement constant. */
1216 while (*operandE != '(')
1217 operandE++;
1218 *operandE = '\0';
1219 process_label_constant (operandS, cr16_ins);
1220 operandS = operandE;
1221 operandS++;
1222 /* Set register pair base. */
1223 while (*operandE != ')')
1224 operandE++;
1225 *operandE = '\0';
1226 if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
1227 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1228 operandS, ins_parse);
1229 break;
1230
1231 case arg_idxr:
1232 /* Set register pair base. */
1233 if ((strchr (operandS,'(') != NULL))
1234 {
1235 while ((*operandE != '(') && (! ISSPACE (*operandE)))
1236 operandE++;
1237 if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister)
1238 as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1239 operandS, ins_parse);
1240 *operandE++ = '\0';
1241 cur_arg->type = arg_idxrp;
1242 }
1243 else
7fac7ff4 1244 cur_arg->rp = -1;
3d3d428f
NC
1245
1246 operandE = operandS;
1247 /* Set displacement constant. */
1248 while (*operandE != ']')
1249 operandE++;
1250 process_label_constant (++operandE, cr16_ins);
1251 *operandE++ = '\0';
1252 operandE = operandS;
1253
1254 /* Set index register . */
1255 operandS = strchr (operandE,'[');
1256 if (operandS != NULL)
1257 { /* Eliminate '[', detach from rest of operand. */
1258 *operandS++ = '\0';
1259
1260 operandE = strchr (operandS, ']');
1261
1262 if (operandE == NULL)
1263 as_bad (_("unmatched '['"));
1264 else
1265 { /* Eliminate ']' and make sure it was the last thing
1266 in the string. */
1267 *operandE = '\0';
1268 if (*(operandE + 1) != '\0')
1269 as_bad (_("garbage after index spec ignored"));
1270 }
1271 }
1272
1273 if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
1274 as_bad (_("Illegal register `%s' in Instruction `%s'"),
1275 operandS, ins_parse);
1276 *operandE = '\0';
1277 *operandS = '\0';
1278 break;
1279
1280 default:
1281 break;
1282 }
1283}
1284
1285/* Parse a single operand.
1286 operand - Current operand to parse.
1287 cr16_ins - Current assembled instruction. */
1288
1289static void
1290parse_operand (char *operand, ins * cr16_ins)
1291{
1292 int ret_val;
1293 argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
1294
1295 /* Initialize the type to NULL before parsing. */
1296 cur_arg->type = nullargs;
1297
1298 /* Check whether this is a condition code . */
1299 if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
1300 {
1301 cur_arg->type = arg_cc;
1302 cur_arg->cc = ret_val;
1303 cur_arg->X_op = O_register;
1304 return;
1305 }
1306
1307 /* Check whether this is a general processor register. */
1308 if ((ret_val = get_register (operand)) != nullregister)
1309 {
1310 cur_arg->type = arg_r;
1311 cur_arg->r = ret_val;
1312 cur_arg->X_op = 0;
1313 return;
1314 }
1315
1316 /* Check whether this is a general processor register pair. */
1317 if ((operand[0] == '(')
1318 && ((ret_val = get_register_pair (operand)) != nullregister))
1319 {
1320 cur_arg->type = arg_rp;
1321 cur_arg->rp = ret_val;
1322 cur_arg->X_op = O_register;
1323 return;
1324 }
1325
1326 /* Check whether the operand is a processor register.
1327 For "lprd" and "sprd" instruction, only 32 bit
1328 processor registers used. */
1329 if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
1330 && ((ret_val = get_pregister (operand)) != nullpregister))
1331 {
1332 cur_arg->type = arg_pr;
1333 cur_arg->pr = ret_val;
1334 cur_arg->X_op = O_register;
1335 return;
1336 }
1337
1338 /* Check whether this is a processor register - 32 bit. */
1339 if ((ret_val = get_pregisterp (operand)) != nullpregister)
1340 {
1341 cur_arg->type = arg_prp;
1342 cur_arg->prp = ret_val;
1343 cur_arg->X_op = O_register;
1344 return;
1345 }
1346
1347 /* Deal with special characters. */
1348 switch (operand[0])
1349 {
1350 case '$':
1351 if (strchr (operand, '(') != NULL)
7fac7ff4 1352 cur_arg->type = arg_icr;
3d3d428f 1353 else
7fac7ff4 1354 cur_arg->type = arg_ic;
3d3d428f
NC
1355 goto set_params;
1356 break;
1357
1358 case '(':
1359 cur_arg->type = arg_rbase;
1360 goto set_params;
1361 break;
1362
1363 case '[':
1364 cur_arg->type = arg_idxr;
1365 goto set_params;
1366 break;
1367
1368 default:
1369 break;
1370 }
1371
1372 if (strchr (operand, '(') != NULL)
1373 {
1374 if (strchr (operand, ',') != NULL
1375 && (strchr (operand, ',') > strchr (operand, '(')))
1376 cur_arg->type = arg_crp;
1377 else
1378 cur_arg->type = arg_cr;
1379 }
1380 else
1381 cur_arg->type = arg_c;
1382
1383/* Parse an operand according to its type. */
1384 set_params:
1385 cur_arg->constant = 0;
1386 set_operand (operand, cr16_ins);
1387}
1388
1389/* Parse the various operands. Each operand is then analyzed to fillup
1390 the fields in the cr16_ins data structure. */
1391
1392static void
1393parse_operands (ins * cr16_ins, char *operands)
1394{
1395 char *operandS; /* Operands string. */
1396 char *operandH, *operandT; /* Single operand head/tail pointers. */
1397 int allocated = 0; /* Indicates a new operands string was allocated.*/
1398 char *operand[MAX_OPERANDS];/* Separating the operands. */
1399 int op_num = 0; /* Current operand number we are parsing. */
1400 int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1401 int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1402
1403 /* Preprocess the list of registers, if necessary. */
1404 operandS = operandH = operandT = operands;
1405
1406 while (*operandT != '\0')
1407 {
1408 if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1409 {
1410 *operandT++ = '\0';
1411 operand[op_num++] = strdup (operandH);
1412 operandH = operandT;
1413 continue;
1414 }
1415
1416 if (*operandT == ' ')
1417 as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1418
1419 if (*operandT == '(')
1420 bracket_flag = 1;
1421 else if (*operandT == '[')
1422 sq_bracket_flag = 1;
1423
1424 if (*operandT == ')')
1425 {
1426 if (bracket_flag)
1427 bracket_flag = 0;
1428 else
1429 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1430 }
1431 else if (*operandT == ']')
1432 {
1433 if (sq_bracket_flag)
1434 sq_bracket_flag = 0;
1435 else
1436 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1437 }
1438
1439 if (bracket_flag == 1 && *operandT == ')')
1440 bracket_flag = 0;
1441 else if (sq_bracket_flag == 1 && *operandT == ']')
1442 sq_bracket_flag = 0;
1443
1444 operandT++;
1445 }
1446
1447 /* Adding the last operand. */
1448 operand[op_num++] = strdup (operandH);
1449 cr16_ins->nargs = op_num;
1450
1451 /* Verifying correct syntax of operands (all brackets should be closed). */
1452 if (bracket_flag || sq_bracket_flag)
1453 as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1454
1455 /* Now we parse each operand separately. */
1456 for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
1457 {
1458 cur_arg_num = op_num;
1459 parse_operand (operand[op_num], cr16_ins);
1460 free (operand[op_num]);
1461 }
1462
1463 if (allocated)
1464 free (operandS);
1465}
1466
1467/* Get the trap index in dispatch table, given its name.
1468 This routine is used by assembling the 'excp' instruction. */
1469
1470static int
1471gettrap (char *s)
1472{
1473 const trap_entry *trap;
1474
1475 for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1476 if (strcasecmp (trap->name, s) == 0)
1477 return trap->entry;
1478
2b0f3761 1479 /* To make compatible with CR16 4.1 tools, the below 3-lines of
3d3d428f
NC
1480 * code added. Refer: Development Tracker item #123 */
1481 for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1482 if (trap->entry == (unsigned int) atoi (s))
1483 return trap->entry;
1484
1485 as_bad (_("Unknown exception: `%s'"), s);
1486 return 0;
1487}
1488
1489/* Top level module where instruction parsing starts.
1490 cr16_ins - data structure holds some information.
1491 operands - holds the operands part of the whole instruction. */
1492
1493static void
1494parse_insn (ins *insn, char *operands)
1495{
1496 int i;
1497
1498 /* Handle instructions with no operands. */
1499 for (i = 0; cr16_no_op_insn[i] != NULL; i++)
1500 {
1501 if (streq (cr16_no_op_insn[i], instruction->mnemonic))
1502 {
1503 insn->nargs = 0;
1504 return;
1505 }
1506 }
1507
1508 /* Handle 'excp' instructions. */
1509 if (IS_INSN_MNEMONIC ("excp"))
1510 {
1511 insn->nargs = 1;
1512 insn->arg[0].type = arg_ic;
1513 insn->arg[0].constant = gettrap (operands);
1514 insn->arg[0].X_op = O_constant;
1515 return;
1516 }
1517
1518 if (operands != NULL)
1519 parse_operands (insn, operands);
1520}
1521
1522/* bCC instruction requires special handling. */
1523static char *
1524get_b_cc (char * op)
1525{
1526 unsigned int i;
1527 char op1[5];
1528
1529 for (i = 1; i < strlen (op); i++)
1530 op1[i-1] = op[i];
1531
1532 op1[i-1] = '\0';
1533
1534 for (i = 0; i < cr16_num_cc ; i++)
1535 if (streq (op1, cr16_b_cond_tab[i]))
1536 return (char *) cr16_b_cond_tab[i];
1537
1538 return NULL;
1539}
1540
1541/* bCC instruction requires special handling. */
1542static int
1543is_bcc_insn (char * op)
1544{
1545 if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
7fac7ff4 1546 || streq (op, "beq0w") || streq (op, "bnq0w")))
3d3d428f
NC
1547 if ((op[0] == 'b') && (get_b_cc (op) != NULL))
1548 return 1;
1549 return 0;
1550}
1551
1552/* Cinv instruction requires special handling. */
1553
fd596c16 1554static void
3d3d428f
NC
1555check_cinv_options (char * operand)
1556{
1557 char *p = operand;
3d3d428f
NC
1558
1559 while (*++p != ']')
1560 {
fd596c16
NC
1561 switch (*p)
1562 {
1563 case ',':
1564 case ' ':
1565 case 'i':
1566 case 'u':
1567 case 'd':
1568 break;
1569 default:
1570 as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1571 }
3d3d428f 1572 }
3d3d428f
NC
1573}
1574
1575/* Retrieve the opcode image of a given register pair.
1576 If the register is illegal for the current instruction,
1577 issue an error. */
1578
1579static int
1580getregp_image (reg r)
1581{
91d6fa6a 1582 const reg_entry *rreg;
3d3d428f
NC
1583 char *reg_name;
1584
1585 /* Check whether the register is in registers table. */
1586 if (r < MAX_REG)
91d6fa6a 1587 rreg = cr16_regptab + r;
3d3d428f
NC
1588 /* Register not found. */
1589 else
1590 {
1591 as_bad (_("Unknown register pair: `%d'"), r);
1592 return 0;
1593 }
1594
91d6fa6a 1595 reg_name = rreg->name;
3d3d428f
NC
1596
1597/* Issue a error message when register pair is illegal. */
1598#define RPAIR_IMAGE_ERR \
1599 as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1600 reg_name, ins_parse); \
1601 break;
1602
91d6fa6a 1603 switch (rreg->type)
3d3d428f
NC
1604 {
1605 case CR16_RP_REGTYPE:
91d6fa6a 1606 return rreg->image;
3d3d428f
NC
1607 default:
1608 RPAIR_IMAGE_ERR;
1609 }
1610
1611 return 0;
1612}
1613
1614/* Retrieve the opcode image of a given index register pair.
1615 If the register is illegal for the current instruction,
1616 issue an error. */
1617
1618static int
1619getidxregp_image (reg r)
1620{
91d6fa6a 1621 const reg_entry *rreg;
3d3d428f
NC
1622 char *reg_name;
1623
1624 /* Check whether the register is in registers table. */
1625 if (r < MAX_REG)
91d6fa6a 1626 rreg = cr16_regptab + r;
3d3d428f
NC
1627 /* Register not found. */
1628 else
1629 {
1630 as_bad (_("Unknown register pair: `%d'"), r);
1631 return 0;
1632 }
1633
91d6fa6a 1634 reg_name = rreg->name;
3d3d428f
NC
1635
1636/* Issue a error message when register pair is illegal. */
1637#define IDX_RPAIR_IMAGE_ERR \
1638 as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1639 reg_name, ins_parse); \
1640
91d6fa6a 1641 if (rreg->type == CR16_RP_REGTYPE)
3d3d428f 1642 {
91d6fa6a 1643 switch (rreg->image)
7fac7ff4
NC
1644 {
1645 case 0: return 0; break;
1646 case 2: return 1; break;
1647 case 4: return 2; break;
1648 case 6: return 3; break;
1649 case 8: return 4; break;
1650 case 10: return 5; break;
1651 case 3: return 6; break;
1652 case 5: return 7; break;
1653 default:
1654 break;
1655 }
3d3d428f
NC
1656 }
1657
1658 IDX_RPAIR_IMAGE_ERR;
1659 return 0;
1660}
1661
33eaf5de 1662/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1663 If the register is illegal for the current instruction,
1664 issue an error. */
1665static int
249c2423 1666getprocreg_image (int r)
3d3d428f 1667{
91d6fa6a 1668 const reg_entry *rreg;
3d3d428f
NC
1669 char *reg_name;
1670
1671 /* Check whether the register is in registers table. */
d86fff44 1672 if (r >= MAX_REG && r < MAX_PREG)
91d6fa6a 1673 rreg = &cr16_pregtab[r - MAX_REG];
3d3d428f
NC
1674 /* Register not found. */
1675 else
1676 {
1677 as_bad (_("Unknown processor register : `%d'"), r);
1678 return 0;
1679 }
1680
91d6fa6a 1681 reg_name = rreg->name;
3d3d428f
NC
1682
1683/* Issue a error message when register pair is illegal. */
1684#define PROCREG_IMAGE_ERR \
1685 as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1686 reg_name, ins_parse); \
1687 break;
1688
91d6fa6a 1689 switch (rreg->type)
3d3d428f
NC
1690 {
1691 case CR16_P_REGTYPE:
91d6fa6a 1692 return rreg->image;
3d3d428f
NC
1693 default:
1694 PROCREG_IMAGE_ERR;
1695 }
1696
1697 return 0;
1698}
1699
33eaf5de 1700/* Retrieve the opcode image of a given processor register.
3d3d428f
NC
1701 If the register is illegal for the current instruction,
1702 issue an error. */
1703static int
249c2423 1704getprocregp_image (int r)
3d3d428f 1705{
91d6fa6a 1706 const reg_entry *rreg;
3d3d428f
NC
1707 char *reg_name;
1708 int pregptab_disp = 0;
1709
1710 /* Check whether the register is in registers table. */
d86fff44 1711 if (r >= MAX_REG && r < MAX_PREG)
3d3d428f
NC
1712 {
1713 r = r - MAX_REG;
1714 switch (r)
1715 {
7fac7ff4
NC
1716 case 4: pregptab_disp = 1; break;
1717 case 6: pregptab_disp = 2; break;
1718 case 8:
1719 case 9:
1720 case 10:
1721 pregptab_disp = 3; break;
1722 case 12:
1723 pregptab_disp = 4; break;
1724 case 14:
1725 pregptab_disp = 5; break;
1726 default: break;
3d3d428f 1727 }
91d6fa6a 1728 rreg = &cr16_pregptab[r - pregptab_disp];
3d3d428f
NC
1729 }
1730 /* Register not found. */
1731 else
1732 {
1733 as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
1734 return 0;
1735 }
1736
91d6fa6a 1737 reg_name = rreg->name;
3d3d428f
NC
1738
1739/* Issue a error message when register pair is illegal. */
1740#define PROCREGP_IMAGE_ERR \
1741 as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"),\
1742 reg_name, ins_parse); \
1743 break;
1744
91d6fa6a 1745 switch (rreg->type)
3d3d428f
NC
1746 {
1747 case CR16_P_REGTYPE:
91d6fa6a 1748 return rreg->image;
3d3d428f
NC
1749 default:
1750 PROCREGP_IMAGE_ERR;
1751 }
1752
1753 return 0;
1754}
1755
1756/* Routine used to represent integer X using NBITS bits. */
1757
1758static long
1759getconstant (long x, int nbits)
1760{
1761 /* The following expression avoids overflow if
1762 'nbits' is the number of bits in 'bfd_vma'. */
1763 return (x & ((((1 << (nbits - 1)) - 1) << 1) | 1));
1764}
1765
1766/* Print a constant value to 'output_opcode':
1767 ARG holds the operand's type and value.
1768 SHIFT represents the location of the operand to be print into.
1769 NBITS determines the size (in bits) of the constant. */
1770
1771static void
1772print_constant (int nbits, int shift, argument *arg)
1773{
1774 unsigned long mask = 0;
1775
1776 long constant = getconstant (arg->constant, nbits);
1777
1778 switch (nbits)
1779 {
1780 case 32:
1781 case 28:
1782 /* mask the upper part of the constant, that is, the bits
7fac7ff4
NC
1783 going to the lowest byte of output_opcode[0].
1784 The upper part of output_opcode[1] is always filled,
1785 therefore it is always masked with 0xFFFF. */
3d3d428f
NC
1786 mask = (1 << (nbits - 16)) - 1;
1787 /* Divide the constant between two consecutive words :
7fac7ff4
NC
1788 0 1 2 3
1789 +---------+---------+---------+---------+
1790 | | X X X X | x X x X | |
1791 +---------+---------+---------+---------+
1792 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1793
1794 CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1795 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1796 break;
1797
1798 case 21:
1a0670f3
AM
1799 if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
1800 nbits = 20;
1801 /* Fall through. */
3d3d428f
NC
1802 case 24:
1803 case 22:
1804 case 20:
1805 /* mask the upper part of the constant, that is, the bits
7fac7ff4
NC
1806 going to the lowest byte of output_opcode[0].
1807 The upper part of output_opcode[1] is always filled,
1808 therefore it is always masked with 0xFFFF. */
3d3d428f
NC
1809 mask = (1 << (nbits - 16)) - 1;
1810 /* Divide the constant between two consecutive words :
7fac7ff4
NC
1811 0 1 2 3
1812 +---------+---------+---------+---------+
1813 | | X X X X | - X - X | |
1814 +---------+---------+---------+---------+
1815 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1816
1817 if ((instruction->size > 2) && (shift == WORD_SHIFT))
7fac7ff4
NC
1818 {
1819 if (arg->type == arg_idxrp)
1820 {
1821 CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
1822 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1823 }
1824 else
1825 {
1826 CR16_PRINT (0, (((((constant >> WORD_SHIFT) & mask) << 8) & 0x0f00) | ((((constant >> WORD_SHIFT) & mask) >> 4) & 0xf)),0);
1827 CR16_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1828 }
1829 }
3d3d428f 1830 else
7fac7ff4 1831 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1832 break;
1833
1834 case 14:
1835 if (arg->type == arg_idxrp)
7fac7ff4
NC
1836 {
1837 if (instruction->size == 2)
1838 {
1839 CR16_PRINT (0, ((constant) & 0xf), shift); /* 0-3 bits. */
1840 CR16_PRINT (0, ((constant >> 4) & 0x3), (shift + 20)); /* 4-5 bits. */
1841 CR16_PRINT (0, ((constant >> 6) & 0x3), (shift + 14)); /* 6-7 bits. */
1842 CR16_PRINT (0, ((constant >> 8) & 0x3f), (shift + 8)); /* 8-13 bits. */
1843 }
1844 else
1845 CR16_PRINT (0, constant, shift);
1846 }
3d3d428f
NC
1847 break;
1848
1849 case 16:
1850 case 12:
1851 /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
7fac7ff4
NC
1852 always filling the upper part of output_opcode[1]. If we mistakenly
1853 write it to output_opcode[0], the constant prefix (that is, 'match')
33eaf5de 1854 will be overridden.
7fac7ff4
NC
1855 0 1 2 3
1856 +---------+---------+---------+---------+
1857 | 'match' | | X X X X | |
1858 +---------+---------+---------+---------+
1859 output_opcode[0] output_opcode[1] */
3d3d428f
NC
1860
1861 if ((instruction->size > 2) && (shift == WORD_SHIFT))
7fac7ff4 1862 CR16_PRINT (1, constant, WORD_SHIFT);
3d3d428f 1863 else
7fac7ff4 1864 CR16_PRINT (0, constant, shift);
3d3d428f
NC
1865 break;
1866
1867 case 8:
7fac7ff4
NC
1868 CR16_PRINT (0, ((constant / 2) & 0xf), shift);
1869 CR16_PRINT (0, ((constant / 2) >> 4), (shift + 8));
3d3d428f
NC
1870 break;
1871
1872 default:
1873 CR16_PRINT (0, constant, shift);
1874 break;
1875 }
1876}
1877
1878/* Print an operand to 'output_opcode', which later on will be
1879 printed to the object file:
1880 ARG holds the operand's type, size and value.
1881 SHIFT represents the printing location of operand.
1882 NBITS determines the size (in bits) of a constant operand. */
1883
1884static void
1885print_operand (int nbits, int shift, argument *arg)
1886{
1887 switch (arg->type)
1888 {
1889 case arg_cc:
1890 CR16_PRINT (0, arg->cc, shift);
1891 break;
1892
1893 case arg_r:
1894 CR16_PRINT (0, getreg_image (arg->r), shift);
1895 break;
1896
1897 case arg_rp:
1898 CR16_PRINT (0, getregp_image (arg->rp), shift);
1899 break;
1900
1901 case arg_pr:
1902 CR16_PRINT (0, getprocreg_image (arg->pr), shift);
1903 break;
1904
1905 case arg_prp:
1906 CR16_PRINT (0, getprocregp_image (arg->prp), shift);
1907 break;
1908
1909 case arg_idxrp:
1910 /* 16 12 8 6 0
1911 +-----------------------------+
1912 | r_index | disp | rp_base |
1913 +-----------------------------+ */
1914
1915 if (instruction->size == 3)
7fac7ff4
NC
1916 {
1917 CR16_PRINT (0, getidxregp_image (arg->rp), 0);
1918 if (getreg_image (arg->i_r) == 12)
1919 CR16_PRINT (0, 0, 3);
1920 else
1921 CR16_PRINT (0, 1, 3);
1922 }
3d3d428f 1923 else
7fac7ff4
NC
1924 {
1925 CR16_PRINT (0, getidxregp_image (arg->rp), 16);
1926 if (getreg_image (arg->i_r) == 12)
1927 CR16_PRINT (0, 0, 19);
1928 else
1929 CR16_PRINT (0, 1, 19);
1930 }
3d3d428f
NC
1931 print_constant (nbits, shift, arg);
1932 break;
1933
1934 case arg_idxr:
1935 if (getreg_image (arg->i_r) == 12)
7fac7ff4
NC
1936 if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1937 || IS_INSN_MNEMONIC ("tbitb"))
1938 CR16_PRINT (0, 0, 23);
1939 else CR16_PRINT (0, 0, 24);
3d3d428f 1940 else
7fac7ff4
NC
1941 if (IS_INSN_MNEMONIC ("cbitb") || IS_INSN_MNEMONIC ("sbitb")
1942 || IS_INSN_MNEMONIC ("tbitb"))
1943 CR16_PRINT (0, 1, 23);
1944 else CR16_PRINT (0, 1, 24);
3d3d428f
NC
1945
1946 print_constant (nbits, shift, arg);
1947 break;
1948
1949 case arg_ic:
1950 case arg_c:
1951 print_constant (nbits, shift, arg);
1952 break;
1953
1954 case arg_rbase:
1955 CR16_PRINT (0, getreg_image (arg->r), shift);
1956 break;
1957
1958 case arg_cr:
1959 print_constant (nbits, shift , arg);
1960 /* Add the register argument to the output_opcode. */
1961 CR16_PRINT (0, getreg_image (arg->r), (shift+16));
1962 break;
1963
1964 case arg_crp:
1965 print_constant (nbits, shift , arg);
1966 if (instruction->size > 1)
7fac7ff4 1967 CR16_PRINT (0, getregp_image (arg->rp), (shift + 16));
3d3d428f 1968 else if (IS_INSN_TYPE (LD_STOR_INS) || (IS_INSN_TYPE (CSTBIT_INS)))
7fac7ff4
NC
1969 {
1970 if (instruction->size == 2)
1971 CR16_PRINT (0, getregp_image (arg->rp), (shift - 8));
1972 else if (instruction->size == 1)
1973 CR16_PRINT (0, getregp_image (arg->rp), 16);
1974 }
3d3d428f 1975 else
7fac7ff4 1976 CR16_PRINT (0, getregp_image (arg->rp), shift);
3d3d428f
NC
1977 break;
1978
1979 default:
1980 break;
1981 }
1982}
1983
1984/* Retrieve the number of operands for the current assembled instruction. */
1985
1986static int
1987get_number_of_operands (void)
1988{
1989 int i;
1990
1991 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1992 ;
1993 return i;
1994}
1995
1996/* Verify that the number NUM can be represented in BITS bits (that is,
1997 within its permitted range), based on the instruction's FLAGS.
1998 If UPDATE is nonzero, update the value of NUM if necessary.
1999 Return OP_LEGAL upon success, actual error type upon failure. */
2000
2001static op_err
2002check_range (long *num, int bits, int unsigned flags, int update)
2003{
2004 long min, max;
6610dc6d 2005 op_err retval = OP_LEGAL;
3d3d428f
NC
2006 long value = *num;
2007
2008 if (bits == 0 && value > 0) return OP_OUT_OF_RANGE;
2009
33eaf5de 2010 /* For hosts with longs bigger than 32-bits make sure that the top
3d3d428f
NC
2011 bits of a 32-bit negative value read in by the parser are set,
2012 so that the correct comparisons are made. */
2013 if (value & 0x80000000)
69c9e028 2014 value |= (-1UL << 31);
3d3d428f
NC
2015
2016
2017 /* Verify operand value is even. */
2018 if (flags & OP_EVEN)
2019 {
2020 if (value % 2)
2021 return OP_NOT_EVEN;
2022 }
2023
2024 if (flags & OP_DEC)
2025 {
2026 value -= 1;
2027 if (update)
2028 *num = value;
2029 }
2030
2031 if (flags & OP_SHIFT)
2032 {
2033 value >>= 1;
2034 if (update)
2035 *num = value;
2036 }
2037 else if (flags & OP_SHIFT_DEC)
2038 {
2039 value = (value >> 1) - 1;
2040 if (update)
2041 *num = value;
2042 }
2043
2044 if (flags & OP_ABS20)
2045 {
2046 if (value > 0xEFFFF)
2047 return OP_OUT_OF_RANGE;
2048 }
2049
2050 if (flags & OP_ESC)
2051 {
2052 if (value == 0xB || value == 0x9)
2053 return OP_OUT_OF_RANGE;
2054 else if (value == -1)
7fac7ff4
NC
2055 {
2056 if (update)
2057 *num = 9;
2058 return retval;
2059 }
3d3d428f
NC
2060 }
2061
2062 if (flags & OP_ESC1)
2063 {
2064 if (value > 13)
2065 return OP_OUT_OF_RANGE;
2066 }
2067
2068 if (flags & OP_SIGNED)
2069 {
2070 max = (1 << (bits - 1)) - 1;
2071 min = - (1 << (bits - 1));
2072 if ((value > max) || (value < min))
2073 retval = OP_OUT_OF_RANGE;
2074 }
2075 else if (flags & OP_UNSIGNED)
2076 {
2077 max = ((((1 << (bits - 1)) - 1) << 1) | 1);
2078 min = 0;
2079 if (((unsigned long) value > (unsigned long) max)
2080 || ((unsigned long) value < (unsigned long) min))
2081 retval = OP_OUT_OF_RANGE;
2082 }
2083 else if (flags & OP_NEG)
2084 {
2085 max = - 1;
7fac7ff4 2086 min = - ((1 << (bits - 1)) - 1);
3d3d428f
NC
2087 if ((value > max) || (value < min))
2088 retval = OP_OUT_OF_RANGE;
2089 }
2090 return retval;
2091}
2092
33eaf5de 2093/* Bunch of error checking.
3d3d428f
NC
2094 The checks are made after a matching instruction was found. */
2095
2096static void
2097warn_if_needed (ins *insn)
2098{
2099 /* If the post-increment address mode is used and the load/store
2100 source register is the same as rbase, the result of the
2101 instruction is undefined. */
2102 if (IS_INSN_TYPE (LD_STOR_INS_INC))
2103 {
2104 /* Enough to verify that one of the arguments is a simple reg. */
2105 if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
2106 if (insn->arg[0].r == insn->arg[1].r)
2107 as_bad (_("Same src/dest register is used (`r%d'), result is undefined"), insn->arg[0].r);
2108 }
2109
2110 if (IS_INSN_MNEMONIC ("pop")
2111 || IS_INSN_MNEMONIC ("push")
2112 || IS_INSN_MNEMONIC ("popret"))
2113 {
2114 unsigned int count = insn->arg[0].constant, reg_val;
2115
33eaf5de 2116 /* Check if count operand caused to save/retrieve the RA twice
7fac7ff4 2117 to generate warning message. */
3d3d428f
NC
2118 if (insn->nargs > 2)
2119 {
2120 reg_val = getreg_image (insn->arg[1].r);
2121
2122 if ( ((reg_val == 9) && (count > 7))
7fac7ff4
NC
2123 || ((reg_val == 10) && (count > 6))
2124 || ((reg_val == 11) && (count > 5))
2125 || ((reg_val == 12) && (count > 4))
2126 || ((reg_val == 13) && (count > 2))
2127 || ((reg_val == 14) && (count > 0)))
3d3d428f
NC
2128 as_warn (_("RA register is saved twice."));
2129
2130 /* Check if the third operand is "RA" or "ra" */
2131 if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
2132 as_bad (_("`%s' Illegal use of registers."), ins_parse);
2133 }
2134
2135 if (insn->nargs > 1)
2136 {
2137 reg_val = getreg_image (insn->arg[1].r);
2138
2139 /* If register is a register pair ie r12/r13/r14 in operand1, then
2140 the count constant should be validated. */
2141 if (((reg_val == 11) && (count > 7))
7fac7ff4
NC
2142 || ((reg_val == 12) && (count > 6))
2143 || ((reg_val == 13) && (count > 4))
2144 || ((reg_val == 14) && (count > 2))
2145 || ((reg_val == 15) && (count > 0)))
3d3d428f
NC
2146 as_bad (_("`%s' Illegal count-register combination."), ins_parse);
2147 }
2148 else
2149 {
2150 /* Check if the operand is "RA" or "ra" */
2151 if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
2152 as_bad (_("`%s' Illegal use of register."), ins_parse);
2153 }
2154 }
2155
2156 /* Some instruction assume the stack pointer as rptr operand.
2157 Issue an error when the register to be loaded is also SP. */
2158 if (instruction->flags & NO_SP)
2159 {
2160 if (getreg_image (insn->arg[1].r) == getreg_image (sp))
2161 as_bad (_("`%s' has undefined result"), ins_parse);
2162 }
2163
2164 /* If the rptr register is specified as one of the registers to be loaded,
2165 the final contents of rptr are undefined. Thus, we issue an error. */
2166 if (instruction->flags & NO_RPTR)
2167 {
2168 if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
2169 as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2170 getreg_image (insn->arg[0].r));
2171 }
2172}
2173
2174/* In some cases, we need to adjust the instruction pointer although a
2175 match was already found. Here, we gather all these cases.
2176 Returns 1 if instruction pointer was adjusted, otherwise 0. */
2177
2178static int
2179adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
2180{
2181 int ret_value = 0;
2182
2183 if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
2184 {
2185 if ((instruction->operands[0].op_type == abs24)
2186 && ((insn->arg[0].constant) > 0xF00000))
2187 {
2188 insn->arg[0].constant &= 0xFFFFF;
2189 instruction--;
2190 ret_value = 1;
2191 }
2192 }
2193
2194 return ret_value;
2195}
2196
2197/* Assemble a single instruction:
2198 INSN is already parsed (that is, all operand values and types are set).
2199 For instruction to be assembled, we need to find an appropriate template in
2200 the instruction table, meeting the following conditions:
2201 1: Has the same number of operands.
2202 2: Has the same operand types.
2203 3: Each operand size is sufficient to represent the instruction's values.
2204 Returns 1 upon success, 0 upon failure. */
2205
2206static int
9202e88a 2207assemble_insn (const char *mnemonic, ins *insn)
3d3d428f
NC
2208{
2209 /* Type of each operand in the current template. */
2210 argtype cur_type[MAX_OPERANDS];
2211 /* Size (in bits) of each operand in the current template. */
2212 unsigned int cur_size[MAX_OPERANDS];
2213 /* Flags of each operand in the current template. */
2214 unsigned int cur_flags[MAX_OPERANDS];
2215 /* Instruction type to match. */
2216 unsigned int ins_type;
2217 /* Boolean flag to mark whether a match was found. */
2218 int match = 0;
2219 int i;
2220 /* Nonzero if an instruction with same number of operands was found. */
2221 int found_same_number_of_operands = 0;
2222 /* Nonzero if an instruction with same argument types was found. */
2223 int found_same_argument_types = 0;
2224 /* Nonzero if a constant was found within the required range. */
2225 int found_const_within_range = 0;
2226 /* Argument number of an operand with invalid type. */
2227 int invalid_optype = -1;
2228 /* Argument number of an operand with invalid constant value. */
2229 int invalid_const = -1;
2230 /* Operand error (used for issuing various constant error messages). */
2231 op_err op_error, const_err = OP_LEGAL;
2232
2233/* Retrieve data (based on FUNC) for each operand of a given instruction. */
2234#define GET_CURRENT_DATA(FUNC, ARRAY) \
2235 for (i = 0; i < insn->nargs; i++) \
2236 ARRAY[i] = FUNC (instruction->operands[i].op_type)
2237
2238#define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type)
2239#define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size)
2240#define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags)
2241
2242 /* Instruction has no operands -> only copy the constant opcode. */
2243 if (insn->nargs == 0)
2244 {
2245 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2246 return 1;
2247 }
2248
2249 /* In some case, same mnemonic can appear with different instruction types.
2250 For example, 'storb' is supported with 3 different types :
2251 LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2252 We assume that when reaching this point, the instruction type was
2253 pre-determined. We need to make sure that the type stays the same
2254 during a search for matching instruction. */
2255 ins_type = CR16_INS_TYPE (instruction->flags);
2256
2257 while (/* Check that match is still not found. */
2258 match != 1
2259 /* Check we didn't get to end of table. */
2260 && instruction->mnemonic != NULL
2261 /* Check that the actual mnemonic is still available. */
2262 && IS_INSN_MNEMONIC (mnemonic)
2263 /* Check that the instruction type wasn't changed. */
2264 && IS_INSN_TYPE (ins_type))
2265 {
2266 /* Check whether number of arguments is legal. */
2267 if (get_number_of_operands () != insn->nargs)
2268 goto next_insn;
2269 found_same_number_of_operands = 1;
2270
2271 /* Initialize arrays with data of each operand in current template. */
2272 GET_CURRENT_TYPE;
2273 GET_CURRENT_SIZE;
2274 GET_CURRENT_FLAGS;
2275
2276 /* Check for type compatibility. */
2277 for (i = 0; i < insn->nargs; i++)
2278 {
2279 if (cur_type[i] != insn->arg[i].type)
2280 {
2281 if (invalid_optype == -1)
2282 invalid_optype = i + 1;
2283 goto next_insn;
2284 }
2285 }
2286 found_same_argument_types = 1;
2287
2288 for (i = 0; i < insn->nargs; i++)
2289 {
2290 /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2291 then goto next instruction. */
2292 if (IS_INSN_MNEMONIC ("bal") && (i == 0)
7fac7ff4 2293 && (instruction->size == 2) && (insn->arg[i].rp != 14))
3d3d428f
NC
2294 goto next_insn;
2295
2296 /* If 'storb' instruction with 'sp' reg and 16-bit disp of
33eaf5de 2297 * reg-pair, leads to undefined trap, so this should use
3d3d428f
NC
2298 * 20-bit disp of reg-pair. */
2299 if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
7fac7ff4 2300 && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
3d3d428f
NC
2301 goto next_insn;
2302
2303 /* Only check range - don't update the constant's value, since the
2304 current instruction may not be the last we try to match.
2305 The constant's value will be updated later, right before printing
2306 it to the object file. */
2307 if ((insn->arg[i].X_op == O_constant)
2308 && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
2309 cur_flags[i], 0)))
2310 {
2311 if (invalid_const == -1)
2312 {
2313 invalid_const = i + 1;
2314 const_err = op_error;
2315 }
2316 goto next_insn;
2317 }
2318 /* For symbols, we make sure the relocation size (which was already
2319 determined) is sufficient. */
2320 else if ((insn->arg[i].X_op == O_symbol)
2321 && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
7fac7ff4 2322 > cur_size[i]))
3d3d428f
NC
2323 goto next_insn;
2324 }
2325 found_const_within_range = 1;
2326
2327 /* If we got till here -> Full match is found. */
2328 match = 1;
2329 break;
2330
2331/* Try again with next instruction. */
2332next_insn:
2333 instruction++;
2334 }
2335
2336 if (!match)
2337 {
2338 /* We haven't found a match - instruction can't be assembled. */
2339 if (!found_same_number_of_operands)
2340 as_bad (_("Incorrect number of operands"));
2341 else if (!found_same_argument_types)
2342 as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
2343 else if (!found_const_within_range)
2344 {
2345 switch (const_err)
2346 {
7fac7ff4
NC
2347 case OP_OUT_OF_RANGE:
2348 as_bad (_("Operand out of range (arg %d)"), invalid_const);
2349 break;
2350 case OP_NOT_EVEN:
2351 as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
2352 break;
2353 default:
2354 as_bad (_("Illegal operand (arg %d)"), invalid_const);
2355 break;
3d3d428f
NC
2356 }
2357 }
2358
2359 return 0;
2360 }
2361 else
2362 /* Full match - print the encoding to output file. */
2363 {
33eaf5de 2364 /* Make further checking (such that couldn't be made earlier).
3d3d428f
NC
2365 Warn the user if necessary. */
2366 warn_if_needed (insn);
2367
2368 /* Check whether we need to adjust the instruction pointer. */
2369 if (adjust_if_needed (insn))
2370 /* If instruction pointer was adjusted, we need to update
2371 the size of the current template operands. */
2372 GET_CURRENT_SIZE;
2373
2374 for (i = 0; i < insn->nargs; i++)
2375 {
2376 int j = instruction->flags & REVERSE_MATCH ?
2377 i == 0 ? 1 :
2378 i == 1 ? 0 : i :
2379 i;
2380
2381 /* This time, update constant value before printing it. */
2382 if ((insn->arg[j].X_op == O_constant)
2383 && (check_range (&insn->arg[j].constant, cur_size[j],
2384 cur_flags[j], 1) != OP_LEGAL))
2385 as_fatal (_("Illegal operand (arg %d)"), j+1);
2386 }
2387
2388 /* First, copy the instruction's opcode. */
2389 output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2390
2391 for (i = 0; i < insn->nargs; i++)
2392 {
2b0f3761 2393 /* For BAL (ra),disp17 instruction only. And also set the
3d3d428f
NC
2394 DISP24a relocation type. */
2395 if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
2396 {
2397 insn->rtype = BFD_RELOC_CR16_DISP24a;
2398 continue;
2399 }
2400 cur_arg_num = i;
2401 print_operand (cur_size[i], instruction->operands[i].shift,
2402 &insn->arg[i]);
2403 }
2404 }
2405
2406 return 1;
2407}
2408
2409/* Print the instruction.
2410 Handle also cases where the instruction is relaxable/relocatable. */
2411
2412static void
2413print_insn (ins *insn)
2414{
2415 unsigned int i, j, insn_size;
2416 char *this_frag;
2417 unsigned short words[4];
2418 int addr_mod;
2419
2420 /* Arrange the insn encodings in a WORD size array. */
2421 for (i = 0, j = 0; i < 2; i++)
2422 {
2423 words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2424 words[j++] = output_opcode[i] & 0xFFFF;
2425 }
2426
3d3d428f 2427 /* Handle relocation. */
7fac7ff4
NC
2428 if ((instruction->flags & RELAXABLE) && relocatable)
2429 {
2430 int relax_subtype;
2431 /* Write the maximal instruction size supported. */
2432 insn_size = INSN_MAX_SIZE;
2433
2434 if (IS_INSN_TYPE (BRANCH_INS))
2435 {
2436 switch (insn->rtype)
2437 {
2438 case BFD_RELOC_CR16_DISP24:
2439 relax_subtype = 2;
2440 break;
2441 case BFD_RELOC_CR16_DISP16:
2442 relax_subtype = 1;
2443 break;
2444 default:
2445 relax_subtype = 0;
2446 break;
2447 }
2448 }
2449 else
2450 abort ();
2451
2452 this_frag = frag_var (rs_machine_dependent, insn_size *2,
2453 4, relax_subtype,
2454 insn->exp.X_add_symbol,
0b9e228a 2455 0,
7fac7ff4
NC
2456 0);
2457 }
2458 else
3d3d428f 2459 {
7fac7ff4
NC
2460 insn_size = instruction->size;
2461 this_frag = frag_more (insn_size * 2);
3d3d428f 2462
7fac7ff4
NC
2463 if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2464 {
2465 reloc_howto_type *reloc_howto;
2466 int size;
3d3d428f 2467
7fac7ff4 2468 reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
3739860c 2469
7fac7ff4
NC
2470 if (!reloc_howto)
2471 abort ();
3d3d428f 2472
7fac7ff4 2473 size = bfd_get_reloc_size (reloc_howto);
3d3d428f 2474
7fac7ff4
NC
2475 if (size < 1 || size > 4)
2476 abort ();
3d3d428f 2477
7fac7ff4
NC
2478 fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2479 size, &insn->exp, reloc_howto->pc_relative,
2480 insn->rtype);
2481 }
3d3d428f
NC
2482 }
2483
2484 /* Verify a 2-byte code alignment. */
2485 addr_mod = frag_now_fix () & 1;
2486 if (frag_now->has_code && frag_now->insn_addr != addr_mod)
2487 as_bad (_("instruction address is not a multiple of 2"));
2488 frag_now->insn_addr = addr_mod;
2489 frag_now->has_code = 1;
2490
2491 /* Write the instruction encoding to frag. */
2492 for (i = 0; i < insn_size; i++)
2493 {
2494 md_number_to_chars (this_frag, (valueT) words[i], 2);
2495 this_frag += 2;
2496 }
2497}
2498
9202e88a
TS
2499/* Actually assemble an instruction. */
2500
2501static void
2502cr16_assemble (const char *op, char *param)
2503{
2504 ins cr16_ins;
2505
2506 /* Find the instruction. */
2507 instruction = (const inst *) hash_find (cr16_inst_hash, op);
2508 if (instruction == NULL)
2509 {
2510 as_bad (_("Unknown opcode: `%s'"), op);
2511 return;
2512 }
2513
2514 /* Tie dwarf2 debug info to the address at the start of the insn. */
2515 dwarf2_emit_insn (0);
2516
2517 /* Parse the instruction's operands. */
2518 parse_insn (&cr16_ins, param);
2519
2520 /* Assemble the instruction - return upon failure. */
2521 if (assemble_insn (op, &cr16_ins) == 0)
2522 return;
2523
2524 /* Print the instruction. */
2525 print_insn (&cr16_ins);
2526}
2527
3d3d428f
NC
2528/* This is the guts of the machine-dependent assembler. OP points to a
2529 machine dependent instruction. This function is supposed to emit
2530 the frags/bytes it assembles to. */
2531
2532void
2533md_assemble (char *op)
2534{
2535 ins cr16_ins;
2536 char *param, param1[32];
3d3d428f
NC
2537
2538 /* Reset global variables for a new instruction. */
2539 reset_vars (op);
2540
2541 /* Strip the mnemonic. */
2542 for (param = op; *param != 0 && !ISSPACE (*param); param++)
2543 ;
3d3d428f
NC
2544 *param++ = '\0';
2545
33eaf5de 2546 /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
3d3d428f
NC
2547 if (is_bcc_insn (op))
2548 {
2549 strcpy (param1, get_b_cc (op));
3d3d428f
NC
2550 strcat (param1,",");
2551 strcat (param1, param);
2552 param = (char *) &param1;
9202e88a
TS
2553 cr16_assemble ("b", param);
2554 return;
3d3d428f
NC
2555 }
2556
2557 /* Checking the cinv options and adjust the mnemonic by removing the
2558 extra white spaces. */
2559 if (streq ("cinv", op))
2560 {
2561 /* Validate the cinv options. */
2562 check_cinv_options (param);
2563 strcat (op, param);
2564 }
2565
2566 /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2567 lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
33eaf5de 2568 as CR16 core doesn't support lsh[b/w] right shift operations. */
3d3d428f
NC
2569 if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
2570 && (param [0] == '$'))
2571 {
2572 strcpy (param1, param);
2573 /* Find the instruction. */
2574 instruction = (const inst *) hash_find (cr16_inst_hash, op);
2575 parse_operands (&cr16_ins, param1);
2576 if (((&cr16_ins)->arg[0].type == arg_ic)
7fac7ff4 2577 && ((&cr16_ins)->arg[0].constant >= 0))
3d3d428f
NC
2578 {
2579 if (streq ("lshb", op))
9202e88a 2580 cr16_assemble ("ashub", param);
3d3d428f 2581 else if (streq ("lshd", op))
9202e88a 2582 cr16_assemble ("ashud", param);
7fac7ff4 2583 else
9202e88a
TS
2584 cr16_assemble ("ashuw", param);
2585 return;
3d3d428f
NC
2586 }
2587 }
2588
9202e88a 2589 cr16_assemble (op, param);
3d3d428f 2590}
This page took 0.567018 seconds and 4 git commands to generate.