8338021: Support new unsigned and saturating vector operators in VectorAPI

Reviewed-by: psandoz, epeter, sviswanathan
This commit is contained in:
Jatin Bhateja 2024-10-28 16:30:29 +00:00
parent e659d9da5d
commit 52382e285f
52 changed files with 9337 additions and 383 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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)
%{

View File

@ -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",

View File

@ -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)

View File

@ -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)

View File

@ -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: {

View File

@ -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

View File

@ -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 {

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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) ->

View File

@ -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) ->

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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();
}
}
}

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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++) {

View 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);
}
}

View File

@ -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" "<"

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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]]);
}

View File

@ -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]]);
}

View File

@ -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().