1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001
3 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. */
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
[] = {
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},
75 /* Local functions. */
76 static void mn10200_insert_operand
PARAMS ((unsigned long *, unsigned long *,
77 const struct mn10200_operand
*,
78 offsetT
, char *, unsigned,
80 static unsigned long check_operand
PARAMS ((unsigned long,
81 const struct mn10200_operand
*,
83 static int reg_name_search
PARAMS ((const struct reg_name
*, int, const char *));
84 static boolean data_register_name
PARAMS ((expressionS
*expressionP
));
85 static boolean address_register_name
PARAMS ((expressionS
*expressionP
));
86 static boolean other_register_name
PARAMS ((expressionS
*expressionP
));
89 #define MAX_INSN_FIXUPS (5)
94 bfd_reloc_code_real_type reloc
;
96 struct mn10200_fixup fixups
[MAX_INSN_FIXUPS
];
99 const char *md_shortopts
= "";
100 struct option md_longopts
[] = {
101 {NULL
, no_argument
, NULL
, 0}
103 size_t md_longopts_size
= sizeof (md_longopts
);
105 /* The target specific pseudo-ops which we support. */
106 const pseudo_typeS md_pseudo_table
[] =
111 /* Opcode hash table. */
112 static struct hash_control
*mn10200_hash
;
114 /* This table is sorted. Suitable for searching by a binary search. */
115 static const struct reg_name data_registers
[] =
122 #define DATA_REG_NAME_CNT \
123 (sizeof (data_registers) / sizeof (struct reg_name))
125 static const struct reg_name address_registers
[] =
132 #define ADDRESS_REG_NAME_CNT \
133 (sizeof (address_registers) / sizeof (struct reg_name))
135 static const struct reg_name other_registers
[] =
140 #define OTHER_REG_NAME_CNT \
141 (sizeof (other_registers) / sizeof (struct reg_name))
143 /* reg_name_search does a binary search of the given register table
144 to see if "name" is a valid regiter name. Returns the register
145 number from the array on success, or -1 on failure. */
148 reg_name_search (regs
, regcount
, name
)
149 const struct reg_name
*regs
;
153 int middle
, low
, high
;
161 middle
= (low
+ high
) / 2;
162 cmp
= strcasecmp (name
, regs
[middle
].name
);
168 return regs
[middle
].value
;
174 /* Summary of register_name().
176 * in: Input_line_pointer points to 1st char of operand.
178 * out: A expressionS.
179 * The operand may have been a register: in this case, X_op == O_register,
180 * X_add_number is set to the register number, and truth is returned.
181 * Input_line_pointer->(next non-blank) char after operand, or is in
182 * its original state.
186 data_register_name (expressionP
)
187 expressionS
*expressionP
;
194 /* Find the spelling of the operand. */
195 start
= name
= input_line_pointer
;
197 c
= get_symbol_end ();
198 reg_number
= reg_name_search (data_registers
, DATA_REG_NAME_CNT
, name
);
200 /* Look to see if it's in the register table. */
203 expressionP
->X_op
= O_register
;
204 expressionP
->X_add_number
= reg_number
;
206 /* Make the rest nice. */
207 expressionP
->X_add_symbol
= NULL
;
208 expressionP
->X_op_symbol
= NULL
;
210 /* Put back the delimiting char. */
211 *input_line_pointer
= c
;
216 /* Reset the line as if we had not done anything. */
217 /* Put back the delimiting char. */
218 *input_line_pointer
= c
;
220 /* Reset input_line pointer. */
221 input_line_pointer
= start
;
226 /* Summary of register_name().
228 * in: Input_line_pointer points to 1st char of operand.
230 * out: A expressionS.
231 * The operand may have been a register: in this case, X_op == O_register,
232 * X_add_number is set to the register number, and truth is returned.
233 * Input_line_pointer->(next non-blank) char after operand, or is in
234 * its original state.
238 address_register_name (expressionP
)
239 expressionS
*expressionP
;
246 /* Find the spelling of the operand. */
247 start
= name
= input_line_pointer
;
249 c
= get_symbol_end ();
250 reg_number
= reg_name_search (address_registers
, ADDRESS_REG_NAME_CNT
, name
);
252 /* Look to see if it's in the register table. */
255 expressionP
->X_op
= O_register
;
256 expressionP
->X_add_number
= reg_number
;
258 /* Make the rest nice. */
259 expressionP
->X_add_symbol
= NULL
;
260 expressionP
->X_op_symbol
= NULL
;
262 /* Put back the delimiting char. */
263 *input_line_pointer
= c
;
268 /* Reset the line as if we had not done anything. */
269 /* Put back the delimiting char. */
270 *input_line_pointer
= c
;
272 /* Reset input_line pointer. */
273 input_line_pointer
= start
;
278 /* Summary of register_name().
280 * in: Input_line_pointer points to 1st char of operand.
282 * out: A expressionS.
283 * The operand may have been a register: in this case, X_op == O_register,
284 * X_add_number is set to the register number, and truth is returned.
285 * Input_line_pointer->(next non-blank) char after operand, or is in
286 * its original state.
290 other_register_name (expressionP
)
291 expressionS
*expressionP
;
298 /* Find the spelling of the operand. */
299 start
= name
= input_line_pointer
;
301 c
= get_symbol_end ();
302 reg_number
= reg_name_search (other_registers
, OTHER_REG_NAME_CNT
, name
);
304 /* Look to see if it's in the register table. */
307 expressionP
->X_op
= O_register
;
308 expressionP
->X_add_number
= reg_number
;
310 /* Make the rest nice. */
311 expressionP
->X_add_symbol
= NULL
;
312 expressionP
->X_op_symbol
= NULL
;
314 /* Put back the delimiting char. */
315 *input_line_pointer
= c
;
320 /* Reset the line as if we had not done anything. */
321 /* Put back the delimiting char. */
322 *input_line_pointer
= c
;
324 /* Reset input_line pointer. */
325 input_line_pointer
= start
;
331 md_show_usage (stream
)
334 fprintf (stream
, _("MN10200 options:\n\
339 md_parse_option (c
, arg
)
347 md_undefined_symbol (name
)
354 md_atof (type
, litp
, sizep
)
360 LITTLENUM_TYPE words
[4];
376 return _("bad call to md_atof");
379 t
= atof_ieee (input_line_pointer
, type
, words
);
381 input_line_pointer
= t
;
385 for (i
= prec
- 1; i
>= 0; i
--)
387 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
395 md_convert_frag (abfd
, sec
, fragP
)
400 static unsigned long label_count
= 0;
403 subseg_change (sec
, 0);
404 if (fragP
->fr_subtype
== 0)
406 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
407 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
411 else if (fragP
->fr_subtype
== 1)
413 /* Reverse the condition of the first branch. */
414 int offset
= fragP
->fr_fix
;
415 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
452 fragP
->fr_literal
[offset
] = opcode
;
454 /* Create a fixup for the reversed conditional branch. */
455 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
456 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
457 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
458 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
460 /* Now create the unconditional branch + fixup to the
462 fragP
->fr_literal
[offset
+ 2] = 0xfc;
463 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
464 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
468 else if (fragP
->fr_subtype
== 2)
470 /* Reverse the condition of the first branch. */
471 int offset
= fragP
->fr_fix
;
472 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
509 fragP
->fr_literal
[offset
] = opcode
;
511 /* Create a fixup for the reversed conditional branch. */
512 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
513 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
514 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
515 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
517 /* Now create the unconditional branch + fixup to the
519 fragP
->fr_literal
[offset
+ 2] = 0xf4;
520 fragP
->fr_literal
[offset
+ 3] = 0xe0;
521 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
522 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
526 else if (fragP
->fr_subtype
== 3)
528 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
529 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
533 else if (fragP
->fr_subtype
== 4)
535 /* Reverse the condition of the first branch. */
536 int offset
= fragP
->fr_fix
;
537 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
597 fragP
->fr_literal
[offset
+ 1] = opcode
;
599 /* Create a fixup for the reversed conditional branch. */
600 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
601 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
602 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
603 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
605 /* Now create the unconditional branch + fixup to the
607 fragP
->fr_literal
[offset
+ 3] = 0xfc;
608 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
609 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
613 else if (fragP
->fr_subtype
== 5)
615 /* Reverse the condition of the first branch. */
616 int offset
= fragP
->fr_fix
;
617 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
677 fragP
->fr_literal
[offset
+ 1] = opcode
;
679 /* Create a fixup for the reversed conditional branch. */
680 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
681 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
682 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
683 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
685 /* Now create the unconditional branch + fixup to the
687 fragP
->fr_literal
[offset
+ 3] = 0xf4;
688 fragP
->fr_literal
[offset
+ 4] = 0xe0;
689 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
690 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
694 else if (fragP
->fr_subtype
== 6)
696 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
697 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
701 else if (fragP
->fr_subtype
== 7)
703 int offset
= fragP
->fr_fix
;
704 fragP
->fr_literal
[offset
] = 0xf4;
705 fragP
->fr_literal
[offset
+ 1] = 0xe1;
707 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
708 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
712 else if (fragP
->fr_subtype
== 8)
714 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
715 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
716 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
720 else if (fragP
->fr_subtype
== 9)
722 int offset
= fragP
->fr_fix
;
723 fragP
->fr_literal
[offset
] = 0xfc;
725 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
726 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
730 else if (fragP
->fr_subtype
== 10)
732 int offset
= fragP
->fr_fix
;
733 fragP
->fr_literal
[offset
] = 0xf4;
734 fragP
->fr_literal
[offset
+ 1] = 0xe0;
736 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
737 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
746 md_section_align (seg
, addr
)
750 int align
= bfd_get_section_alignment (stdoutput
, seg
);
751 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
757 char *prev_name
= "";
758 register const struct mn10200_opcode
*op
;
760 mn10200_hash
= hash_new ();
762 /* Insert unique names into hash table. The MN10200 instruction set
763 has many identical opcode names that have different opcodes based
764 on the operands. This hash table then provides a quick index to
765 the first opcode with a particular name in the opcode table. */
767 op
= mn10200_opcodes
;
770 if (strcmp (prev_name
, op
->name
))
772 prev_name
= (char *) op
->name
;
773 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
778 /* This is both a simplification (we don't have to write md_apply_fix)
779 and support for future optimizations (branch shortening and similar
780 stuff in the linker. */
789 struct mn10200_opcode
*opcode
;
790 struct mn10200_opcode
*next_opcode
;
791 const unsigned char *opindex_ptr
;
792 int next_opindex
, relaxable
;
793 unsigned long insn
, extension
, size
= 0;
798 /* Get the opcode. */
799 for (s
= str
; *s
!= '\0' && !isspace (*s
); s
++)
804 /* Find the first opcode with the proper name. */
805 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
808 as_bad (_("Unrecognized opcode: `%s'"), str
);
813 while (isspace (*str
))
816 input_line_pointer
= str
;
820 const char *errmsg
= NULL
;
829 insn
= opcode
->opcode
;
831 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
833 opindex_ptr
++, op_idx
++)
835 const struct mn10200_operand
*operand
;
838 if (next_opindex
== 0)
840 operand
= &mn10200_operands
[*opindex_ptr
];
844 operand
= &mn10200_operands
[next_opindex
];
850 while (*str
== ' ' || *str
== ',')
853 if (operand
->flags
& MN10200_OPERAND_RELAX
)
856 /* Gather the operand. */
857 hold
= input_line_pointer
;
858 input_line_pointer
= str
;
860 if (operand
->flags
& MN10200_OPERAND_PAREN
)
862 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
864 input_line_pointer
= hold
;
868 input_line_pointer
++;
871 /* See if we can match the operands. */
872 else if (operand
->flags
& MN10200_OPERAND_DREG
)
874 if (!data_register_name (&ex
))
876 input_line_pointer
= hold
;
881 else if (operand
->flags
& MN10200_OPERAND_AREG
)
883 if (!address_register_name (&ex
))
885 input_line_pointer
= hold
;
890 else if (operand
->flags
& MN10200_OPERAND_PSW
)
892 char *start
= input_line_pointer
;
893 char c
= get_symbol_end ();
895 if (strcmp (start
, "psw") != 0)
897 *input_line_pointer
= c
;
898 input_line_pointer
= hold
;
902 *input_line_pointer
= c
;
905 else if (operand
->flags
& MN10200_OPERAND_MDR
)
907 char *start
= input_line_pointer
;
908 char c
= get_symbol_end ();
910 if (strcmp (start
, "mdr") != 0)
912 *input_line_pointer
= c
;
913 input_line_pointer
= hold
;
917 *input_line_pointer
= c
;
920 else if (data_register_name (&ex
))
922 input_line_pointer
= hold
;
926 else if (address_register_name (&ex
))
928 input_line_pointer
= hold
;
932 else if (other_register_name (&ex
))
934 input_line_pointer
= hold
;
938 else if (*str
== ')' || *str
== '(')
940 input_line_pointer
= hold
;
952 errmsg
= _("illegal operand");
955 errmsg
= _("missing operand");
959 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
961 input_line_pointer
= hold
;
966 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
968 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
969 || opcode
->format
== FMT_7
)
974 mn10200_insert_operand (&insn
, &extension
, operand
,
975 ex
.X_add_number
, (char *) NULL
,
981 /* If this operand can be promoted, and it doesn't
982 fit into the allocated bitfield for this insn,
983 then promote it (ie this opcode does not match). */
985 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
986 && !check_operand (insn
, operand
, ex
.X_add_number
))
988 input_line_pointer
= hold
;
993 mn10200_insert_operand (&insn
, &extension
, operand
,
994 ex
.X_add_number
, (char *) NULL
,
999 /* If this operand can be promoted, then this opcode didn't
1000 match since we can't know if it needed promotion! */
1001 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
1003 input_line_pointer
= hold
;
1008 /* We need to generate a fixup for this expression. */
1009 if (fc
>= MAX_INSN_FIXUPS
)
1010 as_fatal (_("too many fixups"));
1011 fixups
[fc
].exp
= ex
;
1012 fixups
[fc
].opindex
= *opindex_ptr
;
1013 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
1019 str
= input_line_pointer
;
1020 input_line_pointer
= hold
;
1022 while (*str
== ' ' || *str
== ',')
1027 /* Make sure we used all the operands! */
1034 next_opcode
= opcode
+ 1;
1035 if (!strcmp (next_opcode
->name
, opcode
->name
))
1037 opcode
= next_opcode
;
1041 as_bad ("%s", errmsg
);
1047 while (isspace (*str
))
1051 as_bad (_("junk at end of line: `%s'"), str
);
1053 input_line_pointer
= str
;
1055 if (opcode
->format
== FMT_1
)
1057 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1059 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1061 else if (opcode
->format
== FMT_6
)
1063 else if (opcode
->format
== FMT_7
)
1068 /* Write out the instruction. */
1070 if (relaxable
&& fc
> 0)
1075 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1077 /* Handle bra specially. Basically treat it like jmp so
1078 that we automatically handle 8, 16 and 32 bit offsets
1079 correctly as well as jumps to an undefined address.
1081 It is also important to not treat it like other bCC
1082 instructions since the long forms of bra is different
1083 from other bCC instructions. */
1084 if (opcode
->opcode
== 0xea00)
1090 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1093 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1099 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1100 fixups
[0].exp
.X_add_symbol
,
1101 fixups
[0].exp
.X_add_number
,
1102 (char *)fixups
[0].opindex
);
1103 number_to_chars_bigendian (f
, insn
, size
);
1106 number_to_chars_bigendian (f
+ size
, 0, 4);
1107 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1110 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1115 f
= frag_more (size
);
1117 /* Oh, what a mess. The instruction is in big endian format, but
1118 16 and 24bit immediates are little endian! */
1119 if (opcode
->format
== FMT_3
)
1121 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1122 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1124 else if (opcode
->format
== FMT_6
)
1126 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1127 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1129 else if (opcode
->format
== FMT_7
)
1131 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1132 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1133 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1137 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1140 /* Create any fixups. */
1141 for (i
= 0; i
< fc
; i
++)
1143 const struct mn10200_operand
*operand
;
1145 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1146 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1148 reloc_howto_type
*reloc_howto
;
1153 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1159 size
= bfd_get_reloc_size (reloc_howto
);
1161 if (size
< 1 || size
> 4)
1165 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1168 reloc_howto
->pc_relative
,
1171 /* PC-relative offsets are from the first byte of the
1172 next instruction, not from the start of the current
1174 if (reloc_howto
->pc_relative
)
1175 fixP
->fx_offset
+= size
;
1179 int reloc
, pcrel
, reloc_size
, offset
;
1182 reloc
= BFD_RELOC_NONE
;
1183 /* How big is the reloc? Remember SPLIT relocs are
1184 implicitly 32bits. */
1185 reloc_size
= operand
->bits
;
1187 offset
= size
- reloc_size
/ 8;
1189 /* Is the reloc pc-relative? */
1190 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1192 /* Choose a proper BFD relocation type. */
1195 if (reloc_size
== 8)
1196 reloc
= BFD_RELOC_8_PCREL
;
1197 else if (reloc_size
== 24)
1198 reloc
= BFD_RELOC_24_PCREL
;
1204 if (reloc_size
== 32)
1205 reloc
= BFD_RELOC_32
;
1206 else if (reloc_size
== 16)
1207 reloc
= BFD_RELOC_16
;
1208 else if (reloc_size
== 8)
1209 reloc
= BFD_RELOC_8
;
1210 else if (reloc_size
== 24)
1211 reloc
= BFD_RELOC_24
;
1216 /* Convert the size of the reloc into what fix_new_exp
1218 reloc_size
= reloc_size
/ 8;
1219 if (reloc_size
== 8)
1221 else if (reloc_size
== 16)
1223 else if (reloc_size
== 32 || reloc_size
== 24)
1226 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1227 reloc_size
, &fixups
[i
].exp
, pcrel
,
1228 ((bfd_reloc_code_real_type
) reloc
));
1230 /* PC-relative offsets are from the first byte of the
1231 next instruction, not from the start of the current
1234 fixP
->fx_offset
+= size
;
1240 /* If while processing a fixup, a reloc really needs to be created
1241 Then it is done here. */
1244 tc_gen_reloc (seg
, fixp
)
1249 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1251 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1252 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1254 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1255 _("reloc %d not supported by object file format"),
1256 (int) fixp
->fx_r_type
);
1259 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1261 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
1263 if ((S_GET_SEGMENT (fixp
->fx_addsy
) != S_GET_SEGMENT (fixp
->fx_subsy
))
1264 || S_GET_SEGMENT (fixp
->fx_addsy
) == undefined_section
)
1266 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1267 "Difference of symbols in different sections is not supported");
1270 reloc
->sym_ptr_ptr
= &bfd_abs_symbol
;
1271 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
1272 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
1276 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1277 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1278 reloc
->addend
= fixp
->fx_offset
;
1284 md_estimate_size_before_relax (fragp
, seg
)
1288 if (fragp
->fr_subtype
== 6
1289 && (!S_IS_DEFINED (fragp
->fr_symbol
)
1290 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
1291 fragp
->fr_subtype
= 7;
1292 else if (fragp
->fr_subtype
== 8
1293 && (!S_IS_DEFINED (fragp
->fr_symbol
)
1294 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
1295 fragp
->fr_subtype
= 10;
1297 if (fragp
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
1300 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
1304 md_pcrel_from (fixp
)
1307 return fixp
->fx_frag
->fr_address
;
1309 if (fixp
->fx_addsy
!= (symbolS
*) NULL
&& !S_IS_DEFINED (fixp
->fx_addsy
))
1311 /* The symbol is undefined. Let the linker figure it out. */
1314 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1319 md_apply_fix3 (fixp
, valuep
, seg
)
1324 /* We shouldn't ever get here because linkrelax is nonzero. */
1330 /* Insert an operand value into an instruction. */
1333 mn10200_insert_operand (insnp
, extensionp
, operand
, val
, file
, line
, shift
)
1334 unsigned long *insnp
;
1335 unsigned long *extensionp
;
1336 const struct mn10200_operand
*operand
;
1342 /* No need to check 24 or 32bit operands for a bit. */
1343 if (operand
->bits
< 24
1344 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1349 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1351 max
= (1 << (operand
->bits
- 1)) - 1;
1352 min
= - (1 << (operand
->bits
- 1));
1356 max
= (1 << operand
->bits
) - 1;
1362 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1365 _("operand out of range (%s not between %ld and %ld)");
1368 sprint_value (buf
, test
);
1369 if (file
== (char *) NULL
)
1370 as_warn (err
, buf
, min
, max
);
1372 as_warn_where (file
, line
, err
, buf
, min
, max
);
1376 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
1378 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1379 << (operand
->shift
+ shift
));
1381 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
1382 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1383 << (operand
->shift
+ shift
+ 2));
1387 *extensionp
|= (val
>> 16) & 0xff;
1388 *insnp
|= val
& 0xffff;
1392 static unsigned long
1393 check_operand (insn
, operand
, val
)
1395 const struct mn10200_operand
*operand
;
1398 /* No need to check 24bit or 32bit operands for a bit. */
1399 if (operand
->bits
< 24
1400 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1405 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1407 max
= (1 << (operand
->bits
- 1)) - 1;
1408 min
= - (1 << (operand
->bits
- 1));
1412 max
= (1 << operand
->bits
) - 1;
1418 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)