constraints.md (wF constraint): Remove power9 fusion documentation.
[gcc] 2018-11-16 Michael Meissner <meissner@linux.ibm.com> * config/rs6000/constraints.md (wF constraint): Remove power9 fusion documentation. Just document wF's use for power8 fusion. * config/rs6000/predicates.md (p9_fusion_reg_operand): Delete. (fusion_gpr_addis): Delete power9 fusion support. Change power8 fusion support to require the upper 12 bits to be all 0's or all 1's. (fusion_gpr_mem_load): Add comment. (fusion_addis_mem_combo_load): Remove power9 fusion support. (fusion_addis_mem_combo_store): Delete. (fusion_offsettable_mem_operand): Delete. * config/rs6000/rs6000-cpus.def (ISA_2_7_MASKS_SERVER): Do not set power8 fusion here. (ISA_3_0_MASKS_SERVER): Delete power9 fusion. (POWERPC_MASKS): Delete power9 fusion. * config/rs6000/rs6000-protos.h (emit_fusion_load_store): Delete. (fusion_p9_p): Delete. (expand_fusion_p9_load): Delete. (expand_fusion_p9_store): Delete. (emit_fusion_p9_load): Delete. (emit_fusion_p9_store): Delete. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Delete power9 fusion support. (rs6000_option_override_internal): Set power8 fusion based on whether we are tuning for power8. Delete power9 fusion support. (rs6000_opt_masks): Delete -mpower9-fusion switch. (emit_fusion_load): Rename emit_fusion_load_store to emit_fusion_load, and drop fusion store support. Update callers. (emit_fusion_load_store): Likewise. (emit_fusion_gpr_load): Likewise. (fusion_p9_p): Delete. (expand_fusion_p9_load): Delete. (expand_fusion_p9_store): Delete. (emit_fusion_p9_load): Delete. (emit_fusion_p9_store): Delete. * config/rs6000/rs6000.md (UNSPEC_FUSION_P9): Delete. (GPR_FUSION): Delete. (FPR_FUSION): Delete. (power9 fusion peephole2s): Delete. (fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load): Delete. (fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store): Delete. (fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load): Delete. (fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store): Delete. (fusion_p9_<mode>_constant): Delete. * config/rs6000/rs6000.opt (-mpower9-fusion): Delete undocumented power9 fusion switch. * doc/md.texi (PowerPC constraints): Update wF constraint documentation for power8 fusion only. [gcc/testsuite] 2018-11-16 Michael Meissner <meissner@linux.ibm.com> * gcc.target/powerpc/fusion3.c: Delete. * gcc.target/powerpc/fusion4.c: Delete. From-SVN: r266220
This commit is contained in:
parent
a09ad34709
commit
2fbd3c3763
@ -1,3 +1,53 @@
|
||||
2018-11-16 Michael Meissner <meissner@linux.ibm.com>
|
||||
|
||||
* config/rs6000/constraints.md (wF constraint): Remove power9
|
||||
fusion documentation. Just document wF's use for power8 fusion.
|
||||
* config/rs6000/predicates.md (p9_fusion_reg_operand): Delete.
|
||||
(fusion_gpr_addis): Delete power9 fusion support. Change power8
|
||||
fusion support to require the upper 12 bits to be all 0's or all
|
||||
1's.
|
||||
(fusion_gpr_mem_load): Add comment.
|
||||
(fusion_addis_mem_combo_load): Remove power9 fusion support.
|
||||
(fusion_addis_mem_combo_store): Delete.
|
||||
(fusion_offsettable_mem_operand): Delete.
|
||||
* config/rs6000/rs6000-cpus.def (ISA_2_7_MASKS_SERVER): Do not set
|
||||
power8 fusion here.
|
||||
(ISA_3_0_MASKS_SERVER): Delete power9 fusion.
|
||||
(POWERPC_MASKS): Delete power9 fusion.
|
||||
* config/rs6000/rs6000-protos.h (emit_fusion_load_store): Delete.
|
||||
(fusion_p9_p): Delete.
|
||||
(expand_fusion_p9_load): Delete.
|
||||
(expand_fusion_p9_store): Delete.
|
||||
(emit_fusion_p9_load): Delete.
|
||||
(emit_fusion_p9_store): Delete.
|
||||
* config/rs6000/rs6000.c (rs6000_debug_reg_global): Delete power9
|
||||
fusion support.
|
||||
(rs6000_option_override_internal): Set power8 fusion based on
|
||||
whether we are tuning for power8. Delete power9 fusion support.
|
||||
(rs6000_opt_masks): Delete -mpower9-fusion switch.
|
||||
(emit_fusion_load): Rename emit_fusion_load_store to
|
||||
emit_fusion_load, and drop fusion store support. Update callers.
|
||||
(emit_fusion_load_store): Likewise.
|
||||
(emit_fusion_gpr_load): Likewise.
|
||||
(fusion_p9_p): Delete.
|
||||
(expand_fusion_p9_load): Delete.
|
||||
(expand_fusion_p9_store): Delete.
|
||||
(emit_fusion_p9_load): Delete.
|
||||
(emit_fusion_p9_store): Delete.
|
||||
* config/rs6000/rs6000.md (UNSPEC_FUSION_P9): Delete.
|
||||
(GPR_FUSION): Delete.
|
||||
(FPR_FUSION): Delete.
|
||||
(power9 fusion peephole2s): Delete.
|
||||
(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load): Delete.
|
||||
(fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store): Delete.
|
||||
(fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load): Delete.
|
||||
(fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store): Delete.
|
||||
(fusion_p9_<mode>_constant): Delete.
|
||||
* config/rs6000/rs6000.opt (-mpower9-fusion): Delete undocumented
|
||||
power9 fusion switch.
|
||||
* doc/md.texi (PowerPC constraints): Update wF constraint
|
||||
documentation for power8 fusion only.
|
||||
|
||||
2018-11-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/87475
|
||||
|
@ -154,7 +154,7 @@
|
||||
|
||||
;; Extended fusion store
|
||||
(define_memory_constraint "wF"
|
||||
"Memory operand suitable for power9 fusion load/stores"
|
||||
"Memory operand suitable for power8 GPR load fusion"
|
||||
(match_operand 0 "fusion_addis_mem_combo_load"))
|
||||
|
||||
(define_register_constraint "wH" "rs6000_constraints[RS6000_CONSTRAINT_wH]"
|
||||
|
@ -406,48 +406,6 @@
|
||||
return FP_REGNO_P (r);
|
||||
})
|
||||
|
||||
;; Return true if this is a register that can has D-form addressing (GPR,
|
||||
;; traditional FPR registers, and Altivec registers for scalars). Unlike
|
||||
;; power8 fusion, this fusion does not depend on putting the ADDIS instruction
|
||||
;; into the GPR register being loaded.
|
||||
(define_predicate "p9_fusion_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")
|
||||
@ -1691,13 +1649,9 @@
|
||||
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));
|
||||
/* Power8 only does the fusion if the top 12 bits of the addis value are all
|
||||
1's or 0's. */
|
||||
return (IN_RANGE (value >> 16, -16, 15));
|
||||
})
|
||||
|
||||
;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis
|
||||
@ -1730,6 +1684,8 @@
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* Do not allow SF/DFmode in GPR fusion. While the loads do occur, they
|
||||
are not common. */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -1762,14 +1718,13 @@
|
||||
;; 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.
|
||||
;; With P9 fusion, also match a fpr/vector load and float_extend
|
||||
(define_predicate "fusion_addis_mem_combo_load"
|
||||
(match_code "mem,zero_extend,float_extend")
|
||||
(match_code "mem,zero_extend")
|
||||
{
|
||||
rtx addr, base, offset;
|
||||
|
||||
/* Handle zero/float extend. */
|
||||
if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND)
|
||||
/* Handle zero extend. */
|
||||
if (GET_CODE (op) == ZERO_EXTEND)
|
||||
{
|
||||
op = XEXP (op, 0);
|
||||
mode = GET_MODE (op);
|
||||
@ -1792,20 +1747,8 @@
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* ISA 2.08/power8 only had fusion of GPR loads. */
|
||||
case E_SFmode:
|
||||
if (!TARGET_P9_FUSION)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* ISA 2.08/power8 only had fusion of GPR loads. Do not allow 64-bit
|
||||
DFmode in 32-bit if -msoft-float since it splits into two separate
|
||||
instructions. */
|
||||
case E_DFmode:
|
||||
if ((!TARGET_POWERPC64 && !TARGET_HARD_FLOAT) || !TARGET_P9_FUSION)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* Do not allow SF/DFmode in GPR fusion. While the loads do occur, they
|
||||
are not common. */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -1833,80 +1776,3 @@
|
||||
|
||||
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 E_QImode:
|
||||
case E_HImode:
|
||||
case E_SImode:
|
||||
case E_SFmode:
|
||||
break;
|
||||
|
||||
/* Do not fuse 64-bit DImode in 32-bit since it splits into two
|
||||
separate instructions. */
|
||||
case E_DImode:
|
||||
if (!TARGET_POWERPC64)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* Do not allow 64-bit DFmode in 32-bit if -msoft-float since it splits
|
||||
into two separate instructions. Do allow fusion if we have hardware
|
||||
floating point. */
|
||||
case E_DFmode:
|
||||
if (!TARGET_POWERPC64 && !TARGET_HARD_FLOAT)
|
||||
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;
|
||||
})
|
||||
|
||||
;; 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);
|
||||
})
|
||||
|
@ -44,9 +44,10 @@
|
||||
| OPTION_MASK_ALTIVEC \
|
||||
| OPTION_MASK_VSX)
|
||||
|
||||
/* For now, don't provide an embedded version of ISA 2.07. */
|
||||
/* For now, don't provide an embedded version of ISA 2.07. Do not set power8
|
||||
fusion here, instead set it in rs6000.c if we are tuning for a power8
|
||||
system. */
|
||||
#define ISA_2_7_MASKS_SERVER (ISA_2_6_MASKS_SERVER \
|
||||
| OPTION_MASK_P8_FUSION \
|
||||
| OPTION_MASK_P8_VECTOR \
|
||||
| OPTION_MASK_CRYPTO \
|
||||
| OPTION_MASK_DIRECT_MOVE \
|
||||
@ -60,7 +61,6 @@
|
||||
#define ISA_3_0_MASKS_SERVER (ISA_2_7_MASKS_SERVER \
|
||||
| OPTION_MASK_ISEL \
|
||||
| OPTION_MASK_MODULO \
|
||||
| OPTION_MASK_P9_FUSION \
|
||||
| OPTION_MASK_P9_MINMAX \
|
||||
| OPTION_MASK_P9_MISC \
|
||||
| OPTION_MASK_P9_VECTOR)
|
||||
@ -121,7 +121,6 @@
|
||||
| OPTION_MASK_NO_UPDATE \
|
||||
| OPTION_MASK_P8_FUSION \
|
||||
| OPTION_MASK_P8_VECTOR \
|
||||
| OPTION_MASK_P9_FUSION \
|
||||
| OPTION_MASK_P9_MINMAX \
|
||||
| OPTION_MASK_P9_MISC \
|
||||
| OPTION_MASK_P9_VECTOR \
|
||||
|
@ -91,13 +91,7 @@ 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);
|
||||
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 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx,
|
||||
enum reg_class);
|
||||
extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
|
||||
|
@ -2787,7 +2787,7 @@ rs6000_debug_reg_global (void)
|
||||
{
|
||||
char options[80];
|
||||
|
||||
strcpy (options, (TARGET_P9_FUSION) ? "power9" : "power8");
|
||||
strcpy (options, "power8");
|
||||
if (TARGET_P8_FUSION_SIGN)
|
||||
strcat (options, ", sign");
|
||||
|
||||
@ -4163,10 +4163,15 @@ rs6000_option_override_internal (bool global_init_p)
|
||||
rs6000_isa_flags |= OPTION_MASK_SAVE_TOC_INDIRECT;
|
||||
|
||||
/* Enable power8 fusion if we are tuning for power8, even if we aren't
|
||||
generating power8 instructions. */
|
||||
generating power8 instructions. Power9 does not optimize power8 fusion
|
||||
cases. */
|
||||
if (!(rs6000_isa_flags_explicit & OPTION_MASK_P8_FUSION))
|
||||
rs6000_isa_flags |= (processor_target_table[tune_index].target_enable
|
||||
& OPTION_MASK_P8_FUSION);
|
||||
{
|
||||
if (processor_target_table[tune_index].processor == PROCESSOR_POWER8)
|
||||
rs6000_isa_flags |= OPTION_MASK_P8_FUSION;
|
||||
else
|
||||
rs6000_isa_flags &= ~OPTION_MASK_P8_FUSION;
|
||||
}
|
||||
|
||||
/* Setting additional fusion flags turns on base fusion. */
|
||||
if (!TARGET_P8_FUSION && TARGET_P8_FUSION_SIGN)
|
||||
@ -4183,28 +4188,6 @@ rs6000_option_override_internal (bool global_init_p)
|
||||
rs6000_isa_flags |= OPTION_MASK_P8_FUSION;
|
||||
}
|
||||
|
||||
/* Power9 fusion is a superset over power8 fusion. */
|
||||
if (TARGET_P9_FUSION && !TARGET_P8_FUSION)
|
||||
{
|
||||
if (rs6000_isa_flags_explicit & OPTION_MASK_P8_FUSION)
|
||||
{
|
||||
/* We prefer to not mention undocumented options in
|
||||
error messages. However, if users have managed to select
|
||||
power9-fusion without selecting power8-fusion, they
|
||||
already know about undocumented flags. */
|
||||
error ("%qs requires %qs", "-mpower9-fusion", "-mpower8-fusion");
|
||||
rs6000_isa_flags &= ~OPTION_MASK_P9_FUSION;
|
||||
}
|
||||
else
|
||||
rs6000_isa_flags |= OPTION_MASK_P8_FUSION;
|
||||
}
|
||||
|
||||
/* Enable power9 fusion if we are tuning for power9, even if we aren't
|
||||
generating power9 instructions. */
|
||||
if (!(rs6000_isa_flags_explicit & OPTION_MASK_P9_FUSION))
|
||||
rs6000_isa_flags |= (processor_target_table[tune_index].target_enable
|
||||
& OPTION_MASK_P9_FUSION);
|
||||
|
||||
/* Power8 does not fuse sign extended loads with the addis. If we are
|
||||
optimizing at high levels for speed, convert a sign extended load into a
|
||||
zero extending load, and an explicit sign extension. */
|
||||
@ -36002,7 +35985,6 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
|
||||
{ "power8-fusion", OPTION_MASK_P8_FUSION, false, true },
|
||||
{ "power8-fusion-sign", OPTION_MASK_P8_FUSION_SIGN, false, true },
|
||||
{ "power8-vector", OPTION_MASK_P8_VECTOR, false, true },
|
||||
{ "power9-fusion", OPTION_MASK_P9_FUSION, false, true },
|
||||
{ "power9-minmax", OPTION_MASK_P9_MINMAX, false, true },
|
||||
{ "power9-misc", OPTION_MASK_P9_MISC, false, true },
|
||||
{ "power9-vector", OPTION_MASK_P9_VECTOR, false, true },
|
||||
@ -38106,14 +38088,13 @@ emit_fusion_addis (rtx target, rtx addis_value)
|
||||
/* Emit a D-form load or store instruction that is the second instruction
|
||||
of a fusion sequence. */
|
||||
|
||||
void
|
||||
emit_fusion_load_store (rtx load_store_reg, rtx addis_reg, rtx offset,
|
||||
const char *insn_str)
|
||||
static void
|
||||
emit_fusion_load (rtx load_reg, rtx addis_reg, rtx offset, const char *insn_str)
|
||||
{
|
||||
rtx fuse_ops[10];
|
||||
char insn_template[80];
|
||||
|
||||
fuse_ops[0] = load_store_reg;
|
||||
fuse_ops[0] = load_reg;
|
||||
fuse_ops[1] = addis_reg;
|
||||
|
||||
if (CONST_INT_P (offset) && satisfies_constraint_I (offset))
|
||||
@ -38251,367 +38232,12 @@ emit_fusion_gpr_load (rtx target, rtx mem)
|
||||
emit_fusion_addis (target, addis_value);
|
||||
|
||||
/* Emit the D-form load instruction. */
|
||||
emit_fusion_load_store (target, target, load_offset, load_str);
|
||||
emit_fusion_load (target, target, load_offset, load_str);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the peephole2 can combine a load/store involving a
|
||||
combination of an addis instruction and the memory operation. This was
|
||||
added to the ISA 3.0 (power9) hardware. */
|
||||
|
||||
bool
|
||||
fusion_p9_p (rtx addis_reg, /* register set via addis. */
|
||||
rtx addis_value, /* addis value. */
|
||||
rtx dest, /* destination (memory or register). */
|
||||
rtx src) /* source (register or memory). */
|
||||
{
|
||||
rtx addr, mem, offset;
|
||||
machine_mode mode = GET_MODE (src);
|
||||
|
||||
/* Validate arguments. */
|
||||
if (!base_reg_operand (addis_reg, GET_MODE (addis_reg)))
|
||||
return false;
|
||||
|
||||
if (!fusion_gpr_addis (addis_value, GET_MODE (addis_value)))
|
||||
return false;
|
||||
|
||||
/* Ignore extend operations that are part of the load. */
|
||||
if (GET_CODE (src) == FLOAT_EXTEND || GET_CODE (src) == ZERO_EXTEND)
|
||||
src = XEXP (src, 0);
|
||||
|
||||
/* Test for memory<-register or register<-memory. */
|
||||
if (fpr_reg_operand (src, mode) || int_reg_operand (src, mode))
|
||||
{
|
||||
if (!MEM_P (dest))
|
||||
return false;
|
||||
|
||||
mem = dest;
|
||||
}
|
||||
|
||||
else if (MEM_P (src))
|
||||
{
|
||||
if (!fpr_reg_operand (dest, mode) && !int_reg_operand (dest, mode))
|
||||
return false;
|
||||
|
||||
mem = src;
|
||||
}
|
||||
|
||||
else
|
||||
return false;
|
||||
|
||||
addr = XEXP (mem, 0); /* either PLUS or LO_SUM. */
|
||||
if (GET_CODE (addr) == PLUS)
|
||||
{
|
||||
if (!rtx_equal_p (addis_reg, XEXP (addr, 0)))
|
||||
return false;
|
||||
|
||||
return satisfies_constraint_I (XEXP (addr, 1));
|
||||
}
|
||||
|
||||
else if (GET_CODE (addr) == LO_SUM)
|
||||
{
|
||||
if (!rtx_equal_p (addis_reg, XEXP (addr, 0)))
|
||||
return false;
|
||||
|
||||
offset = XEXP (addr, 1);
|
||||
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 false;
|
||||
}
|
||||
|
||||
/* During the peephole2 pass, adjust and expand the insns for an extended fusion
|
||||
load sequence.
|
||||
|
||||
The operands are:
|
||||
operands[0] register set with addis
|
||||
operands[1] value set via addis
|
||||
operands[2] target register being loaded
|
||||
operands[3] D-form memory reference using operands[0].
|
||||
|
||||
This is similar to the fusion introduced with power8, except it scales to
|
||||
both loads/stores and does not require the result register to be the same as
|
||||
the base register. At the moment, we only do this if register set with addis
|
||||
is dead. */
|
||||
|
||||
void
|
||||
expand_fusion_p9_load (rtx *operands)
|
||||
{
|
||||
rtx tmp_reg = operands[0];
|
||||
rtx addis_value = operands[1];
|
||||
rtx target = operands[2];
|
||||
rtx orig_mem = operands[3];
|
||||
rtx new_addr, new_mem, orig_addr, offset, set, clobber, insn;
|
||||
enum rtx_code plus_or_lo_sum;
|
||||
machine_mode target_mode = GET_MODE (target);
|
||||
machine_mode extend_mode = target_mode;
|
||||
machine_mode ptr_mode = Pmode;
|
||||
enum rtx_code extend = UNKNOWN;
|
||||
|
||||
if (GET_CODE (orig_mem) == FLOAT_EXTEND || GET_CODE (orig_mem) == ZERO_EXTEND)
|
||||
{
|
||||
extend = GET_CODE (orig_mem);
|
||||
orig_mem = XEXP (orig_mem, 0);
|
||||
target_mode = GET_MODE (orig_mem);
|
||||
}
|
||||
|
||||
gcc_assert (MEM_P (orig_mem));
|
||||
|
||||
orig_addr = XEXP (orig_mem, 0);
|
||||
plus_or_lo_sum = GET_CODE (orig_addr);
|
||||
gcc_assert (plus_or_lo_sum == PLUS || plus_or_lo_sum == LO_SUM);
|
||||
|
||||
offset = XEXP (orig_addr, 1);
|
||||
new_addr = gen_rtx_fmt_ee (plus_or_lo_sum, ptr_mode, addis_value, offset);
|
||||
new_mem = replace_equiv_address_nv (orig_mem, new_addr, false);
|
||||
|
||||
if (extend != UNKNOWN)
|
||||
new_mem = gen_rtx_fmt_e (extend, extend_mode, new_mem);
|
||||
|
||||
new_mem = gen_rtx_UNSPEC (extend_mode, gen_rtvec (1, new_mem),
|
||||
UNSPEC_FUSION_P9);
|
||||
|
||||
set = gen_rtx_SET (target, new_mem);
|
||||
clobber = gen_rtx_CLOBBER (VOIDmode, tmp_reg);
|
||||
insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber));
|
||||
emit_insn (insn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* During the peephole2 pass, adjust and expand the insns for an extended fusion
|
||||
store sequence.
|
||||
|
||||
The operands are:
|
||||
operands[0] register set with addis
|
||||
operands[1] value set via addis
|
||||
operands[2] target D-form memory being stored to
|
||||
operands[3] register being stored
|
||||
|
||||
This is similar to the fusion introduced with power8, except it scales to
|
||||
both loads/stores and does not require the result register to be the same as
|
||||
the base register. At the moment, we only do this if register set with addis
|
||||
is dead. */
|
||||
|
||||
void
|
||||
expand_fusion_p9_store (rtx *operands)
|
||||
{
|
||||
rtx tmp_reg = operands[0];
|
||||
rtx addis_value = operands[1];
|
||||
rtx orig_mem = operands[2];
|
||||
rtx src = operands[3];
|
||||
rtx new_addr, new_mem, orig_addr, offset, set, clobber, insn, new_src;
|
||||
enum rtx_code plus_or_lo_sum;
|
||||
machine_mode target_mode = GET_MODE (orig_mem);
|
||||
machine_mode ptr_mode = Pmode;
|
||||
|
||||
gcc_assert (MEM_P (orig_mem));
|
||||
|
||||
orig_addr = XEXP (orig_mem, 0);
|
||||
plus_or_lo_sum = GET_CODE (orig_addr);
|
||||
gcc_assert (plus_or_lo_sum == PLUS || plus_or_lo_sum == LO_SUM);
|
||||
|
||||
offset = XEXP (orig_addr, 1);
|
||||
new_addr = gen_rtx_fmt_ee (plus_or_lo_sum, ptr_mode, addis_value, offset);
|
||||
new_mem = replace_equiv_address_nv (orig_mem, new_addr, false);
|
||||
|
||||
new_src = gen_rtx_UNSPEC (target_mode, gen_rtvec (1, src),
|
||||
UNSPEC_FUSION_P9);
|
||||
|
||||
set = gen_rtx_SET (new_mem, new_src);
|
||||
clobber = gen_rtx_CLOBBER (VOIDmode, tmp_reg);
|
||||
insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber));
|
||||
emit_insn (insn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return a string to fuse an addis instruction with a load using extended
|
||||
fusion. The address that is used is the logical address that was formed
|
||||
during peephole2: (lo_sum (high) (low-part))
|
||||
|
||||
The code is complicated, so we call output_asm_insn directly, and just
|
||||
return "". */
|
||||
|
||||
const char *
|
||||
emit_fusion_p9_load (rtx reg, rtx mem, rtx tmp_reg)
|
||||
{
|
||||
machine_mode mode = GET_MODE (reg);
|
||||
rtx hi;
|
||||
rtx lo;
|
||||
rtx addr;
|
||||
const char *load_string;
|
||||
int r;
|
||||
|
||||
if (GET_CODE (mem) == FLOAT_EXTEND || GET_CODE (mem) == ZERO_EXTEND)
|
||||
{
|
||||
mem = XEXP (mem, 0);
|
||||
mode = GET_MODE (mem);
|
||||
}
|
||||
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
gcc_assert (SUBREG_BYTE (reg) == 0);
|
||||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
|
||||
if (!REG_P (reg))
|
||||
fatal_insn ("emit_fusion_p9_load, bad reg #1", reg);
|
||||
|
||||
r = REGNO (reg);
|
||||
if (FP_REGNO_P (r))
|
||||
{
|
||||
if (mode == SFmode)
|
||||
load_string = "lfs";
|
||||
else if (mode == DFmode || mode == DImode)
|
||||
load_string = "lfd";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (ALTIVEC_REGNO_P (r) && TARGET_P9_VECTOR)
|
||||
{
|
||||
if (mode == SFmode)
|
||||
load_string = "lxssp";
|
||||
else if (mode == DFmode || mode == DImode)
|
||||
load_string = "lxsd";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (INT_REGNO_P (r))
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case E_QImode:
|
||||
load_string = "lbz";
|
||||
break;
|
||||
case E_HImode:
|
||||
load_string = "lhz";
|
||||
break;
|
||||
case E_SImode:
|
||||
case E_SFmode:
|
||||
load_string = "lwz";
|
||||
break;
|
||||
case E_DImode:
|
||||
case E_DFmode:
|
||||
if (!TARGET_POWERPC64)
|
||||
gcc_unreachable ();
|
||||
load_string = "ld";
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
else
|
||||
fatal_insn ("emit_fusion_p9_load, bad reg #2", reg);
|
||||
|
||||
if (!MEM_P (mem))
|
||||
fatal_insn ("emit_fusion_p9_load not MEM", mem);
|
||||
|
||||
addr = XEXP (mem, 0);
|
||||
fusion_split_address (addr, &hi, &lo);
|
||||
|
||||
/* Emit the addis instruction. */
|
||||
emit_fusion_addis (tmp_reg, hi);
|
||||
|
||||
/* Emit the D-form load instruction. */
|
||||
emit_fusion_load_store (reg, tmp_reg, lo, load_string);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Return a string to fuse an addis instruction with a store using extended
|
||||
fusion. The address that is used is the logical address that was formed
|
||||
during peephole2: (lo_sum (high) (low-part))
|
||||
|
||||
The code is complicated, so we call output_asm_insn directly, and just
|
||||
return "". */
|
||||
|
||||
const char *
|
||||
emit_fusion_p9_store (rtx mem, rtx reg, rtx tmp_reg)
|
||||
{
|
||||
machine_mode mode = GET_MODE (reg);
|
||||
rtx hi;
|
||||
rtx lo;
|
||||
rtx addr;
|
||||
const char *store_string;
|
||||
int r;
|
||||
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
gcc_assert (SUBREG_BYTE (reg) == 0);
|
||||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
|
||||
if (!REG_P (reg))
|
||||
fatal_insn ("emit_fusion_p9_store, bad reg #1", reg);
|
||||
|
||||
r = REGNO (reg);
|
||||
if (FP_REGNO_P (r))
|
||||
{
|
||||
if (mode == SFmode)
|
||||
store_string = "stfs";
|
||||
else if (mode == DFmode)
|
||||
store_string = "stfd";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (ALTIVEC_REGNO_P (r) && TARGET_P9_VECTOR)
|
||||
{
|
||||
if (mode == SFmode)
|
||||
store_string = "stxssp";
|
||||
else if (mode == DFmode || mode == DImode)
|
||||
store_string = "stxsd";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (INT_REGNO_P (r))
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case E_QImode:
|
||||
store_string = "stb";
|
||||
break;
|
||||
case E_HImode:
|
||||
store_string = "sth";
|
||||
break;
|
||||
case E_SImode:
|
||||
case E_SFmode:
|
||||
store_string = "stw";
|
||||
break;
|
||||
case E_DImode:
|
||||
case E_DFmode:
|
||||
if (!TARGET_POWERPC64)
|
||||
gcc_unreachable ();
|
||||
store_string = "std";
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
else
|
||||
fatal_insn ("emit_fusion_p9_store, bad reg #2", reg);
|
||||
|
||||
if (!MEM_P (mem))
|
||||
fatal_insn ("emit_fusion_p9_store not MEM", mem);
|
||||
|
||||
addr = XEXP (mem, 0);
|
||||
fusion_split_address (addr, &hi, &lo);
|
||||
|
||||
/* Emit the addis instruction. */
|
||||
emit_fusion_addis (tmp_reg, hi);
|
||||
|
||||
/* Emit the D-form load instruction. */
|
||||
emit_fusion_load_store (reg, tmp_reg, lo, store_string);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef RS6000_GLIBC_ATOMIC_FENV
|
||||
/* Function declarations for rs6000_atomic_assign_expand_fenv. */
|
||||
static tree atomic_hold_decl, atomic_clear_decl, atomic_update_decl;
|
||||
|
@ -136,7 +136,6 @@
|
||||
UNSPEC_LSQ
|
||||
UNSPEC_FUSION_GPR
|
||||
UNSPEC_STACK_CHECK
|
||||
UNSPEC_FUSION_P9
|
||||
UNSPEC_ADD_ROUND_TO_ODD
|
||||
UNSPEC_SUB_ROUND_TO_ODD
|
||||
UNSPEC_MUL_ROUND_TO_ODD
|
||||
@ -349,19 +348,6 @@
|
||||
; SImode or DImode, even if DImode doesn't fit in GPRs.
|
||||
(define_mode_iterator SDI [SI DI])
|
||||
|
||||
; Types that can be fused with an ADDIS instruction to load or store a GPR
|
||||
; register that has reg+offset addressing.
|
||||
(define_mode_iterator GPR_FUSION [QI
|
||||
HI
|
||||
SI
|
||||
(DI "TARGET_POWERPC64")
|
||||
SF
|
||||
(DF "TARGET_POWERPC64")])
|
||||
|
||||
; Types that can be fused with an ADDIS instruction to load or store a FPR
|
||||
; register that has reg+offset addressing.
|
||||
(define_mode_iterator FPR_FUSION [DI SF DF])
|
||||
|
||||
; The size of a pointer. Also, the size of the value that a record-condition
|
||||
; (one with a '.') will compare; and the size used for arithmetic carries.
|
||||
(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
|
||||
@ -13722,134 +13708,6 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
|
||||
;; ISA 3.0 (power9) fusion support
|
||||
;; Merge addis with floating load/store to FPRs (or GPRs).
|
||||
(define_peephole2
|
||||
[(set (match_operand:P 0 "base_reg_operand")
|
||||
(match_operand:P 1 "fusion_gpr_addis"))
|
||||
(set (match_operand:SFDF 2 "p9_fusion_reg_operand")
|
||||
(match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
|
||||
"TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
|
||||
&& fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
expand_fusion_p9_load (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:P 0 "base_reg_operand")
|
||||
(match_operand:P 1 "fusion_gpr_addis"))
|
||||
(set (match_operand:SFDF 2 "offsettable_mem_operand")
|
||||
(match_operand:SFDF 3 "p9_fusion_reg_operand"))]
|
||||
"TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
|
||||
&& fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
|
||||
&& !rtx_equal_p (operands[0], operands[3])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
expand_fusion_p9_store (operands);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:SDI 0 "int_reg_operand")
|
||||
(match_operand:SDI 1 "upper16_cint_operand"))
|
||||
(set (match_dup 0)
|
||||
(ior:SDI (match_dup 0)
|
||||
(match_operand:SDI 2 "u_short_cint_operand")))]
|
||||
"TARGET_P9_FUSION"
|
||||
[(set (match_dup 0)
|
||||
(unspec:SDI [(match_dup 1)
|
||||
(match_dup 2)] UNSPEC_FUSION_P9))])
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:SDI 0 "int_reg_operand")
|
||||
(match_operand:SDI 1 "upper16_cint_operand"))
|
||||
(set (match_operand:SDI 2 "int_reg_operand")
|
||||
(ior:SDI (match_dup 0)
|
||||
(match_operand:SDI 3 "u_short_cint_operand")))]
|
||||
"TARGET_P9_FUSION
|
||||
&& !rtx_equal_p (operands[0], operands[2])
|
||||
&& peep2_reg_dead_p (2, operands[0])"
|
||||
[(set (match_dup 2)
|
||||
(unspec:SDI [(match_dup 1)
|
||||
(match_dup 3)] UNSPEC_FUSION_P9))])
|
||||
|
||||
;; Fusion insns, created by the define_peephole2 above (and eventually by
|
||||
;; reload). Because we want to eventually have secondary_reload generate
|
||||
;; these, they have to have a single alternative that gives the register
|
||||
;; classes. This means we need to have separate gpr/fpr/altivec versions.
|
||||
(define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
|
||||
[(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
|
||||
(unspec:GPR_FUSION
|
||||
[(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
|
||||
UNSPEC_FUSION_P9))
|
||||
(clobber (match_operand:P 2 "base_reg_operand" "=b"))]
|
||||
"TARGET_P9_FUSION"
|
||||
{
|
||||
/* This insn is a secondary reload insn, which cannot have alternatives.
|
||||
If we are not loading up register 0, use the power8 fusion instead. */
|
||||
if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
|
||||
return emit_fusion_gpr_load (operands[0], operands[1]);
|
||||
|
||||
return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
|
||||
}
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
|
||||
[(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
|
||||
(unspec:GPR_FUSION
|
||||
[(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
|
||||
UNSPEC_FUSION_P9))
|
||||
(clobber (match_operand:P 2 "base_reg_operand" "=b"))]
|
||||
"TARGET_P9_FUSION"
|
||||
{
|
||||
return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
|
||||
}
|
||||
[(set_attr "type" "store")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
|
||||
[(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
|
||||
(unspec:FPR_FUSION
|
||||
[(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
|
||||
UNSPEC_FUSION_P9))
|
||||
(clobber (match_operand:P 2 "base_reg_operand" "=b"))]
|
||||
"TARGET_P9_FUSION"
|
||||
{
|
||||
return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
|
||||
}
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
|
||||
[(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
|
||||
(unspec:FPR_FUSION
|
||||
[(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
|
||||
UNSPEC_FUSION_P9))
|
||||
(clobber (match_operand:P 2 "base_reg_operand" "=b"))]
|
||||
"TARGET_P9_FUSION"
|
||||
{
|
||||
return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
|
||||
}
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*fusion_p9_<mode>_constant"
|
||||
[(set (match_operand:SDI 0 "int_reg_operand" "=r")
|
||||
(unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
|
||||
(match_operand:SDI 2 "u_short_cint_operand" "K")]
|
||||
UNSPEC_FUSION_P9))]
|
||||
"TARGET_P9_FUSION"
|
||||
{
|
||||
emit_fusion_addis (operands[0], operands[1]);
|
||||
return "ori %0,%0,%2";
|
||||
}
|
||||
[(set_attr "type" "two")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
|
||||
;; Optimize cases where we want to do a D-form load (register+offset) on
|
||||
;; ISA 2.06/2.07 to an Altivec register, and the register allocator
|
||||
|
@ -498,10 +498,6 @@ moptimize-swaps
|
||||
Target Undocumented Var(rs6000_optimize_swaps) Init(1) Save
|
||||
Analyze and remove doubleword swaps from VSX computations.
|
||||
|
||||
mpower9-fusion
|
||||
Target Undocumented Report Mask(P9_FUSION) Var(rs6000_isa_flags)
|
||||
Fuse certain operations together for better performance on power9.
|
||||
|
||||
mpower9-misc
|
||||
Target Undocumented Report Mask(P9_MISC) Var(rs6000_isa_flags)
|
||||
Use certain scalar instructions added in ISA 3.0.
|
||||
|
@ -3238,7 +3238,7 @@ Int constant that is the element number of the 64-bit scalar in a vector.
|
||||
Vector constant that can be loaded with the XXSPLTIB instruction.
|
||||
|
||||
@item wF
|
||||
Memory operand suitable for power9 fusion load/stores.
|
||||
Memory operand suitable for power8 GPR load fusion
|
||||
|
||||
@item wG
|
||||
Memory operand suitable for TOC fusion memory references.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2018-11-16 Michael Meissner <meissner@linux.ibm.com>
|
||||
|
||||
* gcc.target/powerpc/fusion3.c: Delete.
|
||||
* gcc.target/powerpc/fusion4.c: Delete.
|
||||
|
||||
2018-11-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/87475
|
||||
|
@ -1,18 +0,0 @@
|
||||
/* { 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 -dp" } */
|
||||
|
||||
#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 {fusion_vsx_[sd]i_sf_load} } } */
|
||||
/* { dg-final { scan-assembler {fusion_vsx_[sd]i_df_load} } } */
|
||||
/* { dg-final { scan-assembler {fusion_vsx_[sd]i_sf_store} } } */
|
||||
/* { dg-final { scan-assembler {fusion_vsx_[sd]i_df_store} } } */
|
@ -1,12 +0,0 @@
|
||||
/* { 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 -msoft-float -dp" } */
|
||||
|
||||
#define LARGE 0x12345
|
||||
|
||||
float fusion_float_read (float *p){ return p[LARGE]; }
|
||||
|
||||
void fusion_float_write (float *p, float f){ p[LARGE] = f; }
|
||||
|
||||
/* { dg-final { scan-assembler {fusion_gpr_[sd]i_sf_store} } } */
|
Loading…
Reference in New Issue
Block a user