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