/* tc-mn10300.c -- Assembler code for the Matsushita 10300
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
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 <stdio.h>
#include "as.h"
as in 0d1.0. */
const char FLT_CHARS[] = "dD";
\f
-const relax_typeS md_relax_table[] = {
+const relax_typeS md_relax_table[] =
+{
+ /* The plus values for the bCC and fBCC instructions in the table below
+ are because the branch instruction is translated into a jump
+ instruction that is now +2 or +3 bytes further on in memory, and the
+ correct size of jump instruction must be selected. */
/* bCC relaxing */
{0x7f, -0x80, 2, 1},
- {0x7fff, -0x8000, 5, 2},
+ {0x7fff + 2, -0x8000 + 2, 5, 2},
{0x7fffffff, -0x80000000, 7, 0},
- /* bCC relaxing (uncommon cases) */
+ /* bCC relaxing (uncommon cases for 3byte length instructions) */
{0x7f, -0x80, 3, 4},
- {0x7fff, -0x8000, 6, 5},
+ {0x7fff + 3, -0x8000 + 3, 6, 5},
{0x7fffffff, -0x80000000, 8, 0},
/* call relaxing */
/* fbCC relaxing */
{0x7f, -0x80, 3, 14},
- {0x7fff, -0x8000, 6, 15},
+ {0x7fff + 3, -0x8000 + 3, 6, 15},
{0x7fffffff, -0x80000000, 8, 0},
};
}
/* Set the default machine type. */
+#ifdef TE_LINUX
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, AM33_2))
+ as_warn (_("could not set architecture and machine"));
+
+ current_machine = AM33_2;
+#else
if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, MN103))
as_warn (_("could not set architecture and machine"));
current_machine = MN103;
+#endif
}
static symbolS *GOT_symbol;
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 loosing 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;
/* We want to anchor the line info to the previous frag (if
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);
/* This is pretty hokey. We basically just care about the
opcode, so we have to write out the first word big endian.
break;
default:
- reloc->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
+ reloc->sym_ptr_ptr
+ = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
return reloc;
}
}
}
void
-md_apply_fix3 (fixP, valP, seg)
+md_apply_fix (fixP, valP, seg)
fixS * fixP;
valueT * valP;
segT seg;
abort ();
/* The value we are passed in *valuep includes the symbol values.
- Since we are using BFD_ASSEMBLER, if we are doing this relocation
- the code in write.c is going to call bfd_install_relocation, which
- is also going to use the symbol value. That means that if the
- reloc is fully resolved we want to use *valuep since
- bfd_install_relocation is not being used.
+ If we are doing this relocation the code in write.c is going to
+ call bfd_install_relocation, which is also going to use the symbol
+ value. That means that if the reloc is fully resolved we want to
+ use *valuep since bfd_install_relocation is not being used.
However, if the reloc is not fully resolved we do not want to use
*valuep, and must use fx_offset instead. However, if the reloc
if (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE)
return 0;
+ /* Likewise, do not adjust symbols that won't be merged, or debug
+ symbols, because they too break relaxation. We do want to adjust
+ other mergable symbols, like .rodata, because code relaxations
+ need section-relative symbols to properly relax them. */
+ if (! (S_GET_SEGMENT(fixp->fx_addsy)->flags & SEC_MERGE))
+ return 0;
+ if (strncmp (S_GET_SEGMENT (fixp->fx_addsy)->name, ".debug", 6) == 0)
+ return 0;
+
return 1;
}
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);
- }
+ as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
}
if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
}
int
-mn10300_parse_name (name, exprP, nextcharP)
+mn10300_parse_name (name, exprP, mode, nextcharP)
char const *name;
expressionS *exprP;
+ enum expr_mode mode;
char *nextcharP;
{
char *next = input_line_pointer;
/* If we have an absolute symbol or a reg,
then we know its value now. */
segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (segment == absolute_section)
+ if (mode != expr_defer && segment == absolute_section)
{
exprP->X_op = O_constant;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
exprP->X_add_symbol = NULL;
}
- else if (segment == reg_section)
+ else if (mode != expr_defer && segment == reg_section)
{
exprP->X_op = O_register;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);