mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-21 15:29:54 +08:00
rs6000.md (allocate_stack): Always use an update form instruction to update the stack back chain word...
* config/rs6000/rs6000.md (allocate_stack): Always use an update form instruction to update the stack back chain word, even if the user has disabled the generation of update instructions. (movdi_<mode>_update_stack): New. (movsi_update_stack): Likewise. * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Likewise, always use an update form instruction to update the stack back chain word. From-SVN: r144047
This commit is contained in:
parent
48965b7c6d
commit
d4bacef026
@ -1,3 +1,14 @@
|
||||
2009-02-10 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000.md (allocate_stack): Always use an update
|
||||
form instruction to update the stack back chain word, even if the
|
||||
user has disabled the generation of update instructions.
|
||||
(movdi_<mode>_update_stack): New.
|
||||
(movsi_update_stack): Likewise.
|
||||
* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Likewise,
|
||||
always use an update form instruction to update the stack back
|
||||
chain word.
|
||||
|
||||
2009-02-09 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR middle-end/38953
|
||||
|
@ -15542,6 +15542,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
|
||||
rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
|
||||
rtx tmp_reg = gen_rtx_REG (Pmode, 0);
|
||||
rtx todec = gen_int_mode (-size, Pmode);
|
||||
rtx par, set, mem;
|
||||
|
||||
if (INTVAL (todec) != -size)
|
||||
{
|
||||
@ -15585,54 +15586,39 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
|
||||
warning (0, "stack limit expression is not supported");
|
||||
}
|
||||
|
||||
if (copy_r12 || copy_r11 || ! TARGET_UPDATE)
|
||||
if (copy_r12 || copy_r11)
|
||||
emit_move_insn (copy_r11
|
||||
? gen_rtx_REG (Pmode, 11)
|
||||
: gen_rtx_REG (Pmode, 12),
|
||||
stack_reg);
|
||||
|
||||
if (TARGET_UPDATE)
|
||||
if (size > 32767)
|
||||
{
|
||||
rtx par, set, mem;
|
||||
|
||||
if (size > 32767)
|
||||
{
|
||||
/* Need a note here so that try_split doesn't get confused. */
|
||||
if (get_last_insn () == NULL_RTX)
|
||||
emit_note (NOTE_INSN_DELETED);
|
||||
insn = emit_move_insn (tmp_reg, todec);
|
||||
try_split (PATTERN (insn), insn, 0);
|
||||
todec = tmp_reg;
|
||||
}
|
||||
|
||||
insn = emit_insn (TARGET_32BIT
|
||||
? gen_movsi_update (stack_reg, stack_reg,
|
||||
todec, stack_reg)
|
||||
: gen_movdi_di_update (stack_reg, stack_reg,
|
||||
todec, stack_reg));
|
||||
/* Since we didn't use gen_frame_mem to generate the MEM, grab
|
||||
it now and set the alias set/attributes. The above gen_*_update
|
||||
calls will generate a PARALLEL with the MEM set being the first
|
||||
operation. */
|
||||
par = PATTERN (insn);
|
||||
gcc_assert (GET_CODE (par) == PARALLEL);
|
||||
set = XVECEXP (par, 0, 0);
|
||||
gcc_assert (GET_CODE (set) == SET);
|
||||
mem = SET_DEST (set);
|
||||
gcc_assert (MEM_P (mem));
|
||||
MEM_NOTRAP_P (mem) = 1;
|
||||
set_mem_alias_set (mem, get_frame_alias_set ());
|
||||
}
|
||||
else
|
||||
{
|
||||
insn = emit_insn (TARGET_32BIT
|
||||
? gen_addsi3 (stack_reg, stack_reg, todec)
|
||||
: gen_adddi3 (stack_reg, stack_reg, todec));
|
||||
emit_move_insn (gen_frame_mem (Pmode, stack_reg),
|
||||
copy_r11
|
||||
? gen_rtx_REG (Pmode, 11)
|
||||
: gen_rtx_REG (Pmode, 12));
|
||||
/* Need a note here so that try_split doesn't get confused. */
|
||||
if (get_last_insn () == NULL_RTX)
|
||||
emit_note (NOTE_INSN_DELETED);
|
||||
insn = emit_move_insn (tmp_reg, todec);
|
||||
try_split (PATTERN (insn), insn, 0);
|
||||
todec = tmp_reg;
|
||||
}
|
||||
|
||||
insn = emit_insn (TARGET_32BIT
|
||||
? gen_movsi_update_stack (stack_reg, stack_reg,
|
||||
todec, stack_reg)
|
||||
: gen_movdi_di_update_stack (stack_reg, stack_reg,
|
||||
todec, stack_reg));
|
||||
/* Since we didn't use gen_frame_mem to generate the MEM, grab
|
||||
it now and set the alias set/attributes. The above gen_*_update
|
||||
calls will generate a PARALLEL with the MEM set being the first
|
||||
operation. */
|
||||
par = PATTERN (insn);
|
||||
gcc_assert (GET_CODE (par) == PARALLEL);
|
||||
set = XVECEXP (par, 0, 0);
|
||||
gcc_assert (GET_CODE (set) == SET);
|
||||
mem = SET_DEST (set);
|
||||
gcc_assert (MEM_P (mem));
|
||||
MEM_NOTRAP_P (mem) = 1;
|
||||
set_mem_alias_set (mem, get_frame_alias_set ());
|
||||
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
REG_NOTES (insn) =
|
||||
|
@ -10079,6 +10079,20 @@
|
||||
stdu %3,%2(%0)"
|
||||
[(set_attr "type" "store_ux,store_u")])
|
||||
|
||||
;; This pattern is only conditional on TARGET_POWERPC64, as it is
|
||||
;; needed for stack allocation, even if the user passes -mno-update.
|
||||
(define_insn "movdi_<mode>_update_stack"
|
||||
[(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
|
||||
(match_operand:DI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:P 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:P (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_POWERPC64"
|
||||
"@
|
||||
stdux %3,%0,%2
|
||||
stdu %3,%2(%0)"
|
||||
[(set_attr "type" "store_ux,store_u")])
|
||||
|
||||
(define_insn "*movsi_update1"
|
||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
@ -10121,6 +10135,20 @@
|
||||
{stu|stwu} %3,%2(%0)"
|
||||
[(set_attr "type" "store_ux,store_u")])
|
||||
|
||||
;; This is an unconditional pattern; needed for stack allocation, even
|
||||
;; if the user passes -mno-update.
|
||||
(define_insn "movsi_update_stack"
|
||||
[(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"@
|
||||
{stux|stwux} %3,%0,%2
|
||||
{stu|stwu} %3,%2(%0)"
|
||||
[(set_attr "type" "store_ux,store_u")])
|
||||
|
||||
(define_insn "*movhi_update1"
|
||||
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
@ -10543,6 +10571,7 @@
|
||||
{ rtx chain = gen_reg_rtx (Pmode);
|
||||
rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
|
||||
rtx neg_op0;
|
||||
rtx insn, par, set, mem;
|
||||
|
||||
emit_move_insn (chain, stack_bot);
|
||||
|
||||
@ -10569,34 +10598,22 @@
|
||||
else
|
||||
neg_op0 = GEN_INT (- INTVAL (operands[1]));
|
||||
|
||||
if (TARGET_UPDATE)
|
||||
{
|
||||
rtx insn, par, set, mem;
|
||||
|
||||
insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update
|
||||
: gen_movdi_di_update))
|
||||
insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update
|
||||
: gen_movdi_di_update))
|
||||
(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
|
||||
chain));
|
||||
/* Since we didn't use gen_frame_mem to generate the MEM, grab
|
||||
it now and set the alias set/attributes. The above gen_*_update
|
||||
calls will generate a PARALLEL with the MEM set being the first
|
||||
operation. */
|
||||
par = PATTERN (insn);
|
||||
gcc_assert (GET_CODE (par) == PARALLEL);
|
||||
set = XVECEXP (par, 0, 0);
|
||||
gcc_assert (GET_CODE (set) == SET);
|
||||
mem = SET_DEST (set);
|
||||
gcc_assert (MEM_P (mem));
|
||||
MEM_NOTRAP_P (mem) = 1;
|
||||
set_mem_alias_set (mem, get_frame_alias_set ());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
|
||||
(stack_pointer_rtx, stack_pointer_rtx, neg_op0));
|
||||
emit_move_insn (gen_frame_mem (Pmode, stack_pointer_rtx), chain);
|
||||
}
|
||||
/* Since we didn't use gen_frame_mem to generate the MEM, grab
|
||||
it now and set the alias set/attributes. The above gen_*_update
|
||||
calls will generate a PARALLEL with the MEM set being the first
|
||||
operation. */
|
||||
par = PATTERN (insn);
|
||||
gcc_assert (GET_CODE (par) == PARALLEL);
|
||||
set = XVECEXP (par, 0, 0);
|
||||
gcc_assert (GET_CODE (set) == SET);
|
||||
mem = SET_DEST (set);
|
||||
gcc_assert (MEM_P (mem));
|
||||
MEM_NOTRAP_P (mem) = 1;
|
||||
set_mem_alias_set (mem, get_frame_alias_set ());
|
||||
|
||||
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
||||
DONE;
|
||||
|
Loading…
Reference in New Issue
Block a user