This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] SPARC long long fix
- To: Richard Henderson <rth at cygnus dot com>, "David S. Miller" <davem at redhat dot com>
- Subject: [PATCH] SPARC long long fix
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Mon, 19 Jun 2000 14:45:50 +0200
- Cc: gcc-patches at gcc dot gnu dot org
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
Hi!
Compiler with 64bit HOST_WIDE_INT (either 32bit one compiled with
-DHOST_BITS_PER_WIDE_INT=64 -DHOST_WIDE_INT=long\ long or native 64bit one)
generates bad code for sparc -m32.
This patch should fix it.
Example of miscompilations:
unsigned long long foo(void) { return 0x8000000000000000UL; }
unsigned long long bar(unsigned long long a) { return a | 0x8000011080000110UL; }
Ok to commit?
2000-06-19 Jakub Jelinek <jakub@redhat.com>
* config/sparc/sparc.md (reload_outdi+1): Handle
HOST_BITS_PER_WIDE_INT == 64 case correctly.
(adddi3_insn_sp32+1, adddi3_insn_sp32+2, andsi3+2): Likewise.
--- gcc/config/sparc/sparc.md.jj Thu May 25 09:54:18 2000
+++ gcc/config/sparc/sparc.md Mon Jun 19 14:07:40 2000
@@ -2857,12 +2857,28 @@
[(clobber (const_int 0))]
"
{
+#if HOST_BITS_PER_WIDE_INT == 32
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
(INTVAL (operands[1]) < 0) ?
constm1_rtx :
const0_rtx));
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
operands[1]));
+#else
+ unsigned int low, high;
+
+ low = INTVAL (operands[1]) & 0xffffffff;
+ high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
+ emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
+
+ /* Slick... but this trick loses if this subreg constant part
+ can be done in one insn. */
+ if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
+ emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
+ gen_highpart (SImode, operands[0])));
+ else
+ emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
+#endif
DONE;
}")
@@ -5575,6 +5591,7 @@
operands[5] = gen_lowpart (SImode, operands[2]);
operands[6] = gen_highpart (SImode, operands[0]);
operands[7] = gen_highpart (SImode, operands[1]);
+#if HOST_BITS_PER_WIDE_INT == 32
if (GET_CODE (operands[2]) == CONST_INT)
{
if (INTVAL (operands[2]) < 0)
@@ -5583,6 +5600,7 @@
operands[8] = const0_rtx;
}
else
+#endif
operands[8] = gen_highpart (SImode, operands[2]);
}")
@@ -5609,6 +5627,7 @@
operands[5] = gen_lowpart (SImode, operands[2]);
operands[6] = gen_highpart (SImode, operands[0]);
operands[7] = gen_highpart (SImode, operands[1]);
+#if HOST_BITS_PER_WIDE_INT == 32
if (GET_CODE (operands[2]) == CONST_INT)
{
if (INTVAL (operands[2]) < 0)
@@ -5617,6 +5636,7 @@
operands[8] = const0_rtx;
}
else
+#endif
operands[8] = gen_highpart (SImode, operands[2]);
}")
@@ -6716,6 +6736,7 @@
operands[5] = gen_lowpart (SImode, operands[0]);
operands[6] = gen_highpart (SImode, operands[2]);
operands[7] = gen_lowpart (SImode, operands[2]);
+#if HOST_BITS_PER_WIDE_INT == 32
if (GET_CODE (operands[3]) == CONST_INT)
{
if (INTVAL (operands[3]) < 0)
@@ -6724,6 +6745,7 @@
operands[8] = const0_rtx;
}
else
+#endif
operands[8] = gen_highpart (SImode, operands[3]);
operands[9] = gen_lowpart (SImode, operands[3]);
}")
Jakub