diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4480c63a82bb3c5c5e79d28785e7c8b0a9e6cbf3..c5989d35b5994aa54d4c5c43090da31894ad6f94 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2005-03-13  David Edelsohn  <edelsohn@gnu.org>
+
+	* config/rs6000/predicates.md (mem_or_easy_const_operand): Delete.
+	(reg_or_none500mem_operand): New predicate.
+	(zero_reg_mem_operand): New predicate.
+	* config/rs6000/rs6000.md (extendsfdf2): Change operand1 predicate
+	to reg_or_none500mem_operand.
+	(extendsfdf2_fpr): Add MEM alternative.
+	(extenddftf2_internal): Change operand2 predicate to
+	zero_reg_mem_operand.
+
 2005-03-13  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* ggc-zone.c: Rewritten.
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 5bf3e1765fe3e7256e36d88581d85a0eeda2a88d..110898fcec6720b8d56147021995bbc9e7da9276 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -342,12 +342,6 @@
 					   || reload_in_progress,
 					   mode, XEXP (op, 0))")))
 
-;; Return 1 if the operand is either an easy FP constant or memory.
-(define_predicate "mem_or_easy_const_operand"
-  (if_then_else (match_code "const_double")
-    (match_operand 0 "easy_fp_constant")
-    (match_operand 0 "memory_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"
@@ -537,6 +531,20 @@
 	       (match_operand 0 "volatile_mem_operand")))
      (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if the operand is either an easy FP constant or memory or reg.
+(define_predicate "reg_or_none500mem_operand"
+  (if_then_else (match_code "mem")
+     (and (match_test "!TARGET_E500_DOUBLE")
+	  (ior (match_operand 0 "memory_operand")
+	       (ior (match_test "macho_lo_sum_memory_operand (op, mode)")
+		    (match_operand 0 "volatile_mem_operand"))))
+     (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand.
+(define_predicate "zero_reg_mem_operand"
+  (ior (match_operand 0 "zero_fp_constant")
+       (match_operand 0 "reg_or_mem_operand")))
+
 ;; Return 1 if the operand is a general register or memory operand without
 ;; pre_inc or pre_dec, which produces invalid form of PowerPC lwa
 ;; instruction.
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d1b0ff4b8690477d2b43d0f9372408716a6de0a6..17d81f242304384ffcbaf641f4e102a4a8ab5d8d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4410,24 +4410,25 @@
 
 (define_expand "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "")))]
+	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
   "")
 
 (define_insn_and_split "*extendsfdf2_fpr"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
-	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "0,f")))]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
+	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS"
   "@
    #
-   fmr %0,%1"
+   fmr %0,%1
+   lfs%U1%X1 %0,%1"
   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
   [(const_int 0)]
 {
   emit_note (NOTE_INSN_DELETED);
   DONE;
 }
-  [(set_attr "type" "fp")])
+  [(set_attr "type" "fp,fp,fpload")])
 
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
@@ -8300,7 +8301,7 @@
 (define_insn_and_split "*extenddftf2_internal"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
        (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
-   (use (match_operand:DF 2 "input_operand" "rf,m,f,n"))]
+   (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))]
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"