rs6000, vector integer multiply/divide/modulo instructions
2021-01-15 Carl Love <cel@us.ibm.com> gcc/ChangeLog: * config/rs6000/altivec.h (vec_mulh, vec_div, vec_dive, vec_mod): New defines. * config/rs6000/altivec.md (VIlong): Move define to file vsx.md. * config/rs6000/rs6000-builtin.def (DIVES_V4SI, DIVES_V2DI, DIVEU_V4SI, DIVEU_V2DI, DIVS_V4SI, DIVS_V2DI, DIVU_V4SI, DIVU_V2DI, MODS_V2DI, MODS_V4SI, MODU_V2DI, MODU_V4SI, MULHS_V2DI, MULHS_V4SI, MULHU_V2DI, MULHU_V4SI, MULLD_V2DI): Add builtin define. (MULH, DIVE, MOD): Add new BU_P10_OVERLOAD_2 definitions. * config/rs6000/rs6000-call.c (VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_VEC_DIVE, P10_BUILTIN_VEC_MOD, P10_BUILTIN_VEC_MULH): New overloaded definitions. (builtin_function_type) [P10V_BUILTIN_DIVEU_V4SI, P10V_BUILTIN_DIVEU_V2DI, P10V_BUILTIN_DIVU_V4SI, P10V_BUILTIN_DIVU_V2DI, P10V_BUILTIN_MODU_V2DI, P10V_BUILTIN_MODU_V4SI, P10V_BUILTIN_MULHU_V2DI, P10V_BUILTIN_MULHU_V4SI]: Add case statement for builtins. * config/rs6000/rs6000.md (bits): Add new attribute sizes V4SI, V2DI. * config/rs6000/vsx.md (VIlong): Moved from config/rs6000/altivec.md. (UNSPEC_VDIVES, UNSPEC_VDIVEU): New unspec definitions. (vsx_mul_v2di): Add if TARGET_POWER10 statement. (vsx_udiv_v2di): Add if TARGET_POWER10 statement. (dives_<mode>, diveu_<mode>, div<mode>3, uvdiv<mode>3, mods_<mode>, modu_<mode>, mulhs_<mode>, mulhu_<mode>, mulv2di3): Add define_insn, mode is VIlong. * doc/extend.texi (vec_mulh, vec_mul, vec_div, vec_dive, vec_mod): Add builtin descriptions. gcc/testsuite/ChangeLog: * gcc.target/powerpc/builtins-1-p10-runnable.c: New test file.
This commit is contained in:
parent
c029fcb568
commit
f1ad419ebf
8 changed files with 760 additions and 54 deletions
|
@ -750,6 +750,10 @@ __altivec_scalar_pred(vec_any_nle,
|
|||
#define vec_strir_p(a) __builtin_vec_strir_p (a)
|
||||
#define vec_stril_p(a) __builtin_vec_stril_p (a)
|
||||
|
||||
#define vec_mulh(a, b) __builtin_vec_mulh ((a), (b))
|
||||
#define vec_dive(a, b) __builtin_vec_dive ((a), (b))
|
||||
#define vec_mod(a, b) __builtin_vec_mod ((a), (b))
|
||||
|
||||
/* VSX Mask Manipulation builtin. */
|
||||
#define vec_genbm __builtin_vec_mtvsrbm
|
||||
#define vec_genhm __builtin_vec_mtvsrhm
|
||||
|
|
|
@ -193,8 +193,6 @@
|
|||
|
||||
;; Short vec int modes
|
||||
(define_mode_iterator VIshort [V8HI V16QI])
|
||||
;; Longer vec int modes for rotate/mask ops
|
||||
(define_mode_iterator VIlong [V2DI V4SI])
|
||||
;; Vec float modes
|
||||
(define_mode_iterator VF [V4SF])
|
||||
;; Vec modes, pity mode iterators are not composable
|
||||
|
|
|
@ -2883,6 +2883,24 @@ BU_P10V_AV_3 (VSRDB_V8HI, "vsrdb_v8hi", CONST, vsrdb_v8hi)
|
|||
BU_P10V_AV_3 (VSRDB_V4SI, "vsrdb_v4si", CONST, vsrdb_v4si)
|
||||
BU_P10V_AV_3 (VSRDB_V2DI, "vsrdb_v2di", CONST, vsrdb_v2di)
|
||||
|
||||
BU_P10V_AV_2 (DIVES_V4SI, "vdivesw", CONST, dives_v4si)
|
||||
BU_P10V_AV_2 (DIVES_V2DI, "vdivesd", CONST, dives_v2di)
|
||||
BU_P10V_AV_2 (DIVEU_V4SI, "vdiveuw", CONST, diveu_v4si)
|
||||
BU_P10V_AV_2 (DIVEU_V2DI, "vdiveud", CONST, diveu_v2di)
|
||||
BU_P10V_AV_2 (DIVS_V4SI, "vdivsw", CONST, divv4si3)
|
||||
BU_P10V_AV_2 (DIVS_V2DI, "vdivsd", CONST, divv2di3)
|
||||
BU_P10V_AV_2 (DIVU_V4SI, "vdivuw", CONST, udivv4si3)
|
||||
BU_P10V_AV_2 (DIVU_V2DI, "vdivud", CONST, udivv2di3)
|
||||
BU_P10V_AV_2 (MODS_V2DI, "vmodsd", CONST, mods_v2di)
|
||||
BU_P10V_AV_2 (MODS_V4SI, "vmodsw", CONST, mods_v4si)
|
||||
BU_P10V_AV_2 (MODU_V2DI, "vmodud", CONST, modu_v2di)
|
||||
BU_P10V_AV_2 (MODU_V4SI, "vmoduw", CONST, modu_v4si)
|
||||
BU_P10V_AV_2 (MULHS_V2DI, "vmulhsd", CONST, mulhs_v2di)
|
||||
BU_P10V_AV_2 (MULHS_V4SI, "vmulhsw", CONST, mulhs_v4si)
|
||||
BU_P10V_AV_2 (MULHU_V2DI, "vmulhud", CONST, mulhu_v2di)
|
||||
BU_P10V_AV_2 (MULHU_V4SI, "vmulhuw", CONST, mulhu_v4si)
|
||||
BU_P10V_AV_2 (MULLD_V2DI, "vmulld", CONST, mulv2di3)
|
||||
|
||||
BU_P10V_VSX_1 (VXXSPLTIW_V4SI, "vxxspltiw_v4si", CONST, xxspltiw_v4si)
|
||||
BU_P10V_VSX_1 (VXXSPLTIW_V4SF, "vxxspltiw_v4sf", CONST, xxspltiw_v4sf)
|
||||
|
||||
|
@ -2958,6 +2976,9 @@ BU_P10_OVERLOAD_1 (VSTRIL_P, "stril_p")
|
|||
BU_P10_OVERLOAD_1 (XVTLSBB_ZEROS, "xvtlsbb_all_zeros")
|
||||
BU_P10_OVERLOAD_1 (XVTLSBB_ONES, "xvtlsbb_all_ones")
|
||||
|
||||
BU_P10_OVERLOAD_2 (MULH, "mulh")
|
||||
BU_P10_OVERLOAD_2 (DIVE, "dive")
|
||||
BU_P10_OVERLOAD_2 (MOD, "mod")
|
||||
|
||||
BU_P10_OVERLOAD_1 (MTVSRBM, "mtvsrbm")
|
||||
BU_P10_OVERLOAD_1 (MTVSRHM, "mtvsrhm")
|
||||
|
|
|
@ -1069,6 +1069,40 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
|||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
|
||||
|
||||
{ VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_DIVS_V4SI,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
|
||||
{ VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_DIVU_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, 0 },
|
||||
{ VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_DIVS_V2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||
{ VSX_BUILTIN_VEC_DIV, P10V_BUILTIN_DIVU_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, 0 },
|
||||
|
||||
{ P10_BUILTIN_VEC_DIVE, P10V_BUILTIN_DIVES_V4SI,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_DIVE, P10V_BUILTIN_DIVEU_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_DIVE, P10V_BUILTIN_DIVES_V2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||
{ P10_BUILTIN_VEC_DIVE, P10V_BUILTIN_DIVEU_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, 0 },
|
||||
|
||||
{ P10_BUILTIN_VEC_MOD, P10V_BUILTIN_MODS_V4SI,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_MOD, P10V_BUILTIN_MODU_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_MOD, P10V_BUILTIN_MODS_V2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||
{ P10_BUILTIN_VEC_MOD, P10V_BUILTIN_MODU_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, 0 },
|
||||
|
||||
{ VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP,
|
||||
RS6000_BTI_V2DF, RS6000_BTI_V2DI, 0, 0 },
|
||||
{ VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVUXDDP,
|
||||
|
@ -1909,6 +1943,17 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
|||
RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB,
|
||||
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
|
||||
{ P10_BUILTIN_VEC_MULH, P10V_BUILTIN_MULHS_V4SI,
|
||||
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_MULH, P10V_BUILTIN_MULHU_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
|
||||
RS6000_BTI_unsigned_V4SI, 0 },
|
||||
{ P10_BUILTIN_VEC_MULH, P10V_BUILTIN_MULHS_V2DI,
|
||||
RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||||
{ P10_BUILTIN_VEC_MULH, P10V_BUILTIN_MULHU_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
|
||||
RS6000_BTI_unsigned_V2DI, 0 },
|
||||
|
||||
{ ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB,
|
||||
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
|
||||
{ ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB,
|
||||
|
@ -14438,6 +14483,14 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
|
|||
case P10V_BUILTIN_XXGENPCVM_V8HI:
|
||||
case P10V_BUILTIN_XXGENPCVM_V4SI:
|
||||
case P10V_BUILTIN_XXGENPCVM_V2DI:
|
||||
case P10V_BUILTIN_DIVEU_V4SI:
|
||||
case P10V_BUILTIN_DIVEU_V2DI:
|
||||
case P10V_BUILTIN_DIVU_V4SI:
|
||||
case P10V_BUILTIN_DIVU_V2DI:
|
||||
case P10V_BUILTIN_MODU_V2DI:
|
||||
case P10V_BUILTIN_MODU_V4SI:
|
||||
case P10V_BUILTIN_MULHU_V2DI:
|
||||
case P10V_BUILTIN_MULHU_V4SI:
|
||||
h.uns_p[0] = 1;
|
||||
h.uns_p[1] = 1;
|
||||
h.uns_p[2] = 1;
|
||||
|
|
|
@ -668,9 +668,10 @@
|
|||
(V4SI "du")
|
||||
(V2DI "d")])
|
||||
|
||||
;; How many bits in this mode?
|
||||
;; How many bits (per element) in this mode?
|
||||
(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
|
||||
(SF "32") (DF "64")])
|
||||
(SF "32") (DF "64")
|
||||
(V4SI "32") (V2DI "64")])
|
||||
|
||||
; DImode bits
|
||||
(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
|
||||
|
|
|
@ -267,6 +267,10 @@
|
|||
(define_mode_iterator VSX_MM [V16QI V8HI V4SI V2DI V1TI])
|
||||
(define_mode_iterator VSX_MM4 [V16QI V8HI V4SI V2DI])
|
||||
|
||||
;; Longer vec int modes for rotate/mask ops
|
||||
;; and Vector Integer Multiply/Divide/Modulo Instructions
|
||||
(define_mode_iterator VIlong [V2DI V4SI])
|
||||
|
||||
;; Constants for creating unspecs
|
||||
(define_c_enum "unspec"
|
||||
[UNSPEC_VSX_CONCAT
|
||||
|
@ -363,6 +367,8 @@
|
|||
UNSPEC_INSERTR
|
||||
UNSPEC_REPLACE_ELT
|
||||
UNSPEC_REPLACE_UN
|
||||
UNSPEC_VDIVES
|
||||
UNSPEC_VDIVEU
|
||||
])
|
||||
|
||||
(define_int_iterator XVCVBF16 [UNSPEC_VSX_XVCVSPBF16
|
||||
|
@ -1623,28 +1629,35 @@
|
|||
rtx op0 = operands[0];
|
||||
rtx op1 = operands[1];
|
||||
rtx op2 = operands[2];
|
||||
rtx op3 = gen_reg_rtx (DImode);
|
||||
rtx op4 = gen_reg_rtx (DImode);
|
||||
rtx op5 = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_muldi3 (op5, op3, op4));
|
||||
|
||||
if (TARGET_POWER10)
|
||||
emit_insn (gen_mulv2di3 (op0, op1, op2) );
|
||||
|
||||
else
|
||||
{
|
||||
rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
|
||||
emit_move_insn (op5, ret);
|
||||
rtx op3 = gen_reg_rtx (DImode);
|
||||
rtx op4 = gen_reg_rtx (DImode);
|
||||
rtx op5 = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_muldi3 (op5, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
|
||||
emit_move_insn (op5, ret);
|
||||
}
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_muldi3 (op3, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
|
||||
emit_move_insn (op3, ret);
|
||||
}
|
||||
emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||||
}
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_muldi3 (op3, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false);
|
||||
emit_move_insn (op3, ret);
|
||||
}
|
||||
emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "mul")])
|
||||
|
@ -1718,37 +1731,46 @@
|
|||
rtx op0 = operands[0];
|
||||
rtx op1 = operands[1];
|
||||
rtx op2 = operands[2];
|
||||
rtx op3 = gen_reg_rtx (DImode);
|
||||
rtx op4 = gen_reg_rtx (DImode);
|
||||
rtx op5 = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_udivdi3 (op5, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||
rtx target = emit_library_call_value (libfunc,
|
||||
op5, LCT_NORMAL, DImode,
|
||||
op3, DImode,
|
||||
op4, DImode);
|
||||
emit_move_insn (op5, target);
|
||||
}
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_udivdi3 (op3, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||
rtx target = emit_library_call_value (libfunc,
|
||||
op3, LCT_NORMAL, DImode,
|
||||
op3, DImode,
|
||||
op4, DImode);
|
||||
emit_move_insn (op3, target);
|
||||
}
|
||||
emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||||
DONE;
|
||||
|
||||
if (TARGET_POWER10)
|
||||
emit_insn (gen_udivv2di3 (op0, op1, op2) );
|
||||
else
|
||||
{
|
||||
rtx op3 = gen_reg_rtx (DImode);
|
||||
rtx op4 = gen_reg_rtx (DImode);
|
||||
rtx op5 = gen_reg_rtx (DImode);
|
||||
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||||
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_udivdi3 (op5, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||
rtx target = emit_library_call_value (libfunc,
|
||||
op5, LCT_NORMAL, DImode,
|
||||
op3, DImode,
|
||||
op4, DImode);
|
||||
emit_move_insn (op5, target);
|
||||
}
|
||||
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||||
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||||
|
||||
if (TARGET_POWERPC64)
|
||||
emit_insn (gen_udivdi3 (op3, op3, op4));
|
||||
else
|
||||
{
|
||||
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||||
rtx target = emit_library_call_value (libfunc,
|
||||
op3, LCT_NORMAL, DImode,
|
||||
op3, DImode,
|
||||
op4, DImode);
|
||||
emit_move_insn (op3, target);
|
||||
}
|
||||
emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||||
}
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "div")])
|
||||
|
||||
|
@ -6104,3 +6126,92 @@
|
|||
"TARGET_POWER10"
|
||||
"vexpand<wd>m %0,%1"
|
||||
[(set_attr "type" "vecsimple")])
|
||||
|
||||
(define_insn "dives_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(unspec:VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")]
|
||||
UNSPEC_VDIVES))]
|
||||
"TARGET_POWER10"
|
||||
"vdives<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "diveu_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(unspec:VIlong [(match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")]
|
||||
UNSPEC_VDIVEU))]
|
||||
"TARGET_POWER10"
|
||||
"vdiveu<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "div<mode>3"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(div:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
|
||||
"TARGET_POWER10"
|
||||
"vdivs<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "udiv<mode>3"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(udiv:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
|
||||
"TARGET_POWER10"
|
||||
"vdivu<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "mods_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(mod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
|
||||
"TARGET_POWER10"
|
||||
"vmods<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "modu_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(umod:VIlong (match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")))]
|
||||
"TARGET_POWER10"
|
||||
"vmodu<wd> %0,%1,%2"
|
||||
[(set_attr "type" "vecdiv")
|
||||
(set_attr "size" "<bits>")])
|
||||
|
||||
(define_insn "mulhs_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(mult:VIlong (ashiftrt
|
||||
(match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(const_int 32))
|
||||
(ashiftrt
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")
|
||||
(const_int 32))))]
|
||||
"TARGET_POWER10"
|
||||
"vmulhs<wd> %0,%1,%2"
|
||||
[(set_attr "type" "veccomplex")])
|
||||
|
||||
(define_insn "mulhu_<mode>"
|
||||
[(set (match_operand:VIlong 0 "vsx_register_operand" "=v")
|
||||
(us_mult:VIlong (ashiftrt
|
||||
(match_operand:VIlong 1 "vsx_register_operand" "v")
|
||||
(const_int 32))
|
||||
(ashiftrt
|
||||
(match_operand:VIlong 2 "vsx_register_operand" "v")
|
||||
(const_int 32))))]
|
||||
"TARGET_POWER10"
|
||||
"vmulhu<wd> %0,%1,%2"
|
||||
[(set_attr "type" "veccomplex")])
|
||||
|
||||
;; Vector multiply low double word
|
||||
(define_insn "mulv2di3"
|
||||
[(set (match_operand:V2DI 0 "vsx_register_operand" "=v")
|
||||
(mult:V2DI (match_operand:V2DI 1 "vsx_register_operand" "v")
|
||||
(match_operand:V2DI 2 "vsx_register_operand" "v")))]
|
||||
"TARGET_POWER10"
|
||||
"vmulld %0,%1,%2"
|
||||
[(set_attr "type" "veccomplex")])
|
||||
|
|
|
@ -21642,6 +21642,126 @@ integer value between 0 and 255 inclusive.
|
|||
@exdent vector unsigned int vec_genpcvm (vector unsigned long long int,
|
||||
const int)
|
||||
@end smallexample
|
||||
|
||||
Vector Integer Multiply/Divide/Modulo
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed int
|
||||
@exdent vec_mulh (vector signed int a, vector signed int b)
|
||||
@exdent vector unsigned int
|
||||
@exdent vec_mulh (vector unsigned int a, vector unsigned int b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 3, do the following. The integer
|
||||
value in word element @code{i} of a is multiplied by the integer value in word
|
||||
element @code{i} of b. The high-order 32 bits of the 64-bit product are placed
|
||||
into word element @code{i} of the vector returned.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed long long
|
||||
@exdent vec_mulh (vector signed long long a, vector signed long long b)
|
||||
@exdent vector unsigned long long
|
||||
@exdent vec_mulh (vector unsigned long long a, vector unsigned long long b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 1, do the following. The integer
|
||||
value in doubleword element @code{i} of a is multiplied by the integer value in
|
||||
doubleword element @code{i} of b. The high-order 64 bits of the 128-bit product
|
||||
are placed into doubleword element @code{i} of the vector returned.
|
||||
|
||||
@smallexample
|
||||
@exdent vector unsigned long long
|
||||
@exdent vec_mul (vector unsigned long long a, vector unsigned long long b)
|
||||
@exdent vector signed long long
|
||||
@exdent vec_mul (vector signed long long a, vector signed long long b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 1, do the following. The integer
|
||||
value in doubleword element @code{i} of a is multiplied by the integer value in
|
||||
doubleword element @code{i} of b. The low-order 64 bits of the 128-bit product
|
||||
are placed into doubleword element @code{i} of the vector returned.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed int
|
||||
@exdent vec_div (vector signed int a, vector signed int b)
|
||||
@exdent vector unsigned int
|
||||
@exdent vec_div (vector unsigned int a, vector unsigned int b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 3, do the following. The integer in
|
||||
word element @code{i} of a is divided by the integer in word element @code{i}
|
||||
of b. The unique integer quotient is placed into the word element @code{i} of
|
||||
the vector returned. If an attempt is made to perform any of the divisions
|
||||
<anything> ÷ 0 then the quotient is undefined.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed long long
|
||||
@exdent vec_div (vector signed long long a, vector signed long long b)
|
||||
@exdent vector unsigned long long
|
||||
@exdent vec_div (vector unsigned long long a, vector unsigned long long b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 1, do the following. The integer in
|
||||
doubleword element @code{i} of a is divided by the integer in doubleword
|
||||
element @code{i} of b. The unique integer quotient is placed into the
|
||||
doubleword element @code{i} of the vector returned. If an attempt is made to
|
||||
perform any of the divisions 0x8000_0000_0000_0000 ÷ -1 or <anything> ÷ 0 then
|
||||
the quotient is undefined.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed int
|
||||
@exdent vec_dive (vector signed int a, vector signed int b)
|
||||
@exdent vector unsigned int
|
||||
@exdent vec_dive (vector unsigned int a, vector unsigned int b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 3, do the following. The integer in
|
||||
word element @code{i} of a is shifted left by 32 bits, then divided by the
|
||||
integer in word element @code{i} of b. The unique integer quotient is placed
|
||||
into the word element @code{i} of the vector returned. If the quotient cannot
|
||||
be represented in 32 bits, or if an attempt is made to perform any of the
|
||||
divisions <anything> ÷ 0 then the quotient is undefined.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed long long
|
||||
@exdent vec_dive (vector signed long long a, vector signed long long b)
|
||||
@exdent vector unsigned long long
|
||||
@exdent vec_dive (vector unsigned long long a, vector unsigned long long b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 1, do the following. The integer in
|
||||
doubleword element @code{i} of a is shifted left by 64 bits, then divided by
|
||||
the integer in doubleword element @code{i} of b. The unique integer quotient is
|
||||
placed into the doubleword element @code{i} of the vector returned. If the
|
||||
quotient cannot be represented in 64 bits, or if an attempt is made to perform
|
||||
<anything> ÷ 0 then the quotient is undefined.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed int
|
||||
@exdent vec_mod (vector signed int a, vector signed int b)
|
||||
@exdent vector unsigned int
|
||||
@exdent vec_mod (vector unsigned int a, vector unsigned int b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 3, do the following. The integer in
|
||||
word element @code{i} of a is divided by the integer in word element @code{i}
|
||||
of b. The unique integer remainder is placed into the word element @code{i} of
|
||||
the vector returned. If an attempt is made to perform any of the divisions
|
||||
0x8000_0000 ÷ -1 or <anything> ÷ 0 then the remainder is undefined.
|
||||
|
||||
@smallexample
|
||||
@exdent vector signed long long
|
||||
@exdent vec_mod (vector signed long long a, vector signed long long b)
|
||||
@exdent vector unsigned long long
|
||||
@exdent vec_mod (vector unsigned long long a, vector unsigned long long b)
|
||||
@end smallexample
|
||||
|
||||
For each integer value @code{i} from 0 to 1, do the following. The integer in
|
||||
doubleword element @code{i} of a is divided by the integer in doubleword
|
||||
element @code{i} of b. The unique integer remainder is placed into the
|
||||
doubleword element @code{i} of the vector returned. If an attempt is made to
|
||||
perform <anything> ÷ 0 then the remainder is undefined.
|
||||
|
||||
Generate PCV from specified Mask size, as if implemented by the
|
||||
@code{xxgenpcvbm}, @code{xxgenpcvhm}, @code{xxgenpcvwm} instructions, where
|
||||
immediate value is either 0, 1, 2 or 3.
|
||||
|
|
398
gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c
Normal file
398
gcc/testsuite/gcc.target/powerpc/builtins-1-p10-runnable.c
Normal file
|
@ -0,0 +1,398 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target power10_hw } */
|
||||
/* { dg-options "-mdejagnu-cpu=power10 -save-temps" } */
|
||||
|
||||
/* { dg-final { scan-assembler-times {\mvdivsw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdivuw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdivsd\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdivud\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdivesw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdiveuw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdivesd\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvdiveud\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmodsw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmoduw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmodsd\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmodud\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmulhsw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmulhuw\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmulhsd\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmulhud\M} 1 } } */
|
||||
/* { dg-final { scan-assembler-times {\mvmulld\M} 2 } } */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <altivec.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
void abort (void);
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
vector int i_arg1, i_arg2;
|
||||
vector unsigned int u_arg1, u_arg2;
|
||||
vector long long int d_arg1, d_arg2;
|
||||
vector long long unsigned int ud_arg1, ud_arg2;
|
||||
|
||||
vector int vec_i_expected, vec_i_result;
|
||||
vector unsigned int vec_u_expected, vec_u_result;
|
||||
vector long long int vec_d_expected, vec_d_result;
|
||||
vector long long unsigned int vec_ud_expected, vec_ud_result;
|
||||
|
||||
/* Signed word divide */
|
||||
i_arg1 = (vector int){ 20, 40, 60, 80};
|
||||
i_arg2 = (vector int){ 2, 2, 2, 2};
|
||||
vec_i_expected = (vector int){10, 20, 30, 40};
|
||||
|
||||
vec_i_result = vec_div (i_arg1, i_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_i_expected[i] != vec_i_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_div signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_i_result[i], i, vec_i_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned word divide */
|
||||
u_arg1 = (vector unsigned int){ 20, 40, 60, 80};
|
||||
u_arg2 = (vector unsigned int){ 2, 2, 2, 2};
|
||||
vec_u_expected = (vector unsigned int){10, 20, 30, 40};
|
||||
|
||||
vec_u_result = vec_div (u_arg1, u_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_u_expected[i] != vec_u_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_div unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_u_result[i], i, vec_u_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed double word divide */
|
||||
d_arg1 = (vector long long){ 24, 68};
|
||||
d_arg2 = (vector long long){ 2, 2};
|
||||
vec_d_expected = (vector long long){12, 34};
|
||||
|
||||
vec_d_result = vec_div (d_arg1, d_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_d_expected[i] != vec_d_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_div signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_d_result[i], i, vec_d_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned double word divide */
|
||||
ud_arg1 = (vector unsigned long long){ 24, 68};
|
||||
ud_arg2 = (vector unsigned long long){ 2, 2};
|
||||
vec_ud_expected = (vector unsigned long long){12, 34};
|
||||
|
||||
vec_ud_result = vec_div (ud_arg1, ud_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_ud_expected[i] != vec_ud_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_div unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_ud_result[i], i, vec_ud_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Divide Extended signed word result = (arg1 << 32)/arg2 */
|
||||
i_arg1 = (vector int){ 2, 4, 6, 8};
|
||||
i_arg2 = (vector int){ 2048, 2048, 2048, 2048};
|
||||
vec_i_expected = (vector int){4194304, 8388608, 12582912, 16777216};
|
||||
|
||||
vec_i_result = vec_dive (i_arg1, i_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_i_expected[i] != vec_i_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_dive signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_i_result[i], i, vec_i_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Divide Extended unsigned word result = (arg1 << 32)/arg2 */
|
||||
u_arg1 = (vector unsigned int){ 2, 4, 6, 8};
|
||||
u_arg2 = (vector unsigned int){ 2048, 2048, 2048, 2048};
|
||||
vec_u_expected = (vector unsigned int){4194304, 8388608,
|
||||
12582912, 16777216};
|
||||
|
||||
vec_u_result = vec_dive (u_arg1, u_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_u_expected[i] != vec_u_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_dive unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_u_result[i], i, vec_u_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Divide Extended double signed esult = (arg1 << 64)/arg2 */
|
||||
d_arg1 = (vector long long int){ 2, 4};
|
||||
d_arg2 = (vector long long int){ 4294967296, 4294967296};
|
||||
|
||||
vec_d_expected = (vector long long int){8589934592, 17179869184};
|
||||
|
||||
vec_d_result = vec_dive (d_arg1, d_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_d_expected[i] != vec_d_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_dive signed result[%d] = %lld != "
|
||||
"expected[%d] = %lld\n",
|
||||
i, vec_d_result[i], i, vec_d_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Divide Extended double unsigned result = (arg1 << 64)/arg2 */
|
||||
ud_arg1 = (vector long long unsigned int){ 2, 4};
|
||||
ud_arg2 = (vector long long unsigned int){ 4294967296, 4294967296};
|
||||
|
||||
vec_ud_expected = (vector long long unsigned int){8589934592,
|
||||
17179869184};
|
||||
|
||||
vec_ud_result = vec_dive (ud_arg1, ud_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_ud_expected[i] != vec_ud_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_dive unsigned result[%d] = %lld != "
|
||||
"expected[%d] = %lld\n",
|
||||
i, vec_ud_result[i], i, vec_ud_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed word modulo */
|
||||
i_arg1 = (vector int){ 23, 45, 61, 89};
|
||||
i_arg2 = (vector int){ 2, 2, 2, 2};
|
||||
vec_i_expected = (vector int){1, 1, 1, 1};
|
||||
|
||||
vec_i_result = vec_mod (i_arg1, i_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_i_expected[i] != vec_i_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mod signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_i_result[i], i, vec_i_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned word modulo */
|
||||
u_arg1 = (vector unsigned int){ 25, 41, 67, 86};
|
||||
u_arg2 = (vector unsigned int){ 3, 3, 3, 3};
|
||||
vec_u_expected = (vector unsigned int){1, 2, 1, 2};
|
||||
|
||||
vec_u_result = vec_mod (u_arg1, u_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_u_expected[i] != vec_u_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mod unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_u_result[i], i, vec_u_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed double word modulo */
|
||||
d_arg1 = (vector long long){ 24, 68};
|
||||
d_arg2 = (vector long long){ 7, 7};
|
||||
vec_d_expected = (vector long long){3, 5};
|
||||
|
||||
vec_d_result = vec_mod (d_arg1, d_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_d_expected[i] != vec_d_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mod signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_d_result[i], i, vec_d_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned double word modulo */
|
||||
ud_arg1 = (vector unsigned long long){ 24, 68};
|
||||
ud_arg2 = (vector unsigned long long){ 8, 8};
|
||||
vec_ud_expected = (vector unsigned long long){0, 4};
|
||||
|
||||
vec_ud_result = vec_mod (ud_arg1, ud_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_ud_expected[i] != vec_ud_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vecmod unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_ud_result[i], i, vec_ud_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed word multiply high */
|
||||
i_arg1 = (vector int){ 2147483648, 2147483648, 2147483648, 2147483648 };
|
||||
i_arg2 = (vector int){ 2, 3, 4, 5};
|
||||
// vec_i_expected = (vector int){-1, -2, -2, -3};
|
||||
vec_i_expected = (vector int){1, -2, -2, -3};
|
||||
|
||||
vec_i_result = vec_mulh (i_arg1, i_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_i_expected[i] != vec_i_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mulh signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_i_result[i], i, vec_i_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned word multiply high */
|
||||
u_arg1 = (vector unsigned int){ 2147483648, 2147483648,
|
||||
2147483648, 2147483648 };
|
||||
u_arg2 = (vector unsigned int){ 4, 5, 6, 7 };
|
||||
vec_u_expected = (vector unsigned int){2, 2, 3, 3 };
|
||||
|
||||
vec_u_result = vec_mulh (u_arg1, u_arg2);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (vec_u_expected[i] != vec_u_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mulh unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_u_result[i], i, vec_u_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed double word multiply high */
|
||||
d_arg1 = (vector long long int){ 2305843009213693951,
|
||||
4611686018427387903 };
|
||||
d_arg2 = (vector long long int){ 12, 20 };
|
||||
vec_d_expected = (vector long long int){ 1, 4 };
|
||||
|
||||
vec_d_result = vec_mulh (d_arg1, d_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_d_expected[i] != vec_d_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mulh signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_d_result[i], i, vec_d_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned double word multiply high */
|
||||
ud_arg1 = (vector unsigned long long int){ 2305843009213693951,
|
||||
4611686018427387903 };
|
||||
ud_arg2 = (vector unsigned long long int){ 32, 10 };
|
||||
vec_ud_expected = (vector unsigned long long int){ 3, 2 };
|
||||
|
||||
vec_ud_result = vec_mulh (ud_arg1, ud_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_ud_expected[i] != vec_ud_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mulh unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_ud_result[i], i, vec_ud_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unsigned double word multiply low */
|
||||
ud_arg1 = (vector unsigned long long int){ 2048, 4096 };
|
||||
ud_arg2 = (vector unsigned long long int){ 2, 4 };
|
||||
vec_ud_expected = (vector unsigned long long int){ 4096, 16384 };
|
||||
|
||||
vec_ud_result = vec_mul (ud_arg1, ud_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_ud_expected[i] != vec_ud_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mul unsigned result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_ud_result[i], i, vec_ud_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Signed double word multiply low */
|
||||
d_arg1 = (vector signed long long int){ 2048, 4096 };
|
||||
d_arg2 = (vector signed long long int){ 2, 4 };
|
||||
vec_d_expected = (vector signed long long int){ 4096, 16384 };
|
||||
|
||||
vec_d_result = vec_mul (d_arg1, d_arg2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (vec_d_expected[i] != vec_d_result[i])
|
||||
#ifdef DEBUG
|
||||
printf("ERROR vec_mul signed result[%d] = %d != "
|
||||
"expected[%d] = %d\n",
|
||||
i, vec_d_result[i], i, vec_d_expected[i]);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue