diff options
author | Ben Elliston <bje@au.ibm.com> | 2009-02-10 00:13:34 +0000 |
---|---|---|
committer | Ben Elliston <bje@gcc.gnu.org> | 2009-02-10 11:13:34 +1100 |
commit | d4bacef026e45bc64c791696a85d61d164b6f145 (patch) | |
tree | c6f7e1f3fb1d6f6224050f23778321aa235e49ab | |
parent | 48965b7c6d095bd06be35733d84dba0e016e206d (diff) | |
download | gcc-d4bacef026e45bc64c791696a85d61d164b6f145.zip gcc-d4bacef026e45bc64c791696a85d61d164b6f145.tar.gz gcc-d4bacef026e45bc64c791696a85d61d164b6f145.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 68 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 69 |
3 files changed, 81 insertions, 67 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 898448a..47e8199 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d2ebf62..966a0f7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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) - { - 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 + if (size > 32767) { - 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) = diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index b6f4181..ffbc8ad 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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; |