diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2016-10-27 20:52:07 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2016-10-27 20:52:07 +0000 |
commit | 787c7a65f6ec2876337e6c50a26a1da0fadcb5bf (patch) | |
tree | 6fef9d9f4d0a61bd0a82f599ed70624bc18e9835 /gcc/config/rs6000/rs6000.md | |
parent | 6f21288f8c3579ec7ae47615e76ba1e6ad25551f (diff) | |
download | gcc-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.md | 119 |
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") |