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