Message ID | CACUk7=WO9+qrZ_3ne-m9sQo+iyz=NF-pJf1urrug3gtoGaNDiA@mail.gmail.com |
---|---|
State | Superseded |
Headers | show |
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\";
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\";