X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-mn10200.c;h=6323e54dc27091e0c4f821d2943983f83d3c4b64;hb=9a01ec4c0368048fb5ea1ba1b3af9afbd651b529;hp=78545080b203a074f6a7850e0398bdd236e5b99f;hpb=f7e42eb4af140e0068476b586464eaed5569548d;p=binutils-gdb.git diff --git a/gas/config/tc-mn10200.c b/gas/config/tc-mn10200.c index 78545080b20..6323e54dc27 100644 --- a/gas/config/tc-mn10200.c +++ b/gas/config/tc-mn10200.c @@ -1,11 +1,11 @@ /* tc-mn10200.c -- Assembler code for the Matsushita 10200 - Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1996-2021 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -15,12 +15,11 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + the Free Software Foundation, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ -#include -#include #include "as.h" +#include "safe-ctype.h" #include "subsegs.h" #include "opcode/mn10200.h" @@ -52,7 +51,8 @@ const char EXP_CHARS[] = "eE"; as in 0d1.0. */ const char FLT_CHARS[] = "dD"; -const relax_typeS md_relax_table[] = { +const relax_typeS md_relax_table[] = + { /* bCC relaxing */ {0x81, -0x7e, 2, 1}, {0x8004, -0x7ffb, 5, 2}, @@ -71,34 +71,27 @@ const relax_typeS md_relax_table[] = { }; -/* Local functions. */ -static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *, - const struct mn10200_operand *, - offsetT, char *, unsigned, - unsigned)); -static unsigned long check_operand PARAMS ((unsigned long, - const struct mn10200_operand *, - offsetT)); -static int reg_name_search PARAMS ((const struct reg_name *, int, const char *)); -static boolean data_register_name PARAMS ((expressionS *expressionP)); -static boolean address_register_name PARAMS ((expressionS *expressionP)); -static boolean other_register_name PARAMS ((expressionS *expressionP)); /* Fixups. */ -#define MAX_INSN_FIXUPS (5) +#define MAX_INSN_FIXUPS 5 + struct mn10200_fixup { expressionS exp; int opindex; bfd_reloc_code_real_type reloc; }; + struct mn10200_fixup fixups[MAX_INSN_FIXUPS]; static int fc; const char *md_shortopts = ""; -struct option md_longopts[] = { + +struct option md_longopts[] = +{ {NULL, no_argument, NULL, 0} }; + size_t md_longopts_size = sizeof (md_longopts); /* The target specific pseudo-ops which we support. */ @@ -108,7 +101,7 @@ const pseudo_typeS md_pseudo_table[] = }; /* Opcode hash table. */ -static struct hash_control *mn10200_hash; +static htab_t mn10200_hash; /* This table is sorted. Suitable for searching by a binary search. */ static const struct reg_name data_registers[] = @@ -140,14 +133,13 @@ static const struct reg_name other_registers[] = (sizeof (other_registers) / sizeof (struct reg_name)) /* reg_name_search does a binary search of the given register table - to see if "name" is a valid regiter name. Returns the register + to see if "name" is a valid register name. Returns the register number from the array on success, or -1 on failure. */ static int -reg_name_search (regs, regcount, name) - const struct reg_name *regs; - int regcount; - const char *name; +reg_name_search (const struct reg_name *regs, + int regcount, + const char *name) { int middle, low, high; int cmp; @@ -171,19 +163,17 @@ reg_name_search (regs, regcount, name) } /* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: A expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - -static boolean -data_register_name (expressionP) - expressionS *expressionP; + + in: Input_line_pointer points to 1st char of operand. + + out: An expressionS. + The operand may have been a register: in this case, X_op == O_register, + X_add_number is set to the register number, and truth is returned. + Input_line_pointer->(next non-blank) char after operand, or is in + its original state. */ + +static bool +data_register_name (expressionS *expressionP) { int reg_number; char *name; @@ -191,11 +181,13 @@ data_register_name (expressionP) char c; /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); + start = input_line_pointer; + c = get_symbol_name (&name); reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name); + /* Put back the delimiting char. */ + (void) restore_line_pointer (c); + /* Look to see if it's in the register table. */ if (reg_number >= 0) { @@ -206,36 +198,26 @@ data_register_name (expressionP) expressionP->X_add_symbol = NULL; expressionP->X_op_symbol = NULL; - /* Put back the delimiting char. */ - *input_line_pointer = c; return true; } - else - { - /* Reset the line as if we had not done anything. */ - /* Put back the delimiting char. */ - *input_line_pointer = c; - /* Reset input_line pointer. */ - input_line_pointer = start; - return false; - } + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + return false; } /* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: A expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - -static boolean -address_register_name (expressionP) - expressionS *expressionP; + + in: Input_line_pointer points to 1st char of operand. + + out: An expressionS. + The operand may have been a register: in this case, X_op == O_register, + X_add_number is set to the register number, and truth is returned. + Input_line_pointer->(next non-blank) char after operand, or is in + its original state. */ + +static bool +address_register_name (expressionS *expressionP) { int reg_number; char *name; @@ -243,11 +225,13 @@ address_register_name (expressionP) char c; /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); + start = input_line_pointer; + c = get_symbol_name (&name); reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name); + /* Put back the delimiting char. */ + (void) restore_line_pointer (c); + /* Look to see if it's in the register table. */ if (reg_number >= 0) { @@ -258,36 +242,26 @@ address_register_name (expressionP) expressionP->X_add_symbol = NULL; expressionP->X_op_symbol = NULL; - /* Put back the delimiting char. */ - *input_line_pointer = c; return true; } - else - { - /* Reset the line as if we had not done anything. */ - /* Put back the delimiting char. */ - *input_line_pointer = c; - /* Reset input_line pointer. */ - input_line_pointer = start; - return false; - } + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + return false; } /* Summary of register_name(). - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: A expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in - * its original state. - */ - -static boolean -other_register_name (expressionP) - expressionS *expressionP; + + in: Input_line_pointer points to 1st char of operand. + + out: An expressionS. + The operand may have been a register: in this case, X_op == O_register, + X_add_number is set to the register number, and truth is returned. + Input_line_pointer->(next non-blank) char after operand, or is in + its original state. */ + +static bool +other_register_name (expressionS *expressionP) { int reg_number; char *name; @@ -295,11 +269,13 @@ other_register_name (expressionP) char c; /* Find the spelling of the operand. */ - start = name = input_line_pointer; - - c = get_symbol_end (); + start = input_line_pointer; + c = get_symbol_name (&name); reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name); + /* Put back the delimiting char. */ + (void) restore_line_pointer (c); + /* Look to see if it's in the register table. */ if (reg_number >= 0) { @@ -310,91 +286,44 @@ other_register_name (expressionP) expressionP->X_add_symbol = NULL; expressionP->X_op_symbol = NULL; - /* Put back the delimiting char. */ - *input_line_pointer = c; return true; } - else - { - /* Reset the line as if we had not done anything. */ - /* Put back the delimiting char. */ - *input_line_pointer = c; - /* Reset input_line pointer. */ - input_line_pointer = start; - return false; - } + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + return false; } void -md_show_usage (stream) - FILE *stream; +md_show_usage (FILE *stream) { fprintf (stream, _("MN10200 options:\n\ none yet\n")); } int -md_parse_option (c, arg) - int c; - char *arg; +md_parse_option (int c ATTRIBUTE_UNUSED, + const char *arg ATTRIBUTE_UNUSED) { return 0; } symbolS * -md_undefined_symbol (name) - char *name; +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { return 0; } -char * -md_atof (type, litp, sizep) - int type; - char *litp; - int *sizep; +const char * +md_atof (int type, char *litp, int *sizep) { - int prec; - LITTLENUM_TYPE words[4]; - char *t; - int i; - - switch (type) - { - case 'f': - prec = 2; - break; - - case 'd': - prec = 4; - break; - - default: - *sizep = 0; - return _("bad call to md_atof"); - } - - t = atof_ieee (input_line_pointer, type, words); - if (t) - input_line_pointer = t; - - *sizep = prec * 2; - - for (i = prec - 1; i >= 0; i--) - { - md_number_to_chars (litp, (valueT) words[i], 2); - litp += 2; - } - - return NULL; + return ieee_md_atof (type, litp, sizep, false); } void -md_convert_frag (abfd, sec, fragP) - bfd *abfd; - asection *sec; - fragS *fragP; +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + fragS *fragP) { static unsigned long label_count = 0; char buf[40]; @@ -451,9 +380,9 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_literal[offset] = opcode; /* Create a fixup for the reversed conditional branch. */ - sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); + sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 1, 1, - symbol_new (buf, sec, 0, fragP->fr_next), + symbol_new (buf, sec, fragP->fr_next, 0), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the @@ -508,9 +437,9 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_literal[offset] = opcode; /* Create a fixup for the reversed conditional branch. */ - sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); + sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 1, 1, - symbol_new (buf, sec, 0, fragP->fr_next), + symbol_new (buf, sec, fragP->fr_next, 0), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the @@ -548,6 +477,7 @@ md_convert_frag (abfd, sec, fragP) break; case 0xff: opcode = 0xfe; + break; case 0xe8: opcode = 0xe9; break; @@ -596,9 +526,9 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ - sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); + sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, - symbol_new (buf, sec, 0, fragP->fr_next), + symbol_new (buf, sec, fragP->fr_next, 0), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the @@ -628,6 +558,7 @@ md_convert_frag (abfd, sec, fragP) break; case 0xff: opcode = 0xfe; + break; case 0xe8: opcode = 0xe9; break; @@ -676,9 +607,9 @@ md_convert_frag (abfd, sec, fragP) fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ - sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); + sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, - symbol_new (buf, sec, 0, fragP->fr_next), + symbol_new (buf, sec, fragP->fr_next, 0), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the @@ -742,21 +673,19 @@ md_convert_frag (abfd, sec, fragP) } valueT -md_section_align (seg, addr) - asection *seg; - valueT addr; +md_section_align (asection *seg, valueT addr) { - int align = bfd_get_section_alignment (stdoutput, seg); - return ((addr + (1 << align) - 1) & (-1 << align)); + int align = bfd_section_alignment (seg); + return ((addr + (1 << align) - 1) & -(1 << align)); } void -md_begin () +md_begin (void) { - char *prev_name = ""; - register const struct mn10200_opcode *op; + const char *prev_name = ""; + const struct mn10200_opcode *op; - mn10200_hash = hash_new (); + mn10200_hash = str_htab_create (); /* Insert unique names into hash table. The MN10200 instruction set has many identical opcode names that have different opcodes based @@ -769,7 +698,7 @@ md_begin () if (strcmp (prev_name, op->name)) { prev_name = (char *) op->name; - hash_insert (mn10200_hash, op->name, (char *) op); + str_hash_insert (mn10200_hash, op->name, op, 0); } op++; } @@ -780,9 +709,169 @@ md_begin () linkrelax = 1; } +static unsigned long +check_operand (unsigned long insn ATTRIBUTE_UNUSED, + const struct mn10200_operand *operand, + offsetT val) +{ + /* No need to check 24bit or 32bit operands for a bit. */ + if (operand->bits < 24 + && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) + { + long min, max; + offsetT test; + + if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) + { + max = (1 << (operand->bits - 1)) - 1; + min = - (1 << (operand->bits - 1)); + } + else + { + max = (1 << operand->bits) - 1; + min = 0; + } + + test = val; + + if (test < (offsetT) min || test > (offsetT) max) + return 0; + else + return 1; + } + return 1; +} +/* If while processing a fixup, a reloc really needs to be created + Then it is done here. */ + +arelent * +tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) +{ + arelent *reloc; + reloc = XNEW (arelent); + + if (fixp->fx_subsy != NULL) + { + if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy) + && S_IS_DEFINED (fixp->fx_subsy)) + { + fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); + fixp->fx_subsy = NULL; + } + else + /* FIXME: We should try more ways to resolve difference expressions + here. At least this is better than silently ignoring the + subtrahend. */ + as_bad_where (fixp->fx_file, fixp->fx_line, + _("can't resolve `%s' {%s section} - `%s' {%s section}"), + fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0", + segment_name (fixp->fx_addsy + ? S_GET_SEGMENT (fixp->fx_addsy) + : absolute_section), + S_GET_NAME (fixp->fx_subsy), + segment_name (S_GET_SEGMENT (fixp->fx_addsy))); + } + + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); + if (reloc->howto == NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("reloc %d not supported by object file format"), + (int) fixp->fx_r_type); + return NULL; + } + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->sym_ptr_ptr = XNEW (asymbol *); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + reloc->addend = fixp->fx_offset; + return reloc; +} + +int +md_estimate_size_before_relax (fragS *fragp, asection *seg) +{ + if (fragp->fr_subtype == 6 + && (!S_IS_DEFINED (fragp->fr_symbol) + || seg != S_GET_SEGMENT (fragp->fr_symbol))) + fragp->fr_subtype = 7; + else if (fragp->fr_subtype == 8 + && (!S_IS_DEFINED (fragp->fr_symbol) + || seg != S_GET_SEGMENT (fragp->fr_symbol))) + fragp->fr_subtype = 10; + + if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0])) + abort (); + + return md_relax_table[fragp->fr_subtype].rlx_length; +} + +long +md_pcrel_from (fixS *fixp) +{ + return fixp->fx_frag->fr_address; +} + +void +md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED) +{ + /* We shouldn't ever get here because linkrelax is nonzero. */ + abort (); + fixP->fx_done = 1; +} + +/* Insert an operand value into an instruction. */ + +static void +mn10200_insert_operand (unsigned long *insnp, + unsigned long *extensionp, + const struct mn10200_operand *operand, + offsetT val, + char *file, + unsigned int line, + unsigned int shift) +{ + /* No need to check 24 or 32bit operands for a bit. */ + if (operand->bits < 24 + && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) + { + long min, max; + offsetT test; + + if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) + { + max = (1 << (operand->bits - 1)) - 1; + min = - (1 << (operand->bits - 1)); + } + else + { + max = (1 << operand->bits) - 1; + min = 0; + } + + test = val; + + if (test < (offsetT) min || test > (offsetT) max) + as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line); + } + + if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0) + { + *insnp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift)); + + if ((operand->flags & MN10200_OPERAND_REPEATED) != 0) + *insnp |= (((long) val & ((1 << operand->bits) - 1)) + << (operand->shift + shift + 2)); + } + else + { + *extensionp |= (val >> 16) & 0xff; + *insnp |= val & 0xffff; + } +} + void -md_assemble (str) - char *str; +md_assemble (char *str) { char *s; struct mn10200_opcode *opcode; @@ -795,13 +884,13 @@ md_assemble (str) int match; /* Get the opcode. */ - for (s = str; *s != '\0' && !isspace (*s); s++) + for (s = str; *s != '\0' && !ISSPACE (*s); s++) ; if (*s != '\0') *s++ = '\0'; /* Find the first opcode with the proper name. */ - opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str); + opcode = (struct mn10200_opcode *) str_hash_find (mn10200_hash, str); if (opcode == NULL) { as_bad (_("Unrecognized opcode: `%s'"), str); @@ -809,7 +898,7 @@ md_assemble (str) } str = s; - while (isspace (*str)) + while (ISSPACE (*str)) ++str; input_line_pointer = str; @@ -888,32 +977,32 @@ md_assemble (str) } else if (operand->flags & MN10200_OPERAND_PSW) { - char *start = input_line_pointer; - char c = get_symbol_end (); + char *start; + char c = get_symbol_name (&start); if (strcmp (start, "psw") != 0) { - *input_line_pointer = c; + (void) restore_line_pointer (c); input_line_pointer = hold; str = hold; goto error; } - *input_line_pointer = c; + (void) restore_line_pointer (c); goto keep_going; } else if (operand->flags & MN10200_OPERAND_MDR) { - char *start = input_line_pointer; - char c = get_symbol_end (); + char *start; + char c = get_symbol_name (&start); if (strcmp (start, "mdr") != 0) { - *input_line_pointer = c; + (void) restore_line_pointer (c); input_line_pointer = hold; str = hold; goto error; } - *input_line_pointer = c; + (void) restore_line_pointer (c); goto keep_going; } else if (data_register_name (&ex)) @@ -971,7 +1060,7 @@ md_assemble (str) extra_shift = 0; mn10200_insert_operand (&insn, &extension, operand, - ex.X_add_number, (char *) NULL, + ex.X_add_number, NULL, 0, extra_shift); break; @@ -990,7 +1079,7 @@ md_assemble (str) } mn10200_insert_operand (&insn, &extension, operand, - ex.X_add_number, (char *) NULL, + ex.X_add_number, NULL, 0, 0); break; @@ -1014,7 +1103,7 @@ md_assemble (str) break; } -keep_going: + keep_going: str = input_line_pointer; input_line_pointer = hold; @@ -1043,7 +1132,7 @@ keep_going: break; } - while (isspace (*str)) + while (ISSPACE (*str)) ++str; if (*str != '\0') @@ -1065,9 +1154,21 @@ keep_going: abort (); /* Write out the instruction. */ - + dwarf2_emit_insn (size); if (relaxable && fc > 0) { + /* On a 64-bit host the size of an 'int' is not the same + as the size of a pointer, so we need a union to convert + the opindex field of the fr_cgen structure into a char * + so that it can be stored in the frag. We do not have + to worry about losing accuracy as we are not going to + be even close to the 32bit limit of the int. */ + union + { + int opindex; + char * ptr; + } + opindex_converter; int type; /* bCC */ @@ -1095,10 +1196,11 @@ keep_going: else type = 3; + opindex_converter.opindex = fixups[0].opindex; f = frag_var (rs_machine_dependent, 8, 8 - size, type, fixups[0].exp.X_add_symbol, fixups[0].exp.X_add_number, - (char *)fixups[0].opindex); + opindex_converter.ptr); number_to_chars_bigendian (f, insn, size); if (8 - size > 4) { @@ -1108,7 +1210,6 @@ keep_going: else number_to_chars_bigendian (f + size, 0, 8 - size); } - else { f = frag_more (size); @@ -1132,20 +1233,18 @@ keep_going: number_to_chars_littleendian (f + 4, extension & 0xff, 1); } else - { - number_to_chars_bigendian (f, insn, size > 4 ? 4 : size); - } + number_to_chars_bigendian (f, insn, size > 4 ? 4 : size); /* Create any fixups. */ for (i = 0; i < fc; i++) { const struct mn10200_operand *operand; + int reloc_size; operand = &mn10200_operands[fixups[i].opindex]; if (fixups[i].reloc != BFD_RELOC_UNUSED) { reloc_howto_type *reloc_howto; - int size; int offset; fixS *fixP; @@ -1155,14 +1254,14 @@ keep_going: if (!reloc_howto) abort (); - size = bfd_get_reloc_size (reloc_howto); + reloc_size = bfd_get_reloc_size (reloc_howto); - if (size < 1 || size > 4) + if (reloc_size < 1 || reloc_size > 4) abort (); - offset = 4 - size; + offset = 4 - reloc_size; fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, - size, + reloc_size, &fixups[i].exp, reloc_howto->pc_relative, fixups[i].reloc); @@ -1171,11 +1270,11 @@ keep_going: next instruction, not from the start of the current instruction. */ if (reloc_howto->pc_relative) - fixP->fx_offset += size; + fixP->fx_offset += reloc_size; } else { - int reloc, pcrel, reloc_size, offset; + int reloc, pcrel, offset; fixS *fixP; reloc = BFD_RELOC_NONE; @@ -1235,199 +1334,3 @@ keep_going: } } } - -/* If while processing a fixup, a reloc really needs to be created - Then it is done here. */ - -arelent * -tc_gen_reloc (seg, fixp) - asection *seg; - fixS *fixp; -{ - arelent *reloc; - reloc = (arelent *) xmalloc (sizeof (arelent)); - - reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); - if (reloc->howto == (reloc_howto_type *) NULL) - { - as_bad_where (fixp->fx_file, fixp->fx_line, - _("reloc %d not supported by object file format"), - (int) fixp->fx_r_type); - return NULL; - } - reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; - - if (fixp->fx_addsy && fixp->fx_subsy) - { - if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy)) - || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section) - { - as_bad_where (fixp->fx_file, fixp->fx_line, - "Difference of symbols in different sections is not supported"); - return NULL; - } - reloc->sym_ptr_ptr = &bfd_abs_symbol; - reloc->addend = (S_GET_VALUE (fixp->fx_addsy) - - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset); - } - else - { - reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); - *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - reloc->addend = fixp->fx_offset; - } - return reloc; -} - -int -md_estimate_size_before_relax (fragp, seg) - fragS *fragp; - asection *seg; -{ - if (fragp->fr_subtype == 0) - return 2; - if (fragp->fr_subtype == 3) - return 3; - if (fragp->fr_subtype == 6) - { - if (!S_IS_DEFINED (fragp->fr_symbol) - || seg != S_GET_SEGMENT (fragp->fr_symbol)) - { - fragp->fr_subtype = 7; - return 5; - } - return 3; - } - if (fragp->fr_subtype == 8) - { - if (!S_IS_DEFINED (fragp->fr_symbol)) - { - fragp->fr_subtype = 10; - return 5; - } - return 2; - } -} - -long -md_pcrel_from (fixp) - fixS *fixp; -{ - return fixp->fx_frag->fr_address; -#if 0 - if (fixp->fx_addsy != (symbolS *) NULL && !S_IS_DEFINED (fixp->fx_addsy)) - { - /* The symbol is undefined. Let the linker figure it out. */ - return 0; - } - return fixp->fx_frag->fr_address + fixp->fx_where; -#endif -} - -int -md_apply_fix3 (fixp, valuep, seg) - fixS *fixp; - valueT *valuep; - segT seg; -{ - /* We shouldn't ever get here because linkrelax is nonzero. */ - abort (); - fixp->fx_done = 1; - return 0; -} - -/* Insert an operand value into an instruction. */ - -static void -mn10200_insert_operand (insnp, extensionp, operand, val, file, line, shift) - unsigned long *insnp; - unsigned long *extensionp; - const struct mn10200_operand *operand; - offsetT val; - char *file; - unsigned int line; - unsigned int shift; -{ - /* No need to check 24 or 32bit operands for a bit. */ - if (operand->bits < 24 - && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) - { - long min, max; - offsetT test; - - if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) - { - max = (1 << (operand->bits - 1)) - 1; - min = - (1 << (operand->bits - 1)); - } - else - { - max = (1 << operand->bits) - 1; - min = 0; - } - - test = val; - - if (test < (offsetT) min || test > (offsetT) max) - { - const char *err = - _("operand out of range (%s not between %ld and %ld)"); - char buf[100]; - - sprint_value (buf, test); - if (file == (char *) NULL) - as_warn (err, buf, min, max); - else - as_warn_where (file, line, err, buf, min, max); - } - } - - if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0) - { - *insnp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift)); - - if ((operand->flags & MN10200_OPERAND_REPEATED) != 0) - *insnp |= (((long) val & ((1 << operand->bits) - 1)) - << (operand->shift + shift + 2)); - } - else - { - *extensionp |= (val >> 16) & 0xff; - *insnp |= val & 0xffff; - } -} - -static unsigned long -check_operand (insn, operand, val) - unsigned long insn; - const struct mn10200_operand *operand; - offsetT val; -{ - /* No need to check 24bit or 32bit operands for a bit. */ - if (operand->bits < 24 - && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) - { - long min, max; - offsetT test; - - if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) - { - max = (1 << (operand->bits - 1)) - 1; - min = - (1 << (operand->bits - 1)); - } - else - { - max = (1 << operand->bits) - 1; - min = 0; - } - - test = val; - - if (test < (offsetT) min || test > (offsetT) max) - return 0; - else - return 1; - } - return 1; -}