From patchwork Sat Jul 9 20:46:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 104024 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 A4986B7090 for ; Sun, 10 Jul 2011 06:46:38 +1000 (EST) Received: (qmail 3118 invoked by alias); 9 Jul 2011 20:46:37 -0000 Received: (qmail 3107 invoked by uid 22791); 9 Jul 2011 20:46:36 -0000 X-SWARE-Spam-Status: No, hits=-4.8 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 09 Jul 2011 20:46:20 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 09 Jul 2011 13:46:16 -0700 X-ExtLoop1: 1 Received: from gnu-4.sc.intel.com ([10.3.194.56]) by fmsmga002.fm.intel.com with ESMTP; 09 Jul 2011 13:46:16 -0700 Received: by gnu-4.sc.intel.com (Postfix, from userid 500) id D6E0C20290; Sat, 9 Jul 2011 13:46:16 -0700 (PDT) Date: Sat, 9 Jul 2011 13:46:16 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Subject: [x32] PATCH: Add x32 LEA zero-extend split Message-ID: <20110709204616.GA10416@lucon.org> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 Hi, I checked in this patch to add x32 LEA zero-extend split. H.J. --- commit a57ad5f219b8aa7cc67c18fb3a217517c2a461f4 Author: H.J. Lu Date: Sat Jul 9 08:00:56 2011 -0700 Support x32 LEA zero-extend split. diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32 index a610f23..fdff5af 100644 --- a/gcc/ChangeLog.x32 +++ b/gcc/ChangeLog.x32 @@ -1,3 +1,14 @@ +2011-07-09 H.J. Lu + + * config/i386/i386.c (ix86_simplify_base_disp): Renamed to ... + (ix86_simplify_base_index_disp): This. Handle index. + (ix86_simplify_base_disp): Updated. + + * config/i386/i386.md (*lea_1_x32): Renamed to ... + (*lea_2_x32): This. + (*lea_2_zext_x32): New. + (X32 LEA zero-extend split): Likewise. + 2011-07-06 H.J. Lu * config.gcc: Check with_multilib_list instead of enable_x32. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b0112b9..c852719 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11054,6 +11054,17 @@ ix86_live_on_entry (bitmap regs) (const (plus:SI (symbol_ref:SI ("A.193.2210")) (const_int CONST)))) + We also translate + + (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74]) + (subreg:SI (plus:DI (reg/f:DI 7 sp) + (const_int 64 [0x40])) 0)) + + into + + (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74]) + (plus:SI (reg/f:SI 7 sp) (const_int 64 [0x40]))) + If PLUS is true, we also translate (set (reg:SI 40 r11) @@ -11072,10 +11083,11 @@ ix86_live_on_entry (bitmap regs) */ static void -ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus) +ix86_simplify_base_index_disp (rtx *base_p, rtx *index_p, rtx *disp_p, + bool plus) { rtx base = *base_p; - rtx disp; + rtx disp, index, op0, op1; if (!base || GET_MODE (base) != ptr_mode) return; @@ -11091,10 +11103,11 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus) if (GET_CODE (base) == PLUS) { - rtx op0 = XEXP (base, 0); - rtx op1 = XEXP (base, 1); rtx addend; + op0 = XEXP (base, 0); + op1 = XEXP (base, 1); + if ((REG_P (op0) || (!plus && GET_CODE (op0) == PLUS @@ -11160,6 +11173,25 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus) *base_p = base; } } + else if (!plus + && (disp == NULL_RTX || disp == const0_rtx) + && index_p + && (index = *index_p) != NULL_RTX + && GET_CODE (index) == SUBREG + && GET_MODE (index) == ptr_mode) + { + index = SUBREG_REG (index); + if (GET_CODE (index) == PLUS && GET_MODE (index) == Pmode) + { + op0 = XEXP (index, 0); + op1 = XEXP (index, 1); + if (REG_P (op0) && CONST_INT_P (op1)) + { + *index_p = gen_rtx_REG (ptr_mode, REGNO (op0)); + *disp_p = op1; + } + } + } } /* Extract the parts of an RTL expression that is a valid memory address @@ -11208,12 +11240,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) { op = XEXP (op, 0); if (n == 1) - ix86_simplify_base_disp (&op, &addends[0], false); + ix86_simplify_base_index_disp (&op, NULL, + &addends[0], false); } else if (n == 1 && GET_CODE (op) == PLUS && GET_MODE (op) == ptr_mode) - ix86_simplify_base_disp (&op, &addends[0], true); + ix86_simplify_base_index_disp (&op, NULL, &addends[0], + true); } } while (GET_CODE (op) == PLUS); @@ -11308,14 +11342,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) scale = INTVAL (scale_rtx); } - index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index; + if (TARGET_X32 && reload_completed) + ix86_simplify_base_index_disp (&base, &index, &disp, false); /* Avoid useless 0 displacement. */ if (disp == const0_rtx && (base || index)) disp = NULL_RTX; - if (TARGET_X32 && reload_completed) - ix86_simplify_base_disp (&base, &disp, false); + index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index; base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index fe4b6be..4230c8f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5477,18 +5477,20 @@ [(set_attr "type" "lea") (set_attr "mode" "")]) -(define_insn "*lea_1_x32" +(define_insn "*lea_2" [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "no_seg_address_operand" "p"))] - "TARGET_X32" + (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] + "TARGET_64BIT" "lea{l}\t{%a1, %0|%0, %a1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn "*lea_2" +;; Place this after lea_2 since 64bit version doesn't have address +;; size override. +(define_insn "*lea_2_x32" [(set (match_operand:SI 0 "register_operand" "=r") - (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] - "TARGET_64BIT" + (match_operand:SI 1 "no_seg_address_operand" "p"))] + "TARGET_X32" "lea{l}\t{%a1, %0|%0, %a1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) @@ -5502,6 +5504,15 @@ [(set_attr "type" "lea") (set_attr "mode" "SI")]) +(define_insn "*lea_2_zext_x32" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (match_operand:SI 1 "no_seg_address_operand" "p")))] + "TARGET_X32" + "lea{l}\t{%a1, %k0|%k0, %a1}" + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + (define_insn "*add_1" [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") (plus:SWI48 @@ -5908,6 +5919,19 @@ operands[2] = gen_lowpart (DImode, operands[2]); }) +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI + (plus:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_X32 + && reload_completed + && ix86_lea_for_add_ok (insn, operands)" + [(set (match_dup 0) + (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) + (define_insn "*add_2" [(set (reg FLAGS_REG) (compare