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