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