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)
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. */
23 #include "safe-ctype.h"
25 #include "opcode/mn10200.h"
27 /* Structure to hold information about predefined registers. */
34 /* Generic assembler global variables which must be defined by all
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
45 const char line_separator_chars
[] = ";";
47 /* Characters which are used to indicate an exponent in a floating
49 const char EXP_CHARS
[] = "eE";
51 /* Characters which mean that a number is a floating point constant,
53 const char FLT_CHARS
[] = "dD";
55 const relax_typeS md_relax_table
[] =
59 {0x8004, -0x7ffb, 5, 2},
60 {0x800006, -0x7ffff9, 7, 0},
63 {0x8004, -0x7ffb, 6, 5},
64 {0x800006, -0x7ffff9, 8, 0},
66 {0x8004, -0x7ffb, 3, 7},
67 {0x800006, -0x7ffff9, 5, 0},
70 {0x8004, -0x7ffb, 3, 10},
71 {0x800006, -0x7ffff9, 5, 0},
77 #define MAX_INSN_FIXUPS 5
83 bfd_reloc_code_real_type reloc
;
86 struct mn10200_fixup fixups
[MAX_INSN_FIXUPS
];
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
[] =
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
[] =
115 #define DATA_REG_NAME_CNT \
116 (sizeof (data_registers) / sizeof (struct reg_name))
118 static const struct reg_name address_registers
[] =
125 #define ADDRESS_REG_NAME_CNT \
126 (sizeof (address_registers) / sizeof (struct reg_name))
128 static const struct reg_name other_registers
[] =
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. */
141 reg_name_search (const struct reg_name
*regs
,
145 int middle
, low
, high
;
153 middle
= (low
+ high
) / 2;
154 cmp
= strcasecmp (name
, regs
[middle
].name
);
160 return regs
[middle
].value
;
166 /* Summary of register_name().
168 in: Input_line_pointer points to 1st char of operand.
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. */
177 data_register_name (expressionS
*expressionP
)
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. */
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
;
206 /* Reset the line as if we had not done anything. */
207 input_line_pointer
= start
;
211 /* Summary of register_name().
213 in: Input_line_pointer points to 1st char of operand.
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. */
222 address_register_name (expressionS
*expressionP
)
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. */
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
;
251 /* Reset the line as if we had not done anything. */
252 input_line_pointer
= start
;
256 /* Summary of register_name().
258 in: Input_line_pointer points to 1st char of operand.
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. */
267 other_register_name (expressionS
*expressionP
)
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. */
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
;
296 /* Reset the line as if we had not done anything. */
297 input_line_pointer
= start
;
302 md_show_usage (FILE *stream
)
304 fprintf (stream
, _("MN10200 options:\n\
309 md_parse_option (int c ATTRIBUTE_UNUSED
,
310 char *arg ATTRIBUTE_UNUSED
)
316 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
322 md_atof (int type
, char *litp
, int *sizep
)
325 LITTLENUM_TYPE words
[4];
341 return _("bad call to md_atof");
344 t
= atof_ieee (input_line_pointer
, type
, words
);
346 input_line_pointer
= t
;
350 for (i
= prec
- 1; i
>= 0; i
--)
352 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
360 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
364 static unsigned long label_count
= 0;
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
);
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;
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
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
);
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;
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
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
);
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
);
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;
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
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
);
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;
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
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
);
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
);
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
);
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
);
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
);
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
);
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
));
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
;
732 if (strcmp (prev_name
, op
->name
))
734 prev_name
= (char *) op
->name
;
735 hash_insert (mn10200_hash
, op
->name
, (char *) 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. */
747 check_operand (unsigned long insn ATTRIBUTE_UNUSED
,
748 const struct mn10200_operand
*operand
,
751 /* No need to check 24bit or 32bit operands for a bit. */
752 if (operand
->bits
< 24
753 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
758 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
760 max
= (1 << (operand
->bits
- 1)) - 1;
761 min
= - (1 << (operand
->bits
- 1));
765 max
= (1 << operand
->bits
) - 1;
771 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
778 /* If while processing a fixup, a reloc really needs to be created
779 Then it is done here. */
782 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
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
;
796 /* FIXME: We should try more ways to resolve difference expressions
797 here. At least this is better than silently ignoring the
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
)
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
);
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
;
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]))
839 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
843 md_pcrel_from (fixS
*fixp
)
845 return fixp
->fx_frag
->fr_address
;
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. */
856 /* Insert an operand value into an instruction. */
859 mn10200_insert_operand (unsigned long *insnp
,
860 unsigned long *extensionp
,
861 const struct mn10200_operand
*operand
,
867 /* No need to check 24 or 32bit operands for a bit. */
868 if (operand
->bits
< 24
869 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
874 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
876 max
= (1 << (operand
->bits
- 1)) - 1;
877 min
= - (1 << (operand
->bits
- 1));
881 max
= (1 << operand
->bits
) - 1;
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));
902 *extensionp
|= (val
>> 16) & 0xff;
903 *insnp
|= val
& 0xffff;
908 md_assemble (char *str
)
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;
920 /* Get the opcode. */
921 for (s
= str
; *s
!= '\0' && !ISSPACE (*s
); s
++)
926 /* Find the first opcode with the proper name. */
927 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
930 as_bad (_("Unrecognized opcode: `%s'"), str
);
935 while (ISSPACE (*str
))
938 input_line_pointer
= str
;
942 const char *errmsg
= NULL
;
951 insn
= opcode
->opcode
;
953 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
955 opindex_ptr
++, op_idx
++)
957 const struct mn10200_operand
*operand
;
960 if (next_opindex
== 0)
962 operand
= &mn10200_operands
[*opindex_ptr
];
966 operand
= &mn10200_operands
[next_opindex
];
972 while (*str
== ' ' || *str
== ',')
975 if (operand
->flags
& MN10200_OPERAND_RELAX
)
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
;
990 input_line_pointer
++;
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
;
1003 else if (operand
->flags
& MN10200_OPERAND_AREG
)
1005 if (!address_register_name (&ex
))
1007 input_line_pointer
= hold
;
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
;
1024 *input_line_pointer
= c
;
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
;
1039 *input_line_pointer
= c
;
1042 else if (data_register_name (&ex
))
1044 input_line_pointer
= hold
;
1048 else if (address_register_name (&ex
))
1050 input_line_pointer
= hold
;
1054 else if (other_register_name (&ex
))
1056 input_line_pointer
= hold
;
1060 else if (*str
== ')' || *str
== '(')
1062 input_line_pointer
= hold
;
1074 errmsg
= _("illegal operand");
1077 errmsg
= _("missing operand");
1081 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
1083 input_line_pointer
= hold
;
1088 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
1090 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
1091 || opcode
->format
== FMT_7
)
1096 mn10200_insert_operand (&insn
, &extension
, operand
,
1097 ex
.X_add_number
, NULL
,
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). */
1107 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
1108 && !check_operand (insn
, operand
, ex
.X_add_number
))
1110 input_line_pointer
= hold
;
1115 mn10200_insert_operand (&insn
, &extension
, operand
,
1116 ex
.X_add_number
, NULL
,
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
;
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
;
1141 str
= input_line_pointer
;
1142 input_line_pointer
= hold
;
1144 while (*str
== ' ' || *str
== ',')
1149 /* Make sure we used all the operands! */
1156 next_opcode
= opcode
+ 1;
1157 if (!strcmp (next_opcode
->name
, opcode
->name
))
1159 opcode
= next_opcode
;
1163 as_bad ("%s", errmsg
);
1169 while (ISSPACE (*str
))
1173 as_bad (_("junk at end of line: `%s'"), str
);
1175 input_line_pointer
= str
;
1177 if (opcode
->format
== FMT_1
)
1179 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1181 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1183 else if (opcode
->format
== FMT_6
)
1185 else if (opcode
->format
== FMT_7
)
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. */
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)
1223 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1226 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
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
);
1240 number_to_chars_bigendian (f
+ size
, 0, 4);
1241 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1244 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
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);
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
;
1284 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1290 size
= bfd_get_reloc_size (reloc_howto
);
1292 if (size
< 1 || size
> 4)
1296 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1299 reloc_howto
->pc_relative
,
1302 /* PC-relative offsets are from the first byte of the
1303 next instruction, not from the start of the current
1305 if (reloc_howto
->pc_relative
)
1306 fixP
->fx_offset
+= size
;
1310 int reloc
, pcrel
, reloc_size
, offset
;
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. */
1326 if (reloc_size
== 8)
1327 reloc
= BFD_RELOC_8_PCREL
;
1328 else if (reloc_size
== 24)
1329 reloc
= BFD_RELOC_24_PCREL
;
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
;
1347 /* Convert the size of the reloc into what fix_new_exp
1349 reloc_size
= reloc_size
/ 8;
1350 if (reloc_size
== 8)
1352 else if (reloc_size
== 16)
1354 else if (reloc_size
== 32 || reloc_size
== 24)
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
1365 fixP
->fx_offset
+= size
;