This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch ARM] Fix PR50022
On 12/08/11 10:28, Ramana Radhakrishnan wrote:
> On 12 August 2011 10:19, Ramana Radhakrishnan
> <ramana.radhakrishnan@linaro.org> wrote:
>> Hi,
>>
>> The attached patch fixes up PR50022 which exposed a problem in my reworking
>
> And with the patch even :( ...
>
> Ramana
>
> 2011-08-12 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
>
> PR target/50022
> * config/arm/arm.c (output_move_double): Add 2 parameters
> to count the number of insns emitted and whether to emit or not.
> Use the flag to decide when to emit and count number of instructions
> that will be emitted.
> Handle case where output_move_double might be called for calculating
> lengths with an invalid constant.
> (arm_count_output_move_double_insns): Define.
> * config/arm/arm-protos.h (arm_count_output_move_double_insns): Declare.
> (output_move_double): Adjust prototype.
> * config/arm/vfp.md ("*movdi_vfp"): Adjust call to
> output_move_double.
> ("*movdi_vfp_cortexa8"): Likewise and add attribute
> for ce_count.
> * config/arm/arm.md ("*arm_movdi"): Adjust call to output_move_double.
> ("*movdf_soft_insn"): Likewise.
> * config/arm/cirrus.md ("*cirrus_arm_movdi"): Likewise.
> ("*cirrus_thumb2_movdi"): Likewise.
> ("*thumb2_cirrus_movdf_hard_insn"): Likewise.
> ("*cirrus_movdf_hard_insn"): Likewise.
> * config/arm/neon.md (*neon_mov<mode> VD): Likewise.
> * config/arm/iwmmxt.md ("*iwmmxt_arm_movdi"): Likewise.
> ("mov<mode>_internal VMMX"): Likewise.
>
Use a bool for "emit". Otherwise OK.
R.
>
> final-pr50022-patch.txt
>
>
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 2f7c508..d99d1ce 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -131,8 +131,9 @@ extern const char *output_mov_long_double_arm_from_fpa (rtx *);
> extern const char *output_mov_long_double_arm_from_arm (rtx *);
> extern const char *output_mov_double_fpa_from_arm (rtx *);
> extern const char *output_mov_double_arm_from_fpa (rtx *);
> -extern const char *output_move_double (rtx *);
> +extern const char *output_move_double (rtx *, int, int *count);
> extern const char *output_move_quad (rtx *);
> +extern int arm_count_output_move_double_insns (rtx *);
> extern const char *output_move_vfp (rtx *operands);
> extern const char *output_move_neon (rtx *operands);
> extern int arm_attr_length_move_neon (rtx);
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 6cd80f8..446be81 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -13262,11 +13262,24 @@ output_mov_double_arm_from_fpa (rtx *operands)
> /* Output a move between double words. It must be REG<-MEM
> or MEM<-REG. */
> const char *
> -output_move_double (rtx *operands)
> +output_move_double (rtx *operands, int emit, int *count)
> {
> enum rtx_code code0 = GET_CODE (operands[0]);
> enum rtx_code code1 = GET_CODE (operands[1]);
> rtx otherops[3];
> + if (count)
> + *count = 1;
> +
> + /* The only case when this might happen is when
> + you are looking at the length of a DImode instruction
> + that has an invalid constant in it. */
> + if (code0 == REG && code1 != MEM)
> + {
> + gcc_assert (!emit);
> + *count = 2;
> + return "";
> + }
> +
>
> if (code0 == REG)
> {
> @@ -13279,35 +13292,49 @@ output_move_double (rtx *operands)
> switch (GET_CODE (XEXP (operands[1], 0)))
> {
> case REG:
> - if (TARGET_LDRD
> - && !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0))))
> - output_asm_insn ("ldr%(d%)\t%0, [%m1]", operands);
> - else
> - output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
> +
> + if (emit)
> + {
> + if (TARGET_LDRD
> + && !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0))))
> + output_asm_insn ("ldr%(d%)\t%0, [%m1]", operands);
> + else
> + output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
> + }
> break;
>
> case PRE_INC:
> gcc_assert (TARGET_LDRD);
> - output_asm_insn ("ldr%(d%)\t%0, [%m1, #8]!", operands);
> + if (emit)
> + output_asm_insn ("ldr%(d%)\t%0, [%m1, #8]!", operands);
> +
> break;
>
> case PRE_DEC:
> - if (TARGET_LDRD)
> - output_asm_insn ("ldr%(d%)\t%0, [%m1, #-8]!", operands);
> - else
> - output_asm_insn ("ldm%(db%)\t%m1!, %M0", operands);
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("ldr%(d%)\t%0, [%m1, #-8]!", operands);
> + else
> + output_asm_insn ("ldm%(db%)\t%m1!, %M0", operands);
> + }
> break;
>
> case POST_INC:
> - if (TARGET_LDRD)
> - output_asm_insn ("ldr%(d%)\t%0, [%m1], #8", operands);
> - else
> - output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands);
> +
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("ldr%(d%)\t%0, [%m1], #8", operands);
> + else
> + output_asm_insn ("ldm%(ia%)\t%m1!, %M0", operands);
> + }
> break;
>
> case POST_DEC:
> gcc_assert (TARGET_LDRD);
> - output_asm_insn ("ldr%(d%)\t%0, [%m1], #-8", operands);
> + if (emit)
> + output_asm_insn ("ldr%(d%)\t%0, [%m1], #-8", operands);
> break;
>
> case PRE_MODIFY:
> @@ -13325,8 +13352,13 @@ output_move_double (rtx *operands)
> if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
> {
> /* Registers overlap so split out the increment. */
> - output_asm_insn ("add%?\t%1, %1, %2", otherops);
> - output_asm_insn ("ldr%(d%)\t%0, [%1] @split", otherops);
> + if (emit)
> + {
> + output_asm_insn ("add%?\t%1, %1, %2", otherops);
> + output_asm_insn ("ldr%(d%)\t%0, [%1] @split", otherops);
> + }
> + if (count)
> + *count = 2;
> }
> else
> {
> @@ -13337,11 +13369,20 @@ output_move_double (rtx *operands)
> || GET_CODE (otherops[2]) != CONST_INT
> || (INTVAL (otherops[2]) > -256
> && INTVAL (otherops[2]) < 256))
> - output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
> + {
> + if (emit)
> + output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
> + }
> else
> {
> - output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
> - output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
> + if (emit)
> + {
> + output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
> + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
> + }
> + if (count)
> + *count = 2;
> +
> }
> }
> }
> @@ -13354,11 +13395,19 @@ output_move_double (rtx *operands)
> || GET_CODE (otherops[2]) != CONST_INT
> || (INTVAL (otherops[2]) > -256
> && INTVAL (otherops[2]) < 256))
> - output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
> + {
> + if (emit)
> + output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
> + }
> else
> {
> - output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
> - output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
> + if (emit)
> + {
> + output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
> + output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
> + }
> + if (count)
> + *count = 2;
> }
> }
> break;
> @@ -13371,12 +13420,19 @@ output_move_double (rtx *operands)
> /* Use the second register of the pair to avoid problematic
> overlap. */
> otherops[1] = operands[1];
> - output_asm_insn ("adr%?\t%0, %1", otherops);
> + if (emit)
> + output_asm_insn ("adr%?\t%0, %1", otherops);
> operands[1] = otherops[0];
> - if (TARGET_LDRD)
> - output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
> - else
> - output_asm_insn ("ldm%(ia%)\t%1, %M0", operands);
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
> + else
> + output_asm_insn ("ldm%(ia%)\t%1, %M0", operands);
> + }
> +
> + if (count)
> + *count = 2;
> break;
>
> /* ??? This needs checking for thumb2. */
> @@ -13395,17 +13451,20 @@ output_move_double (rtx *operands)
> switch ((int) INTVAL (otherops[2]))
> {
> case -8:
> - output_asm_insn ("ldm%(db%)\t%1, %M0", otherops);
> + if (emit)
> + output_asm_insn ("ldm%(db%)\t%1, %M0", otherops);
> return "";
> case -4:
> if (TARGET_THUMB2)
> break;
> - output_asm_insn ("ldm%(da%)\t%1, %M0", otherops);
> + if (emit)
> + output_asm_insn ("ldm%(da%)\t%1, %M0", otherops);
> return "";
> case 4:
> if (TARGET_THUMB2)
> break;
> - output_asm_insn ("ldm%(ib%)\t%1, %M0", otherops);
> + if (emit)
> + output_asm_insn ("ldm%(ib%)\t%1, %M0", otherops);
> return "";
> }
> }
> @@ -13433,34 +13492,50 @@ output_move_double (rtx *operands)
> if (reg_overlap_mentioned_p (operands[0], otherops[2])
> || (fix_cm3_ldrd && reg0 == REGNO (otherops[1])))
> {
> - output_asm_insn ("add%?\t%0, %1, %2", otherops);
> - output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
> + if (emit)
> + {
> + output_asm_insn ("add%?\t%0, %1, %2", otherops);
> + output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
> + }
> + if (count)
> + *count = 2;
> }
> else
> {
> otherops[0] = operands[0];
> - output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
> + if (emit)
> + output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
> }
> return "";
> }
>
> if (GET_CODE (otherops[2]) == CONST_INT)
> + {
> + if (emit)
> + {
> + if (!(const_ok_for_arm (INTVAL (otherops[2]))))
> + output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
> + else
> + output_asm_insn ("add%?\t%0, %1, %2", otherops);
> + }
> +
> + }
> + else
> {
> - if (!(const_ok_for_arm (INTVAL (otherops[2]))))
> - output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
> - else
> + if (emit)
> output_asm_insn ("add%?\t%0, %1, %2", otherops);
> }
> - else
> - output_asm_insn ("add%?\t%0, %1, %2", otherops);
> }
> else
> - output_asm_insn ("sub%?\t%0, %1, %2", otherops);
> + {
> + if (emit)
> + output_asm_insn ("sub%?\t%0, %1, %2", otherops);
> + }
>
> if (TARGET_LDRD)
> return "ldr%(d%)\t%0, [%1]";
> -
> - return "ldm%(ia%)\t%1, %M0";
> +
> + return "ldm%(ia%)\t%1, %M0";
> }
> else
> {
> @@ -13468,13 +13543,24 @@ output_move_double (rtx *operands)
> /* Take care of overlapping base/data reg. */
> if (reg_mentioned_p (operands[0], operands[1]))
> {
> - output_asm_insn ("ldr%?\t%0, %1", otherops);
> - output_asm_insn ("ldr%?\t%0, %1", operands);
> + if (emit)
> + {
> + output_asm_insn ("ldr%?\t%0, %1", otherops);
> + output_asm_insn ("ldr%?\t%0, %1", operands);
> + }
> + if (count)
> + *count = 2;
> +
> }
> else
> {
> - output_asm_insn ("ldr%?\t%0, %1", operands);
> - output_asm_insn ("ldr%?\t%0, %1", otherops);
> + if (emit)
> + {
> + output_asm_insn ("ldr%?\t%0, %1", operands);
> + output_asm_insn ("ldr%?\t%0, %1", otherops);
> + }
> + if (count)
> + *count = 2;
> }
> }
> }
> @@ -13488,34 +13574,45 @@ output_move_double (rtx *operands)
> switch (GET_CODE (XEXP (operands[0], 0)))
> {
> case REG:
> - if (TARGET_LDRD)
> - output_asm_insn ("str%(d%)\t%1, [%m0]", operands);
> - else
> - output_asm_insn ("stm%(ia%)\t%m0, %M1", operands);
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("str%(d%)\t%1, [%m0]", operands);
> + else
> + output_asm_insn ("stm%(ia%)\t%m0, %M1", operands);
> + }
> break;
>
> case PRE_INC:
> gcc_assert (TARGET_LDRD);
> - output_asm_insn ("str%(d%)\t%1, [%m0, #8]!", operands);
> + if (emit)
> + output_asm_insn ("str%(d%)\t%1, [%m0, #8]!", operands);
> break;
>
> case PRE_DEC:
> - if (TARGET_LDRD)
> - output_asm_insn ("str%(d%)\t%1, [%m0, #-8]!", operands);
> - else
> - output_asm_insn ("stm%(db%)\t%m0!, %M1", operands);
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("str%(d%)\t%1, [%m0, #-8]!", operands);
> + else
> + output_asm_insn ("stm%(db%)\t%m0!, %M1", operands);
> + }
> break;
>
> case POST_INC:
> - if (TARGET_LDRD)
> - output_asm_insn ("str%(d%)\t%1, [%m0], #8", operands);
> - else
> - output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands);
> + if (emit)
> + {
> + if (TARGET_LDRD)
> + output_asm_insn ("str%(d%)\t%1, [%m0], #8", operands);
> + else
> + output_asm_insn ("stm%(ia%)\t%m0!, %M1", operands);
> + }
> break;
>
> case POST_DEC:
> gcc_assert (TARGET_LDRD);
> - output_asm_insn ("str%(d%)\t%1, [%m0], #-8", operands);
> + if (emit)
> + output_asm_insn ("str%(d%)\t%1, [%m0], #-8", operands);
> break;
>
> case PRE_MODIFY:
> @@ -13533,19 +13630,35 @@ output_move_double (rtx *operands)
> {
> if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
> {
> - output_asm_insn ("str%?\t%0, [%1, %2]!", otherops);
> - output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
> + if (emit)
> + {
> + output_asm_insn ("str%?\t%0, [%1, %2]!", otherops);
> + output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
> + }
> + if (count)
> + *count = 2;
> }
> else
> {
> - output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
> - output_asm_insn ("str%?\t%0, [%1], %2", otherops);
> + if (emit)
> + {
> + output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
> + output_asm_insn ("str%?\t%0, [%1], %2", otherops);
> + }
> + if (count)
> + *count = 2;
> }
> }
> else if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
> - output_asm_insn ("str%(d%)\t%0, [%1, %2]!", otherops);
> + {
> + if (emit)
> + output_asm_insn ("str%(d%)\t%0, [%1, %2]!", otherops);
> + }
> else
> - output_asm_insn ("str%(d%)\t%0, [%1], %2", otherops);
> + {
> + if (emit)
> + output_asm_insn ("str%(d%)\t%0, [%1], %2", otherops);
> + }
> break;
>
> case PLUS:
> @@ -13555,19 +13668,22 @@ output_move_double (rtx *operands)
> switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
> {
> case -8:
> - output_asm_insn ("stm%(db%)\t%m0, %M1", operands);
> + if (emit)
> + output_asm_insn ("stm%(db%)\t%m0, %M1", operands);
> return "";
>
> case -4:
> if (TARGET_THUMB2)
> break;
> - output_asm_insn ("stm%(da%)\t%m0, %M1", operands);
> + if (emit)
> + output_asm_insn ("stm%(da%)\t%m0, %M1", operands);
> return "";
>
> case 4:
> if (TARGET_THUMB2)
> break;
> - output_asm_insn ("stm%(ib%)\t%m0, %M1", operands);
> + if (emit)
> + output_asm_insn ("stm%(ib%)\t%m0, %M1", operands);
> return "";
> }
> }
> @@ -13580,7 +13696,8 @@ output_move_double (rtx *operands)
> {
> otherops[0] = operands[1];
> otherops[1] = XEXP (XEXP (operands[0], 0), 0);
> - output_asm_insn ("str%(d%)\t%0, [%1, %2]", otherops);
> + if (emit)
> + output_asm_insn ("str%(d%)\t%0, [%1, %2]", otherops);
> return "";
> }
> /* Fall through */
> @@ -13588,8 +13705,14 @@ output_move_double (rtx *operands)
> default:
> otherops[0] = adjust_address (operands[0], SImode, 4);
> otherops[1] = operands[1];
> - output_asm_insn ("str%?\t%1, %0", operands);
> - output_asm_insn ("str%?\t%H1, %0", otherops);
> + if (emit)
> + {
> + output_asm_insn ("str%?\t%1, %0", operands);
> + output_asm_insn ("str%?\t%H1, %0", otherops);
> + }
> + if (count)
> + *count = 2;
> +
> }
> }
>
> @@ -24183,4 +24306,13 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
> return 4;
> }
>
> +/* Compute the number of instructions emitted by output_move_double. */
> +int
> +arm_count_output_move_double_insns (rtx *operands)
> +{
> + int count;
> + output_move_double (operands, 0, &count);
> + return count;
> +}
> +
> #include "gt-arm.h"
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 3d4dcfa..082ded4 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -4981,7 +4981,7 @@
> case 2:
> return \"#\";
> default:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> }
> "
> [(set_attr "length" "8,12,16,8,8")
> @@ -6341,7 +6341,7 @@
> case 2:
> return \"#\";
> default:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> }
> "
> [(set_attr "length" "8,12,16,8,8")
> @@ -10315,6 +10315,7 @@
> [(set (match_operand:SI 0 "s_register_operand" "=r,r")
> (if_then_else:SI (match_operator 4 "arm_comparison_operator"
> [(match_operand 3 "cc_register" "") (const_int 0)])
> +
> (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
> (not:SI
> (match_operand:SI 2 "s_register_operand" "r,r"))))]
> diff --git a/gcc/config/arm/cirrus.md b/gcc/config/arm/cirrus.md
> index f08da0b..e3fe687 100644
> --- a/gcc/config/arm/cirrus.md
> +++ b/gcc/config/arm/cirrus.md
> @@ -1,4 +1,4 @@
> -;; Cirrus EP9312 "Maverick" ARM floating point co-processor description.
> +;; CIRRUS EP9312 "Maverick" ARM floating point co-processor description.
> ;; Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
> ;; Contributed by Red Hat.
> ;; Written by Aldy Hernandez (aldyh@redhat.com)
> @@ -379,7 +379,7 @@
> return \"#\";
> case 1:
> case 2:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
>
> case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
> case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
> @@ -439,7 +439,7 @@
> case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
> case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
> case 2: return \"#\";
> - case 3: case 4: return output_move_double (operands);
> + case 3: case 4: return output_move_double (operands, 1, NULL);
> case 5: return \"cfcpyd%?\\t%V0, %V1\";
> case 6: return \"cfldrd%?\\t%V0, %1\";
> case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
> @@ -466,7 +466,7 @@
> case 0:
> case 1:
> case 2:
> - return (output_move_double (operands));
> + return (output_move_double (operands, 1, NULL));
>
> case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
> case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
> @@ -522,7 +522,7 @@
> {
> case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
> case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
> - case 2: case 3: case 4: return output_move_double (operands);
> + case 2: case 3: case 4: return output_move_double (operands, 1, NULL);
> case 5: return \"cfcpyd%?\\t%V0, %V1\";
> case 6: return \"cfldrd%?\\t%V0, %1\";
> case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
> diff --git a/gcc/config/arm/fpa.md b/gcc/config/arm/fpa.md
> index 6e6dd8d..3d41950 100644
> --- a/gcc/config/arm/fpa.md
> +++ b/gcc/config/arm/fpa.md
> @@ -567,7 +567,7 @@
> case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
> case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
> case 2: return \"#\";
> - case 3: case 4: return output_move_double (operands);
> + case 3: case 4: return output_move_double (operands, 1, NULL);
> case 5: return \"mvf%?d\\t%0, %1\";
> case 6: return \"mnf%?d\\t%0, #%N1\";
> case 7: return \"ldf%?d\\t%0, %1\";
> @@ -657,7 +657,7 @@
> default:
> case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
> case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
> - case 2: case 3: case 4: return output_move_double (operands);
> + case 2: case 3: case 4: return output_move_double (operands, 1, NULL);
> case 5: return \"mvf%?d\\t%0, %1\";
> case 6: return \"mnf%?d\\t%0, #%N1\";
> case 7: return \"ldf%?d\\t%0, %1\";
> diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
> index 7f13ae4..b066157 100644
> --- a/gcc/config/arm/iwmmxt.md
> +++ b/gcc/config/arm/iwmmxt.md
> @@ -76,7 +76,7 @@
> switch (which_alternative)
> {
> default:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> case 0:
> return \"#\";
> case 3:
> @@ -173,7 +173,7 @@
> case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
> case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
> case 5: return \"#\";
> - default: return output_move_double (operands);
> + default: return output_move_double (operands, 1, NULL);
> }"
> [(set_attr "predicable" "yes")
> (set_attr "length" "4, 4, 4,4,4,8, 8,8")
> diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
> index 1f9ea67..6d61233 100644
> --- a/gcc/config/arm/neon.md
> +++ b/gcc/config/arm/neon.md
> @@ -190,7 +190,7 @@
> case 2: gcc_unreachable ();
> case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
> case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
> - default: return output_move_double (operands);
> + default: return output_move_double (operands, 1, NULL);
> }
> }
> [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
> diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
> index 3311ae0..82f96f0 100644
> --- a/gcc/config/arm/vfp.md
> +++ b/gcc/config/arm/vfp.md
> @@ -150,7 +150,7 @@
> case 4:
> case 5:
> case 6:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> case 7:
> return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
> case 8:
> @@ -199,7 +199,7 @@
> case 4:
> case 5:
> case 6:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> case 7:
> return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
> case 8:
> @@ -213,10 +213,19 @@
> }
> "
> [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
> - (set_attr "length" "4,8,12,16,8,8,8,4,4,4,4,4")
> + (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8)
> + (eq_attr "alternative" "2") (const_int 12)
> + (eq_attr "alternative" "3") (const_int 16)
> + (eq_attr "alternative" "4,5,6")
> + (symbol_ref
> + "arm_count_output_move_double_insns (operands) \
> + * 4")]
> + (const_int 4)))
> (set_attr "predicable" "yes")
> (set_attr "pool_range" "*,*,*,*,1020,4096,*,*,*,*,1020,*")
> (set_attr "neg_pool_range" "*,*,*,*,1008,0,*,*,*,*,1008,*")
> + (set (attr "ce_count")
> + (symbol_ref "arm_count_output_move_double_insns (operands)"))
> (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")]
> )
>
> @@ -427,7 +436,7 @@
> case 3: case 4:
> return output_move_vfp (operands);
> case 5: case 6:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> case 7:
> if (TARGET_VFP_SINGLE)
> return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
> @@ -473,7 +482,7 @@
> case 3: case 4:
> return output_move_vfp (operands);
> case 5: case 6: case 8:
> - return output_move_double (operands);
> + return output_move_double (operands, 1, NULL);
> case 7:
> if (TARGET_VFP_SINGLE)
> return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";