diff options
author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-13 03:22:20 +0000 |
---|---|---|
committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-13 03:22:20 +0000 |
commit | 74a1167ab61730977d56fb65bd106183f6570e8a (patch) | |
tree | 334dcd6992f032c9ccae0cee61d50184e161e593 | |
parent | bf9c2a9359ca41079e9a4c6ed0ad3cee3c76b325 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 47 | ||||
-rw-r--r-- | gcc/config/rs6000/spe.md | 8 |
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); |