aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2016-10-27 20:52:07 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2016-10-27 20:52:07 +0000
commit787c7a65f6ec2876337e6c50a26a1da0fadcb5bf (patch)
tree6fef9d9f4d0a61bd0a82f599ed70624bc18e9835 /gcc/config/rs6000/rs6000.md
parent6f21288f8c3579ec7ae47615e76ba1e6ad25551f (diff)
downloadgcc-787c7a65f6ec2876337e6c50a26a1da0fadcb5bf.zip
gcc-787c7a65f6ec2876337e6c50a26a1da0fadcb5bf.tar.gz
gcc-787c7a65f6ec2876337e6c50a26a1da0fadcb5bf.tar.bz2
constraints.md (wH constraint): Add new constraints for allowing 32-bit integers (and eventually 8/16-bit...
[gcc] 2016-10-27 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/constraints.md (wH constraint): Add new constraints for allowing 32-bit integers (and eventually 8/16-bit integers) into the vector registers. (wI constraint): Likewise. (wJ constraint): Likewise. (wK constraint): Likewise. * config/rs6000/rs6000-cpus.def (ISA_2_7_MASKS_SERVER): Add -mvsx-small-integer as a default option for ISA 2.07 (i.e. power8). (POWERPC_MASKS): Likewise. * config/rs6000/rs6000.opt (-mvsx-small-integer): Add new debug switch to turn off small integer support in vector registers. * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Eliminate test for -mupper-regs-di, since it is already done with the reg_add[mode].scalar_in_vsx_p. Add support for the switch -mvsx-small-integer. (rs6000_debug_reg_global): Add support for wH, wI, wJ, and wK constraints. (rs6000_setup_reg_addr_masks): Likewise. (rs6000_init_hard_regno_mode_ok): Likewise. (rs6000_option_override_internal): Add consistency checks for -mvsx-small-integer. (rs6000_secondary_reload_simple_move): SImode is a simple move if -mvsx-small-integer. (rs6000_secondary_reload): Use std::swap. (rs6000_preferred_reload_class): Don't prefer FLOAT_REGS over VSX_REGS for small integers in vector registers, since there is no D-FORM address mode for such types. (rs6000_register_move_cost): Use FIRST_FPR_REGNO instead of 32. (rs6000_opt_masks): Add -mvsx-small-integer. * config/rs6000/vsx.md (VSINT_84): Add SImode for small integer support. (VSX_EXTRACT_I2): Clone VSX_EXTRACT_I, but drop V4SI since SImode extracts can be done on ISA 2.07. (vsx_extract_<mode>): Add support for small integers in vsx registers. (vsx_extract_<mode>_p9): Use 'v' instead of VSX_EX, since we no longer support V4SImode in this pattern. (vsx_extract_si): New insn to support extraction of SImode in ISA 2.07 using either xxextractuw or vspltw. (vsx_extract_<mode>_p8): Use 'v' instead of VSX_EX, since we no longer support V4SImode in this pattern. * config/rs6000/rs6000.h (enum rs6000_reg_class_enum): Add wH, wI, wJ, and wK constraints. * config/rs6000/rs6000.md (f32_sv): Use correct instruction for storing SDmode with VSX instructions. (zero_extendsi<mode>2): Reorder pattern, so RLDICL comes after the GPR load and before the FPR and VSX loads. Remove ??, ! from the constraints. Add MFVSRWZ and XXEXTRACTUW instructions to support small integers in vector registers. (extendsi<mode>2): Reorder pattern, so EXTSW comes after the GPR load and before the FPR and VSX loads. Remove ??, ! from the constraints. Add VEXTSW2D support for small integers in vector registers. (lfiwax): Remove ! constraint. Add VEXTSW2D support for small integers in vector registers. (floatsi<mode>2_lfiwax): If -mvsx-small-integer issue a normal move instead of using an UNSPEC. (lfiwzx): Remove ! constraint. Add XXEXTRACTUW support for small integers in vector registers. (floatunssi<mode>2_lfiwzx): If -mvsx-small-integer issue a normal move instead of using an UNSPEC. (movsi_internal1): Add support for -mvsx-small-integer. Align columns so that it is more readable. (SImode splitter for ISA 3.0 constants): Add splitter for -128..127 constants that can easily be constructed on ISA 3.0. * doc/md.texi (PowerPC Constraints): Document wH, wI, wJ, and wK constraints. [gcc/testsuite] 2016-10-27 Michael Meissner <meissner@linux.vnet.ibm.com> * gcc.target/powerpc/vsx-simode.c: New test. * gcc.target/powerpc/vsx-simode2.c: Likewise. * gcc.target/powerpc/vsx-simode3.c: Likewise. From-SVN: r241631
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md119
1 files changed, 94 insertions, 25 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index e432a5a..bc8e52d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -458,7 +458,7 @@
(define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
(define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
-(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
+(define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwx %x1,%y0")])
; Definitions for 32-bit fpr direct move
; At present, the decimal modes are not allowed in the traditional altivec
@@ -837,16 +837,18 @@
(define_insn "zero_extendsi<mode>2"
- [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
- (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
+ [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
+ (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
""
"@
lwz%U1%X1 %0,%1
rldicl %0,%1,0,32
- mtvsrwz %x0,%1
lfiwzx %0,%y1
- lxsiwzx %x0,%y1"
- [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
+ lxsiwzx %x0,%y1
+ mtvsrwz %x0,%1
+ mfvsrwz %0,%x1
+ xxextractuw %x0,%x1,1"
+ [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
(define_insn_and_split "*zero_extendsi<mode>2_dot"
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
@@ -1005,16 +1007,17 @@
(define_insn "extendsi<mode>2"
- [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
- (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
+ [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
+ (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
""
"@
lwa%U1%X1 %0,%1
extsw %0,%1
- mtvsrwa %x0,%1
lfiwax %0,%y1
- lxsiwax %x0,%y1"
- [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
+ lxsiwax %x0,%y1
+ mtvsrwa %x0,%1
+ vextsw2d %0,%1"
+ [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
(set_attr "sign_extend" "yes")])
(define_insn_and_split "*extendsi<mode>2_dot"
@@ -4947,15 +4950,16 @@
; We don't define lfiwax/lfiwzx with the normal definition, because we
; don't want to support putting SImode in FPR registers.
(define_insn "lfiwax"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
- (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
+ [(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")]
UNSPEC_LFIWAX))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
"@
lfiwax %0,%y1
lxsiwax %x0,%y1
- mtvsrwa %x0,%1"
- [(set_attr "type" "fpload,fpload,mffgpr")])
+ mtvsrwa %x0,%1
+ vextsw2d %0,%1"
+ [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
; 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
@@ -5019,7 +5023,10 @@
operands[1] = rs6000_address_for_fpconvert (operands[1]);
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
- emit_insn (gen_lfiwax (operands[2], operands[1]));
+ if (TARGET_VSX_SMALL_INTEGER)
+ emit_insn (gen_extendsidi2 (operands[2], operands[1]));
+ else
+ emit_insn (gen_lfiwax (operands[2], operands[1]));
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
DONE;
}"
@@ -5027,15 +5034,16 @@
(set_attr "type" "fpload")])
(define_insn "lfiwzx"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
- (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
+ (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
UNSPEC_LFIWZX))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
"@
lfiwzx %0,%y1
lxsiwzx %x0,%y1
- mtvsrwz %x0,%1"
- [(set_attr "type" "fpload,fpload,mftgpr")])
+ mtvsrwz %x0,%1
+ xxextractuw %x0,%x1,1"
+ [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
(define_insn_and_split "floatunssi<mode>2_lfiwzx"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
@@ -5094,7 +5102,10 @@
operands[1] = rs6000_address_for_fpconvert (operands[1]);
if (GET_CODE (operands[2]) == SCRATCH)
operands[2] = gen_reg_rtx (DImode);
- emit_insn (gen_lfiwzx (operands[2], operands[1]));
+ if (TARGET_VSX_SMALL_INTEGER)
+ emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
+ else
+ emit_insn (gen_lfiwzx (operands[2], operands[1]));
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
DONE;
}"
@@ -6518,25 +6529,66 @@
[(set_attr "type" "load")
(set_attr "length" "4")])
+;; MR LA LWZ LFIWZX LXSIWZX
+;; STW STFIWX STXSIWX LI LIS
+;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
+;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
+;; MF%1 MT%0 MT%0 NOP
(define_insn "*movsi_internal1"
- [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
- (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
+ [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
+ "=r, r, r, ?*wI, ?*wH,
+ m, ?Z, ?Z, r, r,
+ r, ?*wIwH, ?*wJwK, ?*wK, ?*wJwK,
+ ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
+ r, *c*l, *h, *h")
+
+ (match_operand:SI 1 "input_operand"
+ "r, U, m, Z, Z,
+ r, wI, wH, I, L,
+ n, wIwH, O, wM, wB,
+ O, wM, wS, r, wIwH,
+ *h, r, r, 0"))]
+
"!TARGET_SINGLE_FPU &&
(gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
"@
mr %0,%1
la %0,%a1
lwz%U1%X1 %0,%1
+ lfiwzx %0,%y1
+ lxsiwzx %x0,%y1
stw%U0%X0 %1,%0
+ stfiwx %1,%y0
+ stxsiwx %x1,%y0
li %0,%1
lis %0,%v1
#
+ xxlor %x0,%x1,%x1
+ xxspltib %x0,0
+ xxspltib %x0,255
+ vspltisw %0,%1
+ xxlxor %x0,%x0,%x0
+ xxlorc %x0,%x0,%x0
+ #
+ mtvsrwz %x0,%1
+ mfvsrwz %0,%x1
mf%1 %0
mt%0 %1
mt%0 %1
nop"
- [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
- (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
+ [(set_attr "type"
+ "*, *, load, fpload, fpload,
+ store, fpstore, fpstore, *, *,
+ *, veclogical, vecsimple, vecsimple, vecsimple,
+ veclogical, veclogical, vecsimple, mffgpr, mftgpr,
+ *, *, *, *")
+
+ (set_attr "length"
+ "4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4,
+ 8, 4, 4, 4, 4,
+ 4, 4, 8, 4, 4,
+ 4, 4, 4, 4")])
(define_insn "*movsi_internal1_single"
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
@@ -6581,6 +6633,23 @@
FAIL;
}")
+;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
+(define_split
+ [(set (match_operand:DI 0 "altivec_register_operand" "")
+ (match_operand:DI 1 "xxspltib_constant_split" ""))]
+ "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
+ [(const_int 0)]
+{
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ int r = REGNO (op0);
+ rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
+
+ emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
+ emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
+ DONE;
+})
+
(define_insn "*mov<mode>_internal2"
[(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")