Merge branch 'master' into loom_s390_v1

This commit is contained in:
Amit Kumar 2026-06-11 18:12:50 +00:00
commit 147213aed2
128 changed files with 47728 additions and 1225 deletions

View File

@ -88,8 +88,7 @@ SRCDIR := $(OUTPUT_ROOT)/src
DOWNLOAD_RPMS_MARKER := $(BUILDDIR)/download-rpms.marker
RPMS_UNPACKED_MARKER := $(BUILDDIR)/rpms_unpacked.marker
UNPATCHED_SYSROOT_MARKER := $(BUILDDIR)/sysroot_unpatched.marker
PATCHED_SYSROOT_MARKER := $(BUILDDIR)/sysroot_patched.marker
SYSROOT_MARKER := $(BUILDDIR)/sysroot.marker
################################################################################
# Download RPMs
@ -101,10 +100,6 @@ else
endif
RPM_ARCHS := $(RPM_ARCH) noarch
ifeq ($(ARCH), x86_64)
# Enable mixed mode.
RPM_ARCHS += i386 i686
endif
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
@ -166,43 +161,12 @@ $(RPMS_UNPACKED_MARKER): $(DOWNLOAD_RPMS_MARKER)
################################################################################
$(UNPATCHED_SYSROOT_MARKER): $(RPMS_UNPACKED_MARKER)
$(SYSROOT_MARKER): $(RPMS_UNPACKED_MARKER)
touch $@
################################################################################
# Patch sysroot
# Note: MUST create a <sysroot>/usr/lib even if not really needed.
# gcc will use a path relative to it to resolve lib64. (x86_64).
# we're creating multi-lib compiler with 32bit libc as well, so we should
# have it anyway, but just to make sure...
# Patch GNU ld scripts to force linking against libraries in the sysroot
# and not the ones installed on the build machine.
LD_SCRIPT_PATCHES := \
-e 's|/usr/lib64/||g' \
-e 's|/usr/lib/||g' \
-e 's|/lib64/||g' \
-e 's|/lib/||g' \
#
$(PATCHED_SYSROOT_MARKER): $(UNPATCHED_SYSROOT_MARKER)
@echo Patching GNU ld scripts
@( \
for f in $$(find $(SYSROOT) -name "*.so" -type f 2>/dev/null); do \
if grep -Iq 'GNU ld script' "$$f"; then \
sed $(LD_SCRIPT_PATCHES) "$$f" > "$$f.tmp" && \
mv "$$f.tmp" "$$f"; \
fi; \
done \
)
@mkdir -p $(SYSROOT)/usr/lib
@touch $@
################################################################################
download-rpms: $(DOWNLOAD_RPMS_MARKER)
unpatched-sysroot: $(UNPATCHED_SYSROOT_MARKER)
sysroot: $(PATCHED_SYSROOT_MARKER)
sysroot: $(SYSROOT_MARKER)
.PHONY: download-rpms unpatched-sysroot sysroot
.PHONY: download-rpms sysroot

View File

@ -103,16 +103,6 @@ ifneq ($(REQUIRED_MIN_MAKE_MAJOR_VERSION),)
endif
################################################################################
# Define common directories and files
# Ensure we have 32-bit libs also for x64. We enable mixed-mode.
ifeq (x86_64,$(ARCH))
LIBDIRS := lib64 lib
CFLAGS_lib := -m32
else
LIBDIRS := lib
endif
# Define directories
DOWNLOAD := $(OUTPUT_ROOT)/download
SRCDIR := $(OUTPUT_ROOT)/src
@ -200,23 +190,19 @@ TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-)
################################################################################
# Create a TARGET bfd + libiberty only.
# Configure one or two times depending on mulitlib arch.
# If multilib, the second should be 32-bit, and we resolve
# CFLAG_<name> to most likely -m32.
define mk_bfd
$$(info Libs for $(1))
$$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile: \
CFLAGS += $$(CFLAGS_$(1))
$$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile: \
LIBDIRS = --libdir=$(TARGETDIR)/$(1)
ifeq (x86_64,$(ARCH))
LIBDIR := lib64
else
LIBDIR := lib
endif
BFDLIB += $$(TARGETDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1)).done
BFDMAKES += $$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile
endef
$(BUILDDIR)/$(BINUTILS_VER)-$(LIBDIR)/Makefile:
CFLAGS += CFLAGS_$(LIBDIR)
$(BUILDDIR)/$(BINUTILS_VER)-$(LIBDIR)/Makefile:
LIBDIR = --libdir=$(TARGETDIR)/$(LIBDIR)
# Create one set of bfds etc for each multilib arch
$(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l))))
BFDLIB += $(TARGETDIR)/$(BINUTILS_VER)-$(LIBDIR).done
BFDMAKES += $(BUILDDIR)/$(BINUTILS_VER)-$(LIBDIR)/Makefile
# Only build these two libs.
$(BFDLIB): MAKECMD = all-libiberty all-bfd
@ -228,7 +214,7 @@ $(BFDMAKES): CONFIG = --target=$(TARGET) \
--host=$(TARGET) --build=$(BUILD) \
--prefix=$(TARGETDIR) \
--with-sysroot=$(SYSROOT) \
$(LIBDIRS)
$(LIBDIR)
$(BFDMAKES): TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
@ -243,11 +229,8 @@ $(GCC) \
$(CCACHE): ENVS += $(TOOLS)
# libdir to work around hateful bfd stuff installing into wrong dirs...
# ensure we have 64 bit bfd support in the HOST library. I.e our
# compiler on i686 will know 64 bit symbols, BUT later
# we build just the libs again for TARGET, then with whatever the arch
# wants.
$(BUILDDIR)/$(BINUTILS_VER)/Makefile: CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
# ensure we have 64 bit bfd support in the HOST library.
$(BUILDDIR)/$(BINUTILS_VER)/Makefile: CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(LIBDIR)
ifeq ($(filter $(ARCH), s390x riscv64 ppc64le), )
# gold compiles but cannot link properly on s390x @ gcc 13.2 and Fedore 41
@ -256,10 +239,6 @@ ifeq ($(filter $(ARCH), s390x riscv64 ppc64le), )
LINKER_CONFIG_ENABLE_GOLD := --enable-gold=default
endif
ifeq ($(filter riscv64 ppc64le s390x armhfp, $(ARCH)), )
ENABLE_MULTILIB := --enable-multilib
endif
# Makefile creation. Simply run configure in build dir.
# Setting CFLAGS to -O2 generates a much faster ld.
$(BFDMAKES) \
@ -275,7 +254,6 @@ $(BUILDDIR)/$(BINUTILS_VER)/Makefile: $(BINUTILS_CFG)
--with-sysroot=$(SYSROOT) \
--disable-nls \
--program-prefix=$(TARGET)- \
$(ENABLE_MULTILIB) \
--enable-threads \
--enable-plugins \
) > $(@D)/log.config 2>&1
@ -340,15 +318,12 @@ ifeq ($(ARCH), riscv64)
$(BUILDDIR)/$(GCC_VER)/Makefile: CONFIG += --disable-libsanitizer
endif
ifneq ($(filter riscv64 ppc64le s390x armhfp, $(ARCH)), )
# We only support 64-bit on these platforms anyway
CONFIG += --disable-multilib
endif
# We don't need to support multilib
CONFIG += --disable-multilib
# Want:
# c,c++
# shared libs
# multilib (-m32/-m64 on x64)
# skip native language.
# and link and assemble with the binutils we created
# earlier, so --with-gnu*
@ -438,14 +413,12 @@ ifeq ($(HOST),$(TARGET))
# "Solve" this by create links from the target libdirs to where they are.
$(LINK_LIBS_MARKER): $(GCC)
@echo -n 'Creating library symlinks...'
@for l in $(LIBDIRS); do \
for f in `cd $(PREFIX)/$$l && ls`; do \
if [ ! -e $(TARGETDIR)/$$l/$$f ]; then \
mkdir -p $(TARGETDIR)/$$l && \
cd $(TARGETDIR)/$$l/ && \
ln -fs ../../$$l/$$f $$f; \
fi \
done \
@for f in `cd $(PREFIX)/$(LIBDIR) && ls`; do \
if [ ! -e $(TARGETDIR)/$(LIBDIR)/$$f ]; then \
mkdir -p $(TARGETDIR)/$(LIBDIR) && \
cd $(TARGETDIR)/$(LIBDIR)/ && \
ln -fs ../../$(LIBDIR)/$$f $$f; \
fi \
done
@touch $@
@echo 'done'

View File

@ -8294,6 +8294,34 @@ instruct castII_checked(iRegI dst, rFlagsReg cr)
ins_pipe(pipe_slow);
%}
// The unchecked and checked variants for CastII below both use iRegINoSp for src and dst
// as some consumers of CastII node like ConvHF2F forbid the stack pointer as an input
// (please see convHF2F_reg_reg rule which requires input to be in an iRegINoSp register).
instruct castII_nosp(iRegINoSp dst)
%{
predicate(VerifyConstraintCasts == 0);
match(Set dst (CastII dst));
size(0);
format %{ "# castII of $dst" %}
ins_encode(/* empty encoding */);
ins_cost(0);
ins_pipe(pipe_class_empty);
%}
instruct castII_checked_nosp(iRegINoSp dst, rFlagsReg cr)
%{
predicate(VerifyConstraintCasts > 0);
match(Set dst (CastII dst));
effect(KILL cr);
format %{ "# castII_checked of $dst" %}
ins_encode %{
__ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register, rscratch1);
%}
ins_pipe(pipe_slow);
%}
instruct castLL(iRegL dst)
%{
predicate(VerifyConstraintCasts == 0);

View File

@ -241,9 +241,9 @@ source %{
return false;
}
break;
// At the time of writing this, the Vector API has no half-float (FP16) species.
// Consequently, AddReductionVHF and MulReductionVHF are only produced by the
// auto-vectorizer, which requires strictly ordered semantics for FP reductions.
// AddReductionVHF and MulReductionVHF are currently only produced by the
// auto-vectorizer (the Vector API does not yet intrinsify Float16 reductions),
// which requires strictly ordered semantics for FP reductions.
//
// There is no direct Neon instruction that performs strictly ordered floating
// point add reduction. Hence, on Neon only machines, the add reduction operation
@ -354,9 +354,9 @@ source %{
opcode = Op_StoreVectorScatterMasked;
break;
// Currently, the masked versions of the following 8 Float16 operations are disabled.
// When the support for Float16 vector classes is added in VectorAPI and the masked
// Float16 IR can be generated, these masked operations will be enabled and relevant
// backend support added.
// The Vector API does not yet emit predicated Float16 IR. When such masked IR can be
// generated, these masked operations will be enabled and the relevant backend support
// added.
case Op_AddVHF:
case Op_SubVHF:
case Op_MulVHF:

View File

@ -976,12 +976,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ lea(c_rarg1, _addr);
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ lea(c_rarg0, _addr);
// flip them
__ mov(_tmp1, c_rarg0);
__ mov(c_rarg0, c_rarg1);
__ mov(c_rarg1, _tmp1);
__ mov(_tmp1, c_rarg1);
__ lea(c_rarg1, _addr);
__ mov(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ lea(c_rarg1, _addr);

View File

@ -61,6 +61,7 @@
// between a callee frame and its stack arguments, where it is part
// of the caller/callee overlap
metadata_words_at_top = 0,
// in bytes
frame_alignment = 16,
// size, in words, of maximum shift in frame position due to alignment
align_wiggle = 1

View File

@ -402,8 +402,7 @@
// between a callee frame and its stack arguments, where it is part
// of the caller/callee overlap
metadata_words_at_top = sizeof(java_abi) >> LogBytesPerWord,
// size, in words, of frame metadata at the frame top that needs
// to be reserved for callee functions in the runtime
// in bytes
frame_alignment = 16,
frame_alignment_in_words = frame_alignment >> LogBytesPerWord,
// size, in words, of maximum shift in frame position due to alignment

View File

@ -1210,12 +1210,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ addi(c_rarg1, _addr.base(), _addr.disp());
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ addi(c_rarg0, _addr.base(), _addr.disp());
// flip them
__ mr(_tmp1, c_rarg0);
__ mr(c_rarg0, c_rarg1);
__ mr(c_rarg1, _tmp1);
__ mr(_tmp1, c_rarg1);
__ addi(c_rarg1, _addr.base(), _addr.disp());
__ mr(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ addi(c_rarg1, _addr.base(), _addr.disp());

View File

@ -912,12 +912,9 @@ void ShenandoahBarrierStubC2::lrb(MacroAssembler& masm) {
if (c_rarg0 == _obj) {
__ la(c_rarg1, _addr);
} else if (c_rarg1 == _obj) {
// Set up arguments in reverse, and then flip them
__ la(c_rarg0, _addr);
// flip them
__ mv(_tmp1, c_rarg0);
__ mv(c_rarg0, c_rarg1);
__ mv(c_rarg1, _tmp1);
__ mv(_tmp1, c_rarg1);
__ la(c_rarg1, _addr);
__ mv(c_rarg0, _tmp1);
} else {
assert_different_registers(c_rarg1, _obj);
__ la(c_rarg1, _addr);

View File

@ -120,10 +120,10 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, UseZvbb, false, EXPERIMENTAL, "Use Zvbb instructions") \
product(bool, UseZvbc, false, EXPERIMENTAL, "Use Zvbc instructions") \
product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \
product(bool, UseZvkn, false, EXPERIMENTAL, \
product(bool, UseZvkg, false, DIAGNOSTIC, "Use Zvkg instructions") \
product(bool, UseZvkn, false, DIAGNOSTIC, \
"Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
product(bool, UseCtxFencei, false, EXPERIMENTAL, \
"Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") \
product(bool, UseZvkg, false, EXPERIMENTAL, "Use Zvkg instructions")
"Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush")
#endif // CPU_RISCV_GLOBALS_RISCV_HPP

View File

@ -101,8 +101,7 @@
// between a callee frame and its stack arguments, where it is part
// of the caller/callee overlap
metadata_words_at_top = 0,
// size, in words, of frame metadata at the frame top that needs
// to be reserved for callee functions in the runtime
// in bytes
frame_alignment = 16,
// size, in words, of maximum shift in frame position due to alignment
align_wiggle = 1

View File

@ -10106,10 +10106,6 @@ void MacroAssembler::load_aotrc_address(Register reg, address a) {
}
void MacroAssembler::setcc(Assembler::Condition comparison, Register dst) {
if (VM_Version::supports_apx_f()) {
esetzucc(comparison, dst);
} else {
setb(comparison, dst);
movzbl(dst, dst);
}
setb(comparison, dst);
movzbl(dst, dst);
}

View File

@ -7287,13 +7287,8 @@ instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr)
"shrl $dst, markWord::klass_shift_at_offset"
%}
ins_encode %{
if (UseAPX) {
__ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false);
}
else {
__ movl($dst$$Register, $mem$$Address);
__ shrl($dst$$Register, markWord::klass_shift_at_offset);
}
__ movl($dst$$Register, $mem$$Address);
__ shrl($dst$$Register, markWord::klass_shift_at_offset);
%}
ins_pipe(ialu_reg_mem);
%}
@ -9269,7 +9264,6 @@ instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src)
// Conditional move
instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
predicate(!UseAPX);
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250); // XXX
@ -9280,24 +9274,9 @@ instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
ins_pipe(pipe_cmov_mem);
%}
// Conditional move
instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2)
%{
predicate(UseAPX);
match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2))));
ins_cost(250);
format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %}
ins_encode %{
__ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
%}
ins_pipe(pipe_cmov_mem);
%}
// Conditional move
instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
%{
predicate(!UseAPX);
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250); // XXX
@ -9317,27 +9296,13 @@ instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
%}
%}
instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2)
%{
predicate(UseAPX);
match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2))));
instruct cmovI_memUCFE(cmpOpUCFE cop, rFlagsRegUCFE cr, rRegI dst, memory src) %{
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250);
format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %}
ins_cost(250); // XXX
format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
ins_encode %{
__ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
%}
ins_pipe(pipe_cmov_mem);
%}
instruct cmovI_rReg_rReg_memUCFE_ndd(rRegI dst, cmpOpUCFE cop, rFlagsRegUCFE cr, rRegI src1, memory src2)
%{
match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2))));
ins_cost(250);
format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, unsigned, int ndd" %}
ins_encode %{
__ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
__ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
%}
ins_pipe(pipe_cmov_mem);
%}
@ -9596,7 +9561,6 @@ instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src
instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
%{
predicate(!UseAPX);
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
ins_cost(200); // XXX
@ -9607,19 +9571,6 @@ instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
ins_pipe(pipe_cmov_mem); // XXX
%}
instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2)
%{
predicate(UseAPX);
match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2))));
ins_cost(200);
format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %}
ins_encode %{
__ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
%}
ins_pipe(pipe_cmov_mem);
%}
instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop)
%{
predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0);
@ -9741,7 +9692,6 @@ instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src)
instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
%{
predicate(!UseAPX);
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
ins_cost(200); // XXX
@ -9761,29 +9711,15 @@ instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
%}
%}
instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2)
%{
predicate(UseAPX);
match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2))));
instruct cmovL_memUCFE(cmpOpUCFE cop, rFlagsRegUCFE cr, rRegL dst, memory src) %{
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
ins_cost(200);
format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %}
ins_cost(200); // XXX
format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
ins_encode %{
__ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
__ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address);
%}
ins_pipe(pipe_cmov_mem);
%}
instruct cmovL_rReg_rReg_memUCFE_ndd(rRegL dst, cmpOpUCFE cop, rFlagsRegUCFE cr, rRegL src1, memory src2)
%{
match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2))));
ins_cost(200);
format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, unsigned, long ndd" %}
ins_encode %{
__ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address);
%}
ins_pipe(pipe_cmov_mem);
ins_pipe(pipe_cmov_mem); // XXX
%}
instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
@ -9970,23 +9906,8 @@ instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
ins_pipe( ialu_reg );
%}
instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AddI (LoadI src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe( ialu_reg );
%}
instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (AddI dst (LoadI src)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
@ -9999,21 +9920,6 @@ instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AddI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
%{
match(Set dst (StoreI dst (AddI (LoadI dst) src)));
@ -10070,19 +9976,6 @@ instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr)
%{
predicate(UseAPX && UseIncDec);
match(Set dst (AddI (LoadI src) val));
effect(KILL cr);
format %{ "eincl $dst, $src\t# int ndd" %}
ins_encode %{
__ eincl($dst$$Register, $src$$Address, false);
%}
ins_pipe(ialu_reg);
%}
instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr)
%{
predicate(UseIncDec);
@ -10125,19 +10018,6 @@ instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr)
%{
predicate(UseAPX && UseIncDec);
match(Set dst (AddI (LoadI src) val));
effect(KILL cr);
format %{ "edecl $dst, $src\t# int ndd" %}
ins_encode %{
__ edecl($dst$$Register, $src$$Address, false);
%}
ins_pipe(ialu_reg);
%}
// XXX why does that use AddI
instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
%{
@ -10260,23 +10140,8 @@ instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
ins_pipe( ialu_reg );
%}
instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AddL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe( ialu_reg );
%}
instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (AddL dst (LoadL src)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
@ -10289,21 +10154,6 @@ instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AddL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
%{
match(Set dst (StoreL dst (AddL (LoadL dst) src)));
@ -10359,19 +10209,6 @@ instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr)
%{
predicate(UseAPX && UseIncDec);
match(Set dst (AddL (LoadL src) val));
effect(KILL cr);
format %{ "eincq $dst, $src\t# long ndd" %}
ins_encode %{
__ eincq($dst$$Register, $src$$Address, false);
%}
ins_pipe(ialu_reg);
%}
instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
%{
predicate(UseIncDec);
@ -10414,19 +10251,6 @@ instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr)
%{
predicate(UseAPX && UseIncDec);
match(Set dst (AddL (LoadL src) val));
effect(KILL cr);
format %{ "edecq $dst, $src\t# long ndd" %}
ins_encode %{
__ edecq($dst$$Register, $src$$Address, false);
%}
ins_pipe(ialu_reg);
%}
// XXX why does that use AddL
instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
%{
@ -11147,23 +10971,8 @@ instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
ins_pipe(ialu_reg_reg);
%}
instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubI (LoadI src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ esubl($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg_reg);
%}
instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (SubI dst (LoadI src)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
@ -11176,36 +10985,6 @@ instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
ins_cost(150);
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ esubl($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubI (LoadI src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
ins_cost(150);
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ esubl($dst$$Register, $src1$$Address, $src2$$Register, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
%{
match(Set dst (StoreI dst (SubI (LoadI dst) src)));
@ -11262,23 +11041,8 @@ instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
ins_pipe(ialu_reg_reg);
%}
instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ esubq($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg_reg);
%}
instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (SubL dst (LoadL src)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
@ -11291,36 +11055,6 @@ instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
ins_cost(150);
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ esubq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (SubL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
ins_cost(150);
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ esubq($dst$$Register, $src1$$Address, $src2$$Register, false);
%}
ins_pipe(ialu_reg_mem);
%}
instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
%{
match(Set dst (StoreL dst (SubL (LoadL dst) src)));
@ -11535,7 +11269,6 @@ instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (MulI dst (LoadI src)));
effect(KILL cr);
@ -11547,21 +11280,6 @@ instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem_alu0);
%}
instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (MulI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(350);
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eimull($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem_alu0);
%}
instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
%{
match(Set dst (MulI (LoadI src) imm));
@ -11629,7 +11347,6 @@ instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (MulL dst (LoadL src)));
effect(KILL cr);
@ -11641,20 +11358,6 @@ instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem_alu0);
%}
instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (MulL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(350);
format %{ "eimulq $dst, $src1, $src2 \t# long" %}
ins_encode %{
__ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem_alu0);
%}
instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
%{
@ -11959,19 +11662,6 @@ instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (LShiftI (LoadI src) shift));
effect(KILL cr);
format %{ "esall $dst, $src, $shift\t# int (ndd)" %}
ins_encode %{
__ esall($dst$$Register, $src$$Address, $shift$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Shift Left by 8-bit immediate
instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@ -12066,19 +11756,6 @@ instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
ins_pipe(ialu_mem_imm);
%}
instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (RShiftI (LoadI src) shift));
effect(KILL cr);
format %{ "esarl $dst, $src, $shift\t# int (ndd)" %}
ins_encode %{
__ esarl($dst$$Register, $src$$Address, $shift$$constant, false);
%}
ins_pipe(ialu_mem_imm);
%}
// Arithmetic Shift Right by 8-bit immediate
instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@ -12173,19 +11850,6 @@ instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (URShiftI (LoadI src) shift));
effect(KILL cr);
format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %}
ins_encode %{
__ eshrl($dst$$Register, $src$$Address, $shift$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Logical Shift Right by 8-bit immediate
instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@ -12310,19 +11974,6 @@ instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (LShiftL (LoadL src) shift));
effect(KILL cr);
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
ins_encode %{
__ esalq($dst$$Register, $src$$Address, $shift$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Shift Left by 8-bit immediate
instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@ -12417,19 +12068,6 @@ instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr)
ins_pipe(ialu_mem_imm);
%}
instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (RShiftL (LoadL src) shift));
effect(KILL cr);
format %{ "esarq $dst, $src, $shift\t# long (ndd)" %}
ins_encode %{
__ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false);
%}
ins_pipe(ialu_mem_imm);
%}
// Arithmetic Shift Right by 8-bit immediate
instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr)
%{
@ -12524,19 +12162,6 @@ instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (URShiftL (LoadL src) shift));
effect(KILL cr);
format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %}
ins_encode %{
__ eshrq($dst$$Register, $src$$Address, $shift$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Logical Shift Right by 8-bit immediate
instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
%{
@ -13064,24 +12689,9 @@ instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AndI (LoadI src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eandl($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// And Register with Memory
instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (AndI dst (LoadI src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -13094,21 +12704,6 @@ instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AndI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eandl($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// And Memory with Register
instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
%{
@ -13351,24 +12946,9 @@ instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (OrI (LoadI src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eorl($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Or Register with Memory
instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (OrI dst (LoadI src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -13381,21 +12961,6 @@ instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (OrI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ eorl($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// Or Memory with Register
instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
%{
@ -13528,26 +13093,9 @@ instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
// Xor Memory with Immediate
instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (XorI (LoadI src1) src2));
effect(KILL cr);
ins_cost(150);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ exorl($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Xor Register with Memory
instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (XorI dst (LoadI src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -13560,21 +13108,6 @@ instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (XorI src1 (LoadI src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
ins_encode %{
__ exorl($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// Xor Memory with Register
instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
%{
@ -13709,24 +13242,9 @@ instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
ins_pipe(ialu_reg);
%}
instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AndL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eandq($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// And Register with Memory
instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (AndL dst (LoadL src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -13739,21 +13257,6 @@ instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (AndL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eandq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// And Memory with Register
instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
%{
@ -14027,25 +13530,9 @@ instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
// Or Memory with Immediate
instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (OrL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eorq($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Or Register with Memory
instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (OrL dst (LoadL src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -14058,21 +13545,6 @@ instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (OrL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ eorq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// Or Memory with Register
instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
%{
@ -14208,26 +13680,9 @@ instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
ins_pipe(ialu_reg);
%}
// Xor Memory with Immediate
instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (XorL (LoadL src1) src2));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
ins_cost(150);
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ exorq($dst$$Register, $src1$$Address, $src2$$constant, false);
%}
ins_pipe(ialu_reg);
%}
// Xor Register with Memory
instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
%{
predicate(!UseAPX);
match(Set dst (XorL dst (LoadL src)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
@ -14240,21 +13695,6 @@ instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
ins_pipe(ialu_reg_mem);
%}
instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
%{
predicate(UseAPX);
match(Set dst (XorL src1 (LoadL src2)));
effect(KILL cr);
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
ins_cost(150);
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
ins_encode %{
__ exorq($dst$$Register, $src1$$Register, $src2$$Address, false);
%}
ins_pipe(ialu_reg_mem);
%}
// Xor Memory with Register
instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
%{

View File

@ -39,6 +39,7 @@
// between a callee frame and its stack arguments, where it is part
// of the caller/callee overlap
metadata_words_at_top = 0,
// in bytes
frame_alignment = 16,
// size, in words, of maximum shift in frame position due to alignment
align_wiggle = 1

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -249,7 +249,6 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) {
VM_Version::ext_Zvfh.enable_feature();
}
#ifndef PRODUCT
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNED) &&
is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKNHB) &&
is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKB) &&
@ -259,7 +258,6 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKG)) {
VM_Version::ext_Zvkg.enable_feature();
}
#endif
// ====== non-extensions ======
//

View File

@ -32,7 +32,7 @@ PSOldGenerationPool::PSOldGenerationPool(PSOldGen* old_gen,
}
MemoryUsage PSOldGenerationPool::get_memory_usage() {
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
size_t used = used_in_bytes();
size_t committed = _old_gen->capacity_in_bytes();
@ -59,7 +59,7 @@ PSEdenSpacePool::PSEdenSpacePool(PSYoungGen* young_gen,
}
MemoryUsage PSEdenSpacePool::get_memory_usage() {
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
size_t used = used_in_bytes();
size_t committed = _space->capacity_in_bytes();
@ -80,7 +80,7 @@ PSSurvivorSpacePool::PSSurvivorSpacePool(PSYoungGen* young_gen,
}
MemoryUsage PSSurvivorSpacePool::get_memory_usage() {
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
size_t used = used_in_bytes();
size_t committed = committed_in_bytes();
return MemoryUsage(initial_size(), used, committed, maxSize);

View File

@ -1268,8 +1268,7 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) {
#endif
}
template<typename Func>
void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter, Func&& on_stripe) {
void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter) {
MutableSpace* sp = PSParallelCompact::space(id);
HeapWord* const bottom = sp->bottom();
HeapWord* const top = sp->top();
@ -1288,53 +1287,46 @@ void PSParallelCompact::adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_c
break;
}
HeapWord* stripe_end = MIN2(cur_stripe + stripe_size, top);
on_stripe(cur_stripe, stripe_end);
adjust_in_stripe(cur_stripe, stripe_end);
}
}
size_t PSParallelCompact::adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right) {
precond(mark_bitmap()->is_marked(obj_start));
oop obj = cast_to_oop(obj_start);
return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right));
}
void PSParallelCompact::adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end) {
precond(_summary_data.is_region_aligned(stripe_start));
RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start);
HeapWord* obj_start;
if (cur_region->partial_obj_size() != 0) {
obj_start = cur_region->partial_obj_addr();
obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end);
} else {
obj_start = stripe_start;
}
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
obj_start += adjust_in_obj_with_limit(obj_start, stripe_start, stripe_end);
}
}
void PSParallelCompact::adjust_in_old_space(Atomic<uint>* claim_counter) {
// Regions in old-space shouldn't be split.
assert(!_space_info[old_space_id].split_info().is_valid(), "inv");
precond(!_space_info[old_space_id].split_info().is_valid());
auto scan_obj_with_limit = [&] (HeapWord* obj_start, HeapWord* left, HeapWord* right) {
assert(mark_bitmap()->is_marked(obj_start), "inv");
oop obj = cast_to_oop(obj_start);
return obj->oop_iterate_size(&pc_adjust_pointer_closure, MemRegion(left, right));
};
adjust_in_space_helper(old_space_id, claim_counter, [&] (HeapWord* stripe_start, HeapWord* stripe_end) {
assert(_summary_data.is_region_aligned(stripe_start), "inv");
RegionData* cur_region = _summary_data.addr_to_region_ptr(stripe_start);
HeapWord* obj_start;
if (cur_region->partial_obj_size() != 0) {
obj_start = cur_region->partial_obj_addr();
obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end);
} else {
obj_start = stripe_start;
}
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
obj_start += scan_obj_with_limit(obj_start, stripe_start, stripe_end);
}
});
adjust_in_space_helper(old_space_id, claim_counter);
}
void PSParallelCompact::adjust_in_young_space(SpaceId id, Atomic<uint>* claim_counter) {
adjust_in_space_helper(id, claim_counter, [](HeapWord* stripe_start, HeapWord* stripe_end) {
HeapWord* obj_start = stripe_start;
while (obj_start < stripe_end) {
obj_start = mark_bitmap()->find_obj_beg(obj_start, stripe_end);
if (obj_start >= stripe_end) {
break;
}
oop obj = cast_to_oop(obj_start);
obj_start += obj->oop_iterate_size(&pc_adjust_pointer_closure);
}
});
adjust_in_space_helper(id, claim_counter);
}
void PSParallelCompact::adjust_pointers_in_spaces(uint worker_id, Atomic<uint>* claim_counters) {

View File

@ -760,8 +760,11 @@ public:
// should_do_max_compaction controls whether all spaces for dead objs should be reclaimed.
static bool invoke(bool clear_all_soft_refs, bool should_do_max_compaction);
template<typename Func>
static void adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter, Func&& on_stripe);
static void adjust_in_space_helper(SpaceId id, Atomic<uint>* claim_counter);
static size_t adjust_in_obj_with_limit(HeapWord* obj_start, HeapWord* left, HeapWord* right);
static void adjust_in_stripe(HeapWord* stripe_start, HeapWord* stripe_end);
static void adjust_in_old_space(Atomic<uint>* claim_counter);

View File

@ -40,7 +40,7 @@ size_t ContiguousSpacePool::used_in_bytes() {
}
MemoryUsage ContiguousSpacePool::get_memory_usage() {
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
size_t used = used_in_bytes();
size_t committed = _space->capacity();
@ -64,7 +64,7 @@ size_t SurvivorContiguousSpacePool::committed_in_bytes() {
}
MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
size_t used = used_in_bytes();
size_t committed = committed_in_bytes();
@ -85,7 +85,7 @@ size_t TenuredGenerationPool::used_in_bytes() {
MemoryUsage TenuredGenerationPool::get_memory_usage() {
size_t used = used_in_bytes();
size_t committed = _gen->capacity();
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
return MemoryUsage(initial_size(), used, committed, maxSize);
}

View File

@ -194,6 +194,7 @@ void CardTable::resize_covered_region(MemRegion new_region) {
// Note that these versions are precise! The scanning code has to handle the
// fact that the write barrier may be either precise or imprecise.
void CardTable::dirty_MemRegion(MemRegion mr) {
assert(!mr.is_empty(), "precondition");
assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
assert(_covered[0].contains(mr) || _covered[1].contains(mr), "precondition");
@ -203,6 +204,7 @@ void CardTable::dirty_MemRegion(MemRegion mr) {
}
void CardTable::clear_MemRegion(MemRegion mr) {
assert(!mr.is_empty(), "precondition");
// Be conservative: only clean cards entirely contained within the
// region.
CardValue* cur;

View File

@ -130,7 +130,10 @@ oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
// pointer delta is scaled to number of elements (length field in
// objArrayOop) which we assume is 32 bit.
assert(pd == (size_t)(int)pd, "length field overflow");
bs->write_ref_array((HeapWord*)dst_raw, pd);
if (pd > 0) {
// Copied at least one element; call the barrier.
bs->write_ref_array((HeapWord*)dst_raw, pd);
}
return OopCopyResult::failed_check_class_cast;
}
}

View File

@ -174,7 +174,7 @@ private:
void take_sample(jlong now, jlong elapsed, size_t unsampled);
double upper_bound_no_lock(const double standard_deviations) const {
assert(_sample_lock.is_locked(), "Caller must hold lock");
assert(_sample_lock.owned_by_self(), "Caller must hold lock");
return _baseline.weighted_average() + standard_deviations * _baseline.weighted_sd();
}
};

View File

@ -114,7 +114,7 @@ void ShenandoahAllocRate<Clock>::force_update() {
template<typename Clock>
void ShenandoahAllocRate<Clock>::take_sample(jlong now, jlong elapsed, size_t unsampled) {
assert(_sample_lock.is_locked(), "Caller must hold lock");
assert(_sample_lock.owned_by_self(), "Caller must hold lock");
_last_sample_time = now;

View File

@ -221,22 +221,22 @@ void ShenandoahControlThread::run_service() {
// Wait before performing the next action. If allocation happened during this wait,
// we exit sooner, to let heuristics re-evaluate new conditions. If we are at idle,
// back off exponentially.
const double before_sleep = most_recent_wake_time;
if (heap->has_changed()) {
sleep = ShenandoahControlIntervalMin;
} else if ((before_sleep - last_sleep_adjust_time) * 1000 > ShenandoahControlIntervalAdjustPeriod){
} else if ((most_recent_wake_time - last_sleep_adjust_time) * 1000 > ShenandoahControlIntervalAdjustPeriod){
sleep = MIN2<int>(ShenandoahControlIntervalMax, MAX2(1, sleep * 2));
last_sleep_adjust_time = before_sleep;
last_sleep_adjust_time = most_recent_wake_time;
}
MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag);
const double before_sleep_time = os::elapsedTime();
ml.wait(sleep);
most_recent_wake_time = os::elapsedTime();
// Record a conservative estimate of the longest anticipated sleep duration until we sample again.
double planned_sleep_interval = MIN2<int>(ShenandoahControlIntervalMax, MAX2(1, sleep * 2)) / 1000.0;
most_recent_wake_time = os::elapsedTime();
heuristics->update_should_start_query_times(most_recent_wake_time, planned_sleep_interval);
if (LogTarget(Debug, gc, thread)::is_enabled()) {
double elapsed = most_recent_wake_time - before_sleep;
double hiccup = elapsed - double(sleep);
double elapsed = most_recent_wake_time - before_sleep_time;
double hiccup = elapsed - double(sleep) / 1000.0;
if (hiccup > 0.001) {
log_debug(gc, thread)("Control Thread hiccup time: %.3fs", hiccup);
}

View File

@ -1745,8 +1745,8 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req, bo
for (idx_t i = beg; i <= end; i++) {
ShenandoahHeapRegion* r = _heap->get_region(i);
assert(i == beg || _heap->get_region(i - 1)->index() + 1 == r->index(), "Should be contiguous");
assert(r->is_empty(), "Should be empty");
r->try_recycle_under_lock();
assert(r->is_empty(), "Should be empty");
r->set_affiliation(req.affiliation());
r->make_regular_allocation(req.affiliation());
if ((i == end) && (used_words_in_last_region > 0)) {

View File

@ -116,23 +116,21 @@ void ShenandoahRegulatorThread::regulator_sleep() {
// Wait before performing the next action. If allocation happened during this wait,
// we exit sooner, to let heuristics re-evaluate new conditions. If we are at idle,
// back off exponentially.
double before_sleep_time = _most_recent_wake_time;
if (ShenandoahHeap::heap()->has_changed()) {
_sleep = ShenandoahControlIntervalMin;
} else if ((before_sleep_time - _last_sleep_adjust_time) * 1000 > ShenandoahControlIntervalAdjustPeriod){
} else if ((_most_recent_wake_time - _last_sleep_adjust_time) * 1000 > ShenandoahControlIntervalAdjustPeriod){
_sleep = MIN2<uint>(ShenandoahControlIntervalMax, MAX2(1u, _sleep * 2));
_last_sleep_adjust_time = before_sleep_time;
_last_sleep_adjust_time = _most_recent_wake_time;
}
SuspendibleThreadSetLeaver leaver;
const double before_sleep_time = os::elapsedTime();
os::naked_short_sleep(_sleep);
double wake_time = os::elapsedTime();
_most_recent_period = wake_time - _most_recent_wake_time;
_most_recent_wake_time = wake_time;
_most_recent_wake_time = os::elapsedTime();
_young_heuristics->update_should_start_query_times(_most_recent_wake_time, double(_sleep) / 1000.0);
if (LogTarget(Debug, gc, thread)::is_enabled()) {
double elapsed = _most_recent_wake_time - before_sleep_time;
double hiccup = elapsed - double(_sleep);
double hiccup = elapsed - double(_sleep) / 1000.0;
if (hiccup > 0.001) {
log_debug(gc, thread)("Regulator hiccup time: %.3fs", hiccup);
}

View File

@ -82,7 +82,6 @@ class ShenandoahRegulatorThread: public ConcurrentGCThread {
// duration of planned regulator sleep period, in ms
uint _sleep;
double _most_recent_wake_time;
double _most_recent_period;
double _last_sleep_adjust_time;
};

View File

@ -1921,6 +1921,31 @@ bool BoolNode::is_counted_loop_exit_test() {
return false;
}
template<typename IntegerType>
static const IntegerType* integral_abs_value(const IntegerType* t) {
typedef typename IntegerType::NativeUType NativeUType;
// Find the absolute value of a type, resulting in a range that fits inside the unsigned range [0, signed_max+1].
// The possible values of a TypeInteger is described with the following range in the signed domain:
// smin----------lo=======uhi--------0--------ulo===========hi----------smax
// To find the absolute value of the range, we find the closer (min) value of uhi and ulo to 0, and the further (max)
// value of lo and hi from 0. In the unsigned domain, the resulting range looks like this:
// 0-----------min(|ulo|,|uhi|)================max(|lo|,|hi|)-----------umax
// When the input range's hi and lo are both positive or negative, lo == ulo and hi == uhi:
// smin------------------------------0-------lo===========hi------------smax (Positive)
// smin--------lo===========hi-------0----------------------------------smax (Negative)
// For these ranges, the result in the unsigned domain is simply [min(|lo|, |hi|), max(|lo|, |hi|)]:
// 0-----------min(|lo|,|hi|)==================max(|lo|,|hi|)-----------umax
NativeUType umin = MIN2<NativeUType>(g_uabs(t->_ulo), g_uabs(t->_uhi));
NativeUType umax = MAX2<NativeUType>(g_uabs(t->_lo), g_uabs(t->_hi));
return IntegerType::make_unsigned(umin, umax, t->_widen);
}
//=============================================================================
//------------------------------Value------------------------------------------
const Type* AbsNode::Value(PhaseGVN* phase) const {
@ -1930,17 +1955,13 @@ const Type* AbsNode::Value(PhaseGVN* phase) const {
switch (t1->base()) {
case Type::Int: {
const TypeInt* ti = t1->is_int();
if (ti->is_con()) {
return TypeInt::make(g_uabs(ti->get_con()));
}
break;
return integral_abs_value(ti);
}
case Type::Long: {
const TypeLong* tl = t1->is_long();
if (tl->is_con()) {
return TypeLong::make(g_uabs(tl->get_con()));
}
break;
return integral_abs_value(tl);
}
case Type::FloatCon:
return TypeF::make(abs(t1->getf()));

View File

@ -1801,6 +1801,12 @@ const TypeInt* TypeInt::make(jint lo, jint hi, int widen) {
return make_or_top(TypeIntPrototype<jint, juint>{{lo, hi}, {0, max_juint}, {0, 0}}, widen)->is_int();
}
const TypeInt* TypeInt::make_unsigned(juint ulo, juint uhi, int widen) {
assert(ulo <= uhi, "must be legal bounds");
// By creating the TypeInt with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds.
return make_or_top(TypeIntPrototype<jint, juint>{{min_jint, max_jint}, {ulo, uhi}, {0, 0}}, widen)->is_int();
}
const Type* TypeInt::make_or_top(const TypeIntPrototype<jint, juint>& t, int widen) {
return make_or_top(t, widen, false);
}
@ -1936,6 +1942,12 @@ const TypeLong* TypeLong::make(jlong lo, jlong hi, int widen) {
return make_or_top(TypeIntPrototype<jlong, julong>{{lo, hi}, {0, max_julong}, {0, 0}}, widen)->is_long();
}
const TypeLong* TypeLong::make_unsigned(julong ulo, julong uhi, int widen) {
assert(ulo <= uhi, "must be legal bounds");
// By creating the TypeLong with the full signed range and the given unsigned range, the signed bounds are inferred from the unsigned bounds.
return make_or_top(TypeIntPrototype<jlong, julong>{{min_jlong, max_jlong}, {ulo, uhi}, {0, 0}}, widen)->is_long();
}
const Type* TypeLong::make_or_top(const TypeIntPrototype<jlong, julong>& t, int widen) {
return make_or_top(t, widen, false);
}

View File

@ -782,6 +782,7 @@ protected:
public:
typedef jint NativeType;
typedef juint NativeUType;
virtual bool eq(const Type* t) const;
virtual uint hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
@ -795,6 +796,7 @@ public:
static const TypeInt* make(jint con);
// must always specify w
static const TypeInt* make(jint lo, jint hi, int widen);
static const TypeInt* make_unsigned(juint ulo, juint uhi, int widen);
static const Type* make_or_top(const TypeIntPrototype<jint, juint>& t, int widen);
static const TypeInt* make(const TypeIntPrototype<jint, juint>& t, int widen) { return make_or_top(t, widen)->is_int(); }
static const TypeInt* make(const TypeIntMirror<jint, juint>& t, int widen) {
@ -871,6 +873,7 @@ protected:
virtual const Type* filter_helper(const Type* kills, bool include_speculative) const;
public:
typedef jlong NativeType;
typedef julong NativeUType;
virtual bool eq( const Type *t ) const;
virtual uint hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
@ -885,6 +888,7 @@ public:
static const TypeLong* make(jlong con);
// must always specify w
static const TypeLong* make(jlong lo, jlong hi, int widen);
static const TypeLong* make_unsigned(julong ulo, julong uhi, int widen);
static const Type* make_or_top(const TypeIntPrototype<jlong, julong>& t, int widen);
static const TypeLong* make(const TypeIntPrototype<jlong, julong>& t, int widen) { return make_or_top(t, widen)->is_long(); }
static const TypeLong* make(const TypeIntMirror<jlong, julong>& t, int widen) {

View File

@ -298,7 +298,7 @@ static bool is_klass_initialized(const TypeInstPtr* vec_klass) {
}
static bool is_primitive_lane_type(VectorSupport::LaneType laneType) {
return laneType >= VectorSupport::LT_FLOAT && laneType <= VectorSupport::LT_LONG;
return laneType >= VectorSupport::LT_FLOAT && laneType <= VectorSupport::LT_FLOAT16;
}
static BasicType get_vector_primitive_lane_type(VectorSupport::LaneType lanetype) {
@ -310,10 +310,15 @@ static BasicType get_vector_primitive_lane_type(VectorSupport::LaneType lanetype
case VectorSupport::LaneType::LT_INT: return T_INT;
case VectorSupport::LaneType::LT_SHORT: return T_SHORT;
case VectorSupport::LaneType::LT_BYTE: return T_BYTE;
case VectorSupport::LaneType::LT_FLOAT16: return T_SHORT;
}
return T_ILLEGAL;
}
static bool is_supported_lane_type(VectorSupport::LaneType laneType) {
return laneType >= VectorSupport::LT_FLOAT && laneType <= VectorSupport::LT_LONG;
}
//
// <V extends Vector<E>,
// M extends VectorMask<E>,
@ -557,6 +562,11 @@ bool LibraryCallKit::inline_vector_call(int arity) {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
@ -651,6 +661,11 @@ bool LibraryCallKit::inline_vector_mask_operation() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
int num_elem = vlen->get_con();
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
int mopc = VectorSupport::vop2ideal(oper->get_con(), vltype);
@ -721,6 +736,12 @@ bool LibraryCallKit::inline_vector_frombits_coerced() {
return false;
}
int bcast_mode = mode->get_con();
if (!is_supported_lane_type(vltype) && bcast_mode != VectorSupport::MODE_BROADCAST) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false; // should be primitive type
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -732,7 +753,6 @@ bool LibraryCallKit::inline_vector_frombits_coerced() {
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
bool is_mask = is_vector_mask(vbox_klass);
int bcast_mode = mode->get_con();
VectorMaskUseType checkFlags = (VectorMaskUseType)(is_mask ? VecMaskUseAll : VecMaskNotUsed);
int opc = bcast_mode == VectorSupport::MODE_BITS_COERCED_LONG_TO_MASK ? Op_VectorLongToMask : Op_Replicate;
@ -1296,6 +1316,11 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
int num_elem = vlen->get_con();
int idx_num_elem = idx_vlen->get_con();
@ -1479,6 +1504,10 @@ bool LibraryCallKit::inline_vector_reduction() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
const Type* vmask_type = gvn().type(argument(6));
bool is_masked_op = vmask_type != TypePtr::NULL_PTR;
@ -1624,6 +1653,11 @@ bool LibraryCallKit::inline_vector_test() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -1773,6 +1807,11 @@ bool LibraryCallKit::inline_vector_compare() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass) || !is_klass_initialized(mask_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -1893,6 +1932,10 @@ bool LibraryCallKit::inline_vector_rearrange() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
BasicType shuffle_bt = elem_bt;
if (shuffle_bt == T_FLOAT) {
@ -2029,6 +2072,10 @@ bool LibraryCallKit::inline_vector_select_from() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
int num_elem = vlen->get_con();
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
if (!is_power_of_2(num_elem)) {
@ -2193,6 +2240,11 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
const Type* vmask_type = gvn().type(argument(7));
bool is_masked_op = vmask_type != TypePtr::NULL_PTR;
if (is_masked_op) {
@ -2369,6 +2421,16 @@ bool LibraryCallKit::inline_vector_convert() {
log_if_needed(" ** not a primitive to lt=%s", VectorSupport::lanetype2name(vltype_to));
return false; // should be primitive type
}
if (!is_supported_lane_type(vltype_from)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype_from));
return false;
}
if (!is_supported_lane_type(vltype_to)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype_to));
return false;
}
BasicType elem_bt_from = get_vector_primitive_lane_type(vltype_from);
BasicType elem_bt_to = get_vector_primitive_lane_type(vltype_to);
@ -2550,6 +2612,11 @@ bool LibraryCallKit::inline_vector_insert() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -2638,6 +2705,11 @@ bool LibraryCallKit::inline_vector_extract() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -2822,6 +2894,11 @@ bool LibraryCallKit::inline_vector_select_from_two_vectors() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -2960,6 +3037,11 @@ bool LibraryCallKit::inline_vector_compress_expand() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
int num_elem = vlen->get_con();
BasicType elem_bt = get_vector_primitive_lane_type(vltype);
int opc = VectorSupport::vop2ideal(opr->get_con(), vltype);
@ -3035,6 +3117,11 @@ bool LibraryCallKit::inline_index_vector() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
@ -3170,6 +3257,11 @@ bool LibraryCallKit::inline_index_partially_in_upper_range() {
return false;
}
if (!is_supported_lane_type(vltype)) {
log_if_needed(" ** unsupported lane type =%s", VectorSupport::lanetype2name(vltype));
return false;
}
if (!is_klass_initialized(mask_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;

View File

@ -206,9 +206,10 @@ const char* VectorSupport::lanetype2name(LaneType lane_type) {
"byte",
"short",
"int",
"long"
"long",
"float16",
};
if (lane_type >= LT_FLOAT && lane_type <= LT_LONG) {
if (lane_type >= LT_FLOAT && lane_type <= LT_FLOAT16) {
return lanetype2name[lane_type];
}
assert(false, "unknown lane type: %d", (int)lane_type);
@ -224,6 +225,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_AddI;
case LT_LONG: return Op_AddL;
case LT_FLOAT16: return Op_AddHF;
case LT_FLOAT: return Op_AddF;
case LT_DOUBLE: return Op_AddD;
default: return 0;
@ -236,6 +238,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_SubI;
case LT_LONG: return Op_SubL;
case LT_FLOAT16: return Op_SubHF;
case LT_FLOAT: return Op_SubF;
case LT_DOUBLE: return Op_SubD;
default: return 0;
@ -248,6 +251,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_MulI;
case LT_LONG: return Op_MulL;
case LT_FLOAT16: return Op_MulHF;
case LT_FLOAT: return Op_MulF;
case LT_DOUBLE: return Op_MulD;
default: return 0;
@ -260,6 +264,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_DivI;
case LT_LONG: return Op_DivL;
case LT_FLOAT16: return Op_DivHF;
case LT_FLOAT: return Op_DivF;
case LT_DOUBLE: return Op_DivD;
default: return 0;
@ -272,6 +277,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT:
case LT_INT: return Op_MinI;
case LT_LONG: return Op_MinL;
case LT_FLOAT16: return Op_MinHF;
case LT_FLOAT: return Op_MinF;
case LT_DOUBLE: return Op_MinD;
default: return 0;
@ -284,6 +290,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT:
case LT_INT: return Op_MaxI;
case LT_LONG: return Op_MaxL;
case LT_FLOAT16: return Op_MaxHF;
case LT_FLOAT: return Op_MaxF;
case LT_DOUBLE: return Op_MaxD;
default: return 0;
@ -316,6 +323,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_AbsI;
case LT_LONG: return Op_AbsL;
case LT_FLOAT16: return 0;
case LT_FLOAT: return Op_AbsF;
case LT_DOUBLE: return Op_AbsD;
default: return 0;
@ -328,6 +336,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: return Op_NegI;
case LT_LONG: return Op_NegL;
case LT_FLOAT16: return 0;
case LT_FLOAT: return Op_NegF;
case LT_DOUBLE: return Op_NegD;
default: return 0;
@ -366,6 +375,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
}
case VECTOR_OP_SQRT: {
switch (lt) {
case LT_FLOAT16: return Op_SqrtHF;
case LT_FLOAT: return Op_SqrtF;
case LT_DOUBLE: return Op_SqrtD;
default: return 0;
@ -374,6 +384,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
}
case VECTOR_OP_FMA: {
switch (lt) {
case LT_FLOAT16: return Op_FmaHF;
case LT_FLOAT: return Op_FmaF;
case LT_DOUBLE: return Op_FmaD;
default: return 0;
@ -436,6 +447,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_VectorMaskLastTrue;
default: return 0;
@ -448,6 +460,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_VectorMaskFirstTrue;
default: return 0;
@ -460,6 +473,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_VectorMaskTrueCount;
default: return 0;
@ -472,6 +486,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_VectorMaskToLong;
default: return 0;
@ -484,6 +499,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_ExpandV;
default: return 0;
@ -496,6 +512,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_CompressV;
default: return 0;
@ -508,6 +525,7 @@ int VectorSupport::vop2ideal(jint id, LaneType lt) {
case LT_SHORT: // fall-through
case LT_INT: // fall-through
case LT_LONG: // fall-through
case LT_FLOAT16: // fall-through
case LT_FLOAT: // fall-through
case LT_DOUBLE: return Op_CompressM;
default: return 0;

View File

@ -144,7 +144,8 @@ class VectorSupport : AllStatic {
LT_BYTE = 2,
LT_SHORT = 3,
LT_INT = 4,
LT_LONG = 5
LT_LONG = 5,
LT_FLOAT16 = 6
};
enum {

View File

@ -51,7 +51,6 @@ MemoryPool::MemoryPool(const char* name,
_type(type),
_initial_size(init_size),
_max_size(max_size),
_available_for_allocation(true),
_managers(),
_num_managers(0),
_peak_usage(),
@ -188,7 +187,7 @@ MemoryUsage CodeHeapPool::get_memory_usage() {
size_t used = used_in_bytes();
OrderAccess::acquire(); // ensure possible cache expansion in CodeCache::allocate is seen
size_t committed = _codeHeap->capacity();
size_t maxSize = (available_for_allocation() ? max_size() : 0);
size_t maxSize = max_size();
return MemoryUsage(initial_size(), used, committed, maxSize);
}

View File

@ -61,7 +61,6 @@ class MemoryPool : public CHeapObj<mtInternal> {
PoolType _type;
size_t _initial_size;
size_t _max_size;
bool _available_for_allocation; // Default is true
MemoryManager* _managers[max_num_managers];
int _num_managers;
MemoryUsage _peak_usage; // Peak memory usage
@ -98,13 +97,6 @@ class MemoryPool : public CHeapObj<mtInternal> {
bool is_pool(instanceHandle pool) const;
bool available_for_allocation() { return _available_for_allocation; }
bool set_available_for_allocation(bool value) {
bool prev = _available_for_allocation;
_available_for_allocation = value;
return prev;
}
MemoryManager* get_memory_manager(int index) {
assert(index >= 0 && index < _num_managers, "Invalid index");
return _managers[index];

View File

@ -32,15 +32,35 @@ import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import jdk.internal.javac.PreviewFeature;
import sun.security.internal.InternalBinaryEncodable;
/**
* This interface is implemented by security API classes that contain
* binary-encodable cryptographic material.
* This interface identifies the cryptographic objects that can be converted
* to and from binary data, and thereby encoded and decoded as PEM text.
*
* <p> This sealed interface may evolve. When using {@code switch}, always include a
* {@code default} case rather than relying on the classes specified in the
* {@code permits} clause to remain fixed. An exhaustive {@code switch} may
* result in a {@link MatchException}.
* <p> The APIs for cryptographic objects such as public keys, private keys,
* certificates, and certificate revocation lists all provide the means to
* convert their instances to and from standardized binary representations.
* Other kinds of cryptographic objects, such as certificate requests, have
* no corresponding API but can still be expressed as standardized binary
* representations. The {@code BinaryEncodable} interface allows the
* {@link PEMEncoder} and {@link PEMDecoder} classes to operate uniformly on
* binary representations of key or certificate material.
*
* <p> The permitted subtype {@code PEM} is notable for supporting the encoding
* and decoding of PEM text that represents cryptographic objects for which no
* API exists. In future releases, other permitted subtypes may be added to
* support the encoding and decoding of such cryptographic objects.
*
* <p> The list of permitted subtypes shown after {@code permits} is not
* exhaustive. This means if application code switches over a
* {@code BinaryEncodable} value, the {@code switch} cannot be made exhaustive
* simply by providing a {@code case} label for every permitted subtype shown
* in the list; there also must be a {@code default} or
* {@code case BinaryEncodable} label to handle additional subtypes. This
* allows the list of permitted subtypes to change over time without causing
* pre-existing switches to fail because of an unrecognized subtype.
*
* @see AsymmetricKey
* @see KeyPair
@ -57,5 +77,5 @@ import jdk.internal.javac.PreviewFeature;
@PreviewFeature(feature = PreviewFeature.Feature.PEM_API)
public sealed interface BinaryEncodable permits AsymmetricKey, KeyPair,
PKCS8EncodedKeySpec, X509EncodedKeySpec, EncryptedPrivateKeyInfo,
X509Certificate, X509CRL, PEM {
X509Certificate, X509CRL, PEM, InternalBinaryEncodable {
}

View File

@ -48,10 +48,10 @@ import java.util.Objects;
* PEM is a textual encoding used to store and transfer cryptographic
* objects, such as asymmetric keys, certificates, and certificate revocation
* lists (CRLs). It is defined in RFC 1421 and RFC 7468. PEM consists of
* Base64-encoded content enclosed by a type-identifying header
* and footer.
* Base64-encoded content enclosed by a header and footer that identify the
* type of the content.
*
* <p>The {@link #decode(String)} and {@link #decode(InputStream)} methods
* <p> The {@link #decode(String)} and {@link #decode(InputStream)} methods
* return an instance of a class that matches the PEM type and implements
* {@link BinaryEncodable}, as follows:
* <ul>
@ -70,11 +70,18 @@ import java.util.Objects;
* </ul>
*
* <p> If the PEM type has no corresponding class, {@code decode(String)} and
* {@code decode(InputStream)} will return a {@code PEM} object.
* {@code decode(InputStream)} return a {@code PEM} object.
*
* <p> If application code switches over the {@code BinaryEncodable} result of
* {@link #decode(String)} or {@link #decode(InputStream)}, the {@code switch} cannot
* be made exhaustive simply by providing a {@code case} label for every permitted
* subtype listed for {@code BinaryEncodable}; there also must be a {@code default}
* or {@code case BinaryEncodable} label to handle additional subtypes that
* might be added in the future.
*
* <p> The {@link #decode(String, Class)} and {@link #decode(InputStream, Class)}
* methods accept a class parameter specifying the desired {@code BinaryEncodable}
* type. These methods avoid the need for casting and are useful when multiple
* methods accept a parameter specifying the desired {@code BinaryEncodable}
* result. These methods avoid the need for casting and are useful when multiple
* representations are possible. For example, if the PEM contains both public and
* private keys, specifying {@code PrivateKey.class} returns only the private key.
* If {@code X509EncodedKeySpec.class} is provided, the public key encoding is
@ -109,11 +116,6 @@ import java.util.Objects;
* for decryption, an {@link EncryptedPrivateKeyInfo} is returned.
* A {@code PEMDecoder} configured for decryption can also decode unencrypted PEM.
*
* <p> The {@code BinaryEncodable} interface may evolve. When using a decode method
* with {@code switch}, always include a {@code default} case rather than
* relying on the classes specified in the permits clause to remain fixed.
* An exhaustive {@code switch} may result in a {@link MatchException}.
*
* <p> This class is immutable and thread-safe.
*
* <p> Example: decode a private key:
@ -136,6 +138,7 @@ import java.util.Objects;
* @see PEMEncoder
* @see PEM
* @see EncryptedPrivateKeyInfo
* @see BinaryEncodable
*
* @spec https://www.rfc-editor.org/info/rfc1421
* RFC 1421: Privacy Enhancement for Internet Electronic Mail

View File

@ -498,15 +498,18 @@ public final class ListFormat extends Format {
midIndex += mbLength;
}
}
parsed = new MessageFormat(createMessageFormatString(count), locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(createMessageFormatString(count)),
locale).parseObject(source, parsePos);
}
}
if (parsed == null) {
// now try exact number patterns
parsed = new MessageFormat(patterns[TWO], locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(patterns[TWO]),
locale).parseObject(source, parsePos);
if (parsed == null) {
parsed = new MessageFormat(patterns[THREE], locale).parseObject(source, parsePos);
parsed = new MessageFormat(listToMessageFormatPattern(patterns[THREE]),
locale).parseObject(source, parsePos);
}
}
@ -584,9 +587,9 @@ public final class ListFormat extends Format {
var len = input.length;
return switch (len) {
case 0 -> throw new IllegalArgumentException("There should at least be one input string");
case 1 -> new MessageFormat("{0}", locale);
case 2, 3 -> new MessageFormat(patterns[len + 1], locale);
default -> new MessageFormat(createMessageFormatString(len), locale);
case 1 -> new MessageFormat(listToMessageFormatPattern("{0}"), locale);
case 2, 3 -> new MessageFormat(listToMessageFormatPattern(patterns[len + 1]), locale);
default -> new MessageFormat(listToMessageFormatPattern(createMessageFormatString(len)), locale);
};
}
@ -742,4 +745,18 @@ public final class ListFormat extends Format {
return prefixPos < suffixPos ?
new int[] {prefixPos, suffixPos + suffix.length()} : null;
}
/**
* {@return the MessageFormat pattern corresponding to the passed ListFormat pattern}
*
* Single quotes must be escaped so they are interpreted as literal text
* as opposed to escaping delimiters when passed to MessageFormat. Everything
* else remains the same; ListFormat already handles other validation on its own.
*
* @param pattern list pattern to use
*/
private static String listToMessageFormatPattern(String pattern) {
return pattern.indexOf('\'') < 0 ? pattern :
pattern.replace("'", "''");
}
}

View File

@ -156,7 +156,8 @@ public class VectorSupport {
LT_BYTE = 2,
LT_SHORT = 3,
LT_INT = 4,
LT_LONG = 5;
LT_LONG = 5,
LT_FLOAT16 = 6;
/* ============================================================================ */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2026, 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 sun.security.internal;
import java.security.BinaryEncodable;
/**
* This class is a non-public subtype of BinaryEncodable. This type
* allows the BinaryEncodable list of permitted subtypes to change
* over time without causing pre-existing switches to fail because of an
* unrecognized subtype.
*/
public final class InternalBinaryEncodable implements BinaryEncodable {
private InternalBinaryEncodable() {}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2026, 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
@ -40,7 +40,7 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.ReentrantLock;
import java.util.zip.Adler32;
import java.util.zip.CRC32C;
import javax.crypto.KDF;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
@ -610,9 +610,9 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
private static int getChecksum(byte[] input) {
Adler32 adler32 = new Adler32();
adler32.update(input);
return (int) adler32.getValue();
CRC32C crc32c = new CRC32C();
crc32c.update(input);
return (int) crc32c.getValue();
}
void setMasterSecret(SecretKey secret) {

View File

@ -352,33 +352,15 @@ getPlatformTimeZoneID()
}
static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
getJavaTimezoneFromPlatform(const char *tz_buf, size_t tz_len, const char *mapfilename) {
FILE *tzmapf;
char mapfilename[PATH_MAX + 1];
char line[256];
int linecount = 0;
char *tz_buf = NULL;
char *temp_tz = NULL;
char *javatz = NULL;
size_t tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields until early AIX6.1.
* This restriction has been removed from AIX7. */
tz_buf = strdup(tz);
tz_len = strlen(tz_buf);
/* Open tzmappings file, with buffer overrun check */
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
goto tzerr;
}
strcpy(mapfilename, java_home_dir);
strcat(mapfilename, "/lib/tzmappings");
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
jio_fprintf(stderr, "can't open %s\n", mapfilename);
goto tzerr;
return NULL;
}
while (fgets(line, sizeof(line), tzmapf) != NULL) {
@ -431,10 +413,58 @@ mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
break;
}
}
(void) fclose(tzmapf);
return javatz;
}
static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
char mapfilename[PATH_MAX + 1];
char *tz_buf = NULL;
char *javatz = NULL;
char *temp_tz = NULL;
size_t tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields until early AIX6.1.
* This restriction has been removed from AIX7. */
tz_buf = strdup(tz);
if (tz_buf == NULL) {
jio_fprintf(stderr, "Failed to allocate timezone buffer\n");
goto tzerr;
}
tz_len = strlen(tz_buf);
/* Open tzmappings file, with buffer overrun check */
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
goto tzerr;
}
strcpy(mapfilename, java_home_dir);
strcat(mapfilename, "/lib/tzmappings");
// First attempt to find the Java timezone for the full tz string
javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename);
// If no match was found, check for timezone with truncated value
if (javatz == NULL) {
temp_tz = strchr(tz, ',');
tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz;
free((void *) tz_buf);
tz_buf = (char *)malloc(tz_len + 1);
if (tz_buf == NULL) {
jio_fprintf(stderr, "Failed to allocate timezone buffer\n");
goto tzerr;
}
memcpy(tz_buf, tz, tz_len);
tz_buf[tz_len] = '\0';
javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename);
}
tzerr:
if (tz_buf != NULL ) {
if (tz_buf != NULL) {
free((void *) tz_buf);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2026, 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
@ -32,13 +32,13 @@ package java.awt.event;
* <P>
* Mouse motion events occur when a mouse is moved or dragged.
* (Many such events will be generated in a normal program.
* To track clicks and other mouse events, use the MouseAdapter.)
* To track clicks and other mouse events, use the {@link MouseAdapter}.)
* <P>
* Extend this class to create a {@code MouseEvent} listener
* and override the methods for the events of interest. (If you implement the
* {@code MouseMotionListener} interface, you have to define all of
* the methods in it. This abstract class defines null methods for them
* all, so you can only have to define methods for events you care about.)
* all, so you have to define only methods for events you care about.)
* <P>
* Create a listener object using the extended class and then register it with
* a component using the component's {@code addMouseMotionListener}
@ -61,17 +61,14 @@ public abstract class MouseMotionAdapter implements MouseMotionListener {
protected MouseMotionAdapter() {}
/**
* Invoked when a mouse button is pressed on a component and then
* dragged. Mouse drag events will continue to be delivered to
* the component where the first originated until the mouse button is
* released (regardless of whether the mouse position is within the
* bounds of the component).
* {@inheritDoc}
*/
@Override
public void mouseDragged(MouseEvent e) {}
/**
* Invoked when the mouse button has been moved on a component
* (with no buttons no down).
* {@inheritDoc}
*/
@Override
public void mouseMoved(MouseEvent e) {}
}

View File

@ -36,7 +36,9 @@ abstract sealed class AbstractMask<E> extends VectorMask<E>
FloatVector64.FloatMask64, FloatVector128.FloatMask128, FloatVector256.FloatMask256, FloatVector512.FloatMask512, FloatVectorMax.FloatMaskMax,
IntVector64.IntMask64, IntVector128.IntMask128, IntVector256.IntMask256, IntVector512.IntMask512, IntVectorMax.IntMaskMax,
LongVector64.LongMask64, LongVector128.LongMask128, LongVector256.LongMask256, LongVector512.LongMask512, LongVectorMax.LongMaskMax,
ShortVector64.ShortMask64, ShortVector128.ShortMask128, ShortVector256.ShortMask256, ShortVector512.ShortMask512, ShortVectorMax.ShortMaskMax {
ShortVector64.ShortMask64, ShortVector128.ShortMask128, ShortVector256.ShortMask256, ShortVector512.ShortMask512, ShortVectorMax.ShortMaskMax,
Float16Vector64.Float16Mask64, Float16Vector128.Float16Mask128, Float16Vector256.Float16Mask256, Float16Vector512.Float16Mask512,
Float16VectorMax.Float16MaskMax {
AbstractMask(boolean[] bits) {
super(bits);
}

View File

@ -35,7 +35,8 @@ abstract sealed class AbstractShuffle<E> extends VectorShuffle<E>
FloatVector64.FloatShuffle64, FloatVector128.FloatShuffle128, FloatVector256.FloatShuffle256, FloatVector512.FloatShuffle512, FloatVectorMax.FloatShuffleMax,
IntVector64.IntShuffle64, IntVector128.IntShuffle128, IntVector256.IntShuffle256, IntVector512.IntShuffle512, IntVectorMax.IntShuffleMax,
LongVector64.LongShuffle64, LongVector128.LongShuffle128, LongVector256.LongShuffle256, LongVector512.LongShuffle512, LongVectorMax.LongShuffleMax,
ShortVector64.ShortShuffle64, ShortVector128.ShortShuffle128, ShortVector256.ShortShuffle256, ShortVector512.ShortShuffle512, ShortVectorMax.ShortShuffleMax {
ShortVector64.ShortShuffle64, ShortVector128.ShortShuffle128, ShortVector256.ShortShuffle256, ShortVector512.ShortShuffle512, ShortVectorMax.ShortShuffleMax,
Float16Vector64.Float16Shuffle64, Float16Vector128.Float16Shuffle128, Float16Vector256.Float16Shuffle256, Float16Vector512.Float16Shuffle512, Float16VectorMax.Float16ShuffleMax {
static final IntUnaryOperator IDENTITY = i -> i;
// Internal representation allows for a maximum index of E.MAX_VALUE - 1

View File

@ -37,7 +37,7 @@ import jdk.internal.vm.annotation.TrustFinalFields;
abstract sealed class AbstractSpecies<E> extends jdk.internal.vm.vector.VectorSupport.VectorSpecies<E>
implements VectorSpecies<E>
permits ByteVector.ByteSpecies, DoubleVector.DoubleSpecies, FloatVector.FloatSpecies,
IntVector.IntSpecies, LongVector.LongSpecies, ShortVector.ShortSpecies {
IntVector.IntSpecies, LongVector.LongSpecies, ShortVector.ShortSpecies, Float16Vector.Float16Species {
final VectorShape vectorShape;
final LaneType laneType;
final int laneCount;
@ -424,14 +424,21 @@ abstract sealed class AbstractSpecies<E> extends jdk.internal.vm.vector.VectorSu
Object ia = Array.newInstance(carrierType(), laneCount);
assert(ia.getClass() == laneType.arrayType);
checkValue(laneCount-1); // worst case
for (int i = 0; i < laneCount; i++) {
if ((byte)i == i)
Array.setByte(ia, i, (byte)i);
else if ((short)i == i)
Array.setShort(ia, i, (short)i);
else
Array.setInt(ia, i, i);
assert(Array.getDouble(ia, i) == i);
if (elementType() == Float16.class) {
for (int i = 0; i < laneCount; i++) {
Array.setShort(ia, i, Float.floatToFloat16((float)i));
assert(Float16.shortBitsToFloat16(Array.getShort(ia, i)).intValue() == i);
}
} else {
for (int i = 0; i < laneCount; i++) {
if ((byte)i == i)
Array.setByte(ia, i, (byte)i);
else if ((short)i == i)
Array.setShort(ia, i, (short)i);
else
Array.setInt(ia, i, i);
assert(Array.getDouble(ia, i) == i);
}
}
return ia;
}
@ -629,6 +636,8 @@ abstract sealed class AbstractSpecies<E> extends jdk.internal.vm.vector.VectorSu
s = IntVector.species(shape); break;
case LaneType.SK_LONG:
s = LongVector.species(shape); break;
case LaneType.SK_FLOAT16:
s = Float16Vector.species(shape); break;
}
if (s == null) {
// NOTE: The result of this method is guaranteed to be

View File

@ -35,7 +35,7 @@ import static jdk.incubator.vector.VectorOperators.*;
@SuppressWarnings("cast")
abstract sealed class AbstractVector<E> extends Vector<E>
permits ByteVector, DoubleVector, FloatVector, IntVector, LongVector, ShortVector {
permits ByteVector, DoubleVector, FloatVector, IntVector, LongVector, ShortVector, Float16Vector {
/**
* The order of vector bytes when stored in natural,
* array elements of the same lane type.
@ -331,6 +331,15 @@ abstract sealed class AbstractVector<E> extends Vector<E>
return (DoubleVector) asVectorRaw(LaneType.DOUBLE);
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
@ForceInline
public Float16Vector reinterpretAsFloat16s() {
return (Float16Vector) asVectorRaw(LaneType.FLOAT16);
}
/**
* {@inheritDoc} <!--workaround-->
*/
@ -682,6 +691,8 @@ abstract sealed class AbstractVector<E> extends Vector<E>
return FloatVector.fromMemorySegment(rsp.check(float.class), ms, 0, bo, m.check(float.class)).check0(rsp);
case LaneType.SK_DOUBLE:
return DoubleVector.fromMemorySegment(rsp.check(double.class), ms, 0, bo, m.check(double.class)).check0(rsp);
case LaneType.SK_FLOAT16:
return Float16Vector.fromMemorySegment(rsp.check(Float16.class), ms, 0, bo, m.check(Float16.class)).check0(rsp);
default:
throw new AssertionError(rsp.toString());
}
@ -744,6 +755,13 @@ abstract sealed class AbstractVector<E> extends Vector<E>
}
return DoubleVector.fromArray(dsp.check(double.class), a, 0).check0(dsp);
}
case LaneType.SK_FLOAT16: {
short[] a = new short[rlength];
for (int i = 0; i < limit; i++) {
a[i] = Float16.float16ToRawShortBits(Float16.valueOf((float) lanes[i]));
}
return Float16Vector.fromArray(dsp.check(Float16.class), a, 0).check0(dsp);
}
default: break;
}
} else {
@ -794,6 +812,13 @@ abstract sealed class AbstractVector<E> extends Vector<E>
}
return DoubleVector.fromArray(dsp.check(double.class), a, 0).check0(dsp);
}
case LaneType.SK_FLOAT16: {
short[] a = new short[rlength];
for (int i = 0; i < limit; i++) {
a[i] = Float16.float16ToRawShortBits(Float16.valueOf((float) lanes[i]));
}
return Float16Vector.fromArray(dsp.check(Float16.class), a, 0).check0(dsp);
}
default: break;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,8 @@ enum LaneType {
BYTE(byte.class, Byte.class, byte[].class, 'I', -1, Byte.SIZE, byte.class),
SHORT(short.class, Short.class, short[].class, 'I', -1, Short.SIZE, short.class),
INT(int.class, Integer.class, int[].class, 'I', -1, Integer.SIZE, int.class),
LONG(long.class, Long.class, long[].class, 'I', -1, Long.SIZE, long.class);
LONG(long.class, Long.class, long[].class, 'I', -1, Long.SIZE, long.class),
FLOAT16(Float16.class, Short.class, short[].class, 'F', 11, Float16.SIZE, short.class);
LaneType(Class<?> elementType,
Class<?> genericElementType,
@ -66,7 +67,7 @@ enum LaneType {
// printName. If we do unsigned or vector or bit lane types,
// report that condition also.
this.typeChar = genericElementType.getSimpleName().charAt(0);
assert("FDBSIL".indexOf(typeChar) == ordinal()) : this;
assert("FDBSILS".charAt(ordinal()) == typeChar) : this;
this.carrierType = carrierType;
assert(carrierType.isPrimitive());
@ -181,7 +182,8 @@ enum LaneType {
SK_SHORT = 4,
SK_INT = 5,
SK_LONG = 6,
SK_LIMIT = 7;
SK_FLOAT16 = 7,
SK_LIMIT = 8;
/*package-private*/
@ForceInline
@ -278,5 +280,6 @@ enum LaneType {
assert(ofLaneTypeOrdinal(LT_SHORT) == SHORT);
assert(ofLaneTypeOrdinal(LT_INT) == INT);
assert(ofLaneTypeOrdinal(LT_LONG) == LONG);
assert(ofLaneTypeOrdinal(LT_FLOAT16) == FLOAT16);
}
}

View File

@ -4149,22 +4149,14 @@ public abstract sealed class ShortVector extends AbstractVector<Short>
/**
* {@inheritDoc} <!--workaround-->
*
* @implNote This method always throws
* {@code UnsupportedOperationException}, because there is no floating
* point type of the same size as {@code short}. The return type
* of this method is arbitrarily designated as
* {@code Vector<?>}. Future versions of this API may change the return
* type if additional floating point types become available.
*/
@ForceInline
@Override
public final
Vector<?>
Float16Vector
viewAsFloatingLanes() {
LaneType flt = LaneType.SHORT.asFloating();
// asFloating() will throw UnsupportedOperationException for the unsupported type short
throw new AssertionError("Cannot reach here");
return (Float16Vector) asVectorRaw(flt);
}
// ================================================

View File

@ -200,11 +200,11 @@ import java.util.Arrays;
* element type (such as access to element values in lanes, logical operations
* on values of integral elements types, or transcendental operations on values
* of floating point element types).
* There are six abstract subclasses of Vector corresponding to the supported set
* There are seven abstract subclasses of Vector corresponding to the supported set
* of element types, {@link ByteVector}, {@link ShortVector},
* {@link IntVector}, {@link LongVector}, {@link FloatVector}, and
* {@link DoubleVector}. Along with type-specific operations these classes
* support creation of vector values (instances of Vector).
* {@link IntVector}, {@link LongVector}, {@link FloatVector},
* {@link DoubleVector}, and {@link Float16Vector}. Along with type-specific
* operations these classes support creation of vector values (instances of Vector).
* They expose static constants corresponding to the supported species,
* and static methods on these types generally take a species as a parameter.
* For example,
@ -3826,6 +3826,19 @@ public abstract sealed class Vector<E> extends jdk.internal.vm.vector.VectorSupp
*/
public abstract LongVector reinterpretAsLongs();
/**
* Reinterprets this vector as a vector of the same shape
* and contents but a lane type of {@code Float16},
* where the lanes are assembled from successive bytes
* according to little-endian order.
* It is a convenience method for the expression
* {@code reinterpretShape(species().withLanes(Float16.class))}.
* It may be considered an inverse to {@link Vector#reinterpretAsBytes()}.
*
* @return a {@code Float16Vector} with the same shape and information content
*/
public abstract Float16Vector reinterpretAsFloat16s();
/**
* Reinterprets this vector as a vector of the same shape
* and contents but a lane type of {@code float},

View File

@ -64,8 +64,9 @@ import static jdk.internal.vm.vector.Utils.isNonCapturingLambda;
*
* <li>{@code bits(x)} &mdash; a function call which produces the
* underlying bits of the value {@code x}. If {@code x} is a floating
* point value, this is either {@code doubleToLongBits(x)} or
* {@code floatToIntBits(x)}. Otherwise, the value is just {@code x}.
* point value, this is {@code doubleToLongBits(x)},
* {@code floatToIntBits(x)}, or {@code float16ToShortBits(x)}.
* Otherwise, the value is just {@code x}.
*
* <li>{@code ESIZE} &mdash; the size in bytes of the operand type
*
@ -73,6 +74,26 @@ import static jdk.internal.vm.vector.Utils.isNonCapturingLambda;
*
* <li>{@code intVal}, {@code byteVal}, etc. &mdash; the operand of a
* conversion, with the indicated type
*
* <li id="type_letters">Single-letter type codes used in the names of
* {@linkplain Conversion conversion} operator tokens (for example
* {@link #B2D}, {@link #F2H}, {@link #H2F}, {@link #REINTERPRET_F2I},
* {@link #ZERO_EXTEND_B2L}) abbreviate lane types as follows:
* <table class="striped">
* <caption style="display:none">Lane type letter codes</caption>
* <thead>
* <tr><th scope="col">Letter</th><th scope="col">Lane type</th></tr>
* </thead>
* <tbody>
* <tr><th scope="row">{@code B}</th><td>{@code byte}</td></tr>
* <tr><th scope="row">{@code S}</th><td>{@code short}</td></tr>
* <tr><th scope="row">{@code I}</th><td>{@code int}</td></tr>
* <tr><th scope="row">{@code L}</th><td>{@code long}</td></tr>
* <tr><th scope="row">{@code F}</th><td>{@code float}</td></tr>
* <tr><th scope="row">{@code D}</th><td>{@code double}</td></tr>
* <tr><th scope="row">{@code H}</th><td>{@link Float16} ("half")</td></tr>
* </tbody>
* </table>
* </ul>
*
* <h2>Operations on floating point vectors</h2>
@ -307,13 +328,13 @@ public final class VectorOperators {
*/
public sealed interface Conversion<E,F> extends Operator {
/**
* The domain of this conversion, a primitive type.
* The domain of this conversion, a supported lane type.
* @return the domain of this conversion
*/
Class<E> domainType();
/**
* The range of this conversion, a primitive type.
* The range of this conversion, a supported lane type.
* @return the range of this conversion
*/
@Override
@ -657,6 +678,8 @@ public final class VectorOperators {
public static final Conversion<Byte,Long> B2L = convert("B2L", 'C', byte.class, long.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code byteVal} to {@code (short)byteVal}. */
public static final Conversion<Byte,Short> B2S = convert("B2S", 'C', byte.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code byteVal} to {@code (Float16)byteVal}. */
public static final Conversion<Byte,Float16> B2H = convert("B2H", 'C', byte.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code doubleVal} to {@code (byte)doubleVal}. */
public static final Conversion<Double,Byte> D2B = convert("D2B", 'C', double.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code doubleVal} to {@code (float)doubleVal}. */
@ -667,6 +690,8 @@ public final class VectorOperators {
public static final Conversion<Double,Long> D2L = convert("D2L", 'C', double.class, long.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code doubleVal} to {@code (short)doubleVal}. */
public static final Conversion<Double,Short> D2S = convert("D2S", 'C', double.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code doubleVal} to {@code (Float16)doubleVal}. */
public static final Conversion<Double,Float16> D2H = convert("D2H", 'C', double.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code floatVal} to {@code (byte)floatVal}. */
public static final Conversion<Float,Byte> F2B = convert("F2B", 'C', float.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code floatVal} to {@code (double)floatVal}. */
@ -677,6 +702,8 @@ public final class VectorOperators {
public static final Conversion<Float,Long> F2L = convert("F2L", 'C', float.class, long.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code floatVal} to {@code (short)floatVal}. */
public static final Conversion<Float,Short> F2S = convert("F2S", 'C', float.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code floatVal} to {@code (Float16)floatVal}. */
public static final Conversion<Float,Float16> F2H = convert("F2H", 'C', float.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code intVal} to {@code (byte)intVal}. */
public static final Conversion<Integer,Byte> I2B = convert("I2B", 'C', int.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code intVal} to {@code (double)intVal}. */
@ -687,6 +714,8 @@ public final class VectorOperators {
public static final Conversion<Integer,Long> I2L = convert("I2L", 'C', int.class, long.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code intVal} to {@code (short)intVal}. */
public static final Conversion<Integer,Short> I2S = convert("I2S", 'C', int.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code intVal} to {@code (Float16)intVal}. */
public static final Conversion<Integer,Float16> I2H = convert("I2H", 'C', int.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code longVal} to {@code (byte)longVal}. */
public static final Conversion<Long,Byte> L2B = convert("L2B", 'C', long.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code longVal} to {@code (double)longVal}. */
@ -697,6 +726,8 @@ public final class VectorOperators {
public static final Conversion<Long,Integer> L2I = convert("L2I", 'C', long.class, int.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code longVal} to {@code (short)longVal}. */
public static final Conversion<Long,Short> L2S = convert("L2S", 'C', long.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code longVal} to {@code (Float16)longVal}. */
public static final Conversion<Long,Float16> L2H = convert("L2H", 'C', long.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code shortVal} to {@code (byte)shortVal}. */
public static final Conversion<Short,Byte> S2B = convert("S2B", 'C', short.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code shortVal} to {@code (double)shortVal}. */
@ -707,6 +738,21 @@ public final class VectorOperators {
public static final Conversion<Short,Integer> S2I = convert("S2I", 'C', short.class, int.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code shortVal} to {@code (long)shortVal}. */
public static final Conversion<Short,Long> S2L = convert("S2L", 'C', short.class, long.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code shortVal} to {@code (Float16)shortVal}. */
public static final Conversion<Short,Float16> S2H = convert("S2H", 'C', short.class, Float16.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (byte)Float16Val}. */
public static final Conversion<Float16,Byte> H2B = convert("H2B", 'C', Float16.class, byte.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (short)Float16Val}. */
public static final Conversion<Float16,Short> H2S = convert("H2S", 'C', Float16.class, short.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (double)Float16Val}. */
public static final Conversion<Float16,Double> H2D = convert("H2D", 'C', Float16.class, double.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (float)Float16Val}. */
public static final Conversion<Float16,Float> H2F = convert("H2F", 'C', Float16.class, float.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (int)Float16Val}. */
public static final Conversion<Float16,Integer> H2I = convert("H2I", 'C', Float16.class, int.class, VO_KIND_CAST, VO_ALL);
/** Convert {@code Float16Val} to {@code (long)Float16Val}. */
public static final Conversion<Float16,Long> H2L = convert("H2L", 'C', Float16.class, long.class, VO_KIND_CAST, VO_ALL);
/** Reinterpret bits of {@code doubleVal} as {@code long}. As if by {@link Double#doubleToRawLongBits(double)} */
public static final Conversion<Double,Long> REINTERPRET_D2L = convert("REINTERPRET_D2L", 'R', double.class, long.class, VO_KIND_BITWISE, VO_ALL);
/** Reinterpret bits of {@code floatVal} as {@code int}. As if by {@link Float#floatToRawIntBits(float)} */

View File

@ -41,12 +41,65 @@ import static jdk.internal.vm.vector.VectorSupport.*;
import static jdk.incubator.vector.VectorIntrinsics.*;
import static jdk.incubator.vector.VectorOperators.*;
#if[FP16]
import jdk.incubator.vector.Float16;
import static jdk.incubator.vector.Float16.*;
import static java.lang.Float.*;
#end[FP16]
#warn This file is preprocessed before being compiled
/**
* A specialized {@link Vector} representing an ordered immutable sequence of
#if[FP16]
* 16-bit data values in the IEEE 754 binary16 format.
* <p>
* The scalar {@linkplain Float16Vector#elementType() element type} of {@code Float16Vector}
* is the class {@link Float16}, a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class holding 16-bit data in IEEE 754 binary16 format. However, the {@code Float16}
* class is not used by vector operations that accept scalar element values, or
* arrays of scalar element values. Instead, the primitive type {@code short} is
* used to explicitly hold 16-bit data in IEEE 754 binary16 format. For such operations
* it may be necessary to explicitly convert between floating-point values of {@code Float16}
* or {@code float} and values of {@code short} using the appropriate conversion
* methods on {@code Float16} or {@code Float}.
*
* <p>
* The specifications for operations on elements of this class are written as if
* {@code Float16} is a primitive floating-point type. An operation referencing a
* Java operator is mapped to a method on {@code Float16} that specifies that
* operator's semantics. For example, the semantics of the {@code +} operator,
* as referenced by {@link Vector#add(Vector)} and {@link VectorOperators#ADD},
* is mapped to the method {@link Float16#add(Float16, Float16)}.
* An operation referencing a method on {@link Math} is mapped to a method of the
* same name on {@code Float16}, if it exists. For example, {@link Math#fma} is
* mapped to {@link Float16#fma}, as referenced by {@link Float16Vector#fma(short, short)}
* and {@link VectorOperators#FMA}.
* Otherwise, if there is no equivalent method on {@code Float16}, the expression that is
* an invocation of a method on {@code Math} is mapped to an expression that converts
* the {@code Float16} arguments to {@code double} values or {@code float} values as
* required by the method's parameter types, invokes the method on {@code Math} with
* the converted values, and converts the resulting {@code double} or {@code float} value
* to a {@code Float16} value. For example, {@link Math#sin} is mapped to the expression
* {@code Float16.valueOf(Math.sin(a.doubleValue()))}, where {@code a} is the
* {@code Float16} lane value, as referenced by {@link VectorOperators#SIN}.
*
* @apiNote
* {@code Float16} is currently a value-based class and therefore cannot be optimally
* used as the scalar element type of vector operations until it becomes a value class
* that behaves similarly to the primitive type {@code short} and to arrays of {@code short}.
* For example, accessing {@code Float16} vectors using arrays requires those arrays be
* {@code short[]} arrays. Accessing vectors using memory segments requires, naturally,
* that consecutive 16-bits of memory hold 16-bit data values in the IEEE 754 binary16
* format.
* @see Float16
* @see Float16#float16ToRawShortBits(Float16)
* @see Float16#shortBitsToFloat16(short)
* @see Float#floatToFloat16(float)
* @see Float#float16ToFloat(short)
#else[FP16]
* {@code $type$} values.
#end[FP16]
*/
@SuppressWarnings("cast") // warning: redundant cast
public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtype$>
@ -62,7 +115,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
static final int FORBID_OPCODE_KIND = VO_ONLYFP;
#end[FP]
static final ValueLayout.Of$Type$ ELEMENT_LAYOUT = ValueLayout.JAVA_$TYPE$.withByteAlignment(1);
static final ValueLayout.Of$ElemLayout$ ELEMENT_LAYOUT = ValueLayout.JAVA_$TYPE$.withByteAlignment(1);
static final int LANE_TYPE_ORDINAL = $laneType$;
@ -158,7 +211,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/*package-private*/
interface FUnOp {
$type$ apply(int i, $type$ a);
$fallbacktype$ apply(int i, $fallbacktype$ a);
}
/*package-private*/
@ -170,7 +223,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] vec = vec();
$type$[] res = new $type$[length()];
for (int i = 0; i < res.length; i++) {
#if[FP16]
res[i] = floatToFloat16(f.apply(i, float16ToFloat(vec[i])));
#else[FP16]
res[i] = f.apply(i, vec[i]);
#end[FP16]
}
return vectorFactory(res);
}
@ -190,16 +247,60 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] res = new $type$[length()];
boolean[] mbits = ((AbstractMask<$Boxtype$>)m).getBits();
for (int i = 0; i < res.length; i++) {
#if[FP16]
res[i] = mbits[i] ? floatToFloat16(f.apply(i, float16ToFloat(vec[i]))) : vec[i];
#else[FP16]
res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
#end[FP16]
}
return vectorFactory(res);
}
#if[FP16]
/*package-private*/
interface FUnRawOp {
$type$ apply(int i, $type$ a);
}
/*package-private*/
abstract
$abstractvectortype$ uRawOp(FUnRawOp f);
@ForceInline
final
$abstractvectortype$ uRawOpTemplate(FUnRawOp f) {
$type$[] vec = vec();
$type$[] res = new $type$[length()];
for (int i = 0; i < res.length; i++) {
res[i] = f.apply(i, vec[i]);
}
return vectorFactory(res);
}
/*package-private*/
abstract
$abstractvectortype$ uRawOp(VectorMask<$Boxtype$> m,
FUnRawOp f);
@ForceInline
final
$abstractvectortype$ uRawOpTemplate(VectorMask<$Boxtype$> m,
FUnRawOp f) {
if (m == null) {
return uRawOpTemplate(f);
}
$type$[] vec = vec();
$type$[] res = new $type$[length()];
boolean[] mbits = ((AbstractMask<$Boxtype$>)m).getBits();
for (int i = 0; i < res.length; i++) {
res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
}
return vectorFactory(res);
}
#end[FP16]
// Binary operator
/*package-private*/
interface FBinOp {
$type$ apply(int i, $type$ a, $type$ b);
$fallbacktype$ apply(int i, $fallbacktype$ a, $fallbacktype$ b);
}
/*package-private*/
@ -214,7 +315,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] vec1 = this.vec();
$type$[] vec2 = (($abstractvectortype$)o).vec();
for (int i = 0; i < res.length; i++) {
#if[FP16]
res[i] = floatToFloat16(f.apply(i, float16ToFloat(vec1[i]), float16ToFloat(vec2[i])));
#else[FP16]
res[i] = f.apply(i, vec1[i], vec2[i]);
#end[FP16]
}
return vectorFactory(res);
}
@ -237,7 +342,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] vec2 = (($abstractvectortype$)o).vec();
boolean[] mbits = ((AbstractMask<$Boxtype$>)m).getBits();
for (int i = 0; i < res.length; i++) {
#if[FP16]
res[i] = mbits[i] ? floatToFloat16(f.apply(i, float16ToFloat(vec1[i]), float16ToFloat(vec2[i]))) : vec1[i];
#else[FP16]
res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
#end[FP16]
}
return vectorFactory(res);
}
@ -310,7 +419,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] vec = vec();
boolean[] mbits = ((AbstractMask<$Boxtype$>)m).getBits();
for (int i = 0; i < vec.length; i++) {
#if[FP16]
v = mbits[i] ? floatToFloat16(f.apply(i, float16ToFloat(v), float16ToFloat(vec[i]))) : v;
#else[FP16]
v = mbits[i] ? f.apply(i, v, vec[i]) : v;
#end[FP16]
}
return v;
}
@ -320,7 +433,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$ rOpTemplate($type$ v, FBinOp f) {
$type$[] vec = vec();
for (int i = 0; i < vec.length; i++) {
#if[FP16]
v = floatToFloat16(f.apply(i, float16ToFloat(v), float16ToFloat(vec[i])));
#else[FP16]
v = f.apply(i, v, vec[i]);
#end[FP16]
}
return v;
}
@ -516,13 +633,21 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/*package-private*/
@ForceInline
static long toBits($type$ e) {
#if[FP16]
return e;
#else[FP16]
return {#if[FP]? $Type$.$type$ToRaw$Bitstype$Bits(e): e};
#end[FP16]
}
/*package-private*/
@ForceInline
static $type$ fromBits(long bits) {
#if[FP16]
return (short)bits;
#else[FP16]
return {#if[FP]?$Type$.$bitstype$BitsTo$Type$}(($bitstype$)bits);
#end[FP16]
}
static $abstractvectortype$ expandHelper(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
@ -562,7 +687,12 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] vecPayload2 = (($abstractvectortype$)src1).vec();
$type$[] vecPayload3 = (($abstractvectortype$)src2).vec();
for (int i = 0; i < vlen; i++) {
#if[FP16]
int index = shortBitsToFloat16(vecPayload1[i]).intValue();
int wrapped_index = VectorIntrinsics.wrapToRange(index, 2 * vlen);
#else[FP16]
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
#end[FP16]
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return (($abstractvectortype$)src1).vectorFactory(res);
@ -594,7 +724,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$Type$Species vsp = ($Type$Species) species;
#if[FP]
return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(),
toBits(0.0f), MODE_BROADCAST, vsp,
toBits({#if[FP16]?(short) 0:0.0f}), MODE_BROADCAST, vsp,
((bits_, s_) -> s_.rvOp(i -> bits_)));
#else[FP]
return VectorSupport.fromBitsCoerced(vsp.vectorType(), LANE_TYPE_ORDINAL, species.length(),
@ -784,27 +914,32 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
private static UnaryOperation<$abstractvectortype$, VectorMask<$Boxtype$>> unaryOperations(int opc_) {
switch (opc_) {
#if[FP16]
case VECTOR_OP_NEG: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) -a);
v0.uOp(m, (i, a) -> Float16.negate(Float16.valueOf(a)).floatValue());
#else[FP16]
case VECTOR_OP_NEG: return (v0, m) ->
v0.uOp(m, (i, a) -> ($fallbacktype$) -a);
#end[FP16]
case VECTOR_OP_ABS: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.abs(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.abs(a));
#if[!FP]
#if[intOrLong]
case VECTOR_OP_BIT_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) $Boxtype$.bitCount(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) $Boxtype$.bitCount(a));
case VECTOR_OP_TZ_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) $Boxtype$.numberOfTrailingZeros(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) $Boxtype$.numberOfTrailingZeros(a));
case VECTOR_OP_LZ_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) $Boxtype$.numberOfLeadingZeros(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) $Boxtype$.numberOfLeadingZeros(a));
case VECTOR_OP_REVERSE: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) $Boxtype$.reverse(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) $Boxtype$.reverse(a));
#else[intOrLong]
case VECTOR_OP_BIT_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) bitCount(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) bitCount(a));
case VECTOR_OP_TZ_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) numberOfTrailingZeros(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) numberOfTrailingZeros(a));
case VECTOR_OP_LZ_COUNT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) numberOfLeadingZeros(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) numberOfLeadingZeros(a));
case VECTOR_OP_REVERSE: return (v0, m) ->
v0.uOp(m, (i, a) -> reverse(a));
#end[intOrLong]
@ -814,43 +949,47 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
v0.uOp(m, (i, a) -> a);
#else[byte]
case VECTOR_OP_REVERSE_BYTES: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) $Boxtype$.reverseBytes(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) $Boxtype$.reverseBytes(a));
#end[byte]
#end[BITWISE]
#end[!FP]
#if[FP]
case VECTOR_OP_SIN: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.sin(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.sin(a));
case VECTOR_OP_COS: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.cos(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.cos(a));
case VECTOR_OP_TAN: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.tan(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.tan(a));
case VECTOR_OP_ASIN: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.asin(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.asin(a));
case VECTOR_OP_ACOS: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.acos(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.acos(a));
case VECTOR_OP_ATAN: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.atan(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.atan(a));
case VECTOR_OP_EXP: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.exp(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.exp(a));
case VECTOR_OP_LOG: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.log(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.log(a));
case VECTOR_OP_LOG10: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.log10(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.log10(a));
case VECTOR_OP_SQRT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.sqrt(a));
#if[FP16]
v0.uOp(m, (i, a) -> Float16.sqrt(Float16.valueOf(a)).floatValue());
#else[FP16]
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.sqrt(a));
#end[FP16]
case VECTOR_OP_CBRT: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.cbrt(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.cbrt(a));
case VECTOR_OP_SINH: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.sinh(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.sinh(a));
case VECTOR_OP_COSH: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.cosh(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.cosh(a));
case VECTOR_OP_TANH: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.tanh(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.tanh(a));
case VECTOR_OP_EXPM1: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.expm1(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.expm1(a));
case VECTOR_OP_LOG1P: return (v0, m) ->
v0.uOp(m, (i, a) -> ($type$) Math.log1p(a));
v0.uOp(m, (i, a) -> ($fallbacktype$) Math.log1p(a));
#end[FP]
default: return null;
}
@ -996,46 +1135,46 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
private static BinaryOperation<$abstractvectortype$, VectorMask<$Boxtype$>> binaryOperations(int opc_) {
switch (opc_) {
case VECTOR_OP_ADD: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a + b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a + b));
case VECTOR_OP_SUB: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a - b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a - b));
case VECTOR_OP_MUL: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a * b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a * b));
case VECTOR_OP_DIV: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a / b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a / b));
case VECTOR_OP_MAX: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)Math.max(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)Math.max(a, b));
case VECTOR_OP_MIN: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)Math.min(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)Math.min(a, b));
#if[BITWISE]
case VECTOR_OP_AND: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a & b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a & b));
case VECTOR_OP_OR: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a | b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a | b));
case VECTOR_OP_XOR: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(a ^ b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(a ^ b));
case VECTOR_OP_LSHIFT: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> ($type$)(a << n));
v0.bOp(v1, vm, (i, a, n) -> ($fallbacktype$)(a << n));
case VECTOR_OP_RSHIFT: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> ($type$)(a >> n));
v0.bOp(v1, vm, (i, a, n) -> ($fallbacktype$)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, n) -> ($type$)((a & LSHR_SETUP_MASK) >>> n));
v0.bOp(v1, vm, (i, a, n) -> ($fallbacktype$)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1, vm) ->
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));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)VectorMath.maxUnsigned(a, b));
case VECTOR_OP_UMIN: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)VectorMath.minUnsigned(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)VectorMath.minUnsigned(a, b));
case VECTOR_OP_SADD: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturating(a, b)));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(VectorMath.addSaturating(a, b)));
case VECTOR_OP_SSUB: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturating(a, b)));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(VectorMath.subSaturating(a, b)));
case VECTOR_OP_SUADD: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.addSaturatingUnsigned(a, b)));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(VectorMath.addSaturatingUnsigned(a, b)));
case VECTOR_OP_SUSUB: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$)(VectorMath.subSaturatingUnsigned(a, b)));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$)(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));
@ -1045,13 +1184,17 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
#end[BITWISE]
#if[FP]
case VECTOR_OP_OR: return (v0, v1, vm) ->
#if[FP16]
v0.bOp(v1, vm, (i, a, b) -> FloatVector.fromBits(FloatVector.toBits(a) | FloatVector.toBits(b)));
#else[FP16]
v0.bOp(v1, vm, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
#end[FP16]
case VECTOR_OP_ATAN2: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$) Math.atan2(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$) Math.atan2(a, b));
case VECTOR_OP_POW: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$) Math.pow(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$) Math.pow(a, b));
case VECTOR_OP_HYPOT: return (v0, v1, vm) ->
v0.bOp(v1, vm, (i, a, b) -> ($type$) Math.hypot(a, b));
v0.bOp(v1, vm, (i, a, b) -> ($fallbacktype$) Math.hypot(a, b));
#end[FP]
default: return null;
}
@ -1147,13 +1290,13 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
public final
$abstractvectortype$ lanewise(VectorOperators.Binary op,
long e) {
$type$ e1 = ($type$) e;
$type$ e1 = {#if[FP16]?float16ToRawShortBits(Float16.valueOf(e)):($type$) e};
#if[BITWISE]
if ((long)e1 != e
// allow shift ops to clip down their int parameters
&& !(opKind(op, VO_SHIFT) && (int)e1 == e)) {
#else[BITWISE]
if ((long)e1 != e) {
if ({#if[FP16]?shortBitsToFloat16(e1).longValue():(long)e1} != e) {
#end[BITWISE]
vspecies().checkValue(e); // for exception
}
@ -1174,13 +1317,13 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
public final
$abstractvectortype$ lanewise(VectorOperators.Binary op,
long e, VectorMask<$Boxtype$> m) {
$type$ e1 = ($type$) e;
$type$ e1 = {#if[FP16]?float16ToRawShortBits(Float16.valueOf(e)):($type$) e};
#if[BITWISE]
if ((long)e1 != e
// allow shift ops to clip down their int parameters
&& !(opKind(op, VO_SHIFT) && (int)e1 == e)) {
#else[BITWISE]
if ((long)e1 != e) {
if ({#if[FP16]?shortBitsToFloat16(e1).longValue():(long)e1} != e) {
#end[BITWISE]
vspecies().checkValue(e); // for exception
}
@ -1255,12 +1398,12 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
// since our lane types are first-class types, not just dressed
// up ints.
private static final int SHIFT_MASK = ($Boxtype$.SIZE - 1);
#if[byteOrShort]
#if[byteOrStrictShort]
// Also simulate >>> on sub-word variables with a mask.
private static final int LSHR_SETUP_MASK = ((1 << $Boxtype$.SIZE) - 1);
#else[byteOrShort]
#else[byteOrStrictShort]
private static final $type$ LSHR_SETUP_MASK = -1;
#end[byteOrShort]
#end[byteOrStrictShort]
#end[BITWISE]
// Ternary lanewise support
@ -1363,7 +1506,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
switch (opc_) {
#if[FP]
case VECTOR_OP_FMA: return (v0, v1_, v2_, m) ->
#if[FP16]
v0.tOp(v1_, v2_, m, (i, a, b, c) -> float16ToRawShortBits(Float16.fma(shortBitsToFloat16(a), shortBitsToFloat16(b), shortBitsToFloat16(c))));
#else[FP16]
v0.tOp(v1_, v2_, m, (i, a, b, c) -> Math.fma(a, b, c));
#end[FP16]
#end[FP]
default: return null;
}
@ -2392,7 +2539,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
// first kill the sign:
bits = bits.and($Boxbitstype$.MAX_VALUE);
// next find the bit pattern for infinity:
$bitstype$ infbits = ($bitstype$) toBits($Boxtype$.POSITIVE_INFINITY);
$bitstype$ infbits = ($bitstype$) toBits({#if[FP16]?float16ToRawShortBits($Boxtype$.POSITIVE_INFINITY):$Boxtype$.POSITIVE_INFINITY});
// now compare:
if (op == IS_FINITE) {
m = bits.compare(LT, infbits);
@ -2446,7 +2593,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
// first kill the sign:
bits = bits.and($Boxbitstype$.MAX_VALUE);
// next find the bit pattern for infinity:
$bitstype$ infbits = ($bitstype$) toBits($Boxtype$.POSITIVE_INFINITY);
$bitstype$ infbits = ($bitstype$) toBits({#if[FP16]?float16ToRawShortBits($Boxtype$.POSITIVE_INFINITY):$Boxtype$.POSITIVE_INFINITY});
// now compare:
if (op == IS_FINITE) {
m = bits.compare(LT, infbits, m);
@ -2517,14 +2664,23 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
@ForceInline
private static boolean compareWithOp(int cond, $type$ a, $type$ b) {
private static boolean compareWithOp(int cond, $carriertype$ a, $carriertype$ b) {
return switch (cond) {
#if[FP16]
case BT_eq -> Float.float16ToFloat(a) == Float.float16ToFloat(b);
case BT_ne -> Float.float16ToFloat(a) != Float.float16ToFloat(b);
case BT_lt -> Float.float16ToFloat(a) < Float.float16ToFloat(b);
case BT_le -> Float.float16ToFloat(a) <= Float.float16ToFloat(b);
case BT_gt -> Float.float16ToFloat(a) > Float.float16ToFloat(b);
case BT_ge -> Float.float16ToFloat(a) >= Float.float16ToFloat(b);
#else[FP16]
case BT_eq -> a == b;
case BT_ne -> a != b;
case BT_lt -> a < b;
case BT_le -> a <= b;
case BT_gt -> a > b;
case BT_ge -> a >= b;
#end[FP16]
#if[!FP]
case BT_ult -> $Boxtype$.compareUnsigned(a, b) < 0;
case BT_ule -> $Boxtype$.compareUnsigned(a, b) <= 0;
@ -2665,7 +2821,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
// and multiply.
$abstractvectortype$ iota = s.iota();
$type$ sc = ($type$) scale_;
return v.add(sc == 1 ? iota : iota.mul(sc));
return v.add(sc == 1 ? iota : iota.mul({#if[FP16]?float16ToRawShortBits(Float16.valueOf(sc)):sc}));
});
}
@ -2875,7 +3031,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
return VectorSupport.rearrangeOp(
getClass(), shuffletype, null, laneTypeOrdinal(), length(),
this, shuffle, null,
(v1, s_, m_) -> v1.uOp((i, a) -> {
(v1, s_, m_) -> v1.{#if[FP16]?uRawOp:uOp}((i, a) -> {
int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length());
return v1.lane(ei);
}));
@ -2902,7 +3058,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
return VectorSupport.rearrangeOp(
getClass(), shuffletype, masktype, laneTypeOrdinal(), length(),
this, shuffle, m,
(v1, s_, m_) -> v1.uOp((i, a) -> {
(v1, s_, m_) -> v1.{#if[FP16]?uRawOp:uOp}((i, a) -> {
int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length());
return !m_.laneIsSet(i) ? 0 : v1.lane(ei);
}));
@ -2928,7 +3084,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
VectorSupport.rearrangeOp(
getClass(), shuffletype, null, laneTypeOrdinal(), length(),
this, shuffle, null,
(v0, s_, m_) -> v0.uOp((i, a) -> {
(v0, s_, m_) -> v0.{#if[FP16]?uRawOp:uOp}((i, a) -> {
int ei = Integer.remainderUnsigned(s_.laneSource(i), v0.length());
return v0.lane(ei);
}));
@ -2936,7 +3092,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
VectorSupport.rearrangeOp(
getClass(), shuffletype, null, laneTypeOrdinal(), length(),
v, shuffle, null,
(v1, s_, m_) -> v1.uOp((i, a) -> {
(v1, s_, m_) -> v1.{#if[FP16]?uRawOp:uOp}((i, a) -> {
int ei = Integer.remainderUnsigned(s_.laneSource(i), v1.length());
return v1.lane(ei);
}));
@ -2963,6 +3119,9 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
final <F>
VectorShuffle<F> toShuffle(AbstractSpecies<F> dsp, boolean wrap) {
assert(dsp.elementSize() == vspecies().elementSize());
#if[FP16]
ShortVector idx = convert(VectorOperators.H2S, 0).reinterpretAsShorts();
#end[FP16]
#if[float]
IntVector idx = convert(VectorOperators.F2I, 0).reinterpretAsInts();
#end[float]
@ -2983,7 +3142,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* {@inheritDoc} <!--workaround-->
* @since 19
* @since {#if[FP16]?27:19}
*/
@Override
public abstract
@ -3002,7 +3161,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* {@inheritDoc} <!--workaround-->
* @since 19
* @since {#if[FP16]?27:19}
*/
@Override
public abstract
@ -3199,7 +3358,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
*
* This is a lane-wise ternary operation which applies an operation
* conforming to the specification of
* {@link Math#fma($type$,$type$,$type$) Math.fma(a,b,c)}
* {@link Math#fma($fallbacktype$,$fallbacktype$,$fallbacktype$) Math.fma(a,b,c)}
* to each lane.
#if[intOrFloat]
* The operation is adapted to cast the operands and the result,
@ -3240,7 +3399,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
*
* This is a lane-wise ternary operation which applies an operation
* conforming to the specification of
* {@link Math#fma($type$,$type$,$type$) Math.fma(a,b,c)}
* {@link Math#fma($fallbacktype$,$fallbacktype$,$fallbacktype$) Math.fma(a,b,c)}
* to each lane.
#if[intOrFloat]
* The operation is adapted to cast the operands and the result,
@ -3447,13 +3606,13 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
private static ReductionOperation<$abstractvectortype$, VectorMask<$Boxtype$>> reductionOperations(int opc_) {
switch (opc_) {
case VECTOR_OP_ADD: return (v, m) ->
toBits(v.rOp(($type$)0, m, (i, a, b) -> ($type$)(a + b)));
toBits(v.rOp(($type$)0, m, (i, a, b) -> ($fallbacktype$)(a + b)));
case VECTOR_OP_MUL: return (v, m) ->
toBits(v.rOp(($type$)1, m, (i, a, b) -> ($type$)(a * b)));
toBits(v.rOp(($type$){#if[FP16]?floatToFloat16(1.0f):1}, m, (i, a, b) -> ($fallbacktype$)(a * b)));
case VECTOR_OP_MIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) Math.min(a, b)));
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($fallbacktype$) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) Math.max(a, b)));
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($fallbacktype$) Math.max(a, b)));
#if[!FP]
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> ($type$) VectorMath.minUnsigned(a, b)));
@ -3475,8 +3634,8 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
#if[FP]
private static final $type$ MIN_OR_INF = $Boxtype$.NEGATIVE_INFINITY;
private static final $type$ MAX_OR_INF = $Boxtype$.POSITIVE_INFINITY;
private static final $type$ MIN_OR_INF = {#if[FP16]?float16ToRawShortBits($Boxtype$.NEGATIVE_INFINITY):$Boxtype$.NEGATIVE_INFINITY};
private static final $type$ MAX_OR_INF = {#if[FP16]?float16ToRawShortBits($Boxtype$.POSITIVE_INFINITY):$Boxtype$.POSITIVE_INFINITY};
#else[FP]
private static final $type$ MIN_OR_INF = $Boxtype$.MIN_VALUE;
private static final $type$ MAX_OR_INF = $Boxtype$.MAX_VALUE;
@ -3656,14 +3815,18 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] a = toArray();
double[] res = new double[a.length];
for (int i = 0; i < a.length; i++) {
res[i] = (double) a[i];
res[i] = (double) {#if[FP16]?shortBitsToFloat16(a[i]).doubleValue():a[i]};
}
return res;
}
#end[double]
/**
#if[FP16]
* Loads a vector from an array of type {@code $type$[]} holding IEEE 754 binary16 values
#else[FP16]
* Loads a vector from an array of type {@code $type$[]}
#end[FP16]
* starting at an offset.
* For each vector lane, where {@code N} is the vector lane index, the
* array element at index {@code offset + N} is placed into the
@ -3687,7 +3850,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
/**
#if[FP16]
* Loads a vector from an array of type {@code $type$[]} holding IEEE 754 binary16 values
#else[FP16]
* Loads a vector from an array of type {@code $type$[]}
#end[FP16]
* starting at an offset and using a mask.
* Lanes where the mask is unset are filled with the default
* value of {@code $type$} ({#if[FP]?positive }zero).
@ -3724,7 +3891,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* Gathers a new vector composed of elements from an array of type
#if[FP16]
* {@code $type$[]} holding IEEE 754 binary16 values,
#else[FP16]
* {@code $type$[]},
#end[FP16]
* using indexes obtained by adding a fixed {@code offset} to a
* series of secondary offsets from an <em>index map</em>.
* The index map is a contiguous sequence of {@code VLENGTH}
@ -3869,7 +4040,11 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* Gathers a new vector composed of elements from an array of type
#if[FP16]
* {@code $type$[]} holding IEEE 754 binary16 values,
#else[FP16]
* {@code $type$[]},
#end[FP16]
* under the control of a mask, and
* using indexes obtained by adding a fixed {@code offset} to a
* series of secondary offsets from an <em>index map</em>.
@ -3918,7 +4093,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
}
#if[short]
#if[strictShort]
/**
* Loads a vector from an array of type {@code char[]}
* starting at an offset.
@ -4069,7 +4244,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$Type$Species vsp = ($Type$Species) species;
return vsp.vOp(m, n -> (short) a[offset + indexMap[mapOffset + n]]);
}
#end[short]
#end[strictShort]
#if[byte]
/**
@ -4258,7 +4433,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
* for any lane {@code N} in the vector
* @throws IllegalStateException if the memory segment's session is not alive,
* or if access occurs from a thread other than the thread owning the session.
* @since 19
* @since {#if[FP16]?27:19}
*/
@ForceInline
public static
@ -4317,7 +4492,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
* where the mask is set
* @throws IllegalStateException if the memory segment's session is not alive,
* or if access occurs from a thread other than the thread owning the session.
* @since 19
* @since {#if[FP16]?27:19}
*/
@ForceInline
public static
@ -4555,7 +4730,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
#end[byteOrShort]
#if[short]
#if[strictShort]
/**
* Stores this vector into an array of type {@code char[]}
* starting at an offset.
@ -4711,7 +4886,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
arr[off + j] = (char) e;
});
}
#end[short]
#end[strictShort]
#if[byte]
/**
@ -4886,7 +5061,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* {@inheritDoc} <!--workaround-->
* @since 19
* @since {#if[FP16]?27:19}
*/
@Override
@ForceInline
@ -4903,7 +5078,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* {@inheritDoc} <!--workaround-->
* @since 19
* @since {#if[FP16]?27:19}
*/
@Override
@ForceInline
@ -5100,7 +5275,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
#end[byteOrShort]
#if[short]
#if[strictShort]
/*package-private*/
abstract
$abstractvectortype$ fromCharArray0(char[] a, int offset);
@ -5132,7 +5307,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
(arr, off, s, vm) -> s.ldOp(arr, (int) off, vm,
(arr_, off_, i) -> (short) arr_[off_ + i]));
}
#end[short]
#end[strictShort]
#if[byte]
/*package-private*/
@ -5346,7 +5521,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
});
}
#if[short]
#if[strictShort]
/*package-private*/
abstract
void intoCharArray0(char[] a, int offset, VectorMask<$Boxtype$> m);
@ -5364,7 +5539,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
-> v.stOp(arr, (int) off, vm,
(arr_, off_, i, e) -> arr_[off_ + i] = (char) e));
}
#end[short]
#end[strictShort]
// End of low-level memory operations.
@ -5423,7 +5598,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
}
#if[short]
#if[strictShort]
static final int ARRAY_CHAR_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_CHAR_INDEX_SCALE);
static final long ARRAY_CHAR_BASE =
@ -5433,7 +5608,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
static long charArrayAddress(char[] a, int index) {
return ARRAY_CHAR_BASE + (((long)index) << ARRAY_CHAR_SHIFT);
}
#end[short]
#end[strictShort]
#if[byte]
static final int ARRAY_BOOLEAN_SHIFT =
@ -5490,7 +5665,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/**
* {@inheritDoc} <!--workaround-->
#if[byteOrShort]
#if[byte]
*
* @implNote This method always throws
* {@code UnsupportedOperationException}, because there is no floating
@ -5498,23 +5673,27 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
* of this method is arbitrarily designated as
* {@code Vector<?>}. Future versions of this API may change the return
* type if additional floating point types become available.
#end[byteOrShort]
#end[byte]
*/
@ForceInline
@Override
public final
{#if[byteOrShort]?Vector<?>:$Fptype$Vector}
#if[FP16]
$Type$Vector
#else[FP16]
{#if[byte]?Vector<?>:$Fptype$Vector}
#end[FP16]
viewAsFloatingLanes() {
#if[FP]
return this;
#else[FP]
LaneType flt = LaneType.$TYPE$.asFloating();
#if[!byteOrShort]
#if[!byte]
return ($Fptype$Vector) asVectorRaw(flt);
#else[!byteOrShort]
#else[!byte]
// asFloating() will throw UnsupportedOperationException for the unsupported type $type$
throw new AssertionError("Cannot reach here");
#end[!byteOrShort]
#end[!byte]
#end[FP]
}
@ -5588,7 +5767,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
Class<? extends AbstractMask<$Boxtype$>> maskType,
Class<? extends AbstractShuffle<$Boxtype$>> shuffleType,
Function<Object, $abstractvectortype$> vectorFactory) {
super(shape, LaneType.of($type$.class),
super(shape, LaneType.of($elemtype$.class),
vectorType, maskType, shuffleType,
vectorFactory);
assert(this.elementSize() == $Boxtype$.SIZE);
@ -5599,7 +5778,7 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
@Override
@ForceInline
public final Class<$Boxtype$> elementType() {
return $type$.class;
return $elemtype$.class;
}
@Override
@ -5656,8 +5835,8 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
return value;
#else[long]
// Do the conversion, and then test it for failure.
$type$ e = ($type$) value;
if ((long) e != value) {
$type$ e = {#if[FP16]?float16ToRawShortBits(Float16.valueOf(value)):($type$) value};
if ({#if[FP16]?shortBitsToFloat16(e).longValue():(long) e} != value) {
throw badElementBits(value, e);
}
return toBits(e);
@ -5667,10 +5846,18 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
/*package-private*/
@ForceInline
static long toIntegralChecked($type$ e, boolean convertToInt) {
#if[FP16]
float ef = shortBitsToFloat16(e).floatValue();
long value = convertToInt ? (int) ef : (long) ef;
if ((float) value != ef) {
throw badArrayBits(e, convertToInt, value);
}
#else[FP16]
long value = convertToInt ? (int) e : (long) e;
if (($type$) value != e) {
throw badArrayBits(e, convertToInt, value);
}
#end[FP16]
return value;
}
@ -5682,11 +5869,19 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
$type$[] va = new $type$[laneCount()];
for (int i = 0; i < va.length; i++) {
int lv = values[i];
#if[FP16]
$type$ v = float16ToRawShortBits(Float16.valueOf(lv));
va[i] = v;
if (Float16.valueOf(lv).intValue() != lv) {
throw badElementBits(lv, v);
}
#else[FP16]
$type$ v = ($type$) lv;
va[i] = v;
if ((int)v != lv) {
throw badElementBits(lv, v);
}
#end[FP16]
}
return dummyVector().fromArray0(va, 0);
}
@ -5859,10 +6054,17 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
}
/**
#if[FP16]
* Finds a species for an element type of {@code $elemtype$} and shape.
*
* @param s the shape
* @return a species for an element type of {@code $elemtype$} and shape
#else[FP16]
* Finds a species for an element type of {@code $type$} and shape.
*
* @param s the shape
* @return a species for an element type of {@code $type$} and shape
#end[FP16]
* @throws IllegalArgumentException if no such species exists for the shape
*/
static $Type$Species species(VectorShape s) {
@ -5922,6 +6124,6 @@ public abstract sealed class $abstractvectortype$ extends AbstractVector<$Boxtyp
* A preferred species is a species of maximal bit-size for the platform.
*/
public static final VectorSpecies<$Boxtype$> SPECIES_PREFERRED
= ($Type$Species) VectorSpecies.ofPreferred($type$.class);
= ($Type$Species) VectorSpecies.ofPreferred($elemtype$.class);
}

View File

@ -59,7 +59,7 @@ final class $vectortype$ extends $abstractvectortype$ {
static final Class<$Carriertype$> CTYPE = $carriertype$.class; // carrier type used by the JVM
static final Class<$Boxtype$> ETYPE = $type$.class; // used by the JVM
static final Class<$Boxtype$> ETYPE = $elemtype$.class; // used by the JVM
$vectortype$($type$[] v) {
super(v);
@ -95,7 +95,7 @@ final class $vectortype$ extends $abstractvectortype$ {
@ForceInline
@Override
public final Class<$Boxtype$> elementType() { return $type$.class; }
public final Class<$Boxtype$> elementType() { return $elemtype$.class; }
@ForceInline
final Class<$Carriertype$> carrierType() { return CTYPE; }
@ -216,6 +216,20 @@ final class $vectortype$ extends $abstractvectortype$ {
super.uOpTemplate(($masktype$)m, f); // specialize
}
#if[FP16]
@ForceInline
final @Override
$vectortype$ uRawOp(FUnRawOp f) {
return ($vectortype$) super.uRawOpTemplate(f); // specialize
}
@ForceInline
final @Override
$vectortype$ uRawOp(VectorMask<$Boxtype$> m, FUnRawOp f) {
return ($vectortype$)
super.uRawOpTemplate(($masktype$)m, f); // specialize
}
#end[FP16]
// Binary operator
@ForceInline
@ -574,6 +588,24 @@ final class $vectortype$ extends $abstractvectortype$ {
case 13: bits = laneHelper(13); break;
case 14: bits = laneHelper(14); break;
case 15: bits = laneHelper(15); break;
#if[!16L]
case 16: bits = laneHelper(16); break;
case 17: bits = laneHelper(17); break;
case 18: bits = laneHelper(18); break;
case 19: bits = laneHelper(19); break;
case 20: bits = laneHelper(20); break;
case 21: bits = laneHelper(21); break;
case 22: bits = laneHelper(22); break;
case 23: bits = laneHelper(23); break;
case 24: bits = laneHelper(24); break;
case 25: bits = laneHelper(25); break;
case 26: bits = laneHelper(26); break;
case 27: bits = laneHelper(27); break;
case 28: bits = laneHelper(28); break;
case 29: bits = laneHelper(29); break;
case 30: bits = laneHelper(30); break;
case 31: bits = laneHelper(31); break;
#end[!16L]
#end[!8L]
#end[!4L]
#end[!2L]
@ -586,7 +618,7 @@ final class $vectortype$ extends $abstractvectortype$ {
}
$bitstype$ bits = laneHelper(i);
#end[!Max]
return $Type$.$bitstype$BitsTo$Fptype$(bits);
return {#if[FP16]?bits:$Type$.$bitstype$BitsTo$Fptype$(bits)};
}
@ForceInline
@ -596,7 +628,7 @@ final class $vectortype$ extends $abstractvectortype$ {
this, i,
(vec, ix) -> {
$type$[] vecarr = vec.vec();
return (long)$Type$.$type$ToRaw$Bitstype$Bits(vecarr[ix]);
return {#if[FP16]?vecarr[ix]:(long)$Type$.$type$ToRaw$Bitstype$Bits(vecarr[ix])};
});
}
@ -625,6 +657,24 @@ final class $vectortype$ extends $abstractvectortype$ {
case 13: return withLaneHelper(13, e);
case 14: return withLaneHelper(14, e);
case 15: return withLaneHelper(15, e);
#if[!16L]
case 16: return withLaneHelper(16, e);
case 17: return withLaneHelper(17, e);
case 18: return withLaneHelper(18, e);
case 19: return withLaneHelper(19, e);
case 20: return withLaneHelper(20, e);
case 21: return withLaneHelper(21, e);
case 22: return withLaneHelper(22, e);
case 23: return withLaneHelper(23, e);
case 24: return withLaneHelper(24, e);
case 25: return withLaneHelper(25, e);
case 26: return withLaneHelper(26, e);
case 27: return withLaneHelper(27, e);
case 28: return withLaneHelper(28, e);
case 29: return withLaneHelper(29, e);
case 30: return withLaneHelper(30, e);
case 31: return withLaneHelper(31, e);
#end[!16L]
#end[!8L]
#end[!4L]
#end[!2L]
@ -643,10 +693,10 @@ final class $vectortype$ extends $abstractvectortype$ {
public $vectortype$ withLaneHelper(int i, $type$ e) {
return VectorSupport.insert(
VCLASS, LANE_TYPE_ORDINAL, VLENGTH,
this, i, (long)$Type$.$type$ToRaw$Bitstype$Bits(e),
this, i, (long){#if[FP16]?e:$Type$.$type$ToRaw$Bitstype$Bits(e)},
(v, ix, bits) -> {
$type$[] res = v.vec().clone();
res[ix] = $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits);
res[ix] = {#if[FP16]?($bitstype$)bits:$Type$.$bitstype$BitsTo$Type$(($bitstype$)bits)};
return v.vectorFactory(res);
});
}
@ -981,7 +1031,7 @@ final class $vectortype$ extends $abstractvectortype$ {
public $masktype$ compress() {
return ($masktype$)VectorSupport.compressExpandOp(VectorSupport.VECTOR_OP_MASK_COMPRESS,
$vectortype$.class, $masktype$.class, LANE_TYPE_ORDINAL, VLENGTH, null, this,
(v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, m1.trueCount()));
(v1, m1) -> VSPECIES.iota().compare(VectorOperators.LT, {#if[FP16]?Float16.float16ToRawShortBits(Float16.valueOf(m1.trueCount())):m1.trueCount()}));
}
@ -1389,7 +1439,7 @@ final class $vectortype$ extends $abstractvectortype$ {
return super.fromArray0Template($masktype$.class, a, offset, indexMap, mapOffset, ($masktype$) m);
}
#if[short]
#if[strictShort]
@ForceInline
@Override
final
@ -1403,7 +1453,7 @@ final class $vectortype$ extends $abstractvectortype$ {
$abstractvectortype$ fromCharArray0(char[] a, int offset, VectorMask<$Boxtype$> m, int offsetInRange) {
return super.fromCharArray0Template($masktype$.class, a, offset, ($masktype$) m, offsetInRange); // specialize
}
#end[short]
#end[strictShort]
#if[byte]
@ForceInline
@ -1474,14 +1524,14 @@ final class $vectortype$ extends $abstractvectortype$ {
super.intoMemorySegment0Template($masktype$.class, ms, offset, ($masktype$) m);
}
#if[short]
#if[strictShort]
@ForceInline
@Override
final
void intoCharArray0(char[] a, int offset, VectorMask<$Boxtype$> m) {
super.intoCharArray0Template($masktype$.class, a, offset, ($masktype$) m);
}
#end[short]
#end[strictShort]
// End of specialized low-level memory operations.

View File

@ -53,19 +53,29 @@ typeprefix=
globalArgs=""
#globalArgs="$globalArgs -KextraOverrides"
for type in byte short int long float double
for type in byte short int long float double float16
do
Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${type})"
case $type in
float16)
type=short
TYPE=SHORT
;;
esac
args=$globalArgs
args="$args -K$type -Dtype=$type -DType=$Type -DTYPE=$TYPE"
Boxtype=$Type
Wideboxtype=$Boxtype
ElemLayout=$Type
kind=BITWISE
bitstype=$type
maskbitstype=$type
Bitstype=$Type
Boxbitstype=$Boxtype
@ -74,23 +84,28 @@ do
Boxfptype=$Boxtype
carriertype=$type
Carriertype=$Type
elemtype=$type
fallbacktype=$type
case $type in
byte)
case $Type in
Byte)
Wideboxtype=Integer
sizeInBytes=1
laneType=LT_BYTE
lanebitsType=LT_BYTE
args="$args -KbyteOrShort"
args="$args -KbyteOrShort -KbyteOrStrictShort"
;;
short)
Short)
fptype=Float16
Fptype=Float16
Boxfptype=Float16
Wideboxtype=Integer
sizeInBytes=2
laneType=LT_SHORT
lanebitsType=LT_SHORT
args="$args -KbyteOrShort"
args="$args -KbyteOrShort -KbyteOrStrictShort -KstrictShort"
;;
int)
Int)
Boxtype=Integer
Carriertype=Integer
Wideboxtype=Integer
@ -103,7 +118,7 @@ do
lanebitsType=LT_INT
args="$args -KintOrLong -KintOrFP -KintOrFloat"
;;
long)
Long)
fptype=double
Fptype=Double
Boxfptype=Double
@ -112,33 +127,53 @@ do
lanebitsType=LT_LONG
args="$args -KintOrLong -KlongOrDouble"
;;
float)
Float)
kind=FP
bitstype=int
maskbitstype=int
Bitstype=Int
Boxbitstype=Integer
sizeInBytes=4
laneType=LT_FLOAT
lanebitsType=LT_INT
args="$args -KintOrFP -KintOrFloat"
args="$args -KFP32 -KintOrFP -KintOrFloat"
;;
double)
Double)
kind=FP
bitstype=long
maskbitstype=long
Bitstype=Long
Boxbitstype=Long
sizeInBytes=8
laneType=LT_DOUBLE
lanebitsType=LT_LONG
args="$args -KintOrFP -KlongOrDouble"
args="$args -KFP64 -KintOrFP -KlongOrDouble"
;;
Float16)
kind=FP
bitstype=short
maskbitstype=short
Bitstype=Short
Boxbitstype=Short
sizeInBytes=2
carriertype=short
Carriertype=Short
Boxtype=Float16
elemtype=Float16
ElemLayout=Short
laneType=LT_FLOAT16
lanebitsType=LT_SHORT
fallbacktype=float
args="$args -KFP16 -KbyteOrShort"
;;
esac
args="$args -K$kind -DlaneType=$laneType -DlanebitsType=$lanebitsType -DBoxtype=$Boxtype -DWideboxtype=$Wideboxtype"
args="$args -Dbitstype=$bitstype -DBitstype=$Bitstype -DBoxbitstype=$Boxbitstype"
args="$args -K$kind -DlaneType=$laneType -DlanebitsType=$lanebitsType -Dfallbacktype=$fallbacktype -DBoxtype=$Boxtype -DWideboxtype=$Wideboxtype"
args="$args -DElemLayout=$ElemLayout -Dbitstype=$bitstype -Dmaskbitstype=$maskbitstype -DBitstype=$Bitstype -DBoxbitstype=$Boxbitstype"
args="$args -Dfptype=$fptype -DFptype=$Fptype -DBoxfptype=$Boxfptype"
args="$args -DsizeInBytes=$sizeInBytes"
args="$args -Dcarriertype=$carriertype -DCarriertype=$Carriertype"
args="$args -Dcarriertype=$carriertype -Delemtype=$elemtype -DCarriertype=$Carriertype"
abstractvectortype=${typeprefix}${Type}Vector
abstractbitsvectortype=${typeprefix}Vector${Bitstype}

View File

@ -55,8 +55,6 @@
# * com.sun.management.jmxremote.password.toHashes property is set to true in
# management.properties file
# * the password file is writable
# * the system security policy allows writing into the password file, if a
# security manager is configured
#
# In order to change the password for a role, replace the hashed password entry
# with a new clear text password or a new hashed password. If the new password
@ -110,6 +108,6 @@
# below entries with clear passwords overwritten by their respective
# SHA3-512 hash
#
# monitorRole trilby APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512
# monitorRole APzBTt34rV2l+OMbuvbnOQ4si8UZmfRCVbIY1+fAofV5CkQzXS/FDMGteQQk/R3q1wtt104qImzJEA7gCwl6dw== 4EeTdSJ7X6Imu0Mb+dWqIns7a7QPIBoM3NB/XlpMQSPSicE7PnlALVWn2pBY3Q3pGDHyAb32Hd8GUToQbUhAjA== SHA3-512
# controlRole roHEJSbRqSSTII4Z4+NOCV2OJaZVQ/dw153Fy2u4ILDP9XiZ426GwzCzc3RtpoqNMwqYIcfdd74xWXSMrWtGaA== w9qDsekgKn0WOVJycDyU0kLBa081zbStcCjUAVEqlfon5Sgx7XHtaodbmzpLegA1jT7Ag36T0zHaEWRHJe2fdA== SHA3-512
#
#

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2026, 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
@ -24,18 +25,50 @@
package compiler.c2.irTests;
import jdk.test.lib.Asserts;
import compiler.lib.generators.*;
import compiler.lib.ir_framework.*;
/*
* @test
* @bug 8276673 8280089
* @bug 8276673 8280089 8349563
* @summary Test abs nodes optimization in C2.
* @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" | os.arch=="riscv64"
* @key randomness
* @library /test/lib /
* @run driver compiler.c2.irTests.TestIRAbs
*/
public class TestIRAbs {
private static final RestrictableGenerator<Integer> INTS = Generators.G.ints();
private static final RestrictableGenerator<Long> LONGS = Generators.G.longs();
private static final IntRange INT_RANGE = IntRange.generate(INTS);
private static final IntRange INT_FULL_RANGE = new IntRange(Integer.MIN_VALUE, Integer.MAX_VALUE);
private static final IntRange INT_UNSIGNED_MAX = new IntRange(-1, Integer.MAX_VALUE);
private static final IntRange INT_POSITIVE = new IntRange(0, Integer.MAX_VALUE);
private static final IntRange INT_NEGATIVE = new IntRange(Integer.MIN_VALUE, 0);
private static final LongRange LONG_RANGE = LongRange.generate(LONGS);
private static final LongRange LONG_FULL_RANGE = new LongRange(Long.MIN_VALUE, Long.MAX_VALUE);
private static final LongRange LONG_UNSIGNED_MAX = new LongRange(-1, Long.MAX_VALUE);
private static final LongRange LONG_POSITIVE = new LongRange(0, Long.MAX_VALUE);
private static final LongRange LONG_NEGATIVE = new LongRange(Long.MIN_VALUE, 0);
private static final int INT_1 = INTS.next();
private static final int INT_2 = INTS.next();
private static final int INT_3 = INTS.next();
private static final int INT_4 = INTS.next();
private static final int INT_5 = INTS.next();
private static final int INT_6 = INTS.next();
private static final int INT_7 = INTS.next();
private static final int INT_8 = INTS.next();
private static final long LONG_1 = LONGS.next();
private static final long LONG_2 = LONGS.next();
private static final long LONG_3 = LONGS.next();
private static final long LONG_4 = LONGS.next();
private static final long LONG_5 = LONGS.next();
private static final long LONG_6 = LONGS.next();
private static final long LONG_7 = LONGS.next();
private static final long LONG_8 = LONGS.next();
public static char [] cspecial = {
0, 42, 128, 256, 1024, 4096, 65535
@ -103,7 +136,7 @@ public class TestIRAbs {
}
@Test
@IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D})
@IR(failOn = {IRNode.ABS_I, IRNode.ABS_L, IRNode.ABS_F, IRNode.ABS_D}, applyIfPlatform = { "64-bit", "true" })
public void testAbsConstant() {
// Test abs(constant) optimization for int
Asserts.assertEquals(Integer.MAX_VALUE, Math.abs(Integer.MAX_VALUE));
@ -160,14 +193,14 @@ public class TestIRAbs {
}
@Test
@IR(counts = {IRNode.ABS_L, "1"})
@IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" })
public long testLong0(long x) {
return Math.abs(Math.abs(x)); // transformed to Math.abs(x)
}
@Test
@IR(failOn = {IRNode.SUB_L})
@IR(counts = {IRNode.ABS_L, "1"})
@IR(failOn = {IRNode.SUB_L}, applyIfPlatform = { "64-bit", "true" })
@IR(counts = {IRNode.ABS_L, "1"}, applyIfPlatform = { "64-bit", "true" })
public long testLong1(long x) {
return Math.abs(0 - x); // transformed to Math.abs(x)
}
@ -229,4 +262,524 @@ public class TestIRAbs {
Asserts.assertEquals(cspecial[i], (char) Math.abs(cspecial[i]));
}
}
}
@Run(test = {"testIntRange1", "testIntRange2", "testIntRange3", "testIntRange4",
"testIntRangeFolding", "testIntFullRangeFolding", "testIntUnsignedMaxFolding",
"testIntPositiveRangeFolding", "testIntNegativeRangeFolding"})
public void checkIntRanges(RunInfo info) {
for (int i : ispecial) {
checkIntRange(i);
}
for (int j = 0; j < 20; j++) {
int i = INTS.next();
checkIntRange(i);
}
}
@DontCompile
public void checkIntRange(int i) {
Asserts.assertEquals(Math.abs((i & 7) - 4) > 4, testIntRange1(i));
Asserts.assertEquals(Math.abs((i & 7) - 4) < 0, testIntRange2(i));
Asserts.assertEquals(Math.abs(-((i & 7) + 2)) < 2, testIntRange3(i));
Asserts.assertEquals(Math.abs(-((i & 7) + 2)) > 9, testIntRange4(i));
Asserts.assertEquals(testIntRangeFoldingInterpreter(i), testIntRangeFolding(i));
Asserts.assertEquals(testIntFullRangeFoldingInterpreter(i), testIntFullRangeFolding(i));
Asserts.assertEquals(testIntUnsignedMaxFoldingInterpreter(i), testIntUnsignedMaxFolding(i));
Asserts.assertEquals(testIntPositiveRangeFoldingInterpreter(i), testIntPositiveRangeFolding(i));
Asserts.assertEquals(testIntNegativeRangeFoldingInterpreter(i), testIntNegativeRangeFolding(i));
}
@Run(test = {"testLongRange1", "testLongRange2", "testLongRange3", "testLongRange4",
"testLongRangeFolding", "testLongFullRangeFolding", "testLongUnsignedMaxFolding",
"testLongPositiveRangeFolding", "testLongNegativeRangeFolding"})
public void checkLongRanges(RunInfo info) {
for (long l : lspecial) {
checkLongRange(l);
}
for (int j = 0; j < 20; j++) {
long l = LONGS.next();
checkLongRange(l);
}
}
@DontCompile
public void checkLongRange(long l) {
Asserts.assertEquals(Math.abs((l & 7) - 4) > 4, testLongRange1(l));
Asserts.assertEquals(Math.abs((l & 7) - 4) < 0, testLongRange2(l));
Asserts.assertEquals(Math.abs(-((l & 7) + 2)) < 2, testLongRange3(l));
Asserts.assertEquals(Math.abs(-((l & 7) + 2)) > 9, testLongRange4(l));
Asserts.assertEquals(testLongRangeFoldingInterpreter(l), testLongRangeFolding(l));
Asserts.assertEquals(testLongFullRangeFoldingInterpreter(l), testLongFullRangeFolding(l));
Asserts.assertEquals(testLongUnsignedMaxFoldingInterpreter(l), testLongUnsignedMaxFolding(l));
Asserts.assertEquals(testLongPositiveRangeFoldingInterpreter(l), testLongPositiveRangeFolding(l));
Asserts.assertEquals(testLongNegativeRangeFoldingInterpreter(l), testLongNegativeRangeFolding(l));
}
// Int ranges
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange1(int in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) > 4;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange2(int in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) < 0;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange3(int in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) < 2;
}
@Test
@IR(failOn = { IRNode.ABS_I })
public boolean testIntRange4(int in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) > 9;
}
@Test
public int testIntRangeFolding(int in) {
int c = INT_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntRangeFoldingInterpreter(int in) {
int c = INT_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntFullRangeFolding(int in) {
int c = INT_FULL_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntFullRangeFoldingInterpreter(int in) {
int c = INT_FULL_RANGE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntUnsignedMaxFolding(int in) {
int c = INT_UNSIGNED_MAX.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntUnsignedMaxFoldingInterpreter(int in) {
int c = INT_UNSIGNED_MAX.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntPositiveRangeFolding(int in) {
int c = INT_POSITIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntPositiveRangeFoldingInterpreter(int in) {
int c = INT_POSITIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@Test
public int testIntNegativeRangeFolding(int in) {
int c = INT_NEGATIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
@DontCompile
public int testIntNegativeRangeFoldingInterpreter(int in) {
int c = INT_NEGATIVE.clamp(in);
int v = Math.abs(c);
int sum = 0;
if (v > INT_1) { sum += 1; }
if (v > INT_2) { sum += 2; }
if (v > INT_3) { sum += 4; }
if (v > INT_4) { sum += 8; }
if (v > INT_5) { sum += 16; }
if (v > INT_6) { sum += 32; }
if (v > INT_7) { sum += 64; }
if (v > INT_8) { sum += 128; }
return sum;
}
// Long ranges
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange1(long in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) > 4;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange2(long in) {
// [-4, 3] => [0, 4]
return Math.abs((in & 7) - 4) < 0;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange3(long in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) < 2;
}
@Test
@IR(failOn = { IRNode.ABS_L }, applyIfPlatform = { "64-bit", "true" })
public boolean testLongRange4(long in) {
// [-9, -2] => [2, 9]
return Math.abs(-((in & 7) + 2)) > 9;
}
@Test
public int testLongRangeFolding(long in) {
long c = LONG_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongRangeFoldingInterpreter(long in) {
long c = LONG_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongFullRangeFolding(long in) {
long c = LONG_FULL_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongFullRangeFoldingInterpreter(long in) {
long c = LONG_FULL_RANGE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongUnsignedMaxFolding(long in) {
long c = LONG_UNSIGNED_MAX.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongUnsignedMaxFoldingInterpreter(long in) {
long c = LONG_UNSIGNED_MAX.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongPositiveRangeFolding(long in) {
long c = LONG_POSITIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongPositiveRangeFoldingInterpreter(long in) {
long c = LONG_POSITIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@Test
public int testLongNegativeRangeFolding(long in) {
long c = LONG_NEGATIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
@DontCompile
public int testLongNegativeRangeFoldingInterpreter(long in) {
long c = LONG_NEGATIVE.clamp(in);
long v = Math.abs(c);
int sum = 0;
if (v > LONG_1) { sum += 1; }
if (v > LONG_2) { sum += 2; }
if (v > LONG_3) { sum += 4; }
if (v > LONG_4) { sum += 8; }
if (v > LONG_5) { sum += 16; }
if (v > LONG_6) { sum += 32; }
if (v > LONG_7) { sum += 64; }
if (v > LONG_8) { sum += 128; }
return sum;
}
record IntRange(int lo, int hi) {
IntRange {
if (lo > hi) {
throw new IllegalArgumentException("lo > hi");
}
}
int clamp(int v) {
return Math.min(hi, Math.max(v, lo));
}
static IntRange generate(Generator<Integer> g) {
var a = g.next();
var b = g.next();
if (a > b) {
var tmp = a;
a = b;
b = tmp;
}
return new IntRange(a, b);
}
}
record LongRange(long lo, long hi) {
LongRange {
if (lo > hi) {
throw new IllegalArgumentException("lo > hi");
}
}
long clamp(long v) {
return Math.min(hi, Math.max(v, lo));
}
static LongRange generate(Generator<Long> g) {
var a = g.next();
var b = g.next();
if (a > b) {
var tmp = a;
a = b;
b = tmp;
}
return new LongRange(a, b);
}
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2025 Arm Limited and/or its affiliates.
* 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 8370691 8373574
* @summary Verify correct execution of CastII -> ConvHF2F IR sequence on AArch64
* @modules jdk.incubator.vector
* @library /test/lib /
* @compile TestCastIIToConvHF2FNoSp.java
* @run driver/timeout=480 compiler.vectorapi.TestCastIIToConvHF2FNoSp
*/
package compiler.vectorapi;
import compiler.lib.ir_framework.*;
import jdk.incubator.vector.*;
import static jdk.incubator.vector.Float16.*;
import static java.lang.Float.*;
import java.util.Arrays;
import jdk.test.lib.*;
import compiler.lib.generators.Generator;
import static compiler.lib.generators.Generators.G;
public class TestCastIIToConvHF2FNoSp {
short[] input1;
short[] output;
static final int LEN = 527;
static final Float16 FP16_CONST = Float16.valueOf(1023.0f);
static final VectorSpecies<Float16> SPECIES = Float16Vector.SPECIES_PREFERRED;
public static void main(String args[]) {
// Test with default MaxVectorSize
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector");
// Test with different values of MaxVectorSize
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=8");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=16");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=32");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=64");
}
static void assertResults(int arity, short ... values) {
assert values.length == (arity + 2);
Float16 expected_fp16 = shortBitsToFloat16(values[arity]);
Float16 actual_fp16 = shortBitsToFloat16(values[arity + 1]);
if(!expected_fp16.equals(actual_fp16)) {
String inputs = Arrays.toString(Arrays.copyOfRange(values, 0, arity - 1));
throw new AssertionError("Result Mismatch!, input = " + inputs + " actual = " + actual_fp16 + " expected = " + expected_fp16);
}
}
public TestCastIIToConvHF2FNoSp() {
input1 = new short[LEN];
output = new short[LEN];
Generator<Short> gen = G.float16s();
for (int i = 0; i < LEN; ++i) {
input1[i] = gen.next();
}
}
@Test
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeature = {"sve", "true"})
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true", "sve", "false"})
void vectorMinConstantInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.MIN,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.MIN,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMinConstantInputFloat16")
void checkResultMinConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(Math.min(FP16_CONST.floatValue(), float16ToFloat(input1[i])));
assertResults(2, float16ToRawShortBits(FP16_CONST), input1[i], expected, output[i]);
}
}
}

View File

@ -0,0 +1,620 @@
/*
* Copyright (c) 2026, 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 8370691
* @summary Test intrinsification of Float16Vector operations
* @modules jdk.incubator.vector
* @library /test/lib /
* @compile TestFloat16VectorOperations.java
* @run driver/timeout=480 compiler.vectorapi.TestFloat16VectorOperations
*/
package compiler.vectorapi;
import compiler.lib.ir_framework.*;
import jdk.incubator.vector.*;
import static jdk.incubator.vector.Float16.*;
import static java.lang.Float.*;
import java.util.Arrays;
import jdk.test.lib.*;
import compiler.lib.generators.Generator;
import static compiler.lib.generators.Generators.G;
public class TestFloat16VectorOperations {
short[] input1;
short[] input2;
short[] input3;
short[] output;
static final int LEN = 527;
static short FP16_SCALAR = (short)0x7777;
static final Float16 FP16_CONST = Float16.valueOf(1023.0f);
static final VectorSpecies<Float16> SPECIES = Float16Vector.SPECIES_PREFERRED;
public static void main(String args[]) {
// Test with default MaxVectorSize
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector");
// Test with different values of MaxVectorSize
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=8");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=16");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=32");
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:MaxVectorSize=64");
}
static void assertResults(int arity, short ... values) {
assert values.length == (arity + 2);
Float16 expected_fp16 = shortBitsToFloat16(values[arity]);
Float16 actual_fp16 = shortBitsToFloat16(values[arity + 1]);
if(!expected_fp16.equals(actual_fp16)) {
String inputs = Arrays.toString(Arrays.copyOfRange(values, 0, arity - 1));
throw new AssertionError("Result Mismatch!, input = " + inputs + " actual = " + actual_fp16 + " expected = " + expected_fp16);
}
}
public TestFloat16VectorOperations() {
input1 = new short[LEN];
input2 = new short[LEN];
input3 = new short[LEN];
output = new short[LEN];
Generator<Short> gen = G.float16s();
for (int i = 0; i < LEN; ++i) {
input1[i] = gen.next();
input2[i] = gen.next();
input3[i] = gen.next();
}
}
@Test
@IR(counts = {IRNode.ADD_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.ADD_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorAddFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.ADD,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.ADD,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorAddFloat16")
void checkResultAdd() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) + float16ToFloat(input2[i]));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.SUB_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.SUB_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorSubFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.SUB,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.SUB,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorSubFloat16")
void checkResultSub() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) - float16ToFloat(input2[i]));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MUL_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.MUL_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMulFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.MUL,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.MUL,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMulFloat16")
void checkResultMul() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) * float16ToFloat(input2[i]));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.DIV_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.DIV_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorDivFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.DIV,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.DIV,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorDivFloat16")
void checkResultDiv() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) / float16ToFloat(input2[i]));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMinFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.MIN,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.MIN,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMinFloat16")
void checkResultMin() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(Math.min(float16ToFloat(input1[i]), float16ToFloat(input2[i])));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MAX_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.MAX_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMaxFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.MAX,
Float16Vector.fromArray(SPECIES, input2, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.MAX,
Float16Vector.fromArray(SPECIES, input2, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMaxFloat16")
void checkResultMax() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(Math.max(float16ToFloat(input1[i]), float16ToFloat(input2[i])));
assertResults(2, input1[i], input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.SQRT_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.SQRT_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorSqrtFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.SQRT)
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.SQRT)
.intoArray(output, i, mask);
}
}
@Check(test="vectorSqrtFloat16")
void checkResultSqrt() {
for (int i = 0; i < LEN; ++i) {
short expected = float16ToRawShortBits(sqrt(shortBitsToFloat16(input1[i])));
assertResults(1, input1[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorFmaFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.FMA,
Float16Vector.fromArray(SPECIES, input2, i),
Float16Vector.fromArray(SPECIES, input3, i))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.FMA,
Float16Vector.fromArray(SPECIES, input2, i, mask),
Float16Vector.fromArray(SPECIES, input3, i, mask))
.intoArray(output, i, mask);
}
}
@Check(test="vectorFmaFloat16")
void checkResultFma() {
for (int i = 0; i < LEN; ++i) {
short expected = float16ToRawShortBits(fma(shortBitsToFloat16(input1[i]), shortBitsToFloat16(input2[i]),
shortBitsToFloat16(input3[i])));
assertResults(3, input1[i], input2[i], input3[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorFmaFloat16ScalarMixedConstants() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.FMA,
FP16_SCALAR,
floatToFloat16(3.0f))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.FMA,
FP16_SCALAR,
floatToFloat16(3.0f))
.intoArray(output, i, mask);
}
}
@Check(test="vectorFmaFloat16ScalarMixedConstants")
void checkResultFmaScalarMixedConstants() {
for (int i = 0; i < LEN; ++i) {
short expected = float16ToRawShortBits(fma(shortBitsToFloat16(input1[i]), shortBitsToFloat16(FP16_SCALAR),
shortBitsToFloat16(floatToFloat16(3.0f))));
assertResults(2, input1[i], FP16_SCALAR, expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorFmaFloat16MixedConstants() {
short input3 = floatToFloat16(3.0f);
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.FMA,
Float16Vector.fromArray(SPECIES, input2, i),
input3)
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.FMA,
Float16Vector.fromArray(SPECIES, input2, i, mask),
input3)
.intoArray(output, i, mask);
}
}
@Check(test="vectorFmaFloat16MixedConstants")
void checkResultFmaMixedConstants() {
short input3 = floatToFloat16(3.0f);
for (int i = 0; i < LEN; ++i) {
short expected = float16ToRawShortBits(fma(shortBitsToFloat16(input1[i]), shortBitsToFloat16(input2[i]), shortBitsToFloat16(input3)));
assertResults(3, input1[i], input2[i], input3, expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.FMA_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorFmaFloat16AllConstants() {
short input1 = floatToFloat16(1.0f);
short input2 = floatToFloat16(2.0f);
short input3 = floatToFloat16(3.0f);
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.broadcast(SPECIES, input1)
.lanewise(VectorOperators.FMA,
input2,
input3)
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.broadcast(SPECIES, input1)
.lanewise(VectorOperators.FMA,
input2,
input3)
.intoArray(output, i, mask);
}
}
@Check(test="vectorFmaFloat16AllConstants")
void checkResultFmaAllConstants() {
short input1 = floatToFloat16(1.0f);
short input2 = floatToFloat16(2.0f);
short input3 = floatToFloat16(3.0f);
for (int i = 0; i < LEN; ++i) {
short expected = float16ToRawShortBits(fma(shortBitsToFloat16(input1), shortBitsToFloat16(input2), shortBitsToFloat16(input3)));
assertResults(3, input1, input2, input3, expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.ADD_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "zvfh", "true", "sve", "true"})
@IR(counts = {IRNode.ADD_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorAddConstInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.ADD,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.ADD,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorAddConstInputFloat16")
void checkResultAddConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) + FP16_CONST.floatValue());
assertResults(2, input1[i], float16ToRawShortBits(FP16_CONST), expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.SUB_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "sve", "true"})
@IR(counts = {IRNode.SUB_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorSubConstInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input1, i)
.lanewise(VectorOperators.SUB,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input1, i, mask)
.lanewise(VectorOperators.SUB,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorSubConstInputFloat16")
void checkResultSubConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input1[i]) - FP16_CONST.floatValue());
assertResults(2, input1[i], float16ToRawShortBits(FP16_CONST), expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MUL_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "sve", "true"})
@IR(counts = {IRNode.MUL_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMulConstantInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input2, i)
.lanewise(VectorOperators.MUL,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input2, i, mask)
.lanewise(VectorOperators.MUL,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMulConstantInputFloat16")
void checkResultMulConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(FP16_CONST.floatValue() * float16ToFloat(input2[i]));
assertResults(2, float16ToRawShortBits(FP16_CONST), input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.DIV_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "sve", "true"})
@IR(counts = {IRNode.DIV_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorDivConstantInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input2, i)
.lanewise(VectorOperators.DIV,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input2, i, mask)
.lanewise(VectorOperators.DIV,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorDivConstantInputFloat16")
void checkResultDivConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(float16ToFloat(input2[i]) / FP16_CONST.floatValue());
assertResults(2, input2[i], float16ToRawShortBits(FP16_CONST), expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MAX_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "sve", "true"})
@IR(counts = {IRNode.MAX_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMaxConstantInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input2, i)
.lanewise(VectorOperators.MAX,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input2, i, mask)
.lanewise(VectorOperators.MAX,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMaxConstantInputFloat16")
void checkResultMaxConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(Math.max(FP16_CONST.floatValue(), float16ToFloat(input2[i])));
assertResults(2, float16ToRawShortBits(FP16_CONST), input2[i], expected, output[i]);
}
}
@Test
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeatureOr = {"avx512_fp16", "true", "sve", "true"})
@IR(counts = {IRNode.MIN_VHF, " >0 "},
applyIfCPUFeatureAnd = {"fphp", "true", "asimdhp", "true"})
void vectorMinConstantInputFloat16() {
int i = 0;
for (; i < SPECIES.loopBound(LEN); i += SPECIES.length()) {
Float16Vector.fromArray(SPECIES, input2, i)
.lanewise(VectorOperators.MIN,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i);
}
if (i < LEN) {
VectorMask<Float16> mask = SPECIES.indexInRange(i, LEN);
Float16Vector.fromArray(SPECIES, input2, i, mask)
.lanewise(VectorOperators.MIN,
float16ToRawShortBits(FP16_CONST))
.intoArray(output, i, mask);
}
}
@Check(test="vectorMinConstantInputFloat16")
void checkResultMinConstantInputFloat16() {
for (int i = 0; i < LEN; ++i) {
short expected = floatToFloat16(Math.min(FP16_CONST.floatValue(), float16ToFloat(input2[i])));
assertResults(2, float16ToRawShortBits(FP16_CONST), input2[i], expected, output[i]);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, 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
@ -71,7 +71,7 @@ public class PreviewVersion {
pb = ProcessTools.createLimitedTestJavaProcessBuilder("--enable-preview", "-Xlog:class+preview",
"-cp", "." + File.pathSeparator + System.getProperty("test.classes"), "PVTest");
oa = new OutputAnalyzer(pb.start());
oa.shouldContain("[info][class,preview] Loading class PVTest that depends on preview features");
oa.shouldMatch("\\[info *\\]\\[class,preview *\\] Loading class PVTest that depends on preview features");
oa.shouldHaveExitValue(0);
// Subtract 1 from class's major version. The class should fail to load

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022 SAP SE. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2026, 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
@ -106,7 +106,7 @@ public class MallocLimitTest {
ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=1m");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("[nmt] MallocLimit: total limit: 1024K (fatal)");
output.shouldMatch("\\[nmt *\\] MallocLimit: total limit: 1024K \\(fatal\\)");
output.shouldMatch("# fatal error: MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)");
}
@ -114,8 +114,8 @@ public class MallocLimitTest {
ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=1m:oom");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("[nmt] MallocLimit: total limit: 1024K (oom)");
output.shouldMatch(".*\\[warning\\]\\[nmt\\] MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)");
output.shouldMatch("\\[nmt *\\] MallocLimit: total limit: 1024K \\(oom\\)");
output.shouldMatch("\\[warning\\]\\[nmt *\\] MallocLimit: reached global limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024K\\)");
// The rest is fuzzy. We may get SIGSEGV or a native OOM message, depending on how the failing allocation was handled.
}
@ -123,7 +123,7 @@ public class MallocLimitTest {
ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=compiler:1234k", "-Xcomp");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1234K (fatal)");
output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1234K \\(fatal\\)");
output.shouldMatch("# fatal error: MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)");
}
@ -131,8 +131,8 @@ public class MallocLimitTest {
ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=compiler:1234k:oom", "-Xcomp");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1234K (oom)");
output.shouldMatch(".*\\[warning\\]\\[nmt\\] MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)");
output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1234K \\(oom\\)");
output.shouldMatch("\\[warning\\]\\[nmt *\\] MallocLimit: reached category \"mtCompiler\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1234K\\)");
// The rest is fuzzy. We may get SIGSEGV or a native OOM message, depending on how the failing allocation was handled.
}
@ -140,9 +140,9 @@ public class MallocLimitTest {
ProcessBuilder pb = processBuilderWithSetting("-XX:MallocLimit=other:2g,compiler:1g:oom,internal:1k");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("[nmt] MallocLimit: category \"mtCompiler\" limit: 1024M (oom)");
output.shouldContain("[nmt] MallocLimit: category \"mtInternal\" limit: 1024B (fatal)");
output.shouldContain("[nmt] MallocLimit: category \"mtOther\" limit: 2048M (fatal)");
output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtCompiler\" limit: 1024M \\(oom\\)");
output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtInternal\" limit: 1024B \\(fatal\\)");
output.shouldMatch("\\[nmt *\\] MallocLimit: category \"mtOther\" limit: 2048M \\(fatal\\)");
output.shouldMatch("# fatal error: MallocLimit: reached category \"mtInternal\" limit \\(triggering allocation size: \\d+[BKM], allocated so far: \\d+[BKM], limit: 1024B\\)");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, 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
@ -27,6 +27,7 @@
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @requires os.family == "linux"
* @requires !jdk.static
* @compile DoOverflow.java
* @run main/native TestStackGuardPagesNative
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, 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
@ -59,7 +59,7 @@ public class LambdaProxyClasslist {
out = TestCommon.dump(appJar,
TestCommon.list("LambHello",
"@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z"));
out.shouldContain("[warning][cds] No invoke dynamic constant pool entry can be found for class LambHello. The classlist is probably out-of-date.")
out.shouldMatch("\\[warning\\]\\[cds *\\] No invoke dynamic constant pool entry can be found for class LambHello\\. The classlist is probably out-of-date\\.")
.shouldHaveExitValue(0);
// 4. More blank spaces in between items should be fine.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, 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
@ -67,7 +67,7 @@ public class LambdaWithOldClass {
.setUseVersion(false)
.addSuffix(mainClass);
OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file")
output.shouldMatch("\\[class,load *\\] LambdaWithOldClassApp source: shared objects file")
.shouldHaveExitValue(0);
if (!CDSTestUtils.isAOTClassLinkingEnabled()) {
// With AOTClassLinking, we don't archive any lambda with old classes in the method

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2026, 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
@ -65,7 +65,7 @@ public class ProhibitedPackage {
TestCommon.list("java/lang/Prohibited", "ProhibitedHelper"),
"-Xlog:class+load")
.shouldContain("Dumping")
.shouldNotContain("[info][class,load] java.lang.Prohibited source: ")
.shouldNotMatch("\\[info *\\]\\[class,load *\\] java.lang.Prohibited source: ")
.shouldHaveExitValue(0);
// Try loading the class in a prohibited package with various -Xshare

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, 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
@ -58,7 +58,7 @@ public class AOTLoggingTag {
"-cp", appJar, helloClass);
out = CDSTestUtils.executeAndLog(pb, "train");
out.shouldContain("[aot] Writing binary AOTConfiguration file:");
out.shouldMatch("\\[aot *\\] Writing binary AOTConfiguration file:");
out.shouldHaveExitValue(0);
//----------------------------------------------------------------------
@ -70,7 +70,7 @@ public class AOTLoggingTag {
"-Xlog:aot",
"-cp", appJar);
out = CDSTestUtils.executeAndLog(pb, "asm");
out.shouldContain("[aot] Opened AOT configuration file hello.aotconfig");
out.shouldMatch("\\[aot *\\] Opened AOT configuration file hello\\.aotconfig");
out.shouldHaveExitValue(0);
//----------------------------------------------------------------------
@ -80,7 +80,7 @@ public class AOTLoggingTag {
"-Xlog:aot",
"-cp", appJar, helloClass);
out = CDSTestUtils.executeAndLog(pb, "prod");
out.shouldContain("[aot] Opened AOT cache hello.aot");
out.shouldMatch("\\[aot *\\] Opened AOT cache hello\\.aot");
out.shouldHaveExitValue(0);
//----------------------------------------------------------------------
@ -90,7 +90,7 @@ public class AOTLoggingTag {
"-XX:AOTMode=on",
"-cp", appJar, helloClass);
out = CDSTestUtils.executeAndLog(pb, "prod");
out.shouldContain("[aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.");
out.shouldMatch("\\[aot *\\] An error has occurred while processing the AOT cache\\. Run with -Xlog:aot for details\\.");
out.shouldNotHaveExitValue(0);
}

View File

@ -67,7 +67,7 @@ public class AddOpens {
{{"-Xlog:cds", "-Xlog:cds"},
{"--add-opens", addOpensArg}};
private static String expectedOutput[] =
{ "[class,load] com.simple.Main source: shared objects file",
{ "\\[class,load *\\] com\\.simple\\.Main source: shared objects file",
"method.setAccessible succeeded!"};
public static void buildTestModule() throws Exception {
@ -103,7 +103,7 @@ public class AddOpens {
out.shouldContain("Full module graph = enabled");
})
.setProductionChecker((OutputAnalyzer out) -> {
out.shouldContain(expectedOutput[0]);
out.shouldMatch(expectedOutput[0]);
out.shouldContain(expectedOutput[1]);
})
.runStaticWorkflow()
@ -154,7 +154,7 @@ public class AddOpens {
@Override
public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
if (runMode == RunMode.PRODUCTION) {
out.shouldContain(expectedOutput[0]);
out.shouldMatch(expectedOutput[0]);
out.shouldContain(expectedOutput[1]);
} else if (runMode == RunMode.ASSEMBLY) {
out.shouldMatch("(full module graph: enabled)|(Full module graph = enabled)");
@ -197,7 +197,7 @@ public class AddOpens {
@Override
public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
if (runMode == RunMode.PRODUCTION) {
out.shouldContain(expectedOutput[0]);
out.shouldMatch(expectedOutput[0]);
out.shouldContain(expectedOutput[1]);
} else if (runMode == RunMode.ASSEMBLY) {
out.shouldMatch("(full module graph: enabled)|(Full module graph = enabled)");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, 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
@ -92,7 +92,7 @@ public class OldClassAndInf {
TestCommon.checkExec(output);
for (String loadee : loadees) {
output.shouldContain("[class,load] " + loadee + " source: shared objects file");
output.shouldMatch("\\[class,load *\\] " + loadee + " source: shared objects file");
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, 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
@ -74,7 +74,7 @@ public class ArchivedSuperIf extends DynamicArchiveTestBase {
.assertNormalExit(output -> {
// The interface Bar will be loaded from the archive.
// The class (Baz) which implements Bar will be loaded from jar.
output.shouldContain("[class,load] pkg.Bar source: shared objects file (top)")
output.shouldMatch("\\[class,load *\\] pkg\\.Bar source: shared objects file \\(top\\)")
.shouldMatch(".class.load. pkg.Baz source:.*archived_super_if.jar")
.shouldHaveExitValue(0);
});

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, 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
@ -62,7 +62,7 @@ public class JFRDynamicCDS extends DynamicArchiveTestBase {
.assertNormalExit(output -> {
output.shouldHaveExitValue(0)
.shouldMatch(".class.load. jdk.jfr.events.*source:.*jrt:/jdk.jfr")
.shouldContain("[class,load] JFRDynamicCDSApp source: shared objects file (top)");
.shouldMatch("\\[class,load *\\] JFRDynamicCDSApp source: shared objects file \\(top\\)");
});
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, 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
@ -76,7 +76,7 @@ public class LambdaContainsOldInf extends DynamicArchiveTestBase {
"-Xlog:class+load=debug",
"-cp", appJar, mainClass, mainArg)
.assertNormalExit(output -> {
output.shouldContain("[class,load] LambdaContainsOldInfApp source: shared objects file (top)")
output.shouldMatch("\\[class,load *\\] LambdaContainsOldInfApp source: shared objects file \\(top\\)")
.shouldMatch(".class.load. OldProvider.source:.*lambda_contains_old_inf.jar")
.shouldMatch(".class.load. LambdaContainsOldInfApp[$][$]Lambda.*/0x.*source:.*LambdaContainsOldInf")
.shouldHaveExitValue(0);

View File

@ -117,7 +117,7 @@ public class MainModuleOnly extends DynamicArchiveTestBase {
"--module-path", moduleDir.toString(),
"-m", TEST_MODULE1)
.assertNormalExit(output -> {
output.shouldContain("[class,load] com.simple.Main source: shared objects file")
output.shouldMatch("\\[class,load *\\] com\\.simple\\.Main source: shared objects file")
.shouldHaveExitValue(0);
});

View File

@ -205,7 +205,7 @@ public class BootAppendTests {
"Test #6", BOOT_APPEND_CLASS, "true", "BOOT");
TestCommon.checkExec(output);
if (!TestCommon.isUnableToMap(output))
output.shouldContain("[class,load] sun.nio.cs.ext1.MyClass source: shared objects file");
output.shouldMatch("\\[class,load *\\] sun\\.nio\\.cs\\.ext1\\.MyClass source: shared objects file");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, 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
@ -118,8 +118,8 @@ public class AddModules {
moduleDir.toString(), // --module-path
MAIN_MODULE1) // -m
.assertNormalExit(out -> {
out.shouldContain("[class,load] com.greetings.Main source: shared objects file")
.shouldContain("[class,load] org.astro.World source: shared objects file");
out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file")
.shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file");
});
// run the com.hello module with the archive with the --module-path
@ -130,8 +130,8 @@ public class AddModules {
moduleDir.toString(), // --module-path
MAIN_MODULE2) // -m
.assertNormalExit(out -> {
out.shouldContain("[class,load] com.hello.Main source: shared objects file")
.shouldContain("[class,load] org.astro.World source: shared objects file");
out.shouldMatch("\\[class,load *\\] com\\.hello\\.Main source: shared objects file")
.shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file");
});
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, 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
@ -115,8 +115,8 @@ public class ModulePathAndCP {
moduleDir.toString(), // --module-path
MAIN_MODULE) // -m
.assertNormalExit(out -> {
out.shouldContain("[class,load] com.greetings.Main source: shared objects file")
.shouldContain("[class,load] org.astro.World source: shared objects file");
out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file")
.shouldMatch("\\[class,load *\\] org\\.astro\\.World source: shared objects file");
});
// run with the archive with the --module-path different from the one during
@ -181,7 +181,7 @@ public class ModulePathAndCP {
jars, // --module-path
MAIN_MODULE) // -m
.assertNormalExit(out -> {
out.shouldContain("[class,load] com.greetings.Main source: shared objects file")
out.shouldMatch("\\[class,load *\\] com\\.greetings\\.Main source: shared objects file")
.shouldMatch(".class.load. org.astro.World source:.*org.astro.jar");
});
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2026, 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
@ -71,8 +71,8 @@ public class OldClassAndRedefineClass {
"-Xlog:cds,class+load",
agentCmdArg,
"OldClassAndRedefineClassApp");
out.shouldContain("[class,load] OldSuper source: shared objects file")
.shouldContain("[class,load] ChildOldSuper source: shared objects file")
.shouldContain("[class,load] Hello source: __VM_RedefineClasses__");
out.shouldMatch("\\[class,load *\\] OldSuper source: shared objects file")
.shouldMatch("\\[class,load *\\] ChildOldSuper source: shared objects file")
.shouldMatch("\\[class,load *\\] Hello source: __VM_RedefineClasses__");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, 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
@ -134,7 +134,7 @@ class MutateFinalsTest {
void testMutateInstanceFinalWithLogging(String methodName) throws Exception {
String type = methodName.contains("Object") ? "Object" : "<Type>";
test(methodName, "-Xlog:jni=debug")
.shouldContain("[debug][jni] Set" + type + "Field mutated final instance field")
.shouldMatch("\\[debug *\\]\\[jni *\\] Set" + type + "Field mutated final instance field")
.shouldHaveExitValue(0);
}
@ -147,7 +147,7 @@ class MutateFinalsTest {
void testMutateStaticFinalWithLogging(String methodName) throws Exception {
String type = methodName.contains("Object") ? "Object" : "<Type>";
test(methodName, "-Xlog:jni=debug")
.shouldContain("[debug][jni] SetStatic" + type + "Field mutated final static field")
.shouldMatch("\\[debug *\\]\\[jni *\\] SetStatic" + type + "Field mutated final static field")
.shouldHaveExitValue(0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, 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
@ -60,7 +60,7 @@ public class ClassInitializationTest {
"BadMap50");
out = new OutputAnalyzer(pb.start());
out.shouldNotHaveExitValue(0);
out.shouldNotContain("[class,init]");
out.shouldNotMatch("\\[class,init *\\]");
out.shouldNotContain("Fail over class verification to old verifier for: BadMap50");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, 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
@ -44,27 +44,27 @@ public class CondyIndyTest {
"CondyIndy");
OutputAnalyzer o = new OutputAnalyzer(pb.start());
o.shouldHaveExitValue(0);
o.shouldContain("[info][methodhandles");
o.shouldNotContain("[debug][methodhandles,indy");
o.shouldNotContain("[debug][methodhandles,condy");
o.shouldMatch("\\[info *\\]\\[methodhandles");
o.shouldNotMatch("\\[debug *\\]\\[methodhandles,indy");
o.shouldNotMatch("\\[debug *\\]\\[methodhandles,condy");
// (2) methodhandles+condy=debug only
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles+condy=debug",
"CondyIndy");
o = new OutputAnalyzer(pb.start());
o.shouldHaveExitValue(0);
o.shouldNotContain("[info ][methodhandles");
o.shouldNotContain("[debug][methodhandles,indy");
o.shouldContain("[debug][methodhandles,condy");
o.shouldNotMatch("\\[info *\\]\\[methodhandles");
o.shouldNotMatch("\\[debug *\\]\\[methodhandles,indy");
o.shouldMatch("\\[debug *\\]\\[methodhandles,condy");
// (3) methodhandles+indy=debug only
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles+indy=debug",
"CondyIndy");
o = new OutputAnalyzer(pb.start());
o.shouldHaveExitValue(0);
o.shouldNotContain("[info ][methodhandles");
o.shouldContain("[debug][methodhandles,indy");
o.shouldNotContain("[debug][methodhandles,condy");
o.shouldNotMatch("\\[info *\\]\\[methodhandles");
o.shouldMatch("\\[debug *\\]\\[methodhandles,indy");
o.shouldNotMatch("\\[debug *\\]\\[methodhandles,condy");
// (4) methodhandles, condy, indy all on
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:methodhandles=info",
@ -73,8 +73,8 @@ public class CondyIndyTest {
"CondyIndy");
o = new OutputAnalyzer(pb.start());
o.shouldHaveExitValue(0);
o.shouldContain("[info ][methodhandles");
o.shouldContain("[debug][methodhandles,indy");
o.shouldContain("[debug][methodhandles,condy");
o.shouldMatch("\\[info *\\]\\[methodhandles");
o.shouldMatch("\\[debug *\\]\\[methodhandles,indy");
o.shouldMatch("\\[debug *\\]\\[methodhandles,condy");
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, 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
@ -68,7 +68,7 @@ public class ExceptionsTest {
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("[exceptions]");
output.shouldNotMatch("\\[exceptions *\\]");
output.shouldHaveExitValue(0);
}

View File

@ -43,7 +43,7 @@ public class GenerateOopMapTest {
static String infoPattern = "[generateoopmap]";
static String debugPattern = "[generateoopmap] Basicblock#0 begins at:";
static String tracePattern = "[trace][generateoopmap] 5 vars = 'r' stack = 'v' monitors = '' \tifne";
static String tracePattern = "\\[trace *\\]\\[generateoopmap\\] 5 vars = 'r' stack = 'v' monitors = '' \tifne";
static String traceDetailPattern = "[generateoopmap] 0 vars = ( r |slot0) invokestatic()V";
static void test() throws Exception {
@ -63,7 +63,7 @@ public class GenerateOopMapTest {
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:generateoopmap=trace",
"GenerateOopMapTest", "test");
o = new OutputAnalyzer(pb.start());
o.shouldContain(tracePattern).shouldHaveExitValue(0);
o.shouldMatch(tracePattern).shouldHaveExitValue(0);
// Prints extra stuff with detailed. Not sure how useful this is but keep it for now.
if (Platform.isDebugBuild()) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -44,7 +44,7 @@ public class StackWalkTest {
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("[stackwalk]");
output.shouldNotMatch("\\[stackwalk *\\]");
output.shouldHaveExitValue(0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2026, 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
@ -47,7 +47,7 @@ public class StartupTimeTest {
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("[startuptime]");
output.shouldNotMatch("\\[startuptime *\\]");
output.shouldHaveExitValue(0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -39,26 +39,26 @@ public class VerificationTest {
static void analyzeOutputOn(ProcessBuilder pb, boolean isLogLevelInfo) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("[verification]");
output.shouldMatch("\\[verification *\\]");
output.shouldContain("Verifying class VerificationTest$InternalClass with new format");
output.shouldContain("Verifying method VerificationTest$InternalClass.<init>()V");
output.shouldContain("End class verification for: VerificationTest$InternalClass");
if (isLogLevelInfo) {
// logging level 'info' should not output stack map and opcode data.
output.shouldNotContain("[verification] StackMapTable: frame_count");
output.shouldNotContain("[verification] offset = 0, opcode =");
output.shouldNotMatch("\\[verification *\\] StackMapTable: frame_count");
output.shouldNotMatch("\\[verification *\\] offset = 0, opcode =");
} else { // log level debug
output.shouldContain("[debug][verification] StackMapTable: frame_count");
output.shouldContain("[debug][verification] offset = 0, opcode =");
output.shouldMatch("\\[debug *\\]\\[verification *\\] StackMapTable: frame_count");
output.shouldMatch("\\[debug *\\]\\[verification *\\] offset = 0, opcode =");
}
output.shouldHaveExitValue(0);
}
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("[verification]");
output.shouldNotMatch("\\[verification *\\]");
output.shouldHaveExitValue(0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2026, 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
@ -60,11 +60,11 @@ public class PatchModuleTraceCL {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
// "modules" jimage case.
output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base");
output.shouldMatch("\\[class,load *\\] java\\.lang\\.Thread source: jrt:/java.base");
// --patch-module case.
output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming");
output.shouldMatch("\\[class,load *\\] javax\\.naming\\.spi\\.NamingManager source: mods/java.naming");
// -cp case.
output.shouldContain("[class,load] PatchModuleMain source: file");
output.shouldMatch("\\[class,load *\\] PatchModuleMain source: file");
// Test -Xlog:class+load=info output for -Xbootclasspath/a
source = "package PatchModuleTraceCL_pkg; " +
@ -82,7 +82,7 @@ public class PatchModuleTraceCL {
"-Xlog:class+load=info", "PatchModuleMain", "PatchModuleTraceCL_pkg.ItIsI");
output = new OutputAnalyzer(pb.start());
// -Xbootclasspath/a case.
output.shouldContain("[class,load] PatchModuleTraceCL_pkg.ItIsI source: xbcp");
output.shouldMatch("\\[class,load *\\] PatchModuleTraceCL_pkg\\.ItIsI source: xbcp");
output.shouldHaveExitValue(0);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -188,7 +188,7 @@ public class THPsInThreadStackPreventionTest {
output.shouldHaveExitValue(0);
// this line indicates the mitigation is active:
output.shouldContain("[pagesize] JVM will attempt to prevent THPs in thread stacks.");
output.shouldMatch("\\[pagesize *\\] JVM will attempt to prevent THPs in thread stacks\\.");
ProcSelfStatus status = ProcSelfStatus.parse(output);
if (status.numLifeThreads < numThreads) {
@ -225,7 +225,7 @@ public class THPsInThreadStackPreventionTest {
output.shouldHaveExitValue(0);
// We deliberately switched off mitigation, VM should tell us:
output.shouldContain("[pagesize] JVM will *not* prevent THPs in thread stacks. This may cause high RSS.");
output.shouldMatch("\\[pagesize *\\] JVM will \\*not\\* prevent THPs in thread stacks\\. This may cause high RSS\\.");
// Parse output from self/status
ProcSelfStatus status = ProcSelfStatus.parse(output);

View File

@ -68,8 +68,8 @@ import java.util.Set;
public class TestHugePageDecisionsAtVMStartup {
// End user warnings, printing with Xlog:pagesize at warning level, should be unconditional
static final String warningNoTHP = "[warning][pagesize] UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system.";
static final String warningNoLP = "[warning][pagesize] UseLargePages disabled, no large pages configured and available on the system.";
static final String warningNoTHP = "\\[warning\\]\\[pagesize *\\] UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system\\.";
static final String warningNoLP = "\\[warning\\]\\[pagesize *\\] UseLargePages disabled, no large pages configured and available on the system\\.";
static final String buildSizeString(long l) {
String units[] = { "K", "M", "G" };
@ -119,27 +119,27 @@ public class TestHugePageDecisionsAtVMStartup {
}
if (!useLP) {
out.shouldContain("[info][pagesize] Large page support disabled");
out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support disabled");
} else if (useLP && !useTHP &&
(!configuration.supportsExplicitHugePages() || !haveUsableExplicitHugePages)) {
out.shouldContain(warningNoLP);
out.shouldMatch(warningNoLP);
} else if (useLP && useTHP && !configuration.supportsTHP()) {
out.shouldContain(warningNoTHP);
out.shouldMatch(warningNoTHP);
} else if (useLP && !useTHP &&
configuration.supportsExplicitHugePages() && haveUsableExplicitHugePages) {
if (configuration.getExplicitAvailableHugePageNumber() == 0) {
throw new SkippedException("No usable explicit hugepages configured on the system, skipping test");
}
out.shouldContain("[info][pagesize] Using the default large page size: " + buildSizeString(configuration.getExplicitDefaultHugePageSize()));
out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=0");
out.shouldContain("[info][pagesize] Large page support enabled");
out.shouldMatch("\\[info *\\]\\[pagesize *\\] Using the default large page size: " + buildSizeString(configuration.getExplicitDefaultHugePageSize()));
out.shouldMatch("\\[info *\\]\\[pagesize *\\] UseLargePages=1, UseTransparentHugePages=0");
out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support enabled");
} else if (useLP && useTHP && configuration.supportsTHP()) {
long thpPageSize = configuration.getThpPageSizeOrFallback();
String thpPageSizeString = buildSizeString(thpPageSize);
// We expect to see exactly two "Usable page sizes" : the system page size and the THP page size. The system
// page size differs, but its always in KB).
out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=1");
out.shouldMatch(".*\\[info]\\[pagesize] Large page support enabled. Usable page sizes: \\d+[kK], " + thpPageSizeString + ". Default large page size: " + thpPageSizeString + ".*");
out.shouldMatch("\\[info *\\]\\[pagesize *\\] UseLargePages=1, UseTransparentHugePages=1");
out.shouldMatch("\\[info *\\]\\[pagesize *\\] Large page support enabled\\. Usable page sizes: \\d+[kK], " + thpPageSizeString + "\\. Default large page size: " + thpPageSizeString);
}
}

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2023 SAP SE. All rights reserved.
* Copyright (c) 2023, 2024, Red Hat, Inc. All rights reserved.
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, 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
@ -322,7 +322,7 @@ public class TestTrimNative {
checkExpectedLogMessages(output, false, 0);
parseOutputAndLookForNegativeTrim(output, 0, 0, strictTesting);
// The following output is expected to be printed with warning level, so it should not need -Xlog
output.shouldContain("[warning][trimnative] Native heap trim is not supported on this platform");
output.shouldMatch("\\[warning\\]\\[trimnative *\\] Native heap trim is not supported on this platform");
} break;
case "testOffExplicit": {

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2023, Alibaba Group Holding Limited. All Rights Reserved.
* Copyright (c) 2026, 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
@ -55,7 +56,7 @@ public class HeapDumpParallelTest {
dcmdOut.shouldHaveExitValue(0);
dcmdOut.shouldContain("Heap dump file created");
OutputAnalyzer appOut = new OutputAnalyzer(app.getProcessStdout());
appOut.shouldContain("[heapdump]");
appOut.shouldMatch("\\[heapdump *\\]");
String opts = Arrays.asList(Utils.getTestJavaOpts()).toString();
if (opts.contains("-XX:+UseSerialGC") || opts.contains("-XX:+UseEpsilonGC")) {
System.out.println("UseSerialGC detected.");
@ -136,4 +137,4 @@ public class HeapDumpParallelTest {
PidJcmdExecutor executor = new PidJcmdExecutor("" + lingeredAppPid);
return executor.execute("GC.heap_dump " + arg + " " + heapDumpFile.getAbsolutePath());
}
}
}

View File

@ -59,7 +59,7 @@ exclusiveAccess.dirs=java/math/BigInteger/largeMemory \
java/rmi/Naming java/util/prefs sun/management/jmxremote \
sun/tools/jstatd sun/security/mscapi java/util/Arrays/largeMemory \
java/util/BitSet/stream javax/rmi java/net/httpclient/websocket \
com/sun/net/httpserver/simpleserver sun/tools/jhsdb
com/sun/net/httpserver/simpleserver sun/tools/jhsdb javax/sound
# Group definitions
groups=TEST.groups

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8041488 8316974 8318569 8306116 8385736 8385834
* @bug 8041488 8316974 8318569 8306116 8385736 8385834 8386200
* @summary Tests for ListFormat class
* @run junit TestListFormat
*/
@ -74,6 +74,14 @@ public class TestListFormat {
"",
"",
};
// Ensures MessageFormat single quotes in custom patterns are treated as literals.
private static final String[] CUSTOM_PATTERNS_SINGLE_QUOTE = {
"' {0} ' {1}",
"{0} '' {1}",
"{0} ''' {1} '''",
"",
"",
};
private static final String[] CUSTOM_PATTERNS_IAE_START = {
"{0}",
"{0} mid {1}",
@ -142,6 +150,10 @@ public class TestListFormat {
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE2, ". foo | bar ["),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE3, ". foo * bar | baz ["),
arguments(CUSTOM_PATTERNS_METACHAR, SAMPLE4, ". foo * bar + baz | qux ["),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE1, "foo"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE2, "' foo ''' bar '''"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE3, "' foo ' bar ''' baz '''"),
arguments(CUSTOM_PATTERNS_SINGLE_QUOTE, SAMPLE4, "' foo ' bar '' baz ''' qux '''")
};
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2026, 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 8380993
* @library /test/lib
* @summary Validates AIX timezone mapping behavior where POSIX TZ strings
* with comma-separated DST rules are truncated and mapped through tzmappings
* to the expected IANA timezone IDs.
* @requires os.family == "aix"
* @run main/othervm AIXTzMappingTest
*/
import java.util.TimeZone;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class AIXTzMappingTest {
// POSIX TZ strings that should be mapped via tzmappings
private static final String TZ_CET = "CET-1CEST,M3.5.0,M10.5.0";
private static final String TZ_MEZ = "MEZ-1MESZ,M3.5.0,M10.5.0/3";
private static final String ID_PARIS = "Europe/Paris";
private static final String ID_BERLIN = "Europe/Berlin";
public static void main(String[] args) throws Throwable {
if (args.length == 0) {
runWithTZ(TZ_CET, ID_PARIS);
runWithTZ(TZ_MEZ, ID_BERLIN);
} else if (args.length == 1) {
runTZTest(args[0]);
} else {
throw new RuntimeException(
"Expected 0 or 1 arguments, got " + args.length);
}
}
private static void runWithTZ(String tz, String expectedId)
throws Throwable {
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
"AIXTzMappingTest", expectedId);
pb.environment().put("TZ", tz);
OutputAnalyzer output = ProcessTools.executeProcess(pb);
output.shouldHaveExitValue(0);
}
/*
* On AIX, POSIX TZ strings such as:
* CET-1CEST,M3.5.0,M10.5.0
* MEZ-1MESZ,M3.5.0,M10.5.0/3
* are truncated at the comma and mapped through tzmappings to
* IANA timezone IDs.
*
* This test verifies that the expected IANA timezone ID is selected.
*/
private static void runTZTest(String expectedId) {
String tzStr = System.getenv("TZ");
if (tzStr == null) {
throw new RuntimeException(
"Got unexpected timezone information: TZ is null");
}
TimeZone tz = TimeZone.getDefault();
String tzId = tz.getID();
if (!expectedId.equals(tzId)) {
throw new RuntimeException(
"Expected timezone ID " + expectedId
+ " but got " + tzId
+ " for TZ=" + tzStr);
}
System.out.println(
"AIX timezone mapping test passed: "
+ tzId + " for TZ=" + tzStr);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2026, 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
@ -26,7 +26,10 @@
* @library /test/lib
* @summary This test will ensure that daylight savings rules are followed
* appropriately when setting a custom timezone ID via the TZ env variable.
* @requires os.family != "windows"
* AIX is excluded because it uses a different timezone mapping mechanism
* through the tzmappings file; see AIXTzMappingTest.java for AIX-specific
* coverage.
* @requires os.family != "windows" & os.family != "aix"
* @run main/othervm CustomTzIDCheckDST
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2026, 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
@ -41,6 +41,7 @@ import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import jdk.incubator.vector.Float16;
abstract class AbstractVectorConversionTest {
@ -156,6 +157,31 @@ abstract class AbstractVectorConversionTest {
return a;
}
interface ToFloat16F {
short apply(int i);
}
static short[] fill_float16(int s, ToFloat16F f) {
return fill_float16(new short[s], f);
}
static short[] fill_float16(short[] a, ToFloat16F f) {
for (int i = 0; i < a.length; i++) {
a[i] = f.apply(i);
}
if (a.length > 7) {
a[0] = Float16.float16ToRawShortBits(Float16.MAX_VALUE);
a[1] = Float16.float16ToRawShortBits(Float16.MIN_VALUE);
a[2] = Float16.float16ToRawShortBits(Float16.NEGATIVE_INFINITY);
a[3] = Float16.float16ToRawShortBits(Float16.POSITIVE_INFINITY);
a[4] = Float16.float16ToRawShortBits(Float16.NaN);
a[5] = (short)0.0;
a[6] = Short.MIN_VALUE;
}
return a;
}
static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
withToString("byte(i)", (int s) -> fill_byte(s, i -> (byte) (i + 1)))
);
@ -180,6 +206,10 @@ abstract class AbstractVectorConversionTest {
withToString("double(i)", (int s) -> fill_double(s, i -> (double) (i * 10 + 0.1)))
);
static final List<IntFunction<short[]>> FLOAT16_GENERATORS = List.of(
withToString("Float16(i)", (int s) -> fill_float16(s, i -> (short) (i * 100 + 1)))
);
static List<?> sourceGenerators(Class<?> src) {
if (src == byte.class) {
return BYTE_GENERATORS;
@ -199,6 +229,9 @@ abstract class AbstractVectorConversionTest {
else if (src == double.class) {
return DOUBLE_GENERATORS;
}
else if (src == Float16.class) {
return FLOAT16_GENERATORS;
}
else
throw new IllegalStateException();
}
@ -206,11 +239,11 @@ abstract class AbstractVectorConversionTest {
static Object[][] fixedShapeXFixedShapeSpeciesArgs(VectorShape shape) {
List<Object[]> args = new ArrayList<>();
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> src = VectorSpecies.of(srcE, shape);
List<?> srcGens = sourceGenerators(srcE);
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> dst = VectorSpecies.of(dstE, shape);
for (Object srcGen : srcGens) {
@ -225,12 +258,12 @@ abstract class AbstractVectorConversionTest {
static Object[][] fixedShapeXShapeSpeciesArgs(VectorShape srcShape) {
List<Object[]> args = new ArrayList<>();
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> src = VectorSpecies.of(srcE, srcShape);
List<?> srcGens = sourceGenerators(srcE);
for (VectorShape dstShape : VectorShape.values()) {
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> dst = VectorSpecies.of(dstE, dstShape);
for (Object srcGen : srcGens) {
@ -245,10 +278,10 @@ abstract class AbstractVectorConversionTest {
static Object[][] fixedShapeXSegmentedCastSpeciesArgs(VectorShape srcShape, boolean legal) {
List<Object[]> args = new ArrayList<>();
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> srcE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> src = VectorSpecies.of(srcE, srcShape);
for (VectorShape dstShape : VectorShape.values()) {
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class)) {
for (Class<?> dstE : List.of(byte.class, short.class, int.class, long.class, float.class, double.class, Float16.class)) {
VectorSpecies<?> dst = VectorSpecies.of(dstE, dstShape);
if (legal == (dst.length() == src.length())) {
args.add(new Object[]{src, dst});
@ -261,6 +294,22 @@ abstract class AbstractVectorConversionTest {
public enum ConvAPI {CONVERT, CONVERTSHAPE, CASTSHAPE, REINTERPRETSHAPE}
static Short float16_conversion_adapter(Number in) {
if (in.getClass() == Short.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.shortValue()));
else if (in.getClass() == Integer.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.intValue()));
else if (in.getClass() == Long.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.longValue()));
else if (in.getClass() == Float.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.floatValue()));
else if (in.getClass() == Double.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.doubleValue()));
else if (in.getClass() == Byte.class)
return Float16.float16ToRawShortBits(Float16.valueOf(in.byteValue()));
else
throw new IllegalStateException();
}
static Function<Number, Object> convertValueFunction(Class<?> to) {
if (to == byte.class)
@ -273,6 +322,8 @@ abstract class AbstractVectorConversionTest {
return Number::longValue;
else if (to == float.class)
return Number::floatValue;
else if (to == Float16.class)
return (N) -> float16_conversion_adapter(N);
else if (to == double.class)
return Number::doubleValue;
else
@ -282,7 +333,7 @@ abstract class AbstractVectorConversionTest {
static BiConsumer<ByteBuffer, Object> putBufferValueFunction(Class<?> from) {
if (from == byte.class)
return (bb, o) -> bb.put((byte) o);
else if (from == short.class)
else if (from == short.class || from == Float16.class)
return (bb, o) -> bb.putShort((short) o);
else if (from == int.class)
return (bb, o) -> bb.putInt((int) o);
@ -299,7 +350,7 @@ abstract class AbstractVectorConversionTest {
static Function<ByteBuffer, Number> getBufferValueFunction(Class<?> to) {
if (to == byte.class)
return ByteBuffer::get;
else if (to == short.class)
else if (to == short.class || to == Float16.class)
return ByteBuffer::getShort;
else if (to == int.class)
return ByteBuffer::getInt;
@ -335,10 +386,23 @@ abstract class AbstractVectorConversionTest {
static void copyConversionArray(Object src, int srcPos,
Object dest, int destPos,
int length,
VectorSpecies srcSpecies,
VectorSpecies dstSpecies,
Function<Number, Object> c) {
if (srcSpecies.elementType() == dstSpecies.elementType()) {
System.arraycopy(src, srcPos, dest, destPos, length);
return;
}
for (int i = 0; i < length; i++) {
Number v = (Number) Array.get(src, srcPos + i);
Array.set(dest, destPos + i, c.apply(v));
if (srcSpecies.elementType() == Float16.class) {
v = (Number) Float16.shortBitsToFloat16(v.shortValue());
}
v = (Number) c.apply(v);
if (dstSpecies.elementType() == Float16.class) {
v = (Number) v.shortValue();
}
Array.set(dest, destPos + i, v);
}
}
@ -420,8 +484,14 @@ abstract class AbstractVectorConversionTest {
int[] parts = getPartsArray(m, is_contracting_conv);
Object expected = Array.newInstance(destSpecies.elementType(), out_len);
Object actual = Array.newInstance(destSpecies.elementType(), out_len);
Object expected = null, actual = null;
if (destSpecies.elementType() == Float16.class) {
expected = Array.newInstance(short.class, out_len);
actual = Array.newInstance(short.class, out_len);
} else {
expected = Array.newInstance(destSpecies.elementType(), out_len);
actual = Array.newInstance(destSpecies.elementType(), out_len);
}
Function<Number, Object> convertValue = convertValueFunction(destSpecies.elementType());
@ -432,11 +502,12 @@ abstract class AbstractVectorConversionTest {
if (is_contracting_conv) {
int start_idx = -part * src_species_len;
zeroArray(expected, j, dst_species_len);
copyConversionArray(in, i, expected, start_idx + j, src_species_len, convertValue);
copyConversionArray(in, i, expected, start_idx + j, src_species_len, srcSpecies, destSpecies, convertValue);
} else {
int start_idx = part * dst_species_len;
copyConversionArray(in, start_idx + i, expected, j, dst_species_len, convertValue);
copyConversionArray(in, start_idx + i, expected, j, dst_species_len, srcSpecies, destSpecies, convertValue);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
@ -452,7 +523,6 @@ abstract class AbstractVectorConversionTest {
System.arraycopy(rv.toArray(), 0, actual, j, dst_species_len);
}
}
Assert.assertEquals(actual, expected);
}
@ -469,8 +539,14 @@ abstract class AbstractVectorConversionTest {
int[] parts = getPartsArray(m, is_contracting_conv);
Object expected = Array.newInstance(dstSpecies.elementType(), out_len);
Object actual = Array.newInstance(dstSpecies.elementType(), out_len);
Object expected = null, actual = null;
if (dstSpecies.elementType() == Float16.class) {
expected = Array.newInstance(short.class, out_len);
actual = Array.newInstance(short.class, out_len);
} else {
expected = Array.newInstance(dstSpecies.elementType(), out_len);
actual = Array.newInstance(dstSpecies.elementType(), out_len);
}
BiConsumer<ByteBuffer, Object> putValue = putBufferValueFunction(srcSpecies.elementType());
Function<ByteBuffer, Number> getValue = getBufferValueFunction(dstSpecies.elementType());

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More