summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-13 03:22:20 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-13 03:22:20 +0000
commit74a1167ab61730977d56fb65bd106183f6570e8a (patch)
tree334dcd6992f032c9ccae0cee61d50184e161e593
parentbf9c2a9359ca41079e9a4c6ed0ad3cee3c76b325 (diff)
downloadgcc-74a1167ab61730977d56fb65bd106183f6570e8a.tar.gz
* config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
* config/rs6000/rs6000.md (signbittf2): New insn. (extenddftf2_internal): Use LONG_DOUBLE_LARGE_FIRST. (abstf2_internal, cmptf_internal2): Likewise. * config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200055 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.h5
-rw-r--r--gcc/config/rs6000/rs6000.md47
-rw-r--r--gcc/config/rs6000/spe.md8
4 files changed, 58 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 83ccd25dd0d..21d85fa48f0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-06-13 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
+ * config/rs6000/rs6000.md (signbittf2): New insn.
+ (extenddftf2_internal): Use LONG_DOUBLE_LARGE_FIRST.
+ (abstf2_internal, cmptf_internal2): Likewise.
+ * config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise.
+
2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Peter Bergner <bergner@vnet.ibm.com>
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index e5573503650..021e72a80e3 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -715,6 +715,11 @@ extern unsigned char rs6000_recip_bits[];
instructions for them. Might as well be consistent with bits and bytes. */
#define WORDS_BIG_ENDIAN 1
+/* This says that for the IBM long double the larger magnitude double
+ comes first. It's really a two element double array, and arrays
+ don't index differently between little- and big-endian. */
+#define LONG_DOUBLE_LARGE_FIRST 1
+
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8be86a4c15c..a0f462a99c1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5184,6 +5184,41 @@
"frsqrtes %0,%1"
[(set_attr "type" "fp")])
+;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
+;; builtins.c and optabs.c that are not correct for IBM long double
+;; when little-endian.
+(define_expand "signbittf2"
+ [(set (match_dup 2)
+ (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+ (set (match_dup 3)
+ (subreg:DI (match_dup 2) 0))
+ (set (match_dup 4)
+ (match_dup 5))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (match_dup 6))]
+ "!TARGET_IEEEQUAD
+ && TARGET_HARD_FLOAT
+ && (TARGET_FPRS || TARGET_E500_DOUBLE)
+ && TARGET_LONG_DOUBLE_128"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ operands[3] = gen_reg_rtx (DImode);
+ if (TARGET_POWERPC64)
+ {
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
+ operands[6] = gen_rtx_SUBREG (SImode, operands[4],
+ WORDS_BIG_ENDIAN ? 4 : 0);
+ }
+ else
+ {
+ operands[4] = gen_reg_rtx (SImode);
+ operands[5] = gen_rtx_SUBREG (SImode, operands[3],
+ WORDS_BIG_ENDIAN ? 0 : 4);
+ operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
+ }
+})
+
(define_expand "copysign<mode>3"
[(set (match_dup 3)
(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
@@ -9266,8 +9301,8 @@
"&& reload_completed"
[(pc)]
{
- const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
- const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
operands[1]);
emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
@@ -9496,8 +9531,8 @@
&& TARGET_LONG_DOUBLE_128"
"
{
- const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
- const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
operands[3] = gen_reg_rtx (DFmode);
operands[4] = gen_reg_rtx (CCFPmode);
operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
@@ -12885,8 +12920,8 @@
(match_dup 13)]
{
REAL_VALUE_TYPE rv;
- const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
- const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
diff --git a/gcc/config/rs6000/spe.md b/gcc/config/rs6000/spe.md
index cec2b430b82..bf10a5dc180 100644
--- a/gcc/config/rs6000/spe.md
+++ b/gcc/config/rs6000/spe.md
@@ -2604,8 +2604,8 @@
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
"
{
- const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
- const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
operands[3] = gen_reg_rtx (DFmode);
operands[4] = gen_reg_rtx (CCFPmode);
operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
@@ -2627,8 +2627,8 @@
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
"
{
- const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
- const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
operands[3] = gen_reg_rtx (DFmode);
operands[4] = gen_reg_rtx (CCFPmode);
operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);