1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include "opcode/mn10200.h"
27 /* Structure to hold information about predefined registers. */
34 /* Generic assembler global variables which must be defined by all targets. */
36 /* Characters which always start a comment. */
37 const char comment_chars
[] = "#";
39 /* Characters which start a comment at the beginning of a line. */
40 const char line_comment_chars
[] = ";#";
42 /* Characters which may be used to separate multiple commands on a
44 const char line_separator_chars
[] = ";";
46 /* Characters which are used to indicate an exponent in a floating
48 const char EXP_CHARS
[] = "eE";
50 /* Characters which mean that a number is a floating point constant,
52 const char FLT_CHARS
[] = "dD";
55 const relax_typeS md_relax_table
[] = {
58 {0x8004, -0x7ffb, 5, 2},
59 {0x800006, -0x7ffff9, 7, 0},
62 {0x8004, -0x7ffb, 6, 5},
63 {0x800006, -0x7ffff9, 8, 0},
65 {0x8004, -0x7ffb, 3, 7},
66 {0x800006, -0x7ffff9, 5, 0},
69 {0x8004, -0x7ffb, 3, 10},
70 {0x800006, -0x7ffff9, 5, 0},
74 static void mn10200_insert_operand
PARAMS ((unsigned long *, unsigned long *,
75 const struct mn10200_operand
*,
76 offsetT
, char *, unsigned,
78 static unsigned long check_operand
PARAMS ((unsigned long,
79 const struct mn10200_operand
*,
81 static int reg_name_search
PARAMS ((const struct reg_name
*, int, const char *));
82 static boolean data_register_name
PARAMS ((expressionS
*expressionP
));
83 static boolean address_register_name
PARAMS ((expressionS
*expressionP
));
84 static boolean other_register_name
PARAMS ((expressionS
*expressionP
));
88 #define MAX_INSN_FIXUPS (5)
93 bfd_reloc_code_real_type reloc
;
95 struct mn10200_fixup fixups
[MAX_INSN_FIXUPS
];
98 const char *md_shortopts
= "";
99 struct option md_longopts
[] = {
100 {NULL
, no_argument
, NULL
, 0}
102 size_t md_longopts_size
= sizeof(md_longopts
);
104 /* The target specific pseudo-ops which we support. */
105 const pseudo_typeS md_pseudo_table
[] =
110 /* Opcode hash table. */
111 static struct hash_control
*mn10200_hash
;
113 /* This table is sorted. Suitable for searching by a binary search. */
114 static const struct reg_name data_registers
[] =
121 #define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
123 static const struct reg_name address_registers
[] =
130 #define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
132 static const struct reg_name other_registers
[] =
137 #define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
139 /* reg_name_search does a binary search of the given register table
140 to see if "name" is a valid regiter name. Returns the register
141 number from the array on success, or -1 on failure. */
144 reg_name_search (regs
, regcount
, name
)
145 const struct reg_name
*regs
;
149 int middle
, low
, high
;
157 middle
= (low
+ high
) / 2;
158 cmp
= strcasecmp (name
, regs
[middle
].name
);
164 return regs
[middle
].value
;
171 /* Summary of register_name().
173 * in: Input_line_pointer points to 1st char of operand.
175 * out: A expressionS.
176 * The operand may have been a register: in this case, X_op == O_register,
177 * X_add_number is set to the register number, and truth is returned.
178 * Input_line_pointer->(next non-blank) char after operand, or is in
179 * its original state.
182 data_register_name (expressionP
)
183 expressionS
*expressionP
;
190 /* Find the spelling of the operand */
191 start
= name
= input_line_pointer
;
193 c
= get_symbol_end ();
194 reg_number
= reg_name_search (data_registers
, DATA_REG_NAME_CNT
, name
);
196 /* look to see if it's in the register table */
199 expressionP
->X_op
= O_register
;
200 expressionP
->X_add_number
= reg_number
;
202 /* make the rest nice */
203 expressionP
->X_add_symbol
= NULL
;
204 expressionP
->X_op_symbol
= NULL
;
205 *input_line_pointer
= c
; /* put back the delimiting char */
210 /* reset the line as if we had not done anything */
211 *input_line_pointer
= c
; /* put back the delimiting char */
212 input_line_pointer
= start
; /* reset input_line pointer */
217 /* Summary of register_name().
219 * in: Input_line_pointer points to 1st char of operand.
221 * out: A expressionS.
222 * The operand may have been a register: in this case, X_op == O_register,
223 * X_add_number is set to the register number, and truth is returned.
224 * Input_line_pointer->(next non-blank) char after operand, or is in
225 * its original state.
228 address_register_name (expressionP
)
229 expressionS
*expressionP
;
236 /* Find the spelling of the operand */
237 start
= name
= input_line_pointer
;
239 c
= get_symbol_end ();
240 reg_number
= reg_name_search (address_registers
, ADDRESS_REG_NAME_CNT
, name
);
242 /* look to see if it's in the register table */
245 expressionP
->X_op
= O_register
;
246 expressionP
->X_add_number
= reg_number
;
248 /* make the rest nice */
249 expressionP
->X_add_symbol
= NULL
;
250 expressionP
->X_op_symbol
= NULL
;
251 *input_line_pointer
= c
; /* put back the delimiting char */
256 /* reset the line as if we had not done anything */
257 *input_line_pointer
= c
; /* put back the delimiting char */
258 input_line_pointer
= start
; /* reset input_line pointer */
263 /* Summary of register_name().
265 * in: Input_line_pointer points to 1st char of operand.
267 * out: A expressionS.
268 * The operand may have been a register: in this case, X_op == O_register,
269 * X_add_number is set to the register number, and truth is returned.
270 * Input_line_pointer->(next non-blank) char after operand, or is in
271 * its original state.
274 other_register_name (expressionP
)
275 expressionS
*expressionP
;
282 /* Find the spelling of the operand */
283 start
= name
= input_line_pointer
;
285 c
= get_symbol_end ();
286 reg_number
= reg_name_search (other_registers
, OTHER_REG_NAME_CNT
, name
);
288 /* look to see if it's in the register table */
291 expressionP
->X_op
= O_register
;
292 expressionP
->X_add_number
= reg_number
;
294 /* make the rest nice */
295 expressionP
->X_add_symbol
= NULL
;
296 expressionP
->X_op_symbol
= NULL
;
297 *input_line_pointer
= c
; /* put back the delimiting char */
302 /* reset the line as if we had not done anything */
303 *input_line_pointer
= c
; /* put back the delimiting char */
304 input_line_pointer
= start
; /* reset input_line pointer */
310 md_show_usage (stream
)
313 fprintf(stream
, _("MN10200 options:\n\
318 md_parse_option (c
, arg
)
326 md_undefined_symbol (name
)
333 md_atof (type
, litp
, sizep
)
339 LITTLENUM_TYPE words
[4];
355 return _("bad call to md_atof");
358 t
= atof_ieee (input_line_pointer
, type
, words
);
360 input_line_pointer
= t
;
364 for (i
= prec
- 1; i
>= 0; i
--)
366 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
375 md_convert_frag (abfd
, sec
, fragP
)
380 static unsigned long label_count
= 0;
383 subseg_change (sec
, 0);
384 if (fragP
->fr_subtype
== 0)
386 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
387 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
391 else if (fragP
->fr_subtype
== 1)
393 /* Reverse the condition of the first branch. */
394 int offset
= fragP
->fr_fix
;
395 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
432 fragP
->fr_literal
[offset
] = opcode
;
434 /* Create a fixup for the reversed conditional branch. */
435 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
436 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
437 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
438 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
440 /* Now create the unconditional branch + fixup to the
442 fragP
->fr_literal
[offset
+ 2] = 0xfc;
443 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
444 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
448 else if (fragP
->fr_subtype
== 2)
450 /* Reverse the condition of the first branch. */
451 int offset
= fragP
->fr_fix
;
452 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
489 fragP
->fr_literal
[offset
] = opcode
;
491 /* Create a fixup for the reversed conditional branch. */
492 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
493 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
494 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
495 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
497 /* Now create the unconditional branch + fixup to the
499 fragP
->fr_literal
[offset
+ 2] = 0xf4;
500 fragP
->fr_literal
[offset
+ 3] = 0xe0;
501 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
502 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
506 else if (fragP
->fr_subtype
== 3)
508 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
509 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
513 else if (fragP
->fr_subtype
== 4)
515 /* Reverse the condition of the first branch. */
516 int offset
= fragP
->fr_fix
;
517 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
577 fragP
->fr_literal
[offset
+ 1] = opcode
;
579 /* Create a fixup for the reversed conditional branch. */
580 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
581 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
582 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
583 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
585 /* Now create the unconditional branch + fixup to the
587 fragP
->fr_literal
[offset
+ 3] = 0xfc;
588 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
589 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
593 else if (fragP
->fr_subtype
== 5)
595 /* Reverse the condition of the first branch. */
596 int offset
= fragP
->fr_fix
;
597 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
657 fragP
->fr_literal
[offset
+ 1] = opcode
;
659 /* Create a fixup for the reversed conditional branch. */
660 sprintf (buf
, ".%s_%d", FAKE_LABEL_NAME
, label_count
++);
661 fix_new (fragP
, fragP
->fr_fix
+ 2, 1,
662 symbol_new (buf
, sec
, 0, fragP
->fr_next
),
663 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
665 /* Now create the unconditional branch + fixup to the
667 fragP
->fr_literal
[offset
+ 3] = 0xf4;
668 fragP
->fr_literal
[offset
+ 4] = 0xe0;
669 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
670 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
674 else if (fragP
->fr_subtype
== 6)
676 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
677 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
681 else if (fragP
->fr_subtype
== 7)
683 int offset
= fragP
->fr_fix
;
684 fragP
->fr_literal
[offset
] = 0xf4;
685 fragP
->fr_literal
[offset
+ 1] = 0xe1;
687 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
688 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
692 else if (fragP
->fr_subtype
== 8)
694 fragP
->fr_literal
[fragP
->fr_fix
] = 0xea;
695 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
696 fragP
->fr_offset
, 1, BFD_RELOC_8_PCREL
);
700 else if (fragP
->fr_subtype
== 9)
702 int offset
= fragP
->fr_fix
;
703 fragP
->fr_literal
[offset
] = 0xfc;
705 fix_new (fragP
, fragP
->fr_fix
+ 1, 4, fragP
->fr_symbol
,
706 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
710 else if (fragP
->fr_subtype
== 10)
712 int offset
= fragP
->fr_fix
;
713 fragP
->fr_literal
[offset
] = 0xf4;
714 fragP
->fr_literal
[offset
+ 1] = 0xe0;
716 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
717 fragP
->fr_offset
, 1, BFD_RELOC_24_PCREL
);
726 md_section_align (seg
, addr
)
730 int align
= bfd_get_section_alignment (stdoutput
, seg
);
731 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
737 char *prev_name
= "";
738 register const struct mn10200_opcode
*op
;
740 mn10200_hash
= hash_new();
742 /* Insert unique names into hash table. The MN10200 instruction set
743 has many identical opcode names that have different opcodes based
744 on the operands. This hash table then provides a quick index to
745 the first opcode with a particular name in the opcode table. */
747 op
= mn10200_opcodes
;
750 if (strcmp (prev_name
, op
->name
))
752 prev_name
= (char *) op
->name
;
753 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
758 /* This is both a simplification (we don't have to write md_apply_fix)
759 and support for future optimizations (branch shortening and similar
760 stuff in the linker. */
769 struct mn10200_opcode
*opcode
;
770 struct mn10200_opcode
*next_opcode
;
771 const unsigned char *opindex_ptr
;
772 int next_opindex
, relaxable
;
773 unsigned long insn
, extension
, size
= 0;
778 /* Get the opcode. */
779 for (s
= str
; *s
!= '\0' && ! isspace (*s
); s
++)
784 /* find the first opcode with the proper name */
785 opcode
= (struct mn10200_opcode
*)hash_find (mn10200_hash
, str
);
788 as_bad (_("Unrecognized opcode: `%s'"), str
);
793 while (isspace (*str
))
796 input_line_pointer
= str
;
800 const char *errmsg
= NULL
;
809 insn
= opcode
->opcode
;
811 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
813 opindex_ptr
++, op_idx
++)
815 const struct mn10200_operand
*operand
;
818 if (next_opindex
== 0)
820 operand
= &mn10200_operands
[*opindex_ptr
];
824 operand
= &mn10200_operands
[next_opindex
];
830 while (*str
== ' ' || *str
== ',')
833 if (operand
->flags
& MN10200_OPERAND_RELAX
)
836 /* Gather the operand. */
837 hold
= input_line_pointer
;
838 input_line_pointer
= str
;
840 if (operand
->flags
& MN10200_OPERAND_PAREN
)
842 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
844 input_line_pointer
= hold
;
848 input_line_pointer
++;
851 /* See if we can match the operands. */
852 else if (operand
->flags
& MN10200_OPERAND_DREG
)
854 if (!data_register_name (&ex
))
856 input_line_pointer
= hold
;
861 else if (operand
->flags
& MN10200_OPERAND_AREG
)
863 if (!address_register_name (&ex
))
865 input_line_pointer
= hold
;
870 else if (operand
->flags
& MN10200_OPERAND_PSW
)
872 char *start
= input_line_pointer
;
873 char c
= get_symbol_end ();
875 if (strcmp (start
, "psw") != 0)
877 *input_line_pointer
= c
;
878 input_line_pointer
= hold
;
882 *input_line_pointer
= c
;
885 else if (operand
->flags
& MN10200_OPERAND_MDR
)
887 char *start
= input_line_pointer
;
888 char c
= get_symbol_end ();
890 if (strcmp (start
, "mdr") != 0)
892 *input_line_pointer
= c
;
893 input_line_pointer
= hold
;
897 *input_line_pointer
= c
;
900 else if (data_register_name (&ex
))
902 input_line_pointer
= hold
;
906 else if (address_register_name (&ex
))
908 input_line_pointer
= hold
;
912 else if (other_register_name (&ex
))
914 input_line_pointer
= hold
;
918 else if (*str
== ')' || *str
== '(')
920 input_line_pointer
= hold
;
932 errmsg
= _("illegal operand");
935 errmsg
= _("missing operand");
939 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
941 input_line_pointer
= hold
;
946 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
948 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
949 || opcode
->format
== FMT_7
)
954 mn10200_insert_operand (&insn
, &extension
, operand
,
955 ex
.X_add_number
, (char *) NULL
,
961 /* If this operand can be promoted, and it doesn't
962 fit into the allocated bitfield for this insn,
963 then promote it (ie this opcode does not match). */
965 & (MN10200_OPERAND_PROMOTE
| MN10200_OPERAND_RELAX
)
966 && ! check_operand (insn
, operand
, ex
.X_add_number
))
968 input_line_pointer
= hold
;
973 mn10200_insert_operand (&insn
, &extension
, operand
,
974 ex
.X_add_number
, (char *) NULL
,
979 /* If this operand can be promoted, then this opcode didn't
980 match since we can't know if it needed promotion! */
981 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
983 input_line_pointer
= hold
;
988 /* We need to generate a fixup for this expression. */
989 if (fc
>= MAX_INSN_FIXUPS
)
990 as_fatal (_("too many fixups"));
992 fixups
[fc
].opindex
= *opindex_ptr
;
993 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
999 str
= input_line_pointer
;
1000 input_line_pointer
= hold
;
1002 while (*str
== ' ' || *str
== ',')
1007 /* Make sure we used all the operands! */
1014 next_opcode
= opcode
+ 1;
1015 if (!strcmp(next_opcode
->name
, opcode
->name
))
1017 opcode
= next_opcode
;
1021 as_bad ("%s", errmsg
);
1027 while (isspace (*str
))
1031 as_bad (_("junk at end of line: `%s'"), str
);
1033 input_line_pointer
= str
;
1035 if (opcode
->format
== FMT_1
)
1037 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1039 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1041 else if (opcode
->format
== FMT_6
)
1043 else if (opcode
->format
== FMT_7
)
1048 /* Write out the instruction. */
1050 if (relaxable
&& fc
> 0)
1055 if (size
== 2 && opcode
->opcode
!= 0xfc0000)
1057 /* Handle bra specially. Basically treat it like jmp so
1058 that we automatically handle 8, 16 and 32 bit offsets
1059 correctly as well as jumps to an undefined address.
1061 It is also important to not treat it like other bCC
1062 instructions since the long forms of bra is different
1063 from other bCC instructions. */
1064 if (opcode
->opcode
== 0xea00)
1070 else if (size
== 3 && opcode
->opcode
== 0xfd0000)
1073 else if (size
== 3 && opcode
->opcode
== 0xfc0000)
1079 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1080 fixups
[0].exp
.X_add_symbol
,
1081 fixups
[0].exp
.X_add_number
,
1082 (char *)fixups
[0].opindex
);
1083 number_to_chars_bigendian (f
, insn
, size
);
1086 number_to_chars_bigendian (f
+ size
, 0, 4);
1087 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1090 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1095 f
= frag_more (size
);
1097 /* Oh, what a mess. The instruction is in big endian format, but
1098 16 and 24bit immediates are little endian! */
1099 if (opcode
->format
== FMT_3
)
1101 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1102 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1104 else if (opcode
->format
== FMT_6
)
1106 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1107 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1109 else if (opcode
->format
== FMT_7
)
1111 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1112 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1113 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1117 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1120 /* Create any fixups. */
1121 for (i
= 0; i
< fc
; i
++)
1123 const struct mn10200_operand
*operand
;
1125 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1126 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1128 reloc_howto_type
*reloc_howto
;
1133 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, fixups
[i
].reloc
);
1138 size
= bfd_get_reloc_size (reloc_howto
);
1140 if (size
< 1 || size
> 4)
1144 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1147 reloc_howto
->pc_relative
,
1150 /* PC-relative offsets are from the first byte of the next
1151 instruction, not from the start of the current instruction. */
1152 if (reloc_howto
->pc_relative
)
1153 fixP
->fx_offset
+= size
;
1157 int reloc
, pcrel
, reloc_size
, offset
;
1160 reloc
= BFD_RELOC_NONE
;
1161 /* How big is the reloc? Remember SPLIT relocs are
1162 implicitly 32bits. */
1163 reloc_size
= operand
->bits
;
1165 offset
= size
- reloc_size
/ 8;
1167 /* Is the reloc pc-relative? */
1168 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1171 /* Choose a proper BFD relocation type. */
1174 if (reloc_size
== 8)
1175 reloc
= BFD_RELOC_8_PCREL
;
1176 else if (reloc_size
== 24)
1177 reloc
= BFD_RELOC_24_PCREL
;
1183 if (reloc_size
== 32)
1184 reloc
= BFD_RELOC_32
;
1185 else if (reloc_size
== 16)
1186 reloc
= BFD_RELOC_16
;
1187 else if (reloc_size
== 8)
1188 reloc
= BFD_RELOC_8
;
1189 else if (reloc_size
== 24)
1190 reloc
= BFD_RELOC_24
;
1195 /* Convert the size of the reloc into what fix_new_exp wants. */
1196 reloc_size
= reloc_size
/ 8;
1197 if (reloc_size
== 8)
1199 else if (reloc_size
== 16)
1201 else if (reloc_size
== 32 || reloc_size
== 24)
1204 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1205 reloc_size
, &fixups
[i
].exp
, pcrel
,
1206 ((bfd_reloc_code_real_type
) reloc
));
1208 /* PC-relative offsets are from the first byte of the next
1209 instruction, not from the start of the current instruction. */
1211 fixP
->fx_offset
+= size
;
1218 /* if while processing a fixup, a reloc really needs to be created */
1219 /* then it is done here */
1222 tc_gen_reloc (seg
, fixp
)
1227 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1229 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1230 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1232 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1233 _("reloc %d not supported by object file format"),
1234 (int)fixp
->fx_r_type
);
1237 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1239 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
1241 if ((S_GET_SEGMENT (fixp
->fx_addsy
) != S_GET_SEGMENT (fixp
->fx_subsy
))
1242 || S_GET_SEGMENT (fixp
->fx_addsy
) == undefined_section
)
1244 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1245 "Difference of symbols in different sections is not supported");
1248 reloc
->sym_ptr_ptr
= &bfd_abs_symbol
;
1249 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
1250 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
1254 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1255 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1256 reloc
->addend
= fixp
->fx_offset
;
1262 md_estimate_size_before_relax (fragp
, seg
)
1266 if (fragp
->fr_subtype
== 0)
1268 if (fragp
->fr_subtype
== 3)
1270 if (fragp
->fr_subtype
== 6)
1272 if (!S_IS_DEFINED (fragp
->fr_symbol
)
1273 || seg
!= S_GET_SEGMENT (fragp
->fr_symbol
))
1275 fragp
->fr_subtype
= 7;
1280 if (fragp
->fr_subtype
== 8)
1282 if (!S_IS_DEFINED (fragp
->fr_symbol
))
1284 fragp
->fr_subtype
= 10;
1292 md_pcrel_from (fixp
)
1295 return fixp
->fx_frag
->fr_address
;
1297 if (fixp
->fx_addsy
!= (symbolS
*) NULL
&& ! S_IS_DEFINED (fixp
->fx_addsy
))
1299 /* The symbol is undefined. Let the linker figure it out. */
1302 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1307 md_apply_fix3 (fixp
, valuep
, seg
)
1312 /* We shouldn't ever get here because linkrelax is nonzero. */
1318 /* Insert an operand value into an instruction. */
1321 mn10200_insert_operand (insnp
, extensionp
, operand
, val
, file
, line
, shift
)
1322 unsigned long *insnp
;
1323 unsigned long *extensionp
;
1324 const struct mn10200_operand
*operand
;
1330 /* No need to check 24 or 32bit operands for a bit. */
1331 if (operand
->bits
< 24
1332 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1337 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1339 max
= (1 << (operand
->bits
- 1)) - 1;
1340 min
= - (1 << (operand
->bits
- 1));
1344 max
= (1 << operand
->bits
) - 1;
1351 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1354 _("operand out of range (%s not between %ld and %ld)");
1357 sprint_value (buf
, test
);
1358 if (file
== (char *) NULL
)
1359 as_warn (err
, buf
, min
, max
);
1361 as_warn_where (file
, line
, err
, buf
, min
, max
);
1365 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
1367 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1368 << (operand
->shift
+ shift
));
1370 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
1371 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1372 << (operand
->shift
+ shift
+ 2));
1376 *extensionp
|= (val
>> 16) & 0xff;
1377 *insnp
|= val
& 0xffff;
1381 static unsigned long
1382 check_operand (insn
, operand
, val
)
1384 const struct mn10200_operand
*operand
;
1387 /* No need to check 24bit or 32bit operands for a bit. */
1388 if (operand
->bits
< 24
1389 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1394 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1396 max
= (1 << (operand
->bits
- 1)) - 1;
1397 min
= - (1 << (operand
->bits
- 1));
1401 max
= (1 << operand
->bits
) - 1;
1408 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)