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.md64
1 files changed, 40 insertions, 24 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f2b10afe35b..6c50b75a97f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -248,6 +248,9 @@
;; Is copying of this instruction disallowed?
(define_attr "cannot_copy" "no,yes" (const_string "no"))
+;; Does this insn require indexed or indirect (x-form) memory addressing?
+(define_attr "xform_memory" "no,yes" (const_string "no"))
+
;; Length of the instruction (in bytes).
(define_attr "length" "" (const_int 4))
@@ -5174,8 +5177,11 @@
;; Conversions to and from floating-point.
-; We don't define lfiwax/lfiwzx with the normal definition, because we
-; don't want to support putting SImode in FPR registers.
+;; We don't define lfiwax/lfiwzx with the normal definition. On ISA 2.05/2.06
+;; (power6/power7), SImode is not allowed in FPR registers. On ISA 2.07 and
+;; above, SImode is allowed, but we prefer to have a special definition so that
+;; the register allocator isn't tempted to load the value into a GPR and use
+;; direct move.
(define_insn "lfiwax"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
@@ -5186,7 +5192,8 @@
lxsiwax %x0,%y1
mtvsrwa %x0,%1
vextsw2d %0,%1"
- [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
+ [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
+ (set_attr "xform_memory" "yes")])
; This split must be run before register allocation because it allocates the
; memory slot that is needed to move values to/from the FPR. We don't allocate
@@ -5217,7 +5224,8 @@
tmp = gen_reg_rtx (DImode);
if (MEM_P (src))
{
- src = rs6000_force_indexed_or_indirect_mem (src);
+ if (!TARGET_OPT_XFORM)
+ src = rs6000_force_indexed_or_indirect_mem (src);
emit_insn (gen_lfiwax (tmp, src));
}
else
@@ -5231,7 +5239,8 @@
DONE;
}
[(set_attr "length" "12")
- (set_attr "type" "fpload")])
+ (set_attr "type" "fpload")
+ (set_attr "xform_memory" "yes")])
(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
@@ -5255,7 +5264,8 @@
DONE;
}
[(set_attr "length" "8")
- (set_attr "type" "fpload")])
+ (set_attr "type" "fpload")
+ (set_attr "xform_memory" "yes")])
(define_insn "lfiwzx"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
@@ -5267,7 +5277,8 @@
lxsiwzx %x0,%y1
mtvsrwz %x0,%1
xxextractuw %x0,%x1,4"
- [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
+ [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
+ (set_attr "xform_memory" "yes")])
(define_insn_and_split "floatunssi<mode>2_lfiwzx"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
@@ -5292,7 +5303,8 @@
tmp = gen_reg_rtx (DImode);
if (MEM_P (src))
{
- src = rs6000_force_indexed_or_indirect_mem (src);
+ if (!TARGET_OPT_XFORM)
+ src = rs6000_force_indexed_or_indirect_mem (src);
emit_insn (gen_lfiwzx (tmp, src));
}
else
@@ -5306,7 +5318,8 @@
DONE;
}
[(set_attr "length" "12")
- (set_attr "type" "fpload")])
+ (set_attr "type" "fpload")
+ (set_attr "xform_memory" "yes")])
(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
@@ -5546,7 +5559,8 @@
emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
DONE;
-})
+}
+ [(set_attr "xform_memory" "yes")])
(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
[(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
@@ -5591,7 +5605,8 @@
emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
DONE;
-})
+}
+ [(set_attr "xform_memory" "yes")])
(define_expand "fix_trunc<mode>si2"
[(set (match_operand:SI 0 "gpc_reg_operand")
@@ -5638,7 +5653,8 @@
emit_insn (gen_fctiwz_<mode> (tmp, src));
if (MEM_P (dest))
{
- dest = rs6000_force_indexed_or_indirect_mem (dest);
+ if (!TARGET_OPT_XFORM)
+ dest = rs6000_force_indexed_or_indirect_mem (dest);
emit_insn (gen_stfiwx (dest, tmp));
DONE;
}
@@ -5657,7 +5673,8 @@
}
}
[(set_attr "length" "12")
- (set_attr "type" "fp")])
+ (set_attr "type" "fp")
+ (set_attr "xform_memory" "yes")])
(define_insn_and_split "fix_trunc<mode>si2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
@@ -5750,7 +5767,8 @@
operands[3] = (<QHSI:MODE>mode == SImode
? operands[2]
: gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
-})
+}
+ [(set_attr "xform_memory" "yes")])
(define_expand "fixuns_trunc<mode>si2"
[(set (match_operand:SI 0 "gpc_reg_operand")
@@ -5785,7 +5803,8 @@
emit_insn (gen_fctiwuz_<mode> (tmp, src));
if (MEM_P (dest))
{
- dest = rs6000_force_indexed_or_indirect_mem (dest);
+ if (!TARGET_OPT_XFORM)
+ dest = rs6000_force_indexed_or_indirect_mem (dest);
emit_insn (gen_stfiwx (dest, tmp));
DONE;
}
@@ -5804,7 +5823,8 @@
}
}
[(set_attr "length" "12")
- (set_attr "type" "fp")])
+ (set_attr "type" "fp")
+ (set_attr "xform_memory" "yes")])
(define_insn "fixuns_trunc<mode>di2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
@@ -14248,10 +14268,8 @@
{
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
-
- if (MEM_P (operands[1]))
- operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
-})
+}
+ [(set_attr "xform_memory" "yes")])
(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
@@ -14314,10 +14332,8 @@
{
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
-
- if (MEM_P (operands[1]))
- operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
-})
+}
+ [(set_attr "xform_memory" "yes")])
(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")