From patchwork Fri Mar 9 18:15:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 145747 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 60642B6EEC for ; Sat, 10 Mar 2012 05:15:32 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1331921733; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=c7BN/YVh5MLKsMgwR4BJb+SoM0Q=; b=EdX7GNULf1ou+ns 7JJoDKXllmBDMIHJbXWYSEGu0YcUmvX3dUgdyOJTa0wHf51DmSF5wleZir6CYKI5 oKAFYgnqY9OiFK/qlmYxJe9DfDH6/k7pxkwbdHKPhi5PkE5BxtLryoNCUlSGXX8P 8QIM6NPQRQvE4Zl10qujNCpZPCEQ= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=IXO/WS0EdcJ2PIBsw/Katex4NtFYCdwzTo+GqZwBvEVRqCpoV1hClUmnEwJocc 4rCro++Y72qpBi9HjP+0XLb4C1ppm2OlGC55RfM+B6j4DDdBC1+R6GTF7xJohxg2 kJyWNnodoHXrnDJ+WLsITYZH2QqLZFpl2LaKK/4/y9ERc=; Received: (qmail 9682 invoked by alias); 9 Mar 2012 18:15:24 -0000 Received: (qmail 9665 invoked by uid 22791); 9 Mar 2012 18:15:21 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-gy0-f175.google.com (HELO mail-gy0-f175.google.com) (209.85.160.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Mar 2012 18:15:07 +0000 Received: by ghbz2 with SMTP id z2so1097435ghb.20 for ; Fri, 09 Mar 2012 10:15:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.101.128.14 with SMTP id f14mr1117891ann.21.1331316906764; Fri, 09 Mar 2012 10:15:06 -0800 (PST) Received: by 10.146.241.19 with HTTP; Fri, 9 Mar 2012 10:15:06 -0800 (PST) In-Reply-To: References: <20120302203833.GB2179@intel.com> Date: Fri, 9 Mar 2012 19:15:06 +0100 Message-ID: Subject: Re: [PATCH 02/10] addr32: Only handle zero-extended DImode addresses From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 On Fri, Mar 9, 2012 at 4:26 PM, H.J. Lu wrote: > On Thu, Mar 8, 2012 at 7:20 AM, Uros Bizjak wrote: >> On Sun, Mar 4, 2012 at 9:13 PM, Uros Bizjak wrote: >> >>>> We only need to handle zero-extended addresses in DImode. >>>> OK for trunk? >>> >>>> 2012-03-02  H.J. Lu   >>>> >>>>        * config/i386/i386.c (ix86_print_operand_address): Only handle >>>>        zero-extended DImode addresses. >>> >>> OK. >> >> The patch was reverted due to PR target/52530. >> > > Revert breaks Pmode == SImode for x32.  Here is a different patch. > It checks Pmode == DImode instead of TARGET_64BIT.  Tested on > Linux/x32.  OK for trunk? This will still emit i.e. "leal 1(%rSImode), %rSImode" on Pmode == SImode targets, so you win nothing really. Attached patch finally decouples LEA operand handling from generic address handling, and by introducing %E operand modifier, we are able to always emit DImode registers for LEAs (which is good anyway to avoid unnecessary addr32 prefixes). Luckily, the "leal 1(%rSImode), %rSImode" triggered some unknown problem with Sun assembler, so we were able to detect the problem. I would like to point out that the patched compiler now also emits address registers in their natural mode (modulo zero-extended RTXes) and fixes following failure on Pmode == SImode targets: --cut here-- struct foo {  int *f;  int i; }; void __attribute__ ((noinline)) bar (struct foo x) {  *(x.f) = 1; } --cut here-- For Pmode == SImode, the compiler emitted (%rdi) address, which was wrong, since "i" was passed in the high part of (%rdi) register. 2012-03-09  Uros Bizjak          PR target/52530        * config/i386/i386.c (ix86_print_operand): Handle 'E' operand modifier.        (ix86_print_operand_address): Handle UNSPEC_LEA_ADDR. Do not fallback        to set code to 'q'.        * config/i386/i386.md (UNSPEC_LEA_ADDR): New unspec.        (*movdi_internal_rex64): Use %E operand modifier for lea.        (*movsi_internal): Ditto.        (*lea_1): Ditto.        (*lea_2): Ditto.        (*lea_{3,4,5,6}_zext): Ditto.        (*tls_global_dynamic_32_gnu): Ditto.        (*tls_global_dynamic_64): Ditto.        (*tls_dynamic_gnu2_lea_32): Ditto.        (*tls_dynamic_gnu2_lea_64): Ditto.        (pro_epilogue_adjust_stack__add): Ditto. Patch was tested on x86_64-pc-linux-gnu {,-m32}. I have also eyeballed x32 code (Pmode == SImode) and found no problems. Committed to mainline SVN. H.J., can you please construct a runtime test from the above example code? Uros. Index: i386.md =================================================================== --- i386.md (revision 185139) +++ i386.md (working copy) @@ -38,6 +38,7 @@ ;; Z -- likewise, with special suffixes for x87 instructions. ;; * -- print a star (in certain assembler syntax) ;; A -- print an absolute memory reference. +;; E -- print address with DImode register names if TARGET_64BIT. ;; w -- print the operand as if it's a "word" (HImode) even if it isn't. ;; s -- print a shift double count, followed by the assemblers argument ;; delimiter. @@ -111,6 +112,7 @@ UNSPEC_MS_TO_SYSV_CALL UNSPEC_CALL_NEEDS_VZEROUPPER UNSPEC_PAUSE + UNSPEC_LEA_ADDR ;; For SSE/MMX support: UNSPEC_FIX_NOTRUNC @@ -1965,7 +1967,7 @@ return "#"; case TYPE_LEA: - return "lea{q}\t{%a1, %0|%0, %a1}"; + return "lea{q}\t{%E1, %0|%0, %E1}"; default: gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); @@ -1974,7 +1976,7 @@ else if (which_alternative == 2) return "movabs{q}\t{%1, %0|%0, %1}"; else if (ix86_use_lea_for_mov (insn, operands)) - return "lea{q}\t{%a1, %0|%0, %a1}"; + return "lea{q}\t{%E1, %0|%0, %E1}"; else return "mov{q}\t{%1, %0|%0, %1}"; } @@ -2206,12 +2208,12 @@ return "movd\t{%1, %0|%0, %1}"; case TYPE_LEA: - return "lea{l}\t{%a1, %0|%0, %a1}"; + return "lea{l}\t{%E1, %0|%0, %E1}"; default: gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); if (ix86_use_lea_for_mov (insn, operands)) - return "lea{l}\t{%a1, %0|%0, %a1}"; + return "lea{l}\t{%E1, %0|%0, %E1}"; else return "mov{l}\t{%1, %0|%0, %1}"; } @@ -5426,7 +5428,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))] "TARGET_64BIT" - "lea{l}\t{%a1, %0|%0, %a1}" + "lea{l}\t{%E1, %0|%0, %E1}" "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)" [(const_int 0)] { @@ -5440,7 +5442,7 @@ [(set (match_operand:SWI48 0 "register_operand" "=r") (match_operand:SWI48 1 "lea_address_operand" "p"))] "" - "lea{}\t{%a1, %0|%0, %a1}" + "lea{}\t{%E1, %0|%0, %E1}" "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" [(const_int 0)] { @@ -5455,7 +5457,7 @@ (zero_extend:DI (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))] "TARGET_64BIT" - "lea{l}\t{%a1, %k0|%k0, %a1}" + "lea{l}\t{%E1, %k0|%k0, %E1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) @@ -5464,7 +5466,7 @@ (zero_extend:DI (match_operand:SI 1 "lea_address_operand" "j")))] "TARGET_64BIT" - "lea{l}\t{%a1, %k0|%k0, %a1}" + "lea{l}\t{%E1, %k0|%k0, %E1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) @@ -5474,7 +5476,7 @@ (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0) (match_operand:DI 2 "const_32bit_mask" "n")))] "TARGET_64BIT" - "lea{l}\t{%a1, %k0|%k0, %a1}" + "lea{l}\t{%E1, %k0|%k0, %E1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) @@ -5484,7 +5486,7 @@ (match_operand:DI 1 "lea_address_operand" "p") (match_operand:DI 2 "const_32bit_mask" "n")))] "TARGET_64BIT" - "lea{l}\t{%a1, %k0|%k0, %a1}" + "lea{l}\t{%E1, %k0|%k0, %E1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) @@ -12541,7 +12543,7 @@ "!TARGET_64BIT && TARGET_GNU_TLS" { output_asm_insn - ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands); + ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); if (TARGET_SUN_TLS) #ifdef HAVE_AS_IX86_TLSGDPLT return "call\t%a2@tlsgdplt"; @@ -12576,7 +12578,7 @@ if (!TARGET_X32) fputs (ASM_BYTE "0x66\n", asm_out_file); output_asm_insn - ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands); + ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); fputs (ASM_SHORT "0x6666\n", asm_out_file); fputs ("\trex64\n", asm_out_file); if (TARGET_SUN_TLS) @@ -12802,7 +12804,7 @@ (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] UNSPEC_TLSDESC))))] "!TARGET_64BIT && TARGET_GNU2_TLS" - "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" + "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" [(set_attr "type" "lea") (set_attr "mode" "SI") (set_attr "length" "6") @@ -12864,7 +12866,7 @@ (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TLSDESC))] "TARGET_64BIT && TARGET_GNU2_TLS" - "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}" + "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" [(set_attr "type" "lea") (set_attr "mode" "DI") (set_attr "length" "7") @@ -16614,7 +16616,7 @@ default: operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); - return "lea{}\t{%a2, %0|%0, %a2}"; + return "lea{}\t{%E2, %0|%0, %E2}"; } } [(set (attr "type") Index: i386.c =================================================================== --- i386.c (revision 185139) +++ i386.c (working copy) @@ -13730,6 +13730,7 @@ get_some_local_dynamic_name (void) Z -- likewise, with special suffixes for x87 instructions. * -- print a star (in certain assembler syntax) A -- print an absolute memory reference. + E -- print address with DImode register names if TARGET_64BIT. w -- print the operand as if it's a "word" (HImode) even if it isn't. s -- print a shift double count, followed by the assemblers argument delimiter. @@ -13806,7 +13807,14 @@ ix86_print_operand (FILE *file, rtx x, int code) ix86_print_operand (file, x, 0); return; + case 'E': + /* Wrap address in an UNSPEC to declare special handling. */ + if (TARGET_64BIT) + x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR); + output_address (x); + return; + case 'L': if (ASSEMBLER_DIALECT == ASM_ATT) putc ('l', file); @@ -14418,6 +14426,7 @@ ix86_print_operand_address (FILE *file, rtx addr) int scale; int ok; bool vsib = false; + int code = 0; if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR) { @@ -14428,6 +14437,12 @@ ix86_print_operand_address (FILE *file, rtx addr) addr = XVECEXP (addr, 0, 0); vsib = true; } + else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR) + { + gcc_assert (TARGET_64BIT); + ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts); + code = 'q'; + } else ok = ix86_decompose_address (addr, &parts); @@ -14498,16 +14513,16 @@ ix86_print_operand_address (FILE *file, rtx addr) } else { - int code = 0; + /* Print SImode register names for zero-extended + addresses to force addr32 prefix. */ + if (TARGET_64BIT + && (GET_CODE (addr) == ZERO_EXTEND + || GET_CODE (addr) == AND)) + { + gcc_assert (!code); + code = 'l'; + } - /* Print SImode registers for zero-extended addresses to force - addr32 prefix. Otherwise print DImode registers to avoid it. */ - if (TARGET_64BIT) - code = ((GET_CODE (addr) == ZERO_EXTEND - || GET_CODE (addr) == AND) - ? 'l' - : 'q'); - if (ASSEMBLER_DIALECT == ASM_ATT) { if (disp)