aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md146
1 files changed, 101 insertions, 45 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a5a6ec17b26..5290e2b68c1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1,6 +1,6 @@
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
;; Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -10055,7 +10055,9 @@
(match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && TARGET_UPDATE"
+ "TARGET_POWERPC64 && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (DImode)
+ || !gpc_reg_operand (operands[2], DImode))"
"@
ldux %3,%0,%2
ldu %3,%2(%0)"
@@ -10067,7 +10069,25 @@
(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 && TARGET_UPDATE"
+ "TARGET_POWERPC64 && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (Pmode)
+ || !gpc_reg_operand (operands[2], Pmode)
+ || (REG_P (operands[0])
+ && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
+ "@
+ stdux %3,%0,%2
+ 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)"
@@ -10079,7 +10099,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
@@ -10092,7 +10114,8 @@
(match_operand:DI 2 "gpc_reg_operand" "r")))))
(set (match_operand:DI 0 "gpc_reg_operand" "=b")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && rs6000_gen_cell_microcode"
+ "TARGET_POWERPC64 && rs6000_gen_cell_microcode
+ && !avoiding_indexed_address_p (DImode)"
"lwaux %3,%0,%2"
[(set_attr "type" "load_ext_ux")])
@@ -10102,7 +10125,25 @@
(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)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode)
+ || (REG_P (operands[0])
+ && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
+ "@
+ {stux|stwux} %3,%0,%2
+ {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)"
@@ -10114,7 +10155,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
@@ -10127,7 +10170,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
@@ -10140,7 +10185,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE && rs6000_gen_cell_microcode"
+ "TARGET_UPDATE && rs6000_gen_cell_microcode
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lhaux %3,%0,%2
lhau %3,%2(%0)"
@@ -10152,7 +10199,9 @@
(match_operand:HI 3 "gpc_reg_operand" "r,r"))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
sthux %3,%0,%2
sthu %3,%2(%0)"
@@ -10164,7 +10213,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
@@ -10177,7 +10228,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
@@ -10189,7 +10242,9 @@
(match_operand:QI 3 "gpc_reg_operand" "r,r"))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_UPDATE"
+ "TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
stbux %3,%0,%2
stbu %3,%2(%0)"
@@ -10201,7 +10256,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lfsux %3,%0,%2
lfsu %3,%2(%0)"
@@ -10213,7 +10270,9 @@
(match_operand:SF 3 "gpc_reg_operand" "f,f"))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
stfsux %3,%0,%2
stfsu %3,%2(%0)"
@@ -10225,7 +10284,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
+ "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
@@ -10237,7 +10298,9 @@
(match_operand:SF 3 "gpc_reg_operand" "r,r"))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
+ "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
@@ -10249,7 +10312,9 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
lfdux %3,%0,%2
lfdu %3,%2(%0)"
@@ -10261,7 +10326,9 @@
(match_operand:DF 3 "gpc_reg_operand" "f,f"))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
+ && (!avoiding_indexed_address_p (SImode)
+ || !gpc_reg_operand (operands[2], SImode))"
"@
stfdux %3,%0,%2
stfdu %3,%2(%0)"
@@ -10504,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);
@@ -10530,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_stack
+ : gen_movdi_di_update_stack))
(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;