ld/testsuite/
[binutils.git] / gas / config / tc-mn10200.c
blob9eecf47ea58aeb4cb34b6b42485300b297e659b7
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #include "as.h"
23 #include "safe-ctype.h"
24 #include "subsegs.h"
25 #include "opcode/mn10200.h"
27 /* Structure to hold information about predefined registers. */
28 struct reg_name
30 const char *name;
31 int value;
34 /* Generic assembler global variables which must be defined by all
35 targets. */
37 /* Characters which always start a comment. */
38 const char comment_chars[] = "#";
40 /* Characters which start a comment at the beginning of a line. */
41 const char line_comment_chars[] = ";#";
43 /* Characters which may be used to separate multiple commands on a
44 single line. */
45 const char line_separator_chars[] = ";";
47 /* Characters which are used to indicate an exponent in a floating
48 point number. */
49 const char EXP_CHARS[] = "eE";
51 /* Characters which mean that a number is a floating point constant,
52 as in 0d1.0. */
53 const char FLT_CHARS[] = "dD";
55 const relax_typeS md_relax_table[] =
57 /* bCC relaxing */
58 {0x81, -0x7e, 2, 1},
59 {0x8004, -0x7ffb, 5, 2},
60 {0x800006, -0x7ffff9, 7, 0},
61 /* bCCx relaxing */
62 {0x81, -0x7e, 3, 4},
63 {0x8004, -0x7ffb, 6, 5},
64 {0x800006, -0x7ffff9, 8, 0},
65 /* jsr relaxing */
66 {0x8004, -0x7ffb, 3, 7},
67 {0x800006, -0x7ffff9, 5, 0},
68 /* jmp relaxing */
69 {0x81, -0x7e, 2, 9},
70 {0x8004, -0x7ffb, 3, 10},
71 {0x800006, -0x7ffff9, 5, 0},
76 /* Fixups. */
77 #define MAX_INSN_FIXUPS 5
79 struct mn10200_fixup
81 expressionS exp;
82 int opindex;
83 bfd_reloc_code_real_type reloc;
86 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
87 static int fc;
89 const char *md_shortopts = "";
91 struct option md_longopts[] =
93 {NULL, no_argument, NULL, 0}
96 size_t md_longopts_size = sizeof (md_longopts);
98 /* The target specific pseudo-ops which we support. */
99 const pseudo_typeS md_pseudo_table[] =
101 { NULL, NULL, 0 }
104 /* Opcode hash table. */
105 static struct hash_control *mn10200_hash;
107 /* This table is sorted. Suitable for searching by a binary search. */
108 static const struct reg_name data_registers[] =
110 { "d0", 0 },
111 { "d1", 1 },
112 { "d2", 2 },
113 { "d3", 3 },
115 #define DATA_REG_NAME_CNT \
116 (sizeof (data_registers) / sizeof (struct reg_name))
118 static const struct reg_name address_registers[] =
120 { "a0", 0 },
121 { "a1", 1 },
122 { "a2", 2 },
123 { "a3", 3 },
125 #define ADDRESS_REG_NAME_CNT \
126 (sizeof (address_registers) / sizeof (struct reg_name))
128 static const struct reg_name other_registers[] =
130 { "mdr", 0 },
131 { "psw", 0 },
133 #define OTHER_REG_NAME_CNT \
134 (sizeof (other_registers) / sizeof (struct reg_name))
136 /* reg_name_search does a binary search of the given register table
137 to see if "name" is a valid regiter name. Returns the register
138 number from the array on success, or -1 on failure. */
140 static int
141 reg_name_search (const struct reg_name *regs,
142 int regcount,
143 const char *name)
145 int middle, low, high;
146 int cmp;
148 low = 0;
149 high = regcount - 1;
153 middle = (low + high) / 2;
154 cmp = strcasecmp (name, regs[middle].name);
155 if (cmp < 0)
156 high = middle - 1;
157 else if (cmp > 0)
158 low = middle + 1;
159 else
160 return regs[middle].value;
162 while (low <= high);
163 return -1;
166 /* Summary of register_name().
168 in: Input_line_pointer points to 1st char of operand.
170 out: An expressionS.
171 The operand may have been a register: in this case, X_op == O_register,
172 X_add_number is set to the register number, and truth is returned.
173 Input_line_pointer->(next non-blank) char after operand, or is in
174 its original state. */
176 static bfd_boolean
177 data_register_name (expressionS *expressionP)
179 int reg_number;
180 char *name;
181 char *start;
182 char c;
184 /* Find the spelling of the operand. */
185 start = name = input_line_pointer;
187 c = get_symbol_end ();
188 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
190 /* Put back the delimiting char. */
191 *input_line_pointer = c;
193 /* Look to see if it's in the register table. */
194 if (reg_number >= 0)
196 expressionP->X_op = O_register;
197 expressionP->X_add_number = reg_number;
199 /* Make the rest nice. */
200 expressionP->X_add_symbol = NULL;
201 expressionP->X_op_symbol = NULL;
203 return TRUE;
206 /* Reset the line as if we had not done anything. */
207 input_line_pointer = start;
208 return FALSE;
211 /* Summary of register_name().
213 in: Input_line_pointer points to 1st char of operand.
215 out: An expressionS.
216 The operand may have been a register: in this case, X_op == O_register,
217 X_add_number is set to the register number, and truth is returned.
218 Input_line_pointer->(next non-blank) char after operand, or is in
219 its original state. */
221 static bfd_boolean
222 address_register_name (expressionS *expressionP)
224 int reg_number;
225 char *name;
226 char *start;
227 char c;
229 /* Find the spelling of the operand. */
230 start = name = input_line_pointer;
232 c = get_symbol_end ();
233 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
235 /* Put back the delimiting char. */
236 *input_line_pointer = c;
238 /* Look to see if it's in the register table. */
239 if (reg_number >= 0)
241 expressionP->X_op = O_register;
242 expressionP->X_add_number = reg_number;
244 /* Make the rest nice. */
245 expressionP->X_add_symbol = NULL;
246 expressionP->X_op_symbol = NULL;
248 return TRUE;
251 /* Reset the line as if we had not done anything. */
252 input_line_pointer = start;
253 return FALSE;
256 /* Summary of register_name().
258 in: Input_line_pointer points to 1st char of operand.
260 out: An expressionS.
261 The operand may have been a register: in this case, X_op == O_register,
262 X_add_number is set to the register number, and truth is returned.
263 Input_line_pointer->(next non-blank) char after operand, or is in
264 its original state. */
266 static bfd_boolean
267 other_register_name (expressionS *expressionP)
269 int reg_number;
270 char *name;
271 char *start;
272 char c;
274 /* Find the spelling of the operand. */
275 start = name = input_line_pointer;
277 c = get_symbol_end ();
278 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
280 /* Put back the delimiting char. */
281 *input_line_pointer = c;
283 /* Look to see if it's in the register table. */
284 if (reg_number >= 0)
286 expressionP->X_op = O_register;
287 expressionP->X_add_number = reg_number;
289 /* Make the rest nice. */
290 expressionP->X_add_symbol = NULL;
291 expressionP->X_op_symbol = NULL;
293 return TRUE;
296 /* Reset the line as if we had not done anything. */
297 input_line_pointer = start;
298 return FALSE;
301 void
302 md_show_usage (FILE *stream)
304 fprintf (stream, _("MN10200 options:\n\
305 none yet\n"));
309 md_parse_option (int c ATTRIBUTE_UNUSED,
310 char *arg ATTRIBUTE_UNUSED)
312 return 0;
315 symbolS *
316 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
318 return 0;
321 char *
322 md_atof (int type, char *litp, int *sizep)
324 int prec;
325 LITTLENUM_TYPE words[4];
326 char *t;
327 int i;
329 switch (type)
331 case 'f':
332 prec = 2;
333 break;
335 case 'd':
336 prec = 4;
337 break;
339 default:
340 *sizep = 0;
341 return _("bad call to md_atof");
344 t = atof_ieee (input_line_pointer, type, words);
345 if (t)
346 input_line_pointer = t;
348 *sizep = prec * 2;
350 for (i = prec - 1; i >= 0; i--)
352 md_number_to_chars (litp, (valueT) words[i], 2);
353 litp += 2;
356 return NULL;
359 void
360 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
361 asection *sec,
362 fragS *fragP)
364 static unsigned long label_count = 0;
365 char buf[40];
367 subseg_change (sec, 0);
368 if (fragP->fr_subtype == 0)
370 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
371 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
372 fragP->fr_var = 0;
373 fragP->fr_fix += 2;
375 else if (fragP->fr_subtype == 1)
377 /* Reverse the condition of the first branch. */
378 int offset = fragP->fr_fix;
379 int opcode = fragP->fr_literal[offset] & 0xff;
381 switch (opcode)
383 case 0xe8:
384 opcode = 0xe9;
385 break;
386 case 0xe9:
387 opcode = 0xe8;
388 break;
389 case 0xe0:
390 opcode = 0xe2;
391 break;
392 case 0xe2:
393 opcode = 0xe0;
394 break;
395 case 0xe3:
396 opcode = 0xe1;
397 break;
398 case 0xe1:
399 opcode = 0xe3;
400 break;
401 case 0xe4:
402 opcode = 0xe6;
403 break;
404 case 0xe6:
405 opcode = 0xe4;
406 break;
407 case 0xe7:
408 opcode = 0xe5;
409 break;
410 case 0xe5:
411 opcode = 0xe7;
412 break;
413 default:
414 abort ();
416 fragP->fr_literal[offset] = opcode;
418 /* Create a fixup for the reversed conditional branch. */
419 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
420 fix_new (fragP, fragP->fr_fix + 1, 1,
421 symbol_new (buf, sec, 0, fragP->fr_next),
422 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
424 /* Now create the unconditional branch + fixup to the
425 final target. */
426 fragP->fr_literal[offset + 2] = 0xfc;
427 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
428 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
429 fragP->fr_var = 0;
430 fragP->fr_fix += 5;
432 else if (fragP->fr_subtype == 2)
434 /* Reverse the condition of the first branch. */
435 int offset = fragP->fr_fix;
436 int opcode = fragP->fr_literal[offset] & 0xff;
438 switch (opcode)
440 case 0xe8:
441 opcode = 0xe9;
442 break;
443 case 0xe9:
444 opcode = 0xe8;
445 break;
446 case 0xe0:
447 opcode = 0xe2;
448 break;
449 case 0xe2:
450 opcode = 0xe0;
451 break;
452 case 0xe3:
453 opcode = 0xe1;
454 break;
455 case 0xe1:
456 opcode = 0xe3;
457 break;
458 case 0xe4:
459 opcode = 0xe6;
460 break;
461 case 0xe6:
462 opcode = 0xe4;
463 break;
464 case 0xe7:
465 opcode = 0xe5;
466 break;
467 case 0xe5:
468 opcode = 0xe7;
469 break;
470 default:
471 abort ();
473 fragP->fr_literal[offset] = opcode;
475 /* Create a fixup for the reversed conditional branch. */
476 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
477 fix_new (fragP, fragP->fr_fix + 1, 1,
478 symbol_new (buf, sec, 0, fragP->fr_next),
479 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
481 /* Now create the unconditional branch + fixup to the
482 final target. */
483 fragP->fr_literal[offset + 2] = 0xf4;
484 fragP->fr_literal[offset + 3] = 0xe0;
485 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
486 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
487 fragP->fr_var = 0;
488 fragP->fr_fix += 7;
490 else if (fragP->fr_subtype == 3)
492 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
493 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
494 fragP->fr_var = 0;
495 fragP->fr_fix += 3;
497 else if (fragP->fr_subtype == 4)
499 /* Reverse the condition of the first branch. */
500 int offset = fragP->fr_fix;
501 int opcode = fragP->fr_literal[offset + 1] & 0xff;
503 switch (opcode)
505 case 0xfc:
506 opcode = 0xfd;
507 break;
508 case 0xfd:
509 opcode = 0xfc;
510 break;
511 case 0xfe:
512 opcode = 0xff;
513 break;
514 case 0xff:
515 opcode = 0xfe;
516 case 0xe8:
517 opcode = 0xe9;
518 break;
519 case 0xe9:
520 opcode = 0xe8;
521 break;
522 case 0xe0:
523 opcode = 0xe2;
524 break;
525 case 0xe2:
526 opcode = 0xe0;
527 break;
528 case 0xe3:
529 opcode = 0xe1;
530 break;
531 case 0xe1:
532 opcode = 0xe3;
533 break;
534 case 0xe4:
535 opcode = 0xe6;
536 break;
537 case 0xe6:
538 opcode = 0xe4;
539 break;
540 case 0xe7:
541 opcode = 0xe5;
542 break;
543 case 0xe5:
544 opcode = 0xe7;
545 break;
546 case 0xec:
547 opcode = 0xed;
548 break;
549 case 0xed:
550 opcode = 0xec;
551 break;
552 case 0xee:
553 opcode = 0xef;
554 break;
555 case 0xef:
556 opcode = 0xee;
557 break;
558 default:
559 abort ();
561 fragP->fr_literal[offset + 1] = opcode;
563 /* Create a fixup for the reversed conditional branch. */
564 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
565 fix_new (fragP, fragP->fr_fix + 2, 1,
566 symbol_new (buf, sec, 0, fragP->fr_next),
567 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
569 /* Now create the unconditional branch + fixup to the
570 final target. */
571 fragP->fr_literal[offset + 3] = 0xfc;
572 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
573 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
574 fragP->fr_var = 0;
575 fragP->fr_fix += 6;
577 else if (fragP->fr_subtype == 5)
579 /* Reverse the condition of the first branch. */
580 int offset = fragP->fr_fix;
581 int opcode = fragP->fr_literal[offset + 1] & 0xff;
583 switch (opcode)
585 case 0xfc:
586 opcode = 0xfd;
587 break;
588 case 0xfd:
589 opcode = 0xfc;
590 break;
591 case 0xfe:
592 opcode = 0xff;
593 break;
594 case 0xff:
595 opcode = 0xfe;
596 case 0xe8:
597 opcode = 0xe9;
598 break;
599 case 0xe9:
600 opcode = 0xe8;
601 break;
602 case 0xe0:
603 opcode = 0xe2;
604 break;
605 case 0xe2:
606 opcode = 0xe0;
607 break;
608 case 0xe3:
609 opcode = 0xe1;
610 break;
611 case 0xe1:
612 opcode = 0xe3;
613 break;
614 case 0xe4:
615 opcode = 0xe6;
616 break;
617 case 0xe6:
618 opcode = 0xe4;
619 break;
620 case 0xe7:
621 opcode = 0xe5;
622 break;
623 case 0xe5:
624 opcode = 0xe7;
625 break;
626 case 0xec:
627 opcode = 0xed;
628 break;
629 case 0xed:
630 opcode = 0xec;
631 break;
632 case 0xee:
633 opcode = 0xef;
634 break;
635 case 0xef:
636 opcode = 0xee;
637 break;
638 default:
639 abort ();
641 fragP->fr_literal[offset + 1] = opcode;
643 /* Create a fixup for the reversed conditional branch. */
644 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
645 fix_new (fragP, fragP->fr_fix + 2, 1,
646 symbol_new (buf, sec, 0, fragP->fr_next),
647 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
649 /* Now create the unconditional branch + fixup to the
650 final target. */
651 fragP->fr_literal[offset + 3] = 0xf4;
652 fragP->fr_literal[offset + 4] = 0xe0;
653 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
654 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
655 fragP->fr_var = 0;
656 fragP->fr_fix += 8;
658 else if (fragP->fr_subtype == 6)
660 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
661 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
662 fragP->fr_var = 0;
663 fragP->fr_fix += 3;
665 else if (fragP->fr_subtype == 7)
667 int offset = fragP->fr_fix;
668 fragP->fr_literal[offset] = 0xf4;
669 fragP->fr_literal[offset + 1] = 0xe1;
671 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
672 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
673 fragP->fr_var = 0;
674 fragP->fr_fix += 5;
676 else if (fragP->fr_subtype == 8)
678 fragP->fr_literal[fragP->fr_fix] = 0xea;
679 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
680 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
681 fragP->fr_var = 0;
682 fragP->fr_fix += 2;
684 else if (fragP->fr_subtype == 9)
686 int offset = fragP->fr_fix;
687 fragP->fr_literal[offset] = 0xfc;
689 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
690 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
691 fragP->fr_var = 0;
692 fragP->fr_fix += 3;
694 else if (fragP->fr_subtype == 10)
696 int offset = fragP->fr_fix;
697 fragP->fr_literal[offset] = 0xf4;
698 fragP->fr_literal[offset + 1] = 0xe0;
700 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
701 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
702 fragP->fr_var = 0;
703 fragP->fr_fix += 5;
705 else
706 abort ();
709 valueT
710 md_section_align (asection *seg, valueT addr)
712 int align = bfd_get_section_alignment (stdoutput, seg);
713 return ((addr + (1 << align) - 1) & (-1 << align));
716 void
717 md_begin (void)
719 char *prev_name = "";
720 register const struct mn10200_opcode *op;
722 mn10200_hash = hash_new ();
724 /* Insert unique names into hash table. The MN10200 instruction set
725 has many identical opcode names that have different opcodes based
726 on the operands. This hash table then provides a quick index to
727 the first opcode with a particular name in the opcode table. */
729 op = mn10200_opcodes;
730 while (op->name)
732 if (strcmp (prev_name, op->name))
734 prev_name = (char *) op->name;
735 hash_insert (mn10200_hash, op->name, (char *) op);
737 op++;
740 /* This is both a simplification (we don't have to write md_apply_fix)
741 and support for future optimizations (branch shortening and similar
742 stuff in the linker. */
743 linkrelax = 1;
746 static unsigned long
747 check_operand (unsigned long insn ATTRIBUTE_UNUSED,
748 const struct mn10200_operand *operand,
749 offsetT val)
751 /* No need to check 24bit or 32bit operands for a bit. */
752 if (operand->bits < 24
753 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
755 long min, max;
756 offsetT test;
758 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
760 max = (1 << (operand->bits - 1)) - 1;
761 min = - (1 << (operand->bits - 1));
763 else
765 max = (1 << operand->bits) - 1;
766 min = 0;
769 test = val;
771 if (test < (offsetT) min || test > (offsetT) max)
772 return 0;
773 else
774 return 1;
776 return 1;
778 /* If while processing a fixup, a reloc really needs to be created
779 Then it is done here. */
781 arelent *
782 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
784 arelent *reloc;
785 reloc = xmalloc (sizeof (arelent));
787 if (fixp->fx_subsy != NULL)
789 if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
790 && S_IS_DEFINED (fixp->fx_subsy))
792 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
793 fixp->fx_subsy = NULL;
795 else
796 /* FIXME: We should try more ways to resolve difference expressions
797 here. At least this is better than silently ignoring the
798 subtrahend. */
799 as_bad_where (fixp->fx_file, fixp->fx_line,
800 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
801 fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
802 segment_name (fixp->fx_addsy
803 ? S_GET_SEGMENT (fixp->fx_addsy)
804 : absolute_section),
805 S_GET_NAME (fixp->fx_subsy),
806 segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
809 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
810 if (reloc->howto == NULL)
812 as_bad_where (fixp->fx_file, fixp->fx_line,
813 _("reloc %d not supported by object file format"),
814 (int) fixp->fx_r_type);
815 return NULL;
817 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
818 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
819 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
820 reloc->addend = fixp->fx_offset;
821 return reloc;
825 md_estimate_size_before_relax (fragS *fragp, asection *seg)
827 if (fragp->fr_subtype == 6
828 && (!S_IS_DEFINED (fragp->fr_symbol)
829 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
830 fragp->fr_subtype = 7;
831 else if (fragp->fr_subtype == 8
832 && (!S_IS_DEFINED (fragp->fr_symbol)
833 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
834 fragp->fr_subtype = 10;
836 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
837 abort ();
839 return md_relax_table[fragp->fr_subtype].rlx_length;
842 long
843 md_pcrel_from (fixS *fixp)
845 return fixp->fx_frag->fr_address;
848 void
849 md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
851 /* We shouldn't ever get here because linkrelax is nonzero. */
852 abort ();
853 fixP->fx_done = 1;
856 /* Insert an operand value into an instruction. */
858 static void
859 mn10200_insert_operand (unsigned long *insnp,
860 unsigned long *extensionp,
861 const struct mn10200_operand *operand,
862 offsetT val,
863 char *file,
864 unsigned int line,
865 unsigned int shift)
867 /* No need to check 24 or 32bit operands for a bit. */
868 if (operand->bits < 24
869 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
871 long min, max;
872 offsetT test;
874 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
876 max = (1 << (operand->bits - 1)) - 1;
877 min = - (1 << (operand->bits - 1));
879 else
881 max = (1 << operand->bits) - 1;
882 min = 0;
885 test = val;
887 if (test < (offsetT) min || test > (offsetT) max)
888 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
891 if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
893 *insnp |= (((long) val & ((1 << operand->bits) - 1))
894 << (operand->shift + shift));
896 if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
897 *insnp |= (((long) val & ((1 << operand->bits) - 1))
898 << (operand->shift + shift + 2));
900 else
902 *extensionp |= (val >> 16) & 0xff;
903 *insnp |= val & 0xffff;
907 void
908 md_assemble (char *str)
910 char *s;
911 struct mn10200_opcode *opcode;
912 struct mn10200_opcode *next_opcode;
913 const unsigned char *opindex_ptr;
914 int next_opindex, relaxable;
915 unsigned long insn, extension, size = 0;
916 char *f;
917 int i;
918 int match;
920 /* Get the opcode. */
921 for (s = str; *s != '\0' && !ISSPACE (*s); s++)
923 if (*s != '\0')
924 *s++ = '\0';
926 /* Find the first opcode with the proper name. */
927 opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
928 if (opcode == NULL)
930 as_bad (_("Unrecognized opcode: `%s'"), str);
931 return;
934 str = s;
935 while (ISSPACE (*str))
936 ++str;
938 input_line_pointer = str;
940 for (;;)
942 const char *errmsg = NULL;
943 int op_idx;
944 char *hold;
945 int extra_shift = 0;
947 relaxable = 0;
948 fc = 0;
949 match = 0;
950 next_opindex = 0;
951 insn = opcode->opcode;
952 extension = 0;
953 for (op_idx = 1, opindex_ptr = opcode->operands;
954 *opindex_ptr != 0;
955 opindex_ptr++, op_idx++)
957 const struct mn10200_operand *operand;
958 expressionS ex;
960 if (next_opindex == 0)
962 operand = &mn10200_operands[*opindex_ptr];
964 else
966 operand = &mn10200_operands[next_opindex];
967 next_opindex = 0;
970 errmsg = NULL;
972 while (*str == ' ' || *str == ',')
973 ++str;
975 if (operand->flags & MN10200_OPERAND_RELAX)
976 relaxable = 1;
978 /* Gather the operand. */
979 hold = input_line_pointer;
980 input_line_pointer = str;
982 if (operand->flags & MN10200_OPERAND_PAREN)
984 if (*input_line_pointer != ')' && *input_line_pointer != '(')
986 input_line_pointer = hold;
987 str = hold;
988 goto error;
990 input_line_pointer++;
991 goto keep_going;
993 /* See if we can match the operands. */
994 else if (operand->flags & MN10200_OPERAND_DREG)
996 if (!data_register_name (&ex))
998 input_line_pointer = hold;
999 str = hold;
1000 goto error;
1003 else if (operand->flags & MN10200_OPERAND_AREG)
1005 if (!address_register_name (&ex))
1007 input_line_pointer = hold;
1008 str = hold;
1009 goto error;
1012 else if (operand->flags & MN10200_OPERAND_PSW)
1014 char *start = input_line_pointer;
1015 char c = get_symbol_end ();
1017 if (strcmp (start, "psw") != 0)
1019 *input_line_pointer = c;
1020 input_line_pointer = hold;
1021 str = hold;
1022 goto error;
1024 *input_line_pointer = c;
1025 goto keep_going;
1027 else if (operand->flags & MN10200_OPERAND_MDR)
1029 char *start = input_line_pointer;
1030 char c = get_symbol_end ();
1032 if (strcmp (start, "mdr") != 0)
1034 *input_line_pointer = c;
1035 input_line_pointer = hold;
1036 str = hold;
1037 goto error;
1039 *input_line_pointer = c;
1040 goto keep_going;
1042 else if (data_register_name (&ex))
1044 input_line_pointer = hold;
1045 str = hold;
1046 goto error;
1048 else if (address_register_name (&ex))
1050 input_line_pointer = hold;
1051 str = hold;
1052 goto error;
1054 else if (other_register_name (&ex))
1056 input_line_pointer = hold;
1057 str = hold;
1058 goto error;
1060 else if (*str == ')' || *str == '(')
1062 input_line_pointer = hold;
1063 str = hold;
1064 goto error;
1066 else
1068 expression (&ex);
1071 switch (ex.X_op)
1073 case O_illegal:
1074 errmsg = _("illegal operand");
1075 goto error;
1076 case O_absent:
1077 errmsg = _("missing operand");
1078 goto error;
1079 case O_register:
1080 if ((operand->flags
1081 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
1083 input_line_pointer = hold;
1084 str = hold;
1085 goto error;
1088 if (opcode->format == FMT_2 || opcode->format == FMT_5)
1089 extra_shift = 8;
1090 else if (opcode->format == FMT_3 || opcode->format == FMT_6
1091 || opcode->format == FMT_7)
1092 extra_shift = 16;
1093 else
1094 extra_shift = 0;
1096 mn10200_insert_operand (&insn, &extension, operand,
1097 ex.X_add_number, NULL,
1098 0, extra_shift);
1100 break;
1102 case O_constant:
1103 /* If this operand can be promoted, and it doesn't
1104 fit into the allocated bitfield for this insn,
1105 then promote it (ie this opcode does not match). */
1106 if (operand->flags
1107 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
1108 && !check_operand (insn, operand, ex.X_add_number))
1110 input_line_pointer = hold;
1111 str = hold;
1112 goto error;
1115 mn10200_insert_operand (&insn, &extension, operand,
1116 ex.X_add_number, NULL,
1117 0, 0);
1118 break;
1120 default:
1121 /* If this operand can be promoted, then this opcode didn't
1122 match since we can't know if it needed promotion! */
1123 if (operand->flags & MN10200_OPERAND_PROMOTE)
1125 input_line_pointer = hold;
1126 str = hold;
1127 goto error;
1130 /* We need to generate a fixup for this expression. */
1131 if (fc >= MAX_INSN_FIXUPS)
1132 as_fatal (_("too many fixups"));
1133 fixups[fc].exp = ex;
1134 fixups[fc].opindex = *opindex_ptr;
1135 fixups[fc].reloc = BFD_RELOC_UNUSED;
1136 ++fc;
1137 break;
1140 keep_going:
1141 str = input_line_pointer;
1142 input_line_pointer = hold;
1144 while (*str == ' ' || *str == ',')
1145 ++str;
1149 /* Make sure we used all the operands! */
1150 if (*str != ',')
1151 match = 1;
1153 error:
1154 if (match == 0)
1156 next_opcode = opcode + 1;
1157 if (!strcmp (next_opcode->name, opcode->name))
1159 opcode = next_opcode;
1160 continue;
1163 as_bad ("%s", errmsg);
1164 return;
1166 break;
1169 while (ISSPACE (*str))
1170 ++str;
1172 if (*str != '\0')
1173 as_bad (_("junk at end of line: `%s'"), str);
1175 input_line_pointer = str;
1177 if (opcode->format == FMT_1)
1178 size = 1;
1179 else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1180 size = 2;
1181 else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1182 size = 3;
1183 else if (opcode->format == FMT_6)
1184 size = 4;
1185 else if (opcode->format == FMT_7)
1186 size = 5;
1187 else
1188 abort ();
1190 /* Write out the instruction. */
1191 if (relaxable && fc > 0)
1193 /* On a 64-bit host the size of an 'int' is not the same
1194 as the size of a pointer, so we need a union to convert
1195 the opindex field of the fr_cgen structure into a char *
1196 so that it can be stored in the frag. We do not have
1197 to worry about loosing accuracy as we are not going to
1198 be even close to the 32bit limit of the int. */
1199 union
1201 int opindex;
1202 char * ptr;
1204 opindex_converter;
1205 int type;
1207 /* bCC */
1208 if (size == 2 && opcode->opcode != 0xfc0000)
1210 /* Handle bra specially. Basically treat it like jmp so
1211 that we automatically handle 8, 16 and 32 bit offsets
1212 correctly as well as jumps to an undefined address.
1214 It is also important to not treat it like other bCC
1215 instructions since the long forms of bra is different
1216 from other bCC instructions. */
1217 if (opcode->opcode == 0xea00)
1218 type = 8;
1219 else
1220 type = 0;
1222 /* jsr */
1223 else if (size == 3 && opcode->opcode == 0xfd0000)
1224 type = 6;
1225 /* jmp */
1226 else if (size == 3 && opcode->opcode == 0xfc0000)
1227 type = 8;
1228 /* bCCx */
1229 else
1230 type = 3;
1232 opindex_converter.opindex = fixups[0].opindex;
1233 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1234 fixups[0].exp.X_add_symbol,
1235 fixups[0].exp.X_add_number,
1236 opindex_converter.ptr);
1237 number_to_chars_bigendian (f, insn, size);
1238 if (8 - size > 4)
1240 number_to_chars_bigendian (f + size, 0, 4);
1241 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1243 else
1244 number_to_chars_bigendian (f + size, 0, 8 - size);
1246 else
1248 f = frag_more (size);
1250 /* Oh, what a mess. The instruction is in big endian format, but
1251 16 and 24bit immediates are little endian! */
1252 if (opcode->format == FMT_3)
1254 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1255 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1257 else if (opcode->format == FMT_6)
1259 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1260 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1262 else if (opcode->format == FMT_7)
1264 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1265 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1266 number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1268 else
1269 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1271 /* Create any fixups. */
1272 for (i = 0; i < fc; i++)
1274 const struct mn10200_operand *operand;
1276 operand = &mn10200_operands[fixups[i].opindex];
1277 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1279 reloc_howto_type *reloc_howto;
1280 int size;
1281 int offset;
1282 fixS *fixP;
1284 reloc_howto = bfd_reloc_type_lookup (stdoutput,
1285 fixups[i].reloc);
1287 if (!reloc_howto)
1288 abort ();
1290 size = bfd_get_reloc_size (reloc_howto);
1292 if (size < 1 || size > 4)
1293 abort ();
1295 offset = 4 - size;
1296 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1297 size,
1298 &fixups[i].exp,
1299 reloc_howto->pc_relative,
1300 fixups[i].reloc);
1302 /* PC-relative offsets are from the first byte of the
1303 next instruction, not from the start of the current
1304 instruction. */
1305 if (reloc_howto->pc_relative)
1306 fixP->fx_offset += size;
1308 else
1310 int reloc, pcrel, reloc_size, offset;
1311 fixS *fixP;
1313 reloc = BFD_RELOC_NONE;
1314 /* How big is the reloc? Remember SPLIT relocs are
1315 implicitly 32bits. */
1316 reloc_size = operand->bits;
1318 offset = size - reloc_size / 8;
1320 /* Is the reloc pc-relative? */
1321 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1323 /* Choose a proper BFD relocation type. */
1324 if (pcrel)
1326 if (reloc_size == 8)
1327 reloc = BFD_RELOC_8_PCREL;
1328 else if (reloc_size == 24)
1329 reloc = BFD_RELOC_24_PCREL;
1330 else
1331 abort ();
1333 else
1335 if (reloc_size == 32)
1336 reloc = BFD_RELOC_32;
1337 else if (reloc_size == 16)
1338 reloc = BFD_RELOC_16;
1339 else if (reloc_size == 8)
1340 reloc = BFD_RELOC_8;
1341 else if (reloc_size == 24)
1342 reloc = BFD_RELOC_24;
1343 else
1344 abort ();
1347 /* Convert the size of the reloc into what fix_new_exp
1348 wants. */
1349 reloc_size = reloc_size / 8;
1350 if (reloc_size == 8)
1351 reloc_size = 0;
1352 else if (reloc_size == 16)
1353 reloc_size = 1;
1354 else if (reloc_size == 32 || reloc_size == 24)
1355 reloc_size = 2;
1357 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1358 reloc_size, &fixups[i].exp, pcrel,
1359 ((bfd_reloc_code_real_type) reloc));
1361 /* PC-relative offsets are from the first byte of the
1362 next instruction, not from the start of the current
1363 instruction. */
1364 if (pcrel)
1365 fixP->fx_offset += size;