file bfdt.texi was initially added on branch binutils-2_10-branch.
[binutils.git] / gas / config / tc-mn10200.c
blob264f7bf001f66844d230b792ebca63f21775c617
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.
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 2, 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "as.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 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";
55 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},
73 /* local functions */
74 static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *,
75 const struct mn10200_operand *,
76 offsetT, char *, unsigned,
77 unsigned));
78 static unsigned long check_operand PARAMS ((unsigned long,
79 const struct mn10200_operand *,
80 offsetT));
81 static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
82 static boolean data_register_name PARAMS ((expressionS *expressionP));
83 static boolean address_register_name PARAMS ((expressionS *expressionP));
84 static boolean other_register_name PARAMS ((expressionS *expressionP));
87 /* fixups */
88 #define MAX_INSN_FIXUPS (5)
89 struct mn10200_fixup
91 expressionS exp;
92 int opindex;
93 bfd_reloc_code_real_type reloc;
95 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
96 static int fc;
98 const char *md_shortopts = "";
99 struct option md_longopts[] = {
100 {NULL, no_argument, NULL, 0}
102 size_t md_longopts_size = sizeof(md_longopts);
104 /* The target specific pseudo-ops which we support. */
105 const pseudo_typeS md_pseudo_table[] =
107 { NULL, NULL, 0 }
110 /* Opcode hash table. */
111 static struct hash_control *mn10200_hash;
113 /* This table is sorted. Suitable for searching by a binary search. */
114 static const struct reg_name data_registers[] =
116 { "d0", 0 },
117 { "d1", 1 },
118 { "d2", 2 },
119 { "d3", 3 },
121 #define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
123 static const struct reg_name address_registers[] =
125 { "a0", 0 },
126 { "a1", 1 },
127 { "a2", 2 },
128 { "a3", 3 },
130 #define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
132 static const struct reg_name other_registers[] =
134 { "mdr", 0 },
135 { "psw", 0 },
137 #define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
139 /* reg_name_search does a binary search of the given register table
140 to see if "name" is a valid regiter name. Returns the register
141 number from the array on success, or -1 on failure. */
143 static int
144 reg_name_search (regs, regcount, name)
145 const struct reg_name *regs;
146 int regcount;
147 const char *name;
149 int middle, low, high;
150 int cmp;
152 low = 0;
153 high = regcount - 1;
157 middle = (low + high) / 2;
158 cmp = strcasecmp (name, regs[middle].name);
159 if (cmp < 0)
160 high = middle - 1;
161 else if (cmp > 0)
162 low = middle + 1;
163 else
164 return regs[middle].value;
166 while (low <= high);
167 return -1;
171 /* Summary of register_name().
173 * in: Input_line_pointer points to 1st char of operand.
175 * out: A expressionS.
176 * The operand may have been a register: in this case, X_op == O_register,
177 * X_add_number is set to the register number, and truth is returned.
178 * Input_line_pointer->(next non-blank) char after operand, or is in
179 * its original state.
181 static boolean
182 data_register_name (expressionP)
183 expressionS *expressionP;
185 int reg_number;
186 char *name;
187 char *start;
188 char c;
190 /* Find the spelling of the operand */
191 start = name = input_line_pointer;
193 c = get_symbol_end ();
194 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
196 /* look to see if it's in the register table */
197 if (reg_number >= 0)
199 expressionP->X_op = O_register;
200 expressionP->X_add_number = reg_number;
202 /* make the rest nice */
203 expressionP->X_add_symbol = NULL;
204 expressionP->X_op_symbol = NULL;
205 *input_line_pointer = c; /* put back the delimiting char */
206 return true;
208 else
210 /* reset the line as if we had not done anything */
211 *input_line_pointer = c; /* put back the delimiting char */
212 input_line_pointer = start; /* reset input_line pointer */
213 return false;
217 /* Summary of register_name().
219 * in: Input_line_pointer points to 1st char of operand.
221 * out: A expressionS.
222 * The operand may have been a register: in this case, X_op == O_register,
223 * X_add_number is set to the register number, and truth is returned.
224 * Input_line_pointer->(next non-blank) char after operand, or is in
225 * its original state.
227 static boolean
228 address_register_name (expressionP)
229 expressionS *expressionP;
231 int reg_number;
232 char *name;
233 char *start;
234 char c;
236 /* Find the spelling of the operand */
237 start = name = input_line_pointer;
239 c = get_symbol_end ();
240 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
242 /* look to see if it's in the register table */
243 if (reg_number >= 0)
245 expressionP->X_op = O_register;
246 expressionP->X_add_number = reg_number;
248 /* make the rest nice */
249 expressionP->X_add_symbol = NULL;
250 expressionP->X_op_symbol = NULL;
251 *input_line_pointer = c; /* put back the delimiting char */
252 return true;
254 else
256 /* reset the line as if we had not done anything */
257 *input_line_pointer = c; /* put back the delimiting char */
258 input_line_pointer = start; /* reset input_line pointer */
259 return false;
263 /* Summary of register_name().
265 * in: Input_line_pointer points to 1st char of operand.
267 * out: A expressionS.
268 * The operand may have been a register: in this case, X_op == O_register,
269 * X_add_number is set to the register number, and truth is returned.
270 * Input_line_pointer->(next non-blank) char after operand, or is in
271 * its original state.
273 static boolean
274 other_register_name (expressionP)
275 expressionS *expressionP;
277 int reg_number;
278 char *name;
279 char *start;
280 char c;
282 /* Find the spelling of the operand */
283 start = name = input_line_pointer;
285 c = get_symbol_end ();
286 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
288 /* look to see if it's in the register table */
289 if (reg_number >= 0)
291 expressionP->X_op = O_register;
292 expressionP->X_add_number = reg_number;
294 /* make the rest nice */
295 expressionP->X_add_symbol = NULL;
296 expressionP->X_op_symbol = NULL;
297 *input_line_pointer = c; /* put back the delimiting char */
298 return true;
300 else
302 /* reset the line as if we had not done anything */
303 *input_line_pointer = c; /* put back the delimiting char */
304 input_line_pointer = start; /* reset input_line pointer */
305 return false;
309 void
310 md_show_usage (stream)
311 FILE *stream;
313 fprintf(stream, _("MN10200 options:\n\
314 none yet\n"));
318 md_parse_option (c, arg)
319 int c;
320 char *arg;
322 return 0;
325 symbolS *
326 md_undefined_symbol (name)
327 char *name;
329 return 0;
332 char *
333 md_atof (type, litp, sizep)
334 int type;
335 char *litp;
336 int *sizep;
338 int prec;
339 LITTLENUM_TYPE words[4];
340 char *t;
341 int i;
343 switch (type)
345 case 'f':
346 prec = 2;
347 break;
349 case 'd':
350 prec = 4;
351 break;
353 default:
354 *sizep = 0;
355 return _("bad call to md_atof");
358 t = atof_ieee (input_line_pointer, type, words);
359 if (t)
360 input_line_pointer = t;
362 *sizep = prec * 2;
364 for (i = prec - 1; i >= 0; i--)
366 md_number_to_chars (litp, (valueT) words[i], 2);
367 litp += 2;
370 return NULL;
374 void
375 md_convert_frag (abfd, sec, fragP)
376 bfd *abfd;
377 asection *sec;
378 fragS *fragP;
380 static unsigned long label_count = 0;
381 char buf[40];
383 subseg_change (sec, 0);
384 if (fragP->fr_subtype == 0)
386 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
387 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
388 fragP->fr_var = 0;
389 fragP->fr_fix += 2;
391 else if (fragP->fr_subtype == 1)
393 /* Reverse the condition of the first branch. */
394 int offset = fragP->fr_fix;
395 int opcode = fragP->fr_literal[offset] & 0xff;
397 switch (opcode)
399 case 0xe8:
400 opcode = 0xe9;
401 break;
402 case 0xe9:
403 opcode = 0xe8;
404 break;
405 case 0xe0:
406 opcode = 0xe2;
407 break;
408 case 0xe2:
409 opcode = 0xe0;
410 break;
411 case 0xe3:
412 opcode = 0xe1;
413 break;
414 case 0xe1:
415 opcode = 0xe3;
416 break;
417 case 0xe4:
418 opcode = 0xe6;
419 break;
420 case 0xe6:
421 opcode = 0xe4;
422 break;
423 case 0xe7:
424 opcode = 0xe5;
425 break;
426 case 0xe5:
427 opcode = 0xe7;
428 break;
429 default:
430 abort ();
432 fragP->fr_literal[offset] = opcode;
434 /* Create a fixup for the reversed conditional branch. */
435 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
436 fix_new (fragP, fragP->fr_fix + 1, 1,
437 symbol_new (buf, sec, 0, fragP->fr_next),
438 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
440 /* Now create the unconditional branch + fixup to the
441 final target. */
442 fragP->fr_literal[offset + 2] = 0xfc;
443 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
444 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
445 fragP->fr_var = 0;
446 fragP->fr_fix += 5;
448 else if (fragP->fr_subtype == 2)
450 /* Reverse the condition of the first branch. */
451 int offset = fragP->fr_fix;
452 int opcode = fragP->fr_literal[offset] & 0xff;
454 switch (opcode)
456 case 0xe8:
457 opcode = 0xe9;
458 break;
459 case 0xe9:
460 opcode = 0xe8;
461 break;
462 case 0xe0:
463 opcode = 0xe2;
464 break;
465 case 0xe2:
466 opcode = 0xe0;
467 break;
468 case 0xe3:
469 opcode = 0xe1;
470 break;
471 case 0xe1:
472 opcode = 0xe3;
473 break;
474 case 0xe4:
475 opcode = 0xe6;
476 break;
477 case 0xe6:
478 opcode = 0xe4;
479 break;
480 case 0xe7:
481 opcode = 0xe5;
482 break;
483 case 0xe5:
484 opcode = 0xe7;
485 break;
486 default:
487 abort ();
489 fragP->fr_literal[offset] = opcode;
491 /* Create a fixup for the reversed conditional branch. */
492 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
493 fix_new (fragP, fragP->fr_fix + 1, 1,
494 symbol_new (buf, sec, 0, fragP->fr_next),
495 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
497 /* Now create the unconditional branch + fixup to the
498 final target. */
499 fragP->fr_literal[offset + 2] = 0xf4;
500 fragP->fr_literal[offset + 3] = 0xe0;
501 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
502 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
503 fragP->fr_var = 0;
504 fragP->fr_fix += 7;
506 else if (fragP->fr_subtype == 3)
508 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
509 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
510 fragP->fr_var = 0;
511 fragP->fr_fix += 3;
513 else if (fragP->fr_subtype == 4)
515 /* Reverse the condition of the first branch. */
516 int offset = fragP->fr_fix;
517 int opcode = fragP->fr_literal[offset + 1] & 0xff;
519 switch (opcode)
521 case 0xfc:
522 opcode = 0xfd;
523 break;
524 case 0xfd:
525 opcode = 0xfc;
526 break;
527 case 0xfe:
528 opcode = 0xff;
529 break;
530 case 0xff:
531 opcode = 0xfe;
532 case 0xe8:
533 opcode = 0xe9;
534 break;
535 case 0xe9:
536 opcode = 0xe8;
537 break;
538 case 0xe0:
539 opcode = 0xe2;
540 break;
541 case 0xe2:
542 opcode = 0xe0;
543 break;
544 case 0xe3:
545 opcode = 0xe1;
546 break;
547 case 0xe1:
548 opcode = 0xe3;
549 break;
550 case 0xe4:
551 opcode = 0xe6;
552 break;
553 case 0xe6:
554 opcode = 0xe4;
555 break;
556 case 0xe7:
557 opcode = 0xe5;
558 break;
559 case 0xe5:
560 opcode = 0xe7;
561 break;
562 case 0xec:
563 opcode = 0xed;
564 break;
565 case 0xed:
566 opcode = 0xec;
567 break;
568 case 0xee:
569 opcode = 0xef;
570 break;
571 case 0xef:
572 opcode = 0xee;
573 break;
574 default:
575 abort ();
577 fragP->fr_literal[offset + 1] = opcode;
579 /* Create a fixup for the reversed conditional branch. */
580 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
581 fix_new (fragP, fragP->fr_fix + 2, 1,
582 symbol_new (buf, sec, 0, fragP->fr_next),
583 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
585 /* Now create the unconditional branch + fixup to the
586 final target. */
587 fragP->fr_literal[offset + 3] = 0xfc;
588 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
589 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
590 fragP->fr_var = 0;
591 fragP->fr_fix += 6;
593 else if (fragP->fr_subtype == 5)
595 /* Reverse the condition of the first branch. */
596 int offset = fragP->fr_fix;
597 int opcode = fragP->fr_literal[offset + 1] & 0xff;
599 switch (opcode)
601 case 0xfc:
602 opcode = 0xfd;
603 break;
604 case 0xfd:
605 opcode = 0xfc;
606 break;
607 case 0xfe:
608 opcode = 0xff;
609 break;
610 case 0xff:
611 opcode = 0xfe;
612 case 0xe8:
613 opcode = 0xe9;
614 break;
615 case 0xe9:
616 opcode = 0xe8;
617 break;
618 case 0xe0:
619 opcode = 0xe2;
620 break;
621 case 0xe2:
622 opcode = 0xe0;
623 break;
624 case 0xe3:
625 opcode = 0xe1;
626 break;
627 case 0xe1:
628 opcode = 0xe3;
629 break;
630 case 0xe4:
631 opcode = 0xe6;
632 break;
633 case 0xe6:
634 opcode = 0xe4;
635 break;
636 case 0xe7:
637 opcode = 0xe5;
638 break;
639 case 0xe5:
640 opcode = 0xe7;
641 break;
642 case 0xec:
643 opcode = 0xed;
644 break;
645 case 0xed:
646 opcode = 0xec;
647 break;
648 case 0xee:
649 opcode = 0xef;
650 break;
651 case 0xef:
652 opcode = 0xee;
653 break;
654 default:
655 abort ();
657 fragP->fr_literal[offset + 1] = opcode;
659 /* Create a fixup for the reversed conditional branch. */
660 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
661 fix_new (fragP, fragP->fr_fix + 2, 1,
662 symbol_new (buf, sec, 0, fragP->fr_next),
663 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
665 /* Now create the unconditional branch + fixup to the
666 final target. */
667 fragP->fr_literal[offset + 3] = 0xf4;
668 fragP->fr_literal[offset + 4] = 0xe0;
669 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
670 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
671 fragP->fr_var = 0;
672 fragP->fr_fix += 8;
674 else if (fragP->fr_subtype == 6)
676 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
677 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
678 fragP->fr_var = 0;
679 fragP->fr_fix += 3;
681 else if (fragP->fr_subtype == 7)
683 int offset = fragP->fr_fix;
684 fragP->fr_literal[offset] = 0xf4;
685 fragP->fr_literal[offset + 1] = 0xe1;
687 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
688 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
689 fragP->fr_var = 0;
690 fragP->fr_fix += 5;
692 else if (fragP->fr_subtype == 8)
694 fragP->fr_literal[fragP->fr_fix] = 0xea;
695 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
696 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
697 fragP->fr_var = 0;
698 fragP->fr_fix += 2;
700 else if (fragP->fr_subtype == 9)
702 int offset = fragP->fr_fix;
703 fragP->fr_literal[offset] = 0xfc;
705 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
706 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
707 fragP->fr_var = 0;
708 fragP->fr_fix += 3;
710 else if (fragP->fr_subtype == 10)
712 int offset = fragP->fr_fix;
713 fragP->fr_literal[offset] = 0xf4;
714 fragP->fr_literal[offset + 1] = 0xe0;
716 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
717 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
718 fragP->fr_var = 0;
719 fragP->fr_fix += 5;
721 else
722 abort ();
725 valueT
726 md_section_align (seg, addr)
727 asection *seg;
728 valueT addr;
730 int align = bfd_get_section_alignment (stdoutput, seg);
731 return ((addr + (1 << align) - 1) & (-1 << align));
734 void
735 md_begin ()
737 char *prev_name = "";
738 register const struct mn10200_opcode *op;
740 mn10200_hash = hash_new();
742 /* Insert unique names into hash table. The MN10200 instruction set
743 has many identical opcode names that have different opcodes based
744 on the operands. This hash table then provides a quick index to
745 the first opcode with a particular name in the opcode table. */
747 op = mn10200_opcodes;
748 while (op->name)
750 if (strcmp (prev_name, op->name))
752 prev_name = (char *) op->name;
753 hash_insert (mn10200_hash, op->name, (char *) op);
755 op++;
758 /* This is both a simplification (we don't have to write md_apply_fix)
759 and support for future optimizations (branch shortening and similar
760 stuff in the linker. */
761 linkrelax = 1;
764 void
765 md_assemble (str)
766 char *str;
768 char *s;
769 struct mn10200_opcode *opcode;
770 struct mn10200_opcode *next_opcode;
771 const unsigned char *opindex_ptr;
772 int next_opindex, relaxable;
773 unsigned long insn, extension, size = 0;
774 char *f;
775 int i;
776 int match;
778 /* Get the opcode. */
779 for (s = str; *s != '\0' && ! isspace (*s); s++)
781 if (*s != '\0')
782 *s++ = '\0';
784 /* find the first opcode with the proper name */
785 opcode = (struct mn10200_opcode *)hash_find (mn10200_hash, str);
786 if (opcode == NULL)
788 as_bad (_("Unrecognized opcode: `%s'"), str);
789 return;
792 str = s;
793 while (isspace (*str))
794 ++str;
796 input_line_pointer = str;
798 for(;;)
800 const char *errmsg = NULL;
801 int op_idx;
802 char *hold;
803 int extra_shift = 0;
805 relaxable = 0;
806 fc = 0;
807 match = 0;
808 next_opindex = 0;
809 insn = opcode->opcode;
810 extension = 0;
811 for (op_idx = 1, opindex_ptr = opcode->operands;
812 *opindex_ptr != 0;
813 opindex_ptr++, op_idx++)
815 const struct mn10200_operand *operand;
816 expressionS ex;
818 if (next_opindex == 0)
820 operand = &mn10200_operands[*opindex_ptr];
822 else
824 operand = &mn10200_operands[next_opindex];
825 next_opindex = 0;
828 errmsg = NULL;
830 while (*str == ' ' || *str == ',')
831 ++str;
833 if (operand->flags & MN10200_OPERAND_RELAX)
834 relaxable = 1;
836 /* Gather the operand. */
837 hold = input_line_pointer;
838 input_line_pointer = str;
840 if (operand->flags & MN10200_OPERAND_PAREN)
842 if (*input_line_pointer != ')' && *input_line_pointer != '(')
844 input_line_pointer = hold;
845 str = hold;
846 goto error;
848 input_line_pointer++;
849 goto keep_going;
851 /* See if we can match the operands. */
852 else if (operand->flags & MN10200_OPERAND_DREG)
854 if (!data_register_name (&ex))
856 input_line_pointer = hold;
857 str = hold;
858 goto error;
861 else if (operand->flags & MN10200_OPERAND_AREG)
863 if (!address_register_name (&ex))
865 input_line_pointer = hold;
866 str = hold;
867 goto error;
870 else if (operand->flags & MN10200_OPERAND_PSW)
872 char *start = input_line_pointer;
873 char c = get_symbol_end ();
875 if (strcmp (start, "psw") != 0)
877 *input_line_pointer = c;
878 input_line_pointer = hold;
879 str = hold;
880 goto error;
882 *input_line_pointer = c;
883 goto keep_going;
885 else if (operand->flags & MN10200_OPERAND_MDR)
887 char *start = input_line_pointer;
888 char c = get_symbol_end ();
890 if (strcmp (start, "mdr") != 0)
892 *input_line_pointer = c;
893 input_line_pointer = hold;
894 str = hold;
895 goto error;
897 *input_line_pointer = c;
898 goto keep_going;
900 else if (data_register_name (&ex))
902 input_line_pointer = hold;
903 str = hold;
904 goto error;
906 else if (address_register_name (&ex))
908 input_line_pointer = hold;
909 str = hold;
910 goto error;
912 else if (other_register_name (&ex))
914 input_line_pointer = hold;
915 str = hold;
916 goto error;
918 else if (*str == ')' || *str == '(')
920 input_line_pointer = hold;
921 str = hold;
922 goto error;
924 else
926 expression (&ex);
929 switch (ex.X_op)
931 case O_illegal:
932 errmsg = _("illegal operand");
933 goto error;
934 case O_absent:
935 errmsg = _("missing operand");
936 goto error;
937 case O_register:
938 if ((operand->flags
939 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
941 input_line_pointer = hold;
942 str = hold;
943 goto error;
946 if (opcode->format == FMT_2 || opcode->format == FMT_5)
947 extra_shift = 8;
948 else if (opcode->format == FMT_3 || opcode->format == FMT_6
949 || opcode->format == FMT_7)
950 extra_shift = 16;
951 else
952 extra_shift = 0;
954 mn10200_insert_operand (&insn, &extension, operand,
955 ex.X_add_number, (char *) NULL,
956 0, extra_shift);
958 break;
960 case O_constant:
961 /* If this operand can be promoted, and it doesn't
962 fit into the allocated bitfield for this insn,
963 then promote it (ie this opcode does not match). */
964 if (operand->flags
965 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
966 && ! check_operand (insn, operand, ex.X_add_number))
968 input_line_pointer = hold;
969 str = hold;
970 goto error;
973 mn10200_insert_operand (&insn, &extension, operand,
974 ex.X_add_number, (char *) NULL,
975 0, 0);
976 break;
978 default:
979 /* If this operand can be promoted, then this opcode didn't
980 match since we can't know if it needed promotion! */
981 if (operand->flags & MN10200_OPERAND_PROMOTE)
983 input_line_pointer = hold;
984 str = hold;
985 goto error;
988 /* We need to generate a fixup for this expression. */
989 if (fc >= MAX_INSN_FIXUPS)
990 as_fatal (_("too many fixups"));
991 fixups[fc].exp = ex;
992 fixups[fc].opindex = *opindex_ptr;
993 fixups[fc].reloc = BFD_RELOC_UNUSED;
994 ++fc;
995 break;
998 keep_going:
999 str = input_line_pointer;
1000 input_line_pointer = hold;
1002 while (*str == ' ' || *str == ',')
1003 ++str;
1007 /* Make sure we used all the operands! */
1008 if (*str != ',')
1009 match = 1;
1011 error:
1012 if (match == 0)
1014 next_opcode = opcode + 1;
1015 if (!strcmp(next_opcode->name, opcode->name))
1017 opcode = next_opcode;
1018 continue;
1021 as_bad ("%s", errmsg);
1022 return;
1024 break;
1027 while (isspace (*str))
1028 ++str;
1030 if (*str != '\0')
1031 as_bad (_("junk at end of line: `%s'"), str);
1033 input_line_pointer = str;
1035 if (opcode->format == FMT_1)
1036 size = 1;
1037 else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1038 size = 2;
1039 else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1040 size = 3;
1041 else if (opcode->format == FMT_6)
1042 size = 4;
1043 else if (opcode->format == FMT_7)
1044 size = 5;
1045 else
1046 abort ();
1048 /* Write out the instruction. */
1050 if (relaxable && fc > 0)
1052 int type;
1054 /* bCC */
1055 if (size == 2 && opcode->opcode != 0xfc0000)
1057 /* Handle bra specially. Basically treat it like jmp so
1058 that we automatically handle 8, 16 and 32 bit offsets
1059 correctly as well as jumps to an undefined address.
1061 It is also important to not treat it like other bCC
1062 instructions since the long forms of bra is different
1063 from other bCC instructions. */
1064 if (opcode->opcode == 0xea00)
1065 type = 8;
1066 else
1067 type = 0;
1069 /* jsr */
1070 else if (size == 3 && opcode->opcode == 0xfd0000)
1071 type = 6;
1072 /* jmp */
1073 else if (size == 3 && opcode->opcode == 0xfc0000)
1074 type = 8;
1075 /* bCCx */
1076 else
1077 type = 3;
1079 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1080 fixups[0].exp.X_add_symbol,
1081 fixups[0].exp.X_add_number,
1082 (char *)fixups[0].opindex);
1083 number_to_chars_bigendian (f, insn, size);
1084 if (8 - size > 4)
1086 number_to_chars_bigendian (f + size, 0, 4);
1087 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1089 else
1090 number_to_chars_bigendian (f + size, 0, 8 - size);
1093 else
1095 f = frag_more (size);
1097 /* Oh, what a mess. The instruction is in big endian format, but
1098 16 and 24bit immediates are little endian! */
1099 if (opcode->format == FMT_3)
1101 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1102 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1104 else if (opcode->format == FMT_6)
1106 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1107 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1109 else if (opcode->format == FMT_7)
1111 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1112 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1113 number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1115 else
1117 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1120 /* Create any fixups. */
1121 for (i = 0; i < fc; i++)
1123 const struct mn10200_operand *operand;
1125 operand = &mn10200_operands[fixups[i].opindex];
1126 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1128 reloc_howto_type *reloc_howto;
1129 int size;
1130 int offset;
1131 fixS *fixP;
1133 reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
1135 if (!reloc_howto)
1136 abort();
1138 size = bfd_get_reloc_size (reloc_howto);
1140 if (size < 1 || size > 4)
1141 abort();
1143 offset = 4 - size;
1144 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1145 size,
1146 &fixups[i].exp,
1147 reloc_howto->pc_relative,
1148 fixups[i].reloc);
1150 /* PC-relative offsets are from the first byte of the next
1151 instruction, not from the start of the current instruction. */
1152 if (reloc_howto->pc_relative)
1153 fixP->fx_offset += size;
1155 else
1157 int reloc, pcrel, reloc_size, offset;
1158 fixS *fixP;
1160 reloc = BFD_RELOC_NONE;
1161 /* How big is the reloc? Remember SPLIT relocs are
1162 implicitly 32bits. */
1163 reloc_size = operand->bits;
1165 offset = size - reloc_size / 8;
1167 /* Is the reloc pc-relative? */
1168 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1171 /* Choose a proper BFD relocation type. */
1172 if (pcrel)
1174 if (reloc_size == 8)
1175 reloc = BFD_RELOC_8_PCREL;
1176 else if (reloc_size == 24)
1177 reloc = BFD_RELOC_24_PCREL;
1178 else
1179 abort ();
1181 else
1183 if (reloc_size == 32)
1184 reloc = BFD_RELOC_32;
1185 else if (reloc_size == 16)
1186 reloc = BFD_RELOC_16;
1187 else if (reloc_size == 8)
1188 reloc = BFD_RELOC_8;
1189 else if (reloc_size == 24)
1190 reloc = BFD_RELOC_24;
1191 else
1192 abort ();
1195 /* Convert the size of the reloc into what fix_new_exp wants. */
1196 reloc_size = reloc_size / 8;
1197 if (reloc_size == 8)
1198 reloc_size = 0;
1199 else if (reloc_size == 16)
1200 reloc_size = 1;
1201 else if (reloc_size == 32 || reloc_size == 24)
1202 reloc_size = 2;
1204 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1205 reloc_size, &fixups[i].exp, pcrel,
1206 ((bfd_reloc_code_real_type) reloc));
1208 /* PC-relative offsets are from the first byte of the next
1209 instruction, not from the start of the current instruction. */
1210 if (pcrel)
1211 fixP->fx_offset += size;
1218 /* if while processing a fixup, a reloc really needs to be created */
1219 /* then it is done here */
1221 arelent *
1222 tc_gen_reloc (seg, fixp)
1223 asection *seg;
1224 fixS *fixp;
1226 arelent *reloc;
1227 reloc = (arelent *) xmalloc (sizeof (arelent));
1229 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1230 if (reloc->howto == (reloc_howto_type *) NULL)
1232 as_bad_where (fixp->fx_file, fixp->fx_line,
1233 _("reloc %d not supported by object file format"),
1234 (int)fixp->fx_r_type);
1235 return NULL;
1237 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1239 if (fixp->fx_addsy && fixp->fx_subsy)
1241 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1242 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1244 as_bad_where (fixp->fx_file, fixp->fx_line,
1245 "Difference of symbols in different sections is not supported");
1246 return NULL;
1248 reloc->sym_ptr_ptr = &bfd_abs_symbol;
1249 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
1250 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
1252 else
1254 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1255 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1256 reloc->addend = fixp->fx_offset;
1258 return reloc;
1262 md_estimate_size_before_relax (fragp, seg)
1263 fragS *fragp;
1264 asection *seg;
1266 if (fragp->fr_subtype == 0)
1267 return 2;
1268 if (fragp->fr_subtype == 3)
1269 return 3;
1270 if (fragp->fr_subtype == 6)
1272 if (!S_IS_DEFINED (fragp->fr_symbol)
1273 || seg != S_GET_SEGMENT (fragp->fr_symbol))
1275 fragp->fr_subtype = 7;
1276 return 5;
1278 return 3;
1280 if (fragp->fr_subtype == 8)
1282 if (!S_IS_DEFINED (fragp->fr_symbol))
1284 fragp->fr_subtype = 10;
1285 return 5;
1287 return 2;
1291 long
1292 md_pcrel_from (fixp)
1293 fixS *fixp;
1295 return fixp->fx_frag->fr_address;
1296 #if 0
1297 if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
1299 /* The symbol is undefined. Let the linker figure it out. */
1300 return 0;
1302 return fixp->fx_frag->fr_address + fixp->fx_where;
1303 #endif
1307 md_apply_fix3 (fixp, valuep, seg)
1308 fixS *fixp;
1309 valueT *valuep;
1310 segT seg;
1312 /* We shouldn't ever get here because linkrelax is nonzero. */
1313 abort ();
1314 fixp->fx_done = 1;
1315 return 0;
1318 /* Insert an operand value into an instruction. */
1320 static void
1321 mn10200_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1322 unsigned long *insnp;
1323 unsigned long *extensionp;
1324 const struct mn10200_operand *operand;
1325 offsetT val;
1326 char *file;
1327 unsigned int line;
1328 unsigned int shift;
1330 /* No need to check 24 or 32bit operands for a bit. */
1331 if (operand->bits < 24
1332 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1334 long min, max;
1335 offsetT test;
1337 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1339 max = (1 << (operand->bits - 1)) - 1;
1340 min = - (1 << (operand->bits - 1));
1342 else
1344 max = (1 << operand->bits) - 1;
1345 min = 0;
1348 test = val;
1351 if (test < (offsetT) min || test > (offsetT) max)
1353 const char *err =
1354 _("operand out of range (%s not between %ld and %ld)");
1355 char buf[100];
1357 sprint_value (buf, test);
1358 if (file == (char *) NULL)
1359 as_warn (err, buf, min, max);
1360 else
1361 as_warn_where (file, line, err, buf, min, max);
1365 if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
1367 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1368 << (operand->shift + shift));
1370 if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
1371 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1372 << (operand->shift + shift + 2));
1374 else
1376 *extensionp |= (val >> 16) & 0xff;
1377 *insnp |= val & 0xffff;
1381 static unsigned long
1382 check_operand (insn, operand, val)
1383 unsigned long insn;
1384 const struct mn10200_operand *operand;
1385 offsetT val;
1387 /* No need to check 24bit or 32bit operands for a bit. */
1388 if (operand->bits < 24
1389 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1391 long min, max;
1392 offsetT test;
1394 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1396 max = (1 << (operand->bits - 1)) - 1;
1397 min = - (1 << (operand->bits - 1));
1399 else
1401 max = (1 << operand->bits) - 1;
1402 min = 0;
1405 test = val;
1408 if (test < (offsetT) min || test > (offsetT) max)
1409 return 0;
1410 else
1411 return 1;
1413 return 1;