Commit facb3fd7 by David S. Miller Committed by David S. Miller

Add support for more sparc VIS 3.0 instructions.

gcc/

	* config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB,
	UNSPEC_XMUL): New unspecs.
	(muldi3_v8plus): Use output_v8plus_mult.
	(*naddsf3, *nadddf3, *nmulsf3, *nmuldf3, *nmuldf3_extend):
	New VIS 3.0 combiner patterns.
	(fhaddsf_vis, fhadddf_vis, fhsubsf_vis, fhsubdf_vis,
	fnhaddsf_vis, fnhaddf_vis, umulxhi_vis, *umulxhi_sp64,
	umulxhi_v8plus, xmulx_vis, *xmulx_sp64, xmulx_v8plus,
	xmulxhi_vis, *xmulxhi_sp64, xmulxhi_v8plus): New VIS 3.0
	builtins patterns.
	* config/sparc/sparc.c (sparc_vis_init_builtins): Emit new
	builtins.
	(output_v8plus_mult): New function.
	* config/sparc/sparc-protos.h: Declare it.
	* config/sparc/visintrin.h (__vis_fhadds, __vis_fhaddd,
	__vis_fhsubs, __vis_fhsubd, __vis_fnhadds, __vis_fnhaddd,
	__vis_umulxhi, __vis_xmulx, __vis_xmulxhi): New intrinsics.
	* doc/extend.texi: Document new builtins.

gcc/testsuite/

	* gcc.target/sparc/fhalve.c: New test.
	* gcc.target/sparc/fnegop.c: New test.
	* gcc.target/sparc/xmul.c: New test.

From-SVN: r179535
parent 9a83cdf7
2011-10-04 David S. Miller <davem@davemloft.net>
* config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB,
UNSPEC_XMUL): New unspecs.
(muldi3_v8plus): Use output_v8plus_mult.
(*naddsf3, *nadddf3, *nmulsf3, *nmuldf3, *nmuldf3_extend):
New VIS 3.0 combiner patterns.
(fhaddsf_vis, fhadddf_vis, fhsubsf_vis, fhsubdf_vis,
fnhaddsf_vis, fnhaddf_vis, umulxhi_vis, *umulxhi_sp64,
umulxhi_v8plus, xmulx_vis, *xmulx_sp64, xmulx_v8plus,
xmulxhi_vis, *xmulxhi_sp64, xmulxhi_v8plus): New VIS 3.0
builtins patterns.
* config/sparc/sparc.c (sparc_vis_init_builtins): Emit new
builtins.
(output_v8plus_mult): New function.
* config/sparc/sparc-protos.h: Declare it.
* config/sparc/visintrin.h (__vis_fhadds, __vis_fhaddd,
__vis_fhsubs, __vis_fhsubd, __vis_fnhadds, __vis_fnhaddd,
__vis_umulxhi, __vis_xmulx, __vis_xmulxhi): New intrinsics.
* doc/extend.texi: Document new builtins.
2011-10-04 Richard Henderson <rth@redhat.com>
* c-typeck.c (c_build_vec_shuffle_expr): Fix uninitialized variable.
......@@ -105,6 +105,7 @@ extern int v9_regcmp_p (enum rtx_code);
extern int sparc_check_64 (rtx, rtx);
extern rtx gen_df_reg (rtx, int);
extern void sparc_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx);
extern const char *output_v8plus_mult (rtx, rtx *, const char *);
#endif /* RTX_CODE */
#endif /* __SPARC_PROTOS_H__ */
......@@ -9236,6 +9236,12 @@ sparc_vis_init_builtins (void)
void_type_node, 0);
tree void_ftype_si = build_function_type_list (void_type_node,
intSI_type_node, 0);
tree sf_ftype_sf_sf = build_function_type_list (float_type_node,
float_type_node,
float_type_node, 0);
tree df_ftype_df_df = build_function_type_list (double_type_node,
double_type_node,
double_type_node, 0);
/* Packing and expanding vectors. */
def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis,
......@@ -9552,6 +9558,26 @@ sparc_vis_init_builtins (void)
def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8si_vis,
si_ftype_v8qi_v8qi);
}
def_builtin_const ("__builtin_vis_fhadds", CODE_FOR_fhaddsf_vis,
sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fhaddd", CODE_FOR_fhadddf_vis,
df_ftype_df_df);
def_builtin_const ("__builtin_vis_fhsubs", CODE_FOR_fhsubsf_vis,
sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fhsubd", CODE_FOR_fhsubdf_vis,
df_ftype_df_df);
def_builtin_const ("__builtin_vis_fnhadds", CODE_FOR_fnhaddsf_vis,
sf_ftype_sf_sf);
def_builtin_const ("__builtin_vis_fnhaddd", CODE_FOR_fnhadddf_vis,
df_ftype_df_df);
def_builtin_const ("__builtin_vis_umulxhi", CODE_FOR_umulxhi_vis,
di_ftype_di_di);
def_builtin_const ("__builtin_vis_xmulx", CODE_FOR_xmulx_vis,
di_ftype_di_di);
def_builtin_const ("__builtin_vis_xmulxhi", CODE_FOR_xmulxhi_vis,
di_ftype_di_di);
}
}
......@@ -10738,4 +10764,77 @@ sparc_preferred_reload_class (rtx x, reg_class_t rclass)
return rclass;
}
const char *
output_v8plus_mult (rtx insn, rtx *operands, const char *name)
{
char mulstr[32];
gcc_assert (! TARGET_ARCH64);
if (sparc_check_64 (operands[1], insn) <= 0)
output_asm_insn ("srl\t%L1, 0, %L1", operands);
if (which_alternative == 1)
output_asm_insn ("sllx\t%H1, 32, %H1", operands);
if (GET_CODE (operands[2]) == CONST_INT)
{
if (which_alternative == 1)
{
output_asm_insn ("or\t%L1, %H1, %H1", operands);
sprintf (mulstr, "%s\t%%H1, %%2, %%L0", name);
output_asm_insn (mulstr, operands);
return "srlx\t%L0, 32, %H0";
}
else
{
output_asm_insn ("sllx\t%H1, 32, %3", operands);
output_asm_insn ("or\t%L1, %3, %3", operands);
sprintf (mulstr, "%s\t%%3, %%2, %%3", name);
output_asm_insn (mulstr, operands);
output_asm_insn ("srlx\t%3, 32, %H0", operands);
return "mov\t%3, %L0";
}
}
else if (rtx_equal_p (operands[1], operands[2]))
{
if (which_alternative == 1)
{
output_asm_insn ("or\t%L1, %H1, %H1", operands);
sprintf (mulstr, "%s\t%%H1, %%H1, %%L0", name);
output_asm_insn (mulstr, operands);
return "srlx\t%L0, 32, %H0";
}
else
{
output_asm_insn ("sllx\t%H1, 32, %3", operands);
output_asm_insn ("or\t%L1, %3, %3", operands);
sprintf (mulstr, "%s\t%%3, %%3, %%3", name);
output_asm_insn (mulstr, operands);
output_asm_insn ("srlx\t%3, 32, %H0", operands);
return "mov\t%3, %L0";
}
}
if (sparc_check_64 (operands[2], insn) <= 0)
output_asm_insn ("srl\t%L2, 0, %L2", operands);
if (which_alternative == 1)
{
output_asm_insn ("or\t%L1, %H1, %H1", operands);
output_asm_insn ("sllx\t%H2, 32, %L1", operands);
output_asm_insn ("or\t%L2, %L1, %L1", operands);
sprintf (mulstr, "%s\t%%H1, %%L1, %%L0", name);
output_asm_insn (mulstr, operands);
return "srlx\t%L0, 32, %H0";
}
else
{
output_asm_insn ("sllx\t%H1, 32, %3", operands);
output_asm_insn ("sllx\t%H2, 32, %4", operands);
output_asm_insn ("or\t%L1, %3, %3", operands);
output_asm_insn ("or\t%L2, %4, %4", operands);
sprintf (mulstr, "%s\t%%3, %%4, %%3", name);
output_asm_insn (mulstr, operands);
output_asm_insn ("srlx\t%3, 32, %H0", operands);
return "mov\t%3, %L0";
}
}
#include "gt-sparc.h"
......@@ -627,4 +627,67 @@ __vis_fucmpeq8 (__v8qi __A, __v8qi __B)
return __builtin_vis_fucmpeq8 (__A, __B);
}
extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fhadds (float __A, float __B)
{
return __builtin_vis_fhadds (__A, __B);
}
extern __inline double
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fhaddd (double __A, double __B)
{
return __builtin_vis_fhaddd (__A, __B);
}
extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fhsubs (float __A, float __B)
{
return __builtin_vis_fhsubs (__A, __B);
}
extern __inline double
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fhsubd (double __A, double __B)
{
return __builtin_vis_fhsubd (__A, __B);
}
extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fnhadds (float __A, float __B)
{
return __builtin_vis_fnhadds (__A, __B);
}
extern __inline double
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_fnhaddd (double __A, double __B)
{
return __builtin_vis_fnhaddd (__A, __B);
}
extern __inline __i64
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_umulxhi (__i64 __A, __i64 __B)
{
return __builtin_vis_umulxhi (__A, __B);
}
extern __inline __i64
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_xmulx (__i64 __A, __i64 __B)
{
return __builtin_vis_xmulx (__A, __B);
}
extern __inline __i64
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_xmulxhi (__i64 __A, __i64 __B)
{
return __builtin_vis_xmulxhi (__A, __B);
}
#endif /* _VISINTRIN_H_INCLUDED */
......@@ -13099,6 +13099,17 @@ long __builtin_vis_fucmple8 (v8qi, v8qi);
long __builtin_vis_fucmpne8 (v8qi, v8qi);
long __builtin_vis_fucmpgt8 (v8qi, v8qi);
long __builtin_vis_fucmpeq8 (v8qi, v8qi);
float __builtin_vis_fhadds (float, float);
double __builtin_vis_fhaddd (double, double);
float __builtin_vis_fhsubs (float, float);
double __builtin_vis_fhsubd (double, double);
float __builtin_vis_fnhadds (float, float);
double __builtin_vis_fnhaddd (double, double);
int64_t __builtin_vis_umulxhi (int64_t, int64_t);
int64_t __builtin_vis_xmulx (int64_t, int64_t);
int64_t __builtin_vis_xmulxhi (int64_t, int64_t);
@end smallexample
@node SPU Built-in Functions
......
2011-10-04 David S. Miller <davem@davemloft.net>
* gcc.target/sparc/fhalve.c: New test.
* gcc.target/sparc/fnegop.c: New test.
* gcc.target/sparc/xmul.c: New test.
2011-10-04 Janus Weil <janus@gcc.gnu.org>
PR fortran/35831
......
/* { dg-do compile } */
/* { dg-options "-mcpu=niagara3 -mvis" } */
float test_fhadds (float x, float y)
{
return __builtin_vis_fhadds (x, y);
}
double test_fhaddd (double x, double y)
{
return __builtin_vis_fhaddd (x, y);
}
float test_fhsubs (float x, float y)
{
return __builtin_vis_fhsubs (x, y);
}
double test_fhsubd (double x, double y)
{
return __builtin_vis_fhsubd (x, y);
}
float test_fnhadds (float x, float y)
{
return __builtin_vis_fnhadds (x, y);
}
double test_fnhaddd (double x, double y)
{
return __builtin_vis_fnhaddd (x, y);
}
/* { dg-final { scan-assembler "fhadds\t%" } } */
/* { dg-final { scan-assembler "fhaddd\t%" } } */
/* { dg-final { scan-assembler "fhsubs\t%" } } */
/* { dg-final { scan-assembler "fhsubd\t%" } } */
/* { dg-final { scan-assembler "fnhadds\t%" } } */
/* { dg-final { scan-assembler "fnhaddd\t%" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -mcpu=niagara3 -mvis" } */
float test_fnadds(float x, float y)
{
return -(x + y);
}
double test_fnaddd(double x, double y)
{
return -(x + y);
}
float test_fnmuls(float x, float y)
{
return -(x * y);
}
double test_fnmuld(double x, double y)
{
return -(x * y);
}
double test_fnsmuld(float x, float y)
{
return -((double)x * (double)y);
}
/* { dg-final { scan-assembler "fnadds\t%" } } */
/* { dg-final { scan-assembler "fnaddd\t%" } } */
/* { dg-final { scan-assembler "fnmuls\t%" } } */
/* { dg-final { scan-assembler "fnmuld\t%" } } */
/* { dg-final { scan-assembler "fnsmuld\t%" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=niagara3 -mvis" } */
typedef long long int64_t;
int64_t test_umulxhi (int64_t x, int64_t y)
{
return __builtin_vis_umulxhi (x, y);
}
int64_t test_xmulx (int64_t x, int64_t y)
{
return __builtin_vis_xmulx (x, y);
}
int64_t test_xmulxhi (int64_t x, int64_t y)
{
return __builtin_vis_xmulxhi (x, y);
}
/* { dg-final { scan-assembler "umulxhi\t%" } } */
/* { dg-final { scan-assembler "xmulx\t%" } } */
/* { dg-final { scan-assembler "xmulxhi\t%" } } */
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