};
/* True if -mgp32 was passed. */
-static int file_mips_gp32 = 0;
+static int file_mips_gp32 = -1;
/* True if -mfp32 was passed. */
-static int file_mips_fp32 = 0;
+static int file_mips_fp32 = -1;
/* This is the struct we use to hold the current set of options. Note
that we must set the isa field to ISA_UNKNOWN and the mips16 field to
/* Similiar for NewABI PIC code, where $gp is callee-saved. NewABI has some
more optimizations, it can use a register value instead of a memory-saved
- offset and even an other than GP as global pointer. */
+ offset and even an other register than $gp as global pointer. */
static offsetT mips_cpreturn_offset = -1;
static int mips_cpreturn_register = -1;
static int mips_gp_register = GP;
+/* Whether mips_cprestore_offset has been set in the current function
+ (or whether it has already been warned about, if not). */
+static int mips_cprestore_valid = 0;
+
/* This is the register which holds the stack frame, as set by the
.frame pseudo-op. This is needed to implement .cprestore. */
static int mips_frame_reg = SP;
+/* Whether mips_frame_reg has been set in the current function
+ (or whether it has already been warned about, if not). */
+static int mips_frame_reg_valid = 0;
+
/* To output NOP instructions correctly, we need to keep information
about the previous two instructions. */
static void mips16_immed PARAMS ((char *, unsigned int, int, offsetT, boolean,
boolean, boolean, unsigned long *,
boolean *, unsigned short *));
+static int my_getPercentOp PARAMS ((char **, unsigned int *, int *));
static int my_getSmallParser PARAMS ((char **, unsigned int *, int *));
static int my_getSmallExpression PARAMS ((expressionS *, char *));
static void my_getExpression PARAMS ((expressionS *, char *));
"Use -march instead of -mcpu."));
}
+#if 1
+ /* For backward compatibility, let -mipsN set various defaults. */
+ /* This code should go away, to be replaced with something rather more
+ draconian. Until GCC 3.1 has been released for some reasonable
+ amount of time, however, we need to support this. */
+ if (mips_opts.isa != ISA_UNKNOWN)
+ {
+ /* Translate -mipsN to the appropriate settings of file_mips_gp32
+ and file_mips_fp32. Tag binaries as using the mipsN ISA. */
+ if (file_mips_gp32 < 0)
+ {
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ file_mips_gp32 = 0;
+ else
+ file_mips_gp32 = 1;
+ }
+ if (file_mips_fp32 < 0)
+ {
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ file_mips_fp32 = 0;
+ else
+ file_mips_fp32 = 1;
+ }
+
+ ci = mips_cpu_info_from_isa (mips_opts.isa);
+ assert (ci != NULL);
+ /* -mipsN has higher priority than -mcpu but lower than -march. */
+ if (mips_arch == CPU_UNKNOWN)
+ mips_arch = ci->cpu;
+
+ /* Default mips_abi. */
+ if (mips_opts.abi == NO_ABI)
+ {
+ if (mips_opts.isa == ISA_MIPS1 || mips_opts.isa == ISA_MIPS2)
+ mips_opts.abi = O32_ABI;
+ else if (mips_opts.isa == ISA_MIPS3 || mips_opts.isa == ISA_MIPS4)
+ mips_opts.abi = O64_ABI;
+ }
+ }
+
+ if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
+ {
+ ci = mips_cpu_info_from_cpu (mips_cpu);
+ assert (ci != NULL);
+ mips_arch = ci->cpu;
+ as_warn (_("The -mcpu option is deprecated. Please use -march and "
+ "-mtune instead."));
+ }
+
+ /* Set tune from -mcpu, not from -mipsN. */
+ if (mips_tune == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
+ {
+ ci = mips_cpu_info_from_cpu (mips_cpu);
+ assert (ci != NULL);
+ mips_tune = ci->cpu;
+ }
+
+ /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was
+ specified on the command line, or some other value if one was.
+ Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on
+ the command line, or will be set otherwise if one was. */
+
+ if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
+ /* Handled above. */;
+#else
if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
{
ci = mips_cpu_info_from_cpu (mips_cpu);
specified on the command line, or some other value if one was.
Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on
the command line, or will be set otherwise if one was. */
+
if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
{
/* We have to check if the isa is the default isa of arch. Otherwise
mips_arch = ci->cpu;
}
}
+#endif
else if (mips_arch != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN)
{
/* We have ARCH, we need ISA. */
if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_arch))
as_warn (_("Could not set architecture and machine"));
+ if (file_mips_gp32 < 0)
+ file_mips_gp32 = 0;
+ if (file_mips_fp32 < 0)
+ file_mips_fp32 = 0;
+
file_mips_isa = mips_opts.isa;
file_mips_abi = mips_opts.abi;
mips_opts.gp32 = file_mips_gp32;
? 1 \
: 0)
+/* Is the given value a sign-extended 32-bit value? */
+#define IS_SEXT_32BIT_NUM(x) \
+ (((x) &~ (offsetT) 0x7fffffff) == 0 \
+ || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
+
/* load_register()
* This routine generates the least number of instructions neccessary to load
* an absolute expression value into a register.
(int) BFD_RELOC_LO16);
return;
}
- else if ((((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
- || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
- == ~ (offsetT) 0x7fffffff))
+ else if ((IS_SEXT_32BIT_NUM (ep->X_add_number)
&& (! dbl
|| ! ep->X_unsigned
|| sizeof (ep->X_add_number) > 4
if (HAVE_32BIT_GPRS)
{
- as_bad (_("Number larger than 32 bits"));
+ as_bad (_("Number (0x%lx) larger than 32 bits"),
+ (unsigned long) ep->X_add_number);
macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
(int) BFD_RELOC_LO16);
return;
int shift, bit;
unsigned long hi, lo;
- if (hi32.X_add_number == 0xffffffff)
+ if (hi32.X_add_number == (offsetT) 0xffffffff)
{
if ((lo32.X_add_number & 0xffff8000) == 0xffff8000)
{
{
expressionS mid16;
- if ((freg == 0) && (lo32.X_add_number == 0xffffffff))
+ if ((freg == 0) && (lo32.X_add_number == (offsetT) 0xffffffff))
{
macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,
(int) BFD_RELOC_HI16);
- macro_build ((char *) NULL, counter, NULL, "dsrl32", "d,w,<", reg,
- reg, 0);
+ macro_build ((char *) NULL, counter, (expressionS *) NULL,
+ "dsrl32", "d,w,<", reg, reg, 0);
return;
}
if (freg != 0)
{
- macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
- freg, 16);
+ macro_build ((char *) NULL, counter, (expressionS *) NULL, "dsll",
+ "d,w,<", reg, freg, 16);
freg = reg;
}
mid16 = lo32;
mid16.X_add_number >>= 16;
macro_build ((char *) NULL, counter, &mid16, "ori", "t,r,i", reg,
freg, (int) BFD_RELOC_LO16);
- macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
- reg, 16);
+ macro_build ((char *) NULL, counter, (expressionS *) NULL, "dsll",
+ "d,w,<", reg, reg, 16);
freg = reg;
}
if ((lo32.X_add_number & 0xffff) != 0)
dsll $reg,16
daddiu $reg,<sym> (BFD_RELOC_LO16)
*/
- if (HAVE_64BIT_ADDRESSES)
+ if (dbl)
{
p = NULL;
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
mips_opts.warn_about_macros),
- ep->X_add_symbol, (offsetT) 0, (char *) NULL);
+ ep->X_add_symbol, 0, NULL);
}
macro_build_lui (p, counter, ep, reg);
if (p != NULL)
p += 4;
- macro_build (p, counter, ep,
- HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
+ macro_build (p, counter, ep, dbl ? "daddiu" : "addiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
(int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, counter, (expressionS *) NULL,
- HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
- "d,v,t", reg, reg, GP);
- macro_build ((char *) NULL, counter, ep,
- HAVE_32BIT_ADDRESSES ? "lw" : "ld",
+ dbl ? "daddu" : "addu", "d,v,t", reg, reg, GP);
+ macro_build ((char *) NULL, counter, ep, dbl ? "ld" : "lw",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);
p = frag_var (rs_machine_dependent, 12 + off, 0,
RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,
mips_opts.warn_about_macros),
- ep->X_add_symbol, (offsetT) 0, (char *) NULL);
+ ep->X_add_symbol, 0, NULL);
if (off > 0)
{
/* We need a nop before loading from $gp. This special
macro_build (p, counter, (expressionS *) NULL, "nop", "");
p += 4;
}
- macro_build (p, counter, ep, HAVE_32BIT_ADDRESSES ? "lw" : "ld",
+ macro_build (p, counter, ep, dbl ? "ld" : "lw",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, counter, (expressionS *) NULL, "nop", "");
p += 4;
- macro_build (p, counter, ep, HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
+ macro_build (p, counter, ep, dbl ? "daddiu" : "addiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
{
if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
ex.X_op = O_constant;
- macro_build ((char *) NULL, counter, &ex,
- HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
+ macro_build ((char *) NULL, counter, &ex, dbl ? "daddiu" : "addiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
if (sreg == 0
|| (HAVE_32BIT_GPRS
&& imm_expr.X_op == O_constant
- && imm_expr.X_add_number == 0xffffffff))
+ && imm_expr.X_add_number == (offsetT) 0xffffffff))
goto do_false;
if (imm_expr.X_op != O_constant)
as_bad (_("Unsupported large constant"));
if (sreg == 0
|| (HAVE_32BIT_GPRS
&& imm_expr.X_op == O_constant
- && imm_expr.X_add_number == 0xffffffff))
+ && imm_expr.X_add_number == (offsetT) 0xffffffff))
goto do_true;
if (imm_expr.X_op != O_constant)
as_bad (_("Unsupported large constant"));
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
mips_opts.warn_about_macros),
- offset_expr.X_add_symbol, (offsetT) 0,
- (char *) NULL);
+ offset_expr.X_add_symbol, 0, NULL);
}
macro_build_lui (p, &icnt, &offset_expr, tempreg);
if (p != NULL)
as_warn (_("No .cprestore pseudo-op used in PIC code"));
else
{
+ if (! mips_frame_reg_valid)
+ {
+ as_warn (_("No .frame pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_frame_reg_valid = 1;
+ }
+ if (! mips_cprestore_valid)
+ {
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_cprestore_valid = 1;
+ }
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
HAVE_32BIT_ADDRESSES ? "lw" : "ld", "t,o(b)",
as_warn (_("No .cprestore pseudo-op used in PIC code"));
else
{
+ if (! mips_frame_reg_valid)
+ {
+ as_warn (_("No .frame pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_frame_reg_valid = 1;
+ }
+ if (! mips_cprestore_valid)
+ {
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ /* Quiet this warning. */
+ mips_cprestore_valid = 1;
+ }
if (mips_opts.noreorder)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
dsll $tempreg,16
daddu $tempreg,$tempreg,$breg
<op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+
+ If we have 64-bit addresses, as an optimization, for
+ addresses which are 32-bit constants (e.g. kseg0/kseg1
+ addresses) we fall back to the 32-bit address generation
+ mechanism since it is more efficient. This code should
+ probably attempt to generate 64-bit constants more
+ efficiently in general.
*/
- if (HAVE_64BIT_ADDRESSES)
+ if (HAVE_64BIT_ADDRESSES
+ && !(offset_expr.X_op == O_constant
+ && IS_SEXT_32BIT_NUM (offset_expr.X_add_number)))
{
p = NULL;
(mips_opts.warn_about_macros
|| (used_at
&& mips_opts.noat))),
- offset_expr.X_add_symbol, (offsetT) 0,
- (char *) NULL);
+ offset_expr.X_add_symbol, 0, NULL);
used_at = 0;
}
macro_build_lui (p, &icnt, &offset_expr, tempreg);
treg, (int) BFD_RELOC_GPREL16, tempreg);
p = frag_var (rs_machine_dependent, 12, 0,
RELAX_ENCODE (8, 12, 0, 8, 0, 0),
- offset_expr.X_add_symbol, (offsetT) 0,
- (char *) NULL);
+ offset_expr.X_add_symbol, 0, NULL);
}
macro_build_lui (p, &icnt, &offset_expr, tempreg);
if (p != NULL)
upper 16 bits of the address. */
if (mips_pic == NO_PIC)
{
- /* FIXME: This won't work for a 64 bit address. */
- macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
+ macro_build_lui (NULL, &icnt, &offset_expr, AT);
}
else if (mips_pic == SVR4_PIC)
{
else
{
/* FIXME: This won't work for a 64 bit address. */
- macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
+ macro_build_lui (NULL, &icnt, &offset_expr, AT);
}
if (mips_opts.isa != ISA_MIPS1)
p = frag_var (rs_machine_dependent, 12 + off, 0,
RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
used_at && mips_opts.noat),
- offset_expr.X_add_symbol, (offsetT) 0,
- (char *) NULL);
+ offset_expr.X_add_symbol, 0, NULL);
/* We just generated two relocs. When tc_gen_reloc
handles this case, it will skip the first reloc and
const enum small_ex_type type;
} percent_op[] =
{
-#ifdef OBJ_ELF
- {"%half", S_EX_HALF},
-#endif
- {"%hi", S_EX_HI},
{"%lo", S_EX_LO},
#ifdef OBJ_ELF
- {"%gp_rel", S_EX_GP_REL},
- {"%got", S_EX_GOT},
+ {"%call_hi", S_EX_CALL_HI},
+ {"%call_lo", S_EX_CALL_LO},
{"%call16", S_EX_CALL16},
{"%got_disp", S_EX_GOT_DISP},
{"%got_page", S_EX_GOT_PAGE},
{"%got_ofst", S_EX_GOT_OFST},
{"%got_hi", S_EX_GOT_HI},
{"%got_lo", S_EX_GOT_LO},
- {"%neg", S_EX_NEG},
- {"%higher", S_EX_HIGHER},
+ {"%got", S_EX_GOT},
+ {"%gp_rel", S_EX_GP_REL},
+ {"%half", S_EX_HALF},
{"%highest", S_EX_HIGHEST},
- {"%call_hi", S_EX_CALL_HI},
- {"%call_lo", S_EX_CALL_LO}
+ {"%higher", S_EX_HIGHER},
+ {"%neg", S_EX_NEG},
#endif
+ {"%hi", S_EX_HI}
};
/* Parse small expression input. STR gets adjusted to eat up whitespace.
unsigned int *len;
int *nestlevel;
{
- int type = S_EX_NONE;
-
*len = 0;
*str += strspn (*str, " \t");
+ /* Check for expression in parentheses. */
if (**str == '(')
{
char *b = *str + 1 + strspn (*str + 1, " \t");
}
}
}
+ /* Check for percent_op (in parentheses). */
else if (b[0] == '%')
{
*str = b;
- goto percent_op;
+ return my_getPercentOp (str, len, nestlevel);
}
- /* Some other expression in the braces. */
- *len = strcspn (*str, ")") + 1;
+ /* Some other expression in the parentheses, which can contain
+ parentheses itself. Attempt to find the matching one. */
+ {
+ int pcnt = 1;
+ char *s;
+
+ *len = 1;
+ for (s = *str + 1; *s && pcnt; s++, (*len)++)
+ {
+ if (*s == '(')
+ pcnt++;
+ else if (*s == ')')
+ pcnt--;
+ }
+ }
}
- /* Check for percent_op. */
+ /* Check for percent_op (outside of parentheses). */
else if (*str[0] == '%')
- {
- char *tmp;
- unsigned int i;
+ return my_getPercentOp (str, len, nestlevel);
-percent_op:
- tmp = *str + 1;
- i = 0;
+ /* Any other expression. */
+ return S_EX_NONE;
+}
- while (ISALPHA (*tmp) || *tmp == '_')
- {
- *tmp = TOLOWER (*tmp);
- tmp++;
- }
- while (i < (sizeof (percent_op) / sizeof (struct percent_op_match)))
+static int
+my_getPercentOp (str, len, nestlevel)
+ char **str;
+ unsigned int *len;
+ int *nestlevel;
+{
+ char *tmp = *str + 1;
+ unsigned int i = 0;
+
+ while (ISALPHA (*tmp) || *tmp == '_')
+ {
+ *tmp = TOLOWER (*tmp);
+ tmp++;
+ }
+ while (i < (sizeof (percent_op) / sizeof (struct percent_op_match)))
+ {
+ if (strncmp (*str, percent_op[i].str, strlen (percent_op[i].str)))
+ i++;
+ else
{
- if (strncmp (*str, percent_op[i].str, strlen (percent_op[i].str)))
- i++;
- else
- {
- type = percent_op[i].type;
+ int type = percent_op[i].type;
- /* Only %hi and %lo are allowed for OldABI. */
- if (! HAVE_NEWABI && type != S_EX_HI && type != S_EX_LO)
- return S_EX_NONE;
+ /* Only %hi and %lo are allowed for OldABI. */
+ if (! HAVE_NEWABI && type != S_EX_HI && type != S_EX_LO)
+ return S_EX_NONE;
- *len = strlen (percent_op[i].str);
- (*nestlevel)++;
- return type;
- }
+ *len = strlen (percent_op[i].str);
+ (*nestlevel)++;
+ return type;
}
}
-
- /* Any other expression. */
return S_EX_NONE;
}
static char *oldstr = NULL;
int c = S_EX_NONE;
int oldc;
- int nest_level = 0;
+ int nestlevel = -1;
unsigned int len;
- /* Don't update oldstr if the last call had nested percent_op's. */
+ /* Don't update oldstr if the last call had nested percent_op's. We need
+ it to parse the outer ones later. */
if (! oldstr)
oldstr = str;
do
{
oldc = c;
- c = my_getSmallParser (&str, &len, &nest_level);
+ c = my_getSmallParser (&str, &len, &nestlevel);
if (c != S_EX_NONE && c != S_EX_REGISTER)
str += len;
}
while (c != S_EX_NONE && c != S_EX_REGISTER);
- /* A percent_op was encountered. */
- if (nest_level)
+ if (nestlevel >= 0)
{
- /* Don't try to get an expression if it is already blanked out. */
+ /* A percent_op was encountered. Don't try to get an expression if
+ it is already blanked out. */
if (*(str + strspn (str + 1, " )")) != ')')
{
char save;
+ /* Let my_getExpression() stop at the closing parenthesis. */
save = *(str + len);
*(str + len) = '\0';
my_getExpression (ep, str);
*(str + len) = save;
}
- if (nest_level > 1)
+ if (nestlevel > 0)
{
- /* blank out including the % sign. */
- char *p = strrchr (oldstr, '%');
- memset (p, ' ', str - p + len);
+ /* Blank out including the % sign and the proper matching
+ parenthesis. */
+ int pcnt = 1;
+ char *s = strrchr (oldstr, '%');
+ char *end;
+
+ for (end = strchr (s, '(') + 1; *end && pcnt; end++)
+ {
+ if (*end == '(')
+ pcnt++;
+ else if (*end == ')')
+ pcnt--;
+ }
+
+ memset (s, ' ', end - s);
str = oldstr;
}
else
- {
- expr_end = strchr (str, ')') + 1;
- }
+ expr_end = str + len;
+
c = oldc;
}
else if (c == S_EX_NONE)
as_fatal(_("internal error"));
}
- if (nest_level <= 1)
+ if (nestlevel <= 0)
+ /* All percent_op's have been handled. */
oldstr = NULL;
return c;
If offset is given, this results in:
sd $gp, offset($sp)
- lui $gp, %gp_rel(%neg(%hi(label)))
- daddiu $gp, $gp, %gp_rel(%neg(%lo(label)))
+ lui $gp, %hi(%neg(%gp_rel(label)))
+ daddiu $gp, $gp, %lo(%neg(%gp_rel(label)))
addu $gp, $gp, $reg1
If $reg2 is given, this results in:
daddu $reg2, $gp, $0
- lui $gp, %gp_rel(%neg(%hi(label)))
- daddiu $gp, $gp, %gp_rel(%neg(%lo(label)))
+ lui $gp, %hi(%neg(%gp_rel(label)))
+ daddiu $gp, $gp, %lo(%neg(%gp_rel(label)))
addu $gp, $gp, $reg1
*/
static void
}
mips_cprestore_offset = get_absolute_expression ();
+ mips_cprestore_valid = 1;
ex.X_op = O_constant;
ex.X_add_symbol = NULL;
{
if (S_IS_DEFINED (symbolP))
{
- as_bad ("Ignoring attempt to redefine symbol `%s'.",
+ as_bad ("ignoring attempt to redefine symbol %s",
S_GET_NAME (symbolP));
ignore_rest_of_line ();
return;
input_line_pointer += 2;
}
if (frame)
- mips_frame_reg = reg != 0 ? reg : SP;
+ {
+ mips_frame_reg = reg != 0 ? reg : SP;
+ mips_frame_reg_valid = 1;
+ mips_cprestore_valid = 0;
+ }
return reg;
}
as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
fixp->fx_r_type = BFD_RELOC_GPREL32;
}
- else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
- reloc->addend = fixp->fx_addnumber;
else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
{
- /* We use a special addend for an internal RELLO reloc. */
- if (symbol_section_p (fixp->fx_addsy))
- reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ reloc->addend = fixp->fx_addnumber;
else
- reloc->addend = fixp->fx_addnumber + reloc->address;
+ {
+ /* We use a special addend for an internal RELLO reloc. */
+ if (symbol_section_p (fixp->fx_addsy))
+ reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+ else
+ reloc->addend = fixp->fx_addnumber + reloc->address;
+ }
}
else if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
{
assert (fixp->fx_next != NULL
&& fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16);
- /* We use a special addend for an internal RELHI reloc. The
- reloc is relative to the RELLO; adjust the addend
+
+ /* The reloc is relative to the RELLO; adjust the addend
accordingly. */
- if (symbol_section_p (fixp->fx_addsy))
- reloc->addend = (fixp->fx_next->fx_frag->fr_address
- + fixp->fx_next->fx_where
- - S_GET_VALUE (fixp->fx_subsy));
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ reloc->addend = fixp->fx_next->fx_addnumber;
else
- reloc->addend = (fixp->fx_addnumber
- + fixp->fx_next->fx_frag->fr_address
- + fixp->fx_next->fx_where);
+ {
+ /* We use a special addend for an internal RELHI reloc. */
+ if (symbol_section_p (fixp->fx_addsy))
+ reloc->addend = (fixp->fx_next->fx_frag->fr_address
+ + fixp->fx_next->fx_where
+ - S_GET_VALUE (fixp->fx_subsy));
+ else
+ reloc->addend = (fixp->fx_addnumber
+ + fixp->fx_next->fx_frag->fr_address
+ + fixp->fx_next->fx_where);
+ }
}
+ else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ reloc->addend = fixp->fx_addnumber;
else
{
if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
negative = 1;
}
if (!ISDIGIT (*input_line_pointer))
- as_bad (_("Expected simple number."));
+ as_bad (_("expected simple number"));
if (input_line_pointer[0] == '0')
{
if (input_line_pointer[1] == 'x')
{
printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
*input_line_pointer, *input_line_pointer);
- as_warn (_("Invalid number"));
+ as_warn (_("invalid number"));
return -1;
}
while (ISDIGIT (*input_line_pointer))
symbolS *p;
int maybe_text;
+ /* Following functions need their own .frame and .cprestore directives. */
+ mips_frame_reg_valid = 0;
+ mips_cprestore_valid = 0;
+
if (!is_end_of_line[(unsigned char) *input_line_pointer])
{
p = get_symbol ();
if (!aent)
{
+ /* This function needs its own .frame and .cprestore directives. */
+ mips_frame_reg_valid = 0;
+ mips_cprestore_valid = 0;
+
cur_proc_ptr = &cur_proc;
memset (cur_proc_ptr, '\0', sizeof (procS));