From patchwork Fri Aug 12 14:16:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ramana Radhakrishnan X-Patchwork-Id: 109844 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9E55BB708F for ; Sat, 13 Aug 2011 00:17:18 +1000 (EST) Received: (qmail 528 invoked by alias); 12 Aug 2011 14:17:14 -0000 Received: (qmail 497 invoked by uid 22791); 12 Aug 2011 14:17:07 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-qy0-f175.google.com (HELO mail-qy0-f175.google.com) (209.85.216.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 12 Aug 2011 14:16:46 +0000 Received: by qyk4 with SMTP id 4so345603qyk.20 for ; Fri, 12 Aug 2011 07:16:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.224.34.20 with SMTP id j20mr642959qad.60.1313158605444; Fri, 12 Aug 2011 07:16:45 -0700 (PDT) Received: by 10.224.89.67 with HTTP; Fri, 12 Aug 2011 07:16:45 -0700 (PDT) In-Reply-To: <4E44F4D4.1040706@arm.com> References: <4E44F4D4.1040706@arm.com> Date: Fri, 12 Aug 2011 15:16:45 +0100 Message-ID: Subject: Re: [Patch ARM] Fix PR50022 From: Ramana Radhakrishnan To: Richard Earnshaw Cc: gcc-patches , Patch Tracking , Matthias Klose X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org > > Use a bool for "emit".  Otherwise OK. Fixed this and a small thinko in the minor modification from my first stab at this. Revised patch attached. I'll commit this if there are no regressions. Ramana > > 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  @ "; >>      case 5: return "vmov\t%P0, %Q1, %R1  @ "; >> -    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..2353704 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 *, bool, 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 afa989e..4457704 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -13284,11 +13284,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, bool 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) { @@ -13301,35 +13314,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: @@ -13347,8 +13374,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 { @@ -13359,11 +13391,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; + } } } @@ -13376,11 +13417,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; @@ -13393,12 +13442,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. */ @@ -13417,17 +13473,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 ""; } } @@ -13455,34 +13514,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 { @@ -13490,13 +13565,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; } } } @@ -13510,34 +13596,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: @@ -13555,19 +13652,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: @@ -13577,19 +13690,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 ""; } } @@ -13602,7 +13718,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 */ @@ -13610,8 +13727,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; + } } @@ -24205,4 +24328,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_length_output_move_double_insns (rtx *operands) +{ + int count; + output_move_double (operands, false, &count); + return count; +} + #include "gt-arm.h" diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 3d4dcfa..473bc7c 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, true, 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, true, 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..bfd2bb8 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, true, 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, true, 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, true, 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, true, 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..f2113a9 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, true, 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, true, 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..bc0b80d 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, true, 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, true, 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..24dd941 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 @ "; case 5: return "vmov\t%P0, %Q1, %R1 @ "; - default: return output_move_double (operands); + default: return output_move_double (operands, true, 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..991b517 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, true, 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, true, 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 "get_attr_length (insn) / 4")) (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, true, 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, true, NULL); case 7: if (TARGET_VFP_SINGLE) return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";