From: Uros Bizjak Date: Mon, 8 Aug 2011 14:59:19 +0000 (+0200) Subject: re PR target/49781 ([x32] Unnecessary lea in x32 mode) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=473b30ce95c6b3f41ced3bcc18fceb2c5f2ac466;p=gcc.git re PR target/49781 ([x32] Unnecessary lea in x32 mode) PR target/49781 * config/i386/i386.c (ix86_decompose_address): Allow zero-extended SImode addresses. (ix86_print_operand_address): Handle zero-extended addresses. (memory_address_length): Add length of addr32 prefix for zero-extended addresses. (ix86_secondary_reload): Handle moves to/from double-word general registers from/to zero-extended addresses. * config/i386/predicates.md (lea_address_operand): Reject zero-extended operands. From-SVN: r177566 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d1371d2b25d..79d104eba8d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,8 +1,20 @@ +2011-08-07 Uros Bizjak + + PR target/49781 + * config/i386/i386.c (ix86_decompose_address): Allow zero-extended + SImode addresses. + (ix86_print_operand_address): Handle zero-extended addresses. + (memory_address_length): Add length of addr32 prefix for + zero-extended addresses. + (ix86_secondary_reload): Handle moves to/from double-word general + registers from/to zero-extended addresses. + * config/i386/predicates.md (lea_address_operand): Reject + zero-extended operands. + 2011-08-08 H.J. Lu PR other/48007 - * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for - Linux/x86. + * config.gcc (libgcc_tm_file): Add i386/value-unwind.h for Linux/x86. * system.h (REG_VALUE_IN_UNWIND_CONTEXT): Poisoned. (ASSUME_EXTENDED_UNWIND_CONTEXT): Likewise. @@ -43,10 +55,8 @@ * config/sparc/driver-sparc.c: New file. * config/sparc/x-sparc: New file. - * config.host: Use driver-sparc.o, sparc/x-sparc on - sparc*-*-solaris2*. - * config/sparc/sparc.opt (native): New value for enum - processor_type. + * config.host: Use driver-sparc.o, sparc/x-sparc on sparc*-*-solaris2*. + * config/sparc/sparc.opt (native): New value for enum processor_type. * config/sparc/sparc-opts.h (PROCESSOR_NATIVE): Declare. * config/sparc/sparc.c (sparc_option_override): Abort if PROCESSOR_NATIVE gets here. @@ -93,7 +103,7 @@ (TARGET_INSTANTIATE_DECLS): New define. 2011-08-06 Paolo Bonzini - Mikael Morin + Mikael Morin * Makefile.in (INCLUDES_FOR_TARGET): New. (LIBGCC2_CFLAGS): Use it. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 19dd24330c5..b50b3d018bb 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11142,6 +11142,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) int retval = 1; enum ix86_address_seg seg = SEG_DEFAULT; + /* Allow zero-extended SImode addresses, + they will be emitted with addr32 prefix. */ + if (TARGET_64BIT + && GET_CODE (addr) == ZERO_EXTEND + && GET_MODE (addr) == DImode + && GET_MODE (XEXP (addr, 0)) == SImode) + addr = XEXP (addr, 0); + if (REG_P (addr)) base = addr; else if (GET_CODE (addr) == SUBREG) @@ -14159,8 +14167,12 @@ ix86_print_operand_address (FILE *file, rtx addr) } else { - /* Print DImode registers on 64bit targets to avoid addr32 prefixes. */ - int code = TARGET_64BIT ? 'q' : 0; + int code = 0; + + /* 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) ? 'l' : 'q'; if (ASSEMBLER_DIALECT == ASM_ATT) { @@ -21772,7 +21784,8 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n) } /* Calculate the length of the memory address in the instruction - encoding. Does not include the one-byte modrm, opcode, or prefix. */ + encoding. Includes addr32 prefix, does not include the one-byte modrm, + opcode, or other prefixes. */ int memory_address_length (rtx addr) @@ -21799,7 +21812,9 @@ memory_address_length (rtx addr) base = parts.base; index = parts.index; disp = parts.disp; - len = 0; + + /* Add length of addr32 prefix. */ + len = (GET_CODE (addr) == ZERO_EXTEND); /* Rule of thumb: - esp as the base always wants an index, @@ -28233,6 +28248,15 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass, enum machine_mode mode, secondary_reload_info *sri ATTRIBUTE_UNUSED) { + /* Double-word spills from general registers to non-offsettable memory + references (zero-extended addresses) go through XMM register. */ + if (TARGET_64BIT + && MEM_P (x) + && GET_MODE_SIZE (mode) > UNITS_PER_WORD + && rclass == GENERAL_REGS + && !offsettable_memref_p (x)) + return SSE_REGS; + /* QImode spills from non-QI registers require intermediate register on 32bit targets. */ if (!TARGET_64BIT diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 52ea3f3a2da..cfcd061e1f6 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -801,6 +801,10 @@ struct ix86_address parts; int ok; + /* LEA handles zero-extend by itself. */ + if (GET_CODE (op) == ZERO_EXTEND) + return false; + ok = ix86_decompose_address (op, &parts); gcc_assert (ok); return parts.seg == SEG_DEFAULT;