2004-06-29 H.J. Lu <hongjiu.lu@intel.com>
[binutils.git] / gas / config / tc-mn10200.c
blob64dd0992142081be82a950a3fe4c7599f6732e51
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <stdio.h>
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "subsegs.h"
26 #include "opcode/mn10200.h"
28 /* Structure to hold information about predefined registers. */
29 struct reg_name
31 const char *name;
32 int value;
35 /* Generic assembler global variables which must be defined by all
36 targets. */
38 /* Characters which always start a comment. */
39 const char comment_chars[] = "#";
41 /* Characters which start a comment at the beginning of a line. */
42 const char line_comment_chars[] = ";#";
44 /* Characters which may be used to separate multiple commands on a
45 single line. */
46 const char line_separator_chars[] = ";";
48 /* Characters which are used to indicate an exponent in a floating
49 point number. */
50 const char EXP_CHARS[] = "eE";
52 /* Characters which mean that a number is a floating point constant,
53 as in 0d1.0. */
54 const char FLT_CHARS[] = "dD";
56 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},
75 /* Local functions. */
76 static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *,
77 const struct mn10200_operand *,
78 offsetT, char *, unsigned,
79 unsigned));
80 static unsigned long check_operand PARAMS ((unsigned long,
81 const struct mn10200_operand *,
82 offsetT));
83 static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
84 static bfd_boolean data_register_name PARAMS ((expressionS *expressionP));
85 static bfd_boolean address_register_name PARAMS ((expressionS *expressionP));
86 static bfd_boolean other_register_name PARAMS ((expressionS *expressionP));
88 /* Fixups. */
89 #define MAX_INSN_FIXUPS (5)
90 struct mn10200_fixup
92 expressionS exp;
93 int opindex;
94 bfd_reloc_code_real_type reloc;
96 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
97 static int fc;
99 const char *md_shortopts = "";
100 struct option md_longopts[] = {
101 {NULL, no_argument, NULL, 0}
103 size_t md_longopts_size = sizeof (md_longopts);
105 /* The target specific pseudo-ops which we support. */
106 const pseudo_typeS md_pseudo_table[] =
108 { NULL, NULL, 0 }
111 /* Opcode hash table. */
112 static struct hash_control *mn10200_hash;
114 /* This table is sorted. Suitable for searching by a binary search. */
115 static const struct reg_name data_registers[] =
117 { "d0", 0 },
118 { "d1", 1 },
119 { "d2", 2 },
120 { "d3", 3 },
122 #define DATA_REG_NAME_CNT \
123 (sizeof (data_registers) / sizeof (struct reg_name))
125 static const struct reg_name address_registers[] =
127 { "a0", 0 },
128 { "a1", 1 },
129 { "a2", 2 },
130 { "a3", 3 },
132 #define ADDRESS_REG_NAME_CNT \
133 (sizeof (address_registers) / sizeof (struct reg_name))
135 static const struct reg_name other_registers[] =
137 { "mdr", 0 },
138 { "psw", 0 },
140 #define OTHER_REG_NAME_CNT \
141 (sizeof (other_registers) / sizeof (struct reg_name))
143 /* reg_name_search does a binary search of the given register table
144 to see if "name" is a valid regiter name. Returns the register
145 number from the array on success, or -1 on failure. */
147 static int
148 reg_name_search (regs, regcount, name)
149 const struct reg_name *regs;
150 int regcount;
151 const char *name;
153 int middle, low, high;
154 int cmp;
156 low = 0;
157 high = regcount - 1;
161 middle = (low + high) / 2;
162 cmp = strcasecmp (name, regs[middle].name);
163 if (cmp < 0)
164 high = middle - 1;
165 else if (cmp > 0)
166 low = middle + 1;
167 else
168 return regs[middle].value;
170 while (low <= high);
171 return -1;
174 /* Summary of register_name().
176 * in: Input_line_pointer points to 1st char of operand.
178 * out: An expressionS.
179 * The operand may have been a register: in this case, X_op == O_register,
180 * X_add_number is set to the register number, and truth is returned.
181 * Input_line_pointer->(next non-blank) char after operand, or is in
182 * its original state.
185 static bfd_boolean
186 data_register_name (expressionP)
187 expressionS *expressionP;
189 int reg_number;
190 char *name;
191 char *start;
192 char c;
194 /* Find the spelling of the operand. */
195 start = name = input_line_pointer;
197 c = get_symbol_end ();
198 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
200 /* Put back the delimiting char. */
201 *input_line_pointer = c;
203 /* Look to see if it's in the register table. */
204 if (reg_number >= 0)
206 expressionP->X_op = O_register;
207 expressionP->X_add_number = reg_number;
209 /* Make the rest nice. */
210 expressionP->X_add_symbol = NULL;
211 expressionP->X_op_symbol = NULL;
213 return TRUE;
216 /* Reset the line as if we had not done anything. */
217 input_line_pointer = start;
218 return FALSE;
221 /* Summary of register_name().
223 * in: Input_line_pointer points to 1st char of operand.
225 * out: An expressionS.
226 * The operand may have been a register: in this case, X_op == O_register,
227 * X_add_number is set to the register number, and truth is returned.
228 * Input_line_pointer->(next non-blank) char after operand, or is in
229 * its original state.
232 static bfd_boolean
233 address_register_name (expressionP)
234 expressionS *expressionP;
236 int reg_number;
237 char *name;
238 char *start;
239 char c;
241 /* Find the spelling of the operand. */
242 start = name = input_line_pointer;
244 c = get_symbol_end ();
245 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
247 /* Put back the delimiting char. */
248 *input_line_pointer = c;
250 /* Look to see if it's in the register table. */
251 if (reg_number >= 0)
253 expressionP->X_op = O_register;
254 expressionP->X_add_number = reg_number;
256 /* Make the rest nice. */
257 expressionP->X_add_symbol = NULL;
258 expressionP->X_op_symbol = NULL;
260 return TRUE;
263 /* Reset the line as if we had not done anything. */
264 input_line_pointer = start;
265 return FALSE;
268 /* Summary of register_name().
270 * in: Input_line_pointer points to 1st char of operand.
272 * out: An expressionS.
273 * The operand may have been a register: in this case, X_op == O_register,
274 * X_add_number is set to the register number, and truth is returned.
275 * Input_line_pointer->(next non-blank) char after operand, or is in
276 * its original state.
279 static bfd_boolean
280 other_register_name (expressionP)
281 expressionS *expressionP;
283 int reg_number;
284 char *name;
285 char *start;
286 char c;
288 /* Find the spelling of the operand. */
289 start = name = input_line_pointer;
291 c = get_symbol_end ();
292 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
294 /* Put back the delimiting char. */
295 *input_line_pointer = c;
297 /* Look to see if it's in the register table. */
298 if (reg_number >= 0)
300 expressionP->X_op = O_register;
301 expressionP->X_add_number = reg_number;
303 /* Make the rest nice. */
304 expressionP->X_add_symbol = NULL;
305 expressionP->X_op_symbol = NULL;
307 return TRUE;
310 /* Reset the line as if we had not done anything. */
311 input_line_pointer = start;
312 return FALSE;
315 void
316 md_show_usage (stream)
317 FILE *stream;
319 fprintf (stream, _("MN10200 options:\n\
320 none yet\n"));
324 md_parse_option (c, arg)
325 int c ATTRIBUTE_UNUSED;
326 char *arg ATTRIBUTE_UNUSED;
328 return 0;
331 symbolS *
332 md_undefined_symbol (name)
333 char *name ATTRIBUTE_UNUSED;
335 return 0;
338 char *
339 md_atof (type, litp, sizep)
340 int type;
341 char *litp;
342 int *sizep;
344 int prec;
345 LITTLENUM_TYPE words[4];
346 char *t;
347 int i;
349 switch (type)
351 case 'f':
352 prec = 2;
353 break;
355 case 'd':
356 prec = 4;
357 break;
359 default:
360 *sizep = 0;
361 return _("bad call to md_atof");
364 t = atof_ieee (input_line_pointer, type, words);
365 if (t)
366 input_line_pointer = t;
368 *sizep = prec * 2;
370 for (i = prec - 1; i >= 0; i--)
372 md_number_to_chars (litp, (valueT) words[i], 2);
373 litp += 2;
376 return NULL;
379 void
380 md_convert_frag (abfd, sec, fragP)
381 bfd *abfd ATTRIBUTE_UNUSED;
382 asection *sec;
383 fragS *fragP;
385 static unsigned long label_count = 0;
386 char buf[40];
388 subseg_change (sec, 0);
389 if (fragP->fr_subtype == 0)
391 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
392 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
393 fragP->fr_var = 0;
394 fragP->fr_fix += 2;
396 else if (fragP->fr_subtype == 1)
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] = 0xfc;
448 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
449 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
450 fragP->fr_var = 0;
451 fragP->fr_fix += 5;
453 else if (fragP->fr_subtype == 2)
455 /* Reverse the condition of the first branch. */
456 int offset = fragP->fr_fix;
457 int opcode = fragP->fr_literal[offset] & 0xff;
459 switch (opcode)
461 case 0xe8:
462 opcode = 0xe9;
463 break;
464 case 0xe9:
465 opcode = 0xe8;
466 break;
467 case 0xe0:
468 opcode = 0xe2;
469 break;
470 case 0xe2:
471 opcode = 0xe0;
472 break;
473 case 0xe3:
474 opcode = 0xe1;
475 break;
476 case 0xe1:
477 opcode = 0xe3;
478 break;
479 case 0xe4:
480 opcode = 0xe6;
481 break;
482 case 0xe6:
483 opcode = 0xe4;
484 break;
485 case 0xe7:
486 opcode = 0xe5;
487 break;
488 case 0xe5:
489 opcode = 0xe7;
490 break;
491 default:
492 abort ();
494 fragP->fr_literal[offset] = opcode;
496 /* Create a fixup for the reversed conditional branch. */
497 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
498 fix_new (fragP, fragP->fr_fix + 1, 1,
499 symbol_new (buf, sec, 0, fragP->fr_next),
500 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
502 /* Now create the unconditional branch + fixup to the
503 final target. */
504 fragP->fr_literal[offset + 2] = 0xf4;
505 fragP->fr_literal[offset + 3] = 0xe0;
506 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
507 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
508 fragP->fr_var = 0;
509 fragP->fr_fix += 7;
511 else if (fragP->fr_subtype == 3)
513 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
514 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
515 fragP->fr_var = 0;
516 fragP->fr_fix += 3;
518 else if (fragP->fr_subtype == 4)
520 /* Reverse the condition of the first branch. */
521 int offset = fragP->fr_fix;
522 int opcode = fragP->fr_literal[offset + 1] & 0xff;
524 switch (opcode)
526 case 0xfc:
527 opcode = 0xfd;
528 break;
529 case 0xfd:
530 opcode = 0xfc;
531 break;
532 case 0xfe:
533 opcode = 0xff;
534 break;
535 case 0xff:
536 opcode = 0xfe;
537 case 0xe8:
538 opcode = 0xe9;
539 break;
540 case 0xe9:
541 opcode = 0xe8;
542 break;
543 case 0xe0:
544 opcode = 0xe2;
545 break;
546 case 0xe2:
547 opcode = 0xe0;
548 break;
549 case 0xe3:
550 opcode = 0xe1;
551 break;
552 case 0xe1:
553 opcode = 0xe3;
554 break;
555 case 0xe4:
556 opcode = 0xe6;
557 break;
558 case 0xe6:
559 opcode = 0xe4;
560 break;
561 case 0xe7:
562 opcode = 0xe5;
563 break;
564 case 0xe5:
565 opcode = 0xe7;
566 break;
567 case 0xec:
568 opcode = 0xed;
569 break;
570 case 0xed:
571 opcode = 0xec;
572 break;
573 case 0xee:
574 opcode = 0xef;
575 break;
576 case 0xef:
577 opcode = 0xee;
578 break;
579 default:
580 abort ();
582 fragP->fr_literal[offset + 1] = opcode;
584 /* Create a fixup for the reversed conditional branch. */
585 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
586 fix_new (fragP, fragP->fr_fix + 2, 1,
587 symbol_new (buf, sec, 0, fragP->fr_next),
588 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
590 /* Now create the unconditional branch + fixup to the
591 final target. */
592 fragP->fr_literal[offset + 3] = 0xfc;
593 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
594 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
595 fragP->fr_var = 0;
596 fragP->fr_fix += 6;
598 else if (fragP->fr_subtype == 5)
600 /* Reverse the condition of the first branch. */
601 int offset = fragP->fr_fix;
602 int opcode = fragP->fr_literal[offset + 1] & 0xff;
604 switch (opcode)
606 case 0xfc:
607 opcode = 0xfd;
608 break;
609 case 0xfd:
610 opcode = 0xfc;
611 break;
612 case 0xfe:
613 opcode = 0xff;
614 break;
615 case 0xff:
616 opcode = 0xfe;
617 case 0xe8:
618 opcode = 0xe9;
619 break;
620 case 0xe9:
621 opcode = 0xe8;
622 break;
623 case 0xe0:
624 opcode = 0xe2;
625 break;
626 case 0xe2:
627 opcode = 0xe0;
628 break;
629 case 0xe3:
630 opcode = 0xe1;
631 break;
632 case 0xe1:
633 opcode = 0xe3;
634 break;
635 case 0xe4:
636 opcode = 0xe6;
637 break;
638 case 0xe6:
639 opcode = 0xe4;
640 break;
641 case 0xe7:
642 opcode = 0xe5;
643 break;
644 case 0xe5:
645 opcode = 0xe7;
646 break;
647 case 0xec:
648 opcode = 0xed;
649 break;
650 case 0xed:
651 opcode = 0xec;
652 break;
653 case 0xee:
654 opcode = 0xef;
655 break;
656 case 0xef:
657 opcode = 0xee;
658 break;
659 default:
660 abort ();
662 fragP->fr_literal[offset + 1] = opcode;
664 /* Create a fixup for the reversed conditional branch. */
665 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
666 fix_new (fragP, fragP->fr_fix + 2, 1,
667 symbol_new (buf, sec, 0, fragP->fr_next),
668 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
670 /* Now create the unconditional branch + fixup to the
671 final target. */
672 fragP->fr_literal[offset + 3] = 0xf4;
673 fragP->fr_literal[offset + 4] = 0xe0;
674 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
675 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
676 fragP->fr_var = 0;
677 fragP->fr_fix += 8;
679 else if (fragP->fr_subtype == 6)
681 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
682 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
683 fragP->fr_var = 0;
684 fragP->fr_fix += 3;
686 else if (fragP->fr_subtype == 7)
688 int offset = fragP->fr_fix;
689 fragP->fr_literal[offset] = 0xf4;
690 fragP->fr_literal[offset + 1] = 0xe1;
692 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
693 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
694 fragP->fr_var = 0;
695 fragP->fr_fix += 5;
697 else if (fragP->fr_subtype == 8)
699 fragP->fr_literal[fragP->fr_fix] = 0xea;
700 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
701 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
702 fragP->fr_var = 0;
703 fragP->fr_fix += 2;
705 else if (fragP->fr_subtype == 9)
707 int offset = fragP->fr_fix;
708 fragP->fr_literal[offset] = 0xfc;
710 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
711 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
712 fragP->fr_var = 0;
713 fragP->fr_fix += 3;
715 else if (fragP->fr_subtype == 10)
717 int offset = fragP->fr_fix;
718 fragP->fr_literal[offset] = 0xf4;
719 fragP->fr_literal[offset + 1] = 0xe0;
721 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
722 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
723 fragP->fr_var = 0;
724 fragP->fr_fix += 5;
726 else
727 abort ();
730 valueT
731 md_section_align (seg, addr)
732 asection *seg;
733 valueT addr;
735 int align = bfd_get_section_alignment (stdoutput, seg);
736 return ((addr + (1 << align) - 1) & (-1 << align));
739 void
740 md_begin ()
742 char *prev_name = "";
743 register const struct mn10200_opcode *op;
745 mn10200_hash = hash_new ();
747 /* Insert unique names into hash table. The MN10200 instruction set
748 has many identical opcode names that have different opcodes based
749 on the operands. This hash table then provides a quick index to
750 the first opcode with a particular name in the opcode table. */
752 op = mn10200_opcodes;
753 while (op->name)
755 if (strcmp (prev_name, op->name))
757 prev_name = (char *) op->name;
758 hash_insert (mn10200_hash, op->name, (char *) op);
760 op++;
763 /* This is both a simplification (we don't have to write md_apply_fix3)
764 and support for future optimizations (branch shortening and similar
765 stuff in the linker. */
766 linkrelax = 1;
769 void
770 md_assemble (str)
771 char *str;
773 char *s;
774 struct mn10200_opcode *opcode;
775 struct mn10200_opcode *next_opcode;
776 const unsigned char *opindex_ptr;
777 int next_opindex, relaxable;
778 unsigned long insn, extension, size = 0;
779 char *f;
780 int i;
781 int match;
783 /* Get the opcode. */
784 for (s = str; *s != '\0' && !ISSPACE (*s); s++)
786 if (*s != '\0')
787 *s++ = '\0';
789 /* Find the first opcode with the proper name. */
790 opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
791 if (opcode == NULL)
793 as_bad (_("Unrecognized opcode: `%s'"), str);
794 return;
797 str = s;
798 while (ISSPACE (*str))
799 ++str;
801 input_line_pointer = str;
803 for (;;)
805 const char *errmsg = NULL;
806 int op_idx;
807 char *hold;
808 int extra_shift = 0;
810 relaxable = 0;
811 fc = 0;
812 match = 0;
813 next_opindex = 0;
814 insn = opcode->opcode;
815 extension = 0;
816 for (op_idx = 1, opindex_ptr = opcode->operands;
817 *opindex_ptr != 0;
818 opindex_ptr++, op_idx++)
820 const struct mn10200_operand *operand;
821 expressionS ex;
823 if (next_opindex == 0)
825 operand = &mn10200_operands[*opindex_ptr];
827 else
829 operand = &mn10200_operands[next_opindex];
830 next_opindex = 0;
833 errmsg = NULL;
835 while (*str == ' ' || *str == ',')
836 ++str;
838 if (operand->flags & MN10200_OPERAND_RELAX)
839 relaxable = 1;
841 /* Gather the operand. */
842 hold = input_line_pointer;
843 input_line_pointer = str;
845 if (operand->flags & MN10200_OPERAND_PAREN)
847 if (*input_line_pointer != ')' && *input_line_pointer != '(')
849 input_line_pointer = hold;
850 str = hold;
851 goto error;
853 input_line_pointer++;
854 goto keep_going;
856 /* See if we can match the operands. */
857 else if (operand->flags & MN10200_OPERAND_DREG)
859 if (!data_register_name (&ex))
861 input_line_pointer = hold;
862 str = hold;
863 goto error;
866 else if (operand->flags & MN10200_OPERAND_AREG)
868 if (!address_register_name (&ex))
870 input_line_pointer = hold;
871 str = hold;
872 goto error;
875 else if (operand->flags & MN10200_OPERAND_PSW)
877 char *start = input_line_pointer;
878 char c = get_symbol_end ();
880 if (strcmp (start, "psw") != 0)
882 *input_line_pointer = c;
883 input_line_pointer = hold;
884 str = hold;
885 goto error;
887 *input_line_pointer = c;
888 goto keep_going;
890 else if (operand->flags & MN10200_OPERAND_MDR)
892 char *start = input_line_pointer;
893 char c = get_symbol_end ();
895 if (strcmp (start, "mdr") != 0)
897 *input_line_pointer = c;
898 input_line_pointer = hold;
899 str = hold;
900 goto error;
902 *input_line_pointer = c;
903 goto keep_going;
905 else if (data_register_name (&ex))
907 input_line_pointer = hold;
908 str = hold;
909 goto error;
911 else if (address_register_name (&ex))
913 input_line_pointer = hold;
914 str = hold;
915 goto error;
917 else if (other_register_name (&ex))
919 input_line_pointer = hold;
920 str = hold;
921 goto error;
923 else if (*str == ')' || *str == '(')
925 input_line_pointer = hold;
926 str = hold;
927 goto error;
929 else
931 expression (&ex);
934 switch (ex.X_op)
936 case O_illegal:
937 errmsg = _("illegal operand");
938 goto error;
939 case O_absent:
940 errmsg = _("missing operand");
941 goto error;
942 case O_register:
943 if ((operand->flags
944 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
946 input_line_pointer = hold;
947 str = hold;
948 goto error;
951 if (opcode->format == FMT_2 || opcode->format == FMT_5)
952 extra_shift = 8;
953 else if (opcode->format == FMT_3 || opcode->format == FMT_6
954 || opcode->format == FMT_7)
955 extra_shift = 16;
956 else
957 extra_shift = 0;
959 mn10200_insert_operand (&insn, &extension, operand,
960 ex.X_add_number, (char *) NULL,
961 0, extra_shift);
963 break;
965 case O_constant:
966 /* If this operand can be promoted, and it doesn't
967 fit into the allocated bitfield for this insn,
968 then promote it (ie this opcode does not match). */
969 if (operand->flags
970 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
971 && !check_operand (insn, operand, ex.X_add_number))
973 input_line_pointer = hold;
974 str = hold;
975 goto error;
978 mn10200_insert_operand (&insn, &extension, operand,
979 ex.X_add_number, (char *) NULL,
980 0, 0);
981 break;
983 default:
984 /* If this operand can be promoted, then this opcode didn't
985 match since we can't know if it needed promotion! */
986 if (operand->flags & MN10200_OPERAND_PROMOTE)
988 input_line_pointer = hold;
989 str = hold;
990 goto error;
993 /* We need to generate a fixup for this expression. */
994 if (fc >= MAX_INSN_FIXUPS)
995 as_fatal (_("too many fixups"));
996 fixups[fc].exp = ex;
997 fixups[fc].opindex = *opindex_ptr;
998 fixups[fc].reloc = BFD_RELOC_UNUSED;
999 ++fc;
1000 break;
1003 keep_going:
1004 str = input_line_pointer;
1005 input_line_pointer = hold;
1007 while (*str == ' ' || *str == ',')
1008 ++str;
1012 /* Make sure we used all the operands! */
1013 if (*str != ',')
1014 match = 1;
1016 error:
1017 if (match == 0)
1019 next_opcode = opcode + 1;
1020 if (!strcmp (next_opcode->name, opcode->name))
1022 opcode = next_opcode;
1023 continue;
1026 as_bad ("%s", errmsg);
1027 return;
1029 break;
1032 while (ISSPACE (*str))
1033 ++str;
1035 if (*str != '\0')
1036 as_bad (_("junk at end of line: `%s'"), str);
1038 input_line_pointer = str;
1040 if (opcode->format == FMT_1)
1041 size = 1;
1042 else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1043 size = 2;
1044 else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1045 size = 3;
1046 else if (opcode->format == FMT_6)
1047 size = 4;
1048 else if (opcode->format == FMT_7)
1049 size = 5;
1050 else
1051 abort ();
1053 /* Write out the instruction. */
1055 if (relaxable && fc > 0)
1057 int type;
1059 /* bCC */
1060 if (size == 2 && opcode->opcode != 0xfc0000)
1062 /* Handle bra specially. Basically treat it like jmp so
1063 that we automatically handle 8, 16 and 32 bit offsets
1064 correctly as well as jumps to an undefined address.
1066 It is also important to not treat it like other bCC
1067 instructions since the long forms of bra is different
1068 from other bCC instructions. */
1069 if (opcode->opcode == 0xea00)
1070 type = 8;
1071 else
1072 type = 0;
1074 /* jsr */
1075 else if (size == 3 && opcode->opcode == 0xfd0000)
1076 type = 6;
1077 /* jmp */
1078 else if (size == 3 && opcode->opcode == 0xfc0000)
1079 type = 8;
1080 /* bCCx */
1081 else
1082 type = 3;
1084 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1085 fixups[0].exp.X_add_symbol,
1086 fixups[0].exp.X_add_number,
1087 (char *)fixups[0].opindex);
1088 number_to_chars_bigendian (f, insn, size);
1089 if (8 - size > 4)
1091 number_to_chars_bigendian (f + size, 0, 4);
1092 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1094 else
1095 number_to_chars_bigendian (f + size, 0, 8 - size);
1098 else
1100 f = frag_more (size);
1102 /* Oh, what a mess. The instruction is in big endian format, but
1103 16 and 24bit immediates are little endian! */
1104 if (opcode->format == FMT_3)
1106 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1107 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1109 else if (opcode->format == FMT_6)
1111 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1112 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1114 else if (opcode->format == FMT_7)
1116 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1117 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1118 number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1120 else
1122 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1125 /* Create any fixups. */
1126 for (i = 0; i < fc; i++)
1128 const struct mn10200_operand *operand;
1130 operand = &mn10200_operands[fixups[i].opindex];
1131 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1133 reloc_howto_type *reloc_howto;
1134 int size;
1135 int offset;
1136 fixS *fixP;
1138 reloc_howto = bfd_reloc_type_lookup (stdoutput,
1139 fixups[i].reloc);
1141 if (!reloc_howto)
1142 abort ();
1144 size = bfd_get_reloc_size (reloc_howto);
1146 if (size < 1 || size > 4)
1147 abort ();
1149 offset = 4 - size;
1150 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1151 size,
1152 &fixups[i].exp,
1153 reloc_howto->pc_relative,
1154 fixups[i].reloc);
1156 /* PC-relative offsets are from the first byte of the
1157 next instruction, not from the start of the current
1158 instruction. */
1159 if (reloc_howto->pc_relative)
1160 fixP->fx_offset += size;
1162 else
1164 int reloc, pcrel, reloc_size, offset;
1165 fixS *fixP;
1167 reloc = BFD_RELOC_NONE;
1168 /* How big is the reloc? Remember SPLIT relocs are
1169 implicitly 32bits. */
1170 reloc_size = operand->bits;
1172 offset = size - reloc_size / 8;
1174 /* Is the reloc pc-relative? */
1175 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1177 /* Choose a proper BFD relocation type. */
1178 if (pcrel)
1180 if (reloc_size == 8)
1181 reloc = BFD_RELOC_8_PCREL;
1182 else if (reloc_size == 24)
1183 reloc = BFD_RELOC_24_PCREL;
1184 else
1185 abort ();
1187 else
1189 if (reloc_size == 32)
1190 reloc = BFD_RELOC_32;
1191 else if (reloc_size == 16)
1192 reloc = BFD_RELOC_16;
1193 else if (reloc_size == 8)
1194 reloc = BFD_RELOC_8;
1195 else if (reloc_size == 24)
1196 reloc = BFD_RELOC_24;
1197 else
1198 abort ();
1201 /* Convert the size of the reloc into what fix_new_exp
1202 wants. */
1203 reloc_size = reloc_size / 8;
1204 if (reloc_size == 8)
1205 reloc_size = 0;
1206 else if (reloc_size == 16)
1207 reloc_size = 1;
1208 else if (reloc_size == 32 || reloc_size == 24)
1209 reloc_size = 2;
1211 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1212 reloc_size, &fixups[i].exp, pcrel,
1213 ((bfd_reloc_code_real_type) reloc));
1215 /* PC-relative offsets are from the first byte of the
1216 next instruction, not from the start of the current
1217 instruction. */
1218 if (pcrel)
1219 fixP->fx_offset += size;
1225 /* If while processing a fixup, a reloc really needs to be created
1226 Then it is done here. */
1228 arelent *
1229 tc_gen_reloc (seg, fixp)
1230 asection *seg ATTRIBUTE_UNUSED;
1231 fixS *fixp;
1233 arelent *reloc;
1234 reloc = (arelent *) xmalloc (sizeof (arelent));
1236 if (fixp->fx_subsy != NULL)
1238 /* FIXME: We should resolve difference expressions if possible
1239 here. At least this is better than silently ignoring the
1240 subtrahend. */
1241 as_bad_where (fixp->fx_file, fixp->fx_line,
1242 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
1243 fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
1244 segment_name (fixp->fx_addsy
1245 ? S_GET_SEGMENT (fixp->fx_addsy)
1246 : absolute_section),
1247 S_GET_NAME (fixp->fx_subsy),
1248 segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
1251 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1252 if (reloc->howto == (reloc_howto_type *) NULL)
1254 as_bad_where (fixp->fx_file, fixp->fx_line,
1255 _("reloc %d not supported by object file format"),
1256 (int) fixp->fx_r_type);
1257 return NULL;
1259 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1260 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1261 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1262 reloc->addend = fixp->fx_offset;
1263 return reloc;
1267 md_estimate_size_before_relax (fragp, seg)
1268 fragS *fragp;
1269 asection *seg;
1271 if (fragp->fr_subtype == 6
1272 && (!S_IS_DEFINED (fragp->fr_symbol)
1273 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
1274 fragp->fr_subtype = 7;
1275 else if (fragp->fr_subtype == 8
1276 && (!S_IS_DEFINED (fragp->fr_symbol)
1277 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
1278 fragp->fr_subtype = 10;
1280 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
1281 abort ();
1283 return md_relax_table[fragp->fr_subtype].rlx_length;
1286 long
1287 md_pcrel_from (fixp)
1288 fixS *fixp;
1290 return fixp->fx_frag->fr_address;
1291 #if 0
1292 if (fixp->fx_addsy != (symbolS *) NULL && !S_IS_DEFINED (fixp->fx_addsy))
1294 /* The symbol is undefined. Let the linker figure it out. */
1295 return 0;
1297 return fixp->fx_frag->fr_address + fixp->fx_where;
1298 #endif
1301 void
1302 md_apply_fix3 (fixP, valP, seg)
1303 fixS * fixP;
1304 valueT * valP ATTRIBUTE_UNUSED;
1305 segT seg ATTRIBUTE_UNUSED;
1307 /* We shouldn't ever get here because linkrelax is nonzero. */
1308 abort ();
1309 fixP->fx_done = 1;
1312 /* Insert an operand value into an instruction. */
1314 static void
1315 mn10200_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1316 unsigned long *insnp;
1317 unsigned long *extensionp;
1318 const struct mn10200_operand *operand;
1319 offsetT val;
1320 char *file;
1321 unsigned int line;
1322 unsigned int shift;
1324 /* No need to check 24 or 32bit operands for a bit. */
1325 if (operand->bits < 24
1326 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1328 long min, max;
1329 offsetT test;
1331 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1333 max = (1 << (operand->bits - 1)) - 1;
1334 min = - (1 << (operand->bits - 1));
1336 else
1338 max = (1 << operand->bits) - 1;
1339 min = 0;
1342 test = val;
1344 if (test < (offsetT) min || test > (offsetT) max)
1345 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
1348 if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
1350 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1351 << (operand->shift + shift));
1353 if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
1354 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1355 << (operand->shift + shift + 2));
1357 else
1359 *extensionp |= (val >> 16) & 0xff;
1360 *insnp |= val & 0xffff;
1364 static unsigned long
1365 check_operand (insn, operand, val)
1366 unsigned long insn ATTRIBUTE_UNUSED;
1367 const struct mn10200_operand *operand;
1368 offsetT val;
1370 /* No need to check 24bit or 32bit operands for a bit. */
1371 if (operand->bits < 24
1372 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1374 long min, max;
1375 offsetT test;
1377 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1379 max = (1 << (operand->bits - 1)) - 1;
1380 min = - (1 << (operand->bits - 1));
1382 else
1384 max = (1 << operand->bits) - 1;
1385 min = 0;
1388 test = val;
1390 if (test < (offsetT) min || test > (offsetT) max)
1391 return 0;
1392 else
1393 return 1;
1395 return 1;