summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>1997-11-13 16:59:07 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>1997-11-13 16:59:07 +0000
commit4b61997dedca6ae5d5ae08b4abbca5e6607c6e98 (patch)
tree370d569088086cfdc94b1a4960afb49500d10f63 /gcc/config/rs6000
parentd70beda9d0093ae8cf5e3e5865732a1be5ebedbc (diff)
downloadgcc-4b61997dedca6ae5d5ae08b4abbca5e6607c6e98.tar.gz
Fix problems in splitting DF constants on big endian hosts & Davids patch for power shifts.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16454 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/rs6000.c53
-rw-r--r--gcc/config/rs6000/rs6000.md44
2 files changed, 61 insertions, 36 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index aa128019dc5..557ef8b9294 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -673,28 +673,47 @@ num_insns_constant (op, mode)
return num_insns_constant_wide ((HOST_WIDE_INT)l);
}
- else if (GET_CODE (op) == CONST_DOUBLE && TARGET_32BIT)
- return (num_insns_constant_wide (CONST_DOUBLE_LOW (op))
- + num_insns_constant_wide (CONST_DOUBLE_HIGH (op)));
-
- else if (GET_CODE (op) == CONST_DOUBLE && TARGET_64BIT)
+ else if (GET_CODE (op) == CONST_DOUBLE)
{
- HOST_WIDE_INT low = CONST_DOUBLE_LOW (op);
- HOST_WIDE_INT high = CONST_DOUBLE_HIGH (op);
-
- if (high == 0 && (low & 0x80000000) == 0)
- return num_insns_constant_wide (low);
+ HOST_WIDE_INT low;
+ HOST_WIDE_INT high;
+ long l[2];
+ REAL_VALUE_TYPE rv;
+ int endian = (WORDS_BIG_ENDIAN == 0);
- else if (((high & 0xffffffff) == 0xffffffff)
- && ((low & 0x80000000) != 0))
- return num_insns_constant_wide (low);
+ if (mode == VOIDmode || mode == DImode)
+ {
+ high = CONST_DOUBLE_HIGH (op);
+ low = CONST_DOUBLE_LOW (op);
+ }
+ else
+ {
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+ high = l[endian];
+ low = l[1 - endian];
+ }
- else if (low == 0)
- return num_insns_constant_wide (high) + 1;
+ if (TARGET_32BIT)
+ return (num_insns_constant_wide (low)
+ + num_insns_constant_wide (high));
else
- return (num_insns_constant_wide (high)
- + num_insns_constant_wide (low) + 1);
+ {
+ if (high == 0 && (low & 0x80000000) == 0)
+ return num_insns_constant_wide (low);
+
+ else if (((high & 0xffffffff) == 0xffffffff)
+ && ((low & 0x80000000) != 0))
+ return num_insns_constant_wide (low);
+
+ else if (low == 0)
+ return num_insns_constant_wide (high) + 1;
+
+ else
+ return (num_insns_constant_wide (high)
+ + num_insns_constant_wide (low) + 1);
+ }
}
else
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 29b6f22e98e..b9bd408e423 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4258,13 +4258,13 @@
[(set_attr "length" "8")])
(define_insn "lshrdi3_power"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r,r,&r")
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
(match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
(clobber (match_scratch:SI 3 "=X,q,q,q"))]
"TARGET_POWER"
"@
- {cal %0,0(0)|li %0,0}\;{s%A2i|s%A2wi} %L0,%1,%h2
+ {s%A2i|s%A2wi} %L0,%1,%h2\;{cal %0,0(0)|li %0,0}
sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
@@ -5734,16 +5734,16 @@
"
{
int endian = (WORDS_BIG_ENDIAN == 0);
+ long l[2];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+
operands[2] = operand_subword (operands[0], endian, 0, DFmode);
operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
-
-#ifdef HOST_WORDS_BIG_ENDIAN
- operands[4] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
- operands[5] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-#else
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
- operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
-#endif
+ operands[4] = GEN_INT (l[endian]);
+ operands[5] = GEN_INT (l[1 - endian]);
}")
(define_split
@@ -5762,16 +5762,15 @@
HOST_WIDE_INT high;
HOST_WIDE_INT low;
int endian = (WORDS_BIG_ENDIAN == 0);
+ long l[2];
+ REAL_VALUE_TYPE rv;
rtx high_reg = operand_subword (operands[0], endian, 0, DFmode);
rtx low_reg = operand_subword (operands[0], 1 - endian, 0, DFmode);
-#ifdef HOST_WORDS_BIG_ENDIAN
- high = CONST_DOUBLE_LOW (operands[1]);
- low = CONST_DOUBLE_HIGH (operands[1]);
-#else
- high = CONST_DOUBLE_HIGH (operands[1]);
- low = CONST_DOUBLE_LOW (operands[1]);
-#endif
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+ high = l[endian];
+ low = l[1 - endian];
if (((unsigned HOST_WIDE_INT) (low + 0x8000) < 0x10000)
|| (low & 0xffff) == 0)
@@ -5806,10 +5805,17 @@
(set (match_dup 3) (ior:SI (match_dup 3) (match_dup 7)))]
"
{
- HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
- HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
+ HOST_WIDE_INT high;
+ HOST_WIDE_INT low;
+ long l[2];
+ REAL_VALUE_TYPE rv;
int endian = (WORDS_BIG_ENDIAN == 0);
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+ high = l[endian];
+ low = l[1 - endian];
+
operands[2] = operand_subword (operands[0], endian, 0, DFmode);
operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
operands[4] = GEN_INT (high & 0xffff0000);