summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-18 20:36:02 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-18 20:36:02 +0000
commitaf5a705a7ed632222c970e43ef20330afc8f7e78 (patch)
treee5936d85783b1d4a0283e2f0c5db8f7fcc95bb87 /gcc
parent2ba1fcba384fb6390f858783fbabc0137a9e9007 (diff)
downloadgcc-af5a705a7ed632222c970e43ef20330afc8f7e78.tar.gz
* rs6000/predicates.md (fix_trunc_dest_operand): New.
* rs6000/rs6000.md (fix_truncdfsi2): Use fix_trunc_dest_operand. Check that a memory operand is valid before trying to use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99927 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/rs6000/predicates.md9
-rw-r--r--gcc/config/rs6000/rs6000.md6
3 files changed, 15 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e0b4534b2e..625fa6ac20b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2005-05-18 Geoffrey Keating <geoffk@apple.com>
+ * rs6000/predicates.md (fix_trunc_dest_operand): New.
+ * rs6000/rs6000.md (fix_truncdfsi2): Use fix_trunc_dest_operand.
+ Check that a memory operand is valid before trying to use it.
+
* tree-cfg.c (pass_remove_useless): This pass works on trees.
2005-05-18 Richard Guenther <rguenth@gcc.gnu.org>
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 05db033089a..570f59d3f0c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -364,6 +364,15 @@
|| GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")))
+;; Used for the destination of the fix_truncdfsi2 expander.
+;; If stfiwx will be used, the result goes to memory; otherwise,
+;; we're going to emit a store and a load of a subreg, so the dest is a
+;; register.
+(define_predicate "fix_trunc_dest_operand"
+ (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT")
+ (match_operand 0 "memory_operand")
+ (match_operand 0 "gpc_reg_operand")))
+
;; Return 1 if the operand is either a non-special register or can be used
;; as the operand of a `mode' add insn.
(define_predicate "add_operand"
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index c627daf2d77..b53792c32ae 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5329,10 +5329,8 @@
}"
[(set_attr "length" "20")])
-; In the TARGET_PPC_GFXOPT case, this could and probably should
-; take a memory destination; but actually making this work is hard.
(define_expand "fix_truncdfsi2"
- [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
+ [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
(clobber (match_dup 2))
(clobber (match_dup 3))])]
@@ -5349,7 +5347,7 @@
if (TARGET_PPC_GFXOPT)
{
rtx orig_dest = operands[0];
- if (GET_CODE (orig_dest) != MEM)
+ if (! memory_operand (orig_dest, GET_MODE (orig_dest)))
operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
operands[2]));