Commit cc845923 by H.J. Lu Committed by H.J. Lu

Use word_mode to push/pop register for x86

2012-03-08  H.J. Lu  <hongjiu.lu@intel.com>

	* config/i386/i386.c (setup_incoming_varargs_64): Use word_mode
	with integer parameters in registers.
	(gen_push): Push register in word_mode instead of Pmode.
	(ix86_emit_save_regs): Likewise.
	(ix86_emit_save_regs_using_mov): Save integer registers in
	word_mode.
	(gen_pop): Pop register in word_mode instead of Pmode.
	(ix86_emit_restore_regs_using_pop): Likewise.
	(ix86_expand_prologue): Replace Pmode with word_mode for push
	immediate.  Use ix86_gen_pro_epilogue_adjust_stack.  Save and
	restore RAX and R10 in word_mode.
	(ix86_emit_restore_regs_using_mov): Restore integer registers
	in word_mode.
	(ix86_expand_split_stack_prologue): Save R10_REG and restore in
	word_mode.
	(ix86_split_to_parts): Use word_mode with PUT_MODE for push.
	(ix86_split_long_move): Likewise.

	* config/i386/i386.md (W): New.
	(*push<mode>2_prologue): Replace :P with :W.
	(*pop<mode>1): Likewise.
	(*pop<mode>1_epilogue): Likewise.
	(push/pop peephole2): Use word_mode scratch registers.

From-SVN: r185123
parent 78d16236
2012-03-08 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (setup_incoming_varargs_64): Use word_mode
with integer parameters in registers.
(gen_push): Push register in word_mode instead of Pmode.
(ix86_emit_save_regs): Likewise.
(ix86_emit_save_regs_using_mov): Save integer registers in
word_mode.
(gen_pop): Pop register in word_mode instead of Pmode.
(ix86_emit_restore_regs_using_pop): Likewise.
(ix86_expand_prologue): Replace Pmode with word_mode for push
immediate. Use ix86_gen_pro_epilogue_adjust_stack. Save and
restore RAX and R10 in word_mode.
(ix86_emit_restore_regs_using_mov): Restore integer registers
in word_mode.
(ix86_expand_split_stack_prologue): Save R10_REG and restore in
word_mode.
(ix86_split_to_parts): Use word_mode with PUT_MODE for push.
(ix86_split_long_move): Likewise.
* config/i386/i386.md (W): New.
(*push<mode>2_prologue): Replace :P with :W.
(*pop<mode>1): Likewise.
(*pop<mode>1_epilogue): Likewise.
(push/pop peephole2): Use word_mode scratch registers.
2012-03-08 Uros Bizjak <ubizjak@gmail.com> 2012-03-08 Uros Bizjak <ubizjak@gmail.com>
* config/i386/predicates.md (indirect_branch_operand): Simplify. * config/i386/predicates.md (indirect_branch_operand): Simplify.
......
...@@ -7601,11 +7601,12 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) ...@@ -7601,11 +7601,12 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
for (i = cum->regno; i < max; i++) for (i = cum->regno; i < max; i++)
{ {
mem = gen_rtx_MEM (Pmode, mem = gen_rtx_MEM (word_mode,
plus_constant (save_area, i * UNITS_PER_WORD)); plus_constant (save_area, i * UNITS_PER_WORD));
MEM_NOTRAP_P (mem) = 1; MEM_NOTRAP_P (mem) = 1;
set_mem_alias_set (mem, set); set_mem_alias_set (mem, set);
emit_move_insn (mem, gen_rtx_REG (Pmode, emit_move_insn (mem,
gen_rtx_REG (word_mode,
x86_64_int_parameter_registers[i])); x86_64_int_parameter_registers[i]));
} }
...@@ -8661,8 +8662,11 @@ gen_push (rtx arg) ...@@ -8661,8 +8662,11 @@ gen_push (rtx arg)
m->fs.cfa_offset += UNITS_PER_WORD; m->fs.cfa_offset += UNITS_PER_WORD;
m->fs.sp_offset += UNITS_PER_WORD; m->fs.sp_offset += UNITS_PER_WORD;
if (REG_P (arg) && GET_MODE (arg) != word_mode)
arg = gen_rtx_REG (word_mode, REGNO (arg));
return gen_rtx_SET (VOIDmode, return gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode, gen_rtx_MEM (word_mode,
gen_rtx_PRE_DEC (Pmode, gen_rtx_PRE_DEC (Pmode,
stack_pointer_rtx)), stack_pointer_rtx)),
arg); arg);
...@@ -8673,9 +8677,12 @@ gen_push (rtx arg) ...@@ -8673,9 +8677,12 @@ gen_push (rtx arg)
static rtx static rtx
gen_pop (rtx arg) gen_pop (rtx arg)
{ {
if (REG_P (arg) && GET_MODE (arg) != word_mode)
arg = gen_rtx_REG (word_mode, REGNO (arg));
return gen_rtx_SET (VOIDmode, return gen_rtx_SET (VOIDmode,
arg, arg,
gen_rtx_MEM (Pmode, gen_rtx_MEM (word_mode,
gen_rtx_POST_INC (Pmode, gen_rtx_POST_INC (Pmode,
stack_pointer_rtx))); stack_pointer_rtx)));
} }
...@@ -9142,7 +9149,7 @@ ix86_emit_save_regs (void) ...@@ -9142,7 +9149,7 @@ ix86_emit_save_regs (void)
for (regno = FIRST_PSEUDO_REGISTER - 1; regno-- > 0; ) for (regno = FIRST_PSEUDO_REGISTER - 1; regno-- > 0; )
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true)) if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
{ {
insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno))); insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
} }
...@@ -9222,7 +9229,7 @@ ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset) ...@@ -9222,7 +9229,7 @@ ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true)) if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
{ {
ix86_emit_save_reg_using_mov (Pmode, regno, cfa_offset); ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
cfa_offset -= UNITS_PER_WORD; cfa_offset -= UNITS_PER_WORD;
} }
} }
...@@ -10159,7 +10166,7 @@ ix86_expand_prologue (void) ...@@ -10159,7 +10166,7 @@ ix86_expand_prologue (void)
to implement macro RETURN_ADDR_RTX and intrinsic function to implement macro RETURN_ADDR_RTX and intrinsic function
expand_builtin_return_addr etc. */ expand_builtin_return_addr etc. */
t = plus_constant (crtl->drap_reg, -UNITS_PER_WORD); t = plus_constant (crtl->drap_reg, -UNITS_PER_WORD);
t = gen_frame_mem (Pmode, t); t = gen_frame_mem (word_mode, t);
insn = emit_insn (gen_push (t)); insn = emit_insn (gen_push (t));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
...@@ -10356,14 +10363,18 @@ ix86_expand_prologue (void) ...@@ -10356,14 +10363,18 @@ ix86_expand_prologue (void)
if (r10_live && eax_live) if (r10_live && eax_live)
{ {
t = choose_baseaddr (m->fs.sp_offset - allocate); t = choose_baseaddr (m->fs.sp_offset - allocate);
emit_move_insn (r10, gen_frame_mem (Pmode, t)); emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
gen_frame_mem (word_mode, t));
t = choose_baseaddr (m->fs.sp_offset - allocate - UNITS_PER_WORD); t = choose_baseaddr (m->fs.sp_offset - allocate - UNITS_PER_WORD);
emit_move_insn (eax, gen_frame_mem (Pmode, t)); emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
gen_frame_mem (word_mode, t));
} }
else if (eax_live || r10_live) else if (eax_live || r10_live)
{ {
t = choose_baseaddr (m->fs.sp_offset - allocate); t = choose_baseaddr (m->fs.sp_offset - allocate);
emit_move_insn ((eax_live ? eax : r10), gen_frame_mem (Pmode, t)); emit_move_insn (gen_rtx_REG (word_mode,
(eax_live ? AX_REG : R10_REG)),
gen_frame_mem (word_mode, t));
} }
} }
gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset); gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
...@@ -10533,7 +10544,7 @@ ix86_emit_restore_regs_using_pop (void) ...@@ -10533,7 +10544,7 @@ ix86_emit_restore_regs_using_pop (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false)) if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false))
ix86_emit_restore_reg_using_pop (gen_rtx_REG (Pmode, regno)); ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno));
} }
/* Emit code and notes for the LEAVE instruction. */ /* Emit code and notes for the LEAVE instruction. */
...@@ -10576,11 +10587,11 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset, ...@@ -10576,11 +10587,11 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return)) if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
{ {
rtx reg = gen_rtx_REG (Pmode, regno); rtx reg = gen_rtx_REG (word_mode, regno);
rtx insn, mem; rtx insn, mem;
mem = choose_baseaddr (cfa_offset); mem = choose_baseaddr (cfa_offset);
mem = gen_frame_mem (Pmode, mem); mem = gen_frame_mem (word_mode, mem);
insn = emit_move_insn (reg, mem); insn = emit_move_insn (reg, mem);
if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg)) if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
...@@ -11185,8 +11196,8 @@ ix86_expand_split_stack_prologue (void) ...@@ -11185,8 +11196,8 @@ ix86_expand_split_stack_prologue (void)
{ {
rtx rax; rtx rax;
rax = gen_rtx_REG (Pmode, AX_REG); rax = gen_rtx_REG (word_mode, AX_REG);
emit_move_insn (rax, reg10); emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
use_reg (&call_fusage, rax); use_reg (&call_fusage, rax);
} }
...@@ -11265,8 +11276,8 @@ ix86_expand_split_stack_prologue (void) ...@@ -11265,8 +11276,8 @@ ix86_expand_split_stack_prologue (void)
/* If we are in 64-bit mode and this function uses a static chain, /* If we are in 64-bit mode and this function uses a static chain,
we saved %r10 in %rax before calling _morestack. */ we saved %r10 in %rax before calling _morestack. */
if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl)) if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
emit_move_insn (gen_rtx_REG (Pmode, R10_REG), emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
gen_rtx_REG (Pmode, AX_REG)); gen_rtx_REG (word_mode, AX_REG));
/* If this function calls va_start, we need to store a pointer to /* If this function calls va_start, we need to store a pointer to
the arguments on the old stack, because they may not have been the arguments on the old stack, because they may not have been
...@@ -20275,7 +20286,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) ...@@ -20275,7 +20286,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
gcc_assert (ok); gcc_assert (ok);
operand = copy_rtx (operand); operand = copy_rtx (operand);
PUT_MODE (operand, Pmode); PUT_MODE (operand, word_mode);
parts[0] = parts[1] = parts[2] = parts[3] = operand; parts[0] = parts[1] = parts[2] = parts[3] = operand;
return size; return size;
} }
...@@ -20428,7 +20439,7 @@ ix86_split_long_move (rtx operands[]) ...@@ -20428,7 +20439,7 @@ ix86_split_long_move (rtx operands[])
if (push_operand (operands[0], VOIDmode)) if (push_operand (operands[0], VOIDmode))
{ {
operands[0] = copy_rtx (operands[0]); operands[0] = copy_rtx (operands[0]);
PUT_MODE (operands[0], Pmode); PUT_MODE (operands[0], word_mode);
} }
else else
operands[0] = gen_lowpart (DImode, operands[0]); operands[0] = gen_lowpart (DImode, operands[0]);
...@@ -894,6 +894,11 @@ ...@@ -894,6 +894,11 @@
;; pointer-sized quantities. Exactly one of the two alternatives will match. ;; pointer-sized quantities. Exactly one of the two alternatives will match.
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
;; This mode iterator allows :W to be used for patterns that operate on
;; word_mode sized quantities.
(define_mode_iterator W
[(SI "word_mode == SImode") (DI "word_mode == DImode")])
;; This mode iterator allows :PTR to be used for patterns that operate on ;; This mode iterator allows :PTR to be used for patterns that operate on
;; ptr_mode sized quantities. ;; ptr_mode sized quantities.
(define_mode_iterator PTR (define_mode_iterator PTR
...@@ -1702,8 +1707,8 @@ ...@@ -1702,8 +1707,8 @@
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "*push<mode>2_prologue" (define_insn "*push<mode>2_prologue"
[(set (match_operand:P 0 "push_operand" "=<") [(set (match_operand:W 0 "push_operand" "=<")
(match_operand:P 1 "general_no_elim_operand" "r<i>*m")) (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
(clobber (mem:BLK (scratch)))] (clobber (mem:BLK (scratch)))]
"" ""
"push{<imodesuffix>}\t%1" "push{<imodesuffix>}\t%1"
...@@ -1711,16 +1716,16 @@ ...@@ -1711,16 +1716,16 @@
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*pop<mode>1" (define_insn "*pop<mode>1"
[(set (match_operand:P 0 "nonimmediate_operand" "=r*m") [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
(match_operand:P 1 "pop_operand" ">"))] (match_operand:W 1 "pop_operand" ">"))]
"" ""
"pop{<imodesuffix>}\t%0" "pop{<imodesuffix>}\t%0"
[(set_attr "type" "pop") [(set_attr "type" "pop")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*pop<mode>1_epilogue" (define_insn "*pop<mode>1_epilogue"
[(set (match_operand:P 0 "nonimmediate_operand" "=r*m") [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
(match_operand:P 1 "pop_operand" ">")) (match_operand:W 1 "pop_operand" ">"))
(clobber (mem:BLK (scratch)))] (clobber (mem:BLK (scratch)))]
"" ""
"pop{<imodesuffix>}\t%0" "pop{<imodesuffix>}\t%0"
...@@ -17334,131 +17339,131 @@ ...@@ -17334,131 +17339,131 @@
;; alternative when no register is available later. ;; alternative when no register is available later.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
[(clobber (match_dup 1)) [(clobber (match_dup 1))
(parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])]) (clobber (mem:BLK (scratch)))])])
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
[(clobber (match_dup 1)) [(clobber (match_dup 1))
(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])]) (clobber (mem:BLK (scratch)))])])
;; Convert esp subtractions to push. ;; Convert esp subtractions to push.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
[(clobber (match_dup 1)) [(clobber (match_dup 1))
(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
[(clobber (match_dup 1)) [(clobber (match_dup 1))
(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
;; Convert epilogue deallocator to pop. ;; Convert epilogue deallocator to pop.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
[(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])]) (clobber (mem:BLK (scratch)))])])
;; Two pops case is tricky, since pop causes dependency ;; Two pops case is tricky, since pop causes dependency
;; on destination register. We use two registers if available. ;; on destination register. We use two registers if available.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(match_scratch:P 2 "r") (match_scratch:W 2 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
&& INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
[(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))]) (clobber (mem:BLK (scratch)))])
(set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"optimize_insn_for_size_p () "optimize_insn_for_size_p ()
&& INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
[(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))]) (clobber (mem:BLK (scratch)))])
(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
;; Convert esp additions to pop. ;; Convert esp additions to pop.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)" "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
[(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
;; Two pops case is tricky, since pop causes dependency ;; Two pops case is tricky, since pop causes dependency
;; on destination register. We use two registers if available. ;; on destination register. We use two registers if available.
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(match_scratch:P 2 "r") (match_scratch:W 2 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
[(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
(set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))]) (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
(define_peephole2 (define_peephole2
[(match_scratch:P 1 "r") [(match_scratch:W 1 "r")
(parallel [(set (reg:P SP_REG) (parallel [(set (reg:P SP_REG)
(plus:P (reg:P SP_REG) (plus:P (reg:P SP_REG)
(match_operand:P 0 "const_int_operand" ""))) (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"optimize_insn_for_size_p () "optimize_insn_for_size_p ()
&& INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)" && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
[(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG)))) [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))]) (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
;; Convert compares with 1 to shorter inc/dec operations when CF is not ;; Convert compares with 1 to shorter inc/dec operations when CF is not
;; required and register dies. Similarly for 128 to -128. ;; required and register dies. Similarly for 128 to -128.
...@@ -17569,7 +17574,7 @@ ...@@ -17569,7 +17574,7 @@
;; leal (%edx,%eax,4), %eax ;; leal (%edx,%eax,4), %eax
(define_peephole2 (define_peephole2
[(match_scratch:P 5 "r") [(match_scratch:W 5 "r")
(parallel [(set (match_operand 0 "register_operand" "") (parallel [(set (match_operand 0 "register_operand" "")
(ashift (match_operand 1 "register_operand" "") (ashift (match_operand 1 "register_operand" "")
(match_operand 2 "const_int_operand" ""))) (match_operand 2 "const_int_operand" "")))
...@@ -17595,16 +17600,16 @@ ...@@ -17595,16 +17600,16 @@
enum machine_mode op1mode = GET_MODE (operands[1]); enum machine_mode op1mode = GET_MODE (operands[1]);
enum machine_mode mode = op1mode == DImode ? DImode : SImode; enum machine_mode mode = op1mode == DImode ? DImode : SImode;
int scale = 1 << INTVAL (operands[2]); int scale = 1 << INTVAL (operands[2]);
rtx index = gen_lowpart (Pmode, operands[1]); rtx index = gen_lowpart (word_mode, operands[1]);
rtx base = gen_lowpart (Pmode, operands[5]); rtx base = gen_lowpart (word_mode, operands[5]);
rtx dest = gen_lowpart (mode, operands[3]); rtx dest = gen_lowpart (mode, operands[3]);
operands[1] = gen_rtx_PLUS (Pmode, base, operands[1] = gen_rtx_PLUS (word_mode, base,
gen_rtx_MULT (Pmode, index, GEN_INT (scale))); gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
operands[5] = base; operands[5] = base;
if (mode != Pmode) if (mode != word_mode)
operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
if (op1mode != Pmode) if (op1mode != word_mode)
operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0); operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
operands[0] = dest; operands[0] = dest;
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment