diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2011-08-09 09:38:02 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2011-08-09 09:38:02 +0200 |
commit | 3968b0504cfc12e1b1f7d6eb385f4d7427a1b32b (patch) | |
tree | 33c06d4aae57b46692c60158762e4baab5567af5 /gcc/config | |
parent | 2292df601d58ad005a47652004c8b76dafd3f00f (diff) | |
download | gcc-3968b0504cfc12e1b1f7d6eb385f4d7427a1b32b.zip gcc-3968b0504cfc12e1b1f7d6eb385f4d7427a1b32b.tar.gz gcc-3968b0504cfc12e1b1f7d6eb385f4d7427a1b32b.tar.bz2 |
re PR target/49781 ([x32] Unnecessary lea in x32 mode)
PR target/49781
* config/i386/i386.md (reload_noff_load): New.
(reload_noff_store): Ditto.
* config/i386/i386.c (ix86_secondary_reload): Use
CODE_FOR_reload_noff_load and CODE_FOR_reload_noff_store to handle
double-word moves from/to non-offsetable addresses instead of
generating XMM temporary.
From-SVN: r177583
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.c | 15 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 34 |
2 files changed, 45 insertions, 4 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9a21e6b..6810356 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -28247,17 +28247,24 @@ ix86_preferred_output_reload_class (rtx x, reg_class_t regclass) static reg_class_t ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass, - enum machine_mode mode, - secondary_reload_info *sri ATTRIBUTE_UNUSED) + enum machine_mode mode, secondary_reload_info *sri) { /* Double-word spills from general registers to non-offsettable memory - references (zero-extended addresses) go through XMM register. */ + references (zero-extended addresses) require special handling. */ if (TARGET_64BIT && MEM_P (x) && GET_MODE_SIZE (mode) > UNITS_PER_WORD && rclass == GENERAL_REGS && !offsettable_memref_p (x)) - return SSE_REGS; + { + sri->icode = (in_p + ? CODE_FOR_reload_noff_load + : CODE_FOR_reload_noff_store); + /* Add the cost of move to a temporary. */ + sri->extra_cost = 1; + + return NO_REGS; + } /* QImode spills from non-QI registers require intermediate register on 32bit targets. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ee93e71..9dc5c85 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2073,6 +2073,40 @@ (const_string "orig"))) (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")]) +;; Reload patterns to support multi-word load/store +;; with non-offsetable address. +(define_expand "reload_noff_store" + [(parallel [(match_operand 0 "memory_operand" "=m") + (match_operand 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "=&r")])] + "TARGET_64BIT" +{ + rtx mem = operands[0]; + rtx addr = XEXP (mem, 0); + + emit_move_insn (operands[2], addr); + mem = replace_equiv_address_nv (mem, operands[2]); + + emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1])); + DONE; +}) + +(define_expand "reload_noff_load" + [(parallel [(match_operand 0 "register_operand" "=r") + (match_operand 1 "memory_operand" "m") + (match_operand:DI 2 "register_operand" "=r")])] + "TARGET_64BIT" +{ + rtx mem = operands[1]; + rtx addr = XEXP (mem, 0); + + emit_move_insn (operands[2], addr); + mem = replace_equiv_address_nv (mem, operands[2]); + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem)); + DONE; +}) + ;; Convert impossible stores of immediate to existing instructions. ;; First try to get scratch register and go through it. In case this ;; fails, move by 32bit parts. |