aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2018-10-30 19:51:04 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2018-10-30 19:51:04 +0000
commitd5f31abf326098cf8b7e1510cc97a1bcfdb9e2e1 (patch)
tree4725b078af96b401d315f780552d75ab41022319
parent65d2ce961d681a36078e0d5dd1035a1305fd8193 (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.meissner10
-rw-r--r--gcc/config/rs6000/predicates.md2
-rw-r--r--gcc/config/rs6000/rs6000.md96
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