From 0f1896e6b7068122f0f46a3c18f9b7c3cc6cc773 Mon Sep 17 00:00:00 2001 From: meissner Date: Thu, 9 Jun 2016 19:51:32 +0000 Subject: checkpoint git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ibm/power9@237273 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.meissner | 28 +++++++++ gcc/config/rs6000/constraints.md | 5 +- gcc/config/rs6000/predicates.md | 78 ------------------------- gcc/config/rs6000/rs6000.c | 104 +++++++++------------------------- gcc/config/rs6000/rs6000.h | 2 +- gcc/config/rs6000/rs6000.md | 119 +++++++++++++++++---------------------- 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 + + * 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 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; }) @@ -13629,50 +13660,6 @@ "xscmpuqp %0,%1,%2" [(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, 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, 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") -- cgit v1.2.3