* config/tc-mips.c (macro): Handle constants for M_LI_D and
M_LI_DD. (mips_ip): For 'F', 'L', 'f', and 'l', generate a constant rather than an address if the floating point value looks sufficiently simple. PR 12237.
This commit is contained in:
parent
381f42ef5d
commit
a5586bdc2f
@ -1,3 +1,11 @@
|
||||
Wed May 7 15:39:48 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* config/tc-mips.c (macro): Handle constants for M_LI_D and
|
||||
M_LI_DD.
|
||||
(mips_ip): For 'F', 'L', 'f', and 'l', generate a constant rather
|
||||
than an address if the floating point value looks sufficiently
|
||||
simple.
|
||||
|
||||
Tue May 6 12:18:09 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* config/tc-i386.c (md_section_align): If a.out and BFD, force
|
||||
|
@ -4897,6 +4897,27 @@ macro (ip)
|
||||
}
|
||||
|
||||
case M_LI_D:
|
||||
/* If we have a constant in IMM_EXPR, then in mips3 mode it is
|
||||
the entire value, and in mips1 mode it is the high order 32
|
||||
bits of the value and the low order 32 bits are either zero
|
||||
or in offset_expr. */
|
||||
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
|
||||
{
|
||||
load_register (&icnt, treg, &imm_expr, mips_opts.isa >= 3);
|
||||
if (mips_opts.isa < 3 && treg != 31)
|
||||
{
|
||||
if (offset_expr.X_op == O_absent)
|
||||
macro_build ((char *) NULL, &icnt, NULL, "move", "d,s",
|
||||
treg + 1, 0);
|
||||
else
|
||||
{
|
||||
assert (offset_expr.X_op == O_constant);
|
||||
load_register (&icnt, treg + 1, &offset_expr, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* We know that sym is in the .rdata section. First we get the
|
||||
upper 16 bits of the address. */
|
||||
if (mips_pic == NO_PIC)
|
||||
@ -4949,6 +4970,34 @@ macro (ip)
|
||||
break;
|
||||
|
||||
case M_LI_DD:
|
||||
/* If we have a constant in IMM_EXPR, then in mips3 mode it is
|
||||
the entire value, and in mips1 mode it is the high order 32
|
||||
bits of the value and the low order 32 bits are either zero
|
||||
or in offset_expr. */
|
||||
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
|
||||
{
|
||||
load_register (&icnt, AT, &imm_expr, mips_opts.isa >= 3);
|
||||
if (mips_opts.isa >= 3)
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
"dmtc1", "t,S", AT, treg);
|
||||
else
|
||||
{
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
"mtc1", "t,G", AT, treg + 1);
|
||||
if (offset_expr.X_op == O_absent)
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
"mtc1", "t,G", 0, treg);
|
||||
else
|
||||
{
|
||||
assert (offset_expr.X_op == O_constant);
|
||||
load_register (&icnt, AT, &offset_expr, 0);
|
||||
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
|
||||
"mtc1", "t,G", AT, treg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
assert (offset_expr.X_op == O_symbol
|
||||
&& offset_expr.X_add_number == 0);
|
||||
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
|
||||
@ -6911,22 +6960,72 @@ mips_ip (str, ip)
|
||||
|| (*args == 'l'
|
||||
&& (! USE_GLOBAL_POINTER_OPT
|
||||
|| mips_pic == EMBEDDED_PIC
|
||||
|| g_switch_value < 4)
|
||||
))
|
||||
|| g_switch_value < 4
|
||||
|| (temp[0] == 0 && temp[1] == 0)
|
||||
|| (temp[2] == 0 && temp[3] == 0))))
|
||||
{
|
||||
imm_expr.X_op = O_constant;
|
||||
if (! target_big_endian)
|
||||
imm_expr.X_add_number =
|
||||
(((((((int) temp[3] << 8)
|
||||
| temp[2]) << 8)
|
||||
| temp[1]) << 8)
|
||||
| temp[0]);
|
||||
imm_expr.X_add_number = bfd_getl32 (temp);
|
||||
else
|
||||
imm_expr.X_add_number =
|
||||
(((((((int) temp[0] << 8)
|
||||
| temp[1]) << 8)
|
||||
| temp[2]) << 8)
|
||||
| temp[3]);
|
||||
imm_expr.X_add_number = bfd_getb32 (temp);
|
||||
}
|
||||
else if (length > 4
|
||||
&& ((temp[0] == 0 && temp[1] == 0)
|
||||
|| (temp[2] == 0 && temp[3] == 0))
|
||||
&& ((temp[4] == 0 && temp[5] == 0)
|
||||
|| (temp[6] == 0 && temp[7] == 0)))
|
||||
{
|
||||
/* The value is simple enough to load with a
|
||||
couple of instructions. In mips1 mode, set
|
||||
imm_expr to the high order 32 bits and
|
||||
offset_expr to the low order 32 bits.
|
||||
Otherwise, set imm_expr to the entire 64 bit
|
||||
constant. */
|
||||
if (mips_opts.isa < 3)
|
||||
{
|
||||
imm_expr.X_op = O_constant;
|
||||
offset_expr.X_op = O_constant;
|
||||
if (! target_big_endian)
|
||||
{
|
||||
imm_expr.X_add_number = bfd_getl32 (temp + 4);
|
||||
offset_expr.X_add_number = bfd_getl32 (temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
imm_expr.X_add_number = bfd_getb32 (temp);
|
||||
offset_expr.X_add_number = bfd_getb32 (temp + 4);
|
||||
}
|
||||
if (offset_expr.X_add_number == 0)
|
||||
offset_expr.X_op = O_absent;
|
||||
}
|
||||
else if (sizeof (imm_expr.X_add_number) > 4)
|
||||
{
|
||||
imm_expr.X_op = O_constant;
|
||||
if (! target_big_endian)
|
||||
imm_expr.X_add_number = bfd_getl64 (temp);
|
||||
else
|
||||
imm_expr.X_add_number = bfd_getb64 (temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
imm_expr.X_op = O_big;
|
||||
imm_expr.X_add_number = 4;
|
||||
if (! target_big_endian)
|
||||
{
|
||||
generic_bignum[0] = bfd_getl16 (temp);
|
||||
generic_bignum[1] = bfd_getl16 (temp + 2);
|
||||
generic_bignum[2] = bfd_getl16 (temp + 4);
|
||||
generic_bignum[3] = bfd_getl16 (temp + 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
generic_bignum[0] = bfd_getb16 (temp + 6);
|
||||
generic_bignum[1] = bfd_getb16 (temp + 4);
|
||||
generic_bignum[2] = bfd_getb16 (temp + 2);
|
||||
generic_bignum[3] = bfd_getb16 (temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9772,11 +9871,15 @@ nopic_need_relax (sym, before_relaxing)
|
||||
#ifndef NO_ECOFF_DEBUGGING
|
||||
|| (sym->ecoff_extern_size != 0
|
||||
&& sym->ecoff_extern_size <= g_switch_value)
|
||||
#endif
|
||||
/* We must defer this decision until after the whole
|
||||
file has been read, since there might be a .extern
|
||||
after the first use of this symbol. */
|
||||
|| (sym->ecoff_extern_size == 0 && before_relaxing)
|
||||
|| (before_relaxing
|
||||
#ifndef NO_ECOFF_DEBUGGING
|
||||
&& sym->ecoff_extern_size == 0
|
||||
#endif
|
||||
&& S_GET_VALUE (sym) == 0)
|
||||
|| (S_GET_VALUE (sym) != 0
|
||||
&& S_GET_VALUE (sym) <= g_switch_value)))
|
||||
change = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user