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;
530 fragP
->fr_literal
[offset
+ 1] = opcode
;
532 /* Create a fixup for the reversed conditional branch. */
533 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
534 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
535 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
536 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
538 /* Now create the unconditional branch + fixup to the
540 fragP
->fr_literal
[offset
+ 3] = 0xfc;
541 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
542 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
546 else if (fragP
->fr_subtype
== 5)
548 /* Reverse the condition of the first branch. */
549 int offset
= fragP
->fr_fix
;
550 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
610 fragP
->fr_literal
[offset
+ 1] = opcode
;
612 /* Create a fixup for the reversed conditional branch. */
613 sprintf (buf
, ".%s_%ld", FAKE_LABEL_NAME
, label_count
++);
614 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
615 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
616 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
618 /* Now create the unconditional branch + fixup to the
620 fragP
->fr_literal
[offset
+ 3] = 0xf4;
621 fragP
->fr_literal
[offset
+ 4] = 0xe0;
622 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
623 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
627 else if (fragP
->fr_subtype
== 6)
629 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
630 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
634 else if (fragP
->fr_subtype
== 7)
636 int offset
= fragP
->fr_fix
;
637 fragP
->fr_literal
[offset
] = 0xf4;
638 fragP
->fr_literal
[offset
+ 1] = 0xe1;
640 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
641 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
645 else if (fragP
->fr_subtype
== 8)
647 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
648 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
649 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
653 else if (fragP
->fr_subtype
== 9)
655 int offset
= fragP
->fr_fix
;
656 fragP
->fr_literal
[offset
] = 0xfc;
658 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
659 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
663 else if (fragP
->fr_subtype
== 10)
665 int offset
= fragP
->fr_fix
;
666 fragP
->fr_literal
[offset
] = 0xf4;
667 fragP
->fr_literal
[offset
+ 1] = 0xe0;
669 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
670 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
679 md_section_align (asection
*seg
, valueT addr
)
681 int align
= bfd_get_section_alignment (stdoutput
, seg
);
682 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
688 char *prev_name
= "";
689 register const struct mn10200_opcode
*op
;
691 mn10200_hash
= hash_new ();
693 /* Insert unique names into hash table. The MN10200 instruction set
694 has many identical opcode names that have different opcodes based
695 on the operands. This hash table then provides a quick index to
696 the first opcode with a particular name in the opcode table. */
698 op
= mn10200_opcodes
;
701 if (strcmp (prev_name
, op
->name
))
703 prev_name
= (char *) op
->name
;
704 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
709 /* This is both a simplification (we don't have to write md_apply_fix)
710 and support for future optimizations (branch shortening and similar
711 stuff in the linker. */
716 check_operand (unsigned long insn ATTRIBUTE_UNUSED
,
717 const struct mn10200_operand
*operand
,
720 /* No need to check 24bit or 32bit operands for a bit. */
721 if (operand
->bits
< 24
722 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
727 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
729 max
= (1 << (operand
->bits
- 1)) - 1;
730 min
= - (1 << (operand
->bits
- 1));
734 max
= (1 << operand
->bits
) - 1;
740 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
747 /* If while processing a fixup, a reloc really needs to be created
748 Then it is done here. */
751 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
754 reloc
= xmalloc (sizeof (arelent
));
756 if (fixp
->fx_subsy
!= NULL
)
758 if (S_GET_SEGMENT (fixp
->fx_addsy
) == S_GET_SEGMENT (fixp
->fx_subsy
)
759 && S_IS_DEFINED (fixp
->fx_subsy
))
761 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
762 fixp
->fx_subsy
= NULL
;
765 /* FIXME: We should try more ways to resolve difference expressions
766 here. At least this is better than silently ignoring the
768 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
769 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
770 fixp
->fx_addsy
? S_GET_NAME (fixp
->fx_addsy
) : "0",
771 segment_name (fixp
->fx_addsy
772 ? S_GET_SEGMENT (fixp
->fx_addsy
)
774 S_GET_NAME (fixp
->fx_subsy
),
775 segment_name (S_GET_SEGMENT (fixp
->fx_addsy
)));
778 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
779 if (reloc
->howto
== NULL
)
781 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
782 _("reloc %d not supported by object file format"),
783 (int) fixp
->fx_r_type
);
786 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
787 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
788 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
789 reloc
->addend
= fixp
->fx_offset
;
794 md_estimate_size_before_relax (fragS
*fragp
, asection
*seg
)
796 if (fragp
->fr_subtype
== 6
797 && (!S_IS_DEFINED (fragp
->fr_symbol
)
798 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
799 fragp
->fr_subtype
= 7;
800 else if (fragp
->fr_subtype
== 8
801 && (!S_IS_DEFINED (fragp
->fr_symbol
)
802 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
803 fragp
->fr_subtype
= 10;
805 if (fragp
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
808 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
812 md_pcrel_from (fixS
*fixp
)
814 return fixp
->fx_frag
->fr_address
;
818 md_apply_fix (fixS
* fixP
, valueT
* valP ATTRIBUTE_UNUSED
, segT seg ATTRIBUTE_UNUSED
)
820 /* We shouldn't ever get here because linkrelax is nonzero. */
825 /* Insert an operand value into an instruction. */
828 mn10200_insert_operand (unsigned long *insnp
,
829 unsigned long *extensionp
,
830 const struct mn10200_operand
*operand
,
836 /* No need to check 24 or 32bit operands for a bit. */
837 if (operand
->bits
< 24
838 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
843 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
845 max
= (1 << (operand
->bits
- 1)) - 1;
846 min
= - (1 << (operand
->bits
- 1));
850 max
= (1 << operand
->bits
) - 1;
856 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
857 as_warn_value_out_of_range (_("operand"), test
, (offsetT
) min
, (offsetT
) max
, file
, line
);
860 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
862 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
863 << (operand
->shift
+ shift
));
865 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
866 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
867 << (operand
->shift
+ shift
+ 2));
871 *extensionp
|= (val
>> 16) & 0xff;
872 *insnp
|= val
& 0xffff;
877 md_assemble (char *str
)
880 struct mn10200_opcode
*opcode
;
881 struct mn10200_opcode
*next_opcode
;
882 const unsigned char *opindex_ptr
;
883 int next_opindex
, relaxable
;
884 unsigned long insn
, extension
, size
= 0;
889 /* Get the opcode. */
890 for (s
= str
; *s
!= '\0' && !ISSPACE (*s
); s
++)
895 /* Find the first opcode with the proper name. */
896 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
899 as_bad (_("Unrecognized opcode: `%s'"), str
);
904 while (ISSPACE (*str
))
907 input_line_pointer
= str
;
911 const char *errmsg
= NULL
;
920 insn
= opcode
->opcode
;
922 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
924 opindex_ptr
++, op_idx
++)
926 const struct mn10200_operand
*operand
;
929 if (next_opindex
== 0)
931 operand
= &mn10200_operands
[*opindex_ptr
];
935 operand
= &mn10200_operands
[next_opindex
];
941 while (*str
== ' ' || *str
== ',')
944 if (operand
->flags
& MN10200_OPERAND_RELAX
)
947 /* Gather the operand. */
948 hold
= input_line_pointer
;
949 input_line_pointer
= str
;
951 if (operand
->flags
& MN10200_OPERAND_PAREN
)
953 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
955 input_line_pointer
= hold
;
959 input_line_pointer
++;
962 /* See if we can match the operands. */
963 else if (operand
->flags
& MN10200_OPERAND_DREG
)
965 if (!data_register_name (&ex
))
967 input_line_pointer
= hold
;
972 else if (operand
->flags
& MN10200_OPERAND_AREG
)
974 if (!address_register_name (&ex
))
976 input_line_pointer
= hold
;
981 else if (operand
->flags
& MN10200_OPERAND_PSW
)
983 char *start
= input_line_pointer
;
984 char c
= get_symbol_end ();
986 if (strcmp (start
, "psw") != 0)
988 *input_line_pointer
= c
;
989 input_line_pointer
= hold
;
993 *input_line_pointer
= c
;
996 else if (operand
->flags
& MN10200_OPERAND_MDR
)
998 char *start
= input_line_pointer
;
999 char c
= get_symbol_end ();
1001 if (strcmp (start
, "mdr") != 0)
1003 *input_line_pointer
= c
;
1004 input_line_pointer
= hold
;
1008 *input_line_pointer
= c
;
1011 else if (data_register_name (&ex
))
1013 input_line_pointer
= hold
;
1017 else if (address_register_name (&ex
))
1019 input_line_pointer
= hold
;
1023 else if (other_register_name (&ex
))
1025 input_line_pointer
= hold
;
1029 else if (*str
== ')' || *str
== '(')
1031 input_line_pointer
= hold
;
1043 errmsg
= _("illegal operand");
1046 errmsg
= _("missing operand");
1050 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
1052 input_line_pointer
= hold
;
1057 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
1059 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
1060 || opcode
->format
== FMT_7
)
1065 mn10200_insert_operand (&insn
, &extension
, operand
,
1066 ex
.X_add_number
, NULL
,
1072 /* If this operand can be promoted, and it doesn't
1073 fit into the allocated bitfield for this insn,
1074 then promote it (ie this opcode does not match). */
1076 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
1077 && !check_operand (insn
, operand
, ex
.X_add_number
))
1079 input_line_pointer
= hold
;
1084 mn10200_insert_operand (&insn
, &extension
, operand
,
1085 ex
.X_add_number
, NULL
,
1090 /* If this operand can be promoted, then this opcode didn't
1091 match since we can't know if it needed promotion! */
1092 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
1094 input_line_pointer
= hold
;
1099 /* We need to generate a fixup for this expression. */
1100 if (fc
>= MAX_INSN_FIXUPS
)
1101 as_fatal (_("too many fixups"));
1102 fixups
[fc
].exp
= ex
;
1103 fixups
[fc
].opindex
= *opindex_ptr
;
1104 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
1110 str
= input_line_pointer
;
1111 input_line_pointer
= hold
;
1113 while (*str
== ' ' || *str
== ',')
1118 /* Make sure we used all the operands! */
1125 next_opcode
= opcode
+ 1;
1126 if (!strcmp (next_opcode
->name
, opcode
->name
))
1128 opcode
= next_opcode
;
1132 as_bad ("%s", errmsg
);
1138 while (ISSPACE (*str
))
1142 as_bad (_("junk at end of line: `%s'"), str
);
1144 input_line_pointer
= str
;
1146 if (opcode
->format
== FMT_1
)
1148 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1150 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1152 else if (opcode
->format
== FMT_6
)
1154 else if (opcode
->format
== FMT_7
)
1159 /* Write out the instruction. */
1160 dwarf2_emit_insn (0);
1161 if (relaxable
&& fc
> 0)
1163 /* On a 64-bit host the size of an 'int' is not the same
1164 as the size of a pointer, so we need a union to convert
1165 the opindex field of the fr_cgen structure into a char *
1166 so that it can be stored in the frag. We do not have
1167 to worry about loosing accuracy as we are not going to
1168 be even close to the 32bit limit of the int. */
1178 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1180 /* Handle bra specially. Basically treat it like jmp so
1181 that we automatically handle 8, 16 and 32 bit offsets
1182 correctly as well as jumps to an undefined address.
1184 It is also important to not treat it like other bCC
1185 instructions since the long forms of bra is different
1186 from other bCC instructions. */
1187 if (opcode
->opcode
== 0xea00)
1193 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1196 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1202 opindex_converter
.opindex
= fixups
[0].opindex
;
1203 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1204 fixups
[0].exp
.X_add_symbol
,
1205 fixups
[0].exp
.X_add_number
,
1206 opindex_converter
.ptr
);
1207 number_to_chars_bigendian (f
, insn
, size
);
1210 number_to_chars_bigendian (f
+ size
, 0, 4);
1211 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1214 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1218 f
= frag_more (size
);
1220 /* Oh, what a mess. The instruction is in big endian format, but
1221 16 and 24bit immediates are little endian! */
1222 if (opcode
->format
== FMT_3
)
1224 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1225 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1227 else if (opcode
->format
== FMT_6
)
1229 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1230 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1232 else if (opcode
->format
== FMT_7
)
1234 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1235 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1236 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1239 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1241 /* Create any fixups. */
1242 for (i
= 0; i
< fc
; i
++)
1244 const struct mn10200_operand
*operand
;
1247 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1248 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1250 reloc_howto_type
*reloc_howto
;
1254 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1260 reloc_size
= bfd_get_reloc_size (reloc_howto
);
1262 if (reloc_size
< 1 || reloc_size
> 4)
1265 offset
= 4 - reloc_size
;
1266 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1269 reloc_howto
->pc_relative
,
1272 /* PC-relative offsets are from the first byte of the
1273 next instruction, not from the start of the current
1275 if (reloc_howto
->pc_relative
)
1276 fixP
->fx_offset
+= reloc_size
;
1280 int reloc
, pcrel
, offset
;
1283 reloc
= BFD_RELOC_NONE
;
1284 /* How big is the reloc? Remember SPLIT relocs are
1285 implicitly 32bits. */
1286 reloc_size
= operand
->bits
;
1288 offset
= size
- reloc_size
/ 8;
1290 /* Is the reloc pc-relative? */
1291 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1293 /* Choose a proper BFD relocation type. */
1296 if (reloc_size
== 8)
1297 reloc
= BFD_RELOC_8_PCREL
;
1298 else if (reloc_size
== 24)
1299 reloc
= BFD_RELOC_24_PCREL
;
1305 if (reloc_size
== 32)
1306 reloc
= BFD_RELOC_32
;
1307 else if (reloc_size
== 16)
1308 reloc
= BFD_RELOC_16
;
1309 else if (reloc_size
== 8)
1310 reloc
= BFD_RELOC_8
;
1311 else if (reloc_size
== 24)
1312 reloc
= BFD_RELOC_24
;
1317 /* Convert the size of the reloc into what fix_new_exp
1319 reloc_size
= reloc_size
/ 8;
1320 if (reloc_size
== 8)
1322 else if (reloc_size
== 16)
1324 else if (reloc_size
== 32 || reloc_size
== 24)
1327 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1328 reloc_size
, &fixups
[i
].exp
, pcrel
,
1329 ((bfd_reloc_code_real_type
) reloc
));
1331 /* PC-relative offsets are from the first byte of the
1332 next instruction, not from the start of the current
1335 fixP
->fx_offset
+= size
;