aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2011-08-11 22:03:29 +0200
committerUros Bizjak <uros@gcc.gnu.org>2011-08-11 22:03:29 +0200
commit88b590c5128b80298568fe15f341cdcf94d9acb7 (patch)
tree4f5ce01cdc39362370b5979fb89a1c34daeeb057 /gcc
parenta4eeb8220731f47d917bf9fc9419bbb2657f4732 (diff)
downloadgcc-88b590c5128b80298568fe15f341cdcf94d9acb7.zip
gcc-88b590c5128b80298568fe15f341cdcf94d9acb7.tar.gz
gcc-88b590c5128b80298568fe15f341cdcf94d9acb7.tar.bz2
re PR target/49781 ([x32] Unnecessary lea in x32 mode)
PR target/49781 * config/i386/i386.md (*lea_5_zext): New. (*lea_6_zext): Ditto. * config/i386/predicates.md (const_32bit_mask): New predicate. (lea_address_operand): Reject AND. * config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with const_32bit_mask immediate. (ix86_print_operand_address): Handle AND. (memory_address_length): Ditto. From-SVN: r177683
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog40
-rw-r--r--gcc/config/i386/i386.c35
-rw-r--r--gcc/config/i386/i386.md36
-rw-r--r--gcc/config/i386/predicates.md9
4 files changed, 85 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 803e9c7..5d6e2d0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
+2011-08-11 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/49781
+ * config/i386/i386.md (*lea_5_zext): New.
+ (*lea_6_zext): Ditto.
+ * config/i386/predicates.md (const_32bit_mask): New predicate.
+ (lea_address_operand): Reject AND.
+ * config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with
+ const_32bit_mask immediate.
+ (ix86_print_operand_address): Handle AND.
+ (memory_address_length): Ditto.
+
2011-08-11 Romain Geissler <romain.geissler@gmail.com>
- Brian Hackett <bhackett1024@gmail.com>
+ Brian Hackett <bhackett1024@gmail.com>
* plugin.def: Add event for finish_decl.
* plugin.c (register_callback, invoke_plugin_callbacks): Same.
@@ -40,8 +52,7 @@
2011-08-11 Kazuhiro Inaoka <kazuhiro.inaoka.ud@renesas.com>
- * config/rx/rx.md (movsicc): Allow register to register
- transfers.
+ * config/rx/rx.md (movsicc): Allow register to register transfers.
(*movsicc): Likewise.
(*stcc): Restrict this pattern to EQ and NE compares.
(*stcc_reg): New pattern. Works for any comparison but only for
@@ -71,8 +82,7 @@
(lto_materialize_tree): ... here.
Handle CALL_EXPR codes.
Remove call to lto_streamer_cache_append.
- * tree-streamer-out.c (lto_output_tree_header): Handle
- CALL_EXPR nodes.
+ * tree-streamer-out.c (lto_output_tree_header): Handle CALL_EXPR nodes.
* tree-streamer.h (tree_read_bitfields): Declare.
* Makefile.in (TREE_STREAMER_H): Add STREAMER_HOOKS_H.
@@ -96,8 +106,7 @@
Remove assertions and adjustments for nodes
main_identifier_node, ptrdiff_type_node and fileptr_type_node.
(lto_streamer_hooks_init): Set streamer_hooks.write_tree to
- lto_output_tree and streamer_hooks.read_tree to
- lto_input_tree.
+ lto_output_tree and streamer_hooks.read_tree to lto_input_tree.
* lto-streamer.h (lto_input_tree): Declare.
(lto_output_tree_ref): Remove.
* streamer-hooks.h (struct streamer_hooks): Remove fields
@@ -121,8 +130,7 @@
(lto_output_integer_cst): Likewise.
(lto_write_tree): Move to lto-streamer-out.c.
(lto_output_tree): Likewise.
- * tree-streamer.c (lto_record_common_node): Move from
- lto-streamer.c
+ * tree-streamer.c (lto_record_common_node): Move from lto-streamer.c
(preload_common_nodes): Likewise.
(lto_streamer_cache_create): Call it.
* tree-streamer.h: Include streamer-hooks.h.
@@ -281,7 +289,7 @@
* doc/tm.texi: Regenerate.
2011-08-10 Georg-Johann Lay <avr@gjlay.de>
-
+
PR target/29560
* config/avr/avr.md (*ashlhiqi3): New insn-and-split.
(*ashl<extend_prefix>qihiqi3): New insn-and-splits.
@@ -337,12 +345,12 @@
2011-08-09 Kirill Yukhin <kirill.yukhin@intel.com>
- * config/i386/i386.c: Remove traling spaces.
- * config/i386/sse.md: Likewise.
- (*fma_fmadd_<mode>): Fix insn alternative 1 mnemonic.
- (*fma_fmsub_<mode>): Likewise.
- (*fma_fnmadd_<mode>): Likewise.
- (*fma_fnmsub_<mode>): Likewise.
+ * config/i386/i386.c: Remove traling spaces.
+ * config/i386/sse.md: Likewise.
+ (*fma_fmadd_<mode>): Fix insn alternative 1 mnemonic.
+ (*fma_fmsub_<mode>): Likewise.
+ (*fma_fnmadd_<mode>): Likewise.
+ (*fma_fnmsub_<mode>): Likewise.
2011-08-09 Nick Clifton <nickc@redhat.com>
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 05dd57c..fedb2ca 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11146,11 +11146,22 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
/* 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 (TARGET_64BIT && GET_MODE (addr) == DImode)
+ {
+ if (GET_CODE (addr) == ZERO_EXTEND
+ && GET_MODE (XEXP (addr, 0)) == SImode)
+ addr = XEXP (addr, 0);
+ else if (GET_CODE (addr) == AND
+ && const_32bit_mask (XEXP (addr, 1), DImode))
+ {
+ addr = XEXP (addr, 0);
+
+ /* Strip subreg. */
+ if (GET_CODE (addr) == SUBREG
+ && GET_MODE (SUBREG_REG (addr)) == SImode)
+ addr = SUBREG_REG (addr);
+ }
+ }
if (REG_P (addr))
base = addr;
@@ -14174,7 +14185,10 @@ ix86_print_operand_address (FILE *file, rtx addr)
/* 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';
+ code = ((GET_CODE (addr) == ZERO_EXTEND
+ || GET_CODE (addr) == AND)
+ ? 'l'
+ : 'q');
if (ASSEMBLER_DIALECT == ASM_ATT)
{
@@ -21785,9 +21799,9 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
return s->rtl;
}
-/* Calculate the length of the memory address in the instruction
- encoding. Includes addr32 prefix, does not include the one-byte modrm,
- opcode, or other prefixes. */
+/* Calculate the length of the memory address in the instruction encoding.
+ Includes addr32 prefix, does not include the one-byte modrm, opcode,
+ or other prefixes. */
int
memory_address_length (rtx addr)
@@ -21816,7 +21830,8 @@ memory_address_length (rtx addr)
disp = parts.disp;
/* Add length of addr32 prefix. */
- len = (GET_CODE (addr) == ZERO_EXTEND);
+ len = (GET_CODE (addr) == ZERO_EXTEND
+ || GET_CODE (addr) == AND);
/* Rule of thumb:
- esp as the base always wants an index,
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1b37118..e61b0f4 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5477,6 +5477,14 @@
(set_attr "mode" "QI")])
(define_insn "*lea_1"
+ [(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}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
+
+(define_insn "*lea<mode>_2"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(match_operand:SWI48 1 "lea_address_operand" "p"))]
""
@@ -5484,7 +5492,16 @@
[(set_attr "type" "lea")
(set_attr "mode" "<MODE>")])
-(define_insn "*lea_1_zext"
+(define_insn "*lea_3_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
+ "TARGET_64BIT"
+ "lea{l}\t{%a1, %k0|%k0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
+
+(define_insn "*lea_4_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(match_operand:SI 1 "lea_address_operand" "p")))]
@@ -5493,18 +5510,21 @@
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
-(define_insn "*lea_2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
+(define_insn "*lea_5_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI
+ (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, %0|%0, %a1}"
+ "lea{l}\t{%a1, %k0|%k0, %a1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
-(define_insn "*lea_2_zext"
+(define_insn "*lea_6_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
+ (and:DI
+ (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}"
[(set_attr "type" "lea")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index cfcd061..bc0a357 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -597,6 +597,12 @@
(and (match_code "const_int")
(match_test "INTVAL (op) == 128")))
+;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation
+(define_predicate "const_32bit_mask"
+ (and (match_code "const_int")
+ (match_test "trunc_int_for_mode (INTVAL (op), DImode)
+ == (HOST_WIDE_INT) 0xffffffff")))
+
;; Match 2, 4, or 8. Used for leal multiplicands.
(define_predicate "const248_operand"
(match_code "const_int")
@@ -802,7 +808,8 @@
int ok;
/* LEA handles zero-extend by itself. */
- if (GET_CODE (op) == ZERO_EXTEND)
+ if (GET_CODE (op) == ZERO_EXTEND
+ || GET_CODE (op) == AND)
return false;
ok = ix86_decompose_address (op, &parts);