1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
3 Copyright (C) 1996, 1997 Free Software Foundation.
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 targets. */
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";
56 const relax_typeS md_relax_table
[] = {
59 {0x7fff, -0x8000, 5, 2},
60 {0x7fffff, -0x8000000, 7, 0},
63 {0x7fff, -0x8000, 6, 5},
64 {0x7fffff, -0x8000000, 8, 0},
65 /* jmp/jsr relaxing, could have a bra variant too! */
66 {0x7fff, -0x8000, 3, 7},
67 {0x7fffff, -0x8000000, 5, 0},
71 static void mn10200_insert_operand
PARAMS ((unsigned long *, unsigned long *,
72 const struct mn10200_operand
*,
73 offsetT
, char *, unsigned,
75 static unsigned long check_operand
PARAMS ((unsigned long,
76 const struct mn10200_operand
*,
78 static int reg_name_search
PARAMS ((const struct reg_name
*, int, const char *));
79 static boolean data_register_name
PARAMS ((expressionS
*expressionP
));
80 static boolean address_register_name
PARAMS ((expressionS
*expressionP
));
81 static boolean other_register_name
PARAMS ((expressionS
*expressionP
));
85 #define MAX_INSN_FIXUPS (5)
90 bfd_reloc_code_real_type reloc
;
92 struct mn10200_fixup fixups
[MAX_INSN_FIXUPS
];
95 const char *md_shortopts
= "";
96 struct option md_longopts
[] = {
97 {NULL
, no_argument
, NULL
, 0}
99 size_t md_longopts_size
= sizeof(md_longopts
);
101 /* The target specific pseudo-ops which we support. */
102 const pseudo_typeS md_pseudo_table
[] =
107 /* Opcode hash table. */
108 static struct hash_control
*mn10200_hash
;
110 /* This table is sorted. Suitable for searching by a binary search. */
111 static const struct reg_name data_registers
[] =
118 #define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
120 static const struct reg_name address_registers
[] =
127 #define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
129 static const struct reg_name other_registers
[] =
134 #define OTHER_REG_NAME_CNT (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 (regs
, regcount
, name
)
142 const struct reg_name
*regs
;
146 int middle
, low
, high
;
154 middle
= (low
+ high
) / 2;
155 cmp
= strcasecmp (name
, regs
[middle
].name
);
161 return regs
[middle
].value
;
168 /* Summary of register_name().
170 * in: Input_line_pointer points to 1st char of operand.
172 * out: A expressionS.
173 * The operand may have been a register: in this case, X_op == O_register,
174 * X_add_number is set to the register number, and truth is returned.
175 * Input_line_pointer->(next non-blank) char after operand, or is in
176 * its original state.
179 data_register_name (expressionP
)
180 expressionS
*expressionP
;
187 /* Find the spelling of the operand */
188 start
= name
= input_line_pointer
;
190 c
= get_symbol_end ();
191 reg_number
= reg_name_search (data_registers
, DATA_REG_NAME_CNT
, name
);
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
;
202 *input_line_pointer
= c
; /* put back the delimiting char */
207 /* reset the line as if we had not done anything */
208 *input_line_pointer
= c
; /* put back the delimiting char */
209 input_line_pointer
= start
; /* reset input_line pointer */
214 /* Summary of register_name().
216 * in: Input_line_pointer points to 1st char of operand.
218 * out: A expressionS.
219 * The operand may have been a register: in this case, X_op == O_register,
220 * X_add_number is set to the register number, and truth is returned.
221 * Input_line_pointer->(next non-blank) char after operand, or is in
222 * its original state.
225 address_register_name (expressionP
)
226 expressionS
*expressionP
;
233 /* Find the spelling of the operand */
234 start
= name
= input_line_pointer
;
236 c
= get_symbol_end ();
237 reg_number
= reg_name_search (address_registers
, ADDRESS_REG_NAME_CNT
, name
);
239 /* look to see if it's in the register table */
242 expressionP
->X_op
= O_register
;
243 expressionP
->X_add_number
= reg_number
;
245 /* make the rest nice */
246 expressionP
->X_add_symbol
= NULL
;
247 expressionP
->X_op_symbol
= NULL
;
248 *input_line_pointer
= c
; /* put back the delimiting char */
253 /* reset the line as if we had not done anything */
254 *input_line_pointer
= c
; /* put back the delimiting char */
255 input_line_pointer
= start
; /* reset input_line pointer */
260 /* Summary of register_name().
262 * in: Input_line_pointer points to 1st char of operand.
264 * out: A expressionS.
265 * The operand may have been a register: in this case, X_op == O_register,
266 * X_add_number is set to the register number, and truth is returned.
267 * Input_line_pointer->(next non-blank) char after operand, or is in
268 * its original state.
271 other_register_name (expressionP
)
272 expressionS
*expressionP
;
279 /* Find the spelling of the operand */
280 start
= name
= input_line_pointer
;
282 c
= get_symbol_end ();
283 reg_number
= reg_name_search (other_registers
, OTHER_REG_NAME_CNT
, name
);
285 /* look to see if it's in the register table */
288 expressionP
->X_op
= O_register
;
289 expressionP
->X_add_number
= reg_number
;
291 /* make the rest nice */
292 expressionP
->X_add_symbol
= NULL
;
293 expressionP
->X_op_symbol
= NULL
;
294 *input_line_pointer
= c
; /* put back the delimiting char */
299 /* reset the line as if we had not done anything */
300 *input_line_pointer
= c
; /* put back the delimiting char */
301 input_line_pointer
= start
; /* reset input_line pointer */
307 md_show_usage (stream
)
310 fprintf(stream
, "MN10200 options:\n\
315 md_parse_option (c
, arg
)
323 md_undefined_symbol (name
)
330 md_atof (type
, litp
, sizep
)
336 LITTLENUM_TYPE words
[4];
352 return "bad call to md_atof";
355 t
= atof_ieee (input_line_pointer
, type
, words
);
357 input_line_pointer
= t
;
361 for (i
= prec
- 1; i
>= 0; i
--)
363 md_number_to_chars (litp
, (valueT
) words
[i
], 2);
372 md_convert_frag (abfd
, sec
, fragP
)
377 subseg_change (sec
, 0);
378 if (fragP
->fr_subtype
== 0)
380 fix_new (fragP
, fragP
->fr_fix
+ 1, 1, fragP
->fr_symbol
,
381 fragP
->fr_offset
+ 1, 1, BFD_RELOC_8_PCREL
);
385 else if (fragP
->fr_subtype
== 1)
387 /* Reverse the condition of the first branch. */
388 int offset
= fragP
->fr_fix
;
389 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
426 fragP
->fr_literal
[offset
] = opcode
;
428 /* Set the displacement bits so that we branch around
429 the unconditional branch. */
430 fragP
->fr_literal
[offset
+ 1] = 0x5;
432 /* Now create the unconditional branch + fixup to the
434 fragP
->fr_literal
[offset
+ 2] = 0xfc;
435 fix_new (fragP
, fragP
->fr_fix
+ 3, 2, fragP
->fr_symbol
,
436 fragP
->fr_offset
+ 1, 1, BFD_RELOC_16_PCREL
);
440 else if (fragP
->fr_subtype
== 2)
442 /* Reverse the condition of the first branch. */
443 int offset
= fragP
->fr_fix
;
444 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
481 fragP
->fr_literal
[offset
] = opcode
;
483 /* Set the displacement bits so that we branch around
484 the unconditional branch. */
485 fragP
->fr_literal
[offset
+ 1] = 0x7;
487 /* Now create the unconditional branch + fixup to the
489 fragP
->fr_literal
[offset
+ 2] = 0xf4;
490 fragP
->fr_literal
[offset
+ 3] = 0xe0;
491 fix_new (fragP
, fragP
->fr_fix
+ 4, 4, fragP
->fr_symbol
,
492 fragP
->fr_offset
+ 2, 1, BFD_RELOC_24_PCREL
);
496 else if (fragP
->fr_subtype
== 3)
498 fix_new (fragP
, fragP
->fr_fix
+ 2, 1, fragP
->fr_symbol
,
499 fragP
->fr_offset
+ 2, 1, BFD_RELOC_8_PCREL
);
503 else if (fragP
->fr_subtype
== 4)
505 /* Reverse the condition of the first branch. */
506 int offset
= fragP
->fr_fix
;
507 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
567 fragP
->fr_literal
[offset
+ 1] = opcode
;
569 /* Set the displacement bits so that we branch around
570 the unconditional branch. */
571 fragP
->fr_literal
[offset
+ 2] = 0x6;
573 /* Now create the unconditional branch + fixup to the
575 fragP
->fr_literal
[offset
+ 3] = 0xfc;
576 fix_new (fragP
, fragP
->fr_fix
+ 4, 2, fragP
->fr_symbol
,
577 fragP
->fr_offset
+ 1, 1, BFD_RELOC_16_PCREL
);
581 else if (fragP
->fr_subtype
== 5)
583 /* Reverse the condition of the first branch. */
584 int offset
= fragP
->fr_fix
;
585 int opcode
= fragP
->fr_literal
[offset
+ 1] & 0xff;
645 fragP
->fr_literal
[offset
+ 1] = opcode
;
647 /* Set the displacement bits so that we branch around
648 the unconditional branch. */
649 fragP
->fr_literal
[offset
+ 2] = 0x8;
651 /* Now create the unconditional branch + fixup to the
653 fragP
->fr_literal
[offset
+ 3] = 0xf4;
654 fragP
->fr_literal
[offset
+ 4] = 0xe0;
655 fix_new (fragP
, fragP
->fr_fix
+ 5, 4, fragP
->fr_symbol
,
656 fragP
->fr_offset
+ 2, 1, BFD_RELOC_24_PCREL
);
660 else if (fragP
->fr_subtype
== 6)
662 fix_new (fragP
, fragP
->fr_fix
+ 1, 2, fragP
->fr_symbol
,
663 fragP
->fr_offset
+ 1, 1, BFD_RELOC_16_PCREL
);
667 else if (fragP
->fr_subtype
== 7)
669 int offset
= fragP
->fr_fix
;
670 int opcode
= fragP
->fr_literal
[offset
] & 0xff;
674 fragP
->fr_literal
[offset
] = 0xf4;
675 fragP
->fr_literal
[offset
+ 1] = 0xe0;
677 else if (opcode
== 0xfd)
679 fragP
->fr_literal
[offset
] = 0xf4;
680 fragP
->fr_literal
[offset
+ 1] = 0xe1;
685 fix_new (fragP
, fragP
->fr_fix
+ 2, 4, fragP
->fr_symbol
,
686 fragP
->fr_offset
+ 2, 1, BFD_RELOC_24_PCREL
);
695 md_section_align (seg
, addr
)
699 int align
= bfd_get_section_alignment (stdoutput
, seg
);
700 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
706 char *prev_name
= "";
707 register const struct mn10200_opcode
*op
;
709 mn10200_hash
= hash_new();
711 /* Insert unique names into hash table. The MN10200 instruction set
712 has many identical opcode names that have different opcodes based
713 on the operands. This hash table then provides a quick index to
714 the first opcode with a particular name in the opcode table. */
716 op
= mn10200_opcodes
;
719 if (strcmp (prev_name
, op
->name
))
721 prev_name
= (char *) op
->name
;
722 hash_insert (mn10200_hash
, op
->name
, (char *) op
);
727 /* This is both a simplification (we don't have to write md_apply_fix)
728 and support for future optimizations (branch shortening and similar
729 stuff in the linker. */
738 struct mn10200_opcode
*opcode
;
739 struct mn10200_opcode
*next_opcode
;
740 const unsigned char *opindex_ptr
;
741 int next_opindex
, relaxable
;
742 unsigned long insn
, extension
, size
= 0;
747 /* Get the opcode. */
748 for (s
= str
; *s
!= '\0' && ! isspace (*s
); s
++)
753 /* find the first opcode with the proper name */
754 opcode
= (struct mn10200_opcode
*)hash_find (mn10200_hash
, str
);
757 as_bad ("Unrecognized opcode: `%s'", str
);
762 while (isspace (*str
))
765 input_line_pointer
= str
;
769 const char *errmsg
= NULL
;
778 insn
= opcode
->opcode
;
780 for (op_idx
= 1, opindex_ptr
= opcode
->operands
;
782 opindex_ptr
++, op_idx
++)
784 const struct mn10200_operand
*operand
;
787 if (next_opindex
== 0)
789 operand
= &mn10200_operands
[*opindex_ptr
];
793 operand
= &mn10200_operands
[next_opindex
];
799 while (*str
== ' ' || *str
== ',')
802 if (operand
->flags
& MN10200_OPERAND_RELAX
)
805 /* Gather the operand. */
806 hold
= input_line_pointer
;
807 input_line_pointer
= str
;
809 if (operand
->flags
& MN10200_OPERAND_PAREN
)
811 if (*input_line_pointer
!= ')' && *input_line_pointer
!= '(')
813 input_line_pointer
= hold
;
817 input_line_pointer
++;
820 /* See if we can match the operands. */
821 else if (operand
->flags
& MN10200_OPERAND_DREG
)
823 if (!data_register_name (&ex
))
825 input_line_pointer
= hold
;
830 else if (operand
->flags
& MN10200_OPERAND_AREG
)
832 if (!address_register_name (&ex
))
834 input_line_pointer
= hold
;
839 else if (operand
->flags
& MN10200_OPERAND_PSW
)
841 char *start
= input_line_pointer
;
842 char c
= get_symbol_end ();
844 if (strcmp (start
, "psw") != 0)
846 *input_line_pointer
= c
;
847 input_line_pointer
= hold
;
851 *input_line_pointer
= c
;
854 else if (operand
->flags
& MN10200_OPERAND_MDR
)
856 char *start
= input_line_pointer
;
857 char c
= get_symbol_end ();
859 if (strcmp (start
, "mdr") != 0)
861 *input_line_pointer
= c
;
862 input_line_pointer
= hold
;
866 *input_line_pointer
= c
;
869 else if (data_register_name (&ex
))
871 input_line_pointer
= hold
;
875 else if (address_register_name (&ex
))
877 input_line_pointer
= hold
;
881 else if (other_register_name (&ex
))
883 input_line_pointer
= hold
;
887 else if (*str
== ')' || *str
== '(')
889 input_line_pointer
= hold
;
901 errmsg
= "illegal operand";
904 errmsg
= "missing operand";
908 & (MN10200_OPERAND_DREG
| MN10200_OPERAND_AREG
)) == 0)
910 input_line_pointer
= hold
;
915 if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_5
)
917 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_6
918 || opcode
->format
== FMT_7
)
923 mn10200_insert_operand (&insn
, &extension
, operand
,
924 ex
.X_add_number
, (char *) NULL
,
930 /* If this operand can be promoted, and it doesn't
931 fit into the allocated bitfield for this insn,
932 then promote it (ie this opcode does not match). */
933 if (operand
->flags
& MN10200_OPERAND_PROMOTE
934 && ! check_operand (insn
, operand
, ex
.X_add_number
))
936 input_line_pointer
= hold
;
941 mn10200_insert_operand (&insn
, &extension
, operand
,
942 ex
.X_add_number
, (char *) NULL
,
947 /* If this operand can be promoted, then this opcode didn't
948 match since we can't know if it needed promotion! */
949 if (operand
->flags
& MN10200_OPERAND_PROMOTE
)
951 input_line_pointer
= hold
;
956 /* We need to generate a fixup for this expression. */
957 if (fc
>= MAX_INSN_FIXUPS
)
958 as_fatal ("too many fixups");
960 fixups
[fc
].opindex
= *opindex_ptr
;
961 fixups
[fc
].reloc
= BFD_RELOC_UNUSED
;
967 str
= input_line_pointer
;
968 input_line_pointer
= hold
;
970 while (*str
== ' ' || *str
== ',')
975 /* Make sure we used all the operands! */
982 next_opcode
= opcode
+ 1;
983 if (!strcmp(next_opcode
->name
, opcode
->name
))
985 opcode
= next_opcode
;
989 as_bad ("%s", errmsg
);
995 while (isspace (*str
))
999 as_bad ("junk at end of line: `%s'", str
);
1001 input_line_pointer
= str
;
1003 if (opcode
->format
== FMT_1
)
1005 else if (opcode
->format
== FMT_2
|| opcode
->format
== FMT_4
)
1007 else if (opcode
->format
== FMT_3
|| opcode
->format
== FMT_5
)
1009 else if (opcode
->format
== FMT_6
)
1011 else if (opcode
->format
== FMT_7
)
1016 /* Write out the instruction. */
1018 if (relaxable
&& fc
> 0)
1025 && opcode
->opcode
!= 0xfd0000 && opcode
->opcode
!= 0xfc0000)
1029 f
= frag_var (rs_machine_dependent
, 8, 8 - size
, type
,
1030 fixups
[0].exp
.X_add_symbol
,
1031 fixups
[0].exp
.X_add_number
,
1032 (char *)fixups
[0].opindex
);
1033 number_to_chars_bigendian (f
, insn
, size
);
1036 number_to_chars_bigendian (f
+ size
, 0, 4);
1037 number_to_chars_bigendian (f
+ size
+ 4, 0, 8 - size
- 4);
1040 number_to_chars_bigendian (f
+ size
, 0, 8 - size
);
1045 f
= frag_more (size
);
1047 /* Oh, what a mess. The instruction is in big endian format, but
1048 16 and 24bit immediates are little endian! */
1049 if (opcode
->format
== FMT_3
)
1051 number_to_chars_bigendian (f
, (insn
>> 16) & 0xff, 1);
1052 number_to_chars_littleendian (f
+ 1, insn
& 0xffff, 2);
1054 else if (opcode
->format
== FMT_6
)
1056 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1057 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1059 else if (opcode
->format
== FMT_7
)
1061 number_to_chars_bigendian (f
, (insn
>> 16) & 0xffff, 2);
1062 number_to_chars_littleendian (f
+ 2, insn
& 0xffff, 2);
1063 number_to_chars_littleendian (f
+ 4, extension
& 0xff, 1);
1067 number_to_chars_bigendian (f
, insn
, size
> 4 ? 4 : size
);
1070 /* Create any fixups. */
1071 for (i
= 0; i
< fc
; i
++)
1073 const struct mn10200_operand
*operand
;
1075 operand
= &mn10200_operands
[fixups
[i
].opindex
];
1076 if (fixups
[i
].reloc
!= BFD_RELOC_UNUSED
)
1078 reloc_howto_type
*reloc_howto
;
1083 reloc_howto
= bfd_reloc_type_lookup (stdoutput
, fixups
[i
].reloc
);
1088 size
= bfd_get_reloc_size (reloc_howto
);
1090 if (size
< 1 || size
> 4)
1094 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1097 reloc_howto
->pc_relative
,
1102 int reloc
, pcrel
, reloc_size
, offset
;
1105 reloc
= BFD_RELOC_NONE
;
1106 /* How big is the reloc? Remember SPLIT relocs are
1107 implicitly 32bits. */
1108 reloc_size
= operand
->bits
;
1110 offset
= size
- reloc_size
/ 8;
1112 /* Is the reloc pc-relative? */
1113 pcrel
= (operand
->flags
& MN10200_OPERAND_PCREL
) != 0;
1116 /* Choose a proper BFD relocation type. */
1119 if (reloc_size
== 8)
1120 reloc
= BFD_RELOC_8_PCREL
;
1121 else if (reloc_size
== 24)
1122 reloc
= BFD_RELOC_24_PCREL
;
1128 if (reloc_size
== 32)
1129 reloc
= BFD_RELOC_32
;
1130 else if (reloc_size
== 16)
1131 reloc
= BFD_RELOC_16
;
1132 else if (reloc_size
== 8)
1133 reloc
= BFD_RELOC_8
;
1134 else if (reloc_size
== 24)
1135 reloc
= BFD_RELOC_24
;
1140 /* Convert the size of the reloc into what fix_new_exp wants. */
1141 reloc_size
= reloc_size
/ 8;
1142 if (reloc_size
== 8)
1144 else if (reloc_size
== 16)
1146 else if (reloc_size
== 32 || reloc_size
== 24)
1149 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
1150 reloc_size
, &fixups
[i
].exp
, pcrel
,
1151 ((bfd_reloc_code_real_type
) reloc
));
1153 fixP
->fx_offset
+= offset
;
1160 /* if while processing a fixup, a reloc really needs to be created */
1161 /* then it is done here */
1164 tc_gen_reloc (seg
, fixp
)
1169 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
1171 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1172 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1174 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1175 "reloc %d not supported by object file format",
1176 (int)fixp
->fx_r_type
);
1179 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1181 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
1183 reloc
->sym_ptr_ptr
= &bfd_abs_symbol
;
1184 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
1185 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
1189 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1190 reloc
->addend
= fixp
->fx_offset
;
1196 md_estimate_size_before_relax (fragp
, seg
)
1200 if (fragp
->fr_subtype
== 0)
1202 if (fragp
->fr_subtype
== 3)
1204 if (fragp
->fr_subtype
== 6)
1206 if (!S_IS_DEFINED (fragp
->fr_symbol
))
1208 fragp
->fr_subtype
= 7;
1216 md_pcrel_from (fixp
)
1219 return fixp
->fx_frag
->fr_address
;
1221 if (fixp
->fx_addsy
!= (symbolS
*) NULL
&& ! S_IS_DEFINED (fixp
->fx_addsy
))
1223 /* The symbol is undefined. Let the linker figure it out. */
1226 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1231 md_apply_fix3 (fixp
, valuep
, seg
)
1236 /* We shouldn't ever get here because linkrelax is nonzero. */
1242 /* Insert an operand value into an instruction. */
1245 mn10200_insert_operand (insnp
, extensionp
, operand
, val
, file
, line
, shift
)
1246 unsigned long *insnp
;
1247 unsigned long *extensionp
;
1248 const struct mn10200_operand
*operand
;
1254 /* No need to check 24 or 32bit operands for a bit. */
1255 if (operand
->bits
< 24
1256 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1261 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1263 max
= (1 << (operand
->bits
- 1)) - 1;
1264 min
= - (1 << (operand
->bits
- 1));
1268 max
= (1 << operand
->bits
) - 1;
1275 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1278 "operand out of range (%s not between %ld and %ld)";
1281 sprint_value (buf
, test
);
1282 if (file
== (char *) NULL
)
1283 as_warn (err
, buf
, min
, max
);
1285 as_warn_where (file
, line
, err
, buf
, min
, max
);
1289 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) == 0)
1291 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1292 << (operand
->shift
+ shift
));
1294 if ((operand
->flags
& MN10200_OPERAND_REPEATED
) != 0)
1295 *insnp
|= (((long) val
& ((1 << operand
->bits
) - 1))
1296 << (operand
->shift
+ shift
+ 2));
1300 *extensionp
|= (val
>> 16) & 0xff;
1301 *insnp
|= val
& 0xffff;
1305 static unsigned long
1306 check_operand (insn
, operand
, val
)
1308 const struct mn10200_operand
*operand
;
1311 /* No need to check 24bit or 32bit operands for a bit. */
1312 if (operand
->bits
< 24
1313 && (operand
->flags
& MN10200_OPERAND_NOCHECK
) == 0)
1318 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
1320 max
= (1 << (operand
->bits
- 1)) - 1;
1321 min
= - (1 << (operand
->bits
- 1));
1325 max
= (1 << operand
->bits
) - 1;
1332 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)