From patchwork Wed Oct 26 21:20:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Miller X-Patchwork-Id: 122017 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 46528B6F8A for ; Thu, 27 Oct 2011 08:21:44 +1100 (EST) Received: (qmail 28919 invoked by alias); 26 Oct 2011 21:21:42 -0000 Received: (qmail 28911 invoked by uid 22791); 26 Oct 2011 21:21:39 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, TW_EG, TW_SV, TW_VT X-Spam-Check-By: sourceware.org Received: from shards.monkeyblade.net (HELO shards.monkeyblade.net) (198.137.202.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 26 Oct 2011 21:21:24 +0000 Received: from localhost (nat-pool-rdu.redhat.com [66.187.233.202]) (authenticated bits=0) by shards.monkeyblade.net (8.14.4/8.14.4) with ESMTP id p9QLKu9T013016 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 26 Oct 2011 14:20:58 -0700 Date: Wed, 26 Oct 2011 17:20:55 -0400 (EDT) Message-Id: <20111026.172055.1361157389798399406.davem@davemloft.net> To: gcc-patches@gcc.gnu.org CC: ebotcazou@adacore.com, rth@redhat.com Subject: [PATCH] Canonicalize sparc movcc patterns such that operand 0 always appears in operand 4. From: David Miller Mime-Version: 1.0 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 The background is that I was putting together some test cases for gcc.target/sparc that make sure the most optimal setcc sequences are being generated. When v9, and thus conditional moves, are enabled we sometimes fall back to conditional moves even when the addx/subx sequence is more efficient. For example, we can do "a = x < y" in 2 instructions when x and y are both unsigned: cmp y, x subx %g0, -1, a but with v9 enabled we get: cmp x, y mov 0, a movleu %icc, 1, a The reason is because of the permissive way in which we define the RTL for conditional moves. For the integer moves we mark both operands 3 and 4 using predicate "arith*_operand" which accepts constants as well as registers. The constraints do in fact express how one of the two operands must be equal the operand 0. However combine doesn't look at constraints to determine if a combined instruction is recognized. So combine thinks that insns of the form: (set op0 (if_then_else (CMP X Y) (const_int 0) (const_int 1))) are ok. Reload later fixes things up by reloading one of the two constants into operand 0, and that's how we end up with the above 3 instruction sequence. Initially I tried to fix up the conditional move patterns by using a "match_dup 0" for operand 4 to show the combiner, in the RTL, that operand 4 must be equal to operand 0. But I learned that this is not legal RTL. You can only use match_dup in instructions after the first instruction of an expansion that initially makes use of the operand. Surprisingly this worked most of the time. The failures I got were in a regrename def/use chain assertion check when loop unrolling was enabled. Anyways, instead what I do here is normalize all expansions of conditional moves to be of the form: (set op0 (if_then_else (cmp X Y) op3 op0)) and in the instruction patterns I use "register_operand" and constraint "0" for operand 4. This is enough to keep the combiner from recognizing sequences like the above. Committed to trunk. gcc/ * config/sparc/sparc-protos.h (sparc_expand_conditional_move): Declare. * config/sparc/sparc.md (movcc, movcc): Call it. (*mov_cc_v9): Normalize to expect operand 0 always in operand 4. (*mov_cc_reg_sp64): Likewise. (*movsf_cc_v9): Likewise. (*movsf_cc_reg_sp64): Likewise. (*movdf_cc_v9): Likewise. (*movdf_cc_reg_sp64): Likewise. (*movtf_cc_hq_v9): Likewise. (*movtf_cc_reg_hq_sp64): Likewise. (*movtf_cc_v9): Likewise. (*movtf_cc_reg_sp64): Likewise. * config/sparc/sparc.c (sparc_expand_conditional_move): New function. (sparc_print_operand): Delete 'c' and 'd' handling, no longer used. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180542 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 17 ++++ gcc/config/sparc/sparc-protos.h | 1 + gcc/config/sparc/sparc.c | 80 ++++++++++++---- gcc/config/sparc/sparc.md | 197 +++++++++++++-------------------------- 4 files changed, 144 insertions(+), 151 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cd1a236..d6d1382 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2011-10-26 David S. Miller + + * config/sparc/sparc-protos.h (sparc_expand_conditional_move): Declare. + * config/sparc/sparc.md (movcc, movcc): Call it. + (*mov_cc_v9): Normalize to expect operand 0 always in operand 4. + (*mov_cc_reg_sp64): Likewise. + (*movsf_cc_v9): Likewise. + (*movsf_cc_reg_sp64): Likewise. + (*movdf_cc_v9): Likewise. + (*movdf_cc_reg_sp64): Likewise. + (*movtf_cc_hq_v9): Likewise. + (*movtf_cc_reg_hq_sp64): Likewise. + (*movtf_cc_v9): Likewise. + (*movtf_cc_reg_sp64): Likewise. + * config/sparc/sparc.c (sparc_expand_conditional_move): New function. + (sparc_print_operand): Delete 'c' and 'd' handling, no longer used. + 2011-10-26 Eric Botcazou * reload.c (reload_inner_reg_of_subreg): Change type of return value diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index bb6fb07..108e105 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -107,6 +107,7 @@ extern void sparc_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx); extern const char *output_v8plus_mult (rtx, rtx *, const char *); extern void sparc_expand_vector_init (rtx, rtx); extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx); +extern bool sparc_expand_conditional_move (enum machine_mode, rtx *); #endif /* RTX_CODE */ #endif /* __SPARC_PROTOS_H__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index f806c6c..964bcaf 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -8162,20 +8162,11 @@ sparc_print_operand (FILE *file, rtx x, int code) } return; - /* These are used by the conditional move instructions. */ - case 'c' : + /* This is used by the conditional move instructions. */ case 'C': { enum rtx_code rc = GET_CODE (x); - if (code == 'c') - { - enum machine_mode mode = GET_MODE (XEXP (x, 0)); - if (mode == CCFPmode || mode == CCFPEmode) - rc = reverse_condition_maybe_unordered (GET_CODE (x)); - else - rc = reverse_condition (GET_CODE (x)); - } switch (rc) { case NE: fputs ("ne", file); break; @@ -8196,20 +8187,15 @@ sparc_print_operand (FILE *file, rtx x, int code) case UNGT: fputs ("ug", file); break; case UNGE: fputs ("uge", file); break; case UNEQ: fputs ("ue", file); break; - default: output_operand_lossage (code == 'c' - ? "invalid %%c operand" - : "invalid %%C operand"); + default: output_operand_lossage ("invalid %%C operand"); } return; } - /* These are used by the movr instruction pattern. */ - case 'd': + /* This are used by the movr instruction pattern. */ case 'D': { - enum rtx_code rc = (code == 'd' - ? reverse_condition (GET_CODE (x)) - : GET_CODE (x)); + enum rtx_code rc = GET_CODE (x); switch (rc) { case NE: fputs ("ne", file); break; @@ -8218,9 +8204,7 @@ sparc_print_operand (FILE *file, rtx x, int code) case LT: fputs ("lz", file); break; case LE: fputs ("lez", file); break; case GT: fputs ("gz", file); break; - default: output_operand_lossage (code == 'd' - ? "invalid %%d operand" - : "invalid %%D operand"); + default: output_operand_lossage ("invalid %%D operand"); } return; } @@ -11377,4 +11361,58 @@ sparc_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, return NO_REGS; } +bool +sparc_expand_conditional_move (enum machine_mode mode, rtx *operands) +{ + enum rtx_code rc = GET_CODE (operands[1]); + enum machine_mode cmp_mode; + rtx cc_reg, dst, cmp; + + cmp = operands[1]; + cmp_mode = GET_MODE (XEXP (cmp, 0)); + if (cmp_mode == DImode && !TARGET_ARCH64) + return false; + + dst = operands[0]; + + if (! rtx_equal_p (operands[2], dst) + && ! rtx_equal_p (operands[3], dst)) + { + if (reg_overlap_mentioned_p (dst, cmp)) + dst = gen_reg_rtx (mode); + + emit_move_insn (dst, operands[3]); + } + else if (operands[2] == dst) + { + operands[2] = operands[3]; + + if (GET_MODE_CLASS (cmp_mode) == MODE_FLOAT) + rc = reverse_condition_maybe_unordered (rc); + else + rc = reverse_condition (rc); + } + + if (cmp_mode == TFmode && !TARGET_HARD_QUAD) + cmp = sparc_emit_float_lib_cmp (XEXP (cmp, 0), XEXP (cmp, 1), rc); + + if (XEXP (cmp, 1) == const0_rtx + && GET_CODE (XEXP (cmp, 0)) == REG + && cmp_mode == DImode + && v9_regcmp_p (rc)) + cc_reg = XEXP (cmp, 0); + else + cc_reg = gen_compare_reg_1 (rc, XEXP (cmp, 0), XEXP (cmp, 1)); + + cmp = gen_rtx_fmt_ee (rc, GET_MODE (cc_reg), cc_reg, const0_rtx); + + emit_insn (gen_rtx_SET (VOIDmode, dst, + gen_rtx_IF_THEN_ELSE (mode, cmp, operands[2], dst))); + + if (dst != operands[0]) + emit_move_insn (operands[0], dst); + + return true; +} + #include "gt-sparc.h" diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index d1ebb24..2bae28e 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -2456,6 +2456,9 @@ ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand ;; 3 contains the constant if one is present, but we handle either for ;; generality (sparc.c puts a constant in operand 2). +;; +;; Our instruction patterns, on the other hand, canonicalize such that +;; operand 3 must be the set destination. (define_expand "movcc" [(set (match_operand:I 0 "register_operand" "") @@ -2464,27 +2467,9 @@ (match_operand:I 3 "arith10_operand" "")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" { - rtx cc_reg; - - if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) + if (! sparc_expand_conditional_move (mode, operands)) FAIL; - - if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) - operands[1] - = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), - GET_CODE (operands[1])); - - if (XEXP (operands[1], 1) == const0_rtx - && GET_CODE (XEXP (operands[1], 0)) == REG - && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (GET_CODE (operands[1]))) - cc_reg = XEXP (operands[1], 0); - else - cc_reg = gen_compare_reg (operands[1]); - - operands[1] - = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, - const0_rtx); + DONE; }) (define_expand "movcc" @@ -2494,146 +2479,112 @@ (match_operand:F 3 "register_operand" "")))] "TARGET_V9 && TARGET_FPU" { - rtx cc_reg; - - if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) + if (! sparc_expand_conditional_move (mode, operands)) FAIL; - - if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) - operands[1] - = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), - GET_CODE (operands[1])); - - if (XEXP (operands[1], 1) == const0_rtx - && GET_CODE (XEXP (operands[1], 0)) == REG - && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (GET_CODE (operands[1]))) - cc_reg = XEXP (operands[1], 0); - else - cc_reg = gen_compare_reg (operands[1]); - - operands[1] - = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, - const0_rtx); + DONE; }) ;; Conditional move define_insns (define_insn "*mov_cc_v9" - [(set (match_operand:I 0 "register_operand" "=r,r") + [(set (match_operand:I 0 "register_operand" "=r") (if_then_else:I (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:I 3 "arith11_operand" "rL,0") - (match_operand:I 4 "arith11_operand" "0,rL")))] + (match_operand:I 3 "arith11_operand" "rL") + (match_operand:I 4 "register_operand" "0")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" - "@ - mov%C1\t%x2, %3, %0 - mov%c1\t%x2, %4, %0" + "mov%C1\t%x2, %3, %0" [(set_attr "type" "cmove")]) (define_insn "*mov_cc_reg_sp64" - [(set (match_operand:I 0 "register_operand" "=r,r") + [(set (match_operand:I 0 "register_operand" "=r") (if_then_else:I (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:I 3 "arith10_operand" "rM,0") - (match_operand:I 4 "arith10_operand" "0,rM")))] + (match_operand:I 3 "arith10_operand" "rM") + (match_operand:I 4 "register_operand" "0")))] "TARGET_ARCH64" - "@ - movr%D1\t%2, %r3, %0 - movr%d1\t%2, %r4, %0" + "movr%D1\t%2, %r3, %0" [(set_attr "type" "cmove")]) (define_insn "*movsf_cc_v9" - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else:SF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f") + (match_operand:SF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" - "@ - fmovs%C1\t%x2, %3, %0 - fmovs%c1\t%x2, %4, %0" + "fmovs%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove")]) (define_insn "*movsf_cc_reg_sp64" - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else:SF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f") + (match_operand:SF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" - "@ - fmovrs%D1\t%2, %3, %0 - fmovrs%d1\t%2, %4, %0" + "fmovrs%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove")]) ;; Named because invoked by movtf_cc_v9 (define_insn "movdf_cc_v9" - [(set (match_operand:DF 0 "register_operand" "=e,e") + [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else:DF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e") + (match_operand:DF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" - "@ - fmovd%C1\t%x2, %3, %0 - fmovd%c1\t%x2, %4, %0" + "fmovd%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove") (set_attr "fptype" "double")]) ;; Named because invoked by movtf_cc_reg_sp64 (define_insn "movdf_cc_reg_sp64" - [(set (match_operand:DF 0 "register_operand" "=e,e") + [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else:DF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e") + (match_operand:DF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" - "@ - fmovrd%D1\t%2, %3, %0 - fmovrd%d1\t%2, %4, %0" + "fmovrd%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove") (set_attr "fptype" "double")]) (define_insn "*movtf_cc_hq_v9" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "@ - fmovq%C1\t%x2, %3, %0 - fmovq%c1\t%x2, %4, %0" + "fmovq%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove")]) (define_insn "*movtf_cc_reg_hq_sp64" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - "@ - fmovrq%D1\t%2, %3, %0 - fmovrq%d1\t%2, %4, %0" + "fmovrq%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove")]) (define_insn_and_split "*movtf_cc_v9" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" "#" "&& reload_completed" @@ -2641,42 +2592,35 @@ { rtx set_dest = operands[0]; rtx set_srca = operands[3]; - rtx set_srcb = operands[4]; - int third = rtx_equal_p (set_dest, set_srca); rtx dest1, dest2; - rtx srca1, srca2, srcb1, srcb2; + rtx srca1, srca2; dest1 = gen_df_reg (set_dest, 0); dest2 = gen_df_reg (set_dest, 1); srca1 = gen_df_reg (set_srca, 0); srca2 = gen_df_reg (set_srca, 1); - srcb1 = gen_df_reg (set_srcb, 0); - srcb2 = gen_df_reg (set_srcb, 1); - /* Now emit using the real source and destination we found, swapping - the order if we detect overlap. */ - if ((third && reg_overlap_mentioned_p (dest1, srcb2)) - || (!third && reg_overlap_mentioned_p (dest1, srca2))) + if (reg_overlap_mentioned_p (dest1, srca2)) { - emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2)); - emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); + emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); } else { - emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1)); - emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); + emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); } DONE; } [(set_attr "length" "2")]) (define_insn_and_split "*movtf_cc_reg_sp64" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" "#" "&& reload_completed" @@ -2684,30 +2628,23 @@ { rtx set_dest = operands[0]; rtx set_srca = operands[3]; - rtx set_srcb = operands[4]; - int third = rtx_equal_p (set_dest, set_srca); rtx dest1, dest2; - rtx srca1, srca2, srcb1, srcb2; + rtx srca1, srca2; dest1 = gen_df_reg (set_dest, 0); dest2 = gen_df_reg (set_dest, 1); srca1 = gen_df_reg (set_srca, 0); srca2 = gen_df_reg (set_srca, 1); - srcb1 = gen_df_reg (set_srcb, 0); - srcb2 = gen_df_reg (set_srcb, 1); - /* Now emit using the real source and destination we found, swapping - the order if we detect overlap. */ - if ((third && reg_overlap_mentioned_p (dest1, srcb2)) - || (!third && reg_overlap_mentioned_p (dest1, srca2))) + if (reg_overlap_mentioned_p (dest1, srca2)) { - emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); - emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); } else { - emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); - emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); } DONE; }