diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 90aba1e77d3..284d3fedc3a 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -252,17 +252,18 @@ (define_constraint "P"
   (and (match_code "const_int")
        (match_test "((- (unsigned HOST_WIDE_INT) ival) + 0x8000) < 0x10000")))
 
-;; Floating-point constraints
+;; Floating-point constraints.  These two are defined so that insn
+;; length attributes can be calculated exactly.
 
 (define_constraint "G"
-  "Constant that can be copied into GPR with two insns for DF/DI
-   and one for SF."
+  "Constant that can be copied into GPR with two insns for DF/DD
+   and one for SF/SD."
   (and (match_code "const_double")
        (match_test "num_insns_constant (op, mode)
 		    == (mode == SFmode ? 1 : 2)")))
 
 (define_constraint "H"
-  "DF/DI constant that takes three insns."
+  "DF/DD constant that takes three insns."
   (and (match_code "const_double")
        (match_test "num_insns_constant (op, mode) == 3")))
 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8b640b1334c..c4d697f856b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7711,9 +7711,9 @@ (define_insn_and_split "*mov<mode>_32bit"
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
   [(set_attr "length" "8,8,8,8,20,20,16")])
 
-(define_insn_and_split "*mov<mode>_softfloat"
-  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
-	(match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
+(define_insn_and_split "*mov<mode>_softfloat128"
+  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
+	(match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
   "TARGET_SOFT_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -7721,7 +7721,19 @@ (define_insn_and_split "*mov<mode>_softfloat"
   "&& reload_completed"
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
-  [(set_attr "length" "20,20,16")])
+  [(set_attr_alternative "length"
+       [(if_then_else (match_test "TARGET_POWERPC64")
+	    (const_string "8")
+	    (const_string "16"))
+	(if_then_else (match_test "TARGET_POWERPC64")
+	    (const_string "8")
+	    (const_string "16"))
+	(if_then_else (match_test "TARGET_POWERPC64")
+	    (const_string "40")
+	    (const_string "32"))
+	(if_then_else (match_test "TARGET_POWERPC64")
+	    (const_string "8")
+	    (const_string "16"))])])
 
 (define_expand "extenddf<mode>2"
   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
@@ -8656,22 +8668,22 @@ (define_insn_and_split "reload_gpr_from_vsxsf"
 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
 
-;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
-;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
-;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
+;;        GPR store  GPR load   GPR move   FPR store   FPR load    FPR move
+;;        GPR const  AVX store  AVX store  AVX load    AVX load    VSX move
+;;        P9 0       P9 -1      AVX 0/-1   VSX 0       VSX -1      P9 const
 ;;        AVX const  
 
 (define_insn "*movdi_internal32"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-         "=Y,        r,         r,         m,         ^d,         ^d,
-          r,         wY,        Z,         ^wb,       $wv,        ^wi,
-          *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
+         "=Y,        r,         r,         m,          ^d,         ^d,
+          r,         wY,        Z,         ^wb,        $wv,        ^wi,
+          *wo,       *wo,       *wv,       *wi,        *wi,        *wv,
           *wv")
 
 	(match_operand:DI 1 "input_operand"
-         "r,         Y,         r,         ^d,        m,          ^d,
-          IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
-          Oj,        wM,        OjwM,      Oj,        wM,         wS,
+         "r,         Y,         r,         ^d,         m,          ^d,
+          IJKnF,     ^wb,       $wv,       wY,         Z,          ^wi,
+          Oj,        wM,        OjwM,      Oj,         wM,         wS,
           wB"))]
 
   "! TARGET_POWERPC64
@@ -8698,11 +8710,16 @@ (define_insn "*movdi_internal32"
    #
    #"
   [(set_attr "type"
-               "store,     load,      *,         fpstore,    fpload,     fpsimple,
-                *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
-                vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
-                vecsimple")
-   (set_attr "size" "64")])
+         "store,     load,      *,         fpstore,    fpload,     fpsimple,
+          *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
+          vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
+          vecsimple")
+   (set_attr "size" "64")
+   (set_attr "length"
+         "8,         8,         8,         4,          4,          4,
+          16,        4,         4,         4,          4,          4,
+          4,         4,         4,         4,          4,          8,
+          4")])
 
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand")
