Commit 0299bc72 by Michael Meissner Committed by Michael Meissner

constraints.md (wF constraint): New constraints for power9/toc fusion.

[gcc]
2015-11-08  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/constraints.md (wF constraint): New constraints
	for power9/toc fusion.
	(wG constraint): Likewise.

	* config/rs6000/predicates.md (u6bit_cint_operand): New
	predicate, recognize 0..63.
	(upper16_cint_operand): New predicate for power9 and toc fusion.
	(fpr_reg_operand): Likewise.
	(toc_fusion_or_p9_reg_operand): Likewise.
	(toc_fusion_mem_raw): Likewise.
	(toc_fusion_mem_wrapped): Likewise.
	(fusion_gpr_addis): If power9 fusion, allow fusion for a larger
	address range.
	(fusion_gpr_mem_combo): Delete, use fusion_addis_mem_combo_load
	instead.
	(fusion_addis_mem_combo_load): Add support for power9 fusion of
	floating point loads, floating point stores, and gpr stores.
	(fusion_addis_mem_combo_store): Likewise.
	(fusion_offsettable_mem_operand): Likewise.

	* config/rs6000/rs6000-protos.h (emit_fusion_addis): Add
	declarations.
	(emit_fusion_load_store): Likewise.
	(fusion_p9_p): Likewise.
	(expand_fusion_p9_load): Likewise.
	(expand_fusion_p9_store): Likewise.
	(emit_fusion_p9_load): Likewise.
	(emit_fusion_p9_store): Likewise.
	(fusion_wrap_memory_address): Likewise.

	* config/rs6000/rs6000.c (struct rs6000_reg_addr): Add new
	elements for power9 fusion.
	(rs6000_debug_print_mode): Rework debug information to print more
	information about fusion.
	(rs6000_init_hard_regno_mode_ok): Setup for power9 fusion
	support.
	(rs6000_legitimate_address_p): Recognize toc fusion as a valid
	offsettable memory address.
	(rs6000_rtx_costs): Update costs for new ISA 3.0 instructions.
	(emit_fusion_gpr_load): Move most of the code from
	emit_fusion_gpr_load into emit_fusion-addis that handles both
	power8 and power9 fusion.
	(emit_fusion_addis): Likewise.
	(emit_fusion_load_store): Likewise.
	(fusion_wrap_memory_address): Add support for TOC fusion.
	(fusion_split_address): Likewise.
	(fusion_p9_p): Add support for power9 fusion.
	(expand_fusion_p9_load): Likewise.
	(expand_fusion_p9_store): Likewise.
	(emit_fusion_p9_load): Likewise.
	(emit_fusion_p9_store): Likewise.

	* config/rs6000/rs6000.h (TARGET_EXTSWSLI): Macros for support for
	new instructions in ISA 3.0.
	(TARGET_CTZ): Likewise.
	(TARGET_TOC_FUSION_INT): Macros for power9 fusion support.
	(TARGET_TOC_FUSION_FP): Likewise.

	* config/rs6000/rs6000.md (UNSPEC_FUSION_P9): New power9/toc
	fusion unspecs.
	(UNSPEC_FUSION_ADDIS): Likewise.
	(QHSI mode iterator): New iterator for power9 fusion.
	(GPR_FUSION): Likewise.
	(FPR_FUSION): Likewise.
	(mod<mode>3): Add support for ISA 3.0
	modulus instructions.
	(umod<mode>3): Likewise.
	(divmod peephole): Likewise.
	(udivmod peephole): Likewise.
	(ctz<mode>2): Add support for ISA 3.0 count trailing zeros scalar
	instructions.
	(ctz<mode>2_h): Likewise.
	(ashdi3_extswsli): Add support for ISA 3.0 EXTSWSLI instruction.
	(ashdi3_extswsli_dot): Likewise.
	(ashdi3_extswsli_dot2): Likewise.
	(power9 fusion splitter): New power9/toc fusion support.
	(toc_fusionload_<mode>): Likewise.
	(toc_fusionload_di): Likewise.
	(fusion_gpr_load_<mode>): Update predicate function.
	(power9 fusion peephole2s): New power9/toc fusion support.
	(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load): Likewise.
	(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store): Likewise.
	(fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load): Likewise.
	(fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store): Likewise.
	(fusion_p9_<mode>_constant): Likewise.

[gcc/testsuite]
2015-11-08  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* lib/target-supports.exp (check_p8vector_hw_available): Split
	long line.
	(check_vsx_hw_available): Likewise.
	(check_p9vector_hw_available): Add new checks for ISA 3.0 hardware
	support and for PowerPC float128 support.
	(check_p9modulo_hw_available): Likewise.
	(check_ppc_float128_sw_available): Likewise.
	(check_ppc_float128_hw_available): Likewise.
	(check_effective_target_powerpc_p9vector_ok): Likewise.
	(check_effective_target_powerpc_p9modulo_ok): Likewise.
	(check_effective_target_powerpc_float128_sw_ok): Likewise.
	(check_effective_target_powerpc_float128_hw_ok): Likewise.
	(is-effective-target): Add new PowerPc targets.
	(is-effective-target-keyword): Likewise.
	(check_vect_support_and_set_flags): If we have ISA 3.0 vector
	instructions, use it.

	* gcc.target/powerpc/mod-1.c: New test for ISA 3.0 instructions.
	* gcc.target/powerpc/mod-2.c: Likewise.
	* gcc.target/powerpc/ctz-1.c: Likewise.
	* gcc.target/powerpc/ctz-2.c: Likewise.
	* gcc.target/powerpc/extswsli-1.c: Likewise.
	* gcc.target/powerpc/extswsli-2.c: Likewise.
	* gcc.target/powerpc/extswsli-3.c: Likewise.

	* gcc.target/powerpc/fusion.c (fusion_vector): Move to fusion2.c
	and allow the test on PowerPC LE.
	* gcc.target/powerpc/fusion2.c (fusion_vector): Likewise.
	* gcc.target/powerpc/fusion3.c: New file, test power9 fusion.

	* gcc.target/powerpc/float128-call.c: Use powerpc_float128_sw_ok
	check instead of powerpc_vsx_ok.
	* gcc.target/powerpc/float128-mix.c: Likewise.

From-SVN: r230066
parent cbb521e7
2015-11-08 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/constraints.md (wF constraint): New constraints
for power9/toc fusion.
(wG constraint): Likewise.
* config/rs6000/predicates.md (u6bit_cint_operand): New
predicate, recognize 0..63.
(upper16_cint_operand): New predicate for power9 and toc fusion.
(fpr_reg_operand): Likewise.
(toc_fusion_or_p9_reg_operand): Likewise.
(toc_fusion_mem_raw): Likewise.
(toc_fusion_mem_wrapped): Likewise.
(fusion_gpr_addis): If power9 fusion, allow fusion for a larger
address range.
(fusion_gpr_mem_combo): Delete, use fusion_addis_mem_combo_load
instead.
(fusion_addis_mem_combo_load): Add support for power9 fusion of
floating point loads, floating point stores, and gpr stores.
(fusion_addis_mem_combo_store): Likewise.
(fusion_offsettable_mem_operand): Likewise.
* config/rs6000/rs6000-protos.h (emit_fusion_addis): Add
declarations.
(emit_fusion_load_store): Likewise.
(fusion_p9_p): Likewise.
(expand_fusion_p9_load): Likewise.
(expand_fusion_p9_store): Likewise.
(emit_fusion_p9_load): Likewise.
(emit_fusion_p9_store): Likewise.
(fusion_wrap_memory_address): Likewise.
* config/rs6000/rs6000.c (struct rs6000_reg_addr): Add new
elements for power9 fusion.
(rs6000_debug_print_mode): Rework debug information to print more
information about fusion.
(rs6000_init_hard_regno_mode_ok): Setup for power9 fusion
support.
(rs6000_legitimate_address_p): Recognize toc fusion as a valid
offsettable memory address.
(rs6000_rtx_costs): Update costs for new ISA 3.0 instructions.
(emit_fusion_gpr_load): Move most of the code from
emit_fusion_gpr_load into emit_fusion-addis that handles both
power8 and power9 fusion.
(emit_fusion_addis): Likewise.
(emit_fusion_load_store): Likewise.
(fusion_wrap_memory_address): Add support for TOC fusion.
(fusion_split_address): Likewise.
(fusion_p9_p): Add support for power9 fusion.
(expand_fusion_p9_load): Likewise.
(expand_fusion_p9_store): Likewise.
(emit_fusion_p9_load): Likewise.
(emit_fusion_p9_store): Likewise.
* config/rs6000/rs6000.h (TARGET_EXTSWSLI): Macros for support for
new instructions in ISA 3.0.
(TARGET_CTZ): Likewise.
(TARGET_TOC_FUSION_INT): Macros for power9 fusion support.
(TARGET_TOC_FUSION_FP): Likewise.
* config/rs6000/rs6000.md (UNSPEC_FUSION_P9): New power9/toc
fusion unspecs.
(UNSPEC_FUSION_ADDIS): Likewise.
(QHSI mode iterator): New iterator for power9 fusion.
(GPR_FUSION): Likewise.
(FPR_FUSION): Likewise.
(mod<mode>3): Add support for ISA 3.0
modulus instructions.
(umod<mode>3): Likewise.
(divmod peephole): Likewise.
(udivmod peephole): Likewise.
(ctz<mode>2): Add support for ISA 3.0 count trailing zeros scalar
instructions.
(ctz<mode>2_h): Likewise.
(ashdi3_extswsli): Add support for ISA 3.0 EXTSWSLI instruction.
(ashdi3_extswsli_dot): Likewise.
(ashdi3_extswsli_dot2): Likewise.
(power9 fusion splitter): New power9/toc fusion support.
(toc_fusionload_<mode>): Likewise.
(toc_fusionload_di): Likewise.
(fusion_gpr_load_<mode>): Update predicate function.
(power9 fusion peephole2s): New power9/toc fusion support.
(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load): Likewise.
(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store): Likewise.
(fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load): Likewise.
(fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store): Likewise.
(fusion_p9_<mode>_constant): Likewise.
2015-11-09 Steve Ellcey <sellcey@imgtec.com>
* optabs.c (prepare_libcall_arg): New function.
......@@ -137,6 +137,16 @@
(and (match_code "const_int")
(match_test "TARGET_VSX && (ival == VECTOR_ELEMENT_SCALAR_64BIT)")))
;; Extended fusion store
(define_memory_constraint "wF"
"Memory operand suitable for power9 fusion load/stores"
(match_operand 0 "fusion_addis_mem_combo_load"))
;; Fusion gpr load.
(define_memory_constraint "wG"
"Memory operand suitable for TOC fusion memory references"
(match_operand 0 "toc_fusion_mem_wrapped"))
;; Lq/stq validates the address for load/store quad
(define_memory_constraint "wQ"
"Memory operand suitable for the load/store quad instructions"
......
......@@ -142,6 +142,11 @@
(and (match_code "const_int")
(match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31")))
;; Return 1 if op is a unsigned 6-bit constant integer.
(define_predicate "u6bit_cint_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) >= 0 && INTVAL (op) <= 63")))
;; Return 1 if op is a signed 8-bit constant integer.
;; Integer multiplication complete more quickly
(define_predicate "s8bit_cint_operand"
......@@ -163,6 +168,12 @@
(and (match_code "const_int")
(match_test "satisfies_constraint_K (op)")))
;; Return 1 if op is a constant integer that is a signed 16-bit constant
;; shifted left 16 bits
(define_predicate "upper16_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_L (op)")))
;; Return 1 if op is a constant integer that cannot fit in a signed D field.
(define_predicate "non_short_cint_operand"
(and (match_code "const_int")
......@@ -271,6 +282,70 @@
return (REGNO (op) != FIRST_GPR_REGNO);
})
;; Return true if this is a traditional floating point register
(define_predicate "fpr_reg_operand"
(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 1;
return FP_REGNO_P (r);
})
;; Return true if this is a register that can has D-form addressing (GPR and
;; traditional FPR registers for scalars). ISA 3.0 (power9) adds D-form
;; addressing for scalars in Altivec registers.
;;
;; If this is a pseudo only allow for GPR fusion in power8. If we have the
;; power9 fusion allow the floating point types.
(define_predicate "toc_fusion_or_p9_reg_operand"
(match_code "reg,subreg")
{
HOST_WIDE_INT r;
bool gpr_p = (mode == QImode || mode == HImode || mode == SImode
|| mode == SFmode
|| (TARGET_POWERPC64 && (mode == DImode || mode == DFmode)));
bool fpr_p = (TARGET_P9_FUSION
&& (mode == DFmode || mode == SFmode
|| (TARGET_POWERPC64 && mode == DImode)));
bool vmx_p = (TARGET_P9_FUSION && TARGET_P9_VECTOR
&& (mode == DFmode || mode == SFmode));
if (!TARGET_P8_FUSION)
return 0;
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
if (!REG_P (op))
return 0;
r = REGNO (op);
if (r >= FIRST_PSEUDO_REGISTER)
return (gpr_p || fpr_p || vmx_p);
if (INT_REGNO_P (r))
return gpr_p;
if (FP_REGNO_P (r))
return fpr_p;
if (ALTIVEC_REGNO_P (r))
return vmx_p;
return 0;
})
;; Return 1 if op is a HTM specific SPR register.
(define_predicate "htm_spr_reg_operand"
(match_operand 0 "register_operand")
......@@ -1598,6 +1673,35 @@
return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
})
;; Match the TOC memory operand that can be fused with an addis instruction.
;; This is used in matching a potential fused address before register
;; allocation.
(define_predicate "toc_fusion_mem_raw"
(match_code "mem")
{
if (!TARGET_TOC_FUSION_INT || !can_create_pseudo_p ())
return false;
return small_toc_ref (XEXP (op, 0), Pmode);
})
;; Match the memory operand that has been fused with an addis instruction and
;; wrapped inside of an (unspec [...] UNSPEC_FUSION_ADDIS) wrapper.
(define_predicate "toc_fusion_mem_wrapped"
(match_code "mem")
{
rtx addr;
if (!TARGET_TOC_FUSION_INT)
return false;
if (!MEM_P (op))
return false;
addr = XEXP (op, 0);
return (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_FUSION_ADDIS);
})
;; Match the first insn (addis) in fusing the combination of addis and loads to
;; GPR registers on power8.
(define_predicate "fusion_gpr_addis"
......@@ -1620,8 +1724,6 @@
else
return 0;
/* Power8 currently will only do the fusion if the top 11 bits of the addis
value are all 1's or 0's. */
value = INTVAL (int_const);
if ((value & (HOST_WIDE_INT)0xffff) != 0)
return 0;
......@@ -1629,6 +1731,12 @@
if ((value & (HOST_WIDE_INT)0xffff0000) == 0)
return 0;
/* Power8 currently will only do the fusion if the top 11 bits of the addis
value are all 1's or 0's. Ignore this restriction if we are testing
advanced fusion. */
if (TARGET_P9_FUSION)
return 1;
return (IN_RANGE (value >> 16, -32, 31));
})
......@@ -1694,13 +1802,14 @@
;; Match a GPR load (lbz, lhz, lwz, ld) that uses a combined address in the
;; memory field with both the addis and the memory offset. Sign extension
;; is not handled here, since lha and lwa are not fused.
(define_predicate "fusion_gpr_mem_combo"
(match_code "mem,zero_extend")
;; With extended fusion, also match a FPR load (lfd, lfs) and float_extend
(define_predicate "fusion_addis_mem_combo_load"
(match_code "mem,zero_extend,float_extend")
{
rtx addr, base, offset;
/* Handle zero extend. */
if (GET_CODE (op) == ZERO_EXTEND)
/* Handle zero/float extend. */
if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND)
{
op = XEXP (op, 0);
mode = GET_MODE (op);
......@@ -1721,6 +1830,71 @@
return 0;
break;
case SFmode:
case DFmode:
if (!TARGET_P9_FUSION)
return 0;
break;
default:
return 0;
}
addr = XEXP (op, 0);
if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
return 0;
base = XEXP (addr, 0);
if (!fusion_gpr_addis (base, GET_MODE (base)))
return 0;
offset = XEXP (addr, 1);
if (GET_CODE (addr) == PLUS)
return satisfies_constraint_I (offset);
else if (GET_CODE (addr) == LO_SUM)
{
if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
return small_toc_ref (offset, GET_MODE (offset));
else if (TARGET_ELF && !TARGET_POWERPC64)
return CONSTANT_P (offset);
}
return 0;
})
;; Like fusion_addis_mem_combo_load, but for stores
(define_predicate "fusion_addis_mem_combo_store"
(match_code "mem")
{
rtx addr, base, offset;
if (!MEM_P (op) || !TARGET_P9_FUSION)
return 0;
switch (mode)
{
case QImode:
case HImode:
case SImode:
break;
case DImode:
if (!TARGET_POWERPC64)
return 0;
break;
case SFmode:
if (!TARGET_SF_FPR)
return 0;
break;
case DFmode:
if (!TARGET_DF_FPR)
return 0;
break;
default:
return 0;
}
......@@ -1748,3 +1922,20 @@
return 0;
})
;; Return true if the operand is a float_extend or zero extend of an
;; offsettable memory operand suitable for use in fusion
(define_predicate "fusion_offsettable_mem_operand"
(match_code "mem,zero_extend,float_extend")
{
if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND)
{
op = XEXP (op, 0);
mode = GET_MODE (op);
}
if (!memory_operand (op, mode))
return 0;
return offsettable_nonstrict_memref_p (op);
})
......@@ -87,7 +87,15 @@ extern bool direct_move_p (rtx, rtx);
extern bool quad_load_store_p (rtx, rtx);
extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx);
extern void expand_fusion_gpr_load (rtx *);
extern void emit_fusion_addis (rtx, rtx, const char *, const char *);
extern void emit_fusion_load_store (rtx, rtx, rtx, const char *);
extern const char *emit_fusion_gpr_load (rtx, rtx);
extern bool fusion_p9_p (rtx, rtx, rtx, rtx);
extern void expand_fusion_p9_load (rtx *);
extern void expand_fusion_p9_store (rtx *);
extern const char *emit_fusion_p9_load (rtx, rtx, rtx);
extern const char *emit_fusion_p9_store (rtx, rtx, rtx);
extern rtx fusion_wrap_memory_address (rtx);
extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx,
enum reg_class);
extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
......
......@@ -565,6 +565,8 @@ extern int rs6000_vector_align[];
#define TARGET_FCFIDUS TARGET_POPCNTD
#define TARGET_FCTIDUZ TARGET_POPCNTD
#define TARGET_FCTIWUZ TARGET_POPCNTD
#define TARGET_CTZ TARGET_MODULO
#define TARGET_EXTSWSLI (TARGET_MODULO && TARGET_POWERPC64)
#define TARGET_XSCVDPSPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR)
#define TARGET_XSCVSPDPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR)
......@@ -701,6 +703,22 @@ extern int rs6000_vector_align[];
&& TARGET_DOUBLE_FLOAT \
&& (TARGET_PPC_GFXOPT || VECTOR_UNIT_VSX_P (DFmode)))
/* Conditions to allow TOC fusion for loading/storing integers. */
#define TARGET_TOC_FUSION_INT (TARGET_P8_FUSION \
&& TARGET_TOC_FUSION \
&& (TARGET_CMODEL != CMODEL_SMALL) \
&& TARGET_POWERPC64)
/* Conditions to allow TOC fusion for loading/storing floating point. */
#define TARGET_TOC_FUSION_FP (TARGET_P9_FUSION \
&& TARGET_TOC_FUSION \
&& (TARGET_CMODEL != CMODEL_SMALL) \
&& TARGET_POWERPC64 \
&& TARGET_HARD_FLOAT \
&& TARGET_FPRS \
&& TARGET_SINGLE_FLOAT \
&& TARGET_DOUBLE_FLOAT)
/* Whether the various reciprocal divide/square root estimate instructions
exist, and whether we should automatically generate code for the instruction
by default. */
......@@ -2095,8 +2113,12 @@ do { \
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
((VALUE) = ((MODE) == SImode ? 32 : 64), 1)
/* The CTZ patterns return -1 for input of zero. */
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 1)
/* The CTZ patterns that are implemented in terms of CLZ return -1 for input of
zero. The hardware instructions added in Power9 return 32 or 64. */
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
((!TARGET_CTZ) \
? ((VALUE) = -1, 1) \
: ((VALUE) = ((MODE) == SImode ? 32 : 64), 1))
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
......
2015-11-08 Michael Meissner <meissner@linux.vnet.ibm.com>
* lib/target-supports.exp (check_p8vector_hw_available): Split
long line.
(check_vsx_hw_available): Likewise.
(check_p9vector_hw_available): Add new checks for ISA 3.0 hardware
support and for PowerPC float128 support.
(check_p9modulo_hw_available): Likewise.
(check_ppc_float128_sw_available): Likewise.
(check_ppc_float128_hw_available): Likewise.
(check_effective_target_powerpc_p9vector_ok): Likewise.
(check_effective_target_powerpc_p9modulo_ok): Likewise.
(check_effective_target_powerpc_float128_sw_ok): Likewise.
(check_effective_target_powerpc_float128_hw_ok): Likewise.
(is-effective-target): Add new PowerPc targets.
(is-effective-target-keyword): Likewise.
(check_vect_support_and_set_flags): If we have ISA 3.0 vector
instructions, use it.
* gcc.target/powerpc/mod-1.c: New test for ISA 3.0 instructions.
* gcc.target/powerpc/mod-2.c: Likewise.
* gcc.target/powerpc/ctz-1.c: Likewise.
* gcc.target/powerpc/ctz-2.c: Likewise.
* gcc.target/powerpc/extswsli-1.c: Likewise.
* gcc.target/powerpc/extswsli-2.c: Likewise.
* gcc.target/powerpc/extswsli-3.c: Likewise.
* gcc.target/powerpc/fusion.c (fusion_vector): Move to fusion2.c
and allow the test on PowerPC LE.
* gcc.target/powerpc/fusion2.c (fusion_vector): Likewise.
* gcc.target/powerpc/fusion3.c: New file, test power9 fusion.
* gcc.target/powerpc/float128-call.c: Use powerpc_float128_sw_ok
check instead of powerpc_vsx_ok.
* gcc.target/powerpc/float128-mix.c: Likewise.
2015-11-09 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/sso/*.c: Robustify dg-output directives.
......
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
int i_trailing_zero (int a) { return __builtin_ctz (a); }
int l_trailing_zero (long a) { return __builtin_ctzl (a); }
int ll_trailing_zero (long long a) { return __builtin_ctzll (a); }
/* { dg-final { scan-assembler "cnttzw " } } */
/* { dg-final { scan-assembler "cnttzd " } } */
/* { dg-final { scan-assembler-not "cntlzw " } } */
/* { dg-final { scan-assembler-not "cntlzd " } } */
/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
int i_trailing_zero (int a) { return __builtin_ctz (a); }
/* { dg-final { scan-assembler "cnttzw " } } */
/* { dg-final { scan-assembler-not "cntlzw " } } */
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
static int mem;
int *ptr = &mem;
long
add (long *p, int reg)
{
__asm__ (" #foo %0" : "+r" (reg));
return p[reg] + p[mem];
}
/* { dg-final { scan-assembler-times "extswsli " 2 } } */
/* { dg-final { scan-assembler-times "lwz " 1 } } */
/* { dg-final { scan-assembler-not "lwa " } } */
/* { dg-final { scan-assembler-not "sldi " } } */
/* { dg-final { scan-assembler-not "extsw " } } */
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
long
func1 (int reg, int *is_zero)
{
long value;
__asm__ (" #foo %0" : "+r" (reg));
value = ((long)reg) << 4;
if (!value)
*is_zero = 1;
return value;
}
long
func2 (int *ptr, int *is_zero)
{
int reg = *ptr;
long value = ((long)reg) << 4;
if (!value)
*is_zero = 1;
return value;
}
/* { dg-final { scan-assembler "extswsli\\. " } } */
/* { dg-final { scan-assembler "lwz " } } */
/* { dg-final { scan-assembler-not "lwa " } } */
/* { dg-final { scan-assembler-not "sldi " } } */
/* { dg-final { scan-assembler-not "sldi\\. " } } */
/* { dg-final { scan-assembler-not "extsw " } } */
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
long
do_ext_add (int *p, long a, long b)
{
long l = *p;
long l2 = l << 4;
return l2 + ((l2 == 0) ? a : b);
}
long
do_ext (int *p, long a, long b)
{
long l = *p;
long l2 = l << 4;
return ((l2 == 0) ? a : b);
}
/* { dg-final { scan-assembler "extswsli\\. "} } */
/* { dg-do compile { target { powerpc*-*-linux* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-require-effective-target powerpc_float128_sw_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-O2 -mcpu=power7 -mfloat128 -mno-regnames" } */
......
/* { dg-do compile { target { powerpc*-*-linux* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-require-effective-target powerpc_float128_sw_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-O2 -mcpu=power7 -mfloat128" } */
......
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-skip-if "" { powerpc*le-*-* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-mcpu=power7 -mtune=power8 -O3" } */
......@@ -14,10 +13,7 @@ int fusion_short (short *p){ return p[LARGE]; }
int fusion_int (int *p){ return p[LARGE]; }
unsigned fusion_uns (unsigned *p){ return p[LARGE]; }
vector double fusion_vector (vector double *p) { return p[2]; }
/* { dg-final { scan-assembler-times "gpr load fusion" 6 } } */
/* { dg-final { scan-assembler-times "vector load fusion" 1 } } */
/* { dg-final { scan-assembler-times "lbz" 2 } } */
/* { dg-final { scan-assembler-times "extsb" 1 } } */
/* { dg-final { scan-assembler-times "lhz" 2 } } */
......
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-skip-if "" { powerpc*le-*-* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-mcpu=power7 -mtune=power8 -O3" } */
vector double fusion_vector (vector double *p) { return p[2]; }
/* { dg-final { scan-assembler-times "vector load fusion" 1 } } */
/* { dg-do compile { target { powerpc*-*-* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-mcpu=power7 -mtune=power9 -O3" } */
#define LARGE 0x12345
int fusion_float_read (float *p){ return p[LARGE]; }
int fusion_double_read (double *p){ return p[LARGE]; }
void fusion_float_write (float *p, float f){ p[LARGE] = f; }
void fusion_double_write (double *p, double d){ p[LARGE] = d; }
/* { dg-final { scan-assembler "load fusion, type SF" } } */
/* { dg-final { scan-assembler "load fusion, type DF" } } */
/* { dg-final { scan-assembler "store fusion, type SF" } } */
/* { dg-final { scan-assembler "store fusion, type DF" } } */
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
int ismod (int a, int b) { return a%b; }
long lsmod (long a, long b) { return a%b; }
unsigned int iumod (unsigned int a, unsigned int b) { return a%b; }
unsigned long lumod (unsigned long a, unsigned long b) { return a%b; }
/* { dg-final { scan-assembler-times "modsw " 1 } } */
/* { dg-final { scan-assembler-times "modsd " 1 } } */
/* { dg-final { scan-assembler-times "moduw " 1 } } */
/* { dg-final { scan-assembler-times "modud " 1 } } */
/* { dg-final { scan-assembler-not "mullw " } } */
/* { dg-final { scan-assembler-not "mulld " } } */
/* { dg-final { scan-assembler-not "divw " } } */
/* { dg-final { scan-assembler-not "divd " } } */
/* { dg-final { scan-assembler-not "divwu " } } */
/* { dg-final { scan-assembler-not "divdu " } } */
/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
/* { dg-require-effective-target powerpc_p9modulo_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
/* { dg-options "-mcpu=power9 -O2" } */
int ismod (int a, int b) { return a%b; }
unsigned int iumod (unsigned int a, unsigned int b) { return a%b; }
/* { dg-final { scan-assembler-times "modsw " 1 } } */
/* { dg-final { scan-assembler-times "moduw " 1 } } */
/* { dg-final { scan-assembler-not "mullw " } } */
/* { dg-final { scan-assembler-not "divw " } } */
/* { dg-final { scan-assembler-not "divwu " } } */
......@@ -1616,7 +1616,9 @@ proc check_p8vector_hw_available { } {
return [check_cached_effective_target p8vector_hw_available {
# Some simulators are known to not support VSX/power8 instructions.
# For now, disable on Darwin
if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mpower8-vector"
......@@ -1635,6 +1637,112 @@ proc check_p8vector_hw_available { } {
}]
}
# Return 1 if the target supports executing power9 vector instructions, 0
# otherwise. Cache the result.
proc check_p9vector_hw_available { } {
return [check_cached_effective_target p9vector_hw_available {
# Some simulators are known to not support VSX/power8/power9
# instructions. For now, disable on Darwin.
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mpower9-vector"
check_runtime_nocache p9vector_hw_available {
int main()
{
long e = -1;
vector double v = (vector double) { 0.0, 0.0 };
asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
return e;
}
} $options
}
}]
}
# Return 1 if the target supports executing power9 modulo instructions, 0
# otherwise. Cache the result.
proc check_p9modulo_hw_available { } {
return [check_cached_effective_target p9modulo_hw_available {
# Some simulators are known to not support VSX/power8/power9
# instructions. For now, disable on Darwin.
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mmodulo"
check_runtime_nocache p9modulo_hw_available {
int main()
{
int i = 5, j = 3, r = -1;
asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
return (r == 2);
}
} $options
}
}]
}
# Return 1 if the target supports executing __float128 on PowerPC via software
# emulation, 0 otherwise. Cache the result.
proc check_ppc_float128_sw_available { } {
return [check_cached_effective_target ppc_float128_sw_available {
# Some simulators are known to not support VSX/power8/power9
# instructions. For now, disable on Darwin.
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mfloat128 -mvsx"
check_runtime_nocache ppc_float128_sw_available {
volatile __float128 x = 1.0q;
volatile __float128 y = 2.0q;
int main()
{
__float128 z = x + y;
return (z == 3.0q);
}
} $options
}
}]
}
# Return 1 if the target supports executing __float128 on PowerPC via power9
# hardware instructions, 0 otherwise. Cache the result.
proc check_ppc_float128_hw_available { } {
return [check_cached_effective_target ppc_float128_hw_available {
# Some simulators are known to not support VSX/power8/power9
# instructions. For now, disable on Darwin.
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mfloat128-hardware"
check_runtime_nocache ppc_float128_hw_available {
volatile __float128 x = 1.0q;
volatile __float128 y = 2.0q;
int main()
{
__float128 z = x + y;
__float128 w = -1.0q;
__asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y));
return ((z == 3.0q) && (z == w);
}
} $options
}
}]
}
# Return 1 if the target supports executing VSX instructions, 0
# otherwise. Cache the result.
......@@ -1642,7 +1750,9 @@ proc check_vsx_hw_available { } {
return [check_cached_effective_target vsx_hw_available {
# Some simulators are known to not support VSX instructions.
# For now, disable on Darwin
if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
if { [istarget powerpc-*-eabi]
|| [istarget powerpc*-*-eabispe]
|| [istarget *-*-darwin*]} {
expr 0
} else {
set options "-mvsx"
......@@ -3358,6 +3468,108 @@ proc check_effective_target_powerpc_p8vector_ok { } {
}
}
# Return 1 if this is a PowerPC target supporting -mpower9-vector
proc check_effective_target_powerpc_p9vector_ok { } {
if { ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
|| [istarget powerpc*-*-aix5.1*]
|| [istarget powerpc*-*-aix5.2*] } {
return 0
}
return [check_no_compiler_messages powerpc_p9vector_ok object {
int main (void) {
long e = -1;
vector double v = (vector double) { 0.0, 0.0 };
asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v));
return e;
}
} "-mpower9-vector"]
} else {
return 0
}
}
# Return 1 if this is a PowerPC target supporting -mmodulo
proc check_effective_target_powerpc_p9modulo_ok { } {
if { ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
|| [istarget powerpc*-*-aix5.1*]
|| [istarget powerpc*-*-aix5.2*] } {
return 0
}
return [check_no_compiler_messages powerpc_p9modulo_ok object {
int main (void) {
int i = 5, j = 3, r = -1;
asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j));
return (r == 2);
}
} "-mmodulo"]
} else {
return 0
}
}
# Return 1 if this is a PowerPC target supporting -mfloat128 via either
# software emulation on power7/power8 systems or hardware support on power9.
proc check_effective_target_powerpc_float128_sw_ok { } {
if { ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
|| [istarget powerpc*-*-aix5.1*]
|| [istarget powerpc*-*-aix5.2*] } {
return 0
}
return [check_no_compiler_messages powerpc_float128_sw_ok object {
volatile __float128 x = 1.0q;
volatile __float128 y = 2.0q;
int main() {
__float128 z = x + y;
return (z == 3.0q);
}
} "-mfloat128 -mvsx"]
} else {
return 0
}
}
# Return 1 if this is a PowerPC target supporting -mfloat128 via hardware
# support on power9.
proc check_effective_target_powerpc_float128_hw_ok { } {
if { ([istarget powerpc*-*-*]
&& ![istarget powerpc-*-linux*paired*])
|| [istarget rs6000-*-*] } {
# AltiVec is not supported on AIX before 5.3.
if { [istarget powerpc*-*-aix4*]
|| [istarget powerpc*-*-aix5.1*]
|| [istarget powerpc*-*-aix5.2*] } {
return 0
}
return [check_no_compiler_messages powerpc_float128_hw_ok object {
volatile __float128 x = 1.0q;
volatile __float128 y = 2.0q;
int main() {
__float128 z;
__asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y));
return (z == 3.0q);
}
} "-mfloat128-hardware"]
} else {
return 0
}
}
# Return 1 if this is a PowerPC target supporting -mvsx
proc check_effective_target_powerpc_vsx_ok { } {
......@@ -5459,6 +5671,10 @@ proc is-effective-target { arg } {
"vmx_hw" { set selected [check_vmx_hw_available] }
"vsx_hw" { set selected [check_vsx_hw_available] }
"p8vector_hw" { set selected [check_p8vector_hw_available] }
"p9vector_hw" { set selected [check_p9vector_hw_available] }
"p9modulo_hw" { set selected [check_p9modulo_hw_available] }
"ppc_float128_sw" { set selected [check_ppc_float128_sw_available] }
"ppc_float128_hw" { set selected [check_ppc_float128_hw_available] }
"ppc_recip_hw" { set selected [check_ppc_recip_hw_available] }
"dfp_hw" { set selected [check_dfp_hw_available] }
"htm_hw" { set selected [check_htm_hw_available] }
......@@ -5483,6 +5699,10 @@ proc is-effective-target-keyword { arg } {
"vmx_hw" { return 1 }
"vsx_hw" { return 1 }
"p8vector_hw" { return 1 }
"p9vector_hw" { return 1 }
"p9modulo_hw" { return 1 }
"ppc_float128_sw" { return 1 }
"ppc_float128_hw" { return 1 }
"ppc_recip_hw" { return 1 }
"dfp_hw" { return 1 }
"htm_hw" { return 1 }
......@@ -6186,7 +6406,9 @@ proc check_vect_support_and_set_flags { } {
}
lappend DEFAULT_VECTCFLAGS "-maltivec"
if [check_p8vector_hw_available] {
if [check_p9vector_hw_available] {
lappend DEFAULT_VECTCFLAGS "-mpower9-vector"
} elseif [check_p8vector_hw_available] {
lappend DEFAULT_VECTCFLAGS "-mpower8-vector"
} elseif [check_vsx_hw_available] {
lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment