1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
3 Copyright (C) 1996, 1997, 1998 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 {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 static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *,
76 const struct mn10200_operand *,
77 offsetT, char *, unsigned,
79 static unsigned long check_operand PARAMS ((unsigned long,
80 const struct mn10200_operand *,
82 static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
83 static boolean data_register_name PARAMS ((expressionS *expressionP));
84 static boolean address_register_name PARAMS ((expressionS *expressionP));
85 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 (sizeof(data_registers) / sizeof(struct reg_name))
124 static const struct reg_name address_registers[] =
131 #define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
133 static const struct reg_name other_registers[] =
138 #define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
140 /* reg_name_search does a binary search of the given register table
141 to see if "name" is a valid regiter name. Returns the register
142 number from the array on success, or -1 on failure. */
145 reg_name_search (regs, regcount, name)
146 const struct reg_name *regs;
150 int middle, low, high;
158 middle = (low + high) / 2;
159 cmp = strcasecmp (name, regs[middle].name);
165 return regs[middle].value;
172 /* Summary of register_name().
174 * in: Input_line_pointer points to 1st char of operand.
176 * out: A expressionS.
177 * The operand may have been a register: in this case, X_op == O_register,
178 * X_add_number is set to the register number, and truth is returned.
179 * Input_line_pointer->(next non-blank) char after operand, or is in
180 * its original state.
183 data_register_name (expressionP)
184 expressionS *expressionP;
191 /* Find the spelling of the operand */
192 start = name = input_line_pointer;
194 c = get_symbol_end ();
195 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
197 /* look to see if it's in the register table */
200 expressionP->X_op = O_register;
201 expressionP->X_add_number = reg_number;
203 /* make the rest nice */
204 expressionP->X_add_symbol = NULL;
205 expressionP->X_op_symbol = NULL;
206 *input_line_pointer = c; /* put back the delimiting char */
211 /* reset the line as if we had not done anything */
212 *input_line_pointer = c; /* put back the delimiting char */
213 input_line_pointer = start; /* reset input_line pointer */
218 /* Summary of register_name().
220 * in: Input_line_pointer points to 1st char of operand.
222 * out: A expressionS.
223 * The operand may have been a register: in this case, X_op == O_register,
224 * X_add_number is set to the register number, and truth is returned.
225 * Input_line_pointer->(next non-blank) char after operand, or is in
226 * its original state.
229 address_register_name (expressionP)
230 expressionS *expressionP;
237 /* Find the spelling of the operand */
238 start = name = input_line_pointer;
240 c = get_symbol_end ();
241 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
243 /* look to see if it's in the register table */
246 expressionP->X_op = O_register;
247 expressionP->X_add_number = reg_number;
249 /* make the rest nice */
250 expressionP->X_add_symbol = NULL;
251 expressionP->X_op_symbol = NULL;
252 *input_line_pointer = c; /* put back the delimiting char */
257 /* reset the line as if we had not done anything */
258 *input_line_pointer = c; /* put back the delimiting char */
259 input_line_pointer = start; /* reset input_line pointer */
264 /* Summary of register_name().
266 * in: Input_line_pointer points to 1st char of operand.
268 * out: A expressionS.
269 * The operand may have been a register: in this case, X_op == O_register,
270 * X_add_number is set to the register number, and truth is returned.
271 * Input_line_pointer->(next non-blank) char after operand, or is in
272 * its original state.
275 other_register_name (expressionP)
276 expressionS *expressionP;
283 /* Find the spelling of the operand */
284 start = name = input_line_pointer;
286 c = get_symbol_end ();
287 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
289 /* look to see if it's in the register table */
292 expressionP->X_op = O_register;
293 expressionP->X_add_number = reg_number;
295 /* make the rest nice */
296 expressionP->X_add_symbol = NULL;
297 expressionP->X_op_symbol = NULL;
298 *input_line_pointer = c; /* put back the delimiting char */
303 /* reset the line as if we had not done anything */
304 *input_line_pointer = c; /* put back the delimiting char */
305 input_line_pointer = start; /* reset input_line pointer */
311 md_show_usage (stream)
314 fprintf(stream, _("MN10200 options:\n\
319 md_parse_option (c, arg)
327 md_undefined_symbol (name)
334 md_atof (type, litp, sizep)
340 LITTLENUM_TYPE words[4];
356 return _("bad call to md_atof");
359 t = atof_ieee (input_line_pointer, type, words);
361 input_line_pointer = t;
365 for (i = prec - 1; i >= 0; i--)
367 md_number_to_chars (litp, (valueT) words[i], 2);
376 md_convert_frag (abfd, sec, fragP)
381 static unsigned long label_count = 0;
384 subseg_change (sec, 0);
385 if (fragP->fr_subtype == 0)
387 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
388 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
392 else if (fragP->fr_subtype == 1)
394 /* Reverse the condition of the first branch. */
395 int offset = fragP->fr_fix;
396 int opcode = fragP->fr_literal[offset] & 0xff;
433 fragP->fr_literal[offset] = opcode;
435 /* Create a fixup for the reversed conditional branch. */
436 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
437 fix_new (fragP, fragP->fr_fix + 1, 1,
438 symbol_new (buf, sec, 0, fragP->fr_next),
439 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
441 /* Now create the unconditional branch + fixup to the
443 fragP->fr_literal[offset + 2] = 0xfc;
444 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
445 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
449 else if (fragP->fr_subtype == 2)
451 /* Reverse the condition of the first branch. */
452 int offset = fragP->fr_fix;
453 int opcode = fragP->fr_literal[offset] & 0xff;
490 fragP->fr_literal[offset] = opcode;
492 /* Create a fixup for the reversed conditional branch. */
493 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
494 fix_new (fragP, fragP->fr_fix + 1, 1,
495 symbol_new (buf, sec, 0, fragP->fr_next),
496 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
498 /* Now create the unconditional branch + fixup to the
500 fragP->fr_literal[offset + 2] = 0xf4;
501 fragP->fr_literal[offset + 3] = 0xe0;
502 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
503 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
507 else if (fragP->fr_subtype == 3)
509 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
510 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
514 else if (fragP->fr_subtype == 4)
516 /* Reverse the condition of the first branch. */
517 int offset = fragP->fr_fix;
518 int opcode = fragP->fr_literal[offset + 1] & 0xff;
578 fragP->fr_literal[offset + 1] = opcode;
580 /* Create a fixup for the reversed conditional branch. */
581 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
582 fix_new (fragP, fragP->fr_fix + 2, 1,
583 symbol_new (buf, sec, 0, fragP->fr_next),
584 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
586 /* Now create the unconditional branch + fixup to the
588 fragP->fr_literal[offset + 3] = 0xfc;
589 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
590 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
594 else if (fragP->fr_subtype == 5)
596 /* Reverse the condition of the first branch. */
597 int offset = fragP->fr_fix;
598 int opcode = fragP->fr_literal[offset + 1] & 0xff;
658 fragP->fr_literal[offset + 1] = opcode;
660 /* Create a fixup for the reversed conditional branch. */
661 sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
662 fix_new (fragP, fragP->fr_fix + 2, 1,
663 symbol_new (buf, sec, 0, fragP->fr_next),
664 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
666 /* Now create the unconditional branch + fixup to the
668 fragP->fr_literal[offset + 3] = 0xf4;
669 fragP->fr_literal[offset + 4] = 0xe0;
670 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
671 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
675 else if (fragP->fr_subtype == 6)
677 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
678 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
682 else if (fragP->fr_subtype == 7)
684 int offset = fragP->fr_fix;
685 fragP->fr_literal[offset] = 0xf4;
686 fragP->fr_literal[offset + 1] = 0xe1;
688 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
689 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
693 else if (fragP->fr_subtype == 8)
695 fragP->fr_literal[fragP->fr_fix] = 0xea;
696 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
697 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
701 else if (fragP->fr_subtype == 9)
703 int offset = fragP->fr_fix;
704 fragP->fr_literal[offset] = 0xfc;
706 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
707 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
711 else if (fragP->fr_subtype == 10)
713 int offset = fragP->fr_fix;
714 fragP->fr_literal[offset] = 0xf4;
715 fragP->fr_literal[offset + 1] = 0xe0;
717 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
718 fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
727 md_section_align (seg, addr)
731 int align = bfd_get_section_alignment (stdoutput, seg);
732 return ((addr + (1 << align) - 1) & (-1 << align));
738 char *prev_name = "";
739 register const struct mn10200_opcode *op;
741 mn10200_hash = hash_new();
743 /* Insert unique names into hash table. The MN10200 instruction set
744 has many identical opcode names that have different opcodes based
745 on the operands. This hash table then provides a quick index to
746 the first opcode with a particular name in the opcode table. */
748 op = mn10200_opcodes;
751 if (strcmp (prev_name, op->name))
753 prev_name = (char *) op->name;
754 hash_insert (mn10200_hash, op->name, (char *) op);
759 /* This is both a simplification (we don't have to write md_apply_fix)
760 and support for future optimizations (branch shortening and similar
761 stuff in the linker. */
770 struct mn10200_opcode *opcode;
771 struct mn10200_opcode *next_opcode;
772 const unsigned char *opindex_ptr;
773 int next_opindex, relaxable;
774 unsigned long insn, extension, size = 0;
779 /* Get the opcode. */
780 for (s = str; *s != '\0' && ! isspace (*s); s++)
785 /* find the first opcode with the proper name */
786 opcode = (struct mn10200_opcode *)hash_find (mn10200_hash, str);
789 as_bad (_("Unrecognized opcode: `%s'"), str);
794 while (isspace (*str))
797 input_line_pointer = str;
801 const char *errmsg = NULL;
810 insn = opcode->opcode;
812 for (op_idx = 1, opindex_ptr = opcode->operands;
814 opindex_ptr++, op_idx++)
816 const struct mn10200_operand *operand;
819 if (next_opindex == 0)
821 operand = &mn10200_operands[*opindex_ptr];
825 operand = &mn10200_operands[next_opindex];
831 while (*str == ' ' || *str == ',')
834 if (operand->flags & MN10200_OPERAND_RELAX)
837 /* Gather the operand. */
838 hold = input_line_pointer;
839 input_line_pointer = str;
841 if (operand->flags & MN10200_OPERAND_PAREN)
843 if (*input_line_pointer != ')' && *input_line_pointer != '(')
845 input_line_pointer = hold;
849 input_line_pointer++;
852 /* See if we can match the operands. */
853 else if (operand->flags & MN10200_OPERAND_DREG)
855 if (!data_register_name (&ex))
857 input_line_pointer = hold;
862 else if (operand->flags & MN10200_OPERAND_AREG)
864 if (!address_register_name (&ex))
866 input_line_pointer = hold;
871 else if (operand->flags & MN10200_OPERAND_PSW)
873 char *start = input_line_pointer;
874 char c = get_symbol_end ();
876 if (strcmp (start, "psw") != 0)
878 *input_line_pointer = c;
879 input_line_pointer = hold;
883 *input_line_pointer = c;
886 else if (operand->flags & MN10200_OPERAND_MDR)
888 char *start = input_line_pointer;
889 char c = get_symbol_end ();
891 if (strcmp (start, "mdr") != 0)
893 *input_line_pointer = c;
894 input_line_pointer = hold;
898 *input_line_pointer = c;
901 else if (data_register_name (&ex))
903 input_line_pointer = hold;
907 else if (address_register_name (&ex))
909 input_line_pointer = hold;
913 else if (other_register_name (&ex))
915 input_line_pointer = hold;
919 else if (*str == ')' || *str == '(')
921 input_line_pointer = hold;
933 errmsg = _("illegal operand");
936 errmsg = _("missing operand");
940 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
942 input_line_pointer = hold;
947 if (opcode->format == FMT_2 || opcode->format == FMT_5)
949 else if (opcode->format == FMT_3 || opcode->format == FMT_6
950 || opcode->format == FMT_7)
955 mn10200_insert_operand (&insn, &extension, operand,
956 ex.X_add_number, (char *) NULL,
962 /* If this operand can be promoted, and it doesn't
963 fit into the allocated bitfield for this insn,
964 then promote it (ie this opcode does not match). */
966 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
967 && ! check_operand (insn, operand, ex.X_add_number))
969 input_line_pointer = hold;
974 mn10200_insert_operand (&insn, &extension, operand,
975 ex.X_add_number, (char *) NULL,
980 /* If this operand can be promoted, then this opcode didn't
981 match since we can't know if it needed promotion! */
982 if (operand->flags & MN10200_OPERAND_PROMOTE)
984 input_line_pointer = hold;
989 /* We need to generate a fixup for this expression. */
990 if (fc >= MAX_INSN_FIXUPS)
991 as_fatal (_("too many fixups"));
993 fixups[fc].opindex = *opindex_ptr;
994 fixups[fc].reloc = BFD_RELOC_UNUSED;
1000 str = input_line_pointer;
1001 input_line_pointer = hold;
1003 while (*str == ' ' || *str == ',')
1008 /* Make sure we used all the operands! */
1015 next_opcode = opcode + 1;
1016 if (!strcmp(next_opcode->name, opcode->name))
1018 opcode = next_opcode;
1022 as_bad ("%s", errmsg);
1028 while (isspace (*str))
1032 as_bad (_("junk at end of line: `%s'"), str);
1034 input_line_pointer = str;
1036 if (opcode->format == FMT_1)
1038 else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1040 else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1042 else if (opcode->format == FMT_6)
1044 else if (opcode->format == FMT_7)
1049 /* Write out the instruction. */
1051 if (relaxable && fc > 0)
1056 if (size == 2 && opcode->opcode != 0xfc0000)
1058 /* Handle bra specially. Basically treat it like jmp so
1059 that we automatically handle 8, 16 and 32 bit offsets
1060 correctly as well as jumps to an undefined address.
1062 It is also important to not treat it like other bCC
1063 instructions since the long forms of bra is different
1064 from other bCC instructions. */
1065 if (opcode->opcode == 0xea00)
1071 else if (size == 3 && opcode->opcode == 0xfd0000)
1074 else if (size == 3 && opcode->opcode == 0xfc0000)
1080 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1081 fixups[0].exp.X_add_symbol,
1082 fixups[0].exp.X_add_number,
1083 (char *)fixups[0].opindex);
1084 number_to_chars_bigendian (f, insn, size);
1087 number_to_chars_bigendian (f + size, 0, 4);
1088 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1091 number_to_chars_bigendian (f + size, 0, 8 - size);
1096 f = frag_more (size);
1098 /* Oh, what a mess. The instruction is in big endian format, but
1099 16 and 24bit immediates are little endian! */
1100 if (opcode->format == FMT_3)
1102 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1103 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1105 else if (opcode->format == FMT_6)
1107 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1108 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1110 else if (opcode->format == FMT_7)
1112 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1113 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1114 number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1118 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1121 /* Create any fixups. */
1122 for (i = 0; i < fc; i++)
1124 const struct mn10200_operand *operand;
1126 operand = &mn10200_operands[fixups[i].opindex];
1127 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1129 reloc_howto_type *reloc_howto;
1134 reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
1139 size = bfd_get_reloc_size (reloc_howto);
1141 if (size < 1 || size > 4)
1145 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1148 reloc_howto->pc_relative,
1151 /* PC-relative offsets are from the first byte of the next
1152 instruction, not from the start of the current instruction. */
1153 if (reloc_howto->pc_relative)
1154 fixP->fx_offset += size;
1158 int reloc, pcrel, reloc_size, offset;
1161 reloc = BFD_RELOC_NONE;
1162 /* How big is the reloc? Remember SPLIT relocs are
1163 implicitly 32bits. */
1164 reloc_size = operand->bits;
1166 offset = size - reloc_size / 8;
1168 /* Is the reloc pc-relative? */
1169 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1172 /* Choose a proper BFD relocation type. */
1175 if (reloc_size == 8)
1176 reloc = BFD_RELOC_8_PCREL;
1177 else if (reloc_size == 24)
1178 reloc = BFD_RELOC_24_PCREL;
1184 if (reloc_size == 32)
1185 reloc = BFD_RELOC_32;
1186 else if (reloc_size == 16)
1187 reloc = BFD_RELOC_16;
1188 else if (reloc_size == 8)
1189 reloc = BFD_RELOC_8;
1190 else if (reloc_size == 24)
1191 reloc = BFD_RELOC_24;
1196 /* Convert the size of the reloc into what fix_new_exp wants. */
1197 reloc_size = reloc_size / 8;
1198 if (reloc_size == 8)
1200 else if (reloc_size == 16)
1202 else if (reloc_size == 32 || reloc_size == 24)
1205 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1206 reloc_size, &fixups[i].exp, pcrel,
1207 ((bfd_reloc_code_real_type) reloc));
1209 /* PC-relative offsets are from the first byte of the next
1210 instruction, not from the start of the current instruction. */
1212 fixP->fx_offset += size;
1219 /* if while processing a fixup, a reloc really needs to be created */
1220 /* then it is done here */
1223 tc_gen_reloc (seg, fixp)
1228 reloc = (arelent *) xmalloc (sizeof (arelent));
1230 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1231 if (reloc->howto == (reloc_howto_type *) NULL)
1233 as_bad_where (fixp->fx_file, fixp->fx_line,
1234 _("reloc %d not supported by object file format"),
1235 (int)fixp->fx_r_type);
1238 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1240 if (fixp->fx_addsy && fixp->fx_subsy)
1242 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1243 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1245 as_bad_where (fixp->fx_file, fixp->fx_line,
1246 "Difference of symbols in different sections is not supported");
1249 reloc->sym_ptr_ptr = &bfd_abs_symbol;
1250 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
1251 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
1255 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
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)