1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2009 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 3, 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
)
324 return ieee_md_atof (type
, litp
, sizep
, FALSE
);
328 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
332 static unsigned long label_count
= 0;
335 subseg_change (sec
, 0);
336 if (fragP
->fr_subtype
== 0)
338 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
339 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
343 else if (fragP
->fr_subtype
== 1)
345 /* Reverse the condition of the first branch. */
346 int offset
= fragP
->fr_fix
;
347 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
384 fragP
->fr_literal
[offset
] = opcode
;
386 /* Create a fixup for the reversed conditional branch. */
387 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
388 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
389 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
390 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
392 /* Now create the unconditional branch + fixup to the
394 fragP
->fr_literal
[offset
+ 2] = 0xfc;
395 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
396 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
400 else if (fragP
->fr_subtype
== 2)
402 /* Reverse the condition of the first branch. */
403 int offset
= fragP
->fr_fix
;
404 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
441 fragP
->fr_literal
[offset
] = opcode
;
443 /* Create a fixup for the reversed conditional branch. */
444 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
445 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
446 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
447 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
449 /* Now create the unconditional branch + fixup to the
451 fragP
->fr_literal
[offset
+ 2] = 0xf4;
452 fragP
->fr_literal
[offset
+ 3] = 0xe0;
453 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
454 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
458 else if (fragP
->fr_subtype
== 3)
460 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
461 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
465 else if (fragP
->fr_subtype
== 4)
467 /* Reverse the condition of the first branch. */
468 int offset
= fragP
->fr_fix
;
469 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
529 fragP
->fr_literal
[offset
+ 1] = opcode
;
531 /* Create a fixup for the reversed conditional branch. */
532 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
533 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
534 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
535 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
537 /* Now create the unconditional branch + fixup to the
539 fragP
->fr_literal
[offset
+ 3] = 0xfc;
540 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
541 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
545 else if (fragP
->fr_subtype
== 5)
547 /* Reverse the condition of the first branch. */
548 int offset
= fragP
->fr_fix
;
549 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
609 fragP
->fr_literal
[offset
+ 1] = opcode
;
611 /* Create a fixup for the reversed conditional branch. */
612 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
613 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
614 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
615 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
617 /* Now create the unconditional branch + fixup to the
619 fragP
->fr_literal
[offset
+ 3] = 0xf4;
620 fragP
->fr_literal
[offset
+ 4] = 0xe0;
621 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
622 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
626 else if (fragP
->fr_subtype
== 6)
628 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
629 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
633 else if (fragP
->fr_subtype
== 7)
635 int offset
= fragP
->fr_fix
;
636 fragP
->fr_literal
[offset
] = 0xf4;
637 fragP
->fr_literal
[offset
+ 1] = 0xe1;
639 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
640 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
644 else if (fragP
->fr_subtype
== 8)
646 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
647 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
648 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
652 else if (fragP
->fr_subtype
== 9)
654 int offset
= fragP
->fr_fix
;
655 fragP
->fr_literal
[offset
] = 0xfc;
657 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
658 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
662 else if (fragP
->fr_subtype
== 10)
664 int offset
= fragP
->fr_fix
;
665 fragP
->fr_literal
[offset
] = 0xf4;
666 fragP
->fr_literal
[offset
+ 1] = 0xe0;
668 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
669 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
678 md_section_align (asection
*seg
, valueT addr
)
680 int align
= bfd_get_section_alignment (stdoutput
, seg
);
681 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
687 char *prev_name
= "";
688 register const struct mn10200_opcode
*op
;
690 mn10200_hash
= hash_new ();
692 /* Insert unique names into hash table. The MN10200 instruction set
693 has many identical opcode names that have different opcodes based
694 on the operands. This hash table then provides a quick index to
695 the first opcode with a particular name in the opcode table. */
697 op
= mn10200_opcodes
;
700 if (strcmp (prev_name
, op
->name
))
702 prev_name
= (char *) op
->name
;
703 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
708 /* This is both a simplification (we don't have to write md_apply_fix)
709 and support for future optimizations (branch shortening and similar
710 stuff in the linker. */
715 check_operand (unsigned long insn ATTRIBUTE_UNUSED
,
716 const struct mn10200_operand
*operand
,
719 /* No need to check 24bit or 32bit operands for a bit. */
720 if (operand
->bits
< 24
721 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
726 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
728 max
= (1 << (operand
->bits
- 1)) - 1;
729 min
= - (1 << (operand
->bits
- 1));
733 max
= (1 << operand
->bits
) - 1;
739 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
746 /* If while processing a fixup, a reloc really needs to be created
747 Then it is done here. */
750 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
753 reloc
= xmalloc (sizeof (arelent
));
755 if (fixp
->fx_subsy
!= NULL
)
757 if (S_GET_SEGMENT (fixp
->fx_addsy
) == S_GET_SEGMENT (fixp
->fx_subsy
)
758 && S_IS_DEFINED (fixp
->fx_subsy
))
760 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
761 fixp
->fx_subsy
= NULL
;
764 /* FIXME: We should try more ways to resolve difference expressions
765 here. At least this is better than silently ignoring the
767 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
768 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
769 fixp
->fx_addsy
? S_GET_NAME (fixp
->fx_addsy
) : "0",
770 segment_name (fixp
->fx_addsy
771 ? S_GET_SEGMENT (fixp
->fx_addsy
)
773 S_GET_NAME (fixp
->fx_subsy
),
774 segment_name (S_GET_SEGMENT (fixp
->fx_addsy
)));
777 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
778 if (reloc
->howto
== NULL
)
780 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
781 _("reloc %d not supported by object file format"),
782 (int) fixp
->fx_r_type
);
785 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
786 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
787 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
788 reloc
->addend
= fixp
->fx_offset
;
793 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
795 if (fragp
->fr_subtype
== 6
796 && (!S_IS_DEFINED (fragp
->fr_symbol
)
797 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
798 fragp
->fr_subtype
= 7;
799 else if (fragp
->fr_subtype
== 8
800 && (!S_IS_DEFINED (fragp
->fr_symbol
)
801 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
802 fragp
->fr_subtype
= 10;
804 if (fragp
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
807 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
811 md_pcrel_from (fixS
*fixp
)
813 return fixp
->fx_frag
->fr_address
;
817 md_apply_fix (fixS
* fixP
, valueT
* valP ATTRIBUTE_UNUSED
, segT seg ATTRIBUTE_UNUSED
)
819 /* We shouldn't ever get here because linkrelax is nonzero. */
824 /* Insert an operand value into an instruction. */
827 mn10200_insert_operand (unsigned long *insnp
,
828 unsigned long *extensionp
,
829 const struct mn10200_operand
*operand
,
835 /* No need to check 24 or 32bit operands for a bit. */
836 if (operand
->bits
< 24
837 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
842 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
844 max
= (1 << (operand
->bits
- 1)) - 1;
845 min
= - (1 << (operand
->bits
- 1));
849 max
= (1 << operand
->bits
) - 1;
855 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
856 as_warn_value_out_of_range (_("operand"), test
, (offsetT
) min
, (offsetT
) max
, file
, line
);
859 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
861 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
862 << (operand
->shift
+ shift
));
864 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
865 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
866 << (operand
->shift
+ shift
+ 2));
870 *extensionp
|= (val
>> 16) & 0xff;
871 *insnp
|= val
& 0xffff;
876 md_assemble (char *str
)
879 struct mn10200_opcode
*opcode
;
880 struct mn10200_opcode
*next_opcode
;
881 const unsigned char *opindex_ptr
;
882 int next_opindex
, relaxable
;
883 unsigned long insn
, extension
, size
= 0;
888 /* Get the opcode. */
889 for (s
= str
; *s
!= '\0' && !ISSPACE (*s
); s
++)
894 /* Find the first opcode with the proper name. */
895 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
898 as_bad (_("Unrecognized opcode: `%s'"), str
);
903 while (ISSPACE (*str
))
906 input_line_pointer
= str
;
910 const char *errmsg
= NULL
;
919 insn
= opcode
->opcode
;
921 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
923 opindex_ptr
++, op_idx
++)
925 const struct mn10200_operand
*operand
;
928 if (next_opindex
== 0)
930 operand
= &mn10200_operands
[*opindex_ptr
];
934 operand
= &mn10200_operands
[next_opindex
];
940 while (*str
== ' ' || *str
== ',')
943 if (operand
->flags
& MN10200_OPERAND_RELAX
)
946 /* Gather the operand. */
947 hold
= input_line_pointer
;
948 input_line_pointer
= str
;
950 if (operand
->flags
& MN10200_OPERAND_PAREN
)
952 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
954 input_line_pointer
= hold
;
958 input_line_pointer
++;
961 /* See if we can match the operands. */
962 else if (operand
->flags
& MN10200_OPERAND_DREG
)
964 if (!data_register_name (&ex
))
966 input_line_pointer
= hold
;
971 else if (operand
->flags
& MN10200_OPERAND_AREG
)
973 if (!address_register_name (&ex
))
975 input_line_pointer
= hold
;
980 else if (operand
->flags
& MN10200_OPERAND_PSW
)
982 char *start
= input_line_pointer
;
983 char c
= get_symbol_end ();
985 if (strcmp (start
, "psw") != 0)
987 *input_line_pointer
= c
;
988 input_line_pointer
= hold
;
992 *input_line_pointer
= c
;
995 else if (operand
->flags
& MN10200_OPERAND_MDR
)
997 char *start
= input_line_pointer
;
998 char c
= get_symbol_end ();
1000 if (strcmp (start
, "mdr") != 0)
1002 *input_line_pointer
= c
;
1003 input_line_pointer
= hold
;
1007 *input_line_pointer
= c
;
1010 else if (data_register_name (&ex
))
1012 input_line_pointer
= hold
;
1016 else if (address_register_name (&ex
))
1018 input_line_pointer
= hold
;
1022 else if (other_register_name (&ex
))
1024 input_line_pointer
= hold
;
1028 else if (*str
== ')' || *str
== '(')
1030 input_line_pointer
= hold
;
1042 errmsg
= _("illegal operand");
1045 errmsg
= _("missing operand");
1049 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
1051 input_line_pointer
= hold
;
1056 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
1058 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
1059 || opcode
->format
== FMT_7
)
1064 mn10200_insert_operand (&insn
, &extension
, operand
,
1065 ex
.X_add_number
, NULL
,
1071 /* If this operand can be promoted, and it doesn't
1072 fit into the allocated bitfield for this insn,
1073 then promote it (ie this opcode does not match). */
1075 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
1076 && !check_operand (insn
, operand
, ex
.X_add_number
))
1078 input_line_pointer
= hold
;
1083 mn10200_insert_operand (&insn
, &extension
, operand
,
1084 ex
.X_add_number
, NULL
,
1089 /* If this operand can be promoted, then this opcode didn't
1090 match since we can't know if it needed promotion! */
1091 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
1093 input_line_pointer
= hold
;
1098 /* We need to generate a fixup for this expression. */
1099 if (fc
>= MAX_INSN_FIXUPS
)
1100 as_fatal (_("too many fixups"));
1101 fixups
[fc
].exp
= ex
;
1102 fixups
[fc
].opindex
= *opindex_ptr
;
1103 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
1109 str
= input_line_pointer
;
1110 input_line_pointer
= hold
;
1112 while (*str
== ' ' || *str
== ',')
1117 /* Make sure we used all the operands! */
1124 next_opcode
= opcode
+ 1;
1125 if (!strcmp (next_opcode
->name
, opcode
->name
))
1127 opcode
= next_opcode
;
1131 as_bad ("%s", errmsg
);
1137 while (ISSPACE (*str
))
1141 as_bad (_("junk at end of line: `%s'"), str
);
1143 input_line_pointer
= str
;
1145 if (opcode
->format
== FMT_1
)
1147 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1149 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1151 else if (opcode
->format
== FMT_6
)
1153 else if (opcode
->format
== FMT_7
)
1158 /* Write out the instruction. */
1159 dwarf2_emit_insn (0);
1160 if (relaxable
&& fc
> 0)
1162 /* On a 64-bit host the size of an 'int' is not the same
1163 as the size of a pointer, so we need a union to convert
1164 the opindex field of the fr_cgen structure into a char *
1165 so that it can be stored in the frag. We do not have
1166 to worry about loosing accuracy as we are not going to
1167 be even close to the 32bit limit of the int. */
1177 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1179 /* Handle bra specially. Basically treat it like jmp so
1180 that we automatically handle 8, 16 and 32 bit offsets
1181 correctly as well as jumps to an undefined address.
1183 It is also important to not treat it like other bCC
1184 instructions since the long forms of bra is different
1185 from other bCC instructions. */
1186 if (opcode
->opcode
== 0xea00)
1192 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1195 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1201 opindex_converter
.opindex
= fixups
[0].opindex
;
1202 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1203 fixups
[0].exp
.X_add_symbol
,
1204 fixups
[0].exp
.X_add_number
,
1205 opindex_converter
.ptr
);
1206 number_to_chars_bigendian (f
, insn
, size
);
1209 number_to_chars_bigendian (f
+ size
, 0, 4);
1210 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1213 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1217 f
= frag_more (size
);
1219 /* Oh, what a mess. The instruction is in big endian format, but
1220 16 and 24bit immediates are little endian! */
1221 if (opcode
->format
== FMT_3
)
1223 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1224 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1226 else if (opcode
->format
== FMT_6
)
1228 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1229 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1231 else if (opcode
->format
== FMT_7
)
1233 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1234 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1235 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1238 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1240 /* Create any fixups. */
1241 for (i
= 0; i
< fc
; i
++)
1243 const struct mn10200_operand
*operand
;
1246 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1247 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1249 reloc_howto_type
*reloc_howto
;
1253 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1259 reloc_size
= bfd_get_reloc_size (reloc_howto
);
1261 if (reloc_size
< 1 || reloc_size
> 4)
1264 offset
= 4 - reloc_size
;
1265 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1268 reloc_howto
->pc_relative
,
1271 /* PC-relative offsets are from the first byte of the
1272 next instruction, not from the start of the current
1274 if (reloc_howto
->pc_relative
)
1275 fixP
->fx_offset
+= reloc_size
;
1279 int reloc
, pcrel
, offset
;
1282 reloc
= BFD_RELOC_NONE
;
1283 /* How big is the reloc? Remember SPLIT relocs are
1284 implicitly 32bits. */
1285 reloc_size
= operand
->bits
;
1287 offset
= size
- reloc_size
/ 8;
1289 /* Is the reloc pc-relative? */
1290 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1292 /* Choose a proper BFD relocation type. */
1295 if (reloc_size
== 8)
1296 reloc
= BFD_RELOC_8_PCREL
;
1297 else if (reloc_size
== 24)
1298 reloc
= BFD_RELOC_24_PCREL
;
1304 if (reloc_size
== 32)
1305 reloc
= BFD_RELOC_32
;
1306 else if (reloc_size
== 16)
1307 reloc
= BFD_RELOC_16
;
1308 else if (reloc_size
== 8)
1309 reloc
= BFD_RELOC_8
;
1310 else if (reloc_size
== 24)
1311 reloc
= BFD_RELOC_24
;
1316 /* Convert the size of the reloc into what fix_new_exp
1318 reloc_size
= reloc_size
/ 8;
1319 if (reloc_size
== 8)
1321 else if (reloc_size
== 16)
1323 else if (reloc_size
== 32 || reloc_size
== 24)
1326 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1327 reloc_size
, &fixups
[i
].exp
, pcrel
,
1328 ((bfd_reloc_code_real_type
) reloc
));
1330 /* PC-relative offsets are from the first byte of the
1331 next instruction, not from the start of the current
1334 fixP
->fx_offset
+= size
;