diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-10-30 19:51:04 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-10-30 19:51:04 +0000 |
commit | d5f31abf326098cf8b7e1510cc97a1bcfdb9e2e1 (patch) | |
tree | 4725b078af96b401d315f780552d75ab41022319 | |
parent | 65d2ce961d681a36078e0d5dd1035a1305fd8193 (diff) |
checkpoint
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ibm/constant@265640 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.meissner | 10 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 96 |
3 files changed, 49 insertions, 59 deletions
diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner index 73d287143fc..596f3362986 100644 --- a/gcc/ChangeLog.meissner +++ b/gcc/ChangeLog.meissner @@ -1,6 +1,16 @@ 2018-10-30 Michael Meissner <meissner@linux.ibm.com> * config/rs6000/predicates.md (easy_fp_direct_move_constant): + Allow SFmode constants once again. + * config/rs6000/rs6000.md (movsf_const_direct_move): Allow SFmode + constants, but only allow targetting a VSX register. + (movsf_const_mem): Add combiner pattern to store constants in + memory. + (movsf_const_mem2): Likewise. + +2018-10-30 Michael Meissner <meissner@linux.ibm.com> + + * config/rs6000/predicates.md (easy_fp_direct_move_constant): Disable SFmode constants. * config/rs6000/rs6000.md (movsf_const_direct_move): Likewise. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index bdd1dbeb2f8..c1afd30f579 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -614,7 +614,7 @@ /* For SFmode, we have to convert the value to double on the assumption we are moving it to a VSX register. */ - if (0 && mode == SFmode) + if (mode == SFmode) { int endian = (WORDS_BIG_ENDIAN == 0); long l[2]; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 854b0310364..5d03e2d9892 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -148,7 +148,6 @@ UNSPEC_SF_FROM_SI UNSPEC_SI_FROM_SF UNSPEC_SF_CONST_MEM - UNSPEC_SF_CONST_GPR ]) ;; @@ -7233,63 +7232,54 @@ ;; Code to load up a SF constant in a GPR and transfer it to a VSX register via ;; direct move. Note, we transfer the constant as a DFmode value instead of -;; SFmode since we are moving it to a VSX register. +;; SFmode since we are moving it to a VSX register. Do not allow putting the +;; constant into GPR registers, since that causes all sorts of confusion due +;; the value in a GPR is different than the value in a VSX register. (define_insn_and_split "movsf_const_direct_move" - [(set (match_operand:SF 0 "nonimmediate_operand" "=wa,m") - (match_operand:SF 1 "easy_fp_direct_move_constant" "wG,wG")) - (clobber (match_scratch:DI 2 "=b,b"))] + [(set (match_operand:SF 0 "vsx_register_operand" "=wa") + (match_operand:SF 1 "easy_fp_direct_move_constant" "wG")) + (clobber (match_scratch:DI 2 "=b"))] "TARGET_DIRECT_MOVE_FP_CONSTANT" "#" "&& reload_completed" - [(const_int 0)] + [(set (match_dup 2) + (match_dup 3)) + (set (match_dup 0) + (unspec:SF [(match_dup 2)] UNSPEC_P8V_MTVSRD))] { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp = operands[2]; - - if (vsx_register_operand (dest, SFmode)) - { - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - HOST_WIDE_INT val; - REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (src), l); - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - - emit_move_insn (tmp, GEN_INT (val)); - emit_insn (gen_p8_mtvsrd_sf (dest, tmp)); - DONE; - } - else - { - long l; - REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (src), l); - - rtx const_rtx = GEN_INT (l); - if (MEM_P (dest)) - { - emit_move_insn (tmp, const_rtx); - emit_insn (gen_movsf_const_mem (dest, tmp)); - } - else - { - if (!satisfies_constraint_L (const_rtx)) - { - emit_move_insn (tmp, const_rtx); - const_rtx = tmp; - } + int endian = (WORDS_BIG_ENDIAN == 0); + long l[2]; + HOST_WIDE_INT val; + REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); + val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - emit_insn (gen_movsf_const_gpr (dest, const_rtx)); - } + operands[3] = GEN_INT (val); +} + [(set_attr "type" "mftgpr") + (set_attr "length" "12")]) - DONE; - } +;; Optimize storing SF constants to memory. +(define_insn_and_split "movsf_const_mem" + [(set (match_operand:SF 0 "memory_operand" "=m") + (match_operand:SF 1 "easy_fp_direct_move_constant" "wG")) + (clobber (match_scratch:DI 2 "=b"))] + "TARGET_DIRECT_MOVE_FP_CONSTANT" + "#" + "&& reload_completed" + [(set (match_dup 2) + (match_dup 3)) + (set (match_dup 0) + (unspec:SF [(match_dup 2)] UNSPEC_SF_CONST_MEM))] +{ + long l; + REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); + operands[3] = GEN_INT (l); } - [(set_attr "type" "mftgpr,store") + [(set_attr "type" "store") (set_attr "length" "12")]) -;; Helper function to store a SF constant to memory. -(define_insn "movsf_const_mem" +(define_insn "*movsf_const_mem2" [(set (match_operand:SF 0 "memory_operand" "=m") (unspec:SF [(match_operand:DI 1 "int_reg_operand" "r")] UNSPEC_SF_CONST_MEM))] @@ -7297,16 +7287,6 @@ "stw%U0%X0 %1,%0" [(set_attr "type" "store")]) -;; Helper function to load up a SF constant to a GPR. -(define_insn "movsf_const_gpr" - [(set (match_operand:SF 0 "int_reg_operand" "=r,r") - (unspec:SF [(match_operand:DI 1 "reg_or_cint_operand" "r,L")] - UNSPEC_SF_CONST_GPR))] - "TARGET_DIRECT_MOVE_FP_CONSTANT" - "@ - mr %0,%1 - lis %0,%v1") - ;; Originally, we tried to keep movsf and movsd common, but the differences ;; addressing was making it rather difficult to hide with mode attributes. In ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store |