Generate XXSPLTIDP for scalars on power10.
This patch implements XXSPLTIDP support for SF, and DF scalar constants. The previous patch added support for vector constants. This patch adds the support for SFmode and DFmode scalar constants. I added 2 new tests to test loading up SF and DF scalar constants. 2021-12-15 Michael Meissner <meissner@the-meissners.org> gcc/ * config/rs6000/rs6000.md (UNSPEC_XXSPLTIDP_CONST): New unspec. (UNSPEC_XXSPLTIW_CONST): New unspec. (movsf_hardfloat): Add support for generating XXSPLTIDP. (mov<mode>_hardfloat32): Likewise. (mov<mode>_hardfloat64): Likewise. (xxspltidp_<mode>_internal): New insns. (xxspltiw_<mode>_internal): New insns. (splitters for SF/DFmode): Add new splitters for XXSPLTIDP. gcc/testsuite/ * gcc.target/powerpc/vec-splat-constant-df.c: New test. * gcc.target/powerpc/vec-splat-constant-sf.c: New test.
This commit is contained in:
parent
8d443ac032
commit
575ad7700f
3 changed files with 199 additions and 18 deletions
|
@ -156,6 +156,8 @@
|
|||
UNSPEC_PEXTD
|
||||
UNSPEC_HASHST
|
||||
UNSPEC_HASHCHK
|
||||
UNSPEC_XXSPLTIDP_CONST
|
||||
UNSPEC_XXSPLTIW_CONST
|
||||
])
|
||||
|
||||
;;
|
||||
|
@ -7764,17 +7766,17 @@
|
|||
;;
|
||||
;; LWZ LFS LXSSP LXSSPX STFS STXSSP
|
||||
;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
|
||||
;; MR MT<x> MF<x> NOP
|
||||
;; MR MT<x> MF<x> NOP XXSPLTIDP
|
||||
|
||||
(define_insn "movsf_hardfloat"
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand"
|
||||
"=!r, f, v, wa, m, wY,
|
||||
Z, m, wa, !r, f, wa,
|
||||
!r, *c*l, !r, *h")
|
||||
!r, *c*l, !r, *h, wa")
|
||||
(match_operand:SF 1 "input_operand"
|
||||
"m, m, wY, Z, f, v,
|
||||
wa, r, j, j, f, wa,
|
||||
r, r, *h, 0"))]
|
||||
r, r, *h, 0, eP"))]
|
||||
"(register_operand (operands[0], SFmode)
|
||||
|| register_operand (operands[1], SFmode))
|
||||
&& TARGET_HARD_FLOAT
|
||||
|
@ -7796,15 +7798,16 @@
|
|||
mr %0,%1
|
||||
mt%0 %1
|
||||
mf%1 %0
|
||||
nop"
|
||||
nop
|
||||
#"
|
||||
[(set_attr "type"
|
||||
"load, fpload, fpload, fpload, fpstore, fpstore,
|
||||
fpstore, store, veclogical, integer, fpsimple, fpsimple,
|
||||
*, mtjmpr, mfjmpr, *")
|
||||
*, mtjmpr, mfjmpr, *, vecperm")
|
||||
(set_attr "isa"
|
||||
"*, *, p9v, p8v, *, p9v,
|
||||
p8v, *, *, *, *, *,
|
||||
*, *, *, *")])
|
||||
*, *, *, *, p10")])
|
||||
|
||||
;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
|
||||
;; FMR MR MT%0 MF%1 NOP
|
||||
|
@ -8064,18 +8067,18 @@
|
|||
|
||||
;; STFD LFD FMR LXSD STXSD
|
||||
;; LXSD STXSD XXLOR XXLXOR GPR<-0
|
||||
;; LWZ STW MR
|
||||
;; LWZ STW MR XXSPLTIDP
|
||||
|
||||
|
||||
(define_insn "*mov<mode>_hardfloat32"
|
||||
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
|
||||
"=m, d, d, <f64_p9>, wY,
|
||||
<f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
|
||||
Y, r, !r")
|
||||
Y, r, !r, wa")
|
||||
(match_operand:FMOVE64 1 "input_operand"
|
||||
"d, m, d, wY, <f64_p9>,
|
||||
Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
|
||||
r, Y, r"))]
|
||||
r, Y, r, eP"))]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT
|
||||
&& (gpc_reg_operand (operands[0], <MODE>mode)
|
||||
|| gpc_reg_operand (operands[1], <MODE>mode))"
|
||||
|
@ -8092,20 +8095,21 @@
|
|||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#"
|
||||
[(set_attr "type"
|
||||
"fpstore, fpload, fpsimple, fpload, fpstore,
|
||||
fpload, fpstore, veclogical, veclogical, two,
|
||||
store, load, two")
|
||||
store, load, two, vecperm")
|
||||
(set_attr "size" "64")
|
||||
(set_attr "length"
|
||||
"*, *, *, *, *,
|
||||
*, *, *, *, 8,
|
||||
8, 8, 8")
|
||||
8, 8, 8, *")
|
||||
(set_attr "isa"
|
||||
"*, *, *, p9v, p9v,
|
||||
p7v, p7v, *, *, *,
|
||||
*, *, *")])
|
||||
*, *, *, p10")])
|
||||
|
||||
;; STW LWZ MR G-const H-const F-const
|
||||
|
||||
|
@ -8132,19 +8136,19 @@
|
|||
;; STFD LFD FMR LXSD STXSD
|
||||
;; LXSDX STXSDX XXLOR XXLXOR LI 0
|
||||
;; STD LD MR MT{CTR,LR} MF{CTR,LR}
|
||||
;; NOP MFVSRD MTVSRD
|
||||
;; NOP MFVSRD MTVSRD XXSPLTIDP
|
||||
|
||||
(define_insn "*mov<mode>_hardfloat64"
|
||||
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
|
||||
"=m, d, d, <f64_p9>, wY,
|
||||
<f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
|
||||
YZ, r, !r, *c*l, !r,
|
||||
*h, r, <f64_dm>")
|
||||
*h, r, <f64_dm>, wa")
|
||||
(match_operand:FMOVE64 1 "input_operand"
|
||||
"d, m, d, wY, <f64_p9>,
|
||||
Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
|
||||
r, YZ, r, r, *h,
|
||||
0, <f64_dm>, r"))]
|
||||
0, <f64_dm>, r, eP"))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT
|
||||
&& (gpc_reg_operand (operands[0], <MODE>mode)
|
||||
|| gpc_reg_operand (operands[1], <MODE>mode))"
|
||||
|
@ -8166,18 +8170,19 @@
|
|||
mf%1 %0
|
||||
nop
|
||||
mfvsrd %0,%x1
|
||||
mtvsrd %x0,%1"
|
||||
mtvsrd %x0,%1
|
||||
#"
|
||||
[(set_attr "type"
|
||||
"fpstore, fpload, fpsimple, fpload, fpstore,
|
||||
fpload, fpstore, veclogical, veclogical, integer,
|
||||
store, load, *, mtjmpr, mfjmpr,
|
||||
*, mfvsr, mtvsr")
|
||||
*, mfvsr, mtvsr, vecperm")
|
||||
(set_attr "size" "64")
|
||||
(set_attr "isa"
|
||||
"*, *, *, p9v, p9v,
|
||||
p7v, p7v, *, *, *,
|
||||
*, *, *, *, *,
|
||||
*, p8v, p8v")])
|
||||
*, p8v, p8v, p10")])
|
||||
|
||||
;; STD LD MR MT<SPR> MF<SPR> G-const
|
||||
;; H-const F-const Special
|
||||
|
@ -8211,6 +8216,62 @@
|
|||
(set_attr "length"
|
||||
"*, *, *, *, *, 8,
|
||||
12, 16, *")])
|
||||
|
||||
;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
|
||||
;; constants that look like DFmode floating point values where both elements
|
||||
;; are the same. The constant has to be expressible as a SFmode constant that
|
||||
;; is not a SFmode denormal value.
|
||||
;;
|
||||
;; We don't need splitters for the 128-bit types, since the function
|
||||
;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
|
||||
(define_insn "xxspltidp_<mode>_internal"
|
||||
[(set (match_operand:SFDF 0 "register_operand" "=wa")
|
||||
(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
|
||||
UNSPEC_XXSPLTIDP_CONST))]
|
||||
"TARGET_POWER10"
|
||||
"xxspltidp %x0,%1"
|
||||
[(set_attr "type" "vecperm")
|
||||
(set_attr "prefixed" "yes")])
|
||||
|
||||
(define_insn "xxspltiw_<mode>_internal"
|
||||
[(set (match_operand:SFDF 0 "register_operand" "=wa")
|
||||
(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
|
||||
UNSPEC_XXSPLTIW_CONST))]
|
||||
"TARGET_POWER10"
|
||||
"xxspltiw %x0,%1"
|
||||
[(set_attr "type" "vecperm")
|
||||
(set_attr "prefixed" "yes")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SFDF 0 "vsx_register_operand")
|
||||
(match_operand:SFDF 1 "vsx_prefixed_constant"))]
|
||||
"TARGET_POWER10"
|
||||
[(pc)]
|
||||
{
|
||||
rtx dest = operands[0];
|
||||
rtx src = operands[1];
|
||||
vec_const_128bit_type vsx_const;
|
||||
|
||||
if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
|
||||
gcc_unreachable ();
|
||||
|
||||
unsigned imm = constant_generates_xxspltidp (&vsx_const);
|
||||
if (imm)
|
||||
{
|
||||
emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
|
||||
DONE;
|
||||
}
|
||||
|
||||
imm = constant_generates_xxspltiw (&vsx_const);
|
||||
if (imm)
|
||||
{
|
||||
emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
|
||||
DONE;
|
||||
}
|
||||
|
||||
else
|
||||
gcc_unreachable ();
|
||||
})
|
||||
|
||||
(define_expand "mov<mode>"
|
||||
[(set (match_operand:FMOVE128 0 "general_operand")
|
||||
|
|
60
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
Normal file
60
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target power10_ok } */
|
||||
/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Test generating DFmode constants with the ISA 3.1 (power10) XXSPLTIDP
|
||||
instruction. */
|
||||
|
||||
double
|
||||
scalar_double_0 (void)
|
||||
{
|
||||
return 0.0; /* XXSPLTIB or XXLXOR. */
|
||||
}
|
||||
|
||||
double
|
||||
scalar_double_1 (void)
|
||||
{
|
||||
return 1.0; /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
#ifndef __FAST_MATH__
|
||||
double
|
||||
scalar_double_m0 (void)
|
||||
{
|
||||
return -0.0; /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
double
|
||||
scalar_double_nan (void)
|
||||
{
|
||||
return __builtin_nan (""); /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
double
|
||||
scalar_double_inf (void)
|
||||
{
|
||||
return __builtin_inf (); /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
double
|
||||
scalar_double_m_inf (void) /* XXSPLTIDP. */
|
||||
{
|
||||
return - __builtin_inf ();
|
||||
}
|
||||
#endif
|
||||
|
||||
double
|
||||
scalar_double_pi (void)
|
||||
{
|
||||
return M_PI; /* PLFD. */
|
||||
}
|
||||
|
||||
double
|
||||
scalar_double_denorm (void)
|
||||
{
|
||||
return 0x1p-149f; /* PLFD. */
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\mxxspltidp\M} 5 } } */
|
60
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
Normal file
60
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target power10_ok } */
|
||||
/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Test generating SFmode constants with the ISA 3.1 (power10) XXSPLTIDP
|
||||
instruction. */
|
||||
|
||||
float
|
||||
scalar_float_0 (void)
|
||||
{
|
||||
return 0.0f; /* XXSPLTIB or XXLXOR. */
|
||||
}
|
||||
|
||||
float
|
||||
scalar_float_1 (void)
|
||||
{
|
||||
return 1.0f; /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
#ifndef __FAST_MATH__
|
||||
float
|
||||
scalar_float_m0 (void)
|
||||
{
|
||||
return -0.0f; /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
float
|
||||
scalar_float_nan (void)
|
||||
{
|
||||
return __builtin_nanf (""); /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
float
|
||||
scalar_float_inf (void)
|
||||
{
|
||||
return __builtin_inff (); /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
float
|
||||
scalar_float_m_inf (void) /* XXSPLTIDP. */
|
||||
{
|
||||
return - __builtin_inff ();
|
||||
}
|
||||
#endif
|
||||
|
||||
float
|
||||
scalar_float_pi (void)
|
||||
{
|
||||
return (float)M_PI; /* XXSPLTIDP. */
|
||||
}
|
||||
|
||||
float
|
||||
scalar_float_denorm (void)
|
||||
{
|
||||
return 0x1p-149f; /* PLFS. */
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\mxxspltidp\M} 6 } } */
|
Loading…
Add table
Reference in a new issue