diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2015-09-16 10:57:42 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2015-09-16 10:57:42 +0200 |
commit | ac19ac6481a3f326d9f41403f5dadab548b2c8a6 (patch) | |
tree | b3e7e392d6f89138ab8343bd9a6157e284e756ae /gcc/config/rs6000 | |
parent | 15a6021253f2cc4c832fd7ddb1469d3f0b281c91 (diff) |
Merge branches/gcc-5-branch rev 227732.linaro-local/gcc-5-integration-branch-new
Change-Id: I2f59904b28323b1c72a8cf1bd62c9e460d95bcea
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/htm.md | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 22 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-cpus.def | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 87 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.opt | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/sync.md | 15 | ||||
-rw-r--r-- | gcc/config/rs6000/t-rs6000 | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/vector.md | 23 |
8 files changed, 111 insertions, 43 deletions
diff --git a/gcc/config/rs6000/htm.md b/gcc/config/rs6000/htm.md index dbfd0db5962..cec253814d3 100644 --- a/gcc/config/rs6000/htm.md +++ b/gcc/config/rs6000/htm.md @@ -48,7 +48,7 @@ (define_insn "tabort" [(set (match_operand:CC 1 "cc_reg_operand" "=x") - (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] + (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")] UNSPECV_HTM_TABORT))] "TARGET_HTM" "tabort. %0" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 3c8dfe6032d..3a23dfe0311 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -41,7 +41,7 @@ if (!REG_P (op)) return 0; - if (REGNO (op) > LAST_VIRTUAL_REGISTER) + if (REGNO (op) >= FIRST_PSEUDO_REGISTER) return 1; return ALTIVEC_REGNO_P (REGNO (op)); @@ -57,7 +57,7 @@ if (!REG_P (op)) return 0; - if (REGNO (op) > LAST_VIRTUAL_REGISTER) + if (REGNO (op) >= FIRST_PSEUDO_REGISTER) return 1; return VSX_REGNO_P (REGNO (op)); @@ -74,7 +74,7 @@ if (!REG_P (op)) return 0; - if (REGNO (op) > LAST_VIRTUAL_REGISTER) + if (REGNO (op) >= FIRST_PSEUDO_REGISTER) return 1; return VFLOAT_REGNO_P (REGNO (op)); @@ -91,7 +91,7 @@ if (!REG_P (op)) return 0; - if (REGNO (op) > LAST_VIRTUAL_REGISTER) + if (REGNO (op) >= FIRST_PSEUDO_REGISTER) return 1; return VINT_REGNO_P (REGNO (op)); @@ -108,7 +108,7 @@ if (!REG_P (op)) return 0; - if (REGNO (op) > LAST_VIRTUAL_REGISTER) + if (REGNO (op) >= FIRST_PSEUDO_REGISTER) return 1; return VLOGICAL_REGNO_P (REGNO (op)); @@ -1048,12 +1048,12 @@ (define_predicate "current_file_function_operand" (and (match_code "symbol_ref") (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)) - && ((SYMBOL_REF_LOCAL_P (op) - && ((DEFAULT_ABI != ABI_AIX - && DEFAULT_ABI != ABI_ELFv2) - || !SYMBOL_REF_EXTERNAL_P (op))) - || (op == XEXP (DECL_RTL (current_function_decl), - 0)))"))) + && (SYMBOL_REF_LOCAL_P (op) + || op == XEXP (DECL_RTL (current_function_decl), 0)) + && !((DEFAULT_ABI == ABI_AIX + || DEFAULT_ABI == ABI_ELFv2) + && (SYMBOL_REF_EXTERNAL_P (op) + || SYMBOL_REF_WEAK (op)))"))) ;; Return 1 if this operand is a valid input for a move insn. (define_predicate "input_operand" diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def index 9fd565286f2..03764aef740 100644 --- a/gcc/config/rs6000/rs6000-cpus.def +++ b/gcc/config/rs6000/rs6000-cpus.def @@ -53,6 +53,7 @@ | OPTION_MASK_P8_VECTOR \ | OPTION_MASK_CRYPTO \ | OPTION_MASK_DIRECT_MOVE \ + | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ | OPTION_MASK_HTM \ | OPTION_MASK_QUAD_MEMORY \ | OPTION_MASK_QUAD_MEMORY_ATOMIC \ @@ -78,6 +79,7 @@ | OPTION_MASK_DFP \ | OPTION_MASK_DIRECT_MOVE \ | OPTION_MASK_DLMZB \ + | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ | OPTION_MASK_FPRND \ | OPTION_MASK_HTM \ | OPTION_MASK_ISEL \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 97c5842f49f..bb7f45d25e7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3692,6 +3692,45 @@ rs6000_option_override_internal (bool global_init_p) && optimize >= 3) rs6000_isa_flags |= OPTION_MASK_P8_FUSION_SIGN; + /* Set -mallow-movmisalign to explicitly on if we have full ISA 2.07 + support. If we only have ISA 2.06 support, and the user did not specify + the switch, leave it set to -1 so the movmisalign patterns are enabled, + but we don't enable the full vectorization support */ + if (TARGET_ALLOW_MOVMISALIGN == -1 && TARGET_P8_VECTOR && TARGET_DIRECT_MOVE) + TARGET_ALLOW_MOVMISALIGN = 1; + + else if (TARGET_ALLOW_MOVMISALIGN && !TARGET_VSX) + { + if (TARGET_ALLOW_MOVMISALIGN > 0) + error ("-mallow-movmisalign requires -mvsx"); + + TARGET_ALLOW_MOVMISALIGN = 0; + } + + /* Determine when unaligned vector accesses are permitted, and when + they are preferred over masked Altivec loads. Note that if + TARGET_ALLOW_MOVMISALIGN has been disabled by the user, then + TARGET_EFFICIENT_UNALIGNED_VSX must be as well. The converse is + not true. */ + if (TARGET_EFFICIENT_UNALIGNED_VSX) + { + if (!TARGET_VSX) + { + if (rs6000_isa_flags_explicit & OPTION_MASK_EFFICIENT_UNALIGNED_VSX) + error ("-mefficient-unaligned-vsx requires -mvsx"); + + rs6000_isa_flags &= ~OPTION_MASK_EFFICIENT_UNALIGNED_VSX; + } + + else if (!TARGET_ALLOW_MOVMISALIGN) + { + if (rs6000_isa_flags_explicit & OPTION_MASK_EFFICIENT_UNALIGNED_VSX) + error ("-mefficient-unaligned-vsx requires -mallow-movmisalign"); + + rs6000_isa_flags &= ~OPTION_MASK_EFFICIENT_UNALIGNED_VSX; + } + } + if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags); @@ -4251,22 +4290,6 @@ rs6000_option_override_internal (bool global_init_p) } } - /* Determine when unaligned vector accesses are permitted, and when - they are preferred over masked Altivec loads. Note that if - TARGET_ALLOW_MOVMISALIGN has been disabled by the user, then - TARGET_EFFICIENT_UNALIGNED_VSX must be as well. The converse is - not true. */ - if (TARGET_EFFICIENT_UNALIGNED_VSX == -1) { - if (TARGET_VSX && rs6000_cpu == PROCESSOR_POWER8 - && TARGET_ALLOW_MOVMISALIGN != 0) - TARGET_EFFICIENT_UNALIGNED_VSX = 1; - else - TARGET_EFFICIENT_UNALIGNED_VSX = 0; - } - - if (TARGET_ALLOW_MOVMISALIGN == -1 && rs6000_cpu == PROCESSOR_POWER8) - TARGET_ALLOW_MOVMISALIGN = 1; - /* Set the builtin mask of the various options used that could affect which builtins were used. In the past we used target_flags, but we've run out of bits, and some options like SPE and PAIRED are no longer in @@ -17678,8 +17701,21 @@ rs6000_secondary_reload_gpr (rtx reg, rtx mem, rtx scratch, bool store_p) if (GET_CODE (addr) == PRE_MODIFY) { + gcc_assert (REG_P (XEXP (addr, 0)) + && GET_CODE (XEXP (addr, 1)) == PLUS + && XEXP (XEXP (addr, 1), 0) == XEXP (addr, 0)); scratch_or_premodify = XEXP (addr, 0); - gcc_assert (REG_P (scratch_or_premodify)); + if (!HARD_REGISTER_P (scratch_or_premodify)) + /* If we have a pseudo here then reload will have arranged + to have it replaced, but only in the original insn. + Use the replacement here too. */ + scratch_or_premodify = find_replacement (&XEXP (addr, 0)); + + /* RTL emitted by rs6000_secondary_reload_gpr uses RTL + expressions from the original insn, without unsharing them. + Any RTL that points into the original insn will of course + have register replacements applied. That is why we don't + need to look for replacements under the PLUS. */ addr = XEXP (addr, 1); } gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); @@ -20537,12 +20573,15 @@ rs6000_pre_atomic_barrier (rtx mem, enum memmodel model) case MEMMODEL_RELAXED: case MEMMODEL_CONSUME: case MEMMODEL_ACQUIRE: + case MEMMODEL_SYNC_ACQUIRE: break; case MEMMODEL_RELEASE: + case MEMMODEL_SYNC_RELEASE: case MEMMODEL_ACQ_REL: emit_insn (gen_lwsync ()); break; case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: emit_insn (gen_hwsync ()); break; default: @@ -20559,10 +20598,13 @@ rs6000_post_atomic_barrier (enum memmodel model) case MEMMODEL_RELAXED: case MEMMODEL_CONSUME: case MEMMODEL_RELEASE: + case MEMMODEL_SYNC_RELEASE: break; case MEMMODEL_ACQUIRE: + case MEMMODEL_SYNC_ACQUIRE: case MEMMODEL_ACQ_REL: case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: emit_insn (gen_isync ()); break; default: @@ -20662,8 +20704,8 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[]) oldval = operands[3]; newval = operands[4]; is_weak = (INTVAL (operands[5]) != 0); - mod_s = (enum memmodel) INTVAL (operands[6]); - mod_f = (enum memmodel) INTVAL (operands[7]); + mod_s = memmodel_from_int (INTVAL (operands[6])); + mod_f = memmodel_from_int (INTVAL (operands[7])); orig_mode = mode = GET_MODE (mem); mask = shift = NULL_RTX; @@ -20751,12 +20793,12 @@ rs6000_expand_atomic_compare_and_swap (rtx operands[]) emit_unlikely_jump (x, label1); } - if (mod_f != MEMMODEL_RELAXED) + if (!is_mm_relaxed (mod_f)) emit_label (XEXP (label2, 0)); rs6000_post_atomic_barrier (mod_s); - if (mod_f == MEMMODEL_RELAXED) + if (is_mm_relaxed (mod_f)) emit_label (XEXP (label2, 0)); if (shift) @@ -22311,6 +22353,7 @@ rs6000_function_ok_for_sibcall (tree decl, tree exp) || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && decl && !DECL_EXTERNAL (decl) + && !DECL_WEAK (decl) && (*targetm.binds_local_p) (decl)) || (DEFAULT_ABI == ABI_V4 && (!TARGET_SECURE_PLT @@ -32274,6 +32317,8 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] = { "crypto", OPTION_MASK_CRYPTO, false, true }, { "direct-move", OPTION_MASK_DIRECT_MOVE, false, true }, { "dlmzb", OPTION_MASK_DLMZB, false, true }, + { "efficient-unaligned-vsx", OPTION_MASK_EFFICIENT_UNALIGNED_VSX, + false, true }, { "fprnd", OPTION_MASK_FPRND, false, true }, { "hard-dfp", OPTION_MASK_DFP, false, true }, { "htm", OPTION_MASK_HTM, false, true }, diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 79d01d4965a..9e89eb7641e 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -212,7 +212,7 @@ Target Undocumented Var(TARGET_ALLOW_MOVMISALIGN) Init(-1) Save ; Allow/disallow the movmisalign in DF/DI vectors mefficient-unaligned-vector -Target Undocumented Report Var(TARGET_EFFICIENT_UNALIGNED_VSX) Init(-1) Save +Target Undocumented Report Mask(EFFICIENT_UNALIGNED_VSX) Var(rs6000_isa_flags) ; Consider unaligned VSX accesses to be efficient/inefficient mallow-df-permute diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md index 4364c8526d4..8ba30b98658 100644 --- a/gcc/config/rs6000/sync.md +++ b/gcc/config/rs6000/sync.md @@ -41,18 +41,21 @@ [(match_operand:SI 0 "const_int_operand" "")] ;; model "" { - enum memmodel model = (enum memmodel) INTVAL (operands[0]); + enum memmodel model = memmodel_from_int (INTVAL (operands[0])); switch (model) { case MEMMODEL_RELAXED: break; case MEMMODEL_CONSUME: case MEMMODEL_ACQUIRE: + case MEMMODEL_SYNC_ACQUIRE: case MEMMODEL_RELEASE: + case MEMMODEL_SYNC_RELEASE: case MEMMODEL_ACQ_REL: emit_insn (gen_lwsync ()); break; case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: emit_insn (gen_hwsync ()); break; default: @@ -144,9 +147,9 @@ if (<MODE>mode == TImode && !TARGET_SYNC_TI) FAIL; - enum memmodel model = (enum memmodel) INTVAL (operands[2]); + enum memmodel model = memmodel_from_int (INTVAL (operands[2])); - if (model == MEMMODEL_SEQ_CST) + if (is_mm_seq_cst (model)) emit_insn (gen_hwsync ()); if (<MODE>mode != TImode) @@ -182,7 +185,9 @@ break; case MEMMODEL_CONSUME: case MEMMODEL_ACQUIRE: + case MEMMODEL_SYNC_ACQUIRE: case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: emit_insn (gen_loadsync_<mode> (operands[0])); break; default: @@ -209,15 +214,17 @@ if (<MODE>mode == TImode && !TARGET_SYNC_TI) FAIL; - enum memmodel model = (enum memmodel) INTVAL (operands[2]); + enum memmodel model = memmodel_from_int (INTVAL (operands[2])); switch (model) { case MEMMODEL_RELAXED: break; case MEMMODEL_RELEASE: + case MEMMODEL_SYNC_RELEASE: emit_insn (gen_lwsync ()); break; case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: emit_insn (gen_hwsync ()); break; default: diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000 index 796d7d8ab2e..1fe5a53ff8e 100644 --- a/gcc/config/rs6000/t-rs6000 +++ b/gcc/config/rs6000/t-rs6000 @@ -19,6 +19,7 @@ # <http://www.gnu.org/licenses/>. TM_H += $(srcdir)/config/rs6000/rs6000-builtin.def +TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c $(COMPILE) $< diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index 668bad1d24f..dd950fa1375 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -918,6 +918,8 @@ ;; General shift amounts can be supported using vsro + vsr. We're ;; not expecting to see these yet (the vectorizer currently ;; generates only shifts by a whole number of vector elements). +;; Note that the vec_shr operation is actually defined as +;; 'shift toward element 0' so is a shr for LE and shl for BE. (define_expand "vec_shr_<mode>" [(match_operand:VEC_L 0 "vlogical_operand" "") (match_operand:VEC_L 1 "vlogical_operand" "") @@ -928,6 +930,7 @@ rtx bitshift = operands[2]; rtx shift; rtx insn; + rtx zero_reg, op1, op2; HOST_WIDE_INT bitshift_val; HOST_WIDE_INT byteshift_val; @@ -937,19 +940,29 @@ if (bitshift_val & 0x7) FAIL; byteshift_val = (bitshift_val >> 3); + zero_reg = gen_reg_rtx (<MODE>mode); + emit_move_insn (zero_reg, CONST0_RTX (<MODE>mode)); if (!BYTES_BIG_ENDIAN) - byteshift_val = 16 - byteshift_val; + { + byteshift_val = 16 - byteshift_val; + op1 = zero_reg; + op2 = operands[1]; + } + else + { + op1 = operands[1]; + op2 = zero_reg; + } + if (TARGET_VSX && (byteshift_val & 0x3) == 0) { shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); - insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], - shift); + insn = gen_vsx_xxsldwi_<mode> (operands[0], op1, op2, shift); } else { shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); + insn = gen_altivec_vsldoi_<mode> (operands[0], op1, op2, shift); } emit_insn (insn); |