* config/tc-mips.c (md_begin): Don't set interlocks for

mips_4650.
PR 11507.
This commit is contained in:
Ian Lance Taylor
1997-01-20 17:43:43 +00:00
parent 68c7761c42
commit c36a90ef65
2 changed files with 103 additions and 46 deletions

View File

@@ -1,3 +1,8 @@
Mon Jan 20 12:42:06 1997 Ian Lance Taylor <ian@cygnus.com>
* config/tc-mips.c (md_begin): Don't set interlocks for
mips_4650.
Wed Jan 15 13:51:50 1997 Ian Lance Taylor <ian@cygnus.com>
* read.c (read_a_source_file): Make sure the symbol ends with

View File

@@ -827,7 +827,7 @@ md_begin ()
if (mips_4100 < 0)
mips_4100 = 0;
if (mips_4650 || mips_4010 || mips_4100 || mips_cpu == 4300)
if (mips_4010 || mips_4100 || mips_cpu == 4300)
interlocks = 1;
else
interlocks = 0;
@@ -2552,8 +2552,8 @@ load_register (counter, reg, ep, dbl)
expressionS *ep;
int dbl;
{
int shift, freg;
expressionS hi32, lo32, tmp;
int freg;
expressionS hi32, lo32;
if (ep->X_op != O_big)
{
@@ -2613,11 +2613,9 @@ load_register (counter, reg, ep, dbl)
if (ep->X_op != O_big)
{
hi32 = *ep;
shift = 32;
hi32.X_add_number >>= shift;
hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
hi32.X_add_number &= 0xffffffff;
if ((hi32.X_add_number & 0x80000000) != 0)
hi32.X_add_number |= ~ (offsetT) 0xffffffff;
lo32 = *ep;
lo32.X_add_number &= 0xffffffff;
}
@@ -2638,76 +2636,130 @@ load_register (counter, reg, ep, dbl)
freg = 0;
else
{
int shift, bit;
unsigned long hi, lo;
if (hi32.X_add_number == 0xffffffff)
{
if ((lo32.X_add_number & 0xffff8000) == 0xffff8000)
{
macro_build ((char *) NULL, counter, &lo32, "addiu", "t,r,j", reg, 0,
(int) BFD_RELOC_LO16);
macro_build ((char *) NULL, counter, &lo32, "addiu", "t,r,j",
reg, 0, (int) BFD_RELOC_LO16);
return;
}
if (lo32.X_add_number & 0x80000000)
{
macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,
(int) BFD_RELOC_HI16);
macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i", reg, reg,
(int) BFD_RELOC_LO16);
if (lo32.X_add_number & 0xffff)
macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i",
reg, reg, (int) BFD_RELOC_LO16);
return;
}
}
/* Check for 16bit shifted constant: */
shift = 32;
tmp.X_add_number = hi32.X_add_number << shift | lo32.X_add_number;
/* We know that hi32 is non-zero, so start the mask on the first
bit of the hi32 value: */
/* Check for 16bit shifted constant. We know that hi32 is
non-zero, so start the mask on the first bit of the hi32
value. */
shift = 17;
do
{
if ((tmp.X_add_number & ~((offsetT)0xffff << shift)) == 0)
{
tmp.X_op = O_constant;
tmp.X_add_number >>= shift;
macro_build ((char *) NULL, counter, &tmp, "ori", "t,r,i", reg, 0,
(int) BFD_RELOC_LO16);
macro_build ((char *) NULL, counter, NULL,
(shift >= 32) ? "dsll32" : "dsll",
"d,w,<", reg, reg, (shift >= 32) ? shift - 32 : shift);
return;
}
unsigned long himask, lomask;
if (shift < 32)
{
himask = 0xffff >> (32 - shift);
lomask = (0xffff << shift) & 0xffffffff;
}
else
{
himask = 0xffff << (shift - 32);
lomask = 0;
}
if ((hi32.X_add_number & ~ (offsetT) himask) == 0
&& (lo32.X_add_number & ~ (offsetT) lomask) == 0)
{
expressionS tmp;
tmp.X_op = O_constant;
if (shift < 32)
tmp.X_add_number = ((hi32.X_add_number << (32 - shift))
| (lo32.X_add_number >> shift));
else
tmp.X_add_number = hi32.X_add_number >> (shift - 32);
macro_build ((char *) NULL, counter, &tmp, "ori", "t,r,i", reg, 0,
(int) BFD_RELOC_LO16);
macro_build ((char *) NULL, counter, NULL,
(shift >= 32) ? "dsll32" : "dsll",
"d,w,<", reg, reg,
(shift >= 32) ? shift - 32 : shift);
return;
}
shift++;
} while (shift <= (64 - 16));
freg = 0;
shift = 32;
tmp.X_add_number = hi32.X_add_number << shift | lo32.X_add_number;
while ((tmp.X_add_number & 1) == 0)
/* Find the bit number of the lowest one bit, and store the
shifted value in hi/lo. */
hi = (unsigned long) (hi32.X_add_number & 0xffffffff);
lo = (unsigned long) (lo32.X_add_number & 0xffffffff);
if (lo != 0)
{
bit = 0;
while ((lo & 1) == 0)
{
lo >>= 1;
++bit;
}
lo |= (hi & (((unsigned long) 1 << bit) - 1)) << (32 - bit);
hi >>= bit;
}
else
{
bit = 32;
while ((hi & 1) == 0)
{
hi >>= 1;
++bit;
}
lo = hi;
hi = 0;
}
/* Optimize if the shifted value is a (power of 2) - 1. */
if ((hi == 0 && ((lo + 1) & lo) == 0)
|| (lo == 0xffffffff && ((hi + 1) & hi) == 0))
{
tmp.X_add_number >>= 1;
freg++;
}
if (((tmp.X_add_number + 1) & tmp.X_add_number) == 0) /* (power-of-2 - 1) */
{
shift = COUNT_TOP_ZEROES((unsigned int)hi32.X_add_number);
shift = COUNT_TOP_ZEROES ((unsigned int) hi32.X_add_number);
if (shift != 0)
{
expressionS tmp;
/* This instruction will set the register to be all
ones. */
tmp.X_op = O_constant;
tmp.X_add_number = (offsetT)-1;
macro_build ((char *) NULL, counter, &tmp, "addiu", "t,r,j", reg, 0,
(int) BFD_RELOC_LO16); /* set all ones */
if (freg != 0)
tmp.X_add_number = (offsetT) -1;
macro_build ((char *) NULL, counter, &tmp, "addiu", "t,r,j",
reg, 0, (int) BFD_RELOC_LO16);
if (bit != 0)
{
freg += shift;
bit += shift;
macro_build ((char *) NULL, counter, NULL,
(freg >= 32) ? "dsll32" : "dsll",
(bit >= 32) ? "dsll32" : "dsll",
"d,w,<", reg, reg,
(freg >= 32) ? freg - 32 : freg);
(bit >= 32) ? bit - 32 : bit);
}
macro_build ((char *) NULL, counter, NULL, (shift >= 32) ? "dsrl32" : "dsrl",
"d,w,<", reg, reg, (shift >= 32) ? shift - 32 : shift);
macro_build ((char *) NULL, counter, NULL,
(shift >= 32) ? "dsrl32" : "dsrl",
"d,w,<", reg, reg,
(shift >= 32) ? shift - 32 : shift);
return;
}
}
/* Sign extend hi32 before calling load_register, because we can
generally get better code when we load a sign extended value. */
if ((hi32.X_add_number & 0x80000000) != 0)
hi32.X_add_number |= ~ (offsetT) 0xffffffff;
load_register (counter, reg, &hi32, 0);
freg = reg;
}