Skip to content

Commit f03fb4e

Browse files
author
Jatin Bhateja
committed
8308363: Initial compiler support for FP16 scalar operations.
Reviewed-by: sviswanathan
1 parent 4dca15b commit f03fb4e

File tree

33 files changed

+880
-13
lines changed

33 files changed

+880
-13
lines changed

make/common/JavaCompilation.gmk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ define SetupJavaCompilationBody
274274
PARANOIA_FLAGS := -implicit:none -Xprefer:source -XDignore.symbol.file=true -encoding ascii
275275

276276
$1_FLAGS += -g -Xlint:all $$($1_TARGET_RELEASE) $$(PARANOIA_FLAGS) $$(JAVA_WARNINGS_ARE_ERRORS)
277-
$1_FLAGS += $$($1_JAVAC_FLAGS)
277+
$1_FLAGS += $$($1_JAVAC_FLAGS) -XDenablePrimitiveClasses
278278

279279
ifneq ($$($1_DISABLED_WARNINGS), )
280280
$1_FLAGS += -Xlint:$$(call CommaList, $$(addprefix -, $$($1_DISABLED_WARNINGS)))

src/hotspot/cpu/x86/assembler_x86.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3144,6 +3144,22 @@ void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
31443144
emit_int16(0x6F, (0xC0 | encode));
31453145
}
31463146

3147+
void Assembler::vmovw(XMMRegister dst, Register src) {
3148+
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
3149+
InstructionAttr attributes(AVX_128bit, false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3150+
attributes.set_is_evex_instruction();
3151+
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
3152+
emit_int16(0x6E, (0xC0 | encode));
3153+
}
3154+
3155+
void Assembler::vmovw(Register dst, XMMRegister src) {
3156+
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
3157+
InstructionAttr attributes(AVX_128bit, false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3158+
attributes.set_is_evex_instruction();
3159+
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
3160+
emit_int16(0x7E, (0xC0 | encode));
3161+
}
3162+
31473163
void Assembler::vmovdqu(XMMRegister dst, Address src) {
31483164
assert(UseAVX > 0, "");
31493165
InstructionMark im(this);
@@ -7311,6 +7327,22 @@ void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector
73117327
emit_operand(dst, src, 0);
73127328
}
73137329

7330+
void Assembler::evaddph(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7331+
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
7332+
InstructionAttr attributes(vector_len, false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7333+
attributes.set_is_evex_instruction();
7334+
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
7335+
emit_int16(0x58, (0xC0 | encode));
7336+
}
7337+
7338+
void Assembler::evaddsh(XMMRegister dst, XMMRegister nds, XMMRegister src) {
7339+
assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16");
7340+
InstructionAttr attributes(AVX_128bit, false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
7341+
attributes.set_is_evex_instruction();
7342+
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
7343+
emit_int16(0x58, (0xC0 | encode));
7344+
}
7345+
73147346
void Assembler::psubb(XMMRegister dst, XMMRegister src) {
73157347
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
73167348
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -11480,7 +11512,7 @@ void Assembler::evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_r, boo
1148011512
int byte2 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0) | (evex_r ? EVEX_Rb : 0);
1148111513
byte2 = (~byte2) & 0xF0;
1148211514
// confine opc opcode extensions in mm bits to lower two bits
11483-
// of form {0F, 0F_38, 0F_3A}
11515+
// of form {0F, 0F_38, 0F_3A, MAP5}
1148411516
byte2 |= opc;
1148511517

1148611518
// P1: byte 3 as Wvvvv1pp

src/hotspot/cpu/x86/assembler_x86.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ class Assembler : public AbstractAssembler {
547547
VEX_OPCODE_0F = 0x1,
548548
VEX_OPCODE_0F_38 = 0x2,
549549
VEX_OPCODE_0F_3A = 0x3,
550+
VEX_OPCODE_MAP5 = 0x5,
550551
VEX_OPCODE_MASK = 0x1F
551552
};
552553

@@ -1649,6 +1650,9 @@ class Assembler : public AbstractAssembler {
16491650
void movsbl(Register dst, Address src);
16501651
void movsbl(Register dst, Register src);
16511652

1653+
void vmovw(XMMRegister dst, Register src);
1654+
void vmovw(Register dst, XMMRegister src);
1655+
16521656
#ifdef _LP64
16531657
void movsbq(Register dst, Address src);
16541658
void movsbq(Register dst, Register src);
@@ -2394,6 +2398,8 @@ class Assembler : public AbstractAssembler {
23942398
void vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
23952399
void vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
23962400
void vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
2401+
void evaddsh(XMMRegister dst, XMMRegister nds, XMMRegister src);
2402+
void evaddph(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
23972403

23982404
// Leaf level assembler routines for masked operations.
23992405
void evpaddb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);

src/hotspot/cpu/x86/vm_version_x86.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ void VM_Version::get_processor_features() {
949949
_features &= ~CPU_AVX512_VBMI2;
950950
_features &= ~CPU_AVX512_BITALG;
951951
_features &= ~CPU_AVX512_IFMA;
952+
_features &= ~CPU_AVX512_FP16;
952953
}
953954

954955
if (UseAVX < 2)
@@ -982,6 +983,7 @@ void VM_Version::get_processor_features() {
982983
_features &= ~CPU_GFNI;
983984
_features &= ~CPU_AVX512_BITALG;
984985
_features &= ~CPU_AVX512_IFMA;
986+
_features &= ~CPU_AVX512_FP16;
985987
}
986988
}
987989

@@ -3017,6 +3019,9 @@ uint64_t VM_Version::feature_flags() {
30173019
}
30183020
if (_cpuid_info.sef_cpuid7_edx.bits.serialize != 0)
30193021
result |= CPU_SERIALIZE;
3022+
3023+
if (_cpuid_info.sef_cpuid7_edx.bits.avx512_fp16 != 0)
3024+
result |= CPU_AVX512_FP16;
30203025
}
30213026

30223027
// ZX features.

src/hotspot/cpu/x86/vm_version_x86.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,9 @@ class VM_Version : public Abstract_VM_Version {
275275
serialize : 1,
276276
: 5,
277277
cet_ibt : 1,
278-
: 11;
278+
: 2,
279+
avx512_fp16 : 1,
280+
: 8;
279281
} bits;
280282
};
281283

@@ -390,7 +392,8 @@ class VM_Version : public Abstract_VM_Version {
390392
decl(OSPKE, "ospke", 55) /* OS enables protection keys */ \
391393
decl(CET_IBT, "cet_ibt", 56) /* Control Flow Enforcement - Indirect Branch Tracking */ \
392394
decl(CET_SS, "cet_ss", 57) /* Control Flow Enforcement - Shadow Stack */ \
393-
decl(AVX512_IFMA, "avx512_ifma", 58) /* Integer Vector FMA instructions*/
395+
decl(AVX512_IFMA, "avx512_ifma", 58) /* Integer Vector FMA instructions*/ \
396+
decl(AVX512_FP16, "avx512_fp16", 59) /* AVX512 FP16 ISA support*/
394397

395398
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1ULL << bit),
396399
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
@@ -696,6 +699,7 @@ class VM_Version : public Abstract_VM_Version {
696699
static bool supports_avx512_bitalg() { return (_features & CPU_AVX512_BITALG) != 0; }
697700
static bool supports_avx512_vbmi() { return (_features & CPU_AVX512_VBMI) != 0; }
698701
static bool supports_avx512_vbmi2() { return (_features & CPU_AVX512_VBMI2) != 0; }
702+
static bool supports_avx512_fp16() { return (_features & CPU_AVX512_FP16) != 0; }
699703
static bool supports_hv() { return (_features & CPU_HV) != 0; }
700704
static bool supports_serialize() { return (_features & CPU_SERIALIZE) != 0; }
701705
static bool supports_f16c() { return (_features & CPU_F16C) != 0; }

src/hotspot/cpu/x86/x86.ad

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,13 @@ bool Matcher::match_rule_supported(int opcode) {
14511451
return false;
14521452
}
14531453
break;
1454+
case Op_AddHF:
1455+
case Op_ReinterpretS2HF:
1456+
case Op_ReinterpretHF2S:
1457+
if (!VM_Version::supports_avx512_fp16()) {
1458+
return false;
1459+
}
1460+
break;
14541461
case Op_VectorLoadShuffle:
14551462
case Op_VectorRearrange:
14561463
case Op_MulReductionVI:
@@ -1722,6 +1729,11 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
17221729
// * 128bit vroundpd instruction is present only in AVX1
17231730
int size_in_bits = vlen * type2aelembytes(bt) * BitsPerByte;
17241731
switch (opcode) {
1732+
case Op_AddVHF:
1733+
if (!VM_Version::supports_avx512_fp16()) {
1734+
return false;
1735+
}
1736+
break;
17251737
case Op_AbsVF:
17261738
case Op_NegVF:
17271739
if ((vlen == 16) && (VM_Version::supports_avx512dq() == false)) {
@@ -10149,4 +10161,52 @@ instruct DoubleClassCheck_reg_reg_vfpclass(rRegI dst, regD src, kReg ktmp, rFlag
1014910161
ins_pipe(pipe_slow);
1015010162
%}
1015110163

10164+
instruct reinterpretS2H (regF dst, rRegI src)
10165+
%{
10166+
match(Set dst (ReinterpretS2HF src));
10167+
format %{ "vmovw $dst, $src" %}
10168+
ins_encode %{
10169+
__ vmovw($dst$$XMMRegister, $src$$Register);
10170+
%}
10171+
ins_pipe(pipe_slow);
10172+
%}
10173+
10174+
instruct convF2HFAndS2HF (regF dst, regF src)
10175+
%{
10176+
match(Set dst (ReinterpretS2HF (ConvF2HF src)));
10177+
format %{ "convF2HFAndS2HF $dst, $src" %}
10178+
ins_encode %{
10179+
__ vcvtps2ph($dst$$XMMRegister, $src$$XMMRegister, 0x04, Assembler::AVX_128bit);
10180+
%}
10181+
ins_pipe(pipe_slow);
10182+
%}
10183+
10184+
instruct reinterpretH2S (rRegI dst, regF src)
10185+
%{
10186+
match(Set dst (ReinterpretHF2S src));
10187+
format %{ "vmovw $dst, $src" %}
10188+
ins_encode %{
10189+
__ vmovw($dst$$Register, $src$$XMMRegister);
10190+
%}
10191+
ins_pipe(pipe_slow);
10192+
%}
10193+
instruct addFP16_scalar (regF dst, regF src1, regF src2)
10194+
%{
10195+
match(Set dst (AddHF src1 src2));
10196+
format %{ "vaddsh $dst, $src1, $src2" %}
10197+
ins_encode %{
10198+
__ evaddsh($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister);
10199+
%}
10200+
ins_pipe(pipe_slow);
10201+
%}
1015210202

10203+
instruct vaddVHF (vec dst, vec src1, vec src2)
10204+
%{
10205+
match(Set dst (AddVHF src1 src2));
10206+
format %{ "vaddph $dst, $src1, $src2" %}
10207+
ins_encode %{
10208+
int vlen_enc = vector_length_encoding(this);
10209+
__ evaddph($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vlen_enc);
10210+
%}
10211+
ins_pipe(pipe_slow);
10212+
%}

src/hotspot/share/adlc/formssel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4201,7 +4201,7 @@ Form::DataType MatchRule::is_ideal_load() const {
42014201

42024202
bool MatchRule::is_vector() const {
42034203
static const char *vector_list[] = {
4204-
"AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
4204+
"AddVB","AddVHF", "AddVS","AddVI","AddVL","AddVF","AddVD",
42054205
"SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
42064206
"MulVB","MulVS","MulVI","MulVL","MulVF","MulVD",
42074207
"DivVF","DivVD",

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4695,6 +4695,22 @@ static void check_illegal_static_method(const InstanceKlass* this_klass, TRAPS)
46954695
}
46964696
}
46974697

4698+
// utility function to skip over internal jdk primitive classes used to override the need for passing
4699+
// an explict JVM flag EnablePrimitiveClasses.
4700+
bool ClassFileParser::is_jdk_internal_class(const Symbol* class_name) const {
4701+
if (vmSymbols::java_lang_Float16() == class_name) {
4702+
return (EnablePrimitiveClasses = true);
4703+
}
4704+
return false;
4705+
}
4706+
4707+
bool ClassFileParser::is_jdk_internal_class_sig(const char* sig) const {
4708+
if (strstr(sig, vmSymbols::java_lang_Float16_signature()->as_C_string())) {
4709+
return true;
4710+
}
4711+
return false;
4712+
}
4713+
46984714
// utility methods for format checking
46994715

47004716
void ClassFileParser::verify_legal_class_modifiers(jint flags, const char* name, bool is_Object, TRAPS) const {
@@ -4725,7 +4741,7 @@ void ClassFileParser::verify_legal_class_modifiers(jint flags, const char* name,
47254741
return;
47264742
}
47274743

4728-
if (is_primitive_class && !EnablePrimitiveClasses) {
4744+
if (is_primitive_class && !is_jdk_internal_class(_class_name) && !EnablePrimitiveClasses) {
47294745
ResourceMark rm(THREAD);
47304746
Exceptions::fthrow(
47314747
THREAD_AND_LOCATION,
@@ -5157,7 +5173,7 @@ const char* ClassFileParser::skip_over_field_signature(const char* signature,
51575173
case JVM_SIGNATURE_PRIMITIVE_OBJECT:
51585174
// Can't enable this check fully until JDK upgrades the bytecode generators (TODO: JDK-8270852).
51595175
// For now, compare to class file version 51 so old verifier doesn't see Q signatures.
5160-
if ( (_major_version < 51 /* CONSTANT_CLASS_DESCRIPTORS */ ) || (!EnablePrimitiveClasses)) {
5176+
if ( (_major_version < 51 /* CONSTANT_CLASS_DESCRIPTORS */ ) || (!EnablePrimitiveClasses && !is_jdk_internal_class_sig(signature))) {
51615177
classfile_parse_error("Class name contains illegal Q-signature "
51625178
"in descriptor in class file %s, requires option -XX:+EnablePrimitiveClasses",
51635179
CHECK_0);

src/hotspot/share/classfile/classFileParser.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ class ClassFileParser {
217217
bool _has_vanilla_constructor;
218218
int _max_bootstrap_specifier_index; // detects BSS values
219219

220+
bool is_jdk_internal_class(const Symbol* class_name) const;
221+
222+
bool is_jdk_internal_class_sig(const char* sig) const;
223+
220224
void parse_stream(const ClassFileStream* const stream, TRAPS);
221225

222226
void mangle_hidden_class_name(InstanceKlass* const ik);

src/hotspot/share/classfile/vmClassMacros.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
do_klass(Boolean_klass, java_lang_Boolean ) \
172172
do_klass(Character_klass, java_lang_Character ) \
173173
do_klass(Float_klass, java_lang_Float ) \
174+
do_klass(Float16_klass, java_lang_Float16 ) \
174175
do_klass(Double_klass, java_lang_Double ) \
175176
do_klass(Byte_klass, java_lang_Byte ) \
176177
do_klass(Short_klass, java_lang_Short ) \

0 commit comments

Comments
 (0)