[PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t}
[binutils-gdb.git] / gas / config / tc-mn10200.c
blob045016bcba04f297ed5d2a55186fd7dbf396cb64
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright (C) 1996-2019 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 #include "as.h"
22 #include "safe-ctype.h"
23 #include "subsegs.h"
24 #include "opcode/mn10200.h"
26 /* Structure to hold information about predefined registers. */
27 struct reg_name
29 const char *name;
30 int value;
33 /* Generic assembler global variables which must be defined by all
34 targets. */
36 /* Characters which always start a comment. */
37 const char comment_chars[] = "#";
39 /* Characters which start a comment at the beginning of a line. */
40 const char line_comment_chars[] = ";#";
42 /* Characters which may be used to separate multiple commands on a
43 single line. */
44 const char line_separator_chars[] = ";";
46 /* Characters which are used to indicate an exponent in a floating
47 point number. */
48 const char EXP_CHARS[] = "eE";
50 /* Characters which mean that a number is a floating point constant,
51 as in 0d1.0. */
52 const char FLT_CHARS[] = "dD";
54 const relax_typeS md_relax_table[] =
56 /* bCC relaxing */
57 {0x81, -0x7e, 2, 1},
58 {0x8004, -0x7ffb, 5, 2},
59 {0x800006, -0x7ffff9, 7, 0},
60 /* bCCx relaxing */
61 {0x81, -0x7e, 3, 4},
62 {0x8004, -0x7ffb, 6, 5},
63 {0x800006, -0x7ffff9, 8, 0},
64 /* jsr relaxing */
65 {0x8004, -0x7ffb, 3, 7},
66 {0x800006, -0x7ffff9, 5, 0},
67 /* jmp relaxing */
68 {0x81, -0x7e, 2, 9},
69 {0x8004, -0x7ffb, 3, 10},
70 {0x800006, -0x7ffff9, 5, 0},
75 /* Fixups. */
76 #define MAX_INSN_FIXUPS 5
78 struct mn10200_fixup
80 expressionS exp;
81 int opindex;
82 bfd_reloc_code_real_type reloc;
85 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
86 static int fc;
88 const char *md_shortopts = "";
90 struct option md_longopts[] =
92 {NULL, no_argument, NULL, 0}
95 size_t md_longopts_size = sizeof (md_longopts);
97 /* The target specific pseudo-ops which we support. */
98 const pseudo_typeS md_pseudo_table[] =
100 { NULL, NULL, 0 }
103 /* Opcode hash table. */
104 static struct hash_control *mn10200_hash;
106 /* This table is sorted. Suitable for searching by a binary search. */
107 static const struct reg_name data_registers[] =
109 { "d0", 0 },
110 { "d1", 1 },
111 { "d2", 2 },
112 { "d3", 3 },
114 #define DATA_REG_NAME_CNT \
115 (sizeof (data_registers) / sizeof (struct reg_name))
117 static const struct reg_name address_registers[] =
119 { "a0", 0 },
120 { "a1", 1 },
121 { "a2", 2 },
122 { "a3", 3 },
124 #define ADDRESS_REG_NAME_CNT \
125 (sizeof (address_registers) / sizeof (struct reg_name))
127 static const struct reg_name other_registers[] =
129 { "mdr", 0 },
130 { "psw", 0 },
132 #define OTHER_REG_NAME_CNT \
133 (sizeof (other_registers) / sizeof (struct reg_name))
135 /* reg_name_search does a binary search of the given register table
136 to see if "name" is a valid register name. Returns the register
137 number from the array on success, or -1 on failure. */
139 static int
140 reg_name_search (const struct reg_name *regs,
141 int regcount,
142 const char *name)
144 int middle, low, high;
145 int cmp;
147 low = 0;
148 high = regcount - 1;
152 middle = (low + high) / 2;
153 cmp = strcasecmp (name, regs[middle].name);
154 if (cmp < 0)
155 high = middle - 1;
156 else if (cmp > 0)
157 low = middle + 1;
158 else
159 return regs[middle].value;
161 while (low <= high);
162 return -1;
165 /* Summary of register_name().
167 in: Input_line_pointer points to 1st char of operand.
169 out: An expressionS.
170 The operand may have been a register: in this case, X_op == O_register,
171 X_add_number is set to the register number, and truth is returned.
172 Input_line_pointer->(next non-blank) char after operand, or is in
173 its original state. */
175 static bfd_boolean
176 data_register_name (expressionS *expressionP)
178 int reg_number;
179 char *name;
180 char *start;
181 char c;
183 /* Find the spelling of the operand. */
184 start = input_line_pointer;
185 c = get_symbol_name (&name);
186 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
188 /* Put back the delimiting char. */
189 (void) restore_line_pointer (c);
191 /* Look to see if it's in the register table. */
192 if (reg_number >= 0)
194 expressionP->X_op = O_register;
195 expressionP->X_add_number = reg_number;
197 /* Make the rest nice. */
198 expressionP->X_add_symbol = NULL;
199 expressionP->X_op_symbol = NULL;
201 return TRUE;
204 /* Reset the line as if we had not done anything. */
205 input_line_pointer = start;
206 return FALSE;
209 /* Summary of register_name().
211 in: Input_line_pointer points to 1st char of operand.
213 out: An expressionS.
214 The operand may have been a register: in this case, X_op == O_register,
215 X_add_number is set to the register number, and truth is returned.
216 Input_line_pointer->(next non-blank) char after operand, or is in
217 its original state. */
219 static bfd_boolean
220 address_register_name (expressionS *expressionP)
222 int reg_number;
223 char *name;
224 char *start;
225 char c;
227 /* Find the spelling of the operand. */
228 start = input_line_pointer;
229 c = get_symbol_name (&name);
230 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
232 /* Put back the delimiting char. */
233 (void) restore_line_pointer (c);
235 /* Look to see if it's in the register table. */
236 if (reg_number >= 0)
238 expressionP->X_op = O_register;
239 expressionP->X_add_number = reg_number;
241 /* Make the rest nice. */
242 expressionP->X_add_symbol = NULL;
243 expressionP->X_op_symbol = NULL;
245 return TRUE;
248 /* Reset the line as if we had not done anything. */
249 input_line_pointer = start;
250 return FALSE;
253 /* Summary of register_name().
255 in: Input_line_pointer points to 1st char of operand.
257 out: An expressionS.
258 The operand may have been a register: in this case, X_op == O_register,
259 X_add_number is set to the register number, and truth is returned.
260 Input_line_pointer->(next non-blank) char after operand, or is in
261 its original state. */
263 static bfd_boolean
264 other_register_name (expressionS *expressionP)
266 int reg_number;
267 char *name;
268 char *start;
269 char c;
271 /* Find the spelling of the operand. */
272 start = input_line_pointer;
273 c = get_symbol_name (&name);
274 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
276 /* Put back the delimiting char. */
277 (void) restore_line_pointer (c);
279 /* Look to see if it's in the register table. */
280 if (reg_number >= 0)
282 expressionP->X_op = O_register;
283 expressionP->X_add_number = reg_number;
285 /* Make the rest nice. */
286 expressionP->X_add_symbol = NULL;
287 expressionP->X_op_symbol = NULL;
289 return TRUE;
292 /* Reset the line as if we had not done anything. */
293 input_line_pointer = start;
294 return FALSE;
297 void
298 md_show_usage (FILE *stream)
300 fprintf (stream, _("MN10200 options:\n\
301 none yet\n"));
305 md_parse_option (int c ATTRIBUTE_UNUSED,
306 const char *arg ATTRIBUTE_UNUSED)
308 return 0;
311 symbolS *
312 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
314 return 0;
317 const char *
318 md_atof (int type, char *litp, int *sizep)
320 return ieee_md_atof (type, litp, sizep, FALSE);
323 void
324 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
325 asection *sec,
326 fragS *fragP)
328 static unsigned long label_count = 0;
329 char buf[40];
331 subseg_change (sec, 0);
332 if (fragP->fr_subtype == 0)
334 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
335 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
336 fragP->fr_var = 0;
337 fragP->fr_fix += 2;
339 else if (fragP->fr_subtype == 1)
341 /* Reverse the condition of the first branch. */
342 int offset = fragP->fr_fix;
343 int opcode = fragP->fr_literal[offset] & 0xff;
345 switch (opcode)
347 case 0xe8:
348 opcode = 0xe9;
349 break;
350 case 0xe9:
351 opcode = 0xe8;
352 break;
353 case 0xe0:
354 opcode = 0xe2;
355 break;
356 case 0xe2:
357 opcode = 0xe0;
358 break;
359 case 0xe3:
360 opcode = 0xe1;
361 break;
362 case 0xe1:
363 opcode = 0xe3;
364 break;
365 case 0xe4:
366 opcode = 0xe6;
367 break;
368 case 0xe6:
369 opcode = 0xe4;
370 break;
371 case 0xe7:
372 opcode = 0xe5;
373 break;
374 case 0xe5:
375 opcode = 0xe7;
376 break;
377 default:
378 abort ();
380 fragP->fr_literal[offset] = opcode;
382 /* Create a fixup for the reversed conditional branch. */
383 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
384 fix_new (fragP, fragP->fr_fix + 1, 1,
385 symbol_new (buf, sec, 0, fragP->fr_next),
386 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
388 /* Now create the unconditional branch + fixup to the
389 final target. */
390 fragP->fr_literal[offset + 2] = 0xfc;
391 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
392 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
393 fragP->fr_var = 0;
394 fragP->fr_fix += 5;
396 else if (fragP->fr_subtype == 2)
398 /* Reverse the condition of the first branch. */
399 int offset = fragP->fr_fix;
400 int opcode = fragP->fr_literal[offset] & 0xff;
402 switch (opcode)
404 case 0xe8:
405 opcode = 0xe9;
406 break;
407 case 0xe9:
408 opcode = 0xe8;
409 break;
410 case 0xe0:
411 opcode = 0xe2;
412 break;
413 case 0xe2:
414 opcode = 0xe0;
415 break;
416 case 0xe3:
417 opcode = 0xe1;
418 break;
419 case 0xe1:
420 opcode = 0xe3;
421 break;
422 case 0xe4:
423 opcode = 0xe6;
424 break;
425 case 0xe6:
426 opcode = 0xe4;
427 break;
428 case 0xe7:
429 opcode = 0xe5;
430 break;
431 case 0xe5:
432 opcode = 0xe7;
433 break;
434 default:
435 abort ();
437 fragP->fr_literal[offset] = opcode;
439 /* Create a fixup for the reversed conditional branch. */
440 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
441 fix_new (fragP, fragP->fr_fix + 1, 1,
442 symbol_new (buf, sec, 0, fragP->fr_next),
443 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
445 /* Now create the unconditional branch + fixup to the
446 final target. */
447 fragP->fr_literal[offset + 2] = 0xf4;
448 fragP->fr_literal[offset + 3] = 0xe0;
449 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
450 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
451 fragP->fr_var = 0;
452 fragP->fr_fix += 7;
454 else if (fragP->fr_subtype == 3)
456 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
457 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
458 fragP->fr_var = 0;
459 fragP->fr_fix += 3;
461 else if (fragP->fr_subtype == 4)
463 /* Reverse the condition of the first branch. */
464 int offset = fragP->fr_fix;
465 int opcode = fragP->fr_literal[offset + 1] & 0xff;
467 switch (opcode)
469 case 0xfc:
470 opcode = 0xfd;
471 break;
472 case 0xfd:
473 opcode = 0xfc;
474 break;
475 case 0xfe:
476 opcode = 0xff;
477 break;
478 case 0xff:
479 opcode = 0xfe;
480 break;
481 case 0xe8:
482 opcode = 0xe9;
483 break;
484 case 0xe9:
485 opcode = 0xe8;
486 break;
487 case 0xe0:
488 opcode = 0xe2;
489 break;
490 case 0xe2:
491 opcode = 0xe0;
492 break;
493 case 0xe3:
494 opcode = 0xe1;
495 break;
496 case 0xe1:
497 opcode = 0xe3;
498 break;
499 case 0xe4:
500 opcode = 0xe6;
501 break;
502 case 0xe6:
503 opcode = 0xe4;
504 break;
505 case 0xe7:
506 opcode = 0xe5;
507 break;
508 case 0xe5:
509 opcode = 0xe7;
510 break;
511 case 0xec:
512 opcode = 0xed;
513 break;
514 case 0xed:
515 opcode = 0xec;
516 break;
517 case 0xee:
518 opcode = 0xef;
519 break;
520 case 0xef:
521 opcode = 0xee;
522 break;
523 default:
524 abort ();
526 fragP->fr_literal[offset + 1] = opcode;
528 /* Create a fixup for the reversed conditional branch. */
529 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
530 fix_new (fragP, fragP->fr_fix + 2, 1,
531 symbol_new (buf, sec, 0, fragP->fr_next),
532 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
534 /* Now create the unconditional branch + fixup to the
535 final target. */
536 fragP->fr_literal[offset + 3] = 0xfc;
537 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
538 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
539 fragP->fr_var = 0;
540 fragP->fr_fix += 6;
542 else if (fragP->fr_subtype == 5)
544 /* Reverse the condition of the first branch. */
545 int offset = fragP->fr_fix;
546 int opcode = fragP->fr_literal[offset + 1] & 0xff;
548 switch (opcode)
550 case 0xfc:
551 opcode = 0xfd;
552 break;
553 case 0xfd:
554 opcode = 0xfc;
555 break;
556 case 0xfe:
557 opcode = 0xff;
558 break;
559 case 0xff:
560 opcode = 0xfe;
561 break;
562 case 0xe8:
563 opcode = 0xe9;
564 break;
565 case 0xe9:
566 opcode = 0xe8;
567 break;
568 case 0xe0:
569 opcode = 0xe2;
570 break;
571 case 0xe2:
572 opcode = 0xe0;
573 break;
574 case 0xe3:
575 opcode = 0xe1;
576 break;
577 case 0xe1:
578 opcode = 0xe3;
579 break;
580 case 0xe4:
581 opcode = 0xe6;
582 break;
583 case 0xe6:
584 opcode = 0xe4;
585 break;
586 case 0xe7:
587 opcode = 0xe5;
588 break;
589 case 0xe5:
590 opcode = 0xe7;
591 break;
592 case 0xec:
593 opcode = 0xed;
594 break;
595 case 0xed:
596 opcode = 0xec;
597 break;
598 case 0xee:
599 opcode = 0xef;
600 break;
601 case 0xef:
602 opcode = 0xee;
603 break;
604 default:
605 abort ();
607 fragP->fr_literal[offset + 1] = opcode;
609 /* Create a fixup for the reversed conditional branch. */
610 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
611 fix_new (fragP, fragP->fr_fix + 2, 1,
612 symbol_new (buf, sec, 0, fragP->fr_next),
613 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
615 /* Now create the unconditional branch + fixup to the
616 final target. */
617 fragP->fr_literal[offset + 3] = 0xf4;
618 fragP->fr_literal[offset + 4] = 0xe0;
619 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
620 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
621 fragP->fr_var = 0;
622 fragP->fr_fix += 8;
624 else if (fragP->fr_subtype == 6)
626 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
627 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
628 fragP->fr_var = 0;
629 fragP->fr_fix += 3;
631 else if (fragP->fr_subtype == 7)
633 int offset = fragP->fr_fix;
634 fragP->fr_literal[offset] = 0xf4;
635 fragP->fr_literal[offset + 1] = 0xe1;
637 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
638 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
639 fragP->fr_var = 0;
640 fragP->fr_fix += 5;
642 else if (fragP->fr_subtype == 8)
644 fragP->fr_literal[fragP->fr_fix] = 0xea;
645 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
646 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
647 fragP->fr_var = 0;
648 fragP->fr_fix += 2;
650 else if (fragP->fr_subtype == 9)
652 int offset = fragP->fr_fix;
653 fragP->fr_literal[offset] = 0xfc;
655 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
656 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
657 fragP->fr_var = 0;
658 fragP->fr_fix += 3;
660 else if (fragP->fr_subtype == 10)
662 int offset = fragP->fr_fix;
663 fragP->fr_literal[offset] = 0xf4;
664 fragP->fr_literal[offset + 1] = 0xe0;
666 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
667 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
668 fragP->fr_var = 0;
669 fragP->fr_fix += 5;
671 else
672 abort ();
675 valueT
676 md_section_align (asection *seg, valueT addr)
678 int align = bfd_get_section_alignment (stdoutput, seg);
679 return ((addr + (1 << align) - 1) & -(1 << align));
682 void
683 md_begin (void)
685 const char *prev_name = "";
686 const struct mn10200_opcode *op;
688 mn10200_hash = hash_new ();
690 /* Insert unique names into hash table. The MN10200 instruction set
691 has many identical opcode names that have different opcodes based
692 on the operands. This hash table then provides a quick index to
693 the first opcode with a particular name in the opcode table. */
695 op = mn10200_opcodes;
696 while (op->name)
698 if (strcmp (prev_name, op->name))
700 prev_name = (char *) op->name;
701 hash_insert (mn10200_hash, op->name, (char *) op);
703 op++;
706 /* This is both a simplification (we don't have to write md_apply_fix)
707 and support for future optimizations (branch shortening and similar
708 stuff in the linker. */
709 linkrelax = 1;
712 static unsigned long
713 check_operand (unsigned long insn ATTRIBUTE_UNUSED,
714 const struct mn10200_operand *operand,
715 offsetT val)
717 /* No need to check 24bit or 32bit operands for a bit. */
718 if (operand->bits < 24
719 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
721 long min, max;
722 offsetT test;
724 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
726 max = (1 << (operand->bits - 1)) - 1;
727 min = - (1 << (operand->bits - 1));
729 else
731 max = (1 << operand->bits) - 1;
732 min = 0;
735 test = val;
737 if (test < (offsetT) min || test > (offsetT) max)
738 return 0;
739 else
740 return 1;
742 return 1;
744 /* If while processing a fixup, a reloc really needs to be created
745 Then it is done here. */
747 arelent *
748 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
750 arelent *reloc;
751 reloc = XNEW (arelent);
753 if (fixp->fx_subsy != NULL)
755 if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
756 && S_IS_DEFINED (fixp->fx_subsy))
758 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
759 fixp->fx_subsy = NULL;
761 else
762 /* FIXME: We should try more ways to resolve difference expressions
763 here. At least this is better than silently ignoring the
764 subtrahend. */
765 as_bad_where (fixp->fx_file, fixp->fx_line,
766 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
767 fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
768 segment_name (fixp->fx_addsy
769 ? S_GET_SEGMENT (fixp->fx_addsy)
770 : absolute_section),
771 S_GET_NAME (fixp->fx_subsy),
772 segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
775 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
776 if (reloc->howto == NULL)
778 as_bad_where (fixp->fx_file, fixp->fx_line,
779 _("reloc %d not supported by object file format"),
780 (int) fixp->fx_r_type);
781 return NULL;
783 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
784 reloc->sym_ptr_ptr = XNEW (asymbol *);
785 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
786 reloc->addend = fixp->fx_offset;
787 return reloc;
791 md_estimate_size_before_relax (fragS *fragp, asection *seg)
793 if (fragp->fr_subtype == 6
794 && (!S_IS_DEFINED (fragp->fr_symbol)
795 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
796 fragp->fr_subtype = 7;
797 else if (fragp->fr_subtype == 8
798 && (!S_IS_DEFINED (fragp->fr_symbol)
799 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
800 fragp->fr_subtype = 10;
802 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
803 abort ();
805 return md_relax_table[fragp->fr_subtype].rlx_length;
808 long
809 md_pcrel_from (fixS *fixp)
811 return fixp->fx_frag->fr_address;
814 void
815 md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
817 /* We shouldn't ever get here because linkrelax is nonzero. */
818 abort ();
819 fixP->fx_done = 1;
822 /* Insert an operand value into an instruction. */
824 static void
825 mn10200_insert_operand (unsigned long *insnp,
826 unsigned long *extensionp,
827 const struct mn10200_operand *operand,
828 offsetT val,
829 char *file,
830 unsigned int line,
831 unsigned int shift)
833 /* No need to check 24 or 32bit operands for a bit. */
834 if (operand->bits < 24
835 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
837 long min, max;
838 offsetT test;
840 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
842 max = (1 << (operand->bits - 1)) - 1;
843 min = - (1 << (operand->bits - 1));
845 else
847 max = (1 << operand->bits) - 1;
848 min = 0;
851 test = val;
853 if (test < (offsetT) min || test > (offsetT) max)
854 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
857 if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
859 *insnp |= (((long) val & ((1 << operand->bits) - 1))
860 << (operand->shift + shift));
862 if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
863 *insnp |= (((long) val & ((1 << operand->bits) - 1))
864 << (operand->shift + shift + 2));
866 else
868 *extensionp |= (val >> 16) & 0xff;
869 *insnp |= val & 0xffff;
873 void
874 md_assemble (char *str)
876 char *s;
877 struct mn10200_opcode *opcode;
878 struct mn10200_opcode *next_opcode;
879 const unsigned char *opindex_ptr;
880 int next_opindex, relaxable;
881 unsigned long insn, extension, size = 0;
882 char *f;
883 int i;
884 int match;
886 /* Get the opcode. */
887 for (s = str; *s != '\0' && !ISSPACE (*s); s++)
889 if (*s != '\0')
890 *s++ = '\0';
892 /* Find the first opcode with the proper name. */
893 opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
894 if (opcode == NULL)
896 as_bad (_("Unrecognized opcode: `%s'"), str);
897 return;
900 str = s;
901 while (ISSPACE (*str))
902 ++str;
904 input_line_pointer = str;
906 for (;;)
908 const char *errmsg = NULL;
909 int op_idx;
910 char *hold;
911 int extra_shift = 0;
913 relaxable = 0;
914 fc = 0;
915 match = 0;
916 next_opindex = 0;
917 insn = opcode->opcode;
918 extension = 0;
919 for (op_idx = 1, opindex_ptr = opcode->operands;
920 *opindex_ptr != 0;
921 opindex_ptr++, op_idx++)
923 const struct mn10200_operand *operand;
924 expressionS ex;
926 if (next_opindex == 0)
928 operand = &mn10200_operands[*opindex_ptr];
930 else
932 operand = &mn10200_operands[next_opindex];
933 next_opindex = 0;
936 errmsg = NULL;
938 while (*str == ' ' || *str == ',')
939 ++str;
941 if (operand->flags & MN10200_OPERAND_RELAX)
942 relaxable = 1;
944 /* Gather the operand. */
945 hold = input_line_pointer;
946 input_line_pointer = str;
948 if (operand->flags & MN10200_OPERAND_PAREN)
950 if (*input_line_pointer != ')' && *input_line_pointer != '(')
952 input_line_pointer = hold;
953 str = hold;
954 goto error;
956 input_line_pointer++;
957 goto keep_going;
959 /* See if we can match the operands. */
960 else if (operand->flags & MN10200_OPERAND_DREG)
962 if (!data_register_name (&ex))
964 input_line_pointer = hold;
965 str = hold;
966 goto error;
969 else if (operand->flags & MN10200_OPERAND_AREG)
971 if (!address_register_name (&ex))
973 input_line_pointer = hold;
974 str = hold;
975 goto error;
978 else if (operand->flags & MN10200_OPERAND_PSW)
980 char *start;
981 char c = get_symbol_name (&start);
983 if (strcmp (start, "psw") != 0)
985 (void) restore_line_pointer (c);
986 input_line_pointer = hold;
987 str = hold;
988 goto error;
990 (void) restore_line_pointer (c);
991 goto keep_going;
993 else if (operand->flags & MN10200_OPERAND_MDR)
995 char *start;
996 char c = get_symbol_name (&start);
998 if (strcmp (start, "mdr") != 0)
1000 (void) restore_line_pointer (c);
1001 input_line_pointer = hold;
1002 str = hold;
1003 goto error;
1005 (void) restore_line_pointer (c);
1006 goto keep_going;
1008 else if (data_register_name (&ex))
1010 input_line_pointer = hold;
1011 str = hold;
1012 goto error;
1014 else if (address_register_name (&ex))
1016 input_line_pointer = hold;
1017 str = hold;
1018 goto error;
1020 else if (other_register_name (&ex))
1022 input_line_pointer = hold;
1023 str = hold;
1024 goto error;
1026 else if (*str == ')' || *str == '(')
1028 input_line_pointer = hold;
1029 str = hold;
1030 goto error;
1032 else
1034 expression (&ex);
1037 switch (ex.X_op)
1039 case O_illegal:
1040 errmsg = _("illegal operand");
1041 goto error;
1042 case O_absent:
1043 errmsg = _("missing operand");
1044 goto error;
1045 case O_register:
1046 if ((operand->flags
1047 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
1049 input_line_pointer = hold;
1050 str = hold;
1051 goto error;
1054 if (opcode->format == FMT_2 || opcode->format == FMT_5)
1055 extra_shift = 8;
1056 else if (opcode->format == FMT_3 || opcode->format == FMT_6
1057 || opcode->format == FMT_7)
1058 extra_shift = 16;
1059 else
1060 extra_shift = 0;
1062 mn10200_insert_operand (&insn, &extension, operand,
1063 ex.X_add_number, NULL,
1064 0, extra_shift);
1066 break;
1068 case O_constant:
1069 /* If this operand can be promoted, and it doesn't
1070 fit into the allocated bitfield for this insn,
1071 then promote it (ie this opcode does not match). */
1072 if (operand->flags
1073 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
1074 && !check_operand (insn, operand, ex.X_add_number))
1076 input_line_pointer = hold;
1077 str = hold;
1078 goto error;
1081 mn10200_insert_operand (&insn, &extension, operand,
1082 ex.X_add_number, NULL,
1083 0, 0);
1084 break;
1086 default:
1087 /* If this operand can be promoted, then this opcode didn't
1088 match since we can't know if it needed promotion! */
1089 if (operand->flags & MN10200_OPERAND_PROMOTE)
1091 input_line_pointer = hold;
1092 str = hold;
1093 goto error;
1096 /* We need to generate a fixup for this expression. */
1097 if (fc >= MAX_INSN_FIXUPS)
1098 as_fatal (_("too many fixups"));
1099 fixups[fc].exp = ex;
1100 fixups[fc].opindex = *opindex_ptr;
1101 fixups[fc].reloc = BFD_RELOC_UNUSED;
1102 ++fc;
1103 break;
1106 keep_going:
1107 str = input_line_pointer;
1108 input_line_pointer = hold;
1110 while (*str == ' ' || *str == ',')
1111 ++str;
1115 /* Make sure we used all the operands! */
1116 if (*str != ',')
1117 match = 1;
1119 error:
1120 if (match == 0)
1122 next_opcode = opcode + 1;
1123 if (!strcmp (next_opcode->name, opcode->name))
1125 opcode = next_opcode;
1126 continue;
1129 as_bad ("%s", errmsg);
1130 return;
1132 break;
1135 while (ISSPACE (*str))
1136 ++str;
1138 if (*str != '\0')
1139 as_bad (_("junk at end of line: `%s'"), str);
1141 input_line_pointer = str;
1143 if (opcode->format == FMT_1)
1144 size = 1;
1145 else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1146 size = 2;
1147 else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1148 size = 3;
1149 else if (opcode->format == FMT_6)
1150 size = 4;
1151 else if (opcode->format == FMT_7)
1152 size = 5;
1153 else
1154 abort ();
1156 /* Write out the instruction. */
1157 dwarf2_emit_insn (size);
1158 if (relaxable && fc > 0)
1160 /* On a 64-bit host the size of an 'int' is not the same
1161 as the size of a pointer, so we need a union to convert
1162 the opindex field of the fr_cgen structure into a char *
1163 so that it can be stored in the frag. We do not have
1164 to worry about losing accuracy as we are not going to
1165 be even close to the 32bit limit of the int. */
1166 union
1168 int opindex;
1169 char * ptr;
1171 opindex_converter;
1172 int type;
1174 /* bCC */
1175 if (size == 2 && opcode->opcode != 0xfc0000)
1177 /* Handle bra specially. Basically treat it like jmp so
1178 that we automatically handle 8, 16 and 32 bit offsets
1179 correctly as well as jumps to an undefined address.
1181 It is also important to not treat it like other bCC
1182 instructions since the long forms of bra is different
1183 from other bCC instructions. */
1184 if (opcode->opcode == 0xea00)
1185 type = 8;
1186 else
1187 type = 0;
1189 /* jsr */
1190 else if (size == 3 && opcode->opcode == 0xfd0000)
1191 type = 6;
1192 /* jmp */
1193 else if (size == 3 && opcode->opcode == 0xfc0000)
1194 type = 8;
1195 /* bCCx */
1196 else
1197 type = 3;
1199 opindex_converter.opindex = fixups[0].opindex;
1200 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1201 fixups[0].exp.X_add_symbol,
1202 fixups[0].exp.X_add_number,
1203 opindex_converter.ptr);
1204 number_to_chars_bigendian (f, insn, size);
1205 if (8 - size > 4)
1207 number_to_chars_bigendian (f + size, 0, 4);
1208 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1210 else
1211 number_to_chars_bigendian (f + size, 0, 8 - size);
1213 else
1215 f = frag_more (size);
1217 /* Oh, what a mess. The instruction is in big endian format, but
1218 16 and 24bit immediates are little endian! */
1219 if (opcode->format == FMT_3)
1221 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1222 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1224 else if (opcode->format == FMT_6)
1226 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1227 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1229 else if (opcode->format == FMT_7)
1231 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1232 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1233 number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1235 else
1236 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1238 /* Create any fixups. */
1239 for (i = 0; i < fc; i++)
1241 const struct mn10200_operand *operand;
1242 int reloc_size;
1244 operand = &mn10200_operands[fixups[i].opindex];
1245 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1247 reloc_howto_type *reloc_howto;
1248 int offset;
1249 fixS *fixP;
1251 reloc_howto = bfd_reloc_type_lookup (stdoutput,
1252 fixups[i].reloc);
1254 if (!reloc_howto)
1255 abort ();
1257 reloc_size = bfd_get_reloc_size (reloc_howto);
1259 if (reloc_size < 1 || reloc_size > 4)
1260 abort ();
1262 offset = 4 - reloc_size;
1263 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1264 reloc_size,
1265 &fixups[i].exp,
1266 reloc_howto->pc_relative,
1267 fixups[i].reloc);
1269 /* PC-relative offsets are from the first byte of the
1270 next instruction, not from the start of the current
1271 instruction. */
1272 if (reloc_howto->pc_relative)
1273 fixP->fx_offset += reloc_size;
1275 else
1277 int reloc, pcrel, offset;
1278 fixS *fixP;
1280 reloc = BFD_RELOC_NONE;
1281 /* How big is the reloc? Remember SPLIT relocs are
1282 implicitly 32bits. */
1283 reloc_size = operand->bits;
1285 offset = size - reloc_size / 8;
1287 /* Is the reloc pc-relative? */
1288 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1290 /* Choose a proper BFD relocation type. */
1291 if (pcrel)
1293 if (reloc_size == 8)
1294 reloc = BFD_RELOC_8_PCREL;
1295 else if (reloc_size == 24)
1296 reloc = BFD_RELOC_24_PCREL;
1297 else
1298 abort ();
1300 else
1302 if (reloc_size == 32)
1303 reloc = BFD_RELOC_32;
1304 else if (reloc_size == 16)
1305 reloc = BFD_RELOC_16;
1306 else if (reloc_size == 8)
1307 reloc = BFD_RELOC_8;
1308 else if (reloc_size == 24)
1309 reloc = BFD_RELOC_24;
1310 else
1311 abort ();
1314 /* Convert the size of the reloc into what fix_new_exp
1315 wants. */
1316 reloc_size = reloc_size / 8;
1317 if (reloc_size == 8)
1318 reloc_size = 0;
1319 else if (reloc_size == 16)
1320 reloc_size = 1;
1321 else if (reloc_size == 32 || reloc_size == 24)
1322 reloc_size = 2;
1324 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1325 reloc_size, &fixups[i].exp, pcrel,
1326 ((bfd_reloc_code_real_type) reloc));
1328 /* PC-relative offsets are from the first byte of the
1329 next instruction, not from the start of the current
1330 instruction. */
1331 if (pcrel)
1332 fixP->fx_offset += size;