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