Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
57745ae
Enable new AVX 10.2 vector and scalar floating point conversion instr…
missa-prime Aug 25, 2025
e67e376
Add memory variants of the AVX 10.2 floating point conversion instruc…
missa-prime Aug 28, 2025
be5c0b4
Fix input size enum values for AVX 10.2 conversion instructions that …
missa-prime Aug 29, 2025
9d7484c
Correct matching rules for AVX 10.2 floating point conversion instruc…
missa-prime Sep 4, 2025
07ac817
Update floating point conversion tests to check for AVX 10.2 CPU feat…
missa-prime Sep 4, 2025
e0c84f6
Add AVX 10.2 CPU feature flag to list of verified ones
missa-prime Sep 4, 2025
a38060e
Fix match rule for AVX 10.2 double to long scalar conversion
missa-prime Sep 6, 2025
6407cc4
Add new IR rules to vector float to integer conversion tests
missa-prime Sep 6, 2025
709b443
Avoid machine instruction searches in IR rules for non-AVX10.2 platfo…
missa-prime Sep 6, 2025
b7d3ae3
Use applyIfCPUFeatureAnd to check multiple CPU feature pairs in tests
missa-prime Sep 6, 2025
4d8f3ab
Check for scalar casting instead of vector casting in tests when disa…
missa-prime Sep 6, 2025
bc59e4d
Add new IR nodes covering x86 floating point conversion instructions
missa-prime Sep 10, 2025
7202ec4
Correctly calculate vector lengths and don't rely on VectorReinterpre…
missa-prime Sep 10, 2025
8587952
Check for instructions that shouldn't appear in vector floating point…
missa-prime Sep 11, 2025
5e8800d
Change debug text format of AVX 10.2 vector conversion instructions
missa-prime Sep 11, 2025
df17575
Change the floating point conversion instruction, IR nodes, and test …
missa-prime Sep 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions src/hotspot/cpu/x86/assembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2232,6 +2232,44 @@ void Assembler::cvttss2sil(Register dst, XMMRegister src) {
emit_int16(0x2C, (0xC0 | encode));
}

void Assembler::evcvttss2sisl(Register dst, XMMRegister src) {
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(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttss2sisl(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::evcvttss2sisq(Register dst, XMMRegister src) {
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(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttss2sisq(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::cvttpd2dq(XMMRegister dst, XMMRegister src) {
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
Expand Down Expand Up @@ -2317,13 +2355,51 @@ void Assembler::vcvttps2dq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x5B, (0xC0 | encode));
}

void Assembler::evcvttps2dqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttps2dqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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_FV, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::vcvttpd2dq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
emit_int16((unsigned char)0xE6, (0xC0 | encode));
}

void Assembler::evcvttpd2dqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttpd2dqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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_FV, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::vcvtps2dq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
Expand All @@ -2339,6 +2415,25 @@ void Assembler::evcvttps2qq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x7A, (0xC0 | encode));
}

void Assembler::evcvttps2qqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttps2qqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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_HV, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::evcvtpd2qq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512dq(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
Expand All @@ -2363,6 +2458,25 @@ void Assembler::evcvttpd2qq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x7A, (0xC0 | encode));
}

void Assembler::evcvttpd2qqs(XMMRegister dst, XMMRegister src, int vector_len) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add memory operand flavour of these assembler routines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added memory variants of the instructions.

assert(VM_Version::supports_avx10_2(), "");
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(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttpd2qqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
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_FV, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::evcvtqq2pd(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512dq(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
Expand Down Expand Up @@ -14993,6 +15107,44 @@ void Assembler::cvttsd2siq(Register dst, Address src) {
emit_operand(dst, src, 0);
}

void Assembler::evcvttsd2sisl(Register dst, XMMRegister src) {
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(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttsd2sisl(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::evcvttsd2sisq(Register dst, XMMRegister src) {
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(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}

void Assembler::evcvttsd2sisq(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}

void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
Expand Down
16 changes: 16 additions & 0 deletions src/hotspot/cpu/x86/assembler_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,11 +1309,19 @@ class Assembler : public AbstractAssembler {
void cvttsd2sil(Register dst, XMMRegister src);
void cvttsd2siq(Register dst, Address src);
void cvttsd2siq(Register dst, XMMRegister src);
void evcvttsd2sisl(Register dst, XMMRegister src);
void evcvttsd2sisl(Register dst, Address src);
void evcvttsd2sisq(Register dst, XMMRegister src);
void evcvttsd2sisq(Register dst, Address src);

// Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
void cvttss2sil(Register dst, XMMRegister src);
void cvttss2siq(Register dst, XMMRegister src);
void cvtss2sil(Register dst, XMMRegister src);
void evcvttss2sisl(Register dst, XMMRegister src);
void evcvttss2sisl(Register dst, Address src);
void evcvttss2sisq(Register dst, XMMRegister src);
void evcvttss2sisq(Register dst, Address src);

// Convert vector double to int
void cvttpd2dq(XMMRegister dst, XMMRegister src);
Expand All @@ -1325,7 +1333,11 @@ class Assembler : public AbstractAssembler {
// Convert vector float to int/long
void vcvtps2dq(XMMRegister dst, XMMRegister src, int vector_len);
void vcvttps2dq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2dqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2dqs(XMMRegister dst, Address src, int vector_len);
void evcvttps2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2qqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2qqs(XMMRegister dst, Address src, int vector_len);

// Convert vector long to vector FP
void evcvtqq2ps(XMMRegister dst, XMMRegister src, int vector_len);
Expand All @@ -1334,9 +1346,13 @@ class Assembler : public AbstractAssembler {
// Convert vector double to long
void evcvtpd2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qqs(XMMRegister dst, Address src, int vector_len);

// Convert vector double to int
void vcvttpd2dq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2dqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2dqs(XMMRegister dst, Address src, int vector_len);

// Evex casts with truncation
void evpmovwb(XMMRegister dst, XMMRegister src, int vector_len);
Expand Down
82 changes: 81 additions & 1 deletion src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5058,7 +5058,7 @@ void C2_MacroAssembler::vector_cast_int_to_subword(BasicType to_elem_bt, XMMRegi
}

/*
* Algorithm for vector D2L and F2I conversions:-
* Algorithm for vector D2L and F2I conversions (AVX 10.2 unsupported):-
* a) Perform vector D2L/F2I cast.
* b) Choose fast path if none of the result vector lane contains 0x80000000 value.
* It signifies that source value could be any of the special floating point
Expand Down Expand Up @@ -5163,6 +5163,86 @@ void C2_MacroAssembler::vector_castD2X_evex(BasicType to_elem_bt, XMMRegister ds
}
}

void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttps2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttps2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttps2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttps2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
}
}

void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttps2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttps2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttps2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttps2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
}
}

void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttpd2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttpd2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
}
}

void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttpd2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttpd2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
}
}

void C2_MacroAssembler::vector_round_double_evex(XMMRegister dst, XMMRegister src,
AddressLiteral double_sign_flip, AddressLiteral new_mxcsr, int vec_enc,
Register tmp, XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp1, KRegister ktmp2) {
Expand Down
7 changes: 7 additions & 0 deletions src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@
XMMRegister xtmp2, XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5,
AddressLiteral float_sign_flip, Register rscratch, int vec_enc);

void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);

void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);

void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);

void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);

void vector_cast_double_to_int_special_cases_avx(XMMRegister dst, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5, Register rscratch,
Expand Down
Loading