projects
/
deliverable
/
binutils-gdb.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
MIPS/GAS: Don't convert RELA JALR relocations on R6
[deliverable/binutils-gdb.git]
/
gas
/
config
/
tc-mips.c
diff --git
a/gas/config/tc-mips.c
b/gas/config/tc-mips.c
index e61bb4daab15e5a35d207f98a1a3f6bb80b4c26e..402282996567642b6791c84c82a9b0236bb2861c 100644
(file)
--- a/
gas/config/tc-mips.c
+++ b/
gas/config/tc-mips.c
@@
-1,5
+1,5
@@
/* tc-mips.c -- assemble code for a MIPS chip.
/* tc-mips.c -- assemble code for a MIPS chip.
- Copyright (C) 1993-201
5
Free Software Foundation, Inc.
+ Copyright (C) 1993-201
6
Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
@@
-349,7
+349,7
@@
static int mips_32bitmode = 0;
/* Likewise 64-bit registers. */
#define ABI_NEEDS_64BIT_REGS(ABI) \
/* Likewise 64-bit registers. */
#define ABI_NEEDS_64BIT_REGS(ABI) \
- ((ABI) == N32_ABI \
+ ((ABI) == N32_ABI \
|| (ABI) == N64_ABI \
|| (ABI) == O64_ABI)
|| (ABI) == N64_ABI \
|| (ABI) == O64_ABI)
@@
-1017,7
+1017,7
@@
static int mips_relax_branch;
/* Branch without likely bit. If label is out of range, we turn:
/* Branch without likely bit. If label is out of range, we turn:
- beq reg1, reg2, label
+ beq reg1, reg2, label
delay slot
into
delay slot
into
@@
-1307,7
+1307,7
@@
static void mips16_macro (struct mips_cl_insn * ip);
static void mips_ip (char *str, struct mips_cl_insn * ip);
static void mips16_ip (char *str, struct mips_cl_insn * ip);
static void mips16_immed
static void mips_ip (char *str, struct mips_cl_insn * ip);
static void mips16_ip (char *str, struct mips_cl_insn * ip);
static void mips16_immed
- (char *, unsigned int, int, bfd_reloc_code_real_type, offsetT,
+ (c
onst c
har *, unsigned int, int, bfd_reloc_code_real_type, offsetT,
unsigned int, unsigned long *);
static size_t my_getSmallExpression
(expressionS *, bfd_reloc_code_real_type *, char *);
unsigned int, unsigned long *);
static size_t my_getSmallExpression
(expressionS *, bfd_reloc_code_real_type *, char *);
@@
-1410,6
+1410,8
@@
enum options
OPTION_NO_SMARTMIPS,
OPTION_DSPR2,
OPTION_NO_DSPR2,
OPTION_NO_SMARTMIPS,
OPTION_DSPR2,
OPTION_NO_DSPR2,
+ OPTION_DSPR3,
+ OPTION_NO_DSPR3,
OPTION_EVA,
OPTION_NO_EVA,
OPTION_XPA,
OPTION_EVA,
OPTION_NO_EVA,
OPTION_XPA,
@@
-1522,6
+1524,8
@@
struct option md_longopts[] =
{"mno-smartmips", no_argument, NULL, OPTION_NO_SMARTMIPS},
{"mdspr2", no_argument, NULL, OPTION_DSPR2},
{"mno-dspr2", no_argument, NULL, OPTION_NO_DSPR2},
{"mno-smartmips", no_argument, NULL, OPTION_NO_SMARTMIPS},
{"mdspr2", no_argument, NULL, OPTION_DSPR2},
{"mno-dspr2", no_argument, NULL, OPTION_NO_DSPR2},
+ {"mdspr3", no_argument, NULL, OPTION_DSPR3},
+ {"mno-dspr3", no_argument, NULL, OPTION_NO_DSPR3},
{"meva", no_argument, NULL, OPTION_EVA},
{"mno-eva", no_argument, NULL, OPTION_NO_EVA},
{"mmicromips", no_argument, NULL, OPTION_MICROMIPS},
{"meva", no_argument, NULL, OPTION_EVA},
{"mno-eva", no_argument, NULL, OPTION_NO_EVA},
{"mmicromips", no_argument, NULL, OPTION_MICROMIPS},
@@
-1663,6
+1667,11
@@
static const struct mips_ase mips_ases[] = {
2, 2, 2, 2,
-1 },
2, 2, 2, 2,
-1 },
+ { "dspr3", ASE_DSP | ASE_DSPR2 | ASE_DSPR3, 0,
+ OPTION_DSPR3, OPTION_NO_DSPR3,
+ 6, 6, -1, -1,
+ -1 },
+
{ "eva", ASE_EVA, 0,
OPTION_EVA, OPTION_NO_EVA,
2, 2, 2, 2,
{ "eva", ASE_EVA, 0,
OPTION_EVA, OPTION_NO_EVA,
2, 2, 2, 2,
@@
-1716,7
+1725,7
@@
static const struct mips_ase mips_ases[] = {
/* Groups of ASE_* flags that represent different revisions of an ASE. */
static const unsigned int mips_ase_groups[] = {
/* Groups of ASE_* flags that represent different revisions of an ASE. */
static const unsigned int mips_ase_groups[] = {
- ASE_DSP | ASE_DSPR2
+ ASE_DSP | ASE_DSPR2
| ASE_DSPR3
};
\f
/* Pseudo-op table.
};
\f
/* Pseudo-op table.
@@
-1868,7
+1877,7
@@
mips_clear_insn_labels (void)
{
for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
;
{
for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
;
-
+
si = seg_info (now_seg);
*pl = si->label_list;
si->label_list = NULL;
si = seg_info (now_seg);
*pl = si->label_list;
si->label_list = NULL;
@@
-2089,10
+2098,8
@@
mips_lookup_ase (const char *name)
}
/* Return the length of a microMIPS instruction in bytes. If bits of
}
/* Return the length of a microMIPS instruction in bytes. If bits of
- the mask beyond the low 16 are 0, then it is a 16-bit instruction.
- Otherwise assume a 32-bit instruction; 48-bit instructions (0x1f
- major opcode) will require further modifications to the opcode
- table. */
+ the mask beyond the low 16 are 0, then it is a 16-bit instruction,
+ otherwise it is a 32-bit instruction. */
static inline unsigned int
micromips_insn_length (const struct mips_opcode *mo)
static inline unsigned int
micromips_insn_length (const struct mips_opcode *mo)
@@
-2422,9
+2429,8
@@
set_insn_error_ss (int argnum, const char *msg, const char *s1, const char *s2)
static void
report_insn_error (const char *str)
{
static void
report_insn_error (const char *str)
{
- const char *msg;
+ const char *msg
= concat (insn_error.msg, " `%s'", NULL)
;
- msg = ACONCAT ((insn_error.msg, " `%s'", NULL));
switch (insn_error.format)
{
case ERR_FMT_PLAIN:
switch (insn_error.format)
{
case ERR_FMT_PLAIN:
@@
-2439,6
+2445,8
@@
report_insn_error (const char *str)
as_bad (msg, insn_error.u.ss[0], insn_error.u.ss[1], str);
break;
}
as_bad (msg, insn_error.u.ss[0], insn_error.u.ss[1], str);
break;
}
+
+ free ((char *) msg);
}
/* Initialize vr4120_conflicts. There is a bit of duplication here:
}
/* Initialize vr4120_conflicts. There is a bit of duplication here:
@@
-2542,7
+2550,7
@@
struct regname {
{"$28", RTYPE_NUM | 28}, \
{"$29", RTYPE_NUM | 29}, \
{"$30", RTYPE_NUM | 30}, \
{"$28", RTYPE_NUM | 28}, \
{"$29", RTYPE_NUM | 29}, \
{"$30", RTYPE_NUM | 30}, \
- {"$31", RTYPE_NUM | 31}
+ {"$31", RTYPE_NUM | 31}
#define FPU_REGISTER_NAMES \
{"$f0", RTYPE_FPU | 0}, \
#define FPU_REGISTER_NAMES \
{"$f0", RTYPE_FPU | 0}, \
@@
-2624,7
+2632,7
@@
struct regname {
{"$ta0", RTYPE_GP | 12}, /* alias for $t4 */ \
{"$ta1", RTYPE_GP | 13}, /* alias for $t5 */ \
{"$ta2", RTYPE_GP | 14}, /* alias for $t6 */ \
{"$ta0", RTYPE_GP | 12}, /* alias for $t4 */ \
{"$ta1", RTYPE_GP | 13}, /* alias for $t5 */ \
{"$ta2", RTYPE_GP | 14}, /* alias for $t6 */ \
- {"$ta3", RTYPE_GP | 15} /* alias for $t7 */
+ {"$ta3", RTYPE_GP | 15} /* alias for $t7 */
/* Remaining symbolic register names */
#define SYMBOLIC_REGISTER_NAMES \
/* Remaining symbolic register names */
#define SYMBOLIC_REGISTER_NAMES \
@@
-2720,7
+2728,7
@@
static const struct regname reg_names[] = {
/* The $txx registers depends on the abi,
these will be added later into the symbol table from
/* The $txx registers depends on the abi,
these will be added later into the symbol table from
- one of the tables below once mips_abi is set after
+ one of the tables below once mips_abi is set after
parsing of arguments from the command line. */
SYMBOLIC_REGISTER_NAMES,
parsing of arguments from the command line. */
SYMBOLIC_REGISTER_NAMES,
@@
-3043,7
+3051,8
@@
mips_parse_base_start (char *s)
static char *
mips_parse_argument_token (char *s, char float_format)
{
static char *
mips_parse_argument_token (char *s, char float_format)
{
- char *end, *save_in, *err;
+ char *end, *save_in;
+ const char *err;
unsigned int regno1, regno2, channels;
struct mips_operand_token token;
unsigned int regno1, regno2, channels;
struct mips_operand_token token;
@@
-3466,6
+3475,12
@@
md_begin (void)
as_bad (_("-G may not be used in position-independent code"));
g_switch_value = 0;
}
as_bad (_("-G may not be used in position-independent code"));
g_switch_value = 0;
}
+ else if (mips_abicalls)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_bad (_("-G may not be used with abicalls"));
+ g_switch_value = 0;
+ }
if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
as_warn (_("could not set architecture and machine"));
if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
as_warn (_("could not set architecture and machine"));
@@
-3578,38
+3593,37
@@
md_begin (void)
/* We add all the general register names to the symbol table. This
helps us detect invalid uses of them. */
/* We add all the general register names to the symbol table. This
helps us detect invalid uses of them. */
- for (i = 0; reg_names[i].name; i++)
+ for (i = 0; reg_names[i].name; i++)
symbol_table_insert (symbol_new (reg_names[i].name, reg_section,
reg_names[i].num, /* & RNUM_MASK, */
&zero_address_frag));
if (HAVE_NEWABI)
symbol_table_insert (symbol_new (reg_names[i].name, reg_section,
reg_names[i].num, /* & RNUM_MASK, */
&zero_address_frag));
if (HAVE_NEWABI)
- for (i = 0; reg_names_n32n64[i].name; i++)
+ for (i = 0; reg_names_n32n64[i].name; i++)
symbol_table_insert (symbol_new (reg_names_n32n64[i].name, reg_section,
reg_names_n32n64[i].num, /* & RNUM_MASK, */
&zero_address_frag));
else
symbol_table_insert (symbol_new (reg_names_n32n64[i].name, reg_section,
reg_names_n32n64[i].num, /* & RNUM_MASK, */
&zero_address_frag));
else
- for (i = 0; reg_names_o32[i].name; i++)
+ for (i = 0; reg_names_o32[i].name; i++)
symbol_table_insert (symbol_new (reg_names_o32[i].name, reg_section,
reg_names_o32[i].num, /* & RNUM_MASK, */
&zero_address_frag));
for (i = 0; i < 32; i++)
{
symbol_table_insert (symbol_new (reg_names_o32[i].name, reg_section,
reg_names_o32[i].num, /* & RNUM_MASK, */
&zero_address_frag));
for (i = 0; i < 32; i++)
{
- char regname[
7
];
+ char regname[
6
];
/* R5900 VU0 floating-point register. */
/* R5900 VU0 floating-point register. */
- regname[sizeof (rename) - 1] = 0;
- snprintf (regname, sizeof (regname) - 1, "$vf%d", i);
+ sprintf (regname, "$vf%d", i);
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_VF | i, &zero_address_frag));
/* R5900 VU0 integer register. */
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_VF | i, &zero_address_frag));
/* R5900 VU0 integer register. */
- s
nprintf (regname, sizeof (regname) - 1
, "$vi%d", i);
+ s
printf (regname
, "$vi%d", i);
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_VI | i, &zero_address_frag));
/* MSA register. */
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_VI | i, &zero_address_frag));
/* MSA register. */
- s
nprintf (regname, sizeof (regname) - 1
, "$w%d", i);
+ s
printf (regname
, "$w%d", i);
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_MSA | i, &zero_address_frag));
}
symbol_table_insert (symbol_new (regname, reg_section,
RTYPE_MSA | i, &zero_address_frag));
}
@@
-3797,6
+3811,10
@@
check_fpabi (int fpabi)
Tag_GNU_MIPS_ABI_FP, fpabi);
break;
Tag_GNU_MIPS_ABI_FP, fpabi);
break;
+ case Val_GNU_MIPS_ABI_FP_NAN2008:
+ /* Silently ignore compatibility value. */
+ break;
+
default:
as_warn (_(".gnu_attribute %d,%d is not a recognized"
" floating-point ABI"), Tag_GNU_MIPS_ABI_FP, fpabi);
default:
as_warn (_(".gnu_attribute %d,%d is not a recognized"
" floating-point ABI"), Tag_GNU_MIPS_ABI_FP, fpabi);
@@
-3840,7
+3858,7
@@
mips_check_options (struct mips_set_options *opts, bfd_boolean abi_checks)
if (abi_checks
&& ABI_NEEDS_64BIT_REGS (mips_abi))
as_warn (_("`fp=32' used with a 64-bit ABI"));
if (abi_checks
&& ABI_NEEDS_64BIT_REGS (mips_abi))
as_warn (_("`fp=32' used with a 64-bit ABI"));
- if (ISA_IS_R6 (
mips_opts.
isa) && opts->single_float == 0)
+ if (ISA_IS_R6 (
opts->
isa) && opts->single_float == 0)
as_bad (_("`fp=32' used with a MIPS R6 cpu"));
break;
default:
as_bad (_("`fp=32' used with a MIPS R6 cpu"));
break;
default:
@@
-3852,13
+3870,13
@@
mips_check_options (struct mips_set_options *opts, bfd_boolean abi_checks)
as_bad (_("`nooddspreg` cannot be used with a 64-bit ABI"));
if (opts->micromips == 1 && opts->mips16 == 1)
as_bad (_("`nooddspreg` cannot be used with a 64-bit ABI"));
if (opts->micromips == 1 && opts->mips16 == 1)
- as_bad (_("`
mips16' cannot be used with `micromips'")
);
- else if (ISA_IS_R6 (
mips_opts.
isa)
+ as_bad (_("`
%s' cannot be used with `%s'"), "mips16", "micromips"
);
+ else if (ISA_IS_R6 (
opts->
isa)
&& (opts->micromips == 1
|| opts->mips16 == 1))
&& (opts->micromips == 1
|| opts->mips16 == 1))
- as_fatal (_("`%s' can
not be used with `%s'"),
+ as_fatal (_("`%s' cannot be used with `%s'"),
opts->micromips ? "micromips" : "mips16",
opts->micromips ? "micromips" : "mips16",
- mips_cpu_info_from_isa (
mips_opts.
isa)->name);
+ mips_cpu_info_from_isa (
opts->
isa)->name);
if (ISA_IS_R6 (opts->isa) && mips_relax_branch)
as_fatal (_("branch relaxation is not supported in `%s'"),
if (ISA_IS_R6 (opts->isa) && mips_relax_branch)
as_fatal (_("branch relaxation is not supported in `%s'"),
@@
-6255,8
+6273,8
@@
nops_for_vr4130 (int ignore, const struct mips_cl_insn *hist,
return 0;
}
return 0;
}
-#define BASE_REG_EQ(INSN1, INSN2) \
- ((((INSN1) >> OP_SH_RS) & OP_MASK_RS) \
+#define BASE_REG_EQ(INSN1, INSN2) \
+ ((((INSN1) >> OP_SH_RS) & OP_MASK_RS)
\
== (((INSN2) >> OP_SH_RS) & OP_MASK_RS))
/* Return the minimum alignment for this store instruction. */
== (((INSN2) >> OP_SH_RS) & OP_MASK_RS))
/* Return the minimum alignment for this store instruction. */
@@
-6362,7
+6380,7
@@
fix_24k_record_store_info (struct fix_24k_store_info *stinfo,
* Run the data cache in write-through mode.
* Insert a non-store instruction between
Store A and Store B or Store B and Store C. */
* Run the data cache in write-through mode.
* Insert a non-store instruction between
Store A and Store B or Store B and Store C. */
-
+
static int
nops_for_24k (int ignore, const struct mips_cl_insn *hist,
const struct mips_cl_insn *insn)
static int
nops_for_24k (int ignore, const struct mips_cl_insn *hist,
const struct mips_cl_insn *insn)
@@
-6723,11
+6741,11
@@
can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
/* Parameter must be 16 bit. */
&& (*reloc_type == BFD_RELOC_16_PCREL_S2)
/* Branch to same segment. */
/* Parameter must be 16 bit. */
&& (*reloc_type == BFD_RELOC_16_PCREL_S2)
/* Branch to same segment. */
- && (S_GET_SEGMENT(address_expr->X_add_symbol) == now_seg)
+ && (S_GET_SEGMENT
(address_expr->X_add_symbol) == now_seg)
/* Branch to same code fragment. */
/* Branch to same code fragment. */
- && (symbol_get_frag(address_expr->X_add_symbol) == frag_now)
+ && (symbol_get_frag
(address_expr->X_add_symbol) == frag_now)
/* Can only calculate branch offset if value is known. */
/* Can only calculate branch offset if value is known. */
- && symbol_constant_p(address_expr->X_add_symbol)
+ && symbol_constant_p
(address_expr->X_add_symbol)
/* Check if branch is really conditional. */
&& !((ip->insn_opcode & 0xffff0000) == 0x10000000 /* beq $0,$0 */
|| (ip->insn_opcode & 0xffff0000) == 0x04010000 /* bgez $0 */
/* Check if branch is really conditional. */
&& !((ip->insn_opcode & 0xffff0000) == 0x10000000 /* beq $0,$0 */
|| (ip->insn_opcode & 0xffff0000) == 0x04010000 /* bgez $0 */
@@
-6736,7
+6754,7
@@
can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
int distance;
/* Check if loop is shorter than 6 instructions including
branch and delay slot. */
int distance;
/* Check if loop is shorter than 6 instructions including
branch and delay slot. */
- distance = frag_now_fix
() - S_GET_VALUE
(address_expr->X_add_symbol);
+ distance = frag_now_fix
() - S_GET_VALUE
(address_expr->X_add_symbol);
if (distance <= 20)
{
int i;
if (distance <= 20)
{
int i;
@@
-6748,7
+6766,7
@@
can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
for (i = 0; i < (distance / 4); i++)
{
if ((history[i].cleared_p)
for (i = 0; i < (distance / 4); i++)
{
if ((history[i].cleared_p)
- || delayed_branch_p(&history[i]))
+ || delayed_branch_p
(&history[i]))
{
rv = TRUE;
break;
{
rv = TRUE;
break;
@@
-7026,7
+7044,9
@@
append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
{
int shift;
{
int shift;
- shift = mips_opts.micromips ? 1 : 2;
+ /* Shift is 2, unusually, for microMIPS JALX. */
+ shift = (mips_opts.micromips
+ && strcmp (ip->insn_mo->name, "jalx") != 0) ? 1 : 2;
if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
as_bad (_("jump to misaligned address (0x%lx)"),
(unsigned long) address_expr->X_add_number);
if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
as_bad (_("jump to misaligned address (0x%lx)"),
(unsigned long) address_expr->X_add_number);
@@
-7404,8
+7424,7
@@
append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
if (hi_fixup == 0
|| !fixup_has_matching_lo_p (hi_fixup->fixp))
{
if (hi_fixup == 0
|| !fixup_has_matching_lo_p (hi_fixup->fixp))
{
- hi_fixup = ((struct mips_hi_fixup *)
- xmalloc (sizeof (struct mips_hi_fixup)));
+ hi_fixup = XNEW (struct mips_hi_fixup);
hi_fixup->next = mips_hi_fixup_list;
mips_hi_fixup_list = hi_fixup;
}
hi_fixup->next = mips_hi_fixup_list;
mips_hi_fixup_list = hi_fixup;
}
@@
-9321,8
+9340,7
@@
move_register (int dest, int source)
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, "move", "mp,mj", dest, source);
else
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, "move", "mp,mj", dest, source);
else
- macro_build (NULL, GPR_SIZE == 32 ? "addu" : "daddu", "d,v,t",
- dest, source, 0);
+ macro_build (NULL, "or", "d,v,t", dest, source, 0);
}
/* Emit an SVR4 PIC sequence to load address LOCAL into DEST, where
}
/* Emit an SVR4 PIC sequence to load address LOCAL into DEST, where
@@
-10331,10
+10349,12
@@
macro (struct mips_cl_insn *ip, char *str)
breg = op[2];
if (dbl && GPR_SIZE == 32)
breg = op[2];
if (dbl && GPR_SIZE == 32)
- as_warn (_("dla used to load 32-bit register"));
+ as_warn (_("dla used to load 32-bit register; recommend using la "
+ "instead"));
if (!dbl && HAVE_64BIT_OBJECTS)
if (!dbl && HAVE_64BIT_OBJECTS)
- as_warn (_("la used to load 64-bit address"));
+ as_warn (_("la used to load 64-bit address; recommend using dla "
+ "instead"));
if (small_offset_p (0, align, 16))
{
if (small_offset_p (0, align, 16))
{
@@
-11026,7
+11046,7
@@
macro (struct mips_cl_insn *ip, char *str)
if (mips_opts.noreorder)
macro_build (NULL, "nop", "");
expr1.X_add_number = mips_cprestore_offset;
if (mips_opts.noreorder)
macro_build (NULL, "nop", "");
expr1.X_add_number = mips_cprestore_offset;
- macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
+ macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
mips_gp_register,
mips_frame_reg,
HAVE_64BIT_ADDRESSES);
mips_gp_register,
mips_frame_reg,
HAVE_64BIT_ADDRESSES);
@@
-11170,7
+11190,7
@@
macro (struct mips_cl_insn *ip, char *str)
if (mips_opts.noreorder)
macro_build (NULL, "nop", "");
expr1.X_add_number = mips_cprestore_offset;
if (mips_opts.noreorder)
macro_build (NULL, "nop", "");
expr1.X_add_number = mips_cprestore_offset;
- macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
+ macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
mips_gp_register,
mips_frame_reg,
HAVE_64BIT_ADDRESSES);
mips_gp_register,
mips_frame_reg,
HAVE_64BIT_ADDRESSES);
@@
-12127,8
+12147,8
@@
macro (struct mips_cl_insn *ip, char *str)
&& offset_expr.X_add_number == 0);
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
&& offset_expr.X_add_number == 0);
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
- {
- op[2] = mips_gp_register;
+ {
+ op[2] = mips_gp_register;
offset_reloc[0] = BFD_RELOC_MIPS_LITERAL;
offset_reloc[1] = BFD_RELOC_UNUSED;
offset_reloc[2] = BFD_RELOC_UNUSED;
offset_reloc[0] = BFD_RELOC_MIPS_LITERAL;
offset_reloc[1] = BFD_RELOC_UNUSED;
offset_reloc[2] = BFD_RELOC_UNUSED;
@@
-12150,7
+12170,7
@@
macro (struct mips_cl_insn *ip, char *str)
offset_reloc[0] = BFD_RELOC_LO16;
offset_reloc[1] = BFD_RELOC_UNUSED;
offset_reloc[2] = BFD_RELOC_UNUSED;
offset_reloc[0] = BFD_RELOC_LO16;
offset_reloc[1] = BFD_RELOC_UNUSED;
offset_reloc[2] = BFD_RELOC_UNUSED;
- }
+ }
align = 8;
/* Fall through */
align = 8;
/* Fall through */
@@
-12482,7
+12502,7
@@
macro (struct mips_cl_insn *ip, char *str)
abort ();
break;
abort ();
break;
-
+
case M_SAA_AB:
s = "saa";
goto saa_saad;
case M_SAA_AB:
s = "saa";
goto saa_saad;
@@
-12684,8
+12704,8
@@
macro (struct mips_cl_insn *ip, char *str)
case M_DROL_I:
{
unsigned int rot;
case M_DROL_I:
{
unsigned int rot;
- char *l;
- char *rr;
+ c
onst c
har *l;
+ c
onst c
har *rr;
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
@@
-12764,8
+12784,8
@@
macro (struct mips_cl_insn *ip, char *str)
case M_DROR_I:
{
unsigned int rot;
case M_DROR_I:
{
unsigned int rot;
- char *l;
- char *rr;
+ c
onst c
har *l;
+ c
onst c
har *rr;
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
@@
-13521,14
+13541,12
@@
mips_lookup_insn (struct hash_control *hash, const char *start,
struct mips_opcode *insn;
/* Make a copy of the instruction so that we can fiddle with it. */
struct mips_opcode *insn;
/* Make a copy of the instruction so that we can fiddle with it. */
- name = alloca (length + 1);
- memcpy (name, start, length);
- name[length] = '\0';
+ name = xstrndup (start, length);
/* Look up the instruction as-is. */
insn = (struct mips_opcode *) hash_find (hash, name);
if (insn)
/* Look up the instruction as-is. */
insn = (struct mips_opcode *) hash_find (hash, name);
if (insn)
-
return insn
;
+
goto end
;
dot = strchr (name, '.');
if (dot && dot[1])
dot = strchr (name, '.');
if (dot && dot[1])
@@
-13543,7
+13561,7
@@
mips_lookup_insn (struct hash_control *hash, const char *start,
if (insn && (insn->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0)
{
*opcode_extra |= mask << mips_vu0_channel_mask.lsb;
if (insn && (insn->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0)
{
*opcode_extra |= mask << mips_vu0_channel_mask.lsb;
-
return insn
;
+
goto end
;
}
}
}
}
}
}
@@
-13568,12
+13586,15
@@
mips_lookup_insn (struct hash_control *hash, const char *start,
if (insn)
{
forced_insn_length = suffix;
if (insn)
{
forced_insn_length = suffix;
-
return insn
;
+
goto end
;
}
}
}
}
}
}
- return NULL;
+ insn = NULL;
+ end:
+ free (name);
+ return insn;
}
/* Assemble an instruction into its binary format. If the instruction
}
/* Assemble an instruction into its binary format. If the instruction
@@
-13775,7
+13796,7
@@
mips16_immed_in_range_p (const struct mips_int_operand *operand,
is the length that the user requested, or 0 if none. */
static void
is the length that the user requested, or 0 if none. */
static void
-mips16_immed (char *file, unsigned int line, int type,
+mips16_immed (c
onst c
har *file, unsigned int line, int type,
bfd_reloc_code_real_type reloc, offsetT val,
unsigned int user_insn_length, unsigned long *insn)
{
bfd_reloc_code_real_type reloc, offsetT val,
unsigned int user_insn_length, unsigned long *insn)
{
@@
-13985,7
+14006,7
@@
my_getExpression (expressionS *ep, char *str)
input_line_pointer = save_in;
}
input_line_pointer = save_in;
}
-char *
+c
onst c
har *
md_atof (int type, char *litP, int *sizeP)
{
return ieee_md_atof (type, litP, sizeP, target_big_endian);
md_atof (int type, char *litP, int *sizeP)
{
return ieee_md_atof (type, litP, sizeP, target_big_endian);
@@
-14033,7
+14054,7
@@
mips_set_option_string (const char **string_ptr, const char *new_value)
}
int
}
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, c
onst c
har *arg)
{
unsigned int i;
{
unsigned int i;
@@
-14838,7
+14859,8
@@
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_SUB
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_SUB
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
- || fixP->fx_r_type == BFD_RELOC_MIPS_TLS_DTPREL64);
+ || fixP->fx_r_type == BFD_RELOC_MIPS_TLS_DTPREL64
+ || fixP->fx_r_type == BFD_RELOC_NONE);
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
@@
-14882,14
+14904,12
@@
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_MIPS16_TLS_GOTTPREL:
case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
case BFD_RELOC_MIPS16_TLS_GOTTPREL:
case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
- if (!fixP->fx_addsy)
- {
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("TLS relocation against a constant"));
- break;
- }
- S_SET_THREAD_LOCAL (fixP->fx_addsy);
- /* fall through */
+ if (fixP->fx_addsy)
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("TLS relocation against a constant"));
+ break;
case BFD_RELOC_MIPS_JMP:
case BFD_RELOC_MIPS_SHIFT5:
case BFD_RELOC_MIPS_JMP:
case BFD_RELOC_MIPS_SHIFT5:
@@
-15108,6
+15128,7
@@
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
S_SET_WEAK (fixP->fx_addsy);
break;
S_SET_WEAK (fixP->fx_addsy);
break;
+ case BFD_RELOC_NONE:
case BFD_RELOC_VTABLE_ENTRY:
fixP->fx_done = 0;
break;
case BFD_RELOC_VTABLE_ENTRY:
fixP->fx_done = 0;
break;
@@
-15127,10
+15148,9
@@
get_symbol (void)
char *name;
symbolS *p;
char *name;
symbolS *p;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
p = (symbolS *) symbol_find_or_make (name);
p = (symbolS *) symbol_find_or_make (name);
-
*input_line_pointer = c
;
+
(void) restore_line_pointer (c)
;
return p;
}
return p;
}
@@
-15273,28
+15293,34
@@
s_change_sec (int sec)
void
s_change_section (int ignore ATTRIBUTE_UNUSED)
{
void
s_change_section (int ignore ATTRIBUTE_UNUSED)
{
+ char *saved_ilp;
char *section_name;
char *section_name;
- char c;
+ char c
, endc
;
char next_c = 0;
int section_type;
int section_flag;
int section_entry_size;
int section_alignment;
char next_c = 0;
int section_type;
int section_flag;
int section_entry_size;
int section_alignment;
- section_name = input_line_pointer;
- c = get_symbol_end ();
+ saved_ilp = input_line_pointer;
+ endc = get_symbol_name (§ion_name);
+ c = (endc == '"' ? input_line_pointer[1] : endc);
if (c)
if (c)
- next_c =
*(input_line_pointer + 1)
;
+ next_c =
input_line_pointer [(endc == '"' ? 2 : 1)]
;
/* Do we have .section Name<,"flags">? */
if (c != ',' || (c == ',' && next_c == '"'))
{
/* Do we have .section Name<,"flags">? */
if (c != ',' || (c == ',' && next_c == '"'))
{
- /*
j
ust after name is now '\0'. */
-
*input_line_pointer = c
;
- input_line_pointer = s
ection_name
;
+ /*
J
ust after name is now '\0'. */
+
(void) restore_line_pointer (endc)
;
+ input_line_pointer = s
aved_ilp
;
obj_elf_section (ignore);
return;
}
obj_elf_section (ignore);
return;
}
+
+ section_name = xstrdup (section_name);
+ c = restore_line_pointer (endc);
+
input_line_pointer++;
/* Do we have .section Name<,type><,flag><,entry_size><,alignment> */
input_line_pointer++;
/* Do we have .section Name<,type><,flag><,entry_size><,alignment> */
@@
-15302,23
+15328,25
@@
s_change_section (int ignore ATTRIBUTE_UNUSED)
section_type = get_absolute_expression ();
else
section_type = 0;
section_type = get_absolute_expression ();
else
section_type = 0;
+
if (*input_line_pointer++ == ',')
section_flag = get_absolute_expression ();
else
section_flag = 0;
if (*input_line_pointer++ == ',')
section_flag = get_absolute_expression ();
else
section_flag = 0;
+
if (*input_line_pointer++ == ',')
section_entry_size = get_absolute_expression ();
else
section_entry_size = 0;
if (*input_line_pointer++ == ',')
section_entry_size = get_absolute_expression ();
else
section_entry_size = 0;
+
if (*input_line_pointer++ == ',')
section_alignment = get_absolute_expression ();
else
section_alignment = 0;
if (*input_line_pointer++ == ',')
section_alignment = get_absolute_expression ();
else
section_alignment = 0;
+
/* FIXME: really ignore? */
(void) section_alignment;
/* FIXME: really ignore? */
(void) section_alignment;
- section_name = xstrdup (section_name);
-
/* When using the generic form of .section (as implemented by obj-elf.c),
there's no way to set the section type to SHT_MIPS_DWARF. Users have
traditionally had to fall back on the more common @progbits instead.
/* When using the generic form of .section (as implemented by obj-elf.c),
there's no way to set the section type to SHT_MIPS_DWARF. Users have
traditionally had to fall back on the more common @progbits instead.
@@
-15397,13
+15425,12
@@
s_mips_globl (int x ATTRIBUTE_UNUSED)
do
{
do
{
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
S_SET_EXTERNAL (symbolP);
*input_line_pointer = c;
symbolP = symbol_find_or_make (name);
S_SET_EXTERNAL (symbolP);
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE
_AFTER_NAME
();
/* On Irix 5, every global symbol that is not explicitly labelled as
being a function is apparently labelled as being an object. */
/* On Irix 5, every global symbol that is not explicitly labelled as
being a function is apparently labelled as being an object. */
@@
-15415,12
+15442,11
@@
s_mips_globl (int x ATTRIBUTE_UNUSED)
char *secname;
asection *sec;
char *secname;
asection *sec;
- secname = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&secname);
sec = bfd_get_section_by_name (stdoutput, secname);
if (sec == NULL)
as_bad (_("%s: no such section"), secname);
sec = bfd_get_section_by_name (stdoutput, secname);
if (sec == NULL)
as_bad (_("%s: no such section"), secname);
-
*input_line_pointer = c
;
+
(void) restore_line_pointer (c)
;
if (sec != NULL && (sec->flags & SEC_CODE) != 0)
flag = BSF_FUNCTION;
if (sec != NULL && (sec->flags & SEC_CODE) != 0)
flag = BSF_FUNCTION;
@@
-15448,27
+15474,28
@@
s_option (int x ATTRIBUTE_UNUSED)
char *opt;
char c;
char *opt;
char c;
- opt = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&opt);
if (*opt == 'O')
{
/* FIXME: What does this mean? */
}
if (*opt == 'O')
{
/* FIXME: What does this mean? */
}
- else if (strncmp (opt, "pic", 3) == 0)
+ else if (strncmp (opt, "pic", 3) == 0
&& ISDIGIT (opt[3]) && opt[4] == '\0'
)
{
int i;
i = atoi (opt + 3);
{
int i;
i = atoi (opt + 3);
- if (i == 0)
+ if (i != 0 && i != 2)
+ as_bad (_(".option pic%d not supported"), i);
+ else if (mips_pic == VXWORKS_PIC)
+ as_bad (_(".option pic%d not supported in VxWorks PIC mode"), i);
+ else if (i == 0)
mips_pic = NO_PIC;
else if (i == 2)
{
mips_pic = SVR4_PIC;
mips_abicalls = TRUE;
}
mips_pic = NO_PIC;
else if (i == 2)
{
mips_pic = SVR4_PIC;
mips_abicalls = TRUE;
}
- else
- as_bad (_(".option pic%d not supported"), i);
if (mips_pic == SVR4_PIC)
{
if (mips_pic == SVR4_PIC)
{
@@
-15481,7
+15508,7
@@
s_option (int x ATTRIBUTE_UNUSED)
else
as_warn (_("unrecognized option \"%s\""), opt);
else
as_warn (_("unrecognized option \"%s\""), opt);
-
*input_line_pointer = c
;
+
(void) restore_line_pointer (c)
;
demand_empty_rest_of_line ();
}
demand_empty_rest_of_line ();
}
@@
-15495,10
+15522,29
@@
struct mips_option_stack
static struct mips_option_stack *mips_opts_stack;
static struct mips_option_stack *mips_opts_stack;
-static bfd_boolean
+/* Return status for .set/.module option handling. */
+
+enum code_option_type
+{
+ /* Unrecognized option. */
+ OPTION_TYPE_BAD = -1,
+
+ /* Ordinary option. */
+ OPTION_TYPE_NORMAL,
+
+ /* ISA changing option. */
+ OPTION_TYPE_ISA
+};
+
+/* Handle common .set/.module options. Return status indicating option
+ type. */
+
+static enum code_option_type
parse_code_option (char * name)
{
parse_code_option (char * name)
{
+ bfd_boolean isa_set = FALSE;
const struct mips_ase *ase;
const struct mips_ase *ase;
+
if (strncmp (name, "at=", 3) == 0)
{
char *s = name + 3;
if (strncmp (name, "at=", 3) == 0)
{
char *s = name + 3;
@@
-15571,6
+15617,7
@@
parse_code_option (char * name)
{
mips_opts.arch = p->cpu;
mips_opts.isa = p->isa;
{
mips_opts.arch = p->cpu;
mips_opts.isa = p->isa;
+ isa_set = TRUE;
}
}
else if (strncmp (name, "mips", 4) == 0)
}
}
else if (strncmp (name, "mips", 4) == 0)
@@
-15584,6
+15631,7
@@
parse_code_option (char * name)
{
mips_opts.arch = p->cpu;
mips_opts.isa = p->isa;
{
mips_opts.arch = p->cpu;
mips_opts.isa = p->isa;
+ isa_set = TRUE;
}
}
else
}
}
else
@@
-15602,8
+15650,9
@@
parse_code_option (char * name)
else if (strcmp (name, "nosym32") == 0)
mips_opts.sym32 = FALSE;
else
else if (strcmp (name, "nosym32") == 0)
mips_opts.sym32 = FALSE;
else
- return FALSE;
- return TRUE;
+ return OPTION_TYPE_BAD;
+
+ return isa_set ? OPTION_TYPE_ISA : OPTION_TYPE_NORMAL;
}
/* Handle the .set pseudo-op. */
}
/* Handle the .set pseudo-op. */
@@
-15611,8
+15660,8
@@
parse_code_option (char * name)
static void
s_mipsset (int x ATTRIBUTE_UNUSED)
{
static void
s_mipsset (int x ATTRIBUTE_UNUSED)
{
+ enum code_option_type type = OPTION_TYPE_NORMAL;
char *name = input_line_pointer, ch;
char *name = input_line_pointer, ch;
- int prev_isa = mips_opts.isa;
file_mips_check_options ();
file_mips_check_options ();
@@
-15663,7
+15712,7
@@
s_mipsset (int x ATTRIBUTE_UNUSED)
{
struct mips_option_stack *s;
{
struct mips_option_stack *s;
- s =
(struct mips_option_stack *) xmalloc (sizeof *s
);
+ s =
XNEW (struct mips_option_stack
);
s->next = mips_opts_stack;
s->options = mips_opts;
mips_opts_stack = s;
s->next = mips_opts_stack;
s->options = mips_opts;
mips_opts_stack = s;
@@
-15689,12
+15738,16
@@
s_mipsset (int x ATTRIBUTE_UNUSED)
free (s);
}
}
free (s);
}
}
- else if (!parse_code_option (name))
- as_warn (_("tried to set unrecognized symbol: %s\n"), name);
+ else
+ {
+ type = parse_code_option (name);
+ if (type == OPTION_TYPE_BAD)
+ as_warn (_("tried to set unrecognized symbol: %s\n"), name);
+ }
/* The use of .set [arch|cpu]= historically 'fixes' the width of gp and fp
registers based on what is supported by the arch/cpu. */
/* The use of .set [arch|cpu]= historically 'fixes' the width of gp and fp
registers based on what is supported by the arch/cpu. */
- if (
mips_opts.isa != prev_isa
)
+ if (
type == OPTION_TYPE_ISA
)
{
switch (mips_opts.isa)
{
{
switch (mips_opts.isa)
{
@@
-15761,7
+15814,7
@@
s_module (int ignore ATTRIBUTE_UNUSED)
if (!file_mips_opts_checked)
{
if (!file_mips_opts_checked)
{
- if (
!parse_code_option (name)
)
+ if (
parse_code_option (name) == OPTION_TYPE_BAD
)
as_bad (_(".module used with unrecognized symbol: %s\n"), name);
/* Update module level settings from mips_opts. */
as_bad (_(".module used with unrecognized symbol: %s\n"), name);
/* Update module level settings from mips_opts. */
@@
-15878,7
+15931,7
@@
s_cpload (int ignore ATTRIBUTE_UNUSED)
daddu $gp, $gp, $reg1
If $reg2 is given, this results in:
daddu $gp, $gp, $reg1
If $reg2 is given, this results in:
-
daddu
$reg2, $gp, $0
+
or
$reg2, $gp, $0
lui $gp, %hi(%neg(%gp_rel(label)))
addiu $gp, $gp, %lo(%neg(%gp_rel(label)))
daddu $gp, $gp, $reg1
lui $gp, %hi(%neg(%gp_rel(label)))
addiu $gp, $gp, %lo(%neg(%gp_rel(label)))
daddu $gp, $gp, $reg1
@@
-15958,8
+16011,7
@@
s_cpsetup (int ignore ATTRIBUTE_UNUSED)
BFD_RELOC_LO16, SP);
}
else
BFD_RELOC_LO16, SP);
}
else
- macro_build (NULL, "daddu", "d,v,t", mips_cpreturn_register,
- mips_gp_register, 0);
+ move_register (mips_cpreturn_register, mips_gp_register);
if (mips_in_shared || HAVE_64BIT_SYMBOLS)
{
if (mips_in_shared || HAVE_64BIT_SYMBOLS)
{
@@
-16072,7
+16124,7
@@
s_cprestore (int ignore ATTRIBUTE_UNUSED)
ld $gp, offset($sp)
If a register $reg2 was given there, it results in:
ld $gp, offset($sp)
If a register $reg2 was given there, it results in:
-
daddu
$gp, $reg2, $0 */
+
or
$gp, $reg2, $0 */
static void
s_cpreturn (int ignore ATTRIBUTE_UNUSED)
static void
s_cpreturn (int ignore ATTRIBUTE_UNUSED)
@@
-16110,8
+16162,8
@@
s_cpreturn (int ignore ATTRIBUTE_UNUSED)
macro_build (&ex, "ld", "t,o(b)", mips_gp_register, BFD_RELOC_LO16, SP);
}
else
macro_build (&ex, "ld", "t,o(b)", mips_gp_register, BFD_RELOC_LO16, SP);
}
else
- m
acro_build (NULL, "daddu", "d,v,t", mips_gp_register,
- mips_cpreturn_register, 0);
+ m
ove_register (mips_gp_register, mips_cpreturn_register);
+
macro_end ();
mips_assembling_insn = FALSE;
macro_end ();
mips_assembling_insn = FALSE;
@@
-16302,7
+16354,7
@@
s_ehword (int ignore ATTRIBUTE_UNUSED)
p = frag_more (4);
md_number_to_chars (p, 0, 4);
fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE,
p = frag_more (4);
md_number_to_chars (p, 0, 4);
fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE,
- BFD_RELOC_
MIPS_EH
);
+ BFD_RELOC_
32_PCREL
);
demand_empty_rest_of_line ();
}
demand_empty_rest_of_line ();
}
@@
-16397,7
+16449,7
@@
s_nan (int ignore ATTRIBUTE_UNUSED)
directive, such as in:
foo:
directive, such as in:
foo:
- .stabs ...
+ .stabs ...
.set mips16
so the current mode wins. */
.set mips16
so the current mode wins. */
@@
-16419,13
+16471,12
@@
s_mips_weakext (int ignore ATTRIBUTE_UNUSED)
symbolS *symbolP;
expressionS exp;
symbolS *symbolP;
expressionS exp;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
S_SET_WEAK (symbolP);
*input_line_pointer = c;
symbolP = symbol_find_or_make (name);
S_SET_WEAK (symbolP);
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE
_AFTER_NAME
();
if (! is_end_of_line[(unsigned char) *input_line_pointer])
{
if (! is_end_of_line[(unsigned char) *input_line_pointer])
{
@@
-16491,7
+16542,7
@@
md_section_align (asection *seg, valueT addr)
if (align > 4)
align = 4;
if (align > 4)
align = 4;
- return ((addr + (1 << align) - 1) &
(-
1 << align));
+ return ((addr + (1 << align) - 1) &
-(
1 << align));
}
/* Utility routine, called from above as well. If called while the
}
/* Utility routine, called from above as well. If called while the
@@
-16781,6
+16832,7
@@
relaxed_branch_length (fragS *fragp, asection *sec, int update)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
+ && !S_IS_WEAK (fragp->fr_symbol)
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
@@
-16794,12
+16846,9
@@
relaxed_branch_length (fragS *fragp, asection *sec, int update)
toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2);
}
toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2);
}
- else if (fragp)
- /* If the symbol is not defined or it's in a different segment,
- assume the user knows what's going on and emit a short
- branch. */
- toofar = FALSE;
else
else
+ /* If the symbol is not defined or it's in a different segment,
+ we emit the long sequence. */
toofar = TRUE;
if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
toofar = TRUE;
if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
@@
-16847,6
+16896,7
@@
relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
+ && !S_IS_WEAK (fragp->fr_symbol)
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
@@
-16864,12
+16914,9
@@
relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update)
toofar = val < - (0x8000 << 1) || val >= (0x8000 << 1);
}
toofar = val < - (0x8000 << 1) || val >= (0x8000 << 1);
}
- else if (fragp)
- /* If the symbol is not defined or it's in a different segment,
- assume the user knows what's going on and emit a short
- branch. */
- toofar = FALSE;
else
else
+ /* If the symbol is not defined or it's in a different segment,
+ we emit the long sequence. */
toofar = TRUE;
if (fragp && update
toofar = TRUE;
if (fragp && update
@@
-16941,6
+16988,7
@@
relaxed_micromips_16bit_branch_length (fragS *fragp, asection *sec, int update)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
if (fragp
&& S_IS_DEFINED (fragp->fr_symbol)
+ && !S_IS_WEAK (fragp->fr_symbol)
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
&& sec == S_GET_SEGMENT (fragp->fr_symbol))
{
addressT addr;
@@
-17054,6
+17102,10
@@
mips_fix_adjustable (fixS *fixp)
if (fixp->fx_addsy == NULL)
return 1;
if (fixp->fx_addsy == NULL)
return 1;
+ /* Allow relocs used for EH tables. */
+ if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
+ return 1;
+
/* If symbol SYM is in a mergeable section, relocations of the form
SYM + 0 can usually be made section-relative. The mergeable data
is then identified by the section offset rather than by the symbol.
/* If symbol SYM is in a mergeable section, relocations of the form
SYM + 0 can usually be made section-relative. The mergeable data
is then identified by the section offset rather than by the symbol.
@@
-17074,16
+17126,18
@@
mips_fix_adjustable (fixS *fixp)
&& (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
return 0;
&& (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
return 0;
- /* There is no place to store an in-place offset for JALR relocations.
- Likewise an in-range offset of limited PC-relative relocations may
+ /* There is no place to store an in-place offset for JALR relocations. */
+ if (jalr_reloc_p (fixp->fx_r_type) && HAVE_IN_PLACE_ADDENDS)
+ return 0;
+
+ /* Likewise an in-range offset of limited PC-relative relocations may
overflow the in-place relocatable field if recalculated against the
start address of the symbol's containing section.
Also, PC relative relocations for MIPS R6 need to be symbol rather than
section relative to allow linker relaxations to be performed later on. */
overflow the in-place relocatable field if recalculated against the
start address of the symbol's containing section.
Also, PC relative relocations for MIPS R6 need to be symbol rather than
section relative to allow linker relaxations to be performed later on. */
- if ((HAVE_IN_PLACE_ADDENDS || ISA_IS_R6 (mips_opts.isa))
- && (limited_pcrel_reloc_p (fixp->fx_r_type)
- || jalr_reloc_p (fixp->fx_r_type)))
+ if (limited_pcrel_reloc_p (fixp->fx_r_type)
+ && (HAVE_IN_PLACE_ADDENDS || ISA_IS_R6 (mips_opts.isa)))
return 0;
/* R_MIPS16_26 relocations against non-MIPS16 functions might resolve
return 0;
/* R_MIPS16_26 relocations against non-MIPS16 functions might resolve
@@
-17113,9
+17167,9
@@
mips_fix_adjustable (fixS *fixp)
There is a further restriction:
5. We cannot reduce jump relocations (R_MIPS_26, R_MIPS16_26 or
There is a further restriction:
5. We cannot reduce jump relocations (R_MIPS_26, R_MIPS16_26 or
- R_MICROMIPS_26_S1) against MIPS16 or microMIPS symbols
on
- targets with in-place addends; the relocation field cannot
-
encode the low bit
.
+ R_MICROMIPS_26_S1) against MIPS16 or microMIPS symbols
because
+ we need to keep the MIPS16 or microMIPS symbol for the purpose
+
of converting JAL to JALX instructions in the linker
.
For simplicity, we deal with (3)-(4) by not reducing _any_ relocation
against a MIPS16 symbol. We deal with (5) by by not reducing any
For simplicity, we deal with (3)-(4) by not reducing _any_ relocation
against a MIPS16 symbol. We deal with (5) by by not reducing any
@@
-17130,10
+17184,9
@@
mips_fix_adjustable (fixS *fixp)
that we have for MIPS16 symbols. */
if (fixp->fx_subsy == NULL
&& (ELF_ST_IS_MIPS16 (S_GET_OTHER (fixp->fx_addsy))
that we have for MIPS16 symbols. */
if (fixp->fx_subsy == NULL
&& (ELF_ST_IS_MIPS16 (S_GET_OTHER (fixp->fx_addsy))
- || *symbol_get_tc (fixp->fx_addsy)
- || (HAVE_IN_PLACE_ADDENDS
- && ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy))
- && jmp_reloc_p (fixp->fx_r_type))))
+ || (ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy))
+ && jmp_reloc_p (fixp->fx_r_type))
+ || *symbol_get_tc (fixp->fx_addsy)))
return 0;
return 1;
return 0;
return 1;
@@
-17150,8
+17203,8
@@
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
bfd_reloc_code_real_type code;
memset (retval, 0, sizeof(retval));
bfd_reloc_code_real_type code;
memset (retval, 0, sizeof(retval));
- reloc = retval[0] =
(arelent *) xcalloc (1, sizeof (arelent)
);
- reloc->sym_ptr_ptr =
(asymbol **) xmalloc (sizeof (asymbol *)
);
+ reloc = retval[0] =
XCNEW (arelent
);
+ reloc->sym_ptr_ptr =
XNEW (asymbol *
);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
@@
-17173,6
+17226,15
@@
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
Relocations want only the symbol offset. */
reloc->addend = fixp->fx_addnumber + reloc->address;
}
Relocations want only the symbol offset. */
reloc->addend = fixp->fx_addnumber + reloc->address;
}
+ else if (HAVE_IN_PLACE_ADDENDS
+ && fixp->fx_r_type == BFD_RELOC_MICROMIPS_JMP
+ && (read_compressed_insn (fixp->fx_frag->fr_literal
+ + fixp->fx_where, 4) >> 26) == 0x3c)
+ {
+ /* Shift is 2, unusually, for microMIPS JALX. Adjust the in-place
+ addend accordingly. */
+ reloc->addend = fixp->fx_addnumber >> 1;
+ }
else
reloc->addend = fixp->fx_addnumber;
else
reloc->addend = fixp->fx_addnumber;
@@
-17868,7
+17930,7
@@
mips_record_label (symbolS *sym)
struct insn_label_list *l;
if (free_insn_labels == NULL)
struct insn_label_list *l;
if (free_insn_labels == NULL)
- l =
(struct insn_label_list *) xmalloc (sizeof *l
);
+ l =
XNEW (struct insn_label_list
);
else
{
l = free_insn_labels;
else
{
l = free_insn_labels;
@@
-17911,6
+17973,8
@@
mips_convert_ase_flags (int ase)
ext_ases |= AFL_ASE_DSP;
if (ase & ASE_DSPR2)
ext_ases |= AFL_ASE_DSPR2;
ext_ases |= AFL_ASE_DSP;
if (ase & ASE_DSPR2)
ext_ases |= AFL_ASE_DSPR2;
+ if (ase & ASE_DSPR3)
+ ext_ases |= AFL_ASE_DSPR3;
if (ase & ASE_EVA)
ext_ases |= AFL_ASE_EVA;
if (ase & ASE_MCU)
if (ase & ASE_EVA)
ext_ases |= AFL_ASE_EVA;
if (ase & ASE_MCU)
@@
-18349,7
+18413,7
@@
s_mips_end (int x ATTRIBUTE_UNUSED)
if (p && cur_proc_ptr)
{
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (p);
if (p && cur_proc_ptr)
{
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (p);
- expressionS *exp =
xmalloc (sizeof (expressionS)
);
+ expressionS *exp =
XNEW (expressionS
);
obj->size = exp;
exp->X_op = O_subtract;
obj->size = exp;
exp->X_op = O_subtract;
@@
-18654,8
+18718,13
@@
static const struct mips_cpu_info mips_cpu_info_table[] =
{ "1004kf2_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf1_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf2_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "1004kf1_1", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
+ /* interaptiv is the new name for 1004kf */
+ { "interaptiv", 0, ASE_DSP | ASE_MT, ISA_MIPS32R2, CPU_MIPS32R2 },
+ /* M5100 family */
+ { "m5100", 0, ASE_MCU, ISA_MIPS32R5, CPU_MIPS32R5 },
+ { "m5101", 0, ASE_MCU, ISA_MIPS32R5, CPU_MIPS32R5 },
/* P5600 with EVA and Virtualization ASEs, other ASEs are optional. */
/* P5600 with EVA and Virtualization ASEs, other ASEs are optional. */
- { "p5600", 0, ASE_VIRT | ASE_EVA | ASE_XPA,
ISA_MIPS32R5, CPU_MIPS32R5 },
+ { "p5600", 0, ASE_VIRT | ASE_EVA | ASE_XPA, ISA_MIPS32R5, CPU_MIPS32R5 },
/* MIPS 64 */
{ "5kc", 0, 0, ISA_MIPS64, CPU_MIPS64 },
/* MIPS 64 */
{ "5kc", 0, 0, ISA_MIPS64, CPU_MIPS64 },
@@
-18667,7
+18736,7
@@
static const struct mips_cpu_info mips_cpu_info_table[] =
{ "sb1", 0, ASE_MIPS3D | ASE_MDMX, ISA_MIPS64, CPU_SB1 },
/* Broadcom SB-1A CPU core */
{ "sb1a", 0, ASE_MIPS3D | ASE_MDMX, ISA_MIPS64, CPU_SB1 },
{ "sb1", 0, ASE_MIPS3D | ASE_MDMX, ISA_MIPS64, CPU_SB1 },
/* Broadcom SB-1A CPU core */
{ "sb1a", 0, ASE_MIPS3D | ASE_MDMX, ISA_MIPS64, CPU_SB1 },
-
+
{ "loongson3a", 0, 0, ISA_MIPS64R2, CPU_LOONGSON_3A },
/* MIPS 64 Release 2 */
{ "loongson3a", 0, 0, ISA_MIPS64R2, CPU_LOONGSON_3A },
/* MIPS 64 Release 2 */
@@
-18686,8
+18755,9
@@
static const struct mips_cpu_info mips_cpu_info_table[] =
MIPS64R2 rather than MIPS64. */
{ "xlp", 0, 0, ISA_MIPS64R2, CPU_XLR },
MIPS64R2 rather than MIPS64. */
{ "xlp", 0, 0, ISA_MIPS64R2, CPU_XLR },
- /*
i6400.
*/
+ /*
MIPS 64 Release 6
*/
{ "i6400", 0, ASE_MSA, ISA_MIPS64R6, CPU_MIPS64R6},
{ "i6400", 0, ASE_MSA, ISA_MIPS64R6, CPU_MIPS64R6},
+ { "p6600", 0, ASE_VIRT | ASE_MSA, ISA_MIPS64R6, CPU_MIPS64R6},
/* End marker */
{ NULL, 0, 0, 0, 0 }
/* End marker */
{ NULL, 0, 0, 0, 0 }
@@
-18907,7
+18977,7
@@
MIPS options:\n\
-mno-micromips do not generate microMIPS instructions\n"));
fprintf (stream, _("\
-msmartmips generate smartmips instructions\n\
-mno-micromips do not generate microMIPS instructions\n"));
fprintf (stream, _("\
-msmartmips generate smartmips instructions\n\
--mno-smartmips do not generate smartmips instructions\n"));
+-mno-smartmips do not generate smartmips instructions\n"));
fprintf (stream, _("\
-mdsp generate DSP instructions\n\
-mno-dsp do not generate DSP instructions\n"));
fprintf (stream, _("\
-mdsp generate DSP instructions\n\
-mno-dsp do not generate DSP instructions\n"));
@@
-18915,6
+18985,9
@@
MIPS options:\n\
-mdspr2 generate DSP R2 instructions\n\
-mno-dspr2 do not generate DSP R2 instructions\n"));
fprintf (stream, _("\
-mdspr2 generate DSP R2 instructions\n\
-mno-dspr2 do not generate DSP R2 instructions\n"));
fprintf (stream, _("\
+-mdspr3 generate DSP R3 instructions\n\
+-mno-dspr3 do not generate DSP R3 instructions\n"));
+ fprintf (stream, _("\
-mmt generate MT instructions\n\
-mno-mt do not generate MT instructions\n"));
fprintf (stream, _("\
-mmt generate MT instructions\n\
-mno-mt do not generate MT instructions\n"));
fprintf (stream, _("\
@@
-19115,3
+19188,13
@@
md_mips_end (void)
Tag_GNU_MIPS_ABI_FP, fpabi);
}
}
Tag_GNU_MIPS_ABI_FP, fpabi);
}
}
+
+/* Returns the relocation type required for a particular CFI encoding. */
+
+bfd_reloc_code_real_type
+mips_cfi_reloc_for_encoding (int encoding)
+{
+ if (encoding == (DW_EH_PE_sdata4 | DW_EH_PE_pcrel))
+ return BFD_RELOC_32_PCREL;
+ else return BFD_RELOC_NONE;
+}
This page took
0.071749 seconds
and
4
git commands to generate.