1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005 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)
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. */
24 #include "safe-ctype.h"
26 #include "opcode/mn10200.h"
28 /* Structure to hold information about predefined registers. */
35 /* Generic assembler global variables which must be defined by all
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
46 const char line_separator_chars
[] = ";";
48 /* Characters which are used to indicate an exponent in a floating
50 const char EXP_CHARS
[] = "eE";
52 /* Characters which mean that a number is a floating point constant,
54 const char FLT_CHARS
[] = "dD";
56 const relax_typeS md_relax_table
[] =
60 {0x8004, -0x7ffb, 5, 2},
61 {0x800006, -0x7ffff9, 7, 0},
64 {0x8004, -0x7ffb, 6, 5},
65 {0x800006, -0x7ffff9, 8, 0},
67 {0x8004, -0x7ffb, 3, 7},
68 {0x800006, -0x7ffff9, 5, 0},
71 {0x8004, -0x7ffb, 3, 10},
72 {0x800006, -0x7ffff9, 5, 0},
78 #define MAX_INSN_FIXUPS 5
84 bfd_reloc_code_real_type reloc
;
87 struct mn10200_fixup fixups
[MAX_INSN_FIXUPS
];
90 const char *md_shortopts
= "";
92 struct option md_longopts
[] =
94 {NULL
, no_argument
, NULL
, 0}
97 size_t md_longopts_size
= sizeof (md_longopts
);
99 /* The target specific pseudo-ops which we support. */
100 const pseudo_typeS md_pseudo_table
[] =
105 /* Opcode hash table. */
106 static struct hash_control
*mn10200_hash
;
108 /* This table is sorted. Suitable for searching by a binary search. */
109 static const struct reg_name data_registers
[] =
116 #define DATA_REG_NAME_CNT \
117 (sizeof (data_registers) / sizeof (struct reg_name))
119 static const struct reg_name address_registers
[] =
126 #define ADDRESS_REG_NAME_CNT \
127 (sizeof (address_registers) / sizeof (struct reg_name))
129 static const struct reg_name other_registers
[] =
134 #define OTHER_REG_NAME_CNT \
135 (sizeof (other_registers) / sizeof (struct reg_name))
137 /* reg_name_search does a binary search of the given register table
138 to see if "name" is a valid regiter name. Returns the register
139 number from the array on success, or -1 on failure. */
142 reg_name_search (const struct reg_name
*regs
,
146 int middle
, low
, high
;
154 middle
= (low
+ high
) / 2;
155 cmp
= strcasecmp (name
, regs
[middle
].name
);
161 return regs
[middle
].value
;
167 /* Summary of register_name().
169 in: Input_line_pointer points to 1st char of operand.
172 The operand may have been a register: in this case, X_op == O_register,
173 X_add_number is set to the register number, and truth is returned.
174 Input_line_pointer->(next non-blank) char after operand, or is in
175 its original state. */
178 data_register_name (expressionS
*expressionP
)
185 /* Find the spelling of the operand. */
186 start
= name
= input_line_pointer
;
188 c
= get_symbol_end ();
189 reg_number
= reg_name_search (data_registers
, DATA_REG_NAME_CNT
, name
);
191 /* Put back the delimiting char. */
192 *input_line_pointer
= c
;
194 /* Look to see if it's in the register table. */
197 expressionP
->X_op
= O_register
;
198 expressionP
->X_add_number
= reg_number
;
200 /* Make the rest nice. */
201 expressionP
->X_add_symbol
= NULL
;
202 expressionP
->X_op_symbol
= NULL
;
207 /* Reset the line as if we had not done anything. */
208 input_line_pointer
= start
;
212 /* Summary of register_name().
214 in: Input_line_pointer points to 1st char of operand.
217 The operand may have been a register: in this case, X_op == O_register,
218 X_add_number is set to the register number, and truth is returned.
219 Input_line_pointer->(next non-blank) char after operand, or is in
220 its original state. */
223 address_register_name (expressionS
*expressionP
)
230 /* Find the spelling of the operand. */
231 start
= name
= input_line_pointer
;
233 c
= get_symbol_end ();
234 reg_number
= reg_name_search (address_registers
, ADDRESS_REG_NAME_CNT
, name
);
236 /* Put back the delimiting char. */
237 *input_line_pointer
= c
;
239 /* Look to see if it's in the register table. */
242 expressionP
->X_op
= O_register
;
243 expressionP
->X_add_number
= reg_number
;
245 /* Make the rest nice. */
246 expressionP
->X_add_symbol
= NULL
;
247 expressionP
->X_op_symbol
= NULL
;
252 /* Reset the line as if we had not done anything. */
253 input_line_pointer
= start
;
257 /* Summary of register_name().
259 in: Input_line_pointer points to 1st char of operand.
262 The operand may have been a register: in this case, X_op == O_register,
263 X_add_number is set to the register number, and truth is returned.
264 Input_line_pointer->(next non-blank) char after operand, or is in
265 its original state. */
268 other_register_name (expressionS
*expressionP
)
275 /* Find the spelling of the operand. */
276 start
= name
= input_line_pointer
;
278 c
= get_symbol_end ();
279 reg_number
= reg_name_search (other_registers
, OTHER_REG_NAME_CNT
, name
);
281 /* Put back the delimiting char. */
282 *input_line_pointer
= c
;
284 /* Look to see if it's in the register table. */
287 expressionP
->X_op
= O_register
;
288 expressionP
->X_add_number
= reg_number
;
290 /* Make the rest nice. */
291 expressionP
->X_add_symbol
= NULL
;
292 expressionP
->X_op_symbol
= NULL
;
297 /* Reset the line as if we had not done anything. */
298 input_line_pointer
= start
;
303 md_show_usage (FILE *stream
)
305 fprintf (stream
, _("MN10200 options:\n\
310 md_parse_option (int c ATTRIBUTE_UNUSED
,
311 char *arg ATTRIBUTE_UNUSED
)
317 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
323 md_atof (int type
, char *litp
, int *sizep
)
326 LITTLENUM_TYPE words
[4];
342 return _("bad call to md_atof");
345 t
= atof_ieee (input_line_pointer
, type
, words
);
347 input_line_pointer
= t
;
351 for (i
= prec
- 1; i
>= 0; i
--)
353 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
361 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
365 static unsigned long label_count
= 0;
368 subseg_change (sec
, 0);
369 if (fragP
->fr_subtype
== 0)
371 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
372 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
376 else if (fragP
->fr_subtype
== 1)
378 /* Reverse the condition of the first branch. */
379 int offset
= fragP
->fr_fix
;
380 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
417 fragP
->fr_literal
[offset
] = opcode
;
419 /* Create a fixup for the reversed conditional branch. */
420 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
421 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
422 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
423 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
425 /* Now create the unconditional branch + fixup to the
427 fragP
->fr_literal
[offset
+ 2] = 0xfc;
428 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
429 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
433 else if (fragP
->fr_subtype
== 2)
435 /* Reverse the condition of the first branch. */
436 int offset
= fragP
->fr_fix
;
437 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
474 fragP
->fr_literal
[offset
] = opcode
;
476 /* Create a fixup for the reversed conditional branch. */
477 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
478 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
479 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
480 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
482 /* Now create the unconditional branch + fixup to the
484 fragP
->fr_literal
[offset
+ 2] = 0xf4;
485 fragP
->fr_literal
[offset
+ 3] = 0xe0;
486 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
487 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
491 else if (fragP
->fr_subtype
== 3)
493 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
494 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
498 else if (fragP
->fr_subtype
== 4)
500 /* Reverse the condition of the first branch. */
501 int offset
= fragP
->fr_fix
;
502 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
562 fragP
->fr_literal
[offset
+ 1] = opcode
;
564 /* Create a fixup for the reversed conditional branch. */
565 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
566 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
567 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
568 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
570 /* Now create the unconditional branch + fixup to the
572 fragP
->fr_literal
[offset
+ 3] = 0xfc;
573 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
574 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
578 else if (fragP
->fr_subtype
== 5)
580 /* Reverse the condition of the first branch. */
581 int offset
= fragP
->fr_fix
;
582 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
642 fragP
->fr_literal
[offset
+ 1] = opcode
;
644 /* Create a fixup for the reversed conditional branch. */
645 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
646 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
647 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
648 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
650 /* Now create the unconditional branch + fixup to the
652 fragP
->fr_literal
[offset
+ 3] = 0xf4;
653 fragP
->fr_literal
[offset
+ 4] = 0xe0;
654 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
655 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
659 else if (fragP
->fr_subtype
== 6)
661 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
662 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
666 else if (fragP
->fr_subtype
== 7)
668 int offset
= fragP
->fr_fix
;
669 fragP
->fr_literal
[offset
] = 0xf4;
670 fragP
->fr_literal
[offset
+ 1] = 0xe1;
672 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
673 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
677 else if (fragP
->fr_subtype
== 8)
679 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
680 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
681 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
685 else if (fragP
->fr_subtype
== 9)
687 int offset
= fragP
->fr_fix
;
688 fragP
->fr_literal
[offset
] = 0xfc;
690 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
691 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
695 else if (fragP
->fr_subtype
== 10)
697 int offset
= fragP
->fr_fix
;
698 fragP
->fr_literal
[offset
] = 0xf4;
699 fragP
->fr_literal
[offset
+ 1] = 0xe0;
701 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
702 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
711 md_section_align (asection
*seg
, valueT addr
)
713 int align
= bfd_get_section_alignment (stdoutput
, seg
);
714 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
720 char *prev_name
= "";
721 register const struct mn10200_opcode
*op
;
723 mn10200_hash
= hash_new ();
725 /* Insert unique names into hash table. The MN10200 instruction set
726 has many identical opcode names that have different opcodes based
727 on the operands. This hash table then provides a quick index to
728 the first opcode with a particular name in the opcode table. */
730 op
= mn10200_opcodes
;
733 if (strcmp (prev_name
, op
->name
))
735 prev_name
= (char *) op
->name
;
736 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
741 /* This is both a simplification (we don't have to write md_apply_fix3)
742 and support for future optimizations (branch shortening and similar
743 stuff in the linker. */
748 check_operand (unsigned long insn ATTRIBUTE_UNUSED
,
749 const struct mn10200_operand
*operand
,
752 /* No need to check 24bit or 32bit operands for a bit. */
753 if (operand
->bits
< 24
754 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
759 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
761 max
= (1 << (operand
->bits
- 1)) - 1;
762 min
= - (1 << (operand
->bits
- 1));
766 max
= (1 << operand
->bits
) - 1;
772 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
779 /* If while processing a fixup, a reloc really needs to be created
780 Then it is done here. */
783 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
786 reloc
= xmalloc (sizeof (arelent
));
788 if (fixp
->fx_subsy
!= NULL
)
790 if (S_GET_SEGMENT (fixp
->fx_addsy
) == S_GET_SEGMENT (fixp
->fx_subsy
)
791 && S_IS_DEFINED (fixp
->fx_subsy
))
793 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
794 fixp
->fx_subsy
= NULL
;
797 /* FIXME: We should try more ways to resolve difference expressions
798 here. At least this is better than silently ignoring the
800 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
801 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
802 fixp
->fx_addsy
? S_GET_NAME (fixp
->fx_addsy
) : "0",
803 segment_name (fixp
->fx_addsy
804 ? S_GET_SEGMENT (fixp
->fx_addsy
)
806 S_GET_NAME (fixp
->fx_subsy
),
807 segment_name (S_GET_SEGMENT (fixp
->fx_addsy
)));
810 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
811 if (reloc
->howto
== NULL
)
813 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
814 _("reloc %d not supported by object file format"),
815 (int) fixp
->fx_r_type
);
818 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
819 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
820 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
821 reloc
->addend
= fixp
->fx_offset
;
826 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
828 if (fragp
->fr_subtype
== 6
829 && (!S_IS_DEFINED (fragp
->fr_symbol
)
830 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
831 fragp
->fr_subtype
= 7;
832 else if (fragp
->fr_subtype
== 8
833 && (!S_IS_DEFINED (fragp
->fr_symbol
)
834 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
835 fragp
->fr_subtype
= 10;
837 if (fragp
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
840 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
844 md_pcrel_from (fixS
*fixp
)
846 return fixp
->fx_frag
->fr_address
;
850 md_apply_fix3 (fixS
* fixP
, valueT
* valP ATTRIBUTE_UNUSED
, segT seg ATTRIBUTE_UNUSED
)
852 /* We shouldn't ever get here because linkrelax is nonzero. */
857 /* Insert an operand value into an instruction. */
860 mn10200_insert_operand (unsigned long *insnp
,
861 unsigned long *extensionp
,
862 const struct mn10200_operand
*operand
,
868 /* No need to check 24 or 32bit operands for a bit. */
869 if (operand
->bits
< 24
870 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
875 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
877 max
= (1 << (operand
->bits
- 1)) - 1;
878 min
= - (1 << (operand
->bits
- 1));
882 max
= (1 << operand
->bits
) - 1;
888 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
889 as_warn_value_out_of_range (_("operand"), test
, (offsetT
) min
, (offsetT
) max
, file
, line
);
892 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
894 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
895 << (operand
->shift
+ shift
));
897 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
898 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
899 << (operand
->shift
+ shift
+ 2));
903 *extensionp
|= (val
>> 16) & 0xff;
904 *insnp
|= val
& 0xffff;
909 md_assemble (char *str
)
912 struct mn10200_opcode
*opcode
;
913 struct mn10200_opcode
*next_opcode
;
914 const unsigned char *opindex_ptr
;
915 int next_opindex
, relaxable
;
916 unsigned long insn
, extension
, size
= 0;
921 /* Get the opcode. */
922 for (s
= str
; *s
!= '\0' && !ISSPACE (*s
); s
++)
927 /* Find the first opcode with the proper name. */
928 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
931 as_bad (_("Unrecognized opcode: `%s'"), str
);
936 while (ISSPACE (*str
))
939 input_line_pointer
= str
;
943 const char *errmsg
= NULL
;
952 insn
= opcode
->opcode
;
954 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
956 opindex_ptr
++, op_idx
++)
958 const struct mn10200_operand
*operand
;
961 if (next_opindex
== 0)
963 operand
= &mn10200_operands
[*opindex_ptr
];
967 operand
= &mn10200_operands
[next_opindex
];
973 while (*str
== ' ' || *str
== ',')
976 if (operand
->flags
& MN10200_OPERAND_RELAX
)
979 /* Gather the operand. */
980 hold
= input_line_pointer
;
981 input_line_pointer
= str
;
983 if (operand
->flags
& MN10200_OPERAND_PAREN
)
985 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
987 input_line_pointer
= hold
;
991 input_line_pointer
++;
994 /* See if we can match the operands. */
995 else if (operand
->flags
& MN10200_OPERAND_DREG
)
997 if (!data_register_name (&ex
))
999 input_line_pointer
= hold
;
1004 else if (operand
->flags
& MN10200_OPERAND_AREG
)
1006 if (!address_register_name (&ex
))
1008 input_line_pointer
= hold
;
1013 else if (operand
->flags
& MN10200_OPERAND_PSW
)
1015 char *start
= input_line_pointer
;
1016 char c
= get_symbol_end ();
1018 if (strcmp (start
, "psw") != 0)
1020 *input_line_pointer
= c
;
1021 input_line_pointer
= hold
;
1025 *input_line_pointer
= c
;
1028 else if (operand
->flags
& MN10200_OPERAND_MDR
)
1030 char *start
= input_line_pointer
;
1031 char c
= get_symbol_end ();
1033 if (strcmp (start
, "mdr") != 0)
1035 *input_line_pointer
= c
;
1036 input_line_pointer
= hold
;
1040 *input_line_pointer
= c
;
1043 else if (data_register_name (&ex
))
1045 input_line_pointer
= hold
;
1049 else if (address_register_name (&ex
))
1051 input_line_pointer
= hold
;
1055 else if (other_register_name (&ex
))
1057 input_line_pointer
= hold
;
1061 else if (*str
== ')' || *str
== '(')
1063 input_line_pointer
= hold
;
1075 errmsg
= _("illegal operand");
1078 errmsg
= _("missing operand");
1082 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
1084 input_line_pointer
= hold
;
1089 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
1091 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
1092 || opcode
->format
== FMT_7
)
1097 mn10200_insert_operand (&insn
, &extension
, operand
,
1098 ex
.X_add_number
, NULL
,
1104 /* If this operand can be promoted, and it doesn't
1105 fit into the allocated bitfield for this insn,
1106 then promote it (ie this opcode does not match). */
1108 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
1109 && !check_operand (insn
, operand
, ex
.X_add_number
))
1111 input_line_pointer
= hold
;
1116 mn10200_insert_operand (&insn
, &extension
, operand
,
1117 ex
.X_add_number
, NULL
,
1122 /* If this operand can be promoted, then this opcode didn't
1123 match since we can't know if it needed promotion! */
1124 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
1126 input_line_pointer
= hold
;
1131 /* We need to generate a fixup for this expression. */
1132 if (fc
>= MAX_INSN_FIXUPS
)
1133 as_fatal (_("too many fixups"));
1134 fixups
[fc
].exp
= ex
;
1135 fixups
[fc
].opindex
= *opindex_ptr
;
1136 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
1142 str
= input_line_pointer
;
1143 input_line_pointer
= hold
;
1145 while (*str
== ' ' || *str
== ',')
1150 /* Make sure we used all the operands! */
1157 next_opcode
= opcode
+ 1;
1158 if (!strcmp (next_opcode
->name
, opcode
->name
))
1160 opcode
= next_opcode
;
1164 as_bad ("%s", errmsg
);
1170 while (ISSPACE (*str
))
1174 as_bad (_("junk at end of line: `%s'"), str
);
1176 input_line_pointer
= str
;
1178 if (opcode
->format
== FMT_1
)
1180 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1182 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1184 else if (opcode
->format
== FMT_6
)
1186 else if (opcode
->format
== FMT_7
)
1191 /* Write out the instruction. */
1192 if (relaxable
&& fc
> 0)
1197 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1199 /* Handle bra specially. Basically treat it like jmp so
1200 that we automatically handle 8, 16 and 32 bit offsets
1201 correctly as well as jumps to an undefined address.
1203 It is also important to not treat it like other bCC
1204 instructions since the long forms of bra is different
1205 from other bCC instructions. */
1206 if (opcode
->opcode
== 0xea00)
1212 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1215 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1221 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1222 fixups
[0].exp
.X_add_symbol
,
1223 fixups
[0].exp
.X_add_number
,
1224 (char *)fixups
[0].opindex
);
1225 number_to_chars_bigendian (f
, insn
, size
);
1228 number_to_chars_bigendian (f
+ size
, 0, 4);
1229 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1232 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1236 f
= frag_more (size
);
1238 /* Oh, what a mess. The instruction is in big endian format, but
1239 16 and 24bit immediates are little endian! */
1240 if (opcode
->format
== FMT_3
)
1242 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1243 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1245 else if (opcode
->format
== FMT_6
)
1247 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1248 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1250 else if (opcode
->format
== FMT_7
)
1252 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1253 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1254 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1257 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1259 /* Create any fixups. */
1260 for (i
= 0; i
< fc
; i
++)
1262 const struct mn10200_operand
*operand
;
1264 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1265 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1267 reloc_howto_type
*reloc_howto
;
1272 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1278 size
= bfd_get_reloc_size (reloc_howto
);
1280 if (size
< 1 || size
> 4)
1284 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1287 reloc_howto
->pc_relative
,
1290 /* PC-relative offsets are from the first byte of the
1291 next instruction, not from the start of the current
1293 if (reloc_howto
->pc_relative
)
1294 fixP
->fx_offset
+= size
;
1298 int reloc
, pcrel
, reloc_size
, offset
;
1301 reloc
= BFD_RELOC_NONE
;
1302 /* How big is the reloc? Remember SPLIT relocs are
1303 implicitly 32bits. */
1304 reloc_size
= operand
->bits
;
1306 offset
= size
- reloc_size
/ 8;
1308 /* Is the reloc pc-relative? */
1309 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1311 /* Choose a proper BFD relocation type. */
1314 if (reloc_size
== 8)
1315 reloc
= BFD_RELOC_8_PCREL
;
1316 else if (reloc_size
== 24)
1317 reloc
= BFD_RELOC_24_PCREL
;
1323 if (reloc_size
== 32)
1324 reloc
= BFD_RELOC_32
;
1325 else if (reloc_size
== 16)
1326 reloc
= BFD_RELOC_16
;
1327 else if (reloc_size
== 8)
1328 reloc
= BFD_RELOC_8
;
1329 else if (reloc_size
== 24)
1330 reloc
= BFD_RELOC_24
;
1335 /* Convert the size of the reloc into what fix_new_exp
1337 reloc_size
= reloc_size
/ 8;
1338 if (reloc_size
== 8)
1340 else if (reloc_size
== 16)
1342 else if (reloc_size
== 32 || reloc_size
== 24)
1345 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1346 reloc_size
, &fixups
[i
].exp
, pcrel
,
1347 ((bfd_reloc_code_real_type
) reloc
));
1349 /* PC-relative offsets are from the first byte of the
1350 next instruction, not from the start of the current
1353 fixP
->fx_offset
+= size
;