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. */
24 #include "safe-ctype.h"
26 #include "opcode/mn10200.h"
28 /* Structure to hold information about predefined registers. */
35 /* Generic assembler global variables which must be defined by all
38 /* Characters which always start a comment. */
39 const char comment_chars
[] = "#";
41 /* Characters which start a comment at the beginning of a line. */
42 const char line_comment_chars
[] = ";#";
44 /* Characters which may be used to separate multiple commands on a
46 const char line_separator_chars
[] = ";";
48 /* Characters which are used to indicate an exponent in a floating
50 const char EXP_CHARS
[] = "eE";
52 /* Characters which mean that a number is a floating point constant,
54 const char FLT_CHARS
[] = "dD";
56 const relax_typeS md_relax_table
[] = {
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: An 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 /* Put back the delimiting char. */
201 *input_line_pointer
= c
;
203 /* Look to see if it's in the register table. */
206 expressionP
->X_op
= O_register
;
207 expressionP
->X_add_number
= reg_number
;
209 /* Make the rest nice. */
210 expressionP
->X_add_symbol
= NULL
;
211 expressionP
->X_op_symbol
= NULL
;
216 /* Reset the line as if we had not done anything. */
217 input_line_pointer
= start
;
221 /* Summary of register_name().
223 * in: Input_line_pointer points to 1st char of operand.
225 * out: An expressionS.
226 * The operand may have been a register: in this case, X_op == O_register,
227 * X_add_number is set to the register number, and truth is returned.
228 * Input_line_pointer->(next non-blank) char after operand, or is in
229 * its original state.
233 address_register_name (expressionP
)
234 expressionS
*expressionP
;
241 /* Find the spelling of the operand. */
242 start
= name
= input_line_pointer
;
244 c
= get_symbol_end ();
245 reg_number
= reg_name_search (address_registers
, ADDRESS_REG_NAME_CNT
, name
);
247 /* Put back the delimiting char. */
248 *input_line_pointer
= c
;
250 /* Look to see if it's in the register table. */
253 expressionP
->X_op
= O_register
;
254 expressionP
->X_add_number
= reg_number
;
256 /* Make the rest nice. */
257 expressionP
->X_add_symbol
= NULL
;
258 expressionP
->X_op_symbol
= NULL
;
263 /* Reset the line as if we had not done anything. */
264 input_line_pointer
= start
;
268 /* Summary of register_name().
270 * in: Input_line_pointer points to 1st char of operand.
272 * out: An expressionS.
273 * The operand may have been a register: in this case, X_op == O_register,
274 * X_add_number is set to the register number, and truth is returned.
275 * Input_line_pointer->(next non-blank) char after operand, or is in
276 * its original state.
280 other_register_name (expressionP
)
281 expressionS
*expressionP
;
288 /* Find the spelling of the operand. */
289 start
= name
= input_line_pointer
;
291 c
= get_symbol_end ();
292 reg_number
= reg_name_search (other_registers
, OTHER_REG_NAME_CNT
, name
);
294 /* Put back the delimiting char. */
295 *input_line_pointer
= c
;
297 /* Look to see if it's in the register table. */
300 expressionP
->X_op
= O_register
;
301 expressionP
->X_add_number
= reg_number
;
303 /* Make the rest nice. */
304 expressionP
->X_add_symbol
= NULL
;
305 expressionP
->X_op_symbol
= NULL
;
310 /* Reset the line as if we had not done anything. */
311 input_line_pointer
= start
;
316 md_show_usage (stream
)
319 fprintf (stream
, _("MN10200 options:\n\
324 md_parse_option (c
, arg
)
332 md_undefined_symbol (name
)
339 md_atof (type
, litp
, sizep
)
345 LITTLENUM_TYPE words
[4];
361 return _("bad call to md_atof");
364 t
= atof_ieee (input_line_pointer
, type
, words
);
366 input_line_pointer
= t
;
370 for (i
= prec
- 1; i
>= 0; i
--)
372 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
380 md_convert_frag (abfd
, sec
, fragP
)
385 static unsigned long label_count
= 0;
388 subseg_change (sec
, 0);
389 if (fragP
->fr_subtype
== 0)
391 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
392 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
396 else if (fragP
->fr_subtype
== 1)
398 /* Reverse the condition of the first branch. */
399 int offset
= fragP
->fr_fix
;
400 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
437 fragP
->fr_literal
[offset
] = opcode
;
439 /* Create a fixup for the reversed conditional branch. */
440 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
441 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
442 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
443 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
445 /* Now create the unconditional branch + fixup to the
447 fragP
->fr_literal
[offset
+ 2] = 0xfc;
448 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
449 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
453 else if (fragP
->fr_subtype
== 2)
455 /* Reverse the condition of the first branch. */
456 int offset
= fragP
->fr_fix
;
457 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
494 fragP
->fr_literal
[offset
] = opcode
;
496 /* Create a fixup for the reversed conditional branch. */
497 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
498 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
499 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
500 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
502 /* Now create the unconditional branch + fixup to the
504 fragP
->fr_literal
[offset
+ 2] = 0xf4;
505 fragP
->fr_literal
[offset
+ 3] = 0xe0;
506 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
507 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
511 else if (fragP
->fr_subtype
== 3)
513 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
514 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
518 else if (fragP
->fr_subtype
== 4)
520 /* Reverse the condition of the first branch. */
521 int offset
= fragP
->fr_fix
;
522 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
582 fragP
->fr_literal
[offset
+ 1] = opcode
;
584 /* Create a fixup for the reversed conditional branch. */
585 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
586 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
587 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
588 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
590 /* Now create the unconditional branch + fixup to the
592 fragP
->fr_literal
[offset
+ 3] = 0xfc;
593 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
594 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
598 else if (fragP
->fr_subtype
== 5)
600 /* Reverse the condition of the first branch. */
601 int offset
= fragP
->fr_fix
;
602 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
662 fragP
->fr_literal
[offset
+ 1] = opcode
;
664 /* Create a fixup for the reversed conditional branch. */
665 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
666 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
667 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
668 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
670 /* Now create the unconditional branch + fixup to the
672 fragP
->fr_literal
[offset
+ 3] = 0xf4;
673 fragP
->fr_literal
[offset
+ 4] = 0xe0;
674 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
675 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
679 else if (fragP
->fr_subtype
== 6)
681 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
682 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
686 else if (fragP
->fr_subtype
== 7)
688 int offset
= fragP
->fr_fix
;
689 fragP
->fr_literal
[offset
] = 0xf4;
690 fragP
->fr_literal
[offset
+ 1] = 0xe1;
692 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
693 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
697 else if (fragP
->fr_subtype
== 8)
699 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
700 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
701 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
705 else if (fragP
->fr_subtype
== 9)
707 int offset
= fragP
->fr_fix
;
708 fragP
->fr_literal
[offset
] = 0xfc;
710 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
711 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
715 else if (fragP
->fr_subtype
== 10)
717 int offset
= fragP
->fr_fix
;
718 fragP
->fr_literal
[offset
] = 0xf4;
719 fragP
->fr_literal
[offset
+ 1] = 0xe0;
721 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
722 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
731 md_section_align (seg
, addr
)
735 int align
= bfd_get_section_alignment (stdoutput
, seg
);
736 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
742 char *prev_name
= "";
743 register const struct mn10200_opcode
*op
;
745 mn10200_hash
= hash_new ();
747 /* Insert unique names into hash table. The MN10200 instruction set
748 has many identical opcode names that have different opcodes based
749 on the operands. This hash table then provides a quick index to
750 the first opcode with a particular name in the opcode table. */
752 op
= mn10200_opcodes
;
755 if (strcmp (prev_name
, op
->name
))
757 prev_name
= (char *) op
->name
;
758 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
763 /* This is both a simplification (we don't have to write md_apply_fix3)
764 and support for future optimizations (branch shortening and similar
765 stuff in the linker. */
774 struct mn10200_opcode
*opcode
;
775 struct mn10200_opcode
*next_opcode
;
776 const unsigned char *opindex_ptr
;
777 int next_opindex
, relaxable
;
778 unsigned long insn
, extension
, size
= 0;
783 /* Get the opcode. */
784 for (s
= str
; *s
!= '\0' && !ISSPACE (*s
); s
++)
789 /* Find the first opcode with the proper name. */
790 opcode
= (struct mn10200_opcode
*) hash_find (mn10200_hash
, str
);
793 as_bad (_("Unrecognized opcode: `%s'"), str
);
798 while (ISSPACE (*str
))
801 input_line_pointer
= str
;
805 const char *errmsg
= NULL
;
814 insn
= opcode
->opcode
;
816 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
818 opindex_ptr
++, op_idx
++)
820 const struct mn10200_operand
*operand
;
823 if (next_opindex
== 0)
825 operand
= &mn10200_operands
[*opindex_ptr
];
829 operand
= &mn10200_operands
[next_opindex
];
835 while (*str
== ' ' || *str
== ',')
838 if (operand
->flags
& MN10200_OPERAND_RELAX
)
841 /* Gather the operand. */
842 hold
= input_line_pointer
;
843 input_line_pointer
= str
;
845 if (operand
->flags
& MN10200_OPERAND_PAREN
)
847 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
849 input_line_pointer
= hold
;
853 input_line_pointer
++;
856 /* See if we can match the operands. */
857 else if (operand
->flags
& MN10200_OPERAND_DREG
)
859 if (!data_register_name (&ex
))
861 input_line_pointer
= hold
;
866 else if (operand
->flags
& MN10200_OPERAND_AREG
)
868 if (!address_register_name (&ex
))
870 input_line_pointer
= hold
;
875 else if (operand
->flags
& MN10200_OPERAND_PSW
)
877 char *start
= input_line_pointer
;
878 char c
= get_symbol_end ();
880 if (strcmp (start
, "psw") != 0)
882 *input_line_pointer
= c
;
883 input_line_pointer
= hold
;
887 *input_line_pointer
= c
;
890 else if (operand
->flags
& MN10200_OPERAND_MDR
)
892 char *start
= input_line_pointer
;
893 char c
= get_symbol_end ();
895 if (strcmp (start
, "mdr") != 0)
897 *input_line_pointer
= c
;
898 input_line_pointer
= hold
;
902 *input_line_pointer
= c
;
905 else if (data_register_name (&ex
))
907 input_line_pointer
= hold
;
911 else if (address_register_name (&ex
))
913 input_line_pointer
= hold
;
917 else if (other_register_name (&ex
))
919 input_line_pointer
= hold
;
923 else if (*str
== ')' || *str
== '(')
925 input_line_pointer
= hold
;
937 errmsg
= _("illegal operand");
940 errmsg
= _("missing operand");
944 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
946 input_line_pointer
= hold
;
951 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
953 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
954 || opcode
->format
== FMT_7
)
959 mn10200_insert_operand (&insn
, &extension
, operand
,
960 ex
.X_add_number
, (char *) NULL
,
966 /* If this operand can be promoted, and it doesn't
967 fit into the allocated bitfield for this insn,
968 then promote it (ie this opcode does not match). */
970 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
971 && !check_operand (insn
, operand
, ex
.X_add_number
))
973 input_line_pointer
= hold
;
978 mn10200_insert_operand (&insn
, &extension
, operand
,
979 ex
.X_add_number
, (char *) NULL
,
984 /* If this operand can be promoted, then this opcode didn't
985 match since we can't know if it needed promotion! */
986 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
988 input_line_pointer
= hold
;
993 /* We need to generate a fixup for this expression. */
994 if (fc
>= MAX_INSN_FIXUPS
)
995 as_fatal (_("too many fixups"));
997 fixups
[fc
].opindex
= *opindex_ptr
;
998 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
1004 str
= input_line_pointer
;
1005 input_line_pointer
= hold
;
1007 while (*str
== ' ' || *str
== ',')
1012 /* Make sure we used all the operands! */
1019 next_opcode
= opcode
+ 1;
1020 if (!strcmp (next_opcode
->name
, opcode
->name
))
1022 opcode
= next_opcode
;
1026 as_bad ("%s", errmsg
);
1032 while (ISSPACE (*str
))
1036 as_bad (_("junk at end of line: `%s'"), str
);
1038 input_line_pointer
= str
;
1040 if (opcode
->format
== FMT_1
)
1042 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1044 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1046 else if (opcode
->format
== FMT_6
)
1048 else if (opcode
->format
== FMT_7
)
1053 /* Write out the instruction. */
1055 if (relaxable
&& fc
> 0)
1060 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1062 /* Handle bra specially. Basically treat it like jmp so
1063 that we automatically handle 8, 16 and 32 bit offsets
1064 correctly as well as jumps to an undefined address.
1066 It is also important to not treat it like other bCC
1067 instructions since the long forms of bra is different
1068 from other bCC instructions. */
1069 if (opcode
->opcode
== 0xea00)
1075 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1078 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1084 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1085 fixups
[0].exp
.X_add_symbol
,
1086 fixups
[0].exp
.X_add_number
,
1087 (char *)fixups
[0].opindex
);
1088 number_to_chars_bigendian (f
, insn
, size
);
1091 number_to_chars_bigendian (f
+ size
, 0, 4);
1092 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1095 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1100 f
= frag_more (size
);
1102 /* Oh, what a mess. The instruction is in big endian format, but
1103 16 and 24bit immediates are little endian! */
1104 if (opcode
->format
== FMT_3
)
1106 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1107 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1109 else if (opcode
->format
== FMT_6
)
1111 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1112 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1114 else if (opcode
->format
== FMT_7
)
1116 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1117 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1118 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1122 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1125 /* Create any fixups. */
1126 for (i
= 0; i
< fc
; i
++)
1128 const struct mn10200_operand
*operand
;
1130 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1131 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1133 reloc_howto_type
*reloc_howto
;
1138 reloc_howto
= bfd_reloc_type_lookup (stdoutput
,
1144 size
= bfd_get_reloc_size (reloc_howto
);
1146 if (size
< 1 || size
> 4)
1150 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1153 reloc_howto
->pc_relative
,
1156 /* PC-relative offsets are from the first byte of the
1157 next instruction, not from the start of the current
1159 if (reloc_howto
->pc_relative
)
1160 fixP
->fx_offset
+= size
;
1164 int reloc
, pcrel
, reloc_size
, offset
;
1167 reloc
= BFD_RELOC_NONE
;
1168 /* How big is the reloc? Remember SPLIT relocs are
1169 implicitly 32bits. */
1170 reloc_size
= operand
->bits
;
1172 offset
= size
- reloc_size
/ 8;
1174 /* Is the reloc pc-relative? */
1175 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1177 /* Choose a proper BFD relocation type. */
1180 if (reloc_size
== 8)
1181 reloc
= BFD_RELOC_8_PCREL
;
1182 else if (reloc_size
== 24)
1183 reloc
= BFD_RELOC_24_PCREL
;
1189 if (reloc_size
== 32)
1190 reloc
= BFD_RELOC_32
;
1191 else if (reloc_size
== 16)
1192 reloc
= BFD_RELOC_16
;
1193 else if (reloc_size
== 8)
1194 reloc
= BFD_RELOC_8
;
1195 else if (reloc_size
== 24)
1196 reloc
= BFD_RELOC_24
;
1201 /* Convert the size of the reloc into what fix_new_exp
1203 reloc_size
= reloc_size
/ 8;
1204 if (reloc_size
== 8)
1206 else if (reloc_size
== 16)
1208 else if (reloc_size
== 32 || reloc_size
== 24)
1211 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1212 reloc_size
, &fixups
[i
].exp
, pcrel
,
1213 ((bfd_reloc_code_real_type
) reloc
));
1215 /* PC-relative offsets are from the first byte of the
1216 next instruction, not from the start of the current
1219 fixP
->fx_offset
+= size
;
1225 /* If while processing a fixup, a reloc really needs to be created
1226 Then it is done here. */
1229 tc_gen_reloc (seg
, fixp
)
1234 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1236 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1237 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1239 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1240 _("reloc %d not supported by object file format"),
1241 (int) fixp
->fx_r_type
);
1244 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1246 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
1248 if ((S_GET_SEGMENT (fixp
->fx_addsy
) != S_GET_SEGMENT (fixp
->fx_subsy
))
1249 || S_GET_SEGMENT (fixp
->fx_addsy
) == undefined_section
)
1251 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1252 "Difference of symbols in different sections is not supported");
1255 reloc
->sym_ptr_ptr
= &bfd_abs_symbol
;
1256 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
1257 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
1261 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1262 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1263 reloc
->addend
= fixp
->fx_offset
;
1269 md_estimate_size_before_relax (fragp
, seg
)
1273 if (fragp
->fr_subtype
== 6
1274 && (!S_IS_DEFINED (fragp
->fr_symbol
)
1275 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
1276 fragp
->fr_subtype
= 7;
1277 else if (fragp
->fr_subtype
== 8
1278 && (!S_IS_DEFINED (fragp
->fr_symbol
)
1279 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
)))
1280 fragp
->fr_subtype
= 10;
1282 if (fragp
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
1285 return md_relax_table
[fragp
->fr_subtype
].rlx_length
;
1289 md_pcrel_from (fixp
)
1292 return fixp
->fx_frag
->fr_address
;
1294 if (fixp
->fx_addsy
!= (symbolS
*) NULL
&& !S_IS_DEFINED (fixp
->fx_addsy
))
1296 /* The symbol is undefined. Let the linker figure it out. */
1299 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1304 md_apply_fix3 (fixP
, valP
, seg
)
1306 valueT
* valP ATTRIBUTE_UNUSED
;
1307 segT seg ATTRIBUTE_UNUSED
;
1309 /* We shouldn't ever get here because linkrelax is nonzero. */
1314 /* Insert an operand value into an instruction. */
1317 mn10200_insert_operand (insnp
, extensionp
, operand
, val
, file
, line
, shift
)
1318 unsigned long *insnp
;
1319 unsigned long *extensionp
;
1320 const struct mn10200_operand
*operand
;
1326 /* No need to check 24 or 32bit operands for a bit. */
1327 if (operand
->bits
< 24
1328 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1333 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1335 max
= (1 << (operand
->bits
- 1)) - 1;
1336 min
= - (1 << (operand
->bits
- 1));
1340 max
= (1 << operand
->bits
) - 1;
1346 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1349 _("operand out of range (%s not between %ld and %ld)");
1352 sprint_value (buf
, test
);
1353 if (file
== (char *) NULL
)
1354 as_warn (err
, buf
, min
, max
);
1356 as_warn_where (file
, line
, err
, buf
, min
, max
);
1360 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
1362 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1363 << (operand
->shift
+ shift
));
1365 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
1366 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1367 << (operand
->shift
+ shift
+ 2));
1371 *extensionp
|= (val
>> 16) & 0xff;
1372 *insnp
|= val
& 0xffff;
1376 static unsigned long
1377 check_operand (insn
, operand
, val
)
1379 const struct mn10200_operand
*operand
;
1382 /* No need to check 24bit or 32bit operands for a bit. */
1383 if (operand
->bits
< 24
1384 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1389 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1391 max
= (1 << (operand
->bits
- 1)) - 1;
1392 min
= - (1 << (operand
->bits
- 1));
1396 max
= (1 << operand
->bits
) - 1;
1402 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)