8338021: Support new unsigned and saturating vector operators in VectorAPI
Reviewed-by: psandoz, epeter, sviswanathan
This commit is contained in:
parent
e659d9da5d
commit
52382e285f
@ -557,6 +557,14 @@ bool Assembler::needs_rex2(Register reg1, Register reg2, Register reg3) {
|
||||
return rex2;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
bool Assembler::needs_evex(XMMRegister reg1, XMMRegister reg2, XMMRegister reg3) {
|
||||
return (reg1->is_valid() && reg1->encoding() >= 16) ||
|
||||
(reg2->is_valid() && reg2->encoding() >= 16) ||
|
||||
(reg3->is_valid() && reg3->encoding() >= 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Assembler::needs_eevex(Register reg1, Register reg2, Register reg3) {
|
||||
return needs_rex2(reg1, reg2, reg3);
|
||||
}
|
||||
@ -3525,7 +3533,7 @@ void Assembler::vmaskmovpd(Address dst, XMMRegister src, XMMRegister mask, int v
|
||||
|
||||
// Move Unaligned EVEX enabled Vector (programmable : 8,16,32,64)
|
||||
void Assembler::evmovdqub(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
attributes.set_is_evex_instruction();
|
||||
@ -3542,7 +3550,7 @@ void Assembler::evmovdqub(XMMRegister dst, XMMRegister src, int vector_len) {
|
||||
}
|
||||
|
||||
void Assembler::evmovdqub(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -3562,7 +3570,7 @@ void Assembler::evmovdqub(XMMRegister dst, Address src, int vector_len) {
|
||||
}
|
||||
|
||||
void Assembler::evmovdqub(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
assert(src != xnoreg, "sanity");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
@ -3583,7 +3591,7 @@ void Assembler::evmovdquw(XMMRegister dst, Address src, int vector_len) {
|
||||
}
|
||||
|
||||
void Assembler::evmovdquw(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -3603,7 +3611,7 @@ void Assembler::evmovdquw(Address dst, XMMRegister src, int vector_len) {
|
||||
}
|
||||
|
||||
void Assembler::evmovdquw(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
assert(src != xnoreg, "sanity");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
@ -3618,6 +3626,19 @@ void Assembler::evmovdquw(Address dst, KRegister mask, XMMRegister src, bool mer
|
||||
emit_operand(src, dst, 0);
|
||||
}
|
||||
|
||||
void Assembler::evmovdquw(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
attributes.set_is_evex_instruction();
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16(0x6F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) {
|
||||
// Unmasked instruction
|
||||
evmovdqul(dst, k0, src, /*merge*/ false, vector_len);
|
||||
@ -4805,6 +4826,7 @@ void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister src1, Address src2, int ve
|
||||
// In this context, kdst is written the mask used to process the equal components
|
||||
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
@ -4812,7 +4834,8 @@ void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int
|
||||
}
|
||||
|
||||
void Assembler::evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -4824,7 +4847,8 @@ void Assembler::evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vect
|
||||
}
|
||||
|
||||
void Assembler::evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -4837,16 +4861,34 @@ void Assembler::evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Addre
|
||||
emit_operand(as_Register(dst_enc), src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpcmpub(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x3E, (0xC0 | encode), vcc);
|
||||
}
|
||||
|
||||
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x3E, (0xC0 | encode), vcc);
|
||||
}
|
||||
|
||||
void Assembler::evpcmpud(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x1E, (0xC0 | encode), vcc);
|
||||
}
|
||||
|
||||
void Assembler::evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vl(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
@ -4854,7 +4896,8 @@ void Assembler::evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, Compa
|
||||
}
|
||||
|
||||
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -4868,6 +4911,7 @@ void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, Compariso
|
||||
|
||||
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
@ -4879,7 +4923,8 @@ void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vect
|
||||
}
|
||||
|
||||
void Assembler::evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512vlbw(), "");
|
||||
assert(VM_Version::supports_avx512bw(), "");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
@ -8353,6 +8398,161 @@ void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpaddsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xEC, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpaddsb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xEC);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpaddsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xED, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpaddsw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xED);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpaddusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDC, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpaddusb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDC);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::vpaddusw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDD, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpaddusw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDD);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::vpsubsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xE8, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubsb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xE8);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpsubsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xE9, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubsw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xE9);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xD8, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubusb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xD8);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpsubusw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xD9, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubusw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xD9);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::psubb(XMMRegister dst, XMMRegister src) {
|
||||
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
|
||||
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
@ -8382,13 +8582,6 @@ void Assembler::psubq(XMMRegister dst, XMMRegister src) {
|
||||
emit_int8((0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0, "requires some form of AVX");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xD8, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0, "requires some form of AVX");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
@ -8565,14 +8758,6 @@ void Assembler::vpminsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
|
||||
emit_int16(0x38, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpminub(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16(0xDA, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::pminsw(XMMRegister dst, XMMRegister src) {
|
||||
assert(VM_Version::supports_sse2(), "");
|
||||
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
@ -8718,6 +8903,346 @@ void Assembler::vmaxpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int ve
|
||||
emit_int16(0x5F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpminub(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDA, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpminub(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDA);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpminub(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDA, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpminub(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDA);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpminuw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3A, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpminuw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
assert(!needs_evex(dst, nds) || VM_Version::supports_avx512bw(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x3A);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpminuw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3A, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpminuw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3A);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpminud(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3B, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpminud(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x3B);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpminud(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3B, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpminud(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3B);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpminuq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3B, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpminuq(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3B);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpmaxub(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDE, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpmaxub(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDE);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpmaxub(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDE, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpmaxub(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDE);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpmaxuw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3E, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpmaxuw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
|
||||
assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x3E);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpmaxuw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3E, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpmaxuw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3E);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::vpmaxud(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(UseAVX > 0, "");
|
||||
assert((vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpmaxud(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(UseAVX > 0, "");
|
||||
assert((vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds) || VM_Version::supports_avx512vl())), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x3F);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpmaxud(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpmaxud(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3F);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpmaxuq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int16(0x3F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpmaxuq(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x3F);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
// Shift packed integers left by specified number of bits.
|
||||
void Assembler::psllw(XMMRegister dst, int shift) {
|
||||
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
|
||||
@ -10421,6 +10946,223 @@ void Assembler::evsubpd(XMMRegister dst, KRegister mask, XMMRegister nds, Addres
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpaddsb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xEC, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpaddsb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xEC);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpaddsw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xED, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpaddsw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xED);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpaddusb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDC, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpaddusb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDC);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpaddusw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xDD, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpaddusw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xDD);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpsubsb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xE8, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpsubsb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xE8);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpsubsw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xE9, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpsubsw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xE9);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpsubusb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xD8, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evpsubusb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xD8);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpsubusw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16((unsigned char)0xD9, (0xC0 | encode));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::evpsubusw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
InstructionMark im(this);
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV,/* input_size_in_bits */ EVEX_NObit);
|
||||
attributes.set_is_evex_instruction();
|
||||
attributes.set_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0xD9);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evpmullw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
assert(VM_Version::supports_avx512bw() && (vector_len == AVX_512bit || VM_Version::supports_avx512vl()), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false,/* legacy_mode */ false, /* no_mask_reg */ false,/* uses_vl */ true);
|
||||
|
@ -780,6 +780,7 @@ private:
|
||||
|
||||
bool needs_eevex(Register reg1, Register reg2 = noreg, Register reg3 = noreg);
|
||||
bool needs_eevex(int enc1, int enc2 = -1, int enc3 = -1);
|
||||
NOT_PRODUCT(bool needs_evex(XMMRegister reg1, XMMRegister reg2 = xnoreg, XMMRegister reg3 = xnoreg);)
|
||||
|
||||
void rex_prefix(Address adr, XMMRegister xreg,
|
||||
VexSimdPrefix pre, VexOpcode opc, bool rex_w);
|
||||
@ -1992,9 +1993,12 @@ private:
|
||||
void evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len);
|
||||
void evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
void evpcmpub(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
|
||||
|
||||
void evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
|
||||
void evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len);
|
||||
|
||||
void evpcmpud(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
|
||||
void evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
|
||||
|
||||
void pcmpeqw(XMMRegister dst, XMMRegister src);
|
||||
@ -2678,6 +2682,40 @@ private:
|
||||
void vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Saturating packed insturctions.
|
||||
void vpaddsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddusw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void evpaddsb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpaddsw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpaddusb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpaddusw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void vpsubsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubusw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void evpsubsb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpsubsw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpsubusb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpsubusw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void vpaddsb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddsw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddusb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddusw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void evpaddsb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpaddsw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpaddusb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpaddusw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void vpsubsb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubsw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubusb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubusw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void evpsubsb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpsubsw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpsubusb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpsubusw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
|
||||
// Leaf level assembler routines for masked operations.
|
||||
void evpaddb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpaddb(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
@ -2821,7 +2859,6 @@ private:
|
||||
void psubw(XMMRegister dst, XMMRegister src);
|
||||
void psubd(XMMRegister dst, XMMRegister src);
|
||||
void psubq(XMMRegister dst, XMMRegister src);
|
||||
void vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
@ -2847,7 +2884,6 @@ private:
|
||||
// Minimum of packed integers
|
||||
void pminsb(XMMRegister dst, XMMRegister src);
|
||||
void vpminsb(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpminub(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void pminsw(XMMRegister dst, XMMRegister src);
|
||||
void vpminsw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void pminsd(XMMRegister dst, XMMRegister src);
|
||||
@ -2871,6 +2907,38 @@ private:
|
||||
void maxpd(XMMRegister dst, XMMRegister src);
|
||||
void vmaxpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
|
||||
// Unsigned maximum packed integers.
|
||||
void vpmaxub(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpmaxuw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpmaxud(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpmaxub(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void vpmaxuw(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void vpmaxud(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void evpmaxub(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpmaxuw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpmaxud(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpmaxuq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpmaxub(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpmaxuw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpmaxud(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpmaxuq(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
|
||||
// Unsigned minimum packed integers.
|
||||
void vpminub(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpminuw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpminud(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
void vpminub(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void vpminuw(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void vpminud(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
|
||||
void evpminub(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpminuw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpminud(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpminuq(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpminub(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpminuw(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpminud(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpminuq(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
|
||||
// Shift left packed integers
|
||||
void psllw(XMMRegister dst, int shift);
|
||||
void pslld(XMMRegister dst, int shift);
|
||||
|
@ -939,6 +939,72 @@ void C2_MacroAssembler::pminmax(int opcode, BasicType elem_bt, XMMRegister dst,
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpuminmax(int opcode, BasicType elem_bt, XMMRegister dst,
|
||||
XMMRegister src1, Address src2, int vlen_enc) {
|
||||
assert(opcode == Op_UMinV || opcode == Op_UMaxV, "sanity");
|
||||
if (opcode == Op_UMinV) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE: vpminub(dst, src1, src2, vlen_enc); break;
|
||||
case T_SHORT: vpminuw(dst, src1, src2, vlen_enc); break;
|
||||
case T_INT: vpminud(dst, src1, src2, vlen_enc); break;
|
||||
case T_LONG: evpminuq(dst, k0, src1, src2, false, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
} else {
|
||||
assert(opcode == Op_UMaxV, "required");
|
||||
switch(elem_bt) {
|
||||
case T_BYTE: vpmaxub(dst, src1, src2, vlen_enc); break;
|
||||
case T_SHORT: vpmaxuw(dst, src1, src2, vlen_enc); break;
|
||||
case T_INT: vpmaxud(dst, src1, src2, vlen_enc); break;
|
||||
case T_LONG: evpmaxuq(dst, k0, src1, src2, false, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpuminmaxq(int opcode, XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc) {
|
||||
// T1 = -1
|
||||
vpcmpeqq(xtmp1, xtmp1, xtmp1, vlen_enc);
|
||||
// T1 = -1 << 63
|
||||
vpsllq(xtmp1, xtmp1, 63, vlen_enc);
|
||||
// Convert SRC2 to signed value i.e. T2 = T1 + SRC2
|
||||
vpaddq(xtmp2, xtmp1, src2, vlen_enc);
|
||||
// Convert SRC1 to signed value i.e. T1 = T1 + SRC1
|
||||
vpaddq(xtmp1, xtmp1, src1, vlen_enc);
|
||||
// Mask = T2 > T1
|
||||
vpcmpgtq(xtmp1, xtmp2, xtmp1, vlen_enc);
|
||||
if (opcode == Op_UMaxV) {
|
||||
// Res = Mask ? Src2 : Src1
|
||||
vpblendvb(dst, src1, src2, xtmp1, vlen_enc);
|
||||
} else {
|
||||
// Res = Mask ? Src1 : Src2
|
||||
vpblendvb(dst, src2, src1, xtmp1, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpuminmax(int opcode, BasicType elem_bt, XMMRegister dst,
|
||||
XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
assert(opcode == Op_UMinV || opcode == Op_UMaxV, "sanity");
|
||||
if (opcode == Op_UMinV) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE: vpminub(dst, src1, src2, vlen_enc); break;
|
||||
case T_SHORT: vpminuw(dst, src1, src2, vlen_enc); break;
|
||||
case T_INT: vpminud(dst, src1, src2, vlen_enc); break;
|
||||
case T_LONG: evpminuq(dst, k0, src1, src2, false, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
} else {
|
||||
assert(opcode == Op_UMaxV, "required");
|
||||
switch(elem_bt) {
|
||||
case T_BYTE: vpmaxub(dst, src1, src2, vlen_enc); break;
|
||||
case T_SHORT: vpmaxuw(dst, src1, src2, vlen_enc); break;
|
||||
case T_INT: vpmaxud(dst, src1, src2, vlen_enc); break;
|
||||
case T_LONG: evpmaxuq(dst, k0, src1, src2, false, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpminmax(int opcode, BasicType elem_bt,
|
||||
XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
int vlen_enc) {
|
||||
@ -2362,6 +2428,10 @@ void C2_MacroAssembler::evmovdqu(BasicType type, KRegister kmask, Address dst, X
|
||||
MacroAssembler::evmovdqu(type, kmask, dst, src, merge, vector_len);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, XMMRegister src, bool merge, int vector_len) {
|
||||
MacroAssembler::evmovdqu(type, kmask, dst, src, merge, vector_len);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vmovmask(BasicType elem_bt, XMMRegister dst, Address src, XMMRegister mask,
|
||||
int vec_enc) {
|
||||
switch(elem_bt) {
|
||||
@ -2660,7 +2730,6 @@ void C2_MacroAssembler::vectortest(BasicType bt, XMMRegister src1, XMMRegister s
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpadd(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
assert(UseAVX >= 2, "required");
|
||||
#ifdef ASSERT
|
||||
bool is_bw = ((elem_bt == T_BYTE) || (elem_bt == T_SHORT));
|
||||
bool is_bw_supported = VM_Version::supports_avx512bw();
|
||||
@ -4634,7 +4703,126 @@ void C2_MacroAssembler::evmasked_op(int ideal_opc, BasicType eType, KRegister ma
|
||||
case Op_RotateLeftV:
|
||||
evrold(eType, dst, mask, src1, imm8, merge, vlen_enc); break;
|
||||
default:
|
||||
fatal("Unsupported masked operation"); break;
|
||||
fatal("Unsupported operation %s", NodeClassNames[ideal_opc]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, bool is_unsigned, bool merge, int vlen_enc) {
|
||||
if (is_unsigned) {
|
||||
evmasked_saturating_unsigned_op(ideal_opc, elem_bt, mask, dst, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
evmasked_saturating_signed_op(ideal_opc, elem_bt, mask, dst, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_signed_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst,
|
||||
XMMRegister src1, XMMRegister src2, bool merge, int vlen_enc) {
|
||||
switch (elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddsb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubsb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddsw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubsw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst,
|
||||
XMMRegister src1, XMMRegister src2, bool merge, int vlen_enc) {
|
||||
switch (elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddusb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubusb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddusw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubusw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1,
|
||||
Address src2, bool is_unsigned, bool merge, int vlen_enc) {
|
||||
if (is_unsigned) {
|
||||
evmasked_saturating_unsigned_op(ideal_opc, elem_bt, mask, dst, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
evmasked_saturating_signed_op(ideal_opc, elem_bt, mask, dst, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_signed_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst,
|
||||
XMMRegister src1, Address src2, bool merge, int vlen_enc) {
|
||||
switch (elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddsb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubsb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddsw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubsw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evmasked_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst,
|
||||
XMMRegister src1, Address src2, bool merge, int vlen_enc) {
|
||||
switch (elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddusb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubusb(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
evpaddusw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
evpsubusw(dst, mask, src1, src2, merge, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4724,6 +4912,10 @@ void C2_MacroAssembler::evmasked_op(int ideal_opc, BasicType eType, KRegister ma
|
||||
evpmaxs(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_MinV:
|
||||
evpmins(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_UMinV:
|
||||
evpminu(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_UMaxV:
|
||||
evpmaxu(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_XorV:
|
||||
evxor(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_OrV:
|
||||
@ -4731,7 +4923,8 @@ void C2_MacroAssembler::evmasked_op(int ideal_opc, BasicType eType, KRegister ma
|
||||
case Op_AndV:
|
||||
evand(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
default:
|
||||
fatal("Unsupported masked operation"); break;
|
||||
fatal("Unsupported operation %s", NodeClassNames[ideal_opc]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4784,6 +4977,10 @@ void C2_MacroAssembler::evmasked_op(int ideal_opc, BasicType eType, KRegister ma
|
||||
evpmaxs(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_MinV:
|
||||
evpmins(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_UMaxV:
|
||||
evpmaxu(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_UMinV:
|
||||
evpminu(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_XorV:
|
||||
evxor(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
case Op_OrV:
|
||||
@ -4791,7 +4988,8 @@ void C2_MacroAssembler::evmasked_op(int ideal_opc, BasicType eType, KRegister ma
|
||||
case Op_AndV:
|
||||
evand(eType, dst, mask, src1, src2, merge, vlen_enc); break;
|
||||
default:
|
||||
fatal("Unsupported masked operation"); break;
|
||||
fatal("Unsupported operation %s", NodeClassNames[ideal_opc]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6479,6 +6677,369 @@ void C2_MacroAssembler::vector_rearrange_int_float(BasicType bt, XMMRegister dst
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddsb(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubsb(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddsw(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubsw(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddusb(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubusb(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddusw(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubusw(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_sub_dq_saturating_unsigned_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, KRegister ktmp, int vlen_enc) {
|
||||
// For unsigned subtraction, overflow happens when magnitude of second input is greater than first input.
|
||||
// overflow_mask = Inp1 <u Inp2
|
||||
evpcmpu(elem_bt, ktmp, src2, src1, Assembler::lt, vlen_enc);
|
||||
// Res = overflow_mask ? Zero : INP1 - INP2 (non-commutative and non-associative)
|
||||
evmasked_op(elem_bt == T_INT ? Op_SubVI : Op_SubVL, elem_bt, ktmp, dst, src1, src2, false, vlen_enc, false);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_sub_dq_saturating_unsigned_avx(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc) {
|
||||
// Emulate unsigned comparison using signed comparison
|
||||
// Mask = Inp1 <u Inp2 => Inp1 + MIN_VALUE < Inp2 + MIN_VALUE
|
||||
vpgenmin_value(elem_bt, xtmp1, xtmp1, vlen_enc, true);
|
||||
vpadd(elem_bt, xtmp2, src1, xtmp1, vlen_enc);
|
||||
vpadd(elem_bt, xtmp1, src2, xtmp1, vlen_enc);
|
||||
|
||||
vpcmpgt(elem_bt, xtmp2, xtmp1, xtmp2, vlen_enc);
|
||||
|
||||
// Res = INP1 - INP2 (non-commutative and non-associative)
|
||||
vpsub(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Res = Mask ? Zero : Res
|
||||
vpxor(xtmp1, xtmp1, xtmp1, vlen_enc);
|
||||
vpblendvb(dst, dst, xtmp1, xtmp2, vlen_enc);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_add_dq_saturating_unsigned_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp, int vlen_enc) {
|
||||
// Unsigned values ranges comprise of only +ve numbers, thus there exist only an upper bound saturation.
|
||||
// overflow_mask = (SRC1 + SRC2) <u (SRC1 | SRC2)
|
||||
// Res = Signed Add INP1, INP2
|
||||
vpadd(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// T1 = SRC1 | SRC2
|
||||
vpor(xtmp1, src1, src2, vlen_enc);
|
||||
// Max_Unsigned = -1
|
||||
vpternlogd(xtmp2, 0xff, xtmp2, xtmp2, vlen_enc);
|
||||
// Unsigned compare: Mask = Res <u T1
|
||||
evpcmpu(elem_bt, ktmp, dst, xtmp1, Assembler::lt, vlen_enc);
|
||||
// res = Mask ? Max_Unsigned : Res
|
||||
evpblend(elem_bt, dst, ktmp, dst, xtmp2, true, vlen_enc);
|
||||
}
|
||||
|
||||
//
|
||||
// Section 2-13 Hacker's Delight list following overflow detection check for saturating
|
||||
// unsigned addition operation.
|
||||
// overflow_mask = ((a & b) | ((a | b) & ~( a + b))) >>> 31 == 1
|
||||
//
|
||||
// We empirically determined its semantic equivalence to following reduced expression
|
||||
// overflow_mask = (a + b) <u (a | b)
|
||||
//
|
||||
// and also verified it though Alive2 solver.
|
||||
// (https://alive2.llvm.org/ce/z/XDQ7dY)
|
||||
//
|
||||
|
||||
void C2_MacroAssembler::vector_add_dq_saturating_unsigned_avx(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, XMMRegister xtmp3, int vlen_enc) {
|
||||
// Res = Signed Add INP1, INP2
|
||||
vpadd(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Compute T1 = INP1 | INP2
|
||||
vpor(xtmp3, src1, src2, vlen_enc);
|
||||
// T1 = Minimum signed value.
|
||||
vpgenmin_value(elem_bt, xtmp2, xtmp1, vlen_enc, true);
|
||||
// Convert T1 to signed value, T1 = T1 + MIN_VALUE
|
||||
vpadd(elem_bt, xtmp3, xtmp3, xtmp2, vlen_enc);
|
||||
// Convert Res to signed value, Res<s> = Res + MIN_VALUE
|
||||
vpadd(elem_bt, xtmp2, xtmp2, dst, vlen_enc);
|
||||
// Compute overflow detection mask = Res<1> <s T1
|
||||
if (elem_bt == T_INT) {
|
||||
vpcmpgtd(xtmp3, xtmp3, xtmp2, vlen_enc);
|
||||
} else {
|
||||
assert(elem_bt == T_LONG, "");
|
||||
vpcmpgtq(xtmp3, xtmp3, xtmp2, vlen_enc);
|
||||
}
|
||||
vpblendvb(dst, dst, xtmp1, xtmp3, vlen_enc);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evpmovq2m_emu(KRegister ktmp, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||
int vlen_enc, bool xtmp2_hold_M1) {
|
||||
if (VM_Version::supports_avx512dq()) {
|
||||
evpmovq2m(ktmp, src, vlen_enc);
|
||||
} else {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
if (!xtmp2_hold_M1) {
|
||||
vpternlogq(xtmp2, 0xff, xtmp2, xtmp2, vlen_enc);
|
||||
}
|
||||
evpsraq(xtmp1, src, 63, vlen_enc);
|
||||
evpcmpeqq(ktmp, k0, xtmp1, xtmp2, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evpmovd2m_emu(KRegister ktmp, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||
int vlen_enc, bool xtmp2_hold_M1) {
|
||||
if (VM_Version::supports_avx512dq()) {
|
||||
evpmovd2m(ktmp, src, vlen_enc);
|
||||
} else {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
if (!xtmp2_hold_M1) {
|
||||
vpternlogd(xtmp2, 0xff, xtmp2, xtmp2, vlen_enc);
|
||||
}
|
||||
vpsrad(xtmp1, src, 31, vlen_enc);
|
||||
Assembler::evpcmpeqd(ktmp, k0, xtmp1, xtmp2, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C2_MacroAssembler::vpsign_extend_dq(BasicType elem_bt, XMMRegister dst, XMMRegister src, int vlen_enc) {
|
||||
if (elem_bt == T_LONG) {
|
||||
if (VM_Version::supports_evex()) {
|
||||
evpsraq(dst, src, 63, vlen_enc);
|
||||
} else {
|
||||
vpsrad(dst, src, 31, vlen_enc);
|
||||
vpshufd(dst, dst, 0xF5, vlen_enc);
|
||||
}
|
||||
} else {
|
||||
assert(elem_bt == T_INT, "");
|
||||
vpsrad(dst, src, 31, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpgenmax_value(BasicType elem_bt, XMMRegister dst, XMMRegister allones, int vlen_enc, bool compute_allones) {
|
||||
if (compute_allones) {
|
||||
if (vlen_enc == Assembler::AVX_512bit) {
|
||||
vpternlogd(allones, 0xff, allones, allones, vlen_enc);
|
||||
} else {
|
||||
vpcmpeqq(allones, allones, allones, vlen_enc);
|
||||
}
|
||||
}
|
||||
if (elem_bt == T_LONG) {
|
||||
vpsrlq(dst, allones, 1, vlen_enc);
|
||||
} else {
|
||||
assert(elem_bt == T_INT, "");
|
||||
vpsrld(dst, allones, 1, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpgenmin_value(BasicType elem_bt, XMMRegister dst, XMMRegister allones, int vlen_enc, bool compute_allones) {
|
||||
if (compute_allones) {
|
||||
if (vlen_enc == Assembler::AVX_512bit) {
|
||||
vpternlogd(allones, 0xff, allones, allones, vlen_enc);
|
||||
} else {
|
||||
vpcmpeqq(allones, allones, allones, vlen_enc);
|
||||
}
|
||||
}
|
||||
if (elem_bt == T_LONG) {
|
||||
vpsllq(dst, allones, 63, vlen_enc);
|
||||
} else {
|
||||
assert(elem_bt == T_INT, "");
|
||||
vpslld(dst, allones, 31, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evpcmpu(BasicType elem_bt, KRegister kmask, XMMRegister src1, XMMRegister src2,
|
||||
Assembler::ComparisonPredicate cond, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_LONG: evpcmpuq(kmask, src1, src2, cond, vlen_enc); break;
|
||||
case T_INT: evpcmpud(kmask, src1, src2, cond, vlen_enc); break;
|
||||
case T_SHORT: evpcmpuw(kmask, src1, src2, cond, vlen_enc); break;
|
||||
case T_BYTE: evpcmpub(kmask, src1, src2, cond, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vpcmpgt(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_LONG: vpcmpgtq(dst, src1, src2, vlen_enc); break;
|
||||
case T_INT: vpcmpgtd(dst, src1, src2, vlen_enc); break;
|
||||
case T_SHORT: vpcmpgtw(dst, src1, src2, vlen_enc); break;
|
||||
case T_BYTE: vpcmpgtb(dst, src1, src2, vlen_enc); break;
|
||||
default: fatal("Unsupported type %s", type2name(elem_bt)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::evpmov_vec_to_mask(BasicType elem_bt, KRegister ktmp, XMMRegister src, XMMRegister xtmp1,
|
||||
XMMRegister xtmp2, int vlen_enc, bool xtmp2_hold_M1) {
|
||||
if (elem_bt == T_LONG) {
|
||||
evpmovq2m_emu(ktmp, src, xtmp1, xtmp2, vlen_enc, xtmp2_hold_M1);
|
||||
} else {
|
||||
assert(elem_bt == T_INT, "");
|
||||
evpmovd2m_emu(ktmp, src, xtmp1, xtmp2, vlen_enc, xtmp2_hold_M1);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_addsub_dq_saturating_evex(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||
KRegister ktmp1, KRegister ktmp2, int vlen_enc) {
|
||||
assert(elem_bt == T_INT || elem_bt == T_LONG, "");
|
||||
// Addition/Subtraction happens over two's compliment representation of numbers and is agnostic to signed'ness.
|
||||
// Overflow detection based on Hacker's delight section 2-13.
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
// res = src1 + src2
|
||||
vpadd(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Overflow occurs if result polarity does not comply with equivalent polarity inputs.
|
||||
// overflow = (((res ^ src1) & (res ^ src2)) >>> 31(I)/63(L)) == 1
|
||||
vpxor(xtmp1, dst, src1, vlen_enc);
|
||||
vpxor(xtmp2, dst, src2, vlen_enc);
|
||||
vpand(xtmp2, xtmp1, xtmp2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
// res = src1 - src2
|
||||
vpsub(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Overflow occurs when both inputs have opposite polarity and
|
||||
// result polarity does not comply with first input polarity.
|
||||
// overflow = ((src1 ^ src2) & (res ^ src1) >>> 31(I)/63(L)) == 1;
|
||||
vpxor(xtmp1, src1, src2, vlen_enc);
|
||||
vpxor(xtmp2, dst, src1, vlen_enc);
|
||||
vpand(xtmp2, xtmp1, xtmp2, vlen_enc);
|
||||
}
|
||||
|
||||
// Compute overflow detection mask.
|
||||
evpmov_vec_to_mask(elem_bt, ktmp1, xtmp2, xtmp2, xtmp1, vlen_enc);
|
||||
// Note: xtmp1 hold -1 in all its lanes after above call.
|
||||
|
||||
// Compute mask based on first input polarity.
|
||||
evpmov_vec_to_mask(elem_bt, ktmp2, src1, xtmp2, xtmp1, vlen_enc, true);
|
||||
|
||||
vpgenmax_value(elem_bt, xtmp2, xtmp1, vlen_enc, true);
|
||||
vpgenmin_value(elem_bt, xtmp1, xtmp1, vlen_enc);
|
||||
|
||||
// Compose a vector of saturating (MAX/MIN) values, where lanes corresponding to
|
||||
// set bits in first input polarity mask holds a min value.
|
||||
evpblend(elem_bt, xtmp2, ktmp2, xtmp2, xtmp1, true, vlen_enc);
|
||||
// Blend destination lanes with saturated values using overflow detection mask.
|
||||
evpblend(elem_bt, dst, ktmp1, dst, xtmp2, true, vlen_enc);
|
||||
}
|
||||
|
||||
|
||||
void C2_MacroAssembler::vector_addsub_dq_saturating_avx(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||
XMMRegister xtmp3, XMMRegister xtmp4, int vlen_enc) {
|
||||
assert(elem_bt == T_INT || elem_bt == T_LONG, "");
|
||||
// Addition/Subtraction happens over two's compliment representation of numbers and is agnostic to signed'ness.
|
||||
// Overflow detection based on Hacker's delight section 2-13.
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
// res = src1 + src2
|
||||
vpadd(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Overflow occurs if result polarity does not comply with equivalent polarity inputs.
|
||||
// overflow = (((res ^ src1) & (res ^ src2)) >>> 31(I)/63(L)) == 1
|
||||
vpxor(xtmp1, dst, src1, vlen_enc);
|
||||
vpxor(xtmp2, dst, src2, vlen_enc);
|
||||
vpand(xtmp2, xtmp1, xtmp2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
// res = src1 - src2
|
||||
vpsub(elem_bt, dst, src1, src2, vlen_enc);
|
||||
// Overflow occurs when both inputs have opposite polarity and
|
||||
// result polarity does not comply with first input polarity.
|
||||
// overflow = ((src1 ^ src2) & (res ^ src1) >>> 31(I)/63(L)) == 1;
|
||||
vpxor(xtmp1, src1, src2, vlen_enc);
|
||||
vpxor(xtmp2, dst, src1, vlen_enc);
|
||||
vpand(xtmp2, xtmp1, xtmp2, vlen_enc);
|
||||
}
|
||||
|
||||
// Sign-extend to compute overflow detection mask.
|
||||
vpsign_extend_dq(elem_bt, xtmp3, xtmp2, vlen_enc);
|
||||
|
||||
vpcmpeqd(xtmp1, xtmp1, xtmp1, vlen_enc);
|
||||
vpgenmax_value(elem_bt, xtmp2, xtmp1, vlen_enc);
|
||||
vpgenmin_value(elem_bt, xtmp1, xtmp1, vlen_enc);
|
||||
|
||||
// Compose saturating min/max vector using first input polarity mask.
|
||||
vpsign_extend_dq(elem_bt, xtmp4, src1, vlen_enc);
|
||||
vpblendvb(xtmp1, xtmp2, xtmp1, xtmp4, vlen_enc);
|
||||
|
||||
// Blend result with saturating vector using overflow detection mask.
|
||||
vpblendvb(dst, dst, xtmp1, xtmp3, vlen_enc);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddsb(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubsb(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddsw(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubsw(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
case T_BYTE:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddusb(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubusb(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
case T_SHORT:
|
||||
if (ideal_opc == Op_SaturatingAddV) {
|
||||
vpaddusw(dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
assert(ideal_opc == Op_SaturatingSubV, "");
|
||||
vpsubusw(dst, src1, src2, vlen_enc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported type %s", type2name(elem_bt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, int vlen_enc) {
|
||||
switch(elem_bt) {
|
||||
@ -6505,3 +7066,19 @@ void C2_MacroAssembler::select_from_two_vectors_evex(BasicType elem_bt, XMMRegis
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, bool is_unsigned, int vlen_enc) {
|
||||
if (is_unsigned) {
|
||||
vector_saturating_unsigned_op(ideal_opc, elem_bt, dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
vector_saturating_op(ideal_opc, elem_bt, dst, src1, src2, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, bool is_unsigned, int vlen_enc) {
|
||||
if (is_unsigned) {
|
||||
vector_saturating_unsigned_op(ideal_opc, elem_bt, dst, src1, src2, vlen_enc);
|
||||
} else {
|
||||
vector_saturating_op(ideal_opc, elem_bt, dst, src1, src2, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +56,21 @@ public:
|
||||
XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
int vlen_enc);
|
||||
|
||||
void vpuminmax(int opcode, BasicType elem_bt,
|
||||
XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
int vlen_enc);
|
||||
|
||||
void vpuminmax(int opcode, BasicType elem_bt,
|
||||
XMMRegister dst, XMMRegister src1, Address src2,
|
||||
int vlen_enc);
|
||||
|
||||
void vminmax_fp(int opcode, BasicType elem_bt,
|
||||
XMMRegister dst, XMMRegister a, XMMRegister b,
|
||||
XMMRegister tmp, XMMRegister atmp, XMMRegister btmp,
|
||||
int vlen_enc);
|
||||
|
||||
void vpuminmaxq(int opcode, XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc);
|
||||
|
||||
void evminmax_fp(int opcode, BasicType elem_bt,
|
||||
XMMRegister dst, XMMRegister a, XMMRegister b,
|
||||
KRegister ktmp, XMMRegister atmp, XMMRegister btmp,
|
||||
@ -105,6 +116,7 @@ public:
|
||||
|
||||
void evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, Address src, bool merge, int vector_len);
|
||||
void evmovdqu(BasicType type, KRegister kmask, Address dst, XMMRegister src, bool merge, int vector_len);
|
||||
void evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, XMMRegister src, bool merge, int vector_len);
|
||||
|
||||
// extract
|
||||
void extract(BasicType typ, Register dst, XMMRegister src, int idx);
|
||||
@ -505,6 +517,70 @@ public:
|
||||
void vgather8b_offset(BasicType elem_bt, XMMRegister dst, Register base, Register idx_base,
|
||||
Register offset, Register rtmp, int vlen_enc);
|
||||
|
||||
void vector_saturating_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, bool is_unsigned, int vlen_enc);
|
||||
|
||||
void vector_saturating_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, bool is_unsigned, int vlen_enc);
|
||||
|
||||
void vector_saturating_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc);
|
||||
|
||||
void vector_saturating_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, int vlen_enc);
|
||||
|
||||
void vector_saturating_unsigned_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc);
|
||||
|
||||
void vector_saturating_unsigned_op(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, Address src2, int vlen_enc);
|
||||
|
||||
void vector_sub_dq_saturating_unsigned_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, KRegister ktmp, int vlen_enc);
|
||||
|
||||
void vector_sub_dq_saturating_unsigned_avx(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc);
|
||||
|
||||
void vector_add_dq_saturating_unsigned_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp, int vlen_enc);
|
||||
|
||||
void vector_add_dq_saturating_unsigned_avx(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, XMMRegister xtmp3, int vlen_enc);
|
||||
|
||||
void vector_addsub_dq_saturating_avx(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, XMMRegister xtmp3, XMMRegister xtmp4, int vlen_enc);
|
||||
|
||||
void vector_addsub_dq_saturating_evex(int opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp1, KRegister ktmp2, int vlen_enc);
|
||||
|
||||
void evpmovd2m_emu(KRegister ktmp, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc, bool xtmp2_hold_M1 = false);
|
||||
|
||||
void evpmovq2m_emu(KRegister ktmp, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2, int vlen_enc, bool xtmp2_hold_M1 = false);
|
||||
|
||||
void vpsign_extend_dq(BasicType etype, XMMRegister dst, XMMRegister src, int vlen_enc);
|
||||
|
||||
void vpgenmin_value(BasicType etype, XMMRegister dst, XMMRegister allones, int vlen_enc, bool compute_allones = false);
|
||||
|
||||
void vpgenmax_value(BasicType etype, XMMRegister dst, XMMRegister allones, int vlen_enc, bool compute_allones = false);
|
||||
|
||||
void evpcmpu(BasicType etype, KRegister kmask, XMMRegister src1, XMMRegister src2, Assembler::ComparisonPredicate cond, int vlen_enc);
|
||||
|
||||
void vpcmpgt(BasicType etype, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc);
|
||||
|
||||
void evpmov_vec_to_mask(BasicType etype, KRegister ktmp, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||
int vlen_enc, bool xtmp2_hold_M1 = false);
|
||||
|
||||
void evmasked_saturating_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
bool is_unsigned, bool merge, int vlen_enc);
|
||||
|
||||
void evmasked_saturating_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1, Address src2,
|
||||
bool is_unsigned, bool merge, int vlen_enc);
|
||||
|
||||
void evmasked_saturating_signed_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1, XMMRegister src2,
|
||||
bool merge, int vlen_enc);
|
||||
|
||||
void evmasked_saturating_signed_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1, Address src2,
|
||||
bool merge, int vlen_enc);
|
||||
|
||||
void evmasked_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1,
|
||||
XMMRegister src2, bool merge, int vlen_enc);
|
||||
|
||||
void evmasked_saturating_unsigned_op(int ideal_opc, BasicType elem_bt, KRegister mask, XMMRegister dst, XMMRegister src1,
|
||||
Address src2, bool merge, int vlen_enc);
|
||||
|
||||
void select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc);
|
||||
|
||||
#endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP
|
||||
|
@ -9314,6 +9314,30 @@ void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void MacroAssembler::evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, XMMRegister src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
case T_BOOLEAN:
|
||||
evmovdqub(dst, kmask, src, merge, vector_len);
|
||||
break;
|
||||
case T_CHAR:
|
||||
case T_SHORT:
|
||||
evmovdquw(dst, kmask, src, merge, vector_len);
|
||||
break;
|
||||
case T_INT:
|
||||
case T_FLOAT:
|
||||
evmovdqul(dst, kmask, src, merge, vector_len);
|
||||
break;
|
||||
case T_LONG:
|
||||
case T_DOUBLE:
|
||||
evmovdquq(dst, kmask, src, merge, vector_len);
|
||||
break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, Address src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
@ -9505,6 +9529,66 @@ void MacroAssembler::evperm(BasicType type, XMMRegister dst, KRegister mask, XMM
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::evpminu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
evpminub(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_SHORT:
|
||||
evpminuw(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_INT:
|
||||
evpminud(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpminuq(dst, mask, nds, src, merge, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::evpmaxu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
evpmaxub(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_SHORT:
|
||||
evpmaxuw(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_INT:
|
||||
evpmaxud(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpmaxuq(dst, mask, nds, src, merge, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::evpminu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
evpminub(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_SHORT:
|
||||
evpminuw(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_INT:
|
||||
evpminud(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpminuq(dst, mask, nds, src, merge, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::evpmaxu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
evpmaxub(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_SHORT:
|
||||
evpmaxuw(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_INT:
|
||||
evpmaxud(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpmaxuq(dst, mask, nds, src, merge, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::evpmins(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
|
||||
switch(type) {
|
||||
case T_BYTE:
|
||||
|
@ -1282,6 +1282,7 @@ public:
|
||||
// AVX512 Unaligned
|
||||
void evmovdqu(BasicType type, KRegister kmask, Address dst, XMMRegister src, bool merge, int vector_len);
|
||||
void evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, Address src, bool merge, int vector_len);
|
||||
void evmovdqu(BasicType type, KRegister kmask, XMMRegister dst, XMMRegister src, bool merge, int vector_len);
|
||||
|
||||
void evmovdqub(XMMRegister dst, XMMRegister src, int vector_len) { Assembler::evmovdqub(dst, src, vector_len); }
|
||||
void evmovdqub(XMMRegister dst, Address src, int vector_len) { Assembler::evmovdqub(dst, src, vector_len); }
|
||||
@ -1589,6 +1590,11 @@ public:
|
||||
void evpmins(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpmaxs(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
|
||||
void evpminu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpmaxu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
void evpminu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
void evpmaxu(BasicType type, XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len);
|
||||
|
||||
void vpsrlw(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len);
|
||||
void vpsrlw(XMMRegister dst, XMMRegister nds, int shift, int vector_len);
|
||||
|
||||
|
@ -1765,6 +1765,12 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_UMinV:
|
||||
case Op_UMaxV:
|
||||
if (UseAVX == 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_MaxV:
|
||||
case Op_MinV:
|
||||
if (UseSSE < 4 && is_integral_type(bt)) {
|
||||
@ -1935,6 +1941,15 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_SaturatingAddV:
|
||||
case Op_SaturatingSubV:
|
||||
if (UseAVX < 1) {
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
if (is_subword_type(bt) && size_in_bits == 512 && !VM_Version::supports_avx512bw()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_SelectFromTwoVector:
|
||||
if (size_in_bits < 128 || (size_in_bits < 512 && !VM_Version::supports_avx512vl())) {
|
||||
return false;
|
||||
@ -2125,6 +2140,8 @@ bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType
|
||||
|
||||
case Op_MaxV:
|
||||
case Op_MinV:
|
||||
case Op_UMinV:
|
||||
case Op_UMaxV:
|
||||
if (is_subword_type(bt) && !VM_Version::supports_avx512bw()) {
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
@ -2132,6 +2149,15 @@ bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
return true;
|
||||
case Op_SaturatingAddV:
|
||||
case Op_SaturatingSubV:
|
||||
if (!is_subword_type(bt)) {
|
||||
return false;
|
||||
}
|
||||
if (size_in_bits < 128 || !VM_Version::supports_avx512bw()) {
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
return true;
|
||||
|
||||
case Op_VectorMaskCmp:
|
||||
if (is_subword_type(bt) && !VM_Version::supports_avx512bw()) {
|
||||
@ -6492,6 +6518,80 @@ instruct evminmaxFP_reg_eavx(vec dst, vec a, vec b, vec atmp, vec btmp, kReg ktm
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// ------------------------------ Unsigned vector Min/Max ----------------------
|
||||
|
||||
instruct vector_uminmax_reg(vec dst, vec a, vec b) %{
|
||||
predicate(VM_Version::supports_avx512vl() || Matcher::vector_element_basic_type(n) != T_LONG);
|
||||
match(Set dst (UMinV a b));
|
||||
match(Set dst (UMaxV a b));
|
||||
format %{ "vector_uminmax $dst,$a,$b\t!" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(elem_bt), "");
|
||||
__ vpuminmax(opcode, elem_bt, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_uminmax_mem(vec dst, vec a, memory b) %{
|
||||
predicate(VM_Version::supports_avx512vl() || Matcher::vector_element_basic_type(n) != T_LONG);
|
||||
match(Set dst (UMinV a (LoadVector b)));
|
||||
match(Set dst (UMaxV a (LoadVector b)));
|
||||
format %{ "vector_uminmax $dst,$a,$b\t!" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
assert(is_integral_type(elem_bt), "");
|
||||
__ vpuminmax(opcode, elem_bt, $dst$$XMMRegister, $a$$XMMRegister, $b$$Address, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_uminmaxq_reg(vec dst, vec a, vec b, vec xtmp1, vec xtmp2) %{
|
||||
predicate(!VM_Version::supports_avx512vl() && Matcher::vector_element_basic_type(n) == T_LONG);
|
||||
match(Set dst (UMinV a b));
|
||||
match(Set dst (UMaxV a b));
|
||||
effect(TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_uminmaxq $dst,$a,$b\t! using xtmp1 and xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
__ vpuminmaxq(opcode, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_uminmax_reg_masked(vec dst, vec src1, vec src2, kReg mask) %{
|
||||
match(Set dst (UMinV (Binary src1 src2) mask));
|
||||
match(Set dst (UMaxV (Binary src1 src2) mask));
|
||||
format %{ "vector_uminmax_masked $dst, $src1, $src2, $mask\t! umin/max masked operation" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int opc = this->ideal_Opcode();
|
||||
__ evmasked_op(opc, bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$dst$$XMMRegister, $src2$$XMMRegister, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_uminmax_mem_masked(vec dst, vec src1, memory src2, kReg mask) %{
|
||||
match(Set dst (UMinV (Binary src1 (LoadVector src2)) mask));
|
||||
match(Set dst (UMaxV (Binary src1 (LoadVector src2)) mask));
|
||||
format %{ "vector_uminmax_masked $dst, $dst, $src2, $mask\t! umin/max masked operation" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int opc = this->ideal_Opcode();
|
||||
__ evmasked_op(opc, bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$Address, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// --------------------------------- Signum/CopySign ---------------------------
|
||||
|
||||
instruct signumF_reg(regF dst, regF zero, regF one, rFlagsReg cr) %{
|
||||
@ -10484,6 +10584,236 @@ instruct DoubleClassCheck_reg_reg_vfpclass(rRegI dst, regD src, kReg ktmp, rFlag
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_subword_reg(vec dst, vec src1, vec src2)
|
||||
%{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
format %{ "vector_addsub_saturating_subword $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_saturating_op(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$XMMRegister, false, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_unsigned_subword_reg(vec dst, vec src1, vec src2)
|
||||
%{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
format %{ "vector_addsub_saturating_unsigned_subword $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_saturating_op(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$XMMRegister, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_reg_evex(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2, kReg ktmp1, kReg ktmp2)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned() &&
|
||||
(Matcher::vector_length_in_bytes(n) == 64 || VM_Version::supports_avx512vl()));
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP ktmp1, TEMP ktmp2);
|
||||
format %{ "vector_addsub_saturating_evex $dst, $src1, $src2 \t! using $xtmp1, $xtmp2, $ktmp1 and $ktmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_addsub_dq_saturating_evex(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$XMMRegister,
|
||||
$xtmp1$$XMMRegister, $xtmp2$$XMMRegister,
|
||||
$ktmp1$$KRegister, $ktmp2$$KRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_reg_avx(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2, vec xtmp3, vec xtmp4)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned() &&
|
||||
Matcher::vector_length_in_bytes(n) <= 32 && !VM_Version::supports_avx512vl());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP xtmp3, TEMP xtmp4);
|
||||
format %{ "vector_addsub_saturating_avx $dst, $src1, $src2 \t! using $xtmp1, $xtmp2, $xtmp3 and $xtmp4 as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_addsub_dq_saturating_avx(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister, $src1$$XMMRegister,
|
||||
$src2$$XMMRegister, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister,
|
||||
$xtmp3$$XMMRegister, $xtmp4$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_add_saturating_unsigned_reg_evex(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2, kReg ktmp)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned() &&
|
||||
(Matcher::vector_length_in_bytes(n) == 64 || VM_Version::supports_avx512vl()));
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP ktmp);
|
||||
format %{ "vector_add_saturating_unsigned_evex $dst, $src1, $src2 \t! using $xtmp1, $xtmp2 and $ktmp as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_add_dq_saturating_unsigned_evex(elem_bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister,
|
||||
$xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $ktmp$$KRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_add_saturating_unsigned_reg_avx(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2, vec xtmp3)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned() &&
|
||||
Matcher::vector_length_in_bytes(n) <= 32 && !VM_Version::supports_avx512vl());
|
||||
match(Set dst (SaturatingAddV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP xtmp3);
|
||||
format %{ "vector_add_saturating_unsigned_avx $dst, $src1, $src2 \t! using $xtmp1, $xtmp2 and $xtmp3 as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_add_dq_saturating_unsigned_avx(elem_bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister,
|
||||
$xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $xtmp3$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_sub_saturating_unsigned_reg_evex(vec dst, vec src1, vec src2, kReg ktmp)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned() &&
|
||||
(Matcher::vector_length_in_bytes(n) == 64 || VM_Version::supports_avx512vl()));
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
effect(TEMP ktmp);
|
||||
format %{ "vector_sub_saturating_unsigned_evex $dst, $src1, $src2 \t! using $ktmp as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_sub_dq_saturating_unsigned_evex(elem_bt, $dst$$XMMRegister, $src1$$XMMRegister,
|
||||
$src2$$XMMRegister, $ktmp$$KRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_sub_saturating_unsigned_reg_avx(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2)
|
||||
%{
|
||||
predicate(!is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned() &&
|
||||
Matcher::vector_length_in_bytes(n) <= 32 && !VM_Version::supports_avx512vl());
|
||||
match(Set dst (SaturatingSubV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_sub_saturating_unsigned_avx $dst, $src1, $src2 \t! using $xtmp1 and $xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_sub_dq_saturating_unsigned_avx(elem_bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister,
|
||||
$xtmp1$$XMMRegister, $xtmp2$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_subword_mem(vec dst, vec src1, memory src2)
|
||||
%{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 (LoadVector src2)));
|
||||
match(Set dst (SaturatingSubV src1 (LoadVector src2)));
|
||||
format %{ "vector_addsub_saturating_subword $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_saturating_op(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$Address, false, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_unsigned_subword_mem(vec dst, vec src1, memory src2)
|
||||
%{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV src1 (LoadVector src2)));
|
||||
match(Set dst (SaturatingSubV src1 (LoadVector src2)));
|
||||
format %{ "vector_addsub_saturating_unsigned_subword $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vector_saturating_op(this->ideal_Opcode(), elem_bt, $dst$$XMMRegister,
|
||||
$src1$$XMMRegister, $src2$$Address, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_subword_masked_reg(vec dst, vec src, kReg mask) %{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV (Binary dst src) mask));
|
||||
match(Set dst (SaturatingSubV (Binary dst src) mask));
|
||||
format %{ "vector_addsub_saturating_subword_masked $dst, $mask, $src" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ evmasked_saturating_op(this->ideal_Opcode(), elem_bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$dst$$XMMRegister, $src$$XMMRegister, false, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_unsigned_subword_masked_reg(vec dst, vec src, kReg mask) %{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV (Binary dst src) mask));
|
||||
match(Set dst (SaturatingSubV (Binary dst src) mask));
|
||||
format %{ "vector_addsub_saturating_unsigned_subword_masked $dst, $mask, $src" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ evmasked_saturating_op(this->ideal_Opcode(), elem_bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$dst$$XMMRegister, $src$$XMMRegister, true, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_subword_masked_mem(vec dst, memory src, kReg mask) %{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && !n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV (Binary dst (LoadVector src)) mask));
|
||||
match(Set dst (SaturatingSubV (Binary dst (LoadVector src)) mask));
|
||||
format %{ "vector_addsub_saturating_subword_masked $dst, $mask, $src" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ evmasked_saturating_op(this->ideal_Opcode(), elem_bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$dst$$XMMRegister, $src$$Address, false, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_addsub_saturating_unsigned_subword_masked_mem(vec dst, memory src, kReg mask) %{
|
||||
predicate(is_subword_type(Matcher::vector_element_basic_type(n)) &&
|
||||
n->is_SaturatingVector() && n->as_SaturatingVector()->is_unsigned());
|
||||
match(Set dst (SaturatingAddV (Binary dst (LoadVector src)) mask));
|
||||
match(Set dst (SaturatingSubV (Binary dst (LoadVector src)) mask));
|
||||
format %{ "vector_addsub_saturating_unsigned_subword_masked $dst, $mask, $src" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ evmasked_saturating_op(this->ideal_Opcode(), elem_bt, $mask$$KRegister, $dst$$XMMRegister,
|
||||
$dst$$XMMRegister, $src$$Address, true, true, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_selectfrom_twovectors_reg_evex(vec index, vec src1, vec src2)
|
||||
%{
|
||||
|
@ -3957,15 +3957,15 @@ void MatchNode::count_commutative_op(int& count) {
|
||||
"AndI","AndL",
|
||||
"MaxI","MinI","MaxF","MinF","MaxD","MinD",
|
||||
"MulI","MulL","MulF","MulD",
|
||||
"OrI","OrL",
|
||||
"XorI","XorL"
|
||||
"OrI","OrL", "XorI","XorL",
|
||||
"UMax","UMin"
|
||||
};
|
||||
|
||||
static const char *commut_vector_op_list[] = {
|
||||
"AddVB", "AddVS", "AddVI", "AddVL", "AddVF", "AddVD",
|
||||
"MulVB", "MulVS", "MulVI", "MulVL", "MulVF", "MulVD",
|
||||
"AndV", "OrV", "XorV",
|
||||
"MaxV", "MinV"
|
||||
"MaxV", "MinV", "UMax","UMin"
|
||||
};
|
||||
|
||||
if (_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild)) {
|
||||
@ -4339,7 +4339,7 @@ bool MatchRule::is_vector() const {
|
||||
"NegVF","NegVD","NegVI","NegVL",
|
||||
"SqrtVD","SqrtVF",
|
||||
"AndV" ,"XorV" ,"OrV",
|
||||
"MaxV", "MinV",
|
||||
"MaxV", "MinV", "UMinV", "UMaxV",
|
||||
"CompressV", "ExpandV", "CompressM", "CompressBitsV", "ExpandBitsV",
|
||||
"AddReductionVI", "AddReductionVL",
|
||||
"AddReductionVF", "AddReductionVD",
|
||||
@ -4362,7 +4362,7 @@ bool MatchRule::is_vector() const {
|
||||
"VectorUCastB2X", "VectorUCastS2X", "VectorUCastI2X",
|
||||
"VectorMaskWrapper","VectorMaskCmp","VectorReinterpret","LoadVectorMasked","StoreVectorMasked",
|
||||
"FmaVD","FmaVF","PopCountVI","PopCountVL","PopulateIndex","VectorLongToMask",
|
||||
"CountLeadingZerosV", "CountTrailingZerosV", "SignumVF", "SignumVD",
|
||||
"CountLeadingZerosV", "CountTrailingZerosV", "SignumVF", "SignumVD", "SaturatingAddV", "SaturatingSubV",
|
||||
// Next are vector mask ops.
|
||||
"MaskAll", "AndVMask", "OrVMask", "XorVMask", "VectorMaskCast",
|
||||
"RoundVF", "RoundVD",
|
||||
|
@ -330,6 +330,8 @@ shmacro(ShenandoahLoadReferenceBarrier)
|
||||
macro(SCMemProj)
|
||||
macro(CopySignD)
|
||||
macro(CopySignF)
|
||||
macro(SaturatingAddV)
|
||||
macro(SaturatingSubV)
|
||||
macro(SignumD)
|
||||
macro(SignumF)
|
||||
macro(SignumVF)
|
||||
@ -436,6 +438,8 @@ macro(XorV)
|
||||
macro(XorReductionV)
|
||||
macro(MinV)
|
||||
macro(MaxV)
|
||||
macro(UMinV)
|
||||
macro(UMaxV)
|
||||
macro(MinReductionV)
|
||||
macro(MaxReductionV)
|
||||
macro(CompressV)
|
||||
|
@ -169,6 +169,7 @@ class RootNode;
|
||||
class SafePointNode;
|
||||
class SafePointScalarObjectNode;
|
||||
class SafePointScalarMergeNode;
|
||||
class SaturatingVectorNode;
|
||||
class StartNode;
|
||||
class State;
|
||||
class StoreNode;
|
||||
@ -741,6 +742,7 @@ public:
|
||||
DEFINE_CLASS_ID(CompressM, Vector, 6)
|
||||
DEFINE_CLASS_ID(Reduction, Vector, 7)
|
||||
DEFINE_CLASS_ID(NegV, Vector, 8)
|
||||
DEFINE_CLASS_ID(SaturatingVector, Vector, 9)
|
||||
DEFINE_CLASS_ID(Con, Type, 8)
|
||||
DEFINE_CLASS_ID(ConI, Con, 0)
|
||||
DEFINE_CLASS_ID(SafePointScalarMerge, Type, 9)
|
||||
@ -1010,6 +1012,7 @@ public:
|
||||
DEFINE_CLASS_QUERY(StoreVectorScatter)
|
||||
DEFINE_CLASS_QUERY(StoreVectorMasked)
|
||||
DEFINE_CLASS_QUERY(StoreVectorScatterMasked)
|
||||
DEFINE_CLASS_QUERY(SaturatingVector)
|
||||
DEFINE_CLASS_QUERY(ShiftV)
|
||||
DEFINE_CLASS_QUERY(Unlock)
|
||||
|
||||
|
@ -365,9 +365,12 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
}
|
||||
|
||||
BasicType elem_bt = elem_type->basic_type();
|
||||
bool has_scalar_op = VectorSupport::has_scalar_op(opr->get_con());
|
||||
bool is_unsigned = VectorSupport::is_unsigned_op(opr->get_con());
|
||||
|
||||
int num_elem = vlen->get_con();
|
||||
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
|
||||
int sopc = VectorNode::opcode(opc, elem_bt);
|
||||
int sopc = has_scalar_op ? VectorNode::opcode(opc, elem_bt) : opc;
|
||||
if ((opc != Op_CallLeafVector) && (sopc == 0)) {
|
||||
log_if_needed(" ** operation not supported: opc=%s bt=%s", NodeClassNames[opc], type2name(elem_bt));
|
||||
return false; // operation not supported
|
||||
@ -481,7 +484,7 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
case 2: {
|
||||
operation = VectorNode::make(sopc, opd1, opd2, vt, is_vector_mask(vbox_klass), VectorNode::is_shift_opcode(opc));
|
||||
operation = VectorNode::make(sopc, opd1, opd2, vt, is_vector_mask(vbox_klass), VectorNode::is_shift_opcode(opc), is_unsigned);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
|
@ -667,7 +667,7 @@ VectorNode* VectorNode::make_mask_node(int vopc, Node* n1, Node* n2, uint vlen,
|
||||
}
|
||||
|
||||
// Make a vector node for binary operation
|
||||
VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask, bool is_var_shift) {
|
||||
VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask, bool is_var_shift, bool is_unsigned) {
|
||||
// This method should not be called for unimplemented vectors.
|
||||
guarantee(vopc > 0, "vopc must be > 0");
|
||||
|
||||
@ -739,6 +739,9 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b
|
||||
case Op_RShiftVI: return new RShiftVINode(n1, n2, vt, is_var_shift);
|
||||
case Op_RShiftVL: return new RShiftVLNode(n1, n2, vt, is_var_shift);
|
||||
|
||||
case Op_UMinV: return new UMinVNode(n1, n2, vt);
|
||||
case Op_UMaxV: return new UMaxVNode(n1, n2, vt);
|
||||
|
||||
case Op_URShiftVB: return new URShiftVBNode(n1, n2, vt, is_var_shift);
|
||||
case Op_URShiftVS: return new URShiftVSNode(n1, n2, vt, is_var_shift);
|
||||
case Op_URShiftVI: return new URShiftVINode(n1, n2, vt, is_var_shift);
|
||||
@ -759,6 +762,10 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b
|
||||
case Op_ExpandBitsV: return new ExpandBitsVNode(n1, n2, vt);
|
||||
case Op_CountLeadingZerosV: return new CountLeadingZerosVNode(n1, vt);
|
||||
case Op_CountTrailingZerosV: return new CountTrailingZerosVNode(n1, vt);
|
||||
|
||||
case Op_SaturatingAddV: return new SaturatingAddVNode(n1, n2, vt, is_unsigned);
|
||||
case Op_SaturatingSubV: return new SaturatingSubVNode(n1, n2, vt, is_unsigned);
|
||||
|
||||
default:
|
||||
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
|
||||
return nullptr;
|
||||
@ -2079,10 +2086,8 @@ Node* VectorBlendNode::Identity(PhaseGVN* phase) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
void VectorBoxAllocateNode::dump_spec(outputStream *st) const {
|
||||
CallStaticJavaNode::dump_spec(st);
|
||||
}
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
@ -78,7 +78,7 @@ class VectorNode : public TypeNode {
|
||||
static VectorNode* scalar2vector(Node* s, uint vlen, BasicType bt, bool is_mask = false);
|
||||
static VectorNode* shift_count(int opc, Node* cnt, uint vlen, BasicType bt);
|
||||
static VectorNode* make(int opc, Node* n1, Node* n2, uint vlen, BasicType bt, bool is_var_shift = false);
|
||||
static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask = false, bool is_var_shift = false);
|
||||
static VectorNode* make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask = false, bool is_var_shift = false, bool is_unsigned = false);
|
||||
static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
|
||||
static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
|
||||
static VectorNode* make_mask_node(int vopc, Node* n1, Node* n2, uint vlen, BasicType bt);
|
||||
@ -144,6 +144,32 @@ class VectorNode : public TypeNode {
|
||||
};
|
||||
|
||||
//===========================Vector=ALU=Operations=============================
|
||||
// Base IR node for saturating signed / unsigned operations.
|
||||
// Saturating operation prevents wrapping result value in over/underflowing
|
||||
// scenarios, instead returns delimiting MAX/MIN value of result type.
|
||||
class SaturatingVectorNode : public VectorNode {
|
||||
private:
|
||||
const bool _is_unsigned;
|
||||
|
||||
public:
|
||||
SaturatingVectorNode(Node* in1, Node* in2, const TypeVect* vt, bool is_unsigned) : VectorNode(in1, in2, vt), _is_unsigned(is_unsigned) {
|
||||
init_class_id(Class_SaturatingVector);
|
||||
}
|
||||
|
||||
// Needed for proper cloning.
|
||||
virtual uint size_of() const { return sizeof(*this); }
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Print node specific info
|
||||
virtual void dump_spec(outputStream *st) const {
|
||||
TypeNode::dump_spec(st);
|
||||
st->print("%s", _is_unsigned ? "{unsigned_vector_node}" : "{signed_vector_node}");
|
||||
}
|
||||
#endif
|
||||
virtual uint hash() const { return Node::hash() + _is_unsigned; }
|
||||
|
||||
bool is_unsigned() { return _is_unsigned; }
|
||||
};
|
||||
|
||||
//------------------------------AddVBNode--------------------------------------
|
||||
// Vector add byte
|
||||
@ -355,6 +381,22 @@ class SubVLNode : public VectorNode {
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------SaturatingAddVNode-----------------------------
|
||||
// Vector saturating addition.
|
||||
class SaturatingAddVNode : public SaturatingVectorNode {
|
||||
public:
|
||||
SaturatingAddVNode(Node* in1, Node* in2, const TypeVect* vt, bool is_unsigned) : SaturatingVectorNode(in1, in2, vt, is_unsigned) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------SaturatingSubVNode-----------------------------
|
||||
// Vector saturating subtraction.
|
||||
class SaturatingSubVNode : public SaturatingVectorNode {
|
||||
public:
|
||||
SaturatingSubVNode(Node* in1, Node* in2, const TypeVect* vt, bool is_unsigned) : SaturatingVectorNode(in1, in2, vt, is_unsigned) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------SubVFNode--------------------------------------
|
||||
// Vector subtract float
|
||||
class SubVFNode : public VectorNode {
|
||||
@ -561,6 +603,14 @@ public:
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
class UMinVNode : public VectorNode {
|
||||
public:
|
||||
UMinVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2 ,vt) {
|
||||
assert(is_integral_type(vt->element_basic_type()), "");
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------MaxVNode--------------------------------------
|
||||
// Vector Max
|
||||
class MaxVNode : public VectorNode {
|
||||
@ -569,6 +619,14 @@ class MaxVNode : public VectorNode {
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
class UMaxVNode : public VectorNode {
|
||||
public:
|
||||
UMaxVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {
|
||||
assert(is_integral_type(vt->element_basic_type()), "");
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//------------------------------AbsVINode--------------------------------------
|
||||
// Vector Abs int
|
||||
class AbsVINode : public VectorNode {
|
||||
|
@ -199,6 +199,36 @@ instanceOop VectorSupport::allocate_vector(InstanceKlass* ik, frame* fr, Registe
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
bool VectorSupport::has_scalar_op(jint id) {
|
||||
VectorOperation vop = (VectorOperation)id;
|
||||
switch (vop) {
|
||||
case VECTOR_OP_COMPRESS:
|
||||
case VECTOR_OP_EXPAND:
|
||||
case VECTOR_OP_SADD:
|
||||
case VECTOR_OP_SUADD:
|
||||
case VECTOR_OP_SSUB:
|
||||
case VECTOR_OP_SUSUB:
|
||||
case VECTOR_OP_UMIN:
|
||||
case VECTOR_OP_UMAX:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorSupport::is_unsigned_op(jint id) {
|
||||
VectorOperation vop = (VectorOperation)id;
|
||||
switch (vop) {
|
||||
case VECTOR_OP_SUADD:
|
||||
case VECTOR_OP_SUSUB:
|
||||
case VECTOR_OP_UMIN:
|
||||
case VECTOR_OP_UMAX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int VectorSupport::vop2ideal(jint id, BasicType bt) {
|
||||
VectorOperation vop = (VectorOperation)id;
|
||||
switch (vop) {
|
||||
@ -274,6 +304,26 @@ int VectorSupport::vop2ideal(jint id, BasicType bt) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_UMIN: {
|
||||
switch (bt) {
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
case T_LONG: return Op_UMinV;
|
||||
default: fatal("MIN: %s", type2name(bt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_UMAX: {
|
||||
switch (bt) {
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
case T_LONG: return Op_UMaxV;
|
||||
default: fatal("MAX: %s", type2name(bt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_ABS: {
|
||||
switch (bt) {
|
||||
case T_BYTE: // fall-through
|
||||
@ -533,6 +583,28 @@ int VectorSupport::vop2ideal(jint id, BasicType bt) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_SADD:
|
||||
case VECTOR_OP_SUADD: {
|
||||
switch(bt) {
|
||||
case T_BYTE: // fall-through
|
||||
case T_SHORT: // fall-through
|
||||
case T_INT: // fall-through
|
||||
case T_LONG: return Op_SaturatingAddV;
|
||||
default: fatal("S[U]ADD: %s", type2name(bt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_SSUB:
|
||||
case VECTOR_OP_SUSUB: {
|
||||
switch(bt) {
|
||||
case T_BYTE: // fall-through
|
||||
case T_SHORT: // fall-through
|
||||
case T_INT: // fall-through
|
||||
case T_LONG: return Op_SaturatingSubV;
|
||||
default: fatal("S[U}SUB: %s", type2name(bt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VECTOR_OP_COMPRESS_BITS: {
|
||||
switch (bt) {
|
||||
case T_INT:
|
||||
|
@ -121,6 +121,13 @@ class VectorSupport : AllStatic {
|
||||
VECTOR_OP_EXPM1 = 117,
|
||||
VECTOR_OP_HYPOT = 118,
|
||||
|
||||
VECTOR_OP_SADD = 119,
|
||||
VECTOR_OP_SSUB = 120,
|
||||
VECTOR_OP_SUADD = 121,
|
||||
VECTOR_OP_SUSUB = 122,
|
||||
VECTOR_OP_UMIN = 123,
|
||||
VECTOR_OP_UMAX = 124,
|
||||
|
||||
VECTOR_OP_MATH_START = VECTOR_OP_TAN,
|
||||
VECTOR_OP_MATH_END = VECTOR_OP_HYPOT,
|
||||
NUM_VECTOR_OP_MATH = VECTOR_OP_MATH_END - VECTOR_OP_MATH_START + 1
|
||||
@ -143,6 +150,8 @@ class VectorSupport : AllStatic {
|
||||
static const char* mathname[VectorSupport::NUM_VECTOR_OP_MATH];
|
||||
|
||||
static int vop2ideal(jint vop, BasicType bt);
|
||||
static bool has_scalar_op(jint id);
|
||||
static bool is_unsigned_op(jint id);
|
||||
|
||||
static instanceOop allocate_vector(InstanceKlass* holder, frame* fr, RegisterMap* reg_map, ObjectValue* sv, TRAPS);
|
||||
|
||||
|
@ -114,6 +114,13 @@ public class VectorSupport {
|
||||
public static final int VECTOR_OP_EXPM1 = 117;
|
||||
public static final int VECTOR_OP_HYPOT = 118;
|
||||
|
||||
public static final int VECTOR_OP_SADD = 119;
|
||||
public static final int VECTOR_OP_SSUB = 120;
|
||||
public static final int VECTOR_OP_SUADD = 121;
|
||||
public static final int VECTOR_OP_SUSUB = 122;
|
||||
public static final int VECTOR_OP_UMIN = 123;
|
||||
public static final int VECTOR_OP_UMAX = 124;
|
||||
|
||||
// See src/hotspot/share/opto/subnode.hpp
|
||||
// struct BoolTest, and enclosed enum mask
|
||||
public static final int BT_eq = 0; // 0000
|
||||
|
@ -884,6 +884,18 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
|
||||
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
|
||||
case VECTOR_OP_UMAX: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)VectorMath.maxUnsigned(a, b));
|
||||
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)VectorMath.minUnsigned(a, b));
|
||||
case VECTOR_OP_SADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.addSaturating(a, b)));
|
||||
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.subSaturating(a, b)));
|
||||
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.addSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (byte)(VectorMath.subSaturatingUnsigned(a, b)));
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@ -884,6 +884,18 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
|
||||
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
|
||||
case VECTOR_OP_UMAX: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)VectorMath.maxUnsigned(a, b));
|
||||
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)VectorMath.minUnsigned(a, b));
|
||||
case VECTOR_OP_SADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.addSaturating(a, b)));
|
||||
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.subSaturating(a, b)));
|
||||
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.addSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (int)(VectorMath.subSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> Integer.compress(a, n));
|
||||
case VECTOR_OP_EXPAND_BITS: return (v0, v1, vm) ->
|
||||
|
@ -842,6 +842,18 @@ public abstract class LongVector extends AbstractVector<Long> {
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
|
||||
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
|
||||
case VECTOR_OP_UMAX: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)VectorMath.maxUnsigned(a, b));
|
||||
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)VectorMath.minUnsigned(a, b));
|
||||
case VECTOR_OP_SADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.addSaturating(a, b)));
|
||||
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.subSaturating(a, b)));
|
||||
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.addSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (long)(VectorMath.subSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> Long.compress(a, n));
|
||||
case VECTOR_OP_EXPAND_BITS: return (v0, v1, vm) ->
|
||||
|
@ -884,6 +884,18 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
|
||||
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
|
||||
case VECTOR_OP_UMAX: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)VectorMath.maxUnsigned(a, b));
|
||||
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)VectorMath.minUnsigned(a, b));
|
||||
case VECTOR_OP_SADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.addSaturating(a, b)));
|
||||
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.subSaturating(a, b)));
|
||||
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.addSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> (short)(VectorMath.subSaturatingUnsigned(a, b)));
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.incubator.vector;
|
||||
|
||||
/**
|
||||
* The class {@code VectorMath} contains methods for performing
|
||||
* scalar numeric operations in support of vector numeric operations.
|
||||
* @since 24
|
||||
*/
|
||||
public final class VectorMath {
|
||||
|
||||
private VectorMath() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smaller of two {@code long} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0L}. If the operands have the
|
||||
* same value, the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the smaller of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMIN
|
||||
*/
|
||||
public static long minUnsigned(long a, long b) {
|
||||
return Long.compareUnsigned(a, b) < 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greater of two {@code long} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0xFFFFFFFF_FFFFFFFFL} numerically
|
||||
* treating it as unsigned. If the operands have the same value,
|
||||
* the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the larger of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMAX
|
||||
*/
|
||||
public static long maxUnsigned(long a, long b) {
|
||||
return Long.compareUnsigned(a, b) > 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code long} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Long.MIN_VALUE} and {@code Long.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the addition would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Long.MAX_VALUE}.
|
||||
* If the result of the addition would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Long.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SADD
|
||||
*/
|
||||
public static long addSaturating(long a, long b) {
|
||||
long res = a + b;
|
||||
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
|
||||
if (((a ^ res) & (b ^ res)) < 0) {
|
||||
return res < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code long} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Long.MIN_VALUE} and {@code Long.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the subtraction would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Long.MAX_VALUE}.
|
||||
* If the result of the subtraction would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Long.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SSUB
|
||||
*/
|
||||
public static long subSaturating(long a, long b) {
|
||||
long res = a - b;
|
||||
// HD 2-12 Overflow iff the arguments have different signs and
|
||||
// the sign of the result is different from the sign of a
|
||||
if (((a ^ b) & (a ^ res)) < 0) {
|
||||
return a < 0 ? Long.MIN_VALUE : Long.MAX_VALUE;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code long} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0L} and {@code 0xFFFFFFFF_FFFFFFFFL}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned addition would otherwise overflow
|
||||
* from the greater of the two operands to a lesser value then the
|
||||
* result is clamped to the upper bound {@code 0xFFFFFFFF_FFFFFFFFL}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SUADD
|
||||
*/
|
||||
public static long addSaturatingUnsigned(long a, long b) {
|
||||
long res = a + b;
|
||||
boolean overflow = Long.compareUnsigned(res, (a | b)) < 0;
|
||||
if (overflow) {
|
||||
return -1L;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code long} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0L} and {@code 0xFFFFFFFF_FFFFFFFFL}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned subtraction would otherwise underflow
|
||||
* from the lesser of the two operands to a greater value then the
|
||||
* result is clamped to the lower bound {@code 0L}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SUSUB
|
||||
*/
|
||||
public static long subSaturatingUnsigned(long a, long b) {
|
||||
if (Long.compareUnsigned(b, a) < 0) {
|
||||
return a - b;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smaller of two {@code int} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0}. If the operands have the
|
||||
* same value, the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the smaller of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMIN
|
||||
*/
|
||||
public static int minUnsigned(int a, int b) {
|
||||
return Integer.compareUnsigned(a, b) < 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greater of two {@code int} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0xFFFFFFFF} numerically
|
||||
* treating it as unsigned. If the operands have the same value,
|
||||
* the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the larger of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMAX
|
||||
*/
|
||||
public static int maxUnsigned(int a, int b) {
|
||||
return Integer.compareUnsigned(a, b) > 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code int} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Integer.MIN_VALUE} and {@code Integer.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the addition would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Integer.MAX_VALUE}.
|
||||
* If the result of the addition would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Integer.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SADD
|
||||
*/
|
||||
public static int addSaturating(int a, int b) {
|
||||
long res = (long)a + (long)b;
|
||||
if (res > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if (res < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
} else {
|
||||
return (int)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code int} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Integer.MIN_VALUE} and {@code Integer.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the subtraction would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Integer.MAX_VALUE}.
|
||||
* If the result of the subtraction would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Integer.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SSUB
|
||||
*/
|
||||
public static int subSaturating(int a, int b) {
|
||||
long res = (long)a - (long)b;
|
||||
if (res > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else if (res < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
} else {
|
||||
return (int)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code int} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code 0xFFFFFFFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned addition would otherwise overflow
|
||||
* from the greater of the two operands to a lesser value then the
|
||||
* result is clamped to the upper bound {@code 0xFFFFFFFF}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SUADD
|
||||
*/
|
||||
public static int addSaturatingUnsigned(int a, int b) {
|
||||
int res = a + b;
|
||||
boolean overflow = Integer.compareUnsigned(res, (a | b)) < 0;
|
||||
if (overflow) {
|
||||
return -1;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code int} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code -0xFFFFFFFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned subtraction would otherwise underflow
|
||||
* from the lesser of the two operands to a greater value then the
|
||||
* result is clamped to the lower bound {@code 0}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SUSUB
|
||||
*/
|
||||
public static int subSaturatingUnsigned(int a, int b) {
|
||||
if (Integer.compareUnsigned(b, a) < 0) {
|
||||
return a - b;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smaller of two {@code short} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0}. If the operands have the
|
||||
* same value, the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the smaller of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMIN
|
||||
*/
|
||||
public static short minUnsigned(short a, short b) {
|
||||
return Short.compareUnsigned(a, b) < 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greater of two {@code short} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0xFFFF} numerically
|
||||
* treating it as unsigned. If the operands have the same value,
|
||||
* the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the larger of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMAX
|
||||
*/
|
||||
public static short maxUnsigned(short a, short b) {
|
||||
return Short.compareUnsigned(a, b) > 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code short} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Short.MIN_VALUE} and {@code Short.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the addition would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Short.MAX_VALUE}.
|
||||
* If the result of the addition would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Short.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SADD
|
||||
*/
|
||||
public static short addSaturating(short a, short b) {
|
||||
int res = a + b;
|
||||
if (res > Short.MAX_VALUE) {
|
||||
return Short.MAX_VALUE;
|
||||
} else if (res < Short.MIN_VALUE) {
|
||||
return Short.MIN_VALUE;
|
||||
} else {
|
||||
return (short)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code short} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Short.MIN_VALUE} and {@code Short.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the subtraction would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Short.MAX_VALUE}.
|
||||
* If the result of the subtraction would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Short.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SSUB
|
||||
*/
|
||||
public static short subSaturating(short a, short b) {
|
||||
int res = a - b;
|
||||
if (res > Short.MAX_VALUE) {
|
||||
return Short.MAX_VALUE;
|
||||
} else if (res < Short.MIN_VALUE) {
|
||||
return Short.MIN_VALUE;
|
||||
} else {
|
||||
return (short)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code short} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code 0xFFFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned addition would otherwise overflow
|
||||
* from the greater of the two operands to a lesser value then the
|
||||
* result is clamped to the upper bound {@code 0xFFFF}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SUADD
|
||||
*/
|
||||
public static short addSaturatingUnsigned(short a, short b) {
|
||||
short res = (short)(a + b);
|
||||
boolean overflow = Short.compareUnsigned(res, (short)(a | b)) < 0;
|
||||
if (overflow) {
|
||||
return (short)(-1);
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code short} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code 0xFFFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned subtraction would otherwise underflow
|
||||
* from the lesser of the two operands to a greater value then the
|
||||
* result is clamped to the lower bound {@code 0}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SUSUB
|
||||
*/
|
||||
public static short subSaturatingUnsigned(short a, short b) {
|
||||
if (Short.compareUnsigned(b, a) < 0) {
|
||||
return (short)(a - b);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smaller of two {@code byte} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0}. If the operands have the
|
||||
* same value, the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the smaller of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMIN
|
||||
*/
|
||||
public static byte minUnsigned(byte a, byte b) {
|
||||
return Byte.compareUnsigned(a, b) < 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greater of two {@code byte} values numerically treating
|
||||
* the values as unsigned. That is, the result is the operand closer
|
||||
* to the value of the expression {@code 0xFF} numerically
|
||||
* treating it as unsigned. If the operands have the same value,
|
||||
* the result is that same value.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the larger of {@code a} and {@code b}.
|
||||
* @see VectorOperators#UMAX
|
||||
*/
|
||||
public static byte maxUnsigned(byte a, byte b) {
|
||||
return Byte.compareUnsigned(a, b) > 0 ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code byte} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Byte.MIN_VALUE} and {@code Byte.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the addition would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Byte.MAX_VALUE}.
|
||||
* If the result of the addition would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Byte.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SADD
|
||||
*/
|
||||
public static byte addSaturating(byte a, byte b) {
|
||||
int res = a + b;
|
||||
if (res > Byte.MAX_VALUE) {
|
||||
return Byte.MAX_VALUE;
|
||||
} else if (res < Byte.MIN_VALUE) {
|
||||
return Byte.MIN_VALUE;
|
||||
} else {
|
||||
return (byte)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code byte} values using saturation
|
||||
* arithemetic. The lower and upper (inclusive) bounds are
|
||||
* {@code Byte.MIN_VALUE} and {@code Byte.MAX_VALUE}, respectively.
|
||||
* <p>
|
||||
* If the result of the subtraction would otherwise overflow from
|
||||
* a positive value to a negative value then the result is clamped
|
||||
* to the upper bound {@code Byte.MAX_VALUE}.
|
||||
* If the result of the subtraction would otherwise underflow from
|
||||
* a negative value to a positive value then the result is clamped
|
||||
* to lower bound {@code Byte.MIN_VALUE}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SSUB
|
||||
*/
|
||||
public static byte subSaturating(byte a, byte b) {
|
||||
int res = a - b;
|
||||
if (res > Byte.MAX_VALUE) {
|
||||
return Byte.MAX_VALUE;
|
||||
} else if (res < Byte.MIN_VALUE) {
|
||||
return Byte.MIN_VALUE;
|
||||
} else {
|
||||
return (byte)res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two {@code byte} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code 0xFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned addition would otherwise overflow
|
||||
* from the greater of the two operands to a lesser value then the
|
||||
* result is clamped to the upper bound {@code 0xFF}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating addition of the operands.
|
||||
* @see VectorOperators#SUADD
|
||||
*/
|
||||
public static byte addSaturatingUnsigned(byte a, byte b) {
|
||||
byte res = (byte)(a + b);
|
||||
boolean overflow = Byte.compareUnsigned(res, (byte)(a | b)) < 0;
|
||||
if (overflow) {
|
||||
return (byte)(-1);
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two {@code byte} values using saturation
|
||||
* arithemetic and numerically treating the values
|
||||
* as unsigned. The lower and upper (inclusive) bounds
|
||||
* are {@code 0} and {@code 0xFF}, respectively,
|
||||
* numerically treating them as unsigned.
|
||||
* <p>
|
||||
* If the result of the unsigned subtraction would otherwise underflow
|
||||
* from the lesser of the two operands to a greater value then the
|
||||
* result is clamped to the lower bound {@code 0}.
|
||||
*
|
||||
* @param a the first operand.
|
||||
* @param b the second operand.
|
||||
* @return the saturating difference of the operands.
|
||||
* @see VectorOperators#SUSUB
|
||||
*/
|
||||
public static byte subSaturatingUnsigned(byte a, byte b) {
|
||||
if (Byte.compareUnsigned(b, a) < 0) {
|
||||
return (byte)(a - b);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -567,6 +567,32 @@ public abstract class VectorOperators {
|
||||
/** Produce {@code a^b}. Integral only. */
|
||||
public static final /*bitwise*/ Associative XOR = assoc("XOR", "^", VectorSupport.VECTOR_OP_XOR, VO_NOFP+VO_ASSOC);
|
||||
|
||||
/** Produce saturating {@code a+b}. Integral only.
|
||||
* @see VectorMath#addSaturating(int, int)
|
||||
*/
|
||||
public static final Binary SADD = binary("SADD", "+", VectorSupport.VECTOR_OP_SADD, VO_NOFP);
|
||||
/** Produce saturating unsigned {@code a+b}. Integral only.
|
||||
* @see VectorMath#addSaturatingUnsigned(int, int)
|
||||
*/
|
||||
public static final Binary SUADD = binary("SUADD", "+", VectorSupport.VECTOR_OP_SUADD, VO_NOFP);
|
||||
/** Produce saturating {@code a-b}. Integral only.
|
||||
* @see VectorMath#subSaturating(int, int)
|
||||
*/
|
||||
public static final Binary SSUB = binary("SSUB", "-", VectorSupport.VECTOR_OP_SSUB, VO_NOFP);
|
||||
/** Produce saturating unsigned {@code a-b}. Integral only.
|
||||
* @see VectorMath#subSaturatingUnsigned(int, int)
|
||||
*/
|
||||
public static final Binary SUSUB = binary("SUSUB", "-", VectorSupport.VECTOR_OP_SUSUB, VO_NOFP);
|
||||
/** Produce unsigned {@code min(a,b)}. Integral only.
|
||||
* @see VectorMath#minUnsigned(int, int) (int, int)
|
||||
*/
|
||||
public static final Associative UMIN = assoc("UMIN", "umin", VectorSupport.VECTOR_OP_UMIN, VO_NOFP+VO_ASSOC);
|
||||
/** Produce unsigned {@code max(a,b)}. Integral only.
|
||||
* @see VectorMath#maxUnsigned(int, int) (int, int)
|
||||
*/
|
||||
public static final Associative UMAX = assoc("UMAX", "umax", VectorSupport.VECTOR_OP_UMAX, VO_NOFP+VO_ASSOC);
|
||||
|
||||
|
||||
/** Produce {@code a<<(n&(ESIZE*8-1))}. Integral only. */
|
||||
public static final /*bitwise*/ Binary LSHL = binary("LSHL", "<<", VectorSupport.VECTOR_OP_LSHIFT, VO_SHIFT);
|
||||
/** Produce {@code a>>(n&(ESIZE*8-1))}. Integral only. */
|
||||
@ -636,22 +662,22 @@ public abstract class VectorOperators {
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_LT = compare("UNSIGNED_LT", "<", VectorSupport.BT_ult, VO_NOFP);
|
||||
public static final Comparison ULT = compare("ULT", "<", VectorSupport.BT_ult, VO_NOFP);
|
||||
/** Unsigned compare {@code a<=b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_LE = compare("UNSIGNED_LE", "<=", VectorSupport.BT_ule, VO_NOFP);
|
||||
public static final Comparison ULE = compare("ULE", "<=", VectorSupport.BT_ule, VO_NOFP);
|
||||
/** Unsigned compare {@code a>b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_GT = compare("UNSIGNED_GT", ">", VectorSupport.BT_ugt, VO_NOFP);
|
||||
public static final Comparison UGT = compare("UGT", ">", VectorSupport.BT_ugt, VO_NOFP);
|
||||
/** Unsigned compare {@code a>=b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_GE = compare("UNSIGNED_GE", ">=", VectorSupport.BT_uge, VO_NOFP);
|
||||
public static final Comparison UGE = compare("UGE", ">=", VectorSupport.BT_uge, VO_NOFP);
|
||||
|
||||
// Conversion operators
|
||||
|
||||
|
@ -980,6 +980,18 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
|
||||
case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
|
||||
case VECTOR_OP_UMAX: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)VectorMath.maxUnsigned(a, b));
|
||||
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)VectorMath.minUnsigned(a, b));
|
||||
case VECTOR_OP_SADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturating(a, b)));
|
||||
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturating(a, b)));
|
||||
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturatingUnsigned(a, b)));
|
||||
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturatingUnsigned(a, b)));
|
||||
#if[intOrLong]
|
||||
case VECTOR_OP_COMPRESS_BITS: return (v0, v1, vm) ->
|
||||
v0.bOp(v1, vm, (i, a, n) -> $Boxtype$.compress(a, n));
|
||||
|
@ -143,7 +143,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
|
||||
public static void testByteUnsignedGTInRange() {
|
||||
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GT, 64).intoArray(br, 0);
|
||||
av.compare(VectorOperators.UGT, 64).intoArray(br, 0);
|
||||
}
|
||||
|
||||
@Run(test = "testByteUnsignedGTInRange")
|
||||
@ -163,7 +163,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
|
||||
public static void testByteUnsignedGTOutOfRange() {
|
||||
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GT, -91).intoArray(br, 0);
|
||||
av.compare(VectorOperators.UGT, -91).intoArray(br, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -183,7 +183,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
|
||||
public static void testShortUnsignedGEInRange() {
|
||||
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GE, 56).intoArray(sr, 0);
|
||||
av.compare(VectorOperators.UGE, 56).intoArray(sr, 0);
|
||||
}
|
||||
|
||||
@Run(test = "testShortUnsignedGEInRange")
|
||||
@ -203,7 +203,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
|
||||
public static void testShortUnsignedGEOutOfRange() {
|
||||
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GE, -85).intoArray(sr, 0);
|
||||
av.compare(VectorOperators.UGE, -85).intoArray(sr, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -223,7 +223,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(counts = { IRNode.VMASK_CMPU_IMM_I_SVE, ">= 1" })
|
||||
public static void testIntUnsignedLTInRange() {
|
||||
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_LT, 101).intoArray(ir, 0);
|
||||
av.compare(VectorOperators.ULT, 101).intoArray(ir, 0);
|
||||
}
|
||||
|
||||
@Run(test = "testIntUnsignedLTInRange")
|
||||
@ -243,7 +243,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(failOn = { IRNode.VMASK_CMPU_IMM_I_SVE })
|
||||
public static void testIntUnsignedLTOutOfRange() {
|
||||
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_LT, -110).intoArray(ir, 0);
|
||||
av.compare(VectorOperators.ULT, -110).intoArray(ir, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -263,7 +263,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(counts = { IRNode.VMASK_CMPU_IMM_L_SVE, ">= 1" })
|
||||
public static void testLongUnsignedLEInRange() {
|
||||
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_LE, 95).intoArray(lr, 0);
|
||||
av.compare(VectorOperators.ULE, 95).intoArray(lr, 0);
|
||||
}
|
||||
|
||||
@Run(test = "testLongUnsignedLEInRange")
|
||||
@ -283,7 +283,7 @@ public class VectorCompareWithImmTest {
|
||||
@IR(failOn = { IRNode.VMASK_CMPU_IMM_L_SVE })
|
||||
public static void testLongUnsignedLEOutOfRange() {
|
||||
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_LE, -99).intoArray(lr, 0);
|
||||
av.compare(VectorOperators.ULE, -99).intoArray(lr, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -240,14 +240,14 @@ public class VectorCompareWithZeroTest {
|
||||
@IR(failOn = { IRNode.VMASK_CMP_ZERO_I_NEON })
|
||||
public static void testIntVectorUnsignedCondition() {
|
||||
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GT, 0).intoArray(ir, 0);
|
||||
av.compare(VectorOperators.UGT, 0).intoArray(ir, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = { IRNode.VMASK_CMP_ZERO_L_NEON })
|
||||
public static void testLongVectorUnsignedCondition() {
|
||||
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
|
||||
av.compare(VectorOperators.UNSIGNED_GE, 0).intoArray(lr, 0);
|
||||
av.compare(VectorOperators.UGE, 0).intoArray(lr, 0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
@ -257,4 +257,4 @@ public class VectorCompareWithZeroTest {
|
||||
.addFlags("-XX:UseSVE=0")
|
||||
.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
|
||||
@ -962,6 +963,33 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<byte[]>> BYTE_SATURATING_GENERATORS = List.of(
|
||||
withToString("byte[Byte.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("byte[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(-i * 5));
|
||||
}),
|
||||
withToString("byte[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_PAIRS =
|
||||
@ -969,6 +997,11 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(BYTE_GENERATORS.get(0)).
|
||||
flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -999,12 +1032,27 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpProvider() {
|
||||
return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteIndexedOpProvider() {
|
||||
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2939,6 +2987,252 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::max);
|
||||
}
|
||||
|
||||
static byte UMIN(byte a, byte b) {
|
||||
return (byte)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMINByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMINByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static byte UMAX(byte a, byte b) {
|
||||
return (byte)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMAXByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMAXByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static byte SADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SADDByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SADDByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::SADD);
|
||||
}
|
||||
|
||||
static byte SSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SSUBByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static byte SUADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUADDByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static byte SUSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUSUBByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void MINByte128VectorTestsBroadcastSmokeTest(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
@ -4147,7 +4441,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LTByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULTByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4155,7 +4449,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4166,7 +4460,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULTByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4178,7 +4472,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4189,7 +4483,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GTByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGTByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4197,7 +4491,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4208,7 +4502,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGTByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4220,7 +4514,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4231,7 +4525,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LEByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULEByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4239,7 +4533,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4250,7 +4544,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULEByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4262,7 +4556,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4273,7 +4567,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GEByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGEByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4281,7 +4575,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4292,7 +4586,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGEByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4304,7 +4598,7 @@ public class Byte128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
|
||||
@ -962,6 +963,33 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<byte[]>> BYTE_SATURATING_GENERATORS = List.of(
|
||||
withToString("byte[Byte.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("byte[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(-i * 5));
|
||||
}),
|
||||
withToString("byte[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_PAIRS =
|
||||
@ -969,6 +997,11 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(BYTE_GENERATORS.get(0)).
|
||||
flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -999,12 +1032,27 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpProvider() {
|
||||
return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteIndexedOpProvider() {
|
||||
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2939,6 +2987,252 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::max);
|
||||
}
|
||||
|
||||
static byte UMIN(byte a, byte b) {
|
||||
return (byte)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMINByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMINByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static byte UMAX(byte a, byte b) {
|
||||
return (byte)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMAXByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMAXByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static byte SADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SADDByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SADDByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::SADD);
|
||||
}
|
||||
|
||||
static byte SSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SSUBByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static byte SUADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUADDByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static byte SUSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUSUBByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void MINByte256VectorTestsBroadcastSmokeTest(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
@ -4147,7 +4441,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LTByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULTByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4155,7 +4449,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4166,7 +4460,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULTByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4178,7 +4472,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4189,7 +4483,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GTByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGTByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4197,7 +4491,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4208,7 +4502,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGTByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4220,7 +4514,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4231,7 +4525,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LEByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULEByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4239,7 +4533,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4250,7 +4544,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULEByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4262,7 +4556,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4273,7 +4567,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GEByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGEByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4281,7 +4575,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4292,7 +4586,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGEByte256VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4304,7 +4598,7 @@ public class Byte256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
|
||||
@ -962,6 +963,33 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<byte[]>> BYTE_SATURATING_GENERATORS = List.of(
|
||||
withToString("byte[Byte.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("byte[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(-i * 5));
|
||||
}),
|
||||
withToString("byte[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_PAIRS =
|
||||
@ -969,6 +997,11 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(BYTE_GENERATORS.get(0)).
|
||||
flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -999,12 +1032,27 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpProvider() {
|
||||
return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteIndexedOpProvider() {
|
||||
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2939,6 +2987,252 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::max);
|
||||
}
|
||||
|
||||
static byte UMIN(byte a, byte b) {
|
||||
return (byte)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMINByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMINByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static byte UMAX(byte a, byte b) {
|
||||
return (byte)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMAXByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMAXByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static byte SADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SADDByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SADDByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::SADD);
|
||||
}
|
||||
|
||||
static byte SSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SSUBByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static byte SUADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUADDByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static byte SUSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUSUBByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void MINByte512VectorTestsBroadcastSmokeTest(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
@ -4147,7 +4441,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LTByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULTByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4155,7 +4449,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4166,7 +4460,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULTByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4178,7 +4472,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4189,7 +4483,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GTByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGTByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4197,7 +4491,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4208,7 +4502,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGTByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4220,7 +4514,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4231,7 +4525,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LEByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULEByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4239,7 +4533,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4250,7 +4544,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULEByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4262,7 +4556,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4273,7 +4567,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GEByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGEByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4281,7 +4575,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4292,7 +4586,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGEByte512VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4304,7 +4598,7 @@ public class Byte512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
|
||||
@ -962,6 +963,33 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<byte[]>> BYTE_SATURATING_GENERATORS = List.of(
|
||||
withToString("byte[Byte.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("byte[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(-i * 5));
|
||||
}),
|
||||
withToString("byte[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_PAIRS =
|
||||
@ -969,6 +997,11 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(BYTE_GENERATORS.get(0)).
|
||||
flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -999,12 +1032,27 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpProvider() {
|
||||
return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteIndexedOpProvider() {
|
||||
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2939,6 +2987,252 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::max);
|
||||
}
|
||||
|
||||
static byte UMIN(byte a, byte b) {
|
||||
return (byte)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMINByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMINByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static byte UMAX(byte a, byte b) {
|
||||
return (byte)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMAXByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMAXByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static byte SADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SADDByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SADDByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::SADD);
|
||||
}
|
||||
|
||||
static byte SSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SSUBByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static byte SUADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUADDByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static byte SUSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUSUBByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Byte64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Byte64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void MINByte64VectorTestsBroadcastSmokeTest(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
@ -4147,7 +4441,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LTByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULTByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4155,7 +4449,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4166,7 +4460,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULTByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4178,7 +4472,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4189,7 +4483,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GTByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGTByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4197,7 +4491,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4208,7 +4502,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGTByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4220,7 +4514,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4231,7 +4525,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LEByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULEByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4239,7 +4533,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4250,7 +4544,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULEByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4262,7 +4556,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4273,7 +4567,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GEByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGEByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4281,7 +4575,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4292,7 +4586,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGEByte64VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4304,7 +4598,7 @@ public class Byte64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
|
||||
@ -967,6 +968,33 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<byte[]>> BYTE_SATURATING_GENERATORS = List.of(
|
||||
withToString("byte[Byte.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE));
|
||||
}),
|
||||
withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("byte[Byte.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(Byte.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("byte[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(-i * 5));
|
||||
}),
|
||||
withToString("byte[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (byte)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_PAIRS =
|
||||
@ -974,6 +1002,11 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> BYTE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<byte[]>>> BYTE_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(BYTE_GENERATORS.get(0)).
|
||||
flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -1004,12 +1037,27 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpProvider() {
|
||||
return BYTE_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteIndexedOpProvider() {
|
||||
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> BYTE_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] byteBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2944,6 +2992,252 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::max);
|
||||
}
|
||||
|
||||
static byte UMIN(byte a, byte b) {
|
||||
return (byte)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMINByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMINByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
static byte UMAX(byte a, byte b) {
|
||||
return (byte)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void UMAXByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpMaskProvider")
|
||||
static void UMAXByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
static byte SADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SADDByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SADDByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
static byte SSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SSUBByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
static byte SUADD(byte a, byte b) {
|
||||
return (byte)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUADDByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
static byte SUSUB(byte a, byte b) {
|
||||
return (byte)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpProvider")
|
||||
static void SUSUBByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ByteMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
byte[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ByteMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteBinaryOpProvider")
|
||||
static void MINByteMaxVectorTestsBroadcastSmokeTest(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
@ -4152,7 +4446,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LTByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULTByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4160,7 +4454,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4171,7 +4465,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULTByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4183,7 +4477,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4194,7 +4488,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GTByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGTByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4202,7 +4496,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4213,7 +4507,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGTByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4225,7 +4519,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4236,7 +4530,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_LEByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void ULEByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4244,7 +4538,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4255,7 +4549,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void ULEByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4267,7 +4561,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4278,7 +4572,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpProvider")
|
||||
static void UNSIGNED_GEByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
static void UGEByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4286,7 +4580,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4297,7 +4591,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "byteCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
static void UGEByteMaxVectorTestsMasked(IntFunction<byte[]> fa, IntFunction<byte[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
byte[] a = fa.apply(SPECIES.length());
|
||||
byte[] b = fb.apply(SPECIES.length());
|
||||
@ -4309,7 +4603,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
|
||||
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Byte> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.IntVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<int[]>> INT_SATURATING_GENERATORS = List.of(
|
||||
withToString("int[Integer.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("int[Integer.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("int[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(-i * 5));
|
||||
}),
|
||||
withToString("int[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<int[]>>> INT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> INT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<int[]>>> INT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(INT_GENERATORS.get(0)).
|
||||
flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpProvider() {
|
||||
return INT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intIndexedOpProvider() {
|
||||
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> INT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2983,6 +3031,252 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::max);
|
||||
}
|
||||
|
||||
static int UMIN(int a, int b) {
|
||||
return (int)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMINInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMINInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static int UMAX(int a, int b) {
|
||||
return (int)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMAXInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMAXInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static int SADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SADDInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SADDInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::SADD);
|
||||
}
|
||||
|
||||
static int SSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SSUBInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static int SUADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUADDInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static int SUSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUSUBInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void MINInt128VectorTestsBroadcastSmokeTest(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
@ -4191,7 +4485,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LTInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULTInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4199,7 +4493,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4210,7 +4504,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULTInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4222,7 +4516,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4233,7 +4527,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GTInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGTInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4241,7 +4535,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4252,7 +4546,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGTInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4264,7 +4558,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4275,7 +4569,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LEInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULEInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4283,7 +4577,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4294,7 +4588,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULEInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4306,7 +4600,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4317,7 +4611,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GEInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGEInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4325,7 +4619,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4336,7 +4630,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGEInt128VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4348,7 +4642,7 @@ public class Int128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.IntVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<int[]>> INT_SATURATING_GENERATORS = List.of(
|
||||
withToString("int[Integer.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("int[Integer.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("int[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(-i * 5));
|
||||
}),
|
||||
withToString("int[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<int[]>>> INT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> INT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<int[]>>> INT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(INT_GENERATORS.get(0)).
|
||||
flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpProvider() {
|
||||
return INT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intIndexedOpProvider() {
|
||||
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> INT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2983,6 +3031,252 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::max);
|
||||
}
|
||||
|
||||
static int UMIN(int a, int b) {
|
||||
return (int)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMINInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMINInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static int UMAX(int a, int b) {
|
||||
return (int)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMAXInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMAXInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static int SADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SADDInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SADDInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::SADD);
|
||||
}
|
||||
|
||||
static int SSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SSUBInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static int SUADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUADDInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static int SUSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUSUBInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void MINInt256VectorTestsBroadcastSmokeTest(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
@ -4191,7 +4485,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LTInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULTInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4199,7 +4493,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4210,7 +4504,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULTInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4222,7 +4516,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4233,7 +4527,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GTInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGTInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4241,7 +4535,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4252,7 +4546,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGTInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4264,7 +4558,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4275,7 +4569,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LEInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULEInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4283,7 +4577,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4294,7 +4588,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULEInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4306,7 +4600,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4317,7 +4611,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GEInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGEInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4325,7 +4619,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4336,7 +4630,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGEInt256VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4348,7 +4642,7 @@ public class Int256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.IntVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<int[]>> INT_SATURATING_GENERATORS = List.of(
|
||||
withToString("int[Integer.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("int[Integer.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("int[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(-i * 5));
|
||||
}),
|
||||
withToString("int[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<int[]>>> INT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> INT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<int[]>>> INT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(INT_GENERATORS.get(0)).
|
||||
flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpProvider() {
|
||||
return INT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intIndexedOpProvider() {
|
||||
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> INT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2983,6 +3031,252 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::max);
|
||||
}
|
||||
|
||||
static int UMIN(int a, int b) {
|
||||
return (int)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMINInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMINInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static int UMAX(int a, int b) {
|
||||
return (int)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMAXInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMAXInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static int SADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SADDInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SADDInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::SADD);
|
||||
}
|
||||
|
||||
static int SSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SSUBInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static int SUADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUADDInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static int SUSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUSUBInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void MINInt512VectorTestsBroadcastSmokeTest(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
@ -4191,7 +4485,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LTInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULTInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4199,7 +4493,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4210,7 +4504,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULTInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4222,7 +4516,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4233,7 +4527,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GTInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGTInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4241,7 +4535,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4252,7 +4546,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGTInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4264,7 +4558,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4275,7 +4569,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LEInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULEInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4283,7 +4577,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4294,7 +4588,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULEInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4306,7 +4600,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4317,7 +4611,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GEInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGEInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4325,7 +4619,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4336,7 +4630,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGEInt512VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4348,7 +4642,7 @@ public class Int512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.IntVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<int[]>> INT_SATURATING_GENERATORS = List.of(
|
||||
withToString("int[Integer.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("int[Integer.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("int[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(-i * 5));
|
||||
}),
|
||||
withToString("int[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<int[]>>> INT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> INT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<int[]>>> INT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(INT_GENERATORS.get(0)).
|
||||
flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpProvider() {
|
||||
return INT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intIndexedOpProvider() {
|
||||
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> INT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2983,6 +3031,252 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::max);
|
||||
}
|
||||
|
||||
static int UMIN(int a, int b) {
|
||||
return (int)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMINInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMINInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static int UMAX(int a, int b) {
|
||||
return (int)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMAXInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMAXInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static int SADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SADDInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SADDInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::SADD);
|
||||
}
|
||||
|
||||
static int SSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SSUBInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static int SUADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUADDInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static int SUSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUSUBInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Int64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Int64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void MINInt64VectorTestsBroadcastSmokeTest(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
@ -4191,7 +4485,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LTInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULTInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4199,7 +4493,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4210,7 +4504,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULTInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4222,7 +4516,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4233,7 +4527,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GTInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGTInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4241,7 +4535,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4252,7 +4546,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGTInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4264,7 +4558,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4275,7 +4569,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LEInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULEInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4283,7 +4577,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4294,7 +4588,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULEInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4306,7 +4600,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4317,7 +4611,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GEInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGEInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4325,7 +4619,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4336,7 +4630,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGEInt64VectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4348,7 +4642,7 @@ public class Int64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.IntVector;
|
||||
|
||||
@ -957,6 +958,33 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<int[]>> INT_SATURATING_GENERATORS = List.of(
|
||||
withToString("int[Integer.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE));
|
||||
}),
|
||||
withToString("int[Integer.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("int[Integer.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(Integer.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("int[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(-i * 5));
|
||||
}),
|
||||
withToString("int[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (int)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<int[]>>> INT_GENERATOR_PAIRS =
|
||||
@ -964,6 +992,11 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> INT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<int[]>>> INT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(INT_GENERATORS.get(0)).
|
||||
flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -994,12 +1027,27 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpProvider() {
|
||||
return INT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intIndexedOpProvider() {
|
||||
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> INT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] intBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2988,6 +3036,252 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::max);
|
||||
}
|
||||
|
||||
static int UMIN(int a, int b) {
|
||||
return (int)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMINIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMINIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
static int UMAX(int a, int b) {
|
||||
return (int)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void UMAXIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpMaskProvider")
|
||||
static void UMAXIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
static int SADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SADDIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SADDIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
static int SSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SSUBIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
static int SUADD(int a, int b) {
|
||||
return (int)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUADDIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
static int SUSUB(int a, int b) {
|
||||
return (int)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpProvider")
|
||||
static void SUSUBIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, IntMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
int[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, IntMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intBinaryOpProvider")
|
||||
static void MINIntMaxVectorTestsBroadcastSmokeTest(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
@ -4196,7 +4490,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LTIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULTIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4204,7 +4498,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4215,7 +4509,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULTIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4227,7 +4521,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4238,7 +4532,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GTIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGTIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4246,7 +4540,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4257,7 +4551,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGTIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4269,7 +4563,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4280,7 +4574,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_LEIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void ULEIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4288,7 +4582,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4299,7 +4593,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void ULEIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4311,7 +4605,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4322,7 +4616,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpProvider")
|
||||
static void UNSIGNED_GEIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
static void UGEIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4330,7 +4624,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4341,7 +4635,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "intCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
static void UGEIntMaxVectorTestsMasked(IntFunction<int[]> fa, IntFunction<int[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
int[] a = fa.apply(SPECIES.length());
|
||||
int[] b = fb.apply(SPECIES.length());
|
||||
@ -4353,7 +4647,7 @@ public class IntMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
IntVector av = IntVector.fromArray(SPECIES, a, i);
|
||||
IntVector bv = IntVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Integer> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.LongVector;
|
||||
|
||||
@ -942,6 +943,33 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<long[]>> LONG_SATURATING_GENERATORS = List.of(
|
||||
withToString("long[Long.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("long[Long.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("long[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(-i * 5));
|
||||
}),
|
||||
withToString("long[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_PAIRS =
|
||||
@ -949,6 +977,11 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> LONG_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<long[]>>> LONG_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(LONG_GENERATORS.get(0)).
|
||||
flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -979,12 +1012,27 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpProvider() {
|
||||
return LONG_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longIndexedOpProvider() {
|
||||
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> LONG_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -3005,6 +3053,252 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::max);
|
||||
}
|
||||
|
||||
static long UMIN(long a, long b) {
|
||||
return (long)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMINLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMINLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static long UMAX(long a, long b) {
|
||||
return (long)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMAXLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMAXLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static long SADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SADDLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SADDLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::SADD);
|
||||
}
|
||||
|
||||
static long SSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SSUBLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static long SUADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUADDLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static long SUSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUSUBLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void MINLong128VectorTestsBroadcastSmokeTest(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
@ -4213,7 +4507,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LTLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULTLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4221,7 +4515,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4232,7 +4526,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULTLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4244,7 +4538,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4255,7 +4549,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GTLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGTLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4263,7 +4557,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4274,7 +4568,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGTLong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4286,7 +4580,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4297,7 +4591,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LELong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULELong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4305,7 +4599,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4316,7 +4610,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LELong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULELong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4328,7 +4622,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4339,7 +4633,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GELong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGELong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4347,7 +4641,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4358,7 +4652,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GELong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGELong128VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4370,7 +4664,7 @@ public class Long128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.LongVector;
|
||||
|
||||
@ -942,6 +943,33 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<long[]>> LONG_SATURATING_GENERATORS = List.of(
|
||||
withToString("long[Long.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("long[Long.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("long[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(-i * 5));
|
||||
}),
|
||||
withToString("long[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_PAIRS =
|
||||
@ -949,6 +977,11 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> LONG_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<long[]>>> LONG_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(LONG_GENERATORS.get(0)).
|
||||
flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -979,12 +1012,27 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpProvider() {
|
||||
return LONG_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longIndexedOpProvider() {
|
||||
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> LONG_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -3005,6 +3053,252 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::max);
|
||||
}
|
||||
|
||||
static long UMIN(long a, long b) {
|
||||
return (long)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMINLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMINLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static long UMAX(long a, long b) {
|
||||
return (long)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMAXLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMAXLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static long SADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SADDLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SADDLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::SADD);
|
||||
}
|
||||
|
||||
static long SSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SSUBLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static long SUADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUADDLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static long SUSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUSUBLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void MINLong256VectorTestsBroadcastSmokeTest(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
@ -4213,7 +4507,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LTLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULTLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4221,7 +4515,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4232,7 +4526,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULTLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4244,7 +4538,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4255,7 +4549,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GTLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGTLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4263,7 +4557,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4274,7 +4568,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGTLong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4286,7 +4580,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4297,7 +4591,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LELong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULELong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4305,7 +4599,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4316,7 +4610,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LELong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULELong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4328,7 +4622,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4339,7 +4633,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GELong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGELong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4347,7 +4641,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4358,7 +4652,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GELong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGELong256VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4370,7 +4664,7 @@ public class Long256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.LongVector;
|
||||
|
||||
@ -942,6 +943,33 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<long[]>> LONG_SATURATING_GENERATORS = List.of(
|
||||
withToString("long[Long.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("long[Long.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("long[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(-i * 5));
|
||||
}),
|
||||
withToString("long[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_PAIRS =
|
||||
@ -949,6 +977,11 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> LONG_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<long[]>>> LONG_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(LONG_GENERATORS.get(0)).
|
||||
flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -979,12 +1012,27 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpProvider() {
|
||||
return LONG_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longIndexedOpProvider() {
|
||||
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> LONG_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -3005,6 +3053,252 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::max);
|
||||
}
|
||||
|
||||
static long UMIN(long a, long b) {
|
||||
return (long)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMINLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMINLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static long UMAX(long a, long b) {
|
||||
return (long)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMAXLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMAXLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static long SADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SADDLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SADDLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::SADD);
|
||||
}
|
||||
|
||||
static long SSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SSUBLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static long SUADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUADDLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static long SUSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUSUBLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void MINLong512VectorTestsBroadcastSmokeTest(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
@ -4213,7 +4507,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LTLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULTLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4221,7 +4515,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4232,7 +4526,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULTLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4244,7 +4538,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4255,7 +4549,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GTLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGTLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4263,7 +4557,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4274,7 +4568,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGTLong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4286,7 +4580,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4297,7 +4591,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LELong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULELong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4305,7 +4599,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4316,7 +4610,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LELong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULELong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4328,7 +4622,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4339,7 +4633,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GELong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGELong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4347,7 +4641,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4358,7 +4652,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GELong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGELong512VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4370,7 +4664,7 @@ public class Long512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.LongVector;
|
||||
|
||||
@ -942,6 +943,33 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<long[]>> LONG_SATURATING_GENERATORS = List.of(
|
||||
withToString("long[Long.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("long[Long.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("long[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(-i * 5));
|
||||
}),
|
||||
withToString("long[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_PAIRS =
|
||||
@ -949,6 +977,11 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> LONG_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<long[]>>> LONG_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(LONG_GENERATORS.get(0)).
|
||||
flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -979,12 +1012,27 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpProvider() {
|
||||
return LONG_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longIndexedOpProvider() {
|
||||
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> LONG_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -3005,6 +3053,252 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::max);
|
||||
}
|
||||
|
||||
static long UMIN(long a, long b) {
|
||||
return (long)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMINLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMINLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static long UMAX(long a, long b) {
|
||||
return (long)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMAXLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMAXLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static long SADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SADDLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SADDLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::SADD);
|
||||
}
|
||||
|
||||
static long SSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SSUBLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static long SUADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUADDLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static long SUSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUSUBLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Long64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Long64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void MINLong64VectorTestsBroadcastSmokeTest(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
@ -4213,7 +4507,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LTLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULTLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4221,7 +4515,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4232,7 +4526,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULTLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4244,7 +4538,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4255,7 +4549,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GTLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGTLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4263,7 +4557,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4274,7 +4568,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGTLong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4286,7 +4580,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4297,7 +4591,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LELong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULELong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4305,7 +4599,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4316,7 +4610,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LELong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULELong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4328,7 +4622,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4339,7 +4633,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GELong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGELong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4347,7 +4641,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4358,7 +4652,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GELong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGELong64VectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4370,7 +4664,7 @@ public class Long64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.LongVector;
|
||||
|
||||
@ -947,6 +948,33 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<long[]>> LONG_SATURATING_GENERATORS = List.of(
|
||||
withToString("long[Long.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE));
|
||||
}),
|
||||
withToString("long[Long.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("long[Long.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(Long.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("long[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(-i * 5));
|
||||
}),
|
||||
withToString("long[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (long)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_PAIRS =
|
||||
@ -954,6 +982,11 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> LONG_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<long[]>>> LONG_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(LONG_GENERATORS.get(0)).
|
||||
flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -984,12 +1017,27 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpProvider() {
|
||||
return LONG_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longIndexedOpProvider() {
|
||||
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> LONG_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] longBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -3010,6 +3058,252 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::max);
|
||||
}
|
||||
|
||||
static long UMIN(long a, long b) {
|
||||
return (long)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMINLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMINLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
static long UMAX(long a, long b) {
|
||||
return (long)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void UMAXLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpMaskProvider")
|
||||
static void UMAXLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
static long SADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SADDLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SADDLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
static long SSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SSUBLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
static long SUADD(long a, long b) {
|
||||
return (long)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUADDLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
static long SUSUB(long a, long b) {
|
||||
return (long)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpProvider")
|
||||
static void SUSUBLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, LongMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
long[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, LongMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longBinaryOpProvider")
|
||||
static void MINLongMaxVectorTestsBroadcastSmokeTest(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
@ -4218,7 +4512,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LTLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULTLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4226,7 +4520,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4237,7 +4531,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULTLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4249,7 +4543,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4260,7 +4554,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GTLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGTLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4268,7 +4562,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4279,7 +4573,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGTLongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4291,7 +4585,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4302,7 +4596,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_LELongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void ULELongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4310,7 +4604,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4321,7 +4615,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_LELongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void ULELongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4333,7 +4627,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4344,7 +4638,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpProvider")
|
||||
static void UNSIGNED_GELongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
static void UGELongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4352,7 +4646,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4363,7 +4657,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "longCompareOpMaskProvider")
|
||||
static void UNSIGNED_GELongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
static void UGELongMaxVectorTestsMasked(IntFunction<long[]> fa, IntFunction<long[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
long[] a = fa.apply(SPECIES.length());
|
||||
long[] b = fb.apply(SPECIES.length());
|
||||
@ -4375,7 +4669,7 @@ public class LongMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
LongVector av = LongVector.fromArray(SPECIES, a, i);
|
||||
LongVector bv = LongVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Long> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<short[]>> SHORT_SATURATING_GENERATORS = List.of(
|
||||
withToString("short[Short.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("short[Short.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("short[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(-i * 5));
|
||||
}),
|
||||
withToString("short[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> SHORT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<short[]>>> SHORT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(SHORT_GENERATORS.get(0)).
|
||||
flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpProvider() {
|
||||
return SHORT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortIndexedOpProvider() {
|
||||
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> SHORT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2930,6 +2978,252 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::max);
|
||||
}
|
||||
|
||||
static short UMIN(short a, short b) {
|
||||
return (short)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMINShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMINShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static short UMAX(short a, short b) {
|
||||
return (short)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMAXShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMAXShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static short SADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SADDShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SADDShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::SADD);
|
||||
}
|
||||
|
||||
static short SSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SSUBShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static short SUADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUADDShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static short SUSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUSUBShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short128VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void MINShort128VectorTestsBroadcastSmokeTest(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
@ -4138,7 +4432,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LTShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULTShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4146,7 +4440,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4157,7 +4451,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULTShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4169,7 +4463,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4180,7 +4474,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GTShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGTShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4188,7 +4482,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4199,7 +4493,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGTShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4211,7 +4505,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4222,7 +4516,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LEShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULEShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4230,7 +4524,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4241,7 +4535,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULEShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4253,7 +4547,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4264,7 +4558,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GEShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGEShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4272,7 +4566,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4283,7 +4577,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGEShort128VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4295,7 +4589,7 @@ public class Short128VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<short[]>> SHORT_SATURATING_GENERATORS = List.of(
|
||||
withToString("short[Short.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("short[Short.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("short[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(-i * 5));
|
||||
}),
|
||||
withToString("short[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> SHORT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<short[]>>> SHORT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(SHORT_GENERATORS.get(0)).
|
||||
flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpProvider() {
|
||||
return SHORT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortIndexedOpProvider() {
|
||||
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> SHORT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2930,6 +2978,252 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::max);
|
||||
}
|
||||
|
||||
static short UMIN(short a, short b) {
|
||||
return (short)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMINShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMINShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static short UMAX(short a, short b) {
|
||||
return (short)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMAXShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMAXShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static short SADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SADDShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SADDShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::SADD);
|
||||
}
|
||||
|
||||
static short SSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SSUBShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static short SUADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUADDShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static short SUSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUSUBShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short256VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void MINShort256VectorTestsBroadcastSmokeTest(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
@ -4138,7 +4432,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LTShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULTShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4146,7 +4440,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4157,7 +4451,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULTShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4169,7 +4463,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4180,7 +4474,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GTShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGTShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4188,7 +4482,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4199,7 +4493,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGTShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4211,7 +4505,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4222,7 +4516,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LEShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULEShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4230,7 +4524,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4241,7 +4535,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULEShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4253,7 +4547,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4264,7 +4558,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GEShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGEShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4272,7 +4566,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4283,7 +4577,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGEShort256VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4295,7 +4589,7 @@ public class Short256VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<short[]>> SHORT_SATURATING_GENERATORS = List.of(
|
||||
withToString("short[Short.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("short[Short.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("short[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(-i * 5));
|
||||
}),
|
||||
withToString("short[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> SHORT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<short[]>>> SHORT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(SHORT_GENERATORS.get(0)).
|
||||
flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpProvider() {
|
||||
return SHORT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortIndexedOpProvider() {
|
||||
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> SHORT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2930,6 +2978,252 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::max);
|
||||
}
|
||||
|
||||
static short UMIN(short a, short b) {
|
||||
return (short)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMINShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMINShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static short UMAX(short a, short b) {
|
||||
return (short)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMAXShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMAXShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static short SADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SADDShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SADDShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::SADD);
|
||||
}
|
||||
|
||||
static short SSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SSUBShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static short SUADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUADDShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static short SUSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUSUBShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short512VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void MINShort512VectorTestsBroadcastSmokeTest(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
@ -4138,7 +4432,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LTShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULTShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4146,7 +4440,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4157,7 +4451,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULTShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4169,7 +4463,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4180,7 +4474,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GTShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGTShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4188,7 +4482,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4199,7 +4493,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGTShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4211,7 +4505,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4222,7 +4516,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LEShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULEShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4230,7 +4524,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4241,7 +4535,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULEShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4253,7 +4547,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4264,7 +4558,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GEShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGEShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4272,7 +4566,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4283,7 +4577,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGEShort512VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4295,7 +4589,7 @@ public class Short512VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
@ -952,6 +953,33 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<short[]>> SHORT_SATURATING_GENERATORS = List.of(
|
||||
withToString("short[Short.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("short[Short.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("short[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(-i * 5));
|
||||
}),
|
||||
withToString("short[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_PAIRS =
|
||||
@ -959,6 +987,11 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> SHORT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<short[]>>> SHORT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(SHORT_GENERATORS.get(0)).
|
||||
flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -989,12 +1022,27 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpProvider() {
|
||||
return SHORT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortIndexedOpProvider() {
|
||||
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> SHORT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2930,6 +2978,252 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::max);
|
||||
}
|
||||
|
||||
static short UMIN(short a, short b) {
|
||||
return (short)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMINShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMINShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::UMIN);
|
||||
}
|
||||
|
||||
static short UMAX(short a, short b) {
|
||||
return (short)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMAXShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMAXShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::UMAX);
|
||||
}
|
||||
|
||||
static short SADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SADDShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SADDShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::SADD);
|
||||
}
|
||||
|
||||
static short SSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SSUBShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::SSUB);
|
||||
}
|
||||
|
||||
static short SUADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUADDShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::SUADD);
|
||||
}
|
||||
|
||||
static short SUSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUSUBShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, Short64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, Short64VectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void MINShort64VectorTestsBroadcastSmokeTest(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
@ -4138,7 +4432,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LTShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULTShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4146,7 +4440,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4157,7 +4451,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULTShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4169,7 +4463,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4180,7 +4474,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GTShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGTShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4188,7 +4482,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4199,7 +4493,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGTShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4211,7 +4505,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4222,7 +4516,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LEShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULEShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4230,7 +4524,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4241,7 +4535,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULEShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4253,7 +4547,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4264,7 +4558,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GEShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGEShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4272,7 +4566,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4283,7 +4577,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGEShort64VectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4295,7 +4589,7 @@ public class Short64VectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
@ -38,6 +38,7 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
@ -957,6 +958,33 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
})
|
||||
);
|
||||
|
||||
static final List<IntFunction<short[]>> SHORT_SATURATING_GENERATORS = List.of(
|
||||
withToString("short[Short.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE));
|
||||
}),
|
||||
withToString("short[Short.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("short[Short.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(Short.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("short[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(-i * 5));
|
||||
}),
|
||||
withToString("short[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> (short)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_PAIRS =
|
||||
@ -964,6 +992,11 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
flatMap(fa -> SHORT_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
static final List<List<IntFunction<short[]>>> SHORT_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of(SHORT_GENERATORS.get(0)).
|
||||
flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -994,12 +1027,27 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpProvider() {
|
||||
return SHORT_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortIndexedOpProvider() {
|
||||
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortSaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> SHORT_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] shortBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
@ -2935,6 +2983,252 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::max);
|
||||
}
|
||||
|
||||
static short UMIN(short a, short b) {
|
||||
return (short)(VectorMath.minUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMINShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMINShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMIN, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::UMIN);
|
||||
}
|
||||
|
||||
static short UMAX(short a, short b) {
|
||||
return (short)(VectorMath.maxUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void UMAXShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpMaskProvider")
|
||||
static void UMAXShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.UMAX, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::UMAX);
|
||||
}
|
||||
|
||||
static short SADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SADDShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SADDShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::SADD);
|
||||
}
|
||||
|
||||
static short SSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturating(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SSUBShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SSUBShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::SSUB);
|
||||
}
|
||||
|
||||
static short SUADD(short a, short b) {
|
||||
return (short)(VectorMath.addSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUADDShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUADDShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUADD, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::SUADD);
|
||||
}
|
||||
|
||||
static short SUSUB(short a, short b) {
|
||||
return (short)(VectorMath.subSaturatingUnsigned(a, b));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpProvider")
|
||||
static void SUSUBShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, ShortMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortSaturatingBinaryOpMaskProvider")
|
||||
static void SUSUBShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
short[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.SUSUB, bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
||||
|
||||
assertArraysEquals(r, a, b, mask, ShortMaxVectorTests::SUSUB);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortBinaryOpProvider")
|
||||
static void MINShortMaxVectorTestsBroadcastSmokeTest(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
@ -4143,7 +4437,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LTShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULTShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4151,7 +4445,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4162,7 +4456,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LTShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULTShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4174,7 +4468,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4185,7 +4479,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GTShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGTShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4193,7 +4487,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4204,7 +4498,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GTShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGTShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4216,7 +4510,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGT, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4227,7 +4521,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_LEShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void ULEShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4235,7 +4529,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4246,7 +4540,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_LEShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void ULEShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4258,7 +4552,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.ULE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4269,7 +4563,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpProvider")
|
||||
static void UNSIGNED_GEShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
static void UGEShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
|
||||
@ -4277,7 +4571,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
@ -4288,7 +4582,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
}
|
||||
|
||||
@Test(dataProvider = "shortCompareOpMaskProvider")
|
||||
static void UNSIGNED_GEShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
static void UGEShortMaxVectorTestsMasked(IntFunction<short[]> fa, IntFunction<short[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
short[] a = fa.apply(SPECIES.length());
|
||||
short[] b = fb.apply(SPECIES.length());
|
||||
@ -4300,7 +4594,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
|
||||
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask);
|
||||
VectorMask<Short> mv = av.compare(VectorOperators.UGE, bv, vmask);
|
||||
|
||||
// Check results as part of computation.
|
||||
for (int j = 0; j < SPECIES.length(); j++) {
|
||||
|
245
test/jdk/jdk/incubator/vector/VectorMathTest.java
Normal file
245
test/jdk/jdk/incubator/vector/VectorMathTest.java
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8338021
|
||||
* @summary Test unsigned and saturating scalar operators for use with Vector API
|
||||
* @modules jdk.incubator.vector
|
||||
* @run testng VectorMathTest
|
||||
*/
|
||||
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
public class VectorMathTest {
|
||||
// @formatter:off
|
||||
public static final byte ZERO_B = (byte)0;
|
||||
public static final short ZERO_S = (short)0;
|
||||
public static final int ZERO_I = 0;
|
||||
public static final long ZERO_L = 0L;
|
||||
|
||||
public static final byte TEN_B = (byte)10;
|
||||
public static final int TEN_S = (short)10;
|
||||
public static final short TEN_I = 10;
|
||||
public static final long TEN_L = 10L;
|
||||
|
||||
public static final byte FIFTY_B = (byte)50;
|
||||
public static final int FIFTY_S = (short)50;
|
||||
public static final short FIFTY_I = 50;
|
||||
public static final long FIFTY_L = 50L;
|
||||
|
||||
public static final byte SIXTY_B = (byte)60;
|
||||
public static final int SIXTY_S = (short)60;
|
||||
public static final short SIXTY_I = 60;
|
||||
public static final long SIXTY_L = 60L;
|
||||
|
||||
public static final byte UMAX_B = (byte)-1;
|
||||
public static final short UMAX_S = (short)-1;
|
||||
public static final int UMAX_I = -1;
|
||||
public static final long UMAX_L = -1L;
|
||||
|
||||
public static byte[] INPUT_SB = {Byte.MIN_VALUE, (byte)(Byte.MIN_VALUE + TEN_B), ZERO_B, (byte)(Byte.MAX_VALUE - TEN_B), Byte.MAX_VALUE};
|
||||
public static short[] INPUT_SS = {Short.MIN_VALUE, (short)(Short.MIN_VALUE + TEN_S), ZERO_S, (short)(Short.MAX_VALUE - TEN_S), Short.MAX_VALUE};
|
||||
public static int[] INPUT_SI = {Integer.MIN_VALUE, (Integer.MIN_VALUE + TEN_I), ZERO_I, Integer.MAX_VALUE - TEN_I, Integer.MAX_VALUE};
|
||||
public static long[] INPUT_SL = {Long.MIN_VALUE, Long.MIN_VALUE + TEN_L, ZERO_L, Long.MAX_VALUE - TEN_L, Long.MAX_VALUE};
|
||||
|
||||
public static int[] INPUT_SADD_I = {-FIFTY_I, -FIFTY_I, -FIFTY_I, FIFTY_I, FIFTY_I};
|
||||
public static byte[] EXPECTED_SADD_B = {Byte.MIN_VALUE, Byte.MIN_VALUE, -FIFTY_B, Byte.MAX_VALUE, Byte.MAX_VALUE};
|
||||
public static short[] EXPECTED_SADD_S = {Short.MIN_VALUE, Short.MIN_VALUE, -FIFTY_S, Short.MAX_VALUE, Short.MAX_VALUE};
|
||||
public static int[] EXPECTED_SADD_I = {Integer.MIN_VALUE, Integer.MIN_VALUE, -FIFTY_I, Integer.MAX_VALUE, Integer.MAX_VALUE};
|
||||
public static long[] EXPECTED_SADD_L = {Long.MIN_VALUE, Long.MIN_VALUE, -FIFTY_L, Long.MAX_VALUE, Long.MAX_VALUE};
|
||||
|
||||
public static int[] INPUT_SSUB_I = {FIFTY_I, FIFTY_I, FIFTY_I, -FIFTY_I, -FIFTY_I};
|
||||
public static byte[] EXPECTED_SSUB_B = {Byte.MIN_VALUE, Byte.MIN_VALUE, -FIFTY_B, Byte.MAX_VALUE, Byte.MAX_VALUE};
|
||||
public static short[] EXPECTED_SSUB_S = {Short.MIN_VALUE, Short.MIN_VALUE, -FIFTY_S, Short.MAX_VALUE, Short.MAX_VALUE};
|
||||
public static int[] EXPECTED_SSUB_I = {Integer.MIN_VALUE, Integer.MIN_VALUE, -FIFTY_I, Integer.MAX_VALUE, Integer.MAX_VALUE};
|
||||
public static long[] EXPECTED_SSUB_L = {Long.MIN_VALUE, Long.MIN_VALUE, -FIFTY_L, Long.MAX_VALUE, Long.MAX_VALUE};
|
||||
|
||||
public static byte[] INPUT_UB = {ZERO_B, (byte)(ZERO_B + TEN_B), (byte)(UMAX_B - TEN_B), UMAX_B};
|
||||
public static short[] INPUT_US = {ZERO_S, (short)(ZERO_S + TEN_S), (short)(UMAX_S - TEN_S), UMAX_S};
|
||||
public static int[] INPUT_UI = {ZERO_I, ZERO_I + TEN_I, UMAX_I - TEN_I, UMAX_I};
|
||||
public static long[] INPUT_UL = {ZERO_L, ZERO_L + TEN_L, UMAX_L - TEN_L, UMAX_L};
|
||||
|
||||
public static int[] INPUT_SUADD_I = {FIFTY_I, FIFTY_I, FIFTY_I, FIFTY_I};
|
||||
public static byte[] EXPECTED_SUADD_B = {FIFTY_B, SIXTY_B, UMAX_B, UMAX_B};
|
||||
public static short[] EXPECTED_SUADD_S = {FIFTY_S, SIXTY_S, UMAX_S, UMAX_S};
|
||||
public static int[] EXPECTED_SUADD_I = {FIFTY_I, SIXTY_I, UMAX_I, UMAX_I};
|
||||
public static long[] EXPECTED_SUADD_L = {FIFTY_L, SIXTY_L, UMAX_L, UMAX_L};
|
||||
|
||||
public static int[] INPUT_SUSUB_I = {FIFTY_I, FIFTY_I, FIFTY_I, FIFTY_I};
|
||||
public static byte[] EXPECTED_SUSUB_B = {ZERO_B, ZERO_B, UMAX_B - SIXTY_B, UMAX_B - FIFTY_B};
|
||||
public static short[] EXPECTED_SUSUB_S = {ZERO_S, ZERO_S, UMAX_S - SIXTY_S, UMAX_S - FIFTY_S};
|
||||
public static int[] EXPECTED_SUSUB_I = {ZERO_I, ZERO_I, UMAX_I - SIXTY_I, UMAX_I - FIFTY_I};
|
||||
public static long[] EXPECTED_SUSUB_L = {ZERO_L, ZERO_L, UMAX_L - SIXTY_L, UMAX_L - FIFTY_L};
|
||||
|
||||
public static byte[] EXPECTED_UMIN_B = {ZERO_B, TEN_B, ZERO_B, Byte.MAX_VALUE - TEN_B};
|
||||
public static short[] EXPECTED_UMIN_S = {ZERO_S, TEN_S, ZERO_S, Short.MAX_VALUE - TEN_S};
|
||||
public static int[] EXPECTED_UMIN_I = {ZERO_I, TEN_I, ZERO_I, Integer.MAX_VALUE - TEN_I};
|
||||
public static long[] EXPECTED_UMIN_L = {ZERO_L, TEN_L, ZERO_L, Long.MAX_VALUE - TEN_L};
|
||||
|
||||
public static byte[] EXPECTED_UMAX_B = {Byte.MIN_VALUE, (byte)(Byte.MIN_VALUE + TEN_B), (byte)(UMAX_B - TEN_B), UMAX_B};
|
||||
public static short[] EXPECTED_UMAX_S = {Short.MIN_VALUE, (short)(Short.MIN_VALUE + TEN_S), (short)(UMAX_S - TEN_S), UMAX_S};
|
||||
public static int[] EXPECTED_UMAX_I = {Integer.MIN_VALUE, Integer.MIN_VALUE + TEN_I, (UMAX_I - TEN_I), UMAX_I};
|
||||
public static long[] EXPECTED_UMAX_L = {Long.MIN_VALUE, Long.MIN_VALUE + TEN_L, (UMAX_L - TEN_L), UMAX_L};
|
||||
// @formatter:on
|
||||
|
||||
static Object conv(Object a, Class<?> ct) {
|
||||
Object na = Array.newInstance(ct, Array.getLength(a));
|
||||
for (int i = 0; i < Array.getLength(a); i++) {
|
||||
Number number = (Number) Array.get(a, i);
|
||||
if (ct == byte.class) {
|
||||
number = number.byteValue();
|
||||
} else if (ct == short.class) {
|
||||
number = number.shortValue();
|
||||
} else if (ct == int.class) {
|
||||
number = number.intValue();
|
||||
} else if (ct == long.class) {
|
||||
number = number.longValue();
|
||||
} else {
|
||||
assert false : "should not reach here";
|
||||
}
|
||||
Array.set(na, i, number);
|
||||
}
|
||||
return na;
|
||||
}
|
||||
|
||||
static <T> BinaryOperator<T> named(String name, BinaryOperator<T> op) {
|
||||
return new BinaryOperator<T>() {
|
||||
@Override
|
||||
public T apply(T a, T b) {
|
||||
return op.apply(a, b);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static final BinaryOperator<Object> OP_UMIN = named("minUnsigned",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.minUnsigned((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.minUnsigned((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.minUnsigned((int) a, (int) b);
|
||||
case Long _ -> VectorMath.minUnsigned((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
static final BinaryOperator<Object> OP_UMAX = named("maxUnsigned",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.maxUnsigned((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.maxUnsigned((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.maxUnsigned((int) a, (int) b);
|
||||
case Long _ -> VectorMath.maxUnsigned((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
static final BinaryOperator<Object> OP_SADD = named("addSaturating",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.addSaturating((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.addSaturating((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.addSaturating((int) a, (int) b);
|
||||
case Long _ -> VectorMath.addSaturating((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
static final BinaryOperator<Object> OP_SSUB = named("subSaturating",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.subSaturating((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.subSaturating((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.subSaturating((int) a, (int) b);
|
||||
case Long _ -> VectorMath.subSaturating((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
static final BinaryOperator<Object> OP_SUADD = named("addSaturatingUnsigned",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.addSaturatingUnsigned((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.addSaturatingUnsigned((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.addSaturatingUnsigned((int) a, (int) b);
|
||||
case Long _ -> VectorMath.addSaturatingUnsigned((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
static final BinaryOperator<Object> OP_SUSUB = named("subSaturatingUnsigned",
|
||||
(a, b) -> switch (a) {
|
||||
case Byte _ -> VectorMath.subSaturatingUnsigned((byte) a, (byte) b);
|
||||
case Short _ -> VectorMath.subSaturatingUnsigned((short) a, (short) b);
|
||||
case Integer _ -> VectorMath.subSaturatingUnsigned((int) a, (int) b);
|
||||
case Long _ -> VectorMath.subSaturatingUnsigned((long) a, (long) b);
|
||||
default -> throw new UnsupportedOperationException("should not reach here");
|
||||
});
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] opProvider() {
|
||||
return new Object[][] {
|
||||
{OP_UMIN, byte.class, INPUT_UB, INPUT_SB, EXPECTED_UMIN_B, },
|
||||
{OP_UMIN, short.class, INPUT_US, INPUT_SS, EXPECTED_UMIN_S, },
|
||||
{OP_UMIN, int.class, INPUT_UI, INPUT_SI, EXPECTED_UMIN_I, },
|
||||
{OP_UMIN, long.class, INPUT_UL, INPUT_SL, EXPECTED_UMIN_L, },
|
||||
|
||||
{OP_UMAX, byte.class, INPUT_UB, INPUT_SB, EXPECTED_UMAX_B, },
|
||||
{OP_UMAX, short.class, INPUT_US, INPUT_SS, EXPECTED_UMAX_S, },
|
||||
{OP_UMAX, int.class, INPUT_UI, INPUT_SI, EXPECTED_UMAX_I, },
|
||||
{OP_UMAX, long.class, INPUT_UL, INPUT_SL, EXPECTED_UMAX_L, },
|
||||
|
||||
{OP_SADD, byte.class, INPUT_SB, conv(INPUT_SADD_I, byte.class), EXPECTED_SADD_B, },
|
||||
{OP_SADD, short.class, INPUT_SS, conv(INPUT_SADD_I, short.class), EXPECTED_SADD_S, },
|
||||
{OP_SADD, int.class, INPUT_SI, INPUT_SADD_I, EXPECTED_SADD_I, },
|
||||
{OP_SADD, long.class, INPUT_SL, conv(INPUT_SADD_I, long.class), EXPECTED_SADD_L, },
|
||||
|
||||
{OP_SSUB, byte.class, INPUT_SB, conv(INPUT_SSUB_I, byte.class), EXPECTED_SSUB_B, },
|
||||
{OP_SSUB, short.class, INPUT_SS, conv(INPUT_SSUB_I, short.class), EXPECTED_SSUB_S, },
|
||||
{OP_SSUB, int.class, INPUT_SI, INPUT_SSUB_I, EXPECTED_SSUB_I, },
|
||||
{OP_SSUB, long.class, INPUT_SL, conv(INPUT_SSUB_I, long.class), EXPECTED_SSUB_L, },
|
||||
|
||||
{OP_SUADD, byte.class, INPUT_UB, conv(INPUT_SUADD_I, byte.class), EXPECTED_SUADD_B, },
|
||||
{OP_SUADD, short.class, INPUT_US, conv(INPUT_SUADD_I, short.class), EXPECTED_SUADD_S, },
|
||||
{OP_SUADD, int.class, INPUT_UI, INPUT_SUADD_I, EXPECTED_SUADD_I, },
|
||||
{OP_SUADD, long.class, INPUT_UL, conv(INPUT_SUADD_I, long.class), EXPECTED_SUADD_L, },
|
||||
|
||||
{OP_SUSUB, byte.class, INPUT_UB, conv(INPUT_SUSUB_I, byte.class), EXPECTED_SUSUB_B, },
|
||||
{OP_SUSUB, short.class, INPUT_US, conv(INPUT_SUSUB_I, short.class), EXPECTED_SUSUB_S, },
|
||||
{OP_SUSUB, int.class, INPUT_UI, INPUT_SUSUB_I, EXPECTED_SUSUB_I, },
|
||||
{OP_SUSUB, long.class, INPUT_UL, conv(INPUT_SUSUB_I, long.class), EXPECTED_SUSUB_L, },
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "opProvider")
|
||||
public void test(BinaryOperator<Object> op, Class<?> type, Object a, Object b, Object expected) {
|
||||
assert Array.getLength(a) <= Array.getLength(b) && Array.getLength(a) <= Array.getLength(expected);
|
||||
|
||||
Object actual = Array.newInstance(type, Array.getLength(a));
|
||||
for (int i = 0; i < Array.getLength(a); i++) {
|
||||
Object e = op.apply(Array.get(a, i), Array.get(b, i));
|
||||
Array.set(actual, i, e);
|
||||
}
|
||||
Assert.assertEquals(actual, expected);
|
||||
}
|
||||
}
|
@ -42,6 +42,8 @@ ternary_double_broadcast_masked="Ternary-Double-Broadcast-Masked-op"
|
||||
ternary_scalar="Ternary-Scalar-op"
|
||||
binary="Binary-op"
|
||||
binary_masked="Binary-Masked-op"
|
||||
saturating_binary="SaturatingBinary-op"
|
||||
saturating_binary_masked="SaturatingBinary-Masked-op"
|
||||
binary_broadcast="Binary-Broadcast-op"
|
||||
binary_broadcast_masked="Binary-Broadcast-Masked-op"
|
||||
binary_broadcast_long="Binary-Broadcast-Long-op"
|
||||
@ -310,6 +312,12 @@ function gen_binary_op {
|
||||
gen_op_tmpl $binary_masked "$@"
|
||||
}
|
||||
|
||||
function gen_saturating_binary_op {
|
||||
echo "Generating binary op $1 ($2)..."
|
||||
gen_op_tmpl $saturating_binary "$@"
|
||||
gen_op_tmpl $saturating_binary_masked "$@"
|
||||
}
|
||||
|
||||
function gen_binary_op_no_masked {
|
||||
echo "Generating binary op $1 ($2)..."
|
||||
# gen_op_tmpl $binary_scalar "$@"
|
||||
@ -459,6 +467,12 @@ gen_shift_cst_op "ROL" "ROL_scalar(a, CONST_SHIFT)" "BITWISE"
|
||||
# Masked reductions.
|
||||
gen_binary_op_no_masked "MIN+min" "Math.min(a, b)"
|
||||
gen_binary_op_no_masked "MAX+max" "Math.max(a, b)"
|
||||
gen_binary_op "UMIN" "VectorMath.minUnsigned(a, b)" "BITWISE"
|
||||
gen_binary_op "UMAX" "VectorMath.maxUnsigned(a, b)" "BITWISE"
|
||||
gen_saturating_binary_op "SADD" "VectorMath.addSaturating(a, b)" "BITWISE"
|
||||
gen_saturating_binary_op "SSUB" "VectorMath.subSaturating(a, b)" "BITWISE"
|
||||
gen_saturating_binary_op "SUADD" "VectorMath.addSaturatingUnsigned(a, b)" "BITWISE"
|
||||
gen_saturating_binary_op "SUSUB" "VectorMath.subSaturatingUnsigned(a, b)" "BITWISE"
|
||||
gen_binary_bcst_op_no_masked "MIN+min" "Math.min(a, b)"
|
||||
gen_binary_bcst_op_no_masked "MAX+max" "Math.max(a, b)"
|
||||
|
||||
@ -494,10 +508,10 @@ gen_compare_op "NE" "neq"
|
||||
gen_compare_op "LE" "le"
|
||||
gen_compare_op "GE" "ge"
|
||||
|
||||
gen_compare_op "UNSIGNED_LT" "ult" "BITWISE"
|
||||
gen_compare_op "UNSIGNED_GT" "ugt" "BITWISE"
|
||||
gen_compare_op "UNSIGNED_LE" "ule" "BITWISE"
|
||||
gen_compare_op "UNSIGNED_GE" "uge" "BITWISE"
|
||||
gen_compare_op "ULT" "ult" "BITWISE"
|
||||
gen_compare_op "UGT" "ugt" "BITWISE"
|
||||
gen_compare_op "ULE" "ule" "BITWISE"
|
||||
gen_compare_op "UGE" "uge" "BITWISE"
|
||||
|
||||
|
||||
gen_compare_bcst_op "LT" "<"
|
||||
|
@ -0,0 +1,13 @@
|
||||
$type$[] a = fa.apply(SPECIES.length());
|
||||
$type$[] b = fb.apply(SPECIES.length());
|
||||
$type$[] r = fr.apply(SPECIES.length());
|
||||
boolean[] mask = fm.apply(SPECIES.length());
|
||||
VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
|
||||
$abstractvectortype$ bv = $abstractvectortype$.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.[[TEST]], bv, vmask).intoArray(r, i);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
$type$[] a = fa.apply(SPECIES.length());
|
||||
$type$[] b = fb.apply(SPECIES.length());
|
||||
$type$[] r = fr.apply(SPECIES.length());
|
||||
|
||||
for (int ic = 0; ic < INVOC_COUNT; ic++) {
|
||||
for (int i = 0; i < a.length; i += SPECIES.length()) {
|
||||
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
|
||||
$abstractvectortype$ bv = $abstractvectortype$.fromArray(SPECIES, b, i);
|
||||
av.lanewise(VectorOperators.[[TEST]], bv).intoArray(r, i);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
|
||||
@Test(dataProvider = "$type$SaturatingBinaryOpMaskProvider")
|
||||
static void [[TEST]]$vectorteststype$Masked(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb,
|
||||
IntFunction<boolean[]> fm) {
|
||||
[[KERNEL]]
|
||||
assertArraysEquals(r, a, b, mask, $vectorteststype$::[[TEST]]);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
|
||||
static $type$ [[TEST]]($type$ a, $type$ b) {
|
||||
return ($type$)([[TEST_OP]]);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "$type$SaturatingBinaryOpProvider")
|
||||
static void [[TEST]]$vectorteststype$(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb) {
|
||||
[[KERNEL]]
|
||||
assertArraysEquals(r, a, b, $vectorteststype$::[[TEST]]);
|
||||
}
|
@ -38,6 +38,9 @@ import jdk.incubator.vector.VectorShuffle;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
import jdk.incubator.vector.Vector;
|
||||
#if[!FP]
|
||||
import jdk.incubator.vector.VectorMath;
|
||||
#end[!FP]
|
||||
|
||||
#if[Byte]
|
||||
import jdk.incubator.vector.ByteVector;
|
||||
@ -1221,6 +1224,35 @@ relativeError));
|
||||
})
|
||||
);
|
||||
|
||||
#if[!FP]
|
||||
static final List<IntFunction<$type$[]>> $TYPE$_SATURATING_GENERATORS = List.of(
|
||||
withToString("$type$[$Boxtype$.MIN_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)($Boxtype$.MIN_VALUE));
|
||||
}),
|
||||
withToString("$type$[$Boxtype$.MAX_VALUE]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)($Boxtype$.MAX_VALUE));
|
||||
}),
|
||||
withToString("$type$[$Boxtype$.MAX_VALUE - 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)($Boxtype$.MAX_VALUE - 100));
|
||||
}),
|
||||
withToString("$type$[$Boxtype$.MIN_VALUE + 100]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)($Boxtype$.MIN_VALUE + 100));
|
||||
}),
|
||||
withToString("$type$[-i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)(-i * 5));
|
||||
}),
|
||||
withToString("$type$[i * 5]", (int s) -> {
|
||||
return fill(s * BUFFER_REPS,
|
||||
i -> ($type$)(i * 5));
|
||||
})
|
||||
);
|
||||
|
||||
#end[!FP]
|
||||
// Create combinations of pairs
|
||||
// @@@ Might be sensitive to order e.g. div by 0
|
||||
static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_PAIRS =
|
||||
@ -1228,6 +1260,13 @@ relativeError));
|
||||
flatMap(fa -> $TYPE$_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
#if[!FP]
|
||||
static final List<List<IntFunction<$type$[]>>> $TYPE$_SATURATING_GENERATOR_PAIRS =
|
||||
Stream.of($TYPE$_GENERATORS.get(0)).
|
||||
flatMap(fa -> $TYPE$_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
|
||||
collect(Collectors.toList());
|
||||
|
||||
#end[!FP]
|
||||
@DataProvider
|
||||
public Object[][] boolUnaryOpProvider() {
|
||||
return BOOL_ARRAY_GENERATORS.stream().
|
||||
@ -1258,12 +1297,31 @@ relativeError));
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
#if[!FP]
|
||||
@DataProvider
|
||||
public Object[][] $type$SaturatingBinaryOpProvider() {
|
||||
return $TYPE$_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
#end[!FP]
|
||||
@DataProvider
|
||||
public Object[][] $type$IndexedOpProvider() {
|
||||
return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
#if[!FP]
|
||||
@DataProvider
|
||||
public Object[][] $type$SaturatingBinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
flatMap(fm -> $TYPE$_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
|
||||
return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
|
||||
})).
|
||||
toArray(Object[][]::new);
|
||||
}
|
||||
|
||||
#end[!FP]
|
||||
@DataProvider
|
||||
public Object[][] $type$BinaryOpMaskProvider() {
|
||||
return BOOLEAN_MASK_GENERATORS.stream().
|
||||
|
Loading…
x
Reference in New Issue
Block a user