aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1995-02-24 19:42:43 +0000
committerIan Lance Taylor <ian@airs.com>1995-02-24 19:42:43 +0000
commit7811254cb06d1572e617939689a38a96a9d6c6e3 (patch)
treea206a49d058e0bddde8730d5ce583fabc00175cd
parent82fc34323433466bc79aabaf88fb4694dfa8138e (diff)
downloadgdb-7811254cb06d1572e617939689a38a96a9d6c6e3.zip
gdb-7811254cb06d1572e617939689a38a96a9d6c6e3.tar.gz
gdb-7811254cb06d1572e617939689a38a96a9d6c6e3.tar.bz2
* config/tc-mips.c (load_register): Correctly handle 32 bit values
with the high bit set in 64 bit mode. PR 6381.
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-mips.c24
2 files changed, 25 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 33e45e6..81ff996 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+Fri Feb 24 14:41:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Correctly handle 32 bit values
+ with the high bit set in 64 bit mode.
+
Wed Feb 22 23:10:56 1995 Jeff Law (law@snake.cs.utah.edu)
* config/tc-hppa.c (md_apply_fix): Don't subtract the value of the
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 9e7924a..c0cb3c4 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1634,7 +1634,7 @@ load_register (counter, reg, ep)
expressionS *ep;
{
int shift;
- expressionS hi32, lo32;
+ expressionS hi32, lo32, tmp;
if (ep->X_op != O_big)
{
@@ -1656,9 +1656,12 @@ load_register (counter, reg, ep)
(int) BFD_RELOC_LO16);
return;
}
- else if ((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
- || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
- == ~ (offsetT) 0x7fffffff))
+ else if (((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
+ || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
+ == ~ (offsetT) 0x7fffffff))
+ && (mips_isa < 3
+ || sizeof (ep->X_add_number) > 4
+ || (ep->X_add_number & 0x80000000) == 0))
{
/* 32 bit values require an lui. */
macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
@@ -1668,6 +1671,19 @@ load_register (counter, reg, ep)
(int) BFD_RELOC_LO16);
return;
}
+ else
+ {
+ /* 32 bit value with high bit set being loaded into a 64 bit
+ register. We can't use lui, because that would
+ incorrectly set the 32 high bits. */
+ generic_bignum[3] = 0;
+ generic_bignum[2] = 0;
+ generic_bignum[1] = (ep->X_add_number >> 16) & 0xffff;
+ generic_bignum[0] = ep->X_add_number & 0xffff;
+ tmp.X_op = O_big;
+ tmp.X_add_number = 4;
+ ep = &tmp;
+ }
}
/* The value is larger than 32 bits. */