aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1996-01-25 22:06:56 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1996-01-25 22:06:56 +0000
commit354b734b2c57333ecddf35bca8f4d81c87f0c34d (patch)
tree2f49c30e77ab42e38eec92c62065bd087bc6a205
parente98bb98212164b1c7485ee93f011a3e8860eb54d (diff)
downloadgcc-354b734b2c57333ecddf35bca8f4d81c87f0c34d.zip
gcc-354b734b2c57333ecddf35bca8f4d81c87f0c34d.tar.gz
gcc-354b734b2c57333ecddf35bca8f4d81c87f0c34d.tar.bz2
Fix Windows NT problem
From-SVN: r11105
-rw-r--r--gcc/config/rs6000/rs6000.h20
-rw-r--r--gcc/config/rs6000/rs6000.md26
2 files changed, 29 insertions, 17 deletions
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 6a5264b..08fa566e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1774,17 +1774,15 @@ typedef struct rs6000_args
{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& (unsigned) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \
- { int high_int, low_int; \
- high_int = INTVAL (XEXP (X, 1)) >> 16; \
+ { HOST_WIDE_INT high_int, low_int; \
+ rtx sum; \
+ high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff); \
low_int = INTVAL (XEXP (X, 1)) & 0xffff; \
if (low_int & 0x8000) \
- high_int += 1, low_int |= 0xffff0000; \
- (X) = gen_rtx (PLUS, Pmode, \
- force_operand \
- (gen_rtx (PLUS, Pmode, XEXP (X, 0), \
- gen_rtx (CONST_INT, VOIDmode, \
- high_int << 16)), 0), \
- gen_rtx (CONST_INT, VOIDmode, low_int)); \
+ high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16; \
+ sum = force_operand (gen_rtx (PLUS, Pmode, XEXP (X, 0), \
+ GEN_INT (high_int)), 0); \
+ (X) = gen_rtx (PLUS, Pmode, sum, GEN_INT (low_int)); \
goto WIN; \
} \
else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
@@ -2772,6 +2770,10 @@ do { \
(no need to use the default) */
#define MACHINE_issue_rate
+/* General optimization flags. */
+extern int optimize;
+extern int flag_expensive_optimizations;
+
/* Declare functions in rs6000.c */
extern void output_options ();
extern void rs6000_override_options ();
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index de1939b..abb6043f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4780,20 +4780,30 @@
if (sym && GET_CODE (const_term) == CONST_INT
&& (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
{
- emit_insn (gen_movsi (operands[0], sym));
+ unsigned HOST_WIDE_INT value = INTVAL (const_term);
+ int new_reg_p = (flag_expensive_optimizations
+ && !reload_completed
+ && !reload_in_progress);
+ rtx tmp1 = (new_reg_p && value != 0) ? gen_reg_rtx (SImode) : operands[0];
+
+ emit_insn (gen_movsi (tmp1, sym));
if (INTVAL (const_term) != 0)
{
- unsigned HOST_WIDE_INT value = INTVAL (const_term);
if (value + 0x8000 < 0x10000)
- emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (value)));
+ emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
+
else
{
- emit_insn (gen_addsi3 (operands[0], operands[0],
- GEN_INT ((value >> 16) + ((value >> 15) & 1))));
+ HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
+ HOST_WIDE_INT low_int = value & 0xffff;
+ rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
+
+ if (low_int & 0x8000)
+ high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
- if ((value & 0xffff) != 0)
- emit_insn (gen_addsi3 (operands[0], operands[0],
- GEN_INT (value & 0xffff)));
+ emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
+ if (low_int)
+ emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
}
}
DONE;