aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2015-09-16 10:57:42 +0200
committerYvan Roux <yvan.roux@linaro.org>2015-09-16 10:57:42 +0200
commitac19ac6481a3f326d9f41403f5dadab548b2c8a6 (patch)
treeb3e7e392d6f89138ab8343bd9a6157e284e756ae /gcc/config/rs6000
parent15a6021253f2cc4c832fd7ddb1469d3f0b281c91 (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.md2
-rw-r--r--gcc/config/rs6000/predicates.md22
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def2
-rw-r--r--gcc/config/rs6000/rs6000.c87
-rw-r--r--gcc/config/rs6000/rs6000.opt2
-rw-r--r--gcc/config/rs6000/sync.md15
-rw-r--r--gcc/config/rs6000/t-rs60001
-rw-r--r--gcc/config/rs6000/vector.md23
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);