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" "#"