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