aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-09 19:51:32 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-09 19:51:32 +0000
commit0f1896e6b7068122f0f46a3c18f9b7c3cc6cc773 (patch)
treecde43245943336167bbeada79b9de8e7247bd721
parent2f577b0eb7df4be3441247fdfb80582c1e949cb1 (diff)
checkpointibm/power9
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ibm/power9@237273 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.meissner28
-rw-r--r--gcc/config/rs6000/constraints.md5
-rw-r--r--gcc/config/rs6000/predicates.md78
-rw-r--r--gcc/config/rs6000/rs6000.c104
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/config/rs6000/rs6000.md119
6 files changed, 112 insertions, 224 deletions
diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner
index 6c97fcaddf2..f9beef2fdd5 100644
--- a/gcc/ChangeLog.meissner
+++ b/gcc/ChangeLog.meissner
@@ -1,3 +1,31 @@
+2016-06-09 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/constraints.md (wB cosntraint): Limit wB to ISA
+ 2.07 and above.
+
+ * config/rs6000/predicates.md (s5bit_cint_operand_not_0_or_m1):
+ Delete.
+ (xxspltib_constant): Likewise.
+ (indirect_address_mem): Likewise.
+ (dform_reg_operand_no_pseudo): Likewise.
+ (lo_sum_operand): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_debug_print_mode): Print mode
+ tieable category.
+ (rs6000_debug_reg_global): Delete printing mode tieable
+ information here.
+ (rs6000_init_hard_regno_mode_ok): Whitespace change.
+ (xxspltib_constant_p): Don't allow
+ -16..-2 and 1..15, since these can be generated via VSPLATISW.
+
+ * config/rs6000/rs6000.h (MODES_TIEABLE_P): White space.
+
+ * config/rs6000/rs6000.md (movdi_internal32): Support DImode in
+ Altivec registers.
+ (32-bit DImode splitters): Return to the original code.
+ (peephole2's for fixing up register allocation): Delete, this code
+ doesn't improve things.
+
2016-06-08 Michael Meissner <meissner@linux.vnet.ibm.com>
Merge up to 237222.
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index f3f254f19dc..8ef8f9b429e 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -133,9 +133,12 @@
(define_register_constraint "wz" "rs6000_constraints[RS6000_CONSTRAINT_wz]"
"Floating point register if the LFIWZX instruction is enabled or NO_REGS.")
+;; wB needs ISA 2.07 VUPKHSW
(define_constraint "wB"
"Signed 5-bit constant integer that can be loaded into an altivec register."
- (match_operand 0 "s5bit_cint_operand_not_0_or_m1"))
+ (and (match_code "const_int")
+ (and (match_test "TARGET_P8_VECTOR")
+ (match_operand 0 "s5bit_cint_operand"))))
(define_constraint "wD"
"Int constant that is the element number of the 64-bit scalar in a vector."
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 03c1b46c07b..3d0f48ea712 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -132,14 +132,6 @@
(and (match_code "const_int")
(match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
-;; Like s5bit_cint_operand, but don't allow 0/-1 used for creating small
-;; constants on ISA 2.07 (power8) systems and above in vector registers.
-(define_predicate "s5bit_cint_operand_not_0_or_m1"
- (and (match_code "const_int")
- (and (match_test ("TARGET_UPPER_REGS_DI && TARGET_P8_VECTOR"))
- (and (match_test ("IN_RANGE (INTVAL (op), -16, 15)"))
- (match_test ("!IN_RANGE (INTVAL (op), -1, 0)"))))))
-
;; Return 1 if op is a unsigned 3-bit constant integer.
(define_predicate "u3bit_cint_operand"
(and (match_code "const_int")
@@ -604,21 +596,6 @@
return num_insns == 1;
})
-;; Return 1 if the operand is a constant that can be loaded with the XXSPLIT
-;; instruction, that may or may not be split.
-
-(define_predicate "xxspltib_constant"
- (match_code "const_vector,vec_duplicate,const_int")
-{
- int value = 256;
- int num_insns = -1;
-
- if (!xxspltib_constant_p (op, mode, &num_insns, &value))
- return false;
-
- return 1;
-})
-
;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
;; vector register without using memory.
(define_predicate "easy_vector_constant"
@@ -851,13 +828,6 @@
|| (GET_CODE (XEXP (op, 0)) == PRE_MODIFY
&& indexed_address (XEXP (XEXP (op, 0), 1), mode))))"))
-;; Return 1 if the operand is a MEM with an indirect address form.
-(define_predicate "indirect_address_mem"
- (match_code "mem")
-{
- return base_reg_operand (XEXP (op, 0), Pmode);
-})
-
;; Return 1 if the operand is either a non-special register or can be used
;; as the operand of a `mode' add insn.
(define_predicate "add_operand"
@@ -1988,51 +1958,3 @@
return offsettable_nonstrict_memref_p (op);
})
-
-
-;; Return true if the operand is a register that can hold normal offsettable
-;; addressing (d-form). This is used for peephole2 processing, so don't
-;; allow pseudo registers.
-(define_predicate "dform_reg_operand_no_pseudo"
- (match_code "reg,subreg")
-{
- HOST_WIDE_INT r;
-
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
-
- if (!REG_P (op))
- return 0;
-
- r = REGNO (op);
- if (r >= FIRST_PSEUDO_REGISTER)
- return 0;
-
- if (INT_REGNO_P (r))
- return (mode == QImode || mode == HImode || mode == SImode || mode == SFmode
- || (TARGET_POWERPC64 && (mode == DImode || mode == DFmode)));
-
- if (mode != DFmode && mode != SFmode && mode != DImode)
- return 0;
-
- if (FP_REGNO_P (r))
- return 1;
-
- if (ALTIVEC_REGNO_P (r) && TARGET_P9_VECTOR)
- return 1;
-
- return 0;
-})
-
-;; Return true if the operand is LO_SUM
-(define_predicate "lo_sum_operand"
- (match_code "lo_sum")
-{
- if (mode != Pmode)
- return 0;
-
- if (!base_reg_operand (XEXP (op, 0), mode))
- return 0;
-
- return 1;
-})
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ddb174528f2..3f7759a5db4 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2165,12 +2165,26 @@ rs6000_debug_print_mode (ssize_t m)
ssize_t rc;
int spaces = 0;
bool fuse_extra_p;
+ const char *tstr;
+
+ switch (rs6000_tieable[m])
+ {
+ case TIEABLE_NORMAL: tstr = "norm"; break;
+ case TIEABLE_PTI: tstr = "pti"; break;
+ case TIEABLE_VECTOR: tstr = "vect"; break;
+ case TIEABLE_FP: tstr = "fp"; break;
+ case TIEABLE_SPE: tstr = "spe"; break;
+ case TIEABLE_CC: tstr = "cc"; break;
+ default: tstr = "bad"; break;
+ }
fprintf (stderr, "Mode: %-5s", GET_MODE_NAME (m));
for (rc = 0; rc < N_RELOAD_REG; rc++)
fprintf (stderr, " %s: %s", reload_reg_map[rc].name,
rs6000_debug_addr_mask (reg_addr[m].addr_mask[rc], true));
+ fprintf (stderr, " Tie: %-4s", tstr);
+
if ((reg_addr[m].reload_store != CODE_FOR_nothing)
|| (reg_addr[m].reload_load != CODE_FOR_nothing))
fprintf (stderr, " Reload=%c%c",
@@ -2285,9 +2299,8 @@ static void
rs6000_debug_reg_global (void)
{
static const char *const tf[2] = { "false", "true" };
- const char *nl = (const char *)0;
int m;
- size_t m1, m2, v;
+ size_t v;
char costly_num[20];
char nop_num[20];
char flags_buffer[40];
@@ -2298,45 +2311,6 @@ rs6000_debug_reg_global (void)
const char *cmodel_str;
struct cl_target_option cl_opts;
- /* Modes we want tieable information on. */
- static const machine_mode print_tieable_modes[] = {
- QImode,
- HImode,
- SImode,
- DImode,
- TImode,
- PTImode,
- SFmode,
- DFmode,
- TFmode,
- IFmode,
- KFmode,
- SDmode,
- DDmode,
- TDmode,
- V8QImode,
- V4HImode,
- V2SImode,
- V16QImode,
- V8HImode,
- V4SImode,
- V2DImode,
- V1TImode,
- V32QImode,
- V16HImode,
- V8SImode,
- V4DImode,
- V2TImode,
- V2SFmode,
- V4SFmode,
- V2DFmode,
- V8SFmode,
- V4DFmode,
- CCmode,
- CCUNSmode,
- CCEQmode,
- };
-
/* Virtual regs we are interested in. */
const static struct {
int regno; /* register number. */
@@ -2437,41 +2411,11 @@ rs6000_debug_reg_global (void)
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wy]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]]);
- nl = "\n";
for (m = 0; m < NUM_MACHINE_MODES; ++m)
rs6000_debug_print_mode (m);
fputs ("\n", stderr);
- for (m1 = 0; m1 < ARRAY_SIZE (print_tieable_modes); m1++)
- {
- machine_mode mode1 = print_tieable_modes[m1];
- bool first_time = true;
-
- nl = (const char *)0;
- for (m2 = 0; m2 < ARRAY_SIZE (print_tieable_modes); m2++)
- {
- machine_mode mode2 = print_tieable_modes[m2];
- if (mode1 != mode2 && MODES_TIEABLE_P (mode1, mode2))
- {
- if (first_time)
- {
- fprintf (stderr, "Tieable modes %s:", GET_MODE_NAME (mode1));
- nl = "\n";
- first_time = false;
- }
-
- fprintf (stderr, " %s", GET_MODE_NAME (mode2));
- }
- }
-
- if (!first_time)
- fputs ("\n", stderr);
- }
-
- if (nl)
- fputs (nl, stderr);
-
if (rs6000_recip_control)
{
fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
@@ -3593,8 +3537,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
else if (ALTIVEC_OR_VSX_VECTOR_MODE (m2))
tieable = TIEABLE_VECTOR;
- else if (SCALAR_FLOAT_MODE_P (m2) && TARGET_HARD_FLOAT
- && TARGET_FPRS)
+ else if (SCALAR_FLOAT_MODE_P (m2) && TARGET_HARD_FLOAT && TARGET_FPRS)
tieable = TIEABLE_FP;
else if (SPE_VECTOR_MODE (m2))
@@ -6409,8 +6352,8 @@ xxspltib_constant_p (rtx op,
}
/* Handle integer constants being loaded into the upper part of the VSX
- register as a scalar. If the value isn't 0/-1, only allow it if
- the mode can go in Altivec registers. */
+ register as a scalar. If the value isn't 0/-1, only allow it if the mode
+ can go in Altivec registers. Prefer VSPLTISW/VUPKHSW over XXSPLITIB. */
else if (CONST_INT_P (op))
{
if (!SCALAR_INT_MODE_P (mode))
@@ -6420,9 +6363,14 @@ xxspltib_constant_p (rtx op,
if (!IN_RANGE (value, -128, 127))
return false;
- if (!IN_RANGE (value, -1, 0)
- && (reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_VALID) == 0)
- return false;
+ if (!IN_RANGE (value, -1, 0))
+ {
+ if (!(reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_VALID))
+ return false;
+
+ if (EASY_VECTOR_15 (value))
+ return false;
+ }
}
else
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 8230079d688..c8a4df7d6e3 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1313,7 +1313,7 @@ typedef enum {
extern rs6000_tieable_type rs6000_tieable[];
#define MODES_TIEABLE_P(MODE1, MODE2) \
-(rs6000_tieable[(int)(MODE1)] == rs6000_tieable[(int)(MODE2)])
+ (rs6000_tieable[(int)(MODE1)] == rs6000_tieable[(int)(MODE2)])
/* Post-reload, we can't use any new AltiVec registers, as we already
emitted the vrsave mask. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a7f38ce952a..3825cc011d6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7700,9 +7700,25 @@
;; non-offsettable address by using r->r which won't make progress.
;; Use of fprs is disparaged slightly otherwise reload prefers to reload
;; a gpr into a fpr instead of reloading an invalid 'Y' address
+
+;; GPR store GPR load GPR move FPR store FPR load FPR move
+;; GPR const AVX store AVX store AVX load AVX load VSX move
+;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
+;; AVX const
+
(define_insn "*movdi_internal32"
- [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
- (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
+ [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
+ "=Y, r, r, ?m, ?*d, ?*d,
+ r, ?Y, ?Z, ?*wb, ?*wv, ?wi,
+ ?wo, ?wo, ?wv, ?wi, ?wi, ?wv,
+ ?wv")
+
+ (match_operand:DI 1 "input_operand"
+ "r, Y, r, d, m, d,
+ IJKnGHF, wb, wv, Y, Z, wi,
+ Oj, wM, OjwM, Oj, wM, wS,
+ wB"))]
+
"! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
@@ -7713,13 +7729,31 @@
stfd%U0%X0 %1,%0
lfd%U1%X1 %0,%1
fmr %0,%1
+ #
+ stxsd %1,%0
+ stxsdx %x1,%y0
+ lxsd %0,%1
+ lxsdx %x0,%y1
+ xxlor %x0,%x1,%x1
+ xxspltib %x0,0
+ xxspltib %x0,255
+ vspltisw %0,%1
+ xxlxor %x0,%x0,%x0
+ xxlorc %x0,%x0,%x0
+ #
#"
- [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
+ [(set_attr "type"
+ "store, load, *, fpstore, fpload, fp,
+ *, fpstore, fpstore, fpload, fpload, vecsimple,
+ vecsimple, vecsimple, vecsimple, vecsimple, vecsimple, vecsimple,
+ vecsimple")])
(define_split
- [(set (match_operand:DI 0 "int_reg_operand" "")
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_int_operand" ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWERPC64 && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])
+ && !direct_move_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 1))]
"
@@ -7856,41 +7890,38 @@
}")
(define_split
- [(set (match_operand:DI 0 "vsx_register_operand" "")
- (match_operand:DI 1 "xxspltib_constant" ""))]
- "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed
- && TARGET_P9_VECTOR"
+ [(set (match_operand:DI 0 "altivec_register_operand" "")
+ (match_operand:DI 1 "s5bit_cint_operand" ""))]
+ "TARGET_UPPER_REGS_DI && TARGET_VSX && 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);
+ rtx op0_v4si = gen_rtx_REG (V4SImode, r);
- emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
+ emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
if (op1 != const0_rtx && op1 != constm1_rtx)
- emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
+ {
+ rtx op0_v2di = gen_rtx_REG (V2DImode, r);
+ emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
+ }
DONE;
})
(define_split
[(set (match_operand:DI 0 "altivec_register_operand" "")
- (match_operand:DI 1 "s5bit_cint_operand" ""))]
- "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed
- && !TARGET_P9_VECTOR"
+ (match_operand:DI 1 "xxspltib_constant_split" ""))]
+ "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
[(const_int 0)]
{
rtx op0 = operands[0];
rtx op1 = operands[1];
int r = REGNO (op0);
- rtx op0_v4si = gen_rtx_REG (V4SImode, r);
+ rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
- emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
- if (op1 != const0_rtx && op1 != constm1_rtx)
- {
- rtx op0_v2di = gen_rtx_REG (V2DImode, r);
- emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
- }
+ emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
+ emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
DONE;
})
@@ -13630,50 +13661,6 @@
[(set_attr "type" "fpcompare")])
-;; The register allocator for medium/large code model might create a reference
-;; during register allocation of the form:
-;;
-;; (set (reg1) (high ...))
-;; (set (reg1) (lo_sum (reg1) ...))
-;; (set (reg2) (mem (reg1))) or (set (mem (reg1)) (reg3))
-;;
-;; Patch this up via peephole2 to:
-;; (set (reg1) (high ...))
-;; (set (reg2) (mem (lo_sum ...))) or (set (mem (lo_sum ...)) (reg3))
-
-(define_mode_iterator DFORM [QI HI SI DI SF DF])
-
-(define_peephole2
- [(set (match_operand:DI 0 "base_reg_operand" "")
- (match_operand:DI 1 "lo_sum_operand" ""))
- (set (match_operand:DFORM 2 "dform_reg_operand_no_pseudo" "")
- (match_operand:DFORM 3 "indirect_address_mem" ""))]
- "TARGET_POWERPC64 && TARGET_CMODEL != CMODEL_SMALL
- && REG_P (XEXP (operands[3], 0))
- && rtx_equal_p (XEXP (operands[3], 0), operands[0])
- && strict_memory_address_p (<MODE>mode, operands[1])
- && peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 2) (match_dup 4))]
-{
- operands[4] = change_address (operands[3], VOIDmode, operands[1]);
-})
-
-(define_peephole2
- [(set (match_operand:DI 0 "base_reg_operand" "")
- (match_operand:DI 1 "lo_sum_operand" ""))
- (set (match_operand:DFORM 2 "indirect_address_mem" "")
- (match_operand:DFORM 3 "dform_reg_operand_no_pseudo" ""))]
- "TARGET_POWERPC64 && TARGET_CMODEL != CMODEL_SMALL
- && REG_P (XEXP (operands[2], 0))
- && rtx_equal_p (XEXP (operands[2], 0), operands[0])
- && strict_memory_address_p (<MODE>mode, operands[1])
- && peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 4) (match_dup 3))]
-{
- operands[4] = change_address (operands[2], VOIDmode, operands[1]);
-})
-
-
(include "sync.md")
(include "vector.md")