mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8360116: Add support for AVX10 floating point minmax instruction
Reviewed-by: mhaessig, sviswanathan
This commit is contained in:
parent
c50370599e
commit
5e30bf6835
@ -8257,6 +8257,14 @@ void Assembler::vmaxsh(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
emit_int16(0x5F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::eminmaxsh(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x53, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::vminsh(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
@ -8771,12 +8779,68 @@ void Assembler::vmaxps(XMMRegister dst, XMMRegister nds, XMMRegister src, int ve
|
||||
emit_int16(0x5F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evminmaxps(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_3A, &attributes);
|
||||
emit_int24(0x52, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::evminmaxps(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_embedded_opmask_register_specifier(mask);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int8(0x52);
|
||||
emit_operand(dst, src, 0);
|
||||
emit_int8(imm8);
|
||||
}
|
||||
|
||||
void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
|
||||
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16(0x5F, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::evminmaxpd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_3A, &attributes);
|
||||
emit_int24(0x52, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::evminmaxpd(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_embedded_opmask_register_specifier(mask);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int8(0x52);
|
||||
emit_operand(dst, src, 0);
|
||||
emit_int8(imm8);
|
||||
}
|
||||
|
||||
void Assembler::vmaxpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
@ -13119,6 +13183,14 @@ void Assembler::vminss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
emit_int16(0x5D, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::eminmaxss(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x53, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::vminsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
@ -13127,6 +13199,14 @@ void Assembler::vminsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
|
||||
emit_int16(0x5D, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::eminmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
attributes.set_is_evex_instruction();
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x53, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::vcmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len) {
|
||||
assert(VM_Version::supports_avx(), "");
|
||||
assert(vector_len <= AVX_256bit, "");
|
||||
@ -16526,6 +16606,34 @@ void Assembler::evminph(XMMRegister dst, XMMRegister nds, Address src, int vecto
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::evminmaxph(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_NONE, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int24(0x52, (0xC0 | encode), imm8);
|
||||
}
|
||||
|
||||
void Assembler::evminmaxph(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len) {
|
||||
assert(VM_Version::supports_avx10_2(), "");
|
||||
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_embedded_opmask_register_specifier(mask);
|
||||
if (merge) {
|
||||
attributes.reset_is_clear_context();
|
||||
}
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3A, &attributes);
|
||||
emit_int8(0x52);
|
||||
emit_operand(dst, src, 0);
|
||||
emit_int8(imm8);
|
||||
}
|
||||
|
||||
void Assembler::evmaxph(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
|
||||
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "");
|
||||
|
||||
@ -441,6 +441,17 @@ class InstructionAttr;
|
||||
// See fxsave and xsave(EVEX enabled) documentation for layout
|
||||
const int FPUStateSizeInWords = 2688 / wordSize;
|
||||
|
||||
|
||||
// AVX10 new minmax instruction control mask encoding.
|
||||
//
|
||||
// imm8[4] = 0 (please refer to Table 11.1 of section 11.2 of AVX10 manual[1] for details)
|
||||
// imm8[3:2] (sign control) = 01 (select sign, please refer to Table 11.5 of section 11.2 of AVX10 manual[1] for details)
|
||||
// imm8[1:0] = 00 (min) / 01 (max)
|
||||
//
|
||||
// [1] https://www.intel.com/content/www/us/en/content-details/856721/intel-advanced-vector-extensions-10-2-intel-avx10-2-architecture-specification.html?wapkw=AVX10
|
||||
const int AVX10_MINMAX_MAX_COMPARE_SIGN = 0x5;
|
||||
const int AVX10_MINMAX_MIN_COMPARE_SIGN = 0x4;
|
||||
|
||||
// The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
|
||||
// level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
|
||||
// is what you get. The Assembler is generating code into a CodeBuffer.
|
||||
@ -2745,6 +2756,17 @@ private:
|
||||
void minpd(XMMRegister dst, XMMRegister src);
|
||||
void vminpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
|
||||
// AVX10.2 floating point minmax instructions
|
||||
void eminmaxsh(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
|
||||
void eminmaxss(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
|
||||
void eminmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
|
||||
void evminmaxph(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len);
|
||||
void evminmaxph(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len);
|
||||
void evminmaxps(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len);
|
||||
void evminmaxps(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len);
|
||||
void evminmaxpd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int imm8, int vector_len);
|
||||
void evminmaxpd(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int imm8, int vector_len);
|
||||
|
||||
// Maximum of packed integers
|
||||
void pmaxsb(XMMRegister dst, XMMRegister src);
|
||||
void vpmaxsb(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
|
||||
|
||||
@ -1230,6 +1230,21 @@ void C2_MacroAssembler::evminmax_fp(int opcode, BasicType elem_bt,
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::vminmax_fp(int opc, BasicType elem_bt, XMMRegister dst, KRegister mask,
|
||||
XMMRegister src1, XMMRegister src2, int vlen_enc) {
|
||||
assert(opc == Op_MinV || opc == Op_MinReductionV ||
|
||||
opc == Op_MaxV || opc == Op_MaxReductionV, "sanity");
|
||||
|
||||
int imm8 = (opc == Op_MinV || opc == Op_MinReductionV) ? AVX10_MINMAX_MIN_COMPARE_SIGN
|
||||
: AVX10_MINMAX_MAX_COMPARE_SIGN;
|
||||
if (elem_bt == T_FLOAT) {
|
||||
evminmaxps(dst, mask, src1, src2, true, imm8, vlen_enc);
|
||||
} else {
|
||||
assert(elem_bt == T_DOUBLE, "");
|
||||
evminmaxpd(dst, mask, src1, src2, true, imm8, vlen_enc);
|
||||
}
|
||||
}
|
||||
|
||||
// Float/Double signum
|
||||
void C2_MacroAssembler::signum_fp(int opcode, XMMRegister dst, XMMRegister zero, XMMRegister one) {
|
||||
assert(opcode == Op_SignumF || opcode == Op_SignumD, "sanity");
|
||||
@ -2537,12 +2552,21 @@ void C2_MacroAssembler::reduceFloatMinMax(int opcode, int vlen, bool is_dst_vali
|
||||
} else { // i = [0,1]
|
||||
vpermilps(wtmp, wsrc, permconst[i], vlen_enc);
|
||||
}
|
||||
vminmax_fp(opcode, T_FLOAT, wdst, wtmp, wsrc, tmp, atmp, btmp, vlen_enc);
|
||||
|
||||
if (VM_Version::supports_avx10_2()) {
|
||||
vminmax_fp(opcode, T_FLOAT, wdst, k0, wtmp, wsrc, vlen_enc);
|
||||
} else {
|
||||
vminmax_fp(opcode, T_FLOAT, wdst, wtmp, wsrc, tmp, atmp, btmp, vlen_enc);
|
||||
}
|
||||
wsrc = wdst;
|
||||
vlen_enc = Assembler::AVX_128bit;
|
||||
}
|
||||
if (is_dst_valid) {
|
||||
vminmax_fp(opcode, T_FLOAT, dst, wdst, dst, tmp, atmp, btmp, Assembler::AVX_128bit);
|
||||
if (VM_Version::supports_avx10_2()) {
|
||||
vminmax_fp(opcode, T_FLOAT, dst, k0, wdst, dst, Assembler::AVX_128bit);
|
||||
} else {
|
||||
vminmax_fp(opcode, T_FLOAT, dst, wdst, dst, tmp, atmp, btmp, Assembler::AVX_128bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2568,12 +2592,23 @@ void C2_MacroAssembler::reduceDoubleMinMax(int opcode, int vlen, bool is_dst_val
|
||||
assert(i == 0, "%d", i);
|
||||
vpermilpd(wtmp, wsrc, 1, vlen_enc);
|
||||
}
|
||||
vminmax_fp(opcode, T_DOUBLE, wdst, wtmp, wsrc, tmp, atmp, btmp, vlen_enc);
|
||||
|
||||
if (VM_Version::supports_avx10_2()) {
|
||||
vminmax_fp(opcode, T_DOUBLE, wdst, k0, wtmp, wsrc, vlen_enc);
|
||||
} else {
|
||||
vminmax_fp(opcode, T_DOUBLE, wdst, wtmp, wsrc, tmp, atmp, btmp, vlen_enc);
|
||||
}
|
||||
|
||||
wsrc = wdst;
|
||||
vlen_enc = Assembler::AVX_128bit;
|
||||
}
|
||||
|
||||
if (is_dst_valid) {
|
||||
vminmax_fp(opcode, T_DOUBLE, dst, wdst, dst, tmp, atmp, btmp, Assembler::AVX_128bit);
|
||||
if (VM_Version::supports_avx10_2()) {
|
||||
vminmax_fp(opcode, T_DOUBLE, dst, k0, wdst, dst, Assembler::AVX_128bit);
|
||||
} else {
|
||||
vminmax_fp(opcode, T_DOUBLE, dst, wdst, dst, tmp, atmp, btmp, Assembler::AVX_128bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,6 +72,9 @@ public:
|
||||
XMMRegister tmp, XMMRegister atmp, XMMRegister btmp,
|
||||
int vlen_enc);
|
||||
|
||||
void vminmax_fp(int opc, BasicType elem_bt, XMMRegister dst, KRegister mask,
|
||||
XMMRegister src1, XMMRegister src2, 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,
|
||||
|
||||
@ -8841,6 +8841,10 @@ void MacroAssembler::evpmins(BasicType type, XMMRegister dst, KRegister mask, XM
|
||||
evpminsd(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_FLOAT:
|
||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||
case T_DOUBLE:
|
||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
@ -8856,6 +8860,10 @@ void MacroAssembler::evpmaxs(BasicType type, XMMRegister dst, KRegister mask, XM
|
||||
evpmaxsd(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_FLOAT:
|
||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||
case T_DOUBLE:
|
||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
@ -8871,6 +8879,10 @@ void MacroAssembler::evpmins(BasicType type, XMMRegister dst, KRegister mask, XM
|
||||
evpminsd(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_FLOAT:
|
||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||
case T_DOUBLE:
|
||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
@ -8886,6 +8898,10 @@ void MacroAssembler::evpmaxs(BasicType type, XMMRegister dst, KRegister mask, XM
|
||||
evpmaxsd(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_LONG:
|
||||
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
||||
case T_FLOAT:
|
||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||
case T_DOUBLE:
|
||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||
default:
|
||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||
}
|
||||
|
||||
@ -2024,7 +2024,7 @@ bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType
|
||||
if (is_subword_type(bt) && !VM_Version::supports_avx512bw()) {
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
if (is_floating_point_type(bt)) {
|
||||
if (is_floating_point_type(bt) && !VM_Version::supports_avx10_2()) {
|
||||
return false; // Implementation limitation
|
||||
}
|
||||
return true;
|
||||
@ -5293,9 +5293,9 @@ instruct mul_reduction64B(rRegI dst, rRegI src1, legVec src2, legVec vtmp1, legV
|
||||
|
||||
//--------------------Min/Max Float Reduction --------------------
|
||||
// Float Min Reduction
|
||||
instruct minmax_reduction2F(legRegF dst, immF src1, legVec src2, legVec tmp,
|
||||
legVec atmp, legVec btmp, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
instruct minmax_reduction2F(legRegF dst, immF src1, legVec src2, legVec tmp, legVec atmp,
|
||||
legVec btmp, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
@ -5316,7 +5316,7 @@ instruct minmax_reduction2F(legRegF dst, immF src1, legVec src2, legVec tmp,
|
||||
|
||||
instruct minmax_reductionF(legRegF dst, immF src1, legVec src2, legVec tmp, legVec atmp,
|
||||
legVec btmp, legVec xmm_0, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
@ -5335,9 +5335,9 @@ instruct minmax_reductionF(legRegF dst, immF src1, legVec src2, legVec tmp, legV
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reduction2F_av(legRegF dst, legVec src, legVec tmp,
|
||||
legVec atmp, legVec btmp, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
instruct minmax_reduction2F_av(legRegF dst, legVec src, legVec tmp, legVec atmp,
|
||||
legVec btmp, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
@ -5355,9 +5355,9 @@ instruct minmax_reduction2F_av(legRegF dst, legVec src, legVec tmp,
|
||||
%}
|
||||
|
||||
|
||||
instruct minmax_reductionF_av(legRegF dst, legVec src, legVec tmp,
|
||||
legVec atmp, legVec btmp, legVec xmm_0, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
instruct minmax_reductionF_av(legRegF dst, legVec src, legVec tmp, legVec atmp, legVec btmp,
|
||||
legVec xmm_0, legVec xmm_1, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
@ -5374,12 +5374,78 @@ instruct minmax_reductionF_av(legRegF dst, legVec src, legVec tmp,
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reduction2F_avx10(regF dst, immF src1, vec src2, vec xtmp1) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV src1 src2));
|
||||
match(Set dst (MaxReductionV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1);
|
||||
format %{ "vector_minmax_reduction $dst, $src1, $src2 \t; using $xtmp1 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src2);
|
||||
__ reduceFloatMinMax(opcode, vlen, false, $dst$$XMMRegister, $src2$$XMMRegister,
|
||||
xnoreg, xnoreg, xnoreg, $xtmp1$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionF_avx10(regF dst, immF src1, vec src2, vec xtmp1, vec xtmp2) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV src1 src2));
|
||||
match(Set dst (MaxReductionV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_minmax_reduction $dst, $src1, $src2 \t; using $xtmp1 and $xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src2);
|
||||
__ reduceFloatMinMax(opcode, vlen, false, $dst$$XMMRegister, $src2$$XMMRegister, xnoreg, xnoreg,
|
||||
xnoreg, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reduction2F_avx10_av(regF dst, vec src, vec xtmp1) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
effect(TEMP dst, TEMP xtmp1);
|
||||
format %{ "vector_minmax2F_reduction $dst, $src \t; using $xtmp1 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src);
|
||||
__ reduceFloatMinMax(opcode, vlen, true, $dst$$XMMRegister, $src$$XMMRegister, xnoreg, xnoreg, xnoreg,
|
||||
$xtmp1$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionF_avx10_av(regF dst, vec src, vec xtmp1, vec xtmp2) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_minmax2F_reduction $dst, $src \t; using $xtmp1 and $xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src);
|
||||
__ reduceFloatMinMax(opcode, vlen, true, $dst$$XMMRegister, $src$$XMMRegister, xnoreg, xnoreg, xnoreg,
|
||||
$xtmp1$$XMMRegister, $xtmp2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
//--------------------Min Double Reduction --------------------
|
||||
instruct minmax_reduction2D(legRegD dst, immD src1, legVec src2,
|
||||
legVec tmp1, legVec tmp2, legVec tmp3, legVec tmp4, // TEMPs
|
||||
rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
instruct minmax_reduction2D(legRegD dst, immD src1, legVec src2, legVec tmp1, legVec tmp2,
|
||||
legVec tmp3, legVec tmp4, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
@ -5398,10 +5464,9 @@ instruct minmax_reduction2D(legRegD dst, immD src1, legVec src2,
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionD(legRegD dst, immD src1, legVec src2,
|
||||
legVec tmp1, legVec tmp2, legVec tmp3, legVec tmp4, legVec tmp5, // TEMPs
|
||||
rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
instruct minmax_reductionD(legRegD dst, immD src1, legVec src2, legVec tmp1, legVec tmp2,
|
||||
legVec tmp3, legVec tmp4, legVec tmp5, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
@ -5421,10 +5486,9 @@ instruct minmax_reductionD(legRegD dst, immD src1, legVec src2,
|
||||
%}
|
||||
|
||||
|
||||
instruct minmax_reduction2D_av(legRegD dst, legVec src,
|
||||
legVec tmp1, legVec tmp2, legVec tmp3, legVec tmp4, // TEMPs
|
||||
rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
instruct minmax_reduction2D_av(legRegD dst, legVec src, legVec tmp1, legVec tmp2,
|
||||
legVec tmp3, legVec tmp4, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
@ -5441,10 +5505,9 @@ instruct minmax_reduction2D_av(legRegD dst, legVec src,
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionD_av(legRegD dst, legVec src,
|
||||
legVec tmp1, legVec tmp2, legVec tmp3, legVec tmp4, legVec tmp5, // TEMPs
|
||||
rFlagsReg cr) %{
|
||||
predicate(Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
instruct minmax_reductionD_av(legRegD dst, legVec src, legVec tmp1, legVec tmp2, legVec tmp3,
|
||||
legVec tmp4, legVec tmp5, rFlagsReg cr) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
@ -5461,6 +5524,75 @@ instruct minmax_reductionD_av(legRegD dst, legVec src,
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reduction2D_avx10(regD dst, immD src1, vec src2, vec xtmp1) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV src1 src2));
|
||||
match(Set dst (MaxReductionV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1);
|
||||
format %{ "vector_minmax2D_reduction $dst, $src1, $src2 ; using $xtmp1 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src2);
|
||||
__ reduceDoubleMinMax(opcode, vlen, false, $dst$$XMMRegister, $src2$$XMMRegister, xnoreg,
|
||||
xnoreg, xnoreg, $xtmp1$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionD_avx10(regD dst, immD src1, vec src2, vec xtmp1, vec xtmp2) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV src1 src2));
|
||||
match(Set dst (MaxReductionV src1 src2));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_minmaxD_reduction $dst, $src1, $src2 ; using $xtmp1 and $xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src2);
|
||||
__ reduceDoubleMinMax(opcode, vlen, false, $dst$$XMMRegister, $src2$$XMMRegister, xnoreg, xnoreg,
|
||||
xnoreg, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
|
||||
instruct minmax_reduction2D_av_avx10(regD dst, vec src, vec xtmp1) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
Matcher::vector_length(n->in(2)) == 2);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
effect(TEMP dst, TEMP xtmp1);
|
||||
format %{ "vector_minmax2D_reduction $dst, $src ; using $xtmp1 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src);
|
||||
__ reduceDoubleMinMax(opcode, vlen, true, $dst$$XMMRegister, $src$$XMMRegister,
|
||||
xnoreg, xnoreg, xnoreg, $xtmp1$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct minmax_reductionD_av_avx10(regD dst, vec src, vec xtmp1, vec xtmp2) %{
|
||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||
Matcher::vector_length(n->in(2)) >= 4);
|
||||
match(Set dst (MinReductionV dst src));
|
||||
match(Set dst (MaxReductionV dst src));
|
||||
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2);
|
||||
format %{ "vector_minmaxD_reduction $dst, $src ; using $xtmp1 and $xtmp2 as TEMP" %}
|
||||
ins_encode %{
|
||||
int opcode = this->ideal_Opcode();
|
||||
int vlen = Matcher::vector_length(this, $src);
|
||||
__ reduceDoubleMinMax(opcode, vlen, true, $dst$$XMMRegister, $src$$XMMRegister,
|
||||
xnoreg, xnoreg, xnoreg, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// ====================VECTOR ARITHMETIC=======================================
|
||||
|
||||
// --------------------------------- ADD --------------------------------------
|
||||
@ -6347,9 +6479,25 @@ instruct vminmaxL_reg_evex(vec dst, vec src1, vec src2) %{
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// Float/Double vector Min/Max
|
||||
instruct minmaxFP_avx10_reg(vec dst, vec a, vec b) %{
|
||||
predicate(VM_Version::supports_avx10_2() &&
|
||||
is_floating_point_type(Matcher::vector_element_basic_type(n))); // T_FLOAT, T_DOUBLE
|
||||
match(Set dst (MinV a b));
|
||||
match(Set dst (MaxV a b));
|
||||
format %{ "vector_minmaxFP $dst, $a, $b" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
int opcode = this->ideal_Opcode();
|
||||
BasicType elem_bt = Matcher::vector_element_basic_type(this);
|
||||
__ vminmax_fp(opcode, elem_bt, $dst$$XMMRegister, k0, $a$$XMMRegister, $b$$XMMRegister, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// Float/Double vector Min/Max
|
||||
instruct minmaxFP_reg(legVec dst, legVec a, legVec b, legVec tmp, legVec atmp, legVec btmp) %{
|
||||
predicate(Matcher::vector_length_in_bytes(n) <= 32 &&
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_length_in_bytes(n) <= 32 &&
|
||||
is_floating_point_type(Matcher::vector_element_basic_type(n)) && // T_FLOAT, T_DOUBLE
|
||||
UseAVX > 0);
|
||||
match(Set dst (MinV a b));
|
||||
@ -6370,8 +6518,8 @@ instruct minmaxFP_reg(legVec dst, legVec a, legVec b, legVec tmp, legVec atmp, l
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct evminmaxFP_reg_eavx(vec dst, vec a, vec b, vec atmp, vec btmp, kReg ktmp) %{
|
||||
predicate(Matcher::vector_length_in_bytes(n) == 64 &&
|
||||
instruct evminmaxFP_reg_evex(vec dst, vec a, vec b, vec atmp, vec btmp, kReg ktmp) %{
|
||||
predicate(!VM_Version::supports_avx10_2() && Matcher::vector_length_in_bytes(n) == 64 &&
|
||||
is_floating_point_type(Matcher::vector_element_basic_type(n))); // T_FLOAT, T_DOUBLE
|
||||
match(Set dst (MinV a b));
|
||||
match(Set dst (MaxV a b));
|
||||
@ -10686,8 +10834,22 @@ instruct scalar_binOps_HF_reg(regF dst, regF src1, regF src2)
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct scalar_minmax_HF_avx10_reg(regF dst, regF src1, regF src2)
|
||||
%{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MaxHF src1 src2));
|
||||
match(Set dst (MinHF src1 src2));
|
||||
format %{ "scalar_min_max_fp16 $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int function = this->ideal_Opcode() == Op_MinHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
||||
__ eminmaxsh($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, function);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct scalar_minmax_HF_reg(regF dst, regF src1, regF src2, kReg ktmp, regF xtmp1, regF xtmp2)
|
||||
%{
|
||||
predicate(!VM_Version::supports_avx10_2());
|
||||
match(Set dst (MaxHF src1 src2));
|
||||
match(Set dst (MinHF src1 src2));
|
||||
effect(TEMP_DEF dst, TEMP ktmp, TEMP xtmp1, TEMP xtmp2);
|
||||
@ -10787,8 +10949,37 @@ instruct vector_fma_HF_mem(vec dst, memory src1, vec src2)
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_minmax_HF_avx10_mem(vec dst, vec src1, memory src2)
|
||||
%{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MinVHF src1 (VectorReinterpret (LoadVector src2))));
|
||||
match(Set dst (MaxVHF src1 (VectorReinterpret (LoadVector src2))));
|
||||
format %{ "vector_min_max_fp16_mem $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
||||
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$Address, true, function, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_minmax_HF_avx10_reg(vec dst, vec src1, vec src2)
|
||||
%{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MinVHF src1 src2));
|
||||
match(Set dst (MaxVHF src1 src2));
|
||||
format %{ "vector_min_max_fp16 $dst, $src1, $src2" %}
|
||||
ins_encode %{
|
||||
int vlen_enc = vector_length_encoding(this);
|
||||
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
||||
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$XMMRegister, true, function, vlen_enc);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vector_minmax_HF_reg(vec dst, vec src1, vec src2, kReg ktmp, vec xtmp1, vec xtmp2)
|
||||
%{
|
||||
predicate(!VM_Version::supports_avx10_2());
|
||||
match(Set dst (MinVHF src1 src2));
|
||||
match(Set dst (MaxVHF src1 src2));
|
||||
effect(TEMP_DEF dst, TEMP ktmp, TEMP xtmp1, TEMP xtmp2);
|
||||
|
||||
@ -4450,9 +4450,20 @@ instruct loadD(regD dst, memory mem)
|
||||
ins_pipe(pipe_slow); // XXX
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.max(float a, float b)
|
||||
instruct maxF_avx10_reg(regF dst, regF a, regF b) %{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MaxF a b));
|
||||
format %{ "maxF $dst, $a, $b" %}
|
||||
ins_encode %{
|
||||
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.max(float a, float b)
|
||||
instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
|
||||
predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MaxF a b));
|
||||
effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
|
||||
format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
|
||||
@ -4463,7 +4474,7 @@ instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp,
|
||||
%}
|
||||
|
||||
instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{
|
||||
predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MaxF a b));
|
||||
effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
|
||||
|
||||
@ -4475,9 +4486,20 @@ instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRe
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.max(double a, double b)
|
||||
instruct maxD_avx10_reg(regD dst, regD a, regD b) %{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MaxD a b));
|
||||
format %{ "maxD $dst, $a, $b" %}
|
||||
ins_encode %{
|
||||
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.max(double a, double b)
|
||||
instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
|
||||
predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MaxD a b));
|
||||
effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp);
|
||||
format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
|
||||
@ -4488,7 +4510,7 @@ instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp,
|
||||
%}
|
||||
|
||||
instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{
|
||||
predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MaxD a b));
|
||||
effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
|
||||
|
||||
@ -4500,9 +4522,20 @@ instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRe
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.min(float a, float b)
|
||||
instruct minF_avx10_reg(regF dst, regF a, regF b) %{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MinF a b));
|
||||
format %{ "minF $dst, $a, $b" %}
|
||||
ins_encode %{
|
||||
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// min = java.lang.Math.min(float a, float b)
|
||||
instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{
|
||||
predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MinF a b));
|
||||
effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
|
||||
format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
|
||||
@ -4513,7 +4546,7 @@ instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp,
|
||||
%}
|
||||
|
||||
instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{
|
||||
predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MinF a b));
|
||||
effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
|
||||
|
||||
@ -4525,9 +4558,20 @@ instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRe
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// max = java.lang.Math.min(double a, double b)
|
||||
instruct minD_avx10_reg(regD dst, regD a, regD b) %{
|
||||
predicate(VM_Version::supports_avx10_2());
|
||||
match(Set dst (MinD a b));
|
||||
format %{ "minD $dst, $a, $b" %}
|
||||
ins_encode %{
|
||||
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
// min = java.lang.Math.min(double a, double b)
|
||||
instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{
|
||||
predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MinD a b));
|
||||
effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp);
|
||||
format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %}
|
||||
@ -4538,7 +4582,7 @@ instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp,
|
||||
%}
|
||||
|
||||
instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{
|
||||
predicate(UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n));
|
||||
match(Set dst (MinD a b));
|
||||
effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user