mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-11 21:15:16 +00:00
Merge branch 'master' into loom_s390_v1
This commit is contained in:
commit
147213aed2
@ -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
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
%{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ======
|
||||
//
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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("'", "''");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
/* ============================================================================ */
|
||||
|
||||
|
||||
@ -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() {}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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) {}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
// ================================================
|
||||
|
||||
@ -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},
|
||||
|
||||
@ -64,8 +64,9 @@ import static jdk.internal.vm.vector.Utils.isNonCapturingLambda;
|
||||
*
|
||||
* <li>{@code bits(x)} — 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} — 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. — 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)} */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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
|
||||
#
|
||||
#
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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\\)");
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)");
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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\\)");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
@ -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__");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
}
|
||||
|
||||
@ -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");
|
||||
};
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 '''")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
102
test/jdk/java/util/TimeZone/AIXTzMappingTest.java
Normal file
102
test/jdk/java/util/TimeZone/AIXTzMappingTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
*/
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
1038
test/jdk/jdk/incubator/vector/Float16Vector128LoadStoreTests.java
Normal file
1038
test/jdk/jdk/incubator/vector/Float16Vector128LoadStoreTests.java
Normal file
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
Loading…
x
Reference in New Issue
Block a user